diff options
author | Andrew Waterman <andrew@sifive.com> | 2017-02-20 21:43:09 -0800 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2017-02-20 21:43:09 -0800 |
commit | f6bca6e35b66632afad68f6b7fb2b3203c8502fb (patch) | |
tree | 3f8d691713d96ef4e7f57b8504691e68cdcda6f7 /machine/htif.c | |
parent | 59484c94e161b0f1870096cfb183533b20569669 (diff) | |
download | riscv-pk-f6bca6e35b66632afad68f6b7fb2b3203c8502fb.zip riscv-pk-f6bca6e35b66632afad68f6b7fb2b3203c8502fb.tar.gz riscv-pk-f6bca6e35b66632afad68f6b7fb2b3203c8502fb.tar.bz2 |
Don't block for acks on console writes
Diffstat (limited to 'machine/htif.c')
-rw-r--r-- | machine/htif.c | 54 |
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() |