]> git.saurik.com Git - apple/xnu.git/blame - pexpert/i386/pe_init.c
xnu-201.42.3.tar.gz
[apple/xnu.git] / pexpert / i386 / pe_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 * file: pe_init.c
24 * i386 platform expert initialization.
25 */
26#include <sys/types.h>
27#include <mach/vm_param.h>
28#include <pexpert/protos.h>
29#include <pexpert/pexpert.h>
30#include <pexpert/boot.h>
31#include <pexpert/device_tree.h>
32#include <pexpert/pe_images.h>
33#include <kern/debug.h>
34
35#include "fakePPCStructs.h"
36#include "fakePPCDeviceTree.h"
37
38/* extern references */
39extern void pe_identify_machine(void * args);
40extern void initialize_screen(void *, unsigned int);
41
42/* Local references */
43static vm_offset_t mapframebuffer(caddr_t,int);
44static vm_offset_t PE_fb_vaddr = 0;
45static int PE_fb_mode = TEXT_MODE;
0b4e3aa0 46static KERNBOOTSTRUCT * PE_kbp = 0;
1c79356b
A
47
48/* private globals */
0b4e3aa0
A
49PE_state_t PE_state;
50dt_data gMemoryMapNode;
51dt_data gDriversProp;
1c79356b
A
52
53/* Clock Frequency Info */
54clock_frequency_info_t gPEClockFrequencyInfo;
55
56int PE_initialize_console( PE_Video * info, int op )
57{
58 static int last_console = -1;
59 Boot_Video bootInfo;
60 Boot_Video * bInfo;
61
62 /*
63 * Refuse changes from outside pexpert.
64 * The video mode setup by the booter cannot be changed.
65 */
66 if ( info && (info == &PE_state.video) )
67 {
68 bootInfo.v_baseAddr = PE_fb_vaddr;
69 bootInfo.v_rowBytes = info->v_rowBytes;
70 bootInfo.v_width = info->v_width;
71 bootInfo.v_height = info->v_height;
72 bootInfo.v_depth = info->v_depth;
73 bootInfo.v_display = PE_fb_mode;
74 bInfo = &bootInfo;
75 }
76 else
77 bInfo = 0;
78
79 switch ( op ) {
80
81 case kPEDisableScreen:
82 initialize_screen((void *) bInfo, op);
83#ifdef FIXME
84 last_console = switch_to_serial_console();
85#endif
86 kprintf("kPEDisableScreen %d\n", last_console);
87 break;
88
89 case kPEEnableScreen:
90 initialize_screen((void *) bInfo, op);
91 kprintf("kPEEnableScreen %d\n", last_console);
92#ifdef FIXME
93 if( last_console != -1)
94 switch_to_old_console( last_console);
95#endif
96 break;
97
98 default:
99 initialize_screen((void *) bInfo, op);
100 break;
101 }
102
103 return 0;
104}
105
106void PE_init_iokit(void)
107{
108 long * dt;
109 void * desc;
110 unsigned char * data;
111 unsigned char * clut;
112
0b4e3aa0
A
113 typedef struct {
114 char name[32];
115 unsigned long length;
116 unsigned long value[2];
117 } DriversPackageProp;
118
119 /*
120 * Update the fake device tree with the driver information provided by
121 * the booter.
122 */
123
124 gDriversProp.length = PE_kbp->numBootDrivers * sizeof(DriversPackageProp);
125 gMemoryMapNode.length = 2 * sizeof(long);
126
127 dt = (long *) createdt( fakePPCDeviceTree,
128 &((boot_args*)PE_state.fakePPCBootArgs)->deviceTreeLength );
129
130 if ( dt )
131 {
132 DriversPackageProp * prop = (DriversPackageProp *) gDriversProp.address;
133 int i;
134
135 /* Copy driver info in kernBootStruct to fake device tree */
136
137 for ( i = 0; i < PE_kbp->numBootDrivers; i++, prop++ )
138 {
139 switch ( PE_kbp->driverConfig[i].type )
140 {
141 case kBootDriverTypeKEXT:
142 sprintf(prop->name, "Driver-%lx", PE_kbp->driverConfig[i].address);
143 break;
144
145 case kBootDriverTypeMKEXT:
146 sprintf(prop->name, "DriversPackage-%lx", PE_kbp->driverConfig[i].address);
147 break;
148
149 default:
150 sprintf(prop->name, "DriverBogus-%lx", PE_kbp->driverConfig[i].address);
151 break;
152 }
153 prop->length = sizeof(prop->value);
154 prop->value[0] = PE_kbp->driverConfig[i].address;
155 prop->value[1] = PE_kbp->driverConfig[i].size;
156 }
157
158 *gMemoryMapNode.address = PE_kbp->numBootDrivers + 1;
159 }
1c79356b
A
160
161 /* Setup powermac_info and powermac_machine_info structures */
162
163 ((boot_args*)PE_state.fakePPCBootArgs)->deviceTreeP = (unsigned long *) dt;
164 ((boot_args*)PE_state.fakePPCBootArgs)->topOfKernelData = (unsigned int) kalloc(0x2000);
165
166 /*
167 * Setup the OpenFirmware Device Tree routines
168 * so the console can be found and the right I/O space
169 * can be used..
170 */
171 DTInit(dt);
172
173 /*
174 * Initialize the spinning wheel (progress indicator).
175 */
176 clut = appleClut8;
177 desc = &default_progress;
178 data = default_progress_data;
179
180 vc_progress_initialize( desc, data, clut );
181
182 PE_initialize_console( (PE_Video *) 0, kPEAcquireScreen );
183
184 (void) StartIOKit( (void*)dt, (void*)PE_state.fakePPCBootArgs, 0, 0);
185}
186
187void PE_init_platform(boolean_t vm_initialized, void * args)
188{
189 if (PE_state.initialized == FALSE)
190 {
191 extern unsigned int halt_in_debugger, disableDebugOuput;
0b4e3aa0
A
192 unsigned int debug_arg;
193
194 PE_kbp = (KERNBOOTSTRUCT *) args;
1c79356b
A
195
196 PE_state.initialized = TRUE;
197 PE_state.bootArgs = args;
0b4e3aa0
A
198 PE_state.video.v_baseAddr = PE_kbp->video.v_baseAddr;
199 PE_state.video.v_rowBytes = PE_kbp->video.v_rowBytes;
200 PE_state.video.v_height = PE_kbp->video.v_height;
201 PE_state.video.v_width = PE_kbp->video.v_width;
202 PE_state.video.v_depth = PE_kbp->video.v_depth;
203 PE_state.video.v_display = PE_kbp->video.v_display;
204 PE_fb_mode = PE_kbp->graphicsMode;
1c79356b
A
205 PE_state.fakePPCBootArgs = (boot_args *)&fakePPCBootArgs;
206 ((boot_args *)PE_state.fakePPCBootArgs)->machineType = 386;
207
208 if (PE_fb_mode == TEXT_MODE)
209 {
210 /* Force a text display if the booter did not setup a
211 * VESA frame buffer.
212 */
213 PE_state.video.v_display = 0;
214 }
215
216 /*
217 * If DB_HALT flag is set, then cause a breakpoint to the debugger
218 * immediately after the kernel debugger has been initialized.
219 *
220 * If DB_PRT flag is set, then enable debugger printf.
221 */
222 disableDebugOuput = TRUE; /* FIXME: override osfmk/i386/AT386/model_dep.c */
223
224 if (PE_parse_boot_arg("debug", &debug_arg)) {
225 if (debug_arg & DB_HALT) halt_in_debugger = 1;
226 if (debug_arg & DB_PRT) disableDebugOuput = FALSE;
0b4e3aa0
A
227 }
228 }
1c79356b
A
229
230 if (!vm_initialized)
231 {
232 /* Hack! FIXME.. */
233 outb(0x21, 0xff); /* Maskout all interrupts Pic1 */
234 outb(0xa1, 0xff); /* Maskout all interrupts Pic2 */
235
0b4e3aa0 236 pe_identify_machine(args);
1c79356b
A
237 }
238 else
239 {
0b4e3aa0
A
240 pe_init_debug();
241
242 PE_create_console();
1c79356b
A
243 }
244}
245
246void PE_create_console( void )
247{
248 if ( (PE_fb_vaddr == 0) && (PE_state.video.v_baseAddr != 0) )
249 {
250 PE_fb_vaddr = mapframebuffer((caddr_t) PE_state.video.v_baseAddr,
251 (PE_fb_mode == TEXT_MODE) ?
252 /* text mode */ PE_state.video.v_rowBytes :
253 /* grfx mode */ PE_state.video.v_rowBytes *
254 PE_state.video.v_height);
255 }
256
257 if (PE_state.video.v_display)
258 PE_initialize_console( &PE_state.video, kPEGraphicsMode );
259 else
260 PE_initialize_console( &PE_state.video, kPETextMode );
261}
262
263int PE_current_console( PE_Video * info )
264{
265 *info = PE_state.video;
266
267 if ( PE_fb_mode == TEXT_MODE )
268 {
269 /*
270 * FIXME: Prevent the IOBootFrameBuffer from starting up
271 * when we are in Text mode.
272 */
273 info->v_baseAddr = 0;
0b4e3aa0
A
274
275 /*
276 * Scale the size of the text screen from characters
277 * to pixels.
278 */
279 info->v_width *= 8; // CHARWIDTH
280 info->v_height *= 16; // CHARHEIGHT
1c79356b
A
281 }
282
283 return (0);
284}
285
286void PE_display_icon( unsigned int flags,
287 const char * name )
288{
289}
290
291extern boolean_t PE_get_hotkey( unsigned char key )
292{
293 return (FALSE);
294}
295
296static timebase_callback_func gTimebaseCallback;
297
298void PE_register_timebase_callback(timebase_callback_func callback)
299{
300 gTimebaseCallback = callback;
301
302 PE_call_timebase_callback();
303}
304
305void PE_call_timebase_callback(void)
306{
307 struct timebase_freq_t timebase_freq;
308 unsigned long num, den, cnt;
309
310 num = gPEClockFrequencyInfo.bus_clock_rate_num * gPEClockFrequencyInfo.bus_to_dec_rate_num;
311 den = gPEClockFrequencyInfo.bus_clock_rate_den * gPEClockFrequencyInfo.bus_to_dec_rate_den;
312
313 cnt = 2;
314 while (cnt <= den) {
315 if ((num % cnt) || (den % cnt)) {
316 cnt++;
317 continue;
318 }
319
320 num /= cnt;
321 den /= cnt;
322 }
323
324 timebase_freq.timebase_num = num;
325 timebase_freq.timebase_den = den;
326
327 if (gTimebaseCallback) gTimebaseCallback(&timebase_freq);
328}
329
330/*
331 * map the framebuffer into kernel vm and return the (virtual)
332 * address.
333 */
334static vm_offset_t
335mapframebuffer( caddr_t physaddr, /* start of framebuffer */
336 int length) /* num bytes to map */
337{
338 vm_offset_t vmaddr;
339
340 if (physaddr != (caddr_t)trunc_page(physaddr))
341 panic("Framebuffer not on page boundary");
342
343 vmaddr = io_map((vm_offset_t)physaddr, length);
344 if (vmaddr == 0)
345 panic("can't alloc VM for framebuffer");
346
347 return vmaddr;
348}
0b4e3aa0
A
349
350/*
351 * The default (non-functional) PE_poll_input handler.
352 */
353static int
354PE_stub_poll_input(unsigned int options, char * c)
355{
356 *c = 0xff;
357 return 1; /* 0 for success, 1 for unsupported */
358}
359
360/*
361 * Called by the kernel debugger to poll for keyboard input.
362 * Keyboard drivers may replace the default stub function
363 * with their polled-mode input function.
364 */
365int (*PE_poll_input)(unsigned int options, char * c)
366 = PE_stub_poll_input;