xref: /haiku/src/system/kernel/arch/riscv64/arch_cpu.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
1 /*
2  * Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <KernelExport.h>
8 
9 #include <arch/cpu.h>
10 #include <boot/kernel_args.h>
11 #include <vm/VMAddressSpace.h>
12 #include <commpage.h>
13 #include <elf.h>
14 #include <Htif.h>
15 #include <platform/sbi/sbi_syscalls.h>
16 
17 
18 extern "C" void SVec();
19 
20 extern uint32 gPlatform;
21 
22 
23 status_t
24 arch_cpu_preboot_init_percpu(kernel_args *args, int curr_cpu)
25 {
26 	// dprintf("arch_cpu_preboot_init_percpu(%" B_PRId32 ")\n", curr_cpu);
27 	return B_OK;
28 }
29 
30 
31 status_t
32 arch_cpu_init_percpu(kernel_args *args, int curr_cpu)
33 {
34 	SetStvec((uint64)SVec);
35 	SstatusReg sstatus{.val = Sstatus()};
36 	sstatus.ie = 0;
37 	sstatus.fs = extStatusInitial; // enable FPU
38 	sstatus.xs = extStatusOff;
39 	SetSstatus(sstatus.val);
40 	SetBitsSie((1 << sTimerInt) | (1 << sSoftInt) | (1 << sExternInt));
41 
42 	return B_OK;
43 }
44 
45 
46 status_t
47 arch_cpu_init(kernel_args *args)
48 {
49 	for (uint32 curCpu = 0; curCpu < args->num_cpus; curCpu++) {
50 		cpu_ent* cpu = &gCPU[curCpu];
51 
52 		cpu->arch.hartId = args->arch_args.hartIds[curCpu];
53 
54 		cpu->topology_id[CPU_TOPOLOGY_PACKAGE] = 0;
55 		cpu->topology_id[CPU_TOPOLOGY_CORE] = curCpu;
56 		cpu->topology_id[CPU_TOPOLOGY_SMT] = 0;
57 
58 		for (unsigned int i = 0; i < CPU_MAX_CACHE_LEVEL; i++)
59 			cpu->cache_id[i] = -1;
60 	}
61 
62 	uint64 conversionFactor
63 		= (1LL << 32) * 1000000LL / args->arch_args.timerFrequency;
64 
65 	__riscv64_setup_system_time(conversionFactor);
66 
67 	return B_OK;
68 }
69 
70 
71 status_t
72 arch_cpu_init_post_vm(kernel_args *args)
73 {
74 	// Set address space ownership to currently running threads
75 	for (uint32 i = 0; i < args->num_cpus; i++) {
76 		VMAddressSpace::Kernel()->Get();
77 	}
78 
79 	return B_OK;
80 }
81 
82 
83 status_t
84 arch_cpu_init_post_modules(kernel_args *args)
85 {
86 	return B_OK;
87 }
88 
89 
90 void
91 arch_cpu_sync_icache(void *address, size_t len)
92 {
93 	FenceI();
94 
95 	if (smp_get_num_cpus() > 1) {
96 		memory_full_barrier();
97 		sbi_remote_fence_i(0, -1);
98 	}
99 }
100 
101 
102 void
103 arch_cpu_memory_read_barrier(void)
104 {
105 }
106 
107 
108 void
109 arch_cpu_memory_write_barrier(void)
110 {
111 }
112 
113 
114 void
115 arch_cpu_invalidate_TLB_range(addr_t start, addr_t end)
116 {
117 	int32 numPages = end / B_PAGE_SIZE - start / B_PAGE_SIZE;
118 	while (numPages-- >= 0) {
119 		FlushTlbPage(start);
120 		start += B_PAGE_SIZE;
121 	}
122 }
123 
124 
125 void
126 arch_cpu_invalidate_TLB_list(addr_t pages[], int num_pages)
127 {
128 	for (int i = 0; i < num_pages; i++)
129 		FlushTlbPage(pages[i]);
130 }
131 
132 
133 void
134 arch_cpu_global_TLB_invalidate(void)
135 {
136 	FlushTlbAll();
137 }
138 
139 
140 void
141 arch_cpu_user_TLB_invalidate(void)
142 {
143 	FlushTlbAll();
144 }
145 
146 
147 status_t
148 arch_cpu_shutdown(bool reboot)
149 {
150 	if (gPlatform == kPlatformSbi) {
151 		sbi_system_reset(
152 			reboot ? SBI_RESET_TYPE_COLD_REBOOT : SBI_RESET_TYPE_SHUTDOWN,
153 			SBI_RESET_REASON_NONE);
154 	}
155 
156 	HtifShutdown();
157 	return B_ERROR;
158 }
159