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
#define CSR_H
#include <stdint.h>
/* 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

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

@ -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();

Loading…
Cancel
Save