summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/riscv/bootblock.S14
-rw-r--r--src/arch/riscv/include/mcall.h42
-rw-r--r--src/arch/riscv/mcall.c25
-rw-r--r--src/arch/riscv/trap_handler.c12
-rw-r--r--src/arch/riscv/trap_util.S12
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