Annotation of XNU/iokit/Drivers/platform/drvAppleIntelClassicPIC/PIC8259.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: Michael Burg
        !            26:  */
        !            27: 
        !            28: 
        !            29: #include <IOKit/IOLib.h>
        !            30: #include <IOKit/IOService.h>
        !            31: #include <IOKit/IODeviceMemory.h>
        !            32: #include <IOKit/IOPlatformExpert.h>
        !            33: 
        !            34: #include "AppleIntelClassicPIC.h"
        !            35: 
        !            36: #define outb(port, datum) \
        !            37:       __asm__ volatile("outb %b0, %1" : : "a" ((unsigned char)(datum)), "i" ((unsigned short)port))
        !            38: 
        !            39: #define send_duel_eoi(port1, port2)  \
        !            40:        __asm__ volatile("outb %b0, %1 ;  outb %b0, %2" : : "a" (kEOICommand), "i" ((unsigned short)port1), "i" ((unsigned short)port2))
        !            41: 
        !            42: 
        !            43: #define kIntelReservedIntVectors       0x40
        !            44: 
        !            45: extern "C" {
        !            46: /* HACK, HACK, HACK.. for rtclock on intel.. FIXME */
        !            47: extern void (*IOKitRegisterInterruptHook)(void *, int, int);
        !            48: };
        !            49: 
        !            50: static AppleIntelClassicPIC    *picObjectHook;
        !            51: 
        !            52: IOInterruptController          *gIntelInterruptController;
        !            53: 
        !            54: extern OSSymbol        *gIntelPICName;
        !            55: 
        !            56: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            57: 
        !            58: #undef  super
        !            59: #define super IOInterruptController
        !            60: 
        !            61: OSDefineMetaClassAndStructors(AppleIntelClassicPIC, IOInterruptController);
        !            62: 
        !            63: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            64: 
        !            65: bool AppleIntelClassicPIC::start(IOService *provider)
        !            66: {
        !            67:   IOInterruptAction    handler;
        !            68:   int cnt;
        !            69: 
        !            70:   if (!super::start(provider))
        !            71:     return false;
        !            72:   
        !            73:   
        !            74:   // Allocate the memory for the vectors.
        !            75:   vectors = (IOInterruptVector *)IOMalloc(kNumVectors *
        !            76:                                          sizeof(IOInterruptVector));
        !            77:   if (vectors == NULL) return false;
        !            78: 
        !            79:   bzero(vectors, kNumVectors * sizeof(IOInterruptVector));
        !            80:   
        !            81: 
        !            82:   // Allocate locks for the vectors.
        !            83:   for (cnt = 0; cnt < kNumVectors; cnt++) {
        !            84:     vectors[cnt].interruptLock = IOLockAlloc();
        !            85:     if (vectors[cnt].interruptLock == NULL) {
        !            86:       for (cnt = 0; cnt < kNumVectors; cnt++) {
        !            87:        if (vectors[cnt].interruptLock != NULL)
        !            88:          IOLockFree(vectors[cnt].interruptLock);
        !            89:       }
        !            90:       return false;
        !            91:     }
        !            92:   }
        !            93:   
        !            94:   maskInterrupts = 0xffff & ~(1<<kPICSlaveID); /* Mask out the interrupts except for the casacde line */
        !            95: 
        !            96:   /* Setup the interrupt controller.. */
        !            97:   /* Original code taken from FreeBSD's sys/i386/isa/intr_machdep.c */
        !            98: 
        !            99:   /* initialize 8259's */
        !           100:   outb(kPIC1BasePort, 0x11);           /* reset; program device, four bytes */
        !           101: 
        !           102:   /* starting at this vector index */
        !           103:   outb(kPIC1BasePort+kPICDataPortOffset, kIntelReservedIntVectors);
        !           104: 
        !           105:   outb(kPIC1BasePort+kPICDataPortOffset, kPICSlaveIRQID);      /* slave on line 7 */
        !           106: 
        !           107:   outb(kPIC1BasePort+kPICDataPortOffset, 1);           /* 8086 mode */
        !           108: 
        !           109:   outb(kPIC1BasePort+kPICDataPortOffset, 0xff);                /* leave interrupts masked */
        !           110:   outb(kPIC1BasePort, 0x0a);           /* default to IRR on read */
        !           111:   outb(kPIC1BasePort, 0xc0 | (3 - 1)); /* pri order 3-7, 0-2 (com2 first) */
        !           112: 
        !           113:   outb(kPIC2BasePort, 0x11);           /* reset; program device, four bytes */
        !           114:   outb(kPIC2BasePort+kPICDataPortOffset, kIntelReservedIntVectors+8); /* staring at this vector index */
        !           115:   outb(kPIC2BasePort+kPICDataPortOffset, kPICSlaveID);         /* my slave id is 7 */
        !           116:   outb(kPIC2BasePort+kPICDataPortOffset,1);            /* 8086 mode */
        !           117:   outb(kPIC2BasePort+kPICDataPortOffset, 0xff);        /* leave interrupts masked */
        !           118:   outb(kPIC2BasePort, 0x0a);                   /* default to IRR on read */
        !           119: 
        !           120:   // Primary interrupt controller
        !           121:   getPlatform()->setCPUInterruptProperties(provider);
        !           122:     
        !           123:   // setup clock interrupt back door hook
        !           124:   IOKitRegisterInterruptHook = getRegisterInterruptHookAddress();
        !           125:   picObjectHook = this;
        !           126: 
        !           127:   // register the interrupt handler so it can receive interrupts.
        !           128:   handler = getInterruptHandlerAddress();
        !           129:   if (provider->registerInterrupt(0, this, handler, 0) != kIOReturnSuccess) 
        !           130:        panic("AppleIntelClassicPIC: Failed to install platform interrupt handler");
        !           131:   provider->enableInterrupt(0);
        !           132:   
        !           133:   // Register this interrupt controller so clients can find it.
        !           134:   getPlatform()->registerInterruptController(gIntelPICName, this) ;
        !           135:   gIntelInterruptController = this;
        !           136: 
        !           137:   return true;
        !           138: }
        !           139: 
        !           140: IOReturn AppleIntelClassicPIC::getInterruptType(IOService */*nub*/,
        !           141:                                                        int /*source*/,
        !           142:                                                        int *interruptType)
        !           143: {
        !           144:   if (interruptType == 0) return kIOReturnBadArgument;
        !           145: 
        !           146:    *interruptType = kIOInterruptTypeEdge;
        !           147: 
        !           148:   return kIOReturnSuccess;
        !           149: }
        !           150: 
        !           151: IOInterruptAction AppleIntelClassicPIC::getInterruptHandlerAddress(void)
        !           152: {
        !           153:   void *value;
        !           154: 
        !           155:   value = (void *) &AppleIntelClassicPIC::handleInterrupt;
        !           156: 
        !           157:   return (IOInterruptAction)(value);
        !           158: }
        !           159: 
        !           160: IOReturn AppleIntelClassicPIC::handleInterrupt(void *savedState,
        !           161:                                                       IOService */*nub*/,
        !           162:                                                       int vectorNumber)
        !           163: {
        !           164:   IOInterruptVector *vector;
        !           165:   typedef void (*IntelClockFuncType)(void *);
        !           166:   IntelClockFuncType   clockFunc;
        !           167: 
        !           168:   vectorNumber -= kIntelReservedIntVectors;
        !           169: 
        !           170:   if (vectorNumber >= kNumVectors) return kIOReturnSuccess;
        !           171:     
        !           172:   maskInterrupts |= (1 << vectorNumber);
        !           173: 
        !           174:   if (vectorNumber > 7) {
        !           175:         /* Mask out interrupt */
        !           176:        outb(kPIC2BasePort+kPICDataPortOffset, maskInterrupts >> 8);
        !           177: 
        !           178:        /* Acknowledge interrupt */
        !           179:        send_duel_eoi(kPIC2BasePort+kPICCmdPortOffset, kPIC1BasePort+kPICCmdPortOffset);
        !           180:   } else {
        !           181:        outb(kPIC1BasePort+kPICDataPortOffset, maskInterrupts & 0xff);
        !           182:        outb(kPIC1BasePort+kPICCmdPortOffset, kEOICommand);
        !           183:   }
        !           184: 
        !           185:   vector = &vectors[vectorNumber];
        !           186: 
        !           187:   vector->interruptActive = 1;
        !           188:   if (!vector->interruptDisabledSoft) {
        !           189:       if (vector->interruptRegistered) {
        !           190:        if (vectorNumber == kClockIRQ) {
        !           191:                clockFunc = (IntelClockFuncType) vector->handler;
        !           192:                clockFunc(savedState);
        !           193:        } else {
        !           194:                vector->handler(vector->target, vector->refCon,
        !           195:                        vector->nub, vector->source);
        !           196:        }
        !           197:         maskInterrupts &= ~(1 << vectorNumber);
        !           198:      }
        !           199:   } else {
        !           200:       printf("*** DISABLING INT %d\n", vectorNumber);
        !           201:       // Hard disable the source.
        !           202:       vector->interruptDisabledHard = 1;
        !           203:       disableVectorHard(vectorNumber, vector);
        !           204:    }
        !           205: 
        !           206:   if (vectorNumber > 7) 
        !           207:        outb(kPIC2BasePort+kPICDataPortOffset, maskInterrupts >> 8);
        !           208:   else
        !           209:        outb(kPIC1BasePort+kPICDataPortOffset, maskInterrupts & 0xff );
        !           210: 
        !           211: 
        !           212:   vector->interruptActive = 0;
        !           213:     
        !           214:   return kIOReturnSuccess;
        !           215: }
        !           216: 
        !           217: bool AppleIntelClassicPIC::vectorCanBeShared(long /*vectorNumber*/, IOInterruptVector */*vector*/)
        !           218: {
        !           219:   /* FIXME! Need to account for PCI sharable interrupts */
        !           220:   return false;
        !           221: }
        !           222: 
        !           223: void AppleIntelClassicPIC::initVector(long /*vectorNumber*/,
        !           224:                                IOInterruptVector * /*vector*/)
        !           225: {
        !           226:        /* Do nothing.. */
        !           227: }
        !           228: 
        !           229: void AppleIntelClassicPIC::disableVectorHard(long vectorNumber, IOInterruptVector */*vector*/)
        !           230: {
        !           231:   if (vectorNumber == kPICSlaveID)     /* Sorry, cacade interrupt cannot be disable */
        !           232:        return; 
        !           233: 
        !           234:   maskInterrupts |= (1<<vectorNumber);
        !           235: 
        !           236:   /* Load up mask interrupts */
        !           237:   if (vectorNumber > 7)
        !           238:        outb(kPIC2BasePort + kPICDataPortOffset, maskInterrupts >> 8);
        !           239:   else
        !           240:        outb(kPIC1BasePort + kPICDataPortOffset, maskInterrupts & 0xff);
        !           241: }
        !           242: 
        !           243: void AppleIntelClassicPIC::enableVector(long vectorNumber,
        !           244:                                                IOInterruptVector *vector)
        !           245: {
        !           246:   maskInterrupts &= ~(1<<vectorNumber);
        !           247: 
        !           248:   /* Load up mask interrupts */
        !           249:   if (vectorNumber > 7)
        !           250:        outb(kPIC2BasePort + kPICDataPortOffset, maskInterrupts >> 8);
        !           251:   else
        !           252:        outb(kPIC1BasePort + kPICDataPortOffset, maskInterrupts & 0xff);
        !           253: }
        !           254: 
        !           255: static void AppleIntelClassicPICRegisterHook(void *func, int source, int isclock)
        !           256: {
        !           257:   picObjectHook->registerInterruptHook(func, source, isclock);
        !           258: }
        !           259: 
        !           260: void AppleIntelClassicPIC::registerInterruptHook(void *func, int source, int isclock)
        !           261: {
        !           262:        IOInterruptVector       *vector;
        !           263: 
        !           264:        vector = &vectors[source];
        !           265: 
        !           266:        vector->handler = (IOInterruptHandler) func;
        !           267:        vector->interruptRegistered = TRUE;
        !           268:        vector->interruptDisabledSoft = FALSE;
        !           269:        vector->interruptDisabledHard = FALSE;
        !           270: 
        !           271:        enableVector(source, vector);
        !           272: }
        !           273: 
        !           274: 
        !           275: IOKitInterruptHookType
        !           276: AppleIntelClassicPIC::getRegisterInterruptHookAddress(void)
        !           277: {
        !           278:        void *value;
        !           279:        value = (void *) AppleIntelClassicPICRegisterHook;
        !           280:        return (IOKitInterruptHookType) value;
        !           281: }

unix.superglobalmegacorp.com

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