summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/riscv/Makefile.mk2
-rw-r--r--src/arch/riscv/include/arch/exception.h2
-rw-r--r--src/arch/riscv/ramdetect.c61
-rw-r--r--src/arch/riscv/trap_handler.c30
-rw-r--r--src/arch/riscv/trap_util.S7
-rw-r--r--src/lib/ramdetect.c9
-rw-r--r--src/mainboard/emulation/qemu-riscv/Kconfig5
7 files changed, 93 insertions, 23 deletions
diff --git a/src/arch/riscv/Makefile.mk b/src/arch/riscv/Makefile.mk
index 1267195b21..0dbfd2a31e 100644
--- a/src/arch/riscv/Makefile.mk
+++ b/src/arch/riscv/Makefile.mk
@@ -97,6 +97,7 @@ endif #CONFIG_ARCH_BOOTBLOCK_RISCV
ifeq ($(CONFIG_ARCH_ROMSTAGE_RISCV),y)
romstage-$(CONFIG_SEPARATE_ROMSTAGE) += romstage.S
+romstage-y += ramdetect.c
# Build the romstage
@@ -120,6 +121,7 @@ ifeq ($(CONFIG_ARCH_RAMSTAGE_RISCV),y)
ramstage-y =
ramstage-y += ramstage.S
+ramstage-y += ramdetect.c
ramstage-y += tables.c
ramstage-y += payload.c
ramstage-y += fit_payload.c
diff --git a/src/arch/riscv/include/arch/exception.h b/src/arch/riscv/include/arch/exception.h
index 208cc81e24..9339437019 100644
--- a/src/arch/riscv/include/arch/exception.h
+++ b/src/arch/riscv/include/arch/exception.h
@@ -26,7 +26,7 @@ static inline void exception_init(void)
}
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 0000000000..3382435cdf
--- /dev/null
+++ b/src/arch/riscv/ramdetect.c
@@ -0,0 +1,61 @@
+/* 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>
+#include <vm.h>
+
+static enum {
+ ABORT_CHECKER_NOT_TRIGGERED,
+ ABORT_CHECKER_TRIGGERED,
+} abort_state = ABORT_CHECKER_NOT_TRIGGERED;
+
+extern void (*trap_handler)(trapframe *tf);
+
+static int get_instruction_len(uintptr_t addr)
+{
+ uint16_t ins = read16p(addr);
+
+ /*
+ * 16-bit or 32-bit instructions supported
+ */
+ if ((ins & 0x3) != 3) {
+ return 2;
+ } else if ((ins & 0x1f) != 0x1f) {
+ return 4;
+ }
+
+ die("Not a 16bit or 32bit instruction 0x%x\n", ins);
+}
+
+static void ramcheck_trap_handler(trapframe *tf)
+{
+ abort_state = ABORT_CHECKER_TRIGGERED;
+
+ /*
+ * skip read instruction.
+ */
+ int insn_size = get_instruction_len(tf->epc);
+
+ 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();
+ printk(BIOS_DEBUG, "%lx is %s DRAM\n", dram_start + size * MiB,
+ abort_state == ABORT_CHECKER_NOT_TRIGGERED ? "" : "not");
+
+ return abort_state == ABORT_CHECKER_NOT_TRIGGERED;
+}
diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c
index fbc6ae4c0e..4cbccc5892 100644
--- a/src/arch/riscv/trap_handler.c
+++ b/src/arch/riscv/trap_handler.c
@@ -33,10 +33,14 @@ static const char *const exception_names[] = {
static const char *mstatus_to_previous_mode(uintptr_t ms)
{
switch (ms & MSTATUS_MPP) {
- case 0x00000000: return "user";
- case 0x00000800: return "supervisor";
- case 0x00001000: return "hypervisor";
- case 0x00001800: return "machine";
+ case 0x00000000:
+ return "user";
+ case 0x00000800:
+ return "supervisor";
+ case 0x00001000:
+ return "hypervisor";
+ case 0x00001800:
+ return "machine";
}
return "unknown";
@@ -52,16 +56,13 @@ static void print_trap_information(const trapframe *tf)
printk(BIOS_DEBUG, "\n");
if (tf->cause < ARRAY_SIZE(exception_names))
- printk(BIOS_DEBUG, "Exception: %s\n",
- exception_names[tf->cause]);
+ printk(BIOS_DEBUG, "Exception: %s\n", exception_names[tf->cause]);
else
- printk(BIOS_DEBUG, "Trap: Unknown cause %p\n",
- (void *)tf->cause);
+ printk(BIOS_DEBUG, "Trap: Unknown cause %p\n", (void *)tf->cause);
previous_mode = mstatus_to_previous_mode(read_csr(mstatus));
printk(BIOS_DEBUG, "Hart ID: %d\n", hart_id);
- printk(BIOS_DEBUG, "Previous mode: %s%s\n",
- previous_mode, mprv? " (MPRV)":"");
+ printk(BIOS_DEBUG, "Previous mode: %s%s\n", previous_mode, mprv ? " (MPRV)" : "");
printk(BIOS_DEBUG, "Bad instruction pc: %p\n", (void *)tf->epc);
printk(BIOS_DEBUG, "Bad address: %p\n", (void *)tf->badvaddr);
printk(BIOS_DEBUG, "Stored ra: %p\n", (void *)tf->gpr[1]);
@@ -101,16 +102,17 @@ static void interrupt_handler(trapframe *tf)
break;
default:
printk(BIOS_EMERG, "======================================\n");
- printk(BIOS_EMERG, "coreboot: Unknown machine interrupt: 0x%llx\n",
- cause);
+ printk(BIOS_EMERG, "coreboot: Unknown machine interrupt: 0x%llx\n", cause);
printk(BIOS_EMERG, "======================================\n");
print_trap_information(tf);
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) {
interrupt_handler(tf);
return;
diff --git a/src/arch/riscv/trap_util.S b/src/arch/riscv/trap_util.S
index c5691c595f..d7b1250b7a 100644
--- a/src/arch/riscv/trap_util.S
+++ b/src/arch/riscv/trap_util.S
@@ -121,7 +121,12 @@ trap_entry:
save_tf
move a0,sp
- jal trap_handler
+
+ # store pointer to stack frame (moved out from trap_handler)
+ csrw mscratch, sp
+
+ LOAD t0, trap_handler
+ jalr t0
trap_return:
csrr a0, mscratch
diff --git a/src/lib/ramdetect.c b/src/lib/ramdetect.c
index 9a29d0fe94..cef3d57234 100644
--- a/src/lib/ramdetect.c
+++ b/src/lib/ramdetect.c
@@ -11,15 +11,12 @@
int __weak probe_mb(const uintptr_t dram_start, const uintptr_t size)
{
uintptr_t addr = dram_start + (size * MiB) - sizeof(uint32_t);
- static const uint32_t patterns[] = {
- 0x55aa55aa,
- 0x12345678
- };
- void *ptr = (void *) addr;
+ static const uint32_t patterns[] = {0x55aa55aa, 0x12345678};
+ void *ptr = (void *)addr;
size_t i;
/* Don't accidentally clobber oneself. */
- if (OVERLAP(addr, addr + sizeof(uint32_t), (uintptr_t)_program, (uintptr_t) _eprogram))
+ if (OVERLAP(addr, addr + sizeof(uint32_t), (uintptr_t)_program, (uintptr_t)_eprogram))
return 1;
uint32_t old = read32(ptr);
diff --git a/src/mainboard/emulation/qemu-riscv/Kconfig b/src/mainboard/emulation/qemu-riscv/Kconfig
index d915d6826e..af4416d0c1 100644
--- a/src/mainboard/emulation/qemu-riscv/Kconfig
+++ b/src/mainboard/emulation/qemu-riscv/Kconfig
@@ -45,7 +45,10 @@ config MAX_CPUS
config DRAM_SIZE_MB
int
- default 32768
+ default 16383
+ help
+ Qemu maps MMIO at ALIGN_UP(top_of_mem, 16 * GiB)
+ To avoid confusing the dram probing algorithm, avoid large dram sizes (16G - 1m)
config OPENSBI_PLATFORM
string