Annotation of XNU/iokit/Drivers/platform/drvAppleVIA/AppleVIA.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) 1999 Apple Computer, Inc.  All rights reserved.
        !            24:  *
        !            25:  *  DRI: Josh de Cesare
        !            26:  */
        !            27: 
        !            28: 
        !            29: #include <ppc/proc_reg.h>
        !            30: 
        !            31: #include <IOKit/IOLib.h>
        !            32: #include <IOKit/IOService.h>
        !            33: #include <IOKit/IODeviceTreeSupport.h>
        !            34: #include <IOKit/IODeviceMemory.h>
        !            35: #include <IOKit/IOPlatformExpert.h>
        !            36: 
        !            37: #include "AppleVIA.h"
        !            38: 
        !            39: 
        !            40: extern "C" {
        !            41: extern void PE_Determine_Clock_Speeds(unsigned int via_addr,
        !            42:                                      int num_speeds,
        !            43:                                      unsigned long *speed_list);
        !            44: }
        !            45: 
        !            46: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            47: 
        !            48: #define super IOService
        !            49: 
        !            50: OSDefineMetaClassAndStructors(AppleVIA, IOService);
        !            51: 
        !            52: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            53: 
        !            54: bool AppleVIA::start(IOService *provider)
        !            55: {
        !            56:   AppleVIADevice     *nub;
        !            57:   IOInterruptAction  handler;
        !            58:   IOReturn           error;
        !            59:   IOMemoryMap        *viaMemoryMap;
        !            60:   OSSymbol           *interruptControllerName;
        !            61:   int                numSpeeds;
        !            62:   unsigned long      *speedList;
        !            63:   
        !            64:   // Call super's start.
        !            65:   if (!super::start(provider))
        !            66:     return false;
        !            67:   
        !            68:   // Figure out what kind of via device nub to make.
        !            69:   if (IODTMatchNubWithKeys(provider, "'via-cuda'"))
        !            70:     viaDeviceType = kVIADeviceTypeCuda;
        !            71:   else if (IODTMatchNubWithKeys(provider, "'via-pmu'"))
        !            72:     viaDeviceType = kVIADeviceTypePMU;
        !            73:   else viaDeviceType = -1;  // This should not happen.
        !            74:   
        !            75:   // get the via's base address
        !            76:   viaMemoryMap = provider->mapDeviceMemoryWithIndex(0);
        !            77:   if (viaMemoryMap == 0) return false;
        !            78:   viaBaseAddress = viaMemoryMap->getVirtualAddress();
        !            79:   viaMemoryMap->release();
        !            80:   
        !            81:   // Calculate the bus and cpu speeds.
        !            82:   getPlatform()->getDefaultBusSpeeds(&numSpeeds, &speedList);
        !            83:   PE_Determine_Clock_Speeds(viaBaseAddress, numSpeeds, speedList);
        !            84:   
        !            85:   // Allocate the interruptController instance.
        !            86:   interruptController = new AppleVIAInterruptController;
        !            87:   if (interruptController == NULL) return false;
        !            88:   
        !            89:   // call the interruptController's init method.
        !            90:   error = interruptController->initInterruptController(provider,
        !            91:                                                       viaBaseAddress);
        !            92:   if (error != kIOReturnSuccess) return false;
        !            93:   
        !            94:   handler = interruptController->getInterruptHandlerAddress();
        !            95:   provider->registerInterrupt(0, interruptController, handler, 0);
        !            96:   
        !            97:   provider->enableInterrupt(0);
        !            98:   
        !            99:   // Register the interrupt controller so clients can find it.
        !           100:   interruptControllerName = OSSymbol::withCStringNoCopy(kInterruptControllerName);
        !           101:   getPlatform()->registerInterruptController(interruptControllerName,
        !           102:                                             interruptController);
        !           103:   
        !           104:   nub = createNub();
        !           105:   if (nub == 0) return false;
        !           106:   
        !           107:   nub->attach(this);
        !           108:   nub->registerService();
        !           109:   
        !           110:   return true;
        !           111: }
        !           112: 
        !           113: AppleVIADevice *AppleVIA::createNub(void)
        !           114: {
        !           115:   int               cnt;
        !           116:   bool              err;
        !           117:   OSSymbol          *cName;
        !           118:   OSSymbol          *name = 0;
        !           119:   OSArray           *array = 0, *vecArray = 0, *deviceMemoryArray;
        !           120:   OSDictionary      *dict = 0;
        !           121:   AppleVIADevice    *nub = 0;
        !           122:   
        !           123:   do {
        !           124:     // create the name symbol for the interrupt controller.
        !           125:     cName = OSSymbol::withCStringNoCopy(kInterruptControllerName);
        !           126:     if (cName == 0) continue;
        !           127:     
        !           128:     // create the vector array.
        !           129:     vecArray = OSDynamicCast(OSArray, getProperty("vectors"));
        !           130:     if ((vecArray == 0) || (vecArray->getCount() != kNumVectors)) continue;
        !           131:     
        !           132:     // create the controller array.
        !           133:     array = OSArray::withCapacity(kNumVectors);
        !           134:     if (array == 0) continue;
        !           135:     
        !           136:     // populate the names array
        !           137:     err = false;
        !           138:     for (cnt = 0; cnt < kNumVectors; cnt++) {
        !           139:       if (!array->setObject(cName)) {
        !           140:         err = true;
        !           141:         break;
        !           142:       }
        !           143:     }
        !           144:     if (err) continue;
        !           145:     
        !           146:     // create the deviceMemory array.
        !           147:     deviceMemoryArray = getProvider()->getDeviceMemory();
        !           148:     if (deviceMemoryArray == 0) continue;
        !           149:     
        !           150:     // create the name for the viaDevice nub
        !           151:     if (viaDeviceType == kVIADeviceTypeCuda)
        !           152:       name = OSSymbol::withCStringNoCopy("cuda");
        !           153:     else if (viaDeviceType == kVIADeviceTypePMU)
        !           154:       name = OSSymbol::withCStringNoCopy("pmu");
        !           155:     else name = 0;
        !           156:     if (name == 0) continue;
        !           157:     
        !           158:     // Create the dictionary for the viaDevice nub.
        !           159:     dict = OSDictionary::withCapacity(1);
        !           160:     if (dict == 0) continue;
        !           161:     
        !           162:     // add the interrupt numbers and parents to the dictionary.
        !           163:     err = !dict->setObject("name", name);
        !           164:     err |= !dict->setObject(gIOInterruptSpecifiersKey, vecArray);
        !           165:     err |= !dict->setObject(gIOInterruptControllersKey, array);
        !           166:     if (err) continue;
        !           167:     
        !           168:     // Create the viaDevice nub
        !           169:     nub = new AppleVIADevice;
        !           170:     if (nub == 0) continue;
        !           171:     
        !           172:     if (!nub->init(dict)) {
        !           173:       nub->release();
        !           174:       nub = 0;
        !           175:       continue;
        !           176:     }
        !           177:     
        !           178:     // set the nub's name.
        !           179:     nub->setName(name);
        !           180:     
        !           181:     // set the nub's deviceMemory.
        !           182:     nub->setDeviceMemory(deviceMemoryArray);
        !           183:     
        !           184:   } while(false);
        !           185:   
        !           186:   if(name) name->release();
        !           187:   if(cName) cName->release();
        !           188:   if(array) array->release();
        !           189:   if(dict) dict->release();
        !           190:   
        !           191:   return nub;
        !           192: }
        !           193: 
        !           194: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           195: 
        !           196: #undef  super
        !           197: #define super IOService
        !           198: 
        !           199: OSDefineMetaClassAndStructors(AppleVIADevice, IOService);
        !           200: 
        !           201: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           202: 
        !           203: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           204: 
        !           205: #undef  super
        !           206: #define super IOInterruptController
        !           207: 
        !           208: OSDefineMetaClassAndStructors(AppleVIAInterruptController, IOInterruptController);
        !           209: 
        !           210: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           211: 
        !           212: IOReturn AppleVIAInterruptController::initInterruptController(IOService *provider, IOLogicalAddress interruptControllerBase)
        !           213: {
        !           214:   int cnt;
        !           215:   
        !           216:   parentNub = provider;
        !           217:   
        !           218:   // Allocate the memory for the vectors
        !           219:   vectors = (IOInterruptVector *)IOMalloc(kNumVectors *
        !           220:                                          sizeof(IOInterruptVector));
        !           221:   if (vectors == NULL) return kIOReturnNoMemory;
        !           222:   bzero(vectors, kNumVectors * sizeof(IOInterruptVector));
        !           223:   
        !           224:   // Allocate locks for the
        !           225:   for (cnt = 0; cnt < kNumVectors; cnt++) {
        !           226:     vectors[cnt].interruptLock = IOLockAlloc();
        !           227:     if (vectors[cnt].interruptLock == NULL) {
        !           228:       for (cnt = 0; cnt < kNumVectors; cnt++) {
        !           229:        if (vectors[cnt].interruptLock != NULL)
        !           230:          IOLockFree(vectors[cnt].interruptLock);
        !           231:       }
        !           232:       return kIOReturnNoResources;
        !           233:     }
        !           234:   }
        !           235:   
        !           236:   // Initialize the registers.
        !           237:   IEReg = (volatile unsigned char *)(interruptControllerBase + kIEOffset);
        !           238:   IFReg = (volatile unsigned char *)(interruptControllerBase + kIFOffset);
        !           239:   PCReg = (volatile unsigned char *)(interruptControllerBase + kPCOffset);
        !           240:   
        !           241:   // Disable all interrupts.
        !           242:   *PCReg = 0x00; eieio();
        !           243:   *IEReg = 0x00; eieio();
        !           244:   *IFReg = 0x7F; eieio();
        !           245:   
        !           246:   return kIOReturnSuccess;
        !           247: }
        !           248: 
        !           249: IOInterruptAction AppleVIAInterruptController::getInterruptHandlerAddress(void)
        !           250: {
        !           251:   return (IOInterruptAction)&AppleVIAInterruptController::handleInterrupt;
        !           252: }
        !           253: 
        !           254: IOReturn AppleVIAInterruptController::handleInterrupt(void */*refCon*/,
        !           255:                                                      IOService */*nub*/,
        !           256:                                                      int /*source*/)
        !           257: {
        !           258:   int               done;
        !           259:   long              events, vectorNumber;
        !           260:   IOInterruptVector *vector;
        !           261:   
        !           262:   do {
        !           263:     done = 1;
        !           264:     
        !           265:     // Do all the sources for events.
        !           266:     events = *IFReg; eieio();
        !           267:     events |= pendingEvents;
        !           268:     pendingEvents = 0;
        !           269:     events &= *IEReg & 0x7F; eieio();
        !           270:     
        !           271:     if (events) {
        !           272:       done = 0;
        !           273:       *IFReg = events; eieio();
        !           274:     }
        !           275:     
        !           276:     while (events) {
        !           277:       vectorNumber = 31 - cntlzw(events);
        !           278:       events ^= (1 << vectorNumber);
        !           279:       vector = &vectors[vectorNumber];
        !           280:       
        !           281:       vector->interruptActive = 1;
        !           282:       sync();
        !           283:       isync();
        !           284:       if (!vector->interruptDisabledSoft) {
        !           285:        isync();
        !           286:        
        !           287:        // Call the handler if it exists.
        !           288:        if (vector->interruptRegistered) {
        !           289:          vector->handler(vector->target, vector->refCon,
        !           290:                          vector->nub, vector->source);
        !           291:        }
        !           292:       } else {
        !           293:        // Hard disable the source.
        !           294:        vector->interruptDisabledHard = 1;
        !           295:        disableVectorHard(vectorNumber, vector);
        !           296:       }
        !           297:       
        !           298:       vector->interruptActive = 0;
        !           299:     }
        !           300:     
        !           301:   } while (!done);
        !           302:   
        !           303:   return kIOReturnSuccess;
        !           304: }
        !           305: 
        !           306: void AppleVIAInterruptController::disableVectorHard(long vectorNumber, IOInterruptVector */*vector*/)
        !           307: {
        !           308:   *IEReg &= ~(1 << vectorNumber);
        !           309:   eieio();
        !           310: }
        !           311: 
        !           312: void AppleVIAInterruptController::enableVector(long vectorNumber,
        !           313:                                               IOInterruptVector *vector)
        !           314: {
        !           315:   *IEReg |= (1 << vectorNumber);
        !           316:   eieio();
        !           317: }
        !           318: 
        !           319: void AppleVIAInterruptController::causeVector(long vectorNumber,
        !           320:                                              IOInterruptVector */*vector*/)
        !           321: {
        !           322:   pendingEvents |= 1 << vectorNumber;
        !           323:   parentNub->causeInterrupt(0);
        !           324: }

unix.superglobalmegacorp.com

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