Skip to content

Commit

Permalink
Patch DCACHE.IALL and SYNC.S to become ECALL
Browse files Browse the repository at this point in the history
  • Loading branch information
lupyuen committed Jan 24, 2024
1 parent 41428e7 commit b8671f7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 24 deletions.
16 changes: 8 additions & 8 deletions riscv_cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,14 @@ static void raise_exception2(RISCVCPUState *s, uint32_t cause,
_info("raise_exception2: cause=%d, tval=%p, pc=%p\n", cause, (void *)tval, s->pc);////
BOOL deleg;
target_ulong causel;


//// Begin Test: Quit if Illegal Instruction, otherwise it will loop forever
if (cause == 2) {
printf("\ntinyemu: Illegal instruction, quitting: pc=%p, instruction=%p\n", s->pc, tval);
exit(1);
}
//// End Test

#if defined(DUMP_EXCEPTIONS) || defined(DUMP_MMU_EXCEPTIONS) || defined(DUMP_INTERRUPTS)
{
int flag;
Expand Down Expand Up @@ -1151,13 +1158,6 @@ static void raise_exception2(RISCVCPUState *s, uint32_t cause,
}
#endif

//// Begin Test: Quit if Illegal Instruction, otherwise it will loop forever
if (cause == 2) {
printf("tinyemu: Illegal instruction, quitting: pc=%p, instruction=%p\n", s->pc, tval);
exit(1);
}
//// End Test

//// Begin Test: Emulate OpenSBI for System Timer
if (cause == CAUSE_SUPERVISOR_ECALL) {
_info("TODO: Emulate OpenSBI for System Timer\n");
Expand Down
43 changes: 27 additions & 16 deletions riscv_machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -905,27 +905,38 @@ static void copy_bios(RISCVMachine *s, const uint8_t *buf, int buf_len,
q[pc++] = 0x34129073; // csrw mepc, t0
q[pc++] = 0x30200073; // mret

// Sentinel to catch overrun
q[pc++] = 0x12345678;

// Machine Mode ECALL: Always return
// *(uint32_t *)(ram_ptr + 0x0) = 0x30200073; // mret

// Patch the RDTTIME (Read System Timer) with NOP for now. We will support later.
// Patch the Unknown Instructions to become ECALL and handle later
uint8_t *kernel_ptr = get_ram_ptr(s, RAM_BASE_ADDR, TRUE);
for (int i = 0; i < 0x10000; i++) {
// Patch RDTTIME to NOP
// ECALL Instruction
// 00000073 ecall
const uint8_t ecall[] = { 0x73, 0x00, 0x00, 0x00 };

// Patch RDTIME to become ECALL
// (Read System Time)
// c0102573 rdtime a0
const uint8_t search[] = { 0x73, 0x25, 0x10, 0xc0 };
// 00010001 nop ; nop
// const uint8_t replace[] = { 0x01, 0x00, 0x01, 0x00 };
const uint8_t rdtime[] = { 0x73, 0x25, 0x10, 0xc0 };
if (memcmp(&kernel_ptr[i], rdtime, sizeof(rdtime)) == 0) {
memcpy(&kernel_ptr[i], ecall, sizeof(ecall));
printf("Patched RDTIME (Read System Time) at %p\n", RAM_BASE_ADDR + i);
}

// 00000073 ecall
const uint8_t replace[] = { 0x73, 0x00, 0x00, 0x00 };
// Patch DCACHE.IALL to become ECALL
// (Invalidate all Page Table Entries in the D-Cache)
// 0020000b DCACHE.IALL
const uint8_t dcache_iall[] = { 0x0b, 0x00, 0x20, 0x00 };
if (memcmp(&kernel_ptr[i], dcache_iall, sizeof(dcache_iall)) == 0) {
memcpy(&kernel_ptr[i], ecall, sizeof(ecall));
printf("Patched DCACHE.IALL (Invalidate all Page Table Entries in the D-Cache) at %p\n", RAM_BASE_ADDR + i);
}

if (memcmp(&kernel_ptr[i], search, sizeof(search)) == 0) {
memcpy(&kernel_ptr[i], replace, sizeof(replace));
printf("Patched RDTTIME (Read System Timer) at %p\n", RAM_BASE_ADDR + i);
// Patch SYNC.S to become ECALL
// (Ensure that all Cache Operations are completed)
// 0190000b SYNC.S
const uint8_t sync_s[] = { 0x0b, 0x00, 0x90, 0x01 };
if (memcmp(&kernel_ptr[i], sync_s, sizeof(sync_s)) == 0) {
memcpy(&kernel_ptr[i], ecall, sizeof(ecall));
printf("Patched SYNC.S (Ensure that all Cache Operations are completed) at %p\n", RAM_BASE_ADDR + i);
}
}
//// End Test
Expand Down

0 comments on commit b8671f7

Please sign in to comment.