1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #ifndef CPU_OPS_H 8*91f16700Schasinglulu #define CPU_OPS_H 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <arch.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu #define CPU_IMPL_PN_MASK (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \ 13*91f16700Schasinglulu (MIDR_PN_MASK << MIDR_PN_SHIFT) 14*91f16700Schasinglulu 15*91f16700Schasinglulu /* Hardcode to keep compatible with assembly. sizeof(uintptr_t) */ 16*91f16700Schasinglulu #if __aarch64__ 17*91f16700Schasinglulu #define CPU_WORD_SIZE 8 18*91f16700Schasinglulu #else 19*91f16700Schasinglulu #define CPU_WORD_SIZE 4 20*91f16700Schasinglulu #endif /* __aarch64__ */ 21*91f16700Schasinglulu 22*91f16700Schasinglulu /* The number of CPU operations allowed */ 23*91f16700Schasinglulu #define CPU_MAX_PWR_DWN_OPS 2 24*91f16700Schasinglulu /* Special constant to specify that CPU has no reset function */ 25*91f16700Schasinglulu #define CPU_NO_RESET_FUNC 0 26*91f16700Schasinglulu 27*91f16700Schasinglulu #if __aarch64__ 28*91f16700Schasinglulu #define CPU_NO_EXTRA1_FUNC 0 29*91f16700Schasinglulu #define CPU_NO_EXTRA2_FUNC 0 30*91f16700Schasinglulu #define CPU_NO_EXTRA3_FUNC 0 31*91f16700Schasinglulu #endif /* __aarch64__ */ 32*91f16700Schasinglulu 33*91f16700Schasinglulu 34*91f16700Schasinglulu /* 35*91f16700Schasinglulu * Define the sizes of the fields in the cpu_ops structure. Word size is set per 36*91f16700Schasinglulu * Aarch so keep these definitions the same and each can include whatever it 37*91f16700Schasinglulu * needs. 38*91f16700Schasinglulu */ 39*91f16700Schasinglulu #define CPU_MIDR_SIZE CPU_WORD_SIZE 40*91f16700Schasinglulu #ifdef IMAGE_AT_EL3 41*91f16700Schasinglulu #define CPU_RESET_FUNC_SIZE CPU_WORD_SIZE 42*91f16700Schasinglulu #else 43*91f16700Schasinglulu #define CPU_RESET_FUNC_SIZE 0 44*91f16700Schasinglulu #endif /* IMAGE_AT_EL3 */ 45*91f16700Schasinglulu #define CPU_EXTRA1_FUNC_SIZE CPU_WORD_SIZE 46*91f16700Schasinglulu #define CPU_EXTRA2_FUNC_SIZE CPU_WORD_SIZE 47*91f16700Schasinglulu #define CPU_EXTRA3_FUNC_SIZE CPU_WORD_SIZE 48*91f16700Schasinglulu #define CPU_E_HANDLER_FUNC_SIZE CPU_WORD_SIZE 49*91f16700Schasinglulu /* The power down core and cluster is needed only in BL31 and BL32 */ 50*91f16700Schasinglulu #if defined(IMAGE_BL31) || defined(IMAGE_BL32) 51*91f16700Schasinglulu #define CPU_PWR_DWN_OPS_SIZE CPU_WORD_SIZE * CPU_MAX_PWR_DWN_OPS 52*91f16700Schasinglulu #else 53*91f16700Schasinglulu #define CPU_PWR_DWN_OPS_SIZE 0 54*91f16700Schasinglulu #endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */ 55*91f16700Schasinglulu 56*91f16700Schasinglulu #define CPU_ERRATA_LIST_START_SIZE CPU_WORD_SIZE 57*91f16700Schasinglulu #define CPU_ERRATA_LIST_END_SIZE CPU_WORD_SIZE 58*91f16700Schasinglulu /* Fields required to print errata status */ 59*91f16700Schasinglulu #if REPORT_ERRATA 60*91f16700Schasinglulu #define CPU_ERRATA_FUNC_SIZE CPU_WORD_SIZE 61*91f16700Schasinglulu #define CPU_CPU_STR_SIZE CPU_WORD_SIZE 62*91f16700Schasinglulu /* BL1 doesn't require mutual exclusion and printed flag. */ 63*91f16700Schasinglulu #if defined(IMAGE_BL31) || defined(IMAGE_BL32) 64*91f16700Schasinglulu #define CPU_ERRATA_LOCK_SIZE CPU_WORD_SIZE 65*91f16700Schasinglulu #define CPU_ERRATA_PRINTED_SIZE CPU_WORD_SIZE 66*91f16700Schasinglulu #else 67*91f16700Schasinglulu #define CPU_ERRATA_LOCK_SIZE 0 68*91f16700Schasinglulu #define CPU_ERRATA_PRINTED_SIZE 0 69*91f16700Schasinglulu #endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */ 70*91f16700Schasinglulu #else 71*91f16700Schasinglulu #define CPU_ERRATA_FUNC_SIZE 0 72*91f16700Schasinglulu #define CPU_CPU_STR_SIZE 0 73*91f16700Schasinglulu #define CPU_ERRATA_LOCK_SIZE 0 74*91f16700Schasinglulu #define CPU_ERRATA_PRINTED_SIZE 0 75*91f16700Schasinglulu #endif /* REPORT_ERRATA */ 76*91f16700Schasinglulu 77*91f16700Schasinglulu #if defined(IMAGE_BL31) && CRASH_REPORTING 78*91f16700Schasinglulu #define CPU_REG_DUMP_SIZE CPU_WORD_SIZE 79*91f16700Schasinglulu #else 80*91f16700Schasinglulu #define CPU_REG_DUMP_SIZE 0 81*91f16700Schasinglulu #endif /* defined(IMAGE_BL31) && CRASH_REPORTING */ 82*91f16700Schasinglulu 83*91f16700Schasinglulu 84*91f16700Schasinglulu /* 85*91f16700Schasinglulu * Define the offsets to the fields in cpu_ops structure. Every offset is 86*91f16700Schasinglulu * defined based on the offset and size of the previous field. 87*91f16700Schasinglulu */ 88*91f16700Schasinglulu #define CPU_MIDR 0 89*91f16700Schasinglulu #define CPU_RESET_FUNC CPU_MIDR + CPU_MIDR_SIZE 90*91f16700Schasinglulu #if __aarch64__ 91*91f16700Schasinglulu #define CPU_EXTRA1_FUNC CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE 92*91f16700Schasinglulu #define CPU_EXTRA2_FUNC CPU_EXTRA1_FUNC + CPU_EXTRA1_FUNC_SIZE 93*91f16700Schasinglulu #define CPU_EXTRA3_FUNC CPU_EXTRA2_FUNC + CPU_EXTRA2_FUNC_SIZE 94*91f16700Schasinglulu #define CPU_E_HANDLER_FUNC CPU_EXTRA3_FUNC + CPU_EXTRA3_FUNC_SIZE 95*91f16700Schasinglulu #define CPU_PWR_DWN_OPS CPU_E_HANDLER_FUNC + CPU_E_HANDLER_FUNC_SIZE 96*91f16700Schasinglulu #else 97*91f16700Schasinglulu #define CPU_PWR_DWN_OPS CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE 98*91f16700Schasinglulu #endif /* __aarch64__ */ 99*91f16700Schasinglulu #define CPU_ERRATA_LIST_START CPU_PWR_DWN_OPS + CPU_PWR_DWN_OPS_SIZE 100*91f16700Schasinglulu #define CPU_ERRATA_LIST_END CPU_ERRATA_LIST_START + CPU_ERRATA_LIST_START_SIZE 101*91f16700Schasinglulu #define CPU_ERRATA_FUNC CPU_ERRATA_LIST_END + CPU_ERRATA_LIST_END_SIZE 102*91f16700Schasinglulu #define CPU_CPU_STR CPU_ERRATA_FUNC + CPU_ERRATA_FUNC_SIZE 103*91f16700Schasinglulu #define CPU_ERRATA_LOCK CPU_CPU_STR + CPU_CPU_STR_SIZE 104*91f16700Schasinglulu #define CPU_ERRATA_PRINTED CPU_ERRATA_LOCK + CPU_ERRATA_LOCK_SIZE 105*91f16700Schasinglulu #if __aarch64__ 106*91f16700Schasinglulu #define CPU_REG_DUMP CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE 107*91f16700Schasinglulu #define CPU_OPS_SIZE CPU_REG_DUMP + CPU_REG_DUMP_SIZE 108*91f16700Schasinglulu #else 109*91f16700Schasinglulu #define CPU_OPS_SIZE CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE 110*91f16700Schasinglulu #endif /* __aarch64__ */ 111*91f16700Schasinglulu 112*91f16700Schasinglulu #ifndef __ASSEMBLER__ 113*91f16700Schasinglulu #include <lib/cassert.h> 114*91f16700Schasinglulu #include <lib/spinlock.h> 115*91f16700Schasinglulu 116*91f16700Schasinglulu struct cpu_ops { 117*91f16700Schasinglulu unsigned long midr; 118*91f16700Schasinglulu #ifdef IMAGE_AT_EL3 119*91f16700Schasinglulu void (*reset_func)(void); 120*91f16700Schasinglulu #endif /* IMAGE_AT_EL3 */ 121*91f16700Schasinglulu #if __aarch64__ 122*91f16700Schasinglulu void (*extra1_func)(void); 123*91f16700Schasinglulu void (*extra2_func)(void); 124*91f16700Schasinglulu void (*extra3_func)(void); 125*91f16700Schasinglulu void (*e_handler_func)(long es); 126*91f16700Schasinglulu #endif /* __aarch64__ */ 127*91f16700Schasinglulu #if (defined(IMAGE_BL31) || defined(IMAGE_BL32)) && CPU_MAX_PWR_DWN_OPS 128*91f16700Schasinglulu void (*pwr_dwn_ops[CPU_MAX_PWR_DWN_OPS])(void); 129*91f16700Schasinglulu #endif /* (defined(IMAGE_BL31) || defined(IMAGE_BL32)) && CPU_MAX_PWR_DWN_OPS */ 130*91f16700Schasinglulu void *errata_list_start; 131*91f16700Schasinglulu void *errata_list_end; 132*91f16700Schasinglulu #if REPORT_ERRATA 133*91f16700Schasinglulu void (*errata_func)(void); 134*91f16700Schasinglulu char *cpu_str; 135*91f16700Schasinglulu #if defined(IMAGE_BL31) || defined(IMAGE_BL32) 136*91f16700Schasinglulu spinlock_t *errata_lock; 137*91f16700Schasinglulu unsigned int *errata_reported; 138*91f16700Schasinglulu #endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */ 139*91f16700Schasinglulu #endif /* REPORT_ERRATA */ 140*91f16700Schasinglulu #if defined(IMAGE_BL31) && CRASH_REPORTING 141*91f16700Schasinglulu void (*reg_dump)(void); 142*91f16700Schasinglulu #endif /* defined(IMAGE_BL31) && CRASH_REPORTING */ 143*91f16700Schasinglulu } __packed; 144*91f16700Schasinglulu 145*91f16700Schasinglulu CASSERT(sizeof(struct cpu_ops) == CPU_OPS_SIZE, 146*91f16700Schasinglulu assert_cpu_ops_asm_c_different_sizes); 147*91f16700Schasinglulu 148*91f16700Schasinglulu long cpu_get_rev_var(void); 149*91f16700Schasinglulu void *get_cpu_ops_ptr(void); 150*91f16700Schasinglulu 151*91f16700Schasinglulu #endif /* __ASSEMBLER__ */ 152*91f16700Schasinglulu #endif /* CPU_OPS_H */ 153