#include "riscv.h" #include "debug.h" #include "stdio.h" #include "stdlib.h" #include "errno.h" #include "string.h" #include "../main.h" #define device_write(riscv,addr,value) \ for (int i = 0;i < riscv->device_num;i++) {\ if (riscv->device_list[i] && riscv->device_list[i]->write) {\ if(addr>=riscv->device_list[i]->addr && addrdevice_list[i]->addr+riscv->device_list[i]->size) {\ riscv->device_list[i]->write(addr, value);\ return;\ }\ }\ } #define device_read(riscv,addr,ret) \ for (int i = 0;i < riscv->device_num;i++) {\ if (riscv->device_list[i] && riscv->device_list[i]->read) {\ if(addr>=riscv->device_list[i]->addr && addrdevice_list[i]->addr+riscv->device_list[i]->size) {\ ret=riscv->device_list[i]->read(addr);\ return ret;\ }\ }\ } int riscv_print(riscv_t* riscv) { printf("x0(zero): %08x\n", riscv->zero); printf("x1(ra): %08x\n", riscv->ra); printf("x2(sp): %08x\n", riscv->sp); printf("x3(gp): %08x\n", riscv->gp); printf("x4(tp): %08x\n", riscv->tp); printf("x5(t0): %08x\n", riscv->t0); printf("x6(t1): %08x\n", riscv->t1); printf("x7(t2): %08x\n", riscv->t2); printf("x8(s0|fp): %08x\n", riscv->fp); printf("x9(s1): %08x\n", riscv->s1); printf("x10(a0): %08x\n", riscv->a0); printf("x11(a1): %08x\n", riscv->a1); printf("x12(a2): %08x\n", riscv->a2); printf("x13(a3): %08x\n", riscv->a3); printf("x14(a4): %08x\n", riscv->a4); printf("x15(a5): %08x\n", riscv->a5); printf("x16(a6): %08x\n", riscv->a6); printf("x17(a7): %08x\n", riscv->a7); printf("x18(s2): %08x\n", riscv->s2); printf("x19(s3): %08x\n", riscv->s3); printf("x20(s4): %08x\n", riscv->s4); printf("x21(s5): %08x\n", riscv->s5); printf("x22(s6): %08x\n", riscv->s6); printf("x23(s7): %08x\n", riscv->s7); printf("x24(s8): %08x\n", riscv->s8); printf("x25(s9): %08x\n", riscv->s9); printf("x26(s10): %08x\n", riscv->s10); printf("x27(s11): %08x\n", riscv->s11); printf("x28(t3): %08x\n", riscv->t3); printf("x29(t4): %08x\n", riscv->t4); printf("x30(t5): %08x\n", riscv->t5); printf("x31(t6): %08x\n", riscv->t6); return 0; } void mem_w_write(riscv_t * riscv, uint32_t addr, uint32_t value) { if (addr & 0x3) { riscv->exc_code = 6; riscv->mtval = addr; return; } if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) { mem_wr(addr) = value; } else { device_write(riscv, addr, value); riscv->exc_code = 7; riscv->mtval = addr; } } void mem_wh_write(riscv_t* riscv, uint32_t addr, uint16_t value) { if (addr & 0x1) { riscv->exc_code = 6; riscv->mtval = addr; return; } if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) { mem_wrh(addr) = value; } else { device_write(riscv, addr, value); riscv->exc_code = 7; riscv->mtval = addr; } } void mem_wb_write(riscv_t* riscv, uint32_t addr, uint8_t value) { if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) { mem_wrb(addr) = value; } else { device_write(riscv, addr, value); riscv->exc_code = 7; riscv->mtval = addr; } } uint32_t mem_w_read(riscv_t* riscv, uint32_t addr) { uint32_t ret = 0xaaaaaaaa; if (addr & 0x3) { riscv->exc_code = 4; riscv->mtval = addr; printf("unaligned access addr:%08x\n", addr); return ret; } if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) { ret = mem_wr(addr); } else if (addr>=riscv->rom_addr_base && addrrom_addr_base+riscv->rom_size){ ret = rom_wr(addr); } else { device_read(riscv, addr, ret); riscv->exc_code = 5; riscv->mtval = addr; printf("error addr:%08x\n", addr); } return ret; } uint16_t mem_wh_read(riscv_t* riscv, uint32_t addr) { uint16_t ret = 0xaaaa; if (addr & 0x1) { riscv->exc_code = 4; riscv->mtval = addr; return ret; } if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) { ret = mem_wrh(addr); } else if (addr>=riscv->rom_addr_base && addrrom_addr_base+riscv->rom_size){ ret = rom_wrh(addr); } else { device_read(riscv, addr, ret); riscv->exc_code = 5; riscv->mtval = addr; } return ret; } uint8_t mem_wb_read(riscv_t* riscv, uint32_t addr) { uint8_t ret = 0xaa; // printf("read addr=%08x\n", addr); if (addr >= MEM_ADDR_BASE && addr < MEM_ADDR_BASE + MEM_SIZE) { ret = mem_wrb(addr); } else if (addr>=riscv->rom_addr_base && addrrom_addr_base+riscv->rom_size){ ret = rom_wrb(addr); } else { device_read(riscv, addr, ret); riscv->exc_code = 5; riscv->mtval = addr; } return ret; } void ins_add(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] + riscv->reg[rs2]; } void ins_addi(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = (int)riscv->reg[rs1] + imm; } void ins_addiw(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = riscv->reg[rs1] + imm; } void ins_addw(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] + riscv->reg[rs2]; } void ins_and(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] & riscv->reg[rs2]; } void ins_andi(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = riscv->reg[rs1] & imm; } // 设置pc指针高位地址 void ins_auipc(riscv_t* riscv, int imm, int rd) { riscv->reg[rd] = riscv->pc + imm; } void ins_beq(riscv_t* riscv, int rs2, int rs1, int imm) { if (riscv->reg[rs1] == riscv->reg[rs2]) { riscv->pc += imm; riscv->pc_modify = 1; } } void ins_bge(riscv_t* riscv, int rs2, int rs1, int imm) { if ((int)riscv->reg[rs1] >= (int)riscv->reg[rs2]) { riscv->pc += imm; riscv->pc_modify = 1; } } void ins_bgeu(riscv_t* riscv, int rs2, int rs1, int imm) { if (riscv->reg[rs1] >= riscv->reg[rs2]) { riscv->pc += imm; riscv->pc_modify = 1; } } void ins_blt(riscv_t* riscv, int rs2, int rs1, int imm) { if ((int)riscv->reg[rs1] < (int)riscv->reg[rs2]) { riscv->pc += imm; riscv->pc_modify = 1; } } void ins_bltu(riscv_t* riscv, int rs2, int rs1, int imm) { if (riscv->reg[rs1] < riscv->reg[rs2]) { riscv->pc += imm; riscv->pc_modify = 1; } } void ins_bne(riscv_t* riscv, int rs2, int rs1, int imm) { // printf("bne %d %d imm=%08x\n", rs2, rs1, imm); if (riscv->reg[rs1] != riscv->reg[rs2]) { riscv->pc += imm; riscv->pc_modify = 1; } } // 读后清除 void ins_csrrc(riscv_t* riscv, int rs1, int rd, int csr) { uint32_t t = riscv->csrs[csr]; riscv->csrs[csr] = riscv->csrs[csr] & ~riscv->reg[rs1]; riscv->reg[rd] = t; } void ins_csrrs(riscv_t* riscv, int rs1, int rd, int csr) { uint32_t t = riscv->csrs[csr]; riscv->csrs[csr] = riscv->csrs[csr] | riscv->reg[rs1]; riscv->reg[rd] = t; } void ins_csrrw(riscv_t* riscv, int rs1, int rd, int csr) { uint32_t t = riscv->csrs[csr]; riscv->csrs[csr] = riscv->reg[rs1]; riscv->reg[rd] = t; } void ins_csrrci(riscv_t* riscv, int imm, int rd, int csr) { uint32_t t = riscv->csrs[csr]; riscv->csrs[csr] = riscv->csrs[csr] & ~imm; riscv->reg[rd] = t; } void ins_csrrsi(riscv_t* riscv, int imm, int rd, int csr) { uint32_t t = riscv->csrs[csr]; riscv->csrs[csr] = riscv->csrs[csr] | imm; riscv->reg[rd] = t; } void ins_csrrwi(riscv_t* riscv, int imm, int rd, int csr) { uint32_t t = riscv->csrs[csr]; riscv->csrs[csr] = imm; riscv->reg[rd] = t; } void ins_ecall(riscv_t* riscv) { printf("ecall\n"); } void ins_ebreak(riscv_t* riscv) { printf("ebreak\n"); } void ins_jal(riscv_t* riscv, int imm, int rd) { riscv->reg[rd] = riscv->pc + 4; riscv->pc += imm; riscv->pc_modify = 1; } void ins_jalr(riscv_t* riscv, int rs1, int imm, int rd) { uint32_t t; t = riscv->pc + 4; riscv->pc = (riscv->reg[rs1] + imm) & (~1); riscv->reg[rd] = t; riscv->pc_modify = 1; } void ins_lb(riscv_t* riscv, int rs1, int imm, int rd) { uint32_t addr = riscv->reg[rs1] + imm; // printf("lb %08x,imm=%d\n",addr,imm); uint32_t r=mem_wb_read(riscv, addr); if(r&(0x80)){ r|=0xffffff00; } riscv->reg[rd] = r; } void ins_lbu(riscv_t* riscv, int rs1, int imm, int rd) { uint32_t addr = riscv->reg[rs1] + imm; // printf("lbu %08x,imm=%d\n",addr,imm); riscv->reg[rd] = mem_wb_read(riscv, addr); } void ins_lh(riscv_t* riscv, int rs1, int imm, int rd) { uint32_t addr = riscv->reg[rs1] + imm; // printf("lh %08x,imm=%d\n",addr,imm); uint32_t r=mem_wh_read(riscv, addr); if(r&(0x8000)){ r|=0xffff0000; } riscv->reg[rd] = r; } void ins_lhu(riscv_t* riscv, int rs1, int imm, int rd) { uint32_t addr = riscv->reg[rs1] + imm; // printf("lhu %08x,imm=%d\n",addr,imm); riscv->reg[rd] = mem_wh_read(riscv, addr); } void ins_lw(riscv_t* riscv, int rs1, int imm, int rd) { uint32_t addr = riscv->reg[rs1] + imm; // printf("lw %08x,imm=%d\n",addr,imm); riscv->reg[rd] = (int)mem_w_read(riscv, addr); } void ins_lwu(riscv_t* riscv, int rs1, int imm, int rd) { uint32_t addr = riscv->reg[rs1] + imm; // printf("lwu %08x,imm=%d\n",addr,imm); riscv->reg[rd] = mem_w_read(riscv, addr); } void ins_lui(riscv_t* riscv, int imm, int rd) { riscv->reg[rd] = imm; } void ins_mret(riscv_t* riscv) { riscv->pc = riscv->mepc; riscv->pc_modify = 1; if (riscv->mstatus & MSTATUS_MPIE) { riscv->mstatus &= ~MSTATUS_MPIE; riscv->mstatus |= MSTATUS_MIE; } else { riscv->mstatus &= ~MSTATUS_MIE; } // printf("mret: pc=%08x\n", riscv->pc); } void ins_or(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] | riscv->reg[rs2]; } void ins_ori(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = riscv->reg[rs1] | imm; } void ins_sb(riscv_t* riscv, int rs2, int rs1, int imm) { uint32_t addr = riscv->reg[rs1] + imm; // printf("sb %08x,imm=%d\n",addr,imm); mem_wb_write(riscv, addr, riscv->reg[rs2]); } void ins_sh(riscv_t* riscv, int rs2, int rs1, int imm) { uint32_t addr = riscv->reg[rs1] + imm; // printf("sh %08x,imm=%d\n",addr,imm); mem_wh_write(riscv, addr, riscv->reg[rs2]); } void ins_sw(riscv_t* riscv, int rs2, int rs1, int imm) { uint32_t addr = riscv->reg[rs1] + imm; // printf("sw %08x,imm=%d\n",addr,imm); mem_w_write(riscv, addr, riscv->reg[rs2]); } void ins_sll(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] << riscv->reg[rs2]; } void ins_slli(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = riscv->reg[rs1] << imm; } void ins_slliw(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = riscv->reg[rs1] << imm; } void ins_sllw(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] << riscv->reg[rs2]; } void ins_slt(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = (int)riscv->reg[rs1] < (int)riscv->reg[rs2]; } void ins_slti(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = (int)riscv->reg[rs1] < imm; } void ins_sltiu(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = riscv->reg[rs1] < (uint32_t)imm; } void ins_sltu(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] < riscv->reg[rs2]; } void ins_sra(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = (int)riscv->reg[rs1] >> riscv->reg[rs2]; } void ins_srai(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = (int)riscv->reg[rs1] >> imm; } void ins_sraiw(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = (int)riscv->reg[rs1] >> imm; } void ins_sraw(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = (int)riscv->reg[rs1] >> riscv->reg[rs2]; } void ins_srl(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] >> riscv->reg[rs2]; } void ins_srli(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = riscv->reg[rs1] >> imm; } void ins_srliw(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = riscv->reg[rs1] >> imm; } void ins_srlw(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] >> riscv->reg[rs2]; } void ins_sub(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] - riscv->reg[rs2]; } void ins_subw(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] - riscv->reg[rs2]; } void ins_wfi(riscv_t* riscv) { printf("wfi\n"); } void ins_xor(riscv_t* riscv, int rs2, int rs1, int rd) { riscv->reg[rd] = riscv->reg[rs1] ^ riscv->reg[rs2]; } void ins_xori(riscv_t* riscv, int rs1, int imm, int rd) { riscv->reg[rd] = riscv->reg[rs1] ^ imm; } // 解析指令 int riscv_decode(riscv_t* riscv, uint32_t ins) { int imm = 0; int rs1 = (ins >> 15) & 0x1f; int rs2 = (ins >> 20) & 0x1f; int rd = (ins >> 7) & 0x1f; int funct3 = (ins >> 12) & 0x7; int funct7 = (ins >> 25) & 0x7f; int opcode = ins & 0x7f; switch (opcode) { // U-type case opcode_lui: imm_u_type(ins, imm); ins_lui(riscv, imm, rd); break; case opcode_auipc: imm_u_type(ins, imm); ins_auipc(riscv, imm, rd); break; // J-type case opcode_jal: imm_j_type(ins, imm); ins_jal(riscv, imm, rd); break; case opcode_jalr: // I-type imm_i_type(ins, imm); 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: riscv->exc_code = 2; break; } break; case opcode_lb: imm_i_type(ins, imm); 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: riscv->exc_code = 2; break; } break; case opcode_sb: imm_s_type(ins, imm); 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: riscv->exc_code = 2; 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: riscv->exc_code = 2; 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: riscv->exc_code = 2; break; } break; case opcode_ecall: imm_csr(ins,imm); switch (funct3) { case 0x0: if (imm == 1) { ins_ebreak(riscv); } else if (imm == 0) { ins_ecall(riscv); } else if (ins == 0x30200073) { ins_mret(riscv); } else{ riscv->exc_code = 2; } 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: riscv->exc_code = 2; break; } break; default: riscv->exc_code = 2; break; } if (riscv->exc_code == 2) { riscv->mtval = ins; } return 0; } // 注册外设 int riscv_register_device(riscv_t* riscv, const device_t* device) { if (riscv->device_num >= DEVICE_MAX_NUM) { printf("riscv register device failed, device num out of range\n"); return -1; } // printf("device: base_addr=%08x, size=%08x\n", device->addr, device->size); riscv->device_list[riscv->device_num] = device; riscv->device_num++; return 0; } // 跑外设(执行外设逻辑,设置中断等) int riscv_device_run(riscv_t* riscv) { for (int i = 0;i < riscv->device_num;i++) { if (riscv->device_list[i] && riscv->device_list[i]->run) { riscv->device_list[i]->run(riscv, riscv->device_list[i]); } } return 0; } // 外设初始化 int riscv_device_init(riscv_t* riscv) { for (int i = 0;i < riscv->device_num;i++) { if (riscv->device_list[i] && riscv->device_list[i]->init) { riscv->device_list[i]->init(riscv->device_list[i]); } } return 0; } int riscv_init(riscv_t* riscv, uint32_t* rom, uint32_t rom_addr_base, uint32_t rom_size) { riscv->rom = rom; riscv->rom_size = rom_size; riscv->rom_addr_base = rom_addr_base; riscv->pc = riscv->rom_addr_base; riscv->pc_modify = 0; riscv->ra = 0xffffffff; return 0; } // 进入中断 is_interrupt=1 进入中断 is_interrupt=0 进入异常 // irq_num 中断号 int riscv_enter_trap(riscv_t* riscv, int is_interrupt, int irq_num) { riscv->mepc = riscv->pc; riscv->mcause = (is_interrupt << 31) | irq_num; riscv->pc = riscv->mtvec; riscv->pc_modify = 1; // 禁用全局中断 if (riscv->mstatus & MSTATUS_MIE) { riscv->mstatus &= ~MSTATUS_MIE; riscv->mstatus |= MSTATUS_MPIE; } else { riscv->mstatus &= ~MSTATUS_MPIE; } return 0; } // 检测是否产生了中断 int riscv_irq_check(riscv_t* riscv) { uint32_t tmp; int irq_num = 0; tmp = riscv->mip & (MIP_MSIP | MIP_MTIP | MIP_MEIP); if (tmp) { if (riscv->mstatus & MSTATUS_MIE) { if ((riscv->mie & MIP_MSIP) && (tmp & MIP_MSIP)) { irq_num = 3; } else if ((riscv->mie & MIP_MTIP) && (tmp & MIP_MTIP)) { irq_num = 7; } else if ((riscv->mie & MIP_MEIP) && (tmp & MIP_MEIP)) { irq_num = 11; } riscv->mtval = 0; if (irq_num>0) { riscv_enter_trap(riscv, 1, irq_num); riscv->mip &= ~(1 << irq_num); irq_num = 0; } } } return 0; } int riscv_run(riscv_t* riscv) { int ret = 0; while (1) { if (riscv->pc == 0xfffffffe && riscv->ra == 0xffffffff) { break; } if (riscv->pc >= riscv->rom_addr_base + riscv->rom_size || riscv->pc < riscv->rom_addr_base) { // 指令访问失败 riscv->mtval = riscv->pc; // printf("riscv run out of rom pc=%08x\n",riscv->pc); riscv_enter_trap(riscv, 0, 1); } if (riscv->pc & 0x3) { // 指令地址未对齐 riscv->mtval = riscv->pc; riscv_enter_trap(riscv, 0, 0); } uint32_t instr = riscv->rom[(riscv->pc - riscv->rom_addr_base) >> 2]; // printf("pc: %08x instr: %08x\n", riscv->pc, instr); ret = riscv_decode(riscv, instr); riscv->zero = 0; // 如果指令修改了pc,则以修改后的为准,如果pc未被修改,则继续执行下一条指令 if (!riscv->pc_modify) { riscv->pc += 4; } else { // printf("pc modify=1\n"); riscv->pc_modify = 0; } if (riscv->exc_code > 0) { riscv_enter_trap(riscv, 0, riscv->exc_code); riscv->exc_code = 0; } riscv_device_run(riscv); riscv_irq_check(riscv); // riscv_print(riscv); if(ret){ break; } if (riscv->mscratch == 0xffffffff) { printf("proactively terminate\n"); break; } } printf("riscv run end\n"); return 0; }