113 lines
3.6 KiB
C++
113 lines
3.6 KiB
C++
/*
|
|
* UniversalisOS RISC-V Hypervisor Entry Point
|
|
*
|
|
* Minimal boot path for the RISC-V port. Initialises the hypervisor
|
|
* foundation (CPU detection, UART, trap handling, timer, PLIC, page
|
|
* tables, scheduler, memory API, HM) and runs self-tests before halting.
|
|
*/
|
|
|
|
#include "uart.h"
|
|
#include "exceptions.h"
|
|
#include "context_switch.h"
|
|
#include "cpu.h"
|
|
#include "page_table.h"
|
|
#include "mem_pikeos.h"
|
|
#include "timer.h"
|
|
#include "plic.h"
|
|
#include "vm.h"
|
|
#include "guest_boot.h"
|
|
#include "sched_pikeos.h"
|
|
#include "hm.h"
|
|
#include "csr.h"
|
|
#include <uos/uos.h>
|
|
|
|
static void test_task(void)
|
|
{
|
|
universalisos::uart::puts("[SCHED] test task running\r\n");
|
|
riscv_sched_task_yield();
|
|
universalisos::uart::puts("[SCHED] test task returned\r\n");
|
|
while (1) {
|
|
riscv_sched_task_yield();
|
|
}
|
|
}
|
|
|
|
extern "C" void kernel_main(uint32_t hart_id, uint64_t dtb_pa)
|
|
{
|
|
(void)dtb_pa;
|
|
|
|
universalisos::uart::init();
|
|
universalisos::uart::puts("\r\n");
|
|
universalisos::uart::puts("UniversalisOS RISC-V 64-bit hypervisor booted.\r\n");
|
|
universalisos::uart::puts("=== PikeOS 5.0 parity foundation ===\r\n");
|
|
|
|
riscv_cpu_init(hart_id);
|
|
riscv_cpu_print_info();
|
|
|
|
riscv_hm_init();
|
|
riscv_exceptions_init();
|
|
riscv_timer_init();
|
|
riscv_plic_init();
|
|
|
|
universalisos::uart::puts("\r\n=== RISC-V Subsystem Tests ===\r\n");
|
|
|
|
/* Sv39 page-table smoke test */
|
|
paddr_t root = riscv_pt_alloc_frame();
|
|
if (root) {
|
|
int rc = riscv_pt_map_page(root, 0x40000000ULL, 0x80000000ULL,
|
|
PTE_PAGE_FLAGS, false);
|
|
if (rc == 0) {
|
|
universalisos::uart::puts("[OK] Sv39 page table map\r\n");
|
|
} else {
|
|
universalisos::uart::puts("[FAIL] Sv39 page table map\r\n");
|
|
}
|
|
riscv_pt_free_frame(root);
|
|
}
|
|
|
|
/* PikeOS-style address-space smoke test */
|
|
riscv_aspace_t as;
|
|
if (riscv_aspace_create(1, 0x40000000ULL, 0x40000000ULL, &as) == 0) {
|
|
if (riscv_aspace_map(&as, 0x40000000ULL, 0x80000000ULL,
|
|
0x10000ULL, RISCV_M_READ | RISCV_M_WRITE | RISCV_M_EXEC) == 0) {
|
|
universalisos::uart::puts("[OK] p4map-style aspace map\r\n");
|
|
}
|
|
riscv_aspace_destroy(&as);
|
|
}
|
|
|
|
/* Guest VM creation smoke test */
|
|
if (riscv_vm_create(0, 0x90000000ULL, 0x10000ULL) == 0) {
|
|
universalisos::uart::puts("[OK] Guest VM create\r\n");
|
|
int vcpu = riscv_vcpu_create(0, 0, hart_id);
|
|
if (vcpu >= 0) {
|
|
universalisos::uart::puts("[OK] vCPU create\r\n");
|
|
riscv_vcpu_reset(vcpu, 0x90000000ULL, 0);
|
|
}
|
|
riscv_vm_destroy(0);
|
|
} else {
|
|
universalisos::uart::puts("[FAIL] Guest VM create\r\n");
|
|
}
|
|
|
|
/* PikeOS-style scheduler smoke test */
|
|
riscv_sched_init(1000); /* 1 ms tick */
|
|
riscv_sched_schema_create(0, 10000); /* 10 ms major frame */
|
|
riscv_sched_window_add(0, 1, 5000, 4500, 0, 0, 0);
|
|
riscv_sched_window_add(0, 2, 5000, 4500, 0, 0, 1);
|
|
static uint8_t test_stack[4096] __attribute__((aligned(16)));
|
|
int tid = riscv_sched_task_create(1, 1, 16, 0, 0, 1000,
|
|
(void*)((uintptr_t)test_stack + sizeof(test_stack)),
|
|
test_task);
|
|
if (tid >= 0) {
|
|
universalisos::uart::puts("[OK] PikeOS-style scheduler task create\r\n");
|
|
}
|
|
|
|
/* Timer smoke test */
|
|
uint64_t now = riscv_timer_get_time();
|
|
riscv_timer_set(now + 1000000ULL);
|
|
universalisos::uart::puts("[OK] SBI timer armed\r\n");
|
|
|
|
riscv_print_exception_stats();
|
|
|
|
universalisos::uart::puts("\r\nHalting.\r\n");
|
|
while (1) {
|
|
__asm__ volatile("wfi");
|
|
}
|
|
}
|