diff options
-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 |