]> git.saurik.com Git - apple/xnu.git/blame - osfmk/ppc/lowmem_vectors.s
xnu-792.6.56.tar.gz
[apple/xnu.git] / osfmk / ppc / lowmem_vectors.s
CommitLineData
1c79356b 1/*
a3d08fcd 2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
1c79356b
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
ff6e181a
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
1c79356b 12 *
ff6e181a
A
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
ff6e181a
A
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
1c79356b
A
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 * @OSF_COPYRIGHT@
25 */
26
1c79356b
A
27#include <assym.s>
28#include <debug.h>
1c79356b 29#include <db_machine_commands.h>
1c79356b
A
30
31#include <mach_debug.h>
32#include <ppc/asm.h>
33#include <ppc/proc_reg.h>
34#include <ppc/exception.h>
35#include <ppc/Performance.h>
9bccf70c 36#include <ppc/savearea.h>
1c79356b 37#include <mach/ppc/vm_param.h>
1c79356b 38
1c79356b 39#define ESPDEBUG 0
55e303ae 40#define INSTRUMENT 0
1c79356b 41
55e303ae
A
42#define featAltivec 29
43#define wasNapping 30
1c79356b
A
44
45#define VECTOR_SEGMENT .section __VECTORS, __interrupts
46
47 VECTOR_SEGMENT
48
91447636
A
49 .globl EXT(lowGlo)
50EXT(lowGlo):
1c79356b 51
91447636 52 .globl EXT(ExceptionVectorsStart)
1c79356b
A
53
54EXT(ExceptionVectorsStart): /* Used if relocating the exception vectors */
55baseR: /* Used so we have more readable code */
56
55e303ae
A
57;
58; Handle system reset.
59; We do not ever expect a hard reset so we do not actually check.
60; When we come here, we check for a RESET_HANDLER_START (which means we are
61; waking up from sleep), a RESET_HANDLER_BUPOR (which is using for bring up
62; when starting directly from a POR), and RESET_HANDLER_IGNORE (which means
63; ignore the interrupt).
64;
65; Some machines (so far, 32-bit guys) will always ignore a non-START interrupt.
66; The ones who do take it, check if the interrupt is too be ignored. This is
67; always the case until the previous reset is handled (i.e., we have exited
68; from the debugger).
69;
1c79356b
A
70 . = 0xf0
71 .globl EXT(ResetHandler)
72EXT(ResetHandler):
73 .long 0x0
74 .long 0x0
75 .long 0x0
76
77 . = 0x100
78.L_handler100:
79 mtsprg 2,r13 /* Save R13 */
80 mtsprg 3,r11 /* Save R11 */
81 lwz r13,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_TYPE)(br0) ; Get reset type
82 mfcr r11
83 cmpi cr0,r13,RESET_HANDLER_START
84 bne resetexc
85
86 li r11,RESET_HANDLER_NULL
87 stw r11,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_TYPE)(br0) ; Clear reset type
88
89 lwz r4,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_CALL)(br0)
90 lwz r3,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_ARG)(br0)
91 mtlr r4
92 blr
93
91447636 94resetexc: cmplwi r13,RESET_HANDLER_BUPOR ; Special bring up POR sequence?
55e303ae
A
95 bne resetexc2 ; No...
96 lis r4,hi16(EXT(resetPOR)) ; Get POR code
97 ori r4,r4,lo16(EXT(resetPOR)) ; The rest
98 mtlr r4 ; Set it
99 blr ; Jump to it....
100
101resetexc2: cmplwi cr1,r13,RESET_HANDLER_IGNORE ; Are we ignoring these? (Software debounce)
102
103 mfsprg r13,0 ; Get per_proc
104 lwz r13,pfAvailable(r13) ; Get the features
105 rlwinm. r13,r13,0,pf64Bitb,pf64Bitb ; Is this a 64-bit machine?
106 cror cr1_eq,cr0_eq,cr1_eq ; See if we want to take this
107 bne-- cr1,rxCont ; Yes, continue...
108 bne-- rxIg64 ; 64-bit path...
109
110 mtcr r11 ; Restore the CR
111 mfsprg r13,2 ; Restore R13
112 mfsprg r11,0 ; Get per_proc
113 lwz r11,pfAvailable(r11) ; Get the features
114 mtsprg 2,r11 ; Restore sprg2
115 mfsprg r11,3 ; Restore R11
116 rfi ; Return and ignore the reset
117
118rxIg64: mtcr r11 ; Restore the CR
119 mfsprg r11,0 ; Get per_proc
120 mtspr hsprg0,r14 ; Save a register
91447636 121 ld r14,UAW(r11) ; Get the User Assist DoubleWord
55e303ae
A
122 mfsprg r13,2 ; Restore R13
123 lwz r11,pfAvailable(r11) ; Get the features
124 mtsprg 2,r11 ; Restore sprg2
125 mfsprg r11,3 ; Restore R11
126 mtsprg 3,r14 ; Set the UAW in sprg3
127 mfspr r14,hsprg0 ; Restore R14
128 rfid ; Return and ignore the reset
129
130rxCont: mtcr r11
131 li r11,RESET_HANDLER_IGNORE ; Get set to ignore
132 stw r11,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_TYPE)(br0) ; Start ignoring these
133 mfsprg r13,1 /* Get the exception save area */
1c79356b
A
134 li r11,T_RESET /* Set 'rupt code */
135 b .L_exception_entry /* Join common... */
136
137/*
138 * Machine check
139 */
140
141 . = 0x200
142.L_handler200:
55e303ae
A
143 mtsprg 2,r13 ; Save R13
144 mtsprg 3,r11 ; Save R11
145
146 .globl EXT(extPatchMCK)
147LEXT(extPatchMCK) ; This is patched to a nop for 64-bit
148 b h200aaa ; Skip 64-bit code...
149
150;
151; Fall through here for 970 MCKs.
152;
153
91447636
A
154 li r11,1 ; ?
155 sldi r11,r11,32+3 ; ?
156 mfspr r13,hid4 ; ?
157 or r11,r11,r13 ; ?
55e303ae 158 sync
91447636 159 mtspr hid4,r11 ; ?
55e303ae 160 isync
91447636
A
161 li r11,1 ; ?
162 sldi r11,r11,32+8 ; ?
163 andc r13,r13,r11 ; ?
55e303ae
A
164 lis r11,0xE000 ; Get the unlikeliest ESID possible
165 sync
91447636
A
166 mtspr hid4,r13 ; ?
167 isync ; ?
55e303ae 168
91447636
A
169 srdi r11,r11,1 ; ?
170 slbie r11 ; ?
55e303ae
A
171 sync
172 isync
173
174 li r11,T_MACHINE_CHECK ; Set rupt code
175 b .L_exception_entry ; Join common...
176
177;
178; Preliminary checking of other MCKs
179;
180
181h200aaa: mfsrr1 r11 ; Get the SRR1
182 mfcr r13 ; Save the CR
183
91447636
A
184 rlwinm. r11,r11,0,dcmck,dcmck ; ?
185 beq+ notDCache ; ?
55e303ae
A
186
187 sync
91447636
A
188 mfspr r11,msscr0 ; ?
189 dssall ; ?
55e303ae
A
190 sync
191 isync
192
91447636
A
193 oris r11,r11,hi16(dl1hwfm) ; ?
194 mtspr msscr0,r11 ; ?
55e303ae 195
91447636 196rstbsy: mfspr r11,msscr0 ; ?
55e303ae 197
91447636
A
198 rlwinm. r11,r11,0,dl1hwf,dl1hwf ; ?
199 bne rstbsy ; ?
55e303ae 200
91447636 201 sync ; ?
55e303ae
A
202
203 mfsprg r11,0 ; Get the per_proc
204 mtcrf 255,r13 ; Restore CRs
205 lwz r13,hwMachineChecks(r11) ; Get old count
206 addi r13,r13,1 ; Count this one
207 stw r13,hwMachineChecks(r11) ; Set new count
208 lwz r11,pfAvailable(r11) ; Get the feature flags
209 mfsprg r13,2 ; Restore R13
210 mtsprg 2,r11 ; Set the feature flags
211 mfsprg r11,3 ; Restore R11
212 rfi ; Return
213
214notDCache: mtcrf 255,r13 ; Restore CRs
215 li r11,T_MACHINE_CHECK ; Set rupt code
216 b .L_exception_entry ; Join common...
217
1c79356b
A
218
219/*
220 * Data access - page fault, invalid memory rights for operation
221 */
222
223 . = 0x300
224.L_handler300:
225 mtsprg 2,r13 /* Save R13 */
226 mtsprg 3,r11 /* Save R11 */
1c79356b
A
227 li r11,T_DATA_ACCESS /* Set 'rupt code */
228 b .L_exception_entry /* Join common... */
229
55e303ae
A
230
231/*
232 * Data segment
233 */
234
235 . = 0x380
236.L_handler380:
237 mtsprg 2,r13 ; Save R13
238 mtsprg 3,r11 ; Save R11
239 li r11,T_DATA_SEGMENT ; Set rupt code
240 b .L_exception_entry ; Join common...
241
1c79356b
A
242/*
243 * Instruction access - as for data access
244 */
245
246 . = 0x400
247.L_handler400:
55e303ae
A
248 mtsprg 2,r13 ; Save R13
249 mtsprg 3,r11 ; Save R11
250 li r11,T_INSTRUCTION_ACCESS ; Set rupt code
251 b .L_exception_entry ; Join common...
252
253/*
254 * Instruction segment
255 */
256
257 . = 0x480
258.L_handler480:
259 mtsprg 2,r13 ; Save R13
260 mtsprg 3,r11 ; Save R11
261 li r11,T_INSTRUCTION_SEGMENT ; Set rupt code
262 b .L_exception_entry ; Join common...
1c79356b
A
263
264/*
265 * External interrupt
266 */
267
268 . = 0x500
269.L_handler500:
55e303ae
A
270 mtsprg 2,r13 ; Save R13
271 mtsprg 3,r11 ; Save R11
272 li r11,T_INTERRUPT ; Set rupt code
273 b .L_exception_entry ; Join common...
1c79356b
A
274
275/*
276 * Alignment - many reasons
277 */
278
279 . = 0x600
280.L_handler600:
281 mtsprg 2,r13 /* Save R13 */
282 mtsprg 3,r11 /* Save R11 */
d7e50217 283 li r11,T_ALIGNMENT|T_FAM /* Set 'rupt code */
1c79356b
A
284 b .L_exception_entry /* Join common... */
285
286/*
287 * Program - floating point exception, illegal inst, priv inst, user trap
288 */
289
290 . = 0x700
291.L_handler700:
292 mtsprg 2,r13 /* Save R13 */
293 mtsprg 3,r11 /* Save R11 */
55e303ae
A
294
295#if 0
296 mfsrr1 r13 ; (BRINGUP)
297 mfcr r11 ; (BRINGUP)
298 rlwinm. r13,r13,0,12,12 ; (BRINGUP)
299 crmove cr1_eq,cr0_eq ; (BRINGUP)
300 mfsrr1 r13 ; (BRINGUP)
301 rlwinm. r13,r13,0,MSR_PR_BIT,MSR_PR_BIT ; (BRINGUP)
302 crorc cr0_eq,cr1_eq,cr0_eq ; (BRINGUP)
303 bf-- cr0_eq,. ; (BRINGUP)
304 mtcrf 255,r11 ; (BRINGUP)
305#endif
306
d7e50217 307 li r11,T_PROGRAM|T_FAM /* Set 'rupt code */
1c79356b
A
308 b .L_exception_entry /* Join common... */
309
310/*
311 * Floating point disabled
312 */
313
314 . = 0x800
315.L_handler800:
316 mtsprg 2,r13 /* Save R13 */
317 mtsprg 3,r11 /* Save R11 */
1c79356b
A
318 li r11,T_FP_UNAVAILABLE /* Set 'rupt code */
319 b .L_exception_entry /* Join common... */
320
321
322/*
323 * Decrementer - DEC register has passed zero.
324 */
325
326 . = 0x900
327.L_handler900:
328 mtsprg 2,r13 /* Save R13 */
329 mtsprg 3,r11 /* Save R11 */
1c79356b
A
330 li r11,T_DECREMENTER /* Set 'rupt code */
331 b .L_exception_entry /* Join common... */
332
333/*
334 * I/O controller interface error - MACH does not use this
335 */
336
337 . = 0xA00
338.L_handlerA00:
339 mtsprg 2,r13 /* Save R13 */
340 mtsprg 3,r11 /* Save R11 */
1c79356b
A
341 li r11,T_IO_ERROR /* Set 'rupt code */
342 b .L_exception_entry /* Join common... */
343
344/*
345 * Reserved
346 */
347
348 . = 0xB00
349.L_handlerB00:
350 mtsprg 2,r13 /* Save R13 */
351 mtsprg 3,r11 /* Save R11 */
1c79356b
A
352 li r11,T_RESERVED /* Set 'rupt code */
353 b .L_exception_entry /* Join common... */
354
91447636
A
355
356; System Calls (sc instruction)
0b4e3aa0 357;
b36670ce
A
358; The syscall number is in r0. All we do here is munge the number into an
359; 8-bit index into the "scTable", and dispatch on it to handle the Ultra
91447636 360; Fast Traps (UFTs.) The index is:
0b4e3aa0 361;
b36670ce 362; 0x80 - set if syscall number is 0x80000000 (CutTrace)
91447636
A
363; 0x40 - set if syscall number is 0x00006004
364; 0x20 - set if upper 29 bits of syscall number are 0xFFFFFFF8
365; 0x10 - set if upper 29 bits of syscall number are 0x00007FF0
366; 0x0E - low three bits of syscall number
367; 0x01 - zero, as scTable is an array of shorts
1c79356b
A
368
369 . = 0xC00
370.L_handlerC00:
55e303ae 371 mtsprg 3,r11 ; Save R11
1c79356b 372 mtsprg 2,r13 ; Save R13
3a60a9f5
A
373 rlwinm r11,r0,0,0xFFFFFFF8 ; mask off low 3 bits of syscall number
374 xori r13,r11,0x7FF0 ; start to check for the 0x7FFx traps
375 addi r11,r11,8 ; make a 0 iff this is a 0xFFFFFFF8 trap
376 cntlzw r13,r13 ; set bit 0x20 iff a 0x7FFx trap
377 cntlzw r11,r11 ; set bit 0x20 iff a 0xFFFFFFF8 trap
b36670ce 378 xoris r0,r0,0x8000 ; Flip bit to make 0 iff 0x80000000
3a60a9f5 379 rlwimi r11,r13,31,0x10 ; move 0x7FFx bit into position
b36670ce
A
380 cntlzw r13,r0 ; Set bit 0x20 iff 0x80000000
381 xoris r0,r0,0x8000 ; Flip bit to restore R0
382 rlwimi r11,r13,2,0x80 ; Set bit 0x80 iff CutTrace
3a60a9f5
A
383 xori r13,r0,0x6004 ; start to check for 0x6004
384 rlwimi r11,r0,1,0xE ; move in low 3 bits of syscall number
385 cntlzw r13,r13 ; set bit 0x20 iff 0x6004
386 rlwinm r11,r11,0,0,30 ; clear out bit 31
387 rlwimi r11,r13,1,0x40 ; move 0x6004 bit into position
388 lhz r11,lo16(scTable)(r11) ; get branch address from sc table
389 mfctr r13 ; save caller's ctr in r13
390 mtctr r11 ; set up branch to syscall handler
391 mfsprg r11,0 ; get per_proc, which most UFTs use
392 bctr ; dispatch (r11 in sprg3, r13 in sprg2, ctr in r13, per_proc in r11)
1c79356b
A
393
394/*
395 * Trace - generated by single stepping
396 * performance monitor BE branch enable tracing/logging
397 * is also done here now. while this is permanently in the
398 * system the impact is completely unnoticable as this code is
399 * only executed when (a) a single step or branch exception is
400 * hit, (b) in the single step debugger case there is so much
401 * overhead already the few extra instructions for testing for BE
402 * are not even noticable, (c) the BE logging code is *only* run
403 * when it is enabled by the tool which will not happen during
404 * normal system usage
405 *
406 * Note that this trace is available only to user state so we do not
407 * need to set sprg2 before returning.
408 */
409
410 . = 0xD00
411.L_handlerD00:
de355530 412 mtsprg 3,r11 ; Save R11
55e303ae
A
413 mfsprg r11,2 ; Get the feature flags
414 mtsprg 2,r13 ; Save R13
415 rlwinm r11,r11,pf64Bitb-4,4,4 ; Get the 64-bit flag
416 mfcr r13 ; Get the CR
417 mtcrf 0x40,r11 ; Set the CR
418 mfsrr1 r11 ; Get the old MSR
419 rlwinm. r11,r11,0,MSR_PR_BIT,MSR_PR_BIT ; Are we in supervisor state?
420
421 mfsprg r11,0 ; Get the per_proc
422 lhz r11,PP_CPU_FLAGS(r11) ; Get the flags
423 crmove cr1_eq,cr0_eq ; Remember if we are in supervisor state
424 rlwinm. r11,r11,0,traceBEb+16,traceBEb+16 ; Special trace enabled?
425 cror cr0_eq,cr0_eq,cr1_eq ; Is trace off or supervisor state?
426 bf-- cr0_eq,specbrtr ; No, we need to trace...
427
428notspectr: mtcr r13 ; Restore CR
d7e50217 429 li r11,T_TRACE|T_FAM ; Set interrupt code
1c79356b
A
430 b .L_exception_entry ; Join common...
431
55e303ae
A
432 .align 5
433
1c79356b
A
434;
435; We are doing the special branch trace
436;
437
55e303ae
A
438specbrtr: mfsprg r11,0 ; Get the per_proc area
439 bt++ 4,sbxx64a ; Jump if 64-bit...
440
441 stw r1,tempr0+4(r11) ; Save in a scratch area
442 stw r2,tempr1+4(r11) ; Save in a scratch area
443 stw r3,tempr2+4(r11) ; Save in a scratch area
444 b sbxx64b ; Skip...
445
446sbxx64a: std r1,tempr0(r11) ; Save in a scratch area
447 std r2,tempr1(r11) ; Save in a scratch area
448 std r3,tempr2(r11) ; Save in a scratch area
449
450sbxx64b: lis r2,hi16(EXT(pc_trace_buf)) ; Get the top of the buffer
451 lwz r3,spcTRp(r11) ; Pick up buffer position
1c79356b 452 ori r2,r2,lo16(EXT(pc_trace_buf)) ; Get the bottom of the buffer
55e303ae 453 cmplwi cr2,r3,4092 ; Set cr1_eq if we should take exception
0b4e3aa0 454 mfsrr0 r1 ; Get the pc
1c79356b
A
455 stwx r1,r2,r3 ; Save it in the buffer
456 addi r3,r3,4 ; Point to the next slot
1c79356b 457 rlwinm r3,r3,0,20,31 ; Wrap the slot at one page
55e303ae
A
458 stw r3,spcTRp(r11) ; Save the new slot
459
460 bt++ 4,sbxx64c ; Jump if 64-bit...
461
462 lwz r1,tempr0+4(r11) ; Restore work register
463 lwz r2,tempr1+4(r11) ; Restore work register
464 lwz r3,tempr2+4(r11) ; Restore work register
465 beq cr2,notspectr ; Buffer filled, make a rupt...
91447636
A
466 mtcr r13 ; Restore CR
467 b uftRFI ; Go restore and leave...
55e303ae
A
468
469sbxx64c: ld r1,tempr0(r11) ; Restore work register
470 ld r2,tempr1(r11) ; Restore work register
471 ld r3,tempr2(r11) ; Restore work register
472 beq cr2,notspectr ; Buffer filled, make a rupt...
91447636
A
473 mtcr r13 ; Restore CR
474 b uftRFI ; Go restore and leave...
1c79356b
A
475
476/*
477 * Floating point assist
478 */
479
55e303ae 480 . = 0xE00
1c79356b
A
481.L_handlerE00:
482 mtsprg 2,r13 /* Save R13 */
483 mtsprg 3,r11 /* Save R11 */
1c79356b
A
484 li r11,T_FP_ASSIST /* Set 'rupt code */
485 b .L_exception_entry /* Join common... */
486
487
488/*
489 * Performance monitor interruption
490 */
491
492 . = 0xF00
493PMIhandler:
494 mtsprg 2,r13 /* Save R13 */
495 mtsprg 3,r11 /* Save R11 */
1c79356b
A
496 li r11,T_PERF_MON /* Set 'rupt code */
497 b .L_exception_entry /* Join common... */
498
499
500/*
501 * VMX exception
502 */
503
504 . = 0xF20
505VMXhandler:
506 mtsprg 2,r13 /* Save R13 */
507 mtsprg 3,r11 /* Save R11 */
1c79356b
A
508 li r11,T_VMX /* Set 'rupt code */
509 b .L_exception_entry /* Join common... */
510
511
512
55e303ae
A
513;
514; Instruction translation miss exception - not supported
515;
1c79356b 516
55e303ae 517 . = 0x1000
1c79356b 518.L_handler1000:
55e303ae
A
519 mtsprg 2,r13 ; Save R13
520 mtsprg 3,r11 ; Save R11
521 li r11,T_INVALID_EXCP0 ; Set rupt code
522 b .L_exception_entry ; Join common...
523
de355530 524
1c79356b 525
55e303ae
A
526;
527; Data load translation miss exception - not supported
528;
529
530 . = 0x1100
1c79356b 531.L_handler1100:
55e303ae
A
532 mtsprg 2,r13 ; Save R13
533 mtsprg 3,r11 ; Save R11
534 li r11,T_INVALID_EXCP1 ; Set rupt code
535 b .L_exception_entry ; Join common...
536
de355530 537
1c79356b 538
55e303ae
A
539;
540; Data store translation miss exception - not supported
541;
542
543 . = 0x1200
1c79356b 544.L_handler1200:
55e303ae
A
545 mtsprg 2,r13 ; Save R13
546 mtsprg 3,r11 ; Save R11
547 li r11,T_INVALID_EXCP2 ; Set rupt code
548 b .L_exception_entry ; Join common...
549
1c79356b
A
550
551/*
552 * Instruction address breakpoint
553 */
554
555 . = 0x1300
556.L_handler1300:
557 mtsprg 2,r13 /* Save R13 */
558 mtsprg 3,r11 /* Save R11 */
1c79356b
A
559 li r11,T_INSTRUCTION_BKPT /* Set 'rupt code */
560 b .L_exception_entry /* Join common... */
561
562/*
563 * System management interrupt
564 */
565
566 . = 0x1400
567.L_handler1400:
568 mtsprg 2,r13 /* Save R13 */
569 mtsprg 3,r11 /* Save R11 */
1c79356b
A
570 li r11,T_SYSTEM_MANAGEMENT /* Set 'rupt code */
571 b .L_exception_entry /* Join common... */
572
55e303ae
A
573
574/*
575 * Soft Patch
576 */
577
578 . = 0x1500
579.L_handler1500:
580 mtsprg 2,r13 /* Save R13 */
581 mtsprg 3,r11 /* Save R11 */
582 li r11,T_SOFT_PATCH /* Set 'rupt code */
583 b .L_exception_entry /* Join common... */
584
1c79356b 585;
55e303ae 586; Altivec Java Mode Assist interrupt or Maintenace interrupt
1c79356b
A
587;
588
589 . = 0x1600
590.L_handler1600:
591 mtsprg 2,r13 /* Save R13 */
592 mtsprg 3,r11 /* Save R11 */
1c79356b
A
593 li r11,T_ALTIVEC_ASSIST /* Set 'rupt code */
594 b .L_exception_entry /* Join common... */
595
596;
55e303ae 597; Altivec Java Mode Assist interrupt or Thermal interruption
1c79356b
A
598;
599
600 . = 0x1700
601.L_handler1700:
602 mtsprg 2,r13 /* Save R13 */
603 mtsprg 3,r11 /* Save R11 */
1c79356b
A
604 li r11,T_THERMAL /* Set 'rupt code */
605 b .L_exception_entry /* Join common... */
606
55e303ae
A
607;
608; Thermal interruption - 64-bit
609;
610
611 . = 0x1800
612.L_handler1800:
613 mtsprg 2,r13 /* Save R13 */
614 mtsprg 3,r11 /* Save R11 */
615 li r11,T_ARCHDEP0 /* Set 'rupt code */
616 b .L_exception_entry /* Join common... */
617
1c79356b
A
618/*
619 * There is now a large gap of reserved traps
620 */
621
622/*
55e303ae 623 * Instrumentation interruption
1c79356b
A
624 */
625
626 . = 0x2000
627.L_handler2000:
628 mtsprg 2,r13 /* Save R13 */
629 mtsprg 3,r11 /* Save R11 */
55e303ae 630 li r11,T_INSTRUMENTATION /* Set 'rupt code */
1c79356b
A
631 b .L_exception_entry /* Join common... */
632
d7e50217 633
91447636
A
634
635 .data
636 .align ALIGN
637 .globl EXT(exception_entry)
638EXT(exception_entry):
639 .long .L_exception_entry-EXT(ExceptionVectorsStart) /* phys addr of fn */
640
641 VECTOR_SEGMENT
642
643/*<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
644 *
645 * First-level syscall dispatch. The syscall vector maps r0 (the syscall number) into an
646 * index into the "scTable" (below), and then branches to one of these routines. The PPC
647 * syscalls come in several varieties, as follows:
648 *
649 * 1. If (syscall & 0xFFFFF000) == 0x00007000, then it is a PPC Fast Trap or UFT.
650 * The UFTs are dispatched here, the Fast Traps are dispatched in hw_exceptions.s.
651 *
652 * 2. If (syscall & 0xFFFFF000) == 0x00006000, then it is a PPC-only trap.
653 * One of these (0x6004) is a UFT, but most are dispatched in hw_exceptions.s. These
654 * are mostly Blue Box or VMM (Virtual Machine) calls.
655 *
656 * 3. If (syscall & 0xFFFFFFF0) == 0xFFFFFFF0, then it is also a UFT and is dispatched here.
657 *
658 * 4. If (syscall & 0xFFFFF000) == 0x80000000, then it is a "firmware" call and is dispatched in
b36670ce
A
659 * Firmware.s, though the special "Cut Trace" trap (0x80000000) is handled here as an ultra
660 * fast trap.
91447636
A
661 *
662 * 5. If (syscall & 0xFFFFF000) == 0xFFFFF000, and it is not one of the above, then it is a Mach
663 * syscall, which are dispatched in hw_exceptions.s via "mach_trap_table".
664 *
665 * 6. If (syscall & 0xFFFFF000) == 0x00000000, then it is a BSD syscall, which are dispatched
666 * by "unix_syscall" using the "sysent" table.
667 *
668 * What distinguishes the UFTs, aside from being ultra fast, is that they cannot rely on translation
669 * being on, and so cannot look at the activation or task control block, etc. We handle them right
670 * here, and return to the caller without turning interrupts or translation on. The UFTs are:
671 *
672 * 0xFFFFFFFF - BlueBox only - MKIsPreemptiveTask
673 * 0xFFFFFFFE - BlueBox only - MKIsPreemptiveTaskEnv
674 * 0x00007FF2 - User state only - thread info (32-bit mode)
675 * 0x00007FF3 - User state only - floating point / vector facility status
676 * 0x00007FF4 - Kernel only - loadMSR - not used on 64-bit machines
677 * 0x00006004 - vmm_dispatch (only some of which are UFTs)
678 *
679 * "scTable" is an array of 2-byte addresses, accessed using a 7-bit index derived from the syscall
680 * number as follows:
681 *
b36670ce
A
682 * 0x80 (A) - set if syscall number is 0x80000000
683 * 0x40 (B) - set if syscall number is 0x00006004
684 * 0x20 (C) - set if upper 29 bits of syscall number are 0xFFFFFFF8
685 * 0x10 (D) - set if upper 29 bits of syscall number are 0x00007FF0
686 * 0x0E (E) - low three bits of syscall number
91447636
A
687 *
688 * If you define another UFT, try to use a number in one of the currently decoded ranges, ie one marked
689 * "unassigned" below. The dispatch table and the UFT handlers must reside in the first 32KB of
690 * physical memory.
691 */
692
b36670ce
A
693 .align 8 ; start this table on a 256-byte boundry
694scTable: ; ABCD E
695 .short uftNormalSyscall-baseR ; 0000 0 these syscalls are not in a reserved range
696 .short uftNormalSyscall-baseR ; 0000 1 these syscalls are not in a reserved range
697 .short uftNormalSyscall-baseR ; 0000 2 these syscalls are not in a reserved range
698 .short uftNormalSyscall-baseR ; 0000 3 these syscalls are not in a reserved range
699 .short uftNormalSyscall-baseR ; 0000 4 these syscalls are not in a reserved range
700 .short uftNormalSyscall-baseR ; 0000 5 these syscalls are not in a reserved range
701 .short uftNormalSyscall-baseR ; 0000 6 these syscalls are not in a reserved range
702 .short uftNormalSyscall-baseR ; 0000 7 these syscalls are not in a reserved range
703
704 .short uftNormalSyscall-baseR ; 0001 0 0x7FF0 is unassigned
705 .short uftNormalSyscall-baseR ; 0001 1 0x7FF1 is Set Thread Info Fast Trap (pass up)
706 .short uftThreadInfo-baseR ; 0001 2 0x7FF2 is Thread Info
707 .short uftFacilityStatus-baseR ; 0001 3 0x7FF3 is Facility Status
708 .short uftLoadMSR-baseR ; 0001 4 0x7FF4 is Load MSR
709 .short uftNormalSyscall-baseR ; 0001 5 0x7FF5 is the Null FastPath Trap (pass up)
710 .short uftNormalSyscall-baseR ; 0001 6 0x7FF6 is unassigned
711 .short uftNormalSyscall-baseR ; 0001 7 0x7FF7 is unassigned
712
713 .short uftNormalSyscall-baseR ; 0010 0 0xFFFFFFF0 is unassigned
714 .short uftNormalSyscall-baseR ; 0010 1 0xFFFFFFF1 is unassigned
715 .short uftNormalSyscall-baseR ; 0010 2 0xFFFFFFF2 is unassigned
716 .short uftNormalSyscall-baseR ; 0010 3 0xFFFFFFF3 is unassigned
717 .short uftNormalSyscall-baseR ; 0010 4 0xFFFFFFF4 is unassigned
718 .short uftNormalSyscall-baseR ; 0010 5 0xFFFFFFF5 is unassigned
719 .short uftIsPreemptiveTaskEnv-baseR ; 0010 6 0xFFFFFFFE is Blue Box uftIsPreemptiveTaskEnv
720 .short uftIsPreemptiveTask-baseR ; 0010 7 0xFFFFFFFF is Blue Box IsPreemptiveTask
721
722 .short WhoaBaby-baseR ; 0011 0 impossible combination
723 .short WhoaBaby-baseR ; 0011 1 impossible combination
724 .short WhoaBaby-baseR ; 0011 2 impossible combination
725 .short WhoaBaby-baseR ; 0011 3 impossible combination
726 .short WhoaBaby-baseR ; 0011 4 impossible combination
727 .short WhoaBaby-baseR ; 0011 5 impossible combination
728 .short WhoaBaby-baseR ; 0011 6 impossible combination
729 .short WhoaBaby-baseR ; 0011 7 impossible combination
730
731 .short WhoaBaby-baseR ; 0100 0 0x6000 is an impossible index (diagCall)
732 .short WhoaBaby-baseR ; 0100 1 0x6001 is an impossible index (vmm_get_version)
733 .short WhoaBaby-baseR ; 0100 2 0x6002 is an impossible index (vmm_get_features)
734 .short WhoaBaby-baseR ; 0100 3 0x6003 is an impossible index (vmm_init_context)
735 .short uftVMM-baseR ; 0100 4 0x6004 is vmm_dispatch (only some of which are UFTs)
736 .short WhoaBaby-baseR ; 0100 5 0x6005 is an impossible index (bb_enable_bluebox)
737 .short WhoaBaby-baseR ; 0100 6 0x6006 is an impossible index (bb_disable_bluebox)
738 .short WhoaBaby-baseR ; 0100 7 0x6007 is an impossible index (bb_settaskenv)
739
740 .short uftNormalSyscall-baseR ; 0101 0 these syscalls are not in a reserved range
741 .short uftNormalSyscall-baseR ; 0101 1 these syscalls are not in a reserved range
742 .short uftNormalSyscall-baseR ; 0101 2 these syscalls are not in a reserved range
743 .short uftNormalSyscall-baseR ; 0101 3 these syscalls are not in a reserved range
744 .short uftNormalSyscall-baseR ; 0101 4 these syscalls are not in a reserved range
745 .short uftNormalSyscall-baseR ; 0101 5 these syscalls are not in a reserved range
746 .short uftNormalSyscall-baseR ; 0101 6 these syscalls are not in a reserved range
747 .short uftNormalSyscall-baseR ; 0101 7 these syscalls are not in a reserved range
748
749 .short uftNormalSyscall-baseR ; 0110 0 these syscalls are not in a reserved range
750 .short uftNormalSyscall-baseR ; 0110 1 these syscalls are not in a reserved range
751 .short uftNormalSyscall-baseR ; 0110 2 these syscalls are not in a reserved range
752 .short uftNormalSyscall-baseR ; 0110 3 these syscalls are not in a reserved range
753 .short uftNormalSyscall-baseR ; 0110 4 these syscalls are not in a reserved range
754 .short uftNormalSyscall-baseR ; 0110 5 these syscalls are not in a reserved range
755 .short uftNormalSyscall-baseR ; 0110 6 these syscalls are not in a reserved range
756 .short uftNormalSyscall-baseR ; 0110 7 these syscalls are not in a reserved range
757
758 .short uftNormalSyscall-baseR ; 0111 0 these syscalls are not in a reserved range
759 .short uftNormalSyscall-baseR ; 0111 1 these syscalls are not in a reserved range
760 .short uftNormalSyscall-baseR ; 0111 2 these syscalls are not in a reserved range
761 .short uftNormalSyscall-baseR ; 0111 3 these syscalls are not in a reserved range
762 .short uftNormalSyscall-baseR ; 0111 4 these syscalls are not in a reserved range
763 .short uftNormalSyscall-baseR ; 0111 5 these syscalls are not in a reserved range
764 .short uftNormalSyscall-baseR ; 0111 6 these syscalls are not in a reserved range
765 .short uftNormalSyscall-baseR ; 0111 7 these syscalls are not in a reserved range
766
767 .short uftCutTrace-baseR ; 1000 0 CutTrace
768 .short uftNormalSyscall-baseR ; 1000 1 these syscalls are not in a reserved range
769 .short uftNormalSyscall-baseR ; 1000 2 these syscalls are not in a reserved range
770 .short uftNormalSyscall-baseR ; 1000 3 these syscalls are not in a reserved range
771 .short uftNormalSyscall-baseR ; 1000 4 these syscalls are not in a reserved range
772 .short uftNormalSyscall-baseR ; 1000 5 these syscalls are not in a reserved range
773 .short uftNormalSyscall-baseR ; 1000 6 these syscalls are not in a reserved range
774 .short uftNormalSyscall-baseR ; 1000 7 these syscalls are not in a reserved range
775
776 .short uftNormalSyscall-baseR ; 1001 0 these syscalls are not in a reserved range
777 .short uftNormalSyscall-baseR ; 1001 1 these syscalls are not in a reserved range
778 .short uftNormalSyscall-baseR ; 1001 2 these syscalls are not in a reserved range
779 .short uftNormalSyscall-baseR ; 1001 3 these syscalls are not in a reserved range
780 .short uftNormalSyscall-baseR ; 1001 4 these syscalls are not in a reserved range
781 .short uftNormalSyscall-baseR ; 1001 5 these syscalls are not in a reserved range
782 .short uftNormalSyscall-baseR ; 1001 6 these syscalls are not in a reserved range
783 .short uftNormalSyscall-baseR ; 1001 7 these syscalls are not in a reserved range
784
785 .short uftNormalSyscall-baseR ; 1010 0 these syscalls are not in a reserved range
786 .short uftNormalSyscall-baseR ; 1010 1 these syscalls are not in a reserved range
787 .short uftNormalSyscall-baseR ; 1010 2 these syscalls are not in a reserved range
788 .short uftNormalSyscall-baseR ; 1010 3 these syscalls are not in a reserved range
789 .short uftNormalSyscall-baseR ; 1010 4 these syscalls are not in a reserved range
790 .short uftNormalSyscall-baseR ; 1010 5 these syscalls are not in a reserved range
791 .short uftNormalSyscall-baseR ; 1010 6 these syscalls are not in a reserved range
792 .short uftNormalSyscall-baseR ; 1010 7 these syscalls are not in a reserved range
793
794 .short uftNormalSyscall-baseR ; 1011 0 these syscalls are not in a reserved range
795 .short uftNormalSyscall-baseR ; 1011 1 these syscalls are not in a reserved range
796 .short uftNormalSyscall-baseR ; 1011 2 these syscalls are not in a reserved range
797 .short uftNormalSyscall-baseR ; 1011 3 these syscalls are not in a reserved range
798 .short uftNormalSyscall-baseR ; 1011 4 these syscalls are not in a reserved range
799 .short uftNormalSyscall-baseR ; 1011 5 these syscalls are not in a reserved range
800 .short uftNormalSyscall-baseR ; 1011 6 these syscalls are not in a reserved range
801 .short uftNormalSyscall-baseR ; 1011 7 these syscalls are not in a reserved range
802
803 .short uftNormalSyscall-baseR ; 1100 0 these syscalls are not in a reserved range
804 .short uftNormalSyscall-baseR ; 1100 1 these syscalls are not in a reserved range
805 .short uftNormalSyscall-baseR ; 1100 2 these syscalls are not in a reserved range
806 .short uftNormalSyscall-baseR ; 1100 3 these syscalls are not in a reserved range
807 .short uftNormalSyscall-baseR ; 1100 4 these syscalls are not in a reserved range
808 .short uftNormalSyscall-baseR ; 1100 5 these syscalls are not in a reserved range
809 .short uftNormalSyscall-baseR ; 1100 6 these syscalls are not in a reserved range
810 .short uftNormalSyscall-baseR ; 1100 7 these syscalls are not in a reserved range
811
812 .short uftNormalSyscall-baseR ; 1101 0 these syscalls are not in a reserved range
813 .short uftNormalSyscall-baseR ; 1101 1 these syscalls are not in a reserved range
814 .short uftNormalSyscall-baseR ; 1101 2 these syscalls are not in a reserved range
815 .short uftNormalSyscall-baseR ; 1101 3 these syscalls are not in a reserved range
816 .short uftNormalSyscall-baseR ; 1101 4 these syscalls are not in a reserved range
817 .short uftNormalSyscall-baseR ; 1101 5 these syscalls are not in a reserved range
818 .short uftNormalSyscall-baseR ; 1101 6 these syscalls are not in a reserved range
819 .short uftNormalSyscall-baseR ; 1101 7 these syscalls are not in a reserved range
820
821 .short uftNormalSyscall-baseR ; 1110 0 these syscalls are not in a reserved range
822 .short uftNormalSyscall-baseR ; 1110 1 these syscalls are not in a reserved range
823 .short uftNormalSyscall-baseR ; 1110 2 these syscalls are not in a reserved range
824 .short uftNormalSyscall-baseR ; 1110 3 these syscalls are not in a reserved range
825 .short uftNormalSyscall-baseR ; 1110 4 these syscalls are not in a reserved range
826 .short uftNormalSyscall-baseR ; 1110 5 these syscalls are not in a reserved range
827 .short uftNormalSyscall-baseR ; 1110 6 these syscalls are not in a reserved range
828 .short uftNormalSyscall-baseR ; 1110 7 these syscalls are not in a reserved range
829
830 .short uftNormalSyscall-baseR ; 1111 0 these syscalls are not in a reserved range
831 .short uftNormalSyscall-baseR ; 1111 1 these syscalls are not in a reserved range
832 .short uftNormalSyscall-baseR ; 1111 2 these syscalls are not in a reserved range
833 .short uftNormalSyscall-baseR ; 1111 3 these syscalls are not in a reserved range
834 .short uftNormalSyscall-baseR ; 1111 4 these syscalls are not in a reserved range
835 .short uftNormalSyscall-baseR ; 1111 5 these syscalls are not in a reserved range
836 .short uftNormalSyscall-baseR ; 1111 6 these syscalls are not in a reserved range
837 .short uftNormalSyscall-baseR ; 1111 7 these syscalls are not in a reserved range
91447636
A
838
839 .align 2 ; prepare for code
840
841
842/* Ultra Fast Trap (UFT) Handlers:
843 *
844 * We get here directly from the hw syscall vector via the "scTable" vector (above),
845 * with interrupts and VM off, in 64-bit mode if supported, and with all registers live
846 * except the following:
847 *
848 * r11 = per_proc ptr (ie, sprg0)
849 * r13 = holds caller's ctr register
850 * sprg2 = holds caller's r13
851 * sprg3 = holds caller's r11
d7e50217 852 */
91447636 853
3a60a9f5 854; Handle "vmm_dispatch" (0x6004), of which only some selectors are UFTs.
91447636
A
855
856uftVMM:
3a60a9f5
A
857 mtctr r13 ; restore caller's ctr
858 lwz r11,spcFlags(r11) ; get the special flags word from per_proc
859 mfcr r13 ; save caller's entire cr (we use all fields below)
91447636
A
860 rlwinm r11,r11,16,16,31 ; Extract spcFlags upper bits
861 andi. r11,r11,hi16(runningVM|FamVMena|FamVMmode)
862 cmpwi cr0,r11,hi16(runningVM|FamVMena|FamVMmode) ; Test in VM FAM
3a60a9f5 863 bne-- uftNormal80 ; not eligible for FAM UFTs
d7e50217 864 cmpwi cr5,r3,kvmmResumeGuest ; Compare r3 with kvmmResumeGuest
55e303ae
A
865 cmpwi cr2,r3,kvmmSetGuestRegister ; Compare r3 with kvmmSetGuestRegister
866 cror cr1_eq,cr5_lt,cr2_gt ; Set true if out of VMM Fast syscall range
3a60a9f5 867 bt-- cr1_eq,uftNormalFF ; Exit if out of range (the others are not UFTs)
91447636 868 b EXT(vmm_ufp) ; handle UFT range of vmm_dispatch syscall
d7e50217 869
3a60a9f5
A
870
871; Handle blue box UFTs (syscalls -1 and -2).
91447636
A
872
873uftIsPreemptiveTask:
874uftIsPreemptiveTaskEnv:
3a60a9f5
A
875 mtctr r13 ; restore caller's ctr
876 lwz r11,spcFlags(r11) ; get the special flags word from per_proc
877 mfcr r13,0x80 ; save caller's cr0 so we can use it
878 andi. r11,r11,bbNoMachSC|bbPreemptive ; Clear what we do not need
91447636 879 cmplwi r11,bbNoMachSC ; See if we are trapping syscalls
3a60a9f5
A
880 blt-- uftNormal80 ; No...
881 cmpwi r0,-2 ; is this call IsPreemptiveTaskEnv?
91447636
A
882 rlwimi r13,r11,bbPreemptivebit-cr0_eq,cr0_eq,cr0_eq ; Copy preemptive task flag into user cr0_eq
883 mfsprg r11,0 ; Get the per proc once more
3a60a9f5 884 bne++ uftRestoreThenRFI ; do not load r0 if IsPreemptiveTask
91447636 885 lwz r0,ppbbTaskEnv(r11) ; Get the shadowed taskEnv (only difference)
3a60a9f5 886 b uftRestoreThenRFI ; restore modified cr0 and return
91447636
A
887
888
3a60a9f5 889; Handle "Thread Info" UFT (0x7FF2)
91447636 890
3a60a9f5 891 .globl EXT(uft_uaw_nop_if_32bit)
91447636 892uftThreadInfo:
3a60a9f5 893 lwz r3,UAW+4(r11) ; get user assist word, assuming a 32-bit processor
91447636 894LEXT(uft_uaw_nop_if_32bit)
3a60a9f5
A
895 ld r3,UAW(r11) ; get the whole doubleword if 64-bit (patched to nop if 32-bit)
896 mtctr r13 ; restore caller's ctr
897 b uftRFI ; done
91447636
A
898
899
3a60a9f5 900; Handle "Facility Status" UFT (0x7FF3)
91447636
A
901
902uftFacilityStatus:
3a60a9f5
A
903 lwz r3,spcFlags(r11) ; get "special flags" word from per_proc
904 mtctr r13 ; restore caller's ctr
905 b uftRFI ; done
91447636
A
906
907
3a60a9f5 908; Handle "Load MSR" UFT (0x7FF4). This is not used on 64-bit processors, though it would work.
91447636
A
909
910uftLoadMSR:
3a60a9f5
A
911 mfsrr1 r11 ; get caller's MSR
912 mtctr r13 ; restore caller's ctr
913 mfcr r13,0x80 ; save caller's cr0 so we can test PR
914 rlwinm. r11,r11,0,MSR_PR_BIT,MSR_PR_BIT ; really in the kernel?
915 bne- uftNormal80 ; do not permit from user mode
916 mfsprg r11,0 ; restore per_proc
91447636
A
917 mtsrr1 r3 ; Set new MSR
918
919
3a60a9f5
A
920; Return to caller after UFT. When called:
921; r11 = per_proc ptr
922; r13 = callers cr0 in upper nibble (if uftRestoreThenRFI called)
923; sprg2 = callers r13
924; sprg3 = callers r11
91447636 925
3a60a9f5
A
926uftRestoreThenRFI: ; WARNING: can drop down to here
927 mtcrf 0x80,r13 ; restore caller's cr0
91447636 928uftRFI:
3a60a9f5 929 .globl EXT(uft_nop_if_32bit)
91447636 930LEXT(uft_nop_if_32bit)
3a60a9f5 931 b uftX64 ; patched to NOP if 32-bit processor
91447636 932
b36670ce 933uftX32: lwz r11,pfAvailable(r11) ; Get the feature flags
91447636
A
934 mfsprg r13,2 ; Restore R13
935 mtsprg 2,r11 ; Set the feature flags
936 mfsprg r11,3 ; Restore R11
937 rfi ; Back to our guy...
938
939uftX64: mtspr hsprg0,r14 ; Save a register in a Hypervisor SPRG
940 ld r14,UAW(r11) ; Get the User Assist DoubleWord
941 lwz r11,pfAvailable(r11) ; Get the feature flags
942 mfsprg r13,2 ; Restore R13
943 mtsprg 2,r11 ; Set the feature flags
944 mfsprg r11,3 ; Restore R11
945 mtsprg 3,r14 ; Set the UAW in sprg3
946 mfspr r14,hsprg0 ; Restore R14
947 rfid ; Back to our guy...
948
b36670ce
A
949;
950; Quickly cut a trace table entry for the CutTrace firmware call.
951;
952; All registers except R11 and R13 are unchanged.
953;
954; Note that this code cuts a trace table entry for the CutTrace call only.
955; An identical entry is made during normal interrupt processing. Any entry
956; format entry changes made must be done in both places.
957;
958
959 .align 5
960
961 .globl EXT(uft_cuttrace)
962LEXT(uft_cuttrace)
963uftCutTrace:
964 b uftct64 ; patched to NOP if 32-bit processor
965
966 stw r20,tempr0(r11) ; Save some work registers
967 lwz r20,dgFlags(0) ; Get the flags
968 stw r21,tempr1(r11) ; Save some work registers
969 mfsrr1 r21 ; Get the SRR1
970 rlwinm r20,r20,MSR_PR_BIT-enaUsrFCallb,MASK(MSR_PR) ; Shift the validity bit over to pr bit spot
971 stw r25,tempr2(r11) ; Save some work registers
972 orc r20,r20,r21 ; Get ~PR | FC
973 mfcr r25 ; Save the CR
974 stw r22,tempr3(r11) ; Save some work registers
975 lhz r22,PP_CPU_NUMBER(r11) ; Get the logical processor number
976 andi. r20,r20,MASK(MSR_PR) ; Set cr0_eq is we are in problem state and the validity bit is not set
977 stw r23,tempr4(r11) ; Save some work registers
978 lwz r23,traceMask(0) ; Get the trace mask
979 stw r24,tempr5(r11) ; Save some work registers
980 beq- ctbail32 ; Can not issue from user...
981
982
983 addi r24,r22,16 ; Get shift to move cpu mask to syscall mask
984 rlwnm r24,r23,r24,12,12 ; Shift cpu mask bit to rupt type mask
985 and. r24,r24,r23 ; See if both are on
986
987;
988; We select a trace entry using a compare and swap on the next entry field.
989; Since we do not lock the actual trace buffer, there is a potential that
990; another processor could wrap an trash our entry. Who cares?
991;
992
993 li r23,trcWork ; Get the trace work area address
994 lwz r21,traceStart(0) ; Get the start of trace table
995 lwz r22,traceEnd(0) ; Get end of trace table
996
997 beq-- ctdisa32 ; Leave because tracing is disabled...
998
999ctgte32: lwarx r20,0,r23 ; Get and reserve the next slot to allocate
1000 addi r24,r20,LTR_size ; Point to the next trace entry
1001 cmplw r24,r22 ; Do we need to wrap the trace table?
1002 bne+ ctgte32s ; No wrap, we got us a trace entry...
1003
1004 mr r24,r21 ; Wrap back to start
1005
1006ctgte32s: stwcx. r24,0,r23 ; Try to update the current pointer
1007 bne- ctgte32 ; Collision, try again...
1008
1009#if ESPDEBUG
1010 dcbf 0,r23 ; Force to memory
1011 sync
1012#endif
1013
1014 dcbz 0,r20 ; Clear and allocate first trace line
1015 li r24,32 ; Offset to next line
1016
1017ctgte32tb: mftbu r21 ; Get the upper time now
1018 mftb r22 ; Get the lower time now
1019 mftbu r23 ; Get upper again
1020 cmplw r21,r23 ; Has it ticked?
1021 bne- ctgte32tb ; Yes, start again...
1022
1023 dcbz r24,r20 ; Clean second line
1024
1025;
1026; Let us cut that trace entry now.
1027;
1028; Note that this code cuts a trace table entry for the CutTrace call only.
1029; An identical entry is made during normal interrupt processing. Any entry
1030; format entry changes made must be done in both places.
1031;
1032
1033 lhz r24,PP_CPU_NUMBER(r11) ; Get the logical processor number
1034 li r23,T_SYSTEM_CALL ; Get the system call id
1035 mtctr r13 ; Restore the caller's CTR
1036 sth r24,LTR_cpu(r20) ; Save processor number
1037 li r24,64 ; Offset to third line
1038 sth r23,LTR_excpt(r20) ; Set the exception code
1039 dcbz r24,r20 ; Clean 3rd line
1040 mfspr r23,dsisr ; Get the DSISR
1041 stw r21,LTR_timeHi(r20) ; Save top of time stamp
1042 li r24,96 ; Offset to fourth line
1043 mflr r21 ; Get the LR
1044 dcbz r24,r20 ; Clean 4th line
1045 stw r22,LTR_timeLo(r20) ; Save bottom of time stamp
1046 mfsrr0 r22 ; Get SRR0
1047 stw r25,LTR_cr(r20) ; Save CR
1048 mfsrr1 r24 ; Get the SRR1
1049 stw r23,LTR_dsisr(r20) ; Save DSISR
1050 stw r22,LTR_srr0+4(r20) ; Save SRR0
1051 mfdar r23 ; Get DAR
1052 stw r24,LTR_srr1+4(r20) ; Save SRR1
1053 stw r23,LTR_dar+4(r20) ; Save DAR
1054 stw r21,LTR_lr+4(r20) ; Save LR
1055
1056 stw r13,LTR_ctr+4(r20) ; Save CTR
1057 stw r0,LTR_r0+4(r20) ; Save register
1058 stw r1,LTR_r1+4(r20) ; Save register
1059 stw r2,LTR_r2+4(r20) ; Save register
1060 stw r3,LTR_r3+4(r20) ; Save register
1061 stw r4,LTR_r4+4(r20) ; Save register
1062 stw r5,LTR_r5+4(r20) ; Save register
1063 stw r6,LTR_r6+4(r20) ; Save register
1064
1065#if 0
1066 lwz r21,FPUowner(r11) ; (TEST/DEBUG) Get the current floating point owner
1067 stw r21,LTR_rsvd0(r20) ; (TEST/DEBUG) Record the owner
1068#endif
1069
1070#if ESPDEBUG
1071 addi r21,r20,32 ; Second line
1072 addi r22,r20,64 ; Third line
1073 dcbst 0,r20 ; Force to memory
1074 dcbst 0,r21 ; Force to memory
1075 addi r21,r22,32 ; Fourth line
1076 dcbst 0,r22 ; Force to memory
1077 dcbst 0,r21 ; Force to memory
1078 sync ; Make sure it all goes
1079#endif
1080
1081ctdisa32: mtcrf 0x80,r25 ; Restore the used condition register field
1082 lwz r20,tempr0(r11) ; Restore work register
1083 lwz r21,tempr1(r11) ; Restore work register
1084 lwz r25,tempr2(r11) ; Restore work register
1085 mtctr r13 ; Restore the caller's CTR
1086 lwz r22,tempr3(r11) ; Restore work register
1087 lwz r23,tempr4(r11) ; Restore work register
1088 lwz r24,tempr5(r11) ; Restore work register
1089 b uftX32 ; Go restore the rest and go...
1090
1091ctbail32: mtcrf 0x80,r25 ; Restore the used condition register field
1092 lwz r20,tempr0(r11) ; Restore work register
1093 lwz r21,tempr1(r11) ; Restore work register
1094 lwz r25,tempr2(r11) ; Restore work register
1095 mtctr r13 ; Restore the caller's CTR
1096 lwz r22,tempr3(r11) ; Restore work register
1097 lwz r23,tempr4(r11) ; Restore work register
1098 b uftNormalSyscall ; Go pass it on along...
91447636 1099
b36670ce
A
1100;
1101; This is the 64-bit version.
1102;
1103
1104uftct64: std r20,tempr0(r11) ; Save some work registers
1105 lwz r20,dgFlags(0) ; Get the flags
1106 std r21,tempr1(r11) ; Save some work registers
1107 mfsrr1 r21 ; Get the SRR1
1108 rlwinm r20,r20,MSR_PR_BIT-enaUsrFCallb,MASK(MSR_PR) ; Shift the validity bit over to pr bit spot
1109 std r25,tempr2(r11) ; Save some work registers
1110 orc r20,r20,r21 ; Get ~PR | FC
1111 mfcr r25 ; Save the CR
1112 std r22,tempr3(r11) ; Save some work registers
1113 lhz r22,PP_CPU_NUMBER(r11) ; Get the logical processor number
1114 andi. r20,r20,MASK(MSR_PR) ; Set cr0_eq when we are in problem state and the validity bit is not set
1115 std r23,tempr4(r11) ; Save some work registers
1116 lwz r23,traceMask(0) ; Get the trace mask
1117 std r24,tempr5(r11) ; Save some work registers
1118 beq-- ctbail64 ; Can not issue from user...
1119
1120 addi r24,r22,16 ; Get shift to move cpu mask to syscall mask
1121 rlwnm r24,r23,r24,12,12 ; Shift cpu mask bit to rupt type mask
1122 and. r24,r24,r23 ; See if both are on
1123
1124;
1125; We select a trace entry using a compare and swap on the next entry field.
1126; Since we do not lock the actual trace buffer, there is a potential that
1127; another processor could wrap an trash our entry. Who cares?
1128;
1129
1130 li r23,trcWork ; Get the trace work area address
1131 lwz r21,traceStart(0) ; Get the start of trace table
1132 lwz r22,traceEnd(0) ; Get end of trace table
1133
1134 beq-- ctdisa64 ; Leave because tracing is disabled...
1135
1136ctgte64: lwarx r20,0,r23 ; Get and reserve the next slot to allocate
1137 addi r24,r20,LTR_size ; Point to the next trace entry
1138 cmplw r24,r22 ; Do we need to wrap the trace table?
1139 bne++ ctgte64s ; No wrap, we got us a trace entry...
1140
1141 mr r24,r21 ; Wrap back to start
91447636 1142
b36670ce
A
1143ctgte64s: stwcx. r24,0,r23 ; Try to update the current pointer
1144 bne-- ctgte64 ; Collision, try again...
1145
1146#if ESPDEBUG
1147 dcbf 0,r23 ; Force to memory
1148 sync
1149#endif
1150
1151 dcbz128 0,r20 ; Zap the trace entry
1152
1153 mftb r21 ; Get the time
1154
1155;
1156; Let us cut that trace entry now.
1157;
1158; Note that this code cuts a trace table entry for the CutTrace call only.
1159; An identical entry is made during normal interrupt processing. Any entry
1160; format entry changes made must be done in both places.
1161;
1162
1163 lhz r24,PP_CPU_NUMBER(r11) ; Get the logical processor number
1164 li r23,T_SYSTEM_CALL ; Get the system call id
1165 sth r24,LTR_cpu(r20) ; Save processor number
1166 sth r23,LTR_excpt(r20) ; Set the exception code
1167 mfspr r23,dsisr ; Get the DSISR
1168 std r21,LTR_timeHi(r20) ; Save top of time stamp
1169 mflr r21 ; Get the LR
1170 mfsrr0 r22 ; Get SRR0
1171 stw r25,LTR_cr(r20) ; Save CR
1172 mfsrr1 r24 ; Get the SRR1
1173 stw r23,LTR_dsisr(r20) ; Save DSISR
1174 std r22,LTR_srr0(r20) ; Save SRR0
1175 mfdar r23 ; Get DAR
1176 std r24,LTR_srr1(r20) ; Save SRR1
1177 std r23,LTR_dar(r20) ; Save DAR
1178 std r21,LTR_lr(r20) ; Save LR
1179
1180 std r13,LTR_ctr(r20) ; Save CTR
1181 std r0,LTR_r0(r20) ; Save register
1182 std r1,LTR_r1(r20) ; Save register
1183 std r2,LTR_r2(r20) ; Save register
1184 std r3,LTR_r3(r20) ; Save register
1185 std r4,LTR_r4(r20) ; Save register
1186 std r5,LTR_r5(r20) ; Save register
1187 std r6,LTR_r6(r20) ; Save register
1188
1189#if 0
1190 lwz r21,FPUowner(r11) ; (TEST/DEBUG) Get the current floating point owner
1191 stw r21,LTR_rsvd0(r20) ; (TEST/DEBUG) Record the owner
1192#endif
1193
1194#if ESPDEBUG
1195 dcbf 0,r20 ; Force to memory
1196 sync ; Make sure it all goes
1197#endif
1198
1199ctdisa64: mtcrf 0x80,r25 ; Restore the used condition register field
1200 ld r20,tempr0(r11) ; Restore work register
1201 ld r21,tempr1(r11) ; Restore work register
1202 ld r25,tempr2(r11) ; Restore work register
1203 mtctr r13 ; Restore the caller's CTR
1204 ld r22,tempr3(r11) ; Restore work register
1205 ld r23,tempr4(r11) ; Restore work register
1206 ld r24,tempr5(r11) ; Restore work register
1207 b uftX64 ; Go restore the rest and go...
1208
1209ctbail64: mtcrf 0x80,r25 ; Restore the used condition register field
1210 ld r20,tempr0(r11) ; Restore work register
1211 ld r21,tempr1(r11) ; Restore work register
1212 ld r25,tempr2(r11) ; Restore work register
1213 mtctr r13 ; Restore the caller's CTR
1214 ld r22,tempr3(r11) ; Restore work register
1215 ld r23,tempr4(r11) ; Restore work register
1216 li r11,T_SYSTEM_CALL|T_FAM ; Set system code call
1217 b extEntry64 ; Go straight to the 64-bit code...
1218
1219
1220
3a60a9f5 1221; Handle a system call that is not a UFT and which thus goes upstairs.
b36670ce 1222
3a60a9f5
A
1223uftNormalFF: ; here with entire cr in r13
1224 mtcr r13 ; restore all 8 fields
91447636 1225 b uftNormalSyscall1 ; Join common...
3a60a9f5
A
1226
1227uftNormal80: ; here with callers cr0 in r13
1228 mtcrf 0x80,r13 ; restore cr0
91447636 1229 b uftNormalSyscall1 ; Join common...
3a60a9f5
A
1230
1231uftNormalSyscall: ; r13 = callers ctr
1232 mtctr r13 ; restore ctr
91447636 1233uftNormalSyscall1:
3a60a9f5 1234 li r11,T_SYSTEM_CALL|T_FAM ; this is a system call (and fall through)
91447636
A
1235
1236
1237/*<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>*/
1c79356b
A
1238/*
1239 * .L_exception_entry(type)
1240 *
91447636
A
1241 * Come here via branch directly from the vector, or falling down from above, with the following
1242 * set up:
1c79356b 1243 *
91447636
A
1244 * ENTRY: interrupts off, VM off, in 64-bit mode if supported
1245 * Caller's r13 saved in sprg2.
1246 * Caller's r11 saved in sprg3.
1247 * Exception code (ie, T_SYSTEM_CALL etc) in r11.
1248 * All other registers are live.
1c79356b
A
1249 *
1250 */
1c79356b 1251
91447636 1252.L_exception_entry: ; WARNING: can fall through from UFT handler
1c79356b
A
1253
1254/*
1255 *
1256 * Here we will save off a mess of registers, the special ones and R0-R12. We use the DCBZ
1257 * instruction to clear and allcoate a line in the cache. This way we won't take any cache
1258 * misses, so these stores won't take all that long. Except the first line that is because
1259 * we can't do a DCBZ if the L1 D-cache is off. The rest we will skip if they are
1260 * off also.
3a60a9f5 1261 *
1c79356b
A
1262 * Note that if we are attempting to sleep (as opposed to nap or doze) all interruptions
1263 * are ignored.
1264 */
1265
55e303ae
A
1266
1267 .globl EXT(extPatch32)
1268
1269
1270LEXT(extPatch32)
91447636 1271 b extEntry64 ; Go do 64-bit (patched to a nop if 32-bit)
55e303ae
A
1272 mfsprg r13,0 ; Load per_proc
1273 lwz r13,next_savearea+4(r13) ; Get the exception save area
1274 stw r0,saver0+4(r13) ; Save register 0
1275 stw r1,saver1+4(r13) ; Save register 1
1276
1c79356b 1277 mfspr r1,hid0 ; Get HID0
55e303ae
A
1278 mfcr r0 ; Save the whole CR
1279
1280 mtcrf 0x20,r1 ; Get set to test for sleep
1281 cror doze,doze,nap ; Remember if we are napping
1c79356b
A
1282 bf sleep,notsleep ; Skip if we are not trying to sleep
1283
55e303ae
A
1284 mtcrf 0x20,r0 ; Restore the CR
1285 lwz r0,saver0+4(r13) ; Restore R0
1286 lwz r1,saver1+4(r13) ; Restore R1
1c79356b
A
1287 mfsprg r13,0 ; Get the per_proc
1288 lwz r11,pfAvailable(r13) ; Get back the feature flags
1289 mfsprg r13,2 ; Restore R13
1290 mtsprg 2,r11 ; Set sprg2 to the features
1291 mfsprg r11,3 ; Restore R11
1292 rfi ; Jump back into sleep code...
1293 .long 0 ; Leave these here please...
1294 .long 0
1295 .long 0
1296 .long 0
1297 .long 0
1298 .long 0
1299 .long 0
1300 .long 0
1301
55e303ae
A
1302
1303;
1304; This is the 32-bit context saving stuff
1305;
1306
1c79356b
A
1307 .align 5
1308
55e303ae
A
1309notsleep: stw r2,saver2+4(r13) ; Save this one
1310 bf doze,notspdo ; Skip the next if we are not napping/dozing...
1c79356b
A
1311 rlwinm r2,r1,0,nap+1,doze-1 ; Clear any possible nap and doze bits
1312 mtspr hid0,r2 ; Clear the nap/doze bits
55e303ae
A
1313notspdo:
1314
1315#if INSTRUMENT
1316 mfspr r2,pmc1 ; INSTRUMENT - saveinstr[0] - Take earliest possible stamp
1317 stw r2,0x6100+(0x00*16)+0x0(0) ; INSTRUMENT - Save it
1318 mfspr r2,pmc2 ; INSTRUMENT - Get stamp
1319 stw r2,0x6100+(0x00*16)+0x4(0) ; INSTRUMENT - Save it
1320 mfspr r2,pmc3 ; INSTRUMENT - Get stamp
1321 stw r2,0x6100+(0x00*16)+0x8(0) ; INSTRUMENT - Save it
1322 mfspr r2,pmc4 ; INSTRUMENT - Get stamp
1323 stw r2,0x6100+(0x00*16)+0xC(0) ; INSTRUMENT - Save it
1324#endif
1325
1326 la r1,saver4(r13) ; Point to the next line in case we need it
1327 crmove wasNapping,doze ; Remember if we were napping
1c79356b 1328 mfsprg r2,0 ; Get the per_proc area
55e303ae 1329 dcbz 0,r1 ; allocate r4-r7 32-byte line in cache
1c79356b
A
1330
1331;
1332; Remember, we are setting up CR6 with feature flags
1333;
55e303ae
A
1334 andi. r1,r11,T_FAM ; Check FAM bit
1335
1336 stw r3,saver3+4(r13) ; Save this one
1337 stw r4,saver4+4(r13) ; Save this one
d7e50217
A
1338 andc r11,r11,r1 ; Clear FAM bit
1339 beq+ noFAM ; Is it FAM intercept
1340 mfsrr1 r3 ; Load srr1
1341 rlwinm. r3,r3,0,MSR_PR_BIT,MSR_PR_BIT ; Are we trapping from supervisor state?
1342 beq+ noFAM ; From supervisor state
1343 lwz r1,spcFlags(r2) ; Load spcFlags
1344 rlwinm r1,r1,1+FamVMmodebit,30,31 ; Extract FamVMenabit and FamVMmodebit
1345 cmpwi cr0,r1,2 ; Check FamVMena set without FamVMmode
1346 bne+ noFAM ; Can this context be FAM intercept
1347 lwz r4,FAMintercept(r2) ; Load exceptions mask to intercept
1348 srwi r1,r11,2 ; divide r11 by 4
1349 lis r3,0x8000 ; Set r3 to 0x80000000
1350 srw r1,r3,r1 ; Set bit for current exception
1351 and. r1,r1,r4 ; And current exception with the intercept mask
1352 beq+ noFAM ; Is it FAM intercept
55e303ae 1353 b EXT(vmm_fam_exc)
d7e50217
A
1354noFAM:
1355 lwz r1,pfAvailable(r2) ; Get the CPU features flags
55e303ae
A
1356 la r3,saver8(r13) ; Point to line with r8-r11
1357 mtcrf 0xE2,r1 ; Put the features flags (that we care about) in the CR
1358 dcbz 0,r3 ; allocate r8-r11 32-byte line in cache
1359 la r3,saver12(r13) ; point to r12-r15 line
1360 lis r4,hi16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Set up the MSR we will use throughout. Note that ME come on here if MCK
1361 stw r6,saver6+4(r13) ; Save this one
1362 ori r4,r4,lo16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Rest of MSR
1363 stw r8,saver8+4(r13) ; Save this one
1c79356b 1364 crmove featAltivec,pfAltivecb ; Set the Altivec flag
55e303ae
A
1365 mtmsr r4 ; Set MSR
1366 isync
9bccf70c 1367 mfsrr0 r6 ; Get the interruption SRR0
55e303ae
A
1368 la r8,savesrr0(r13) ; point to line with SRR0, SRR1, CR, XER, and LR
1369 dcbz 0,r3 ; allocate r12-r15 32-byte line in cache
1370 la r3,saver16(r13) ; point to next line
1371 dcbz 0,r8 ; allocate 32-byte line with SRR0, SRR1, CR, XER, and LR
1372 stw r7,saver7+4(r13) ; Save this one
1c79356b 1373 lhz r8,PP_CPU_FLAGS(r2) ; Get the flags
9bccf70c 1374 mfsrr1 r7 ; Get the interrupt SRR1
1c79356b 1375 rlwinm r8,r8,(((31-MSR_BE_BIT)+(traceBEb+16+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Set BE bit if special trace is on
55e303ae 1376 stw r6,savesrr0+4(r13) ; Save the SRR0
1c79356b 1377 rlwinm r6,r7,(((31-MSR_BE_BIT)+(MSR_PR_BIT+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Move PR bit to BE bit
55e303ae 1378 stw r5,saver5+4(r13) ; Save this one
1c79356b
A
1379 and r8,r6,r8 ; Remove BE bit only if problem state and special tracing on
1380 mfsprg r6,2 ; Get interrupt time R13
1381 mtsprg 2,r1 ; Set the feature flags
1382 andc r7,r7,r8 ; Clear BE bit if special trace is on and PR is set
9bccf70c 1383 mfsprg r8,3 ; Get rupt time R11
55e303ae
A
1384 stw r7,savesrr1+4(r13) ; Save SRR1
1385 stw r8,saver11+4(r13) ; Save rupt time R11
1386 stw r6,saver13+4(r13) ; Save rupt R13
1387 dcbz 0,r3 ; allocate 32-byte line with r16-r19
1388 la r3,saver20(r13) ; point to next line
1c79356b
A
1389
1390getTB: mftbu r6 ; Get the upper timebase
1391 mftb r7 ; Get the lower timebase
1392 mftbu r8 ; Get the upper one again
1393 cmplw r6,r8 ; Did the top tick?
1394 bne- getTB ; Yeah, need to get it again...
1395
55e303ae
A
1396#if INSTRUMENT
1397 mfspr r6,pmc1 ; INSTRUMENT - saveinstr[1] - Save halfway context save stamp
1398 stw r6,0x6100+(0x01*16)+0x0(0) ; INSTRUMENT - Save it
1399 mfspr r6,pmc2 ; INSTRUMENT - Get stamp
1400 stw r6,0x6100+(0x01*16)+0x4(0) ; INSTRUMENT - Save it
1401 mfspr r6,pmc3 ; INSTRUMENT - Get stamp
1402 stw r6,0x6100+(0x01*16)+0x8(0) ; INSTRUMENT - Save it
1403 mfspr r6,pmc4 ; INSTRUMENT - Get stamp
1404 stw r6,0x6100+(0x01*16)+0xC(0) ; INSTRUMENT - Save it
1405#endif
1406
1c79356b 1407 stw r8,ruptStamp(r2) ; Save the top of time stamp
9bccf70c 1408 stw r8,SAVtime(r13) ; Save the top of time stamp
1c79356b 1409 stw r7,ruptStamp+4(r2) ; Save the bottom of time stamp
9bccf70c
A
1410 stw r7,SAVtime+4(r13) ; Save the bottom of time stamp
1411
55e303ae
A
1412 dcbz 0,r3 ; allocate 32-byte line with r20-r23
1413 stw r9,saver9+4(r13) ; Save this one
1c79356b 1414
55e303ae 1415 stw r10,saver10+4(r13) ; Save this one
9bccf70c 1416 mflr r4 ; Get the LR
1c79356b
A
1417 mfxer r10 ; Get the XER
1418
1419 bf+ wasNapping,notNapping ; Skip if not waking up from nap...
1420
1421 lwz r6,napStamp+4(r2) ; Pick up low order nap stamp
1422 lis r3,hi16(EXT(machine_idle_ret)) ; Get high part of nap/doze return
1423 lwz r5,napStamp(r2) ; and high order
1424 subfc r7,r6,r7 ; Subtract low stamp from now
1425 lwz r6,napTotal+4(r2) ; Pick up low total
1426 subfe r5,r5,r8 ; Subtract high stamp and borrow from now
1427 lwz r8,napTotal(r2) ; Pick up the high total
1428 addc r6,r6,r7 ; Add low to total
1429 ori r3,r3,lo16(EXT(machine_idle_ret)) ; Get low part of nap/doze return
1430 adde r8,r8,r5 ; Add high and carry to total
1431 stw r6,napTotal+4(r2) ; Save the low total
1432 stw r8,napTotal(r2) ; Save the high total
55e303ae 1433 stw r3,savesrr0+4(r13) ; Modify to return to nap/doze exit
9bccf70c 1434
55e303ae 1435 rlwinm. r3,r1,0,pfSlowNapb,pfSlowNapb ; Should HID1 be restored?
9bccf70c
A
1436 beq notInSlowNap
1437
1438 lwz r3,pfHID1(r2) ; Get saved HID1 value
55e303ae 1439 mtspr hid1,r3 ; Restore HID1
d52fe63f 1440
9bccf70c 1441notInSlowNap:
55e303ae 1442 rlwinm. r3,r1,0,pfNoL2PFNapb,pfNoL2PFNapb ; Should MSSCR0 be restored?
9bccf70c 1443 beq notNapping
d52fe63f 1444
9bccf70c 1445 lwz r3,pfMSSCR0(r2) ; Get saved MSSCR0 value
55e303ae 1446 mtspr msscr0,r3 ; Restore MSSCR0
9bccf70c
A
1447 sync
1448 isync
1449
55e303ae 1450notNapping: stw r12,saver12+4(r13) ; Save this one
1c79356b 1451
55e303ae
A
1452 stw r14,saver14+4(r13) ; Save this one
1453 stw r15,saver15+4(r13) ; Save this one
9bccf70c 1454 la r14,saver24(r13) ; Point to the next block to save into
9bccf70c 1455 mfctr r6 ; Get the CTR
55e303ae
A
1456 stw r16,saver16+4(r13) ; Save this one
1457 la r15,savectr(r13) ; point to line with CTR, DAR, DSISR, Exception code, and VRSAVE
1458 stw r4,savelr+4(r13) ; Save rupt LR
1c79356b 1459
55e303ae
A
1460 dcbz 0,r14 ; allocate 32-byte line with r24-r27
1461 la r16,saver28(r13) ; point to line with r28-r31
1462 dcbz 0,r15 ; allocate line with CTR, DAR, DSISR, Exception code, and VRSAVE
1463 stw r17,saver17+4(r13) ; Save this one
1464 stw r18,saver18+4(r13) ; Save this one
1465 stw r6,savectr+4(r13) ; Save rupt CTR
1466 stw r0,savecr(r13) ; Save rupt CR
1467 stw r19,saver19+4(r13) ; Save this one
9bccf70c 1468 mfdar r6 ; Get the rupt DAR
55e303ae
A
1469 stw r20,saver20+4(r13) ; Save this one
1470 dcbz 0,r16 ; allocate 32-byte line with r28-r31
1471
1472 stw r21,saver21+4(r13) ; Save this one
1473 lwz r21,spcFlags(r2) ; Get the special flags from per_proc
1474 stw r10,savexer+4(r13) ; Save the rupt XER
1475 stw r30,saver30+4(r13) ; Save this one
1476 lhz r30,pfrptdProc(r2) ; Get the reported processor type
1477 stw r31,saver31+4(r13) ; Save this one
1478 stw r22,saver22+4(r13) ; Save this one
1479 stw r23,saver23+4(r13) ; Save this one
1480 stw r24,saver24+4(r13) ; Save this one
1481 stw r25,saver25+4(r13) ; Save this one
9bccf70c 1482 mfdsisr r7 ; Get the rupt DSISR
55e303ae
A
1483 stw r26,saver26+4(r13) ; Save this one
1484 stw r27,saver27+4(r13) ; Save this one
1485 andis. r21,r21,hi16(perfMonitor) ; Is the performance monitor enabled?
1486 stw r28,saver28+4(r13) ; Save this one
1487 cmpwi cr1, r30,CPU_SUBTYPE_POWERPC_750 ; G3?
1488 la r27,savevscr(r13) ; point to 32-byte line with VSCR and FPSCR
1489 cmpwi cr2,r30,CPU_SUBTYPE_POWERPC_7400 ; This guy?
1490 stw r29,saver29+4(r13) ; Save R29
1491 stw r6,savedar+4(r13) ; Save the rupt DAR
1492 li r10,savepmc ; Point to pmc savearea
1493
1494 beq+ noPerfMonSave32 ; No perfmon on here...
1495
1496 dcbz r10,r13 ; Clear first part of pmc area
1497 li r10,savepmc+0x20 ; Point to pmc savearea second part
1498 li r22,0 ; r22: zero
1499 dcbz r10,r13 ; Clear second part of pmc area
1500
1501 beq cr1,perfMonSave32_750 ; This is a G3...
1502
1503 beq cr2,perfMonSave32_7400 ; Regular olde G4...
1504
1505 mfspr r24,pmc5 ; Here for a 7450
1506 mfspr r25,pmc6
1507 stw r24,savepmc+16(r13) ; Save PMC5
1508 stw r25,savepmc+20(r13) ; Save PMC6
1509 mtspr pmc5,r22 ; Leave PMC5 clear
1510 mtspr pmc6,r22 ; Leave PMC6 clear
1511
1512perfMonSave32_7400:
1513 mfspr r25,mmcr2
1514 stw r25,savemmcr2+4(r13) ; Save MMCR2
1515 mtspr mmcr2,r22 ; Leave MMCR2 clear
1516
1517perfMonSave32_750:
1518 mfspr r23,mmcr0
1519 mfspr r24,mmcr1
1520 stw r23,savemmcr0+4(r13) ; Save MMCR0
1521 stw r24,savemmcr1+4(r13) ; Save MMCR1
1522 mtspr mmcr0,r22 ; Leave MMCR0 clear
1523 mtspr mmcr1,r22 ; Leave MMCR1 clear
1524 mfspr r23,pmc1
1525 mfspr r24,pmc2
1526 mfspr r25,pmc3
1527 mfspr r26,pmc4
1528 stw r23,savepmc+0(r13) ; Save PMC1
1529 stw r24,savepmc+4(r13) ; Save PMC2
1530 stw r25,savepmc+8(r13) ; Save PMC3
1531 stw r26,savepmc+12(r13) ; Save PMC4
1532 mtspr pmc1,r22 ; Leave PMC1 clear
1533 mtspr pmc2,r22 ; Leave PMC2 clear
1534 mtspr pmc3,r22 ; Leave PMC3 clear
1535 mtspr pmc4,r22 ; Leave PMC4 clear
1536
1537noPerfMonSave32:
1538 dcbz 0,r27 ; allocate line with VSCR and FPSCR
1539
1540 stw r7,savedsisr(r13) ; Save the rupt code DSISR
9bccf70c 1541 stw r11,saveexception(r13) ; Save the exception code
1c79356b 1542
9bccf70c
A
1543
1544;
55e303ae
A
1545; Everything is saved at this point, except for FPRs, and VMX registers.
1546; Time for us to get a new savearea and then trace interrupt if it is enabled.
9bccf70c
A
1547;
1548
55e303ae
A
1549 lwz r25,traceMask(0) ; Get the trace mask
1550 li r0,SAVgeneral ; Get the savearea type value
1551 lhz r19,PP_CPU_NUMBER(r2) ; Get the logical processor number
3a60a9f5 1552 rlwinm r22,r11,30,0,31 ; Divide interrupt code by 2
55e303ae
A
1553 stb r0,SAVflags+2(r13) ; Mark valid context
1554 addi r22,r22,10 ; Adjust code so we shift into CR5
1555 li r23,trcWork ; Get the trace work area address
1556 rlwnm r7,r25,r22,22,22 ; Set CR5_EQ bit position to 0 if tracing allowed
1557 li r26,0x8 ; Get start of cpu mask
1558 srw r26,r26,r19 ; Get bit position of cpu number
1559 mtcrf 0x04,r7 ; Set CR5 to show trace or not
1560 and. r26,r26,r25 ; See if we trace this cpu
1561 crandc cr5_eq,cr5_eq,cr0_eq ; Turn off tracing if cpu is disabled
1562;
1563; At this point, we can take another exception and lose nothing.
1564;
d7e50217 1565
55e303ae
A
1566#if INSTRUMENT
1567 mfspr r26,pmc1 ; INSTRUMENT - saveinstr[2] - Take stamp after save is done
1568 stw r26,0x6100+(0x02*16)+0x0(0) ; INSTRUMENT - Save it
1569 mfspr r26,pmc2 ; INSTRUMENT - Get stamp
1570 stw r26,0x6100+(0x02*16)+0x4(0) ; INSTRUMENT - Save it
1571 mfspr r26,pmc3 ; INSTRUMENT - Get stamp
1572 stw r26,0x6100+(0x02*16)+0x8(0) ; INSTRUMENT - Save it
1573 mfspr r26,pmc4 ; INSTRUMENT - Get stamp
1574 stw r26,0x6100+(0x02*16)+0xC(0) ; INSTRUMENT - Save it
1575#endif
d7e50217 1576
55e303ae 1577 bne+ cr5,xcp32xit ; Skip all of this if no tracing here...
d7e50217
A
1578
1579;
55e303ae
A
1580; We select a trace entry using a compare and swap on the next entry field.
1581; Since we do not lock the actual trace buffer, there is a potential that
1582; another processor could wrap an trash our entry. Who cares?
d7e50217
A
1583;
1584
55e303ae
A
1585 lwz r25,traceStart(0) ; Get the start of trace table
1586 lwz r26,traceEnd(0) ; Get end of trace table
1587
1588trcsel: lwarx r20,0,r23 ; Get and reserve the next slot to allocate
9bccf70c 1589
55e303ae
A
1590 addi r22,r20,LTR_size ; Point to the next trace entry
1591 cmplw r22,r26 ; Do we need to wrap the trace table?
1592 bne+ gotTrcEnt ; No wrap, we got us a trace entry...
1593
1594 mr r22,r25 ; Wrap back to start
d7e50217 1595
55e303ae
A
1596gotTrcEnt: stwcx. r22,0,r23 ; Try to update the current pointer
1597 bne- trcsel ; Collision, try again...
1598
1599#if ESPDEBUG
1600 dcbf 0,r23 ; Force to memory
1601 sync
1602#endif
1603
1604 dcbz 0,r20 ; Clear and allocate first trace line
1605
1606;
1607; Let us cut that trace entry now.
b36670ce
A
1608;
1609; Note that this code cuts a trace table entry for everything but the CutTrace call.
1610; An identical entry is made during normal CutTrace processing. Any entry
1611; format changes made must be done in both places.
55e303ae
A
1612;
1613
1614 lwz r16,ruptStamp(r2) ; Get top of time base
1615 lwz r17,ruptStamp+4(r2) ; Get the bottom of time stamp
1616
1617 li r14,32 ; Offset to second line
1618
1619 lwz r0,saver0+4(r13) ; Get back interrupt time R0
1620 lwz r1,saver1+4(r13) ; Get back interrupt time R1
1621 lwz r8,savecr(r13) ; Get the CR value
1622
1623 dcbz r14,r20 ; Zap the second line
1624
1625 sth r19,LTR_cpu(r20) ; Stash the cpu number
1626 li r14,64 ; Offset to third line
1627 sth r11,LTR_excpt(r20) ; Save the exception type
1628 lwz r7,saver2+4(r13) ; Get back interrupt time R2
1629 lwz r3,saver3+4(r13) ; Restore this one
1630
1631 dcbz r14,r20 ; Zap the third half
1632
1633 mfdsisr r9 ; Get the DSISR
1634 li r14,96 ; Offset to forth line
1635 stw r16,LTR_timeHi(r20) ; Set the upper part of TB
1636 stw r17,LTR_timeLo(r20) ; Set the lower part of TB
1637 lwz r10,savelr+4(r13) ; Get the LR
1638 mfsrr0 r17 ; Get SRR0 back, it is still good
1639
1640 dcbz r14,r20 ; Zap the forth half
1641 lwz r4,saver4+4(r13) ; Restore this one
1642 lwz r5,saver5+4(r13) ; Restore this one
1643 mfsrr1 r18 ; SRR1 is still good in here
1644
1645 stw r8,LTR_cr(r20) ; Save the CR
1646 lwz r6,saver6+4(r13) ; Get R6
1647 mfdar r16 ; Get this back
1648 stw r9,LTR_dsisr(r20) ; Save the DSISR
1649 stw r17,LTR_srr0+4(r20) ; Save the SSR0
1650
1651 stw r18,LTR_srr1+4(r20) ; Save the SRR1
1652 stw r16,LTR_dar+4(r20) ; Save the DAR
1653 mfctr r17 ; Get the CTR (still good in register)
1654 stw r13,LTR_save+4(r20) ; Save the savearea
1655 stw r10,LTR_lr+4(r20) ; Save the LR
1656
1657 stw r17,LTR_ctr+4(r20) ; Save off the CTR
1658 stw r0,LTR_r0+4(r20) ; Save off register 0
1659 stw r1,LTR_r1+4(r20) ; Save off register 1
1660 stw r7,LTR_r2+4(r20) ; Save off register 2
1661
1662
1663 stw r3,LTR_r3+4(r20) ; Save off register 3
1664 stw r4,LTR_r4+4(r20) ; Save off register 4
1665 stw r5,LTR_r5+4(r20) ; Save off register 5
1666 stw r6,LTR_r6+4(r20) ; Save off register 6
1667
1668#if ESPDEBUG
1669 addi r17,r20,32 ; Second line
1670 addi r16,r20,64 ; Third line
1671 dcbst br0,r20 ; Force to memory
1672 dcbst br0,r17 ; Force to memory
1673 addi r17,r17,32 ; Fourth line
1674 dcbst br0,r16 ; Force to memory
1675 dcbst br0,r17 ; Force to memory
1676
1677 sync ; Make sure it all goes
1678#endif
1679xcp32xit: mr r14,r11 ; Save the interrupt code across the call
1680 bl EXT(save_get_phys_32) ; Grab a savearea
1681 mfsprg r2,0 ; Get the per_proc info
1682 li r10,emfp0 ; Point to floating point save
1683 mr r11,r14 ; Get the exception code back
1684 dcbz r10,r2 ; Clear for speed
1685 stw r3,next_savearea+4(r2) ; Store the savearea for the next rupt
1686
1687#if INSTRUMENT
1688 mfspr r4,pmc1 ; INSTRUMENT - saveinstr[3] - Take stamp after next savearea
1689 stw r4,0x6100+(0x03*16)+0x0(0) ; INSTRUMENT - Save it
1690 mfspr r4,pmc2 ; INSTRUMENT - Get stamp
1691 stw r4,0x6100+(0x03*16)+0x4(0) ; INSTRUMENT - Save it
1692 mfspr r4,pmc3 ; INSTRUMENT - Get stamp
1693 stw r4,0x6100+(0x03*16)+0x8(0) ; INSTRUMENT - Save it
1694 mfspr r4,pmc4 ; INSTRUMENT - Get stamp
1695 stw r4,0x6100+(0x03*16)+0xC(0) ; INSTRUMENT - Save it
1696#endif
1697 b xcpCommon ; Go join the common interrupt processing...
1698
1699;
1700;
1701; This is the 64-bit context saving stuff
1702;
1703
1704 .align 5
1705
1706extEntry64: mfsprg r13,0 ; Load per_proc
1707 ld r13,next_savearea(r13) ; Get the exception save area
1708 std r0,saver0(r13) ; Save register 0
1709 lis r0,hi16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Set up the MSR we will use throughout. Note that ME come on here if MCK
1710 std r1,saver1(r13) ; Save register 1
1711 ori r1,r0,lo16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Rest of MSR
1712 lis r0,0x0010 ; Get rupt code transform validity mask
1713 mtmsr r1 ; Set MSR
de355530 1714 isync
55e303ae
A
1715
1716 ori r0,r0,0x0200 ; Get rupt code transform validity mask
1717 std r2,saver2(r13) ; Save this one
1718 lis r1,0x00F0 ; Top half of xform XOR
1719 rlwinm r2,r11,29,27,31 ; Get high 5 bits of rupt code
1720 std r3,saver3(r13) ; Save this one
1721 slw r0,r0,r2 ; Move transform validity bit to bit 0
1722 std r4,saver4(r13) ; Save this one
1723 std r5,saver5(r13) ; Save this one
1724 ori r1,r1,0x04EC ; Bottom half of xform XOR
1725 mfxer r5 ; Save the XER because we are about to muck with it
1726 rlwinm r4,r11,1,27,28 ; Get bottom of interrupt code * 8
1727 lis r3,hi16(dozem|napm) ; Get the nap and doze bits
1728 srawi r0,r0,31 ; Get 0xFFFFFFFF of xform valid, 0 otherwise
1729 rlwnm r4,r1,r4,24,31 ; Extract the xform XOR
1730 li r1,saver16 ; Point to the next line
1731 and r4,r4,r0 ; Only keep transform if we are to use it
1732 li r2,lgKillResv ; Point to the killing field
1733 mfcr r0 ; Save the CR
1734 stwcx. r2,0,r2 ; Kill any pending reservation
1735 dcbz128 r1,r13 ; Blow away the line
1736 sldi r3,r3,32 ; Position it
1737 mfspr r1,hid0 ; Get HID0
1738 andc r3,r1,r3 ; Clear nap and doze
1739 xor r11,r11,r4 ; Transform 970 rupt code to standard keeping FAM bit
1740 cmpld r3,r1 ; See if nap and/or doze was on
1741 std r6,saver6(r13) ; Save this one
1742 mfsprg r2,0 ; Get the per_proc area
1743 la r6,savesrr0(r13) ; point to line with SRR0, SRR1, CR, XER, and LR
1744 beq++ eE64NoNap ; No nap here, skip all this...
1745
1746 sync ; Make sure we are clean
1747 mtspr hid0,r3 ; Set the updated hid0
1748 mfspr r1,hid0 ; Yes, this is silly, keep it here
1749 mfspr r1,hid0 ; Yes, this is a duplicate, keep it here
1750 mfspr r1,hid0 ; Yes, this is a duplicate, keep it here
1751 mfspr r1,hid0 ; Yes, this is a duplicate, keep it here
1752 mfspr r1,hid0 ; Yes, this is a duplicate, keep it here
1753 mfspr r1,hid0 ; Yes, this is a duplicate, keep it here
1754
1755eE64NoNap: crnot wasNapping,cr0_eq ; Remember if we were napping
1756 andi. r1,r11,T_FAM ; Check FAM bit
1757 beq++ eEnoFAM ; Is it FAM intercept
1758 mfsrr1 r3 ; Load srr1
1759 andc r11,r11,r1 ; Clear FAM bit
1760 rlwinm. r3,r3,0,MSR_PR_BIT,MSR_PR_BIT ; Are we trapping from supervisor state?
91447636 1761 beq++ eEnoFAM ; From supervisor state
55e303ae
A
1762 lwz r1,spcFlags(r2) ; Load spcFlags
1763 rlwinm r1,r1,1+FamVMmodebit,30,31 ; Extract FamVMenabit and FamVMmodebit
1764 cmpwi cr0,r1,2 ; Check FamVMena set without FamVMmode
1765 bne++ eEnoFAM ; Can this context be FAM intercept
1766 lwz r4,FAMintercept(r2) ; Load exceptions mask to intercept
1767 li r3,0 ; Clear
1768 srwi r1,r11,2 ; divide r11 by 4
1769 oris r3,r3,0x8000 ; Set r3 to 0x80000000
1770 srw r1,r3,r1 ; Set bit for current exception
1771 and. r1,r1,r4 ; And current exception with the intercept mask
1772 beq++ eEnoFAM ; Is it FAM intercept
1773 b EXT(vmm_fam_exc)
1774
1775 .align 5
1776
1777eEnoFAM: lwz r1,pfAvailable(r2) ; Get the CPU features flags
1778 dcbz128 0,r6 ; allocate 128-byte line with SRR0, SRR1, CR, XER, and LR
1779
1780;
1781; Remember, we are setting up CR6 with feature flags
1782;
1783 std r7,saver7(r13) ; Save this one
1784 mtcrf 0x80,r1 ; Put the features flags (that we care about) in the CR
1785 std r8,saver8(r13) ; Save this one
1786 mtcrf 0x40,r1 ; Put the features flags (that we care about) in the CR
1787 mfsrr0 r6 ; Get the interruption SRR0
1788 lhz r8,PP_CPU_FLAGS(r2) ; Get the flags
1789 mtcrf 0x20,r1 ; Put the features flags (that we care about) in the CR
1790 mfsrr1 r7 ; Get the interrupt SRR1
1791 rlwinm r8,r8,(((31-MSR_BE_BIT)+(traceBEb+16+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Set BE bit if special trace is on
1792 std r6,savesrr0(r13) ; Save the SRR0
1793 mtcrf 0x02,r1 ; Put the features flags (that we care about) in the CR
1794 rlwinm r6,r7,(((31-MSR_BE_BIT)+(MSR_PR_BIT+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Move PR bit to BE bit
1795 and r8,r6,r8 ; Remove BE bit only if problem state and special tracing on
1796 std r9,saver9(r13) ; Save this one
1797 andc r7,r7,r8 ; Clear BE bit if special trace is on and PR is set
1798 crmove featAltivec,pfAltivecb ; Set the Altivec flag
1799 std r7,savesrr1(r13) ; Save SRR1
1800 mfsprg r9,3 ; Get rupt time R11
1801 std r10,saver10(r13) ; Save this one
1802 mfsprg r6,2 ; Get interrupt time R13
1803 std r9,saver11(r13) ; Save rupt time R11
1804 mtsprg 2,r1 ; Set the feature flags
1805 std r12,saver12(r13) ; Save this one
1806 mflr r4 ; Get the LR
1807 mftb r7 ; Get the timebase
1808 std r6,saver13(r13) ; Save rupt R13
1809 std r7,ruptStamp(r2) ; Save the time stamp
1810 std r7,SAVtime(r13) ; Save the time stamp
1811
1812 bf++ wasNapping,notNappingSF ; Skip if not waking up from nap...
1813
1814 ld r6,napStamp(r2) ; Pick up nap stamp
1815 lis r3,hi16(EXT(machine_idle_ret)) ; Get high part of nap/doze return
1816 sub r7,r7,r6 ; Subtract stamp from now
1817 ld r6,napTotal(r2) ; Pick up total
1818 add r6,r6,r7 ; Add low to total
1819 ori r3,r3,lo16(EXT(machine_idle_ret)) ; Get low part of nap/doze return
1820 std r6,napTotal(r2) ; Save the high total
1821 std r3,savesrr0(r13) ; Modify to return to nap/doze exit
d7e50217 1822
55e303ae
A
1823notNappingSF:
1824 std r14,saver14(r13) ; Save this one
1825 std r15,saver15(r13) ; Save this one
1826 stw r0,savecr(r13) ; Save rupt CR
1827 mfctr r6 ; Get the CTR
1828 std r16,saver16(r13) ; Save this one
1829 std r4,savelr(r13) ; Save rupt LR
1830
1831 std r17,saver17(r13) ; Save this one
1832 li r7,savepmc ; Point to pmc area
1833 std r18,saver18(r13) ; Save this one
1834 lwz r17,spcFlags(r2) ; Get the special flags from per_proc
1835 std r6,savectr(r13) ; Save rupt CTR
1836 std r19,saver19(r13) ; Save this one
1837 mfdar r6 ; Get the rupt DAR
1838 std r20,saver20(r13) ; Save this one
1839
1840 dcbz128 r7,r13 ; Clear out the pmc spot
1841
1842 std r21,saver21(r13) ; Save this one
1843 std r5,savexer(r13) ; Save the rupt XER
1844 std r22,saver22(r13) ; Save this one
1845 std r23,saver23(r13) ; Save this one
1846 std r24,saver24(r13) ; Save this one
1847 std r25,saver25(r13) ; Save this one
1848 mfdsisr r7 ; Get the rupt DSISR
1849 std r26,saver26(r13) ; Save this one
1850 andis. r17,r17,hi16(perfMonitor) ; Is the performance monitor enabled?
1851 std r27,saver27(r13) ; Save this one
1852 li r10,emfp0 ; Point to floating point save
1853 std r28,saver28(r13) ; Save this one
1854 la r27,savevscr(r13) ; point to 32-byte line with VSCR and FPSCR
1855 std r29,saver29(r13) ; Save R29
1856 std r30,saver30(r13) ; Save this one
1857 std r31,saver31(r13) ; Save this one
1858 std r6,savedar(r13) ; Save the rupt DAR
1859 stw r7,savedsisr(r13) ; Save the rupt code DSISR
1860 stw r11,saveexception(r13) ; Save the exception code
1861
1862 beq++ noPerfMonSave64 ; Performance monitor not on...
1863
1864 li r22,0 ; r22: zero
1865
1866 mfspr r23,mmcr0_gp
1867 mfspr r24,mmcr1_gp
1868 mfspr r25,mmcra_gp
1869 std r23,savemmcr0(r13) ; Save MMCR0
1870 std r24,savemmcr1(r13) ; Save MMCR1
1871 std r25,savemmcr2(r13) ; Save MMCRA
1872 mtspr mmcr0_gp,r22 ; Leave MMCR0 clear
1873 mtspr mmcr1_gp,r22 ; Leave MMCR1 clear
1874 mtspr mmcra_gp,r22 ; Leave MMCRA clear
1875 mfspr r23,pmc1_gp
1876 mfspr r24,pmc2_gp
1877 mfspr r25,pmc3_gp
1878 mfspr r26,pmc4_gp
1879 stw r23,savepmc+0(r13) ; Save PMC1
1880 stw r24,savepmc+4(r13) ; Save PMC2
1881 stw r25,savepmc+8(r13) ; Save PMC3
1882 stw r26,savepmc+12(r13) ; Save PMC4
1883 mfspr r23,pmc5_gp
1884 mfspr r24,pmc6_gp
1885 mfspr r25,pmc7_gp
1886 mfspr r26,pmc8_gp
1887 stw r23,savepmc+16(r13) ; Save PMC5
1888 stw r24,savepmc+20(r13) ; Save PMC6
1889 stw r25,savepmc+24(r13) ; Save PMC7
1890 stw r26,savepmc+28(r13) ; Save PMC8
1891 mtspr pmc1_gp,r22 ; Leave PMC1 clear
1892 mtspr pmc2_gp,r22 ; Leave PMC2 clear
1893 mtspr pmc3_gp,r22 ; Leave PMC3 clear
1894 mtspr pmc4_gp,r22 ; Leave PMC4 clear
1895 mtspr pmc5_gp,r22 ; Leave PMC5 clear
1896 mtspr pmc6_gp,r22 ; Leave PMC6 clear
1897 mtspr pmc7_gp,r22 ; Leave PMC7 clear
1898 mtspr pmc8_gp,r22 ; Leave PMC8 clear
1899
1900noPerfMonSave64:
1c79356b 1901
9bccf70c
A
1902;
1903; Everything is saved at this point, except for FPRs, and VMX registers.
1904; Time for us to get a new savearea and then trace interrupt if it is enabled.
1905;
1906
55e303ae 1907 lwz r25,traceMask(0) ; Get the trace mask
9bccf70c 1908 li r0,SAVgeneral ; Get the savearea type value
55e303ae 1909 lhz r19,PP_CPU_NUMBER(r2) ; Get the logical processor number
9bccf70c 1910 stb r0,SAVflags+2(r13) ; Mark valid context
9bccf70c 1911 rlwinm r22,r11,30,0,31 ; Divide interrupt code by 2
55e303ae 1912 li r23,trcWork ; Get the trace work area address
9bccf70c 1913 addi r22,r22,10 ; Adjust code so we shift into CR5
de355530 1914 li r26,0x8 ; Get start of cpu mask
55e303ae 1915 rlwnm r7,r25,r22,22,22 ; Set CR5_EQ bit position to 0 if tracing allowed
9bccf70c
A
1916 srw r26,r26,r19 ; Get bit position of cpu number
1917 mtcrf 0x04,r7 ; Set CR5 to show trace or not
1918 and. r26,r26,r25 ; See if we trace this cpu
9bccf70c 1919 crandc cr5_eq,cr5_eq,cr0_eq ; Turn off tracing if cpu is disabled
9bccf70c 1920
55e303ae 1921 bne++ cr5,xcp64xit ; Skip all of this if no tracing here...
1c79356b 1922
9bccf70c
A
1923;
1924; We select a trace entry using a compare and swap on the next entry field.
1925; Since we do not lock the actual trace buffer, there is a potential that
1926; another processor could wrap an trash our entry. Who cares?
1927;
1c79356b 1928
55e303ae
A
1929 lwz r25,traceStart(0) ; Get the start of trace table
1930 lwz r26,traceEnd(0) ; Get end of trace table
1931
1932trcselSF: lwarx r20,0,r23 ; Get and reserve the next slot to allocate
1c79356b 1933
9bccf70c
A
1934 addi r22,r20,LTR_size ; Point to the next trace entry
1935 cmplw r22,r26 ; Do we need to wrap the trace table?
b36670ce 1936 bne++ gotTrcEntSF ; No wrap, we got us a trace entry...
1c79356b 1937
9bccf70c
A
1938 mr r22,r25 ; Wrap back to start
1939
55e303ae
A
1940gotTrcEntSF:
1941 stwcx. r22,0,r23 ; Try to update the current pointer
1942 bne- trcselSF ; Collision, try again...
1c79356b
A
1943
1944#if ESPDEBUG
9bccf70c
A
1945 dcbf 0,r23 ; Force to memory
1946 sync
1c79356b 1947#endif
1c79356b 1948
9bccf70c
A
1949;
1950; Let us cut that trace entry now.
b36670ce
A
1951;
1952; Note that this code cuts a trace table entry for everything but the CutTrace call.
1953; An identical entry is made during normal CutTrace processing. Any entry
1954; format changes made must be done in both places.
9bccf70c 1955;
1c79356b 1956
55e303ae 1957 dcbz128 0,r20 ; Zap the trace entry
1c79356b 1958
a3d08fcd
A
1959 lwz r9,SAVflags(r13) ; Get savearea flags
1960
55e303ae
A
1961 ld r16,ruptStamp(r2) ; Get top of time base
1962 ld r0,saver0(r13) ; Get back interrupt time R0 (we need this whether we trace or not)
1963 std r16,LTR_timeHi(r20) ; Set the upper part of TB
1964 ld r1,saver1(r13) ; Get back interrupt time R1
a3d08fcd 1965 rlwinm r9,r9,20,16,23 ; Isolate the special flags
55e303ae 1966 ld r18,saver2(r13) ; Get back interrupt time R2
91447636 1967 std r0,LTR_r0(r20) ; Save off register 0
a3d08fcd 1968 rlwimi r9,r19,0,24,31 ; Slide in the cpu number
55e303ae 1969 ld r3,saver3(r13) ; Restore this one
a3d08fcd 1970 sth r9,LTR_cpu(r20) ; Stash the cpu number and special flags
55e303ae
A
1971 std r1,LTR_r1(r20) ; Save off register 1
1972 ld r4,saver4(r13) ; Restore this one
1973 std r18,LTR_r2(r20) ; Save off register 2
1974 ld r5,saver5(r13) ; Restore this one
1975 ld r6,saver6(r13) ; Get R6
1976 std r3,LTR_r3(r20) ; Save off register 3
9bccf70c 1977 lwz r16,savecr(r13) ; Get the CR value
55e303ae 1978 std r4,LTR_r4(r20) ; Save off register 4
9bccf70c 1979 mfsrr0 r17 ; Get SRR0 back, it is still good
55e303ae
A
1980 std r5,LTR_r5(r20) ; Save off register 5
1981 std r6,LTR_r6(r20) ; Save off register 6
9bccf70c
A
1982 mfsrr1 r18 ; SRR1 is still good in here
1983 stw r16,LTR_cr(r20) ; Save the CR
55e303ae
A
1984 std r17,LTR_srr0(r20) ; Save the SSR0
1985 std r18,LTR_srr1(r20) ; Save the SRR1
1986
9bccf70c 1987 mfdar r17 ; Get this back
55e303ae
A
1988 ld r16,savelr(r13) ; Get the LR
1989 std r17,LTR_dar(r20) ; Save the DAR
9bccf70c 1990 mfctr r17 ; Get the CTR (still good in register)
55e303ae
A
1991 std r16,LTR_lr(r20) ; Save the LR
1992 std r17,LTR_ctr(r20) ; Save off the CTR
1993 mfdsisr r17 ; Get the DSISR
1994 std r13,LTR_save(r20) ; Save the savearea
1995 stw r17,LTR_dsisr(r20) ; Save the DSISR
9bccf70c 1996 sth r11,LTR_excpt(r20) ; Save the exception type
b36670ce
A
1997#if 0
1998 lwz r17,FPUowner(r2) ; (TEST/DEBUG) Get the current floating point owner
1999 stw r17,LTR_rsvd0(r20) ; (TEST/DEBUG) Record the owner
2000#endif
55e303ae 2001
1c79356b 2002#if ESPDEBUG
55e303ae
A
2003 dcbf 0,r20 ; Force to memory
2004 sync ; Make sure it all goes
1c79356b 2005#endif
55e303ae
A
2006xcp64xit: mr r14,r11 ; Save the interrupt code across the call
2007 bl EXT(save_get_phys_64) ; Grab a savearea
2008 mfsprg r2,0 ; Get the per_proc info
2009 li r10,emfp0 ; Point to floating point save
2010 mr r11,r14 ; Get the exception code back
2011 dcbz128 r10,r2 ; Clear for speed
2012 std r3,next_savearea(r2) ; Store the savearea for the next rupt
2013 b xcpCommon ; Go join the common interrupt processing...
d7e50217 2014
d7e50217 2015;
55e303ae
A
2016; All of the context is saved. Now we will get a
2017; fresh savearea. After this we can take an interrupt.
2018;
2019
2020 .align 5
2021
2022xcpCommon:
2023
2024;
2025; Here we will save some floating point and vector status
2026; and we also set a clean default status for a new interrupt level.
2027; Note that we assume that emfp0 is on an altivec boundary
2028; and that R10 points to it (as a displacemnt from R2).
2029;
2030; We need to save the FPSCR as if it is normal context.
2031; This is because pending exceptions will cause an exception even if
2032; FP is disabled. We need to clear the FPSCR when we first start running in the
2033; kernel.
2034;
2035
2036 stfd f0,emfp0(r2) ; Save FPR0
2037 stfd f1,emfp1(r2) ; Save FPR1
2038 li r19,0 ; Assume no Altivec
2039 mffs f0 ; Get the FPSCR
2040 lfd f1,Zero(0) ; Make a 0
2041 stfd f0,savefpscrpad(r13) ; Save the FPSCR
2042 li r9,0 ; Get set to clear VRSAVE
2043 mtfsf 0xFF,f1 ; Clear it
2044 addi r14,r10,16 ; Displacement to second vector register
2045 lfd f0,emfp0(r2) ; Restore FPR0
2046 la r28,savevscr(r13) ; Point to the status area
2047 lfd f1,emfp1(r2) ; Restore FPR1
2048
2049 bf featAltivec,noavec ; No Altivec on this CPU...
2050
2051 stvxl v0,r10,r2 ; Save a register
2052 stvxl v1,r14,r2 ; Save a second register
2053 mfspr r19,vrsave ; Get the VRSAVE register
2054 mfvscr v0 ; Get the vector status register
2055 vspltish v1,1 ; Turn on the non-Java bit and saturate
2056 stvxl v0,0,r28 ; Save the vector status
2057 vspltisw v0,1 ; Turn on the saturate bit
2058 vxor v1,v1,v0 ; Turn off saturate
2059 mtvscr v1 ; Set the non-java, no saturate status for new level
2060 mtspr vrsave,r9 ; Clear VRSAVE for each interrupt level
2061
2062 lvxl v0,r10,r2 ; Restore first work register
2063 lvxl v1,r14,r2 ; Restore second work register
2064
2065noavec: stw r19,savevrsave(r13) ; Save the vector register usage flags
2066
2067;
2068; We are now done saving all of the context. Start filtering the interrupts.
2069; Note that a Redrive will count as an actual interrupt.
2070; Note also that we take a lot of system calls so we will start decode here.
d7e50217
A
2071;
2072
55e303ae
A
2073Redrive:
2074
2075
2076#if INSTRUMENT
2077 mfspr r20,pmc1 ; INSTRUMENT - saveinstr[4] - Take stamp before exception filter
2078 stw r20,0x6100+(0x04*16)+0x0(0) ; INSTRUMENT - Save it
2079 mfspr r20,pmc2 ; INSTRUMENT - Get stamp
2080 stw r20,0x6100+(0x04*16)+0x4(0) ; INSTRUMENT - Save it
2081 mfspr r20,pmc3 ; INSTRUMENT - Get stamp
2082 stw r20,0x6100+(0x04*16)+0x8(0) ; INSTRUMENT - Save it
2083 mfspr r20,pmc4 ; INSTRUMENT - Get stamp
2084 stw r20,0x6100+(0x04*16)+0xC(0) ; INSTRUMENT - Save it
2085#endif
2086 lwz r22,SAVflags(r13) ; Pick up the flags
2087 lwz r0,saver0+4(r13) ; Get back interrupt time syscall number
2088 mfsprg r2,0 ; Restore per_proc
2089
91447636 2090 lwz r20,lo16(xcpTable)(r11) ; Get the interrupt handler (note: xcpTable must be in 1st 32k of physical memory)
55e303ae 2091 la r12,hwCounts(r2) ; Point to the exception count area
a3d08fcd 2092 andis. r24,r22,hi16(SAVeat) ; Should we eat this one?
55e303ae
A
2093 rlwinm r22,r22,SAVredriveb+1,31,31 ; Get a 1 if we are redriving
2094 add r12,r12,r11 ; Point to the count
55e303ae
A
2095 lwz r25,0(r12) ; Get the old value
2096 lwz r23,hwRedrives(r2) ; Get the redrive count
a3d08fcd 2097 crmove cr3_eq,cr0_eq ; Remember if we are ignoring
55e303ae
A
2098 xori r24,r22,1 ; Get the NOT of the redrive
2099 mtctr r20 ; Point to the interrupt handler
9bccf70c 2100 mtcrf 0x80,r0 ; Set our CR0 to the high nybble of possible syscall code
55e303ae 2101 add r25,r25,r24 ; Count this one if not a redrive
91447636 2102 add r23,r23,r22 ; Count this one if if is a redrive
de355530 2103 crandc cr0_lt,cr0_lt,cr0_gt ; See if we have R0 equal to 0b10xx...x
55e303ae
A
2104 stw r25,0(r12) ; Store it back
2105 stw r23,hwRedrives(r2) ; Save the redrive count
a3d08fcd 2106 bne-- cr3,IgnoreRupt ; Interruption is being ignored...
55e303ae
A
2107 bctr ; Go process the exception...
2108
2109
2110;
91447636 2111; Exception vector filter table (like everything in this file, must be in 1st 32KB of physical memory)
55e303ae
A
2112;
2113
2114 .align 7
2115
2116xcpTable:
2117 .long EatRupt ; T_IN_VAIN
2118 .long PassUpTrap ; T_RESET
2119 .long MachineCheck ; T_MACHINE_CHECK
2120 .long EXT(handlePF) ; T_DATA_ACCESS
2121 .long EXT(handlePF) ; T_INSTRUCTION_ACCESS
2122 .long PassUpRupt ; T_INTERRUPT
2123 .long EXT(AlignAssist) ; T_ALIGNMENT
2124 .long EXT(Emulate) ; T_PROGRAM
2125 .long PassUpFPU ; T_FP_UNAVAILABLE
2126 .long PassUpRupt ; T_DECREMENTER
2127 .long PassUpTrap ; T_IO_ERROR
2128 .long PassUpTrap ; T_RESERVED
2129 .long xcpSyscall ; T_SYSTEM_CALL
2130 .long PassUpTrap ; T_TRACE
2131 .long PassUpTrap ; T_FP_ASSIST
2132 .long PassUpTrap ; T_PERF_MON
2133 .long PassUpVMX ; T_VMX
2134 .long PassUpTrap ; T_INVALID_EXCP0
2135 .long PassUpTrap ; T_INVALID_EXCP1
2136 .long PassUpTrap ; T_INVALID_EXCP2
2137 .long PassUpTrap ; T_INSTRUCTION_BKPT
2138 .long PassUpRupt ; T_SYSTEM_MANAGEMENT
2139 .long EXT(AltivecAssist) ; T_ALTIVEC_ASSIST
2140 .long PassUpRupt ; T_THERMAL
2141 .long PassUpTrap ; T_INVALID_EXCP5
2142 .long PassUpTrap ; T_INVALID_EXCP6
2143 .long PassUpTrap ; T_INVALID_EXCP7
2144 .long PassUpTrap ; T_INVALID_EXCP8
2145 .long PassUpTrap ; T_INVALID_EXCP9
2146 .long PassUpTrap ; T_INVALID_EXCP10
2147 .long PassUpTrap ; T_INVALID_EXCP11
2148 .long PassUpTrap ; T_INVALID_EXCP12
2149 .long PassUpTrap ; T_INVALID_EXCP13
2150
2151 .long PassUpTrap ; T_RUNMODE_TRACE
2152
2153 .long PassUpRupt ; T_SIGP
2154 .long PassUpTrap ; T_PREEMPT
2155 .long conswtch ; T_CSWITCH
2156 .long PassUpRupt ; T_SHUTDOWN
2157 .long PassUpAbend ; T_CHOKE
2158
2159 .long EXT(handleDSeg) ; T_DATA_SEGMENT
2160 .long EXT(handleISeg) ; T_INSTRUCTION_SEGMENT
2161
2162 .long WhoaBaby ; T_SOFT_PATCH
2163 .long WhoaBaby ; T_MAINTENANCE
2164 .long WhoaBaby ; T_INSTRUMENTATION
a3d08fcd
A
2165 .long WhoaBaby ; T_ARCHDEP0
2166 .long EatRupt ; T_HDEC
55e303ae 2167;
91447636
A
2168; Just what the heck happened here????
2169; NB: also get here from UFT dispatch table, on bogus index
55e303ae 2170;
55e303ae
A
2171
2172WhoaBaby: b . ; Open the hood and wait for help
2173
a3d08fcd
A
2174 .align 5
2175
2176IgnoreRupt:
2177 lwz r20,hwIgnored(r2) ; Grab the ignored interruption count
2178 addi r20,r20,1 ; Count this one
2179 stw r20,hwIgnored(r2) ; Save the ignored count
2180 b EatRupt ; Ignore it...
2181
2182
55e303ae
A
2183
2184;
2185; System call
2186;
2187
2188 .align 5
2189
2190xcpSyscall: lis r20,hi16(EXT(shandler)) ; Assume this is a normal one, get handler address
2191 rlwinm r6,r0,1,0,31 ; Move sign bit to the end
2192 ori r20,r20,lo16(EXT(shandler)) ; Assume this is a normal one, get handler address
2193 bnl++ cr0,PassUp ; R0 not 0b10xxx...x, can not be any kind of magical system call, just pass it up...
2194 lwz r7,savesrr1+4(r13) ; Get the entering MSR (low half)
2195 lwz r1,dgFlags(0) ; Get the flags
9bccf70c 2196 cmplwi cr2,r6,1 ; See if original R0 had the CutTrace request code in it
1c79356b 2197
1c79356b 2198 rlwinm. r7,r7,0,MSR_PR_BIT,MSR_PR_BIT ; Did we come from user state?
55e303ae 2199 beq++ FCisok ; From supervisor state...
1c79356b 2200
1c79356b 2201 rlwinm. r1,r1,0,enaUsrFCallb,enaUsrFCallb ; Are they valid?
55e303ae 2202 beq++ PassUp ; No, treat as a normal one...
1c79356b 2203
55e303ae 2204FCisok: beq++ cr2,EatRupt ; This is a CutTrace system call, we are done with it...
1c79356b 2205
9bccf70c
A
2206;
2207; Here is where we call the firmware. If it returns T_IN_VAIN, that means
2208; that it has handled the interruption. Remember: thou shalt not trash R13
55e303ae 2209; while you are away. Anything else is ok.
9bccf70c
A
2210;
2211
55e303ae
A
2212 lwz r3,saver3+4(r13) ; Restore the first parameter
2213 b EXT(FirmwareCall) ; Go handle the firmware call....
1c79356b 2214
9bccf70c 2215;
55e303ae 2216; Here is where we return from the firmware call
9bccf70c 2217;
1c79356b 2218
55e303ae
A
2219 .align 5
2220 .globl EXT(FCReturn)
1c79356b 2221
55e303ae
A
2222LEXT(FCReturn)
2223 cmplwi r3,T_IN_VAIN ; Was it handled?
91447636 2224 beq++ EatRupt ; Interrupt was handled...
55e303ae
A
2225 mr r11,r3 ; Put the rupt code into the right register
2226 b Redrive ; Go through the filter again...
2227
9bccf70c 2228
de355530 2229;
55e303ae 2230; Here is where we return from the PTE miss and segment exception handler
de355530 2231;
9bccf70c 2232
de355530 2233 .align 5
55e303ae 2234 .globl EXT(PFSExit)
1c79356b 2235
55e303ae 2236LEXT(PFSExit)
1c79356b 2237
55e303ae
A
2238#if 0
2239 mfsprg r2,0 ; (BRINGUP)
2240 lwz r0,savedsisr(r13) ; (BRINGUP)
2241 andis. r0,r0,hi16(dsiAC) ; (BRINGUP)
2242 beq++ didnthit ; (BRINGUP)
2243 lwz r0,20(0) ; (BRINGUP)
2244 mr. r0,r0 ; (BRINGUP)
2245 bne-- didnthit ; (BRINGUP)
2246#if 0
2247 li r0,1 ; (BRINGUP)
2248 stw r0,20(0) ; (BRINGUP)
2249 lis r0,hi16(Choke) ; (BRINGUP)
2250 ori r0,r0,lo16(Choke) ; (BRINGUP)
2251 sc ; (BRINGUP)
2252#endif
2253
2254 lwz r4,savesrr0+4(r13) ; (BRINGUP)
2255 lwz r8,savesrr1+4(r13) ; (BRINGUP)
2256 lwz r6,savedar+4(r13) ; (BRINGUP)
2257 rlwinm. r0,r8,0,MSR_IR_BIT,MSR_IR_BIT ; (BRINGUP)
2258 mfmsr r9 ; (BRINGUP)
2259 ori r0,r9,lo16(MASK(MSR_DR)) ; (BRINGUP)
2260 beq-- hghg ; (BRINGUP)
2261 mtmsr r0 ; (BRINGUP)
2262 isync ; (BRINGUP)
2263
2264hghg: lwz r5,0(r4) ; (BRINGUP)
2265 beq-- hghg1 ; (BRINGUP)
2266 mtmsr r9 ; (BRINGUP)
2267 isync ; (BRINGUP)
2268
2269hghg1: rlwinm r7,r5,6,26,31 ; (BRINGUP)
2270 rlwinm r27,r5,14,24,28 ; (BRINGUP)
2271 addi r3,r13,saver0+4 ; (BRINGUP)
2272 lwzx r3,r3,r27 ; (BRINGUP)
2273
2274#if 0
2275 lwz r27,patcharea+4(r2) ; (BRINGUP)
2276 mr. r3,r3 ; (BRINGUP)
2277 bne++ nbnbnb ; (BRINGUP)
2278 addi r27,r27,1 ; (BRINGUP)
2279 stw r27,patcharea+4(r2) ; (BRINGUP)
2280nbnbnb:
2281#endif
2282
2283 rlwinm. r28,r8,0,MSR_DR_BIT,MSR_DR_BIT ; (BRINGUP)
2284 rlwinm r27,r6,0,0,29 ; (BRINGUP)
2285 ori r28,r9,lo16(MASK(MSR_DR)) ; (BRINGUP)
2286 mfspr r10,dabr ; (BRINGUP)
2287 li r0,0 ; (BRINGUP)
2288 mtspr dabr,r0 ; (BRINGUP)
2289 cmplwi cr1,r7,31 ; (BRINGUP)
2290 beq-- qqq0 ; (BRINGUP)
2291 mtmsr r28 ; (BRINGUP)
2292qqq0:
2293 isync ; (BRINGUP)
2294
2295 lwz r27,0(r27) ; (BRINGUP) - Get original value
2296
2297 bne cr1,qqq1 ; (BRINGUP)
2298
2299 rlwinm r5,r5,31,22,31 ; (BRINGUP)
2300 cmplwi cr1,r5,151 ; (BRINGUP)
2301 beq cr1,qqq3 ; (BRINGUP)
2302 cmplwi cr1,r5,407 ; (BRINGUP)
2303 beq cr1,qqq2 ; (BRINGUP)
2304 cmplwi cr1,r5,215 ; (BRINGUP)
2305 beq cr1,qqq0q ; (BRINGUP)
2306 cmplwi cr1,r5,1014 ; (BRINGUP)
2307 beq cr1,qqqm1 ; (BRINGUP)
2308
2309 lis r0,hi16(Choke) ; (BRINGUP)
2310 ori r0,r0,lo16(Choke) ; (BRINGUP)
2311 sc ; (BRINGUP)
2312
2313qqqm1: rlwinm r7,r6,0,0,26 ; (BRINGUP)
2314 stw r0,0(r7) ; (BRINGUP)
2315 stw r0,4(r7) ; (BRINGUP)
2316 stw r0,8(r7) ; (BRINGUP)
2317 stw r0,12(r7) ; (BRINGUP)
2318 stw r0,16(r7) ; (BRINGUP)
2319 stw r0,20(r7) ; (BRINGUP)
2320 stw r0,24(r7) ; (BRINGUP)
2321 stw r0,28(r7) ; (BRINGUP)
2322 b qqq9
2323
2324qqq1: cmplwi r7,38 ; (BRINGUP)
2325 bgt qqq2 ; (BRINGUP)
2326 blt qqq3 ; (BRINGUP)
9bccf70c 2327
55e303ae
A
2328qqq0q: stb r3,0(r6) ; (BRINGUP)
2329 b qqq9 ; (BRINGUP)
2330
2331qqq2: sth r3,0(r6) ; (BRINGUP)
2332 b qqq9 ; (BRINGUP)
2333
2334qqq3: stw r3,0(r6) ; (BRINGUP)
2335
2336qqq9:
2337#if 0
2338 rlwinm r7,r6,0,0,29 ; (BRINGUP)
2339 lwz r0,0(r7) ; (BRINGUP) - Get newest value
2340#else
2341 lis r7,hi16(0x000792B8) ; (BRINGUP)
2342 ori r7,r7,lo16(0x000792B8) ; (BRINGUP)
2343 lwz r0,0(r7) ; (BRINGUP) - Get newest value
2344#endif
2345 mtmsr r9 ; (BRINGUP)
2346 mtspr dabr,r10 ; (BRINGUP)
2347 isync ; (BRINGUP)
1c79356b 2348
55e303ae
A
2349#if 0
2350 lwz r28,patcharea+12(r2) ; (BRINGUP)
2351 mr. r28,r28 ; (BRINGUP)
2352 bne++ qqq12 ; (BRINGUP)
2353 lis r28,0x4000 ; (BRINGUP)
2354
2355qqq12: stw r27,0(r28) ; (BRINGUP)
2356 lwz r6,savedar+4(r13) ; (BRINGUP)
2357 stw r0,4(r28) ; (BRINGUP)
2358 stw r4,8(r28) ; (BRINGUP)
2359 stw r6,12(r28) ; (BRINGUP)
2360 addi r28,r28,16 ; (BRINGUP)
2361 mr. r3,r3 ; (BRINGUP)
2362 stw r28,patcharea+12(r2) ; (BRINGUP)
2363 lwz r10,patcharea+8(r2) ; (BRINGUP)
2364 lwz r0,patcharea+4(r2) ; (BRINGUP)
2365#endif
1c79356b 2366
55e303ae
A
2367#if 1
2368 stw r0,patcharea(r2) ; (BRINGUP)
2369#endif
de355530 2370
55e303ae
A
2371#if 0
2372 xor r28,r0,r27 ; (BRINGUP) - See how much it changed
2373 rlwinm r28,r28,24,24,31 ; (BRINGUP)
2374 cmplwi r28,1 ; (BRINGUP)
2375
2376 ble++ qqq10 ; (BRINGUP)
2377
2378 mr r7,r0 ; (BRINGUP)
2379 li r0,1 ; (BRINGUP)
2380 stw r0,20(0) ; (BRINGUP)
2381 lis r0,hi16(Choke) ; (BRINGUP)
2382 ori r0,r0,lo16(Choke) ; (BRINGUP)
2383 sc ; (BRINGUP)
2384#endif
de355530 2385
de355530 2386
55e303ae
A
2387qqq10: addi r4,r4,4 ; (BRINGUP)
2388 stw r4,savesrr0+4(r13) ; (BRINGUP)
2389
2390 li r11,T_IN_VAIN ; (BRINGUP)
2391 b EatRupt ; (BRINGUP)
2392
2393didnthit: ; (BRINGUP)
2394#endif
2395#if 0
2396 lwz r0,20(0) ; (BRINGUP)
2397 mr. r0,r0 ; (BRINGUP)
2398 beq++ opopop ; (BRINGUP)
2399 li r0,0 ; (BRINGUP)
2400 stw r0,20(0) ; (BRINGUP)
2401 lis r0,hi16(Choke) ; (BRINGUP)
2402 ori r0,r0,lo16(Choke) ; (BRINGUP)
2403 sc ; (BRINGUP)
2404opopop:
2405#endif
2406 lwz r0,savesrr1+4(r13) ; Get the MSR in use at exception time
2407 cmplwi cr1,r11,T_IN_VAIN ; Was it handled?
d7e50217 2408 rlwinm. r4,r0,0,MSR_PR_BIT,MSR_PR_BIT ; Are we trapping from supervisor state?
55e303ae
A
2409 beq++ cr1,EatRupt ; Yeah, just blast back to the user...
2410 beq-- NoFamPf
2411 mfsprg r2,0 ; Get back per_proc
d7e50217
A
2412 lwz r1,spcFlags(r2) ; Load spcFlags
2413 rlwinm r1,r1,1+FamVMmodebit,30,31 ; Extract FamVMenabit and FamVMmodebit
2414 cmpi cr0,r1,2 ; Check FamVMena set without FamVMmode
55e303ae 2415 bne-- cr0,NoFamPf
d7e50217 2416 lwz r6,FAMintercept(r2) ; Load exceptions mask to intercept
55e303ae 2417 li r5,0 ; Clear
d7e50217 2418 srwi r1,r11,2 ; divide r11 by 4
55e303ae 2419 oris r5,r5,0x8000 ; Set r5 to 0x80000000
d7e50217
A
2420 srw r1,r5,r1 ; Set bit for current exception
2421 and. r1,r1,r6 ; And current exception with the intercept mask
55e303ae
A
2422 beq++ NoFamPf ; Is it FAM intercept
2423 bl EXT(vmm_fam_pf)
d7e50217 2424 b EatRupt
55e303ae
A
2425
2426NoFamPf: andi. r4,r0,lo16(MASK(MSR_RI)) ; See if the recover bit is on
2427 lis r0,0x8000 ; Get 0xFFFFFFFF80000000
2428 add r0,r0,r0 ; Get 0xFFFFFFFF00000000
2429 beq++ PassUpTrap ; Not on, normal case...
9bccf70c
A
2430;
2431; Here is where we handle the "recovery mode" stuff.
2432; This is set by an emulation routine to trap any faults when it is fetching data or
2433; instructions.
2434;
2435; If we get a fault, we turn off RI, set CR0_EQ to false, bump the PC, and set R0
2436; and R1 to the DAR and DSISR, respectively.
2437;
55e303ae
A
2438 lwz r3,savesrr0(r13) ; Get the failing instruction address
2439 lwz r4,savesrr0+4(r13) ; Get the failing instruction address
1c79356b 2440 lwz r5,savecr(r13) ; Get the condition register
55e303ae
A
2441 or r4,r4,r0 ; Fill the high part with foxes
2442 lwz r0,savedar(r13) ; Get the DAR
2443 addic r4,r4,4 ; Skip failing instruction
2444 lwz r6,savedar+4(r13) ; Get the DAR
2445 addze r3,r3 ; Propagate carry
1c79356b 2446 rlwinm r5,r5,0,3,1 ; Clear CR0_EQ to let emulation code know we failed
9bccf70c 2447 lwz r7,savedsisr(r13) ; Grab the DSISR
55e303ae
A
2448 stw r3,savesrr0(r13) ; Save resume address
2449 stw r4,savesrr0+4(r13) ; Save resume address
9bccf70c 2450 stw r5,savecr(r13) ; And the resume CR
55e303ae
A
2451 stw r0,saver0(r13) ; Pass back the DAR
2452 stw r6,saver0+4(r13) ; Pass back the DAR
2453 stw r7,saver1+4(r13) ; Pass back the DSISR
1c79356b
A
2454 b EatRupt ; Resume emulated code
2455
9bccf70c
A
2456;
2457; Here is where we handle the context switch firmware call. The old
55e303ae
A
2458; context has been saved. The new savearea is in kind of hokey, the high order
2459; half is stored in saver7 and the low half is in saver3. We will just
9bccf70c
A
2460; muck around with the savearea pointers, and then join the exit routine
2461;
2462
2463 .align 5
2464
2465conswtch:
55e303ae 2466 li r0,0xFFF ; Get page boundary
9bccf70c 2467 mr r29,r13 ; Save the save
55e303ae
A
2468 andc r30,r13,r0 ; Round down to page boundary (64-bit safe)
2469 lwz r5,saver3+4(r13) ; Switch to the new savearea
2470 bf-- pf64Bitb,xcswNo64 ; Not 64-bit...
2471 lwz r6,saver7+4(r13) ; Get the high order half
2472 sldi r6,r6,32 ; Position high half
2473 or r5,r5,r6 ; Merge them
2474
2475xcswNo64: lwz r30,SACvrswap+4(r30) ; get real to virtual translation
9bccf70c 2476 mr r13,r5 ; Switch saveareas
55e303ae 2477 li r0,0 ; Clear this
9bccf70c 2478 xor r27,r29,r30 ; Flip to virtual
55e303ae
A
2479 stw r0,saver3(r5) ; Push the new virtual savearea to the switch to routine
2480 stw r27,saver3+4(r5) ; Push the new virtual savearea to the switch to routine
9bccf70c 2481 b EatRupt ; Start it up...
1c79356b
A
2482
2483;
2484; Handle machine check here.
2485;
91447636 2486; ?
1c79356b 2487;
9bccf70c
A
2488
2489 .align 5
2490
1c79356b 2491MachineCheck:
9bccf70c 2492
91447636 2493 bt++ pf64Bitb,mck64 ; ?
d7e50217 2494
55e303ae 2495 lwz r27,savesrr1+4(r13) ; Pick up srr1
1c79356b 2496
1c79356b 2497;
de355530
A
2498; Check if the failure was in
2499; ml_probe_read. If so, this is expected, so modify the PC to
2500; ml_proble_read_mck and then eat the exception.
1c79356b 2501;
55e303ae 2502 lwz r30,savesrr0+4(r13) ; Get the failing PC
de355530
A
2503 lis r28,hi16(EXT(ml_probe_read_mck)) ; High order part
2504 lis r27,hi16(EXT(ml_probe_read)) ; High order part
2505 ori r28,r28,lo16(EXT(ml_probe_read_mck)) ; Get the low part
2506 ori r27,r27,lo16(EXT(ml_probe_read)) ; Get the low part
2507 cmplw r30,r28 ; Check highest possible
2508 cmplw cr1,r30,r27 ; Check lowest
55e303ae
A
2509 bge- PassUpTrap ; Outside of range
2510 blt- cr1,PassUpTrap ; Outside of range
2511;
2512; We need to fix up the BATs here because the probe
2513; routine messed them all up... As long as we are at it,
2514; fix up to return directly to caller of probe.
2515;
2516
2517 lis r11,hi16(EXT(shadow_BAT)+shdDBAT) ; Get shadow address
2518 ori r11,r11,lo16(EXT(shadow_BAT)+shdDBAT) ; Get shadow address
2519
2520 lwz r30,0(r11) ; Pick up DBAT 0 high
2521 lwz r28,4(r11) ; Pick up DBAT 0 low
2522 lwz r27,8(r11) ; Pick up DBAT 1 high
2523 lwz r18,16(r11) ; Pick up DBAT 2 high
2524 lwz r11,24(r11) ; Pick up DBAT 3 high
2525
2526 sync
2527 mtdbatu 0,r30 ; Restore DBAT 0 high
2528 mtdbatl 0,r28 ; Restore DBAT 0 low
2529 mtdbatu 1,r27 ; Restore DBAT 1 high
2530 mtdbatu 2,r18 ; Restore DBAT 2 high
2531 mtdbatu 3,r11 ; Restore DBAT 3 high
2532 sync
2533
2534 lwz r28,savelr+4(r13) ; Get return point
2535 lwz r27,saver0+4(r13) ; Get the saved MSR
2536 li r30,0 ; Get a failure RC
2537 stw r28,savesrr0+4(r13) ; Set the return point
2538 stw r27,savesrr1+4(r13) ; Set the continued MSR
2539 stw r30,saver3+4(r13) ; Set return code
2540 b EatRupt ; Yum, yum, eat it all up...
2541
2542;
2543; 64-bit machine checks
2544;
2545
2546mck64:
2547
2548;
2549; NOTE: WE NEED TO RETHINK RECOVERABILITY A BIT - radar 3167190
2550;
2551
2552 ld r23,savesrr0(r13) ; Grab the SRR0 in case we need bad instruction
2553 ld r20,savesrr1(r13) ; Grab the SRR1 so we can decode the thing
2554 lwz r21,savedsisr(r13) ; We might need this in a bit
2555 ld r22,savedar(r13) ; We might need this in a bit
2556
2557 lis r8,AsyMCKSrc ; Get the Async MCK Source register address
2558 mfsprg r19,2 ; Get the feature flags
2559 ori r8,r8,0x8000 ; Set to read data
2560 rlwinm. r0,r19,0,pfSCOMFixUpb,pfSCOMFixUpb ; Do we need to fix the SCOM data?
2561
2562 sync
2563
2564 mtspr scomc,r8 ; Request the MCK source
2565 mfspr r24,scomd ; Get the source
2566 mfspr r8,scomc ; Get back the status (we just ignore it)
2567 sync
2568 isync
2569
2570 lis r8,AsyMCKRSrc ; Get the Async MCK Source AND mask address
2571 li r9,0 ; Get and AND mask of 0
2572
2573 sync
2574
2575 mtspr scomd,r9 ; Set the AND mask to 0
2576 mtspr scomc,r8 ; Write the AND mask and clear conditions
2577 mfspr r8,scomc ; Get back the status (we just ignore it)
2578 sync
2579 isync
2580
2581 lis r8,cFIR ; Get the Core FIR register address
2582 ori r8,r8,0x8000 ; Set to read data
2583
2584 sync
2585
2586 mtspr scomc,r8 ; Request the Core FIR
2587 mfspr r25,scomd ; Get the source
2588 mfspr r8,scomc ; Get back the status (we just ignore it)
2589 sync
2590 isync
2591
2592 lis r8,cFIRrst ; Get the Core FIR AND mask address
2593
2594 sync
2595
2596 mtspr scomd,r9 ; Set the AND mask to 0
2597 mtspr scomc,r8 ; Write the AND mask and clear conditions
2598 mfspr r8,scomc ; Get back the status (we just ignore it)
2599 sync
2600 isync
e5568f75
A
2601
2602 lis r8,l2FIR ; Get the L2 FIR register address
2603 ori r8,r8,0x8000 ; Set to read data
2604
2605 sync
2606
2607 mtspr scomc,r8 ; Request the L2 FIR
2608 mfspr r26,scomd ; Get the source
2609 mfspr r8,scomc ; Get back the status (we just ignore it)
2610 sync
2611 isync
2612
2613 lis r8,l2FIRrst ; Get the L2 FIR AND mask address
2614
2615 sync
2616
2617 mtspr scomd,r9 ; Set the AND mask to 0
2618 mtspr scomc,r8 ; Write the AND mask and clear conditions
2619 mfspr r8,scomc ; Get back the status (we just ignore it)
2620 sync
2621 isync
2622
2623 lis r8,busFIR ; Get the Bus FIR register address
2624 ori r8,r8,0x8000 ; Set to read data
2625
2626 sync
2627
2628 mtspr scomc,r8 ; Request the Bus FIR
2629 mfspr r27,scomd ; Get the source
2630 mfspr r8,scomc ; Get back the status (we just ignore it)
2631 sync
2632 isync
2633
2634 lis r8,busFIRrst ; Get the Bus FIR AND mask address
2635
2636 sync
2637
2638 mtspr scomd,r9 ; Set the AND mask to 0
2639 mtspr scomc,r8 ; Write the AND mask and clear conditions
2640 mfspr r8,scomc ; Get back the status (we just ignore it)
2641 sync
2642 isync
55e303ae
A
2643
2644; Note: bug in early chips where scom reads are shifted right by 1. We fix that here.
2645; Also note that we will lose bit 63
2646
2647 beq++ mckNoFix ; No fix up is needed
2648 sldi r24,r24,1 ; Shift left 1
2649 sldi r25,r25,1 ; Shift left 1
e5568f75
A
2650 sldi r26,r26,1 ; Shift left 1
2651 sldi r27,r27,1 ; Shift left 1
55e303ae 2652
e5568f75
A
2653mckNoFix: std r24,savexdat0(r13) ; Save the MCK source in case we pass the error
2654 std r25,savexdat1(r13) ; Save the Core FIR in case we pass the error
2655 std r26,savexdat2(r13) ; Save the L2 FIR in case we pass the error
2656 std r27,savexdat3(r13) ; Save the BUS FIR in case we pass the error
55e303ae
A
2657
2658 rlwinm. r0,r20,0,mckIFUE-32,mckIFUE-32 ; Is this some kind of uncorrectable?
2659 bne mckUE ; Yeah...
2660
2661 rlwinm. r0,r20,0,mckLDST-32,mckLDST-32 ; Some kind of load/store error?
2662 bne mckHandleLDST ; Yes...
2663
2664 rldicl. r0,r20,46,62 ; Get the error cause code
2665 beq mckNotSure ; We need some more checks for this one...
2666
2667 cmplwi r0,2 ; Check for TLB parity error
2668 blt mckSLBparity ; This is an SLB parity error...
2669 bgt mckhIFUE ; This is an IFetch tablewalk reload UE...
2670
2671; IFetch TLB parity error
2672
2673 isync
2674 tlbiel r23 ; Locally invalidate TLB entry for iaddr
2675 sync ; Wait for it
e5568f75 2676 b ceMck ; All recovered...
55e303ae
A
2677
2678; SLB parity error. This could be software caused. We get one if there is
2679; more than 1 valid SLBE with a matching ESID. That one we do not want to
2680; try to recover from. Search for it and if we get it, panic.
2681
2682mckSLBparity:
2683 crclr cr0_eq ; Make sure we are not equal so we take correct exit
2684
2685 la r3,emvr0(r2) ; Use this to keep track of valid ESIDs we find
2686 li r5,0 ; Start with index 0
2687
2688mckSLBck: la r4,emvr0(r2) ; Use this to keep track of valid ESIDs we find
2689 slbmfee r6,r5 ; Get the next SLBE
2690 andis. r0,r6,0x0800 ; See if valid bit is on
2691 beq mckSLBnx ; Skip invalid and go to next
2692
2693mckSLBck2: cmpld r4,r3 ; Have we reached the end of the table?
2694 beq mckSLBne ; Yes, go enter this one...
2695 ld r7,0(r4) ; Pick up the saved ESID
2696 cmpld r6,r7 ; Is this a match?
2697 beq mckSLBrec ; Whoops, I did bad, recover and pass up...
2698 addi r4,r4,8 ; Next table entry
2699 b mckSLBck2 ; Check the next...
2700
2701mckSLBnx: addi r5,r5,1 ; Point to next SLBE
2702 cmplwi r5,64 ; Have we checked all of them?
2703 bne++ mckSLBck ; Not yet, check again...
2704 b mckSLBrec ; We looked at them all, go recover...
2705
2706mckSLBne: std r6,0(r3) ; Save this ESID
2707 addi r3,r3,8 ; Point to the new slot
2708 b mckSLBnx ; Go do the next SLBE...
2709
2710; Recover an SLB error
2711
2712mckSLBrec: li r0,0 ; Set an SLB slot index of 0
2713 slbia ; Trash all SLB entries (except for entry 0 that is)
2714 slbmfee r7,r0 ; Get the entry that is in SLB index 0
2715 rldicr r7,r7,0,35 ; Clear the valid bit and the rest
2716 slbie r7 ; Invalidate it
2717
2718 li r3,0 ; Set the first SLBE
2719
2720mckSLBclr: slbmte r0,r3 ; Clear the whole entry to 0s
2721 addi r3,r3,1 ; Bump index
2722 cmplwi cr1,r3,64 ; Have we done them all?
2723 bne++ cr1,mckSLBclr ; Yup....
2724
2725 sth r3,ppInvSeg(r2) ; Store non-zero to trigger SLB reload
e5568f75
A
2726 bne++ ceMck ; This was not a programming error, all recovered...
2727 b ueMck ; Pass the software error up...
55e303ae
A
2728
2729;
2730; Handle a load/store unit error. We need to decode the DSISR
2731;
2732
2733mckHandleLDST:
2734 rlwinm. r0,r21,0,mckL1DCPE,mckL1DCPE ; An L1 data cache parity error?
2735 bne++ mckL1D ; Yeah, we dealt with this back in the vector...
2736
2737 rlwinm. r0,r21,0,mckL1DTPE,mckL1DTPE ; An L1 tag error?
2738 bne++ mckL1T ; Yeah, we dealt with this back in the vector...
2739
2740 rlwinm. r0,r21,0,mckUEdfr,mckUEdfr ; Is the a "deferred" UE?
2741 bne mckDUE ; Yeah, go see if expected...
2742
2743 rlwinm. r0,r21,0,mckUETwDfr,mckUETwDfr ; Is the a "deferred" tablewalk UE?
2744 bne mckDTW ; Yeah, no recovery...
2745
2746 rlwinm. r0,r21,0,mckSLBPE,mckSLBPE ; SLB parity error?
2747 bne mckSLBparity ; Yeah, go attempt recovery....
2748
2749; This is a recoverable D-ERAT or TLB error
2750
2751 la r9,hwMckERCPE(r2) ; Get DERAT parity error count
2752
2753mckInvDAR: isync
2754 tlbiel r22 ; Locally invalidate the TLB entry
2755 sync
2756
2757 lwz r21,0(r9) ; Get count
2758 addi r21,r21,1 ; Count this one
2759 stw r21,0(r9) ; Stick it back
2760
e5568f75 2761 b ceMck ; All recovered...
55e303ae
A
2762
2763;
2764; When we come here, we are not quite sure what the error is. We need to
2765; dig a bit further.
2766;
2767; R24 is interrupt source
2768; R25 is Core FIR
2769;
2770; Note that both have been cleared already.
2771;
2772
2773mckNotSure:
2774 rldicl. r0,r24,AsyMCKfir+1,63 ; Something in the FIR?
2775 bne-- mckFIR ; Yup, go check some more...
2776
2777 rldicl. r0,r24,AsyMCKhri+1,63 ; Hang recovery?
2778 bne-- mckHangRcvr ; Yup...
2779
2780 rldicl. r0,r24,AsyMCKext+1,63 ; External signal?
2781 bne-- mckExtMck ; Yup...
2782
2783;
2784; We really do not know what this one is or what to do with it...
2785;
2786
2787mckUnk: lwz r21,hwMckUnk(r2) ; Get unknown error count
2788 addi r21,r21,1 ; Count it
2789 stw r21,hwMckUnk(r2) ; Stuff it
e5568f75 2790 b ueMck ; Go south, young man...
55e303ae
A
2791
2792;
2793; Hang recovery. This is just a notification so we only count.
2794;
2795
2796mckHangRcrvr:
2797 lwz r21,hwMckHang(r2) ; Get hang recovery count
2798 addi r21,r21,1 ; Count this one
2799 stw r21,hwMckHang(r2) ; Stick it back
e5568f75 2800 b ceMck ; All recovered...
55e303ae
A
2801
2802;
2803; Externally signaled MCK. No recovery for the moment, but we this may be
2804; where we handle ml_probe_read problems eventually.
2805;
2806mckExtMck:
2807 lwz r21,hwMckHang(r2) ; Get hang recovery count
2808 addi r21,r21,1 ; Count this one
2809 stw r21,hwMckHang(r2) ; Stick it back
e5568f75 2810 b ceMck ; All recovered...
55e303ae
A
2811
2812;
2813; Machine check cause is in a FIR. Suss it out here.
2814; Core FIR is in R25 and has been cleared in HW.
2815;
2816
2817mckFIR: rldicl. r0,r25,cFIRICachePE+1,63 ; I-Cache parity error?
2818 la r19,hwMckICachePE(r2) ; Point to counter
2819 bne mckInvICache ; Go invalidate I-Cache...
2820
2821 rldicl. r0,r25,cFIRITagPE0+1,63 ; I-Cache tag parity error?
2822 la r19,hwMckITagPE(r2) ; Point to counter
2823 bne mckInvICache ; Go invalidate I-Cache...
2824
2825 rldicl. r0,r25,cFIRITagPE1+1,63 ; I-Cache tag parity error?
2826 la r19,hwMckITagPE(r2) ; Point to counter
2827 bne mckInvICache ; Go invalidate I-Cache...
2828
2829 rldicl. r0,r25,cFIRIEratPE+1,63 ; IERAT parity error?
2830 la r19,hwMckIEratPE(r2) ; Point to counter
2831 bne mckInvERAT ; Go invalidate ERATs...
2832
2833 rldicl. r0,r25,cFIRIFUL2UE+1,63 ; IFetch got L2 UE?
2834 bne mckhIFUE ; Go count and pass up...
2835
2836 rldicl. r0,r25,cFIRDCachePE+1,63 ; D-Cache PE?
2837 bne mckL1D ; Handled, just go count...
2838
2839 rldicl. r0,r25,cFIRDTagPE+1,63 ; D-Cache tag PE?
2840 bne mckL1T ; Handled, just go count...
2841
2842 rldicl. r0,r25,cFIRDEratPE+1,63 ; DERAT PE?
2843 la r19,hwMckDEratPE(r2) ; Point to counter
2844 bne mckInvERAT ; Go invalidate ERATs...
2845
2846 rldicl. r0,r25,cFIRTLBPE+1,63 ; TLB PE?
2847 la r9,hwMckTLBPE(r2) ; Get TLB parity error count
2848 bne mckInvDAR ; Go recover...
2849
2850 rldicl. r0,r25,cFIRSLBPE+1,63 ; SLB PE?
2851 bne mckSLBparity ; Cope with it...
2852
2853 b mckUnk ; Have not a clue...
2854
de355530 2855;
55e303ae 2856; General recovery for I-Cache errors. Just flush it completely.
de355530 2857;
55e303ae
A
2858
2859 .align 7 ; Force into cache line
2860
2861mckInvICache:
2862 lis r0,0x0080 ; Get a 0x0080 (bit 9 >> 32)
2863 mfspr r21,hid1 ; Get the current HID1
2864 sldi r0,r0,32 ; Get the "forced ICBI match" bit
2865 or r0,r0,r21 ; Set forced match
de355530 2866
55e303ae
A
2867 isync
2868 mtspr hid1,r0 ; Stick it
2869 mtspr hid1,r0 ; Stick it again
2870 isync
2871
2872 li r6,0 ; Start at 0
1c79356b 2873
55e303ae
A
2874mckIcbi: icbi 0,r6 ; Kill I$
2875 addi r6,r6,128 ; Next line
2876 andis. r5,r6,1 ; Have we done them all?
2877 beq++ mckIcbi ; Not yet...
de355530 2878
de355530 2879 isync
55e303ae
A
2880 mtspr hid1,r21 ; Restore original HID1
2881 mtspr hid1,r21 ; Stick it again
2882 isync
2883
2884 lwz r5,0(r19) ; Get the counter
2885 addi r5,r5,1 ; Count it
2886 stw r5,0(r19) ; Stuff it back
e5568f75 2887 b ceMck ; All recovered...
55e303ae
A
2888
2889
2890; General recovery for ERAT problems - handled in exception vector already
de355530 2891
55e303ae
A
2892mckInvERAT: lwz r21,0(r19) ; Get the exception count spot
2893 addi r21,r21,1 ; Count this one
2894 stw r21,0(r19) ; Save count
e5568f75 2895 b ceMck ; All recovered...
55e303ae
A
2896
2897; General hang recovery - this is a notification only, just count.
2898
2899mckHangRcvr:
2900 lwz r21,hwMckHang(r2) ; Get hang recovery count
2901 addi r21,r21,1 ; Count this one
2902 stw r21,hwMckHang(r2) ; Stick it back
e5568f75 2903 b ceMck ; All recovered...
55e303ae
A
2904
2905
2906;
2907; These are the uncorrectable errors, just count them then pass it along.
2908;
2909
2910mckUE: lwz r21,hwMckUE(r2) ; Get general uncorrectable error count
2911 addi r21,r21,1 ; Count it
2912 stw r21,hwMckUE(r2) ; Stuff it
e5568f75 2913 b ueMck ; Go south, young man...
55e303ae
A
2914
2915mckhIFUE: lwz r21,hwMckIUEr(r2) ; Get I-Fetch TLB reload uncorrectable error count
2916 addi r21,r21,1 ; Count it
2917 stw r21,hwMckIUEr(r2) ; Stuff it
e5568f75 2918 b ueMck ; Go south, young man...
55e303ae
A
2919
2920mckDUE: lwz r21,hwMckDUE(r2) ; Get deferred uncorrectable error count
2921 addi r21,r21,1 ; Count it
2922 stw r21,hwMckDUE(r2) ; Stuff it
2923
2924;
2925; Right here is where we end up after a failure on a ml_probe_read_64.
2926; We will check if that is the case, and if so, fix everything up and
2927; return from it.
2928
2929 lis r8,hi16(EXT(ml_probe_read_64)) ; High of start
2930 lis r9,hi16(EXT(ml_probe_read_mck_64)) ; High of end
2931 ori r8,r8,lo16(EXT(ml_probe_read_64)) ; Low of start
2932 ori r9,r9,lo16(EXT(ml_probe_read_mck_64)) ; Low of end
2933 cmpld r23,r8 ; Too soon?
2934 cmpld cr1,r23,r9 ; Too late?
2935
e5568f75 2936 cror cr0_lt,cr0_lt,cr1_gt ; Too soon or too late?
55e303ae
A
2937 ld r3,saver12(r13) ; Get the original MSR
2938 ld r5,savelr(r13) ; Get the return address
2939 li r4,0 ; Get fail code
e5568f75 2940 blt-- ueMck ; This is a normal machine check, just pass up...
55e303ae
A
2941 std r5,savesrr0(r13) ; Set the return MSR
2942
2943 std r3,savesrr1(r13) ; Set the return address
2944 std r4,saver3(r13) ; Set failure return code
e5568f75 2945 b ceMck ; All recovered...
55e303ae
A
2946
2947mckDTW: lwz r21,hwMckDTW(r2) ; Get deferred tablewalk uncorrectable error count
2948 addi r21,r21,1 ; Count it
2949 stw r21,hwMckDTW(r2) ; Stuff it
e5568f75 2950 b ueMck ; Go south, young man...
55e303ae
A
2951
2952mckL1D: lwz r21,hwMckL1DPE(r2) ; Get data cache parity error count
2953 addi r21,r21,1 ; Count it
2954 stw r21,hwMckL1DPE(r2) ; Stuff it
e5568f75 2955 b ceMck ; All recovered...
55e303ae
A
2956
2957mckL1T: lwz r21,hwMckL1TPE(r2) ; Get TLB parity error count
2958 addi r21,r21,1 ; Count it
2959 stw r21,hwMckL1TPE(r2) ; Stuff it
e5568f75 2960
91447636
A
2961ceMck: lwz r21,mckFlags(0) ; Get the flags
2962 li r0,1 ; Set the recovered flag before passing up
2963 rlwinm. r21,r21,0,31,31 ; Check if we want to log recoverables
e5568f75 2964 stw r0,savemisc3(r13) ; Set it
91447636 2965 beq++ EatRupt ; No log of recoverables wanted...
e5568f75
A
2966 b PassUpTrap ; Go up and log error...
2967
2968ueMck: li r0,0 ; Set the unrecovered flag before passing up
2969 stw r0,savemisc3(r13) ; Set it
2970 b PassUpTrap ; Go up and log error and probably panic
55e303ae 2971
1c79356b
A
2972
2973/*
2974 * Here's where we come back from some instruction emulator. If we come back with
2975 * T_IN_VAIN, the emulation is done and we should just reload state and directly
2976 * go back to the interrupted code. Otherwise, we'll check to see if
2977 * we need to redrive with a different interrupt, i.e., DSI.
55e303ae
A
2978 * Note that this we are actually not redriving the rupt, rather changing it
2979 * into a different one. Thus we clear the redrive bit.
1c79356b
A
2980 */
2981
2982 .align 5
2983 .globl EXT(EmulExit)
2984
2985LEXT(EmulExit)
2986
55e303ae 2987 cmplwi cr1,r11,T_IN_VAIN ; Was it emulated?
1c79356b 2988 lis r1,hi16(SAVredrive) ; Get redrive request
55e303ae 2989 beq++ cr1,EatRupt ; Yeah, just blast back to the user...
1c79356b
A
2990 lwz r4,SAVflags(r13) ; Pick up the flags
2991
2992 and. r0,r4,r1 ; Check if redrive requested
1c79356b 2993
55e303ae 2994 beq++ PassUpTrap ; No redrive, just keep on going...
1c79356b 2995
1c79356b
A
2996 b Redrive ; Redrive the exception...
2997
9bccf70c
A
2998;
2999; Jump into main handler code switching on VM at the same time.
3000;
3001; We assume kernel data is mapped contiguously in physical
3002; memory, otherwise we would need to switch on (at least) virtual data.
3003; SRs are already set up.
3004;
55e303ae
A
3005
3006 .align 5
3007
3008PassUpTrap: lis r20,hi16(EXT(thandler)) ; Get thandler address
3009 ori r20,r20,lo16(EXT(thandler)) ; Get thandler address
3010 b PassUp ; Go pass it up...
3011
3012PassUpRupt: lis r20,hi16(EXT(ihandler)) ; Get ihandler address
3013 ori r20,r20,lo16(EXT(ihandler)) ; Get ihandler address
3014 b PassUp ; Go pass it up...
3015
3016 .align 5
3017
3018PassUpFPU: lis r20,hi16(EXT(fpu_switch)) ; Get FPU switcher address
3019 ori r20,r20,lo16(EXT(fpu_switch)) ; Get FPU switcher address
3020 b PassUp ; Go pass it up...
3021
3022PassUpVMX: lis r20,hi16(EXT(vec_switch)) ; Get VMX switcher address
3023 ori r20,r20,lo16(EXT(vec_switch)) ; Get VMX switcher address
3024 bt++ featAltivec,PassUp ; We have VMX on this CPU...
3025 li r11,T_PROGRAM ; Say that it is a program exception
3026 li r20,8 ; Set invalid instruction
3027 stw r11,saveexception(r13) ; Set the new the exception code
3028 sth r20,savesrr1+4(r13) ; Set the invalid instruction SRR code
3029
3030 b PassUpTrap ; Go pass it up...
3031
d7e50217 3032 .align 5
55e303ae
A
3033
3034PassUpAbend:
3035 lis r20,hi16(EXT(chandler)) ; Get choke handler address
3036 ori r20,r20,lo16(EXT(chandler)) ; Get choke handler address
3037 b PassUp ; Go pass it up...
9bccf70c 3038
55e303ae 3039 .align 5
d7e50217 3040
55e303ae
A
3041PassUp:
3042#if INSTRUMENT
3043 mfspr r29,pmc1 ; INSTRUMENT - saveinstr[11] - Take stamp at passup or eatrupt
3044 stw r29,0x6100+(11*16)+0x0(0) ; INSTRUMENT - Save it
3045 mfspr r29,pmc2 ; INSTRUMENT - Get stamp
3046 stw r29,0x6100+(11*16)+0x4(0) ; INSTRUMENT - Save it
3047 mfspr r29,pmc3 ; INSTRUMENT - Get stamp
3048 stw r29,0x6100+(11*16)+0x8(0) ; INSTRUMENT - Save it
3049 mfspr r29,pmc4 ; INSTRUMENT - Get stamp
3050 stw r29,0x6100+(11*16)+0xC(0) ; INSTRUMENT - Save it
3051#endif
de355530 3052
55e303ae
A
3053 lwz r10,SAVflags(r13) ; Pick up the flags
3054
3055 li r0,0xFFF ; Get a page mask
3056 li r2,MASK(MSR_BE)|MASK(MSR_SE) ; Get the mask to save trace bits
3057 andc r5,r13,r0 ; Back off to the start of savearea block
9bccf70c 3058 mfmsr r3 ; Get our MSR
55e303ae
A
3059 rlwinm r10,r10,0,SAVredriveb+1,SAVredriveb-1 ; Clear the redrive before we pass it up
3060 li r21,MSR_SUPERVISOR_INT_OFF ; Get our normal MSR value
3061 and r3,r3,r2 ; Clear all but trace
3062 lwz r5,SACvrswap+4(r5) ; Get real to virtual conversion
3063 or r21,r21,r3 ; Keep the trace bits if they are on
3064 stw r10,SAVflags(r13) ; Set the flags with the cleared redrive flag
91447636 3065
9bccf70c 3066 xor r4,r13,r5 ; Pass up the virtual address of context savearea
55e303ae
A
3067 mfsprg r29,0 ; Get the per_proc block back
3068 rlwinm r4,r4,0,0,31 ; Clean top half of virtual savearea if 64-bit
3069
3070 mr r3,r21 ; Pass in the MSR we will go to
3071 bl EXT(switchSegs) ; Go handle the segment registers/STB
3072
3073#if INSTRUMENT
3074 mfspr r30,pmc1 ; INSTRUMENT - saveinstr[7] - Take stamp afer switchsegs
3075 stw r30,0x6100+(7*16)+0x0(0) ; INSTRUMENT - Save it
3076 mfspr r30,pmc2 ; INSTRUMENT - Get stamp
3077 stw r30,0x6100+(7*16)+0x4(0) ; INSTRUMENT - Save it
3078 mfspr r30,pmc3 ; INSTRUMENT - Get stamp
3079 stw r30,0x6100+(7*16)+0x8(0) ; INSTRUMENT - Save it
3080 mfspr r30,pmc4 ; INSTRUMENT - Get stamp
3081 stw r30,0x6100+(7*16)+0xC(0) ; INSTRUMENT - Save it
3082#endif
3083 lwz r3,saveexception(r13) ; Recall the exception code
3084
3085 mtsrr0 r20 ; Set up the handler address
3086 mtsrr1 r21 ; Set up our normal MSR value
9bccf70c 3087
55e303ae 3088 bt++ pf64Bitb,puLaunch ; Handle 64-bit machine...
de355530 3089
55e303ae
A
3090 rfi ; Launch the exception handler
3091
3092puLaunch: rfid ; Launch the exception handler
1c79356b
A
3093
3094/*
55e303ae
A
3095 * This routine is the main place where we return from an interruption.
3096 *
3097 * This is also where we release the quickfret list. These are saveareas
3098 * that were released as part of the exception exit path in hw_exceptions.
3099 * In order to save an atomic operation (which actually will not work
3100 * properly on a 64-bit machine) we use holdQFret to indicate that the list
3101 * is in flux and should not be looked at here. This comes into play only
3102 * when we take a PTE miss when we are queuing a savearea onto qfret.
3103 * Quite rare but could happen. If the flag is set, this code does not
3104 * release the list and waits until next time.
1c79356b
A
3105 *
3106 * All we need to remember here is that R13 must point to the savearea
3107 * that has the context we need to load up. Translation and interruptions
3108 * must be disabled.
3109 *
3110 * This code always loads the context in the savearea pointed to
3111 * by R13. In the process, it throws away the savearea. If there
3112 * is any tomfoolery with savearea stacks, it must be taken care of
3113 * before we get here.
3114 *
1c79356b
A
3115 */
3116
3117 .align 5
3118
9bccf70c
A
3119EatRupt: mfsprg r29,0 ; Get the per_proc block back
3120 mr r31,r13 ; Move the savearea pointer to the far end of the register set
55e303ae 3121 mfsprg r27,2 ; Get the processor features
9bccf70c 3122
55e303ae 3123 lwz r3,holdQFret(r29) ; Get the release hold off flag
d7e50217 3124
55e303ae
A
3125 bt++ pf64Bitb,eat64a ; Skip down to the 64-bit version of this
3126
3127;
3128; This starts the 32-bit version
3129;
3130
3131 mr. r3,r3 ; Should we hold off the quick release?
3132 lwz r30,quickfret+4(r29) ; Pick up the quick fret list, if any
3133 la r21,saver0(r31) ; Point to the first thing we restore
3134 bne- ernoqfret ; Hold off set, do not release just now...
9bccf70c
A
3135
3136erchkfret: mr. r3,r30 ; Any savearea to quickly release?
3137 beq+ ernoqfret ; No quickfrets...
55e303ae 3138 lwz r30,SAVprev+4(r30) ; Chain back now
9bccf70c
A
3139
3140 bl EXT(save_ret_phys) ; Put it on the free list
55e303ae 3141 stw r30,quickfret+4(r29) ; Dequeue previous guy (really, it is ok to wait until after the release)
9bccf70c 3142 b erchkfret ; Try the next one...
1c79356b 3143
9bccf70c
A
3144 .align 5
3145
55e303ae
A
3146ernoqfret:
3147#if INSTRUMENT
3148 mfspr r30,pmc1 ; INSTRUMENT - saveinstr[5] - Take stamp at saveareas released
3149 stw r30,0x6100+(5*16)+0x0(0) ; INSTRUMENT - Save it
3150 mfspr r30,pmc2 ; INSTRUMENT - Get stamp
3151 stw r30,0x6100+(5*16)+0x4(0) ; INSTRUMENT - Save it
3152 mfspr r30,pmc3 ; INSTRUMENT - Get stamp
3153 stw r30,0x6100+(5*16)+0x8(0) ; INSTRUMENT - Save it
3154 mfspr r30,pmc4 ; INSTRUMENT - Get stamp
3155 stw r30,0x6100+(5*16)+0xC(0) ; INSTRUMENT - Save it
3156#endif
de355530 3157
55e303ae 3158 dcbt 0,r21 ; Touch in the first thing we need
1c79356b 3159
1c79356b 3160;
9bccf70c 3161; Here we release the savearea.
1c79356b 3162;
9bccf70c
A
3163; Important!!!! The savearea is released before we are done with it. When the
3164; local free savearea list (anchored at lclfree) gets too long, save_ret_phys
3165; will trim the list, making the extra saveareas allocatable by another processor
3166; The code in there must ALWAYS leave our savearea on the local list, otherwise
3167; we could be very, very unhappy. The code there always queues the "just released"
3168; savearea to the head of the local list. Then, if it needs to trim, it will
3169; start with the SECOND savearea, leaving ours intact.
1c79356b 3170;
1c79356b
A
3171;
3172
9bccf70c
A
3173 mr r3,r31 ; Get the exiting savearea in parm register
3174 bl EXT(save_ret_phys) ; Put it on the free list
55e303ae
A
3175#if INSTRUMENT
3176 mfspr r3,pmc1 ; INSTRUMENT - saveinstr[6] - Take stamp afer savearea released
3177 stw r3,0x6100+(6*16)+0x0(0) ; INSTRUMENT - Save it
3178 mfspr r3,pmc2 ; INSTRUMENT - Get stamp
3179 stw r3,0x6100+(6*16)+0x4(0) ; INSTRUMENT - Save it
3180 mfspr r3,pmc3 ; INSTRUMENT - Get stamp
3181 stw r3,0x6100+(6*16)+0x8(0) ; INSTRUMENT - Save it
3182 mfspr r3,pmc4 ; INSTRUMENT - Get stamp
3183 stw r3,0x6100+(6*16)+0xC(0) ; INSTRUMENT - Save it
3184#endif
9bccf70c 3185
55e303ae
A
3186 lwz r3,savesrr1+4(r31) ; Pass in the MSR we are going to
3187 bl EXT(switchSegs) ; Go handle the segment registers/STB
3188#if INSTRUMENT
3189 mfspr r30,pmc1 ; INSTRUMENT - saveinstr[10] - Take stamp afer switchsegs
3190 stw r30,0x6100+(10*16)+0x0(0) ; INSTRUMENT - Save it
3191 mfspr r30,pmc2 ; INSTRUMENT - Get stamp
3192 stw r30,0x6100+(10*16)+0x4(0) ; INSTRUMENT - Save it
3193 mfspr r30,pmc3 ; INSTRUMENT - Get stamp
3194 stw r30,0x6100+(10*16)+0x8(0) ; INSTRUMENT - Save it
3195 mfspr r30,pmc4 ; INSTRUMENT - Get stamp
3196 stw r30,0x6100+(10*16)+0xC(0) ; INSTRUMENT - Save it
3197#endif
3198 li r3,savesrr1+4 ; Get offset to the srr1 value
9bccf70c 3199
55e303ae 3200 lhz r9,PP_CPU_FLAGS(r29) ; Get the processor flags
9bccf70c 3201 lwarx r26,r3,r31 ; Get destination MSR and take reservation along the way (just so we can blow it away)
55e303ae
A
3202
3203 rlwinm r25,r26,27,22,22 ; Move PR bit to BE
3204
1c79356b 3205 cmplw cr3,r14,r14 ; Set that we do not need to stop streams
9bccf70c 3206
55e303ae
A
3207 rlwinm r9,r9,(((31-MSR_BE_BIT)+(traceBEb+16+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Set BE bit if special trace is on
3208 li r21,emfp0 ; Point to the fp savearea
3209 and r9,r9,r25 ; Clear BE if supervisor state
3210 or r26,r26,r9 ; Flip on the BE bit for special trace if needed
3211 stwcx. r26,r3,r31 ; Blow away any reservations we hold (and set BE)
3212
3213 lwz r25,savesrr0+4(r31) ; Get the SRR0 to use
3214
3215 la r28,saver4(r31) ; Point to the 32-byte line with r4-r7
3216 dcbz r21,r29 ; Clear a work area
3217 lwz r0,saver0+4(r31) ; Restore R0
3218 dcbt 0,r28 ; Touch in r4-r7
3219 lwz r1,saver1+4(r31) ; Restore R1
3220 lwz r2,saver2+4(r31) ; Restore R2
3221 la r28,saver8(r31) ; Point to the 32-byte line with r8-r11
3222 lwz r3,saver3+4(r31) ; Restore R3
3223 andis. r6,r27,hi16(pfAltivec) ; Do we have altivec on the machine?
3224 dcbt 0,r28 ; touch in r8-r11
3225 lwz r4,saver4+4(r31) ; Restore R4
3226 la r28,saver12(r31) ; Point to the 32-byte line with r12-r15
3227 mtsrr0 r25 ; Restore the SRR0 now
3228 lwz r5,saver5+4(r31) ; Restore R5
3229 mtsrr1 r26 ; Restore the SRR1 now
3230 lwz r6,saver6+4(r31) ; Restore R6
3231
3232 dcbt 0,r28 ; touch in r12-r15
3233 la r28,saver16(r31)
3234
3235 lwz r7,saver7+4(r31) ; Restore R7
3236 lwz r8,saver8+4(r31) ; Restore R8
3237 lwz r9,saver9+4(r31) ; Restore R9
3238
3239 dcbt 0,r28 ; touch in r16-r19
3240 la r28,saver20(r31)
3241
3242 lwz r10,saver10+4(r31) ; Restore R10
3243 lwz r11,saver11+4(r31) ; Restore R11
3244
3245 dcbt 0,r28 ; touch in r20-r23
3246 la r28,savevscr(r31) ; Point to the status area
3247
3248 lwz r12,saver12+4(r31) ; Restore R12
3249 lwz r13,saver13+4(r31) ; Restore R13
9bccf70c 3250
55e303ae
A
3251 la r14,savectr+4(r31)
3252 dcbt 0,r28 ; Touch in VSCR and FPSCR
3253 dcbt 0,r14 ; touch in CTR, DAR, DSISR, VRSAVE, and Exception code
9bccf70c 3254
55e303ae
A
3255 lwz r26,next_savearea+4(r29) ; Get the exception save area
3256 la r28,saver24(r31)
9bccf70c 3257
55e303ae
A
3258 lwz r14,saver14+4(r31) ; Restore R14
3259 lwz r15,saver15+4(r31) ; Restore R15
1c79356b 3260
1c79356b 3261
55e303ae
A
3262 stfd f0,emfp0(r29) ; Save FP0
3263 lwz r27,savevrsave(r31) ; Get the vrsave
3264 dcbt 0,r28 ; touch in r24-r27
3265 la r28,savevscr(r31) ; Point to the status area
3266 lfd f0,savefpscrpad(r31) ; Get the fpscr
3267 la r22,saver28(r31)
3268 mtfsf 0xFF,f0 ; Restore fpscr
3269 lfd f0,emfp0(r29) ; Restore the used register
1c79356b 3270
55e303ae 3271 beq noavec3 ; No Altivec on this CPU...
1c79356b 3272
55e303ae
A
3273 stvxl v0,r21,r29 ; Save a vector register
3274 lvxl v0,0,r28 ; Get the vector status
3275 mtspr vrsave,r27 ; Set the vrsave
3276 mtvscr v0 ; Set the vector status
3277 lvxl v0,r21,r29 ; Restore work vector register
1c79356b 3278
55e303ae
A
3279noavec3: dcbt 0,r22 ; touch in r28-r31
3280
3281 lwz r23,spcFlags(r29) ; Get the special flags from per_proc
3282 la r17,savesrr0(r31)
3283 la r26,saver0(r26) ; Point to the first part of the next savearea
3284 dcbt 0,r17 ; touch in SRR0, SRR1, CR, XER, LR
3285 lhz r28,pfrptdProc(r29) ; Get the reported processor type
3286
3287 lwz r16,saver16+4(r31) ; Restore R16
3288 lwz r17,saver17+4(r31) ; Restore R17
3289 lwz r18,saver18+4(r31) ; Restore R18
3290 lwz r19,saver19+4(r31) ; Restore R19
3291 lwz r20,saver20+4(r31) ; Restore R20
3292 lwz r21,saver21+4(r31) ; Restore R21
3293 lwz r22,saver22+4(r31) ; Restore R22
3294
3295 cmpwi cr1,r28,CPU_SUBTYPE_POWERPC_750 ; G3?
3296
3297 dcbz 0,r26 ; Clear and allocate next savearea we use in the off chance it is still in when we next interrupt
3298
3299 andis. r23,r23,hi16(perfMonitor) ; Is the performance monitor enabled?
3300 lwz r23,saver23+4(r31) ; Restore R23
3301 cmpwi cr2,r28,CPU_SUBTYPE_POWERPC_7400 ; Yer standard G4?
3302 lwz r24,saver24+4(r31) ; Restore R24
3303 lwz r25,saver25+4(r31) ; Restore R25
3304 lwz r26,saver26+4(r31) ; Restore R26
3305 lwz r27,saver27+4(r31) ; Restore R27
3306
3307 beq+ noPerfMonRestore32 ; No perf monitor...
3308
3309 beq- cr1,perfMonRestore32_750 ; This is a G3...
3310 beq- cr2,perfMonRestore32_7400 ; Standard G4...
3311
3312 lwz r28,savepmc+16(r31)
3313 lwz r29,savepmc+20(r31)
3314 mtspr pmc5,r28 ; Restore PMC5
3315 mtspr pmc6,r29 ; Restore PMC6
3316
3317perfMonRestore32_7400:
3318 lwz r28,savemmcr2+4(r31)
3319 mtspr mmcr2,r28 ; Restore MMCR2
3320
3321perfMonRestore32_750:
3322 lwz r28,savepmc+0(r31)
3323 lwz r29,savepmc+4(r31)
3324 mtspr pmc1,r28 ; Restore PMC1
3325 mtspr pmc2,r29 ; Restore PMC2
3326 lwz r28,savepmc+8(r31)
3327 lwz r29,savepmc+12(r31)
3328 mtspr pmc3,r28 ; Restore PMC3
3329 mtspr pmc4,r29 ; Restore PMC4
3330 lwz r28,savemmcr1+4(r31)
3331 lwz r29,savemmcr0+4(r31)
3332 mtspr mmcr1,r28 ; Restore MMCR1
3333 mtspr mmcr0,r29 ; Restore MMCR0
3334
3335noPerfMonRestore32:
3336 lwz r28,savecr(r31) ; Get CR to restore
3337 lwz r29,savexer+4(r31) ; Get XER to restore
3338 mtcr r28 ; Restore the CR
3339 lwz r28,savelr+4(r31) ; Get LR to restore
3340 mtxer r29 ; Restore the XER
3341 lwz r29,savectr+4(r31) ; Get the CTR to restore
3342 mtlr r28 ; Restore the LR
3343 lwz r28,saver30+4(r31) ; Get R30
3344 mtctr r29 ; Restore the CTR
3345 lwz r29,saver31+4(r31) ; Get R31
3346 mtsprg 2,r28 ; Save R30 for later
3347 lwz r28,saver28+4(r31) ; Restore R28
3348 mtsprg 3,r29 ; Save R31 for later
3349 lwz r29,saver29+4(r31) ; Restore R29
1c79356b 3350
55e303ae
A
3351 mfsprg r31,0 ; Get per_proc
3352 mfsprg r30,2 ; Restore R30
3353 lwz r31,pfAvailable(r31) ; Get the feature flags
3354 mtsprg 2,r31 ; Set the feature flags
3355 mfsprg r31,3 ; Restore R31
1c79356b 3356
55e303ae 3357 rfi ; Click heels three times and think very hard that there is no place like home...
1c79356b 3358
55e303ae
A
3359 .long 0 ; Leave this here
3360 .long 0
3361 .long 0
3362 .long 0
3363 .long 0
3364 .long 0
3365 .long 0
3366 .long 0
1c79356b 3367
1c79356b 3368
55e303ae
A
3369;
3370; This starts the 64-bit version
3371;
1c79356b 3372
55e303ae 3373 .align 7
1c79356b 3374
55e303ae 3375eat64a: ld r30,quickfret(r29) ; Pick up the quick fret list, if any
de355530 3376
55e303ae
A
3377 mr. r3,r3 ; Should we hold off the quick release?
3378 la r21,saver0(r31) ; Point to the first thing we restore
3379 bne-- ernoqfre64 ; Hold off set, do not release just now...
1c79356b 3380
55e303ae
A
3381erchkfre64: mr. r3,r30 ; Any savearea to quickly release?
3382 beq+ ernoqfre64 ; No quickfrets...
3383 ld r30,SAVprev(r30) ; Chain back now
de355530 3384
55e303ae 3385 bl EXT(save_ret_phys) ; Put it on the free list
1c79356b 3386
55e303ae
A
3387 std r30,quickfret(r29) ; Dequeue previous guy (really, it is ok to wait until after the release)
3388 b erchkfre64 ; Try the next one...
de355530 3389
55e303ae 3390 .align 7
1c79356b 3391
55e303ae 3392ernoqfre64: dcbt 0,r21 ; Touch in the first thing we need
1c79356b 3393
55e303ae
A
3394;
3395; Here we release the savearea.
3396;
3397; Important!!!! The savearea is released before we are done with it. When the
3398; local free savearea list (anchored at lclfree) gets too long, save_ret_phys
3399; will trim the list, making the extra saveareas allocatable by another processor
3400; The code in there must ALWAYS leave our savearea on the local list, otherwise
3401; we could be very, very unhappy. The code there always queues the "just released"
3402; savearea to the head of the local list. Then, if it needs to trim, it will
3403; start with the SECOND savearea, leaving ours intact.
3404;
3405;
1c79356b 3406
55e303ae
A
3407 li r3,lgKillResv ; Get spot to kill reservation
3408 stdcx. r3,0,r3 ; Blow away any reservations we hold
de355530 3409
55e303ae
A
3410 mr r3,r31 ; Get the exiting savearea in parm register
3411 bl EXT(save_ret_phys) ; Put it on the free list
1c79356b 3412
55e303ae
A
3413 lwz r3,savesrr1+4(r31) ; Pass in the MSR we will be going to
3414 bl EXT(switchSegs) ; Go handle the segment registers/STB
9bccf70c 3415
55e303ae
A
3416 lhz r9,PP_CPU_FLAGS(r29) ; Get the processor flags
3417 ld r26,savesrr1(r31) ; Get destination MSR
3418 cmplw cr3,r14,r14 ; Set that we do not need to stop streams
3419 rlwinm r25,r26,27,22,22 ; Move PR bit to BE
d7e50217 3420
55e303ae
A
3421 rlwinm r9,r9,(((31-MSR_BE_BIT)+(traceBEb+16+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Set BE bit if special trace is on
3422 li r21,emfp0 ; Point to a workarea
3423 and r9,r9,r25 ; Clear BE if supervisor state
3424 or r26,r26,r9 ; Flip on the BE bit for special trace if needed
3425
3426 ld r25,savesrr0(r31) ; Get the SRR0 to use
3427 la r28,saver16(r31) ; Point to the 128-byte line with r16-r31
3428 dcbz128 r21,r29 ; Clear a work area
3429 ld r0,saver0(r31) ; Restore R0
3430 dcbt 0,r28 ; Touch in r16-r31
3431 ld r1,saver1(r31) ; Restore R1
3432 ld r2,saver2(r31) ; Restore R2
3433 ld r3,saver3(r31) ; Restore R3
1c79356b 3434 mtcrf 0x80,r27 ; Get facility availability flags (do not touch CR1-7)
55e303ae 3435 ld r4,saver4(r31) ; Restore R4
9bccf70c 3436 mtsrr0 r25 ; Restore the SRR0 now
55e303ae 3437 ld r5,saver5(r31) ; Restore R5
9bccf70c 3438 mtsrr1 r26 ; Restore the SRR1 now
55e303ae
A
3439 ld r6,saver6(r31) ; Restore R6
3440
3441 ld r7,saver7(r31) ; Restore R7
3442 ld r8,saver8(r31) ; Restore R8
3443 ld r9,saver9(r31) ; Restore R9
3444
3445 la r28,savevscr(r31) ; Point to the status area
3446
3447 ld r10,saver10(r31) ; Restore R10
3448 ld r11,saver11(r31) ; Restore R11
3449 ld r12,saver12(r31) ; Restore R12
3450 ld r13,saver13(r31) ; Restore R13
de355530 3451
55e303ae 3452 ld r26,next_savearea(r29) ; Get the exception save area
de355530 3453
55e303ae
A
3454 ld r14,saver14(r31) ; Restore R14
3455 ld r15,saver15(r31) ; Restore R15
3456 lwz r27,savevrsave(r31) ; Get the vrsave
3457
3458 bf-- pfAltivecb,noavec2s ; Skip if no VMX...
9bccf70c 3459
9bccf70c
A
3460 stvxl v0,r21,r29 ; Save a vector register
3461 lvxl v0,0,r28 ; Get the vector status
9bccf70c
A
3462 mtvscr v0 ; Set the vector status
3463
3464 lvxl v0,r21,r29 ; Restore work vector register
9bccf70c 3465
55e303ae 3466noavec2s: mtspr vrsave,r27 ; Set the vrsave
9bccf70c 3467
55e303ae 3468 lwz r28,saveexception(r31) ; Get exception type
1c79356b 3469 stfd f0,emfp0(r29) ; Save FP0
9bccf70c 3470 lfd f0,savefpscrpad(r31) ; Get the fpscr
1c79356b
A
3471 mtfsf 0xFF,f0 ; Restore fpscr
3472 lfd f0,emfp0(r29) ; Restore the used register
55e303ae
A
3473 ld r16,saver16(r31) ; Restore R16
3474 lwz r30,spcFlags(r29) ; Get the special flags from per_proc
3475 ld r17,saver17(r31) ; Restore R17
3476 ld r18,saver18(r31) ; Restore R18
3477 cmplwi cr1,r28,T_RESET ; Are we returning from a reset?
3478 ld r19,saver19(r31) ; Restore R19
3479 ld r20,saver20(r31) ; Restore R20
3480 li r27,0 ; Get a zero
3481 ld r21,saver21(r31) ; Restore R21
3482 la r26,saver0(r26) ; Point to the first part of the next savearea
3483 andis. r30,r30,hi16(perfMonitor) ; Is the performance monitor enabled?
3484 ld r22,saver22(r31) ; Restore R22
3485 ld r23,saver23(r31) ; Restore R23
3486 bne++ cr1,er64rrst ; We are not returning from a reset...
3487 stw r27,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_TYPE)(br0) ; Allow resets again
3488
3489er64rrst: ld r24,saver24(r31) ; Restore R24
3490
3491 dcbz128 0,r26 ; Clear and allocate next savearea we use in the off chance it is still in when we next interrupt
3492
3493 ld r25,saver25(r31) ; Restore R25
3494 ld r26,saver26(r31) ; Restore R26
3495 ld r27,saver27(r31) ; Restore R27
3496
3497 beq++ noPerfMonRestore64 ; Nope...
3498
3499 lwz r28,savepmc+0(r31)
3500 lwz r29,savepmc+4(r31)
3501 mtspr pmc1_gp,r28 ; Restore PMC1
3502 mtspr pmc2_gp,r29 ; Restore PMC2
3503 lwz r28,savepmc+8(r31)
3504 lwz r29,savepmc+12(r31)
3505 mtspr pmc3_gp,r28 ; Restore PMC3
3506 mtspr pmc4_gp,r29 ; Restore PMC4
3507 lwz r28,savepmc+16(r31)
3508 lwz r29,savepmc+20(r31)
3509 mtspr pmc5_gp,r28 ; Restore PMC5
3510 mtspr pmc6_gp,r29 ; Restore PMC6
3511 lwz r28,savepmc+24(r31)
3512 lwz r29,savepmc+28(r31)
3513 mtspr pmc7_gp,r28 ; Restore PMC7
3514 mtspr pmc8_gp,r29 ; Restore PMC8
3515 ld r28,savemmcr1(r31)
3516 ld r29,savemmcr2(r31)
3517 mtspr mmcr1_gp,r28 ; Restore MMCR1
3518 mtspr mmcra_gp,r29 ; Restore MMCRA
3519 ld r28,savemmcr0(r31)
3520
3521 mtspr mmcr0_gp,r28 ; Restore MMCR0
3522
3523noPerfMonRestore64:
3524 mfsprg r30,0 ; Get per_proc
9bccf70c 3525 lwz r28,savecr(r31) ; Get CR to restore
55e303ae 3526 ld r29,savexer(r31) ; Get XER to restore
9bccf70c 3527 mtcr r28 ; Restore the CR
55e303ae 3528 ld r28,savelr(r31) ; Get LR to restore
9bccf70c 3529 mtxer r29 ; Restore the XER
55e303ae 3530 ld r29,savectr(r31) ; Get the CTR to restore
9bccf70c 3531 mtlr r28 ; Restore the LR
55e303ae 3532 ld r28,saver30(r31) ; Get R30
9bccf70c 3533 mtctr r29 ; Restore the CTR
55e303ae
A
3534 ld r29,saver31(r31) ; Get R31
3535 mtspr hsprg0,r28 ; Save R30 for later
3536 ld r28,saver28(r31) ; Restore R28
9bccf70c 3537 mtsprg 3,r29 ; Save R31 for later
55e303ae 3538 ld r29,saver29(r31) ; Restore R29
1c79356b 3539
55e303ae 3540 lwz r31,pfAvailable(r30) ; Get the feature flags
91447636 3541 ld r30,UAW(r30) ; Get the User Assist DoubleWord
1c79356b 3542 mtsprg 2,r31 ; Set the feature flags
9bccf70c 3543 mfsprg r31,3 ; Restore R31
55e303ae
A
3544 mtsprg 3,r30 ; Set the UAW
3545 mfspr r30,hsprg0 ; Restore R30
1c79356b 3546
55e303ae 3547 rfid ; Click heels three times and think very hard that there is no place like home...
1c79356b
A
3548
3549
3550
3551/*
3552 * exception_exit(savearea *)
3553 *
3554 *
3555 * ENTRY : IR and/or DR and/or interruptions can be on
55e303ae 3556 * R3 points to the virtual address of a savearea
1c79356b
A
3557 */
3558
3559 .align 5
3560 .globl EXT(exception_exit)
3561
3562LEXT(exception_exit)
3563
3564 mfsprg r29,2 ; Get feature flags
de355530 3565 mr r31,r3 ; Get the savearea in the right register
55e303ae
A
3566 mtcrf 0x04,r29 ; Set the features
3567 li r0,1 ; Get this just in case
3568 mtcrf 0x02,r29 ; Set the features
3569 lis r30,hi16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Set up the MSR we will use throughout. Note that ME come on here if MCK
3570 rlwinm r4,r3,0,0,19 ; Round down to savearea block base
1c79356b 3571 lis r1,hi16(SAVredrive) ; Get redrive request
55e303ae
A
3572 mfsprg r2,0 ; Get the per_proc block
3573 ori r30,r30,lo16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Rest of MSR
3574 bt++ pf64Bitb,eeSixtyFour ; We are 64-bit...
3575
3576 lwz r4,SACvrswap+4(r4) ; Get the virtual to real translation
3577
1c79356b
A
3578 bt pfNoMSRirb,eeNoMSR ; No MSR...
3579
3580 mtmsr r30 ; Translation and all off
3581 isync ; Toss prefetch
3582 b eeNoMSRx
3583
55e303ae
A
3584 .align 5
3585
3586eeSixtyFour:
3587 ld r4,SACvrswap(r4) ; Get the virtual to real translation
3588 rldimi r30,r0,63,MSR_SF_BIT ; Set SF bit (bit 0)
3589 mtmsrd r30 ; Set 64-bit mode, turn off EE, DR, and IR
3590 isync ; Toss prefetch
3591 b eeNoMSRx
3592
3593 .align 5
3594
1c79356b
A
3595eeNoMSR: li r0,loadMSR ; Get the MSR setter SC
3596 mr r3,r30 ; Get new MSR
3597 sc ; Set it
3598
55e303ae 3599eeNoMSRx: xor r31,r31,r4 ; Convert the savearea to physical addressing
1c79356b
A
3600 lwz r4,SAVflags(r31) ; Pick up the flags
3601 mr r13,r31 ; Put savearea here also
3602
55e303ae
A
3603#if INSTRUMENT
3604 mfspr r5,pmc1 ; INSTRUMENT - saveinstr[8] - stamp exception exit
3605 stw r5,0x6100+(8*16)+0x0(0) ; INSTRUMENT - Save it
3606 mfspr r5,pmc2 ; INSTRUMENT - Get stamp
3607 stw r5,0x6100+(8*16)+0x4(0) ; INSTRUMENT - Save it
3608 mfspr r5,pmc3 ; INSTRUMENT - Get stamp
3609 stw r5,0x6100+(8*16)+0x8(0) ; INSTRUMENT - Save it
3610 mfspr r5,pmc4 ; INSTRUMENT - Get stamp
3611 stw r5,0x6100+(8*16)+0xC(0) ; INSTRUMENT - Save it
3612#endif
3613
3614
1c79356b 3615 and. r0,r4,r1 ; Check if redrive requested
1c79356b
A
3616
3617 dcbt br0,r2 ; We will need this in just a sec
3618
3619 beq+ EatRupt ; No redrive, just exit...
3620
91447636
A
36210: mftbu r2 ; Avoid using an obsolete timestamp for the redrive
3622 mftb r4
3623 mftbu r0
3624 cmplw r0,r2
3625 bne-- 0b
3626
3627 stw r2,SAVtime(r13)
3628 stw r4,SAVtime+4(r13)
3629
9bccf70c 3630 lwz r11,saveexception(r13) ; Restore exception code
1c79356b 3631 b Redrive ; Redrive the exception...
55e303ae
A
3632
3633
1c79356b 3634
55e303ae 3635 .align 12 ; Force page alignment
1c79356b 3636
1c79356b
A
3637 .globl EXT(ExceptionVectorsEnd)
3638EXT(ExceptionVectorsEnd): /* Used if relocating the exception vectors */
55e303ae
A
3639
3640
3641
3642
3643;
3644; Here is where we keep the low memory globals
3645;
3646
3647 . = 0x5000
55e303ae 3648
55e303ae
A
3649 .ascii "Hagfish " ; 5000 Unique eyecatcher
3650 .long 0 ; 5008 Zero
3651 .long 0 ; 500C Zero cont...
91447636
A
3652 .long EXT(PerProcTable) ; 5010 pointer to per_proc_entry table
3653 .long 0 ; 5014 Zero
3654
3655 .globl EXT(mckFlags)
3656EXT(mckFlags):
3657 .long 0 ; 5018 Machine check flags
3658
3659 .long EXT(version) ; 501C Pointer to kernel version string
3660 .long 0 ; 5020 physical memory window virtual address
3661 .long 0 ; 5024 physical memory window virtual address
3662 .long 0 ; 5028 user memory window virtual address
3663 .long 0 ; 502C user memory window virtual address
3664 .long 0 ; 5030 VMM boot-args forced feature flags
3a60a9f5
A
3665
3666 .globl EXT(maxDec)
3667EXT(maxDec):
3668 .long 0x7FFFFFFF ; 5034 maximum decrementer value
3669
3670
3671 .globl EXT(pmsCtlp)
3672EXT(pmsCtlp):
3673 .long 0 ; 5038 Pointer to power management stepper control
3674
55e303ae
A
3675 .long 0 ; 503C reserved
3676 .long 0 ; 5040 reserved
3677 .long 0 ; 5044 reserved
3678 .long 0 ; 5048 reserved
3679 .long 0 ; 504C reserved
3680 .long 0 ; 5050 reserved
3681 .long 0 ; 5054 reserved
3682 .long 0 ; 5058 reserved
3683 .long 0 ; 505C reserved
3684 .long 0 ; 5060 reserved
3685 .long 0 ; 5064 reserved
3686 .long 0 ; 5068 reserved
3687 .long 0 ; 506C reserved
3688 .long 0 ; 5070 reserved
3689 .long 0 ; 5074 reserved
3690 .long 0 ; 5078 reserved
3691 .long 0 ; 507C reserved
3692
3693 .globl EXT(trcWork)
3694EXT(trcWork):
3695 .long 0 ; 5080 The next trace entry to use
3696#if DEBUG
3697 .long 0xFFFFFFFF ; 5084 All enabled
3698#else
3699 .long 0x00000000 ; 5084 All disabled on non-debug systems
1c79356b 3700#endif
55e303ae
A
3701 .long 0 ; 5088 Start of the trace table
3702 .long 0 ; 508C End (wrap point) of the trace
3703 .long 0 ; 5090 Saved mask while in debugger
3704 .long 0 ; 5094 Size of trace table (1 - 256 pages)
3705 .long 0 ; 5098 traceGas[0]
3706 .long 0 ; 509C traceGas[1]
3707
3708 .long 0 ; 50A0 reserved
3709 .long 0 ; 50A4 reserved
3710 .long 0 ; 50A8 reserved
3711 .long 0 ; 50AC reserved
3712 .long 0 ; 50B0 reserved
3713 .long 0 ; 50B4 reserved
3714 .long 0 ; 50B8 reserved
3715 .long 0 ; 50BC reserved
3716 .long 0 ; 50C0 reserved
3717 .long 0 ; 50C4 reserved
3718 .long 0 ; 50C8 reserved
3719 .long 0 ; 50CC reserved
3720 .long 0 ; 50D0 reserved
3721 .long 0 ; 50D4 reserved
3722 .long 0 ; 50D8 reserved
3723 .long 0 ; 50DC reserved
3724 .long 0 ; 50E0 reserved
3725 .long 0 ; 50E4 reserved
3726 .long 0 ; 50E8 reserved
3727 .long 0 ; 50EC reserved
3728 .long 0 ; 50F0 reserved
3729 .long 0 ; 50F4 reserved
3730 .long 0 ; 50F8 reserved
3731 .long 0 ; 50FC reserved
3732
3733 .globl EXT(saveanchor)
3734
3735EXT(saveanchor): ; 5100 saveanchor
3736 .set .,.+SVsize
3737
3738 .long 0 ; 5140 reserved
3739 .long 0 ; 5144 reserved
3740 .long 0 ; 5148 reserved
3741 .long 0 ; 514C reserved
3742 .long 0 ; 5150 reserved
3743 .long 0 ; 5154 reserved
3744 .long 0 ; 5158 reserved
3745 .long 0 ; 515C reserved
3746 .long 0 ; 5160 reserved
3747 .long 0 ; 5164 reserved
3748 .long 0 ; 5168 reserved
3749 .long 0 ; 516C reserved
3750 .long 0 ; 5170 reserved
3751 .long 0 ; 5174 reserved
3752 .long 0 ; 5178 reserved
3753 .long 0 ; 517C reserved
3754
3755 .long 0 ; 5180 tlbieLock
3756
3757 .long 0 ; 5184 reserved
3758 .long 0 ; 5188 reserved
3759 .long 0 ; 518C reserved
3760 .long 0 ; 5190 reserved
3761 .long 0 ; 5194 reserved
3762 .long 0 ; 5198 reserved
3763 .long 0 ; 519C reserved
3764 .long 0 ; 51A0 reserved
3765 .long 0 ; 51A4 reserved
3766 .long 0 ; 51A8 reserved
3767 .long 0 ; 51AC reserved
3768 .long 0 ; 51B0 reserved
3769 .long 0 ; 51B4 reserved
3770 .long 0 ; 51B8 reserved
3771 .long 0 ; 51BC reserved
3772 .long 0 ; 51C0 reserved
3773 .long 0 ; 51C4 reserved
3774 .long 0 ; 51C8 reserved
3775 .long 0 ; 51CC reserved
3776 .long 0 ; 51D0 reserved
3777 .long 0 ; 51D4 reserved
3778 .long 0 ; 51D8 reserved
3779 .long 0 ; 51DC reserved
3780 .long 0 ; 51E0 reserved
3781 .long 0 ; 51E4 reserved
3782 .long 0 ; 51E8 reserved
3783 .long 0 ; 51EC reserved
3784 .long 0 ; 51F0 reserved
3785 .long 0 ; 51F4 reserved
3786 .long 0 ; 51F8 reserved
3787 .long 0 ; 51FC reserved
3788
3789 .globl EXT(dgWork)
3790
3791EXT(dgWork):
55e303ae
A
3792 .long 0 ; 5200 dgLock
3793 .long 0 ; 5204 dgFlags
3794 .long 0 ; 5208 dgMisc0
3795 .long 0 ; 520C dgMisc1
3796 .long 0 ; 5210 dgMisc2
3797 .long 0 ; 5214 dgMisc3
3798 .long 0 ; 5218 dgMisc4
3799 .long 0 ; 521C dgMisc5
91447636
A
3800
3801 .globl EXT(LcksOpts)
3802EXT(LcksOpts):
3803 .long 0 ; 5220 lcksWork
55e303ae
A
3804 .long 0 ; 5224 reserved
3805 .long 0 ; 5228 reserved
3806 .long 0 ; 522C reserved
3807 .long 0 ; 5230 reserved
3808 .long 0 ; 5234 reserved
3809 .long 0 ; 5238 reserved
3810 .long 0 ; 523C reserved
3811 .long 0 ; 5240 reserved
3812 .long 0 ; 5244 reserved
3813 .long 0 ; 5248 reserved
3814 .long 0 ; 524C reserved
3815 .long 0 ; 5250 reserved
3816 .long 0 ; 5254 reserved
3817 .long 0 ; 5258 reserved
3818 .long 0 ; 525C reserved
3819 .long 0 ; 5260 reserved
3820 .long 0 ; 5264 reserved
3821 .long 0 ; 5268 reserved
3822 .long 0 ; 526C reserved
3823 .long 0 ; 5270 reserved
3824 .long 0 ; 5274 reserved
3825 .long 0 ; 5278 reserved
3826 .long 0 ; 527C reserved
3827
91447636
A
3828 .globl EXT(pPcfg)
3829EXT(pPcfg):
3830 .long 0x80000000 | (12 << 8) | 12 ; 5280 pcfDefPcfg - 4k
3831 .long 0 ; 5284 pcfLargePcfg
3832 .long 0 ; 5288 Non-primary page configurations
3833 .long 0 ; 528C Non-primary page configurations
3834 .long 0 ; 5290 Non-primary page configurations
3835 .long 0 ; 5294 Non-primary page configurations
3836 .long 0 ; 5298 Non-primary page configurations
3837 .long 0 ; 529C Non-primary page configurations
3838
55e303ae
A
3839 .long 0 ; 52A0 reserved
3840 .long 0 ; 52A4 reserved
3841 .long 0 ; 52A8 reserved
3842 .long 0 ; 52AC reserved
3843 .long 0 ; 52B0 reserved
3844 .long 0 ; 52B4 reserved
3845 .long 0 ; 52B8 reserved
3846 .long 0 ; 52BC reserved
3847 .long 0 ; 52C0 reserved
3848 .long 0 ; 52C4 reserved
3849 .long 0 ; 52C8 reserved
3850 .long 0 ; 52CC reserved
3851 .long 0 ; 52D0 reserved
3852 .long 0 ; 52D4 reserved
3853 .long 0 ; 52D8 reserved
3854 .long 0 ; 52DC reserved
3855 .long 0 ; 52E0 reserved
3856 .long 0 ; 52E4 reserved
3857 .long 0 ; 52E8 reserved
3858 .long 0 ; 52EC reserved
3859 .long 0 ; 52F0 reserved
3860 .long 0 ; 52F4 reserved
3861 .long 0 ; 52F8 reserved
3862 .long 0 ; 52FC reserved
3863
3864 .globl EXT(killresv)
3865EXT(killresv):
3866
3867 .long 0 ; 5300 Used to kill reservations
3868 .long 0 ; 5304 Used to kill reservations
3869 .long 0 ; 5308 Used to kill reservations
3870 .long 0 ; 530C Used to kill reservations
3871 .long 0 ; 5310 Used to kill reservations
3872 .long 0 ; 5314 Used to kill reservations
3873 .long 0 ; 5318 Used to kill reservations
3874 .long 0 ; 531C Used to kill reservations
3875 .long 0 ; 5320 Used to kill reservations
3876 .long 0 ; 5324 Used to kill reservations
3877 .long 0 ; 5328 Used to kill reservations
3878 .long 0 ; 532C Used to kill reservations
3879 .long 0 ; 5330 Used to kill reservations
3880 .long 0 ; 5334 Used to kill reservations
3881 .long 0 ; 5338 Used to kill reservations
3882 .long 0 ; 533C Used to kill reservations
3883 .long 0 ; 5340 Used to kill reservations
3884 .long 0 ; 5344 Used to kill reservations
3885 .long 0 ; 5348 Used to kill reservations
3886 .long 0 ; 534C Used to kill reservations
3887 .long 0 ; 5350 Used to kill reservations
3888 .long 0 ; 5354 Used to kill reservations
3889 .long 0 ; 5358 Used to kill reservations
3890 .long 0 ; 535C Used to kill reservations
3891 .long 0 ; 5360 Used to kill reservations
3892 .long 0 ; 5364 Used to kill reservations
3893 .long 0 ; 5368 Used to kill reservations
3894 .long 0 ; 536C Used to kill reservations
3895 .long 0 ; 5370 Used to kill reservations
3896 .long 0 ; 5374 Used to kill reservations
3897 .long 0 ; 5378 Used to kill reservations
3898 .long 0 ; 537C Used to kill reservations
3899
3900 .long 0 ; 5380 reserved
3901 .long 0 ; 5384 reserved
3902 .long 0 ; 5388 reserved
3903 .long 0 ; 538C reserved
3904 .long 0 ; 5390 reserved
3905 .long 0 ; 5394 reserved
3906 .long 0 ; 5398 reserved
3907 .long 0 ; 539C reserved
3908 .long 0 ; 53A0 reserved
3909 .long 0 ; 53A4 reserved
3910 .long 0 ; 53A8 reserved
3911 .long 0 ; 53AC reserved
3912 .long 0 ; 53B0 reserved
3913 .long 0 ; 53B4 reserved
3914 .long 0 ; 53B8 reserved
3915 .long 0 ; 53BC reserved
3916 .long 0 ; 53C0 reserved
3917 .long 0 ; 53C4 reserved
3918 .long 0 ; 53C8 reserved
3919 .long 0 ; 53CC reserved
3920 .long 0 ; 53D0 reserved
3921 .long 0 ; 53D4 reserved
3922 .long 0 ; 53D8 reserved
3923 .long 0 ; 53DC reserved
3924 .long 0 ; 53E0 reserved
3925 .long 0 ; 53E4 reserved
3926 .long 0 ; 53E8 reserved
3927 .long 0 ; 53EC reserved
3928 .long 0 ; 53F0 reserved
3929 .long 0 ; 53F4 reserved
3930 .long 0 ; 53F8 reserved
3931 .long 0 ; 53FC reserved
a3d08fcd
A
3932 .long 0 ; 5400 reserved
3933 .long 0 ; 5404 reserved
3934 .long 0 ; 5408 reserved
3935 .long 0 ; 540C reserved
3936 .long 0 ; 5410 reserved
3937 .long 0 ; 5414 reserved
3938 .long 0 ; 5418 reserved
3939 .long 0 ; 541C reserved
3940 .long 0 ; 5420 reserved
3941 .long 0 ; 5424 reserved
3942 .long 0 ; 5428 reserved
3943 .long 0 ; 542C reserved
3944 .long 0 ; 5430 reserved
3945 .long 0 ; 5434 reserved
3946 .long 0 ; 5438 reserved
3947 .long 0 ; 543C reserved
3948 .long 0 ; 5440 reserved
3949 .long 0 ; 5444 reserved
3950 .long 0 ; 5448 reserved
3951 .long 0 ; 544C reserved
3952 .long 0 ; 5450 reserved
3953 .long 0 ; 5454 reserved
3954 .long 0 ; 5458 reserved
3955 .long 0 ; 545C reserved
3956 .long 0 ; 5460 reserved
3957 .long 0 ; 5464 reserved
3958 .long 0 ; 5468 reserved
3959 .long 0 ; 546C reserved
3960 .long 0 ; 5470 reserved
3961 .long 0 ; 5474 reserved
3962 .long 0 ; 5478 reserved
3963 .long 0 ; 547C reserved
55e303ae
A
3964;
3965; The "shared page" is used for low-level debugging
3966;
3967
3968 . = 0x6000
3969 .globl EXT(sharedPage)
3970
3971EXT(sharedPage): ; Per processor data area
3972 .long 0xC24BC195 ; Comm Area validity value
3973 .long 0x87859393 ; Comm Area validity value
3974 .long 0xE681A2C8 ; Comm Area validity value
3975 .long 0x8599855A ; Comm Area validity value
3976 .long 0xD74BD296 ; Comm Area validity value
3977 .long 0x8388E681 ; Comm Area validity value
3978 .long 0xA2C88599 ; Comm Area validity value
3979 .short 0x855A ; Comm Area validity value
3980 .short 1 ; Comm Area version number
3981 .fill 1016*4,1,0 ; (filled with 0s)
1c79356b
A
3982
3983 .data
3984 .align ALIGN
3985 .globl EXT(exception_end)
3986EXT(exception_end):
3987 .long EXT(ExceptionVectorsEnd) -EXT(ExceptionVectorsStart) /* phys fn */
3988
3989
55e303ae 3990