]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - stand/powerpc/kboot/kerneltramp.S
devd.conf(5): Fix a mandoc related issue
[FreeBSD/FreeBSD.git] / stand / powerpc / kboot / kerneltramp.S
1 /*
2  * This is the analog to the kexec "purgatory" code
3  *
4  * The goal here is to call the actual kernel entry point with the arguments it
5  * expects when kexec calls into it with no arguments. The value of the kernel
6  * entry point and arguments r3-r7 are copied into the trampoline text (which
7  * can be executed from any address) at bytes 8-32. kexec begins execution
8  * of APs at 0x60 bytes past the entry point, executing in a copy relocated
9  * to the absolute address 0x60. Here we implement a loop waiting on the release
10  * of a lock by the kernel at 0x40.
11  * 
12  * $FreeBSD$
13  */
14
15 #include <machine/asm.h>
16
17         .globl  CNAME(kerneltramp),CNAME(szkerneltramp)
18 CNAME(kerneltramp):
19         mflr %r9
20         bl 2f
21         .space 24       /* branch address, r3-r7 */
22
23 /*
24  * MUST BE IN SYNC WITH:
25  *  struct trampoline_data {
26  *   uint32_t   kernel_entry;
27  *   uint32_t   dtb;
28  *   uint32_t   phys_mem_offset;
29  *   uint32_t   of_entry;
30  *   uint32_t   mdp;
31  *   uint32_t   mdp_size;
32  *  };
33  */
34
35 . = kerneltramp + 0x40  /* AP spinlock */
36         .long 0
37
38 . = kerneltramp + 0x60  /* AP entry point */
39         li      %r3,0x40
40 1:      lwz     %r1,0(%r3)
41         cmpwi   %r1,0
42         beq     1b
43
44         /* Jump into CPU reset */
45         li      %r0,0x100
46         icbi    0,%r0
47         isync
48         sync
49         ba      0x100
50
51 2:      /* Continuation of kerneltramp */
52         mflr    %r8
53         mtlr    %r9
54
55         mfmsr   %r10
56         andi.   %r10, %r10, 1   /* test MSR_LE */
57         bne     little_endian
58
59 /* We're starting in BE */
60 big_endian:
61         lwz     %r3,4(%r8)
62         lwz     %r4,8(%r8)
63         lwz     %r5,12(%r8)
64         lwz     %r6,16(%r8)
65         lwz     %r7,20(%r8)
66
67         lwz     %r10, 0(%r8)
68         mtctr   %r10
69         bctr
70
71 /* We're starting in LE */
72 little_endian:
73
74         /* Entries are BE, swap them during load. */
75         li      %r10, 4
76         lwbrx   %r3, %r8, %r10
77         li      %r10, 8
78         lwbrx   %r4, %r8, %r10
79         li      %r10, 12
80         lwbrx   %r5, %r8, %r10
81         li      %r10, 16
82         lwbrx   %r6, %r8, %r10
83         li      %r10, 20
84         lwbrx   %r7, %r8, %r10
85
86         /* Clear MSR_LE flag to enter the BE world */
87         mfmsr   %r10
88         clrrdi  %r10, %r10, 1
89         mtsrr1  %r10
90
91         /* Entry is at 0(%r8) */
92         li      %r10, 0
93         lwbrx   %r10, %r8, %r10
94         mtsrr0  %r10
95
96         rfid
97
98 endkerneltramp:
99
100         .data
101 CNAME(szkerneltramp):
102         .long endkerneltramp - CNAME(kerneltramp)