Skip to content

Commit

Permalink
feat(csr): Adapt csr access to be done through functions
Browse files Browse the repository at this point in the history
Change the access to csr from macros to functions generated by macros.

Signed-off-by: Miguel Silva <[email protected]>
  • Loading branch information
miguelafsilva5 committed Feb 6, 2024
1 parent 0f12ebb commit f47ab49
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ $(build_dir)/%.d : $(src_dir)/%.[c,S]

$(objs-y):
@echo "Compiling source $(patsubst $(cur_dir)/%, %, $<)"
-@$(cc) $(CFLAGS) -c $< -o $@
@$(cc) $(CFLAGS) -c $< -o $@

%.bin: %.elf
@echo "Generating binary $(patsubst $(cur_dir)/%, %, $@)"
Expand Down
52 changes: 51 additions & 1 deletion src/arch/riscv/inc/arch/csrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@

#ifndef __ASSEMBLER__

#define CSRR(csr) \
/*#define CSRR(csr) \
({ \
unsigned long _temp; \
__asm__ volatile("csrr %0, " XSTR(csr) "\n\r" : "=r"(_temp)::"memory"); \
Expand All @@ -227,6 +227,56 @@
#define CSRW(csr, rs) __asm__ volatile("csrw " XSTR(csr) ", %0\n\r" ::"rK"(rs) : "memory")
#define CSRS(csr, rs) __asm__ volatile("csrs " XSTR(csr) ", %0\n\r" ::"rK"(rs) : "memory")
#define CSRC(csr, rs) __asm__ volatile("csrc " XSTR(csr) ", %0\n\r" ::"rK"(rs) : "memory")
*/

#define CSRS_GEN_ACCESSORS_NAMED(csr_name, csr_id) \
static inline unsigned long csrs_##csr_name##_read(void) { \
unsigned long csr_value; \
__asm__ volatile ("csrr %0," XSTR(csr_id) : "=r"(csr_value) :: "memory");\
return csr_value; \
} \
static inline void csrs_##csr_name##_write(unsigned long csr_value) { \
__asm__ volatile ("csrw " XSTR(csr_id) ",%0" :: "r"(csr_value) : "memory");\
} \
static inline void csrs_##csr_name##_set(unsigned long csr_value) { \
__asm__ volatile ("csrs " XSTR(csr_id) ",%0" :: "r"(csr_value) : "memory");\
} \
static inline void csrs_##csr_name##_clear(unsigned long csr_value) { \
__asm__ volatile ("csrc " XSTR(csr_id) ",%0" :: "r"(csr_value) : "memory");\
} \

#define CSRS_GEN_ACCESSORS(csr) CSRS_GEN_ACCESSORS_NAMED(csr, csr)

CSRS_GEN_ACCESSORS(sstatus)
CSRS_GEN_ACCESSORS(sscratch)
CSRS_GEN_ACCESSORS(scause)
CSRS_GEN_ACCESSORS(stval)
CSRS_GEN_ACCESSORS(sepc)
CSRS_GEN_ACCESSORS(sie)
CSRS_GEN_ACCESSORS(sip)
CSRS_GEN_ACCESSORS(satp)

CSRS_GEN_ACCESSORS_NAMED(hstatus, CSR_HSTATUS)
CSRS_GEN_ACCESSORS_NAMED(hgatp, CSR_HGATP)
CSRS_GEN_ACCESSORS_NAMED(htinst, CSR_HTINST)
CSRS_GEN_ACCESSORS_NAMED(htval, CSR_HTVAL)
CSRS_GEN_ACCESSORS_NAMED(hideleg, CSR_HIDELEG)
CSRS_GEN_ACCESSORS_NAMED(hedeleg, CSR_HEDELEG)
CSRS_GEN_ACCESSORS_NAMED(hcounteren, CSR_HCOUNTEREN)
CSRS_GEN_ACCESSORS_NAMED(stimecmp, CSR_STIMECMP)
CSRS_GEN_ACCESSORS_NAMED(vstimecmp, CSR_VSTIMECMP)
CSRS_GEN_ACCESSORS_NAMED(henvcfg, CSR_HENVCFG)
CSRS_GEN_ACCESSORS_NAMED(vsstatus, CSR_VSSTATUS)
CSRS_GEN_ACCESSORS_NAMED(vstvec, CSR_VSTVEC)
CSRS_GEN_ACCESSORS_NAMED(vsscratch, CSR_VSSCRATCH)
CSRS_GEN_ACCESSORS_NAMED(vsepc, CSR_VSEPC)
CSRS_GEN_ACCESSORS_NAMED(vscause, CSR_VSCAUSE)
CSRS_GEN_ACCESSORS_NAMED(vstval, CSR_VSTVAL)
CSRS_GEN_ACCESSORS_NAMED(vsatp, CSR_VSATP)
CSRS_GEN_ACCESSORS_NAMED(hvip, CSR_HVIP)
CSRS_GEN_ACCESSORS_NAMED(vsie, CSR_VSIE)
CSRS_GEN_ACCESSORS_NAMED(htimedelta, CSR_HTIMEDELTA)
CSRS_GEN_ACCESSORS_NAMED(hie, CSR_HIE)

#endif /* __ASSEMBLER__ */

Expand Down
24 changes: 12 additions & 12 deletions src/arch/riscv/interrupts.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ void interrupts_arch_init()
/**
* Enable external interrupts.
*/
CSRS(sie, SIE_SEIE);
csrs_sie_set(SIE_SEIE);
}

void interrupts_arch_ipi_send(cpuid_t target_cpu, irqid_t ipi_id)
Expand All @@ -48,25 +48,25 @@ void interrupts_arch_ipi_send(cpuid_t target_cpu, irqid_t ipi_id)
void interrupts_arch_cpu_enable(bool en)
{
if (en) {
CSRS(sstatus, SSTATUS_SIE_BIT);
csrs_sstatus_set(SSTATUS_SIE_BIT);
} else {
CSRC(sstatus, SSTATUS_SIE_BIT);
csrs_sstatus_clear(SSTATUS_SIE_BIT);
}
}

void interrupts_arch_enable(irqid_t int_id, bool en)
{
if (int_id == SOFT_INT_ID) {
if (en) {
CSRS(sie, SIE_SSIE);
csrs_sie_set(SIE_SSIE);
} else {
CSRC(sie, SIE_SSIE);
csrs_sie_clear(SIE_SSIE);
}
} else if (int_id == TIMR_INT_ID) {
if (en) {
CSRS(sie, SIE_STIE);
csrs_sie_set(SIE_STIE);
} else {
CSRC(sie, SIE_STIE);
csrs_sie_clear(SIE_STIE);
}
} else {
irqc_config_irq(int_id, en);
Expand All @@ -75,11 +75,11 @@ void interrupts_arch_enable(irqid_t int_id, bool en)

void interrupts_arch_handle()
{
unsigned long _scause = CSRR(scause);
unsigned long _scause = csrs_scause_read();

switch (_scause) {
case SCAUSE_CODE_SSI:
CSRC(sip, SIP_SSIP);
csrs_sip_clear(SIP_SSIP);
interrupts_handle(SOFT_INT_ID);
break;
case SCAUSE_CODE_STI:
Expand All @@ -104,9 +104,9 @@ void interrupts_arch_handle()
bool interrupts_arch_check(irqid_t int_id)
{
if (int_id == SOFT_INT_ID) {
return CSRR(sip) & SIP_SSIP;
return csrs_sip_read() & SIP_SSIP;
} else if (int_id == TIMR_INT_ID) {
return CSRR(sip) & SIP_STIP;
return csrs_sip_read() & SIP_STIP;
} else {
return irqc_get_pend(int_id);
}
Expand All @@ -115,7 +115,7 @@ bool interrupts_arch_check(irqid_t int_id)
void interrupts_arch_clear(irqid_t int_id)
{
if (int_id == SOFT_INT_ID) {
CSRC(sip, SIP_SSIP);
csrs_sip_clear(SIP_SSIP);
} else if (int_id == TIMR_INT_ID) {
/**
* It is not actually possible to clear timer by software.
Expand Down
4 changes: 2 additions & 2 deletions src/arch/riscv/irqc/plic/vplic.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ void vplic_update_hart_line(struct vcpu* vcpu, int vcntxt)
if (pcntxt.hart_id == cpu()->id) {
int id = vplic_next_pending(vcpu, vcntxt);
if (id != 0) {
CSRS(CSR_HVIP, HIP_VSEIP);
csrs_hvip_set(HIP_VSEIP);
} else {
CSRC(CSR_HVIP, HIP_VSEIP);
csrs_hvip_clear(HIP_VSEIP);
}
} else {
struct cpu_msg msg = { VPLIC_IPI_ID, UPDATE_HART_LINE, vcntxt };
Expand Down
12 changes: 6 additions & 6 deletions src/arch/riscv/sbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ void sbi_msg_handler(uint32_t event, uint64_t data)
{
switch (event) {
case SEND_IPI:
CSRS(CSR_HVIP, HIP_VSSIP);
csrs_hvip_set(HIP_VSSIP);
break;
case HART_START: {
spin_lock(&cpu()->vcpu->arch.sbi_ctx.lock);
Expand All @@ -204,20 +204,20 @@ struct sbiret sbi_time_handler(unsigned long fid)

uint64_t stime_value = vcpu_readreg(cpu()->vcpu, REG_A0);
if (CPU_HAS_EXTENSION(CPU_EXT_SSTC)) {
CSRW(CSR_VSTIMECMP, stime_value);
csrs_vstimecmp_write(stime_value);
} else {
sbi_set_timer(stime_value); // assumes always success
CSRC(CSR_HVIP, HIP_VSTIP);
CSRS(sie, SIE_STIE);
csrs_hvip_clear(HIP_VSTIP);
csrs_sie_set(SIE_STIE);
}

return (struct sbiret){ SBI_SUCCESS };
}

void sbi_timer_irq_handler()
{
CSRS(CSR_HVIP, HIP_VSTIP);
CSRC(sie, SIE_STIE);
csrs_hvip_set(HIP_VSTIP);
csrs_sie_clear(SIE_STIE);
}

struct sbiret sbi_ipi_handler(unsigned long fid)
Expand Down
20 changes: 10 additions & 10 deletions src/arch/riscv/sync_exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ void internal_exception_handler(unsigned long gprs[])
for (int i = 0; i < 31; i++) {
console_printk("x%d:\t\t0x%0lx\n", i, gprs[i]);
}
console_printk("sstatus:\t0x%0lx\n", CSRR(sstatus));
console_printk("stval:\t\t0x%0lx\n", CSRR(stval));
console_printk("sepc:\t\t0x%0lx\n", CSRR(sepc));
console_printk("sstatus:\t0x%0lx\n", csrs_sstatus_read());
console_printk("stval:\t\t0x%0lx\n", csrs_stval_read());
console_printk("sepc:\t\t0x%0lx\n", csrs_sepc_read());
ERROR("cpu%d internal hypervisor abort - PANIC\n", cpu()->id);
}

Expand Down Expand Up @@ -80,18 +80,18 @@ static inline bool is_pseudo_ins(uint32_t ins)

size_t guest_page_fault_handler()
{
vaddr_t addr = CSRR(CSR_HTVAL) << 2;
vaddr_t addr = csrs_htval_read() << 2;

emul_handler_t handler = vm_emul_get_mem(cpu()->vcpu->vm, addr);
if (handler != NULL) {
unsigned long ins = CSRR(CSR_HTINST);
unsigned long ins = csrs_htinst_read();
size_t ins_size;
if (ins == 0) {
/**
* If htinst does not provide information about the trap, we must read the instruction
* from the guest's memory manually.
*/
vaddr_t ins_addr = CSRR(sepc);
vaddr_t ins_addr = csrs_sepc_read();
ins = read_ins(ins_addr);
ins_size = INS_SIZE(ins);
} else if (is_pseudo_ins(ins)) {
Expand Down Expand Up @@ -119,10 +119,10 @@ size_t guest_page_fault_handler()
if (handler(&emul)) {
return ins_size;
} else {
ERROR("emulation handler failed (0x%x at 0x%x)", addr, CSRR(sepc));
ERROR("emulation handler failed (0x%x at 0x%x)", addr, csrs_sepc_read());
}
} else {
ERROR("no emulation handler for abort(0x%x at 0x%x)", addr, CSRR(sepc));
ERROR("no emulation handler for abort(0x%x at 0x%x)", addr, csrs_sepc_read());
}
}

Expand All @@ -137,9 +137,9 @@ static const size_t sync_handler_table_size = sizeof(sync_handler_table) / sizeo
void sync_exception_handler()
{
size_t pc_step = 0;
unsigned long _scause = CSRR(scause);
unsigned long _scause = csrs_scause_read();

if (!(CSRR(CSR_HSTATUS) & HSTATUS_SPV)) {
if (!(csrs_hstatus_read() & HSTATUS_SPV)) {
internal_exception_handler(&cpu()->vcpu->regs.x[0]);
}

Expand Down
29 changes: 15 additions & 14 deletions src/arch/riscv/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ void vm_arch_init(struct vm* vm, const struct vm_config* config)
unsigned long hgatp = (root_pt_pa >> PAGE_SHIFT) | (HGATP_MODE_DFLT) |
((vm->id << HGATP_VMID_OFF) & HGATP_VMID_MSK);

CSRW(CSR_HGATP, hgatp);
csrs_hgatp_write(hgatp);

virqc_init(vm, &config->platform.arch.irqc);
}
Expand All @@ -34,7 +34,7 @@ void vcpu_arch_reset(struct vcpu* vcpu, vaddr_t entry)
{
memset(&vcpu->regs, 0, sizeof(struct arch_regs));

CSRW(sscratch, &vcpu->regs);
csrs_sscratch_write((uintptr_t)&vcpu->regs);

vcpu->regs.hstatus = HSTATUS_SPV | HSTATUS_VSXL_64;
vcpu->regs.sstatus = SSTATUS_SPP_BIT | SSTATUS_FS_DIRTY | SSTATUS_XS_DIRTY;
Expand All @@ -43,19 +43,20 @@ void vcpu_arch_reset(struct vcpu* vcpu, vaddr_t entry)
vcpu->regs.a1 = 0; // according to sbi it should be the dtb load address

if (CPU_HAS_EXTENSION(CPU_EXT_SSTC)) {
CSRW(CSR_VSTIMECMP, -1);
csrs_stimecmp_write(-1);
}
CSRW(CSR_HCOUNTEREN, HCOUNTEREN_TM);
CSRW(CSR_HTIMEDELTA, 0);
CSRW(CSR_VSSTATUS, SSTATUS_SD | SSTATUS_FS_DIRTY | SSTATUS_XS_DIRTY);
CSRW(CSR_HIE, 0);
CSRW(CSR_VSTVEC, 0);
CSRW(CSR_VSSCRATCH, 0);
CSRW(CSR_VSEPC, 0);
CSRW(CSR_VSCAUSE, 0);
CSRW(CSR_VSTVAL, 0);
CSRW(CSR_HVIP, 0);
CSRW(CSR_VSATP, 0);

csrs_hcounteren_write(HCOUNTEREN_TM);
csrs_htimedelta_write(0);
csrs_vsstatus_write(SSTATUS_SD | SSTATUS_FS_DIRTY | SSTATUS_XS_DIRTY);
csrs_hie_write(0);
csrs_vstvec_write(0);
csrs_vsscratch_write(0);
csrs_vsepc_write(0);
csrs_vscause_write(0);
csrs_vstval_write(0);
csrs_hvip_write(0);
csrs_vsatp_write(0);
}

unsigned long vcpu_readreg(struct vcpu* vcpu, unsigned long reg)
Expand Down
13 changes: 7 additions & 6 deletions src/arch/riscv/vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,26 @@ void vmm_arch_init()
* Delegate all interrupts and exceptions not meant to be dealt by the hypervisor
*/

CSRW(CSR_HIDELEG, HIDELEG_VSSI | HIDELEG_VSTI | HIDELEG_VSEI);
CSRW(CSR_HEDELEG, HEDELEG_ECU | HEDELEG_IPF | HEDELEG_LPF | HEDELEG_SPF);
csrs_hideleg_write(HIDELEG_VSSI | HIDELEG_VSTI | HIDELEG_VSEI);
csrs_hedeleg_write(HEDELEG_ECU | HEDELEG_IPF | HEDELEG_LPF | HEDELEG_SPF);

/**
* Enable and sanity check presence of Sstc extension if the hypervisor was
* configured to use it (via the CPU_EXT_SSTC macro). Otherwise, make sure
* it is disabled.
*/
if (CPU_HAS_EXTENSION(CPU_EXT_SSTC)) {
CSRS(CSR_HENVCFG, HENVCFG_STCE);
bool sstc_present = (CSRR(CSR_HENVCFG) & HENVCFG_STCE) != 0;

csrs_henvcfg_set(HENVCFG_STCE);
bool sstc_present = (csrs_henvcfg_read() & HENVCFG_STCE) != 0;
if (cpu_is_master() && !sstc_present) {
ERROR("Platform configured to use Sstc extension, but extension not present.");
}
// Set stimecmp to infinity in case we enable the stimer interrupt somewhere else
// and fail to set the timer to a point in the future.
CSRS(CSR_STIMECMP, -1);
csrs_stimecmp_write(-1);
} else {
CSRC(CSR_HENVCFG, HENVCFG_STCE);
csrs_henvcfg_clear(HENVCFG_STCE);
}

/**
Expand Down

0 comments on commit f47ab49

Please sign in to comment.