boards/mips/pic32mz/ev49n51a: enable the L1 caches.

The I- and D-Caches were disabled, so all code ran from flash through
the prefetch buffer and all data accesses went to SRAM.  Enable both
caches in nsh and netnsh, and link the data memory in KSEG0 instead of
KSEG1 so that it goes through the D-Cache (KSEG0 is uncached when the
caches are disabled).  CONFIG_BOARD_LOOPSPERMSEC is recalibrated with
calib_udelay for the cached configuration.

CoreMark (XC32 v6.00, -O2) goes from 82.5 to 544.6 iterations/s.  The
average ping round trip time drops from 0.74 to 0.56 ms for 64-byte
packets and from 1.92 to 0.93 ms for 1400-byte packets.

Tested on the EV49N51A with XC32: 5000 pings of 1472 bytes at 2 ms
intervals with payload checking, ifdown/ifup cycles, telnet sessions
and CoreMark.  With Pinguino GCC: 2000 pings of 1472 bytes and 1000
small pings at 3 ms intervals.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
This commit is contained in:
Daniel P. Carvalho 2026-10-04 00:55:17 -03:00 • committed by Xiang Xiao
parent e8cef71b45
commit 2c736d0860
4 changed files with 31 additions and 13 deletions

View file

@ -309,6 +309,19 @@ The PIC32MZ-W1 has no factory-programmed Ethernet MAC address. Assign one
with ``CONFIG_NETINIT_NOMAC`` or with the ``SIOCSIFHWADDR`` ioctl before the
interface is brought up.
L1 cache
========
Both configurations enable the 16 KB instruction and 16 KB data caches
(``CONFIG_MIPS32_ICACHE``, which also selects ``CONFIG_MIPS32_DCACHE``).
The linker script places the data memory in KSEG0, so that it goes through
the D-Cache; KSEG0 is uncached when the caches are disabled. The Ethernet
driver performs the D-Cache maintenance around its DMA transfers.
``CONFIG_BOARD_LOOPSPERMSEC`` (22224) is calibrated with the caches
enabled. If you disable them, set it to 7245, or the busy-wait delays will
be about three times too long.
Boot trace
==========

View file

@ -15,7 +15,7 @@ CONFIG_ARCH_CHIP_PIC32MZW1=y
CONFIG_ARCH_CHIP_WFI32E01=y
CONFIG_ARCH_MIPS=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_LOOPSPERMSEC=7245
CONFIG_BOARD_LOOPSPERMSEC=22224
CONFIG_BUILTIN=y
CONFIG_ETH0_PHY_LAN8720=y
CONFIG_FS_PROCFS=y
@ -23,6 +23,8 @@ CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LINE_MAX=64
CONFIG_MIPS32_DCACHE_SIZE=16384
CONFIG_MIPS32_ICACHE=y
CONFIG_MIPS32_TOOLCHAIN_MICROCHIPL_XC32=y
CONFIG_MTD=y
CONFIG_MTD_SST26=y
@ -48,7 +50,7 @@ CONFIG_PIC32MZ_SPI1=y
CONFIG_PIC32MZ_UART1=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0xa0000000
CONFIG_RAM_START=0x80000000
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_LPWORK=y

View file

@ -15,13 +15,15 @@ CONFIG_ARCH_CHIP_PIC32MZW1=y
CONFIG_ARCH_CHIP_WFI32E01=y
CONFIG_ARCH_MIPS=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_LOOPSPERMSEC=7245
CONFIG_BOARD_LOOPSPERMSEC=22224
CONFIG_BUILTIN=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LINE_MAX=64
CONFIG_MIPS32_DCACHE_SIZE=16384
CONFIG_MIPS32_ICACHE=y
CONFIG_MIPS32_TOOLCHAIN_MICROCHIPL_XC32=y
CONFIG_MTD=y
CONFIG_MTD_SST26=y
@ -33,7 +35,7 @@ CONFIG_PIC32MZ_SPI1=y
CONFIG_PIC32MZ_UART1=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0xa0000000
CONFIG_RAM_START=0x80000000
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=2

View file

@ -82,11 +82,12 @@ MEMORY
kseg1_devsign (r) : ORIGIN = 0xbfc55fdc, LENGTH = 4
/* WFI32E01 has 256Kb of data memory at physical address 0x00000000,
* always accessed through KSEG1 (no data cache). 640 bytes are set
* accessed through KSEG0 so that it goes through the D-Cache when the
* cache is enabled (KSEG0 is uncached otherwise). 640 bytes are set
* aside at the start, matching the margin EC/EF boards reserve.
*/
kseg1_datamem (rw!x) : ORIGIN = 0xa0000200, LENGTH = 256K - 640
kseg0_datamem (rw!x) : ORIGIN = 0x80000200, LENGTH = 256K - 640
}
/* No OUTPUT_FORMAT: XC32 names its little-endian ELF target
@ -212,7 +213,7 @@ SECTIONS
*(.gnu.linkonce.d.*)
KEEP (*(.gnu.linkonce.d.*personality*))
*(.data1)
} > kseg1_datamem AT > kseg0_progmem
} > kseg0_datamem AT > kseg0_progmem
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
_gp = ALIGN(16) + 0x7FF0 ;
@ -220,24 +221,24 @@ SECTIONS
.got :
{
*(.got.plt) *(.got)
} > kseg1_datamem AT > kseg0_progmem
} > kseg0_datamem AT > kseg0_progmem
.sdata :
{
*(.sdata .sdata.* .gnu.linkonce.s.*)
} > kseg1_datamem AT > kseg0_progmem
} > kseg0_datamem AT > kseg0_progmem
.lit8 :
{
*(.lit8)
} > kseg1_datamem AT > kseg0_progmem
} > kseg0_datamem AT > kseg0_progmem
.lit4 :
{
*(.lit4)
. = ALIGN(4);
_edata = ABSOLUTE(.);
} >kseg1_datamem AT>kseg0_progmem
} >kseg0_datamem AT>kseg0_progmem
.sbss :
{
@ -246,7 +247,7 @@ SECTIONS
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
} >kseg1_datamem
} >kseg0_datamem
.bss :
{
@ -256,7 +257,7 @@ SECTIONS
*(COMMON)
. = ALIGN(16);
_ebss = ABSOLUTE(.);
} > kseg1_datamem
} > kseg0_datamem
/* Stabs debugging sections */