The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/osfmk/ppc/model_dep.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * The contents of this file constitute Original Code as defined in and
    7  * are subject to the Apple Public Source License Version 1.1 (the
    8  * "License").  You may not use this file except in compliance with the
    9  * License.  Please obtain a copy of the License at
   10  * http://www.apple.com/publicsource and read it before using this file.
   11  * 
   12  * This Original Code and all software distributed under the License are
   13  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   14  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   15  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   16  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
   17  * License for the specific language governing rights and limitations
   18  * under the License.
   19  * 
   20  * @APPLE_LICENSE_HEADER_END@
   21  */
   22 /*
   23  * @OSF_COPYRIGHT@
   24  */
   25 /*
   26  * @APPLE_FREE_COPYRIGHT@
   27  */
   28 /*
   29  *  (c) Copyright 1988 HEWLETT-PACKARD COMPANY
   30  *
   31  *  To anyone who acknowledges that this file is provided "AS IS"
   32  *  without any express or implied warranty:
   33  *      permission to use, copy, modify, and distribute this file
   34  *  for any purpose is hereby granted without fee, provided that
   35  *  the above copyright notice and this notice appears in all
   36  *  copies, and that the name of Hewlett-Packard Company not be
   37  *  used in advertising or publicity pertaining to distribution
   38  *  of the software without specific, written prior permission.
   39  *  Hewlett-Packard Company makes no representations about the
   40  *  suitability of this software for any purpose.
   41  */
   42 /*
   43  * Copyright (c) 1990,1991,1992,1994 The University of Utah and
   44  * the Computer Systems Laboratory (CSL).  All rights reserved.
   45  *
   46  * THE UNIVERSITY OF UTAH AND CSL PROVIDE THIS SOFTWARE IN ITS "AS IS"
   47  * CONDITION, AND DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
   48  * WHATSOEVER RESULTING FROM ITS USE.
   49  *
   50  * CSL requests users of this software to return to csl-dist@cs.utah.edu any
   51  * improvements that they make and grant CSL redistribution rights.
   52  *
   53  *      Utah $Hdr: model_dep.c 1.34 94/12/14$
   54  */
   55 
   56 #include <debug.h>
   57 #include <mach_kdb.h>
   58 #include <mach_kdp.h>
   59 #include <db_machine_commands.h>
   60 
   61 #include <kern/thread.h>
   62 #include <machine/pmap.h>
   63 #include <device/device_types.h>
   64 
   65 #include <mach/vm_param.h>
   66 #include <mach/clock_types.h>
   67 #include <mach/machine.h>
   68 #include <mach/kmod.h>
   69 #include <ppc/boot.h>
   70 
   71 #include <kern/misc_protos.h>
   72 #include <kern/startup.h>
   73 #include <ppc/misc_protos.h>
   74 #include <ppc/proc_reg.h>
   75 #include <ppc/thread.h>
   76 #include <ppc/asm.h>
   77 #include <ppc/mem.h>
   78 #include <ppc/Firmware.h>
   79 #include <ppc/low_trace.h>
   80 #include <ppc/mappings.h>
   81 #include <ppc/FirmwareCalls.h>
   82 #include <ppc/cpu_internal.h>
   83 #include <ppc/exception.h>
   84 #include <ppc/hw_perfmon.h>
   85 #include <ppc/lowglobals.h>
   86 
   87 #include <kern/clock.h>
   88 #include <kern/debug.h>
   89 #include <machine/trap.h>
   90 #include <kern/spl.h>
   91 #include <pexpert/pexpert.h>
   92 
   93 #include <IOKit/IOPlatformExpert.h>
   94 
   95 #include <mach/vm_prot.h>
   96 #include <vm/pmap.h>
   97 #include <mach/time_value.h>
   98 #include <machine/machparam.h>  /* for btop */
   99 
  100 #if     MACH_KDB
  101 #include <ddb/db_aout.h>
  102 #include <ddb/db_output.h>
  103 #include <ddb/db_command.h>
  104 #include <machine/db_machdep.h>
  105 
  106 extern struct db_command ppc_db_commands[];
  107 #endif  /* MACH_KDB */
  108 
  109 char kernel_args_buf[256] = "/mach_kernel";
  110 char boot_args_buf[256] = "/mach_servers/bootstrap";
  111 char env_buf[256];
  112 
  113 #define TRAP_DEBUGGER   __asm__ volatile("tw 4,r3,r3");
  114 #define TRAP_DEBUGGER_INST      0x7c831808
  115 #define TRAP_DIRECT     __asm__ volatile("tw 4,r4,r4");
  116 #define TRAP_DIRECT_INST        0x7c842008
  117 #define TRAP_INST_SIZE  4
  118 #define BREAK_TO_KDP0 0x7fe00008
  119 #define BREAK_TO_KDP1 0x7c800008
  120 #define BREAK_TO_KDB0 0x7c810808
  121 
  122 /*
  123  * Code used to synchronize debuggers among all cpus, one active at a time, switch
  124  * from on to another using kdb_on! #cpu or cpu #cpu
  125  */
  126 
  127 hw_lock_data_t debugger_lock;   /* debugger lock */
  128 hw_lock_data_t pbtlock;         /* backtrace print lock */
  129 
  130 int                     debugger_cpu = -1;                      /* current cpu running debugger */
  131 int                     debugger_debug = 0;                     /* Debug debugger */
  132 int             db_run_mode;                            /* Debugger run mode */
  133 unsigned int debugger_sync = 0;                 /* Cross processor debugger entry sync */
  134 extern          unsigned int NMIss;                     /* NMI debounce switch */
  135 
  136 extern volatile int panicwait;
  137 volatile unsigned int pbtcnt = 0;
  138 volatile unsigned int pbtcpu = -1;
  139 
  140 unsigned int lastTrace;                                 /* Value of low-level exception trace controls */
  141 
  142 
  143 volatile unsigned int   cpus_holding_bkpts;     /* counter for number of cpus holding
  144                                                                                            breakpoints (ie: cpus that did not
  145                                                                                            insert back breakpoints) */
  146 void unlock_debugger(void);
  147 void lock_debugger(void);
  148 void dump_backtrace(savearea *sv, unsigned int stackptr, unsigned int fence);
  149 void dump_savearea(savearea *sv, unsigned int fence);
  150 
  151 int packAsc (unsigned char *inbuf, unsigned int length);
  152 
  153 #if !MACH_KDB
  154 boolean_t       db_breakpoints_inserted = TRUE;
  155 jmp_buf_t *db_recover = 0;
  156 #endif
  157 
  158 #if     MACH_KDB
  159 #include <ddb/db_run.h>
  160 int     kdb_flag=0;
  161 extern boolean_t db_breakpoints_inserted;
  162 extern jmp_buf_t *db_recover;
  163 #define KDB_READY       0x1
  164 #endif
  165 
  166 #if     MACH_KDP
  167 extern int      kdp_flag;
  168 #define KDP_READY       0x1
  169 #endif
  170 
  171 boolean_t db_im_stepping = 0xFFFFFFFF;  /* Remember if we were stepping */
  172 
  173 
  174 char *failNames[] = {   
  175 
  176         "Debugging trap",                       /* failDebug */
  177         "Corrupt stack",                        /* failStack */
  178         "Corrupt mapping tables",       /* failMapping */
  179         "Corrupt context",                      /* failContext */
  180         "No saveareas",                         /* failNoSavearea */
  181         "Savearea corruption",          /* failSaveareaCorr */
  182         "Invalid live context",         /* failBadLiveContext */
  183         "Corrupt skip lists",           /* failSkipLists */
  184         "Unaligned stack",                      /* failUnalignedStk */
  185         "Invalid pmap",                         /* failPmap */
  186         "Lock timeout",                         /* failTimeout */
  187         "Unknown failure code"          /* Unknown failure code - must always be last */
  188 };
  189 
  190 char *invxcption = "Unknown code";
  191 
  192 extern const char version[];
  193 extern char *trap_type[];
  194 
  195 #if !MACH_KDB
  196 void kdb_trap(int type, struct savearea *regs);
  197 void kdb_trap(int type, struct savearea *regs) {
  198         return;
  199 }
  200 #endif
  201 
  202 #if !MACH_KDP
  203 void kdp_trap(int type, struct savearea *regs);
  204 void kdp_trap(int type, struct savearea *regs) {
  205         return;
  206 }
  207 #endif
  208 
  209 void
  210 machine_startup(boot_args *args)
  211 {
  212         int     boot_arg;
  213         unsigned int wncpu;
  214         unsigned int vmm_arg;
  215 
  216         if (PE_parse_boot_arg("cpus", &wncpu)) {
  217                 if ((wncpu > 0) && (wncpu < MAX_CPUS))
  218                         max_ncpus = wncpu;
  219         }
  220 
  221         if( PE_get_hotkey( kPEControlKey ))
  222             halt_in_debugger = halt_in_debugger ? 0 : 1;
  223 
  224         if (PE_parse_boot_arg("debug", &boot_arg)) {
  225                 if (boot_arg & DB_HALT) halt_in_debugger=1;
  226                 if (boot_arg & DB_PRT) disableDebugOuput=FALSE; 
  227                 if (boot_arg & DB_SLOG) systemLogDiags=TRUE; 
  228                 if (boot_arg & DB_NMI) panicDebugging=TRUE; 
  229                 if (boot_arg & DB_LOG_PI_SCRN) logPanicDataToScreen=TRUE; 
  230         }
  231         
  232         PE_parse_boot_arg("vmmforce", &lowGlo.lgVMMforcedFeats);
  233 
  234         hw_lock_init(&debugger_lock);                           /* initialize debugger lock */
  235         hw_lock_init(&pbtlock);                                         /* initialize print backtrace lock */
  236 
  237 #if     MACH_KDB
  238         /*
  239          * Initialize KDB
  240          */
  241 #if     DB_MACHINE_COMMANDS
  242         db_machine_commands_install(ppc_db_commands);
  243 #endif  /* DB_MACHINE_COMMANDS */
  244         ddb_init();
  245 
  246         if (boot_arg & DB_KDB)
  247                 current_debugger = KDB_CUR_DB;
  248 
  249         /*
  250          * Cause a breakpoint trap to the debugger before proceeding
  251          * any further if the proper option bit was specified in
  252          * the boot flags.
  253          */
  254         if (halt_in_debugger && (current_debugger == KDB_CUR_DB)) {
  255                 Debugger("inline call to debugger(machine_startup)");
  256                 halt_in_debugger = 0;
  257                 active_debugger =1;
  258         }
  259 #endif /* MACH_KDB */
  260         if (PE_parse_boot_arg("preempt", &boot_arg)) {
  261                 extern int default_preemption_rate;
  262 
  263                 default_preemption_rate = boot_arg;
  264         }
  265         if (PE_parse_boot_arg("unsafe", &boot_arg)) {
  266                 extern int max_unsafe_quanta;
  267 
  268                 max_unsafe_quanta = boot_arg;
  269         }
  270         if (PE_parse_boot_arg("poll", &boot_arg)) {
  271                 extern int max_poll_quanta;
  272 
  273                 max_poll_quanta = boot_arg;
  274         }
  275         if (PE_parse_boot_arg("yield", &boot_arg)) {
  276                 extern int sched_poll_yield_shift;
  277 
  278                 sched_poll_yield_shift = boot_arg;
  279         }
  280 
  281         machine_conf();
  282 
  283         /*
  284          * Kick off the kernel bootstrap.
  285          */
  286         kernel_bootstrap();
  287         /*NOTREACHED*/
  288 }
  289 
  290 char *
  291 machine_boot_info(
  292         char *buf, 
  293         vm_size_t size)
  294 {
  295         return(PE_boot_args());
  296 }
  297 
  298 void
  299 machine_conf(void)
  300 {
  301         machine_info.memory_size = mem_size;    /* Note that this will be 2 GB for >= 2 GB machines */
  302 }
  303 
  304 void
  305 machine_init(void)
  306 {
  307         clock_config();
  308 /*      Note that we must initialize the stepper tables AFTER the clock is configured!!!!! */
  309         if(pmsExperimental & 1) pmsCPUConf();   /* (EXPERIMENTAL) Initialize the stepper tables */
  310         perfmon_init();
  311         return;
  312 
  313 }
  314 
  315 void slave_machine_init(void)
  316 {
  317         cpu_machine_init();                     /* Initialize the processor */
  318         clock_init();                           /* Init the clock */
  319 }                               
  320 
  321 void
  322 halt_all_cpus(boolean_t reboot)
  323 {
  324         if(reboot)
  325         {
  326                 printf("MACH Reboot\n");
  327                 PEHaltRestart(kPERestartCPU);
  328         }
  329         else
  330         {
  331                 printf("CPU halted\n");
  332                 PEHaltRestart(kPEHaltCPU);
  333         } 
  334         while(1);
  335 }
  336 
  337 void
  338 halt_cpu(void)
  339 {
  340         halt_all_cpus(FALSE);
  341 }
  342 
  343 #if     MACH_ASSERT
  344 /*
  345  * Machine-dependent routine to fill in an array with up to callstack_max
  346  * levels of return pc information.
  347  */
  348 void machine_callstack(
  349         natural_t       *buf,
  350         vm_size_t       callstack_max)
  351 {
  352 }
  353 #endif  /* MACH_ASSERT */
  354 
  355 
  356 void
  357 print_backtrace(struct savearea *ssp)
  358 {
  359         unsigned int stackptr, *raddr, *rstack, trans, fence;
  360         int i, frames_cnt, skip_top_frames, frames_max;
  361         unsigned int store[8];                  /* Buffer for real storage reads */
  362         vm_offset_t backtrace_entries[32];
  363         savearea *sv, *svssp;
  364         int cpu;
  365         savearea *psv;
  366 
  367 /*
  368  *      We need this lock to make sure we don't hang up when we double panic on an MP.
  369  */
  370 
  371         cpu  = cpu_number();                                    /* Just who are we anyways? */
  372         if(pbtcpu != cpu) {                                             /* Allow recursion */
  373                 hw_atomic_add((uint32_t *)&pbtcnt, 1); /* Remember we are trying */
  374                 while(!hw_lock_try(&pbtlock));          /* Spin here until we can get in. If we never do, well, we're crashing anyhow... */     
  375                 pbtcpu = cpu;                                           /* Mark it as us */     
  376         }       
  377 
  378         svssp = (savearea *)ssp;                                /* Make this easier */
  379         sv = 0;
  380         if(current_thread()) sv = (savearea *)current_thread()->machine.pcb;    /* Find most current savearea if system has started */
  381 
  382         fence = 0xFFFFFFFF;                                             /* Show we go all the way */
  383         if(sv) fence = (unsigned int)sv->save_r1;       /* Stop at previous exception point */
  384         
  385         if(!svssp) {                                                    /* Should we start from stack? */
  386                 kdb_printf("Latest stack backtrace for cpu %d:\n", cpu_number());
  387                 __asm__ volatile("mr %0,r1" : "=r" (stackptr)); /* Get current stack */
  388                 dump_backtrace((savearea *)0,stackptr, fence);  /* Dump the backtrace */
  389                 if(!sv) {                                                       /* Leave if no saveareas */
  390                         kdb_printf("\nKernel version:\n%s\n",version);  /* Print kernel version */
  391                         hw_lock_unlock(&pbtlock);               /* Allow another back trace to happen */
  392                         return; 
  393                 }
  394         }
  395         else {                                                                  /* Were we passed an exception? */
  396                 fence = 0xFFFFFFFF;                                     /* Show we go all the way */
  397                 if(svssp->save_hdr.save_prev) {
  398                         if((svssp->save_hdr.save_prev <= vm_last_addr) && ((unsigned int)pmap_find_phys(kernel_pmap, (addr64_t)svssp->save_hdr.save_prev))) {   /* Valid address? */    
  399                                 psv = (savearea *)((unsigned int)svssp->save_hdr.save_prev);    /* Get the 64-bit back chain converted to a regualr pointer */
  400                                 fence = (unsigned int)psv->save_r1;     /* Stop at previous exception point */
  401                         }
  402                 }
  403         
  404                 kdb_printf("Latest crash info for cpu %d:\n", cpu_number());
  405                 kdb_printf("   Exception state (sv=0x%08X)\n", sv);
  406                 dump_savearea(svssp, fence);            /* Dump this savearea */        
  407         }
  408 
  409         if(!sv) {                                                               /* Leave if no saveareas */
  410                 kdb_printf("\nKernel version:\n%s\n",version);  /* Print kernel version */
  411                 hw_lock_unlock(&pbtlock);                       /* Allow another back trace to happen */
  412                 return; 
  413         }
  414         
  415         kdb_printf("Proceeding back via exception chain:\n");
  416 
  417         while(sv) {                                                             /* Do them all... */
  418                 if(!(((addr64_t)((uintptr_t)sv) <= vm_last_addr) && 
  419                         (unsigned int)pmap_find_phys(kernel_pmap, (addr64_t)((uintptr_t)sv)))) {        /* Valid address? */    
  420                         kdb_printf("   Exception state (sv=0x%08X) Not mapped or invalid. stopping...\n", sv);
  421                         break;
  422                 }
  423                 
  424                 kdb_printf("   Exception state (sv=0x%08X)\n", sv);
  425                 if(sv == svssp) {                                       /* Did we dump it already? */
  426                         kdb_printf("      previously dumped as \"Latest\" state. skipping...\n");
  427                 }
  428                 else {
  429                         fence = 0xFFFFFFFF;                             /* Show we go all the way */
  430                         if(sv->save_hdr.save_prev) {
  431                                 if((sv->save_hdr.save_prev <= vm_last_addr) && ((unsigned int)pmap_find_phys(kernel_pmap, (addr64_t)sv->save_hdr.save_prev))) { /* Valid address? */    
  432                                         psv = (savearea *)((unsigned int)sv->save_hdr.save_prev);       /* Get the 64-bit back chain converted to a regualr pointer */
  433                                         fence = (unsigned int)psv->save_r1;     /* Stop at previous exception point */
  434                                 }
  435                         }
  436                         dump_savearea(sv, fence);               /* Dump this savearea */        
  437                 }       
  438                 
  439                 sv = CAST_DOWN(savearea *, sv->save_hdr.save_prev);     /* Back chain */ 
  440         }
  441         
  442         kdb_printf("\nKernel version:\n%s\n",version);  /* Print kernel version */
  443 
  444         pbtcpu = -1;                                                    /* Mark as unowned */
  445         hw_lock_unlock(&pbtlock);                               /* Allow another back trace to happen */
  446         hw_atomic_sub((uint32_t *) &pbtcnt, 1);  /* Show we are done */
  447 
  448         while(pbtcnt);                                                  /* Wait for completion */
  449 
  450         return;
  451 }
  452 
  453 void dump_savearea(savearea *sv, unsigned int fence) {
  454 
  455         char *xcode;
  456         
  457         if(sv->save_exception > T_MAX) xcode = invxcption;      /* Too big for table */
  458         else xcode = trap_type[sv->save_exception / 4];         /* Point to the type */
  459         
  460         kdb_printf("      PC=0x%08X; MSR=0x%08X; DAR=0x%08X; DSISR=0x%08X; LR=0x%08X; R1=0x%08X; XCP=0x%08X (%s)\n",
  461                 (unsigned int)sv->save_srr0, (unsigned int)sv->save_srr1, (unsigned int)sv->save_dar, sv->save_dsisr,
  462                 (unsigned int)sv->save_lr, (unsigned int)sv->save_r1, sv->save_exception, xcode);
  463         
  464         if(!(sv->save_srr1 & MASK(MSR_PR))) {           /* Are we in the kernel? */
  465                 dump_backtrace(sv, (unsigned int)sv->save_r1, fence);   /* Dump the stack back trace from  here if not user state */
  466         }
  467         
  468         return;
  469 }
  470 
  471 
  472 
  473 #define DUMPFRAMES 34
  474 #define LRindex 2
  475 
  476 void dump_backtrace(savearea *sv, unsigned int stackptr, unsigned int fence) {
  477 
  478         unsigned int bframes[DUMPFRAMES];
  479         unsigned int  sframe[8], raddr, dumbo;
  480         int i, index=0;
  481         
  482         kdb_printf("      Backtrace:\n");
  483         if (sv != (savearea *)0) {
  484                 bframes[0] = (unsigned int)sv->save_srr0;
  485                 bframes[1] = (unsigned int)sv->save_lr;
  486                 index = 2;
  487         }
  488         for(i = index; i < DUMPFRAMES; i++) {                   /* Dump up to max frames */
  489         
  490                 if(!stackptr || (stackptr == fence)) break;             /* Hit stop point or end... */
  491                 
  492                 if(stackptr & 0x0000000F) {                             /* Is stack pointer valid? */
  493                         kdb_printf("\n         backtrace terminated - unaligned frame address: 0x%08X\n", stackptr);    /* No, tell 'em */
  494                         break;
  495                 }
  496 
  497                 raddr = (unsigned int)pmap_find_phys(kernel_pmap, (addr64_t)stackptr);  /* Get physical frame address */
  498                 if(!raddr || (stackptr > vm_last_addr)) {               /* Is it mapped? */
  499                         kdb_printf("\n         backtrace terminated - frame not mapped or invalid: 0x%08X\n", stackptr);        /* No, tell 'em */
  500                         break;
  501                 }
  502         
  503                 if(!mapping_phys_lookup(raddr, &dumbo)) {       /* Is it within physical RAM? */
  504                         kdb_printf("\n         backtrace terminated - frame outside of RAM: v=0x%08X, p=%08X\n", stackptr, raddr);      /* No, tell 'em */
  505                         break;
  506                 }
  507         
  508                 ReadReal((addr64_t)((raddr << 12) | (stackptr & 4095)), &sframe[0]);    /* Fetch the stack frame */
  509 
  510                 bframes[i] = sframe[LRindex];                           /* Save the link register */
  511                 
  512                 if(!i) kdb_printf("         ");                         /* Indent first time */
  513                 else if(!(i & 7)) kdb_printf("\n         ");    /* Skip to new line every 8 */
  514                 kdb_printf("0x%08X ", bframes[i]);                      /* Dump the link register */
  515                 
  516                 stackptr = sframe[0];                                           /* Chain back */
  517         }
  518         kdb_printf("\n");
  519         if(i >= DUMPFRAMES) kdb_printf("      backtrace continues...\n");       /* Say we terminated early */
  520         if(i) kmod_dump((vm_offset_t *)&bframes[0], i); /* Show what kmods are in trace */
  521         
  522 }
  523         
  524 
  525 
  526 void 
  527 Debugger(const char     *message) {
  528 
  529         int i;
  530         unsigned int store[8];
  531         unsigned long pi_size = 0;
  532         spl_t spl;
  533         
  534         spl = splhigh();                                                                /* No interruptions from here on */
  535         
  536 /*
  537  *      backtrace for Debugger() call  from panic() if no current debugger
  538  *      backtrace and return for double panic() call
  539  */
  540         if ((panicstr != (char *)0) && 
  541           (((nestedpanic != 0) && (current_debugger == 1)) || (active_debugger == 0))) {
  542                 print_backtrace(NULL);
  543                 if (nestedpanic != 0)  {
  544                         splx(spl);
  545                         return;                                                                 /* Yeah, don't enter again... */
  546                 }
  547         }
  548         
  549         if (debug_mode && getPerProc()->debugger_active) {      /* Are we already on debugger on this processor? */
  550                 splx(spl);
  551                 return;                                                                         /* Yeah, don't do it again... */
  552         }
  553 
  554 
  555 /*
  556  * The above stuff catches the double panic case so we shouldn't have to worry about that here.
  557  */
  558         if ( panicstr != (char *)0 )
  559         {
  560                 /* diable kernel preemptions */
  561                 disable_preemption();
  562         
  563                 /* everything should be printed now so copy to NVRAM
  564                 */
  565                 if( debug_buf_size > 0)
  566 
  567                   {
  568                     /* Do not compress the panic log unless kernel debugging 
  569                      * is disabled - the panic log isn't synced to NVRAM if 
  570                      * debugging is enabled, and the panic log is valuable 
  571                      * whilst debugging
  572                      */
  573                     if (!panicDebugging)
  574                       {
  575                         unsigned int bufpos;
  576                         
  577                         /* Now call the compressor */
  578                         bufpos = packAsc (debug_buf, (unsigned int) (debug_buf_ptr - debug_buf) );
  579                         /* If compression was successful, use the compressed length                */
  580                         if (bufpos)
  581                           {
  582                             debug_buf_ptr = debug_buf + bufpos;
  583                           }
  584                       }
  585                     /* Truncate if the buffer is larger than a certain magic 
  586                      * size - this really ought to be some appropriate fraction
  587                      * of the NVRAM image buffer, and is best done in the 
  588                      * savePanicInfo() or PESavePanicInfo() calls 
  589                      */
  590                     pi_size = debug_buf_ptr - debug_buf;
  591                     pi_size = PESavePanicInfo( debug_buf, ((pi_size > 2040) ? 2040 : pi_size));
  592                   }
  593                         
  594                 if( !panicDebugging && (pi_size != 0) ) {
  595                         int     my_cpu;
  596                         int     tcpu;
  597 
  598                         my_cpu = cpu_number();
  599                         debugger_cpu = my_cpu;
  600 
  601                         hw_atomic_add(&debug_mode, 1);
  602                         PerProcTable[my_cpu].ppe_vaddr->debugger_active++;
  603                         lock_debugger();
  604 
  605                         for(tcpu = 0; tcpu < real_ncpus; tcpu++) {
  606                                 if(tcpu == my_cpu) continue;
  607                                 hw_atomic_add(&debugger_sync, 1);
  608                                 (void)cpu_signal(tcpu, SIGPdebug, 0 ,0);
  609                         }
  610                         (void)hw_cpu_sync(&debugger_sync, LockTimeOut);
  611                         debugger_sync = 0;
  612                 }
  613 
  614                 draw_panic_dialog();
  615                 
  616                 if( !panicDebugging && (pi_size != 0))
  617                                         PEHaltRestart( kPEHangCPU );
  618 
  619                 enable_preemption();
  620         }
  621 
  622 
  623         if ((current_debugger != NO_CUR_DB)) {                  /* If there is a debugger configured, enter it */
  624                 printf("Debugger(%s)\n", message);
  625                 TRAP_DEBUGGER;
  626                 splx(spl);
  627                 return;                                                                         /* Done debugging for a while */
  628         }
  629 
  630         printf("\nNo debugger configured - dumping debug information\n");
  631         printf("MSR=%08X\n",mfmsr());
  632         print_backtrace(NULL);
  633         splx(spl);
  634         return;
  635 }
  636 
  637 /*
  638  *              Here's where we attempt to get some diagnostic information dumped out
  639  *              when the system is really confused.  We will try to get into the 
  640  *              debugger as well.
  641  *
  642  *              We are here with interrupts disabled and on the debug stack.  The savearea
  643  *              that was passed in is NOT chained to the activation.
  644  *
  645  *              save_r3 contains the failure reason code.
  646  */
  647 
  648 void SysChoked(int type, savearea *sv) {                        /* The system is bad dead */
  649 
  650         unsigned int failcode;
  651         
  652         mp_disable_preemption();
  653         disableDebugOuput = FALSE;
  654         debug_mode = TRUE;
  655 
  656         failcode = (unsigned int)sv->save_r3;                   /* Get the failure code */
  657         if(failcode > failUnknown) failcode = failUnknown;      /* Set unknown code code */
  658         
  659         kprintf("System Failure: cpu=%d; code=%08X (%s)\n", cpu_number(), (unsigned int)sv->save_r3, failNames[failcode]);
  660         kdb_printf("System Failure: cpu=%d; code=%08X (%s)\n", cpu_number(), (unsigned int)sv->save_r3, failNames[failcode]);
  661 
  662         print_backtrace(sv);                                                    /* Attempt to print backtrace */
  663         Call_DebuggerC(type, sv);                                               /* Attempt to get into debugger */
  664 
  665         if ((current_debugger != NO_CUR_DB)) Call_DebuggerC(type, sv);  /* Attempt to get into debugger */
  666 
  667 }
  668 
  669 
  670 
  671 /*
  672  *      When we get here, interruptions are disabled and we are on the debugger stack
  673  *      Never, ever, ever, ever enable interruptions from here on
  674  */
  675 
  676 int Call_DebuggerC(
  677         int     type,
  678         struct savearea *saved_state)
  679 {
  680         int                             directcall, wait;
  681         addr64_t                instr_ptr;
  682         ppnum_t                 instr_pp;
  683         unsigned int    instr;
  684         int                     my_cpu, tcpu, wasdebugger;
  685         struct per_proc_info *pp;
  686         uint64_t nowtime, poptime;
  687 
  688         my_cpu = cpu_number();                                                          /* Get our CPU */
  689 
  690 #if     MACH_KDB
  691         if((debugger_cpu == my_cpu) &&                                          /* Do we already own debugger? */
  692           PerProcTable[my_cpu].ppe_vaddr->debugger_active &&                                            /* and are we really active? */
  693           db_recover &&                                                                         /* and have we set up recovery? */
  694           (current_debugger == KDB_CUR_DB)) {                           /* and are we in KDB (only it handles recovery) */
  695                 kdb_trap(type, saved_state);                                    /* Then reenter it... */
  696         }
  697 #endif
  698         
  699         hw_atomic_add(&debug_mode, 1);                                          /* Indicate we are in debugger */
  700         PerProcTable[my_cpu].ppe_vaddr->debugger_active++;      /* Show active on our CPU */
  701         
  702         lock_debugger();                                                                        /* Insure that only one CPU is in debugger */
  703 
  704         if(db_im_stepping == my_cpu) {                                          /* Are we just back from a step? */
  705                 enable_preemption_no_check();                                   /* Enable preemption now */
  706                 db_im_stepping = 0xFFFFFFFF;                                    /* Nobody stepping right now */
  707         }
  708 
  709         if (debugger_debug) {
  710 #if 0
  711                 kprintf("Call_DebuggerC(%d): %08X %08X, debact = %d\n", my_cpu, type, saved_state, debug_mode); /* (TEST/DEBUG) */
  712 #endif
  713                 printf("Call_Debugger: enter - cpu %d, is_slave %d, debugger_cpu %d, pc %08X\n",
  714                    my_cpu, PerProcTable[my_cpu].ppe_vaddr->debugger_is_slave, debugger_cpu, saved_state->save_srr0);
  715         }
  716         
  717         instr_pp = (vm_offset_t)pmap_find_phys(kernel_pmap, (addr64_t)(saved_state->save_srr0));
  718 
  719         if (instr_pp) {
  720                 instr_ptr = (addr64_t)(((addr64_t)instr_pp << 12) | (saved_state->save_srr0 & 0xFFF));  /* Make physical address */
  721                 instr = ml_phys_read_64(instr_ptr);                             /* Get the trap that caused entry */
  722         } 
  723         else instr = 0;
  724 
  725 #if 0
  726         if (debugger_debug) kprintf("Call_DebuggerC(%d): instr_pp = %08X, instr_ptr = %016llX, instr = %08X\n", my_cpu, instr_pp, instr_ptr, instr);    /* (TEST/DEBUG) */
  727 #endif
  728 
  729         if (db_breakpoints_inserted) cpus_holding_bkpts++;      /* Bump up the holding count */
  730         if (debugger_cpu == -1 && !PerProcTable[my_cpu].ppe_vaddr->debugger_is_slave) {
  731 #if 0
  732                 if (debugger_debug) kprintf("Call_DebuggerC(%d): lasttrace = %08X\n", my_cpu, lastTrace);       /* (TEST/DEBUG) */
  733 #endif
  734                 debugger_cpu = my_cpu;                                                  /* Show that we are debugger */
  735 
  736 
  737                 lastTrace = LLTraceSet(0);                                              /* Disable low-level tracing */
  738 
  739                 for(tcpu = 0; tcpu < real_ncpus; tcpu++) {              /* Stop all the other guys */
  740                         if(tcpu == my_cpu) continue;                            /* Don't diddle ourselves */
  741                         hw_atomic_add(&debugger_sync, 1);                       /* Count signal sent */
  742                         (void)cpu_signal(tcpu, SIGPdebug, 0 ,0);        /* Tell 'em to enter debugger */
  743                 }
  744                 (void)hw_cpu_sync(&debugger_sync, LockTimeOut); /* Wait for the other processors to enter debug */
  745                 debugger_sync = 0;                                                              /* We're done with it */
  746         } 
  747         else if (debugger_cpu != my_cpu)  goto debugger_exit;   /* We are not debugger, don't continue... */
  748         
  749 
  750         if (instr == TRAP_DIRECT_INST) {
  751                 disableDebugOuput = FALSE;
  752                 print_backtrace(saved_state);
  753         }
  754 
  755         switch_debugger = 0;                                                            /* Make sure switch request is off */
  756         directcall = 1;                                                                         /* Assume direct call */
  757 
  758         if (saved_state->save_srr1 & MASK(SRR1_PRG_TRAP)) {     /* Trap instruction? */
  759                 
  760                 directcall = 0;                                                                 /* We had a trap not a direct call */
  761 
  762                 switch (instr) {                                                                /* Select trap type */
  763 
  764 #if     MACH_KDP
  765                         case BREAK_TO_KDP0:                                                     /* Breakpoint into KDP? */
  766                         case BREAK_TO_KDP1:                                                     /* Breakpoint into KDP? */
  767                                 current_debugger = KDP_CUR_DB;                  /* Yes, set KDP */
  768                                 kdp_trap(type, saved_state);                    /* Enter it */
  769                                 break;
  770 #endif
  771         
  772 #if     MACH_KDB
  773                         case BREAK_TO_KDB0:                                             /* Breakpoint to KDB (the "good" debugger)? */
  774                                 current_debugger = KDB_CUR_DB;                  /* Yes, set it */
  775                                 kdb_trap(type, saved_state);                    /* Enter it */
  776                                 break;
  777 #endif
  778                                 
  779                         case TRAP_DEBUGGER_INST:                                        /* Should we enter the current debugger? */
  780                         case TRAP_DIRECT_INST:                                          /* Should we enter the current debugger? */
  781                                 if (current_debugger == KDP_CUR_DB)     /* Is current KDP? */
  782                                         kdp_trap(type, saved_state);            /* Yes, enter it */
  783                                 else if (current_debugger == KDB_CUR_DB)        /* Is this KDB? */
  784                                         kdb_trap(type, saved_state);            /* Yes, go ahead and enter */
  785                                 else goto debugger_error;                               /* No debugger active */
  786                                 break;
  787                                 
  788                         default:                                                                        /* Unknown/bogus trap type */
  789                                 goto debugger_error;
  790                 }
  791         }
  792 
  793         while(1) {                                                                                      /* We are here to handle debugger switches */
  794                 
  795                 if(!directcall) {                                                               /* Was this a direct call? */
  796                         if(!switch_debugger) break;                                     /* No, then leave if no switch requested... */
  797 
  798 /*
  799  *                      Note: we can only switch to a debugger we have.  Ignore bogus switch requests.
  800  */
  801 #if 0
  802                         if (debugger_debug) kprintf("Call_DebuggerC(%d): switching debuggers\n", my_cpu);       /* (TEST/DEBUG) */
  803 #endif
  804 #if MACH_KDB
  805                         if(current_debugger == KDP_CUR_DB) current_debugger = KDB_CUR_DB; /* Switch to KDB */
  806 #if MACH_KDP
  807                         else 
  808 #endif
  809 #endif
  810 #if MACH_KDP
  811                         if(current_debugger == KDB_CUR_DB) current_debugger = KDP_CUR_DB;               /* Switch to KDP */
  812 #endif
  813                 }
  814                 
  815                 switch_debugger = 0;                                                    /* Clear request */
  816                 directcall = 0;                                                                 /* Clear first-time direct call indication */
  817 
  818                 switch (current_debugger) {                                             /* Enter correct debugger */
  819                 
  820                         case KDP_CUR_DB:                                                        /* Enter KDP */
  821                                 kdp_trap(type, saved_state);
  822                                 break;
  823                                 
  824                         case KDB_CUR_DB:                                                        /* Enter KDB */
  825                                 kdb_trap(type, saved_state);
  826                                 break;
  827                                 
  828                         default:                                                                        /* No debugger installed */
  829                                 goto debugger_error;
  830                                 break;
  831                 }
  832         }
  833 
  834 debugger_exit:
  835 #if 0
  836         if (debugger_debug) kprintf("Call_DebuggerC(%d): exit - inst = %08X, cpu=%d(%d), run=%d\n", my_cpu, 
  837                 instr, my_cpu, debugger_cpu, db_run_mode);      /* (TEST/DEBUG) */
  838 #endif
  839         if ((instr == TRAP_DEBUGGER_INST) ||                            /* Did we trap to enter debugger? */
  840                 (instr == TRAP_DIRECT_INST)) saved_state->save_srr0 += TRAP_INST_SIZE;  /* Yes, point past trap */
  841 
  842         wasdebugger = 0;                                                                        /* Assume not debugger */
  843         if(debugger_cpu == my_cpu) {                                            /* Are the debugger processor? */
  844                 wasdebugger = 1;                                                                /* Remember that we were the debugger */
  845                 LLTraceSet(lastTrace);                                                  /* Enable tracing on the way out if we are debugger */
  846         }
  847 
  848         wait = FALSE;                                                                           /* Assume we are not going to wait */
  849         if (db_run_mode == STEP_CONTINUE) {                                     /* Are we going to run? */
  850                 wait = TRUE;                                                                    /* Yeah, remember to wait for breakpoints to clear */
  851                 debugger_cpu = -1;                                                              /* Release other processor's debuggers */
  852                 for(tcpu = 0; tcpu < real_ncpus; tcpu++)
  853                         PerProcTable[tcpu].ppe_vaddr->debugger_pending = 0;     /* Release request (this is a HACK) */
  854                 NMIss = 0;                                                                              /* Let NMI bounce */
  855         }
  856         
  857         if(db_run_mode == STEP_ONCE) {                                          /* Are we about to step? */
  858                 disable_preemption();                                                   /* Disable preemption for the step */
  859                 db_im_stepping = my_cpu;                                                /* Remember that I am about to step */
  860         }
  861 
  862         if (db_breakpoints_inserted) cpus_holding_bkpts--;      /* If any breakpoints, back off count */
  863         if (PerProcTable[my_cpu].ppe_vaddr->debugger_is_slave) PerProcTable[my_cpu].ppe_vaddr->debugger_is_slave--;     /* If we were a slove, uncount us */
  864         if (debugger_debug)
  865                 printf("Call_Debugger: exit - cpu %d, debugger_cpu %d, run_mode %d holds %d\n",
  866                           my_cpu, debugger_cpu, db_run_mode,
  867                           cpus_holding_bkpts);
  868 
  869         unlock_debugger();                                                                      /* Release the lock */
  870         PerProcTable[my_cpu].ppe_vaddr->debugger_active--;      /* Say we aren't active anymore */
  871 
  872         if (wait) while(cpus_holding_bkpts);                            /* Wait for breakpoints to clear */
  873 
  874 
  875         hw_atomic_sub(&debug_mode, 1);                                          /* Set out of debug now */
  876 
  877         return(1);                                                                                      /* Exit debugger normally */
  878 
  879 debugger_error:
  880         if(db_run_mode != STEP_ONCE) enable_preemption_no_check();      /* Enable preemption, but don't preempt here */
  881         hw_atomic_sub(&debug_mode, 1);                                          /* Set out of debug now */
  882         return(0);                                                                                      /* Return in shame... */
  883 
  884 }
  885 
  886 void lock_debugger(void) {
  887         int             my_cpu;
  888         register int    i;
  889 
  890         my_cpu = cpu_number();                                                          /* Get our CPU number */
  891 
  892         while(1) {                                                                                      /* Check until we get it */
  893 
  894                 if (debugger_cpu != -1 && debugger_cpu != my_cpu) continue;     /* Someone, not us, is debugger... */
  895                 if (hw_lock_try(&debugger_lock)) {                              /* Get the debug lock */                        
  896                         if (debugger_cpu == -1 || debugger_cpu == my_cpu) break;        /* Is it us? */
  897                         hw_lock_unlock(&debugger_lock);                         /* Not us, release lock */
  898                 }
  899         } 
  900 }
  901 
  902 void unlock_debugger(void) {
  903 
  904         hw_lock_unlock(&debugger_lock);
  905 
  906 }
  907 
  908 struct pasc {
  909   unsigned a: 7;
  910   unsigned b: 7;
  911   unsigned c: 7;
  912   unsigned d: 7;
  913   unsigned e: 7;
  914   unsigned f: 7;
  915   unsigned g: 7;
  916   unsigned h: 7;
  917 }  __attribute__((packed));
  918 
  919 typedef struct pasc pasc_t;
  920 
  921 int packAsc (unsigned char *inbuf, unsigned int length)
  922 {
  923   unsigned int i, j = 0;
  924   pasc_t pack;
  925 
  926   for (i = 0; i < length; i+=8)
  927     {
  928       pack.a = inbuf[i];
  929       pack.b = inbuf[i+1];
  930       pack.c = inbuf[i+2];
  931       pack.d = inbuf[i+3];
  932       pack.e = inbuf[i+4];
  933       pack.f = inbuf[i+5];
  934       pack.g = inbuf[i+6];
  935       pack.h = inbuf[i+7];
  936       bcopy ((char *) &pack, inbuf + j, 7);
  937       j += 7;
  938     }
  939   if (0 != (i - length))
  940     inbuf[j - (i - length)] &= 0xFF << (8-(i - length));
  941   return j-(((i-length) == 7) ? 6 : (i - length));
  942 }

Cache object: 70ccf03055b0f5d49814e052da404286


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.