1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 3 #include <types.h> 4 #include <device/mmio.h> 5 #include <ramdetect.h> 6 #include <arch/exception.h> 7 #include <arch/transition.h> 8 9 static enum { 10 ABORT_CHECKER_NOT_TRIGGERED, 11 ABORT_CHECKER_TRIGGERED, 12 } abort_state = ABORT_CHECKER_NOT_TRIGGERED; 13 abort_checker(struct exc_state * state,uint64_t vector_id)14static int abort_checker(struct exc_state *state, uint64_t vector_id) 15 { 16 if (raw_read_esr() >> 26 != 0x25) 17 return EXC_RET_IGNORED; /* Not a data abort. */ 18 19 abort_state = ABORT_CHECKER_TRIGGERED; 20 state->elx.elr += sizeof(uint32_t); /* Jump over faulting instruction. */ 21 raw_write_elr(state->elx.elr); 22 23 return EXC_RET_HANDLED; 24 } 25 26 static struct exception_handler sync_el0 = {.handler = &abort_checker}; 27 probe_mb(const uintptr_t dram_start,const uintptr_t size)28int probe_mb(const uintptr_t dram_start, const uintptr_t size) 29 { 30 uintptr_t addr = dram_start + (size * MiB) - sizeof(uint32_t); 31 void *ptr = (void *)addr; 32 33 abort_state = ABORT_CHECKER_NOT_TRIGGERED; 34 exception_handler_register(EXC_VID_CUR_SP_EL0_SYNC, &sync_el0); 35 read32(ptr); 36 exception_handler_unregister(EXC_VID_CUR_SP_EL0_SYNC, &sync_el0); 37 return abort_state == ABORT_CHECKER_NOT_TRIGGERED; 38 } 39