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	o0	- kernelArgs
12	o1	- kernelEntry
13	o2	- kernelStackTop
14*/
15FUNCTION(arch_start_kernel):
16	save  %sp, -176, %sp
17
18	// Now we have
19	// - Kernel args in i0
20	// - Kernel entry in i1
21	// - Kernel stack top in i2
22
23	// Set the stack, adding the stack bias
24	sub %i2, 2047, %sp // apply stack bias
25
26	// We need to call the kernel with:
27	// o0 = kernel args
28	// o1 = current CPU
29	mov %i0, %o0
30	// Current CPU is always 0 on boot
31	mov %g0, %o1
32
33	// Jump into the kernel, store return address in o7
34	jmpl %i1, %o7
35	nop // branch delay slot...
36
37	// We should never get here, but in case the kernel returns, attempt to
38	// exit cleanly.
39
40	// Forward the return code to the caller
41	mov %o0, %i0
42
43	// Since we saved our context at the start of this function,
44	// a simple "return" should do the job and restore the previous register
45	// window and put us back on the old stack
46	return %i7 + 8
47	nop // Branch delay slot...
48