/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
*
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
mtlr r4
blr
-resetexc: cmplwi r13,RESET_HANDLER_BUPOR ; Special bring up POR sequence?
+resetexc: cmplwi r13,RESET_HANDLER_BUPOR ; Special bring up POR sequence?
bne resetexc2 ; No...
lis r4,hi16(EXT(resetPOR)) ; Get POR code
ori r4,r4,lo16(EXT(resetPOR)) ; The rest
; Fall through here for 970 MCKs.
;
- li r11,1 ; ?
- sldi r11,r11,32+3 ; ?
- mfspr r13,hid4 ; ?
- or r11,r11,r13 ; ?
+ li r11,1 ;
+ sldi r11,r11,32+3 ;
+ mfspr r13,hid4 ;
+ or r11,r11,r13 ;
sync
- mtspr hid4,r11 ; ?
+ mtspr hid4,r11 ;
isync
- li r11,1 ; ?
- sldi r11,r11,32+8 ; ?
- andc r13,r13,r11 ; ?
+ li r11,1 ;
+ sldi r11,r11,32+8 ;
+ andc r13,r13,r11 ;
lis r11,0xE000 ; Get the unlikeliest ESID possible
sync
- mtspr hid4,r13 ; ?
- isync ; ?
+ mtspr hid4,r13 ;
+ isync ;
- srdi r11,r11,1 ; ?
- slbie r11 ; ?
+ srdi r11,r11,1 ;
+ slbie r11 ;
sync
isync
h200aaa: mfsrr1 r11 ; Get the SRR1
mfcr r13 ; Save the CR
- rlwinm. r11,r11,0,dcmck,dcmck ; ?
- beq+ notDCache ; ?
+ rlwinm. r11,r11,0,dcmck,dcmck ;
+ beq+ notDCache ;
sync
- mfspr r11,msscr0 ; ?
- dssall ; ?
+ mfspr r11,msscr0 ;
+ dssall ;
sync
isync
- oris r11,r11,hi16(dl1hwfm) ; ?
- mtspr msscr0,r11 ; ?
+ oris r11,r11,hi16(dl1hwfm) ;
+ mtspr msscr0,r11 ;
-rstbsy: mfspr r11,msscr0 ; ?
+rstbsy: mfspr r11,msscr0 ;
- rlwinm. r11,r11,0,dl1hwf,dl1hwf ; ?
- bne rstbsy ; ?
+ rlwinm. r11,r11,0,dl1hwf,dl1hwf ;
+ bne rstbsy ;
- sync ; ?
+ sync ;
mfsprg r11,0 ; Get the per_proc
mtcrf 255,r13 ; Restore CRs
li r0,SAVgeneral ; Get the savearea type value
lhz r19,PP_CPU_NUMBER(r2) ; Get the logical processor number
stb r0,SAVflags+2(r13) ; Mark valid context
- ori r23,r23,lo16(EXT(trcWork)) ; Get the rest
rlwinm r22,r11,30,0,31 ; Divide interrupt code by 2
li r23,trcWork ; Get the trace work area address
addi r22,r22,10 ; Adjust code so we shift into CR5
dcbz128 0,r20 ; Zap the trace entry
+ lwz r9,SAVflags(r13) ; Get savearea flags
+
ld r16,ruptStamp(r2) ; Get top of time base
ld r0,saver0(r13) ; Get back interrupt time R0 (we need this whether we trace or not)
std r16,LTR_timeHi(r20) ; Set the upper part of TB
ld r1,saver1(r13) ; Get back interrupt time R1
+ rlwinm r9,r9,20,16,23 ; Isolate the special flags
ld r18,saver2(r13) ; Get back interrupt time R2
- std r0,LTR_r0(r20) ; Save off register 0
+ std r0,LTR_r0(r20) ; Save off register 0
+ rlwimi r9,r19,0,24,31 ; Slide in the cpu number
ld r3,saver3(r13) ; Restore this one
- sth r19,LTR_cpu(r20) ; Stash the cpu number
+ sth r9,LTR_cpu(r20) ; Stash the cpu number and special flags
std r1,LTR_r1(r20) ; Save off register 1
ld r4,saver4(r13) ; Restore this one
std r18,LTR_r2(r20) ; Save off register 2
li r20,lo16(xcpTable) ; Point to the vector table (note: this must be in 1st 64k of physical memory)
la r12,hwCounts(r2) ; Point to the exception count area
+ andis. r24,r22,hi16(SAVeat) ; Should we eat this one?
rlwinm r22,r22,SAVredriveb+1,31,31 ; Get a 1 if we are redriving
add r12,r12,r11 ; Point to the count
lwzx r20,r20,r11 ; Get the interrupt handler
lwz r25,0(r12) ; Get the old value
lwz r23,hwRedrives(r2) ; Get the redrive count
+ crmove cr3_eq,cr0_eq ; Remember if we are ignoring
xori r24,r22,1 ; Get the NOT of the redrive
mtctr r20 ; Point to the interrupt handler
mtcrf 0x80,r0 ; Set our CR0 to the high nybble of possible syscall code
crandc cr0_lt,cr0_lt,cr0_gt ; See if we have R0 equal to 0b10xx...x
stw r25,0(r12) ; Store it back
stw r23,hwRedrives(r2) ; Save the redrive count
+ bne-- cr3,IgnoreRupt ; Interruption is being ignored...
bctr ; Go process the exception...
.long WhoaBaby ; T_SOFT_PATCH
.long WhoaBaby ; T_MAINTENANCE
.long WhoaBaby ; T_INSTRUMENTATION
-
+ .long WhoaBaby ; T_ARCHDEP0
+ .long EatRupt ; T_HDEC
;
; Just what the heck happened here????
;
WhoaBaby: b . ; Open the hood and wait for help
+ .align 5
+
+IgnoreRupt:
+ lwz r20,hwIgnored(r2) ; Grab the ignored interruption count
+ addi r20,r20,1 ; Count this one
+ stw r20,hwIgnored(r2) ; Save the ignored count
+ b EatRupt ; Ignore it...
+
+
;
; System call
;
; Handle machine check here.
;
-; ?
+;
;
.align 5
MachineCheck:
- bt++ pf64Bitb,mck64 ; ?
+ bt++ pf64Bitb,mck64 ;
lwz r27,savesrr1+4(r13) ; Pick up srr1
mfspr r8,scomc ; Get back the status (we just ignore it)
sync
isync
+
+ lis r8,l2FIR ; Get the L2 FIR register address
+ ori r8,r8,0x8000 ; Set to read data
+
+ sync
+
+ mtspr scomc,r8 ; Request the L2 FIR
+ mfspr r26,scomd ; Get the source
+ mfspr r8,scomc ; Get back the status (we just ignore it)
+ sync
+ isync
+
+ lis r8,l2FIRrst ; Get the L2 FIR AND mask address
+
+ sync
+
+ mtspr scomd,r9 ; Set the AND mask to 0
+ mtspr scomc,r8 ; Write the AND mask and clear conditions
+ mfspr r8,scomc ; Get back the status (we just ignore it)
+ sync
+ isync
+
+ lis r8,busFIR ; Get the Bus FIR register address
+ ori r8,r8,0x8000 ; Set to read data
+
+ sync
+
+ mtspr scomc,r8 ; Request the Bus FIR
+ mfspr r27,scomd ; Get the source
+ mfspr r8,scomc ; Get back the status (we just ignore it)
+ sync
+ isync
+
+ lis r8,busFIRrst ; Get the Bus FIR AND mask address
+
+ sync
+
+ mtspr scomd,r9 ; Set the AND mask to 0
+ mtspr scomc,r8 ; Write the AND mask and clear conditions
+ mfspr r8,scomc ; Get back the status (we just ignore it)
+ sync
+ isync
; Note: bug in early chips where scom reads are shifted right by 1. We fix that here.
; Also note that we will lose bit 63
beq++ mckNoFix ; No fix up is needed
sldi r24,r24,1 ; Shift left 1
sldi r25,r25,1 ; Shift left 1
+ sldi r26,r26,1 ; Shift left 1
+ sldi r27,r27,1 ; Shift left 1
-mckNoFix: std r24,savemisc0(r13) ; Save the MCK source in case we pass the error
- std r25,savemisc1(r13) ; Save the Core FIR in case we pass the error
+mckNoFix: std r24,savexdat0(r13) ; Save the MCK source in case we pass the error
+ std r25,savexdat1(r13) ; Save the Core FIR in case we pass the error
+ std r26,savexdat2(r13) ; Save the L2 FIR in case we pass the error
+ std r27,savexdat3(r13) ; Save the BUS FIR in case we pass the error
rlwinm. r0,r20,0,mckIFUE-32,mckIFUE-32 ; Is this some kind of uncorrectable?
bne mckUE ; Yeah...
isync
tlbiel r23 ; Locally invalidate TLB entry for iaddr
sync ; Wait for it
- b EatRupt ; All recovered...
+ b ceMck ; All recovered...
; SLB parity error. This could be software caused. We get one if there is
; more than 1 valid SLBE with a matching ESID. That one we do not want to
bne++ cr1,mckSLBclr ; Yup....
sth r3,ppInvSeg(r2) ; Store non-zero to trigger SLB reload
- bne++ EatRupt ; This was not a programming error, all recovered...
- b PassUpTrap ; Pass the software error up...
+ bne++ ceMck ; This was not a programming error, all recovered...
+ b ueMck ; Pass the software error up...
;
; Handle a load/store unit error. We need to decode the DSISR
addi r21,r21,1 ; Count this one
stw r21,0(r9) ; Stick it back
- b EatRupt ; All recovered...
+ b ceMck ; All recovered...
;
; When we come here, we are not quite sure what the error is. We need to
mckUnk: lwz r21,hwMckUnk(r2) ; Get unknown error count
addi r21,r21,1 ; Count it
stw r21,hwMckUnk(r2) ; Stuff it
- b PassUpTrap ; Go south, young man...
+ b ueMck ; Go south, young man...
;
; Hang recovery. This is just a notification so we only count.
lwz r21,hwMckHang(r2) ; Get hang recovery count
addi r21,r21,1 ; Count this one
stw r21,hwMckHang(r2) ; Stick it back
- b EatRupt ; All recovered...
+ b ceMck ; All recovered...
;
; Externally signaled MCK. No recovery for the moment, but we this may be
lwz r21,hwMckHang(r2) ; Get hang recovery count
addi r21,r21,1 ; Count this one
stw r21,hwMckHang(r2) ; Stick it back
- b EatRupt ; All recovered...
+ b ceMck ; All recovered...
;
; Machine check cause is in a FIR. Suss it out here.
lwz r5,0(r19) ; Get the counter
addi r5,r5,1 ; Count it
stw r5,0(r19) ; Stuff it back
- b EatRupt ; All recovered...
+ b ceMck ; All recovered...
; General recovery for ERAT problems - handled in exception vector already
mckInvERAT: lwz r21,0(r19) ; Get the exception count spot
addi r21,r21,1 ; Count this one
stw r21,0(r19) ; Save count
- b EatRupt ; All recovered...
+ b ceMck ; All recovered...
; General hang recovery - this is a notification only, just count.
lwz r21,hwMckHang(r2) ; Get hang recovery count
addi r21,r21,1 ; Count this one
stw r21,hwMckHang(r2) ; Stick it back
- b EatRupt ; All recovered...
+ b ceMck ; All recovered...
;
mckUE: lwz r21,hwMckUE(r2) ; Get general uncorrectable error count
addi r21,r21,1 ; Count it
stw r21,hwMckUE(r2) ; Stuff it
- b PassUpTrap ; Go south, young man...
+ b ueMck ; Go south, young man...
mckhIFUE: lwz r21,hwMckIUEr(r2) ; Get I-Fetch TLB reload uncorrectable error count
addi r21,r21,1 ; Count it
stw r21,hwMckIUEr(r2) ; Stuff it
- b PassUpTrap ; Go south, young man...
+ b ueMck ; Go south, young man...
mckDUE: lwz r21,hwMckDUE(r2) ; Get deferred uncorrectable error count
addi r21,r21,1 ; Count it
cmpld r23,r8 ; Too soon?
cmpld cr1,r23,r9 ; Too late?
- cror cr0_lt,cr0_lt,cr1_gt ; Too soo or too late?
+ cror cr0_lt,cr0_lt,cr1_gt ; Too soon or too late?
ld r3,saver12(r13) ; Get the original MSR
ld r5,savelr(r13) ; Get the return address
li r4,0 ; Get fail code
- blt-- PassUpTrap ; This is a normal machine check, just pass up...
+ blt-- ueMck ; This is a normal machine check, just pass up...
std r5,savesrr0(r13) ; Set the return MSR
std r3,savesrr1(r13) ; Set the return address
std r4,saver3(r13) ; Set failure return code
- b EatRupt ; Go return from ml_probe_read_64...
+ b ceMck ; All recovered...
mckDTW: lwz r21,hwMckDTW(r2) ; Get deferred tablewalk uncorrectable error count
addi r21,r21,1 ; Count it
stw r21,hwMckDTW(r2) ; Stuff it
- b PassUpTrap ; Go south, young man...
+ b ueMck ; Go south, young man...
mckL1D: lwz r21,hwMckL1DPE(r2) ; Get data cache parity error count
addi r21,r21,1 ; Count it
stw r21,hwMckL1DPE(r2) ; Stuff it
- b PassUpTrap ; Go south, young man...
+ b ceMck ; All recovered...
mckL1T: lwz r21,hwMckL1TPE(r2) ; Get TLB parity error count
addi r21,r21,1 ; Count it
stw r21,hwMckL1TPE(r2) ; Stuff it
- b PassUpTrap ; Go south, young man...
+
+ceMck: li r0,1 ; Set the recovered flag before passing up
+ stw r0,savemisc3(r13) ; Set it
+ b PassUpTrap ; Go up and log error...
+
+ueMck: li r0,0 ; Set the unrecovered flag before passing up
+ stw r0,savemisc3(r13) ; Set it
+ b PassUpTrap ; Go up and log error and probably panic
/*
.long 0 ; 5008 Zero
.long 0 ; 500C Zero cont...
.long EXT(per_proc_info) ; 5010 pointer to per_procs
- .long 0 ;
+ .long 0
.long 0 ; 5018 reserved
.long 0 ; 501C reserved
.long 0 ; 5020 reserved
.long 0 ; 53F4 reserved
.long 0 ; 53F8 reserved
.long 0 ; 53FC reserved
-
-
+ .long 0 ; 5400 reserved
+ .long 0 ; 5404 reserved
+ .long 0 ; 5408 reserved
+ .long 0 ; 540C reserved
+ .long 0 ; 5410 reserved
+ .long 0 ; 5414 reserved
+ .long 0 ; 5418 reserved
+ .long 0 ; 541C reserved
+ .long 0 ; 5420 reserved
+ .long 0 ; 5424 reserved
+ .long 0 ; 5428 reserved
+ .long 0 ; 542C reserved
+ .long 0 ; 5430 reserved
+ .long 0 ; 5434 reserved
+ .long 0 ; 5438 reserved
+ .long 0 ; 543C reserved
+ .long 0 ; 5440 reserved
+ .long 0 ; 5444 reserved
+ .long 0 ; 5448 reserved
+ .long 0 ; 544C reserved
+ .long 0 ; 5450 reserved
+ .long 0 ; 5454 reserved
+ .long 0 ; 5458 reserved
+ .long 0 ; 545C reserved
+ .long 0 ; 5460 reserved
+ .long 0 ; 5464 reserved
+ .long 0 ; 5468 reserved
+ .long 0 ; 546C reserved
+ .long 0 ; 5470 reserved
+ .long 0 ; 5474 reserved
+ .long 0 ; 5478 reserved
+ .long 0 ; 547C reserved
;
; The "shared page" is used for low-level debugging
;