Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions arch/arm/src/nrf53/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,23 @@ endif # NRF53_SYSTIMER_RTC

endmenu # System Timer

config NRF53_CACHE
bool "Application core flash cache"
depends on NRF53_APPCORE
default n
---help---
Enable the application core CACHE peripheral, which caches both
instruction and data accesses towards flash and XIP code regions.
The application core runs uncached without this, so enabling it is
a substantial speedup on any flash-resident code path.

The cache does not observe writes to the memory it caches. The
in-tree progmem driver handles this, but code outside the kernel
that programs flash, or a board that maps QSPI into the XIP
window and writes it, must invalidate the cache itself. Left off
by default for that reason, matching ARMV7M_ICACHE and
ARMV8M_ICACHE/DCACHE.

config NRF53_FLASH_PREFETCH
bool "Enable FLASH Pre-fetch"
depends on NRF53_NETCORE
Expand Down
66 changes: 66 additions & 0 deletions arch/arm/src/nrf53/hardware/nrf53_cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/****************************************************************************
* arch/arm/src/nrf53/hardware/nrf53_cache.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/

#ifndef __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_CACHE_H
#define __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_CACHE_H

/****************************************************************************
* Included Files
****************************************************************************/

#include <nuttx/config.h>
#include "hardware/nrf53_memorymap.h"

/* The application core CACHE peripheral (flash instruction/data cache).
* Distinct from the nRF52-era NVMC ICACHECNF register, which does not
* exist on this part.
*/

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

/* Register offsets *********************************************************/

#define NRF53_CACHE_ENABLE_OFFSET 0x500 /* Enable the cache */
#define NRF53_CACHE_INVALIDATE_OFFSET 0x504 /* Invalidate the cache */
#define NRF53_CACHE_INFO_OFFSET 0x508 /* Cache info */
#define NRF53_CACHE_PROFILINGENABLE_OFFSET 0x518 /* Profiling enable */
#define NRF53_CACHE_MODE_OFFSET 0x51c /* Cache mode */

/* Register addresses *******************************************************/

#define NRF53_CACHE_ENABLE (NRF53_CACHE_BASE + NRF53_CACHE_ENABLE_OFFSET)
#define NRF53_CACHE_INVALIDATE (NRF53_CACHE_BASE + NRF53_CACHE_INVALIDATE_OFFSET)
#define NRF53_CACHE_INFO (NRF53_CACHE_BASE + NRF53_CACHE_INFO_OFFSET)
#define NRF53_CACHE_PROFILINGENABLE (NRF53_CACHE_BASE + NRF53_CACHE_PROFILINGENABLE_OFFSET)
#define NRF53_CACHE_MODE (NRF53_CACHE_BASE + NRF53_CACHE_MODE_OFFSET)

/* ENABLE Register **********************************************************/

#define CACHE_ENABLE_ENABLE (1 << 0) /* Enable cache */

/* INVALIDATE Register ******************************************************/

#define CACHE_INVALIDATE_INVALIDATE (1 << 0) /* Invalidate cache */

#endif /* __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_CACHE_H */
41 changes: 41 additions & 0 deletions arch/arm/src/nrf53/nrf53_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@

#include "hardware/nrf53_ficr.h"
#include "hardware/nrf53_nvmc.h"
#ifdef CONFIG_NRF53_CACHE
# include "hardware/nrf53_cache.h"
#endif

/****************************************************************************
* Pre-processor Definitions
Expand Down Expand Up @@ -64,6 +67,35 @@ static inline uint32_t nrf53_get_pages_num(void)
return getreg32(NRF53_FICR_INFO_CODESIZE);
}

/****************************************************************************
* Private Functions
****************************************************************************/

/* The CACHE peripheral caches both instruction and data accesses towards
* flash, and does not observe NVMC programming. A line held from before an
* erase or a write would otherwise satisfy the read-back that both paths use
* to verify what they just programmed -- up_progmem_ispageerased() reads a
* whole page, so the lines are commonly resident.
*
* Bypass the cache for the duration of the operation so the verify sees the
* array, then invalidate before re-enabling so later readers do too.
*/

static void nrf53_flash_cache_bypass(void)
{
#ifdef CONFIG_NRF53_CACHE
putreg32(0, NRF53_CACHE_ENABLE);
#endif
}

static void nrf53_flash_cache_restore(void)
{
#ifdef CONFIG_NRF53_CACHE
putreg32(CACHE_INVALIDATE_INVALIDATE, NRF53_CACHE_INVALIDATE);
putreg32(CACHE_ENABLE_ENABLE, NRF53_CACHE_ENABLE);
#endif
}

/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down Expand Up @@ -212,6 +244,8 @@ ssize_t up_progmem_eraseblock(size_t block)

page_address = up_progmem_getaddress(block);

nrf53_flash_cache_bypass();

/* Enable erase mode */

putreg32(NVMC_CONFIG_EEN, NRF53_NVMC_CONFIG);
Expand Down Expand Up @@ -244,10 +278,12 @@ ssize_t up_progmem_eraseblock(size_t block)

if (up_progmem_ispageerased(block) == 0)
{
nrf53_flash_cache_restore();
return up_progmem_erasesize(block);
}
else
{
nrf53_flash_cache_restore();
return -EIO;
}
}
Expand Down Expand Up @@ -344,6 +380,8 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)

addr += NRF53_FLASH_BASE;

nrf53_flash_cache_bypass();

/* Begin flashing */

for (; count; count -= 4, pword++, addr += 4)
Expand Down Expand Up @@ -378,10 +416,13 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)

if (getreg32(addr) != *pword)
{
nrf53_flash_cache_restore();
return -EIO;
}
}

nrf53_flash_cache_restore();

return written;
}

Expand Down
11 changes: 11 additions & 0 deletions arch/arm/src/nrf53/nrf53_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "nvic.h"

#include "nrf53_clockconfig.h"
#include "hardware/nrf53_cache.h"
#include "hardware/nrf53_nvmc.h"
#include "hardware/nrf53_utils.h"
#include "hardware/nrf53_uicr.h"
Expand Down Expand Up @@ -253,6 +254,16 @@ void __start(void)
nrf53_enable_profile(true);
#endif

#ifdef CONFIG_NRF53_CACHE
/* Enable the application core CACHE peripheral. The nrf53_enable_icache()
* path above drives NVMC ICACHECNF and is gated on NRF53_FLASH_PREFETCH,
* which depends on NRF53_NETCORE, so nothing else enables a cache on the
* application core.
*/

putreg32(CACHE_ENABLE_ENABLE, NRF53_CACHE_ENABLE);
#endif

#ifdef CONFIG_ARCH_PERF_EVENTS
up_perf_init((void *)BOARD_SYSTICK_CLOCK);
#endif
Expand Down
Loading