diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2018-03-01 16:45:40 +0100 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-03-02 06:49:06 -0800 |
commit | f23f45e74e4c0aff7116a832556d194747997ffe (patch) | |
tree | 348f7a5a727346f0317155b84938488c68e78a48 | |
parent | c55f09496009249426574e1facf96a222b4e4693 (diff) | |
download | chrome-ec-f23f45e74e4c0aff7116a832556d194747997ffe.tar.gz |
cortex-m: enable I-cache on ARMv7-M
The ARMv7-M ISA defines standard (and optional) mechanism to manage the
CPU caches through the SCB (System Control Block) registers.
So far, only the Cortex-M7 core implements such as a mechanism (e.g. the
Cortex-M4 with caches we have are using a proprietary mechanism for the
management).
Define the functions to use the I-Cache,
and enable them on STM32H7 which is our only supported Cortex-M7 core.
The D-Cache mechanism is still To Be Done, as it involves a bit more
support in the firmware for the DMA memory areas.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=none
BUG=b:67081508
TEST=on ZerbleBarn, verify manually that the 'IC' bit is set in the CCR
(e.g. 'rw 0xe000ed14' returns 0x60218), and runs some CPU workload
without crash and with a speed-up.
Change-Id: I6af1021d65048b787630387f7d95797db15d069c
Reviewed-on: https://chromium-review.googlesource.com/943445
Commit-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | chip/stm32/config-stm32h7x3.h | 3 | ||||
-rw-r--r-- | chip/stm32/system.c | 4 | ||||
-rw-r--r-- | core/cortex-m/cpu.c | 38 | ||||
-rw-r--r-- | core/cortex-m/cpu.h | 10 | ||||
-rw-r--r-- | include/config.h | 6 |
5 files changed, 61 insertions, 0 deletions
diff --git a/chip/stm32/config-stm32h7x3.h b/chip/stm32/config-stm32h7x3.h index 72b9bd21de..4fde40b957 100644 --- a/chip/stm32/config-stm32h7x3.h +++ b/chip/stm32/config-stm32h7x3.h @@ -59,3 +59,6 @@ /* Number of IRQ vectors on the NVIC */ #define CONFIG_IRQ_COUNT 150 + +/* the Cortex-M7 core has 'standard' ARMv7-M caches */ +#define CONFIG_ARMV7M_CACHE diff --git a/chip/stm32/system.c b/chip/stm32/system.c index 4a5927d90c..d2c48cdc11 100644 --- a/chip/stm32/system.c +++ b/chip/stm32/system.c @@ -205,6 +205,10 @@ void chip_pre_init(void) uint32_t apb1fz_reg = 0; uint32_t apb2fz_reg = 0; +#ifdef CONFIG_ARMV7M_CACHE + cpu_enable_icache(); +#endif + #if defined(CHIP_FAMILY_STM32F0) apb1fz_reg = STM32_RCC_PB1_TIM2 | STM32_RCC_PB1_TIM3 | STM32_RCC_PB1_TIM6 | diff --git a/core/cortex-m/cpu.c b/core/cortex-m/cpu.c index 2571a4a17c..ea6cf5c4a5 100644 --- a/core/cortex-m/cpu.c +++ b/core/cortex-m/cpu.c @@ -5,7 +5,9 @@ * Set up the Cortex-M core */ +#include "common.h" #include "cpu.h" +#include "hooks.h" void cpu_init(void) { @@ -16,3 +18,39 @@ void cpu_init(void) CPU_NVIC_SHCSR |= CPU_NVIC_SHCSR_MEMFAULTENA | CPU_NVIC_SHCSR_BUSFAULTENA | CPU_NVIC_SHCSR_USGFAULTENA; } + +#ifdef CONFIG_ARMV7M_CACHE +static void cpu_invalidate_icache(void) +{ + /* + * Invalidates the entire instruction cache to the point of + * unification. + */ + CPU_SCB_ICIALLU = 0; + asm volatile("dsb; isb"); +} + +void cpu_enable_icache(void) +{ + /* Check whether the I-cache is already enabled */ + if (!(CPU_NVIC_CCR & CPU_NVIC_CCR_ICACHE)) { + /* Invalidate the I-cache first */ + cpu_invalidate_icache(); + /* Turn on the caching */ + CPU_NVIC_CCR |= CPU_NVIC_CCR_ICACHE; + asm volatile("dsb; isb"); + } +} + +static void cpu_sysjump_cache(void) +{ + /* + * Disable the I-cache + * so we will invalidate it after the sysjump if needed + * (e.g after a flash update). + */ + CPU_NVIC_CCR &= ~CPU_NVIC_CCR_ICACHE; + asm volatile("dsb; isb"); +} +DECLARE_HOOK(HOOK_SYSJUMP, cpu_sysjump_cache, HOOK_PRIO_LAST); +#endif /* CONFIG_ARMV7M_CACHE */ diff --git a/core/cortex-m/cpu.h b/core/cortex-m/cpu.h index 07e1c4b543..f4400a0444 100644 --- a/core/cortex-m/cpu.h +++ b/core/cortex-m/cpu.h @@ -41,6 +41,8 @@ enum { CPU_NVIC_MMFS_BFARVALID = 1 << 15, CPU_NVIC_MMFS_MFARVALID = 1 << 7, + CPU_NVIC_CCR_ICACHE = 1 << 17, + CPU_NVIC_CCR_DCACHE = 1 << 16, CPU_NVIC_CCR_DIV_0_TRAP = 1 << 4, CPU_NVIC_CCR_UNALIGN_TRAP = 1 << 3, @@ -53,7 +55,15 @@ enum { CPU_NVIC_SHCSR_USGFAULTENA = 1 << 18, }; +/* System Control Block: cache registers */ +#define CPU_SCB_CCSIDR CPUREG(0xe000ed80) +#define CPU_SCB_CCSELR CPUREG(0xe000ed84) +#define CPU_SCB_ICIALLU CPUREG(0xe000ef50) +#define CPU_SCB_DCISW CPUREG(0xe000ef60) + /* Set up the cpu to detect faults */ void cpu_init(void); +/* Enable the CPU instruction cache if it is not already enabled */ +void cpu_enable_icache(void); #endif /* __CROS_EC_CPU_H */ diff --git a/include/config.h b/include/config.h index 8d023c54ba..bdf40ec722 100644 --- a/include/config.h +++ b/include/config.h @@ -187,6 +187,12 @@ /* Support AP Warm reset Interrupt. */ #undef CONFIG_AP_WARM_RESET_INTERRUPT +/* + * Enable support for CPU caches behaving according to the ARMv7-M ISA. + * (so far, only the Cortex-M7 has such caches) + */ +#undef CONFIG_ARMV7M_CACHE + /* Allow proprietary communication protocols' extensions. */ #undef CONFIG_EXTENSION_COMMAND |