xref: /aosp_15_r20/external/coreboot/src/arch/arm64/ramdetect.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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)14 static 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)28 int 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