smp: Add A7-A9X cache errata workaround

Signed-off-by: Nick Chan <towinchenmi@gmail.com>
This commit is contained in:
Nick Chan 2024-10-08 11:51:12 +08:00 committed by Hector Martin
parent da3519de14
commit c28d6b7172
4 changed files with 20 additions and 4 deletions

View file

@ -70,7 +70,7 @@ void init_t6031_sawtooth(void);
void init_t6031_everest(int rev); void init_t6031_everest(int rev);
bool cpufeat_actlr_el2, cpufeat_fast_ipi, cpufeat_mmu_sprr; bool cpufeat_actlr_el2, cpufeat_fast_ipi, cpufeat_mmu_sprr;
bool cpufeat_global_sleep; bool cpufeat_global_sleep, cpufeat_workaround_cyclone_cache;
const char *init_cpu(void) const char *init_cpu(void)
{ {
@ -244,9 +244,11 @@ const char *init_cpu(void)
if (part >= MIDR_PART_T8010_2_HURRICANE) if (part >= MIDR_PART_T8010_2_HURRICANE)
cpufeat_global_sleep = true; cpufeat_global_sleep = true;
else else {
/* Disable deep sleep */ /* Disable deep sleep */
reg_clr(SYS_IMP_APL_ACC_CFG, ACC_CFG_DEEP_SLEEP); reg_clr(SYS_IMP_APL_ACC_CFG, ACC_CFG_DEEP_SLEEP);
cpufeat_workaround_cyclone_cache = true;
}
/* Unmask external IRQs, set WFI mode to up (2) */ /* Unmask external IRQs, set WFI mode to up (2) */
reg_mask(SYS_IMP_APL_CYC_OVRD, reg_mask(SYS_IMP_APL_CYC_OVRD,

View file

@ -19,12 +19,20 @@
#define CACHE_RANGE_OP(func, op) \ #define CACHE_RANGE_OP(func, op) \
void func(void *addr, size_t length) \ void func(void *addr, size_t length) \
{ \ { \
if (func == dc_civac_range && cpufeat_workaround_cyclone_cache) { \
reg_clr(SYS_IMP_APL_HID4, HID4_DISABLE_DC_MVA); \
sysop("isb"); \
} \
u64 p = (u64)addr; \ u64 p = (u64)addr; \
u64 end = p + length; \ u64 end = p + length; \
while (p < end) { \ while (p < end) { \
cacheop(op, p); \ cacheop(op, p); \
p += CACHE_LINE_SIZE; \ p += CACHE_LINE_SIZE; \
} \ } \
if (func == dc_civac_range && cpufeat_workaround_cyclone_cache) { \
reg_set(SYS_IMP_APL_HID4, HID4_DISABLE_DC_MVA); \
sysop("isb"); \
} \
} }
CACHE_RANGE_OP(ic_ivau_range, "ic ivau") CACHE_RANGE_OP(ic_ivau_range, "ic ivau")

View file

@ -6,6 +6,7 @@
#include "aic_regs.h" #include "aic_regs.h"
#include "cpu_regs.h" #include "cpu_regs.h"
#include "malloc.h" #include "malloc.h"
#include "memory.h"
#include "pmgr.h" #include "pmgr.h"
#include "soc.h" #include "soc.h"
#include "string.h" #include "string.h"
@ -129,10 +130,14 @@ static void smp_start_cpu(int index, int die, int cluster, int core, u64 impl, u
secondary_stacks_el3[index] = memalign(0x4000, SECONDARY_STACK_SIZE); secondary_stacks_el3[index] = memalign(0x4000, SECONDARY_STACK_SIZE);
_reset_stack = secondary_stacks_el3[index] + SECONDARY_STACK_SIZE; // EL3 _reset_stack = secondary_stacks_el3[index] + SECONDARY_STACK_SIZE; // EL3
_reset_stack_el1 = secondary_stacks[index] + SECONDARY_STACK_SIZE; // EL1 _reset_stack_el1 = secondary_stacks[index] + SECONDARY_STACK_SIZE; // EL1
dc_civac_range(&_reset_stack_el1, sizeof(void *));
} else } else
_reset_stack = secondary_stacks[index] + SECONDARY_STACK_SIZE; _reset_stack = secondary_stacks[index] + SECONDARY_STACK_SIZE;
sysop("dmb sy"); dc_civac_range(&_reset_stack, sizeof(void *));
sysop("dsb sy");
write64(impl, (u64)_vectors_start); write64(impl, (u64)_vectors_start);

View file

@ -3,6 +3,7 @@
#ifndef UTILS_H #ifndef UTILS_H
#define UTILS_H #define UTILS_H
#include "cpu_regs.h"
#include "soc.h" #include "soc.h"
#include "types.h" #include "types.h"
@ -460,7 +461,7 @@ extern u32 board_id, chip_id;
extern bool is_mac, has_dcp; extern bool is_mac, has_dcp;
extern bool cpufeat_actlr_el2, cpufeat_fast_ipi, cpufeat_mmu_sprr; extern bool cpufeat_actlr_el2, cpufeat_fast_ipi, cpufeat_mmu_sprr;
extern bool cpufeat_global_sleep; extern bool cpufeat_global_sleep, cpufeat_workaround_cyclone_cache;
extern struct vector_args next_stage; extern struct vector_args next_stage;
extern u64 boot_flags, mem_size_actual; extern u64 boot_flags, mem_size_actual;