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