Added CSR_TIME support

master
vhaudiquet 11 months ago
parent 256a56f70e
commit 326b52ef86
  1. 21
      src/cpu/csr.c
  2. 8
      src/cpu/csr.h
  3. 29
      src/cpu/rv32cpu.c
  4. 3
      src/cpu/rv32cpu.h

@ -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;
}

@ -1,9 +1,17 @@
#ifndef CSR_H #ifndef CSR_H
#define CSR_H #define CSR_H
#include <stdint.h>
/* ZICSR : Control and Status Registers */ /* ZICSR : Control and Status Registers */
#define CSR_COUNT 0x2000 #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-level CSR */
/* Supervisor Trap setup CSR */ /* Supervisor Trap setup CSR */
#define CSR_SSTATUS 0x100 #define CSR_SSTATUS 0x100

@ -507,6 +507,7 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
} }
case OPCODE_SYSTEM: case OPCODE_SYSTEM:
{ {
uint32_t csr = instruction->immediate;
switch(instruction->func3) switch(instruction->func3)
{ {
case FUNC3_ECALL_EBREAK: case FUNC3_ECALL_EBREAK:
@ -549,35 +550,39 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
break; break;
case FUNC3_CSRRW: case FUNC3_CSRRW:
// CSR atomic Read/Write // CSR atomic Read/Write
uint32_t csrrw_old_value = cpu->csr[instruction->immediate]; uint32_t csrrw_old_value = 0;
cpu->csr[instruction->immediate] = cpu->regs.x[instruction->rs1]; 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; cpu->regs.x[instruction->rd] = csrrw_old_value;
break; break;
case FUNC3_CSRRS: case FUNC3_CSRRS:
// CSR atomic Read and Set bits // CSR atomic Read and Set bits
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
cpu->csr[instruction->immediate] |= cpu->regs.x[instruction->rs1]; csr_write(cpu, csr, cpu->regs.x[instruction->rd] | cpu->regs.x[instruction->rs1]);
break; break;
case FUNC3_CSRRC: case FUNC3_CSRRC:
// CSR atomic Read and Clear bits // CSR atomic Read and Clear bits
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
cpu->csr[instruction->immediate] &= (~cpu->regs.x[instruction->rs1]); csr_write(cpu, csr, cpu->regs.x[instruction->rd] & (~cpu->regs.x[instruction->rs1]));
break; break;
case FUNC3_CSRRWI: case FUNC3_CSRRWI:
// CSR atomic Read/Write Immediate (immediate in rs1) // CSR atomic Read/Write Immediate (immediate in rs1)
uint32_t csrrwi_old_value = cpu->csr[instruction->immediate]; uint32_t csrrwi_old_value = 0;
cpu->csr[instruction->immediate] = instruction->rs1; if(instruction->rd)
csrrwi_old_value = csr_read(cpu, csr);
csr_write(cpu, csr, instruction->rs1);
cpu->regs.x[instruction->rd] = csrrwi_old_value; cpu->regs.x[instruction->rd] = csrrwi_old_value;
break; break;
case FUNC3_CSRRSI: case FUNC3_CSRRSI:
// CSR atomic Read and Set bits immediate // CSR atomic Read and Set bits immediate
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
cpu->csr[instruction->immediate] |= instruction->rs1; csr_write(cpu, csr, cpu->regs.x[instruction->rd] | instruction->rs1);
break; break;
case FUNC3_CSRRCI: case FUNC3_CSRRCI:
// CSR atomic Read and Clear bits Immediate (immediate in rs1) // CSR atomic Read and Clear bits Immediate (immediate in rs1)
cpu->regs.x[instruction->rd] = cpu->csr[instruction->immediate]; cpu->regs.x[instruction->rd] = csr_read(cpu, csr);
cpu->csr[instruction->immediate] &= (~((uint32_t) instruction->rs1)); csr_write(cpu, csr, cpu->regs.x[instruction->rd] & (~((uint32_t) instruction->rs1)));
break; break;
default: default:
fprintf(stderr, "FATAL: Unknown func3 0x%x for SYSTEM instruction while executing\n", instruction->func3); fprintf(stderr, "FATAL: Unknown func3 0x%x for SYSTEM instruction while executing\n", instruction->func3);

@ -207,6 +207,9 @@ typedef struct RV32_CPU
pthread_cond_t sim_condition; pthread_cond_t sim_condition;
} rv32_cpu_t; } 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 rv32_cpu_t* cpu0;
extern pthread_mutex_t cpu0_mutex; extern pthread_mutex_t cpu0_mutex;
void cpu_init(); void cpu_init();

Loading…
Cancel
Save