mirror of
https://github.com/SpinalHDL/VexRiscv.git
synced 2025-01-03 03:43:39 -05:00
Machine mode emulator
This commit is contained in:
parent
e28702eb40
commit
9d55283b3b
16 changed files with 1255 additions and 10 deletions
151
src/main/c/common/ram.ld
Executable file
151
src/main/c/common/ram.ld
Executable file
|
@ -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
|
||||
}
|
16
src/main/c/common/riscv64-unknown-elf.mk
Normal file
16
src/main/c/common/riscv64-unknown-elf.mk
Normal file
|
@ -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
|
||||
|
74
src/main/c/common/standalone.mk
Normal file
74
src/main/c/common/standalone.mk
Normal file
|
@ -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)
|
4
src/main/c/emulator/.gitignore
vendored
Normal file
4
src/main/c/emulator/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
*.map
|
||||
*.v
|
||||
*.elf
|
||||
*.o
|
509
src/main/c/emulator/build/emulator.asm
Normal file
509
src/main/c/emulator/build/emulator.asm
Normal file
|
@ -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 <init>
|
||||
la ra, done
|
||||
80000060: 00000097 auipc ra,0x0
|
||||
80000064: 01408093 addi ra,ra,20 # 80000074 <done>
|
||||
li a0, DTB
|
||||
80000068: 81000537 lui a0,0x81000
|
||||
li a1, 0
|
||||
8000006c: 00000593 li a1,0
|
||||
mret
|
||||
80000070: 30200073 mret
|
||||
|
||||
80000074 <done>:
|
||||
done:
|
||||
j done
|
||||
80000074: 0000006f j 80000074 <done>
|
||||
|
||||
80000078 <_init>:
|
||||
|
||||
|
||||
.globl _init
|
||||
_init:
|
||||
ret
|
||||
80000078: 00008067 ret
|
||||
|
||||
8000007c <trapEntry>:
|
||||
.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 <trap>
|
||||
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 <init>:
|
||||
|
||||
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 <readRegister>:
|
||||
|
||||
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 <writeRegister>:
|
||||
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 <stopSim>:
|
||||
|
||||
|
||||
void stopSim(){
|
||||
*((volatile int*) SIM_STOP) = 0;
|
||||
800001f0: fe002e23 sw zero,-4(zero) # fffffffc <_sp+0x7ffff34c>
|
||||
}
|
||||
800001f4: 00008067 ret
|
||||
|
||||
800001f8 <putC>:
|
||||
|
||||
void putC(char c){
|
||||
*((volatile int*) PUTC) = c;
|
||||
800001f8: fea02c23 sw a0,-8(zero) # fffffff8 <_sp+0x7ffff348>
|
||||
}
|
||||
800001fc: 00008067 ret
|
||||
|
||||
80000200 <redirectTrap>:
|
||||
|
||||
|
||||
void redirectTrap(){
|
||||
80000200: ff010113 addi sp,sp,-16
|
||||
80000204: 00112623 sw ra,12(sp)
|
||||
stopSim();
|
||||
80000208: fe9ff0ef jal ra,800001f0 <stopSim>
|
||||
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 <trap>:
|
||||
#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 <trap+0x50>
|
||||
redirectTrap();
|
||||
} else {
|
||||
switch(cause){
|
||||
80000250: 00200713 li a4,2
|
||||
80000254: 02e78a63 beq a5,a4,80000288 <trap+0x58>
|
||||
80000258: 00900713 li a4,9
|
||||
8000025c: 10e78863 beq a5,a4,8000036c <trap+0x13c>
|
||||
csr_write(mepc, csr_read(mepc) + 4);
|
||||
}break;
|
||||
default: stopSim(); break;
|
||||
}
|
||||
}break;
|
||||
default: redirectTrap(); break;
|
||||
80000260: fa1ff0ef jal ra,80000200 <redirectTrap>
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
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 <redirectTrap>
|
||||
80000284: fe1ff06f j 80000264 <trap+0x34>
|
||||
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 <trap+0x34>
|
||||
switch(funct3){
|
||||
800002a0: 00200713 li a4,2
|
||||
800002a4: 0ce79063 bne a5,a4,80000364 <trap+0x134>
|
||||
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 <readRegister>
|
||||
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 <readRegister>
|
||||
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 <trap+0x12c>
|
||||
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 <writeRegister>
|
||||
*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 <trap+0x34>
|
||||
case 0x4: writeValue = src ^ readValue; break;
|
||||
80000314: 00b94933 xor s2,s2,a1
|
||||
80000318: fe5ff06f j 800002fc <trap+0xcc>
|
||||
case 0xC: writeValue = src & readValue; break;
|
||||
8000031c: 00b97933 and s2,s2,a1
|
||||
80000320: fddff06f j 800002fc <trap+0xcc>
|
||||
case 0x8: writeValue = src | readValue; break;
|
||||
80000324: 00b96933 or s2,s2,a1
|
||||
80000328: fd5ff06f j 800002fc <trap+0xcc>
|
||||
case 0x10: writeValue = min(src, readValue); break;
|
||||
8000032c: fd25d8e3 ble s2,a1,800002fc <trap+0xcc>
|
||||
80000330: 00058913 mv s2,a1
|
||||
80000334: fc9ff06f j 800002fc <trap+0xcc>
|
||||
case 0x14: writeValue = max(src, readValue); break;
|
||||
80000338: fcb952e3 ble a1,s2,800002fc <trap+0xcc>
|
||||
8000033c: 00058913 mv s2,a1
|
||||
80000340: fbdff06f j 800002fc <trap+0xcc>
|
||||
case 0x18: writeValue = min((unsigned int)src, (unsigned int)readValue); break;
|
||||
80000344: fb25fce3 bleu s2,a1,800002fc <trap+0xcc>
|
||||
80000348: 00058913 mv s2,a1
|
||||
8000034c: fb1ff06f j 800002fc <trap+0xcc>
|
||||
case 0x1C: writeValue = max((unsigned int)src, (unsigned int)readValue); break;
|
||||
80000350: fab976e3 bleu a1,s2,800002fc <trap+0xcc>
|
||||
80000354: 00058913 mv s2,a1
|
||||
80000358: fa5ff06f j 800002fc <trap+0xcc>
|
||||
default: redirectTrap(); return; break;
|
||||
8000035c: ea5ff0ef jal ra,80000200 <redirectTrap>
|
||||
80000360: f05ff06f j 80000264 <trap+0x34>
|
||||
default: redirectTrap(); break;
|
||||
80000364: e9dff0ef jal ra,80000200 <redirectTrap>
|
||||
80000368: efdff06f j 80000264 <trap+0x34>
|
||||
int which = readRegister(17);
|
||||
8000036c: 01100513 li a0,17
|
||||
80000370: e51ff0ef jal ra,800001c0 <readRegister>
|
||||
switch(which){
|
||||
80000374: 00100793 li a5,1
|
||||
80000378: 02f51263 bne a0,a5,8000039c <trap+0x16c>
|
||||
putC(readRegister(10));
|
||||
8000037c: 00a00513 li a0,10
|
||||
80000380: e41ff0ef jal ra,800001c0 <readRegister>
|
||||
80000384: 0ff57513 andi a0,a0,255
|
||||
80000388: e71ff0ef jal ra,800001f8 <putC>
|
||||
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 <trap+0x34>
|
||||
default: stopSim(); break;
|
||||
8000039c: e55ff0ef jal ra,800001f0 <stopSim>
|
||||
800003a0: ec5ff06f j 80000264 <trap+0x34>
|
||||
|
||||
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>
|
80
src/main/c/emulator/build/emulator.hex
Normal file
80
src/main/c/emulator/build/emulator.hex
Normal file
|
@ -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
|
17
src/main/c/emulator/makefile
Executable file
17
src/main/c/emulator/makefile
Executable file
|
@ -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
|
||||
|
10
src/main/c/emulator/src/config.h
Normal file
10
src/main/c/emulator/src/config.h
Normal file
|
@ -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
|
109
src/main/c/emulator/src/main.c
Executable file
109
src/main/c/emulator/src/main.c
Executable file
|
@ -0,0 +1,109 @@
|
|||
#include <stdint.h>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
107
src/main/c/emulator/src/riscv.h
Normal file
107
src/main/c/emulator/src/riscv.h
Normal file
|
@ -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
|
||||
|
||||
|
51
src/main/c/emulator/src/start.S
Executable file
51
src/main/c/emulator/src/start.S
Executable file
|
@ -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
|
71
src/main/c/emulator/src/trap.S
Normal file
71
src/main/c/emulator/src/trap.S
Normal file
|
@ -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
|
|
@ -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")
|
||||
|
|
|
@ -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._
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue