Annotation of XNU/iokit/Drivers/pci/drvApplePCI/AppleI386PCI.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-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:  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved. 
        !            24:  *
        !            25:  * HISTORY
        !            26:  * 23 Nov 98 sdouglas created from objc version.
        !            27:  */
        !            28:  
        !            29: #include <IOKit/system.h>
        !            30: 
        !            31: #include <libkern/c++/OSContainers.h>
        !            32: #include <IOKit/IODeviceMemory.h>
        !            33: #include <IOKit/IODeviceTreeSupport.h>
        !            34: #include <IOKit/IOLib.h>
        !            35: 
        !            36: #include <architecture/i386/kernBootStruct.h>
        !            37: #include <architecture/i386/pio.h>
        !            38: 
        !            39: #include "AppleI386PCI.h"
        !            40: 
        !            41: #include <assert.h>
        !            42: 
        !            43: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            44: 
        !            45: #define super IOPCIBridge
        !            46: 
        !            47: OSDefineMetaClassAndStructors(AppleI386PCI, IOPCIBridge)
        !            48: 
        !            49: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            50: 
        !            51: bool AppleI386PCI::start( IOService * provider )
        !            52: {
        !            53:     OSData *           prop;
        !            54:     PCI_bus_info_t *   info;
        !            55: 
        !            56:     prop = (OSData *) provider->getProperty("pci-bus-info");
        !            57:     if( 0 == prop)
        !            58:        return( false);
        !            59: 
        !            60:     info = (PCI_bus_info_t *) prop->getBytesNoCopy();
        !            61: 
        !            62:     maxBusNum = info->maxBusNum;
        !            63:     maxDevNum = 0;
        !            64:     majorVersion = info->majorVersion;
        !            65:     minorVersion = info->minorVersion;
        !            66:     BIOS16Present = info->BIOSPresent;
        !            67:     BIOS32Present = false;
        !            68:     BIOS32Entry   = 0x00000000;
        !            69:     configMethod1 = info->u_bus.s.configMethod1;
        !            70:     configMethod2 = info->u_bus.s.configMethod2;
        !            71:     specialCycle1 = info->u_bus.s.specialCycle1;
        !            72:     specialCycle2 = info->u_bus.s.specialCycle2;
        !            73: 
        !            74:         /*
        !            75:          if ((BIOS16Present) & !(configMethod1 | configMethod2)) {
        !            76:              // This is a PCI system, but neither method is supported
        !            77:              // Lets try them both just in case (ala NEC ExpressII P60)
        !            78:              if (!(configMethod1 = [self test_M1]))
        !            79:                  configMethod2 = [self test_M2];
        !            80:          }
        !            81:          */
        !            82: 
        !            83: #define IFYES(b, s) ((b) ? s : "")
        !            84:     IOLog("PCI Ver=%x.%02x BusCount=%d Features=[ %s%s%s%s%s%s]\n",
        !            85:        majorVersion, minorVersion, maxBusNum+1,
        !            86:        IFYES(BIOS16Present, "BIOS16 "), IFYES(BIOS32Present, "BIOS32 "),
        !            87:        IFYES(configMethod1, "CM1 "), IFYES(configMethod2, "CM2 "),
        !            88:        IFYES(specialCycle1, "SC1 "), IFYES(specialCycle2, "SC2 ") );
        !            89: 
        !            90:     if (configMethod1)
        !            91:         maxDevNum = 31;
        !            92:     else if (configMethod2)
        !            93:         maxDevNum = 15;
        !            94:     else
        !            95:        return( false );
        !            96: 
        !            97:     ioMemory = IODeviceMemory::withRange( 0, 65536 );
        !            98:     if( !ioMemory)
        !            99:        return( false);
        !           100:     ioMemory->setMapping( kernel_task, 0 );    /* mapped to zero in IO space */
        !           101: 
        !           102:     return( super::start( provider));
        !           103: }
        !           104: 
        !           105: bool AppleI386PCI::configure( IOService * provider )
        !           106: {
        !           107:     bool ok;
        !           108: 
        !           109:     ok = addBridgeMemoryRange( 0x80000000, 0x7f000000, true );
        !           110:     ok = addBridgeIORange( 0, 0x10000 );
        !           111: 
        !           112:     return( super::configure( provider ));
        !           113: }
        !           114: 
        !           115: void AppleI386PCI::free()
        !           116: {
        !           117:     if( ioMemory)
        !           118:        ioMemory->release();
        !           119: 
        !           120:     super::free();
        !           121: }
        !           122: 
        !           123: IODeviceMemory * AppleI386PCI::ioDeviceMemory( void )
        !           124: {
        !           125:     return( ioMemory);
        !           126: }
        !           127: 
        !           128: 
        !           129: UInt8 AppleI386PCI::firstBusNum( void )
        !           130: {
        !           131:     return( 0 );
        !           132: }
        !           133: 
        !           134: UInt8 AppleI386PCI::lastBusNum( void )
        !           135: {
        !           136:     return( firstBusNum() );
        !           137: }
        !           138: 
        !           139: IOPCIAddressSpace AppleI386PCI::getBridgeSpace( void )
        !           140: {
        !           141:     IOPCIAddressSpace  space;
        !           142: 
        !           143:     space.bits = 0;
        !           144: 
        !           145:     return( space );
        !           146: }
        !           147: 
        !           148: /* defines for Configuration Method #1 (PCI 2.0 Spec, sec 3.6.4.1.1) */
        !           149: #define PCI_CONFIG_ADDRESS      0x0cf8
        !           150: #define PCI_CONFIG_DATA         0x0cfc
        !           151: 
        !           152: /* defines for Configuration Method #2 (PCI 2.0 Spec, sec 3.6.4.1.3) */
        !           153: #define PCI_CSE_REGISTER        0x0cf8
        !           154: #define PCI_BUS_FORWARD         0x0cfa
        !           155: 
        !           156: #define        PCI_DEFAULT_DATA        0xffffffff
        !           157: 
        !           158: #if 0
        !           159: 
        !           160: - (BOOL) test_M1
        !           161: {
        !           162:     unsigned long address, data;
        !           163: 
        !           164:     for (address = 0x80000000; address < 0x80010000; address += 0x800) {
        !           165:         outl (PCI_CONFIG_ADDRESS, address);
        !           166:         if (inl (PCI_CONFIG_ADDRESS) != address) {
        !           167:             return NO;
        !           168:         }
        !           169:         data = inl(PCI_CONFIG_DATA);
        !           170:         if ((data != PCI_DEFAULT_DATA) && (data != 0x00)) {
        !           171:             outl (PCI_CONFIG_ADDRESS, 0);
        !           172:             return YES;
        !           173:         }
        !           174:     }
        !           175: 
        !           176:     outl (PCI_CONFIG_ADDRESS, 0);
        !           177:     return NO;
        !           178: }
        !           179: 
        !           180: - (BOOL) test_M2
        !           181: {
        !           182:     unsigned long address, data;
        !           183: 
        !           184:     /*  Enable configuration space at I/O ports Cxxx.  */
        !           185: 
        !           186:     outb (PCI_CSE_REGISTER, 0xF0);
        !           187:     if (inb (PCI_CSE_REGISTER) != 0xF0) {
        !           188:         return NO;
        !           189:     }
        !           190: 
        !           191:     outb (PCI_BUS_FORWARD, 0x00);
        !           192:     if (inb (PCI_BUS_FORWARD) != 0x00) {
        !           193:         return NO;
        !           194:     }
        !           195:     /*  Search all devices on the bus.  */
        !           196:     for (address = 0xc000; address <= 0xcfff; address += 0x100) {
        !           197:         data = inl(address);
        !           198:         if ((data != PCI_DEFAULT_DATA) && (data != 0x00)) {
        !           199:             outb (PCI_CSE_REGISTER, 0);
        !           200:             return YES;
        !           201:         }
        !           202:     }
        !           203: 
        !           204:     outb (PCI_CSE_REGISTER, 0);
        !           205:     return NO;
        !           206: }
        !           207: #endif
        !           208: 
        !           209: UInt32 AppleI386PCI::configRead32Method1( IOPCIAddressSpace space,
        !           210:                                             UInt8 offset )
        !           211: {
        !           212:     IOPCIAddressSpace  addrCycle;
        !           213:     UInt32             data = PCI_DEFAULT_DATA;
        !           214: 
        !           215:     addrCycle = space;
        !           216:     addrCycle.s.reloc = 1;
        !           217:     addrCycle.s.registerNum = offset;
        !           218: 
        !           219:     outl( PCI_CONFIG_ADDRESS, addrCycle.bits);
        !           220:     if (inl( PCI_CONFIG_ADDRESS) == addrCycle.bits)
        !           221:         data = inl( PCI_CONFIG_DATA);
        !           222: 
        !           223:     outl( PCI_CONFIG_ADDRESS, 0);
        !           224: 
        !           225:     return( data );
        !           226: }
        !           227: 
        !           228: 
        !           229: void AppleI386PCI::configWrite32Method1( IOPCIAddressSpace space, 
        !           230:                                        UInt8 offset, UInt32 data )
        !           231: {
        !           232:     IOPCIAddressSpace  addrCycle;
        !           233: 
        !           234:     addrCycle = space;
        !           235:     addrCycle.s.reloc = 1;
        !           236:     addrCycle.s.registerNum = offset;
        !           237: 
        !           238:     outl( PCI_CONFIG_ADDRESS, addrCycle.bits);
        !           239:     if (inl( PCI_CONFIG_ADDRESS) == addrCycle.bits)
        !           240:         outl(PCI_CONFIG_DATA, data);
        !           241: 
        !           242:     outl( PCI_CONFIG_ADDRESS, 0);
        !           243: }
        !           244: 
        !           245: UInt32 AppleI386PCI::configRead32Method2( IOPCIAddressSpace space,
        !           246:                                             UInt8 offset )
        !           247: {
        !           248:     UInt32     data = PCI_DEFAULT_DATA;
        !           249:     UInt8      cse;
        !           250: 
        !           251:     if( space.s.deviceNum > 15)
        !           252:        return( data);
        !           253: 
        !           254:     cse = 0xf0 | (space.s.functionNum << 1);
        !           255:     outb( PCI_CSE_REGISTER, cse);
        !           256:     if (inb( PCI_CSE_REGISTER) == cse) {
        !           257:         outb( PCI_BUS_FORWARD, space.s.busNum);
        !           258:             if (inb( PCI_BUS_FORWARD) == space.s.busNum) {
        !           259:                 data = inl(    0xc000
        !           260:                             | (offset & 0xfc)
        !           261:                             | (space.s.deviceNum << 8));
        !           262:         }
        !           263:         outb( PCI_BUS_FORWARD, 0x00);
        !           264:     }
        !           265:     outb( PCI_CSE_REGISTER, 0x00);
        !           266: 
        !           267:     return( data );
        !           268: }
        !           269: 
        !           270: 
        !           271: void AppleI386PCI::configWrite32Method2( IOPCIAddressSpace space, 
        !           272:                                        UInt8 offset, UInt32 data )
        !           273: {
        !           274:     UInt8      cse;
        !           275: 
        !           276:     if( space.s.deviceNum > 15)
        !           277:        return;
        !           278: 
        !           279:     cse = 0xf0 | (space.s.functionNum << 1);
        !           280:     outb( PCI_CSE_REGISTER, cse);
        !           281:     if (inb( PCI_CSE_REGISTER) == cse) {
        !           282:         outb( PCI_BUS_FORWARD, space.s.busNum);
        !           283:             if (inb( PCI_BUS_FORWARD) == space.s.busNum) {
        !           284:                 outl(  0xc000
        !           285:                     | (offset & 0xfc)
        !           286:                     | (space.s.deviceNum << 8), data);
        !           287:         }
        !           288:         outb( PCI_BUS_FORWARD, 0x00);
        !           289:     }
        !           290:     outb( PCI_CSE_REGISTER, 0x00);
        !           291: }
        !           292: 
        !           293: UInt32 AppleI386PCI::configRead32( IOPCIAddressSpace space,
        !           294:                                        UInt8 offset )
        !           295: {
        !           296:     /* should disable ints */
        !           297:     if( configMethod1)
        !           298:        return( configRead32Method1( space, offset ));
        !           299:     else
        !           300:        return( configRead32Method2( space, offset ));
        !           301:     /* enable ints */
        !           302: }
        !           303: 
        !           304: void AppleI386PCI::configWrite32( IOPCIAddressSpace space, 
        !           305:                                        UInt8 offset, UInt32 data )
        !           306: {
        !           307:     /* should disable ints */
        !           308:     if( configMethod1)
        !           309:        configWrite32Method1( space, offset, data );
        !           310:     else
        !           311:        configWrite32Method2( space, offset, data );
        !           312:     /* enable ints */
        !           313: }
        !           314: 

unix.superglobalmegacorp.com

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