2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
32 * i386 platform expert initialization.
34 #include <sys/types.h>
35 #include <mach/vm_param.h>
36 #include <pexpert/protos.h>
37 #include <pexpert/pexpert.h>
38 #include <pexpert/boot.h>
39 #include <pexpert/device_tree.h>
40 #include <pexpert/pe_images.h>
41 #include <kern/sched_prim.h>
43 #include "fakePPCStructs.h"
44 #include "fakePPCDeviceTree.h"
45 #include "boot_images.h"
47 /* extern references */
48 extern void pe_identify_machine(void * args
);
49 extern void initialize_screen(void *, unsigned int);
51 /* Local references */
52 static int PE_fb_mode
= TEXT_MODE
;
56 dt_data gMemoryMapNode
;
58 dt_data gRootpathProp
;
59 dt_data gCompatibleProp
;
61 /* Clock Frequency Info */
62 clock_frequency_info_t gPEClockFrequencyInfo
;
64 int PE_initialize_console( PE_Video
* info
, int op
)
66 static int last_console
= -1;
71 * Refuse changes from outside pexpert.
72 * The video mode setup by the booter cannot be changed.
76 bootInfo
.v_baseAddr
= info
->v_baseAddr
;
77 bootInfo
.v_rowBytes
= info
->v_rowBytes
;
78 bootInfo
.v_width
= info
->v_width
;
79 bootInfo
.v_height
= info
->v_height
;
80 bootInfo
.v_depth
= info
->v_depth
;
82 if (info
== &PE_state
.video
) {
83 bootInfo
.v_display
= PE_fb_mode
;
85 bootInfo
.v_display
= GRAPHICS_MODE
;
93 case kPEDisableScreen
:
94 initialize_screen((void *) bInfo
, op
);
96 last_console
= switch_to_serial_console();
98 kprintf("kPEDisableScreen %d\n", last_console
);
101 case kPEEnableScreen
:
102 initialize_screen((void *) bInfo
, op
);
103 kprintf("kPEEnableScreen %d\n", last_console
);
105 if( last_console
!= -1)
106 switch_to_old_console( last_console
);
111 initialize_screen((void *) bInfo
, op
);
118 void PE_init_iokit(void)
122 KernelBootArgs_t
*kap
= (KernelBootArgs_t
*)PE_state
.bootArgs
;
123 enum { kMaxBootVar
= 128 };
124 char *rdValue
, *platformValue
;
128 unsigned long length
;
129 unsigned long value
[2];
130 } DriversPackageProp
;
132 PE_init_kprintf(TRUE
);
133 PE_init_printf(TRUE
);
136 * Update the fake device tree with the driver information provided by
140 gDriversProp
.length
= kap
->numBootDrivers
* sizeof(DriversPackageProp
);
141 gMemoryMapNode
.length
= 2 * sizeof(long);
143 rdValue
= kalloc(kMaxBootVar
);
144 if ( PE_parse_boot_arg("rd", rdValue
) ) {
145 if (*rdValue
== '*') {
146 gRootpathProp
.address
= (rdValue
+ 1);
148 gRootpathProp
.address
= rdValue
;
150 strcat(rdValue
, ",");
152 gRootpathProp
.address
= rdValue
;
155 strcat(rdValue
, kap
->bootFile
);
156 gRootpathProp
.length
= strlen(rdValue
) + 1;
158 platformValue
= kalloc(kMaxBootVar
);
159 if ( ! PE_parse_boot_arg("platform", platformValue
) ) {
160 strcpy(platformValue
, kDefaultPlatformName
);
162 gCompatibleProp
.address
= platformValue
;
163 gCompatibleProp
.length
= strlen(platformValue
) + 1;
165 dt
= (long *) createdt( fakePPCDeviceTree
,
166 &((boot_args
*)PE_state
.fakePPCBootArgs
)->deviceTreeLength
);
168 kfree(rdValue
, kMaxBootVar
);
169 kfree(platformValue
, kMaxBootVar
);
174 DriversPackageProp
* prop
= (DriversPackageProp
*) gDriversProp
.address
;
176 /* Copy driver info in kernBootStruct to fake device tree */
178 for ( i
= 0; i
< kap
->numBootDrivers
; i
++, prop
++ )
180 switch ( kap
->driverConfig
[i
].type
)
182 case kBootDriverTypeKEXT
:
183 sprintf(prop
->name
, "Driver-%lx", kap
->driverConfig
[i
].address
);
186 case kBootDriverTypeMKEXT
:
187 sprintf(prop
->name
, "DriversPackage-%lx", kap
->driverConfig
[i
].address
);
191 sprintf(prop
->name
, "DriverBogus-%lx", kap
->driverConfig
[i
].address
);
194 prop
->length
= sizeof(prop
->value
);
195 prop
->value
[0] = kap
->driverConfig
[i
].address
;
196 prop
->value
[1] = kap
->driverConfig
[i
].size
;
199 *((long *)gMemoryMapNode
.address
) = kap
->numBootDrivers
+ 1;
202 /* Setup powermac_info and powermac_machine_info structures */
204 ((boot_args
*)PE_state
.fakePPCBootArgs
)->deviceTreeP
= (unsigned long *) dt
;
205 ((boot_args
*)PE_state
.fakePPCBootArgs
)->topOfKernelData
= (unsigned long) kalloc(0x2000);
208 * Setup the OpenFirmware Device Tree routines
209 * so the console can be found and the right I/O space
215 * Fetch the CLUT and the noroot image.
217 bcopy( (void *) (uintptr_t) bootClut
, (void *) appleClut8
, sizeof(appleClut8
) );
219 default_noroot
.width
= kFailedBootWidth
;
220 default_noroot
.height
= kFailedBootHeight
;
221 default_noroot
.dx
= 0;
222 default_noroot
.dy
= kFailedBootOffset
;
223 default_noroot_data
= failedBootPict
;
226 * Initialize the panic UI
228 panic_ui_initialize( (unsigned char *) appleClut8
);
231 * Initialize the spinning wheel (progress indicator).
233 vc_progress_initialize( &default_progress
, default_progress_data
,
234 (unsigned char *) appleClut8
);
236 (void) StartIOKit( (void*)dt
, PE_state
.bootArgs
, 0, 0);
239 void PE_init_platform(boolean_t vm_initialized
, void * args
)
241 if (PE_state
.initialized
== FALSE
)
243 KernelBootArgs_t
*kap
= (KernelBootArgs_t
*) args
;
245 PE_state
.initialized
= TRUE
;
246 PE_state
.bootArgs
= args
;
247 PE_state
.video
.v_baseAddr
= kap
->video
.v_baseAddr
;
248 PE_state
.video
.v_rowBytes
= kap
->video
.v_rowBytes
;
249 PE_state
.video
.v_height
= kap
->video
.v_height
;
250 PE_state
.video
.v_width
= kap
->video
.v_width
;
251 PE_state
.video
.v_depth
= kap
->video
.v_depth
;
252 PE_state
.video
.v_display
= kap
->video
.v_display
;
253 PE_fb_mode
= kap
->graphicsMode
;
254 PE_state
.fakePPCBootArgs
= (boot_args
*)&fakePPCBootArgs
;
255 ((boot_args
*)PE_state
.fakePPCBootArgs
)->machineType
= 386;
257 if (PE_fb_mode
== TEXT_MODE
)
259 /* Force a text display if the booter did not setup a
262 PE_state
.video
.v_display
= 0;
269 outb(0x21, 0xff); /* Maskout all interrupts Pic1 */
270 outb(0xa1, 0xff); /* Maskout all interrupts Pic2 */
272 pe_identify_machine(args
);
280 void PE_create_console( void )
282 if ( PE_state
.video
.v_display
)
283 PE_initialize_console( &PE_state
.video
, kPEGraphicsMode
);
285 PE_initialize_console( &PE_state
.video
, kPETextMode
);
288 int PE_current_console( PE_Video
* info
)
290 *info
= PE_state
.video
;
292 if ( PE_fb_mode
== TEXT_MODE
)
295 * FIXME: Prevent the IOBootFrameBuffer from starting up
296 * when we are in Text mode.
298 info
->v_baseAddr
= 0;
301 * Scale the size of the text screen from characters
304 info
->v_width
*= 8; // CHARWIDTH
305 info
->v_height
*= 16; // CHARHEIGHT
311 void PE_display_icon( __unused
unsigned int flags
, __unused
const char * name
)
313 if ( default_noroot_data
)
314 vc_display_icon( &default_noroot
, default_noroot_data
);
317 extern boolean_t
PE_get_hotkey( __unused
unsigned char key
)
322 static timebase_callback_func gTimebaseCallback
;
324 void PE_register_timebase_callback(timebase_callback_func callback
)
326 gTimebaseCallback
= callback
;
328 PE_call_timebase_callback();
331 void PE_call_timebase_callback(void)
333 struct timebase_freq_t timebase_freq
;
334 unsigned long num
, den
, cnt
;
336 num
= gPEClockFrequencyInfo
.bus_clock_rate_num
* gPEClockFrequencyInfo
.bus_to_dec_rate_num
;
337 den
= gPEClockFrequencyInfo
.bus_clock_rate_den
* gPEClockFrequencyInfo
.bus_to_dec_rate_den
;
341 if ((num
% cnt
) || (den
% cnt
)) {
350 timebase_freq
.timebase_num
= num
;
351 timebase_freq
.timebase_den
= den
;
353 if (gTimebaseCallback
) gTimebaseCallback(&timebase_freq
);
357 * The default (non-functional) PE_poll_input handler.
360 PE_stub_poll_input(__unused
unsigned int options
, char * c
)
363 return 1; /* 0 for success, 1 for unsupported */
367 * Called by the kernel debugger to poll for keyboard input.
368 * Keyboard drivers may replace the default stub function
369 * with their polled-mode input function.
371 int (*PE_poll_input
)(unsigned int options
, char * c
)
372 = PE_stub_poll_input
;