From fa41d6fa7a4c1d9f4dffb0a88cb35c9eca315826 Mon Sep 17 00:00:00 2001 From: X512 Date: Sun, 6 Jun 2021 22:57:41 +0900 Subject: [PATCH] kernel/arch/platform: implement for riscv64 Change-Id: Id1839ef39d927e6a2017c8b8ac3482d9eeb00fa1 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4059 Reviewed-by: Alex von Gluck IV --- .../kernel/arch/riscv64/arch_kernel_args.h | 18 ++----- .../platform/efi/arch/riscv64/arch_start.cpp | 5 +- src/system/kernel/arch/riscv64/arch_cpu.cpp | 5 +- .../kernel/arch/riscv64/arch_platform.cpp | 52 ++++++++++++++++++- src/system/kernel/arch/riscv64/arch_timer.cpp | 15 +++--- 5 files changed, 67 insertions(+), 28 deletions(-) diff --git a/headers/private/kernel/arch/riscv64/arch_kernel_args.h b/headers/private/kernel/arch/riscv64/arch_kernel_args.h index 279175bc24..cfbbe64640 100644 --- a/headers/private/kernel/arch/riscv64/arch_kernel_args.h +++ b/headers/private/kernel/arch/riscv64/arch_kernel_args.h @@ -19,19 +19,11 @@ enum { - kPlatform1None, - kPlatform1Riscv, - kPlatform1Sbi, + kPlatformNone, + kPlatformMNative, + kPlatformSbi, }; -enum { - kPlatform2None, - kPlatform2Riscv, - kPlatform2Efi, - kPlatform2UBoot, -}; - - enum { kUartKindNone, kUartKind8250, @@ -57,8 +49,8 @@ typedef struct { uint32 num_virtual_ranges_to_keep; addr_range virtual_ranges_to_keep[MAX_VIRTUAL_RANGES_TO_KEEP]; - uint32 platform1; - uint32 platform2; + // MNative hooks, or SBI + uint32 machine_platform; uint bootHart; uint64 timerFrequrency; // in Hz diff --git a/src/system/boot/platform/efi/arch/riscv64/arch_start.cpp b/src/system/boot/platform/efi/arch/riscv64/arch_start.cpp index 788adbe815..27d4585621 100644 --- a/src/system/boot/platform/efi/arch/riscv64/arch_start.cpp +++ b/src/system/boot/platform/efi/arch/riscv64/arch_start.cpp @@ -37,9 +37,8 @@ extern uint64_t arch_mmu_generate_post_efi_page_tables(size_t memory_map_size, void arch_start_kernel(addr_t kernelEntry) { - // Set RV64 platform information - gKernelArgs.arch_args.platform1 = kPlatform1Sbi; - gKernelArgs.arch_args.platform2 = kPlatform2Efi; + // EFI assumed to be SBI booted + gKernelArgs.arch_args.machine_platform = kPlatformSbi; // Prepare to exit EFI boot services. // Read the memory map. diff --git a/src/system/kernel/arch/riscv64/arch_cpu.cpp b/src/system/kernel/arch/riscv64/arch_cpu.cpp index d6a8000c69..b0f57b6bd0 100644 --- a/src/system/kernel/arch/riscv64/arch_cpu.cpp +++ b/src/system/kernel/arch/riscv64/arch_cpu.cpp @@ -15,8 +15,7 @@ #include -extern uint32 gPlatform1; -extern uint32 gPlatform2; +extern uint32 gPlatform; status_t @@ -113,7 +112,7 @@ arch_cpu_user_TLB_invalidate(void) status_t arch_cpu_shutdown(bool reboot) { - if (gPlatform1 == kPlatform1Sbi) { + if (gPlatform == kPlatformSbi) { sbi_system_reset( reboot ? SBI_RESET_TYPE_COLD_REBOOT : SBI_RESET_TYPE_SHUTDOWN, SBI_RESET_REASON_NONE); diff --git a/src/system/kernel/arch/riscv64/arch_platform.cpp b/src/system/kernel/arch/riscv64/arch_platform.cpp index 30a2394057..455208634a 100644 --- a/src/system/kernel/arch/riscv64/arch_platform.cpp +++ b/src/system/kernel/arch/riscv64/arch_platform.cpp @@ -4,11 +4,48 @@ #include +#include +#include +#include +#include +#include + +#include + + +uint32 gPlatform; + +void* gFDT = NULL; + +HtifRegs *volatile gHtifRegs = (HtifRegs *volatile)0x40008000; +PlicRegs *volatile gPlicRegs; +ClintRegs *volatile gClintRegs; status_t -arch_platform_init(struct kernel_args *kernelArgs) +arch_platform_init(struct kernel_args *args) { + gPlatform = args->arch_args.machine_platform; + + debug_early_boot_message("machine_platform: "); + switch (gPlatform) { + case kPlatformMNative: + debug_early_boot_message("Native mmode hooks\n"); + break; + case kPlatformSbi: + debug_early_boot_message("SBI\n"); + break; + default: + debug_early_boot_message("?\n"); + break; + } + + gFDT = args->arch_args.fdt; + + gHtifRegs = (HtifRegs *volatile)args->arch_args.htif.start; + gPlicRegs = (PlicRegs *volatile)args->arch_args.plic.start; + gClintRegs = (ClintRegs *volatile)args->arch_args.clint.start; + return B_OK; } @@ -16,6 +53,19 @@ arch_platform_init(struct kernel_args *kernelArgs) status_t arch_platform_init_post_vm(struct kernel_args *kernelArgs) { + if (gPlatform == kPlatformSbi) { + sbiret res; + res = sbi_get_spec_version(); + dprintf("SBI spec version: %#lx\n", res.value); + res = sbi_get_impl_id(); + dprintf("SBI implementation ID: %#lx\n", res.value); + res = sbi_get_impl_version(); + dprintf("SBI implementation version: %#lx\n", res.value); + res = sbi_get_mvendorid(); + dprintf("SBI vendor ID: %#lx\n", res.value); + res = sbi_get_marchid(); + dprintf("SBI arch ID: %#lx\n", res.value); + } return B_OK; } diff --git a/src/system/kernel/arch/riscv64/arch_timer.cpp b/src/system/kernel/arch/riscv64/arch_timer.cpp index 3b0eda3260..a9724319cc 100644 --- a/src/system/kernel/arch/riscv64/arch_timer.cpp +++ b/src/system/kernel/arch/riscv64/arch_timer.cpp @@ -18,20 +18,19 @@ #include -extern uint32 gPlatform1; -extern uint32 gPlatform2; +extern uint32 gPlatform; void arch_timer_set_hardware_timer(bigtime_t timeout) { // TODO: Read timer frequency from FDT - switch (gPlatform1) { - case kPlatform1Riscv: + switch (gPlatform) { + case kPlatformMNative: MSyscall(kMSyscallSetTimer, true, gClintRegs->mtime + timeout * 10); break; - case kPlatform1Sbi: { + case kPlatformSbi: { sbi_set_timer(CpuTime() + timeout); break; } @@ -44,11 +43,11 @@ arch_timer_set_hardware_timer(bigtime_t timeout) void arch_timer_clear_hardware_timer() { - switch (gPlatform1) { - case kPlatform1Riscv: + switch (gPlatform) { + case kPlatformMNative: MSyscall(kMSyscallSetTimer, false); break; - case kPlatform1Sbi: { + case kPlatformSbi: { sbi_set_timer(CpuTime() + (uint64)10000000 * 3600); break; }