X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0b4e3aa066abc0728aacb4bbeb86f53f9737156e..eee3565979933af707c711411001ba11fe406a3c:/pexpert/i386/pe_init.c diff --git a/pexpert/i386/pe_init.c b/pexpert/i386/pe_init.c index aa1c089ec..f1e24b31e 100644 --- a/pexpert/i386/pe_init.c +++ b/pexpert/i386/pe_init.c @@ -1,102 +1,100 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * file: pe_init.c * i386 platform expert initialization. */ + #include #include +#include #include #include #include #include #include +#include #include -#include "fakePPCStructs.h" -#include "fakePPCDeviceTree.h" +#if CONFIG_CSR +#include +#endif + +#include "boot_images.h" /* extern references */ extern void pe_identify_machine(void * args); -extern void initialize_screen(void *, unsigned int); - -/* Local references */ -static vm_offset_t mapframebuffer(caddr_t,int); -static vm_offset_t PE_fb_vaddr = 0; -static int PE_fb_mode = TEXT_MODE; -static KERNBOOTSTRUCT * PE_kbp = 0; /* private globals */ PE_state_t PE_state; -dt_data gMemoryMapNode; -dt_data gDriversProp; /* Clock Frequency Info */ clock_frequency_info_t gPEClockFrequencyInfo; +void *gPEEFISystemTable; +void *gPEEFIRuntimeServices; + +static boot_icon_element* norootIcon_lzss; +static const uint8_t* norootClut_lzss; + int PE_initialize_console( PE_Video * info, int op ) { static int last_console = -1; - Boot_Video bootInfo; - Boot_Video * bInfo; - /* - * Refuse changes from outside pexpert. - * The video mode setup by the booter cannot be changed. - */ - if ( info && (info == &PE_state.video) ) - { - bootInfo.v_baseAddr = PE_fb_vaddr; - bootInfo.v_rowBytes = info->v_rowBytes; - bootInfo.v_width = info->v_width; - bootInfo.v_height = info->v_height; - bootInfo.v_depth = info->v_depth; - bootInfo.v_display = PE_fb_mode; - bInfo = &bootInfo; + if (info) { + info->v_offset = 0; + info->v_length = 0; + info->v_display = GRAPHICS_MODE; } - else - bInfo = 0; switch ( op ) { case kPEDisableScreen: - initialize_screen((void *) bInfo, op); -#ifdef FIXME - last_console = switch_to_serial_console(); -#endif + initialize_screen(info, op); kprintf("kPEDisableScreen %d\n", last_console); + if (!console_is_serial()) + last_console = switch_to_serial_console(); break; case kPEEnableScreen: - initialize_screen((void *) bInfo, op); + initialize_screen(info, op); + if (info) PE_state.video = *info; kprintf("kPEEnableScreen %d\n", last_console); -#ifdef FIXME if( last_console != -1) switch_to_old_console( last_console); -#endif break; + case kPEBaseAddressChange: + if (info) PE_state.video = *info; + /* fall thru */ + default: - initialize_screen((void *) bInfo, op); + initialize_screen(info, op); break; } @@ -105,156 +103,137 @@ int PE_initialize_console( PE_Video * info, int op ) void PE_init_iokit(void) { - long * dt; - void * desc; - unsigned char * data; - unsigned char * clut; + enum { kMaxBootVar = 128 }; + + boolean_t bootClutInitialized = FALSE; + boolean_t noroot_rle_Initialized = FALSE; - typedef struct { - char name[32]; - unsigned long length; - unsigned long value[2]; - } DriversPackageProp; + DTEntry entry; + unsigned int size; + uint32_t *map; + boot_progress_element *bootPict; + + norootIcon_lzss = NULL; + norootClut_lzss = NULL; + + PE_init_kprintf(TRUE); + PE_init_printf(TRUE); + + kprintf("Kernel boot args: '%s'\n", PE_boot_args()); /* - * Update the fake device tree with the driver information provided by - * the booter. + * Fetch the CLUT and the noroot image. */ - gDriversProp.length = PE_kbp->numBootDrivers * sizeof(DriversPackageProp); - gMemoryMapNode.length = 2 * sizeof(long); - - dt = (long *) createdt( fakePPCDeviceTree, - &((boot_args*)PE_state.fakePPCBootArgs)->deviceTreeLength ); - - if ( dt ) - { - DriversPackageProp * prop = (DriversPackageProp *) gDriversProp.address; - int i; - - /* Copy driver info in kernBootStruct to fake device tree */ - - for ( i = 0; i < PE_kbp->numBootDrivers; i++, prop++ ) - { - switch ( PE_kbp->driverConfig[i].type ) - { - case kBootDriverTypeKEXT: - sprintf(prop->name, "Driver-%lx", PE_kbp->driverConfig[i].address); - break; - - case kBootDriverTypeMKEXT: - sprintf(prop->name, "DriversPackage-%lx", PE_kbp->driverConfig[i].address); - break; - - default: - sprintf(prop->name, "DriverBogus-%lx", PE_kbp->driverConfig[i].address); - break; + if( kSuccess == DTLookupEntry(NULL, "/chosen/memory-map", &entry)) { + if( kSuccess == DTGetProperty(entry, "BootCLUT", (void **) &map, &size)) { + if (sizeof(appleClut8) <= map[1]) { + bcopy( (void *)ml_static_ptovirt(map[0]), appleClut8, sizeof(appleClut8) ); + bootClutInitialized = TRUE; } - prop->length = sizeof(prop->value); - prop->value[0] = PE_kbp->driverConfig[i].address; - prop->value[1] = PE_kbp->driverConfig[i].size; } - *gMemoryMapNode.address = PE_kbp->numBootDrivers + 1; - } + if( kSuccess == DTGetProperty(entry, "Pict-FailedBoot", (void **) &map, &size)) { + bootPict = (boot_progress_element *) ml_static_ptovirt(map[0]); + default_noroot.width = bootPict->width; + default_noroot.height = bootPict->height; + default_noroot.dx = 0; + default_noroot.dy = bootPict->yOffset; + default_noroot_data = &bootPict->data[0]; + noroot_rle_Initialized = TRUE; + } - /* Setup powermac_info and powermac_machine_info structures */ + if( kSuccess == DTGetProperty(entry, "FailedCLUT", (void **) &map, &size)) { + norootClut_lzss = (uint8_t*) ml_static_ptovirt(map[0]); + } - ((boot_args*)PE_state.fakePPCBootArgs)->deviceTreeP = (unsigned long *) dt; - ((boot_args*)PE_state.fakePPCBootArgs)->topOfKernelData = (unsigned int) kalloc(0x2000); + if( kSuccess == DTGetProperty(entry, "FailedImage", (void **) &map, &size)) { + norootIcon_lzss = (boot_icon_element *) ml_static_ptovirt(map[0]); + if (norootClut_lzss == NULL) { + printf("ERROR: No FailedCLUT provided for noroot icon!\n"); + } + } + } - /* - * Setup the OpenFirmware Device Tree routines - * so the console can be found and the right I/O space - * can be used.. - */ - DTInit(dt); + if (!bootClutInitialized) { + bcopy( (void *) (uintptr_t) bootClut, (void *) appleClut8, sizeof(appleClut8) ); + } + if (!noroot_rle_Initialized) { + default_noroot.width = kFailedBootWidth; + default_noroot.height = kFailedBootHeight; + default_noroot.dx = 0; + default_noroot.dy = kFailedBootOffset; + default_noroot_data = failedBootPict; + } + /* * Initialize the spinning wheel (progress indicator). */ - clut = appleClut8; - desc = &default_progress; - data = default_progress_data; + vc_progress_initialize(&default_progress, + default_progress_data1x, + default_progress_data2x, + default_progress_data3x, + (unsigned char *) appleClut8); - vc_progress_initialize( desc, data, clut ); - - PE_initialize_console( (PE_Video *) 0, kPEAcquireScreen ); - - (void) StartIOKit( (void*)dt, (void*)PE_state.fakePPCBootArgs, 0, 0); + StartIOKit( PE_state.deviceTreeHead, PE_state.bootArgs, gPEEFIRuntimeServices, NULL); } -void PE_init_platform(boolean_t vm_initialized, void * args) +void PE_init_platform(boolean_t vm_initialized, void * _args) { - if (PE_state.initialized == FALSE) - { - extern unsigned int halt_in_debugger, disableDebugOuput; - unsigned int debug_arg; - - PE_kbp = (KERNBOOTSTRUCT *) args; + boot_args *args = (boot_args *)_args; + if (PE_state.initialized == FALSE) { PE_state.initialized = TRUE; - PE_state.bootArgs = args; - PE_state.video.v_baseAddr = PE_kbp->video.v_baseAddr; - PE_state.video.v_rowBytes = PE_kbp->video.v_rowBytes; - PE_state.video.v_height = PE_kbp->video.v_height; - PE_state.video.v_width = PE_kbp->video.v_width; - PE_state.video.v_depth = PE_kbp->video.v_depth; - PE_state.video.v_display = PE_kbp->video.v_display; - PE_fb_mode = PE_kbp->graphicsMode; - PE_state.fakePPCBootArgs = (boot_args *)&fakePPCBootArgs; - ((boot_args *)PE_state.fakePPCBootArgs)->machineType = 386; - - if (PE_fb_mode == TEXT_MODE) - { - /* Force a text display if the booter did not setup a - * VESA frame buffer. - */ - PE_state.video.v_display = 0; - } - /* - * If DB_HALT flag is set, then cause a breakpoint to the debugger - * immediately after the kernel debugger has been initialized. - * - * If DB_PRT flag is set, then enable debugger printf. - */ - disableDebugOuput = TRUE; /* FIXME: override osfmk/i386/AT386/model_dep.c */ - - if (PE_parse_boot_arg("debug", &debug_arg)) { - if (debug_arg & DB_HALT) halt_in_debugger = 1; - if (debug_arg & DB_PRT) disableDebugOuput = FALSE; + // New EFI-style + PE_state.bootArgs = _args; + PE_state.deviceTreeHead = (void *) ml_static_ptovirt(args->deviceTreeP); + if (args->Video.v_baseAddr) { + PE_state.video.v_baseAddr = args->Video.v_baseAddr; // remains physical address + PE_state.video.v_rowBytes = args->Video.v_rowBytes; + PE_state.video.v_width = args->Video.v_width; + PE_state.video.v_height = args->Video.v_height; + PE_state.video.v_depth = args->Video.v_depth; + PE_state.video.v_display = args->Video.v_display; + strlcpy(PE_state.video.v_pixelFormat, "PPPPPPPP", + sizeof(PE_state.video.v_pixelFormat)); + } else { + PE_state.video.v_baseAddr = args->VideoV1.v_baseAddr; // remains physical address + PE_state.video.v_rowBytes = args->VideoV1.v_rowBytes; + PE_state.video.v_width = args->VideoV1.v_width; + PE_state.video.v_height = args->VideoV1.v_height; + PE_state.video.v_depth = args->VideoV1.v_depth; + PE_state.video.v_display = args->VideoV1.v_display; + strlcpy(PE_state.video.v_pixelFormat, "PPPPPPPP", + sizeof(PE_state.video.v_pixelFormat)); } + +#ifdef kBootArgsFlagHiDPI + if (args->flags & kBootArgsFlagHiDPI) + PE_state.video.v_scale = kPEScaleFactor2x; + else + PE_state.video.v_scale = kPEScaleFactor1x; +#else + PE_state.video.v_scale = kPEScaleFactor1x; +#endif } - if (!vm_initialized) - { - /* Hack! FIXME.. */ - outb(0x21, 0xff); /* Maskout all interrupts Pic1 */ - outb(0xa1, 0xff); /* Maskout all interrupts Pic2 */ - + if (!vm_initialized) { + + if (PE_state.deviceTreeHead) { + DTInit(PE_state.deviceTreeHead); + } + pe_identify_machine(args); - } - else - { pe_init_debug(); + } - PE_create_console(); - } } void PE_create_console( void ) { - if ( (PE_fb_vaddr == 0) && (PE_state.video.v_baseAddr != 0) ) - { - PE_fb_vaddr = mapframebuffer((caddr_t) PE_state.video.v_baseAddr, - (PE_fb_mode == TEXT_MODE) ? - /* text mode */ PE_state.video.v_rowBytes : - /* grfx mode */ PE_state.video.v_rowBytes * - PE_state.video.v_height); - } - - if (PE_state.video.v_display) + if ( PE_state.video.v_display == GRAPHICS_MODE ) PE_initialize_console( &PE_state.video, kPEGraphicsMode ); else PE_initialize_console( &PE_state.video, kPETextMode ); @@ -264,31 +243,31 @@ int PE_current_console( PE_Video * info ) { *info = PE_state.video; - if ( PE_fb_mode == TEXT_MODE ) - { - /* - * FIXME: Prevent the IOBootFrameBuffer from starting up - * when we are in Text mode. - */ - info->v_baseAddr = 0; - - /* - * Scale the size of the text screen from characters - * to pixels. - */ - info->v_width *= 8; // CHARWIDTH - info->v_height *= 16; // CHARHEIGHT - } - return (0); } -void PE_display_icon( unsigned int flags, - const char * name ) +void PE_display_icon( __unused unsigned int flags, __unused const char * name ) { + if ( norootIcon_lzss && norootClut_lzss ) { + uint32_t width = norootIcon_lzss->width; + uint32_t height = norootIcon_lzss->height; + uint32_t x = ((PE_state.video.v_width - width) / 2); + uint32_t y = ((PE_state.video.v_height - height) / 2) + norootIcon_lzss->y_offset_from_center; + + vc_display_lzss_icon(x, y, width, height, + &norootIcon_lzss->data[0], + norootIcon_lzss->data_size, + norootClut_lzss); + } + else if ( default_noroot_data ) { + vc_display_icon( &default_noroot, default_noroot_data ); + } else { + printf("ERROR: No data found for noroot icon!\n"); + } } -extern boolean_t PE_get_hotkey( unsigned char key ) +boolean_t +PE_get_hotkey(__unused unsigned char key) { return (FALSE); } @@ -327,31 +306,11 @@ void PE_call_timebase_callback(void) if (gTimebaseCallback) gTimebaseCallback(&timebase_freq); } -/* - * map the framebuffer into kernel vm and return the (virtual) - * address. - */ -static vm_offset_t -mapframebuffer( caddr_t physaddr, /* start of framebuffer */ - int length) /* num bytes to map */ -{ - vm_offset_t vmaddr; - - if (physaddr != (caddr_t)trunc_page(physaddr)) - panic("Framebuffer not on page boundary"); - - vmaddr = io_map((vm_offset_t)physaddr, length); - if (vmaddr == 0) - panic("can't alloc VM for framebuffer"); - - return vmaddr; -} - /* * The default (non-functional) PE_poll_input handler. */ static int -PE_stub_poll_input(unsigned int options, char * c) +PE_stub_poll_input(__unused unsigned int options, char * c) { *c = 0xff; return 1; /* 0 for success, 1 for unsupported */ @@ -364,3 +323,37 @@ PE_stub_poll_input(unsigned int options, char * c) */ int (*PE_poll_input)(unsigned int options, char * c) = PE_stub_poll_input; + +boolean_t +PE_reboot_on_panic(void) +{ + boot_args *args = (boot_args *)PE_state.bootArgs; + + if (args->flags & kBootArgsFlagRebootOnPanic) + return TRUE; + else + return FALSE; +} + +void +PE_sync_panic_buffers(void) +{ +} + +/* rdar://problem/21244753 */ +uint32_t +PE_i_can_has_debugger(uint32_t *debug_flags) +{ +#if CONFIG_CSR + if (csr_check(CSR_ALLOW_KERNEL_DEBUGGER) != 0 && + csr_check(CSR_ALLOW_APPLE_INTERNAL) != 0) { + if (debug_flags) + *debug_flags = 0; + return FALSE; + } +#endif + if (debug_flags) { + *debug_flags = debug_boot_arg; + } + return TRUE; +}