From 857e33e27f1feeec328ae8be5ad61ee51b75e4ec Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Mon, 22 Aug 2016 19:37:16 +0200 Subject: arch/riscv: Implement the SBI again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not all SBI calls are implemented, but it's enough to see a couple dozen lines of Linux boot output. It should also be noted that the SBI is still in flux: https://groups.google.com/a/groups.riscv.org/forum/#!topic/sw-dev/6oNhlW0OFKM Change-Id: I80e4fe508336d6428ca7136bc388fbc3cda4f1e4 Signed-off-by: Jonathan Neuschäfer Reviewed-on: https://review.coreboot.org/16119 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich --- src/arch/riscv/Makefile.inc | 1 + src/arch/riscv/include/arch/sbi.h | 36 +++++++ src/arch/riscv/sbi.S | 117 +++++++++++++++++++++++ src/arch/riscv/trap_handler.c | 43 ++++----- src/arch/riscv/virtual_memory.c | 3 +- src/mainboard/emulation/spike-riscv/spike_util.c | 22 ++--- 6 files changed, 183 insertions(+), 39 deletions(-) create mode 100644 src/arch/riscv/include/arch/sbi.h create mode 100644 src/arch/riscv/sbi.S (limited to 'src') diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc index 718aad9582..4bab459676 100644 --- a/src/arch/riscv/Makefile.inc +++ b/src/arch/riscv/Makefile.inc @@ -95,6 +95,7 @@ ramstage-y += stages.c ramstage-y += misc.c ramstage-y += boot.c ramstage-y += tables.c +ramstage-y += sbi.S ramstage-y += \ $(top)/src/lib/memchr.c \ $(top)/src/lib/memcmp.c \ diff --git a/src/arch/riscv/include/arch/sbi.h b/src/arch/riscv/include/arch/sbi.h new file mode 100644 index 0000000000..df7f6cc70e --- /dev/null +++ b/src/arch/riscv/include/arch/sbi.h @@ -0,0 +1,36 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Jonathan Neuschäfer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#ifndef _ARCH_SBI_H +#define _ARCH_SBI_H + +#define SBI_ECALL_HART_ID 0 +#define SBI_ECALL_CONSOLE_PUT 1 +#define SBI_ECALL_SEND_DEVICE_REQUEST 2 +#define SBI_ECALL_RECEIVE_DEVICE_RESPONSE 3 +#define SBI_ECALL_SEND_IPI 4 +#define SBI_ECALL_CLEAR_IPI 5 +#define SBI_ECALL_SHUTDOWN 6 +#define SBI_ECALL_SET_TIMER 7 +#define SBI_ECALL_QUERY_MEMORY 8 +#define SBI_ECALL_NUM_HARTS 9 + +#ifndef __ASSEMBLY__ +struct opaque; +extern struct opaque sbi_page; +#endif + +#endif diff --git a/src/arch/riscv/sbi.S b/src/arch/riscv/sbi.S new file mode 100644 index 0000000000..f4d5411879 --- /dev/null +++ b/src/arch/riscv/sbi.S @@ -0,0 +1,117 @@ +/* + * RISC-V supervisor binary interface (SBI) trampoline page + * + * Copyright 2016 Jonathan Neuschäfer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + */ + +#define __ASSEMBLY__ +#include +#include + +.section ".text.sbi", "ax", %progbits + +/* align to a page boundary */ +.align RISCV_PGSHIFT + +.globl sbi_page +sbi_page: + + /* + * None of the SBI entry points is located in the first half of the + * page + */ + .skip 0x800 + + /* -2048: size_t sbi_hart_id(void); */ + li a7, SBI_ECALL_HART_ID + ecall + jr ra + .align 4 + + /* -2032: size_t sbi_num_harts(void); */ + li a7, SBI_ECALL_NUM_HARTS + ecall + jr ra + .align 4 + + /* -2016: unsigned long sbi_query_memory(unsigned long id, + memory_block_info *p); */ + li a7, SBI_ECALL_QUERY_MEMORY + ecall + jr ra + .align 4 + + /* -2000: int sbi_console_putchar(uint8_t ch); */ + li a7, SBI_ECALL_CONSOLE_PUT + ecall + jr ra + .align 4 + + /* -1984: int sbi_console_getchar(void); */ + li a0, -1 /* failure: Coreboot doesn't support console input */ + jr ra + .align 4 + + /* -1968: Not allocated */ + ebreak + .align 4 + + /* -1952: int sbi_send_ipi(size_t hart_id); */ + ebreak + .align 4 + + /* -1936: int bool sbi_clear_ipi(void); */ + ebreak + .align 4 + + /* -1920: unsigned long sbi_timebase(void); */ + li a0, 1000000000 /* I have no idea. */ + jr ra + .align 4 + + /* -1904: void sbi_shutdown(void); */ + li a7, SBI_ECALL_SHUTDOWN + ecall + jr ra + .align 4 + + /* -1888: void sbi_set_timer(unsigned long long stime_value); */ + li a7, SBI_ECALL_SET_TIMER + ecall + jr ra + .align 4 + + /* -1872: int sbi_mask_interrupt(int which); */ + ebreak + .align 4 + + /* -1856: int sbi_unmask_interrupt(int which); */ + ebreak + .align 4 + + /* -1840: void sbi_remote_sfence_vm(const uintptr_t* harts, + size_t asid); */ + ebreak + .align 4 + + /* -1824: void sbi_remote_sfence_vm_range(const uintptr_t* harts, + size_t asid, uintptr_t start, uintptr_t size); */ + ebreak + .align 4 + + /* -1808: void sbi_remote_fence_i(const uintptr_t* harts); */ + ebreak + .align 4 + +/* Fill the remainder of the page */ +.align RISCV_PGSHIFT diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c index d8ac784c27..29d5a0b28c 100644 --- a/src/arch/riscv/trap_handler.c +++ b/src/arch/riscv/trap_handler.c @@ -15,63 +15,56 @@ */ #include +#include #include #include #include #include -#define HART_ID 0 -#define CONSOLE_PUT 1 -#define SEND_DEVICE_REQUEST 2 -#define RECEIVE_DEVICE_RESPONSE 3 -#define SEND_IPI 4 -#define CLEAR_IPI 5 -#define SHUTDOWN 6 -#define SET_TIMER 7 -#define QUERY_MEMORY 8 - -int loopBreak2 = 1; - void handle_supervisor_call(trapframe *tf) { - uintptr_t call = tf->gpr[17]; - uintptr_t arg0 = tf->gpr[10]; - uintptr_t arg1 = tf->gpr[11]; + uintptr_t call = tf->gpr[17]; /* a7 */ + uintptr_t arg0 = tf->gpr[10]; /* a0 */ + uintptr_t arg1 = tf->gpr[11]; /* a1 */ uintptr_t returnValue; switch(call) { - case HART_ID: + case SBI_ECALL_HART_ID: printk(BIOS_DEBUG, "Getting hart id...\n"); - returnValue = mcall_hart_id(); + returnValue = read_csr(mhartid); break; - case CONSOLE_PUT: + case SBI_ECALL_NUM_HARTS: + /* TODO: parse the hardware-supplied config string and + return the correct value */ + returnValue = 1; + case SBI_ECALL_CONSOLE_PUT: returnValue = mcall_console_putchar(arg0); break; - case SEND_DEVICE_REQUEST: + case SBI_ECALL_SEND_DEVICE_REQUEST: printk(BIOS_DEBUG, "Sending device request...\n"); returnValue = mcall_dev_req((sbi_device_message*) arg0); break; - case RECEIVE_DEVICE_RESPONSE: + case SBI_ECALL_RECEIVE_DEVICE_RESPONSE: printk(BIOS_DEBUG, "Getting device response...\n"); returnValue = mcall_dev_resp(); break; - case SEND_IPI: + case SBI_ECALL_SEND_IPI: printk(BIOS_DEBUG, "Sending IPI...\n"); returnValue = mcall_send_ipi(arg0); break; - case CLEAR_IPI: + case SBI_ECALL_CLEAR_IPI: printk(BIOS_DEBUG, "Clearing IPI...\n"); returnValue = mcall_clear_ipi(); break; - case SHUTDOWN: + case SBI_ECALL_SHUTDOWN: printk(BIOS_DEBUG, "Shutting down...\n"); returnValue = mcall_shutdown(); break; - case SET_TIMER: + case SBI_ECALL_SET_TIMER: printk(BIOS_DEBUG, "Setting timer to %p (current time is %p)...\n", (void *)arg0, (void *)rdtime()); returnValue = mcall_set_timer(arg0); break; - case QUERY_MEMORY: + case SBI_ECALL_QUERY_MEMORY: printk(BIOS_DEBUG, "Querying memory, CPU #%lld...\n", arg0); returnValue = mcall_query_memory(arg0, (memory_block_info*) arg1); break; diff --git a/src/arch/riscv/virtual_memory.c b/src/arch/riscv/virtual_memory.c index fab7d90d70..74b382527b 100644 --- a/src/arch/riscv/virtual_memory.c +++ b/src/arch/riscv/virtual_memory.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -151,7 +152,7 @@ void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, uintptr_t pageTable // map SBI at top of vaddr space uintptr_t num_sbi_pages = 1; // only need to map a single page for sbi interface - uintptr_t sbiStartAddress = 0x2000; // the start of the sbi mapping + uintptr_t sbiStartAddress = (uintptr_t) &sbi_page; uintptr_t sbiAddr = sbiStartAddress; for (uintptr_t i = 0; i < num_sbi_pages; i++) { uintptr_t idx = (1 << RISCV_PGLEVEL_BITS) - num_sbi_pages + i; diff --git a/src/mainboard/emulation/spike-riscv/spike_util.c b/src/mainboard/emulation/spike-riscv/spike_util.c index f0f5301814..7ddf16ba2c 100644 --- a/src/mainboard/emulation/spike-riscv/spike_util.c +++ b/src/mainboard/emulation/spike-riscv/spike_util.c @@ -25,12 +25,13 @@ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#include #include #include #include -#include #include +#include +#include +#include uintptr_t translate_address(uintptr_t vAddr) { // TODO: implement the page table translation algorithm @@ -41,13 +42,13 @@ uintptr_t translate_address(uintptr_t vAddr) { return translationResult; } -uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *p) +uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *info) { - uintptr_t physicalAddr = translate_address((uintptr_t) p); - memory_block_info *info = (memory_block_info*) physicalAddr; if (id == 0) { - info->base = 0x1000000; // hard coded for now, but we can put these values somewhere later - info->size = 0x7F000000 - info->base; + mprv_write_ulong(&info->base, 2U*GiB); + + /* TODO: Return the correct value */ + mprv_write_ulong(&info->size, 1*GiB); return 0; } @@ -79,7 +80,7 @@ uintptr_t mcall_shutdown(void) uintptr_t mcall_set_timer(unsigned long long when) { - die("mcall_set_timer is currently not implemented"); + printk(BIOS_DEBUG, "mcall_set_timer is currently not implemented, ignoring\n"); return 0; } @@ -95,11 +96,6 @@ uintptr_t mcall_dev_resp(void) return 0; } -uintptr_t mcall_hart_id(void) -{ - return HLS()->hart_id; -} - void hls_init(uint32_t hart_id) { memset(HLS(), 0, sizeof(*HLS())); -- cgit v1.2.3