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
;
50 /* Clock Frequency Info */
51 clock_frequency_info_t gPEClockFrequencyInfo
;
53 int PE_initialize_console( PE_Video
* info
, int op
)
55 static int last_console
= -1;
60 * Refuse changes from outside pexpert.
61 * The video mode setup by the booter cannot be changed.
63 if ( info
&& (info
== &PE_state
.video
) )
65 bootInfo
.v_baseAddr
= PE_fb_vaddr
;
66 bootInfo
.v_rowBytes
= info
->v_rowBytes
;
67 bootInfo
.v_width
= info
->v_width
;
68 bootInfo
.v_height
= info
->v_height
;
69 bootInfo
.v_depth
= info
->v_depth
;
70 bootInfo
.v_display
= PE_fb_mode
;
78 case kPEDisableScreen
:
79 initialize_screen((void *) bInfo
, op
);
81 last_console
= switch_to_serial_console();
83 kprintf("kPEDisableScreen %d\n", last_console
);
87 initialize_screen((void *) bInfo
, op
);
88 kprintf("kPEEnableScreen %d\n", last_console
);
90 if( last_console
!= -1)
91 switch_to_old_console( last_console
);
96 initialize_screen((void *) bInfo
, op
);
103 void PE_init_iokit(void)
107 unsigned char * data
;
108 unsigned char * clut
;
110 dt
= (long *) createdt(
112 &((boot_args
*)PE_state
.fakePPCBootArgs
)->deviceTreeLength
);
114 /* Setup powermac_info and powermac_machine_info structures */
116 ((boot_args
*)PE_state
.fakePPCBootArgs
)->deviceTreeP
= (unsigned long *) dt
;
117 ((boot_args
*)PE_state
.fakePPCBootArgs
)->topOfKernelData
= (unsigned int) kalloc(0x2000);
120 * Setup the OpenFirmware Device Tree routines
121 * so the console can be found and the right I/O space
127 * Initialize the spinning wheel (progress indicator).
130 desc
= &default_progress
;
131 data
= default_progress_data
;
133 vc_progress_initialize( desc
, data
, clut
);
135 PE_initialize_console( (PE_Video
*) 0, kPEAcquireScreen
);
137 (void) StartIOKit( (void*)dt
, (void*)PE_state
.fakePPCBootArgs
, 0, 0);
140 void PE_init_platform(boolean_t vm_initialized
, void * args
)
142 if (PE_state
.initialized
== FALSE
)
144 extern unsigned int halt_in_debugger
, disableDebugOuput
;
145 unsigned int debug_arg
;
147 PE_state
.initialized
= TRUE
;
148 PE_state
.bootArgs
= args
;
149 PE_state
.video
.v_baseAddr
= ((KERNBOOTSTRUCT
*)args
)->video
.v_baseAddr
;
150 PE_state
.video
.v_rowBytes
= ((KERNBOOTSTRUCT
*)args
)->video
.v_rowBytes
;
151 PE_state
.video
.v_height
= ((KERNBOOTSTRUCT
*)args
)->video
.v_height
;
152 PE_state
.video
.v_width
= ((KERNBOOTSTRUCT
*)args
)->video
.v_width
;
153 PE_state
.video
.v_depth
= ((KERNBOOTSTRUCT
*)args
)->video
.v_depth
;
154 PE_state
.video
.v_display
= ((KERNBOOTSTRUCT
*)args
)->video
.v_display
;
155 PE_fb_mode
= ((KERNBOOTSTRUCT
*)args
)->graphicsMode
;
156 PE_state
.fakePPCBootArgs
= (boot_args
*)&fakePPCBootArgs
;
157 ((boot_args
*)PE_state
.fakePPCBootArgs
)->machineType
= 386;
159 if (PE_fb_mode
== TEXT_MODE
)
161 /* Force a text display if the booter did not setup a
164 PE_state
.video
.v_display
= 0;
168 * If DB_HALT flag is set, then cause a breakpoint to the debugger
169 * immediately after the kernel debugger has been initialized.
171 * If DB_PRT flag is set, then enable debugger printf.
173 disableDebugOuput
= TRUE
; /* FIXME: override osfmk/i386/AT386/model_dep.c */
175 if (PE_parse_boot_arg("debug", &debug_arg
)) {
176 if (debug_arg
& DB_HALT
) halt_in_debugger
= 1;
177 if (debug_arg
& DB_PRT
) disableDebugOuput
= FALSE
;
184 outb(0x21, 0xff); /* Maskout all interrupts Pic1 */
185 outb(0xa1, 0xff); /* Maskout all interrupts Pic2 */
187 pe_identify_machine(args
);
197 void PE_create_console( void )
199 if ( (PE_fb_vaddr
== 0) && (PE_state
.video
.v_baseAddr
!= 0) )
201 PE_fb_vaddr
= mapframebuffer((caddr_t
) PE_state
.video
.v_baseAddr
,
202 (PE_fb_mode
== TEXT_MODE
) ?
203 /* text mode */ PE_state
.video
.v_rowBytes
:
204 /* grfx mode */ PE_state
.video
.v_rowBytes
*
205 PE_state
.video
.v_height
);
208 if (PE_state
.video
.v_display
)
209 PE_initialize_console( &PE_state
.video
, kPEGraphicsMode
);
211 PE_initialize_console( &PE_state
.video
, kPETextMode
);
214 int PE_current_console( PE_Video
* info
)
216 *info
= PE_state
.video
;
218 if ( PE_fb_mode
== TEXT_MODE
)
221 * FIXME: Prevent the IOBootFrameBuffer from starting up
222 * when we are in Text mode.
224 info
->v_baseAddr
= 0;
230 void PE_display_icon( unsigned int flags
,
235 extern boolean_t
PE_get_hotkey( unsigned char key
)
240 static timebase_callback_func gTimebaseCallback
;
242 void PE_register_timebase_callback(timebase_callback_func callback
)
244 gTimebaseCallback
= callback
;
246 PE_call_timebase_callback();
249 void PE_call_timebase_callback(void)
251 struct timebase_freq_t timebase_freq
;
252 unsigned long num
, den
, cnt
;
254 num
= gPEClockFrequencyInfo
.bus_clock_rate_num
* gPEClockFrequencyInfo
.bus_to_dec_rate_num
;
255 den
= gPEClockFrequencyInfo
.bus_clock_rate_den
* gPEClockFrequencyInfo
.bus_to_dec_rate_den
;
259 if ((num
% cnt
) || (den
% cnt
)) {
268 timebase_freq
.timebase_num
= num
;
269 timebase_freq
.timebase_den
= den
;
271 if (gTimebaseCallback
) gTimebaseCallback(&timebase_freq
);
275 * map the framebuffer into kernel vm and return the (virtual)
279 mapframebuffer( caddr_t physaddr
, /* start of framebuffer */
280 int length
) /* num bytes to map */
284 if (physaddr
!= (caddr_t
)trunc_page(physaddr
))
285 panic("Framebuffer not on page boundary");
287 vmaddr
= io_map((vm_offset_t
)physaddr
, length
);
289 panic("can't alloc VM for framebuffer");