Skip to content

Commit

Permalink
Enforce 64-bit timer manipulation
Browse files Browse the repository at this point in the history
The initial code was overly complex and also exhibited slightly slower
performance.
  • Loading branch information
jserv committed Jan 18, 2024
1 parent ac75287 commit c27d0de
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 10 deletions.
2 changes: 1 addition & 1 deletion device.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,5 @@ typedef struct {
#if SEMU_HAS(VIRTIOBLK)
virtio_blk_state_t vblk;
#endif
uint32_t timer_lo, timer_hi;
uint64_t timer;
} emu_state_t;
9 changes: 4 additions & 5 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ static inline sbi_ret_t handle_sbi_ecall_TIMER(vm_t *vm, int32_t fid)
emu_state_t *data = (emu_state_t *) vm->priv;
switch (fid) {
case SBI_TIMER__SET_TIMER:
data->timer_lo = vm->x_regs[RV_R_A0];
data->timer_hi = vm->x_regs[RV_R_A1];
data->timer = (((uint64_t) vm->x_regs[RV_R_A1]) << 32) |
(uint64_t) (vm->x_regs[RV_R_A0]);
return (sbi_ret_t){SBI_SUCCESS, 0};
default:
return (sbi_ret_t){SBI_ERR_NOT_SUPPORTED, 0};
Expand Down Expand Up @@ -406,7 +406,7 @@ static int semu_start(int argc, char **argv)
atexit(unmap_files);

/* Set up RISC-V hart */
emu.timer_hi = emu.timer_lo = 0xFFFFFFFF;
emu.timer = 0xFFFFFFFFFFFFFFFF;
vm.s_mode = true;
vm.x_regs[RV_R_A0] = 0; /* hart ID. i.e., cpuid */
vm.x_regs[RV_R_A1] = dtb_addr;
Expand Down Expand Up @@ -446,8 +446,7 @@ static int semu_start(int argc, char **argv)
#endif
}

if (vm.insn_count_hi > emu.timer_hi ||
(vm.insn_count_hi == emu.timer_hi && vm.insn_count > emu.timer_lo))
if (vm.insn_count > emu.timer)
vm.sip |= RV_INT_STI_BIT;
else
vm.sip &= ~RV_INT_STI_BIT;
Expand Down
5 changes: 2 additions & 3 deletions riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ static void csr_read(vm_t *vm, uint16_t addr, uint32_t *value)
* and writes should set the value after the increment. However,
* we do not expose any way to write the counters.
*/
*value = (addr & (1 << 7)) ? vm->insn_count_hi : vm->insn_count;
*value = vm->insn_count >> ((addr & (1 << 7)) ? 32 : 0);
}
return;
}
Expand Down Expand Up @@ -806,9 +806,8 @@ void vm_step(vm_t *vm)
return;

vm->pc += 4;
/* Assume no integer overflow */
vm->insn_count++;
if (!vm->insn_count)
vm->insn_count_hi++;

uint32_t insn_opcode = insn & MASK(7), value;
switch (insn_opcode) {
Expand Down
2 changes: 1 addition & 1 deletion riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ struct __vm_internal {
* utilized in these capacities and should not be modified between logical
* resets.
*/
uint32_t insn_count, insn_count_hi;
uint64_t insn_count;

/* Instruction execution state must be set to "NONE" for instruction
* execution to continue. If the state is not "NONE," the vm_step()
Expand Down

0 comments on commit c27d0de

Please sign in to comment.