]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ppc/trap.c
xnu-517.9.5.tar.gz
[apple/xnu.git] / osfmk / ppc / trap.c
index fd3514628b93b89d0542acb0e1168e8d82e8ad5d..e87a876e9e625008f548fd20d8a764f784f7425f 100644 (file)
@@ -3,22 +3,19 @@
  *
  * @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@
  */
@@ -73,7 +70,7 @@ extern boolean_t db_breakpoints_inserted;
 extern int debugger_active[NCPUS];
 extern task_t bsd_init_task;
 extern char init_task_failure_data[];
-
+extern int not_in_kdp;
 
 #define        PROT_EXEC       (VM_PROT_EXECUTE)
 #define PROT_RO                (VM_PROT_READ)
@@ -95,6 +92,9 @@ static void unresolved_kernel_trap(int trapno,
                                   addr64_t dar,
                                   char *message);
 
+static void handleMck(struct savearea *ssp);           /* Common machine check handler */
+
+
 struct savearea *trap(int trapno,
                             struct savearea *ssp,
                             unsigned int dsisr,
@@ -145,7 +145,7 @@ struct savearea *trap(int trapno,
                switch (trapno) {
 
                case T_PREEMPT:                 /* Handle a preempt trap */
-                       ast_taken(AST_PREEMPT, FALSE);
+                       ast_taken(AST_PREEMPTION, FALSE);
                        break;  
 
                case T_PERF_MON:
@@ -167,7 +167,6 @@ struct savearea *trap(int trapno,
                 */
                case T_DECREMENTER:
                case T_IN_VAIN:                 /* Shouldn't ever see this, lowmem_vectors eats it */
-               case T_MACHINE_CHECK:
                case T_SYSTEM_MANAGEMENT:
                case T_ALTIVEC_ASSIST:
                case T_INTERRUPT:
@@ -179,6 +178,15 @@ struct savearea *trap(int trapno,
                        break;
 
 
+/*
+ *                     Here we handle a machine check in the kernel
+ */
+
+               case T_MACHINE_CHECK:
+                       handleMck(ssp);                                         /* Common to both user and kernel */
+                       break;
+
+
                case T_ALIGNMENT:
 /*
 *                      If enaNotifyEMb is set, we get here, and
@@ -227,7 +235,6 @@ struct savearea *trap(int trapno,
                        break;
 
                case T_DATA_ACCESS:
-
 #if    MACH_KDB
                        mp_disable_preemption();
                        if (debug_mode
@@ -240,6 +247,16 @@ struct savearea *trap(int trapno,
                        }
                        mp_enable_preemption();
 #endif /* MACH_KDB */
+                       /* can we take this during normal panic dump operation? */
+                       if (debug_mode
+                           && debugger_active[cpu_number()]
+                           && !not_in_kdp) {
+                               /* 
+                                * Access fault while in kernel core dump.
+                                */
+                               kdp_dump_trap(trapno, ssp); 
+                       }
+
 
                        if(ssp->save_dsisr & dsiInvMode) {                      /* Did someone try to reserve cache inhibited? */
                                panic("trap: disallowed access to cache inhibited memory - %016llX\n", dar);
@@ -392,7 +409,6 @@ struct savearea *trap(int trapno,
                         */
                case T_DECREMENTER:
                case T_IN_VAIN:                                                         /* Shouldn't ever see this, lowmem_vectors eats it */
-               case T_MACHINE_CHECK:
                case T_INTERRUPT:
                case T_FP_UNAVAILABLE:
                case T_SYSTEM_MANAGEMENT:
@@ -407,6 +423,15 @@ struct savearea *trap(int trapno,
                               cpu_number(), trapno, dsisr, dar, ssp->save_srr0, ssp->save_srr1);
                        break;
 
+
+/*
+ *                     Here we handle a machine check in user state
+ */
+
+               case T_MACHINE_CHECK:
+                       handleMck(ssp);                                         /* Common to both user and kernel */
+                       break;
+
                case T_RESET:
                        ml_set_interrupts_enabled(FALSE);                                       /* Turn off interruptions */
                        if (!Call_Debugger(trapno, ssp))
@@ -480,7 +505,7 @@ struct savearea *trap(int trapno,
                                unsigned int inst;
                                char *iaddr;
                                
-                               iaddr = (char *)ssp->save_srr0;         /* Trim from long long and make a char pointer */
+                               iaddr = CAST_DOWN(char *, ssp->save_srr0);              /* Trim from long long and make a char pointer */ 
                                if (copyin(iaddr, (char *) &inst, 4 )) panic("copyin failed\n");
                                
                                if(dgWork.dgFlags & enaDiagTrap) {      /* Is the diagnostic trap enabled? */
@@ -806,6 +831,30 @@ void unresolved_kernel_trap(int trapno,
        panic(message);
 }
 
+char *corr[2] = {"uncorrected", "corrected  "};
+
+void handleMck(struct savearea *ssp) {                                 /* Common machine check handler */
+
+       int cpu;
+       
+       cpu = cpu_number();
+
+       printf("Machine check (%d) - %s - pc = %016llX, msr = %016llX, dsisr = %08X, dar = %016llX\n",
+               cpu, corr[ssp->save_hdr.save_misc3], ssp->save_srr0, ssp->save_srr1, ssp->save_dsisr, ssp->save_dar);           /* Tell us about it */
+       printf("Machine check (%d) -   AsyncSrc = %016llX, CoreFIR = %016llx\n", cpu, ssp->save_xdat0, ssp->save_xdat1);
+       printf("Machine check (%d) -      L2FIR = %016llX,  BusFir = %016llx\n", cpu, ssp->save_xdat2, ssp->save_xdat3);
+       
+       if(ssp->save_hdr.save_misc3) return;                            /* Leave the the machine check was recovered */
+
+       panic("Uncorrectable machine check: pc = %016llX, msr = %016llX, dsisr = %08X, dar = %016llX\n"
+             "  AsyncSrc = %016llX, CoreFIR = %016llx\n"
+             "     L2FIR = %016llX,  BusFir = %016llx\n",
+                 ssp->save_srr0, ssp->save_srr1, ssp->save_dsisr, ssp->save_dar, 
+                 ssp->save_xdat0, ssp->save_xdat1, ssp->save_xdat2, ssp->save_xdat3);
+       
+       return;
+}
+
 void
 thread_syscall_return(
         kern_return_t ret)