-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement basic CLINT support mtimer device
In this PR, replace the `timer` defined in the `emu_state_t` structure, which originally compared with the instruction counter and triggered software timer interrupts. Further, make 64-bit unsigned integer `mtime` with Real time counter (RTC) to prevent mtime overflow. Replacing timer with MTIMER perpheral also triggers timer interrupts normally. Clarify that the MTIMER peripheral can also trigger timer interrupts within a scheduled period by monitoring `/proc/interrupts` reveals an increase in timer interrupts triggered by `riscv-timer`: ``` 1: 595 SiFive PLIC 1 Edge ttyS0 2: 19 SiFive PLIC 3 Edge virtio1 3: 0 SiFive PLIC 2 Edge virtio0 5: 58985 RISC-V INTC 5 Edge riscv-timer ... 1: 610 SiFive PLIC 1 Edge ttyS0 2: 19 SiFive PLIC 3 Edge virtio1 3: 0 SiFive PLIC 2 Edge virtio0 5: 59196 RISC-V INTC 5 Edge riscv-timer ... 1: 625 SiFive PLIC 1 Edge ttyS0 2: 19 SiFive PLIC 3 Edge virtio1 3: 0 SiFive PLIC 2 Edge virtio0 5: 59296 RISC-V INTC 5 Edge riscv-timer ``` Additionally, the `vm_timer_t` structure is use to retrieve system-wide clock through `clock_gettime()`. The clock frequency is configured to 65MHz, which matches the `timebase-frequency` specified in `minimal.dts`.
- Loading branch information
Showing
10 changed files
with
287 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,8 @@ all: $(BIN) minimal.dtb | |
OBJS := \ | ||
riscv.o \ | ||
ram.o \ | ||
timer.o \ | ||
aclint.o \ | ||
plic.o \ | ||
uart.o \ | ||
main.o \ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
#include "device.h" | ||
#include "riscv.h" | ||
#include "riscv_private.h" | ||
|
||
void aclint_timer_interrupts(vm_t *vm, aclint_state_t *aclint) | ||
{ | ||
uint64_t time_delta = aclint->mtimecmp - vm_timer_gettime(&vm->timer); | ||
if ((time_delta & 0x8000000000000000) || time_delta == 0) | ||
vm->sip |= RV_INT_STI_BIT; | ||
else | ||
vm->sip &= ~RV_INT_STI_BIT; | ||
} | ||
|
||
void aclint_update_interrupts(vm_t *vm, aclint_state_t *aclint) | ||
{ | ||
if (aclint->setssip) | ||
vm->sip |= RV_INT_SSI_BIT; | ||
else | ||
vm->sip &= ~RV_INT_SSI_BIT; | ||
} | ||
|
||
static bool aclint_reg_read(aclint_state_t *aclint, | ||
uint32_t addr, | ||
uint32_t *value) | ||
{ | ||
#define _(reg) ACLINT_##reg | ||
switch (addr) { | ||
case _(SSWI): | ||
/* sswi */ | ||
*value = aclint->setssip; | ||
return true; | ||
case _(MTIMECMP_LO): | ||
/* mtimecmp */ | ||
*value = aclint->mtimecmp & 0xFFFFFFFF; | ||
return true; | ||
case _(MTIMECMP_HI): | ||
/* mtimecmph */ | ||
*value = (aclint->mtimecmp >> 32) & 0xFFFFFFFF; | ||
return true; | ||
case _(MTIME_LO): | ||
/* mtime */ | ||
*value = (uint32_t) (vm_timer_gettime(&aclint->mtimer) & 0xFFFFFFFF); | ||
return true; | ||
case _(MTIME_HI): | ||
/* mtimeh */ | ||
*value = | ||
(uint32_t) (vm_timer_gettime(&aclint->mtimer) >> 32) & 0xFFFFFFFF; | ||
return true; | ||
default: | ||
return false; | ||
} | ||
#undef _ | ||
} | ||
|
||
static bool aclint_reg_write(aclint_state_t *aclint, | ||
uint32_t addr, | ||
uint32_t value) | ||
{ | ||
#define _(reg) ACLINT_##reg | ||
switch (addr) { | ||
case _(SSWI): | ||
/* sswi */ | ||
aclint->setssip = value; | ||
return true; | ||
case _(MTIMECMP_LO): | ||
/* mtimecmp */ | ||
aclint->mtimecmp |= value; | ||
return true; | ||
case _(MTIMECMP_HI): | ||
/* mtimecmph */ | ||
aclint->mtimecmp |= ((uint64_t) value) << 32; | ||
return true; | ||
case _(MTIME_LO): | ||
/* mtime */ | ||
vm_timer_rebase(&aclint->mtimer, value); | ||
return true; | ||
case _(MTIME_HI): | ||
/* mtimeh */ | ||
vm_timer_rebase(&aclint->mtimer, ((uint64_t) value) << 32); | ||
return true; | ||
default: | ||
return false; | ||
} | ||
#undef _ | ||
} | ||
|
||
void aclint_read(vm_t *vm, | ||
aclint_state_t *aclint, | ||
uint32_t addr, | ||
uint8_t width, | ||
uint32_t *value) | ||
{ | ||
switch (width) { | ||
case RV_MEM_LW: | ||
if (!aclint_reg_read(aclint, addr >> 2, value)) | ||
vm_set_exception(vm, RV_EXC_LOAD_FAULT, vm->exc_val); | ||
break; | ||
case RV_MEM_LBU: | ||
case RV_MEM_LB: | ||
case RV_MEM_LHU: | ||
case RV_MEM_LH: | ||
vm_set_exception(vm, RV_EXC_LOAD_MISALIGN, vm->exc_val); | ||
return; | ||
default: | ||
vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); | ||
return; | ||
} | ||
} | ||
void aclint_write(vm_t *vm, | ||
aclint_state_t *aclint, | ||
uint32_t addr, | ||
uint8_t width, | ||
uint32_t value) | ||
{ | ||
switch (width) { | ||
case RV_MEM_SW: | ||
if (!aclint_reg_write(aclint, addr >> 2, value)) | ||
vm_set_exception(vm, RV_EXC_STORE_FAULT, vm->exc_val); | ||
break; | ||
case RV_MEM_SB: | ||
case RV_MEM_SH: | ||
vm_set_exception(vm, RV_EXC_STORE_MISALIGN, vm->exc_val); | ||
return; | ||
default: | ||
vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); | ||
return; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.