Skip to content

arch/arm/nrf53: enable the application core CACHE peripheral - #20005

Open
AlmAck wants to merge 1 commit into
apache:masterfrom
AlmAck:fix/nrf53-enable-appcore-cache
Open

arch/arm/nrf53: enable the application core CACHE peripheral#20005
AlmAck wants to merge 1 commit into
apache:masterfrom
AlmAck:fix/nrf53-enable-appcore-cache

Conversation

@AlmAck

@AlmAck AlmAck commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

The nRF5340 application core comes out of reset with its flash cache
disabled and nothing in the tree turns it on. nrf53_start() does call
nrf53_enable_icache(), but that drives NVMC ICACHECNF and is gated on
NRF53_FLASH_PREFETCH, which depends on NRF53_NETCORE so it is not
even compiled for an application core build.

The nRF5340 places the application core cache in a separate CACHE
peripheral at 0x50001000. NRF53_CACHE_BASE is already defined in
hardware/nrf53_memorymap_cpuapp.h, but there was no register header and
no enable. This adds both, behind a new NRF53_CACHE option
(depends on NRF53_APPCORE, default y).

New Kconfig option, a new register header, one write at startup, and a
bypass/invalidate around the two progmem operations. The option defaults to n, matching ARMV7M_ICACHE and ARMV8M_ICACHE/DCACHE, so that upgrading does not silently change the behaviour of an existing configuration.

Cache coherency with the progmem driver

Per the nRF5340 Product Specification, CACHE Instruction and data
cache
:

Both instruction and data accesses towards flash memory or XIP code
regions are cached.

The cache does not observe NVMC programming, so enabling it has a
consequence for arch/arm/src/nrf53/nrf53_flash.c:

  • up_progmem_eraseblock() verifies via up_progmem_ispageerased(),
    which reads the whole page, populating cache lines over exactly the
    region being programmed.
  • up_progmem_write() reads back every word it writes to verify it.

A line held from before the operation would satisfy those read-backs, so
the verify could pass or fail on stale data. This patch therefore
bypasses the cache for the duration of an erase or a write and
invalidates it before re-enabling, so the verify sees the array and
later readers do too.

nrf53_flash.c is built only when NRF53_PROGMEM is selected, which is
not the default.

Testing

Host: Linux x86_64, arm-none-eabi GCC 14.
Board: nrf5340-dk, cpuapp, at 64 MHz.

Measured with apps/benchmarks/scbench before and after the patch, same
binary otherwise:

before after
protected-build syscall round trip 64.1 us 29.6 us
userspace sem wait + post pair 4.75 us 1.95 us

Both a flat build and a CONFIG_BUILD_PROTECTED build were exercised.
The application (LVGL rendering to an SPI display, LittleFS on QSPI NOR,
BLE active) behaves identically apart from being faster; flash is not
written during normal operation, so no coherency issue arises.

@github-actions github-actions Bot added Arch: arm Issues related to ARM (32-bit) architecture Size: M The size of the change in this PR is medium labels Aug 30, 2026
@github-actions

github-actions Bot commented Aug 30, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@simbit18

Copy link
Copy Markdown
Contributor

Hi @AlmAck, please rebase

The nRF5340 application core comes out of reset with its flash cache
disabled and nothing in the tree turns it on.  nrf53_start() does call
nrf53_enable_icache(), but that drives NVMC ICACHECNF and is gated on
NRF53_FLASH_PREFETCH, which depends on NRF53_NETCORE -- so it is not
even compiled for an application core build.

The nRF5340 places the application core cache in a separate CACHE
peripheral at 0x50001000.  NRF53_CACHE_BASE is already defined in
hardware/nrf53_memorymap_cpuapp.h, but there was no register header and
no enable.  Add both, behind a new NRF53_CACHE option.

The option defaults to n, matching ARMV7M_ICACHE and
ARMV8M_ICACHE/DCACHE, so that upgrading does not silently change the
behaviour of an existing configuration.

Measured on nrf5340-dk at 64 MHz with apps/benchmarks/scbench:

  protected-build syscall round trip   64.1 us -> 29.6 us
  userspace sem wait + post pair       4.75 us -> 1.95 us

Flat builds benefit equally; the gain is on any flash-resident code
path.

Per the nRF5340 Product Specification, 'CACHE - Instruction and data
cache', 'both instruction and data accesses towards flash memory or XIP
code regions are cached'.  The cache does not observe NVMC programming,
so nrf53_flash.c has to account for it: both up_progmem_eraseblock() and
up_progmem_write() read back what they just programmed to verify it, and
up_progmem_ispageerased() reads a whole page, so lines covering the
region being programmed are commonly resident.  Bypass the cache for the
duration of an erase or a write and invalidate it before re-enabling, so
the verify reads the array and later readers do too.  That file is built
only when NRF53_PROGMEM is selected, which is not the default.

Signed-off-by: AlmAck <gluca86@gmail.com>
@AlmAck
AlmAck force-pushed the fix/nrf53-enable-appcore-cache branch from 34f4aa3 to 49e0fe1 Compare August 30, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: arm Issues related to ARM (32-bit) architecture Size: M The size of the change in this PR is medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants