void handle_supervisor_call(trapframe *tf) { uintptr_t call = tf->gpr[17]; /* a7 */ uintptr_t arg0 = tf->gpr[10]; /* a0 */ uintptr_t arg1 = tf->gpr[11]; /* a1 */ uintptr_t returnValue; switch(call) { case SBI_ECALL_HART_ID: printk(BIOS_DEBUG, "Getting hart id...\n"); returnValue = read_csr(mhartid); break; case SBI_ECALL_NUM_HARTS: /* TODO: parse the hardware-supplied config string and return the correct value */ returnValue = 1; break; case SBI_ECALL_CONSOLE_PUT: returnValue = mcall_console_putchar(arg0); break; case SBI_ECALL_SEND_DEVICE_REQUEST: printk(BIOS_DEBUG, "Sending device request...\n"); returnValue = mcall_dev_req((sbi_device_message*) arg0); break; case SBI_ECALL_RECEIVE_DEVICE_RESPONSE: printk(BIOS_DEBUG, "Getting device response...\n"); returnValue = mcall_dev_resp(); break; case SBI_ECALL_SEND_IPI: printk(BIOS_DEBUG, "Sending IPI...\n"); returnValue = mcall_send_ipi(arg0); break; case SBI_ECALL_CLEAR_IPI: printk(BIOS_DEBUG, "Clearing IPI...\n"); returnValue = mcall_clear_ipi(); break; case SBI_ECALL_SHUTDOWN: printk(BIOS_DEBUG, "Shutting down...\n"); returnValue = mcall_shutdown(); break; case SBI_ECALL_SET_TIMER: printk(BIOS_DEBUG, "Setting timer to %p (current time is %p)...\n", (void *)arg0, (void *)rdtime()); returnValue = mcall_set_timer(arg0); break; case SBI_ECALL_QUERY_MEMORY: printk(BIOS_DEBUG, "Querying memory, CPU #%lld...\n", arg0); returnValue = mcall_query_memory(arg0, (memory_block_info*) arg1); break; default: printk(BIOS_DEBUG, "ERROR! Unrecognized system call\n"); returnValue = 0; break; // note: system call we do not know how to handle } tf->gpr[10] = returnValue; write_csr(mepc, read_csr(mepc) + 4); asm volatile("j supervisor_call_return"); }
void testPrint(void) { /* Print a test command to check Spike console output */ mcall_console_putchar('h'); mcall_console_putchar('e'); mcall_console_putchar('l'); mcall_console_putchar('l'); mcall_console_putchar('o'); mcall_console_putchar('\n'); }