darwin-xnu/pexpert/i386/pe_init.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
   3 *
   4 * @APPLE_LICENSE_HEADER_START@
   5 * 
   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.
  11 * 
  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
  18 * under the License.
  19 * 
  20 * @APPLE_LICENSE_HEADER_END@
  21 */
  22/*
  23 * file: pe_init.c
  24 *    i386 platform expert initialization.
  25 */
  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/sched_prim.h>
  34
  35#include "fakePPCStructs.h"
  36#include "fakePPCDeviceTree.h"
  37#include "boot_images.h"
  38
  39/* extern references */
  40extern void pe_identify_machine(void * args);
  41extern void initialize_screen(void *, unsigned int);
  42
  43/* Local references */
  44static int         PE_fb_mode  = TEXT_MODE;
  45
  46/* private globals */
  47PE_state_t  PE_state;
  48dt_data     gMemoryMapNode;
  49dt_data     gDriversProp;
  50dt_data     gRootpathProp;
  51dt_data     gCompatibleProp;
  52
  53/* Clock Frequency Info */
  54clock_frequency_info_t gPEClockFrequencyInfo;
  55
  56int PE_initialize_console( PE_Video * info, int op )
  57{
  58    static int   last_console = -1;
  59    Boot_Video   bootInfo;
  60    Boot_Video * bInfo;
  61
  62    /*
  63     * Refuse changes from outside pexpert.
  64     * The video mode setup by the booter cannot be changed.
  65     */
  66    if ( info )
  67    {
  68        bootInfo.v_baseAddr = info->v_baseAddr;
  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        bInfo = &bootInfo;
  74        if (info == &PE_state.video) {
  75            bootInfo.v_display  = PE_fb_mode;
  76        } else {
  77            bootInfo.v_display  = GRAPHICS_MODE;
  78        }
  79    }
  80    else
  81        bInfo = 0;
  82
  83    switch ( op ) {
  84
  85        case kPEDisableScreen:
  86            initialize_screen((void *) bInfo, op);
  87#ifdef FIXME
  88            last_console = switch_to_serial_console();
  89#endif
  90            kprintf("kPEDisableScreen %d\n", last_console);
  91            break;
  92
  93        case kPEEnableScreen:
  94            initialize_screen((void *) bInfo, op);
  95            kprintf("kPEEnableScreen %d\n", last_console);
  96#ifdef FIXME
  97            if( last_console != -1)
  98                switch_to_old_console( last_console);
  99#endif
 100            break;
 101        
 102        default:
 103            initialize_screen((void *) bInfo, op);
 104            break;
 105    }
 106
 107    return 0;
 108}
 109
 110void PE_init_iokit(void)
 111{
 112    long * dt;
 113    int    i;
 114    KernelBootArgs_t *kap = (KernelBootArgs_t *)PE_state.bootArgs;
 115    enum { kMaxBootVar = 128 };
 116    char *rdValue, *platformValue;
 117        
 118    typedef struct {
 119        char            name[32];
 120        unsigned long   length;
 121        unsigned long   value[2];
 122    } DriversPackageProp;
 123
 124    PE_init_kprintf(TRUE);
 125    PE_init_printf(TRUE);
 126
 127    /*
 128     * Update the fake device tree with the driver information provided by
 129     * the booter.
 130     */
 131
 132    gDriversProp.length   = kap->numBootDrivers * sizeof(DriversPackageProp);
 133    gMemoryMapNode.length = 2 * sizeof(long);
 134
 135    rdValue = kalloc(kMaxBootVar);
 136    if ( PE_parse_boot_arg("rd", rdValue) ) {
 137        if (*rdValue == '*') {
 138            gRootpathProp.address = (rdValue + 1);
 139        } else {
 140            gRootpathProp.address = rdValue;
 141        }
 142        strcat(rdValue, ",");
 143    } else {
 144        gRootpathProp.address = rdValue;
 145        rdValue[0] = '\0';
 146    }
 147    strcat(rdValue, kap->bootFile);
 148    gRootpathProp.length = strlen(rdValue) + 1;
 149
 150    platformValue = kalloc(kMaxBootVar);
 151    if ( ! PE_parse_boot_arg("platform", platformValue) ) {
 152        strcpy(platformValue, kDefaultPlatformName);
 153    }
 154    gCompatibleProp.address = platformValue;
 155    gCompatibleProp.length = strlen(platformValue) + 1;
 156
 157    dt = (long *) createdt( fakePPCDeviceTree,
 158                  &((boot_args*)PE_state.fakePPCBootArgs)->deviceTreeLength );
 159
 160    kfree(rdValue, kMaxBootVar);
 161    kfree(platformValue, kMaxBootVar);
 162
 163
 164    if ( dt )
 165    {
 166        DriversPackageProp * prop = (DriversPackageProp *) gDriversProp.address;
 167
 168        /* Copy driver info in kernBootStruct to fake device tree */
 169
 170        for ( i = 0; i < kap->numBootDrivers; i++, prop++ )
 171        {
 172            switch ( kap->driverConfig[i].type )
 173            {
 174                case kBootDriverTypeKEXT:
 175                    sprintf(prop->name, "Driver-%lx", kap->driverConfig[i].address);
 176                    break;
 177                
 178                 case kBootDriverTypeMKEXT:
 179                    sprintf(prop->name, "DriversPackage-%lx", kap->driverConfig[i].address);
 180                    break;
 181
 182                default:
 183                    sprintf(prop->name, "DriverBogus-%lx", kap->driverConfig[i].address);
 184                    break;
 185            }
 186            prop->length   = sizeof(prop->value);
 187            prop->value[0] = kap->driverConfig[i].address;
 188            prop->value[1] = kap->driverConfig[i].size;
 189        }
 190
 191        *((long *)gMemoryMapNode.address) = kap->numBootDrivers + 1;
 192    }
 193
 194    /* Setup powermac_info and powermac_machine_info structures */
 195
 196    ((boot_args*)PE_state.fakePPCBootArgs)->deviceTreeP = (unsigned long *) dt;
 197    ((boot_args*)PE_state.fakePPCBootArgs)->topOfKernelData = (unsigned long) kalloc(0x2000);
 198
 199    /* 
 200     * Setup the OpenFirmware Device Tree routines
 201     * so the console can be found and the right I/O space 
 202     * can be used..
 203     */
 204    DTInit(dt);
 205
 206    /*
 207     * Fetch the CLUT and the noroot image.
 208     */
 209    bcopy( (void *) (uintptr_t) bootClut, (void *) appleClut8, sizeof(appleClut8) );
 210
 211    default_noroot.width  = kFailedBootWidth;
 212    default_noroot.height = kFailedBootHeight;
 213    default_noroot.dx     = 0;
 214    default_noroot.dy     = kFailedBootOffset;
 215    default_noroot_data   = failedBootPict;
 216    
 217    /*
 218     * Initialize the panic UI
 219     */
 220    panic_ui_initialize( (unsigned char *) appleClut8 );
 221
 222    /*
 223     * Initialize the spinning wheel (progress indicator).
 224     */
 225    vc_progress_initialize( &default_progress, default_progress_data,
 226                            (unsigned char *) appleClut8 );
 227
 228    (void) StartIOKit( (void*)dt, PE_state.bootArgs, 0, 0);
 229}
 230
 231void PE_init_platform(boolean_t vm_initialized, void * args)
 232{
 233        if (PE_state.initialized == FALSE)
 234        {
 235            KernelBootArgs_t *kap = (KernelBootArgs_t *) args;
 236
 237            PE_state.initialized        = TRUE;
 238            PE_state.bootArgs           = args;
 239            PE_state.video.v_baseAddr   = kap->video.v_baseAddr;
 240            PE_state.video.v_rowBytes   = kap->video.v_rowBytes;
 241            PE_state.video.v_height     = kap->video.v_height;
 242            PE_state.video.v_width      = kap->video.v_width;
 243            PE_state.video.v_depth      = kap->video.v_depth;
 244            PE_state.video.v_display    = kap->video.v_display;
 245            PE_fb_mode                  = kap->graphicsMode;
 246            PE_state.fakePPCBootArgs    = (boot_args *)&fakePPCBootArgs;
 247            ((boot_args *)PE_state.fakePPCBootArgs)->machineType        = 386;
 248
 249        if (PE_fb_mode == TEXT_MODE)
 250        {
 251            /* Force a text display if the booter did not setup a
 252             * VESA frame buffer.
 253             */
 254            PE_state.video.v_display = 0;
 255        }
 256    }
 257
 258    if (!vm_initialized)
 259    {
 260                /* Hack! FIXME.. */ 
 261        outb(0x21, 0xff);   /* Maskout all interrupts Pic1 */
 262        outb(0xa1, 0xff);   /* Maskout all interrupts Pic2 */
 263 
 264        pe_identify_machine(args);
 265    }
 266    else
 267    {
 268        pe_init_debug();
 269    }
 270}
 271
 272void PE_create_console( void )
 273{
 274    if ( PE_state.video.v_display )
 275        PE_initialize_console( &PE_state.video, kPEGraphicsMode );
 276    else
 277        PE_initialize_console( &PE_state.video, kPETextMode );
 278}
 279
 280int PE_current_console( PE_Video * info )
 281{
 282    *info = PE_state.video;
 283
 284    if ( PE_fb_mode == TEXT_MODE )
 285    {
 286        /*
 287         * FIXME: Prevent the IOBootFrameBuffer from starting up
 288         * when we are in Text mode.
 289         */
 290        info->v_baseAddr = 0;
 291        
 292        /*
 293         * Scale the size of the text screen from characters
 294         * to pixels.
 295         */
 296        info->v_width  *= 8;   // CHARWIDTH
 297        info->v_height *= 16;  // CHARHEIGHT
 298    }
 299
 300    return (0);
 301}
 302
 303void PE_display_icon( __unused unsigned int flags, __unused const char * name )
 304{
 305    if ( default_noroot_data )
 306        vc_display_icon( &default_noroot, default_noroot_data );
 307}
 308
 309extern boolean_t PE_get_hotkey( __unused unsigned char key )
 310{
 311    return (FALSE);
 312}
 313
 314static timebase_callback_func gTimebaseCallback;
 315
 316void PE_register_timebase_callback(timebase_callback_func callback)
 317{
 318    gTimebaseCallback = callback;
 319  
 320    PE_call_timebase_callback();
 321}
 322
 323void PE_call_timebase_callback(void)
 324{
 325  struct timebase_freq_t timebase_freq;
 326  unsigned long          num, den, cnt;
 327  
 328  num = gPEClockFrequencyInfo.bus_clock_rate_num * gPEClockFrequencyInfo.bus_to_dec_rate_num;
 329  den = gPEClockFrequencyInfo.bus_clock_rate_den * gPEClockFrequencyInfo.bus_to_dec_rate_den;
 330  
 331  cnt = 2;
 332  while (cnt <= den) {
 333    if ((num % cnt) || (den % cnt)) {
 334      cnt++;
 335      continue;
 336    }
 337    
 338    num /= cnt;
 339    den /= cnt;
 340  }
 341  
 342  timebase_freq.timebase_num = num;
 343  timebase_freq.timebase_den = den;
 344  
 345  if (gTimebaseCallback) gTimebaseCallback(&timebase_freq);
 346}
 347
 348/*
 349 * The default (non-functional) PE_poll_input handler.
 350 */
 351static int
 352PE_stub_poll_input(__unused unsigned int options, char * c)
 353{
 354    *c = 0xff;
 355    return 1;  /* 0 for success, 1 for unsupported */
 356}
 357
 358/*
 359 * Called by the kernel debugger to poll for keyboard input.
 360 * Keyboard drivers may replace the default stub function
 361 * with their polled-mode input function.
 362 */
 363int (*PE_poll_input)(unsigned int options, char * c)
 364        = PE_stub_poll_input;
 365
 366
 367
 368
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.