aboutsummaryrefslogtreecommitdiff
path: root/VexRiscv/src/main/c/emulator
diff options
context:
space:
mode:
Diffstat (limited to 'VexRiscv/src/main/c/emulator')
-rw-r--r--VexRiscv/src/main/c/emulator/.gitignore6
-rw-r--r--VexRiscv/src/main/c/emulator/build/emulator.asm620
-rwxr-xr-xVexRiscv/src/main/c/emulator/build/emulator.binbin0 -> 2440 bytes
-rwxr-xr-xVexRiscv/src/main/c/emulator/makefile29
-rw-r--r--VexRiscv/src/main/c/emulator/src/config.h12
-rw-r--r--VexRiscv/src/main/c/emulator/src/hal.c203
-rw-r--r--VexRiscv/src/main/c/emulator/src/hal.h25
-rwxr-xr-xVexRiscv/src/main/c/emulator/src/main.c288
-rw-r--r--VexRiscv/src/main/c/emulator/src/riscv.h133
-rwxr-xr-xVexRiscv/src/main/c/emulator/src/start.S51
-rw-r--r--VexRiscv/src/main/c/emulator/src/trap.S71
-rw-r--r--VexRiscv/src/main/c/emulator/src/utils.S47
12 files changed, 1485 insertions, 0 deletions
diff --git a/VexRiscv/src/main/c/emulator/.gitignore b/VexRiscv/src/main/c/emulator/.gitignore
new file mode 100644
index 0000000..a7caa3b
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/.gitignore
@@ -0,0 +1,6 @@
+*.map
+*.v
+*.elf
+*.o
+*.hex
+!*.bin \ No newline at end of file
diff --git a/VexRiscv/src/main/c/emulator/build/emulator.asm b/VexRiscv/src/main/c/emulator/build/emulator.asm
new file mode 100644
index 0000000..5e5dfe2
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/build/emulator.asm
@@ -0,0 +1,620 @@
+
+build/emulator.elf: file format elf32-littleriscv
+
+
+Disassembly of section .init:
+
+80000000 <_start>:
+80000000: 00001117 auipc sp,0x1
+80000004: 18810113 addi sp,sp,392 # 80001188 <_sp>
+80000008: 00001517 auipc a0,0x1
+8000000c: 8dc50513 addi a0,a0,-1828 # 800008e4 <__init_array_end>
+80000010: 00001597 auipc a1,0x1
+80000014: 8d458593 addi a1,a1,-1836 # 800008e4 <__init_array_end>
+80000018: 00001617 auipc a2,0x1
+8000001c: 97060613 addi a2,a2,-1680 # 80000988 <__bss_start>
+80000020: 00c5fc63 bgeu a1,a2,80000038 <_start+0x38>
+80000024: 00052283 lw t0,0(a0)
+80000028: 0055a023 sw t0,0(a1)
+8000002c: 00450513 addi a0,a0,4
+80000030: 00458593 addi a1,a1,4
+80000034: fec5e8e3 bltu a1,a2,80000024 <_start+0x24>
+80000038: 00001517 auipc a0,0x1
+8000003c: 95050513 addi a0,a0,-1712 # 80000988 <__bss_start>
+80000040: 00001597 auipc a1,0x1
+80000044: 94858593 addi a1,a1,-1720 # 80000988 <__bss_start>
+80000048: 00b57863 bgeu a0,a1,80000058 <_start+0x58>
+8000004c: 00052023 sw zero,0(a0)
+80000050: 00450513 addi a0,a0,4
+80000054: feb56ce3 bltu a0,a1,8000004c <_start+0x4c>
+80000058: 7e4000ef jal ra,8000083c <__libc_init_array>
+8000005c: 178000ef jal ra,800001d4 <init>
+80000060: 00000097 auipc ra,0x0
+80000064: 01408093 addi ra,ra,20 # 80000074 <done>
+80000068: 00000513 li a0,0
+8000006c: c30005b7 lui a1,0xc3000
+80000070: 30200073 mret
+
+80000074 <done>:
+80000074: 0000006f j 80000074 <done>
+
+80000078 <_init>:
+80000078: 00008067 ret
+
+8000007c <trapEntry>:
+8000007c: 34011173 csrrw sp,mscratch,sp
+80000080: 00112223 sw ra,4(sp)
+80000084: 00312623 sw gp,12(sp)
+80000088: 00412823 sw tp,16(sp)
+8000008c: 00512a23 sw t0,20(sp)
+80000090: 00612c23 sw t1,24(sp)
+80000094: 00712e23 sw t2,28(sp)
+80000098: 02812023 sw s0,32(sp)
+8000009c: 02912223 sw s1,36(sp)
+800000a0: 02a12423 sw a0,40(sp)
+800000a4: 02b12623 sw a1,44(sp)
+800000a8: 02c12823 sw a2,48(sp)
+800000ac: 02d12a23 sw a3,52(sp)
+800000b0: 02e12c23 sw a4,56(sp)
+800000b4: 02f12e23 sw a5,60(sp)
+800000b8: 05012023 sw a6,64(sp)
+800000bc: 05112223 sw a7,68(sp)
+800000c0: 05212423 sw s2,72(sp)
+800000c4: 05312623 sw s3,76(sp)
+800000c8: 05412823 sw s4,80(sp)
+800000cc: 05512a23 sw s5,84(sp)
+800000d0: 05612c23 sw s6,88(sp)
+800000d4: 05712e23 sw s7,92(sp)
+800000d8: 07812023 sw s8,96(sp)
+800000dc: 07912223 sw s9,100(sp)
+800000e0: 07a12423 sw s10,104(sp)
+800000e4: 07b12623 sw s11,108(sp)
+800000e8: 07c12823 sw t3,112(sp)
+800000ec: 07d12a23 sw t4,116(sp)
+800000f0: 07e12c23 sw t5,120(sp)
+800000f4: 07f12e23 sw t6,124(sp)
+800000f8: 2c4000ef jal ra,800003bc <trap>
+800000fc: 00412083 lw ra,4(sp)
+80000100: 00c12183 lw gp,12(sp)
+80000104: 01012203 lw tp,16(sp)
+80000108: 01412283 lw t0,20(sp)
+8000010c: 01812303 lw t1,24(sp)
+80000110: 01c12383 lw t2,28(sp)
+80000114: 02012403 lw s0,32(sp)
+80000118: 02412483 lw s1,36(sp)
+8000011c: 02812503 lw a0,40(sp)
+80000120: 02c12583 lw a1,44(sp)
+80000124: 03012603 lw a2,48(sp)
+80000128: 03412683 lw a3,52(sp)
+8000012c: 03812703 lw a4,56(sp)
+80000130: 03c12783 lw a5,60(sp)
+80000134: 04012803 lw a6,64(sp)
+80000138: 04412883 lw a7,68(sp)
+8000013c: 04812903 lw s2,72(sp)
+80000140: 04c12983 lw s3,76(sp)
+80000144: 05012a03 lw s4,80(sp)
+80000148: 05412a83 lw s5,84(sp)
+8000014c: 05812b03 lw s6,88(sp)
+80000150: 05c12b83 lw s7,92(sp)
+80000154: 06012c03 lw s8,96(sp)
+80000158: 06412c83 lw s9,100(sp)
+8000015c: 06812d03 lw s10,104(sp)
+80000160: 06c12d83 lw s11,108(sp)
+80000164: 07012e03 lw t3,112(sp)
+80000168: 07412e83 lw t4,116(sp)
+8000016c: 07812f03 lw t5,120(sp)
+80000170: 07c12f83 lw t6,124(sp)
+80000174: 34011173 csrrw sp,mscratch,sp
+80000178: 30200073 mret
+
+Disassembly of section .text:
+
+8000017c <putString>:
+8000017c: ff010113 addi sp,sp,-16
+80000180: 00812423 sw s0,8(sp)
+80000184: 00112623 sw ra,12(sp)
+80000188: 00050413 mv s0,a0
+8000018c: 00054503 lbu a0,0(a0)
+80000190: 00050a63 beqz a0,800001a4 <putString+0x28>
+80000194: 00140413 addi s0,s0,1
+80000198: 668000ef jal ra,80000800 <putC>
+8000019c: 00044503 lbu a0,0(s0)
+800001a0: fe051ae3 bnez a0,80000194 <putString+0x18>
+800001a4: 00c12083 lw ra,12(sp)
+800001a8: 00812403 lw s0,8(sp)
+800001ac: 01010113 addi sp,sp,16
+800001b0: 00008067 ret
+
+800001b4 <setup_pmp>:
+800001b4: 01f00793 li a5,31
+800001b8: fff00713 li a4,-1
+800001bc: 00000297 auipc t0,0x0
+800001c0: 01428293 addi t0,t0,20 # 800001d0 <setup_pmp+0x1c>
+800001c4: 30529073 csrw mtvec,t0
+800001c8: 3b071073 csrw pmpaddr0,a4
+800001cc: 3a079073 csrw pmpcfg0,a5
+800001d0: 00008067 ret
+
+800001d4 <init>:
+800001d4: ff010113 addi sp,sp,-16
+800001d8: 00112623 sw ra,12(sp)
+800001dc: 00812423 sw s0,8(sp)
+800001e0: 01f00793 li a5,31
+800001e4: fff00713 li a4,-1
+800001e8: 00000297 auipc t0,0x0
+800001ec: 01428293 addi t0,t0,20 # 800001fc <init+0x28>
+800001f0: 30529073 csrw mtvec,t0
+800001f4: 3b071073 csrw pmpaddr0,a4
+800001f8: 3a079073 csrw pmpcfg0,a5
+800001fc: 80001437 lui s0,0x80001
+80000200: 638000ef jal ra,80000838 <halInit>
+80000204: 95840413 addi s0,s0,-1704 # 80000958 <_sp+0xfffff7d0>
+80000208: 02a00513 li a0,42
+8000020c: 00140413 addi s0,s0,1
+80000210: 5f0000ef jal ra,80000800 <putC>
+80000214: 00044503 lbu a0,0(s0)
+80000218: fe051ae3 bnez a0,8000020c <init+0x38>
+8000021c: 800007b7 lui a5,0x80000
+80000220: 07c78793 addi a5,a5,124 # 8000007c <_sp+0xffffeef4>
+80000224: 30579073 csrw mtvec,a5
+80000228: 800017b7 lui a5,0x80001
+8000022c: 10878793 addi a5,a5,264 # 80001108 <_sp+0xffffff80>
+80000230: 34079073 csrw mscratch,a5
+80000234: 000017b7 lui a5,0x1
+80000238: 88078793 addi a5,a5,-1920 # 880 <__stack_size+0x80>
+8000023c: 30079073 csrw mstatus,a5
+80000240: 30405073 csrwi mie,0
+80000244: c00007b7 lui a5,0xc0000
+80000248: 34179073 csrw mepc,a5
+8000024c: 0000b7b7 lui a5,0xb
+80000250: 10078793 addi a5,a5,256 # b100 <__stack_size+0xa900>
+80000254: 30279073 csrw medeleg,a5
+80000258: 22200793 li a5,546
+8000025c: 30379073 csrw mideleg,a5
+80000260: 14305073 csrwi stval,0
+80000264: 80001437 lui s0,0x80001
+80000268: 97040413 addi s0,s0,-1680 # 80000970 <_sp+0xfffff7e8>
+8000026c: 02a00513 li a0,42
+80000270: 00140413 addi s0,s0,1
+80000274: 58c000ef jal ra,80000800 <putC>
+80000278: 00044503 lbu a0,0(s0)
+8000027c: fe051ae3 bnez a0,80000270 <init+0x9c>
+80000280: 00c12083 lw ra,12(sp)
+80000284: 00812403 lw s0,8(sp)
+80000288: 01010113 addi sp,sp,16
+8000028c: 00008067 ret
+
+80000290 <readRegister>:
+80000290: 800017b7 lui a5,0x80001
+80000294: 10878793 addi a5,a5,264 # 80001108 <_sp+0xffffff80>
+80000298: 00251513 slli a0,a0,0x2
+8000029c: 00f50533 add a0,a0,a5
+800002a0: 00052503 lw a0,0(a0)
+800002a4: 00008067 ret
+
+800002a8 <writeRegister>:
+800002a8: 800017b7 lui a5,0x80001
+800002ac: 00251513 slli a0,a0,0x2
+800002b0: 10878793 addi a5,a5,264 # 80001108 <_sp+0xffffff80>
+800002b4: 00f50533 add a0,a0,a5
+800002b8: 00b52023 sw a1,0(a0)
+800002bc: 00008067 ret
+
+800002c0 <redirectTrap>:
+800002c0: ff010113 addi sp,sp,-16
+800002c4: 00112623 sw ra,12(sp)
+800002c8: 530000ef jal ra,800007f8 <stopSim>
+800002cc: 343027f3 csrr a5,mtval
+800002d0: 14379073 csrw stval,a5
+800002d4: 341027f3 csrr a5,mepc
+800002d8: 14179073 csrw sepc,a5
+800002dc: 342027f3 csrr a5,mcause
+800002e0: 14279073 csrw scause,a5
+800002e4: 105027f3 csrr a5,stvec
+800002e8: 34179073 csrw mepc,a5
+800002ec: 00c12083 lw ra,12(sp)
+800002f0: 01010113 addi sp,sp,16
+800002f4: 00008067 ret
+
+800002f8 <emulationTrapToSupervisorTrap>:
+800002f8: 800007b7 lui a5,0x80000
+800002fc: 07c78793 addi a5,a5,124 # 8000007c <_sp+0xffffeef4>
+80000300: 30579073 csrw mtvec,a5
+80000304: 343027f3 csrr a5,mtval
+80000308: 14379073 csrw stval,a5
+8000030c: 342027f3 csrr a5,mcause
+80000310: 14279073 csrw scause,a5
+80000314: 14151073 csrw sepc,a0
+80000318: 105027f3 csrr a5,stvec
+8000031c: 34179073 csrw mepc,a5
+80000320: 0035d793 srli a5,a1,0x3
+80000324: 00459713 slli a4,a1,0x4
+80000328: 02077713 andi a4,a4,32
+8000032c: 1007f793 andi a5,a5,256
+80000330: 00e7e7b3 or a5,a5,a4
+80000334: ffffe737 lui a4,0xffffe
+80000338: 6dd70713 addi a4,a4,1757 # ffffe6dd <_sp+0x7fffd555>
+8000033c: 00e5f5b3 and a1,a1,a4
+80000340: 00b7e7b3 or a5,a5,a1
+80000344: 000015b7 lui a1,0x1
+80000348: 88058593 addi a1,a1,-1920 # 880 <__stack_size+0x80>
+8000034c: 00b7e7b3 or a5,a5,a1
+80000350: 30079073 csrw mstatus,a5
+80000354: 00008067 ret
+
+80000358 <readWord>:
+80000358: 00020737 lui a4,0x20
+8000035c: 30072073 csrs mstatus,a4
+80000360: 00000717 auipc a4,0x0
+80000364: 01870713 addi a4,a4,24 # 80000378 <readWord+0x20>
+80000368: 30571073 csrw mtvec,a4
+8000036c: 00100693 li a3,1
+80000370: 00052783 lw a5,0(a0)
+80000374: 00000693 li a3,0
+80000378: 00020737 lui a4,0x20
+8000037c: 30073073 csrc mstatus,a4
+80000380: 00068513 mv a0,a3
+80000384: 00f5a023 sw a5,0(a1)
+80000388: 00008067 ret
+
+8000038c <writeWord>:
+8000038c: 00020737 lui a4,0x20
+80000390: 30072073 csrs mstatus,a4
+80000394: 00000717 auipc a4,0x0
+80000398: 01870713 addi a4,a4,24 # 800003ac <writeWord+0x20>
+8000039c: 30571073 csrw mtvec,a4
+800003a0: 00100793 li a5,1
+800003a4: 00b52023 sw a1,0(a0)
+800003a8: 00000793 li a5,0
+800003ac: 00020737 lui a4,0x20
+800003b0: 30073073 csrc mstatus,a4
+800003b4: 00078513 mv a0,a5
+800003b8: 00008067 ret
+
+800003bc <trap>:
+800003bc: fe010113 addi sp,sp,-32
+800003c0: 00112e23 sw ra,28(sp)
+800003c4: 00812c23 sw s0,24(sp)
+800003c8: 00912a23 sw s1,20(sp)
+800003cc: 01212823 sw s2,16(sp)
+800003d0: 01312623 sw s3,12(sp)
+800003d4: 342027f3 csrr a5,mcause
+800003d8: 0807cc63 bltz a5,80000470 <trap+0xb4>
+800003dc: 00200713 li a4,2
+800003e0: 0ce78463 beq a5,a4,800004a8 <trap+0xec>
+800003e4: 00900693 li a3,9
+800003e8: 04d79463 bne a5,a3,80000430 <trap+0x74>
+800003ec: 80001437 lui s0,0x80001
+800003f0: 18840413 addi s0,s0,392 # 80001188 <_sp+0x0>
+800003f4: fc442783 lw a5,-60(s0)
+800003f8: 00100693 li a3,1
+800003fc: fa842503 lw a0,-88(s0)
+80000400: 2ed78463 beq a5,a3,800006e8 <trap+0x32c>
+80000404: 2ee78e63 beq a5,a4,80000700 <trap+0x344>
+80000408: 2a078c63 beqz a5,800006c0 <trap+0x304>
+8000040c: 01812403 lw s0,24(sp)
+80000410: 01c12083 lw ra,28(sp)
+80000414: 01412483 lw s1,20(sp)
+80000418: 01012903 lw s2,16(sp)
+8000041c: 00c12983 lw s3,12(sp)
+80000420: 02010113 addi sp,sp,32
+80000424: 3d40006f j 800007f8 <stopSim>
+80000428: 00777713 andi a4,a4,7
+8000042c: 12f70c63 beq a4,a5,80000564 <trap+0x1a8>
+80000430: 3c8000ef jal ra,800007f8 <stopSim>
+80000434: 343027f3 csrr a5,mtval
+80000438: 14379073 csrw stval,a5
+8000043c: 341027f3 csrr a5,mepc
+80000440: 14179073 csrw sepc,a5
+80000444: 342027f3 csrr a5,mcause
+80000448: 14279073 csrw scause,a5
+8000044c: 105027f3 csrr a5,stvec
+80000450: 34179073 csrw mepc,a5
+80000454: 01c12083 lw ra,28(sp)
+80000458: 01812403 lw s0,24(sp)
+8000045c: 01412483 lw s1,20(sp)
+80000460: 01012903 lw s2,16(sp)
+80000464: 00c12983 lw s3,12(sp)
+80000468: 02010113 addi sp,sp,32
+8000046c: 00008067 ret
+80000470: 0ff7f793 andi a5,a5,255
+80000474: 00700713 li a4,7
+80000478: fae79ce3 bne a5,a4,80000430 <trap+0x74>
+8000047c: 02000793 li a5,32
+80000480: 1447a073 csrs sip,a5
+80000484: 08000793 li a5,128
+80000488: 3047b073 csrc mie,a5
+8000048c: 01c12083 lw ra,28(sp)
+80000490: 01812403 lw s0,24(sp)
+80000494: 01412483 lw s1,20(sp)
+80000498: 01012903 lw s2,16(sp)
+8000049c: 00c12983 lw s3,12(sp)
+800004a0: 02010113 addi sp,sp,32
+800004a4: 00008067 ret
+800004a8: 341024f3 csrr s1,mepc
+800004ac: 300025f3 csrr a1,mstatus
+800004b0: 34302473 csrr s0,mtval
+800004b4: 02f00613 li a2,47
+800004b8: 07f47693 andi a3,s0,127
+800004bc: 00c45713 srli a4,s0,0xc
+800004c0: f6c684e3 beq a3,a2,80000428 <trap+0x6c>
+800004c4: 07300613 li a2,115
+800004c8: f6c694e3 bne a3,a2,80000430 <trap+0x74>
+800004cc: 00377713 andi a4,a4,3
+800004d0: 10f70c63 beq a4,a5,800005e8 <trap+0x22c>
+800004d4: 00300793 li a5,3
+800004d8: 10f70863 beq a4,a5,800005e8 <trap+0x22c>
+800004dc: 00100993 li s3,1
+800004e0: 03370463 beq a4,s3,80000508 <trap+0x14c>
+800004e4: 314000ef jal ra,800007f8 <stopSim>
+800004e8: 343027f3 csrr a5,mtval
+800004ec: 14379073 csrw stval,a5
+800004f0: 341027f3 csrr a5,mepc
+800004f4: 14179073 csrw sepc,a5
+800004f8: 342027f3 csrr a5,mcause
+800004fc: 14279073 csrw scause,a5
+80000500: 105027f3 csrr a5,stvec
+80000504: 34179073 csrw mepc,a5
+80000508: 00001737 lui a4,0x1
+8000050c: 01445793 srli a5,s0,0x14
+80000510: c0070693 addi a3,a4,-1024 # c00 <__stack_size+0x400>
+80000514: 0ed7e263 bltu a5,a3,800005f8 <trap+0x23c>
+80000518: c0270713 addi a4,a4,-1022
+8000051c: 0cf77063 bgeu a4,a5,800005dc <trap+0x220>
+80000520: fffff737 lui a4,0xfffff
+80000524: 38070713 addi a4,a4,896 # fffff380 <_sp+0x7fffe1f8>
+80000528: 00e787b3 add a5,a5,a4
+8000052c: 00200713 li a4,2
+80000530: 0cf76463 bltu a4,a5,800005f8 <trap+0x23c>
+80000534: 2e4000ef jal ra,80000818 <rdtimeh>
+80000538: 00050913 mv s2,a0
+8000053c: 1c099e63 bnez s3,80000718 <trap+0x35c>
+80000540: 00545413 srli s0,s0,0x5
+80000544: 800017b7 lui a5,0x80001
+80000548: 10878793 addi a5,a5,264 # 80001108 <_sp+0xffffff80>
+8000054c: 07c47413 andi s0,s0,124
+80000550: 00f40433 add s0,s0,a5
+80000554: 01242023 sw s2,0(s0)
+80000558: 00448493 addi s1,s1,4
+8000055c: 34149073 csrw mepc,s1
+80000560: ef5ff06f j 80000454 <trap+0x98>
+80000564: 00d45713 srli a4,s0,0xd
+80000568: 01245793 srli a5,s0,0x12
+8000056c: 800016b7 lui a3,0x80001
+80000570: 10868693 addi a3,a3,264 # 80001108 <_sp+0xffffff80>
+80000574: 07c77713 andi a4,a4,124
+80000578: 07c7f793 andi a5,a5,124
+8000057c: 00d70733 add a4,a4,a3
+80000580: 00d787b3 add a5,a5,a3
+80000584: 00072703 lw a4,0(a4)
+80000588: 0007a603 lw a2,0(a5)
+8000058c: 00020537 lui a0,0x20
+80000590: 30052073 csrs mstatus,a0
+80000594: 00000517 auipc a0,0x0
+80000598: 01850513 addi a0,a0,24 # 800005ac <trap+0x1f0>
+8000059c: 30551073 csrw mtvec,a0
+800005a0: 00100793 li a5,1
+800005a4: 00072803 lw a6,0(a4)
+800005a8: 00000793 li a5,0
+800005ac: 00020537 lui a0,0x20
+800005b0: 30053073 csrc mstatus,a0
+800005b4: 18079663 bnez a5,80000740 <trap+0x384>
+800005b8: 01b45793 srli a5,s0,0x1b
+800005bc: 01c00513 li a0,28
+800005c0: e6f568e3 bltu a0,a5,80000430 <trap+0x74>
+800005c4: 80001537 lui a0,0x80001
+800005c8: 00279793 slli a5,a5,0x2
+800005cc: 8e450513 addi a0,a0,-1820 # 800008e4 <_sp+0xfffff75c>
+800005d0: 00a787b3 add a5,a5,a0
+800005d4: 0007a783 lw a5,0(a5)
+800005d8: 00078067 jr a5
+800005dc: 234000ef jal ra,80000810 <rdtime>
+800005e0: 00050913 mv s2,a0
+800005e4: f59ff06f j 8000053c <trap+0x180>
+800005e8: 00f45993 srli s3,s0,0xf
+800005ec: 01f9f993 andi s3,s3,31
+800005f0: 013039b3 snez s3,s3
+800005f4: f15ff06f j 80000508 <trap+0x14c>
+800005f8: 200000ef jal ra,800007f8 <stopSim>
+800005fc: 343027f3 csrr a5,mtval
+80000600: 14379073 csrw stval,a5
+80000604: 341027f3 csrr a5,mepc
+80000608: 14179073 csrw sepc,a5
+8000060c: 342027f3 csrr a5,mcause
+80000610: 14279073 csrw scause,a5
+80000614: 105027f3 csrr a5,stvec
+80000618: 34179073 csrw mepc,a5
+8000061c: f21ff06f j 8000053c <trap+0x180>
+80000620: 01067463 bgeu a2,a6,80000628 <trap+0x26c>
+80000624: 00080613 mv a2,a6
+80000628: 00020537 lui a0,0x20
+8000062c: 30052073 csrs mstatus,a0
+80000630: 00000517 auipc a0,0x0
+80000634: 01850513 addi a0,a0,24 # 80000648 <trap+0x28c>
+80000638: 30551073 csrw mtvec,a0
+8000063c: 00100793 li a5,1
+80000640: 00c72023 sw a2,0(a4)
+80000644: 00000793 li a5,0
+80000648: 00020537 lui a0,0x20
+8000064c: 30053073 csrc mstatus,a0
+80000650: 80000737 lui a4,0x80000
+80000654: 07c70713 addi a4,a4,124 # 8000007c <_sp+0xffffeef4>
+80000658: 14079463 bnez a5,800007a0 <trap+0x3e4>
+8000065c: 00545793 srli a5,s0,0x5
+80000660: 07c7f793 andi a5,a5,124
+80000664: 00d786b3 add a3,a5,a3
+80000668: 0106a023 sw a6,0(a3)
+8000066c: 00448493 addi s1,s1,4
+80000670: 34149073 csrw mepc,s1
+80000674: 30571073 csrw mtvec,a4
+80000678: dddff06f j 80000454 <trap+0x98>
+8000067c: 01064633 xor a2,a2,a6
+80000680: fa9ff06f j 80000628 <trap+0x26c>
+80000684: fac872e3 bgeu a6,a2,80000628 <trap+0x26c>
+80000688: 00080613 mv a2,a6
+8000068c: f9dff06f j 80000628 <trap+0x26c>
+80000690: f9065ce3 bge a2,a6,80000628 <trap+0x26c>
+80000694: 00080613 mv a2,a6
+80000698: f91ff06f j 80000628 <trap+0x26c>
+8000069c: f8c856e3 bge a6,a2,80000628 <trap+0x26c>
+800006a0: 00080613 mv a2,a6
+800006a4: f85ff06f j 80000628 <trap+0x26c>
+800006a8: 01067633 and a2,a2,a6
+800006ac: f7dff06f j 80000628 <trap+0x26c>
+800006b0: 01066633 or a2,a2,a6
+800006b4: f75ff06f j 80000628 <trap+0x26c>
+800006b8: 01060633 add a2,a2,a6
+800006bc: f6dff06f j 80000628 <trap+0x26c>
+800006c0: fac42583 lw a1,-84(s0)
+800006c4: 15c000ef jal ra,80000820 <setMachineTimerCmp>
+800006c8: 08000793 li a5,128
+800006cc: 3047a073 csrs mie,a5
+800006d0: 02000793 li a5,32
+800006d4: 1447b073 csrc sip,a5
+800006d8: 341027f3 csrr a5,mepc
+800006dc: 00478793 addi a5,a5,4
+800006e0: 34179073 csrw mepc,a5
+800006e4: d71ff06f j 80000454 <trap+0x98>
+800006e8: 0ff57513 andi a0,a0,255
+800006ec: 114000ef jal ra,80000800 <putC>
+800006f0: 341027f3 csrr a5,mepc
+800006f4: 00478793 addi a5,a5,4
+800006f8: 34179073 csrw mepc,a5
+800006fc: d59ff06f j 80000454 <trap+0x98>
+80000700: 108000ef jal ra,80000808 <getC>
+80000704: faa42423 sw a0,-88(s0)
+80000708: 341027f3 csrr a5,mepc
+8000070c: 00478793 addi a5,a5,4
+80000710: 34179073 csrw mepc,a5
+80000714: d41ff06f j 80000454 <trap+0x98>
+80000718: 0e0000ef jal ra,800007f8 <stopSim>
+8000071c: 343027f3 csrr a5,mtval
+80000720: 14379073 csrw stval,a5
+80000724: 341027f3 csrr a5,mepc
+80000728: 14179073 csrw sepc,a5
+8000072c: 342027f3 csrr a5,mcause
+80000730: 14279073 csrw scause,a5
+80000734: 105027f3 csrr a5,stvec
+80000738: 34179073 csrw mepc,a5
+8000073c: e05ff06f j 80000540 <trap+0x184>
+80000740: 800007b7 lui a5,0x80000
+80000744: 07c78793 addi a5,a5,124 # 8000007c <_sp+0xffffeef4>
+80000748: 30579073 csrw mtvec,a5
+8000074c: 343027f3 csrr a5,mtval
+80000750: 14379073 csrw stval,a5
+80000754: 342027f3 csrr a5,mcause
+80000758: 14279073 csrw scause,a5
+8000075c: 14149073 csrw sepc,s1
+80000760: 105027f3 csrr a5,stvec
+80000764: 34179073 csrw mepc,a5
+80000768: 0035d793 srli a5,a1,0x3
+8000076c: 00459713 slli a4,a1,0x4
+80000770: 02077713 andi a4,a4,32
+80000774: 1007f793 andi a5,a5,256
+80000778: 00e7e7b3 or a5,a5,a4
+8000077c: ffffe737 lui a4,0xffffe
+80000780: 6dd70713 addi a4,a4,1757 # ffffe6dd <_sp+0x7fffd555>
+80000784: 00e5f5b3 and a1,a1,a4
+80000788: 00001737 lui a4,0x1
+8000078c: 00b7e7b3 or a5,a5,a1
+80000790: 88070713 addi a4,a4,-1920 # 880 <__stack_size+0x80>
+80000794: 00e7e7b3 or a5,a5,a4
+80000798: 30079073 csrw mstatus,a5
+8000079c: cb9ff06f j 80000454 <trap+0x98>
+800007a0: 30571073 csrw mtvec,a4
+800007a4: 343027f3 csrr a5,mtval
+800007a8: 14379073 csrw stval,a5
+800007ac: 342027f3 csrr a5,mcause
+800007b0: 14279073 csrw scause,a5
+800007b4: 14149073 csrw sepc,s1
+800007b8: 105027f3 csrr a5,stvec
+800007bc: 34179073 csrw mepc,a5
+800007c0: 0035d793 srli a5,a1,0x3
+800007c4: 00459713 slli a4,a1,0x4
+800007c8: 02077713 andi a4,a4,32
+800007cc: 1007f793 andi a5,a5,256
+800007d0: 00e7e7b3 or a5,a5,a4
+800007d4: ffffe737 lui a4,0xffffe
+800007d8: 6dd70713 addi a4,a4,1757 # ffffe6dd <_sp+0x7fffd555>
+800007dc: 00e5f5b3 and a1,a1,a4
+800007e0: 00b7e5b3 or a1,a5,a1
+800007e4: 000017b7 lui a5,0x1
+800007e8: 88078793 addi a5,a5,-1920 # 880 <__stack_size+0x80>
+800007ec: 00f5e7b3 or a5,a1,a5
+800007f0: 30079073 csrw mstatus,a5
+800007f4: c61ff06f j 80000454 <trap+0x98>
+
+800007f8 <stopSim>:
+800007f8: fe002e23 sw zero,-4(zero) # fffffffc <_sp+0x7fffee74>
+800007fc: 0000006f j 800007fc <stopSim+0x4>
+
+80000800 <putC>:
+80000800: fea02c23 sw a0,-8(zero) # fffffff8 <_sp+0x7fffee70>
+80000804: 00008067 ret
+
+80000808 <getC>:
+80000808: ff802503 lw a0,-8(zero) # fffffff8 <_sp+0x7fffee70>
+8000080c: 00008067 ret
+
+80000810 <rdtime>:
+80000810: fe002503 lw a0,-32(zero) # ffffffe0 <_sp+0x7fffee58>
+80000814: 00008067 ret
+
+80000818 <rdtimeh>:
+80000818: fe402503 lw a0,-28(zero) # ffffffe4 <_sp+0x7fffee5c>
+8000081c: 00008067 ret
+
+80000820 <setMachineTimerCmp>:
+80000820: fec00793 li a5,-20
+80000824: fff00713 li a4,-1
+80000828: 00e7a023 sw a4,0(a5)
+8000082c: fea02423 sw a0,-24(zero) # ffffffe8 <_sp+0x7fffee60>
+80000830: 00b7a023 sw a1,0(a5)
+80000834: 00008067 ret
+
+80000838 <halInit>:
+80000838: 00008067 ret
+
+8000083c <__libc_init_array>:
+8000083c: ff010113 addi sp,sp,-16
+80000840: 00000797 auipc a5,0x0
+80000844: 0a478793 addi a5,a5,164 # 800008e4 <__init_array_end>
+80000848: 00812423 sw s0,8(sp)
+8000084c: 00000417 auipc s0,0x0
+80000850: 09840413 addi s0,s0,152 # 800008e4 <__init_array_end>
+80000854: 40f40433 sub s0,s0,a5
+80000858: 00912223 sw s1,4(sp)
+8000085c: 01212023 sw s2,0(sp)
+80000860: 00112623 sw ra,12(sp)
+80000864: 40245413 srai s0,s0,0x2
+80000868: 00000493 li s1,0
+8000086c: 00078913 mv s2,a5
+80000870: 04849263 bne s1,s0,800008b4 <__libc_init_array+0x78>
+80000874: 805ff0ef jal ra,80000078 <_init>
+80000878: 00000797 auipc a5,0x0
+8000087c: 06c78793 addi a5,a5,108 # 800008e4 <__init_array_end>
+80000880: 00000417 auipc s0,0x0
+80000884: 06440413 addi s0,s0,100 # 800008e4 <__init_array_end>
+80000888: 40f40433 sub s0,s0,a5
+8000088c: 40245413 srai s0,s0,0x2
+80000890: 00000493 li s1,0
+80000894: 00078913 mv s2,a5
+80000898: 02849a63 bne s1,s0,800008cc <__libc_init_array+0x90>
+8000089c: 00c12083 lw ra,12(sp)
+800008a0: 00812403 lw s0,8(sp)
+800008a4: 00412483 lw s1,4(sp)
+800008a8: 00012903 lw s2,0(sp)
+800008ac: 01010113 addi sp,sp,16
+800008b0: 00008067 ret
+800008b4: 00249793 slli a5,s1,0x2
+800008b8: 00f907b3 add a5,s2,a5
+800008bc: 0007a783 lw a5,0(a5)
+800008c0: 00148493 addi s1,s1,1
+800008c4: 000780e7 jalr a5
+800008c8: fa9ff06f j 80000870 <__libc_init_array+0x34>
+800008cc: 00249793 slli a5,s1,0x2
+800008d0: 00f907b3 add a5,s2,a5
+800008d4: 0007a783 lw a5,0(a5)
+800008d8: 00148493 addi s1,s1,1
+800008dc: 000780e7 jalr a5
+800008e0: fb9ff06f j 80000898 <__libc_init_array+0x5c>
diff --git a/VexRiscv/src/main/c/emulator/build/emulator.bin b/VexRiscv/src/main/c/emulator/build/emulator.bin
new file mode 100755
index 0000000..83e0a0d
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/build/emulator.bin
Binary files differ
diff --git a/VexRiscv/src/main/c/emulator/makefile b/VexRiscv/src/main/c/emulator/makefile
new file mode 100755
index 0000000..6f3c8fc
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/makefile
@@ -0,0 +1,29 @@
+PROJ_NAME=emulator
+DEBUG=no
+MULDIV=no
+COMPRESSED=no
+STANDALONE = ..
+
+
+SRCS = $(wildcard src/*.c) \
+ $(wildcard src/*.cpp) \
+ $(wildcard src/*.S)
+
+
+LDSCRIPT = ${STANDALONE}/common/ram.ld
+
+sim: CFLAGS += -DSIM
+sim: all
+
+qemu: CFLAGS += -DQEMU
+qemu: all
+
+litex: CFLAGS += -DLITEX -I${LITEX_GENERATED} -I${LITEX_BASE}/litex/soc/software/include
+litex: | check_litex all
+check_litex:
+ @[ "${LITEX_BASE}" ] || ( echo ">> LITEX_BASE is not set"; exit 1 )
+ @[ "${LITEX_GENERATED}" ] || ( echo ">> LITEX_GENERATED is not set"; exit 1 )
+
+include ${STANDALONE}/common/riscv64-unknown-elf.mk
+include ${STANDALONE}/common/standalone.mk
+
diff --git a/VexRiscv/src/main/c/emulator/src/config.h b/VexRiscv/src/main/c/emulator/src/config.h
new file mode 100644
index 0000000..afce2d5
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/src/config.h
@@ -0,0 +1,12 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#ifndef OS_CALL
+#define OS_CALL 0xC0000000
+#endif
+
+#ifndef DTB
+#define DTB 0xC3000000
+#endif
+
+#endif
diff --git a/VexRiscv/src/main/c/emulator/src/hal.c b/VexRiscv/src/main/c/emulator/src/hal.c
new file mode 100644
index 0000000..aa6745b
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/src/hal.c
@@ -0,0 +1,203 @@
+#include "hal.h"
+#include "config.h"
+
+#ifdef SIM
+void stopSim(){
+ *((volatile uint32_t*) 0xFFFFFFFC) = 0;
+ while(1);
+}
+
+void putC(char c){
+ *((volatile uint32_t*) 0xFFFFFFF8) = c;
+}
+
+int32_t getC(){
+ return *((volatile int32_t*) 0xFFFFFFF8);
+}
+
+uint32_t rdtime(){
+ return *((volatile uint32_t*) 0xFFFFFFE0);
+}
+
+uint32_t rdtimeh(){
+ return *((volatile uint32_t*) 0xFFFFFFE4);
+}
+
+void setMachineTimerCmp(uint32_t low, uint32_t high){
+ volatile uint32_t* base = (volatile uint32_t*) 0xFFFFFFE8;
+ base[1] = 0xffffffff;
+ base[0] = low;
+ base[1] = high;
+}
+
+
+void halInit(){
+// putC('*');
+// putC('*');
+// putC('*');
+// while(1){
+// int32_t c = getC();
+// if(c > 0) putC(c);
+// }
+}
+#endif
+
+#ifdef QEMU
+#define VIRT_CLINT 0x2000000
+#define SIFIVE_TIMECMP_BASE (VIRT_CLINT + 0x4000)
+#define SIFIVE_TIME_BASE (VIRT_CLINT + 0xBFF8)
+#define NS16550A_UART0_CTRL_ADDR 0x10000000
+#define UART0_CLOCK_FREQ 32000000
+#define UART0_BAUD_RATE 115200
+enum {
+ UART_RBR = 0x00, /* Receive Buffer Register */
+ UART_THR = 0x00, /* Transmit Hold Register */
+ UART_IER = 0x01, /* Interrupt Enable Register */
+ UART_DLL = 0x00, /* Divisor LSB (LCR_DLAB) */
+ UART_DLM = 0x01, /* Divisor MSB (LCR_DLAB) */
+ UART_FCR = 0x02, /* FIFO Control Register */
+ UART_LCR = 0x03, /* Line Control Register */
+ UART_MCR = 0x04, /* Modem Control Register */
+ UART_LSR = 0x05, /* Line Status Register */
+ UART_MSR = 0x06, /* Modem Status Register */
+ UART_SCR = 0x07, /* Scratch Register */
+
+ UART_LCR_DLAB = 0x80, /* Divisor Latch Bit */
+ UART_LCR_8BIT = 0x03, /* 8-bit */
+ UART_LCR_PODD = 0x08, /* Parity Odd */
+
+ UART_LSR_DA = 0x01, /* Data Available */
+ UART_LSR_OE = 0x02, /* Overrun Error */
+ UART_LSR_PE = 0x04, /* Parity Error */
+ UART_LSR_FE = 0x08, /* Framing Error */
+ UART_LSR_BI = 0x10, /* Break indicator */
+ UART_LSR_RE = 0x20, /* THR is empty */
+ UART_LSR_RI = 0x40, /* THR is empty and line is idle */
+ UART_LSR_EF = 0x80, /* Erroneous data in FIFO */
+};
+
+static volatile uint8_t *uart;
+
+static void ns16550a_init()
+{
+ uart = (uint8_t *)(void *)(NS16550A_UART0_CTRL_ADDR);
+ uint32_t uart_freq = (UART0_CLOCK_FREQ);
+ uint32_t baud_rate = (UART0_BAUD_RATE);
+ uint32_t divisor = uart_freq / (16 * baud_rate);
+ uart[UART_LCR] = UART_LCR_DLAB;
+ uart[UART_DLL] = divisor & 0xff;
+ uart[UART_DLM] = (divisor >> 8) & 0xff;
+ uart[UART_LCR] = UART_LCR_PODD | UART_LCR_8BIT;
+}
+
+//static int ns16550a_getchar()
+//{
+// if (uart[UART_LSR] & UART_LSR_DA) {
+// return uart[UART_RBR];
+// } else {
+// return -1;
+// }
+//}
+//
+//static int ns16550a_putchar(int ch)
+//{
+// while ((uart[UART_LSR] & UART_LSR_RI) == 0);
+// return uart[UART_THR] = ch & 0xff;
+//}
+
+void stopSim(){
+ while(1);
+}
+
+void putC(char ch){
+ while ((uart[UART_LSR] & UART_LSR_RI) == 0);
+ uart[UART_THR] = ch & 0xff;
+}
+
+int32_t getC(){
+ if (uart[UART_LSR] & UART_LSR_DA) {
+ return uart[UART_RBR];
+ } else {
+ return -1;
+ }
+}
+
+
+uint32_t rdtime(){
+ return *((volatile uint32_t*) SIFIVE_TIME_BASE);
+}
+
+uint32_t rdtimeh(){
+ return *((volatile uint32_t*) (SIFIVE_TIME_BASE + 4));
+}
+
+void setMachineTimerCmp(uint32_t low, uint32_t high){
+ volatile uint32_t* base = (volatile uint32_t*) SIFIVE_TIMECMP_BASE;
+ base[1] = 0xffffffff;
+ base[0] = low;
+ base[1] = high;
+}
+
+void halInit(){
+ ns16550a_init();
+}
+#endif
+
+
+#ifdef LITEX
+
+// this is a file generated by LiteX
+#include <generated/csr.h>
+
+#if !defined(CSR_UART_BASE) || !defined(CSR_CPU_BASE)
+ #error LiteX configuration with uart and cpu_timer is required.
+#endif
+
+void stopSim(){
+ while(1);
+}
+
+void putC(char ch){
+ // protect against writing to a full tx fifo
+ while(uart_txfull_read());
+ uart_rxtx_write(ch);
+}
+
+int32_t getC(){
+ if(uart_rxempty_read())
+ {
+ return -1;
+ }
+
+ // this is required to refresh rexempty status
+ uart_ev_pending_write(1 << 1);
+ return uart_rxtx_read();
+}
+
+uint32_t rdtime(){
+ cpu_timer_latch_write(0);
+ uint32_t result = (uint32_t)cpu_timer_time_read();
+ cpu_timer_latch_write(1);
+ return result;
+}
+
+uint32_t rdtimeh(){
+ cpu_timer_latch_write(0);
+ uint32_t result = (uint32_t)(cpu_timer_time_read() >> 32);
+ cpu_timer_latch_write(1);
+ return result;
+}
+
+void setMachineTimerCmp(uint32_t low, uint32_t high){
+ cpu_timer_latch_write(0);
+ cpu_timer_time_cmp_write((((unsigned long long int)high) << 32) | low);
+ cpu_timer_latch_write(1);
+}
+
+void halInit(){
+ cpu_timer_latch_write(1);
+}
+
+#endif
+
+
diff --git a/VexRiscv/src/main/c/emulator/src/hal.h b/VexRiscv/src/main/c/emulator/src/hal.h
new file mode 100644
index 0000000..8b4e1c2
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/src/hal.h
@@ -0,0 +1,25 @@
+
+#ifndef HAL_H
+#define HAL_H
+
+#include <stdint.h>
+
+#define SBI_SET_TIMER 0
+#define SBI_CONSOLE_PUTCHAR 1
+#define SBI_CONSOLE_GETCHAR 2
+#define SBI_CLEAR_IPI 3
+#define SBI_SEND_IPI 4
+#define SBI_REMOTE_FENCE_I 5
+#define SBI_REMOTE_SFENCE_VMA 6
+#define SBI_REMOTE_SFENCE_VMA_ASID 7
+#define SBI_SHUTDOWN 8
+
+void halInit();
+void stopSim();
+void putC(char c);
+int32_t getC();
+uint32_t rdtime();
+uint32_t rdtimeh();
+void setMachineTimerCmp(uint32_t low, uint32_t high);
+
+#endif
diff --git a/VexRiscv/src/main/c/emulator/src/main.c b/VexRiscv/src/main/c/emulator/src/main.c
new file mode 100755
index 0000000..dc12fb8
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/src/main.c
@@ -0,0 +1,288 @@
+#include <stdint.h>
+#include "riscv.h"
+#include "config.h"
+#include "hal.h"
+
+extern const uint32_t _sp;
+extern void trapEntry();
+extern void emulationTrap();
+
+void putString(char* s){
+ while(*s){
+ putC(*s);
+ s++;
+ }
+}
+
+//Affect mtvec
+void setup_pmp(void)
+{
+ // Set up a PMP to permit access to all of memory.
+ // Ignore the illegal-instruction trap if PMPs aren't supported.
+ uintptr_t pmpc = PMP_NAPOT | PMP_R | PMP_W | PMP_X;
+ asm volatile ("la t0, 1f\n\t"
+ "csrw mtvec, t0\n\t"
+ "csrw pmpaddr0, %1\n\t"
+ "csrw pmpcfg0, %0\n\t"
+ ".align 2\n\t"
+ "1:"
+ : : "r" (pmpc), "r" (-1UL) : "t0");
+}
+
+void init() {
+ setup_pmp();
+ halInit();
+ putString("*** VexRiscv BIOS ***\n");
+ uint32_t sp = (uint32_t) (&_sp);
+ csr_write(mtvec, trapEntry);
+ csr_write(mscratch, sp -32*4);
+ csr_write(mstatus, 0x0800 | MSTATUS_MPIE);
+ csr_write(mie, 0);
+ csr_write(mepc, OS_CALL);
+ //In future it would probably need to manage missaligned stuff, now it will stop the simulation
+ csr_write(medeleg, MEDELEG_INSTRUCTION_PAGE_FAULT | MEDELEG_LOAD_PAGE_FAULT | MEDELEG_STORE_PAGE_FAULT | MEDELEG_USER_ENVIRONNEMENT_CALL);
+ csr_write(mideleg, MIDELEG_SUPERVISOR_TIMER | MIDELEG_SUPERVISOR_EXTERNAL | MIDELEG_SUPERVISOR_SOFTWARE);
+ csr_write(sbadaddr, 0); //Used to avoid simulation missmatch
+
+ putString("*** Supervisor ***\n");
+}
+
+int readRegister(uint32_t id){
+ unsigned int sp = (unsigned int) (&_sp);
+ return ((int*) sp)[id-32];
+}
+void writeRegister(uint32_t id, int value){
+ uint32_t sp = (uint32_t) (&_sp);
+ ((uint32_t*) sp)[id-32] = value;
+}
+
+
+//Currently, this should not happen, unless kernel things are going wrong
+void redirectTrap(){
+ stopSim();
+ csr_write(sbadaddr, csr_read(mbadaddr));
+ csr_write(sepc, csr_read(mepc));
+ csr_write(scause, csr_read(mcause));
+ csr_write(mepc, csr_read(stvec));
+}
+
+void emulationTrapToSupervisorTrap(uint32_t sepc, uint32_t mstatus){
+ csr_write(mtvec, trapEntry);
+ csr_write(sbadaddr, csr_read(mbadaddr));
+ csr_write(scause, csr_read(mcause));
+ csr_write(sepc, sepc);
+ csr_write(mepc, csr_read(stvec));
+ csr_write(mstatus,
+ (mstatus & ~(MSTATUS_SPP | MSTATUS_MPP | MSTATUS_SIE | MSTATUS_SPIE))
+ | ((mstatus >> 3) & MSTATUS_SPP)
+ | (0x0800 | MSTATUS_MPIE)
+ | ((mstatus & MSTATUS_SIE) << 4)
+ );
+}
+
+#define max(a,b) \
+ ({ __typeof__ (a) _a = (a); \
+ __typeof__ (b) _b = (b); \
+ _a > _b ? _a : _b; })
+
+
+#define min(a,b) \
+ ({ __typeof__ (a) _a = (a); \
+ __typeof__ (b) _b = (b); \
+ _a < _b ? _a : _b; })
+
+
+
+//Will modify MTVEC
+int32_t readWord(uint32_t address, int32_t *data){
+ int32_t result, tmp;
+ int32_t failed;
+ __asm__ __volatile__ (
+ " li %[tmp], 0x00020000\n"
+ " csrs mstatus, %[tmp]\n"
+ " la %[tmp], 1f\n"
+ " csrw mtvec, %[tmp]\n"
+ " li %[failed], 1\n"
+ " lw %[result], 0(%[address])\n"
+ " li %[failed], 0\n"
+ "1:\n"
+ " li %[tmp], 0x00020000\n"
+ " csrc mstatus, %[tmp]\n"
+ : [result]"=&r" (result), [failed]"=&r" (failed), [tmp]"=&r" (tmp)
+ : [address]"r" (address)
+ : "memory"
+ );
+
+ *data = result;
+ return failed;
+}
+
+//Will modify MTVEC
+int32_t writeWord(uint32_t address, int32_t data){
+ int32_t result, tmp;
+ int32_t failed;
+ __asm__ __volatile__ (
+ " li %[tmp], 0x00020000\n"
+ " csrs mstatus, %[tmp]\n"
+ " la %[tmp], 1f\n"
+ " csrw mtvec, %[tmp]\n"
+ " li %[failed], 1\n"
+ " sw %[data], 0(%[address])\n"
+ " li %[failed], 0\n"
+ "1:\n"
+ " li %[tmp], 0x00020000\n"
+ " csrc mstatus, %[tmp]\n"
+ : [failed]"=&r" (failed), [tmp]"=&r" (tmp)
+ : [address]"r" (address), [data]"r" (data)
+ : "memory"
+ );
+
+ return failed;
+}
+
+
+
+
+void trap(){
+ int32_t cause = csr_read(mcause);
+ if(cause < 0){ //interrupt
+ switch(cause & 0xFF){
+ case CAUSE_MACHINE_TIMER:{
+ csr_set(sip, MIP_STIP);
+ csr_clear(mie, MIE_MTIE);
+ }break;
+ default: redirectTrap(); break;
+ }
+ } else { //exception
+ switch(cause){
+ case CAUSE_ILLEGAL_INSTRUCTION:{
+ uint32_t mepc = csr_read(mepc);
+ uint32_t mstatus = csr_read(mstatus);
+#ifdef SIM
+ uint32_t instruction = csr_read(mbadaddr);
+#endif
+#if defined(QEMU) || defined(LITEX)
+ uint32_t instruction = 0;
+ uint32_t i;
+ if (mepc & 2) {
+ readWord(mepc - 2, &i);
+ i >>= 16;
+ if (i & 3 == 3) {
+ uint32_t u32Buf;
+ readWord(mepc+2, &u32Buf);
+ i |= u32Buf << 16;
+ }
+ } else {
+ readWord(mepc, &i);
+ }
+ instruction = i;
+ csr_write(mtvec, trapEntry); //Restore mtvec
+#endif
+
+ uint32_t opcode = instruction & 0x7F;
+ uint32_t funct3 = (instruction >> 12) & 0x7;
+ switch(opcode){
+ case 0x2F: //Atomic
+ switch(funct3){
+ case 0x2:{
+ uint32_t sel = instruction >> 27;
+ uint32_t addr = readRegister((instruction >> 15) & 0x1F);
+ int32_t src = readRegister((instruction >> 20) & 0x1F);
+ uint32_t rd = (instruction >> 7) & 0x1F;
+ int32_t readValue;
+ if(readWord(addr, &readValue)){
+ emulationTrapToSupervisorTrap(mepc, mstatus);
+ return;
+ }
+ int writeValue;
+ switch(sel){
+ case 0x0: writeValue = src + readValue; break;
+ case 0x1: writeValue = src; break;
+//LR SC done in hardware (cheap), and require to keep track of context switches
+// case 0x2:{ //LR
+// }break;
+// case 0x3:{ //SC
+// }break;
+ case 0x4: writeValue = src ^ readValue; break;
+ case 0xC: writeValue = src & readValue; break;
+ case 0x8: writeValue = src | readValue; break;
+ case 0x10: writeValue = min(src, readValue); break;
+ case 0x14: writeValue = max(src, readValue); break;
+ case 0x18: writeValue = min((unsigned int)src, (unsigned int)readValue); break;
+ case 0x1C: writeValue = max((unsigned int)src, (unsigned int)readValue); break;
+ default: redirectTrap(); return; break;
+ }
+ if(writeWord(addr, writeValue)){
+ emulationTrapToSupervisorTrap(mepc, mstatus);
+ return;
+ }
+ writeRegister(rd, readValue);
+ csr_write(mepc, mepc + 4);
+ csr_write(mtvec, trapEntry); //Restore mtvec
+ }break;
+ default: redirectTrap(); break;
+ } break;
+ case 0x73:{
+ //CSR
+ uint32_t input = (instruction & 0x4000) ? ((instruction >> 15) & 0x1F) : readRegister((instruction >> 15) & 0x1F);;
+ uint32_t clear, set;
+ uint32_t write;
+ switch (funct3 & 0x3) {
+ case 0: redirectTrap(); break;
+ case 1: clear = ~0; set = input; write = 1; break;
+ case 2: clear = 0; set = input; write = ((instruction >> 15) & 0x1F) != 0; break;
+ case 3: clear = input; set = 0; write = ((instruction >> 15) & 0x1F) != 0; break;
+ }
+ uint32_t csrAddress = instruction >> 20;
+ uint32_t old;
+ switch(csrAddress){
+ case RDCYCLE :
+ case RDINSTRET:
+ case RDTIME : old = rdtime(); break;
+ case RDCYCLEH :
+ case RDINSTRETH:
+ case RDTIMEH : old = rdtimeh(); break;
+ default: redirectTrap(); break;
+ }
+ if(write) {
+ uint32_t newValue = (old & ~clear) | set;
+ switch(csrAddress){
+ default: redirectTrap(); break;
+ }
+ }
+
+ writeRegister((instruction >> 7) & 0x1F, old);
+ csr_write(mepc, mepc + 4);
+
+ }break;
+ default: redirectTrap(); break;
+ }
+ }break;
+ case CAUSE_SCALL:{
+ uint32_t which = readRegister(17);
+ uint32_t a0 = readRegister(10);
+ uint32_t a1 = readRegister(11);
+ uint32_t a2 = readRegister(12);
+ switch(which){
+ case SBI_CONSOLE_PUTCHAR:{
+ putC(a0);
+ csr_write(mepc, csr_read(mepc) + 4);
+ }break;
+ case SBI_CONSOLE_GETCHAR:{
+ writeRegister(10, getC()); //no char
+ csr_write(mepc, csr_read(mepc) + 4);
+ }break;
+ case SBI_SET_TIMER:{
+ setMachineTimerCmp(a0, a1);
+ csr_set(mie, MIE_MTIE);
+ csr_clear(sip, MIP_STIP);
+ csr_write(mepc, csr_read(mepc) + 4);
+ }break;
+ default: stopSim(); break;
+ }
+ }break;
+ default: redirectTrap(); break;
+ }
+ }
+
+}
diff --git a/VexRiscv/src/main/c/emulator/src/riscv.h b/VexRiscv/src/main/c/emulator/src/riscv.h
new file mode 100644
index 0000000..488b172
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/src/riscv.h
@@ -0,0 +1,133 @@
+#ifndef RISCV_H
+#define RISCV_H
+
+#define CAUSE_ILLEGAL_INSTRUCTION 2
+#define CAUSE_MACHINE_TIMER 7
+#define CAUSE_SCALL 9
+
+#define MEDELEG_INSTRUCTION_PAGE_FAULT (1 << 12)
+#define MEDELEG_LOAD_PAGE_FAULT (1 << 13)
+#define MEDELEG_STORE_PAGE_FAULT (1 << 15)
+#define MEDELEG_USER_ENVIRONNEMENT_CALL (1 << 8)
+#define MIDELEG_SUPERVISOR_SOFTWARE (1 << 1)
+#define MIDELEG_SUPERVISOR_TIMER (1 << 5)
+#define MIDELEG_SUPERVISOR_EXTERNAL (1 << 9)
+
+#define MIE_MTIE (1 << 7)
+#define MIP_STIP (1 << 5)
+
+#define MSTATUS_UIE 0x00000001
+#define MSTATUS_SIE 0x00000002
+#define MSTATUS_HIE 0x00000004
+#define MSTATUS_MIE 0x00000008
+#define MSTATUS_UPIE 0x00000010
+#define MSTATUS_SPIE 0x00000020
+#define MSTATUS_HPIE 0x00000040
+#define MSTATUS_MPIE 0x00000080
+#define MSTATUS_SPP 0x00000100
+#define MSTATUS_HPP 0x00000600
+#define MSTATUS_MPP 0x00001800
+#define MSTATUS_FS 0x00006000
+#define MSTATUS_XS 0x00018000
+#define MSTATUS_MPRV 0x00020000
+#define MSTATUS_SUM 0x00040000
+#define MSTATUS_MXR 0x00080000
+#define MSTATUS_TVM 0x00100000
+#define MSTATUS_TW 0x00200000
+#define MSTATUS_TSR 0x00400000
+#define MSTATUS32_SD 0x80000000
+#define MSTATUS_UXL 0x0000000300000000
+#define MSTATUS_SXL 0x0000000C00000000
+#define MSTATUS64_SD 0x8000000000000000
+
+#define SSTATUS_UIE 0x00000001
+#define SSTATUS_SIE 0x00000002
+#define SSTATUS_UPIE 0x00000010
+#define SSTATUS_SPIE 0x00000020
+#define SSTATUS_SPP 0x00000100
+#define SSTATUS_FS 0x00006000
+#define SSTATUS_XS 0x00018000
+#define SSTATUS_SUM 0x00040000
+#define SSTATUS_MXR 0x00080000
+#define SSTATUS32_SD 0x80000000
+#define SSTATUS_UXL 0x0000000300000000
+#define SSTATUS64_SD 0x8000000000000000
+
+
+#define PMP_R 0x01
+#define PMP_W 0x02
+#define PMP_X 0x04
+#define PMP_A 0x18
+#define PMP_L 0x80
+#define PMP_SHIFT 2
+
+#define PMP_TOR 0x08
+#define PMP_NA4 0x10
+#define PMP_NAPOT 0x18
+
+#define RDCYCLE 0xC00 //Read-only cycle Cycle counter for RDCYCLE instruction.
+#define RDTIME 0xC01 //Read-only time Timer for RDTIME instruction.
+#define RDINSTRET 0xC02 //Read-only instret Instructions-retired counter for RDINSTRET instruction.
+#define RDCYCLEH 0xC80 //Read-only cycleh Upper 32 bits of cycle, RV32I only.
+#define RDTIMEH 0xC81 //Read-only timeh Upper 32 bits of time, RV32I only.
+#define RDINSTRETH 0xC82 //Read-only instreth Upper 32 bits of instret, RV32I only.
+
+
+#define csr_swap(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrw %0, " #csr ", %1" \
+ : "=r" (__v) : "rK" (__v)); \
+ __v; \
+})
+
+#define csr_read(csr) \
+({ \
+ register unsigned long __v; \
+ __asm__ __volatile__ ("csrr %0, " #csr \
+ : "=r" (__v)); \
+ __v; \
+})
+
+#define csr_write(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrw " #csr ", %0" \
+ : : "rK" (__v)); \
+})
+
+#define csr_read_set(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrs %0, " #csr ", %1" \
+ : "=r" (__v) : "rK" (__v)); \
+ __v; \
+})
+
+#define csr_set(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrs " #csr ", %0" \
+ : : "rK" (__v)); \
+})
+
+#define csr_read_clear(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrc %0, " #csr ", %1" \
+ : "=r" (__v) : "rK" (__v)); \
+ __v; \
+})
+
+#define csr_clear(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrc " #csr ", %0" \
+ : : "rK" (__v)); \
+})
+
+
+
+#endif
+
+
diff --git a/VexRiscv/src/main/c/emulator/src/start.S b/VexRiscv/src/main/c/emulator/src/start.S
new file mode 100755
index 0000000..af7fafe
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/src/start.S
@@ -0,0 +1,51 @@
+ .section .init
+ .globl _start
+ .type _start,@function
+
+#include "config.h"
+_start:
+/*#ifdef USE_GP
+.option push
+.option norelax
+ la gp, __global_pointer$
+.option pop
+#endif*/
+ la sp, _sp
+
+
+ /* Load data section */
+ la a0, _data_lma
+ la a1, _data
+ la a2, _edata
+ bgeu a1, a2, 2f
+1:
+ lw t0, (a0)
+ sw t0, (a1)
+ addi a0, a0, 4
+ addi a1, a1, 4
+ bltu a1, a2, 1b
+2:
+
+ /* Clear bss section */
+ la a0, __bss_start
+ la a1, _end
+ bgeu a0, a1, 2f
+1:
+ sw zero, (a0)
+ addi a0, a0, 4
+ bltu a0, a1, 1b
+2:
+
+ call __libc_init_array
+ call init
+ la ra, done
+ li a0, 0
+ li a1, DTB
+ mret
+done:
+ j done
+
+
+ .globl _init
+_init:
+ ret
diff --git a/VexRiscv/src/main/c/emulator/src/trap.S b/VexRiscv/src/main/c/emulator/src/trap.S
new file mode 100644
index 0000000..53af1a8
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/src/trap.S
@@ -0,0 +1,71 @@
+ .section .init
+ .globl trapEntry
+ .type trapEntry,@function
+
+trapEntry:
+ csrrw sp, mscratch, sp
+ sw x1, 1*4(sp)
+ sw x3, 3*4(sp)
+ sw x4, 4*4(sp)
+ sw x5, 5*4(sp)
+ sw x6, 6*4(sp)
+ sw x7, 7*4(sp)
+ sw x8, 8*4(sp)
+ sw x9, 9*4(sp)
+ sw x10, 10*4(sp)
+ sw x11, 11*4(sp)
+ sw x12, 12*4(sp)
+ sw x13, 13*4(sp)
+ sw x14, 14*4(sp)
+ sw x15, 15*4(sp)
+ sw x16, 16*4(sp)
+ sw x17, 17*4(sp)
+ sw x18, 18*4(sp)
+ sw x19, 19*4(sp)
+ sw x20, 20*4(sp)
+ sw x21, 21*4(sp)
+ sw x22, 22*4(sp)
+ sw x23, 23*4(sp)
+ sw x24, 24*4(sp)
+ sw x25, 25*4(sp)
+ sw x26, 26*4(sp)
+ sw x27, 27*4(sp)
+ sw x28, 28*4(sp)
+ sw x29, 29*4(sp)
+ sw x30, 30*4(sp)
+ sw x31, 31*4(sp)
+ call trap
+ lw x1, 1*4(sp)
+ lw x3, 3*4(sp)
+ lw x4, 4*4(sp)
+ lw x5, 5*4(sp)
+ lw x6, 6*4(sp)
+ lw x7, 7*4(sp)
+ lw x8, 8*4(sp)
+ lw x9, 9*4(sp)
+ lw x10, 10*4(sp)
+ lw x11, 11*4(sp)
+ lw x12, 12*4(sp)
+ lw x13, 13*4(sp)
+ lw x14, 14*4(sp)
+ lw x15, 15*4(sp)
+ lw x16, 16*4(sp)
+ lw x17, 17*4(sp)
+ lw x18, 18*4(sp)
+ lw x19, 19*4(sp)
+ lw x20, 20*4(sp)
+ lw x21, 21*4(sp)
+ lw x22, 22*4(sp)
+ lw x23, 23*4(sp)
+ lw x24, 24*4(sp)
+ lw x25, 25*4(sp)
+ lw x26, 26*4(sp)
+ lw x27, 27*4(sp)
+ lw x28, 28*4(sp)
+ lw x29, 29*4(sp)
+ lw x30, 30*4(sp)
+ lw x31, 31*4(sp)
+ csrrw sp, mscratch, sp
+ mret
+
+
diff --git a/VexRiscv/src/main/c/emulator/src/utils.S b/VexRiscv/src/main/c/emulator/src/utils.S
new file mode 100644
index 0000000..90c7b64
--- /dev/null
+++ b/VexRiscv/src/main/c/emulator/src/utils.S
@@ -0,0 +1,47 @@
+#include "riscv.h"
+/*
+
+ .section .init
+ .globl readMemory
+ .type readMemory,@function
+readWord:
+ csrr a4, mepc
+ li a2, MSTATUS_MPRV
+ csrs mstatus, a2
+ li a3, emulationTrap
+ csrw mepc, a3
+ lw a0, 0(a0)
+ li a3, trapEntry
+ csrw mepc, a3
+ csrc mstatus, a2
+
+writeWord:
+ csrr a4, mepc
+ li a2, MSTATUS_MPRV
+ csrs mstatus, a2
+ li a3, emulationTrap
+ csrw mepc, a3
+ sw a1, 0(a0)
+ li a3, trapEntry
+ csrw mepc, a3
+ csrc mstatus, a2
+*/
+//Redirect trap to supervisor
+/*
+ .section .init
+ .globl emulationTrap
+ .type emulationTrap,@function
+emulationTrap:
+ li a0, MSTATUS_MPRV
+ csrc mstatus, a0
+
+ la sp, _sp
+ csrw sepc, a4
+ csrr a0, mcause
+ csrw scause, a0
+ csrr a0, mbadaddr
+ csrw sbadaddr, a0
+
+ call init
+ mret
+*/