aboutsummaryrefslogtreecommitdiff
path: root/pk
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-02-28 20:42:42 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-02-28 20:42:42 -0800
commitd2d2e0a55c08b15a08892d5b89ee939a5986e69e (patch)
tree610c4abb4f618b7d6946dd48d8e0d5ad0d752a43 /pk
parent75471727f834ba6e227804a2b7330658a65f700a (diff)
downloadpk-d2d2e0a55c08b15a08892d5b89ee939a5986e69e.zip
pk-d2d2e0a55c08b15a08892d5b89ee939a5986e69e.tar.gz
pk-d2d2e0a55c08b15a08892d5b89ee939a5986e69e.tar.bz2
Remove SBI HTIF support; add console_getchar
Diffstat (limited to 'pk')
-rw-r--r--pk/frontend.c16
-rw-r--r--pk/frontend.h1
-rw-r--r--pk/mcall.h4
-rw-r--r--pk/minit.c2
-rw-r--r--pk/mtrap.c176
-rw-r--r--pk/mtrap.h11
-rw-r--r--pk/sbi.S3
-rw-r--r--pk/sbi.h14
-rw-r--r--pk/sbi_entry.S12
9 files changed, 84 insertions, 155 deletions
diff --git a/pk/frontend.c b/pk/frontend.c
index b2d26ce..5055a28 100644
--- a/pk/frontend.c
+++ b/pk/frontend.c
@@ -8,20 +8,6 @@
#include "syscall.h"
#include <stdint.h>
-uint64_t tohost_sync(unsigned dev, unsigned cmd, uint64_t payload)
-{
- uint64_t fromhost;
- __sync_synchronize();
-
- sbi_device_message m = {dev, cmd, payload}, *p;
- do_mcall(MCALL_SEND_DEVICE_REQUEST, &m);
- while ((p = (void*)do_mcall(MCALL_RECEIVE_DEVICE_RESPONSE)) == 0);
- kassert(p == &m);
-
- __sync_synchronize();
- return m.data;
-}
-
long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4, long a5, long a6)
{
static volatile uint64_t magic_mem[8];
@@ -38,7 +24,7 @@ long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4, long
magic_mem[6] = a5;
magic_mem[7] = a6;
- tohost_sync(0, 0, (uintptr_t)magic_mem);
+ do_mcall(MCALL_HTIF_SYSCALL, magic_mem);
long ret = magic_mem[0];
diff --git a/pk/frontend.h b/pk/frontend.h
index 65f3c47..ea5d244 100644
--- a/pk/frontend.h
+++ b/pk/frontend.h
@@ -20,7 +20,6 @@
void die(int) __attribute__((noreturn));
long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4, long a5, long a6);
-uint64_t tohost_sync(unsigned dev, unsigned cmd, uint64_t payload);
struct frontend_stat {
uint64_t dev;
diff --git a/pk/mcall.h b/pk/mcall.h
index c829f21..e612628 100644
--- a/pk/mcall.h
+++ b/pk/mcall.h
@@ -3,8 +3,8 @@
#define MCALL_HART_ID 0
#define MCALL_CONSOLE_PUTCHAR 1
-#define MCALL_SEND_DEVICE_REQUEST 2
-#define MCALL_RECEIVE_DEVICE_RESPONSE 3
+#define MCALL_CONSOLE_GETCHAR 2
+#define MCALL_HTIF_SYSCALL 3
#define MCALL_SEND_IPI 4
#define MCALL_CLEAR_IPI 5
#define MCALL_SHUTDOWN 6
diff --git a/pk/minit.c b/pk/minit.c
index 2c662b4..4784e75 100644
--- a/pk/minit.c
+++ b/pk/minit.c
@@ -76,6 +76,7 @@ void hls_init(uint32_t id, uintptr_t* csrs)
memset(hls, 0, sizeof(*hls));
hls->hart_id = id;
hls->csrs = csrs;
+ hls->console_ibuf = -1;
if (id != 0) {
while (((booted_harts_mask >> id) & 1) == 0)
@@ -106,6 +107,7 @@ void init_first_hart()
memory_init();
vm_init();
+ request_htif_keyboard_interrupt();
boot_loader(args);
}
diff --git a/pk/mtrap.c b/pk/mtrap.c
index c7cad95..e55aaa6 100644
--- a/pk/mtrap.c
+++ b/pk/mtrap.c
@@ -80,72 +80,54 @@ void __attribute__((noreturn)) bad_trap()
panic("machine mode: unhandlable trap %d @ %p", read_csr(mcause), read_csr(mepc));
}
-void htif_interrupt()
+static uintptr_t mcall_hart_id()
{
- uintptr_t fromhost = swap_csr(mfromhost, 0);
- if (!fromhost)
- return;
-
- uintptr_t dev = FROMHOST_DEV(fromhost);
- uintptr_t cmd = FROMHOST_CMD(fromhost);
- uintptr_t data = FROMHOST_DATA(fromhost);
-
- sbi_device_message* m = HLS()->device_request_queue_head;
- sbi_device_message* prev = NULL;
- for (size_t i = 0, n = HLS()->device_request_queue_size; i < n; i++) {
- if (!supervisor_paddr_valid(m, sizeof(*m))
- && EXTRACT_FIELD(read_csr(mstatus), MSTATUS_MPP) != PRV_M)
- panic("htif: page fault");
-
- sbi_device_message* next = (void*)m->sbi_private_data;
- if (m->dev == dev && m->cmd == cmd) {
- m->data = data;
-
- // dequeue from request queue
- if (prev)
- prev->sbi_private_data = (uintptr_t)next;
- else
- HLS()->device_request_queue_head = next;
- HLS()->device_request_queue_size = n-1;
- m->sbi_private_data = 0;
-
- // enqueue to response queue
- if (HLS()->device_response_queue_tail)
- HLS()->device_response_queue_tail->sbi_private_data = (uintptr_t)m;
- else
- HLS()->device_response_queue_head = m;
- HLS()->device_response_queue_tail = m;
-
- // signal software interrupt
- set_csr(mip, MIP_SSIP);
- return;
- }
-
- prev = m;
- m = (void*)atomic_read(&m->sbi_private_data);
- }
+ return HLS()->hart_id;
+}
- panic("htif: no record");
+void request_htif_keyboard_interrupt()
+{
+ uintptr_t old_tohost = swap_csr(mtohost, TOHOST_CMD(1, 0, 0));
+ kassert(old_tohost == 0);
}
-static uintptr_t mcall_hart_id()
+void htif_interrupt()
{
- return HLS()->hart_id;
+ // we should only be interrupted by keypresses
+ uintptr_t fromhost = swap_csr(mfromhost, 0);
+ kassert(FROMHOST_DEV(fromhost) == 1 && FROMHOST_CMD(fromhost) == 0);
+ HLS()->console_ibuf = (uint8_t)FROMHOST_DATA(fromhost);
+ set_csr(mip, MIP_SSIP);
+ request_htif_keyboard_interrupt();
}
-static uintptr_t mcall_console_putchar(uint8_t ch)
+static void do_tohost_fromhost(uintptr_t dev, uintptr_t cmd, uintptr_t data)
{
- while (swap_csr(mtohost, TOHOST_CMD(1, 1, ch)) != 0);
+ while (swap_csr(mtohost, TOHOST_CMD(dev, cmd, data)) != 0)
+ if (read_csr(mfromhost))
+ htif_interrupt();
+
while (1) {
uintptr_t fromhost = read_csr(mfromhost);
- if (FROMHOST_DEV(fromhost) != 1 || FROMHOST_CMD(fromhost) != 1) {
- if (fromhost)
- htif_interrupt();
- continue;
+ if (fromhost) {
+ if (FROMHOST_DEV(fromhost) == dev && FROMHOST_CMD(fromhost) == cmd) {
+ write_csr(mfromhost, 0);
+ break;
+ }
+ htif_interrupt();
}
- write_csr(mfromhost, 0);
- break;
}
+}
+
+static uintptr_t mcall_console_putchar(uint8_t ch)
+{
+ do_tohost_fromhost(1, 1, ch);
+ return 0;
+}
+
+static uintptr_t mcall_htif_syscall(uintptr_t magic_mem)
+{
+ do_tohost_fromhost(0, 0, magic_mem);
return 0;
}
@@ -163,51 +145,9 @@ void printm(const char* s, ...)
mcall_console_putchar(*p++);
}
-static uintptr_t mcall_dev_req(sbi_device_message *m)
-{
- //printm("req %d %p\n", HLS()->device_request_queue_size, m);
- if (!supervisor_paddr_valid(m, sizeof(*m))
- && EXTRACT_FIELD(read_csr(mstatus), MSTATUS_MPP) != PRV_M)
- return -EFAULT;
-
- if ((m->dev > 0xFFU) | (m->cmd > 0xFFU) | (m->data > 0x0000FFFFFFFFFFFFU))
- return -EINVAL;
-
- while (swap_csr(mtohost, TOHOST_CMD(m->dev, m->cmd, m->data)) != 0)
- ;
-
- m->sbi_private_data = (uintptr_t)HLS()->device_request_queue_head;
- HLS()->device_request_queue_head = m;
- HLS()->device_request_queue_size++;
-
- return 0;
-}
-
-static uintptr_t mcall_dev_resp()
-{
- htif_interrupt();
-
- sbi_device_message* m = HLS()->device_response_queue_head;
- if (m) {
- //printm("resp %p\n", m);
- sbi_device_message* next = (void*)atomic_read(&m->sbi_private_data);
- HLS()->device_response_queue_head = next;
- if (!next) {
- HLS()->device_response_queue_tail = 0;
-
- // only clear SSIP if no other events are pending
- clear_csr(mip, MIP_SSIP);
- mb();
- if (HLS()->ipi_pending & IPI_SOFT)
- set_csr(mip, MIP_SSIP);
- }
- }
- return (uintptr_t)m;
-}
-
static void send_ipi(uintptr_t recipient, int event)
{
- if ((atomic_or(&OTHER_HLS(recipient)->ipi_pending, event) & event) == 0) {
+ if ((atomic_or(&OTHER_HLS(recipient)->mipi_pending, event) & event) == 0) {
mb();
OTHER_HLS(recipient)->csrs[CSR_MIPI] = 1;
}
@@ -222,15 +162,27 @@ static uintptr_t mcall_send_ipi(uintptr_t recipient)
return 0;
}
-static uintptr_t mcall_clear_ipi()
+static void reset_ssip()
{
- // only clear SSIP if no other events are pending
- if (HLS()->device_response_queue_head == NULL) {
- clear_csr(mip, MIP_SSIP);
- mb();
- }
+ clear_csr(mip, MIP_SSIP);
+ mb();
+
+ if (HLS()->sipi_pending || HLS()->console_ibuf >= 0)
+ set_csr(mip, MIP_SSIP);
+}
- return atomic_swap(&HLS()->ipi_pending, 0);
+static uintptr_t mcall_console_getchar()
+{
+ int ch = atomic_swap(&HLS()->console_ibuf, -1);
+ reset_ssip();
+ return ch;
+}
+
+static uintptr_t mcall_clear_ipi()
+{
+ int ipi = atomic_swap(&HLS()->sipi_pending, 0);
+ reset_ssip();
+ return ipi;
}
static uintptr_t mcall_shutdown()
@@ -256,10 +208,12 @@ void software_interrupt()
{
clear_csr(mip, MIP_MSIP);
mb();
- int ipi_pending = atomic_swap(&HLS()->ipi_pending, 0);
+ int ipi_pending = atomic_swap(&HLS()->mipi_pending, 0);
- if (ipi_pending & IPI_SOFT)
+ if (ipi_pending & IPI_SOFT) {
+ HLS()->sipi_pending = 1;
set_csr(mip, MIP_SSIP);
+ }
if (ipi_pending & IPI_FENCE_I)
asm volatile ("fence.i");
@@ -286,7 +240,7 @@ static void send_ipi_many(uintptr_t* pmask, int event)
// prevent deadlock while spinning by handling any IPIs from other harts.
for (ssize_t i = num_harts-1; i >= 0; i--)
if ((mask >> i) & 1)
- while (OTHER_HLS(i)->ipi_pending & event)
+ while (OTHER_HLS(i)->mipi_pending & event)
software_interrupt();
}
@@ -315,11 +269,11 @@ void mcall_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc)
case MCALL_CONSOLE_PUTCHAR:
retval = mcall_console_putchar(arg0);
break;
- case MCALL_SEND_DEVICE_REQUEST:
- retval = mcall_dev_req((sbi_device_message*)arg0);
+ case MCALL_CONSOLE_GETCHAR:
+ retval = mcall_console_getchar();
break;
- case MCALL_RECEIVE_DEVICE_RESPONSE:
- retval = mcall_dev_resp();
+ case MCALL_HTIF_SYSCALL:
+ retval = mcall_htif_syscall(arg0);
break;
case MCALL_SEND_IPI:
retval = mcall_send_ipi(arg0);
diff --git a/pk/mtrap.h b/pk/mtrap.h
index b0369ca..7ab1f6c 100644
--- a/pk/mtrap.h
+++ b/pk/mtrap.h
@@ -163,20 +163,19 @@ static inline int xlen()
}
typedef struct {
- sbi_device_message* device_request_queue_head;
- size_t device_request_queue_size;
- sbi_device_message* device_response_queue_head;
- sbi_device_message* device_response_queue_tail;
-
volatile uintptr_t* csrs;
int hart_id;
- volatile int ipi_pending;
+ volatile int mipi_pending;
+ volatile int sipi_pending;
+ int console_ibuf;
} hls_t;
#define IPI_SOFT 0x1
#define IPI_FENCE_I 0x2
#define IPI_SFENCE_VM 0x4
+void request_htif_keyboard_interrupt();
+
void hls_init(uint32_t hart_id, uintptr_t* csrs);
#define MACHINE_STACK_TOP() ({ \
diff --git a/pk/sbi.S b/pk/sbi.S
index 0c32d06..cbea78a 100644
--- a/pk/sbi.S
+++ b/pk/sbi.S
@@ -2,8 +2,7 @@
.globl sbi_num_harts; sbi_num_harts = -2032
.globl sbi_query_memory; sbi_query_memory = -2016
.globl sbi_console_putchar; sbi_console_putchar = -2000
-.globl sbi_send_device_request; sbi_send_device_request = -1984
-.globl sbi_receive_device_response; sbi_receive_device_response = -1968
+.globl sbi_console_getchar; sbi_console_getchar = -1984
.globl sbi_send_ipi; sbi_send_ipi = -1952
.globl sbi_clear_ipi; sbi_clear_ipi = -1936
.globl sbi_timebase; sbi_timebase = -1920
diff --git a/pk/sbi.h b/pk/sbi.h
index cc112d9..4e2fbd8 100644
--- a/pk/sbi.h
+++ b/pk/sbi.h
@@ -15,23 +15,15 @@ unsigned long sbi_timebase(void);
void sbi_set_timer(unsigned long long stime_value);
void sbi_send_ipi(unsigned long hart_id);
unsigned long sbi_clear_ipi(void);
-void sbi_console_putchar(unsigned long ch);
void sbi_shutdown(void);
+void sbi_console_putchar(unsigned char ch);
+int sbi_console_getchar(void);
+
void sbi_remote_sfence_vm(unsigned long hart_mask_ptr, unsigned long asid);
void sbi_remote_sfence_vm_range(unsigned long hart_mask_ptr, unsigned long asid, unsigned long start, unsigned long size);
void sbi_remote_fence_i(unsigned long hart_mask_ptr);
-typedef struct {
- unsigned long dev;
- unsigned long cmd;
- unsigned long data;
- unsigned long sbi_private_data;
-} sbi_device_message;
-
-unsigned long sbi_send_device_request(unsigned long req);
-unsigned long sbi_receive_device_response(void);
-
unsigned long sbi_mask_interrupt(unsigned long which);
unsigned long sbi_unmask_interrupt(unsigned long which);
diff --git a/pk/sbi_entry.S b/pk/sbi_entry.S
index eef456b..bfb0703 100644
--- a/pk/sbi_entry.S
+++ b/pk/sbi_entry.S
@@ -32,17 +32,15 @@ sbi_base:
ecall
ret
- # send_device_request
+ # console_getchar
.align 4
- li a7, MCALL_SEND_DEVICE_REQUEST
+ li a7, MCALL_CONSOLE_GETCHAR
ecall
ret
- # receive_device_response
+ # empty
.align 4
- li a7, MCALL_RECEIVE_DEVICE_RESPONSE
- ecall
- ret
+ unimp
# send ipi
.align 4
@@ -50,7 +48,7 @@ sbi_base:
ecall
ret
- # send ipi
+ # clear ipi
.align 4
li a7, MCALL_CLEAR_IPI
ecall