Skip to content

Commit

Permalink
Handle System Timer with mtimecmp
Browse files Browse the repository at this point in the history
  • Loading branch information
lupyuen committed Jan 24, 2024
1 parent 29e5c96 commit f00d40c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
16 changes: 12 additions & 4 deletions riscv_cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
#include "iomem.h"
#include "riscv_cpu.h"

// #define _info(...) {} ////
#define _info printf ////
#define _info(...) {} ////
// #define _info printf ////

#ifndef MAX_XLEN
#error MAX_XLEN must be defined
Expand All @@ -58,6 +58,7 @@ extern uint64_t ecall_addr;
extern uint64_t rdtime_addr;
extern uint64_t dcache_iall_addr;
extern uint64_t sync_s_addr;
extern uint64_t real_time;

#if FLEN > 0
#include "softfp.h"
Expand Down Expand Up @@ -1173,12 +1174,19 @@ static void raise_exception2(RISCVCPUState *s, uint32_t cause,
_info(" reg %s=%p\n", reg_name[10], s->reg[10]); //// A0 is X10 (parm0)
riscv_cpu_reset_mip(s, MIP_STIP);

// If parm0 is not -1, set the System Timer (timecmp)
uint64_t timecmp = s->reg[10]; // A0 is X10 (parm0)
if (timecmp != (uint64_t) -1) {
void set_timecmp(void *machine0, uint64_t timecmp);
set_timecmp(NULL, timecmp);
}
} else if (s->pc == rdtime_addr) {
// For RDTIME: Return the time
// https://five-embeddev.com/riscv-isa-manual/latest/counters.html#zicntr-standard-extension-for-base-counters-and-timers
_info("Get Time\n");
static uint64_t t = 0;
s->reg[10] = t++; // Not too much or usleep will hang
// static uint64_t t = 0;
// s->reg[10] = t++; // Not too much or usleep will hang
s->reg[10] = real_time;
_info(" Return reg %s=%p\n", reg_name[10], s->reg[10]); //// A0 is X10
}

Expand Down
32 changes: 26 additions & 6 deletions riscv_machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,14 @@ typedef struct RISCVMachine {
#define RTC_FREQ_DIV 16 /* arbitrary, relative to CPU freq to have a
10 MHz frequency */

void set_timecmp(RISCVMachine *machine0, uint64_t timecmp);
void print_console(RISCVMachine *machine0, const char *buf, int len);

uint64_t ecall_addr = 0;
uint64_t rdtime_addr = 0;
uint64_t dcache_iall_addr = 0;
uint64_t sync_s_addr = 0;
uint64_t real_time = 0;

static uint64_t rtc_get_real_time(RISCVMachine *s)
{
Expand Down Expand Up @@ -1042,7 +1046,6 @@ static VirtMachine *riscv_machine_init(const VirtMachineParams *p)
if (p->console) {
//// Begin Test: Save the Console
const char *msg = "TinyEMU Emulator for Ox64 BL808 RISC-V SBC\r\n";
void print_console(RISCVMachine *machine0, const char *buf, int len);
print_console(s, msg, strlen(msg));
//// End Test
vbus->irq = &s->plic_irq[irq_num];
Expand Down Expand Up @@ -1131,6 +1134,7 @@ static VirtMachine *riscv_machine_init(const VirtMachineParams *p)
p->cmdline,
p->files[VM_FILE_INITRD].buf, p->files[VM_FILE_INITRD].len);

set_timecmp(s, 0); //// Init the System Timer
return (VirtMachine *)s;
}

Expand Down Expand Up @@ -1167,10 +1171,16 @@ static int riscv_machine_get_sleep_duration(VirtMachine *s1, int delay)
delay = 0;

//// Begin Test: Trigger the Supervisor-Mode Timer Interrupt
static uint64_t t = 0;
if (t++ % 100 == 0) {
riscv_cpu_set_mip(s, MIP_STIP);
} ////
real_time = rtc_get_time(m);
if (!(riscv_cpu_get_mip(s) & MIP_STIP)) {
const int64_t delay2 = m->timecmp - rtc_get_time(m);
if (delay2 <= 0) {
static uint64_t t = 0;
if (t++ % 100 == 0) {
riscv_cpu_set_mip(s, MIP_STIP);
}
}
}
//// End Test
return delay;
}
Expand Down Expand Up @@ -1216,7 +1226,17 @@ const VirtMachineClass riscv_machine_class = {
riscv_vm_send_key_event,
};

//// Begin Test: Print to Console
//// Begin Test
// Set Timer
void set_timecmp(RISCVMachine *machine0, uint64_t timecmp) {
static RISCVMachine *machine = NULL;
if (machine0 != NULL) { machine = machine0; return; }
if (machine == NULL) { puts("set_timecmp: machine is null"); return; }
machine->timecmp = timecmp;
printf("set_timecmp: timecmp=%p\n", timecmp);
}

// Print to Console
void print_console(RISCVMachine *machine0, const char *buf, int len) {
static RISCVMachine *machine = NULL;
if (machine0 != NULL) { machine = machine0; }
Expand Down

0 comments on commit f00d40c

Please sign in to comment.