diff --git a/src/cpu/csr.c b/src/cpu/csr.c new file mode 100644 index 0000000..bcd159c --- /dev/null +++ b/src/cpu/csr.c @@ -0,0 +1,21 @@ +#include "csr.h" +#include "rv32cpu.h" + +uint32_t csr_read(struct RV32_CPU* cpu, uint32_t csr) +{ + switch(csr) + { + case CSR_TIME: + return cpu->sim_ticks_done; + break; + default: + break; + } + + return cpu->csr[csr]; +} + +void csr_write(struct RV32_CPU* cpu, uint32_t csr, uint32_t value) +{ + cpu->csr[csr] = value; +} diff --git a/src/cpu/csr.h b/src/cpu/csr.h index f7d4796..317398d 100644 --- a/src/cpu/csr.h +++ b/src/cpu/csr.h @@ -1,9 +1,17 @@ #ifndef CSR_H #define CSR_H +#include + /* ZICSR : Control and Status Registers */ #define CSR_COUNT 0x2000 +/* Unprivileged CSR */ +#define CSR_CYCLE 0xC00 +#define CSR_TIME 0xC01 +#define CSR_CYCLEH 0xC80 +#define CSR_TIMEH 0xC81 + /* Supervisor-level CSR */ /* Supervisor Trap setup CSR */ #define CSR_SSTATUS 0x100 diff --git a/src/cpu/rv32cpu.c b/src/cpu/rv32cpu.c index bea9c9c..744df55 100644 --- a/src/cpu/rv32cpu.c +++ b/src/cpu/rv32cpu.c @@ -507,6 +507,7 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction) } case OPCODE_SYSTEM: { + uint32_t csr = instruction->immediate; switch(instruction->func3) { case FUNC3_ECALL_EBREAK: @@ -549,35 +550,39 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction) break; case FUNC3_CSRRW: // CSR atomic Read/Write - uint32_t csrrw_old_value = cpu->csr[instruction->immediate]; - cpu->csr[instruction->immediate] = cpu->regs.x[instruction->rs1]; + uint32_t csrrw_old_value = 0; + if(instruction->rd) + csrrw_old_value = csr_read(cpu, csr); + csr_write(cpu, csr, cpu->regs.x[instruction->rs1]); cpu->regs.x[instruction->rd] = csrrw_old_value; break; case FUNC3_CSRRS: // CSR atomic Read and Set bits - cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; - cpu->csr[instruction->immediate] |= cpu->regs.x[instruction->rs1]; + cpu->regs.x[instruction->rd] = csr_read(cpu, csr); + csr_write(cpu, csr, cpu->regs.x[instruction->rd] | cpu->regs.x[instruction->rs1]); break; case FUNC3_CSRRC: // CSR atomic Read and Clear bits - cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; - cpu->csr[instruction->immediate] &= (~cpu->regs.x[instruction->rs1]); + cpu->regs.x[instruction->rd] = csr_read(cpu, csr); + csr_write(cpu, csr, cpu->regs.x[instruction->rd] & (~cpu->regs.x[instruction->rs1])); break; case FUNC3_CSRRWI: // CSR atomic Read/Write Immediate (immediate in rs1) - uint32_t csrrwi_old_value = cpu->csr[instruction->immediate]; - cpu->csr[instruction->immediate] = instruction->rs1; + uint32_t csrrwi_old_value = 0; + if(instruction->rd) + csrrwi_old_value = csr_read(cpu, csr); + csr_write(cpu, csr, instruction->rs1); cpu->regs.x[instruction->rd] = csrrwi_old_value; break; case FUNC3_CSRRSI: // CSR atomic Read and Set bits immediate - cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; - cpu->csr[instruction->immediate] |= instruction->rs1; + cpu->regs.x[instruction->rd] = csr_read(cpu, csr); + csr_write(cpu, csr, cpu->regs.x[instruction->rd] | instruction->rs1); break; case FUNC3_CSRRCI: // CSR atomic Read and Clear bits Immediate (immediate in rs1) - cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; - cpu->csr[instruction->immediate] &= (~((uint32_t) instruction->rs1)); + cpu->regs.x[instruction->rd] = csr_read(cpu, csr); + csr_write(cpu, csr, cpu->regs.x[instruction->rd] & (~((uint32_t) instruction->rs1))); break; default: fprintf(stderr, "FATAL: Unknown func3 0x%x for SYSTEM instruction while executing\n", instruction->func3); diff --git a/src/cpu/rv32cpu.h b/src/cpu/rv32cpu.h index f6248ed..e931784 100644 --- a/src/cpu/rv32cpu.h +++ b/src/cpu/rv32cpu.h @@ -207,6 +207,9 @@ typedef struct RV32_CPU pthread_cond_t sim_condition; } rv32_cpu_t; +uint32_t csr_read(struct RV32_CPU* cpu, uint32_t csr); +void csr_write(struct RV32_CPU* cpu, uint32_t csr, uint32_t value); + extern rv32_cpu_t* cpu0; extern pthread_mutex_t cpu0_mutex; void cpu_init();