From 2c736d0860251e2242080d411a0a4d949f5b5ade Mon Sep 17 00:00:00 2001 From: "Daniel P. Carvalho" Date: Sun, 4 Oct 2026 00:55:17 -0300 Subject: [PATCH] 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 --- .../mips/pic32mz/boards/ev49n51a/index.rst | 13 +++++++++++++ .../pic32mz/ev49n51a/configs/netnsh/defconfig | 6 ++++-- .../pic32mz/ev49n51a/configs/nsh/defconfig | 6 ++++-- .../pic32mz/ev49n51a/scripts/mips-debug.ld | 19 ++++++++++--------- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/Documentation/platforms/mips/pic32mz/boards/ev49n51a/index.rst b/Documentation/platforms/mips/pic32mz/boards/ev49n51a/index.rst index addf4cb4a6d..fea00bea53c 100644 --- a/Documentation/platforms/mips/pic32mz/boards/ev49n51a/index.rst +++ b/Documentation/platforms/mips/pic32mz/boards/ev49n51a/index.rst @@ -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 ========== diff --git a/boards/mips/pic32mz/ev49n51a/configs/netnsh/defconfig b/boards/mips/pic32mz/ev49n51a/configs/netnsh/defconfig index 1162e285b4b..8bfde21e2ad 100644 --- a/boards/mips/pic32mz/ev49n51a/configs/netnsh/defconfig +++ b/boards/mips/pic32mz/ev49n51a/configs/netnsh/defconfig @@ -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 diff --git a/boards/mips/pic32mz/ev49n51a/configs/nsh/defconfig b/boards/mips/pic32mz/ev49n51a/configs/nsh/defconfig index e0a67eab8eb..17c3edb4bb4 100644 --- a/boards/mips/pic32mz/ev49n51a/configs/nsh/defconfig +++ b/boards/mips/pic32mz/ev49n51a/configs/nsh/defconfig @@ -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 diff --git a/boards/mips/pic32mz/ev49n51a/scripts/mips-debug.ld b/boards/mips/pic32mz/ev49n51a/scripts/mips-debug.ld index 687043f05a4..12e2f495c4e 100644 --- a/boards/mips/pic32mz/ev49n51a/scripts/mips-debug.ld +++ b/boards/mips/pic32mz/ev49n51a/scripts/mips-debug.ld @@ -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 */