1/*
2 * Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5
6#define FUNCTION(x) .global x; .type x,@function; x
7
8/*	status_t arch_start_kernel(struct kernel_args *kernelArgs,
9		addr_t kernelEntry, addr_t kernelStackTop);
10
11	r3	- kernelArgs
12	r4	- kernelEntry
13	r5	- kernelStackTop
14*/
15FUNCTION(arch_start_kernel):
16	// push a stack frame
17	stwu	%r1, -32(%r1)
18	mflr	%r0
19	stw		%r0, 36(%r1)
20
21	// save the old stack pointer in r29
22	stw		%r29, 20(%r1)
23	mr		%r29, %r1
24
25	// set up the kernel stack
26	subi	%r1, %r5, 16
27
28	// clear the pointer to the previous frame
29	li		%r0, 0
30	stw		%r0, 0(%r1)
31
32	// enter the kernel
33	mtlr	%r4
34	li		%r4, 0
35	blrl
36
37	/* Actually we should never get here, but at least for debugging purposes
38	   it's quite nice to return in an orderly manner. */
39
40	// reset the boot loader stack
41	mr		%r1, %r29
42	lwz		%r29, 20(%r1)
43
44	// pop the stack frame
45	lwz		%r0, 36(%r1)
46	mtlr	%r0
47	addi	%r1, %r1, 32
48	blr
49
50