summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assembly/extint-test/extint-test.S26
-rw-r--r--c/inline/Makefile20
-rw-r--r--c/inline/inline.c25
-rw-r--r--c/inline/rvcontroller.ld45
-rw-r--r--doc/csr.txt9
-rw-r--r--rvcontroller.lua33
6 files changed, 143 insertions, 15 deletions
diff --git a/assembly/extint-test/extint-test.S b/assembly/extint-test/extint-test.S
index c1b872d..68a218c 100644
--- a/assembly/extint-test/extint-test.S
+++ b/assembly/extint-test/extint-test.S
@@ -4,8 +4,8 @@ la t0,handler
csrw mtvec,t0 # Set up trap handler
li t0,0x400
csrc mstatush,t0 # Turn off MDT
-li t0,0x30000
-csrw mie,t0 # Mask all interrupts except mesecons/digilines
+li t0,0x70000
+csrw mie,t0 # Mask all interrupts except mesecons/digilines/console
csrw mip,zero # Clear any pending interrupts
csrsi mstatus,0x8 # Turn on MIE to enable interrupts
@@ -43,12 +43,16 @@ sw x30,120(x31) # and write that back out too
csrr t0,mcause # Read why the trap occurred
+
li t1,0x80000010 # Interrupt 16 = mesecons
beq t0,t1,handler_mesecons
li t1,0x80000011 # Interrupt 17 = digilines
beq t0,t1,handler_digilines
+li t1,0x80000012 # Interrupt 18 = console
+beq t0,t1,handler_console
+
j handler_other # Something else
handler_mesecons:
@@ -100,6 +104,23 @@ ecall # Clear out any other digilines messages
j handler_epilogue
+handler_console:
+li a7,4
+la a0,consolemsg
+ecall # Show that this was a console event
+
+li a7,132
+ecall # Read the first character from the input buffer
+li a7,11
+ecall # And print it
+li a0,'\n'
+ecall # Followed by a line feed
+
+li a7,131
+ecall # Discard the rest
+
+j handler_epilogue
+
handler_other:
li a7,4
la a0,unimplementedmsg
@@ -140,6 +161,7 @@ waitingmsg: .asciz "Waiting...\n"
meseconsmsg: .asciz "Mesecons event!\nInput value: "
digilinesmsg: .asciz "Digilines event!\nChannel:\n"
digilinesmsg2: .asciz "\nMessage:\n"
+consolemsg: .asciz "Console event!\nFirst char: "
unimplementedmsg: .asciz "Unimplemented trap!\nmcause: "
channelbuf: .asciz " "
msgbuf: .asciz " "
diff --git a/c/inline/Makefile b/c/inline/Makefile
new file mode 100644
index 0000000..4a1fb6e
--- /dev/null
+++ b/c/inline/Makefile
@@ -0,0 +1,20 @@
+all: inline.hex
+
+inline.o: inline.c
+ clang -target riscv32-none-elf -I../rvcontroller-libraries -march=rv32imacb_zicntr_zicond_zicsr_zifencei_zihintpause_zilsd_zclsd_zabha_zacas_zbkb_zbkx_zcb_zcmp_zcmt -ffreestanding -O3 -c -o inline.o inline.c
+
+inline.elf: ../rvcontroller-libraries/rvcontroller-init.o ../rvcontroller-libraries/rvcontroller-ecalls.o inline.o
+ clang -target riscv32-none-elf -T rvcontroller.ld -nostdlib -nostartfiles -Xlinker --no-warn-rwx-segments -o inline.elf ../rvcontroller-libraries/rvcontroller-init.o inline.o ../rvcontroller-libraries/rvcontroller-ecalls.o
+
+dump: inline.elf
+ riscv32-none-elf-objdump -d inline.elf
+
+inline.hex: inline.elf
+ riscv32-none-elf-objcopy -O ihex inline.elf inline.hex
+
+load: inline.hex
+ bash -c "wl-copy < inline.hex"
+
+clean:
+ rm -f inline.hex inline.elf inline.o init.o
+
diff --git a/c/inline/inline.c b/c/inline/inline.c
new file mode 100644
index 0000000..c8db8e3
--- /dev/null
+++ b/c/inline/inline.c
@@ -0,0 +1,25 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include "rvcontroller-ecalls.h"
+
+volatile char thischar;
+
+volatile uint32_t nonblocking_read() {
+ volatile uint32_t ret;
+ asm(
+ "li a7,132 \n\
+ ecall \n\
+ mv %0,a0 \n"
+ : "=r" (ret)
+ :
+ : "a0"
+ );
+ return ret;
+}
+
+void main() {
+ while (true) {
+ thischar = nonblocking_read();
+ //printint(thischar);
+ }
+}
diff --git a/c/inline/rvcontroller.ld b/c/inline/rvcontroller.ld
new file mode 100644
index 0000000..985892b
--- /dev/null
+++ b/c/inline/rvcontroller.ld
@@ -0,0 +1,45 @@
+/* Thanks https://github.com/darklife/darkriscv */
+ __heap_size = 0x200; /* required amount of heap */
+ __stack_size = 0x800; /* required amount of stack */
+ ENTRY(_start);
+ MEMORY
+ {
+ RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 0x10000
+ }
+ SECTIONS
+ {
+ .text :
+ {
+ *(.text.startup)
+ *(.text)
+ *(.text)
+ *(.rodata*)
+ } > RAM
+ .data :
+ {
+ *(.sbss)
+ *(.data)
+ *(.bss)
+ *(.rela*)
+ *(COMMON)
+ } > RAM
+
+ .heap :
+ {
+ . = ALIGN(4);
+ PROVIDE ( end = . );
+ _sheap = .;
+ . = . + __heap_size;
+ . = ALIGN(4);
+ _eheap = .;
+ } >RAM
+
+ .stack :
+ {
+ . = ALIGN(4);
+ _estack = .;
+ . = . + __stack_size;
+ . = ALIGN(4);
+ _sstack = .;
+ } >RAM
+ }
diff --git a/doc/csr.txt b/doc/csr.txt
index fdd7939..3eae14f 100644
--- a/doc/csr.txt
+++ b/doc/csr.txt
@@ -69,18 +69,19 @@ while some of the platform-use bits have been assigned to additional interrupts.
0x304 - mie (Machine Interrupt-Enable)
- 31 18 17 16 15 8 7 6 0
+ 31 19 18 17 16 15 8 7 6 0
+---------------------------------------------------------------------+
-| Reserved |MDIE|MMIE| Reserved |MTIE| Reserved |
+| Reserved |MCIE|MDIE|MMIE| Reserved |MTIE| Reserved |
+---------------------------------------------------------------------+
0x344 - mie (Machine Interrupt-Pending)
- 31 18 17 16 15 8 7 6 0
+ 31 19 18 17 16 15 8 7 6 0
+---------------------------------------------------------------------+
-| Reserved |MDIP|MMIP| Reserved |MTIP| Reserved |
+| Reserved |MCIE|MDIP|MMIP| Reserved |MTIP| Reserved |
+---------------------------------------------------------------------+
* MTIE/MTIP: Machine Timer Interrupt (see RISC-V Machine-Level ISA documentation)
* MMIE/MMIP: Machine Mesecons Interrupt - Becomes pending when a mesecons input changes state and remains pending until manually set to 0
* MDIE/MDIP: Machine Digilines Interrupt - Becomes pending when a digilines message is received and remains pending until manually set to 0
+* MCIE/MCIP: Machine Console Interrupt - Becomes pending when a character is received on standard input and remains pending until manually set to 0
diff --git a/rvcontroller.lua b/rvcontroller.lua
index 13e4c24..1b787da 100644
--- a/rvcontroller.lua
+++ b/rvcontroller.lua
@@ -36,20 +36,25 @@ local traptypes = {
[0x12] = "Software check",
[0x13] = "Hardware error",
--0x14-0x80000000 = reserved/custom
- [0x8000001] = "Supv soft interrupt",
+ [0x80000001] = "Supv soft interrupt",
--0x80000002 = reserved
- [0x8000003] = "Mach soft interrupt",
+ [0x80000003] = "Mach soft interrupt",
--0x80000004 = reserved
- [0x8000005] = "Supv timer interrupt",
+ [0x80000005] = "Supv timer interrupt",
--0x80000006 = reserved
- [0x8000007] = "Mach timer interrupt",
+ [0x80000007] = "Mach timer interrupt",
--0x80000008 = reserved
- [0x8000009] = "Supv ext interrupt",
+ [0x80000009] = "Supv ext interrupt",
--0x8000000a = reserved
- [0x800000b] = "Mach ext interrupt",
+ [0x8000000b] = "Mach ext interrupt",
--0x8000000c = reserved
- [0x800000d] = "Count over interrupt",
- --0x8000000e-0xffffffff = reserved/platform
+ [0x8000000d] = "Count over interrupt",
+ --0x8000000e = reserved
+ --0x8000000f = reserved
+ [0x80000010] = "Mach mesec interrupt",
+ [0x80000011] = "Mach dglne interrupt",
+ [0x80000012] = "Mach cons interrupt",
+ --0x80000013-0xffffffff = reserved/platform
}
local fault --non-nil values are for deferred faults that will trap after the instruction finishes
@@ -709,7 +714,7 @@ local function checkinterrupts()
end
mem.csr[0x344] = implodebits(mipbits,32)
if not mem.mie then return end
- local order = {11,3,7,9,1,5,13,16,17}
+ local order = {11,3,7,9,1,5,13,16,17,18}
for _,i in ipairs(order) do
if miebits[i] and mipbits[i] then
return trap(0x80000000+i)
@@ -3293,6 +3298,16 @@ elseif event.channel == "stdin" then
else
--No blocking read in progress, buffer the data for nonblocking reads later
mem.inputbuf = string.sub(mem.inputbuf..event.msg,1,256)
+ local mipbits = explodebits(mem.csr[0x344],32)
+ mipbits[18] = true
+ mem.csr[0x344] = implodebits(mipbits,32)
+ local miebits = explodebits(mem.csr[0x304],32)
+ if miebits[18] and mem.interruptwaiting then
+ mem.interruptwaiting = false
+ mem.running = true
+ digiline_send("monitordisp","CPU started")
+ interrupt(1/CLOCK_SPEED,"tick")
+ end
end
elseif event.channel == "load" then
if event.msg.done then