]>
Commit | Line | Data |
---|---|---|
1c79356b | 1 | /* |
2d21ac55 | 2 | * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. |
1c79356b | 3 | * |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
1c79356b | 5 | * |
2d21ac55 A |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
8f6c56a5 | 14 | * |
2d21ac55 A |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
18 | * The Original Code and all software distributed under the License are | |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
23 | * Please see the License for the specific language governing rights and | |
24 | * limitations under the License. | |
8f6c56a5 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
1c79356b A |
27 | */ |
28 | /* | |
29 | * @OSF_COPYRIGHT@ | |
30 | */ | |
31 | /* | |
32 | * @APPLE_FREE_COPYRIGHT@ | |
33 | */ | |
34 | ||
35 | #include <mach_debug.h> | |
36 | #include <mach_kdb.h> | |
37 | #include <mach_kdp.h> | |
38 | #include <debug.h> | |
1c79356b A |
39 | |
40 | #include <mach/vm_types.h> | |
41 | #include <mach/vm_param.h> | |
42 | #include <mach/thread_status.h> | |
43 | #include <kern/misc_protos.h> | |
44 | #include <kern/assert.h> | |
45 | #include <kern/cpu_number.h> | |
91447636 | 46 | #include <kern/thread.h> |
0c530ab8 | 47 | #include <console/serial_protos.h> |
1c79356b A |
48 | |
49 | #include <ppc/proc_reg.h> | |
50 | #include <ppc/Firmware.h> | |
51 | #include <ppc/boot.h> | |
52 | #include <ppc/misc_protos.h> | |
53 | #include <ppc/pmap.h> | |
1c79356b A |
54 | #include <ppc/mem.h> |
55 | #include <ppc/mappings.h> | |
56 | #include <ppc/exception.h> | |
55e303ae | 57 | #include <ppc/lowglobals.h> |
2d21ac55 | 58 | #include <ppc/serial_io.h> |
1c79356b | 59 | |
1c79356b | 60 | #include <mach-o/mach_header.h> |
1c79356b | 61 | |
55e303ae A |
62 | extern const char version[]; |
63 | extern const char version_variant[]; | |
1c79356b | 64 | |
55e303ae A |
65 | addr64_t hash_table_base; /* Hash table base */ |
66 | unsigned int hash_table_size; /* Hash table size */ | |
91447636 | 67 | int hash_table_shift; /* "ht_shift" boot arg, used to scale hash_table_size */ |
55e303ae A |
68 | vm_offset_t taproot_addr; /* (BRINGUP) */ |
69 | unsigned int taproot_size; /* (BRINGUP) */ | |
55e303ae | 70 | extern int disableConsoleOutput; |
1c79356b | 71 | |
55e303ae | 72 | struct shadowBAT shadow_BAT; |
d7e50217 | 73 | |
3a60a9f5 A |
74 | |
75 | ||
55e303ae A |
76 | /* |
77 | * NOTE: mem_size is bogus on large memory machines. We will pin it to 0x80000000 if there is more than 2 GB | |
78 | * This is left only for compatibility and max_mem should be used. | |
79 | */ | |
80 | vm_offset_t mem_size; /* Size of actual physical memory present | |
81 | minus any performance buffer and possibly limited | |
82 | by mem_limit in bytes */ | |
83 | uint64_t mem_actual; /* The "One True" physical memory size | |
84 | actually, it's the highest physical address + 1 */ | |
85 | uint64_t max_mem; /* Size of physical memory (bytes), adjusted by maxmem */ | |
86 | uint64_t sane_size; /* Memory size to use for defaults calculations */ | |
87 | ||
88 | ||
89 | mem_region_t pmap_mem_regions[PMAP_MEM_REGION_MAX + 1]; | |
2d21ac55 | 90 | unsigned int pmap_mem_regions_count; /* Assume no non-contiguous memory regions */ |
1c79356b A |
91 | |
92 | unsigned int avail_remaining = 0; | |
93 | vm_offset_t first_avail; | |
94 | vm_offset_t static_memory_end; | |
55e303ae | 95 | addr64_t vm_last_addr = VM_MAX_KERNEL_ADDRESS; /* Highest kernel virtual address known to the VM system */ |
1c79356b | 96 | |
1c79356b A |
97 | extern struct mach_header _mh_execute_header; |
98 | vm_offset_t sectTEXTB; | |
99 | int sectSizeTEXT; | |
100 | vm_offset_t sectDATAB; | |
101 | int sectSizeDATA; | |
1c79356b A |
102 | vm_offset_t sectLINKB; |
103 | int sectSizeLINK; | |
104 | vm_offset_t sectKLDB; | |
105 | int sectSizeKLD; | |
55e303ae A |
106 | vm_offset_t sectPRELINKB; |
107 | int sectSizePRELINK; | |
91447636 A |
108 | vm_offset_t sectHIBB; |
109 | int sectSizeHIB; | |
1c79356b A |
110 | |
111 | vm_offset_t end, etext, edata; | |
1c79356b A |
112 | |
113 | extern unsigned long exception_entry; | |
114 | extern unsigned long exception_end; | |
115 | ||
116 | ||
55e303ae | 117 | void ppc_vm_init(uint64_t mem_limit, boot_args *args) |
1c79356b | 118 | { |
91447636 A |
119 | unsigned int i, kmapsize, pvr; |
120 | vm_offset_t addr; | |
55e303ae A |
121 | unsigned int *xtaproot, bank_shift; |
122 | uint64_t cbsize, xhid0; | |
1c79356b | 123 | |
de355530 | 124 | |
55e303ae A |
125 | /* |
126 | * Invalidate all shadow BATs | |
1c79356b | 127 | */ |
1c79356b | 128 | |
55e303ae A |
129 | /* Initialize shadow IBATs */ |
130 | shadow_BAT.IBATs[0].upper=BAT_INVALID; | |
131 | shadow_BAT.IBATs[0].lower=BAT_INVALID; | |
132 | shadow_BAT.IBATs[1].upper=BAT_INVALID; | |
133 | shadow_BAT.IBATs[1].lower=BAT_INVALID; | |
134 | shadow_BAT.IBATs[2].upper=BAT_INVALID; | |
135 | shadow_BAT.IBATs[2].lower=BAT_INVALID; | |
136 | shadow_BAT.IBATs[3].upper=BAT_INVALID; | |
137 | shadow_BAT.IBATs[3].lower=BAT_INVALID; | |
138 | ||
139 | /* Initialize shadow DBATs */ | |
140 | shadow_BAT.DBATs[0].upper=BAT_INVALID; | |
141 | shadow_BAT.DBATs[0].lower=BAT_INVALID; | |
142 | shadow_BAT.DBATs[1].upper=BAT_INVALID; | |
143 | shadow_BAT.DBATs[1].lower=BAT_INVALID; | |
144 | shadow_BAT.DBATs[2].upper=BAT_INVALID; | |
145 | shadow_BAT.DBATs[2].lower=BAT_INVALID; | |
146 | shadow_BAT.DBATs[3].upper=BAT_INVALID; | |
147 | shadow_BAT.DBATs[3].lower=BAT_INVALID; | |
148 | ||
149 | ||
150 | /* | |
151 | * Go through the list of memory regions passed in via the boot_args | |
1c79356b A |
152 | * and copy valid entries into the pmap_mem_regions table, adding |
153 | * further calculated entries. | |
55e303ae A |
154 | * |
155 | * boot_args version 1 has address instead of page numbers | |
156 | * in the PhysicalDRAM banks, set bank_shift accordingly. | |
1c79356b A |
157 | */ |
158 | ||
55e303ae A |
159 | bank_shift = 0; |
160 | if (args->Version == kBootArgsVersion1) bank_shift = 12; | |
161 | ||
1c79356b | 162 | pmap_mem_regions_count = 0; |
55e303ae A |
163 | max_mem = 0; /* Will use to total memory found so far */ |
164 | mem_actual = 0; /* Actual size of memory */ | |
165 | ||
166 | if (mem_limit == 0) mem_limit = 0xFFFFFFFFFFFFFFFFULL; /* If there is no set limit, use all */ | |
167 | ||
168 | for (i = 0; i < kMaxDRAMBanks; i++) { /* Look at all of the banks */ | |
169 | ||
170 | cbsize = (uint64_t)args->PhysicalDRAM[i].size << (12 - bank_shift); /* Remember current size */ | |
171 | ||
172 | if (!cbsize) continue; /* Skip if the bank is empty */ | |
173 | ||
174 | mem_actual = mem_actual + cbsize; /* Get true memory size */ | |
1c79356b | 175 | |
55e303ae | 176 | if(mem_limit == 0) continue; /* If we hit restriction, just keep counting */ |
1c79356b | 177 | |
55e303ae A |
178 | if (cbsize > mem_limit) cbsize = mem_limit; /* Trim to max allowed */ |
179 | max_mem += cbsize; /* Total up what we have so far */ | |
180 | mem_limit = mem_limit - cbsize; /* Calculate amount left to do */ | |
181 | ||
182 | pmap_mem_regions[pmap_mem_regions_count].mrStart = args->PhysicalDRAM[i].base >> bank_shift; /* Set the start of the bank */ | |
183 | pmap_mem_regions[pmap_mem_regions_count].mrAStart = pmap_mem_regions[pmap_mem_regions_count].mrStart; /* Set the start of allocatable area */ | |
184 | pmap_mem_regions[pmap_mem_regions_count].mrEnd = ((uint64_t)args->PhysicalDRAM[i].base >> bank_shift) + (cbsize >> 12) - 1; /* Set the end address of bank */ | |
185 | pmap_mem_regions[pmap_mem_regions_count].mrAEnd = pmap_mem_regions[pmap_mem_regions_count].mrEnd; /* Set the end address of allocatable area */ | |
1c79356b | 186 | |
de355530 A |
187 | /* Regions must be provided in ascending order */ |
188 | assert ((pmap_mem_regions_count == 0) || | |
55e303ae A |
189 | pmap_mem_regions[pmap_mem_regions_count].mrStart > |
190 | pmap_mem_regions[pmap_mem_regions_count-1].mrStart); | |
1c79356b | 191 | |
55e303ae | 192 | pmap_mem_regions_count++; /* Count this region */ |
de355530 | 193 | } |
91447636 | 194 | |
55e303ae A |
195 | mem_size = (unsigned int)max_mem; /* Get size of memory */ |
196 | if(max_mem > 0x0000000080000000ULL) mem_size = 0x80000000; /* Pin at 2 GB */ | |
d7e50217 | 197 | |
55e303ae A |
198 | sane_size = max_mem; /* Calculate a sane value to use for init */ |
199 | if(sane_size > (addr64_t)(VM_MAX_KERNEL_ADDRESS + 1)) | |
200 | sane_size = (addr64_t)(VM_MAX_KERNEL_ADDRESS + 1); /* If flush with ram, use addressible portion */ | |
43866e37 | 201 | |
d7e50217 | 202 | |
55e303ae A |
203 | /* |
204 | * Initialize the pmap system, using space above `first_avail' | |
205 | * for the necessary data structures. | |
206 | * NOTE : assume that we'll have enough space mapped in already | |
207 | */ | |
208 | ||
209 | first_avail = static_memory_end; | |
d7e50217 | 210 | |
2d21ac55 A |
211 | /* |
212 | * Now retrieve addresses for end, edata, and etext | |
213 | * from MACH-O headers for the currently running 32 bit kernel. | |
214 | */ | |
215 | /* XXX fix double casts for 64 bit kernel */ | |
216 | sectTEXTB = (vm_offset_t)(uint32_t *)getsegdatafromheader( | |
55e303ae | 217 | &_mh_execute_header, "__TEXT", §SizeTEXT); |
2d21ac55 | 218 | sectDATAB = (vm_offset_t)(uint32_t *)getsegdatafromheader( |
55e303ae | 219 | &_mh_execute_header, "__DATA", §SizeDATA); |
2d21ac55 | 220 | sectLINKB = (vm_offset_t)(uint32_t *)getsegdatafromheader( |
55e303ae | 221 | &_mh_execute_header, "__LINKEDIT", §SizeLINK); |
2d21ac55 | 222 | sectKLDB = (vm_offset_t)(uint32_t *)getsegdatafromheader( |
55e303ae | 223 | &_mh_execute_header, "__KLD", §SizeKLD); |
2d21ac55 | 224 | sectHIBB = (vm_offset_t)(uint32_t *)getsegdatafromheader( |
91447636 | 225 | &_mh_execute_header, "__HIB", §SizeHIB); |
2d21ac55 | 226 | sectPRELINKB = (vm_offset_t)(uint32_t *)getsegdatafromheader( |
55e303ae A |
227 | &_mh_execute_header, "__PRELINK", §SizePRELINK); |
228 | ||
229 | etext = (vm_offset_t) sectTEXTB + sectSizeTEXT; | |
230 | edata = (vm_offset_t) sectDATAB + sectSizeDATA; | |
91447636 | 231 | end = round_page(getlastaddr()); /* Force end to next page */ |
1c79356b | 232 | |
91447636 A |
233 | kmapsize = (round_page(exception_end) - trunc_page(exception_entry)) + /* Get size we will map later */ |
234 | (round_page(sectTEXTB+sectSizeTEXT) - trunc_page(sectTEXTB)) + | |
235 | (round_page(sectDATAB+sectSizeDATA) - trunc_page(sectDATAB)) + | |
236 | (round_page(sectLINKB+sectSizeLINK) - trunc_page(sectLINKB)) + | |
237 | (round_page(sectKLDB+sectSizeKLD) - trunc_page(sectKLDB)) + | |
238 | (round_page_32(sectKLDB+sectSizeHIB) - trunc_page_32(sectHIBB)) + | |
239 | (round_page(sectPRELINKB+sectSizePRELINK) - trunc_page(sectPRELINKB)) + | |
240 | (round_page(static_memory_end) - trunc_page(end)); | |
d7e50217 | 241 | |
55e303ae | 242 | pmap_bootstrap(max_mem, &first_avail, kmapsize); |
d7e50217 | 243 | |
91447636 | 244 | pmap_map(trunc_page(exception_entry), trunc_page(exception_entry), |
0c530ab8 | 245 | round_page(exception_end), VM_PROT_READ|VM_PROT_EXECUTE, VM_WIMG_USE_DEFAULT); |
55e303ae | 246 | |
91447636 | 247 | pmap_map(trunc_page(sectTEXTB), trunc_page(sectTEXTB), |
0c530ab8 | 248 | round_page(sectTEXTB+sectSizeTEXT), VM_PROT_READ|VM_PROT_EXECUTE, VM_WIMG_USE_DEFAULT); |
55e303ae | 249 | |
91447636 | 250 | pmap_map(trunc_page(sectDATAB), trunc_page(sectDATAB), |
0c530ab8 | 251 | round_page(sectDATAB+sectSizeDATA), VM_PROT_READ|VM_PROT_WRITE, VM_WIMG_USE_DEFAULT); |
55e303ae A |
252 | |
253 | /* The KLD and LINKEDIT segments are unloaded in toto after boot completes, | |
254 | * but via ml_static_mfree(), through IODTFreeLoaderInfo(). Hence, we have | |
255 | * to map both segments page-by-page. | |
256 | */ | |
257 | ||
91447636 A |
258 | for (addr = trunc_page(sectPRELINKB); |
259 | addr < round_page(sectPRELINKB+sectSizePRELINK); | |
260 | addr += PAGE_SIZE) { | |
261 | ||
262 | pmap_enter(kernel_pmap, (vm_map_offset_t)addr, (ppnum_t)(addr>>12), | |
0c530ab8 | 263 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, |
91447636 A |
264 | VM_WIMG_USE_DEFAULT, TRUE); |
265 | ||
266 | } | |
267 | ||
268 | for (addr = trunc_page(sectKLDB); | |
269 | addr < round_page(sectKLDB+sectSizeKLD); | |
1c79356b A |
270 | addr += PAGE_SIZE) { |
271 | ||
91447636 | 272 | pmap_enter(kernel_pmap, (vm_map_offset_t)addr, (ppnum_t)(addr>>12), |
0c530ab8 | 273 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, |
9bccf70c | 274 | VM_WIMG_USE_DEFAULT, TRUE); |
55e303ae | 275 | |
1c79356b A |
276 | } |
277 | ||
91447636 A |
278 | for (addr = trunc_page(sectLINKB); |
279 | addr < round_page(sectLINKB+sectSizeLINK); | |
1c79356b A |
280 | addr += PAGE_SIZE) { |
281 | ||
91447636 A |
282 | pmap_enter(kernel_pmap, (vm_map_offset_t)addr, |
283 | (ppnum_t)(addr>>12), | |
0c530ab8 | 284 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, |
9bccf70c | 285 | VM_WIMG_USE_DEFAULT, TRUE); |
55e303ae | 286 | |
1c79356b A |
287 | } |
288 | ||
91447636 A |
289 | for (addr = trunc_page_32(sectHIBB); |
290 | addr < round_page_32(sectHIBB+sectSizeHIB); | |
55e303ae A |
291 | addr += PAGE_SIZE) { |
292 | ||
91447636 | 293 | pmap_enter(kernel_pmap, (vm_map_offset_t)addr, (ppnum_t)(addr>>12), |
0c530ab8 | 294 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, |
55e303ae A |
295 | VM_WIMG_USE_DEFAULT, TRUE); |
296 | ||
297 | } | |
298 | ||
cf7d32b8 | 299 | pmap_enter(kernel_pmap, (vm_map_offset_t)(uintptr_t)&sharedPage, |
91447636 | 300 | (ppnum_t)&sharedPage >> 12, /* Make sure the sharedPage is mapped */ |
55e303ae A |
301 | VM_PROT_READ|VM_PROT_WRITE, |
302 | VM_WIMG_USE_DEFAULT, TRUE); | |
303 | ||
cf7d32b8 | 304 | pmap_enter(kernel_pmap, (vm_map_offset_t)(uintptr_t)&lowGlo.lgVerCode, |
91447636 | 305 | (ppnum_t)&lowGlo.lgVerCode >> 12, /* Make sure the low memory globals are mapped */ |
55e303ae A |
306 | VM_PROT_READ|VM_PROT_WRITE, |
307 | VM_WIMG_USE_DEFAULT, TRUE); | |
308 | ||
1c79356b A |
309 | /* |
310 | * We need to map the remainder page-by-page because some of this will | |
311 | * be released later, but not all. Ergo, no block mapping here | |
312 | */ | |
55e303ae | 313 | |
91447636 | 314 | for(addr = trunc_page(end); addr < round_page(static_memory_end); addr += PAGE_SIZE) { |
55e303ae | 315 | |
91447636 | 316 | pmap_enter(kernel_pmap, (vm_map_address_t)addr, (ppnum_t)addr>>12, |
0c530ab8 | 317 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, |
9bccf70c | 318 | VM_WIMG_USE_DEFAULT, TRUE); |
d7e50217 | 319 | |
de355530 | 320 | } |
91447636 A |
321 | |
322 | /* | |
323 | * Here we map a window into the kernel address space that will be used to | |
324 | * access a slice of a user address space. Clients for this service include | |
325 | * copyin/out and copypv. | |
326 | */ | |
55e303ae | 327 | |
91447636 A |
328 | lowGlo.lgUMWvaddr = USER_MEM_WINDOW_VADDR; |
329 | /* Initialize user memory window base address */ | |
330 | MapUserMemoryWindowInit(); /* Go initialize user memory window */ | |
1c79356b | 331 | |
d52fe63f | 332 | /* |
55e303ae A |
333 | * At this point, there is enough mapped memory and all hw mapping structures are |
334 | * allocated and initialized. Here is where we turn on translation for the | |
335 | * VERY first time.... | |
336 | * | |
337 | * NOTE: Here is where our very first interruption will happen. | |
338 | * | |
d52fe63f | 339 | */ |
1c79356b | 340 | |
55e303ae | 341 | hw_start_trans(); /* Start translating */ |
3a60a9f5 A |
342 | PE_init_platform(TRUE, args); /* Initialize this right off the bat */ |
343 | ||
55e303ae A |
344 | |
345 | #if 0 | |
346 | GratefulDebInit((bootBumbleC *)&(args->Video)); /* Initialize the GratefulDeb debugger */ | |
347 | #endif | |
348 | ||
349 | ||
350 | printf_init(); /* Init this in case we need debugger */ | |
351 | panic_init(); /* Init this in case we need debugger */ | |
352 | PE_init_kprintf(TRUE); /* Note on PPC we only call this after VM is set up */ | |
353 | ||
354 | kprintf("kprintf initialized\n"); | |
355 | ||
356 | serialmode = 0; /* Assume normal keyboard and console */ | |
593a1d5f | 357 | if(PE_parse_boot_argn("serial", &serialmode, sizeof (serialmode))) { /* Do we want a serial keyboard and/or console? */ |
55e303ae A |
358 | kprintf("Serial mode specified: %08X\n", serialmode); |
359 | } | |
360 | if(serialmode & 1) { /* Start serial if requested */ | |
361 | (void)switch_to_serial_console(); /* Switch into serial mode */ | |
362 | disableConsoleOutput = FALSE; /* Allow printfs to happen */ | |
363 | } | |
364 | ||
365 | kprintf("max_mem: %ld M\n", (unsigned long)(max_mem >> 20)); | |
366 | kprintf("version_variant = %s\n", version_variant); | |
367 | kprintf("version = %s\n\n", version); | |
368 | __asm__ ("mfpvr %0" : "=r" (pvr)); | |
369 | kprintf("proc version = %08x\n", pvr); | |
91447636 | 370 | if(getPerProc()->pf.Available & pf64Bit) { /* 64-bit processor? */ |
55e303ae A |
371 | xhid0 = hid0get64(); /* Get the hid0 */ |
372 | if(xhid0 & (1ULL << (63 - 19))) kprintf("Time base is externally clocked\n"); | |
373 | else kprintf("Time base is internally clocked\n"); | |
374 | } | |
375 | ||
376 | ||
377 | taproot_size = PE_init_taproot(&taproot_addr); /* (BRINGUP) See if there is a taproot */ | |
378 | if(taproot_size) { /* (BRINGUP) */ | |
379 | kprintf("TapRoot card configured to use vaddr = %08X, size = %08X\n", taproot_addr, taproot_size); | |
2d21ac55 | 380 | bcopy_nc(version, (void *)(taproot_addr + 16), strlen(version)); /* (BRINGUP) Pass it our kernel version */ |
55e303ae A |
381 | __asm__ volatile("eieio"); /* (BRINGUP) */ |
382 | xtaproot = (unsigned int *)taproot_addr; /* (BRINGUP) */ | |
383 | xtaproot[0] = 1; /* (BRINGUP) */ | |
384 | __asm__ volatile("eieio"); /* (BRINGUP) */ | |
385 | } | |
386 | ||
387 | PE_create_console(); /* create the console for verbose or pretty mode */ | |
1c79356b | 388 | |
55e303ae A |
389 | /* setup console output */ |
390 | PE_init_printf(FALSE); | |
1c79356b | 391 | |
1c79356b | 392 | #if DEBUG |
55e303ae A |
393 | printf("\n\n\nThis program was compiled using gcc %d.%d for powerpc\n", |
394 | __GNUC__,__GNUC_MINOR__); | |
395 | ||
396 | ||
397 | /* Processor version information */ | |
2d21ac55 A |
398 | __asm__ ("mfpvr %0" : "=r" (pvr)); |
399 | printf("processor version register : %08X\n", pvr); | |
55e303ae | 400 | |
2d21ac55 | 401 | kprintf("Args at %p\n", args); |
55e303ae | 402 | for (i = 0; i < pmap_mem_regions_count; i++) { |
2d21ac55 | 403 | printf("DRAM at %08lX size %08lX\n", |
55e303ae A |
404 | args->PhysicalDRAM[i].base, |
405 | args->PhysicalDRAM[i].size); | |
406 | } | |
407 | #endif /* DEBUG */ | |
408 | ||
409 | #if DEBUG | |
410 | kprintf("Mapped memory:\n"); | |
91447636 A |
411 | kprintf(" exception vector: %08X, %08X - %08X\n", trunc_page(exception_entry), |
412 | trunc_page(exception_entry), round_page(exception_end)); | |
413 | kprintf(" sectTEXTB: %08X, %08X - %08X\n", trunc_page(sectTEXTB), | |
414 | trunc_page(sectTEXTB), round_page(sectTEXTB+sectSizeTEXT)); | |
415 | kprintf(" sectDATAB: %08X, %08X - %08X\n", trunc_page(sectDATAB), | |
416 | trunc_page(sectDATAB), round_page(sectDATAB+sectSizeDATA)); | |
417 | kprintf(" sectLINKB: %08X, %08X - %08X\n", trunc_page(sectLINKB), | |
418 | trunc_page(sectLINKB), round_page(sectLINKB+sectSizeLINK)); | |
419 | kprintf(" sectKLDB: %08X, %08X - %08X\n", trunc_page(sectKLDB), | |
420 | trunc_page(sectKLDB), round_page(sectKLDB+sectSizeKLD)); | |
421 | kprintf(" end: %08X, %08X - %08X\n", trunc_page(end), | |
422 | trunc_page(end), static_memory_end); | |
55e303ae | 423 | |
1c79356b | 424 | #endif |
55e303ae A |
425 | |
426 | return; | |
1c79356b A |
427 | } |
428 |