Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/powerpc/platforms/iseries/exception.S
10820 views
1
/*
2
* Low level routines for legacy iSeries support.
3
*
4
* Extracted from head_64.S
5
*
6
* PowerPC version
7
* Copyright (C) 1995-1996 Gary Thomas ([email protected])
8
*
9
* Rewritten by Cort Dougan ([email protected]) for PReP
10
* Copyright (C) 1996 Cort Dougan <[email protected]>
11
* Adapted for Power Macintosh by Paul Mackerras.
12
* Low-level exception handlers and MMU support
13
* rewritten by Paul Mackerras.
14
* Copyright (C) 1996 Paul Mackerras.
15
*
16
* Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
17
* Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
18
*
19
* This file contains the low-level support and setup for the
20
* PowerPC-64 platform, including trap and interrupt dispatch.
21
*
22
* This program is free software; you can redistribute it and/or
23
* modify it under the terms of the GNU General Public License
24
* as published by the Free Software Foundation; either version
25
* 2 of the License, or (at your option) any later version.
26
*/
27
28
#include <asm/reg.h>
29
#include <asm/ppc_asm.h>
30
#include <asm/asm-offsets.h>
31
#include <asm/thread_info.h>
32
#include <asm/ptrace.h>
33
#include <asm/cputable.h>
34
#include <asm/mmu.h>
35
36
#include "exception.h"
37
38
.text
39
40
.globl system_reset_iSeries
41
system_reset_iSeries:
42
bl .relative_toc
43
mfspr r13,SPRN_SPRG3 /* Get alpaca address */
44
LOAD_REG_ADDR(r23, alpaca)
45
li r0,ALPACA_SIZE
46
sub r23,r13,r23
47
divdu r24,r23,r0 /* r24 has cpu number */
48
cmpwi 0,r24,0 /* Are we processor 0? */
49
bne 1f
50
LOAD_REG_ADDR(r13, boot_paca)
51
mtspr SPRN_SPRG_PACA,r13 /* Save it away for the future */
52
mfmsr r23
53
ori r23,r23,MSR_RI
54
mtmsrd r23 /* RI on */
55
b .__start_initialization_iSeries /* Start up the first processor */
56
1: mfspr r4,SPRN_CTRLF
57
li r5,CTRL_RUNLATCH /* Turn off the run light */
58
andc r4,r4,r5
59
mtspr SPRN_CTRLT,r4
60
61
/* Spin on __secondary_hold_spinloop until it is updated by the boot cpu. */
62
/* In the UP case we'll yield() later, and we will not access the paca anyway */
63
#ifdef CONFIG_SMP
64
iSeries_secondary_wait_paca:
65
HMT_LOW
66
LOAD_REG_ADDR(r23, __secondary_hold_spinloop)
67
ld r23,0(r23)
68
69
cmpdi 0,r23,0
70
bne 2f /* go on when the master is ready */
71
72
/* Keep poking the Hypervisor until we're released */
73
/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
74
lis r3,0x8002
75
rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */
76
li r0,-1 /* r0=-1 indicates a Hypervisor call */
77
sc /* Invoke the hypervisor via a system call */
78
b iSeries_secondary_wait_paca
79
80
2:
81
HMT_MEDIUM
82
sync
83
84
LOAD_REG_ADDR(r3, nr_cpu_ids) /* get number of pacas allocated */
85
lwz r3,0(r3) /* nr_cpus= or NR_CPUS can limit */
86
cmpld 0,r24,r3 /* is our cpu number allocated? */
87
bge iSeries_secondary_yield /* no, yield forever */
88
89
/* Load our paca now that it's been allocated */
90
LOAD_REG_ADDR(r13, paca)
91
ld r13,0(r13)
92
mulli r0,r24,PACA_SIZE
93
add r13,r13,r0
94
mtspr SPRN_SPRG_PACA,r13 /* Save it away for the future */
95
mfmsr r23
96
ori r23,r23,MSR_RI
97
mtmsrd r23 /* RI on */
98
99
iSeries_secondary_smp_loop:
100
lbz r23,PACAPROCSTART(r13) /* Test if this processor
101
* should start */
102
cmpwi 0,r23,0
103
bne 3f /* go on when we are told */
104
105
HMT_LOW
106
/* Let the Hypervisor know we are alive */
107
/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
108
lis r3,0x8002
109
rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */
110
li r0,-1 /* r0=-1 indicates a Hypervisor call */
111
sc /* Invoke the hypervisor via a system call */
112
mfspr r13,SPRN_SPRG_PACA /* Put r13 back ???? */
113
b iSeries_secondary_smp_loop /* wait for signal to start */
114
115
3:
116
HMT_MEDIUM
117
sync
118
LOAD_REG_ADDR(r3,current_set)
119
sldi r28,r24,3 /* get current_set[cpu#] */
120
ldx r3,r3,r28
121
addi r1,r3,THREAD_SIZE
122
subi r1,r1,STACK_FRAME_OVERHEAD
123
124
b __secondary_start /* Loop until told to go */
125
#endif /* CONFIG_SMP */
126
127
iSeries_secondary_yield:
128
/* Yield the processor. This is required for non-SMP kernels
129
which are running on multi-threaded machines. */
130
HMT_LOW
131
lis r3,0x8000
132
rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */
133
addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */
134
li r4,0 /* "yield timed" */
135
li r5,-1 /* "yield forever" */
136
li r0,-1 /* r0=-1 indicates a Hypervisor call */
137
sc /* Invoke the hypervisor via a system call */
138
mfspr r13,SPRN_SPRG_PACA /* Put r13 back ???? */
139
b iSeries_secondary_yield /* If SMP not configured, secondaries
140
* loop forever */
141
142
/*** ISeries-LPAR interrupt handlers ***/
143
144
STD_EXCEPTION_ISERIES(machine_check, PACA_EXMC)
145
146
.globl data_access_iSeries
147
data_access_iSeries:
148
mtspr SPRN_SPRG_SCRATCH0,r13
149
BEGIN_FTR_SECTION
150
mfspr r13,SPRN_SPRG_PACA
151
std r9,PACA_EXSLB+EX_R9(r13)
152
std r10,PACA_EXSLB+EX_R10(r13)
153
mfspr r10,SPRN_DAR
154
mfspr r9,SPRN_DSISR
155
srdi r10,r10,60
156
rlwimi r10,r9,16,0x20
157
mfcr r9
158
cmpwi r10,0x2c
159
beq .do_stab_bolted_iSeries
160
ld r10,PACA_EXSLB+EX_R10(r13)
161
std r11,PACA_EXGEN+EX_R11(r13)
162
ld r11,PACA_EXSLB+EX_R9(r13)
163
std r12,PACA_EXGEN+EX_R12(r13)
164
mfspr r12,SPRN_SPRG_SCRATCH0
165
std r10,PACA_EXGEN+EX_R10(r13)
166
std r11,PACA_EXGEN+EX_R9(r13)
167
std r12,PACA_EXGEN+EX_R13(r13)
168
EXCEPTION_PROLOG_ISERIES_1
169
FTR_SECTION_ELSE
170
EXCEPTION_PROLOG_1(PACA_EXGEN)
171
EXCEPTION_PROLOG_ISERIES_1
172
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_SLB)
173
b data_access_common
174
175
.do_stab_bolted_iSeries:
176
std r11,PACA_EXSLB+EX_R11(r13)
177
std r12,PACA_EXSLB+EX_R12(r13)
178
mfspr r10,SPRN_SPRG_SCRATCH0
179
std r10,PACA_EXSLB+EX_R13(r13)
180
EXCEPTION_PROLOG_ISERIES_1
181
b .do_stab_bolted
182
183
.globl data_access_slb_iSeries
184
data_access_slb_iSeries:
185
mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */
186
mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */
187
std r3,PACA_EXSLB+EX_R3(r13)
188
mfspr r3,SPRN_DAR
189
std r9,PACA_EXSLB+EX_R9(r13)
190
mfcr r9
191
#ifdef __DISABLED__
192
cmpdi r3,0
193
bge slb_miss_user_iseries
194
#endif
195
std r10,PACA_EXSLB+EX_R10(r13)
196
std r11,PACA_EXSLB+EX_R11(r13)
197
std r12,PACA_EXSLB+EX_R12(r13)
198
mfspr r10,SPRN_SPRG_SCRATCH0
199
std r10,PACA_EXSLB+EX_R13(r13)
200
ld r12,PACALPPACAPTR(r13)
201
ld r12,LPPACASRR1(r12)
202
b .slb_miss_realmode
203
204
STD_EXCEPTION_ISERIES(instruction_access, PACA_EXGEN)
205
206
.globl instruction_access_slb_iSeries
207
instruction_access_slb_iSeries:
208
mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */
209
mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */
210
std r3,PACA_EXSLB+EX_R3(r13)
211
ld r3,PACALPPACAPTR(r13)
212
ld r3,LPPACASRR0(r3) /* get SRR0 value */
213
std r9,PACA_EXSLB+EX_R9(r13)
214
mfcr r9
215
#ifdef __DISABLED__
216
cmpdi r3,0
217
bge slb_miss_user_iseries
218
#endif
219
std r10,PACA_EXSLB+EX_R10(r13)
220
std r11,PACA_EXSLB+EX_R11(r13)
221
std r12,PACA_EXSLB+EX_R12(r13)
222
mfspr r10,SPRN_SPRG_SCRATCH0
223
std r10,PACA_EXSLB+EX_R13(r13)
224
ld r12,PACALPPACAPTR(r13)
225
ld r12,LPPACASRR1(r12)
226
b .slb_miss_realmode
227
228
#ifdef __DISABLED__
229
slb_miss_user_iseries:
230
std r10,PACA_EXGEN+EX_R10(r13)
231
std r11,PACA_EXGEN+EX_R11(r13)
232
std r12,PACA_EXGEN+EX_R12(r13)
233
mfspr r10,SPRG_SCRATCH0
234
ld r11,PACA_EXSLB+EX_R9(r13)
235
ld r12,PACA_EXSLB+EX_R3(r13)
236
std r10,PACA_EXGEN+EX_R13(r13)
237
std r11,PACA_EXGEN+EX_R9(r13)
238
std r12,PACA_EXGEN+EX_R3(r13)
239
EXCEPTION_PROLOG_ISERIES_1
240
b slb_miss_user_common
241
#endif
242
243
MASKABLE_EXCEPTION_ISERIES(hardware_interrupt)
244
STD_EXCEPTION_ISERIES(alignment, PACA_EXGEN)
245
STD_EXCEPTION_ISERIES(program_check, PACA_EXGEN)
246
STD_EXCEPTION_ISERIES(fp_unavailable, PACA_EXGEN)
247
MASKABLE_EXCEPTION_ISERIES(decrementer)
248
STD_EXCEPTION_ISERIES(trap_0a, PACA_EXGEN)
249
STD_EXCEPTION_ISERIES(trap_0b, PACA_EXGEN)
250
251
.globl system_call_iSeries
252
system_call_iSeries:
253
mr r9,r13
254
mfspr r13,SPRN_SPRG_PACA
255
EXCEPTION_PROLOG_ISERIES_1
256
b system_call_common
257
258
STD_EXCEPTION_ISERIES(single_step, PACA_EXGEN)
259
STD_EXCEPTION_ISERIES(trap_0e, PACA_EXGEN)
260
STD_EXCEPTION_ISERIES(performance_monitor, PACA_EXGEN)
261
262
decrementer_iSeries_masked:
263
/* We may not have a valid TOC pointer in here. */
264
li r11,1
265
ld r12,PACALPPACAPTR(r13)
266
stb r11,LPPACADECRINT(r12)
267
li r12,-1
268
clrldi r12,r12,33 /* set DEC to 0x7fffffff */
269
mtspr SPRN_DEC,r12
270
/* fall through */
271
272
hardware_interrupt_iSeries_masked:
273
mtcrf 0x80,r9 /* Restore regs */
274
ld r12,PACALPPACAPTR(r13)
275
ld r11,LPPACASRR0(r12)
276
ld r12,LPPACASRR1(r12)
277
mtspr SPRN_SRR0,r11
278
mtspr SPRN_SRR1,r12
279
ld r9,PACA_EXGEN+EX_R9(r13)
280
ld r10,PACA_EXGEN+EX_R10(r13)
281
ld r11,PACA_EXGEN+EX_R11(r13)
282
ld r12,PACA_EXGEN+EX_R12(r13)
283
ld r13,PACA_EXGEN+EX_R13(r13)
284
rfid
285
b . /* prevent speculative execution */
286
287
_INIT_STATIC(__start_initialization_iSeries)
288
/* Clear out the BSS */
289
LOAD_REG_ADDR(r11,__bss_stop)
290
LOAD_REG_ADDR(r8,__bss_start)
291
sub r11,r11,r8 /* bss size */
292
addi r11,r11,7 /* round up to an even double word */
293
rldicl. r11,r11,61,3 /* shift right by 3 */
294
beq 4f
295
addi r8,r8,-8
296
li r0,0
297
mtctr r11 /* zero this many doublewords */
298
3: stdu r0,8(r8)
299
bdnz 3b
300
4:
301
LOAD_REG_ADDR(r1,init_thread_union)
302
addi r1,r1,THREAD_SIZE
303
li r0,0
304
stdu r0,-STACK_FRAME_OVERHEAD(r1)
305
306
bl .iSeries_early_setup
307
bl .early_setup
308
309
/* relocation is on at this point */
310
311
b .start_here_common
312
313