模拟cpu成功运行
This commit is contained in:
20
cpu/riscv.c
20
cpu/riscv.c
@@ -90,7 +90,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define MEM_SIZE 1024*1024
|
#define MEM_SIZE 1024*1024
|
||||||
#define MEM_ADDR_BASE 0x100000000
|
#define MEM_ADDR_BASE 0x10000000
|
||||||
|
|
||||||
#define zero reg[0]
|
#define zero reg[0]
|
||||||
#define ra reg[1]
|
#define ra reg[1]
|
||||||
@@ -670,20 +670,24 @@ int riscv_init(riscv_t* riscv, uint32_t* rom, uint32_t rom_addr_base, uint32_t r
|
|||||||
riscv->rom = rom;
|
riscv->rom = rom;
|
||||||
riscv->rom_size = rom_size;
|
riscv->rom_size = rom_size;
|
||||||
riscv->rom_addr_base = rom_addr_base;
|
riscv->rom_addr_base = rom_addr_base;
|
||||||
riscv->pc = 0;
|
riscv->pc = riscv->rom_addr_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int riscv_run(riscv_t* riscv) {
|
int riscv_run(riscv_t* riscv) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
while(1) {
|
while(1) {
|
||||||
uint32_t instr = riscv->rom[riscv->pc >> 2];
|
uint32_t instr = riscv->rom[(riscv->pc-riscv->rom_addr_base) >> 2];
|
||||||
|
printf("pc: %08x instr: %08x\n", riscv->pc, instr);
|
||||||
riscv->pc += 4;
|
riscv->pc += 4;
|
||||||
if(riscv->pc >= riscv->rom_addr_base + riscv->rom_size){
|
if(riscv->pc >= riscv->rom_addr_base + riscv->rom_size){
|
||||||
printf("riscv run out of rom");
|
printf("riscv run out of rom\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret=riscv_decode(riscv, instr);
|
ret=riscv_decode(riscv, instr);
|
||||||
|
for (int i = 0;i < 32;i++) {
|
||||||
|
printf("reg[%d]: %08x\n", i, riscv->reg[i]);
|
||||||
|
}
|
||||||
if(ret){
|
if(ret){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -729,12 +733,14 @@ int thread_fun(void* t)
|
|||||||
printf("open file error\n");
|
printf("open file error\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
riscv.rom_size=get_file_size(file);
|
riscv.rom_size = get_file_size(file);
|
||||||
riscv.rom=calloc((riscv.rom_size+3)/4,4);
|
printf("rom size: %d\n", riscv.rom_size);
|
||||||
|
riscv.rom = calloc((riscv.rom_size + 3) / 4, 4);
|
||||||
fread(riscv.rom, 1, riscv.rom_size, file);
|
fread(riscv.rom, 1, riscv.rom_size, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
riscv_init(&riscv,riscv.rom,0x80000000,riscv.rom_size);
|
riscv_init(&riscv, riscv.rom, 0x80000000, riscv.rom_size);
|
||||||
|
riscv_run(&riscv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,8 @@ import time
|
|||||||
|
|
||||||
|
|
||||||
CC="riscv64-unknown-elf-gcc"
|
CC="riscv64-unknown-elf-gcc"
|
||||||
OBJ="riscv64-unknown-elf-objcopy"
|
OBJCPY="riscv64-unknown-elf-objcopy"
|
||||||
|
OBJDUMP="riscv64-unknown-elf-objdump"
|
||||||
|
|
||||||
CFLAG=[
|
CFLAG=[
|
||||||
"-march=rv32i",
|
"-march=rv32i",
|
||||||
@@ -27,11 +28,15 @@ CFLAG=[
|
|||||||
]
|
]
|
||||||
|
|
||||||
SRC=[
|
SRC=[
|
||||||
"riscv/main.c"
|
"riscv/main.c",
|
||||||
|
"riscv/start.S"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
LD_FILE="riscv.ld"
|
||||||
|
|
||||||
TARGET="riscv"
|
TARGET="riscv"
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
os.system(f"{CC} {' '.join(CFLAG)} {' '.join(SRC)} -o {TARGET}.elf")
|
os.system(f"{CC} {' '.join(CFLAG)} {' '.join(SRC)} -T{LD_FILE} -Wall -Wextra -nostartfiles -Wl,-Map,\"{TARGET}.map\" -o {TARGET}.elf")
|
||||||
os.system(f"{OBJ} -O binary {TARGET}.elf {TARGET}.bin")
|
os.system(f"{OBJCPY} -O binary {TARGET}.elf {TARGET}.bin")
|
||||||
|
os.system(f"{OBJDUMP} -d {TARGET}.elf > {TARGET}.lst")
|
||||||
|
153
riscv.ld
Normal file
153
riscv.ld
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
|
||||||
|
ENTRY( _start )
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
flash (rxai!w) : ORIGIN = 0x80000000, LENGTH = 1024K
|
||||||
|
dram (wxa!ri) : ORIGIN = 0x10000000, LENGTH = 1024K
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
|
||||||
|
|
||||||
|
.init :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.init)))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.text .text.*)
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.fini :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.fini)))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
PROVIDE (__etext = .);
|
||||||
|
PROVIDE (_etext = .);
|
||||||
|
PROVIDE (etext = .);
|
||||||
|
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
*(.rdata)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
.preinit_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.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 = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.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 = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.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))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dtors :
|
||||||
|
{
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*crtbegin?.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.lalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data_lma = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data = . );
|
||||||
|
} >dram AT>flash
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
PROVIDE( _gp = . + 0x800 );
|
||||||
|
*(.srodata.cst16)
|
||||||
|
*(.srodata.cst8)
|
||||||
|
*(.srodata.cst4)
|
||||||
|
*(.srodata.cst2)
|
||||||
|
*(.srodata .srodata.*)
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
} >dram AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _edata = . );
|
||||||
|
PROVIDE( edata = . );
|
||||||
|
|
||||||
|
PROVIDE( _fbss = . );
|
||||||
|
PROVIDE( __bss_start = . );
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
*(.sbss*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >dram AT>dram
|
||||||
|
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( _end = . );
|
||||||
|
PROVIDE( end = . );
|
||||||
|
PROVIDE( _heap_start = . );
|
||||||
|
|
||||||
|
.stack ORIGIN(dram) + LENGTH(dram) - __stack_size :
|
||||||
|
{
|
||||||
|
PROVIDE( _heap_end = . );
|
||||||
|
. = __stack_size;
|
||||||
|
PROVIDE( _sp = . );
|
||||||
|
} >dram AT>dram
|
||||||
|
}
|
8
riscv/start.S
Normal file
8
riscv/start.S
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
.section .init
|
||||||
|
.globl _start
|
||||||
|
.type _start,@function
|
||||||
|
|
||||||
|
_start:
|
||||||
|
|
||||||
|
la sp, _sp
|
Reference in New Issue
Block a user