aboutsummaryrefslogtreecommitdiff
path: root/machine/htif.c
diff options
context:
space:
mode:
Diffstat (limited to 'machine/htif.c')
-rw-r--r--machine/htif.c54
1 files changed, 32 insertions, 22 deletions
diff --git a/machine/htif.c b/machine/htif.c
index 8b8d69b..fa3db53 100644
--- a/machine/htif.c
+++ b/machine/htif.c
@@ -2,47 +2,56 @@
#include "atomic.h"
#include "mtrap.h"
-volatile uint64_t tohost __attribute__((section("htif")));
-volatile uint64_t fromhost __attribute__((section("htif")));
+volatile uint64_t tohost __attribute__((section(".htif")));
+volatile uint64_t fromhost __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;
- assert(FROMHOST_DEV(fh) == 1 && FROMHOST_CMD(fh) == 0);
- htif_console_buf = 1 + (uint8_t)FROMHOST_DATA(fh);
fromhost = 0;
+
+ // this should be from the console
+ assert(FROMHOST_DEV(fh) == 1);
+ switch (FROMHOST_CMD(fh)) {
+ case 0:
+ htif_console_buf = 1 + (uint8_t)FROMHOST_DATA(fh);
+ break;
+ case 1:
+ break;
+ default:
+ assert(0);
+ }
+}
+
+static void __set_tohost(uintptr_t dev, uintptr_t cmd, uintptr_t data)
+{
+ while (tohost)
+ __check_fromhost();
+ tohost = TOHOST_CMD(dev, cmd, data);
}
int htif_console_getchar()
{
- if (spinlock_trylock(&htif_lock) == 0) {
+ spinlock_lock(&htif_lock);
__check_fromhost();
- spinlock_unlock(&htif_lock);
- }
+ int ch = htif_console_buf;
+ if (ch >= 0) {
+ htif_console_buf = -1;
+ __set_tohost(1, 0, 0);
+ }
+ 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);
+ __set_tohost(dev, cmd, data);
while (1) {
uint64_t fh = fromhost;
@@ -53,7 +62,6 @@ static void do_tohost_fromhost(uintptr_t dev, uintptr_t cmd, uintptr_t data)
}
__check_fromhost();
}
- wfi();
}
spinlock_unlock(&htif_lock);
}
@@ -65,7 +73,9 @@ void htif_syscall(uintptr_t arg)
void htif_console_putchar(uint8_t ch)
{
- do_tohost_fromhost(1, 1, ch);
+ spinlock_lock(&htif_lock);
+ __set_tohost(1, 1, ch);
+ spinlock_unlock(&htif_lock);
}
void htif_poweroff()