aboutsummaryrefslogtreecommitdiff
path: root/VexRiscv/src/main/c
diff options
context:
space:
mode:
Diffstat (limited to 'VexRiscv/src/main/c')
-rwxr-xr-xVexRiscv/src/main/c/common/ram.ld151
-rw-r--r--VexRiscv/src/main/c/common/riscv64-unknown-elf.mk16
-rw-r--r--VexRiscv/src/main/c/common/standalone.mk74
-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
-rw-r--r--VexRiscv/src/main/c/murax/hello_world/makefile134
-rw-r--r--VexRiscv/src/main/c/murax/hello_world/src/crt.S98
-rw-r--r--VexRiscv/src/main/c/murax/hello_world/src/gpio.h15
-rw-r--r--VexRiscv/src/main/c/murax/hello_world/src/interrupt.h17
-rw-r--r--VexRiscv/src/main/c/murax/hello_world/src/linker.ld110
-rw-r--r--VexRiscv/src/main/c/murax/hello_world/src/main.c42
-rw-r--r--VexRiscv/src/main/c/murax/hello_world/src/murax.h17
-rw-r--r--VexRiscv/src/main/c/murax/hello_world/src/prescaler.h16
-rw-r--r--VexRiscv/src/main/c/murax/hello_world/src/timer.h20
-rw-r--r--VexRiscv/src/main/c/murax/hello_world/src/uart.h42
-rw-r--r--VexRiscv/src/main/c/murax/xipBootloader/.gitignore5
-rw-r--r--VexRiscv/src/main/c/murax/xipBootloader/crt.S74
-rw-r--r--VexRiscv/src/main/c/murax/xipBootloader/demo.S27
-rw-r--r--VexRiscv/src/main/c/murax/xipBootloader/makefile37
-rw-r--r--VexRiscv/src/main/c/murax/xipBootloader/mapping.ld96
-rw-r--r--VexRiscv/src/main/c/murax/xipBootloader/mapping_rom.ld96
-rw-r--r--VexRiscv/src/main/c/murax/xipBootloader/mapping_xip.ld96
32 files changed, 2668 insertions, 0 deletions
diff --git a/VexRiscv/src/main/c/common/ram.ld b/VexRiscv/src/main/c/common/ram.ld
new file mode 100755
index 0000000..2ebf858
--- /dev/null
+++ b/VexRiscv/src/main/c/common/ram.ld
@@ -0,0 +1,151 @@
+OUTPUT_ARCH( "riscv" )
+
+ENTRY( _start )
+
+MEMORY
+{
+ ram : ORIGIN = DEFINED(__ram_origin) ? __ram_origin : 0x80000000, LENGTH = 64k
+}
+
+
+SECTIONS
+{
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
+
+ .init :
+ {
+ KEEP (*(SORT_NONE(.init)))
+ }> ram
+
+ .text :
+ {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ *(.note.gnu.build-id)
+ } > ram
+
+ .fini :
+ {
+ KEEP (*(SORT_NONE(.fini)))
+ } > ram
+
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+
+ . = ALIGN(4);
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } > ram
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } > ram
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } > ram
+
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ } > ram
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ } > ram
+
+ .lalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data_lma = . );
+ } > ram
+
+ .dalign :
+ {
+ . = ALIGN(4);
+ PROVIDE( _data = . );
+ } > ram
+
+ .data :
+ {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.*)
+ *(.gnu.linkonce.s.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } >ram
+
+ . = ALIGN(4);
+ PROVIDE( _edata = . );
+ PROVIDE( edata = . );
+
+ PROVIDE( _fbss = . );
+ PROVIDE( __bss_start = . );
+ .bss :
+ {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ } >ram
+
+ . = ALIGN(8);
+ PROVIDE( _end = . );
+ PROVIDE( end = . );
+
+ .stack :
+ {
+ PROVIDE( _heap_end = . );
+ . = __stack_size;
+ PROVIDE( _sp = . );
+ } > ram
+}
diff --git a/VexRiscv/src/main/c/common/riscv64-unknown-elf.mk b/VexRiscv/src/main/c/common/riscv64-unknown-elf.mk
new file mode 100644
index 0000000..e17a9d1
--- /dev/null
+++ b/VexRiscv/src/main/c/common/riscv64-unknown-elf.mk
@@ -0,0 +1,16 @@
+RISCV_BIN ?= riscv64-unknown-elf-
+RISCV_CC=${RISCV_BIN}gcc
+RISCV_OBJCOPY=${RISCV_BIN}objcopy
+RISCV_OBJDUMP=${RISCV_BIN}objdump
+
+MARCH := rv32i
+ifeq ($(MULDIV),yes)
+ MARCH := $(MARCH)M
+endif
+ifeq ($(COMPRESSED),yes)
+ MARCH := $(MARCH)AC
+endif
+
+CFLAGS += -march=$(MARCH) -mabi=ilp32 -DUSE_GP
+LDFLAGS += -march=$(MARCH) -mabi=ilp32
+
diff --git a/VexRiscv/src/main/c/common/standalone.mk b/VexRiscv/src/main/c/common/standalone.mk
new file mode 100644
index 0000000..88328a2
--- /dev/null
+++ b/VexRiscv/src/main/c/common/standalone.mk
@@ -0,0 +1,74 @@
+
+
+LDFLAGS += -lc
+
+CFLAGS += -I${STANDALONE}/include
+
+
+
+
+ifeq ($(DEBUG),yes)
+ CFLAGS += -g3 -Og
+endif
+
+ifeq ($(DEBUG),no)
+ CFLAGS += -O3
+endif
+
+
+LDFLAGS += -nostdlib -lgcc -nostartfiles -ffreestanding -Wl,-Bstatic,-T,$(LDSCRIPT),-Map,$(OBJDIR)/$(PROJ_NAME).map,--print-memory-usage
+
+
+
+OBJDIR ?= build
+OBJS := $(SRCS)
+OBJS := $(OBJS:.c=.o)
+OBJS := $(OBJS:.cpp=.o)
+OBJS := $(OBJS:.S=.o)
+OBJS := $(OBJS:..=miaou)
+OBJS := $(addprefix $(OBJDIR)/,$(OBJS))
+
+
+
+all: $(OBJDIR)/$(PROJ_NAME).elf $(OBJDIR)/$(PROJ_NAME).hex $(OBJDIR)/$(PROJ_NAME).asm $(OBJDIR)/$(PROJ_NAME).bin
+
+$(OBJDIR)/%.elf: $(OBJS) | $(OBJDIR)
+ $(RISCV_CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+%.hex: %.elf
+ $(RISCV_OBJCOPY) -O ihex $^ $@
+
+%.bin: %.elf
+ $(RISCV_OBJCOPY) -O binary $^ $@
+
+%.v: %.elf
+ $(RISCV_OBJCOPY) -O verilog $^ $@
+
+%.asm: %.elf
+ $(RISCV_OBJDUMP) -S -d $^ > $@
+
+$(OBJDIR)/%.o: %.c
+ mkdir -p $(dir $@)
+ $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
+
+$(OBJDIR)/%.o: %.cpp
+ mkdir -p $(dir $@)
+ $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
+
+$(OBJDIR)/%.o: %.S
+ mkdir -p $(dir $@)
+ $(RISCV_CC) -c $(CFLAGS) -o $@ $^ -D__ASSEMBLY__=1
+
+$(OBJDIR):
+ mkdir -p $@
+
+clean:
+ rm -f $(OBJDIR)/$(PROJ_NAME).elf
+ rm -f $(OBJDIR)/$(PROJ_NAME).hex
+ rm -f $(OBJDIR)/$(PROJ_NAME).map
+ rm -f $(OBJDIR)/$(PROJ_NAME).v
+ rm -f $(OBJDIR)/$(PROJ_NAME).bin
+ rm -f $(OBJDIR)/$(PROJ_NAME).asm
+ find $(OBJDIR) -type f -name '*.o' -print0 | xargs -0 -r rm
+
+.SECONDARY: $(OBJS) \ No newline at end of file
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
+*/
diff --git a/VexRiscv/src/main/c/murax/hello_world/makefile b/VexRiscv/src/main/c/murax/hello_world/makefile
new file mode 100644
index 0000000..dc560c0
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/hello_world/makefile
@@ -0,0 +1,134 @@
+PROJ_NAME=hello_world
+DEBUG=no
+BENCH=no
+MULDIV=no
+
+SRCS = $(wildcard src/*.c) \
+ $(wildcard src/*.cpp) \
+ $(wildcard src/*.S)
+
+OBJDIR = build
+
+INC =
+LIBS =
+LIBSINC = -L$(OBJDIR)
+LDSCRIPT = ./src/linker.ld
+
+#include ../../../resources/gcc.mk
+# Set it to yes if you are using the sifive precompiled GCC pack
+SIFIVE_GCC_PACK ?= yes
+
+ifeq ($(SIFIVE_GCC_PACK),yes)
+ RISCV_NAME ?= riscv64-unknown-elf
+ RISCV_PATH ?= /opt/riscv/
+else
+ RISCV_NAME ?= riscv32-unknown-elf
+ ifeq ($(MULDIV),yes)
+ RISCV_PATH ?= /opt/riscv32im/
+ else
+ RISCV_PATH ?= /opt/riscv32i/
+ endif
+endif
+
+MABI=ilp32
+MARCH := rv32i
+ifeq ($(MULDIV),yes)
+ MARCH := $(MARCH)m
+endif
+ifeq ($(COMPRESSED),yes)
+ MARCH := $(MARCH)ac
+endif
+
+CFLAGS += -march=$(MARCH) -mabi=$(MABI) -DNDEBUG
+LDFLAGS += -march=$(MARCH) -mabi=$(MABI)
+
+
+
+#include ../../../resources/subproject.mk
+
+
+ifeq ($(DEBUG),yes)
+ CFLAGS += -g3 -O0
+endif
+
+ifeq ($(DEBUG),no)
+ CFLAGS += -g -Os
+endif
+
+ifeq ($(BENCH),yes)
+ CFLAGS += -fno-inline
+endif
+
+ifeq ($(SIFIVE_GCC_PACK),yes)
+ RISCV_CLIB=$(RISCV_PATH)/$(RISCV_NAME)/lib/$(MARCH)/$(MABI)/
+else
+ RISCV_CLIB=$(RISCV_PATH)/$(RISCV_NAME)/lib/
+endif
+
+
+
+
+
+RISCV_OBJCOPY = $(RISCV_PATH)/bin/$(RISCV_NAME)-objcopy
+RISCV_OBJDUMP = $(RISCV_PATH)/bin/$(RISCV_NAME)-objdump
+RISCV_CC=$(RISCV_PATH)/bin/$(RISCV_NAME)-gcc
+
+CFLAGS += -MD -fstrict-volatile-bitfields -fno-strict-aliasing
+LDFLAGS += -nostdlib -lgcc -mcmodel=medany -nostartfiles -ffreestanding -Wl,-Bstatic,-T,$(LDSCRIPT),-Map,$(OBJDIR)/$(PROJ_NAME).map,--print-memory-usage
+#LDFLAGS += -lgcc -lc -lg -nostdlib -lgcc -msave-restore --strip-debug,
+
+OBJS := $(SRCS)
+OBJS := $(OBJS:.c=.o)
+OBJS := $(OBJS:.cpp=.o)
+OBJS := $(OBJS:.S=.o)
+OBJS := $(OBJS:..=miaou)
+OBJS := $(addprefix $(OBJDIR)/,$(OBJS))
+
+
+all: $(OBJDIR)/$(PROJ_NAME).elf $(OBJDIR)/$(PROJ_NAME).hex $(OBJDIR)/$(PROJ_NAME).asm $(OBJDIR)/$(PROJ_NAME).v
+
+$(OBJDIR)/%.elf: $(OBJS) | $(OBJDIR)
+ $(RISCV_CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBSINC) $(LIBS)
+
+%.hex: %.elf
+ $(RISCV_OBJCOPY) -O ihex $^ $@
+
+%.bin: %.elf
+ $(RISCV_OBJCOPY) -O binary $^ $@
+
+%.v: %.elf
+ $(RISCV_OBJCOPY) -O verilog $^ $@
+
+%.asm: %.elf
+ $(RISCV_OBJDUMP) -S -d $^ > $@
+
+$(OBJDIR)/%.o: %.c
+ mkdir -p $(dir $@)
+ $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
+ $(RISCV_CC) -S $(CFLAGS) $(INC) -o $@.disasm $^
+
+$(OBJDIR)/%.o: %.cpp
+ mkdir -p $(dir $@)
+ $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
+
+$(OBJDIR)/%.o: %.S
+ mkdir -p $(dir $@)
+ $(RISCV_CC) -c $(CFLAGS) -o $@ $^ -D__ASSEMBLY__=1
+
+$(OBJDIR):
+ mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -rf $(OBJDIR)/src
+ rm -f $(OBJDIR)/$(PROJ_NAME).elf
+ rm -f $(OBJDIR)/$(PROJ_NAME).hex
+ rm -f $(OBJDIR)/$(PROJ_NAME).map
+ rm -f $(OBJDIR)/$(PROJ_NAME).v
+ rm -f $(OBJDIR)/$(PROJ_NAME).asm
+ find $(OBJDIR) -type f -name '*.o' -print0 | xargs -0 -r rm
+ find $(OBJDIR) -type f -name '*.d' -print0 | xargs -0 -r rm
+
+clean-all : clean
+
+.SECONDARY: $(OBJS)
diff --git a/VexRiscv/src/main/c/murax/hello_world/src/crt.S b/VexRiscv/src/main/c/murax/hello_world/src/crt.S
new file mode 100644
index 0000000..62d67b9
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/hello_world/src/crt.S
@@ -0,0 +1,98 @@
+.global crtStart
+.global main
+.global irqCallback
+
+ .section .start_jump,"ax",@progbits
+crtStart:
+ //long jump to allow crtInit to be anywhere
+ //do it always in 12 bytes
+ lui x2, %hi(crtInit)
+ addi x2, x2, %lo(crtInit)
+ jalr x1,x2
+ nop
+
+.section .text
+
+.global trap_entry
+.align 5
+trap_entry:
+ sw x1, - 1*4(sp)
+ sw x5, - 2*4(sp)
+ sw x6, - 3*4(sp)
+ sw x7, - 4*4(sp)
+ sw x10, - 5*4(sp)
+ sw x11, - 6*4(sp)
+ sw x12, - 7*4(sp)
+ sw x13, - 8*4(sp)
+ sw x14, - 9*4(sp)
+ sw x15, -10*4(sp)
+ sw x16, -11*4(sp)
+ sw x17, -12*4(sp)
+ sw x28, -13*4(sp)
+ sw x29, -14*4(sp)
+ sw x30, -15*4(sp)
+ sw x31, -16*4(sp)
+ addi sp,sp,-16*4
+ call irqCallback
+ lw x1 , 15*4(sp)
+ lw x5, 14*4(sp)
+ lw x6, 13*4(sp)
+ lw x7, 12*4(sp)
+ lw x10, 11*4(sp)
+ lw x11, 10*4(sp)
+ lw x12, 9*4(sp)
+ lw x13, 8*4(sp)
+ lw x14, 7*4(sp)
+ lw x15, 6*4(sp)
+ lw x16, 5*4(sp)
+ lw x17, 4*4(sp)
+ lw x28, 3*4(sp)
+ lw x29, 2*4(sp)
+ lw x30, 1*4(sp)
+ lw x31, 0*4(sp)
+ addi sp,sp,16*4
+ mret
+ .text
+
+
+crtInit:
+ .option push
+ .option norelax
+ la gp, __global_pointer$
+ .option pop
+ la sp, _stack_start
+
+bss_init:
+ la a0, _bss_start
+ la a1, _bss_end
+bss_loop:
+ beq a0,a1,bss_done
+ sw zero,0(a0)
+ add a0,a0,4
+ j bss_loop
+bss_done:
+
+ctors_init:
+ la a0, _ctors_start
+ addi sp,sp,-4
+ctors_loop:
+ la a1, _ctors_end
+ beq a0,a1,ctors_done
+ lw a3,0(a0)
+ add a0,a0,4
+ sw a0,0(sp)
+ jalr a3
+ lw a0,0(sp)
+ j ctors_loop
+ctors_done:
+ addi sp,sp,4
+
+
+ li a0, 0x880 //880 enable timer + external interrupts
+ csrw mie,a0
+ li a0, 0x1808 //1808 enable interrupts
+ csrw mstatus,a0
+
+ call main
+infinitLoop:
+ j infinitLoop
diff --git a/VexRiscv/src/main/c/murax/hello_world/src/gpio.h b/VexRiscv/src/main/c/murax/hello_world/src/gpio.h
new file mode 100644
index 0000000..34348fe
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/hello_world/src/gpio.h
@@ -0,0 +1,15 @@
+#ifndef GPIO_H_
+#define GPIO_H_
+
+
+typedef struct
+{
+ volatile uint32_t INPUT;
+ volatile uint32_t OUTPUT;
+ volatile uint32_t OUTPUT_ENABLE;
+} Gpio_Reg;
+
+
+#endif /* GPIO_H_ */
+
+
diff --git a/VexRiscv/src/main/c/murax/hello_world/src/interrupt.h b/VexRiscv/src/main/c/murax/hello_world/src/interrupt.h
new file mode 100644
index 0000000..23b7d27
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/hello_world/src/interrupt.h
@@ -0,0 +1,17 @@
+#ifndef INTERRUPTCTRL_H_
+#define INTERRUPTCTRL_H_
+
+#include <stdint.h>
+
+typedef struct
+{
+ volatile uint32_t PENDINGS;
+ volatile uint32_t MASKS;
+} InterruptCtrl_Reg;
+
+static void interruptCtrl_init(InterruptCtrl_Reg* reg){
+ reg->MASKS = 0;
+ reg->PENDINGS = 0xFFFFFFFF;
+}
+
+#endif /* INTERRUPTCTRL_H_ */
diff --git a/VexRiscv/src/main/c/murax/hello_world/src/linker.ld b/VexRiscv/src/main/c/murax/hello_world/src/linker.ld
new file mode 100644
index 0000000..57bc2f7
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/hello_world/src/linker.ld
@@ -0,0 +1,110 @@
+/*
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+*/
+OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
+OUTPUT_ARCH(riscv)
+ENTRY(crtStart)
+
+MEMORY {
+ RAM (rwx): ORIGIN = 0x80000000, LENGTH = 2k
+}
+
+_stack_size = DEFINED(_stack_size) ? _stack_size : 256;
+_heap_size = DEFINED(_heap_size) ? _heap_size : 0;
+
+SECTIONS {
+
+ ._vector ORIGIN(RAM): {
+ *crt.o(.start_jump);
+ *crt.o(.text);
+ } > RAM
+
+ ._user_heap (NOLOAD):
+ {
+ . = ALIGN(8);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ PROVIDE ( _heap_start = .);
+ . = . + _heap_size;
+ . = ALIGN(8);
+ PROVIDE ( _heap_end = .);
+ } > RAM
+
+._stack (NOLOAD):
+ {
+ . = ALIGN(16);
+ PROVIDE (_stack_end = .);
+ . = . + _stack_size;
+ . = ALIGN(16);
+ PROVIDE (_stack_start = .);
+ } > RAM
+
+ .data :
+ {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.*)
+ *(.gnu.linkonce.s.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } > RAM
+
+ .bss (NOLOAD) : {
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .bss secion */
+ _bss_start = .;
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _bss_end = .;
+ } > RAM
+
+
+ .rodata :
+ {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ } > RAM
+
+ .noinit (NOLOAD) : {
+ . = ALIGN(4);
+ *(.noinit .noinit.*)
+ . = ALIGN(4);
+ } > RAM
+
+ .memory : {
+ *(.text);
+ end = .;
+ } > RAM
+
+ .ctors :
+ {
+ . = ALIGN(4);
+ _ctors_start = .;
+ KEEP(*(.init_array*))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ . = ALIGN(4);
+ _ctors_end = .;
+ PROVIDE ( END_OF_SW_IMAGE = . );
+ } > RAM
+
+}
diff --git a/VexRiscv/src/main/c/murax/hello_world/src/main.c b/VexRiscv/src/main/c/murax/hello_world/src/main.c
new file mode 100644
index 0000000..05f3227
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/hello_world/src/main.c
@@ -0,0 +1,42 @@
+//#include "stddefs.h"
+#include <stdint.h>
+
+#include "murax.h"
+
+void print(const char*str){
+ while(*str){
+ uart_write(UART,*str);
+ str++;
+ }
+}
+void println(const char*str){
+ print(str);
+ uart_write(UART,'\n');
+}
+
+void delay(uint32_t loops){
+ for(int i=0;i<loops;i++){
+ int tmp = GPIO_A->OUTPUT;
+ }
+}
+
+void main() {
+ GPIO_A->OUTPUT_ENABLE = 0x0000000F;
+ GPIO_A->OUTPUT = 0x00000001;
+ println("hello world arty a7 v1");
+ const int nleds = 4;
+ const int nloops = 2000000;
+ while(1){
+ for(unsigned int i=0;i<nleds-1;i++){
+ GPIO_A->OUTPUT = 1<<i;
+ delay(nloops);
+ }
+ for(unsigned int i=0;i<nleds-1;i++){
+ GPIO_A->OUTPUT = (1<<(nleds-1))>>i;
+ delay(nloops);
+ }
+ }
+}
+
+void irqCallback(){
+}
diff --git a/VexRiscv/src/main/c/murax/hello_world/src/murax.h b/VexRiscv/src/main/c/murax/hello_world/src/murax.h
new file mode 100644
index 0000000..fbfdf3e
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/hello_world/src/murax.h
@@ -0,0 +1,17 @@
+#ifndef __MURAX_H__
+#define __MURAX_H__
+
+#include "timer.h"
+#include "prescaler.h"
+#include "interrupt.h"
+#include "gpio.h"
+#include "uart.h"
+
+#define GPIO_A ((Gpio_Reg*)(0xF0000000))
+#define TIMER_PRESCALER ((Prescaler_Reg*)0xF0020000)
+#define TIMER_INTERRUPT ((InterruptCtrl_Reg*)0xF0020010)
+#define TIMER_A ((Timer_Reg*)0xF0020040)
+#define TIMER_B ((Timer_Reg*)0xF0020050)
+#define UART ((Uart_Reg*)(0xF0010000))
+
+#endif /* __MURAX_H__ */
diff --git a/VexRiscv/src/main/c/murax/hello_world/src/prescaler.h b/VexRiscv/src/main/c/murax/hello_world/src/prescaler.h
new file mode 100644
index 0000000..6bd9694
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/hello_world/src/prescaler.h
@@ -0,0 +1,16 @@
+#ifndef PRESCALERCTRL_H_
+#define PRESCALERCTRL_H_
+
+#include <stdint.h>
+
+
+typedef struct
+{
+ volatile uint32_t LIMIT;
+} Prescaler_Reg;
+
+static void prescaler_init(Prescaler_Reg* reg){
+
+}
+
+#endif /* PRESCALERCTRL_H_ */
diff --git a/VexRiscv/src/main/c/murax/hello_world/src/timer.h b/VexRiscv/src/main/c/murax/hello_world/src/timer.h
new file mode 100644
index 0000000..1577535
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/hello_world/src/timer.h
@@ -0,0 +1,20 @@
+#ifndef TIMERCTRL_H_
+#define TIMERCTRL_H_
+
+#include <stdint.h>
+
+
+typedef struct
+{
+ volatile uint32_t CLEARS_TICKS;
+ volatile uint32_t LIMIT;
+ volatile uint32_t VALUE;
+} Timer_Reg;
+
+static void timer_init(Timer_Reg *reg){
+ reg->CLEARS_TICKS = 0;
+ reg->VALUE = 0;
+}
+
+
+#endif /* TIMERCTRL_H_ */
diff --git a/VexRiscv/src/main/c/murax/hello_world/src/uart.h b/VexRiscv/src/main/c/murax/hello_world/src/uart.h
new file mode 100644
index 0000000..c3a30a5
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/hello_world/src/uart.h
@@ -0,0 +1,42 @@
+#ifndef UART_H_
+#define UART_H_
+
+
+typedef struct
+{
+ volatile uint32_t DATA;
+ volatile uint32_t STATUS;
+ volatile uint32_t CLOCK_DIVIDER;
+ volatile uint32_t FRAME_CONFIG;
+} Uart_Reg;
+
+enum UartParity {NONE = 0,EVEN = 1,ODD = 2};
+enum UartStop {ONE = 0,TWO = 1};
+
+typedef struct {
+ uint32_t dataLength;
+ enum UartParity parity;
+ enum UartStop stop;
+ uint32_t clockDivider;
+} Uart_Config;
+
+static uint32_t uart_writeAvailability(Uart_Reg *reg){
+ return (reg->STATUS >> 16) & 0xFF;
+}
+static uint32_t uart_readOccupancy(Uart_Reg *reg){
+ return reg->STATUS >> 24;
+}
+
+static void uart_write(Uart_Reg *reg, uint32_t data){
+ while(uart_writeAvailability(reg) == 0);
+ reg->DATA = data;
+}
+
+static void uart_applyConfig(Uart_Reg *reg, Uart_Config *config){
+ reg->CLOCK_DIVIDER = config->clockDivider;
+ reg->FRAME_CONFIG = ((config->dataLength-1) << 0) | (config->parity << 8) | (config->stop << 16);
+}
+
+#endif /* UART_H_ */
+
+
diff --git a/VexRiscv/src/main/c/murax/xipBootloader/.gitignore b/VexRiscv/src/main/c/murax/xipBootloader/.gitignore
new file mode 100644
index 0000000..2b33f1e
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/xipBootloader/.gitignore
@@ -0,0 +1,5 @@
+*.elf
+*.map
+*.d
+*.asm
+*.o \ No newline at end of file
diff --git a/VexRiscv/src/main/c/murax/xipBootloader/crt.S b/VexRiscv/src/main/c/murax/xipBootloader/crt.S
new file mode 100644
index 0000000..5268767
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/xipBootloader/crt.S
@@ -0,0 +1,74 @@
+#define CTRL_BASE 0xF001F000
+#define XIP_BASE 0xE0040000
+#define CTRL_DATA 0x00
+#define CTRL_STATUS 0x04
+#define CTRL_MODE 0x08
+#define CTRL_RATE 0x20
+#define CTRL_SS_SETUP 0x24
+#define CTRL_SS_HOLD 0x28
+#define CTRL_SS_DISABLE 0x2C
+
+#define CTRL_XIP_CONFIG 0x40
+#define CTRL_XIP_MODE 0x44
+
+.global crtStart
+.global main
+
+#define CTRL x31
+
+crtStart:
+ li x31, CTRL_BASE
+ sw x0, CTRL_MODE(CTRL)
+ li t0, 2
+ sw t0, CTRL_RATE(CTRL)
+ li t0, 4
+ sw t0, CTRL_SS_SETUP(CTRL)
+ sw t0, CTRL_SS_HOLD(CTRL)
+ sw t0, CTRL_SS_DISABLE(CTRL)
+
+
+ li a0, 0x880
+ call spiWrite
+ li a0, 0x181
+ call spiWrite
+ li a0, 0x183
+ call spiWrite
+ li a0, 0x800
+ call spiWrite
+
+
+ li t0, 0x00FF010B
+ sw t0, CTRL_XIP_MODE(CTRL)
+ li t0, 0x1
+ sw t0, CTRL_XIP_CONFIG(CTRL)
+ li t0, XIP_BASE
+ lw t1, (t0)
+ li t2, 0xFFFFFFFF
+ xor t3,t1,t2
+ beqz t3,retry
+ //if we are here we have read a value from flash which is not all ones
+ lw t2, (t0)
+ xor t3,t1,t2
+ bnez t3,retry
+ lw t2, (t0)
+ xor t3,t1,t2
+ bnez t3,retry
+ //if we are here we have read the same value 3 times, so flash seems good, lets's jump
+ jr t0
+
+retry:
+ li a0, 0x800
+ call spiWrite
+ li t1,100000
+loop:
+ addi t1,t1,-1
+ bnez t1, loop
+ j crtStart
+
+spiWrite:
+ sw a0,CTRL_DATA(CTRL)
+spiWrite_wait:
+ lw t0,CTRL_STATUS(CTRL)
+ slli t0,t0,0x10
+ beqz t0,spiWrite_wait
+ ret
diff --git a/VexRiscv/src/main/c/murax/xipBootloader/demo.S b/VexRiscv/src/main/c/murax/xipBootloader/demo.S
new file mode 100644
index 0000000..064db6f
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/xipBootloader/demo.S
@@ -0,0 +1,27 @@
+#define GPIO_BASE 0xF0000000
+#define GPIO_OUTPUT 4
+#define GPIO_OUTPUT_ENABLE 8
+
+
+.global crtStart
+
+crtStart:
+
+ li x31, 0x12340000 // magic word expected by bootloader
+
+ li x31, GPIO_BASE
+ li t0, 0x000000FF
+ sw t0, GPIO_OUTPUT_ENABLE(x31)
+
+ li t0,1
+redo:
+ sw t0, GPIO_OUTPUT(x31)
+ li t1,10000
+ slli t0,t0,1
+ andi t0,t0,0xFF
+ bnez t0, loop
+ li t0,1
+loop:
+ addi t1,t1,-1
+ bnez t1, loop
+ j redo
diff --git a/VexRiscv/src/main/c/murax/xipBootloader/makefile b/VexRiscv/src/main/c/murax/xipBootloader/makefile
new file mode 100644
index 0000000..e08c17b
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/xipBootloader/makefile
@@ -0,0 +1,37 @@
+CFLAGS= -march=rv32i -mabi=ilp32 -g -O3 -MD
+LFLAGS= -nostdlib -mcmodel=medany -nostartfiles -ffreestanding -fPIC -fPIE
+
+
+all: crt.S demo.S
+ riscv64-unknown-elf-gcc -c $(CFLAGS) -o crt.o crt.S
+ riscv64-unknown-elf-gcc $(CFLAGS) -o crt.elf crt.o $(LFLAGS) -Wl,-Bstatic,-T,mapping_rom.ld,-Map,crt.map,--print-memory-usage
+ riscv64-unknown-elf-objdump -S -d crt.elf > crt.asm
+ riscv64-unknown-elf-objcopy -O binary crt.elf crt.bin
+
+ riscv64-unknown-elf-gcc $(CFLAGS) -o crt_ram.elf crt.o $(LFLAGS) -Wl,-Bstatic,-T,mapping.ld,-Map,crt_ram.map,--print-memory-usage
+ riscv64-unknown-elf-objdump -S -d crt_ram.elf > crt_ram.asm
+ riscv64-unknown-elf-objcopy -O binary crt_ram.elf crt_ram.bin
+
+ riscv64-unknown-elf-gcc -c $(CFLAGS) -o demo.o demo.S
+ riscv64-unknown-elf-gcc $(CFLAGS) -o demo.elf demo.o $(LFLAGS) -Wl,-Bstatic,-T,mapping.ld,-Map,demo.map,--print-memory-usage
+ riscv64-unknown-elf-objdump -S -d demo.elf > demo.asm
+ riscv64-unknown-elf-objcopy -O binary demo.elf demo.bin
+
+ riscv64-unknown-elf-gcc $(CFLAGS) -o demo_rom.elf demo.o $(LFLAGS) -Wl,-Bstatic,-T,mapping_rom.ld,-Map,demo_rom.map,--print-memory-usage
+ riscv64-unknown-elf-objdump -S -d demo_rom.elf > demo_rom.asm
+ riscv64-unknown-elf-objcopy -O binary demo_rom.elf demo_rom.bin
+
+ riscv64-unknown-elf-gcc $(CFLAGS) -o demo_xip.elf demo.o $(LFLAGS) -Wl,-Bstatic,-T,mapping_xip.ld,-Map,demo_xip.map,--print-memory-usage
+ riscv64-unknown-elf-objdump -S -d demo_xip.elf > demo_xip.asm
+ riscv64-unknown-elf-objcopy -O binary demo_xip.elf demo_xip.bin
+
+clean-for-commit:
+ rm -f *.o
+ rm -f *.elf
+ rm -f *.asm
+ rm -f *.map
+ rm -f *.d
+ rm demo_rom.bin demo.bin crt_ram.bin
+
+clean: clean-for-commit
+ rm -f *.bin
diff --git a/VexRiscv/src/main/c/murax/xipBootloader/mapping.ld b/VexRiscv/src/main/c/murax/xipBootloader/mapping.ld
new file mode 100644
index 0000000..cc1b070
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/xipBootloader/mapping.ld
@@ -0,0 +1,96 @@
+/*
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+*/
+OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
+OUTPUT_ARCH(riscv)
+ENTRY(crtStart)
+
+MEMORY {
+ mem : ORIGIN = 0x80000000, LENGTH = 0x00000400
+}
+
+_stack_size = DEFINED(_stack_size) ? _stack_size : 0;
+
+SECTIONS {
+
+ .vector : {
+ *crt.o(.text);
+ } > mem
+
+ .memory : {
+ *(.text);
+ end = .;
+ } > mem
+
+ .rodata :
+ {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ } > mem
+
+ .ctors :
+ {
+ . = ALIGN(4);
+ _ctors_start = .;
+ KEEP(*(.init_array*))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ . = ALIGN(4);
+ _ctors_end = .;
+ } > mem
+
+ .data :
+ {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.*)
+ *(.gnu.linkonce.s.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } > mem
+
+ .bss (NOLOAD) : {
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .bss secion */
+ _bss_start = .;
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _bss_end = .;
+ } > mem
+
+ .noinit (NOLOAD) : {
+ . = ALIGN(4);
+ *(.noinit .noinit.*)
+ . = ALIGN(4);
+ } > mem
+
+ ._stack (NOLOAD):
+ {
+ . = ALIGN(16);
+ PROVIDE (_stack_end = .);
+ . = . + _stack_size;
+ . = ALIGN(16);
+ PROVIDE (_stack_start = .);
+ } > mem
+
+}
+
diff --git a/VexRiscv/src/main/c/murax/xipBootloader/mapping_rom.ld b/VexRiscv/src/main/c/murax/xipBootloader/mapping_rom.ld
new file mode 100644
index 0000000..aaa0c3c
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/xipBootloader/mapping_rom.ld
@@ -0,0 +1,96 @@
+/*
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+*/
+OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
+OUTPUT_ARCH(riscv)
+ENTRY(crtStart)
+
+MEMORY {
+ mem : ORIGIN = 0x80000000, LENGTH = 0x00000400
+ rom : ORIGIN = 0xF001E000, LENGTH = 0x00000400
+}
+
+_stack_size = DEFINED(_stack_size) ? _stack_size : 0;
+
+SECTIONS {
+
+ .vector : {
+ *crt.o(.text);
+ } > rom
+
+ .memory : {
+ *(.text);
+ end = .;
+ } > rom
+
+ .rodata :
+ {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ } > rom
+
+ .ctors :
+ {
+ . = ALIGN(4);
+ _ctors_start = .;
+ KEEP(*(.init_array*))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ . = ALIGN(4);
+ _ctors_end = .;
+ } > rom
+
+ .data :
+ {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.*)
+ *(.gnu.linkonce.s.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } > rom
+
+ .bss (NOLOAD) : {
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .bss secion */
+ _bss_start = .;
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _bss_end = .;
+ } > mem
+
+ .noinit (NOLOAD) : {
+ . = ALIGN(4);
+ *(.noinit .noinit.*)
+ . = ALIGN(4);
+ } > mem
+
+ ._stack (NOLOAD):
+ {
+ . = ALIGN(16);
+ PROVIDE (_stack_end = .);
+ . = . + _stack_size;
+ . = ALIGN(16);
+ PROVIDE (_stack_start = .);
+ } > mem
+
+}
diff --git a/VexRiscv/src/main/c/murax/xipBootloader/mapping_xip.ld b/VexRiscv/src/main/c/murax/xipBootloader/mapping_xip.ld
new file mode 100644
index 0000000..ed56400
--- /dev/null
+++ b/VexRiscv/src/main/c/murax/xipBootloader/mapping_xip.ld
@@ -0,0 +1,96 @@
+/*
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+*/
+OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
+OUTPUT_ARCH(riscv)
+ENTRY(crtStart)
+
+MEMORY {
+ mem : ORIGIN = 0x80000000, LENGTH = 0x00000400
+ xip : ORIGIN = 0xE0040000, LENGTH = 0x00000400
+}
+
+_stack_size = DEFINED(_stack_size) ? _stack_size : 0;
+
+SECTIONS {
+
+ .vector : {
+ *crt.o(.text);
+ } > xip
+
+ .memory : {
+ *(.text);
+ end = .;
+ } > xip
+
+ .rodata :
+ {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ } > xip
+
+ .ctors :
+ {
+ . = ALIGN(4);
+ _ctors_start = .;
+ KEEP(*(.init_array*))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ . = ALIGN(4);
+ _ctors_end = .;
+ } > xip
+
+ .data :
+ {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.*)
+ *(.gnu.linkonce.s.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } > xip
+
+ .bss (NOLOAD) : {
+ . = ALIGN(4);
+ /* This is used by the startup in order to initialize the .bss secion */
+ _bss_start = .;
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _bss_end = .;
+ } > mem
+
+ .noinit (NOLOAD) : {
+ . = ALIGN(4);
+ *(.noinit .noinit.*)
+ . = ALIGN(4);
+ } > mem
+
+ ._stack (NOLOAD):
+ {
+ . = ALIGN(16);
+ PROVIDE (_stack_end = .);
+ . = . + _stack_size;
+ . = ALIGN(16);
+ PROVIDE (_stack_start = .);
+ } > mem
+
+}