Ejemplo n.º 1
0
bool CmdInterrupt::shouldBreak(DebuggerProxy &proxy,
                               const std::vector<BreakPointInfoPtr> &bps,
                               int stackDepth) {

  switch (m_interrupt) {
    case SessionStarted:
    case SessionEnded:
    case HardBreakPoint:
      return true; // always break
    case RequestStarted:
    case RequestEnded:
    case PSPEnded:
    case BreakPointReached:
    case ExceptionThrown:
      m_matched.clear();
      if (m_site) {
        auto offset = m_site->getCurOffset();
        for (unsigned int i = 0; i < bps.size(); i++) {
          if (bps[i]->m_state != BreakPointInfo::Disabled &&
              bps[i]->breakable(stackDepth, offset) &&
              bps[i]->cmatch(proxy, getInterruptType(), *m_site)) {
            BreakPointInfoPtr bp(new BreakPointInfo());
            *bp = *bps[i]; // make a copy
            m_matched.push_back(bp);
          }
        }
      }
      return !m_matched.empty();
    case ExceptionHandler:
      return false; // For flow control only at this time.
  }
  assert(false);
  return false;
}
Ejemplo n.º 2
0
bool CmdInterrupt::shouldBreak(const BreakPointInfoPtrVec &bps) {

  switch (m_interrupt) {
    case SessionStarted:
    case SessionEnded:
    case HardBreakPoint:
      return true; // always break
    case RequestStarted:
    case RequestEnded:
    case PSPEnded:
    case BreakPointReached:
    case ExceptionThrown:
      m_matched.clear();
      if (m_site) {
        for (unsigned int i = 0; i < bps.size(); i++) {
          if (bps[i]->m_state != BreakPointInfo::Disabled &&
              bps[i]->match(getInterruptType(), *getSite())) {
            BreakPointInfoPtr bp(new BreakPointInfo());
            *bp = *bps[i]; // make a copy
            m_matched.push_back(bp);
          }
        }
      }
      return !m_matched.empty();
  }
  assert(false);
  return false;
}
Ejemplo n.º 3
0
IOReturn IOInterruptController::registerInterrupt(IOService *nub, int source,
						  void *target,
						  IOInterruptHandler handler,
						  void *refCon)
{
  IOInterruptSource *interruptSources;
  IOInterruptVectorNumber vectorNumber;
  IOInterruptVector *vector;
  int               wasDisabledSoft;
  IOReturn          error;
  OSData            *vectorData;
  IOOptionBits      options;
  bool              canBeShared, shouldBeShared, wasAlreadyRegisterd;

  IOService         *originalNub = NULL; // Protected by wasAlreadyRegisterd
  int               originalSource = 0; // Protected by wasAlreadyRegisterd
 

  interruptSources = nub->_interruptSources;
  vectorData = interruptSources[source].vectorData;
  vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy();
  vector = &vectors[vectorNumber];
  
  // Get the lock for this vector.
  IOLockLock(vector->interruptLock);
  
  // Check if the interrupt source can/should be shared.
  canBeShared = vectorCanBeShared(vectorNumber, vector);
  IODTGetInterruptOptions(nub, source, &options);
#if defined(__i386__) || defined(__x86_64__)
  int   interruptType;
  if (OSDynamicCast(IOPlatformDevice, getProvider()) &&
      (getInterruptType(nub, source, &interruptType) == kIOReturnSuccess) &&
      (kIOInterruptTypeLevel & interruptType))
  {
    options |= kIODTInterruptShared;
  }
#endif
  shouldBeShared = canBeShared && (options & kIODTInterruptShared);
  wasAlreadyRegisterd = vector->interruptRegistered;
  
  // If the vector is registered and can not be shared return error.
  if (wasAlreadyRegisterd && !canBeShared) {
    IOLockUnlock(vector->interruptLock);
    return kIOReturnNoResources;
  }
  
  // If this vector is already in use, and can be shared (implied),
  // or it is not registered and should be shared,
  // register as a shared interrupt.
  if (wasAlreadyRegisterd || shouldBeShared) {
    // If this vector is not already shared, break it out.
    if (vector->sharedController == 0) {
      // Make the IOShareInterruptController instance
      vector->sharedController = new IOSharedInterruptController;
      if (vector->sharedController == 0) {
        IOLockUnlock(vector->interruptLock);
        return kIOReturnNoMemory;
      }
      
      if (wasAlreadyRegisterd) {
	// Save the nub and source for the original consumer.
	originalNub = vector->nub;
	originalSource = vector->source;
	
	// Physically disable the interrupt, but mark it as being enabled in the hardware.
	// The interruptDisabledSoft now indicates the driver's request for enablement.
	disableVectorHard(vectorNumber, vector);
	vector->interruptDisabledHard = 0;
      }
      
      // Initialize the new shared interrupt controller.
      error = vector->sharedController->initInterruptController(this, vectorData);
      // If the IOSharedInterruptController could not be initalized,
      // if needed, put the original consumer's interrupt back to normal and
      // get rid of whats left of the shared controller.
      if (error != kIOReturnSuccess) {
	if (wasAlreadyRegisterd) enableInterrupt(originalNub, originalSource);
        vector->sharedController->release();
        vector->sharedController = 0;
        IOLockUnlock(vector->interruptLock);
        return error;
      }
      
      // If there was an original consumer try to register it on the shared controller.
      if (wasAlreadyRegisterd) {
	error = vector->sharedController->registerInterrupt(originalNub,
							    originalSource,
							    vector->target,
							    vector->handler,
							    vector->refCon);
	// If the original consumer could not be moved to the shared controller,
	// put the original consumor's interrupt back to normal and
	// get rid of whats left of the shared controller.
	if (error != kIOReturnSuccess) {
	  // Save the driver's interrupt enablement state.
	  wasDisabledSoft = vector->interruptDisabledSoft;
	  
	  // Make the interrupt really hard disabled.
	  vector->interruptDisabledSoft = 1;
	  vector->interruptDisabledHard = 1;
	  
	  // Enable the original consumer's interrupt if needed.
	  if (!wasDisabledSoft) originalNub->enableInterrupt(originalSource);
	  enableInterrupt(originalNub, originalSource);
	  
	  vector->sharedController->release();
	  vector->sharedController = 0;
	  IOLockUnlock(vector->interruptLock);
	  return error;
	}
      }
      
      // Fill in vector with the shared controller's info.
      vector->handler = (IOInterruptHandler)vector->sharedController->getInterruptHandlerAddress();
      vector->nub     = vector->sharedController;
      vector->source  = 0;
      vector->target  = vector->sharedController;
      vector->refCon  = 0;
      
      // If the interrupt was already registered,
      // save the driver's interrupt enablement state.
      if (wasAlreadyRegisterd) wasDisabledSoft = vector->interruptDisabledSoft;
      else wasDisabledSoft = true;
      
      // Do any specific initalization for this vector if it has not yet been used.
      if (!wasAlreadyRegisterd) initVector(vectorNumber, vector);
      
      // Make the interrupt really hard disabled.
      vector->interruptDisabledSoft = 1;
      vector->interruptDisabledHard = 1;
      vector->interruptRegistered   = 1;
      
      // Enable the original consumer's interrupt if needed.
      // originalNub is protected by wasAlreadyRegisterd here (see line 184).
      if (!wasDisabledSoft) originalNub->enableInterrupt(originalSource);
    }
    
    error = vector->sharedController->registerInterrupt(nub, source, target,
                                                        handler, refCon);
    IOLockUnlock(vector->interruptLock);
    return error;
  }
  
  // Fill in vector with the client's info.
  vector->handler = handler;
  vector->nub     = nub;
  vector->source  = source;
  vector->target  = target;
  vector->refCon  = refCon;
  
  // Do any specific initalization for this vector.
  initVector(vectorNumber, vector);
  
  // Get the vector ready.  It starts hard disabled.
  vector->interruptDisabledHard = 1;
  vector->interruptDisabledSoft = 1;
  vector->interruptRegistered   = 1;
  
  IOLockUnlock(vector->interruptLock);
  return kIOReturnSuccess;
}