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