X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/060df5ea7c632b1ac8cc8aac1fb59758165c2084..5c9f46613a83ebfc29a5b1f099448259e96a98f0:/iokit/Kernel/IOInterruptController.cpp diff --git a/iokit/Kernel/IOInterruptController.cpp b/iokit/Kernel/IOInterruptController.cpp index a8e04bddd..81f07dcab 100644 --- a/iokit/Kernel/IOInterruptController.cpp +++ b/iokit/Kernel/IOInterruptController.cpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 1998-2011 Apple Inc. All rights reserved. + * Copyright (c) 2007-2012 Apple Inc. All rights reserved. + * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -26,11 +27,6 @@ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ - -#if __ppc__ -#include -#endif - #include #include #include @@ -295,17 +291,13 @@ IOReturn IOInterruptController::enableInterrupt(IOService *nub, int source) if (vector->interruptDisabledSoft) { vector->interruptDisabledSoft = 0; -#if __ppc__ - sync(); - isync(); +#if !defined(__i386__) && !defined(__x86_64__) + OSMemoryBarrier(); #endif - + if (!getPlatform()->atInterruptLevel()) { while (vector->interruptActive) {} -#if __ppc__ - isync(); -#endif } if (vector->interruptDisabledHard) { vector->interruptDisabledHard = 0; @@ -330,17 +322,13 @@ IOReturn IOInterruptController::disableInterrupt(IOService *nub, int source) vector = &vectors[vectorNumber]; vector->interruptDisabledSoft = 1; -#if __ppc__ - sync(); - isync(); +#if !defined(__i386__) && !defined(__x86_64__) + OSMemoryBarrier(); #endif if (!getPlatform()->atInterruptLevel()) { while (vector->interruptActive) {} -#if __ppc__ - isync(); -#endif } return kIOReturnSuccess; @@ -409,6 +397,54 @@ void IOInterruptController::causeVector(IOInterruptVectorNumber /*vectorNumber*/ { } +void IOInterruptController::timeStampSpuriousInterrupt(void) +{ + uint64_t providerID = 0; + IOService * provider = getProvider(); + + if (provider) { + providerID = provider->getRegistryEntryID(); + } + + IOTimeStampConstant(IODBG_INTC(IOINTC_SPURIOUS), providerID); +} + +void IOInterruptController::timeStampInterruptHandlerInternal(bool isStart, IOInterruptVectorNumber vectorNumber, IOInterruptVector *vector) +{ + uint64_t providerID = 0; + vm_offset_t unslidHandler = 0; + vm_offset_t unslidTarget = 0; + + IOService * provider = getProvider(); + + if (provider) { + providerID = provider->getRegistryEntryID(); + } + + if (vector) { + unslidHandler = VM_KERNEL_UNSLIDE((vm_offset_t)vector->handler); + unslidTarget = VM_KERNEL_UNSLIDE_OR_PERM((vm_offset_t)vector->target); + } + + + if (isStart) { + IOTimeStampStartConstant(IODBG_INTC(IOINTC_HANDLER), (uintptr_t)vectorNumber, (uintptr_t)unslidHandler, + (uintptr_t)unslidTarget, (uintptr_t)providerID); + } else { + IOTimeStampEndConstant(IODBG_INTC(IOINTC_HANDLER), (uintptr_t)vectorNumber, (uintptr_t)unslidHandler, + (uintptr_t)unslidTarget, (uintptr_t)providerID); + } +} + +void IOInterruptController::timeStampInterruptHandlerStart(IOInterruptVectorNumber vectorNumber, IOInterruptVector *vector) +{ + timeStampInterruptHandlerInternal(true, vectorNumber, vector); +} + +void IOInterruptController::timeStampInterruptHandlerEnd(IOInterruptVectorNumber vectorNumber, IOInterruptVector *vector) +{ + timeStampInterruptHandlerInternal(false, vectorNumber, vector); +} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -430,6 +466,8 @@ IOReturn IOSharedInterruptController::initInterruptController(IOInterruptControl { int cnt, interruptType; IOReturn error; + + reserved = NULL; if (!super::init()) return kIOReturnNoResources; @@ -529,6 +567,7 @@ IOReturn IOSharedInterruptController::registerInterrupt(IOService *nub, // Create the vectorData for the IOInterruptSource. vectorData = OSData::withBytes(&vectorNumber, sizeof(vectorNumber)); if (vectorData == 0) { + IOLockUnlock(vector->interruptLock); return kIOReturnNoMemory; } @@ -663,10 +702,10 @@ IOReturn IOSharedInterruptController::disableInterrupt(IOService *nub, interruptState = IOSimpleLockLockDisableInterrupt(controllerLock); if (!vector->interruptDisabledSoft) { vector->interruptDisabledSoft = 1; -#if __ppc__ - sync(); - isync(); +#if !defined(__i386__) && !defined(__x86_64__) + OSMemoryBarrier(); #endif + vectorsEnabled--; } IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState); @@ -674,9 +713,6 @@ IOReturn IOSharedInterruptController::disableInterrupt(IOService *nub, if (!getPlatform()->atInterruptLevel()) { while (vector->interruptActive) {} -#if __ppc__ - isync(); -#endif } return kIOReturnSuccess; @@ -699,47 +735,26 @@ IOReturn IOSharedInterruptController::handleInterrupt(void * /*refCon*/, vector = &vectors[vectorNumber]; vector->interruptActive = 1; -#if __ppc__ - sync(); - isync(); +#if !defined(__i386__) && !defined(__x86_64__) + OSMemoryBarrier(); #endif + if (!vector->interruptDisabledSoft) { -#if __ppc__ - isync(); -#endif - + // Call the handler if it exists. if (vector->interruptRegistered) { - - bool trace = (gIOKitTrace & kIOTraceInterrupts) ? true : false; - bool timeHandler = gIOInterruptThresholdNS ? true : false; - uint64_t startTime = 0; - uint64_t endTime = 0; - - if (trace) - IOTimeStampStartConstant(IODBG_INTC(IOINTC_HANDLER), - (uintptr_t) vectorNumber, (uintptr_t) vector->handler, (uintptr_t)vector->target); - - if (timeHandler) - startTime = mach_absolute_time(); - - // Call handler. - vector->handler(vector->target, vector->refCon, vector->nub, vector->source); - - if (timeHandler) - { - endTime = mach_absolute_time(); - if ((endTime - startTime) > gIOInterruptThresholdNS) - panic("IOSIC::handleInterrupt: interrupt exceeded threshold, handlerTime = %qd, vectorNumber = %d, handler = %p, target = %p\n", - endTime - startTime, (int)vectorNumber, vector->handler, vector->target); - } - - if (trace) - IOTimeStampEndConstant(IODBG_INTC(IOINTC_HANDLER), - (uintptr_t) vectorNumber, (uintptr_t) vector->handler, (uintptr_t)vector->target); - + + bool trace = (gIOKitTrace & kIOTraceInterrupts) ? true : false; + + if (trace) + timeStampInterruptHandlerStart(vectorNumber, vector); + + // Call handler. + vector->handler(vector->target, vector->refCon, vector->nub, vector->source); + + if (trace) + timeStampInterruptHandlerEnd(vectorNumber, vector); } - } vector->interruptActive = 0;