1c085f386SAlexander von Gluck IV /* 2c085f386SAlexander von Gluck IV * Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk. 3c085f386SAlexander von Gluck IV * Distributed under the terms of the MIT License. 4c085f386SAlexander von Gluck IV */ 5c085f386SAlexander von Gluck IV 6c085f386SAlexander von Gluck IV 7c085f386SAlexander von Gluck IV #include <KernelExport.h> 8c085f386SAlexander von Gluck IV 9c085f386SAlexander von Gluck IV #include <arch/cpu.h> 10c085f386SAlexander von Gluck IV #include <boot/kernel_args.h> 11d031c09cSX512 #include <vm/VMAddressSpace.h> 12c085f386SAlexander von Gluck IV #include <commpage.h> 13c085f386SAlexander von Gluck IV #include <elf.h> 14d031c09cSX512 #include <Htif.h> 15d031c09cSX512 #include <platform/sbi/sbi_syscalls.h> 16d031c09cSX512 17d031c09cSX512 188ca0f03dSX512 extern "C" void SVec(); 198ca0f03dSX512 20fa41d6faSX512 extern uint32 gPlatform; 21c085f386SAlexander von Gluck IV 22c085f386SAlexander von Gluck IV 23c085f386SAlexander von Gluck IV status_t 24c085f386SAlexander von Gluck IV arch_cpu_preboot_init_percpu(kernel_args *args, int curr_cpu) 25c085f386SAlexander von Gluck IV { 268ca0f03dSX512 // dprintf("arch_cpu_preboot_init_percpu(%" B_PRId32 ")\n", curr_cpu); 27c085f386SAlexander von Gluck IV return B_OK; 28c085f386SAlexander von Gluck IV } 29c085f386SAlexander von Gluck IV 30c085f386SAlexander von Gluck IV 31c085f386SAlexander von Gluck IV status_t 32c085f386SAlexander von Gluck IV arch_cpu_init_percpu(kernel_args *args, int curr_cpu) 33c085f386SAlexander von Gluck IV { 348ca0f03dSX512 SetStvec((uint64)SVec); 35fa557843SX512 SstatusReg sstatus{.val = Sstatus()}; 368ca0f03dSX512 sstatus.ie = 0; 378ca0f03dSX512 sstatus.fs = extStatusInitial; // enable FPU 388ca0f03dSX512 sstatus.xs = extStatusOff; 398ca0f03dSX512 SetSstatus(sstatus.val); 40fa557843SX512 SetBitsSie((1 << sTimerInt) | (1 << sSoftInt) | (1 << sExternInt)); 41c085f386SAlexander von Gluck IV 428ca0f03dSX512 return B_OK; 43c085f386SAlexander von Gluck IV } 44c085f386SAlexander von Gluck IV 45c085f386SAlexander von Gluck IV 46c085f386SAlexander von Gluck IV status_t 47c085f386SAlexander von Gluck IV arch_cpu_init(kernel_args *args) 48c085f386SAlexander von Gluck IV { 498ca0f03dSX512 for (uint32 curCpu = 0; curCpu < args->num_cpus; curCpu++) { 508ca0f03dSX512 cpu_ent* cpu = &gCPU[curCpu]; 518ca0f03dSX512 528ca0f03dSX512 cpu->arch.hartId = args->arch_args.hartIds[curCpu]; 538ca0f03dSX512 548ca0f03dSX512 cpu->topology_id[CPU_TOPOLOGY_PACKAGE] = 0; 558ca0f03dSX512 cpu->topology_id[CPU_TOPOLOGY_CORE] = curCpu; 568ca0f03dSX512 cpu->topology_id[CPU_TOPOLOGY_SMT] = 0; 578ca0f03dSX512 588ca0f03dSX512 for (unsigned int i = 0; i < CPU_MAX_CACHE_LEVEL; i++) 598ca0f03dSX512 cpu->cache_id[i] = -1; 608ca0f03dSX512 } 618ca0f03dSX512 62d031c09cSX512 uint64 conversionFactor 635855a8e3SPrzemysław Buczkowski = (1LL << 32) * 1000000LL / args->arch_args.timerFrequency; 64d031c09cSX512 65d031c09cSX512 __riscv64_setup_system_time(conversionFactor); 66f8ef2441SAlexander von Gluck IV 67c085f386SAlexander von Gluck IV return B_OK; 68c085f386SAlexander von Gluck IV } 69c085f386SAlexander von Gluck IV 70c085f386SAlexander von Gluck IV 71c085f386SAlexander von Gluck IV status_t 72c085f386SAlexander von Gluck IV arch_cpu_init_post_vm(kernel_args *args) 73c085f386SAlexander von Gluck IV { 74d031c09cSX512 // Set address space ownership to currently running threads 75d031c09cSX512 for (uint32 i = 0; i < args->num_cpus; i++) { 76d031c09cSX512 VMAddressSpace::Kernel()->Get(); 77d031c09cSX512 } 78d031c09cSX512 79c085f386SAlexander von Gluck IV return B_OK; 80c085f386SAlexander von Gluck IV } 81c085f386SAlexander von Gluck IV 82c085f386SAlexander von Gluck IV 83c085f386SAlexander von Gluck IV status_t 84c085f386SAlexander von Gluck IV arch_cpu_init_post_modules(kernel_args *args) 85c085f386SAlexander von Gluck IV { 86c085f386SAlexander von Gluck IV return B_OK; 87c085f386SAlexander von Gluck IV } 88c085f386SAlexander von Gluck IV 89c085f386SAlexander von Gluck IV 90c085f386SAlexander von Gluck IV void 91c085f386SAlexander von Gluck IV arch_cpu_sync_icache(void *address, size_t len) 92c085f386SAlexander von Gluck IV { 93*408a7e27SX512 FenceI(); 94*408a7e27SX512 95*408a7e27SX512 if (smp_get_num_cpus() > 1) { 96*408a7e27SX512 memory_full_barrier(); 97*408a7e27SX512 sbi_remote_fence_i(0, -1); 98*408a7e27SX512 } 99c085f386SAlexander von Gluck IV } 100c085f386SAlexander von Gluck IV 101c085f386SAlexander von Gluck IV 102c085f386SAlexander von Gluck IV void 103c085f386SAlexander von Gluck IV arch_cpu_memory_read_barrier(void) 104c085f386SAlexander von Gluck IV { 105c085f386SAlexander von Gluck IV } 106c085f386SAlexander von Gluck IV 107c085f386SAlexander von Gluck IV 108c085f386SAlexander von Gluck IV void 109c085f386SAlexander von Gluck IV arch_cpu_memory_write_barrier(void) 110c085f386SAlexander von Gluck IV { 111c085f386SAlexander von Gluck IV } 112c085f386SAlexander von Gluck IV 113c085f386SAlexander von Gluck IV 114c085f386SAlexander von Gluck IV void 115c085f386SAlexander von Gluck IV arch_cpu_invalidate_TLB_range(addr_t start, addr_t end) 116c085f386SAlexander von Gluck IV { 1178ca0f03dSX512 int32 numPages = end / B_PAGE_SIZE - start / B_PAGE_SIZE; 1188ca0f03dSX512 while (numPages-- >= 0) { 1198ca0f03dSX512 FlushTlbPage(start); 1208ca0f03dSX512 start += B_PAGE_SIZE; 1218ca0f03dSX512 } 122c085f386SAlexander von Gluck IV } 123c085f386SAlexander von Gluck IV 124c085f386SAlexander von Gluck IV 125c085f386SAlexander von Gluck IV void 126c085f386SAlexander von Gluck IV arch_cpu_invalidate_TLB_list(addr_t pages[], int num_pages) 127c085f386SAlexander von Gluck IV { 1288ca0f03dSX512 for (int i = 0; i < num_pages; i++) 1298ca0f03dSX512 FlushTlbPage(pages[i]); 130c085f386SAlexander von Gluck IV } 131c085f386SAlexander von Gluck IV 132c085f386SAlexander von Gluck IV 133c085f386SAlexander von Gluck IV void 134c085f386SAlexander von Gluck IV arch_cpu_global_TLB_invalidate(void) 135c085f386SAlexander von Gluck IV { 1368ca0f03dSX512 FlushTlbAll(); 137c085f386SAlexander von Gluck IV } 138c085f386SAlexander von Gluck IV 139c085f386SAlexander von Gluck IV 140c085f386SAlexander von Gluck IV void 141c085f386SAlexander von Gluck IV arch_cpu_user_TLB_invalidate(void) 142c085f386SAlexander von Gluck IV { 1438ca0f03dSX512 FlushTlbAll(); 144c085f386SAlexander von Gluck IV } 145c085f386SAlexander von Gluck IV 146c085f386SAlexander von Gluck IV 147c085f386SAlexander von Gluck IV status_t 148c085f386SAlexander von Gluck IV arch_cpu_shutdown(bool reboot) 149c085f386SAlexander von Gluck IV { 150fa41d6faSX512 if (gPlatform == kPlatformSbi) { 151d031c09cSX512 sbi_system_reset( 152d031c09cSX512 reboot ? SBI_RESET_TYPE_COLD_REBOOT : SBI_RESET_TYPE_SHUTDOWN, 153d031c09cSX512 SBI_RESET_REASON_NONE); 154d031c09cSX512 } 155d031c09cSX512 156d031c09cSX512 HtifShutdown(); 157c085f386SAlexander von Gluck IV return B_ERROR; 158c085f386SAlexander von Gluck IV } 159