diff options
Diffstat (limited to 'src/arch/arm64/ramdetect.c')
-rw-r--r-- | src/arch/arm64/ramdetect.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/arch/arm64/ramdetect.c b/src/arch/arm64/ramdetect.c new file mode 100644 index 0000000000..bc034c311b --- /dev/null +++ b/src/arch/arm64/ramdetect.c @@ -0,0 +1,41 @@ +/* + * This file is part of the coreboot project. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <types.h> +#include <device/mmio.h> +#include <ramdetect.h> +#include <arch/exception.h> +#include <arch/transition.h> + +static enum { + ABORT_CHECKER_NOT_TRIGGERED, + ABORT_CHECKER_TRIGGERED, +} abort_state = ABORT_CHECKER_NOT_TRIGGERED; + +static int abort_checker(struct exc_state *state, uint64_t vector_id) +{ + if (raw_read_esr_el3() >> 26 != 0x25) + return EXC_RET_IGNORED; /* Not a data abort. */ + + abort_state = ABORT_CHECKER_TRIGGERED; + state->elx.elr += sizeof(uint32_t); /* Jump over faulting instruction. */ + raw_write_elr_el3(state->elx.elr); + return EXC_RET_HANDLED; +} + +static struct exception_handler sync_el0 = {.handler = &abort_checker}; + +int probe_mb(const uintptr_t dram_start, const uintptr_t size) +{ + uintptr_t addr = dram_start + (size * MiB) - sizeof(uint32_t); + void *ptr = (void *)addr; + + abort_state = ABORT_CHECKER_NOT_TRIGGERED; + exception_handler_register(EXC_VID_CUR_SP_EL0_SYNC, &sync_el0); + read32(ptr); + exception_handler_unregister(EXC_VID_CUR_SP_EL0_SYNC, &sync_el0); + return abort_state == ABORT_CHECKER_NOT_TRIGGERED; +} |