]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOInterruptController.cpp
xnu-4570.31.3.tar.gz
[apple/xnu.git] / iokit / Kernel / IOInterruptController.cpp
index a8e04bddd28deb711e851fd8b40c818a20890c24..81f07dcabf6a7a7253743d739e5b576dcb774569 100644 (file)
@@ -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@
  * 
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
-
-#if __ppc__
-#include <ppc/proc_reg.h> 
-#endif
-
 #include <IOKit/IOLib.h>
 #include <IOKit/IOService.h>
 #include <IOKit/IOPlatformExpert.h>
 #include <IOKit/IOLib.h>
 #include <IOKit/IOService.h>
 #include <IOKit/IOPlatformExpert.h>
@@ -295,17 +291,13 @@ IOReturn IOInterruptController::enableInterrupt(IOService *nub, int source)
   
   if (vector->interruptDisabledSoft) {
     vector->interruptDisabledSoft = 0;
   
   if (vector->interruptDisabledSoft) {
     vector->interruptDisabledSoft = 0;
-#if __ppc__
-    sync();
-    isync();
+#if !defined(__i386__) && !defined(__x86_64__)
+    OSMemoryBarrier();
 #endif
 #endif
-    
+
     if (!getPlatform()->atInterruptLevel()) {
       while (vector->interruptActive)
        {}
     if (!getPlatform()->atInterruptLevel()) {
       while (vector->interruptActive)
        {}
-#if __ppc__
-      isync();
-#endif
     }
     if (vector->interruptDisabledHard) {
       vector->interruptDisabledHard = 0;
     }
     if (vector->interruptDisabledHard) {
       vector->interruptDisabledHard = 0;
@@ -330,17 +322,13 @@ IOReturn IOInterruptController::disableInterrupt(IOService *nub, int source)
   vector = &vectors[vectorNumber];
   
   vector->interruptDisabledSoft = 1;
   vector = &vectors[vectorNumber];
   
   vector->interruptDisabledSoft = 1;
-#if __ppc__
-  sync();
-  isync();
+#if !defined(__i386__) && !defined(__x86_64__)
+  OSMemoryBarrier();
 #endif
   
   if (!getPlatform()->atInterruptLevel()) {
     while (vector->interruptActive)
        {}
 #endif
   
   if (!getPlatform()->atInterruptLevel()) {
     while (vector->interruptActive)
        {}
-#if __ppc__
-    isync();
-#endif
   }
   
   return kIOReturnSuccess;
   }
   
   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;
 {
   int      cnt, interruptType;
   IOReturn error;
+
+  reserved = NULL;
   
   if (!super::init())
     return kIOReturnNoResources;
   
   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) {
   // Create the vectorData for the IOInterruptSource.
   vectorData = OSData::withBytes(&vectorNumber, sizeof(vectorNumber));
   if (vectorData == 0) {
+    IOLockUnlock(vector->interruptLock);
     return kIOReturnNoMemory;
   }
   
     return kIOReturnNoMemory;
   }
   
@@ -663,10 +702,10 @@ IOReturn IOSharedInterruptController::disableInterrupt(IOService *nub,
   interruptState = IOSimpleLockLockDisableInterrupt(controllerLock); 
   if (!vector->interruptDisabledSoft) {
     vector->interruptDisabledSoft = 1;
   interruptState = IOSimpleLockLockDisableInterrupt(controllerLock); 
   if (!vector->interruptDisabledSoft) {
     vector->interruptDisabledSoft = 1;
-#if __ppc__
-    sync();
-    isync();
+#if !defined(__i386__) && !defined(__x86_64__)
+    OSMemoryBarrier();
 #endif
 #endif
+
     vectorsEnabled--;
   }
   IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
     vectorsEnabled--;
   }
   IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
@@ -674,9 +713,6 @@ IOReturn IOSharedInterruptController::disableInterrupt(IOService *nub,
   if (!getPlatform()->atInterruptLevel()) {
     while (vector->interruptActive)
        {}
   if (!getPlatform()->atInterruptLevel()) {
     while (vector->interruptActive)
        {}
-#if __ppc__
-    isync();
-#endif
   }
   
   return kIOReturnSuccess;
   }
   
   return kIOReturnSuccess;
@@ -699,47 +735,26 @@ IOReturn IOSharedInterruptController::handleInterrupt(void * /*refCon*/,
     vector = &vectors[vectorNumber];
     
     vector->interruptActive = 1;
     vector = &vectors[vectorNumber];
     
     vector->interruptActive = 1;
-#if __ppc__
-    sync();
-    isync();
+#if !defined(__i386__) && !defined(__x86_64__)
+    OSMemoryBarrier();
 #endif
 #endif
+
     if (!vector->interruptDisabledSoft) {
     if (!vector->interruptDisabledSoft) {
-#if __ppc__
-      isync();
-#endif
-      
+
       // Call the handler if it exists.
       if (vector->interruptRegistered) {
       // 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;
     }
     
     vector->interruptActive = 0;