Annotation of XNU/iokit/Drivers/platform/drvAppleIntelClassicPIC/PIC8259.cpp, revision 1.1.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.