xref: /haiku/src/system/kernel/arch/ppc/arch_asm.S (revision d25503d3dbd8e3f526fd0a9bdd884b8e43c1b794)
1/*
2 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 *
5 * Copyright 2003, Travis Geiselbrecht. All rights reserved.
6 * Distributed under the terms of the NewOS License.
7 */
8
9#define FUNCTION(x) .global x; .type x,@function; x
10
11#define MSR_EXCEPTIONS_ENABLED 15
12
13.text
14
15// ToDo: fixme
16FUNCTION(reboot):
17    b   .
18
19
20/* void arch_int_enable_interrupts(void) */
21FUNCTION(arch_int_enable_interrupts):
22	mfmsr	%r3							// load msr
23
24	li		%r4, 1
25	insrwi  %r3, %r4, 1, 31 - MSR_EXCEPTIONS_ENABLED
26		// sets bit 15, EE
27
28	mtmsr	%r3							// put it back into the msr
29	isync
30	blr
31
32
33/* int arch_int_disable_interrupts(void)
34 * r3
35 */
36FUNCTION(arch_int_disable_interrupts):
37	mfmsr	%r4							// load msr
38
39	mr		%r3, %r4					// save old state
40	rlwinm  %r4, %r4, 0, 32 - MSR_EXCEPTIONS_ENABLED, 30 - MSR_EXCEPTIONS_ENABLED
41		// clears bit 15, EE
42
43	mtmsr	%r4							// put it back into the msr
44	isync
45	blr
46
47
48/* void arch_int_restore_interrupts(int oldState)
49 *									r3
50 */
51FUNCTION(arch_int_restore_interrupts):
52	mfmsr	%r4
53
54	rlwimi  %r4, %r3, 0, 31 - MSR_EXCEPTIONS_ENABLED, 31 - MSR_EXCEPTIONS_ENABLED
55		// clear or set bit 15, EE to the same state as in r3, oldState
56
57	mtmsr	%r4
58	isync
59	blr
60
61/* bool arch_int_are_interrupts_enabled(void) */
62FUNCTION(arch_int_are_interrupts_enabled):
63	mfmsr	%r3							// load msr
64	extrwi	%r3, %r3, 1, 31 - MSR_EXCEPTIONS_ENABLED
65		// mask out the EE bit
66	blr
67
68
69// ToDo: fixme
70FUNCTION(dbg_save_registers):
71	blr
72
73/* long long get_time_base(void) */
74FUNCTION(get_time_base):
751:
76	mftbu	%r3							// get the upper time base register
77	mftb	%r4							// get the lower time base register
78	mftbu	%r5							// get the upper again
79	cmpw	%r5, %r3					// see if it changed while we were reading the lower
80	bne-	1b							// if so, repeat
81	blr
82
83/* void getibats(int bats[8]); */
84FUNCTION(getibats):
85	mfibatu 	%r0,0
86	stw     	%r0,0(%r3)
87	mfibatl 	%r0,0
88	stwu		%r0,4(%r3)
89	mfibatu 	%r0,1
90	stwu		%r0,4(%r3)
91	mfibatl 	%r0,1
92	stwu		%r0,4(%r3)
93	mfibatu 	%r0,2
94	stwu		%r0,4(%r3)
95	mfibatl 	%r0,2
96	stwu		%r0,4(%r3)
97	mfibatu 	%r0,3
98	stwu		%r0,4(%r3)
99	mfibatl 	%r0,3
100	stwu		%r0,4(%r3)
101	blr
102
103// void setibats(int bats[8]);
104FUNCTION(setibats):
105	lwz			%r0,0(%r3)
106	mtibatu 	0,%r0
107	isync
108	lwzu		%r0,4(%r3)
109	mtibatl 	0,%r0
110	isync
111	lwzu		%r0,4(%r3)
112	mtibatu 	1,%r0
113	isync
114	lwzu		%r0,4(%r3)
115	mtibatl 	1,%r0
116	isync
117	lwzu		%r0,4(%r3)
118	mtibatu 	2,%r0
119	isync
120	lwzu		%r0,4(%r3)
121	mtibatl 	2,%r0
122	isync
123	lwzu		%r0,4(%r3)
124	mtibatu 	3,%r0
125	isync
126	lwzu		%r0,4(%r3)
127	mtibatl 	3,%r0
128	isync
129
130	blr
131
132// void getdbats(int bats[8]);
133FUNCTION(getdbats):
134	mfdbatu 	%r0,0
135	stw     	%r0,0(%r3)
136	mfdbatl 	%r0,0
137	stwu		%r0,4(%r3)
138	mfdbatu 	%r0,1
139	stwu		%r0,4(%r3)
140	mfdbatl 	%r0,1
141	stwu		%r0,4(%r3)
142	mfdbatu 	%r0,2
143	stwu		%r0,4(%r3)
144	mfdbatl 	%r0,2
145	stwu		%r0,4(%r3)
146	mfdbatu		%r0,3
147	stwu		%r0,4(%r3)
148	mfdbatl 	%r0,3
149	stwu		%r0,4(%r3)
150	blr
151
152// void setdbats(int bats[8]);
153FUNCTION(setdbats):
154	lwz			%r0,0(%r3)
155	mtdbatu 	0,%r0
156	lwzu		%r0,4(%r3)
157	mtdbatl 	0,%r0
158	lwzu		%r0,4(%r3)
159	mtdbatu 	1,%r0
160	lwzu		%r0,4(%r3)
161	mtdbatl 	1,%r0
162	lwzu		%r0,4(%r3)
163	mtdbatu 	2,%r0
164	lwzu		%r0,4(%r3)
165	mtdbatl 	2,%r0
166	lwzu		%r0,4(%r3)
167	mtdbatu 	3,%r0
168	lwzu		%r0,4(%r3)
169	mtdbatl 	3,%r0
170	sync
171
172	blr
173
174// unsigned int gethid0();
175FUNCTION(gethid0):
176	mfspr		%r3, 1008
177	blr
178
179// void sethid0(unsigned int val);
180FUNCTION(sethid0):
181	isync
182	mtspr		1008, %r3
183	isync
184	blr
185
186// unsigned int getl2cr();
187FUNCTION(getl2cr):
188	mfspr		%r3, 1017
189	blr
190
191// void setl2cr(unsigned int val);
192FUNCTION(setl2cr):
193	isync
194	mtspr		1017, %r3
195	isync
196	blr
197
198
199// void ppc_context_switch(addr_t *old_sp, addr_t new_sp);
200FUNCTION(ppc_context_switch):
201
202	// regs to push on the stack: f13-f31, r13-r31, cr, r2, lr
203
204	// push the old regs we need to save on the stack
205	// f31-13
206	stfdu		%f31, -8(%r1)
207	stfdu		%f30, -8(%r1)
208	stfdu		%f29, -8(%r1)
209	stfdu		%f28, -8(%r1)
210	stfdu		%f27, -8(%r1)
211	stfdu		%f26, -8(%r1)
212	stfdu		%f25, -8(%r1)
213	stfdu		%f24, -8(%r1)
214	stfdu		%f23, -8(%r1)
215	stfdu		%f22, -8(%r1)
216	stfdu		%f21, -8(%r1)
217	stfdu		%f20, -8(%r1)
218	stfdu		%f19, -8(%r1)
219	stfdu		%f18, -8(%r1)
220	stfdu		%f17, -8(%r1)
221	stfdu		%f16, -8(%r1)
222	stfdu		%f15, -8(%r1)
223	stfdu		%f14, -8(%r1)
224	stfdu		%f13, -8(%r1)
225
226	// r31-13, r2
227	stwu		%r31, -4(%r1)
228	stwu		%r30, -4(%r1)
229	stwu		%r29, -4(%r1)
230	stwu		%r28, -4(%r1)
231	stwu		%r27, -4(%r1)
232	stwu		%r26, -4(%r1)
233	stwu		%r25, -4(%r1)
234	stwu		%r24, -4(%r1)
235	stwu		%r23, -4(%r1)
236	stwu		%r22, -4(%r1)
237	stwu		%r21, -4(%r1)
238	stwu		%r20, -4(%r1)
239	stwu		%r19, -4(%r1)
240	stwu		%r18, -4(%r1)
241	stwu		%r17, -4(%r1)
242	stwu		%r16, -4(%r1)
243	stwu		%r15, -4(%r1)
244	stwu		%r14, -4(%r1)
245	stwu		%r13, -4(%r1)
246	stwu		%r2, -4(%r1)
247
248	// CR and LR
249	mfcr		%r0
250	stwu		%r0, -4(%r1)
251	mflr		%r0
252	stwu		%r0, -4(%r1)
253
254	// save the old stack pointer
255	stwu		%r1, 0(%r3)
256
257	// restore the new stack pointer
258	mr			%r1, %r4
259
260	// restore the new regs
261	// LR and CR
262	lwz			%r0, 0(%r1)
263	mtlr		%r0
264	lwzu		%r0, 4(%r1)
265	mtcr		%r0
266
267	// r2, r13-31
268	lwzu		%r2, 4(%r1)
269	lwzu		%r13, 4(%r1)
270	lwzu		%r14, 4(%r1)
271	lwzu		%r15, 4(%r1)
272	lwzu		%r16, 4(%r1)
273	lwzu		%r17, 4(%r1)
274	lwzu		%r18, 4(%r1)
275	lwzu		%r19, 4(%r1)
276	lwzu		%r20, 4(%r1)
277	lwzu		%r21, 4(%r1)
278	lwzu		%r22, 4(%r1)
279	lwzu		%r23, 4(%r1)
280	lwzu		%r24, 4(%r1)
281	lwzu		%r25, 4(%r1)
282	lwzu		%r26, 4(%r1)
283	lwzu		%r27, 4(%r1)
284	lwzu		%r28, 4(%r1)
285	lwzu		%r29, 4(%r1)
286	lwzu		%r30, 4(%r1)
287	lwzu		%r31, 4(%r1)
288
289	// f13-31
290	lfdu		%f13, 4(%r1)
291	lfdu		%f14, 8(%r1)
292	lfdu		%f15, 8(%r1)
293	lfdu		%f16, 8(%r1)
294	lfdu		%f17, 8(%r1)
295	lfdu		%f18, 8(%r1)
296	lfdu		%f19, 8(%r1)
297	lfdu		%f20, 8(%r1)
298	lfdu		%f21, 8(%r1)
299	lfdu		%f22, 8(%r1)
300	lfdu		%f23, 8(%r1)
301	lfdu		%f24, 8(%r1)
302	lfdu		%f25, 8(%r1)
303	lfdu		%f26, 8(%r1)
304	lfdu		%f27, 8(%r1)
305	lfdu		%f28, 8(%r1)
306	lfdu		%f29, 8(%r1)
307	lfdu		%f30, 8(%r1)
308	lfdu		%f31, 8(%r1)
309
310	addi		%r1, %r1, 8
311
312	blr
313
314
315// void ppc_switch_stack_and_call(addr_t newKstack,
316//		void (*func)(void *), void *arg)
317FUNCTION(ppc_switch_stack_and_call):
318	mr			%r1, %r3	// set the new stack pointer
319	mtctr		%r4			// move the target function into CTR
320	mr			%r3, %r5	// move the arg to this func to the new arg
321	bctr
322
323
324// ppc_kernel_thread_root(): parameters in r13-r15, the functions to call
325// (in that order). The function is used when spawing threads. It usually calls
326// an initialization function, the actual thread function, and a function that
327// destroys the thread.
328FUNCTION(ppc_kernel_thread_root):
329	mtlr		%r13
330	blrl
331	mtlr		%r14
332	blrl
333	mtlr		%r15
334	blrl
335
336	// We should never get here. If we do, it's time to enter the kernel
337	// debugger (without a message at the moment).
338	li			%r3, 0
339	b			kernel_debugger
340
341