2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
24 * i386 platform expert initialization.
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>
35 #include "fakePPCStructs.h"
36 #include "fakePPCDeviceTree.h"
38 /* extern references */
39 extern void pe_identify_machine(void * args
);
40 extern void initialize_screen(void *, unsigned int);
42 /* Local references */
43 static vm_offset_t
mapframebuffer(caddr_t
,int);
44 static vm_offset_t PE_fb_vaddr
= 0;
45 static int PE_fb_mode
= TEXT_MODE
;
46 static KERNBOOTSTRUCT
* PE_kbp
= 0;
50 dt_data gMemoryMapNode
;
53 /* Clock Frequency Info */
54 clock_frequency_info_t gPEClockFrequencyInfo
;
56 int PE_initialize_console( PE_Video
* info
, int op
)
58 static int last_console
= -1;
63 * Refuse changes from outside pexpert.
64 * The video mode setup by the booter cannot be changed.
66 if ( info
&& (info
== &PE_state
.video
) )
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
;
81 case kPEDisableScreen
:
82 initialize_screen((void *) bInfo
, op
);
84 last_console
= switch_to_serial_console();
86 kprintf("kPEDisableScreen %d\n", last_console
);
90 initialize_screen((void *) bInfo
, op
);
91 kprintf("kPEEnableScreen %d\n", last_console
);
93 if( last_console
!= -1)
94 switch_to_old_console( last_console
);
99 initialize_screen((void *) bInfo
, op
);
106 void PE_init_iokit(void)
110 unsigned char * data
;
111 unsigned char * clut
;
115 unsigned long length
;
116 unsigned long value
[2];
117 } DriversPackageProp
;
120 * Update the fake device tree with the driver information provided by
124 gDriversProp
.length
= PE_kbp
->numBootDrivers
* sizeof(DriversPackageProp
);
125 gMemoryMapNode
.length
= 2 * sizeof(long);
127 dt
= (long *) createdt( fakePPCDeviceTree
,
128 &((boot_args
*)PE_state
.fakePPCBootArgs
)->deviceTreeLength
);
132 DriversPackageProp
* prop
= (DriversPackageProp
*) gDriversProp
.address
;
135 /* Copy driver info in kernBootStruct to fake device tree */
137 for ( i
= 0; i
< PE_kbp
->numBootDrivers
; i
++, prop
++ )
139 switch ( PE_kbp
->driverConfig
[i
].type
)
141 case kBootDriverTypeKEXT
:
142 sprintf(prop
->name
, "Driver-%lx", PE_kbp
->driverConfig
[i
].address
);
145 case kBootDriverTypeMKEXT
:
146 sprintf(prop
->name
, "DriversPackage-%lx", PE_kbp
->driverConfig
[i
].address
);
150 sprintf(prop
->name
, "DriverBogus-%lx", PE_kbp
->driverConfig
[i
].address
);
153 prop
->length
= sizeof(prop
->value
);
154 prop
->value
[0] = PE_kbp
->driverConfig
[i
].address
;
155 prop
->value
[1] = PE_kbp
->driverConfig
[i
].size
;
158 *gMemoryMapNode
.address
= PE_kbp
->numBootDrivers
+ 1;
161 /* Setup powermac_info and powermac_machine_info structures */
163 ((boot_args
*)PE_state
.fakePPCBootArgs
)->deviceTreeP
= (unsigned long *) dt
;
164 ((boot_args
*)PE_state
.fakePPCBootArgs
)->topOfKernelData
= (unsigned int) kalloc(0x2000);
167 * Setup the OpenFirmware Device Tree routines
168 * so the console can be found and the right I/O space
174 * Initialize the spinning wheel (progress indicator).
177 desc
= &default_progress
;
178 data
= default_progress_data
;
180 vc_progress_initialize( desc
, data
, clut
);
182 PE_initialize_console( (PE_Video
*) 0, kPEAcquireScreen
);
184 (void) StartIOKit( (void*)dt
, (void*)PE_state
.fakePPCBootArgs
, 0, 0);
187 void PE_init_platform(boolean_t vm_initialized
, void * args
)
189 if (PE_state
.initialized
== FALSE
)
191 extern unsigned int halt_in_debugger
, disableDebugOuput
;
192 unsigned int debug_arg
;
194 PE_kbp
= (KERNBOOTSTRUCT
*) args
;
196 PE_state
.initialized
= TRUE
;
197 PE_state
.bootArgs
= args
;
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
;
205 PE_state
.fakePPCBootArgs
= (boot_args
*)&fakePPCBootArgs
;
206 ((boot_args
*)PE_state
.fakePPCBootArgs
)->machineType
= 386;
208 if (PE_fb_mode
== TEXT_MODE
)
210 /* Force a text display if the booter did not setup a
213 PE_state
.video
.v_display
= 0;
217 * If DB_HALT flag is set, then cause a breakpoint to the debugger
218 * immediately after the kernel debugger has been initialized.
220 * If DB_PRT flag is set, then enable debugger printf.
222 disableDebugOuput
= TRUE
; /* FIXME: override osfmk/i386/AT386/model_dep.c */
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
;
233 outb(0x21, 0xff); /* Maskout all interrupts Pic1 */
234 outb(0xa1, 0xff); /* Maskout all interrupts Pic2 */
236 pe_identify_machine(args
);
246 void PE_create_console( void )
248 if ( (PE_fb_vaddr
== 0) && (PE_state
.video
.v_baseAddr
!= 0) )
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
);
257 if (PE_state
.video
.v_display
)
258 PE_initialize_console( &PE_state
.video
, kPEGraphicsMode
);
260 PE_initialize_console( &PE_state
.video
, kPETextMode
);
263 int PE_current_console( PE_Video
* info
)
265 *info
= PE_state
.video
;
267 if ( PE_fb_mode
== TEXT_MODE
)
270 * FIXME: Prevent the IOBootFrameBuffer from starting up
271 * when we are in Text mode.
273 info
->v_baseAddr
= 0;
276 * Scale the size of the text screen from characters
279 info
->v_width
*= 8; // CHARWIDTH
280 info
->v_height
*= 16; // CHARHEIGHT
286 void PE_display_icon( unsigned int flags
,
291 extern boolean_t
PE_get_hotkey( unsigned char key
)
296 static timebase_callback_func gTimebaseCallback
;
298 void PE_register_timebase_callback(timebase_callback_func callback
)
300 gTimebaseCallback
= callback
;
302 PE_call_timebase_callback();
305 void PE_call_timebase_callback(void)
307 struct timebase_freq_t timebase_freq
;
308 unsigned long num
, den
, cnt
;
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
;
315 if ((num
% cnt
) || (den
% cnt
)) {
324 timebase_freq
.timebase_num
= num
;
325 timebase_freq
.timebase_den
= den
;
327 if (gTimebaseCallback
) gTimebaseCallback(&timebase_freq
);
331 * map the framebuffer into kernel vm and return the (virtual)
335 mapframebuffer( caddr_t physaddr
, /* start of framebuffer */
336 int length
) /* num bytes to map */
340 if (physaddr
!= (caddr_t
)trunc_page(physaddr
))
341 panic("Framebuffer not on page boundary");
343 vmaddr
= io_map((vm_offset_t
)physaddr
, length
);
345 panic("can't alloc VM for framebuffer");
351 * The default (non-functional) PE_poll_input handler.
354 PE_stub_poll_input(unsigned int options
, char * c
)
357 return 1; /* 0 for success, 1 for unsupported */
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.
365 int (*PE_poll_input
)(unsigned int options
, char * c
)
366 = PE_stub_poll_input
;