hc
2025-02-14 bbb9540dc49f70f6b703d1c8d1b85fa5f602d86e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
#include <linux/kexec.h>
 
#include <asm/assembly.h>
#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/setup.h>
#include <asm/psw.h>
 
.level PA_ASM_LEVEL
 
.macro    kexec_param name
.align 8
ENTRY(kexec\()_\name)
#ifdef CONFIG_64BIT
   .dword 0
#else
   .word 0
#endif
 
ENTRY(kexec\()_\name\()_offset)
   .word kexec\()_\name - relocate_new_kernel
.endm
 
.text
 
/* args:
 * r26 - kimage->head
 * r25 - start address of kernel
 * r24 - physical address of relocate code
 */
 
ENTRY_CFI(relocate_new_kernel)
0:    copy    %arg1, %rp
   /* disable I and Q bit, so we are allowed to execute RFI */
   rsm PSW_SM_I, %r0
   nop
   nop
   nop
   nop
   nop
   nop
   nop
 
   rsm PSW_SM_Q, %r0
   nop
   nop
   nop
   nop
   nop
   nop
   nop
 
   /*
    * After return-from-interrupt, we want to run without Code/Data
    * translation enabled just like on a normal boot.
    */
 
   /* calculate new physical execution address */
   ldo    1f-0b(%arg2), %r1
   mtctl    %r0, %cr17 /* IIASQ */
   mtctl    %r0, %cr17 /* IIASQ */
   mtctl    %r1, %cr18 /* IIAOQ */
   ldo    4(%r1),%r1
   mtctl    %r1, %cr18 /* IIAOQ */
#ifdef CONFIG_64BIT
   depdi,z    1, PSW_W_BIT, 1, %r1
   mtctl    %r1, %cr22 /* IPSW */
#else
   mtctl    %r0, %cr22 /* IPSW */
#endif
   /* lets go... */
   rfi
1:    nop
   nop
 
.Lloop:
   LDREG,ma    REG_SZ(%arg0), %r3
   /* If crash kernel, no copy needed */
   cmpib,COND(=),n 0,%r3,boot
 
   bb,<,n        %r3, 31 - IND_DONE_BIT, boot
   bb,>=,n        %r3, 31 - IND_INDIRECTION_BIT, .Lnotind
   /* indirection, load and restart */
   movb        %r3, %arg0, .Lloop
   depi        0, 31, PAGE_SHIFT, %arg0
 
.Lnotind:
   bb,>=,n        %r3, 31 - IND_DESTINATION_BIT, .Lnotdest
   b        .Lloop
   copy        %r3, %r20
 
.Lnotdest:
   bb,>=        %r3, 31 - IND_SOURCE_BIT, .Lloop
   depi        0, 31, PAGE_SHIFT, %r3
   copy        %r3, %r21
 
   /* copy page */
   copy        %r0, %r18
   zdepi        1, 31 - PAGE_SHIFT, 1, %r18
   add        %r20, %r18, %r17
 
   depi        0, 31, PAGE_SHIFT, %r20
.Lcopy:
   copy        %r20, %r12
   LDREG,ma    REG_SZ(%r21), %r8
   LDREG,ma    REG_SZ(%r21), %r9
   LDREG,ma    REG_SZ(%r21), %r10
   LDREG,ma    REG_SZ(%r21), %r11
   STREG,ma    %r8, REG_SZ(%r20)
   STREG,ma    %r9, REG_SZ(%r20)
   STREG,ma    %r10, REG_SZ(%r20)
   STREG,ma    %r11, REG_SZ(%r20)
 
#ifndef CONFIG_64BIT
   LDREG,ma    REG_SZ(%r21), %r8
   LDREG,ma    REG_SZ(%r21), %r9
   LDREG,ma    REG_SZ(%r21), %r10
   LDREG,ma    REG_SZ(%r21), %r11
   STREG,ma    %r8, REG_SZ(%r20)
   STREG,ma    %r9, REG_SZ(%r20)
   STREG,ma    %r10, REG_SZ(%r20)
   STREG,ma    %r11, REG_SZ(%r20)
#endif
 
   fdc        %r0(%r12)
   cmpb,COND(<<)    %r20,%r17,.Lcopy
   fic        (%sr4, %r12)
   b,n        .Lloop
 
boot:
   mtctl    %r0, %cr15
 
   LDREG    kexec_free_mem-0b(%arg2), %arg0
   LDREG    kexec_cmdline-0b(%arg2), %arg1
   LDREG    kexec_initrd_end-0b(%arg2), %arg3
   LDREG    kexec_initrd_start-0b(%arg2), %arg2
   bv,n %r0(%rp)
 
ENDPROC_CFI(relocate_new_kernel);
 
ENTRY(relocate_new_kernel_size)
       .word relocate_new_kernel_size - relocate_new_kernel
 
kexec_param cmdline
kexec_param initrd_start
kexec_param initrd_end
kexec_param free_mem