xref: /haiku/src/system/kernel/arch/riscv64/arch_cpu.cpp (revision 408a7e27d991f2cbc3335b8d2a119ad5db7d9a6d)
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