diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/riscv/bootblock.S | 14 | ||||
-rw-r--r-- | src/arch/riscv/include/mcall.h | 42 | ||||
-rw-r--r-- | src/arch/riscv/mcall.c | 25 | ||||
-rw-r--r-- | src/arch/riscv/trap_handler.c | 12 | ||||
-rw-r--r-- | src/arch/riscv/trap_util.S | 12 |
5 files changed, 70 insertions, 35 deletions
diff --git a/src/arch/riscv/bootblock.S b/src/arch/riscv/bootblock.S index c54c0e235c..43bca907bb 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 a43b9cf49b..e303d0d28d 100644 --- a/src/arch/riscv/include/mcall.h +++ b/src/arch/riscv/include/mcall.h @@ -16,35 +16,43 @@ #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) + +#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 +75,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 aa61ae464a..37a9366821 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 56812090c5..9a8947c990 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 33579590dc..ae32379562 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 |