diff --git a/cpu/riscv.c b/cpu/riscv.c index b406e2b..b527091 100644 --- a/cpu/riscv.c +++ b/cpu/riscv.c @@ -457,6 +457,9 @@ void ins_xori(riscv_t* riscv, int rs1, int imm, int rd) { _imm |= (_ins >> 25) << 5;\ } + #define imm_csr(_ins,_imm) {\ + _imm = (_ins >> 20) & 0xfff;\ + } // 解析指令 int riscv_decode(riscv_t* riscv, uint32_t ins) { @@ -488,8 +491,179 @@ int riscv_decode(riscv_t* riscv, uint32_t ins) { ins_jalr(riscv, rs1, imm, rd); break; case opcode_beq: - + imm_b_type(ins, imm); + switch(funct3) { + case 0x0: + ins_beq(riscv, rs2, rs1, imm); + break; + case 0x1: + ins_bne(riscv, rs2, rs1, imm); + break; + case 0x4: + ins_blt(riscv, rs2, rs1, imm); + break; + case 0x5: + ins_bge(riscv, rs2, rs1, imm); + break; + case 0x6: + ins_bltu(riscv, rs2, rs1, imm); + break; + case 0x7: + ins_bgeu(riscv, rs2, rs1, imm); + break; + default: + break; + } + break; + case opcode_lb: + imm_i_type(imm, ins); + switch (funct3) + { + case 0x0: + ins_lb(riscv, rs1, imm, rd); + break; + case 0x1: + ins_lh(riscv, rs1, imm, rd); + break; + case 0x2: + ins_lw(riscv, rs1, imm, rd); + break; + case 0x4: + ins_lbu(riscv, rs1, imm, rd); + break; + case 0x5: + ins_lhu(riscv, rs1, imm, rd); + break; + default: + break; + } + break; + case opcode_sb: + switch(funct3){ + case 0x0: + ins_sb(riscv, rs2, rs1, imm); + break; + case 0x1: + ins_sh(riscv, rs2, rs1, imm); + break; + case 0x2: + ins_sw(riscv, rs2, rs1, imm); + break; + default: + break; + } + break; + case opcode_addi: + imm_i_type(ins,imm); + switch (funct3) + { + case 0x0: + ins_addi(riscv, rs1, imm, rd); + break; + case 0x2: + ins_slti(riscv, rs1, imm, rd); + break; + case 0x3: + ins_sltiu(riscv, rs1, imm, rd); + break; + case 0x4: + ins_xori(riscv, rs1, imm, rd); + break; + case 0x6: + ins_ori(riscv, rs1, imm, rd); + break; + case 0x7: + ins_andi(riscv, rs1, imm, rd); + break; + case 0x1: + imm = imm&0x1f; + ins_slli(riscv, rs1, imm, rd); + break; + case 0x5: + imm = imm&0x1f; + if(funct7 == 0x20){ + ins_srai(riscv, rs1, imm, rd); + }else{ + ins_srli(riscv, rs1, imm, rd); + } + break; + default: + break; + } + break; + case opcode_add: + switch (funct3) + { + case 0x0: + if(funct7 == 0x20){ + ins_sub(riscv, rs2, rs1, rd); + }else{ + ins_add(riscv, rs2, rs1, rd); + } + break; + case 0x1: + ins_sll(riscv, rs2, rs1, rd); + break; + case 0x2: + ins_slt(riscv, rs2, rs1, rd); + break; + case 0x3: + ins_sltu(riscv, rs2, rs1, rd); + break; + case 0x4: + ins_xor(riscv, rs2, rs1, rd); + break; + case 0x5: + if (funct7 == 0x20) { + ins_sra(riscv, rs2, rs1, rd); + }else{ + ins_srl(riscv, rs2, rs1, rd); + } + break; + case 0x6: + ins_or(riscv, rs2, rs1, rd); + break; + case 0x7: + ins_and(riscv, rs2, rs1, rd); + break; + default: + break; + } + break; + case opcode_ecall: + imm_csr(ins,imm); + switch (funct3) + { + case 0x0: + ins_ebreak(riscv); + break; + case 0x1: + ins_csrrw(riscv, rs1, rd, imm); + break; + case 0x2: + ins_csrrs(riscv, rs1, rd, imm); + break; + case 0x3: + ins_csrrc(riscv, rs1, rd, imm); + break; + case 0x5: + // rs1 保存的是zimm 值 + ins_csrrwi(riscv, rs1, rd, imm); + break; + case 0x6: + ins_csrrsi(riscv, rs1, rd, imm); + break; + case 0x7: + ins_csrrci(riscv, rs1, rd, imm); + break; + default: + break; + } + break; + default: + break; } + return 0; } int riscv_init(riscv_t* riscv, uint32_t* rom, uint32_t rom_addr_base, uint32_t rom_size) { @@ -498,3 +672,65 @@ int riscv_init(riscv_t* riscv, uint32_t* rom, uint32_t rom_addr_base, uint32_t r riscv->rom_addr_base = rom_addr_base; riscv->pc = 0; } + + +int riscv_run(riscv_t* riscv) { + int ret = 0; + while(1) { + uint32_t instr = riscv->rom[riscv->pc >> 2]; + riscv->pc += 4; + if(riscv->pc >= riscv->rom_addr_base + riscv->rom_size){ + printf("riscv run out of rom"); + break; + } + ret=riscv_decode(riscv, instr); + if(ret){ + break; + } + } + printf("riscv run end\n"); +} + +#include "stdio.h" +#include "stdlib.h" +#include "errno.h" + +long get_file_size(FILE *stream) +{ + long file_size = -1; + long cur_offset = ftell(stream); // 获取当前偏移位置 + if (cur_offset == -1) { + printf("ftell failed :%s\n", strerror(errno)); + return -1; + } + if (fseek(stream, 0, SEEK_END) != 0) { // 移动文件指针到文件末尾 + printf("fseek failed: %s\n", strerror(errno)); + return -1; + } + file_size = ftell(stream); // 获取此时偏移值,即文件大小 + if (file_size == -1) { + printf("ftell failed :%s\n", strerror(errno)); + } + if (fseek(stream, cur_offset, SEEK_SET) != 0) { // 将文件指针恢复初始位置 + printf("fseek failed: %s\n", strerror(errno)); + return -1; + } + return file_size; +} + +int thread_fun(void* t) +{ + riscv_t riscv={0}; + FILE *file=fopen("riscv.bin", "rb" ); + if(file==NULL) + { + printf("open file error\n"); + return -1; + } + riscv.rom_size=get_file_size(file); + riscv.rom=calloc((riscv.rom_size+3)/4,4); + fread(riscv.rom, 1, riscv.rom_size, file); + fclose(file); + + riscv_init(&riscv,riscv.rom,0x80000000,riscv.rom_size); +} diff --git a/make.py b/make.py index 66ba86c..d9eb432 100644 --- a/make.py +++ b/make.py @@ -23,9 +23,9 @@ CC = 'gcc' # HEX = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O ihex' # BIN = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O binary -S' -CSRC = [] +CSRC = ["main.c"] -CINC = ['-Isoft'] +CINC = ['-Isoft',"-Icpu"] CDEF = ["-DTEST","-DLINUX"] @@ -184,7 +184,8 @@ def build_target(src:list[str]): def main(): global CSRC global ASRC - CSRC+=find_type('.\\',['c','C']) + CSRC+=find_type('.\\soft',['c','C']) + CSRC+=find_type('.\\cpu',['c','C']) # ASRC+=find_type('./',['s','S','asm','ASM']) if(not os.path.exists(BUILD_DIR)): diff --git a/make_riscv.py b/make_riscv.py new file mode 100644 index 0000000..6b79599 --- /dev/null +++ b/make_riscv.py @@ -0,0 +1,37 @@ + +import os +import sys +import time + + + + + +CC="riscv64-unknown-elf-gcc" +OBJ="riscv64-unknown-elf-objcopy" + +CFLAG=[ + "-march=rv32i", + "-mabi=ilp32", + "-ffunction-sections", + "-fdata-sections", + "-ffast-math", + "-fno-common", + "-fno-builtin-printf", + "-Wall", + "-Werror", + "-g", + "-Os", + "-fno-omit-frame-pointer", + "-msave-restore" +] + +SRC=[ + "riscv/main.c" +] + +TARGET="riscv" + +if __name__ == "__main__": + os.system(f"{CC} {' '.join(CFLAG)} {' '.join(SRC)} -o {TARGET}.elf") + os.system(f"{OBJ} -O binary {TARGET}.elf {TARGET}.bin") diff --git a/riscv/main.c b/riscv/main.c new file mode 100644 index 0000000..50ff107 --- /dev/null +++ b/riscv/main.c @@ -0,0 +1,10 @@ + + + +int main() +{ + int a=1; + int b=2; + int c=a+b; + return c; +} \ No newline at end of file