1 /* 2 * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <string.h> 9 10 #include <bl31/interrupt_mgmt.h> 11 #include <lib/el3_runtime/context_mgmt.h> 12 #include <lib/extensions/ras.h> 13 #include <plat/common/platform.h> 14 #include <services/sdei.h> 15 #include <services/spm_mm_svc.h> 16 17 #include <sgi_ras.h> 18 19 #define CPU_CONTEXT_REG_GPR_ARR_SIZE 32 20 #define CPU_CONTEXT_REG_EL1_ARR_SIZE 17 21 #define CPU_CONTEXT_REG_EL2_ARR_SIZE 16 22 #define CPU_CONTEXT_REG_EL3_ARR_SIZE 10 23 24 /* 25 * MM Communicate message header GUID to indicate the payload is intended for 26 * CPU MM driver. 27 */ 28 struct efi_guid cpu_ecc_event_guid = { 29 0x2c1b3bfc, 0x42cd, 0x4a66, 30 {0xac, 0xd1, 0xa4, 0xd1, 0x63, 0xe9, 0x90, 0xf6} 31 }; 32 33 /* 34 * CPU error information data structure communicated as part of MM 35 * Communication data payload. 36 */ 37 typedef struct { 38 uint64_t ErrStatus; 39 uint64_t ErrMisc0; 40 uint64_t ErrAddr; 41 uint64_t SecurityState; 42 uint64_t ErrCtxGpr[CPU_CONTEXT_REG_GPR_ARR_SIZE]; 43 uint64_t ErrCtxEl1Reg[CPU_CONTEXT_REG_EL1_ARR_SIZE]; 44 uint64_t ErrCtxEl2Reg[CPU_CONTEXT_REG_EL2_ARR_SIZE]; 45 uint64_t ErrCtxEl3Reg[CPU_CONTEXT_REG_EL3_ARR_SIZE]; 46 } cpu_err_info; 47 48 /* 49 * Reads the CPU context and error information from the relevant registers and 50 * populates the CPU error information data structure. 51 */ 52 static void populate_cpu_err_data(cpu_err_info *cpu_info, 53 uint64_t security_state) 54 { 55 void *ctx; 56 57 ctx = cm_get_context(security_state); 58 59 cpu_info->ErrStatus = read_erxstatus_el1(); 60 cpu_info->ErrMisc0 = read_erxmisc0_el1(); 61 cpu_info->ErrAddr = read_erxaddr_el1(); 62 cpu_info->SecurityState = security_state; 63 64 /* populate CPU EL1 context information. */ 65 cpu_info->ErrCtxEl1Reg[0] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 66 CTX_ELR_EL1); 67 cpu_info->ErrCtxEl1Reg[1] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 68 CTX_ESR_EL1); 69 cpu_info->ErrCtxEl1Reg[2] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 70 CTX_FAR_EL1); 71 cpu_info->ErrCtxEl1Reg[3] = read_isr_el1(); 72 cpu_info->ErrCtxEl1Reg[4] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 73 CTX_MAIR_EL1); 74 cpu_info->ErrCtxEl1Reg[5] = read_midr_el1(); 75 cpu_info->ErrCtxEl1Reg[6] = read_mpidr_el1(); 76 cpu_info->ErrCtxEl1Reg[7] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 77 CTX_SCTLR_EL1); 78 cpu_info->ErrCtxEl1Reg[8] = read_ctx_reg(get_gpregs_ctx(ctx), 79 CTX_GPREG_SP_EL0); 80 cpu_info->ErrCtxEl1Reg[9] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 81 CTX_SP_EL1); 82 cpu_info->ErrCtxEl1Reg[10] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 83 CTX_SPSR_EL1); 84 cpu_info->ErrCtxEl1Reg[11] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 85 CTX_TCR_EL1); 86 cpu_info->ErrCtxEl1Reg[12] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 87 CTX_TPIDR_EL0); 88 cpu_info->ErrCtxEl1Reg[13] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 89 CTX_TPIDR_EL1); 90 cpu_info->ErrCtxEl1Reg[14] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 91 CTX_TPIDRRO_EL0); 92 cpu_info->ErrCtxEl1Reg[15] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 93 CTX_TTBR0_EL1); 94 cpu_info->ErrCtxEl1Reg[16] = read_ctx_reg(get_el1_sysregs_ctx(ctx), 95 CTX_TTBR1_EL1); 96 97 #if CTX_INCLUDE_EL2_REGS 98 cpu_info->ErrCtxEl2Reg[0] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 99 CTX_ELR_EL2); 100 cpu_info->ErrCtxEl2Reg[1] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 101 CTX_ESR_EL2); 102 cpu_info->ErrCtxEl2Reg[2] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 103 CTX_FAR_EL2); 104 cpu_info->ErrCtxEl2Reg[3] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 105 CTX_HACR_EL2); 106 cpu_info->ErrCtxEl2Reg[4] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 107 CTX_HCR_EL2); 108 cpu_info->ErrCtxEl2Reg[5] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 109 CTX_HPFAR_EL2); 110 cpu_info->ErrCtxEl2Reg[6] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 111 CTX_MAIR_EL2); 112 cpu_info->ErrCtxEl2Reg[7] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 113 CTX_SCTLR_EL2); 114 cpu_info->ErrCtxEl2Reg[8] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 115 CTX_SP_EL2); 116 cpu_info->ErrCtxEl2Reg[9] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 117 CTX_SPSR_EL2); 118 cpu_info->ErrCtxEl2Reg[10] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 119 CTX_TCR_EL2); 120 cpu_info->ErrCtxEl2Reg[11] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 121 CTX_TPIDR_EL2); 122 cpu_info->ErrCtxEl2Reg[12] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 123 CTX_TTBR0_EL2); 124 cpu_info->ErrCtxEl2Reg[13] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 125 CTX_VTCR_EL2); 126 cpu_info->ErrCtxEl2Reg[14] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 127 CTX_VTTBR_EL2); 128 cpu_info->ErrCtxEl2Reg[15] = read_ctx_reg(get_el2_sysregs_ctx(ctx), 129 CTX_ESR_EL2); 130 #endif 131 132 cpu_info->ErrCtxEl3Reg[0] = read_ctx_reg(get_el3state_ctx(ctx), 133 CTX_ELR_EL3); 134 cpu_info->ErrCtxEl3Reg[1] = read_ctx_reg(get_el3state_ctx(ctx), 135 CTX_ESR_EL3); 136 cpu_info->ErrCtxEl3Reg[2] = read_far_el3(); 137 cpu_info->ErrCtxEl3Reg[4] = read_mair_el3(); 138 cpu_info->ErrCtxEl3Reg[5] = read_sctlr_el3(); 139 cpu_info->ErrCtxEl3Reg[6] = 0; /* sp_el3 */ 140 cpu_info->ErrCtxEl3Reg[7] = read_tcr_el3(); 141 cpu_info->ErrCtxEl3Reg[8] = read_tpidr_el3(); 142 cpu_info->ErrCtxEl3Reg[9] = read_ttbr0_el3(); 143 } 144 145 /* CPU RAS interrupt handler */ 146 int sgi_ras_cpu_intr_handler(const struct err_record_info *err_rec, 147 int probe_data, 148 const struct err_handler_data *const data) 149 { 150 struct sgi_ras_ev_map *ras_map; 151 mm_communicate_header_t *header; 152 cpu_err_info cpu_info = {0}; 153 uint64_t clear_status; 154 uint32_t intr; 155 int ret; 156 157 cm_el1_sysregs_context_save(NON_SECURE); 158 intr = data->interrupt; 159 160 INFO("[CPU RAS] CPU intr received = %d on cpu_id = %d\n", 161 intr, plat_my_core_pos()); 162 163 INFO("[CPU RAS] ERXMISC0_EL1 = 0x%lx\n", read_erxmisc0_el1()); 164 INFO("[CPU RAS] ERXSTATUS_EL1 = 0x%lx\n", read_erxstatus_el1()); 165 INFO("[CPU RAS] ERXADDR_EL1 = 0x%lx\n", read_erxaddr_el1()); 166 167 /* Populate CPU Error Source Information. */ 168 populate_cpu_err_data(&cpu_info, get_interrupt_src_ss(data->flags)); 169 170 /* Clear the interrupt. */ 171 clear_status = read_erxstatus_el1(); 172 write_erxstatus_el1(clear_status); 173 plat_ic_end_of_interrupt(intr); 174 175 header = (void *) PLAT_SPM_BUF_BASE; 176 memset(header, 0, sizeof(*header)); 177 memcpy(&header->data, &cpu_info, sizeof(cpu_info)); 178 header->message_len = sizeof(cpu_info); 179 memcpy(&header->header_guid, (void *) &cpu_ecc_event_guid, 180 sizeof(struct efi_guid)); 181 182 spm_mm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0, 183 plat_my_core_pos()); 184 185 /* 186 * Find if this is a RAS interrupt. There must be an event against 187 * this interrupt 188 */ 189 ras_map = sgi_find_ras_event_map_by_intr(intr); 190 if (ras_map == NULL) { 191 ERROR("SGI: RAS error info for interrupt id: %d not found\n", 192 intr); 193 return -1; 194 } 195 196 /* Dispatch the event to the SDEI client */ 197 ret = sdei_dispatch_event(ras_map->sdei_ev_num); 198 if (ret != 0) { 199 /* 200 * sdei_dispatch_event() may return failing result in some 201 * cases, for example kernel may not have registered a handler 202 * or RAS event may happen early during boot. We restore the NS 203 * context when sdei_dispatch_event() returns failing result. 204 */ 205 ERROR("SDEI dispatch failed: %d", ret); 206 cm_el1_sysregs_context_restore(NON_SECURE); 207 cm_set_next_eret_context(NON_SECURE); 208 } 209 210 return ret; 211 } 212