aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2017-02-15 18:59:21 -0800
committerAndrew Waterman <andrew@sifive.com>2017-02-15 18:59:21 -0800
commit611290ccde8d76c1973a37d82a5d4b3e4b7b90c4 (patch)
treed8b19a464a043d362663d8207daeae1f31d226d1
parent15a111444d6819021328e990eb5308155a9def6a (diff)
downloadpk-611290ccde8d76c1973a37d82a5d4b3e4b7b90c4.zip
pk-611290ccde8d76c1973a37d82a5d4b3e4b7b90c4.tar.gz
pk-611290ccde8d76c1973a37d82a5d4b3e4b7b90c4.tar.bz2
Cleanly separate HTIF code; don't poll keyboard on timer interrupt
-rw-r--r--machine/htif.c78
-rw-r--r--machine/htif.h5
-rw-r--r--machine/machine.mk.in1
-rw-r--r--machine/mcall.h1
-rw-r--r--machine/mtrap.c89
-rw-r--r--machine/mtrap.h1
-rw-r--r--pk/frontend.c4
7 files changed, 92 insertions, 87 deletions
diff --git a/machine/htif.c b/machine/htif.c
new file mode 100644
index 0000000..a513305
--- /dev/null
+++ b/machine/htif.c
@@ -0,0 +1,78 @@
+#include "htif.h"
+#include "atomic.h"
+#include "mtrap.h"
+
+volatile uint64_t tohost __attribute__((aligned(64))) __attribute__((section("htif")));
+volatile uint64_t fromhost __attribute__((aligned(64))) __attribute__((section("htif")));
+volatile int htif_console_buf;
+static spinlock_t htif_lock = SPINLOCK_INIT;
+
+static void request_htif_keyboard_interrupt()
+{
+ assert(tohost == 0);
+ tohost = TOHOST_CMD(1, 0, 0);
+}
+
+static void __check_fromhost()
+{
+ // we should only be interrupted by keypresses
+ uint64_t fh = fromhost;
+ if (!fh)
+ return;
+ if (!(FROMHOST_DEV(fh) == 1 && FROMHOST_CMD(fh) == 0))
+ die("unexpected htif interrupt");
+ htif_console_buf = 1 + (uint8_t)FROMHOST_DATA(fh);
+ fromhost = 0;
+}
+
+int htif_console_getchar()
+{
+ if (spinlock_trylock(&htif_lock) == 0) {
+ __check_fromhost();
+ spinlock_unlock(&htif_lock);
+ }
+
+ int ch = atomic_swap(&htif_console_buf, -1);
+ if (ch >= 0)
+ request_htif_keyboard_interrupt();
+ return ch - 1;
+}
+
+static void do_tohost_fromhost(uintptr_t dev, uintptr_t cmd, uintptr_t data)
+{
+ spinlock_lock(&htif_lock);
+ while (tohost)
+ __check_fromhost();
+ tohost = TOHOST_CMD(dev, cmd, data);
+
+ while (1) {
+ uint64_t fh = fromhost;
+ if (fh) {
+ if (FROMHOST_DEV(fh) == dev && FROMHOST_CMD(fh) == cmd) {
+ fromhost = 0;
+ break;
+ }
+ __check_fromhost();
+ }
+ }
+ spinlock_unlock(&htif_lock);
+}
+
+uintptr_t htif_syscall(uintptr_t arg)
+{
+ do_tohost_fromhost(0, 0, arg);
+ return 0;
+}
+
+void htif_console_putchar(uint8_t ch)
+{
+ do_tohost_fromhost(1, 1, ch);
+}
+
+void htif_poweroff()
+{
+ while (1) {
+ fromhost = 0;
+ tohost = 1;
+ }
+}
diff --git a/machine/htif.h b/machine/htif.h
index 7107ddb..f47e965 100644
--- a/machine/htif.h
+++ b/machine/htif.h
@@ -15,4 +15,9 @@
#define FROMHOST_CMD(fromhost_value) ((uint64_t)(fromhost_value) << 8 >> 56)
#define FROMHOST_DATA(fromhost_value) ((uint64_t)(fromhost_value) << 16 >> 16)
+void htif_console_putchar(uint8_t);
+int htif_console_getchar();
+void htif_poweroff() __attribute__((noreturn));
+uintptr_t htif_syscall(uintptr_t);
+
#endif
diff --git a/machine/machine.mk.in b/machine/machine.mk.in
index 6568dc5..e224982 100644
--- a/machine/machine.mk.in
+++ b/machine/machine.mk.in
@@ -18,6 +18,7 @@ machine_hdrs = \
machine_c_srcs = \
mtrap.c \
minit.c \
+ htif.c \
emulation.c \
muldiv_emulation.c \
fp_emulation.c \
diff --git a/machine/mcall.h b/machine/mcall.h
index 2096d16..ed5a28c 100644
--- a/machine/mcall.h
+++ b/machine/mcall.h
@@ -4,7 +4,6 @@
#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
diff --git a/machine/mtrap.c b/machine/mtrap.c
index 34772b7..0ed27e9 100644
--- a/machine/mtrap.c
+++ b/machine/mtrap.c
@@ -8,10 +8,6 @@
#include <stdarg.h>
#include <stdio.h>
-volatile uint64_t tohost __attribute__((aligned(64))) __attribute__((section("htif")));
-volatile uint64_t fromhost __attribute__((aligned(64))) __attribute__((section("htif")));
-static spinlock_t htif_lock = SPINLOCK_INIT;
-
void __attribute__((noreturn)) bad_trap()
{
die("machine mode: unhandlable trap %d @ %p", read_csr(mcause), read_csr(mepc));
@@ -22,81 +18,24 @@ static uintptr_t mcall_hart_id()
return read_const_csr(mhartid);
}
-static void request_htif_keyboard_interrupt()
-{
- assert(tohost == 0);
- tohost = TOHOST_CMD(1, 0, 0);
-}
-
-static void __htif_interrupt()
-{
- // we should only be interrupted by keypresses
- uint64_t fh = fromhost;
- if (!fh)
- return;
- if (!(FROMHOST_DEV(fh) == 1 && FROMHOST_CMD(fh) == 0))
- die("unexpected htif interrupt");
- HLS()->console_ibuf = 1 + (uint8_t)FROMHOST_DATA(fh);
- fromhost = 0;
- set_csr(mip, MIP_SSIP);
-}
-
-static void do_tohost_fromhost(uintptr_t dev, uintptr_t cmd, uintptr_t data)
-{
- spinlock_lock(&htif_lock);
- while (tohost)
- __htif_interrupt();
- tohost = TOHOST_CMD(dev, cmd, data);
-
- while (1) {
- uint64_t fh = fromhost;
- if (fh) {
- if (FROMHOST_DEV(fh) == dev && FROMHOST_CMD(fh) == cmd) {
- fromhost = 0;
- break;
- }
- __htif_interrupt();
- }
- }
- spinlock_unlock(&htif_lock);
-}
-
-static void htif_interrupt()
-{
- if (spinlock_trylock(&htif_lock) == 0) {
- __htif_interrupt();
- spinlock_unlock(&htif_lock);
- }
-}
-
uintptr_t timer_interrupt()
{
// just send the timer interrupt to the supervisor
clear_csr(mie, MIP_MTIP);
set_csr(mip, MIP_STIP);
- // and poll the HTIF console
- htif_interrupt();
-
return 0;
}
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);
+ htif_console_putchar(ch);
return 0;
}
void poweroff()
{
- while (1)
- tohost = 1;
+ htif_poweroff();
}
void putstring(const char* s)
@@ -134,29 +73,16 @@ static uintptr_t mcall_send_ipi(uintptr_t recipient)
return 0;
}
-static void reset_ssip()
-{
- clear_csr(mip, MIP_SSIP);
- mb();
-
- if (HLS()->sipi_pending || HLS()->console_ibuf > 0)
- set_csr(mip, MIP_SSIP);
-}
-
static uintptr_t mcall_console_getchar()
{
- int ch = atomic_swap(&HLS()->console_ibuf, -1);
- if (ch >= 0)
- request_htif_keyboard_interrupt();
- reset_ssip();
- return ch - 1;
+ return htif_console_getchar();
}
static uintptr_t mcall_clear_ipi()
{
- int ipi = atomic_swap(&HLS()->sipi_pending, 0);
- reset_ssip();
- return ipi;
+ clear_csr(mip, MIP_SSIP);
+ mb();
+ return atomic_swap(&HLS()->sipi_pending, 0);
}
static uintptr_t mcall_shutdown()
@@ -239,9 +165,6 @@ void mcall_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc)
case MCALL_CONSOLE_GETCHAR:
retval = mcall_console_getchar();
break;
- case MCALL_HTIF_SYSCALL:
- retval = mcall_htif_syscall(arg0);
- break;
case MCALL_SEND_IPI:
retval = mcall_send_ipi(arg0);
break;
diff --git a/machine/mtrap.h b/machine/mtrap.h
index 9995203..68c93f2 100644
--- a/machine/mtrap.h
+++ b/machine/mtrap.h
@@ -41,7 +41,6 @@ typedef struct {
uint32_t* ipi;
volatile int mipi_pending;
volatile int sipi_pending;
- int console_ibuf;
volatile uint32_t* plic_m_thresh;
volatile uintptr_t* plic_m_ie;
diff --git a/pk/frontend.c b/pk/frontend.c
index 13fdfcf..716f050 100644
--- a/pk/frontend.c
+++ b/pk/frontend.c
@@ -4,8 +4,8 @@
#include "atomic.h"
#include "frontend.h"
#include "sbi.h"
-#include "mcall.h"
#include "syscall.h"
+#include "htif.h"
#include <stdint.h>
long frontend_syscall(long n, uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5, uint64_t a6)
@@ -24,7 +24,7 @@ long frontend_syscall(long n, uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3
magic_mem[6] = a5;
magic_mem[7] = a6;
- do_mcall(MCALL_HTIF_SYSCALL, magic_mem);
+ htif_syscall((uintptr_t)magic_mem);
long ret = magic_mem[0];