GNU Linux-libre 4.14.266-gnu1
[releases.git] / arch / powerpc / purgatory / trampoline.S
1 /*
2  * kexec trampoline
3  *
4  * Based on code taken from kexec-tools and kexec-lite.
5  *
6  * Copyright (C) 2004 - 2005, Milton D Miller II, IBM Corporation
7  * Copyright (C) 2006, Mohan Kumar M, IBM Corporation
8  * Copyright (C) 2013, Anton Blanchard, IBM Corporation
9  *
10  * This program is free software; you can redistribute it and/or modify it under
11  * the terms of the GNU General Public License as published by the Free
12  * Software Foundation (version 2 of the License).
13  */
14
15 #if defined(__LITTLE_ENDIAN__)
16 #define STWX_BE stwbrx
17 #define LWZX_BE lwbrx
18 #elif defined(__BIG_ENDIAN__)
19 #define STWX_BE stwx
20 #define LWZX_BE lwzx
21 #else
22 #error no endianness defined!
23 #endif
24
25         .machine ppc64
26         .balign 256
27         .globl purgatory_start
28 purgatory_start:
29         b       master
30
31         /* ABI: possible run_at_load flag at 0x5c */
32         .org purgatory_start + 0x5c
33         .globl run_at_load
34 run_at_load:
35         .long 0
36         .size run_at_load, . - run_at_load
37
38         /* ABI: slaves start at 60 with r3=phys */
39         .org purgatory_start + 0x60
40 slave:
41         b .
42         /* ABI: end of copied region */
43         .org purgatory_start + 0x100
44         .size purgatory_start, . - purgatory_start
45
46 /*
47  * The above 0x100 bytes at purgatory_start are replaced with the
48  * code from the kernel (or next stage) by setup_purgatory().
49  */
50
51 master:
52         or      %r1,%r1,%r1     /* low priority to let other threads catchup */
53         isync
54         mr      %r17,%r3        /* save cpu id to r17 */
55         mr      %r15,%r4        /* save physical address in reg15 */
56
57         or      %r3,%r3,%r3     /* ok now to high priority, lets boot */
58         lis     %r6,0x1
59         mtctr   %r6             /* delay a bit for slaves to catch up */
60         bdnz    .               /* before we overwrite 0-100 again */
61
62         bl      0f              /* Work out where we're running */
63 0:      mflr    %r18
64
65         /* load device-tree address */
66         ld      %r3, (dt_offset - 0b)(%r18)
67         mr      %r16,%r3        /* save dt address in reg16 */
68         li      %r4,20
69         LWZX_BE %r6,%r3,%r4     /* fetch __be32 version number at byte 20 */
70         cmpwi   %cr0,%r6,2      /* v2 or later? */
71         blt     1f
72         li      %r4,28
73         STWX_BE %r17,%r3,%r4    /* Store my cpu as __be32 at byte 28 */
74 1:
75         /* load the kernel address */
76         ld      %r4,(kernel - 0b)(%r18)
77
78         /* load the run_at_load flag */
79         /* possibly patched by kexec */
80         ld      %r6,(run_at_load - 0b)(%r18)
81         /* and patch it into the kernel */
82         stw     %r6,(0x5c)(%r4)
83
84         mr      %r3,%r16        /* restore dt address */
85
86         li      %r5,0           /* r5 will be 0 for kernel */
87
88         mfmsr   %r11
89         andi.   %r10,%r11,1     /* test MSR_LE */
90         bne     .Little_endian
91
92         mtctr   %r4             /* prepare branch to */
93         bctr                    /* start kernel */
94
95 .Little_endian:
96         mtsrr0  %r4             /* prepare branch to */
97
98         clrrdi  %r11,%r11,1     /* clear MSR_LE */
99         mtsrr1  %r11
100
101         rfid                    /* update MSR and start kernel */
102
103
104         .balign 8
105         .globl kernel
106 kernel:
107         .8byte  0x0
108         .size kernel, . - kernel
109
110         .balign 8
111         .globl dt_offset
112 dt_offset:
113         .8byte  0x0
114         .size dt_offset, . - dt_offset
115
116
117         .data
118         .balign 8
119 .globl purgatory_sha256_digest
120 purgatory_sha256_digest:
121         .skip   32
122         .size purgatory_sha256_digest, . - purgatory_sha256_digest
123
124         .balign 8
125 .globl purgatory_sha_regions
126 purgatory_sha_regions:
127         .skip   8 * 2 * 16
128         .size purgatory_sha_regions, . - purgatory_sha_regions