xref: /haiku/src/system/kernel/arch/arm/arch_cpu.cpp (revision 6f80a9801fedbe7355c4360bd204ba746ec3ec2d)
1 /*
2  * Copyright 2007, François Revol, revol@free.fr.
3  * Distributed under the terms of the MIT License.
4  *
5  * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de.
6  * Distributed under the terms of the MIT License.
7  *
8  * Copyright 2001, Travis Geiselbrecht. All rights reserved.
9  * Distributed under the terms of the NewOS License.
10  */
11 
12 
13 #include <KernelExport.h>
14 
15 #include <arch/cpu.h>
16 #include <boot/kernel_args.h>
17 #include <commpage.h>
18 #include <elf.h>
19 
20 
21 int arch_cpu_type;
22 int arch_fpu_type;
23 int arch_mmu_type;
24 int arch_platform;
25 
26 status_t
27 arch_cpu_preboot_init_percpu(kernel_args *args, int curr_cpu)
28 {
29 	// enable FPU
30 	//ppc:set_msr(get_msr() | MSR_FP_AVAILABLE);
31 
32 	// The current thread must be NULL for all CPUs till we have threads.
33 	// Some boot code relies on this.
34 	arch_thread_set_current_thread(NULL);
35 
36 	return B_OK;
37 }
38 
39 
40 status_t
41 arch_cpu_init_percpu(kernel_args *args, int curr_cpu)
42 {
43 	if (curr_cpu != 0)
44 		panic("No SMP support on ARM yet!\n");
45 
46 	return 0;
47 }
48 
49 
50 status_t
51 arch_cpu_init(kernel_args *args)
52 {
53 	arch_cpu_type = args->arch_args.cpu_type;
54 	arch_fpu_type = args->arch_args.fpu_type;
55 	arch_mmu_type = args->arch_args.mmu_type;
56 	arch_platform = args->arch_args.platform;
57 	arch_platform = args->arch_args.machine;
58 
59 	return B_OK;
60 }
61 
62 
63 status_t
64 arch_cpu_init_post_vm(kernel_args *args)
65 {
66 	return B_OK;
67 }
68 
69 
70 status_t
71 arch_cpu_init_post_modules(kernel_args *args)
72 {
73 	// add the functions to the commpage image
74 	image_id image = get_commpage_image();
75 
76 	return B_OK;
77 }
78 
79 
80 status_t
81 arch_cpu_shutdown(bool reboot)
82 {
83 	while(1)
84 		arch_cpu_idle();
85 
86 	// never reached
87 	return B_ERROR;
88 }
89 
90 
91 void
92 arch_cpu_sync_icache(void *address, size_t len)
93 {
94 	uint32 Rd = 0;
95 	asm volatile ("mcr p15, 0, %[c7format], c7, c5, 0"
96 		: : [c7format] "r" (Rd) );
97 }
98 
99 
100 void
101 arch_cpu_memory_read_barrier(void)
102 {
103 	// TODO: check if we need more here
104 	// (or just call the inline version?)
105 	// cf. headers/private/kernel/arch/arm/arch_atomic.h
106 	asm volatile ("" : : : "memory");
107 }
108 
109 
110 void
111 arch_cpu_memory_write_barrier(void)
112 {
113 	// TODO: check if we need more here
114 	// (or just call the inline version?)
115 	// cf. headers/private/kernel/arch/arm/arch_atomic.h
116 	asm volatile ("" : : : "memory");
117 }
118 
119 
120 void
121 arch_cpu_invalidate_TLB_page(addr_t page)
122 {
123 	// ensure visibility of the update to translation table walks
124 	dsb();
125 
126 	// TLBIMVAIS(page)
127 	asm volatile ("mcr p15, 0, %0, c8, c3, 1"
128 		: : "r" (page));
129 
130 	// ensure completion of TLB invalidation
131 	dsb();
132 	isb();
133 }
134 
135 void
136 arch_cpu_invalidate_TLB_range(addr_t start, addr_t end)
137 {
138 	// ensure visibility of the update to translation table walks
139 	dsb();
140 
141 	int32 num_pages = end / B_PAGE_SIZE - start / B_PAGE_SIZE;
142 	while (num_pages-- >= 0) {
143 		asm volatile ("mcr p15, 0, %[c8format], c8, c6, 1"
144 			: : [c8format] "r" (start) );
145 		start += B_PAGE_SIZE;
146 	}
147 
148 	// ensure completion of TLB invalidation
149 	dsb();
150 	isb();
151 }
152 
153 
154 void
155 arch_cpu_invalidate_TLB_list(addr_t pages[], int num_pages)
156 {
157 	// ensure visibility of the update to translation table walks
158 	dsb();
159 
160 	for (int i = 0; i < num_pages; i++) {
161 		asm volatile ("mcr p15, 0, %[c8format], c8, c6, 1":
162 			: [c8format] "r" (pages[i]) );
163 	}
164 
165 	// ensure completion of TLB invalidation
166 	dsb();
167 	isb();
168 }
169 
170 
171 void
172 arch_cpu_global_TLB_invalidate(void)
173 {
174 	// ensure visibility of the update to translation table walks
175 	dsb();
176 
177 	uint32 Rd = 0;
178 	asm volatile ("mcr p15, 0, %[c8format], c8, c7, 0"
179 		: : [c8format] "r" (Rd) );
180 
181 	// ensure completion of TLB invalidation
182 	dsb();
183 	isb();
184 }
185 
186 
187 void
188 arch_cpu_user_TLB_invalidate(void)
189 {/*
190 	cpu_ops.flush_insn_pipeline();
191 	cpu_ops.flush_atc_user();
192 	cpu_ops.flush_insn_pipeline();
193 */
194 #warning WRITEME
195 }
196