]> git.saurik.com Git - apple/xnu.git/blame - osfmk/ppc/ppc_init.c
xnu-201.tar.gz
[apple/xnu.git] / osfmk / ppc / ppc_init.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 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#include <debug.h>
27#include <mach_kdb.h>
28#include <mach_kdp.h>
29
30#include <kern/misc_protos.h>
31#include <kern/thread.h>
32#include <kern/processor.h>
33#include <machine/machine_routines.h>
34#include <ppc/boot.h>
35#include <ppc/proc_reg.h>
36#include <ppc/misc_protos.h>
37#include <ppc/pmap.h>
38#include <ppc/new_screen.h>
39#include <ppc/exception.h>
40#include <ppc/Firmware.h>
41#include <ppc/savearea.h>
42#include <ppc/low_trace.h>
43#include <ppc/Diagnostics.h>
44
45#include <pexpert/pexpert.h>
46
47extern const char version[];
48extern const char version_variant[];
49
50extern unsigned int intstack_top_ss; /* declared in start.s */
1c79356b
A
51extern unsigned int debstackptr; /* declared in start.s */
52extern unsigned int debstack_top_ss; /* declared in start.s */
1c79356b
A
53
54extern void thandler(void); /* trap handler */
55extern void ihandler(void); /* interrupt handler */
56extern void shandler(void); /* syscall handler */
0b4e3aa0 57extern void chandler(void); /* system choke */
1c79356b
A
58extern void fpu_switch(void); /* fp handler */
59extern void vec_switch(void); /* vector handler */
60extern void atomic_switch_trap(void); /* fast path atomic thread switch */
61
62void (*exception_handlers[])(void) = {
63 thandler, /* 0x000 INVALID EXCEPTION (T_IN_VAIN) */
64 thandler, /* 0x100 System reset (T_RESET) */
65 thandler, /* 0x200 Machine check (T_MACHINE_CHECK) */
66 thandler, /* 0x300 Data access (T_DATA_ACCESS) */
67 thandler, /* 0x400 Instruction access (T_INSTRUCTION_ACCESS) */
68 ihandler, /* 0x500 External interrupt (T_INTERRUPT) */
69 thandler, /* 0x600 Alignment (T_ALIGNMENT) */
70 thandler, /* 0x700 fp exc, ill/priv instr, trap (T_PROGRAM) */
71 fpu_switch, /* 0x800 Floating point disabled (T_FP_UNAVAILABLE) */
72 ihandler, /* 0x900 Decrementer (T_DECREMENTER) */
73 thandler, /* 0xA00 I/O controller interface (T_IO_ERROR) */
74 thandler, /* 0xB00 INVALID EXCEPTION (T_RESERVED) */
75 shandler, /* 0xC00 System call exception (T_SYSTEM_CALL) */
76 thandler, /* 0xD00 Trace (T_TRACE) */
77 thandler, /* 0xE00 FP assist (T_FP_ASSIST) */
78 thandler, /* 0xF00 Performance monitor (T_PERF_MON) */
79 vec_switch, /* 0xF20 VMX (T_VMX) */
80 thandler, /* 0x1000 INVALID EXCEPTION (T_INVALID_EXCP0) */
81 thandler, /* 0x1100 INVALID EXCEPTION (T_INVALID_EXCP1) */
82 thandler, /* 0x1200 INVALID EXCEPTION (T_INVALID_EXCP2) */
83 thandler, /* 0x1300 instruction breakpoint (T_INSTRUCTION_BKPT) */
84 ihandler, /* 0x1400 system management (T_SYSTEM_MANAGEMENT) */
85 thandler, /* 0x1600 Altivec Assist (T_ALTIVEC_ASSIST) */
86 ihandler, /* 0x1700 Thermal interruption (T_THERMAL) */
87 thandler, /* 0x1800 INVALID EXCEPTION (T_INVALID_EXCP5) */
88 thandler, /* 0x1900 INVALID EXCEPTION (T_INVALID_EXCP6) */
89 thandler, /* 0x1A00 INVALID EXCEPTION (T_INVALID_EXCP7) */
90 thandler, /* 0x1B00 INVALID EXCEPTION (T_INVALID_EXCP8) */
91 thandler, /* 0x1C00 INVALID EXCEPTION (T_INVALID_EXCP9) */
92 thandler, /* 0x1D00 INVALID EXCEPTION (T_INVALID_EXCP10) */
93 thandler, /* 0x1E00 INVALID EXCEPTION (T_INVALID_EXCP11) */
94 thandler, /* 0x1F00 INVALID EXCEPTION (T_INVALID_EXCP12) */
95 thandler, /* 0x1F00 INVALID EXCEPTION (T_INVALID_EXCP13) */
96 thandler, /* 0x2000 Run Mode/Trace (T_RUNMODE_TRACE) */
97
98 ihandler, /* Software Signal processor (T_SIGP) */
99 thandler, /* Software Preemption (T_PREEMPT) */
100 ihandler, /* Software INVALID EXCEPTION (T_CSWITCH) */
0b4e3aa0
A
101 ihandler, /* Software Shutdown Context (T_SHUTDOWN) */
102 chandler /* Software System choke (crash) (T_CHOKE) */
1c79356b
A
103};
104
105int pc_trace_buf[1024] = {0};
106int pc_trace_cnt = 1024;
107
108void ppc_init(boot_args *args)
109{
110 int i;
111 unsigned long *src,*dst;
112 char *str;
113 unsigned long addr, videoAddr;
114 unsigned int maxmem;
115 bat_t bat;
116 extern vm_offset_t static_memory_end;
117
118 /*
119 * Setup per_proc info for first cpu.
120 */
121
122 per_proc_info[0].cpu_number = 0;
123 per_proc_info[0].cpu_flags = 0;
124 per_proc_info[0].istackptr = 0; /* we're on the interrupt stack */
125 per_proc_info[0].intstack_top_ss = intstack_top_ss;
1c79356b
A
126 per_proc_info[0].debstackptr = debstackptr;
127 per_proc_info[0].debstack_top_ss = debstack_top_ss;
0b4e3aa0 128 per_proc_info[0].interrupts_enabled = 0;
1c79356b
A
129 per_proc_info[0].active_kloaded = (unsigned int)
130 &active_kloaded[0];
131 per_proc_info[0].cpu_data = (unsigned int)
132 &cpu_data[0];
133 per_proc_info[0].active_stacks = (unsigned int)
134 &active_stacks[0];
135 per_proc_info[0].need_ast = (unsigned int)
136 &need_ast[0];
137 per_proc_info[0].FPU_thread = 0;
138 per_proc_info[0].FPU_vmmCtx = 0;
139 per_proc_info[0].VMX_thread = 0;
140 per_proc_info[0].VMX_vmmCtx = 0;
141
142 machine_slot[0].is_cpu = TRUE;
143
144 cpu_init();
145
146 /*
147 * Setup some processor related structures to satisfy funnels.
148 * Must be done before using unparallelized device drivers.
149 */
150 processor_ptr[0] = &processor_array[0];
151 master_cpu = 0;
152 master_processor = cpu_to_processor(master_cpu);
153
154 /* Set up segment registers as VM through space 0 */
155 for (i=0; i<=15; i++) {
156 isync();
157 mtsrin((KERNEL_SEG_REG0_VALUE | (i << 20)), i * 0x10000000);
158 sync();
159 }
160
161 static_memory_end = round_page(args->topOfKernelData);;
162 /* Get platform expert set up */
163 PE_init_platform(FALSE, args);
164
165
166 /* This is how the BATs get configured */
167 /* IBAT[0] maps Segment 0 1:1 */
168 /* DBAT[0] maps Segment 0 1:1 */
169 /* DBAT[2] maps the I/O Segment 1:1 */
170 /* DBAT[3] maps the Video Segment 1:1 */
171
172 /* If v_baseAddr is non zero, use DBAT3 to map the video segment */
173 videoAddr = args->Video.v_baseAddr & 0xF0000000;
174 if (videoAddr) {
175 /* start off specifying 1-1 mapping of video seg */
176 bat.upper.word = videoAddr;
177 bat.lower.word = videoAddr;
178
179 bat.upper.bits.bl = 0x7ff; /* size = 256M */
180 bat.upper.bits.vs = 1;
181 bat.upper.bits.vp = 0;
182
183 bat.lower.bits.wimg = PTE_WIMG_IO;
184 bat.lower.bits.pp = 2; /* read/write access */
185
186 sync();isync();
187 mtdbatu(3, BAT_INVALID); /* invalidate old mapping */
188 mtdbatl(3, bat.lower.word);
189 mtdbatu(3, bat.upper.word);
190 sync();isync();
191 }
192
193 /* Use DBAT2 to map the io segment */
194 addr = get_io_base_addr() & 0xF0000000;
195 if (addr != videoAddr) {
196 /* start off specifying 1-1 mapping of io seg */
197 bat.upper.word = addr;
198 bat.lower.word = addr;
199
200 bat.upper.bits.bl = 0x7ff; /* size = 256M */
201 bat.upper.bits.vs = 1;
202 bat.upper.bits.vp = 0;
203
204 bat.lower.bits.wimg = PTE_WIMG_IO;
205 bat.lower.bits.pp = 2; /* read/write access */
206
207 sync();isync();
208 mtdbatu(2, BAT_INVALID); /* invalidate old mapping */
209 mtdbatl(2, bat.lower.word);
210 mtdbatu(2, bat.upper.word);
211 sync();isync();
212 }
213
214 if (!PE_parse_boot_arg("diag", &dgWork.dgFlags)) dgWork.dgFlags=0; /* Set diagnostic flags */
215 if(dgWork.dgFlags & enaExpTrace) trcWork.traceMask = 0xFFFFFFFF; /* If tracing requested, enable it */
216
217#if 0
218 GratefulDebInit((bootBumbleC *)&(args->Video)); /* Initialize the GratefulDeb debugger */
219#endif
220
221 printf_init(); /* Init this in case we need debugger */
222 panic_init(); /* Init this in case we need debugger */
223
224 /* setup debugging output if one has been chosen */
225 PE_init_kprintf(FALSE);
226 kprintf("kprintf initialized\n");
227
228 /* create the console for verbose or pretty mode */
229 PE_create_console();
230
231 /* setup console output */
232 PE_init_printf(FALSE);
233
234 kprintf("version_variant = %s\n", version_variant);
235 kprintf("version = %s\n", version);
236
237#if DEBUG
238 printf("\n\n\nThis program was compiled using gcc %d.%d for powerpc\n",
239 __GNUC__,__GNUC_MINOR__);
240
241 /* Processor version information */
242 {
243 unsigned int pvr;
244 __asm__ ("mfpvr %0" : "=r" (pvr));
245 printf("processor version register : 0x%08x\n",pvr);
246 }
247 for (i = 0; i < kMaxDRAMBanks; i++) {
248 if (args->PhysicalDRAM[i].size)
249 printf("DRAM at 0x%08x size 0x%08x\n",
250 args->PhysicalDRAM[i].base,
251 args->PhysicalDRAM[i].size);
252 }
253#endif /* DEBUG */
254
255 /*
256 * VM initialization, after this we're using page tables...
257 */
258 if (!PE_parse_boot_arg("maxmem", &maxmem))
259 maxmem=0;
260 else
261 maxmem = maxmem * (1024 * 1024);
262
263 ppc_vm_init(maxmem, args);
264
265 PE_init_platform(TRUE, args);
266
267 machine_startup(args);
268}
269
270ppc_init_cpu(
271 struct per_proc_info *proc_info)
272{
273 int i;
274 unsigned int gph;
275 savectl *sctl; /* Savearea controls */
276
277 if(proc_info->savedSave) { /* Do we have a savearea set up already? */
278 mtsprg(1, proc_info->savedSave); /* Set saved address of savearea */
279 }
280 else {
281 gph = (unsigned int)save_get_phys(); /* Get a savearea (physical addressing) */
282 mtsprg(1, gph); /* Set physical address of savearea */
283 }
284
285 cpu_init();
286
287 proc_info->Lastpmap = 0; /* Clear last used space */
288
289 /* Set up segment registers as VM through space 0 */
290 for (i=0; i<=15; i++) {
291 isync();
292 mtsrin((KERNEL_SEG_REG0_VALUE | (i << 20)), i * 0x10000000);
293 sync();
294 }
295
296 ppc_vm_cpu_init(proc_info);
297
298 ml_thrm_init(); /* Start thermal monitoring on this processor */
299
300 slave_main();
301}