Skip to content

Commit c27d0de

Browse files
committed
Enforce 64-bit timer manipulation
The initial code was overly complex and also exhibited slightly slower performance.
1 parent ac75287 commit c27d0de

File tree

4 files changed

+8
-10
lines changed

4 files changed

+8
-10
lines changed

device.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,5 +185,5 @@ typedef struct {
185185
#if SEMU_HAS(VIRTIOBLK)
186186
virtio_blk_state_t vblk;
187187
#endif
188-
uint32_t timer_lo, timer_hi;
188+
uint64_t timer;
189189
} emu_state_t;

main.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ static inline sbi_ret_t handle_sbi_ecall_TIMER(vm_t *vm, int32_t fid)
162162
emu_state_t *data = (emu_state_t *) vm->priv;
163163
switch (fid) {
164164
case SBI_TIMER__SET_TIMER:
165-
data->timer_lo = vm->x_regs[RV_R_A0];
166-
data->timer_hi = vm->x_regs[RV_R_A1];
165+
data->timer = (((uint64_t) vm->x_regs[RV_R_A1]) << 32) |
166+
(uint64_t) (vm->x_regs[RV_R_A0]);
167167
return (sbi_ret_t){SBI_SUCCESS, 0};
168168
default:
169169
return (sbi_ret_t){SBI_ERR_NOT_SUPPORTED, 0};
@@ -406,7 +406,7 @@ static int semu_start(int argc, char **argv)
406406
atexit(unmap_files);
407407

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

449-
if (vm.insn_count_hi > emu.timer_hi ||
450-
(vm.insn_count_hi == emu.timer_hi && vm.insn_count > emu.timer_lo))
449+
if (vm.insn_count > emu.timer)
451450
vm.sip |= RV_INT_STI_BIT;
452451
else
453452
vm.sip &= ~RV_INT_STI_BIT;

riscv.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ static void csr_read(vm_t *vm, uint16_t addr, uint32_t *value)
439439
* and writes should set the value after the increment. However,
440440
* we do not expose any way to write the counters.
441441
*/
442-
*value = (addr & (1 << 7)) ? vm->insn_count_hi : vm->insn_count;
442+
*value = vm->insn_count >> ((addr & (1 << 7)) ? 32 : 0);
443443
}
444444
return;
445445
}
@@ -806,9 +806,8 @@ void vm_step(vm_t *vm)
806806
return;
807807

808808
vm->pc += 4;
809+
/* Assume no integer overflow */
809810
vm->insn_count++;
810-
if (!vm->insn_count)
811-
vm->insn_count_hi++;
812811

813812
uint32_t insn_opcode = insn & MASK(7), value;
814813
switch (insn_opcode) {

riscv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ struct __vm_internal {
6868
* utilized in these capacities and should not be modified between logical
6969
* resets.
7070
*/
71-
uint32_t insn_count, insn_count_hi;
71+
uint64_t insn_count;
7272

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

0 commit comments

Comments
 (0)