2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
27 * i386 platform expert initialization.
29 #include <sys/types.h>
30 #include <mach/vm_param.h>
31 #include <pexpert/protos.h>
32 #include <pexpert/pexpert.h>
33 #include <pexpert/boot.h>
34 #include <pexpert/device_tree.h>
35 #include <pexpert/pe_images.h>
36 #include <kern/sched_prim.h>
38 #include "fakePPCStructs.h"
39 #include "fakePPCDeviceTree.h"
40 #include "boot_images.h"
42 /* extern references */
43 extern void pe_identify_machine(void * args
);
44 extern void initialize_screen(void *, unsigned int);
46 /* Local references */
47 static vm_offset_t
mapframebuffer(caddr_t
,int);
48 static vm_offset_t PE_fb_vaddr
= 0;
49 static int PE_fb_mode
= TEXT_MODE
;
50 static KERNBOOTSTRUCT
* PE_kbp
= 0;
54 dt_data gMemoryMapNode
;
57 /* Clock Frequency Info */
58 clock_frequency_info_t gPEClockFrequencyInfo
;
60 int PE_initialize_console( PE_Video
* info
, int op
)
62 static int last_console
= -1;
67 * Refuse changes from outside pexpert.
68 * The video mode setup by the booter cannot be changed.
70 if ( info
&& (info
== &PE_state
.video
) )
72 bootInfo
.v_baseAddr
= PE_fb_vaddr
;
73 bootInfo
.v_rowBytes
= info
->v_rowBytes
;
74 bootInfo
.v_width
= info
->v_width
;
75 bootInfo
.v_height
= info
->v_height
;
76 bootInfo
.v_depth
= info
->v_depth
;
77 bootInfo
.v_display
= PE_fb_mode
;
85 case kPEDisableScreen
:
86 initialize_screen((void *) bInfo
, op
);
88 last_console
= switch_to_serial_console();
90 kprintf("kPEDisableScreen %d\n", last_console
);
94 initialize_screen((void *) bInfo
, op
);
95 kprintf("kPEEnableScreen %d\n", last_console
);
97 if( last_console
!= -1)
98 switch_to_old_console( last_console
);
103 initialize_screen((void *) bInfo
, op
);
110 void PE_init_iokit(void)
117 unsigned long length
;
118 unsigned long value
[2];
119 } DriversPackageProp
;
122 * Update the fake device tree with the driver information provided by
126 gDriversProp
.length
= PE_kbp
->numBootDrivers
* sizeof(DriversPackageProp
);
127 gMemoryMapNode
.length
= 2 * sizeof(long);
129 dt
= (long *) createdt( fakePPCDeviceTree
,
130 &((boot_args
*)PE_state
.fakePPCBootArgs
)->deviceTreeLength
);
134 DriversPackageProp
* prop
= (DriversPackageProp
*) gDriversProp
.address
;
136 /* Copy driver info in kernBootStruct to fake device tree */
138 for ( i
= 0; i
< PE_kbp
->numBootDrivers
; i
++, prop
++ )
140 switch ( PE_kbp
->driverConfig
[i
].type
)
142 case kBootDriverTypeKEXT
:
143 sprintf(prop
->name
, "Driver-%lx", PE_kbp
->driverConfig
[i
].address
);
146 case kBootDriverTypeMKEXT
:
147 sprintf(prop
->name
, "DriversPackage-%lx", PE_kbp
->driverConfig
[i
].address
);
151 sprintf(prop
->name
, "DriverBogus-%lx", PE_kbp
->driverConfig
[i
].address
);
154 prop
->length
= sizeof(prop
->value
);
155 prop
->value
[0] = PE_kbp
->driverConfig
[i
].address
;
156 prop
->value
[1] = PE_kbp
->driverConfig
[i
].size
;
159 *gMemoryMapNode
.address
= PE_kbp
->numBootDrivers
+ 1;
162 /* Setup powermac_info and powermac_machine_info structures */
164 ((boot_args
*)PE_state
.fakePPCBootArgs
)->deviceTreeP
= (unsigned long *) dt
;
165 ((boot_args
*)PE_state
.fakePPCBootArgs
)->topOfKernelData
= (unsigned int) kalloc(0x2000);
168 * Setup the OpenFirmware Device Tree routines
169 * so the console can be found and the right I/O space
175 * Fetch the CLUT and the noroot image.
177 bcopy( bootClut
, appleClut8
, sizeof(appleClut8
) );
179 default_noroot
.width
= kFailedBootWidth
;
180 default_noroot
.height
= kFailedBootHeight
;
181 default_noroot
.dx
= 0;
182 default_noroot
.dy
= kFailedBootOffset
;
183 default_noroot_data
= failedBootPict
;
186 * Initialize the spinning wheel (progress indicator).
188 vc_progress_initialize( &default_progress
, default_progress_data
,
189 (unsigned char *) appleClut8
);
191 PE_initialize_console( (PE_Video
*) 0, kPEAcquireScreen
);
193 (void) StartIOKit( (void*)dt
, (void*)PE_state
.fakePPCBootArgs
, 0, 0);
196 void PE_init_platform(boolean_t vm_initialized
, void * args
)
198 if (PE_state
.initialized
== FALSE
)
200 PE_kbp
= (KERNBOOTSTRUCT
*) args
;
202 PE_state
.initialized
= TRUE
;
203 PE_state
.bootArgs
= args
;
204 PE_state
.video
.v_baseAddr
= PE_kbp
->video
.v_baseAddr
;
205 PE_state
.video
.v_rowBytes
= PE_kbp
->video
.v_rowBytes
;
206 PE_state
.video
.v_height
= PE_kbp
->video
.v_height
;
207 PE_state
.video
.v_width
= PE_kbp
->video
.v_width
;
208 PE_state
.video
.v_depth
= PE_kbp
->video
.v_depth
;
209 PE_state
.video
.v_display
= PE_kbp
->video
.v_display
;
210 PE_fb_mode
= PE_kbp
->graphicsMode
;
211 PE_state
.fakePPCBootArgs
= (boot_args
*)&fakePPCBootArgs
;
212 ((boot_args
*)PE_state
.fakePPCBootArgs
)->machineType
= 386;
214 if (PE_fb_mode
== TEXT_MODE
)
216 /* Force a text display if the booter did not setup a
219 PE_state
.video
.v_display
= 0;
226 outb(0x21, 0xff); /* Maskout all interrupts Pic1 */
227 outb(0xa1, 0xff); /* Maskout all interrupts Pic2 */
229 pe_identify_machine(args
);
239 void PE_create_console( void )
241 if ( (PE_fb_vaddr
== 0) && (PE_state
.video
.v_baseAddr
!= 0) )
243 PE_fb_vaddr
= mapframebuffer((caddr_t
) PE_state
.video
.v_baseAddr
,
244 (PE_fb_mode
== TEXT_MODE
) ?
245 /* text mode */ PE_state
.video
.v_rowBytes
:
246 /* grfx mode */ PE_state
.video
.v_rowBytes
*
247 PE_state
.video
.v_height
);
250 if (PE_state
.video
.v_display
)
251 PE_initialize_console( &PE_state
.video
, kPEGraphicsMode
);
253 PE_initialize_console( &PE_state
.video
, kPETextMode
);
256 int PE_current_console( PE_Video
* info
)
258 *info
= PE_state
.video
;
260 if ( PE_fb_mode
== TEXT_MODE
)
263 * FIXME: Prevent the IOBootFrameBuffer from starting up
264 * when we are in Text mode.
266 info
->v_baseAddr
= 0;
269 * Scale the size of the text screen from characters
272 info
->v_width
*= 8; // CHARWIDTH
273 info
->v_height
*= 16; // CHARHEIGHT
279 void PE_display_icon( unsigned int flags
, const char * name
)
281 if ( default_noroot_data
)
282 vc_display_icon( &default_noroot
, default_noroot_data
);
285 extern boolean_t
PE_get_hotkey( unsigned char key
)
290 static timebase_callback_func gTimebaseCallback
;
292 void PE_register_timebase_callback(timebase_callback_func callback
)
294 gTimebaseCallback
= callback
;
296 PE_call_timebase_callback();
299 void PE_call_timebase_callback(void)
301 struct timebase_freq_t timebase_freq
;
302 unsigned long num
, den
, cnt
;
304 num
= gPEClockFrequencyInfo
.bus_clock_rate_num
* gPEClockFrequencyInfo
.bus_to_dec_rate_num
;
305 den
= gPEClockFrequencyInfo
.bus_clock_rate_den
* gPEClockFrequencyInfo
.bus_to_dec_rate_den
;
309 if ((num
% cnt
) || (den
% cnt
)) {
318 timebase_freq
.timebase_num
= num
;
319 timebase_freq
.timebase_den
= den
;
321 if (gTimebaseCallback
) gTimebaseCallback(&timebase_freq
);
325 * map the framebuffer into kernel vm and return the (virtual)
329 mapframebuffer( caddr_t physaddr
, /* start of framebuffer */
330 int length
) /* num bytes to map */
334 if (physaddr
!= (caddr_t
)trunc_page(physaddr
))
335 panic("Framebuffer not on page boundary");
337 vmaddr
= io_map((vm_offset_t
)physaddr
, length
);
339 panic("can't alloc VM for framebuffer");
345 * The default (non-functional) PE_poll_input handler.
348 PE_stub_poll_input(unsigned int options
, char * c
)
351 return 1; /* 0 for success, 1 for unsupported */
355 * Called by the kernel debugger to poll for keyboard input.
356 * Keyboard drivers may replace the default stub function
357 * with their polled-mode input function.
359 int (*PE_poll_input
)(unsigned int options
, char * c
)
360 = PE_stub_poll_input
;