diff --git a/src/main/c/common/ram.ld b/src/main/c/common/ram.ld new file mode 100755 index 0000000..19dc3d9 --- /dev/null +++ b/src/main/c/common/ram.ld @@ -0,0 +1,151 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + 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/src/main/c/common/riscv64-unknown-elf.mk b/src/main/c/common/riscv64-unknown-elf.mk new file mode 100644 index 0000000..e17a9d1 --- /dev/null +++ b/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/src/main/c/common/standalone.mk b/src/main/c/common/standalone.mk new file mode 100644 index 0000000..88328a2 --- /dev/null +++ b/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/src/main/c/emulator/.gitignore b/src/main/c/emulator/.gitignore new file mode 100644 index 0000000..c12cb2c --- /dev/null +++ b/src/main/c/emulator/.gitignore @@ -0,0 +1,4 @@ +*.map +*.v +*.elf +*.o \ No newline at end of file diff --git a/src/main/c/emulator/build/emulator.asm b/src/main/c/emulator/build/emulator.asm new file mode 100644 index 0000000..5893188 --- /dev/null +++ b/src/main/c/emulator/build/emulator.asm @@ -0,0 +1,509 @@ + +build/emulator.elf: file format elf32-littleriscv + + +Disassembly of section .init: + +80000000 <_start>: +.option push +.option norelax + la gp, __global_pointer$ +.option pop +#endif*/ + la sp, _sp +80000000: 00001117 auipc sp,0x1 +80000004: cb010113 addi sp,sp,-848 # 80000cb0 <_sp> + + + /* Load data section */ + la a0, _data_lma +80000008: 00000517 auipc a0,0x0 +8000000c: 43450513 addi a0,a0,1076 # 8000043c <__init_array_end> + la a1, _data +80000010: 00000597 auipc a1,0x0 +80000014: 42c58593 addi a1,a1,1068 # 8000043c <__init_array_end> + la a2, _edata +80000018: 00000617 auipc a2,0x0 +8000001c: 49860613 addi a2,a2,1176 # 800004b0 <__bss_start> + bgeu a1, a2, 2f +80000020: 00c5fc63 bleu a2,a1,80000038 <_start+0x38> +1: + lw t0, (a0) +80000024: 00052283 lw t0,0(a0) + sw t0, (a1) +80000028: 0055a023 sw t0,0(a1) + addi a0, a0, 4 +8000002c: 00450513 addi a0,a0,4 + addi a1, a1, 4 +80000030: 00458593 addi a1,a1,4 + bltu a1, a2, 1b +80000034: fec5e8e3 bltu a1,a2,80000024 <_start+0x24> +2: + + /* Clear bss section */ + la a0, __bss_start +80000038: 00000517 auipc a0,0x0 +8000003c: 47850513 addi a0,a0,1144 # 800004b0 <__bss_start> + la a1, _end +80000040: 00000597 auipc a1,0x0 +80000044: 47058593 addi a1,a1,1136 # 800004b0 <__bss_start> + bgeu a0, a1, 2f +80000048: 00b57863 bleu a1,a0,80000058 <_start+0x58> +1: + sw zero, (a0) +8000004c: 00052023 sw zero,0(a0) + addi a0, a0, 4 +80000050: 00450513 addi a0,a0,4 + bltu a0, a1, 1b +80000054: feb56ce3 bltu a0,a1,8000004c <_start+0x4c> +2: + + call __libc_init_array +80000058: 34c000ef jal ra,800003a4 <__libc_init_array> + call init +8000005c: 128000ef jal ra,80000184 + la ra, done +80000060: 00000097 auipc ra,0x0 +80000064: 01408093 addi ra,ra,20 # 80000074 + li a0, DTB +80000068: 81000537 lui a0,0x81000 + li a1, 0 +8000006c: 00000593 li a1,0 + mret +80000070: 30200073 mret + +80000074 : +done: + j done +80000074: 0000006f j 80000074 + +80000078 <_init>: + + + .globl _init +_init: + ret +80000078: 00008067 ret + +8000007c : + .section .init + .globl trapEntry + .type trapEntry,@function + +trapEntry: + csrrw sp, mscratch, sp +8000007c: 34011173 csrrw sp,mscratch,sp + sw x0, 0*4(sp) +80000080: 00012023 sw zero,0(sp) + sw x1, 1*4(sp) +80000084: 00112223 sw ra,4(sp) + sw x3, 3*4(sp) +80000088: 00312623 sw gp,12(sp) + sw x4, 4*4(sp) +8000008c: 00412823 sw tp,16(sp) + sw x5, 5*4(sp) +80000090: 00512a23 sw t0,20(sp) + sw x6, 6*4(sp) +80000094: 00612c23 sw t1,24(sp) + sw x7, 7*4(sp) +80000098: 00712e23 sw t2,28(sp) + sw x8, 8*4(sp) +8000009c: 02812023 sw s0,32(sp) + sw x9, 9*4(sp) +800000a0: 02912223 sw s1,36(sp) + sw x10, 10*4(sp) +800000a4: 02a12423 sw a0,40(sp) + sw x11, 11*4(sp) +800000a8: 02b12623 sw a1,44(sp) + sw x12, 12*4(sp) +800000ac: 02c12823 sw a2,48(sp) + sw x13, 13*4(sp) +800000b0: 02d12a23 sw a3,52(sp) + sw x14, 14*4(sp) +800000b4: 02e12c23 sw a4,56(sp) + sw x15, 15*4(sp) +800000b8: 02f12e23 sw a5,60(sp) + sw x16, 16*4(sp) +800000bc: 05012023 sw a6,64(sp) + sw x17, 17*4(sp) +800000c0: 05112223 sw a7,68(sp) + sw x18, 18*4(sp) +800000c4: 05212423 sw s2,72(sp) + sw x19, 19*4(sp) +800000c8: 05312623 sw s3,76(sp) + sw x20, 20*4(sp) +800000cc: 05412823 sw s4,80(sp) + sw x21, 21*4(sp) +800000d0: 05512a23 sw s5,84(sp) + sw x22, 22*4(sp) +800000d4: 05612c23 sw s6,88(sp) + sw x23, 23*4(sp) +800000d8: 05712e23 sw s7,92(sp) + sw x24, 24*4(sp) +800000dc: 07812023 sw s8,96(sp) + sw x25, 25*4(sp) +800000e0: 07912223 sw s9,100(sp) + sw x26, 26*4(sp) +800000e4: 07a12423 sw s10,104(sp) + sw x27, 27*4(sp) +800000e8: 07b12623 sw s11,108(sp) + sw x28, 28*4(sp) +800000ec: 07c12823 sw t3,112(sp) + sw x29, 29*4(sp) +800000f0: 07d12a23 sw t4,116(sp) + sw x30, 30*4(sp) +800000f4: 07e12c23 sw t5,120(sp) + sw x31, 31*4(sp) +800000f8: 07f12e23 sw t6,124(sp) + call trap +800000fc: 134000ef jal ra,80000230 + lw x0, 0*4(sp) +80000100: 00012003 lw zero,0(sp) + lw x1, 1*4(sp) +80000104: 00412083 lw ra,4(sp) + lw x3, 3*4(sp) +80000108: 00c12183 lw gp,12(sp) + lw x4, 4*4(sp) +8000010c: 01012203 lw tp,16(sp) + lw x5, 5*4(sp) +80000110: 01412283 lw t0,20(sp) + lw x6, 6*4(sp) +80000114: 01812303 lw t1,24(sp) + lw x7, 7*4(sp) +80000118: 01c12383 lw t2,28(sp) + lw x8, 8*4(sp) +8000011c: 02012403 lw s0,32(sp) + lw x9, 9*4(sp) +80000120: 02412483 lw s1,36(sp) + lw x10, 10*4(sp) +80000124: 02812503 lw a0,40(sp) + lw x11, 11*4(sp) +80000128: 02c12583 lw a1,44(sp) + lw x12, 12*4(sp) +8000012c: 03012603 lw a2,48(sp) + lw x13, 13*4(sp) +80000130: 03412683 lw a3,52(sp) + lw x14, 14*4(sp) +80000134: 03812703 lw a4,56(sp) + lw x15, 15*4(sp) +80000138: 03c12783 lw a5,60(sp) + lw x16, 16*4(sp) +8000013c: 04012803 lw a6,64(sp) + lw x17, 17*4(sp) +80000140: 04412883 lw a7,68(sp) + lw x18, 18*4(sp) +80000144: 04812903 lw s2,72(sp) + lw x19, 19*4(sp) +80000148: 04c12983 lw s3,76(sp) + lw x20, 20*4(sp) +8000014c: 05012a03 lw s4,80(sp) + lw x21, 21*4(sp) +80000150: 05412a83 lw s5,84(sp) + lw x22, 22*4(sp) +80000154: 05812b03 lw s6,88(sp) + lw x23, 23*4(sp) +80000158: 05c12b83 lw s7,92(sp) + lw x24, 24*4(sp) +8000015c: 06012c03 lw s8,96(sp) + lw x25, 25*4(sp) +80000160: 06412c83 lw s9,100(sp) + lw x26, 26*4(sp) +80000164: 06812d03 lw s10,104(sp) + lw x27, 27*4(sp) +80000168: 06c12d83 lw s11,108(sp) + lw x28, 28*4(sp) +8000016c: 07012e03 lw t3,112(sp) + lw x29, 29*4(sp) +80000170: 07412e83 lw t4,116(sp) + lw x30, 30*4(sp) +80000174: 07812f03 lw t5,120(sp) + lw x31, 31*4(sp) +80000178: 07c12f83 lw t6,124(sp) + csrrw sp, mscratch, sp +8000017c: 34011173 csrrw sp,mscratch,sp + mret +80000180: 30200073 mret + +Disassembly of section .text: + +80000184 : + +extern const unsigned int _sp; +extern void trapEntry(); + +void init() { + csr_write(mtvec, trapEntry); +80000184: 800007b7 lui a5,0x80000 +80000188: 07c78793 addi a5,a5,124 # 8000007c <_sp+0xfffff3cc> +8000018c: 30579073 csrw mtvec,a5 + + unsigned int sp = (unsigned int) (&_sp); +80000190: 800017b7 lui a5,0x80001 +80000194: cb078793 addi a5,a5,-848 # 80000cb0 <_sp+0x0> + csr_write(mscratch, sp -32*4); +80000198: f8078793 addi a5,a5,-128 +8000019c: 34079073 csrw mscratch,a5 + csr_write(mstatus, 0x0800); +800001a0: 000017b7 lui a5,0x1 +800001a4: 80078793 addi a5,a5,-2048 # 800 <__stack_size> +800001a8: 30079073 csrw mstatus,a5 + csr_write(mepc, OS_CALL); +800001ac: c00007b7 lui a5,0xc0000 +800001b0: 34179073 csrw mepc,a5 + csr_write(medeleg, MDELEG_INSTRUCTION_PAGE_FAULT | MDELEG_LOAD_PAGE_FAULT | MDELEG_STORE_PAGE_FAULT); +800001b4: 0000b7b7 lui a5,0xb +800001b8: 30279073 csrw medeleg,a5 +} +800001bc: 00008067 ret + +800001c0 : + +int readRegister(int id){ + unsigned int sp = (unsigned int) (&_sp); + return ((int*) sp)[id-32]; +800001c0: 00251513 slli a0,a0,0x2 +800001c4: 800017b7 lui a5,0x80001 +800001c8: cb078793 addi a5,a5,-848 # 80000cb0 <_sp+0x0> +800001cc: 00f50533 add a0,a0,a5 +} +800001d0: f8052503 lw a0,-128(a0) # 80ffff80 <_sp+0xfff2d0> +800001d4: 00008067 ret + +800001d8 : +void writeRegister(int id, int value){ + unsigned int sp = (unsigned int) (&_sp); + ((int*) sp)[id-32] = value; +800001d8: 00251513 slli a0,a0,0x2 +800001dc: 800017b7 lui a5,0x80001 +800001e0: cb078793 addi a5,a5,-848 # 80000cb0 <_sp+0x0> +800001e4: 00f50533 add a0,a0,a5 +800001e8: f8b52023 sw a1,-128(a0) +} +800001ec: 00008067 ret + +800001f0 : + + +void stopSim(){ + *((volatile int*) SIM_STOP) = 0; +800001f0: fe002e23 sw zero,-4(zero) # fffffffc <_sp+0x7ffff34c> +} +800001f4: 00008067 ret + +800001f8 : + +void putC(char c){ + *((volatile int*) PUTC) = c; +800001f8: fea02c23 sw a0,-8(zero) # fffffff8 <_sp+0x7ffff348> +} +800001fc: 00008067 ret + +80000200 : + + +void redirectTrap(){ +80000200: ff010113 addi sp,sp,-16 +80000204: 00112623 sw ra,12(sp) + stopSim(); +80000208: fe9ff0ef jal ra,800001f0 + csr_write(sbadaddr, csr_read(mbadaddr)); +8000020c: 343027f3 csrr a5,mbadaddr +80000210: 14379073 csrw sbadaddr,a5 + csr_write(sepc, csr_read(mepc)); +80000214: 341027f3 csrr a5,mepc +80000218: 14179073 csrw sepc,a5 + csr_write(scause, csr_read(mcause)); +8000021c: 342027f3 csrr a5,mcause +80000220: 14279073 csrw scause,a5 +} +80000224: 00c12083 lw ra,12(sp) +80000228: 01010113 addi sp,sp,16 +8000022c: 00008067 ret + +80000230 : +#define min(a,b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; }) + +void trap(){ +80000230: fe010113 addi sp,sp,-32 +80000234: 00112e23 sw ra,28(sp) +80000238: 00812c23 sw s0,24(sp) +8000023c: 00912a23 sw s1,20(sp) +80000240: 01212823 sw s2,16(sp) +80000244: 01312623 sw s3,12(sp) + int cause = csr_read(mcause); +80000248: 342027f3 csrr a5,mcause + if(cause < 0){ +8000024c: 0207ca63 bltz a5,80000280 + redirectTrap(); + } else { + switch(cause){ +80000250: 00200713 li a4,2 +80000254: 02e78a63 beq a5,a4,80000288 +80000258: 00900713 li a4,9 +8000025c: 10e78863 beq a5,a4,8000036c + csr_write(mepc, csr_read(mepc) + 4); + }break; + default: stopSim(); break; + } + }break; + default: redirectTrap(); break; +80000260: fa1ff0ef jal ra,80000200 + } + } + +} +80000264: 01c12083 lw ra,28(sp) +80000268: 01812403 lw s0,24(sp) +8000026c: 01412483 lw s1,20(sp) +80000270: 01012903 lw s2,16(sp) +80000274: 00c12983 lw s3,12(sp) +80000278: 02010113 addi sp,sp,32 +8000027c: 00008067 ret + redirectTrap(); +80000280: f81ff0ef jal ra,80000200 +80000284: fe1ff06f j 80000264 + int instruction = csr_read(mbadaddr); +80000288: 34302473 csrr s0,mbadaddr + int opcode = instruction & 0x7F; +8000028c: 07f47693 andi a3,s0,127 + int funct3 = (instruction >> 12) & 0x7; +80000290: 40c45793 srai a5,s0,0xc +80000294: 0077f793 andi a5,a5,7 + switch(opcode){ +80000298: 02f00713 li a4,47 +8000029c: fce694e3 bne a3,a4,80000264 + switch(funct3){ +800002a0: 00200713 li a4,2 +800002a4: 0ce79063 bne a5,a4,80000364 + int sel = instruction >> 27; +800002a8: 41b45493 srai s1,s0,0x1b + int*addr = (int*)readRegister((instruction >> 15) & 0x1F); +800002ac: 40f45513 srai a0,s0,0xf +800002b0: 01f57513 andi a0,a0,31 +800002b4: f0dff0ef jal ra,800001c0 +800002b8: 00050993 mv s3,a0 + int src = readRegister((instruction >> 20) & 0x1F); +800002bc: 41445513 srai a0,s0,0x14 +800002c0: 01f57513 andi a0,a0,31 +800002c4: efdff0ef jal ra,800001c0 +800002c8: 00050913 mv s2,a0 + int rd = (instruction >> 7) & 0x1F; +800002cc: 40745413 srai s0,s0,0x7 +800002d0: 01f47513 andi a0,s0,31 + int readValue = *addr; +800002d4: 0009a583 lw a1,0(s3) + switch(sel){ +800002d8: 01c00793 li a5,28 +800002dc: 0897e063 bltu a5,s1,8000035c +800002e0: 00249493 slli s1,s1,0x2 +800002e4: 800007b7 lui a5,0x80000 +800002e8: 43c78793 addi a5,a5,1084 # 8000043c <_sp+0xfffff78c> +800002ec: 00f484b3 add s1,s1,a5 +800002f0: 0004a783 lw a5,0(s1) +800002f4: 00078067 jr a5 + case 0x0: writeValue = src + readValue; break; +800002f8: 00b90933 add s2,s2,a1 + writeRegister(rd, readValue); +800002fc: eddff0ef jal ra,800001d8 + *addr = writeValue; +80000300: 0129a023 sw s2,0(s3) + csr_write(mepc, csr_read(mepc) + 4); +80000304: 341027f3 csrr a5,mepc +80000308: 00478793 addi a5,a5,4 +8000030c: 34179073 csrw mepc,a5 + }break; +80000310: f55ff06f j 80000264 + case 0x4: writeValue = src ^ readValue; break; +80000314: 00b94933 xor s2,s2,a1 +80000318: fe5ff06f j 800002fc + case 0xC: writeValue = src & readValue; break; +8000031c: 00b97933 and s2,s2,a1 +80000320: fddff06f j 800002fc + case 0x8: writeValue = src | readValue; break; +80000324: 00b96933 or s2,s2,a1 +80000328: fd5ff06f j 800002fc + case 0x10: writeValue = min(src, readValue); break; +8000032c: fd25d8e3 ble s2,a1,800002fc +80000330: 00058913 mv s2,a1 +80000334: fc9ff06f j 800002fc + case 0x14: writeValue = max(src, readValue); break; +80000338: fcb952e3 ble a1,s2,800002fc +8000033c: 00058913 mv s2,a1 +80000340: fbdff06f j 800002fc + case 0x18: writeValue = min((unsigned int)src, (unsigned int)readValue); break; +80000344: fb25fce3 bleu s2,a1,800002fc +80000348: 00058913 mv s2,a1 +8000034c: fb1ff06f j 800002fc + case 0x1C: writeValue = max((unsigned int)src, (unsigned int)readValue); break; +80000350: fab976e3 bleu a1,s2,800002fc +80000354: 00058913 mv s2,a1 +80000358: fa5ff06f j 800002fc + default: redirectTrap(); return; break; +8000035c: ea5ff0ef jal ra,80000200 +80000360: f05ff06f j 80000264 + default: redirectTrap(); break; +80000364: e9dff0ef jal ra,80000200 +80000368: efdff06f j 80000264 + int which = readRegister(17); +8000036c: 01100513 li a0,17 +80000370: e51ff0ef jal ra,800001c0 + switch(which){ +80000374: 00100793 li a5,1 +80000378: 02f51263 bne a0,a5,8000039c + putC(readRegister(10)); +8000037c: 00a00513 li a0,10 +80000380: e41ff0ef jal ra,800001c0 +80000384: 0ff57513 andi a0,a0,255 +80000388: e71ff0ef jal ra,800001f8 + csr_write(mepc, csr_read(mepc) + 4); +8000038c: 341027f3 csrr a5,mepc +80000390: 00478793 addi a5,a5,4 +80000394: 34179073 csrw mepc,a5 + }break; +80000398: ecdff06f j 80000264 + default: stopSim(); break; +8000039c: e55ff0ef jal ra,800001f0 +800003a0: ec5ff06f j 80000264 + +800003a4 <__libc_init_array>: +800003a4: ff010113 addi sp,sp,-16 +800003a8: 00812423 sw s0,8(sp) +800003ac: 00912223 sw s1,4(sp) +800003b0: 00000417 auipc s0,0x0 +800003b4: 08c40413 addi s0,s0,140 # 8000043c <__init_array_end> +800003b8: 00000497 auipc s1,0x0 +800003bc: 08448493 addi s1,s1,132 # 8000043c <__init_array_end> +800003c0: 408484b3 sub s1,s1,s0 +800003c4: 01212023 sw s2,0(sp) +800003c8: 00112623 sw ra,12(sp) +800003cc: 4024d493 srai s1,s1,0x2 +800003d0: 00000913 li s2,0 +800003d4: 04991063 bne s2,s1,80000414 <__libc_init_array+0x70> +800003d8: 00000417 auipc s0,0x0 +800003dc: 06440413 addi s0,s0,100 # 8000043c <__init_array_end> +800003e0: 00000497 auipc s1,0x0 +800003e4: 05c48493 addi s1,s1,92 # 8000043c <__init_array_end> +800003e8: 408484b3 sub s1,s1,s0 +800003ec: c8dff0ef jal ra,80000078 <_init> +800003f0: 4024d493 srai s1,s1,0x2 +800003f4: 00000913 li s2,0 +800003f8: 02991863 bne s2,s1,80000428 <__libc_init_array+0x84> +800003fc: 00c12083 lw ra,12(sp) +80000400: 00812403 lw s0,8(sp) +80000404: 00412483 lw s1,4(sp) +80000408: 00012903 lw s2,0(sp) +8000040c: 01010113 addi sp,sp,16 +80000410: 00008067 ret +80000414: 00042783 lw a5,0(s0) +80000418: 00190913 addi s2,s2,1 +8000041c: 00440413 addi s0,s0,4 +80000420: 000780e7 jalr a5 +80000424: fb1ff06f j 800003d4 <__libc_init_array+0x30> +80000428: 00042783 lw a5,0(s0) +8000042c: 00190913 addi s2,s2,1 +80000430: 00440413 addi s0,s0,4 +80000434: 000780e7 jalr a5 +80000438: fc1ff06f j 800003f8 <__libc_init_array+0x54> diff --git a/src/main/c/emulator/build/emulator.hex b/src/main/c/emulator/build/emulator.hex new file mode 100644 index 0000000..f70c1b4 --- /dev/null +++ b/src/main/c/emulator/build/emulator.hex @@ -0,0 +1,80 @@ +:0200000480007A +:1000000017110000130101CB17050000130545432C +:10001000970500009385C542170600001306864920 +:1000200063FCC5008322050023A05500130545008D +:1000300093854500E3E8C5FE1705000013058547D5 +:1000400097050000938505476378B50023200500D8 +:1000500013054500E36CB5FEEF00C034EF008012DD +:100060009700000093804001370500819305000050 +:10007000730020306F0000006780000073110134AE +:1000800023200100232211002326310023284100D0 +:10009000232A5100232C6100232E7100232081028A +:1000A000232291022324A1022326B1022328C10284 +:1000B000232AD102232CE102232EF1022320010561 +:1000C0002322110523242105232631052328410558 +:1000D000232A5105232C6105232E71052320810736 +:1000E000232291072324A1072326B1072328C10730 +:1000F000232AD107232CE107232EF107EF00401319 +:1001000003200100832041008321C100032201015B +:1001100083224101032381018323C10103240102BE +:1001200083244102032581028325C10203260103A2 +:1001300083264103032781038327C1030328010486 +:1001400083284104032981048329C104032A01056A +:10015000832A4105032B8105832BC105032C01064E +:10016000832C4106032D8106832DC106032E010732 +:10017000832E4107032F8107832FC1077311013499 +:0401800073002030B8 +:10018400B70700809387C70773905730B71700806D +:10019400938707CB938707F873900734B71700004A +:1001A4009387078073900730B70700C073901734A4 +:1001B400B7B700007390273067800000131525003F +:1001C400B7170080938707CB3305F500032505F89F +:1001D4006780000013152500B7170080938707CBAD +:1001E4003305F5002320B5F867800000232E00FEB8 +:1001F40067800000232CA0FE67800000130101FF2C +:1002040023261100EFF09FFEF32730347390371448 +:10021400F327103473901714F327203473902714A2 +:100224008320C1001301010167800000130101FE56 +:10023400232E1100232C8100232A9100232821013D +:1002440023263101F327203463CA07021307200051 +:10025400638AE702130790006388E710EFF01FFA40 +:100264008320C10103248101832441010329010165 +:100274008329C1001301010267800000EFF01FF819 +:100284006FF01FFE732430349376F4079357C44001 +:1002940093F777001307F002E394E6FC13072000BA +:1002A4006390E70C9354B4411355F4401375F5016E +:1002B400EFF0DFF093090500135544411375F50180 +:1002C400EFF0DFEF13090500135474401375F401C4 +:1002D40083A509009307C00163E097089394240061 +:1002E400B70700809387C743B384F40083A704004F +:1002F400678007003309B900EFF0DFED23A029017F +:10030400F327103493874700739017346FF05FF529 +:100314003349B9006FF05FFE3379B9006FF0DFFD48 +:100324003369B9006FF05FFDE3D825FD138905003B +:100334006FF09FFCE352B9FC138905006FF0DFFBFB +:10034400E3FC25FB138905006FF01FFBE376B9FA84 +:10035400138905006FF05FFAEFF05FEA6FF05FF06A +:10036400EFF0DFE96FF0DFEF13051001EFF01FE5A9 +:10037400930710006312F5021305A000EFF01FE4C9 +:100384001375F50FEFF01FE7F32710349387470039 +:10039400739017346FF0DFECEFF05FE56FF05FEC14 +:1003A400130101FF2324810023229100170400007C +:1003B4001304C4089704000093844408B38484405D +:1003C400232021012326110093D424401309000083 +:1003D40063109904170400001304440697040000F2 +:1003E4009384C405B3848440EFF0DFC893D42440DD +:1003F40013090000631899028320C10003248100BB +:1004040083244100032901001301010167800000D6 +:10041400832704001309190013044400E78007002C +:100424006FF01FFB83270400130919001304440011 +:08043400E78007006FF01FFCD8 +:10043C00F8020080FC0200805C0300805C030080FA +:10044C00140300805C0300805C0300805C0300806C +:10045C00240300805C0300805C0300805C0300804C +:10046C001C0300805C0300805C0300805C03008044 +:10047C002C0300805C0300805C0300805C03008024 +:10048C00380300805C0300805C0300805C03008008 +:10049C00440300805C0300805C0300805C030080EC +:0404AC005003008079 +:040000058000000077 +:00000001FF diff --git a/src/main/c/emulator/makefile b/src/main/c/emulator/makefile new file mode 100755 index 0000000..348a113 --- /dev/null +++ b/src/main/c/emulator/makefile @@ -0,0 +1,17 @@ +PROJ_NAME=emulator +DEBUG=yes +MULDIV=no +COMPRESSED=no +STANDALONE = .. + + +SRCS = $(wildcard src/*.c) \ + $(wildcard src/*.cpp) \ + $(wildcard src/*.S) + + +LDSCRIPT = ${STANDALONE}/common/ram.ld + +include ${STANDALONE}/common/riscv64-unknown-elf.mk +include ${STANDALONE}/common/standalone.mk + diff --git a/src/main/c/emulator/src/config.h b/src/main/c/emulator/src/config.h new file mode 100644 index 0000000..e39fa65 --- /dev/null +++ b/src/main/c/emulator/src/config.h @@ -0,0 +1,10 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define OS_CALL 0xC0000000 +#define DTB 0x81000000 +#define SIM_STOP 0xFFFFFFFC +#define PUTC 0xFFFFFFF8 + + +#endif diff --git a/src/main/c/emulator/src/main.c b/src/main/c/emulator/src/main.c new file mode 100755 index 0000000..36090c7 --- /dev/null +++ b/src/main/c/emulator/src/main.c @@ -0,0 +1,109 @@ +#include +#include "riscv.h" +#include "config.h" + +extern const unsigned int _sp; +extern void trapEntry(); + +void init() { + csr_write(mtvec, trapEntry); + + unsigned int sp = (unsigned int) (&_sp); + csr_write(mscratch, sp -32*4); + csr_write(mstatus, 0x0800); + csr_write(mepc, OS_CALL); + csr_write(medeleg, MDELEG_INSTRUCTION_PAGE_FAULT | MDELEG_LOAD_PAGE_FAULT | MDELEG_STORE_PAGE_FAULT); +} + +int readRegister(int id){ + unsigned int sp = (unsigned int) (&_sp); + return ((int*) sp)[id-32]; +} +void writeRegister(int id, int value){ + unsigned int sp = (unsigned int) (&_sp); + ((int*) sp)[id-32] = value; +} + + +void stopSim(){ + *((volatile int*) SIM_STOP) = 0; +} + +void putC(char c){ + *((volatile int*) PUTC) = c; +} + + +void redirectTrap(){ + stopSim(); + csr_write(sbadaddr, csr_read(mbadaddr)); + csr_write(sepc, csr_read(mepc)); + csr_write(scause, csr_read(mcause)); +} + +#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; }) + +void trap(){ + int cause = csr_read(mcause); + if(cause < 0){ + redirectTrap(); + } else { + switch(cause){ + case CAUSE_ILLEGAL_INSTRUCTION:{ + int instruction = csr_read(mbadaddr); + int opcode = instruction & 0x7F; + int funct3 = (instruction >> 12) & 0x7; + switch(opcode){ + case 0x2F: //Atomic + switch(funct3){ + case 0x2:{ + int sel = instruction >> 27; + int*addr = (int*)readRegister((instruction >> 15) & 0x1F); + int src = readRegister((instruction >> 20) & 0x1F); + int rd = (instruction >> 7) & 0x1F; + int readValue = *addr; + int writeValue; + switch(sel){ + case 0x0: writeValue = src + readValue; break; + case 0x1: writeValue = src; 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; + } + writeRegister(rd, readValue); + *addr = writeValue; + csr_write(mepc, csr_read(mepc) + 4); + }break; + default: redirectTrap(); break; + } + } + }break; + case CAUSE_SCALL:{ + int which = readRegister(17); + switch(which){ + case 1:{ + putC(readRegister(10)); + csr_write(mepc, csr_read(mepc) + 4); + }break; + default: stopSim(); break; + } + }break; + default: redirectTrap(); break; + } + } + +} diff --git a/src/main/c/emulator/src/riscv.h b/src/main/c/emulator/src/riscv.h new file mode 100644 index 0000000..dcb125e --- /dev/null +++ b/src/main/c/emulator/src/riscv.h @@ -0,0 +1,107 @@ +#ifndef RISCV_H +#define RISCV_H + +#define CAUSE_ILLEGAL_INSTRUCTION 2 +#define CAUSE_SCALL 9 + +#define MDELEG_INSTRUCTION_PAGE_FAULT (1 << 12) +#define MDELEG_LOAD_PAGE_FAULT (1 << 13) +#define MDELEG_STORE_PAGE_FAULT (1 << 15) + +#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 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/src/main/c/emulator/src/start.S b/src/main/c/emulator/src/start.S new file mode 100755 index 0000000..ef020e3 --- /dev/null +++ b/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, DTB + li a1, 0 + mret +done: + j done + + + .globl _init +_init: + ret diff --git a/src/main/c/emulator/src/trap.S b/src/main/c/emulator/src/trap.S new file mode 100644 index 0000000..4746c22 --- /dev/null +++ b/src/main/c/emulator/src/trap.S @@ -0,0 +1,71 @@ + .section .init + .globl trapEntry + .type trapEntry,@function + +trapEntry: + csrrw sp, mscratch, sp + sw x0, 0*4(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 x0, 0*4(sp) + 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/src/main/scala/vexriscv/demo/Linux.scala b/src/main/scala/vexriscv/demo/Linux.scala index 8eea1ad..f2a84e8 100644 --- a/src/main/scala/vexriscv/demo/Linux.scala +++ b/src/main/scala/vexriscv/demo/Linux.scala @@ -40,7 +40,20 @@ make run DBUS=SIMPLE IBUS=SIMPLE DHRYSTONE=yes SUPERVISOR=yes CSR=yes COMPRESSED Run linux => sbt "runMain vexriscv.demo.LinuxGen" cd src/test/cpp/regression -make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes LITEX=yes VMLINUX=/home/spinalvm/hdl/linuxDave/vmlinux.bin RAMDISK=/home/spinalvm/hdl/linuxDave/initramdisk_dave TRACE=no +make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes LITEX=yes EMULATOR=/home/spinalvm/hdl/VexRiscv/src/main/c/emulator/build/emulator.bin VMLINUX=/home/spinalvm/hdl/linuxDave/vmlinux.bin DTB=/home/spinalvm/hdl/linuxDave/vmlinux/rv32.dtb RAMDISK=/home/spinalvm/hdl/linuxDave/initramdisk_dave TRACE=no + + + +Other commands (Memo): +cp litex_default_configuration .config +ARCH=riscv CROSS_COMPILE=riscv64-unknown-elf- make -j`nproc` +riscv64-unknown-elf-objcopy -O binary vmlinux vmlinux.bin +riscv64-unknown-elf-objdump -S -d vmlinux > vmlinux.asm + +split -b 1M vmlinux.asm +dtc -O dtb -o rv32.dtb rv32.dts +make run DBUS=SIMPLE IBUS=SIMPLE SUPERVISOR=yes CSR=yes COMPRESSED=yes LITEX=yes EMULATOR=/home/spinalvm/hdl/VexRiscv/src/main/c/emulator/build/emulator.bin VMLINUX=/home/spinalvm/hdl/riscv-linux/vmlinux.bin DTB=/home/spinalvm/hdl/riscv-linux/rv32.dtb RAMDISK=/home/spinalvm/hdl/linuxDave/initramdisk_dave TRACE=yes FLOW_INFO=yes TRACE_START=0000000 + */ object LinuxGen { @@ -188,7 +201,7 @@ object LinuxGen { ) if(withMmu) config.plugins += new MmuPlugin( virtualRange = a => True, - ioRange = (x => if(litex) x(31 downto 28) === 0xB || x(31 downto 28) === 0xE else x(31 downto 28) === 0xF), + ioRange = (x => if(litex) x(31 downto 28) === 0xB || x(31 downto 28) === 0xE || x(31 downto 28) === 0xF else x(31 downto 28) === 0xF), allowUserIo = true ) config @@ -324,10 +337,10 @@ object LinuxSyntesisBench extends App{ val targets = XilinxStdTargets( vivadoArtix7Path = "/eda/Xilinx/Vivado/2017.2/bin" - ) ++ AlteraStdTargets( + )/* ++ AlteraStdTargets( quartusCycloneIVPath = "/eda/intelFPGA_lite/17.0/quartus/bin", quartusCycloneVPath = "/eda/intelFPGA_lite/17.0/quartus/bin" - ) ++ IcestormStdTargets().take(1) + ) ++ IcestormStdTargets().take(1)*/ Bench(rtls, targets, "/eda/tmp") diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index c3e254f..35866b4 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -798,11 +798,17 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception } } + //Avoid having the fetch confused by the incomming privilege switch + when(hadException){ + fetcher.haltIt() + } + lastStage plug new Area{ import lastStage._ //Manage MRET / SRET instructions when(arbitration.isValid && input(ENV_CTRL) === EnvCtrlEnum.XRET) { + fetcher.haltIt() jumpInterface.valid := True beforeLastStage.arbitration.flushAll := True switch(input(INSTRUCTION)(29 downto 28)){ @@ -852,7 +858,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception } } - decode.arbitration.haltByOther setWhen(stagesFromExecute.dropRight(1).map(s => s.arbitration.isValid && s.input(ENV_CTRL) === EnvCtrlEnum.XRET).asBits.orR) + decode.arbitration.haltByOther setWhen(stagesFromExecute.map(s => s.arbitration.isValid && s.input(ENV_CTRL) === EnvCtrlEnum.XRET).asBits.orR) execute plug new Area { import execute._ diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index 86ba2d0..f5832ce 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -444,6 +444,12 @@ public: trap(interrupt, cause, true, value); } void trap(bool interrupt,int32_t cause, bool valueWrite, uint32_t value) { +#ifdef FLOW_INFO + cout << "TRAP " << (interrupt ? "interrupt" : "exception") << " cause=" << cause << " PC=0x" << hex << pc << " val=0x" << hex << value << dec << endl; + if(cause == 9){ + cout << hex << " a7=0x" << regs[17] << " a0=0x" << regs[10] << " a1=0x" << regs[11] << " a2=0x" << regs[12] << dec << endl; + } +#endif //Check leguality of the interrupt if(interrupt) { bool hit = false; @@ -493,8 +499,9 @@ public: if(!interrupt) step(); //As VexRiscv instruction which trap do not reach writeback stage fire } + uint32_t currentInstruction; void ilegalInstruction(){ - trap(0, 2); + trap(0, 2, currentInstruction); } virtual void fail() { @@ -684,6 +691,7 @@ public: return; } } + currentInstruction = i; if ((i & 0x3) == 0x3) { //32 bit switch (i & 0x7F) { @@ -1362,7 +1370,9 @@ public: currentTime = i; - + #ifdef FLOW_INFO + if(i % 100000 == 0) cout << "PROGRESS TRACE_START=" << i << endl; + #endif // dump variables into VCD file and toggle clock @@ -2876,6 +2886,13 @@ public: virtual void dBusAccess(uint32_t addr,bool wr, uint32_t size,uint32_t mask, uint32_t *data, bool *error) { switch(addr){ //TODO Emulate peripherals here + case 0xFFFFFFFC: fail(); break; //Simulation end + case 0xFFFFFFF8: + if(wr){ + cout << (char)*data; + logTraces << (char)*data; + } + break; } Workspace::dBusAccess(addr,wr,size,mask,data,error); @@ -3153,11 +3170,13 @@ int main(int argc, char **argv, char **env) { #ifdef LITEX LitexSoC("linux") .withRiscvRef() - ->loadBin(VMLINUX, 0xc0000000) - ->loadBin(RAMDISK, 0xc2000000) + ->loadBin(EMULATOR, 0x80000000) + ->loadBin(DTB, 0x81000000) + ->loadBin(VMLINUX, 0xc0000000) + ->loadBin(RAMDISK, 0xc2000000) ->setIStall(false) //TODO It currently improve speed but should be removed later ->setDStall(false) - ->bootAt(0xc0000000) + ->bootAt(0x80000000) ->run(0); return 1; #endif diff --git a/src/test/cpp/regression/makefile b/src/test/cpp/regression/makefile index f44cd59..86d5d52 100644 --- a/src/test/cpp/regression/makefile +++ b/src/test/cpp/regression/makefile @@ -52,9 +52,17 @@ endif ifeq ($(LITEX),yes) ADDCFLAGS += -CFLAGS -DLITEX ADDCFLAGS += -CFLAGS -DVMLINUX='\"$(VMLINUX)\"' + ADDCFLAGS += -CFLAGS -DDTB='\"$(DTB)\"' ADDCFLAGS += -CFLAGS -DRAMDISK='\"$(RAMDISK)\"' + ADDCFLAGS += -CFLAGS -DEMULATOR='\"$(EMULATOR)\"' endif +ifeq ($(FLOW_INFO),yes) + ADDCFLAGS += -CFLAGS -DFLOW_INFO +endif + + + ifneq ($(shell grep timerInterrupt ../../../../VexRiscv.v -w),) ADDCFLAGS += -CFLAGS -DTIMER_INTERRUPT endif