From 23266231f60181b350c228f7be632fe12c71a3bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 11 Apr 2024 14:03:32 +0200 Subject: [PATCH 1/7] [nrf fromtree] soc: nordic: nrf54h: Remove redundant ICACHE kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove CONFIG_NRF_ENABLE_ICACHE as it is not needed. There is CONFIG_ICACHE which is by default enabled for nrf54h. Signed-off-by: Krzysztof Chruściński (cherry picked from commit cfa6e250e4ab7f6e38547f8d9b06f117bc1910bc) --- soc/nordic/nrf54h/Kconfig | 8 -------- soc/nordic/nrf54h/soc.c | 2 -- 2 files changed, 10 deletions(-) diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index 2b967bece7c..8925669ae0d 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -31,11 +31,3 @@ config SOC_NRF54H20_CPURAD config SOC_NRF54H20_CPUPPR depends on RISCV_CORE_NORDIC_VPR - -if SOC_NRF54H20 - -config NRF_ENABLE_ICACHE - bool "Instruction cache (I-Cache)" - default y - -endif # SOC_NRF54H20 diff --git a/soc/nordic/nrf54h/soc.c b/soc/nordic/nrf54h/soc.c index 1d071f96b20..dd04dbe1b59 100644 --- a/soc/nordic/nrf54h/soc.c +++ b/soc/nordic/nrf54h/soc.c @@ -82,9 +82,7 @@ static int trim_hsfll(void) static int nordicsemi_nrf54h_init(void) { -#if defined(CONFIG_NRF_ENABLE_ICACHE) sys_cache_instr_enable(); -#endif power_domain_init(); From b40508b099d81e51887c52e2e3374c80044ddc85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 11 Apr 2024 14:06:57 +0200 Subject: [PATCH 2/7] [nrf fromtree] soc: nordic: nrf54h: Add DCACHE initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add initialization of the data cache. Signed-off-by: Krzysztof Chruściński (cherry picked from commit d82b27b08bd7a9dce716b5932b4beeb37b287ea3) --- soc/nordic/nrf54h/soc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/nordic/nrf54h/soc.c b/soc/nordic/nrf54h/soc.c index dd04dbe1b59..df72cdb977b 100644 --- a/soc/nordic/nrf54h/soc.c +++ b/soc/nordic/nrf54h/soc.c @@ -83,6 +83,7 @@ static int trim_hsfll(void) static int nordicsemi_nrf54h_init(void) { sys_cache_instr_enable(); + sys_cache_data_enable(); power_domain_init(); From 683c0d31e464c28cde75396038ca60aa480fe445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 15 Apr 2024 11:46:19 +0200 Subject: [PATCH 3/7] [nrf fromtree] manifest: Update hal_nordic with nrf_cache change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add nrf_cache_lineaddr_get to nordic HAL. Signed-off-by: Krzysztof Chruściński (cherry picked from commit 29a4bb61a00fa53d1dccce9dcf057efdcf25b237) --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 39252a3dfa4..a81bbc3e666 100644 --- a/west.yml +++ b/west.yml @@ -183,7 +183,7 @@ manifest: groups: - hal - name: hal_nordic - revision: f8e4d73a78316ea9ef85f09f24a3a229e40c1a80 + revision: bdef8b66d5f59d95c09889918a04ddaecce322c8 path: modules/hal/nordic groups: - hal From df150f6c55200ddd86e5187002ef065c21d3a236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 15 Apr 2024 11:37:43 +0200 Subject: [PATCH 4/7] [nrf fromtree] drivers: cache: nrf: Handle issue with LINEADDR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nrf54h20 has a bug that requires to manually set 28th bit in the line address. 28th bit indicates secure memory space. Add handling to the cache driver. Signed-off-by: Krzysztof Chruściński (cherry picked from commit 73d4f58b98e9a920066ece1765b5cad5152220ee) --- drivers/cache/Kconfig.nrf | 6 ++++++ drivers/cache/cache_nrf.c | 12 +++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/cache/Kconfig.nrf b/drivers/cache/Kconfig.nrf index 820445db432..c1cfc2c8c58 100644 --- a/drivers/cache/Kconfig.nrf +++ b/drivers/cache/Kconfig.nrf @@ -7,3 +7,9 @@ config CACHE_NRF_CACHE depends on HAS_NRFX && CACHE_MANAGEMENT help Enable support for the nRF cache driver. + +config CACHE_NRF_PATCH_LINEADDR + bool "Patch lineaddr" + default y if SOC_NRF54H20 + help + Manually set 28th bit in the LINEADDR in Trustzone Secure build. diff --git a/drivers/cache/cache_nrf.c b/drivers/cache/cache_nrf.c index 63d76a47d6e..dc40c5066d9 100644 --- a/drivers/cache/cache_nrf.c +++ b/drivers/cache/cache_nrf.c @@ -144,7 +144,17 @@ static inline int _cache_range(NRF_CACHE_Type *cache, enum k_nrf_cache_op op, vo size_t size) { uintptr_t line_addr = (uintptr_t)addr; - uintptr_t end_addr = line_addr + size; + uintptr_t end_addr; + + /* Some SOCs has a bug that requires to set 28th bit in the address on + * Trustzone secure builds. + */ + if (IS_ENABLED(CONFIG_CACHE_NRF_PATCH_LINEADDR) && + !IS_ENABLED(CONFIG_TRUSTED_EXECUTION_NONSECURE)) { + line_addr |= BIT(28); + } + + end_addr = line_addr + size; /* * Align address to line size From f530a2886b90d7e467205add7d40503798535386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 15 Apr 2024 11:41:15 +0200 Subject: [PATCH 5/7] [nrf fromtree] drivers: cache: nrf: Fix case when driver may hang MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Driver was disabling cache before full range operations and that was causing hanging on polling for cache busy status since state was never changing (because cache was disabled). Additionally, added flushing to data cache disabling. If flushing is not performed then execution fails since data in cache is lost. Signed-off-by: Krzysztof Chruściński (cherry picked from commit b83a11281d9e1b8c7a73738513b19d8952d643cd) --- drivers/cache/cache_nrf.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/cache/cache_nrf.c b/drivers/cache/cache_nrf.c index dc40c5066d9..b0fa8a02de8 100644 --- a/drivers/cache/cache_nrf.c +++ b/drivers/cache/cache_nrf.c @@ -68,14 +68,6 @@ static inline int _cache_all(NRF_CACHE_Type *cache, enum k_nrf_cache_op op) return -ENOTSUP; } - k_spinlock_key_t key = k_spin_lock(&lock); - - /* - * Invalidating the whole cache is dangerous. For good measure - * disable the cache. - */ - nrf_cache_disable(cache); - wait_for_cache(cache); switch (op) { @@ -102,10 +94,6 @@ static inline int _cache_all(NRF_CACHE_Type *cache, enum k_nrf_cache_op op) wait_for_cache(cache); - nrf_cache_enable(cache); - - k_spin_unlock(&lock, key); - return 0; } @@ -202,11 +190,6 @@ void cache_data_enable(void) nrf_cache_enable(NRF_DCACHE); } -void cache_data_disable(void) -{ - nrf_cache_disable(NRF_DCACHE); -} - int cache_data_flush_all(void) { #if NRF_CACHE_HAS_TASK_CLEAN @@ -216,6 +199,14 @@ int cache_data_flush_all(void) #endif } +void cache_data_disable(void) +{ + if (nrf_cache_enable_check(NRF_DCACHE)) { + (void)cache_data_flush_all(); + } + nrf_cache_disable(NRF_DCACHE); +} + int cache_data_invd_all(void) { return _cache_checks(NRF_DCACHE, K_NRF_CACHE_INVD, NULL, 0, false); From 5e97f8e541488e05fb6f0b7ea6c9e280decfda6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 15 Apr 2024 11:44:39 +0200 Subject: [PATCH 6/7] [nrf fromtree] drivers: cache: nrf: Optimize operation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply changes which significantly speed up cache operations. Removed k_busy_wait from function which polls for cache busyness. Removed spinlock from cache operation. Lock taking and releasing takes time and it is faster to check if LINEADDR changed after performing the operation. If LINEADDR changed then it indicates that current context was preempted by another cache operation. If such state is detected current operation is repeated. Signed-off-by: Krzysztof Chruściński (cherry picked from commit 9f6567b87a36f6d08a4923db08932ece5deb7d4d) --- drivers/cache/cache_nrf.c | 44 +++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/drivers/cache/cache_nrf.c b/drivers/cache/cache_nrf.c index b0fa8a02de8..d1a28127727 100644 --- a/drivers/cache/cache_nrf.c +++ b/drivers/cache/cache_nrf.c @@ -17,7 +17,6 @@ LOG_MODULE_REGISTER(cache_nrfx, CONFIG_CACHE_LOG_LEVEL); #define CACHE_LINE_SIZE 32 #define CACHE_BUSY_RETRY_INTERVAL_US 10 -static struct k_spinlock lock; enum k_nrf_cache_op { /* @@ -55,7 +54,6 @@ static inline bool is_cache_busy(NRF_CACHE_Type *cache) static inline void wait_for_cache(NRF_CACHE_Type *cache) { while (is_cache_busy(cache)) { - k_busy_wait(CACHE_BUSY_RETRY_INTERVAL_US); } } @@ -99,33 +97,33 @@ static inline int _cache_all(NRF_CACHE_Type *cache, enum k_nrf_cache_op op) static inline void _cache_line(NRF_CACHE_Type *cache, enum k_nrf_cache_op op, uintptr_t line_addr) { - wait_for_cache(cache); + do { + wait_for_cache(cache); - nrf_cache_lineaddr_set(cache, line_addr); + nrf_cache_lineaddr_set(cache, line_addr); - switch (op) { + switch (op) { #if NRF_CACHE_HAS_TASK_CLEAN - case K_NRF_CACHE_CLEAN: - nrf_cache_task_trigger(cache, NRF_CACHE_TASK_CLEANLINE); - break; + case K_NRF_CACHE_CLEAN: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_CLEANLINE); + break; #endif - case K_NRF_CACHE_INVD: - nrf_cache_task_trigger(cache, NRF_CACHE_TASK_INVALIDATELINE); - break; + case K_NRF_CACHE_INVD: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_INVALIDATELINE); + break; #if NRF_CACHE_HAS_TASK_FLUSH - case K_NRF_CACHE_FLUSH: - nrf_cache_task_trigger(cache, NRF_CACHE_TASK_FLUSHLINE); - break; + case K_NRF_CACHE_FLUSH: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_FLUSHLINE); + break; #endif - default: - break; - } - - wait_for_cache(cache); + default: + break; + } + } while (nrf_cache_lineaddr_get(cache) != line_addr); } static inline int _cache_range(NRF_CACHE_Type *cache, enum k_nrf_cache_op op, void *addr, @@ -150,16 +148,12 @@ static inline int _cache_range(NRF_CACHE_Type *cache, enum k_nrf_cache_op op, vo line_addr &= ~(CACHE_LINE_SIZE - 1); do { - k_spinlock_key_t key = k_spin_lock(&lock); - _cache_line(cache, op, line_addr); - - k_spin_unlock(&lock, key); - line_addr += CACHE_LINE_SIZE; - } while (line_addr < end_addr); + wait_for_cache(cache); + return 0; } From fe9c9aa7a97d6fe45bfcfb7038316c06cfb9fd9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 15 Apr 2024 11:56:10 +0200 Subject: [PATCH 7/7] [nrf fromtree] drivers: cache: nrf: Use CONFIG_DCACHE_LINE_SIZE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use Kconfig instead of fixed value in the driver code. Signed-off-by: Krzysztof Chruściński (cherry picked from commit 4e880e62dc37f76da4c8428ea6c519a139f3b0d2) --- drivers/cache/cache_nrf.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/cache/cache_nrf.c b/drivers/cache/cache_nrf.c index d1a28127727..3cf79897874 100644 --- a/drivers/cache/cache_nrf.c +++ b/drivers/cache/cache_nrf.c @@ -14,7 +14,6 @@ LOG_MODULE_REGISTER(cache_nrfx, CONFIG_CACHE_LOG_LEVEL); #define NRF_ICACHE NRF_CACHE #endif -#define CACHE_LINE_SIZE 32 #define CACHE_BUSY_RETRY_INTERVAL_US 10 @@ -145,11 +144,11 @@ static inline int _cache_range(NRF_CACHE_Type *cache, enum k_nrf_cache_op op, vo /* * Align address to line size */ - line_addr &= ~(CACHE_LINE_SIZE - 1); + line_addr &= ~(CONFIG_DCACHE_LINE_SIZE - 1); do { _cache_line(cache, op, line_addr); - line_addr += CACHE_LINE_SIZE; + line_addr += CONFIG_DCACHE_LINE_SIZE; } while (line_addr < end_addr); wait_for_cache(cache);