ron minnich has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/81294?usp=email )
Change subject: arch/riscv: add new SBI calls ......................................................................
arch/riscv: add new SBI calls
This is just a start. We are playing catch up.
7 down, 70+ to go.
Signed-off-by: Ronald G Minnich rminnich@gmail.com
clang-formatted-by: Ronald G Minnich
Change-Id: I5dac8613020e26ec74ac1c74158fc9791553693f --- M src/arch/riscv/sbi.c 1 file changed, 80 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/94/81294/1
diff --git a/src/arch/riscv/sbi.c b/src/arch/riscv/sbi.c index 8bf21b7..fd6d1d3 100644 --- a/src/arch/riscv/sbi.c +++ b/src/arch/riscv/sbi.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */
+#include <console/console.h> #include <mcall.h> #include <stdint.h> #include <arch/exception.h> @@ -49,6 +50,52 @@ return 0; }
+static void print_sbi_trap(uintptr_t trap) +{ + switch (trap) { + case SBI_SHUTDOWN: + printk(BIOS_EMERG, "SBI_SHUTDOWN\n"); + break; + case SBI_REMOTE_SFENCE_VMA_ASID: + printk(BIOS_EMERG, "SBI_REMOTE_SFENCE_VMA_ASID\n"); + break; + case SBI_REMOTE_SFENCE_VMA: + printk(BIOS_EMERG, "SBI_REMOTE_SFENCE_VMA\n"); + break; + case SBI_REMOTE_FENCE_I: + printk(BIOS_EMERG, "SBI_REMOTE_FENCE_I\n"); + break; + case SBI_SEND_IPI: + printk(BIOS_EMERG, "SBI_SEND_IPI\n"); + break; + case SBI_CLEAR_IPI: + printk(BIOS_EMERG, "SBI_CLEAR_IPI\n"); + break; + case SBI_CONSOLE_GETCHAR: + printk(BIOS_EMERG, "SBI_CONSOLE_GETCHAR\n"); + break; + case SBI_CONSOLE_PUTCHAR: + printk(BIOS_EMERG, "SBI_CONSOLE_PUTCHAR\n"); + break; + case SBI_SET_TIMER: + printk(BIOS_EMERG, "SBI_SET_TIMER\n"); + break; + case SBI_EXTENSION_ID: + printk(BIOS_EMERG, "SBI_EXTENSION_ID\n"); + break; + default: + printk(BIOS_EMERG, "%lx is an unknown SBI trap\n", trap); + break; + } +} + +/* These are the default sbi extension values. + * They can be overridden in the case of an older SoC like the FU[57]40 + * 1 is the most basic SBI, per the standard; per the standard, + * all the other values can be 0. + */ +int __weak sbi_features[] = {1, 0, 0, 0, 0, 0, 0}; + /* * sbi is triggered by the s-mode ecall * parameter : register a0 a1 a2 @@ -58,11 +105,24 @@ void handle_sbi(struct trapframe *tf) { uintptr_t ret = 0; + uintptr_t sbiret = 0; uintptr_t arg0 = tf->gpr[10]; __maybe_unused uintptr_t arg1 = tf->gpr[11]; - uintptr_t which = tf->gpr[17]; + uintptr_t fid = tf->gpr[16]; + uintptr_t eid = tf->gpr[17]; + uintptr_t retpc = read_csr(mepc) + 4;
- switch (which) { + /* + * These are for when things are going seriously wrong. + * In practice we don't want them compiled in, + * hence the if(0). + */ + if (0) { + printk(BIOS_EMERG, "%s\n", __func__); + print_sbi_trap(eid); + } + + switch (eid) { case SBI_SET_TIMER: #if __riscv_xlen == 32 ret = sbi_set_timer(arg0 + ((uint64_t)arg1 << 32)); @@ -96,10 +156,25 @@ case SBI_SHUTDOWN: ret = send_ipi((uintptr_t *)arg0, IPI_SHUTDOWN); break; + case SBI_EXTENSION_ID: + /* zero is an allowed return value for most features, + * and the only required one is feature 0. + * So this test will return legal values + * for all possible values of fid. + */ + if (fid < ARRAY_SIZE(sbi_features)) + ret = sbi_features[fid]; + break; default: - ret = -SBI_ENOSYS; + printk(BIOS_EMERG, "SBI: %lx: ENOSYS\n", fid); + sbiret = -SBI_ENOSYS; break; } - tf->gpr[10] = ret; - write_csr(mepc, read_csr(mepc) + 4); + tf->gpr[10] = sbiret; + tf->gpr[11] = ret; + + if (0) + printk(BIOS_EMERG, "%s:returning [%lx,%lx] to %lx\n", __func__, sbiret, ret, retpc); + + write_csr(mepc, retpc); }