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
|
/*
* PowerNV OPAL takeover assembly code, for use by prom_init.c
*
* Copyright 2011 IBM Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <asm/ppc_asm.h>
#include <asm/hvcall.h>
#include <asm/asm-offsets.h>
#include <asm/opal.h>
#define H_HAL_TAKEOVER 0x5124
#define H_HAL_TAKEOVER_QUERY_MAGIC -1
.text
_GLOBAL(opal_query_takeover)
mfcr r0
stw r0,8(r1)
stdu r1,-STACKFRAMESIZE(r1)
std r3,STK_PARAM(R3)(r1)
std r4,STK_PARAM(R4)(r1)
li r3,H_HAL_TAKEOVER
li r4,H_HAL_TAKEOVER_QUERY_MAGIC
HVSC
addi r1,r1,STACKFRAMESIZE
ld r10,STK_PARAM(R3)(r1)
std r4,0(r10)
ld r10,STK_PARAM(R4)(r1)
std r5,0(r10)
lwz r0,8(r1)
mtcrf 0xff,r0
blr
_GLOBAL(opal_do_takeover)
mfcr r0
stw r0,8(r1)
mflr r0
std r0,16(r1)
bl __opal_do_takeover
ld r0,16(r1)
mtlr r0
lwz r0,8(r1)
mtcrf 0xff,r0
blr
__opal_do_takeover:
ld r4,0(r3)
ld r5,0x8(r3)
ld r6,0x10(r3)
ld r7,0x18(r3)
ld r8,0x20(r3)
ld r9,0x28(r3)
ld r10,0x30(r3)
ld r11,0x38(r3)
li r3,H_HAL_TAKEOVER
HVSC
blr
.globl opal_secondary_entry
opal_secondary_entry:
mr r31,r3
mfmsr r11
li r12,(MSR_SF | MSR_ISF)@highest
sldi r12,r12,48
or r11,r11,r12
mtmsrd r11
isync
mfspr r4,SPRN_PIR
std r4,0(r3)
1: HMT_LOW
ld r4,8(r3)
cmpli cr0,r4,0
beq 1b
HMT_MEDIUM
1: addi r3,r31,16
bl __opal_do_takeover
b 1b
_GLOBAL(opal_enter_rtas)
mflr r0
std r0,16(r1)
stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
/* Because PROM is running in 32b mode, it clobbers the high order half
* of all registers that it saves. We therefore save those registers
* PROM might touch to the stack. (r0, r3-r13 are caller saved)
*/
SAVE_GPR(2, r1)
SAVE_GPR(13, r1)
SAVE_8GPRS(14, r1)
SAVE_10GPRS(22, r1)
mfcr r10
mfmsr r11
std r10,_CCR(r1)
std r11,_MSR(r1)
/* Get the PROM entrypoint */
mtlr r5
/* Switch MSR to 32 bits mode
*/
li r12,1
rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
andc r11,r11,r12
li r12,1
rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
andc r11,r11,r12
mtmsrd r11
isync
/* Enter RTAS here... */
blrl
/* Just make sure that r1 top 32 bits didn't get
* corrupt by OF
*/
rldicl r1,r1,0,32
/* Restore the MSR (back to 64 bits) */
ld r0,_MSR(r1)
MTMSRD(r0)
isync
/* Restore other registers */
REST_GPR(2, r1)
REST_GPR(13, r1)
REST_8GPRS(14, r1)
REST_10GPRS(22, r1)
ld r4,_CCR(r1)
mtcr r4
addi r1,r1,PROM_FRAME_SIZE
ld r0,16(r1)
mtlr r0
blr
|