]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ppc/ppc_init.c
xnu-344.23.tar.gz
[apple/xnu.git] / osfmk / ppc / ppc_init.c
index 7c3f7a70dbc157b7ce1ee7c68e5ae261523c455a..e52131729d99de7cbed2846a03ca57c0838f7b9b 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@
  */
@@ -27,7 +24,6 @@
  */
 
 #include <debug.h>
-#include <mach_ldebug.h>
 #include <mach_kdb.h>
 #include <mach_kdp.h>
 
 #include <ppc/low_trace.h>
 #include <ppc/Diagnostics.h>
 #include <ppc/mem.h>
-#include <ppc/mappings.h>
 
 #include <pexpert/pexpert.h>
 
+extern const char version[];
+extern const char version_variant[];
+
 extern unsigned int intstack_top_ss;   /* declared in start.s */
-extern unsigned int debstackptr;               /* declared in start.s */
+extern unsigned int debstackptr;       /* declared in start.s */
 extern unsigned int debstack_top_ss;   /* declared in start.s */
 
+extern void thandler(void);     /* trap handler */
+extern void ihandler(void);     /* interrupt handler */
+extern void shandler(void);     /* syscall handler */
+extern void chandler(void);     /* system choke */
+extern void fpu_switch(void);   /* fp handler */
+extern void vec_switch(void);   /* vector handler */
+extern void atomic_switch_trap(void);   /* fast path atomic thread switch */
+
+void (*exception_handlers[])(void) = {
+       thandler,       /* 0x000   INVALID EXCEPTION (T_IN_VAIN) */
+       thandler,       /* 0x100   System reset (T_RESET) */
+       thandler,       /* 0x200   Machine check (T_MACHINE_CHECK) */
+       thandler,       /* 0x300   Data access (T_DATA_ACCESS) */
+       thandler,       /* 0x400   Instruction access (T_INSTRUCTION_ACCESS) */
+       ihandler,       /* 0x500   External interrupt (T_INTERRUPT) */
+       thandler,       /* 0x600   Alignment (T_ALIGNMENT) */
+       thandler,       /* 0x700   fp exc, ill/priv instr, trap  (T_PROGRAM) */
+       fpu_switch,     /* 0x800   Floating point disabled (T_FP_UNAVAILABLE) */
+       ihandler,       /* 0x900   Decrementer (T_DECREMENTER) */
+       thandler,       /* 0xA00   I/O controller interface (T_IO_ERROR) */
+       thandler,       /* 0xB00   INVALID EXCEPTION (T_RESERVED) */
+       shandler,       /* 0xC00   System call exception (T_SYSTEM_CALL) */
+       thandler,       /* 0xD00   Trace (T_TRACE) */
+       thandler,       /* 0xE00   FP assist (T_FP_ASSIST) */
+       thandler,       /* 0xF00   Performance monitor (T_PERF_MON) */
+       vec_switch,     /* 0xF20   VMX (T_VMX) */
+       thandler,       /* 0x1000  INVALID EXCEPTION (T_INVALID_EXCP0) */
+       thandler,       /* 0x1100  INVALID EXCEPTION (T_INVALID_EXCP1) */
+       thandler,       /* 0x1200  INVALID EXCEPTION (T_INVALID_EXCP2) */
+       thandler,       /* 0x1300  instruction breakpoint (T_INSTRUCTION_BKPT) */
+       ihandler,       /* 0x1400  system management (T_SYSTEM_MANAGEMENT) */
+       thandler,       /* 0x1600  Altivec Assist (T_ALTIVEC_ASSIST) */
+       ihandler,       /* 0x1700  Thermal interruption (T_THERMAL) */
+       thandler,       /* 0x1800  INVALID EXCEPTION (T_INVALID_EXCP5) */
+       thandler,       /* 0x1900  INVALID EXCEPTION (T_INVALID_EXCP6) */
+       thandler,       /* 0x1A00  INVALID EXCEPTION (T_INVALID_EXCP7) */
+       thandler,       /* 0x1B00  INVALID EXCEPTION (T_INVALID_EXCP8) */
+       thandler,       /* 0x1C00  INVALID EXCEPTION (T_INVALID_EXCP9) */
+       thandler,       /* 0x1D00  INVALID EXCEPTION (T_INVALID_EXCP10) */
+       thandler,       /* 0x1E00  INVALID EXCEPTION (T_INVALID_EXCP11) */
+       thandler,       /* 0x1F00  INVALID EXCEPTION (T_INVALID_EXCP12) */
+       thandler,       /* 0x1F00  INVALID EXCEPTION (T_INVALID_EXCP13) */
+       thandler,       /* 0x2000  Run Mode/Trace (T_RUNMODE_TRACE) */
+
+       ihandler,       /* Software  Signal processor (T_SIGP) */
+       thandler,       /* Software  Preemption (T_PREEMPT) */
+       ihandler,       /* Software  INVALID EXCEPTION (T_CSWITCH) */ 
+       ihandler,       /* Software  Shutdown Context (T_SHUTDOWN) */
+       chandler        /* Software  System choke (crash) (T_CHOKE) */
+};
+
 int pc_trace_buf[1024] = {0};
 int pc_trace_cnt = 1024;
 
-extern unsigned int extPatchMCK;
-extern unsigned int extPatch32;
-extern unsigned int hwulckPatch_isync;
-extern unsigned int hwulckPatch_eieio;
-extern unsigned int hwulckbPatch_isync;
-extern unsigned int hwulckbPatch_eieio;
-extern unsigned int mulckPatch_isync;
-extern unsigned int mulckPatch_eieio;
-extern unsigned int sulckPatch_isync;
-extern unsigned int sulckPatch_eieio;
-extern unsigned int retfsectPatch_eieio;
-extern unsigned int retfsectPatch_isync;
-
-int forcenap = 0;
-
-patch_entry_t patch_table[PATCH_TABLE_SIZE] = {
-       &extPatch32,                    0x60000000, PATCH_FEATURE,              PatchExt32,
-       &extPatchMCK,                   0x60000000, PATCH_PROCESSOR,    CPU_SUBTYPE_POWERPC_970,
-       &hwulckPatch_isync,             0x60000000, PATCH_FEATURE,              PatchLwsync,
-       &hwulckPatch_eieio,             0x7c2004ac, PATCH_FEATURE,              PatchLwsync,
-       &hwulckbPatch_isync,            0x60000000, PATCH_FEATURE,              PatchLwsync,
-       &hwulckbPatch_eieio,            0x7c2004ac, PATCH_FEATURE,              PatchLwsync,
-       &mulckPatch_isync,              0x60000000, PATCH_FEATURE,              PatchLwsync,
-       &mulckPatch_eieio,              0x7c2004ac, PATCH_FEATURE,              PatchLwsync,
-       &sulckPatch_isync,              0x60000000, PATCH_FEATURE,              PatchLwsync,
-       &sulckPatch_eieio,              0x7c2004ac, PATCH_FEATURE,              PatchLwsync,
-#if    !MACH_LDEBUG
-       &retfsectPatch_isync,   0x60000000, PATCH_FEATURE,              PatchLwsync,
-       &retfsectPatch_eieio,   0x7c2004ac, PATCH_FEATURE,              PatchLwsync
-#else
-       0,                                              0,                      PATCH_INVALID,          0,
-       0,                                              0,                      PATCH_INVALID,          0
-#endif
-       };
-
 void ppc_init(boot_args *args)
 {
        int i;
@@ -99,11 +113,9 @@ void ppc_init(boot_args *args)
        char *str;
        unsigned long   addr, videoAddr;
        unsigned int    maxmem;
-       uint64_t                xmaxmem;
        unsigned int    cputrace;
-       unsigned int    novmx;
+       bat_t               bat;
        extern vm_offset_t static_memory_end;
-       mapping *mp;
        
        /*
         * Setup per_proc info for first cpu.
@@ -122,11 +134,7 @@ void ppc_init(boot_args *args)
        set_machine_current_act(&pageout_act);
        pageout_thread.top_act = &pageout_act;
        pageout_act.thread = &pageout_thread;
-       pageout_act.mact.curctx = &pageout_act.mact.facctx;
-       pageout_act.mact.facctx.facAct = &pageout_act;
-       pageout_act.mact.cioSpace = invalSpace;                                 /* Initialize copyin/out space to invalid */
-       pageout_act.mact.preemption_count = 1;
-       per_proc_info[0].pp_preemption_count = -1;
+       per_proc_info[0].pp_preemption_count = 1;
        per_proc_info[0].pp_simple_lock_count = 0;
        per_proc_info[0].pp_interrupt_level = 0;
        per_proc_info[0].active_stacks = (unsigned int)
@@ -135,9 +143,6 @@ void ppc_init(boot_args *args)
                &need_ast[0];
        per_proc_info[0].FPU_owner = 0;
        per_proc_info[0].VMX_owner = 0;
-       mp = (mapping *)per_proc_info[0].ppCIOmp;
-       mp->mpFlags = 0x01000000 | mpSpecial | 1;
-       mp->mpSpace = invalSpace;
 
        machine_slot[0].is_cpu = TRUE;
 
@@ -151,24 +156,95 @@ void ppc_init(boot_args *args)
        master_cpu = 0;
        master_processor = cpu_to_processor(master_cpu);
 
-       static_memory_end = round_page_32(args->topOfKernelData);;
-      
-       PE_init_platform(FALSE, args);                          /* Get platform expert set up */
-
-       if (!PE_parse_boot_arg("novmx", &novmx)) novmx=0;       /* Special run without VMX? */
-       if(novmx) {                                                                     /* Yeah, turn it off */
-               for(i = 0; i < NCPUS; i++) {                    /* Cycle through all potential processors */
-                       per_proc_info[i].pf.Available &= ~pfAltivec;    /* Turn off Altivec available */
-               }
-               __asm__ volatile("mtsprg 2,%0" : : "r" (per_proc_info[0].pf.Available));        /* Set live value */
+       /* Set up segment registers as VM through space 0 */
+       for (i=0; i<=15; i++) {
+         isync();
+         mtsrin((KERNEL_SEG_REG0_VALUE | (i << 20)), i * 0x10000000);
+         sync();
        }
 
-       if (!PE_parse_boot_arg("fn", &forcenap)) forcenap = 0;  /* If force nap not set, make 0 */
-       else {
-               if(forcenap < 2) forcenap = forcenap + 1;                       /* Else set 1 for off, 2 for on */
-               else forcenap = 0;                                                                      /* Clear for error case */
+       static_memory_end = round_page(args->topOfKernelData);;
+        /* Get platform expert set up */
+       PE_init_platform(FALSE, args);
+
+
+       /* This is how the BATs get configured */
+       /* IBAT[0] maps Segment 0 1:1 */
+       /* DBAT[0] maps Segment 0 1:1 */
+       /* DBAT[2] maps the I/O Segment 1:1 */
+       /* DBAT[3] maps the Video Segment 1:1 */
+
+
+       /* Initialize shadow IBATs */
+       shadow_BAT.IBATs[0].upper=BAT_INVALID;
+       shadow_BAT.IBATs[0].lower=BAT_INVALID;
+       shadow_BAT.IBATs[1].upper=BAT_INVALID;
+       shadow_BAT.IBATs[1].lower=BAT_INVALID;
+       shadow_BAT.IBATs[2].upper=BAT_INVALID;
+       shadow_BAT.IBATs[2].lower=BAT_INVALID;
+       shadow_BAT.IBATs[3].upper=BAT_INVALID;
+       shadow_BAT.IBATs[3].lower=BAT_INVALID;
+
+       /* Initialize shadow DBATs */
+       shadow_BAT.DBATs[0].upper=BAT_INVALID;
+       shadow_BAT.DBATs[0].lower=BAT_INVALID;
+       shadow_BAT.DBATs[1].upper=BAT_INVALID;
+       shadow_BAT.DBATs[1].lower=BAT_INVALID;
+       shadow_BAT.DBATs[2].upper=BAT_INVALID;
+       shadow_BAT.DBATs[2].lower=BAT_INVALID;
+       shadow_BAT.DBATs[3].upper=BAT_INVALID;
+       shadow_BAT.DBATs[3].lower=BAT_INVALID;
+
+
+       /* If v_baseAddr is non zero, use DBAT3 to map the video segment */
+       videoAddr = args->Video.v_baseAddr & 0xF0000000;
+       if (videoAddr) {
+               /* start off specifying 1-1 mapping of video seg */
+               bat.upper.word       = videoAddr;
+               bat.lower.word       = videoAddr;
+               
+               bat.upper.bits.bl    = 0x7ff;   /* size = 256M */
+               bat.upper.bits.vs    = 1;
+               bat.upper.bits.vp    = 0;
+               
+               bat.lower.bits.wimg  = PTE_WIMG_IO;
+               bat.lower.bits.pp    = 2;       /* read/write access */
+                               
+               shadow_BAT.DBATs[3].upper = bat.upper.word;
+               shadow_BAT.DBATs[3].lower = bat.lower.word;
+               
+               sync();isync();
+               
+               mtdbatu(3, BAT_INVALID); /* invalidate old mapping */
+               mtdbatl(3, bat.lower.word);
+               mtdbatu(3, bat.upper.word);
+               sync();isync();
        }
        
+       /* Use DBAT2 to map the io segment */
+       addr = get_io_base_addr() & 0xF0000000;
+       if (addr != videoAddr) {
+               /* start off specifying 1-1 mapping of io seg */
+               bat.upper.word       = addr;
+               bat.lower.word       = addr;
+               
+               bat.upper.bits.bl    = 0x7ff;   /* size = 256M */
+               bat.upper.bits.vs    = 1;
+               bat.upper.bits.vp    = 0;
+               
+               bat.lower.bits.wimg  = PTE_WIMG_IO;
+               bat.lower.bits.pp    = 2;       /* read/write access */
+                               
+               shadow_BAT.DBATs[2].upper = bat.upper.word;
+               shadow_BAT.DBATs[2].lower = bat.lower.word;
+               
+               sync();isync();
+               mtdbatu(2, BAT_INVALID); /* invalidate old mapping */
+               mtdbatl(2, bat.lower.word);
+               mtdbatu(2, bat.upper.word);
+               sync();isync();
+       }
+
        if (!PE_parse_boot_arg("diag", &dgWork.dgFlags)) dgWork.dgFlags=0;      /* Set diagnostic flags */
        if(dgWork.dgFlags & enaExpTrace) trcWork.traceMask = 0xFFFFFFFF;        /* If tracing requested, enable it */
 
@@ -176,29 +252,54 @@ void ppc_init(boot_args *args)
                trcWork.traceMask = (trcWork.traceMask & 0xFFFFFFF0) | (cputrace & 0xF);        /* Limit to 4 */
        }
 
-       if(!PE_parse_boot_arg("tb", &trcWork.traceSize)) {      /* See if non-default trace buffer size */
-#if DEBUG
-               trcWork.traceSize = 32;                                 /* Default 32 page trace table for DEBUG */
-#else
-               trcWork.traceSize = 8;                                  /* Default 8 page trace table for RELEASE */
+#if 0
+       GratefulDebInit((bootBumbleC *)&(args->Video)); /* Initialize the GratefulDeb debugger */
 #endif
-       }
 
-       if(trcWork.traceSize < 1) trcWork.traceSize = 1;        /* Minimum size of 1 page */
-       if(trcWork.traceSize > 256) trcWork.traceSize = 256;    /* Maximum size of 256 pages */
-       trcWork.traceSize = trcWork.traceSize * 4096;   /* Change page count to size */
+       printf_init();                                          /* Init this in case we need debugger */
+       panic_init();                                           /* Init this in case we need debugger */
 
+       /* setup debugging output if one has been chosen */
+       PE_init_kprintf(FALSE);
+       kprintf("kprintf initialized\n");
+
+       /* create the console for verbose or pretty mode */
+       PE_create_console();
+
+       /* setup console output */
+       PE_init_printf(FALSE);
+
+       kprintf("version_variant = %s\n", version_variant);
+       kprintf("version         = %s\n", version);
+
+#if DEBUG
+       printf("\n\n\nThis program was compiled using gcc %d.%d for powerpc\n",
+              __GNUC__,__GNUC_MINOR__);
+
+       /* Processor version information */
+       {       
+               unsigned int pvr;
+               __asm__ ("mfpvr %0" : "=r" (pvr));
+               printf("processor version register : 0x%08x\n",pvr);
+       }
+       for (i = 0; i < kMaxDRAMBanks; i++) {
+               if (args->PhysicalDRAM[i].size) 
+                       printf("DRAM at 0x%08x size 0x%08x\n",
+                              args->PhysicalDRAM[i].base,
+                              args->PhysicalDRAM[i].size);
+       }
+#endif /* DEBUG */
+
+       /*   
+        * VM initialization, after this we're using page tables...
+        */
        if (!PE_parse_boot_arg("maxmem", &maxmem))
-               xmaxmem=0;
+               maxmem=0;
        else
-               xmaxmem = (uint64_t)maxmem * (1024 * 1024);
+               maxmem = maxmem * (1024 * 1024);
 
-/*   
- * VM initialization, after this we're using page tables...
- */
+       ppc_vm_init(maxmem, args);
 
-       ppc_vm_init(xmaxmem, args);
-       
        PE_init_platform(TRUE, args);
        
        machine_startup(args);
@@ -210,10 +311,23 @@ ppc_init_cpu(
        int i;
 
        if(!(proc_info->next_savearea))                 /* Do we have a savearea set up already? */
-               proc_info->next_savearea = (vm_offset_t)save_get_init();        /* Get a savearea  */
+               proc_info->next_savearea = (savearea *)save_get_init(); /* Get a savearea  */
        
        cpu_init();
-       
+
+       proc_info->pp_preemption_count = 1;
+       proc_info->pp_simple_lock_count = 0;
+       proc_info->pp_interrupt_level = 0;
+
+       proc_info->Lastpmap = 0;                                /* Clear last used space */
+
+       /* Set up segment registers as VM through space 0 */
+       for (i=0; i<=15; i++) {
+         isync();
+         mtsrin((KERNEL_SEG_REG0_VALUE | (i << 20)), i * 0x10000000);
+         sync();
+       }
+
        ppc_vm_cpu_init(proc_info);
 
        ml_thrm_init();                                                 /* Start thermal monitoring on this processor */