Annotation of kernel/driverkit/i386/autoconf_i386.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:  * Copyright (c) 1993 NeXT Computer, Inc.
                     27:  *
                     28:  * 486 Driverkit configuration.
                     29:  *
                     30:  * HISTORY
                     31:  *
                     32:  * 28 Jan 1993  Brian Pinkerton at NeXT
                     33:  *     Added support for new, MI autoconf logic, and new driverkit API.
                     34:  * 10 Nov 1992 Brian Pinkerton at NeXT
                     35:  *     Added indirect probe logic.
                     36:  * 20 Aug 1992 Joe Pasqua
                     37:  *     Init intrReq & intrAttached of kern_dev in configure_device_class().
                     38:  * 3 August 1992 ? at NeXT
                     39:  *     Created.
                     40:  */
                     41: 
                     42: #import <mach/mach_types.h>
                     43: #import <kern/mach_header.h>
                     44: 
                     45: #import <machkit/NXLock.h>
                     46: #import <driverkit/KernDeviceDescription.h>
                     47: #import <driverkit/KernStringList.h>
                     48: #import <driverkit/i386/IOEISADeviceDescription.h>
                     49: #import <driverkit/IODeviceDescriptionPrivate.h>
                     50: #import <driverkit/IODirectDevice.h>
                     51: #import <driverkit/IODeviceKernPrivate.h>
                     52: #import <driverkit/IODeviceParams.h>
                     53: #import <driverkit/Device_ddm.h>
                     54: #import <driverkit/configTableKern.h>
                     55: #import <driverkit/KernDevice.h>
                     56: #import <driverkit/IOConfigTable.h>
                     57: #import <driverkit/driverTypesPrivate.h>
                     58: #import <driverkit/autoconfCommon.h>
                     59: #import <driverkit/i386/EISAKernBus.h>
                     60: #import <driverkit/i386/PCMCIA.h>
                     61: #import <driverkit/i386/PCMCIAKernBus.h>
                     62: #import <driverkit/i386/PCIKernBus.h>
                     63: 
                     64: #import <machdep/i386/kernBootStruct.h>
                     65: 
                     66: boolean_t eisa_id(int slot, unsigned int *_id);
                     67: 
                     68: static void probe_indirect(const char **indirectNamep, id driverInstance);
                     69: 
                     70: static BOOL configureDriver(const char *configData);
                     71: const char *findBootConfigString(int n);
                     72: static void bootDriverInit(void);
                     73: 
                     74: id             defaultBus, defaultBusClass;
                     75: static BOOL    printedPCMCIAMessage;
                     76: 
                     77: /*
                     78:  * Native indirect driver classes.
                     79:  */
                     80: char *indirectDevList[] = {
                     81:        "SCSIDisk",
                     82:        "SCSIGeneric",
                     83:        "IODiskPartition",
                     84:        NULL
                     85: };
                     86: 
                     87: /*
                     88:  * Pseudo device list.
                     89:  */
                     90: char *pseudoDevList[] = {
                     91:        "EventDriver",
                     92:        "kmDevice",
                     93:        NULL
                     94: };
                     95: 
                     96: #define SERVER_NAME_KEY                "Server Name"
                     97: #define CLASS_NAMES_KEY        "Class Names"
                     98: #define DRIVER_NAME_KEY        "Driver Name"
                     99: #define BUS_TYPE_KEY           "Bus Type"
                    100: #define BUS_CLASS_KEY          "Bus Class"
                    101: #define FAMILY_KEY             "Family"
                    102: #define BUS_FAMILY             "Bus"
                    103: #define KERN_BUS_FORMAT                "%sKernBus"
                    104: #define DEVICE_DESCR_FORMAT    "IO%sDeviceDescription"
                    105: #define DEFAULT_BUS            "EISA"
                    106: #define NAME_BUF_LEN           128
                    107: 
                    108: 
                    109: BOOL is_ISA;
                    110: 
                    111: static BOOL
                    112: versionIsOK(const char *serverName)
                    113: {
                    114:     int version;
                    115:     
                    116:     /*
                    117:      * Right now, if serverName is NULL, that means the driver
                    118:      * is compiled into the kernel, so don't check the version.
                    119:      * This may change later, however.
                    120:      */
                    121:     
                    122:     if (serverName != NULL) {
                    123:        version = [IODevice
                    124:                driverKitVersionForDriverNamed:(char *)serverName];
                    125:        if (version == -1)
                    126:            version = 310;
                    127:        /*
                    128:         * TODO: revisit this policy decision if DriverKit
                    129:         * compatibility changes in the future.
                    130:         */
                    131:        if (version <= 310) {
                    132:            IOLog("WARNING: driver %s uses incompatible DriverKit version %d\n", serverName, version);
                    133:            IOLog("Driver %s could not be configured\n", 
                    134:                serverName);
                    135:            return NO;
                    136:        }
                    137:     }
                    138:     return YES;
                    139: }
                    140: 
                    141: /*
                    142:  * Eventually, this routine will only initialize the boot device(s) per 
                    143:  * input from the booter via KERNBOOTSTRUCT. 
                    144:  * For now, configure all native devices enumerated in the various
                    145:  * tables in device_configuration.c.
                    146:  */
                    147: void
                    148: probeNativeDevices(void)
                    149: {
                    150:        int             slot;
                    151:        unsigned int    _id;
                    152:        char            **configData;
                    153:        int             i;
                    154:        const char      *config;
                    155:        IOConfigTable   *configTable = nil;
                    156:        const char      *family, *busName;
                    157:        char            *nameBuf;
                    158:        id              busClass;
                    159:        
                    160:        //
                    161:        // Initialize drivers and modules loaded by booter.
                    162:        
                    163:        bootDriverInit();
                    164: 
                    165:        nameBuf = (char *)IOMalloc(NAME_BUF_LEN);
                    166: 
                    167:        //
                    168:        // Find all bus drivers.
                    169:        //
                    170:        for(i=1; ; i++) {
                    171:                config = findBootConfigString(i);
                    172:                if(config == NULL) {
                    173:                        break;
                    174:                }
                    175:                configTable = [IOConfigTable newForConfigData:config];
                    176:                family = [configTable valueForStringKey:FAMILY_KEY];
                    177:                if (family && strcmp(family, BUS_FAMILY) == 0) {
                    178:                    busName = [configTable valueForStringKey:BUS_CLASS_KEY];
                    179:                    busClass = objc_getClass(busName);
                    180:                    (void)[busClass probeBus:configTable];
                    181:                }
                    182:                if (family)
                    183:                    [configTable freeString:family];
                    184:        }
                    185:        
                    186:        defaultBusClass = [KernBus lookupBusClassWithName:DEFAULT_BUS]; // XXX
                    187:        if (defaultBusClass == nil) {
                    188:                sprintf(nameBuf, "Missing %s kernel bus class", DEFAULT_BUS);
                    189:                panic(nameBuf);
                    190:        }
                    191:        defaultBus = [KernBus lookupBusInstanceWithName:DEFAULT_BUS busId:0];
                    192:        
                    193:        /*
                    194:         * For now this is the only
                    195:         * concession to EISA bus.
                    196:         */
                    197:        if (eisa_id(0, &_id)) {
                    198:                printf("CPU:\tEISA id %08x\n", _id);
                    199:                for (slot = 1; slot <= 0xf; slot++) {
                    200:                        if (eisa_id(slot, &_id))
                    201:                                printf("slot %x:\tEISA id %08x\n", slot, _id);
                    202:                }
                    203:                led_msg("NeXT");
                    204:                is_ISA = NO;
                    205:        }
                    206:        else {
                    207:                printf("ISA bus\n");
                    208:                is_ISA = YES;
                    209:        }
                    210: 
                    211: 
                    212:        printf("DriverKit version %d\n",[IODevice driverKitVersion]);
                    213: 
                    214:        /*
                    215:         * Configure all devices for which the booter has given us config info.
                    216:         * The zeroth config string is the system config table.
                    217:         */
                    218:        for(i=1; ; i++) {
                    219:                config = findBootConfigString(i);
                    220:                if(config == NULL) {
                    221:                        break;
                    222:                }
                    223:                configureDriver(config);
                    224:        }
                    225:        IOFree(nameBuf, NAME_BUF_LEN);
                    226: }
                    227: 
                    228: 
                    229: @protocol OldProbeMethods
                    230: + probe;
                    231: + probe:(int)a deviceMaster:(port_t) b;
                    232: @end
                    233: 
                    234: /* 
                    235:  * Called from MD probeNativeDevices() and from configureThread(), the
                    236:  * IOTask version of IOProbeDriver().
                    237:  *
                    238:  * Given a class name and an ASCII representation of a config file,
                    239:  * create a kern_dev and an IODeviceDescription and probe the class. 
                    240:  * This is used both at boot time - for the boot device and (temporarily) 
                    241:  * any native drivers with static config tables - and by IOProbeDriver().
                    242:  * 
                    243:  * Returns YES if driver was started successfully, else returns NO.
                    244: */
                    245: static BOOL
                    246: configureDriver(
                    247:     const char *configData
                    248: )
                    249: {
                    250:        const char      *className, *classNames;
                    251:        KernStringList  *classNameList = nil;
                    252:        const char      *serverName = NULL;
                    253:        IOConfigTable   *configTable = nil;
                    254:        Class           theClass;
                    255:        id              deviceDescription = nil;
                    256:        id              device = nil;
                    257:        id              ioDeviceDescription = nil;
                    258:        IOReturn        drtn;
                    259:        int             index, classesLoaded, version;
                    260:        BOOL            versionChecked = NO;
                    261:        const char      *busType, *busTypeString;
                    262:        char            *nameBuf;
                    263:        id              busClass, busDescriptionClass;
                    264: 
                    265:        nameBuf = (char *)IOMalloc(NAME_BUF_LEN);
                    266:        
                    267:        configTable = [IOConfigTable newForConfigData:configData];
                    268: 
                    269:        serverName = [configTable valueForStringKey:SERVER_NAME_KEY];
                    270:        
                    271:        classNames = (char *)[configTable valueForStringKey:CLASS_NAMES_KEY];
                    272:        if (classNames == NULL)
                    273:            classNames = (char *)[configTable 
                    274:                                     valueForStringKey:DRIVER_NAME_KEY];
                    275:        classNameList = [[KernStringList alloc]
                    276:                            initWithWhitespaceDelimitedString:classNames];
                    277:        IOFree(classNames, strlen(classNames) + 1);
                    278:        busTypeString = [configTable valueForStringKey:BUS_TYPE_KEY];
                    279:        if (busTypeString == NULL || *busTypeString == '\0')
                    280:            busType = DEFAULT_BUS;
                    281:        else
                    282:            busType = busTypeString;
                    283: 
                    284:        sprintf(nameBuf, KERN_BUS_FORMAT, busType);
                    285:        busClass = objc_getClass((const char *)nameBuf);
                    286:        if (busClass == nil)    {
                    287:            busClass = defaultBusClass;
                    288:            busType = DEFAULT_BUS;
                    289:        }
                    290: 
                    291:        classesLoaded = 0;
                    292:        for (index = 0; index < [classNameList count]; index++) {
                    293:            className = [classNameList stringAt:index];
                    294:            theClass = objc_getClass(className);
                    295: 
                    296:            if (theClass == nil) {
                    297:                    IOLog("configureDriver: "
                    298:                          "driver class '%s' was not loaded\n", className);
                    299:                    IOLog("Driver %s could not be configured\n", serverName);
                    300:                    goto abort;
                    301:            }
                    302:            
                    303:            if (versionChecked == NO) {
                    304:                /*
                    305:                 * Right now, if serverName is NULL, that means the driver
                    306:                 * is compiled into the kernel, so don't check the version.
                    307:                 * This may change later, however.
                    308:                 */
                    309:     
                    310:                if (serverName != NULL) {
                    311:                    if (versionIsOK(serverName) == NO)
                    312:                        goto abort;
                    313:                }
                    314:                versionChecked = YES;
                    315:            }
                    316: 
                    317:            /*
                    318:             * Check to see if bus wants to configure driver itself.
                    319:             */
                    320:            if ([busClass configureDriverWithTable:configTable]) {
                    321:                classesLoaded = 1;
                    322:                /* Return success. */
                    323:                break;
                    324:            }
                    325:            
                    326:            /*
                    327:             *  Depending on the deviceStyle, we either make
                    328:             *  an DeviceDescription or the bus type device description.
                    329:             */
                    330:            switch ([theClass deviceStyle]) {
                    331:                case IO_DirectDevice:
                    332:                    deviceDescription = [busClass
                    333:                        deviceDescriptionFromConfigTable:configTable];  
                    334:     
                    335:                    if (deviceDescription == nil) {
                    336:                            IOLog("configureDriver: initFromConfigTable "
                    337:                                        "failed for class %s\n", className);
                    338:                                goto abort;
                    339:                    }
                    340:                    
                    341:                    if ([deviceDescription bus] == nil) {
                    342:                        [deviceDescription setBus:defaultBus];
                    343:                    }
                    344:                    
                    345:                    if ([[deviceDescription bus] allocateResourcesForDeviceDescription:
                    346:                                    deviceDescription] == nil) {
                    347:                            IOLog("configureDriver: could not allocate "
                    348:                                  "resources for class %s\n", className);
                    349:                                goto abort;
                    350:                    }
                    351: 
                    352:                    device = [[KernDevice alloc]
                    353:                        initWithDeviceDescription:deviceDescription];
                    354:     
                    355:                    if (device == nil) {
                    356:                            IOLog("configureDriver: initFromDeviceDescription "
                    357:                                        "failed for class %s\n", className);
                    358:                                goto abort;
                    359:                    }
                    360:                    
                    361:                    [deviceDescription setDevice:device];
                    362:                    
                    363:                    sprintf(nameBuf, "IO%sDeviceDescription", busType);
                    364:                    busDescriptionClass = objc_getClass((const char *)nameBuf);
                    365: 
                    366:                    ioDeviceDescription = [[busDescriptionClass alloc]
                    367:                        _initWithDelegate:deviceDescription];
                    368:                        
                    369:                    if (ioDeviceDescription == nil) {
                    370:                                goto abort;
                    371:                    }
                    372:                                
                    373:                    [ioDeviceDescription 
                    374:                                setDevicePort:create_dev_port(device)];
                    375:                    break;
                    376:     
                    377:                case IO_IndirectDevice:
                    378:                case IO_PseudoDevice:
                    379:                    deviceDescription = [[KernDeviceDescription alloc]
                    380:                                            initFromConfigTable:configTable];
                    381:                    if (deviceDescription == nil) {
                    382:                            goto abort;
                    383:                    }
                    384:                    
                    385:                    ioDeviceDescription = [[IODeviceDescription alloc]
                    386:                        _initWithDelegate:deviceDescription];
                    387:                        
                    388:                    if (ioDeviceDescription == nil)
                    389:                                goto abort;
                    390: 
                    391:                    break;
                    392: 
                    393:                default:
                    394:                    IOLog("Invalid style for class %s", className);
                    395:                    goto abort;
                    396:            }
                    397:     
                    398:            /*
                    399:             *  Now that we have a valid device description for the device,
                    400:             *  probe the sucker.
                    401:             */
                    402:            if (![theClass respondsTo:@selector(probe:)]) {
                    403:                    IOLog("configureDriver: Class %s does not respond "
                    404:                          "to probe:\n", className);
                    405:                    continue;
                    406:            }
                    407:     
                    408:            if (
                    409:                [IODevice addLoadedClass:theClass 
                    410:                            description:ioDeviceDescription] == IO_R_SUCCESS) {
                    411:                    classesLoaded++;
                    412:            }
                    413:        }
                    414: 
                    415:        /*
                    416:         * Only free resources if there was a fatal error before
                    417:         * addLoadedClass: was called, because the class may cache
                    418:         * the device description and config table for later use.
                    419:         */
                    420:        IOFree(nameBuf, NAME_BUF_LEN);
                    421:        [classNameList free];
                    422:        if (serverName)
                    423:            [configTable freeString:serverName];
                    424:        if (busTypeString)
                    425:            [configTable freeString:busTypeString];
                    426:        if (classesLoaded)
                    427:            return YES;
                    428:        else {
                    429:            [configTable free];
                    430:            [ioDeviceDescription free];
                    431:            [deviceDescription free];
                    432:            [device free];
                    433:            return NO;
                    434:        }
                    435: 
                    436: abort:
                    437:        if (serverName)
                    438:                [configTable freeString:serverName];
                    439:        if (busTypeString)
                    440:                [configTable freeString:busTypeString];
                    441:        if (configTable)
                    442:                [configTable free];
                    443: 
                    444:        if (ioDeviceDescription) {
                    445:                [ioDeviceDescription free];
                    446:        }
                    447:        if (deviceDescription) {
                    448:                [deviceDescription free];
                    449:        }
                    450:        if (device) {
                    451:                [device free];
                    452:        }
                    453: 
                    454:        return NO;
                    455: }
                    456: 
                    457: 
                    458: static boolean_t       isEISA=FALSE;
                    459: 
                    460: boolean_t
                    461: eisa_present(
                    462:     void
                    463: )
                    464: {
                    465:     static boolean_t   checked;
                    466: 
                    467:     if (!checked) {
                    468:        if (strncmp((char *)0xfffd9, "EISA", 4) == 0)
                    469:            isEISA = TRUE;
                    470:            
                    471:        checked = TRUE;
                    472:     }
                    473:     
                    474:     return (isEISA);
                    475: }
                    476: 
                    477: boolean_t
                    478: eisa_id(
                    479:     int                        slot,
                    480:     unsigned int       *_id
                    481: )
                    482: {
                    483:     unsigned char      *ids = (unsigned char *)_id;
                    484:     IOEISAPortAddress          port;
                    485:     
                    486:     if (!eisa_present())
                    487:        return (FALSE);
                    488:     
                    489:     port = (slot << 12) | 0x0C80;
                    490:     
                    491:     ids[3] = inb(port);
                    492:     ids[2] = inb(++port);
                    493:     ids[1] = inb(++port);
                    494:     ids[0] = inb(++port);
                    495:     
                    496:     if (*_id == 0xffffffff)
                    497:        return (FALSE);
                    498:        
                    499:     return (TRUE);
                    500: }
                    501: 
                    502: 
                    503: /*
                    504:  * probe all indirect drivers associated with specified driver.
                    505:  * As of mk-149.10, this is only used for IdeDisk.
                    506:  */
                    507: static void
                    508: probe_indirect(const char **indirectNamep, id driverInstance)
                    509: {
                    510:        id driverClass;
                    511:        
                    512:        if(indirectNamep == NULL) {
                    513:                return;
                    514:        }
                    515:        for(;  *indirectNamep; indirectNamep++) {
                    516:                driverClass = objc_getClass(*indirectNamep);
                    517:                if(driverClass == nil) {
                    518:                        printf("probe_indirect: Class %s does not exist\n",
                    519:                                *indirectNamep);
                    520:                        continue;
                    521:                }
                    522:                if(![driverClass respondsTo:@selector(probe:)]) {
                    523:                        printf("probe_indirect: Class %s does not respond to"
                    524:                                " probe:\n", *indirectNamep);
                    525:                        continue;
                    526:                }
                    527: 
                    528:                [driverClass probe:driverInstance]; 
                    529:        }
                    530: }
                    531: 
                    532: /*
                    533:  *  Configure a driver based on some config information.  This is really just
                    534:  *  a wrapper around configureDriver that runs in its own thread, and needs to
                    535:  *  be called in the IOTask context.
                    536:  */
                    537: void
                    538: configureThread(struct probeDriverArgs *args)
                    539: {
                    540:        args->rtn = configureDriver(args->configData);
                    541:        
                    542:        /*
                    543:         * Notify parent that we're finished, then terminate.
                    544:         */
                    545:        [args->waitLock lock];
                    546:        [args->waitLock unlockWith:YES];
                    547:        IOExitThread();
                    548: }
                    549: 
                    550: /*
                    551:  * Perform machine dependent hardware probe/config.
                    552:  */
                    553: void probeHardware(void)
                    554: {
                    555: }
                    556: 
                    557: /*
                    558:  * Start up all non-native direct drivers. Called after probeHardware(). 
                    559:  */
                    560: void probeDirectDevices(void)
                    561: {
                    562:        /* nope */
                    563: }
                    564: 
                    565: /*
                    566:  * Obtain n'th string in KERNBOOSTRUCT.config[]. Returns pointer to desired
                    567:  * string if found, else returns NULL.
                    568:  * KERNBOOTSTRUCT.config is a set of contiguous strings, NULL separated. 
                    569:  * The end of the list is delineated by a double NULL.
                    570:  */
                    571: const char *findBootConfigString(int n)
                    572: {
                    573:        KERNBOOTSTRUCT *kernBootStruct = KERNSTRUCT_ADDR;
                    574:        int stringsFound;
                    575:        const char *cp = kernBootStruct->config;
                    576:        int currentIndex = 0;
                    577:        int length;
                    578:        
                    579:        if(*cp == '\0') {
                    580:                IOLog("WARNING: No config table in KERNBOOTSTRUCT!\n");
                    581:                return NULL;
                    582:        }
                    583:        for(stringsFound=0; stringsFound<n; stringsFound++) {
                    584:                length = strlen(cp);
                    585:                currentIndex += (length + 1);
                    586:                cp += (length + 1);
                    587:                if( (length == 0) || 
                    588:                    (currentIndex > CONFIG_SIZE) ||
                    589:                    (*cp == '\0')) {
                    590:                        /*
                    591:                         * Explicit end of list or beyond boundary.
                    592:                         */
                    593:                        return NULL;
                    594:                }
                    595:        }
                    596:        return cp;
                    597: }
                    598: 
                    599: 
                    600: static void
                    601: bootDriverInit(void)
                    602: {
                    603:     KERNBOOTSTRUCT *bootstruct = KERNSTRUCT_ADDR;
                    604:     int i;
                    605:     struct section *sp;
                    606:     struct mach_header *hdr;
                    607:     
                    608:     for (i = 0; i < bootstruct->numBootDrivers; i++) {
                    609:        hdr = (struct mach_header *)bootstruct->driverConfig[i].address;
                    610:        /* Zero out bss */
                    611:        sp = getsectbynamefromheader(hdr,"__DATA","__bss");
                    612:        if (sp)
                    613:            bzero(sp->addr, sp->size);
                    614:        (void)objc_registerModule(hdr, 0);
                    615:     }
                    616: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.