[coreboot-gerrit] Patch set updated for coreboot: riscv: get SBI calls to work

Ronald G. Minnich (rminnich@gmail.com) gerrit at coreboot.org
Sat Jan 14 05:03:20 CET 2017


Ronald G. Minnich (rminnich at gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18097

-gerrit

commit a94517f6db705ff73ce1c4c856bf3fab4dcf73cb
Author: Ronald G. Minnich <rminnich at gmail.com>
Date:   Tue Jan 10 18:06:48 2017 -0800

    riscv: get SBI calls to work
    
    SBI calls, as it turned out, were never right.
    They did not set the stack correctly on traps.
    They were not correctly setting the MIP instead of the SIP
    (although this was not really well documented).
    On Harvey, we were trying to avoid using them,
    and due to a bug in SPIKE, our avoidance worked.
    Once SPIKE was fixed, our avoidance broke.
    
    This set of changes is tested and working with Harvey
    which, for the first time, is making SBI calls.
    
    It's not pretty and we're going to want to rework
    trap_util.S in coming days.
    
    Change-Id: Ibef530adcc58d33e2c44ff758e0b7d2acbdc5e99
    Signed-off-by: Ronald G. Minnich <rminnich at gmail.com>
---
 src/arch/riscv/bootblock.S     | 14 ++++++-----
 src/arch/riscv/include/mcall.h | 55 ++++++++++++++++++++++++++++++------------
 src/arch/riscv/mcall.c         | 25 +++++++++++++++++--
 src/arch/riscv/trap_handler.c  | 12 ++++-----
 src/arch/riscv/trap_util.S     | 12 ++++++---
 5 files changed, 83 insertions(+), 35 deletions(-)

diff --git a/src/arch/riscv/bootblock.S b/src/arch/riscv/bootblock.S
index c54c0e2..43bca90 100644
--- a/src/arch/riscv/bootblock.S
+++ b/src/arch/riscv/bootblock.S
@@ -16,6 +16,7 @@
  */
 
 #include <arch/encoding.h>
+#include <mcall.h>
 
 .section ".text._start", "ax", %progbits
 
@@ -30,8 +31,14 @@ _start:
 	# and the stack must be page-aligned.
 	la sp, _estack
 
+	# poison the stack
+	la t1, _stack
+	li t0, 0xdeadbeef
+	sd t0, 0(t1)
+
 	# make room for HLS and initialize it
-	addi sp, sp, -64 // MENTRY_FRAME_SIZE
+	addi sp, sp, -HLS_SIZE
+
 	// Once again, the docs and toolchain disagree.
 	// Rather than get fancy I'll just lock this down
 	// until it all stabilizes.
@@ -39,11 +46,6 @@ _start:
 	csrr a0, 0xf14
 	call hls_init
 
-	# poison the stack
-	la t1, _stack
-	li t0, 0xdeadbeef
-	sd t0, 0(t1)
-
 	la t0, trap_entry
 	csrw mtvec, t0
 
diff --git a/src/arch/riscv/include/mcall.h b/src/arch/riscv/include/mcall.h
index a43b9cf..d74bdf1 100644
--- a/src/arch/riscv/include/mcall.h
+++ b/src/arch/riscv/include/mcall.h
@@ -16,35 +16,56 @@
 #ifndef _MCALL_H
 #define _MCALL_H
 
+// NOTE: this is the size of hls_t below. A static_assert would be
+// nice to have.
+#define HLS_SIZE 64
+
+/* We save 37 registers, currently. */
+#define MENTRY_FRAME_SIZE (HLS_SIZE + 37 * 8)
+
+#define MCALL_HART_ID 0
+#define MCALL_CONSOLE_PUTCHAR 1
+#define MCALL_CONSOLE_GETCHAR 2
+#define MCALL_HTIF_SYSCALL 3
+#define MCALL_SEND_IPI 4
+#define MCALL_CLEAR_IPI 5
+#define MCALL_SHUTDOWN 6
+#define MCALL_SET_TIMER 7
+#define MCALL_REMOTE_SFENCE_VM 8
+#define MCALL_REMOTE_FENCE_I 9
+#define MCALL_CONFIG_STRING_BASE 10
+#define MCALL_CONFIG_STRING_SIZE 11
+
+#ifndef __ASSEMBLER__
+
 #include <arch/encoding.h>
 #include <atomic.h>
 #include <stdint.h>
 
-#define HLS_SIZE 64
-#define MENTRY_FRAME_SIZE HLS_SIZE
-
 typedef struct {
-  unsigned long base;
-  unsigned long size;
-  unsigned long node_id;
+	unsigned long base;
+	unsigned long size;
+	unsigned long node_id;
 } memory_block_info;
 
 typedef struct {
-  unsigned long dev;
-  unsigned long cmd;
-  unsigned long data;
-  unsigned long sbi_private_data;
+	unsigned long dev;
+	unsigned long cmd;
+	unsigned long data;
+	unsigned long sbi_private_data;
 } sbi_device_message;
 
 
 typedef struct {
-  sbi_device_message* device_request_queue_head;
-  unsigned long device_request_queue_size;
-  sbi_device_message* device_response_queue_head;
-  sbi_device_message* device_response_queue_tail;
+	sbi_device_message *device_request_queue_head;
+	unsigned long device_request_queue_size;
+	sbi_device_message *device_response_queue_head;
+	sbi_device_message *device_response_queue_tail;
 
-  int hart_id;
-  int ipi_pending;
+	int hart_id;
+	int ipi_pending;
+	uint64_t *timecmp;
+	uint64_t *time;
 } hls_t;
 
 #define MACHINE_STACK_TOP() ({ \
@@ -67,4 +88,6 @@ uintptr_t mcall_send_ipi(uintptr_t recipient);
 uintptr_t mcall_shutdown(void);
 void hls_init(uint32_t hart_id); // need to call this before launching linux
 
+#endif // __ASSEMBLER__
+
 #endif
diff --git a/src/arch/riscv/mcall.c b/src/arch/riscv/mcall.c
index aa61ae4..37a9366 100644
--- a/src/arch/riscv/mcall.c
+++ b/src/arch/riscv/mcall.c
@@ -34,6 +34,8 @@
 #include <string.h>
 #include <vm.h>
 
+int mcalldebug; // set this interactively for copious debug.
+
 uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *info)
 {
 	if (id == 0) {
@@ -74,9 +76,17 @@ uintptr_t mcall_shutdown(void)
 	return 0;
 }
 
-uintptr_t mcall_set_timer(unsigned long long when)
+uintptr_t mcall_set_timer(uint64_t when)
 {
-	printk(BIOS_DEBUG, "mcall_set_timer is currently not implemented, ignoring\n");
+	uint64_t *timecmp = HLS()->timecmp;
+
+	if (mcalldebug)
+		printk(BIOS_SPEW,
+		       "hart %d: HLS %p: mcall timecmp@%p to 0x%llx\n",
+		       HLS()->hart_id, HLS(), timecmp, when);
+	*timecmp = when;
+	clear_csr(mip, MIP_STIP);
+	set_csr(mie, MIP_MTIP);
 	return 0;
 }
 
@@ -94,8 +104,19 @@ uintptr_t mcall_dev_resp(void)
 
 void hls_init(uint32_t hart_id)
 {
+	query_result res;
+
+	printk(BIOS_SPEW, "hart %d: HLS is %p\n", hart_id, HLS());
 	memset(HLS(), 0, sizeof(*HLS()));
 	HLS()->hart_id = hart_id;
+
+	res = query_config_string(configstring(), "rtc{addr");
+	HLS()->time = (void *)get_uint(res);
+	res = query_config_string(configstring(), "core{0{0{timecmp");
+	HLS()->timecmp = (void *)get_uint(res);
+
+	printk(BIOS_SPEW, "Time is %p and timecmp is %p\n",
+	       HLS()->time, HLS()->timecmp);
 }
 
 uintptr_t mcall_console_putchar(uint8_t ch)
diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c
index 5681209..9a8947c 100644
--- a/src/arch/riscv/trap_handler.c
+++ b/src/arch/riscv/trap_handler.c
@@ -64,9 +64,6 @@ void handle_supervisor_call(trapframe *tf) {
 			returnValue = mcall_shutdown();
 			break;
 		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 SBI_ECALL_QUERY_MEMORY:
@@ -152,7 +149,7 @@ static void gettimer(void)
 static void interrupt_handler(trapframe *tf)
 {
 	uint64_t cause = tf->cause & ~0x8000000000000000ULL;
-	uint32_t ssip, ssie;
+	uint32_t msip, ssie;
 
 	switch (cause) {
 	case IRQ_M_TIMER:
@@ -183,10 +180,11 @@ static void interrupt_handler(trapframe *tf)
 
 		if (!timecmp)
 			gettimer();
+		//printk(BIOS_SPEW, "timer interrupt\n");
 		*timecmp = (uint64_t) -1;
-		ssip = read_csr(sip);
-		ssip |= SIP_STIP;
-		write_csr(sip, ssip);
+		msip = read_csr(mip);
+		msip |= SIP_STIP;
+		write_csr(mip, msip);
 		break;
 	default:
 		printk(BIOS_EMERG, "======================================\n");
diff --git a/src/arch/riscv/trap_util.S b/src/arch/riscv/trap_util.S
index 3357959..ae32379 100644
--- a/src/arch/riscv/trap_util.S
+++ b/src/arch/riscv/trap_util.S
@@ -15,6 +15,8 @@
  */
 
 #include <bits.h>
+#include <mcall.h>
+
 .macro restore_regs
     # restore x registers
     LOAD  x1,1*REGBYTES(a0)
@@ -100,16 +102,17 @@
   # get faulting insn, if it wasn't a fetch-related trap
   li x5,-1
   STORE x5,36*REGBYTES(x2)
-1:
+
   .endm
 
+.globl estack
   .text
   .global  supervisor_trap_entry
 supervisor_trap_entry:
     csrw mscratch, sp
     # load in the top of the machine stack
-    li sp, 0x80FFF0 - 64
-    1:addi sp,sp,-320
+    la	sp, _estack
+    addi sp,sp,-MENTRY_FRAME_SIZE
     save_tf
     move  a0,sp
     jal trap_handler
@@ -127,7 +130,8 @@ trap_entry:
 
   # TODO: Use the old stack pointer (plus an offset) for exceptions in machine
   # mode, to avoid overwriting stack data.
-  li sp, 0x8000fff0
+    la	sp, _estack
+    addi sp,sp,-MENTRY_FRAME_SIZE
 
   save_tf
   move  a0,sp



More information about the coreboot-gerrit mailing list