[coreboot-gerrit] Patch set updated for coreboot: arch/riscv: Implement the SBI again

Jonathan Neuschäfer (j.neuschaefer@gmx.net) gerrit at coreboot.org
Fri Aug 19 12:46:09 CEST 2016


Jonathan Neuschäfer (j.neuschaefer at gmx.net) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16119

-gerrit

commit 50a82d968b544555ae973453cce3940e45a5a58f
Author: Jonathan Neuschäfer <j.neuschaefer at gmx.net>
Date:   Fri Aug 19 12:10:20 2016 +0200

    arch/riscv: Implement the SBI again
    
    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 <j.neuschaefer at gmx.net>
---
 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(-)

diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc
index 718aad9..4bab459 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 0000000..df7f6cc
--- /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 <j.neuschaefer at gmx.net>
+ *
+ * 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 0000000..f4d5411
--- /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 <j.neuschaefer at gmx.net>
+ *
+ * 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 <arch/encoding.h>
+#include <arch/sbi.h>
+
+.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 d8ac784..29d5a0b 100644
--- a/src/arch/riscv/trap_handler.c
+++ b/src/arch/riscv/trap_handler.c
@@ -15,63 +15,56 @@
  */
 
 #include <arch/exception.h>
+#include <arch/sbi.h>
 #include <console/console.h>
 #include <spike_util.h>
 #include <string.h>
 #include <vm.h>
 
-#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 c68ed4d..18d2862 100644
--- a/src/arch/riscv/virtual_memory.c
+++ b/src/arch/riscv/virtual_memory.c
@@ -16,6 +16,7 @@
 
 #include <arch/barrier.h>
 #include <arch/encoding.h>
+#include <arch/sbi.h>
 #include <atomic.h>
 #include <console/console.h>
 #include <stdint.h>
@@ -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 f0f5301..7ddf16b 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 <spike_util.h>
 #include <arch/barrier.h>
 #include <arch/errno.h>
 #include <atomic.h>
-#include <string.h>
 #include <console/console.h>
+#include <spike_util.h>
+#include <string.h>
+#include <vm.h>
 
 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()));



More information about the coreboot-gerrit mailing list