Philipp Hug has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/36486 )
Change subject: WIP: riscv/mb/qemu: fix DRAM probing ......................................................................
WIP: riscv/mb/qemu: fix DRAM probing
Current version of qemu raise an exception when accessing invalid memory. Modify the probing code to temporary redirect the exception handler like on ARM platform.
TEST=qemu detects RAM size correctly Change-Id: I25860f688c7546714f6fdbce8c8f96da6400813c Signed-off-by: Philipp Hug philipp@hug.cx --- M src/arch/riscv/Makefile.inc M src/arch/riscv/include/arch/exception.h A src/arch/riscv/ramdetect.c M src/arch/riscv/trap_handler.c M src/arch/riscv/trap_util.S M src/lib/ramdetect.c 6 files changed, 57 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/86/36486/1
diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc index 0039fab..7465a8f 100644 --- a/src/arch/riscv/Makefile.inc +++ b/src/arch/riscv/Makefile.inc @@ -101,6 +101,7 @@ romstage-y += stages.c romstage-y += misc.c romstage-$(ARCH_RISCV_PMP) += pmp.c +romstage-y += ramdetect.c romstage-y += smp.c romstage-y += \ $(top)/src/lib/memchr.c \ @@ -142,6 +143,7 @@ ramstage-y += virtual_memory.c ramstage-y += stages.c ramstage-y += misc.c +ramstage-y += ramdetect.c ramstage-y += smp.c ramstage-y += boot.c ramstage-y += tables.c diff --git a/src/arch/riscv/include/arch/exception.h b/src/arch/riscv/include/arch/exception.h index 6fbbdf0..cdca582 100644 --- a/src/arch/riscv/include/arch/exception.h +++ b/src/arch/riscv/include/arch/exception.h @@ -53,7 +53,7 @@ }
void redirect_trap(void); -void trap_handler(trapframe *tf); +void default_trap_handler(trapframe *tf); void handle_supervisor_call(trapframe *tf); void handle_misaligned(trapframe *tf);
diff --git a/src/arch/riscv/ramdetect.c b/src/arch/riscv/ramdetect.c new file mode 100644 index 0000000..47153ab --- /dev/null +++ b/src/arch/riscv/ramdetect.c @@ -0,0 +1,46 @@ +/* + * This file is part of the coreboot project. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <arch/exception.h> +#include <types.h> +#include <console/console.h> +#include <device/mmio.h> +#include <ramdetect.h> +#include <arch/smp/spinlock.h> + +static enum { + ABORT_CHECKER_NOT_TRIGGERED, + ABORT_CHECKER_TRIGGERED, +} abort_state = ABORT_CHECKER_NOT_TRIGGERED; + +extern void(*trap_handler)(trapframe *tf); + +#define insn_size 4 +static void ramcheck_trap_handler(trapframe *tf) +{ + printk(BIOS_DEBUG, "TRAP 0x%lx!!!\n", tf->epc); + abort_state = ABORT_CHECKER_TRIGGERED; + + /* + * skip read instruction. + * currenctly hardcoded to 32bit instruction size + */ + write_csr(mepc, read_csr(mepc) + insn_size); +} + +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; + trap_handler = ramcheck_trap_handler; + barrier(); + read32(ptr); + trap_handler = default_trap_handler; + barrier(); + return abort_state == ABORT_CHECKER_NOT_TRIGGERED; +} diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c index 6b39fab..1d51268 100644 --- a/src/arch/riscv/trap_handler.c +++ b/src/arch/riscv/trap_handler.c @@ -118,7 +118,10 @@ break; } } -void trap_handler(trapframe *tf) + +void(*trap_handler)(trapframe *tf) = default_trap_handler; + +void default_trap_handler(trapframe *tf) { write_csr(mscratch, tf); if (tf->cause & 0x8000000000000000ULL) { diff --git a/src/arch/riscv/trap_util.S b/src/arch/riscv/trap_util.S index 67e917c..93f5afd 100644 --- a/src/arch/riscv/trap_util.S +++ b/src/arch/riscv/trap_util.S @@ -120,7 +120,8 @@ save_tf
mv a0, sp - jal trap_handler + ld t0, trap_handler + jalr t0
restore_regs addi sp, sp, MENTRY_FRAME_SIZE diff --git a/src/lib/ramdetect.c b/src/lib/ramdetect.c index 2c83092..eaf6190 100644 --- a/src/lib/ramdetect.c +++ b/src/lib/ramdetect.c @@ -58,6 +58,8 @@ if (saved_result) return saved_result;
+ printk(BIOS_DEBUG, "RAMDETECT: Starting\n"); + /* Find the MSB + 1. */ size_t tmp = probe_size; do {