]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Families/IONetworking/IOKernelDebugger.cpp
xnu-201.tar.gz
[apple/xnu.git] / iokit / Families / IONetworking / IOKernelDebugger.cpp
diff --git a/iokit/Families/IONetworking/IOKernelDebugger.cpp b/iokit/Families/IONetworking/IOKernelDebugger.cpp
deleted file mode 100644 (file)
index daa450d..0000000
+++ /dev/null
@@ -1,688 +0,0 @@
-/*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved. 
- *
- * IOKernelDebugger.cpp
- *
- * HISTORY
- */
-
-#include <IOKit/assert.h>
-#include <IOKit/IOLib.h>
-#include <IOKit/IOMessage.h>
-#include <IOKit/IOLocks.h>
-#include <IOKit/network/IONetworkController.h>
-#include <IOKit/network/IOKernelDebugger.h>
-#include <libkern/OSAtomic.h>
-
-//---------------------------------------------------------------------------
-// IOKDP
-
-#define kIOKDPEnableKDP         "IOEnableKDP"
-#define kIOKDPDriverMatch       "IODriverMatch"
-#define kIOKDPDriverNubMatch    "IODriverNubMatch"
-
-class IOKDP : public IOService
-{
-    OSDeclareDefaultStructors( IOKDP )
-
-public:
-    static void  initialize();
-
-    virtual bool start( IOService * provider );
-
-    virtual void stop( IOService * provider );
-
-    virtual bool matchProvider( IOService * provider );
-
-    virtual bool matchServiceWithDictionary( IOService *    service,
-                                             OSDictionary * match );
-
-    virtual IOReturn message( UInt32       type,
-                              IOService *  provider,
-                              void *       argument = 0 );
-};
-
-//---------------------------------------------------------------------------
-// IOKDP defined globals.
-
-static IOLock * gIOKDPLock = 0;
-static IOKDP *  gIOKDP     = 0;
-
-#define super IOService
-OSDefineMetaClassAndStructorsWithInit( IOKDP, IOService,
-                                       IOKDP::initialize() )
-
-//---------------------------------------------------------------------------
-// Match the provider with the matching dictionary in our property table.
-
-bool IOKDP::matchProvider(IOService * provider)
-{
-    IOService * driver    = 0;
-    IOService * driverNub = 0;
-    OSBoolean * aBool;
-
-    if ( provider )  driver = provider->getProvider();
-    if ( driver ) driverNub = driver->getProvider();
-
-    if ( (driver == 0) || (driverNub == 0) )
-        return false;
-
-    if ( ( aBool = OSDynamicCast(OSBoolean, getProperty(kIOKDPEnableKDP)) ) &&
-         ( aBool->isTrue() == false ) )
-        return false;
-
-    if ( matchServiceWithDictionary( driver, (OSDictionary *)
-                                     getProperty(kIOKDPDriverMatch)) )
-    {
-        // IOLog("IOKDP: %s\n", kIOKDPDriverMatch);
-        return true;
-    }
-
-    if ( matchServiceWithDictionary( driverNub, (OSDictionary *) 
-                                     getProperty(kIOKDPDriverNubMatch)) )
-    {
-        // IOLog("IOKDP: %s\n", kIOKDPDriverNubMatch);
-        return true;
-    }
-
-    return false;
-}
-
-//---------------------------------------------------------------------------
-// Match an IOService with a matching dictionary.
-
-bool IOKDP::matchServiceWithDictionary(IOService *    service,
-                                       OSDictionary * match)
-{
-    OSCollectionIterator * matchIter;
-    OSCollectionIterator * arrayIter = 0;
-    OSCollection *         array;
-    OSObject *             objM;
-    OSObject *             objP;
-    OSSymbol *             sym;
-    bool                   isMatch = false;
-
-    if ( ( OSDynamicCast(OSDictionary, match) == 0 ) ||
-         ( match->getCount() == 0 )                  ||
-         ( (matchIter = OSCollectionIterator::withCollection(match)) == 0 ) )
-        return false;
-
-    while ( ( sym = OSDynamicCast(OSSymbol, matchIter->getNextObject()) ) )
-    {
-        objM = match->getObject(sym);
-        objP = service->getProperty(sym);
-
-        isMatch = false;
-
-        if ( arrayIter )
-        {
-            arrayIter->release();
-            arrayIter = 0;
-        }
-
-        if ( (array = OSDynamicCast( OSCollection, objM )) )
-        {
-            arrayIter = OSCollectionIterator::withCollection( array );
-            if ( arrayIter == 0 ) break;
-        }
-
-        do {
-            if ( arrayIter && ((objM = arrayIter->getNextObject()) == 0) )
-                break;
-
-            if ( objM && objP && objM->isEqualTo(objP) )
-            {
-                isMatch = true;
-                break;
-            }
-        }
-        while ( arrayIter );
-
-        if ( isMatch == false ) break;
-    }
-
-    if ( arrayIter ) arrayIter->release();
-    matchIter->release();
-
-    return isMatch;
-}
-
-//---------------------------------------------------------------------------
-// IOKDP class initializer.
-
-void IOKDP::initialize()
-{
-    gIOKDPLock = IOLockAlloc();
-    assert( gIOKDPLock );
-}
-
-//---------------------------------------------------------------------------
-// start/stop/message.
-
-bool IOKDP::start( IOService * provider )
-{
-    bool ret = false;
-
-    if ( super::start(provider) == false )
-        return false;
-
-    IOLockLock( gIOKDPLock );
-
-    do {
-        if ( gIOKDP )
-            break;
-
-        if ( matchProvider(provider) == false )
-            break;
-
-        if ( provider->open(this) == false )
-            break;
-
-        publishResource("kdp");
-
-        gIOKDP = this;
-        ret    = true;
-    }
-    while ( false );
-
-    IOLockUnlock( gIOKDPLock );
-
-    return ret;
-}
-
-void IOKDP::stop( IOService * provider )
-{
-    provider->close(this);
-
-    IOLockLock( gIOKDPLock );
-
-    if ( gIOKDP == this ) gIOKDP = 0;
-
-    IOLockUnlock( gIOKDPLock );
-
-    super::stop(provider);
-}
-
-IOReturn IOKDP::message( UInt32       type,
-                         IOService *  provider,
-                         void *       argument )
-{
-    if ( type == kIOMessageServiceIsTerminated )
-    {
-        provider->close(this);
-    }
-    return kIOReturnSuccess;
-}
-
-
-//---------------------------------------------------------------------------
-// IOKernelDebugger
-
-extern "C" {
-//
-// Defined in osfmk/kdp/kdp_en_debugger.h, but the header file is not
-// exported, thus the definition is replicated here.
-//
-typedef void (*kdp_send_t)( void * pkt, UInt pkt_len );
-typedef void (*kdp_receive_t)( void * pkt, UInt * pkt_len, UInt timeout );
-void kdp_register_send_receive( kdp_send_t send, kdp_receive_t receive );
-}
-
-#undef  super
-#define super IOService
-OSDefineMetaClassAndStructors( IOKernelDebugger, IOService )
-OSMetaClassDefineReservedUnused( IOKernelDebugger,  0);
-OSMetaClassDefineReservedUnused( IOKernelDebugger,  1);
-OSMetaClassDefineReservedUnused( IOKernelDebugger,  2);
-OSMetaClassDefineReservedUnused( IOKernelDebugger,  3);
-
-// IOKernelDebugger global variables.
-//
-IOService *          gIODebuggerDevice    = 0;
-IODebuggerTxHandler  gIODebuggerTxHandler = 0;
-IODebuggerRxHandler  gIODebuggerRxHandler = 0;
-UInt32               gIODebuggerTxBytes   = 0;
-UInt32               gIODebuggerRxBytes   = 0;
-SInt32               gIODebuggerSemaphore = 0;
-UInt32               gIODebuggerFlag      = 0;
-
-// Global debugger flags.
-// 
-enum {
-    kIODebuggerFlagRegistered       = 0x01,
-    kIODebuggerFlagWarnNullHandler  = 0x02
-};
-
-//---------------------------------------------------------------------------
-// The KDP receive dispatch function. Dispatches KDP receive requests to the
-// registered receive handler. This function is registered with KDP via 
-// kdp_register_send_receive().
-
-void IOKernelDebugger::kdpReceiveDispatcher( void *   buffer,
-                                             UInt32 * length, 
-                                             UInt32   timeout )
-{
-    *length = 0;    // return a zero length field by default.
-
-    if ( gIODebuggerSemaphore ) return;  // FIXME - Driver is busy!
-
-    (*gIODebuggerRxHandler)( gIODebuggerDevice, buffer, length, timeout );
-
-    gIODebuggerRxBytes += *length;
-}
-
-//---------------------------------------------------------------------------
-// The KDP transmit dispatch function. Dispatches KDP receive requests to the
-// registered transmit handler. This function is registered with KDP via 
-// kdp_register_send_receive().
-
-void IOKernelDebugger::kdpTransmitDispatcher( void * buffer, UInt32 length )
-{
-    if ( gIODebuggerSemaphore ) return;  // FIXME - Driver is busy!
-
-    (*gIODebuggerTxHandler)( gIODebuggerDevice, buffer, length );
-
-    gIODebuggerTxBytes += length;
-}
-
-//---------------------------------------------------------------------------
-// Null debugger handlers.
-
-void IOKernelDebugger::nullTxHandler( IOService * target,
-                                      void *      buffer,
-                                      UInt32      length )
-{
-}
-
-void IOKernelDebugger::nullRxHandler( IOService * target,
-                                      void *      buffer,
-                                      UInt32 *    length,
-                                      UInt32      timeout )
-{
-    if ( gIODebuggerFlag & kIODebuggerFlagWarnNullHandler )
-    {
-        IOLog("IOKernelDebugger::%s no debugger device\n", __FUNCTION__);
-        gIODebuggerFlag &= ~kIODebuggerFlagWarnNullHandler;
-    }
-}
-
-//---------------------------------------------------------------------------
-// Take the debugger lock conditionally.
-
-IODebuggerLockState IOKernelDebugger::lock( IOService * object )
-{
-    if ( gIODebuggerDevice == object )
-    {
-        OSIncrementAtomic( &gIODebuggerSemaphore );
-        return kIODebuggerLockTaken;
-    }
-    return (IODebuggerLockState) 0;
-}
-
-//---------------------------------------------------------------------------
-// Release the debugger lock if the kIODebuggerLockTaken flag is set.
-
-void IOKernelDebugger::unlock( IODebuggerLockState state )
-{
-    if ( state & kIODebuggerLockTaken )
-        OSDecrementAtomic( &gIODebuggerSemaphore );
-}
-
-//---------------------------------------------------------------------------
-// Initialize an IOKernelDebugger instance.
-
-bool IOKernelDebugger::init( IOService *          target,
-                             IODebuggerTxHandler  txHandler,
-                             IODebuggerRxHandler  rxHandler )
-{
-    if ( ( super::init() == false )                ||
-         ( OSDynamicCast(IOService, target) == 0 ) ||
-         ( txHandler == 0 )                        ||
-         ( rxHandler == 0 ) )
-    {
-        return false;
-    }
-
-    // Cache the target and handlers provided.
-
-    _target     = target;
-    _txHandler  = txHandler;
-    _rxHandler  = rxHandler;
-
-    return true;
-}
-
-//---------------------------------------------------------------------------
-// Factory method which performs allocation and initialization of an 
-// IOKernelDebugger instance.
-
-IOKernelDebugger * IOKernelDebugger::debugger( IOService *          target,
-                                               IODebuggerTxHandler  txHandler,
-                                               IODebuggerRxHandler  rxHandler )
-{
-    IOKernelDebugger * debugger = new IOKernelDebugger;
-
-    if (debugger && (debugger->init( target, txHandler, rxHandler ) == false))
-    {
-        debugger->release();
-        debugger = 0;
-    }
-
-    return debugger;
-}
-
-//---------------------------------------------------------------------------
-// Register the debugger handlers.
-
-void IOKernelDebugger::registerHandler( IOService *          target,
-                                        IODebuggerTxHandler  txHandler,
-                                        IODebuggerRxHandler  rxHandler )
-{
-    bool doRegister;
-
-    assert( ( target == gIODebuggerDevice ) ||
-            ( target == 0 )                 ||
-            ( gIODebuggerDevice == 0 ) );
-
-    doRegister = ( target && ( txHandler != 0 ) && ( rxHandler != 0 ) );
-
-    if ( txHandler == 0 ) txHandler = &IOKernelDebugger::nullTxHandler;
-    if ( rxHandler == 0 ) rxHandler = &IOKernelDebugger::nullRxHandler;    
-
-    OSIncrementAtomic( &gIODebuggerSemaphore );
-
-    gIODebuggerDevice    = target;  
-    gIODebuggerTxHandler = txHandler;
-    gIODebuggerRxHandler = rxHandler;
-    gIODebuggerFlag     |= kIODebuggerFlagWarnNullHandler;
-
-    OSDecrementAtomic( &gIODebuggerSemaphore );
-
-    if ( doRegister && (( gIODebuggerFlag & kIODebuggerFlagRegistered ) == 0) )
-    {
-        // Register dispatch function, these in turn will call the
-        // handlers when the debugger is active.
-        // 
-        // Note: The following call may trigger an immediate break
-        //       to the debugger.
-
-        kdp_register_send_receive( (kdp_send_t) kdpTransmitDispatcher,
-                                   (kdp_receive_t) kdpReceiveDispatcher );
-
-        // Limit ourself to a single real KDP registration.
-
-        gIODebuggerFlag |= kIODebuggerFlagRegistered;
-    }
-}
-
-//---------------------------------------------------------------------------
-// Called by open() with the arbitration lock held.
-
-bool IOKernelDebugger::handleOpen( IOService *    forClient,
-                                   IOOptionBits   options,
-                                   void *         arg )
-{
-    IONetworkController * ctr = OSDynamicCast(IONetworkController, _target);
-    bool                  ret = false;
-
-    do {
-        // Only a single client at a time.
-
-        if ( _client ) break;
-
-        // Register the target to prime the lock()/unlock() functionality
-        // before opening the target.
-
-        registerHandler( _target );
-
-        // While the target is opened/enabled, it must block any thread
-        // which may acquire the debugger lock in its execution path.
-
-        if ( _target->open( this ) == false )
-            break;
-
-        // Register interest in receiving notifications about controller
-        // power state changes.
-        //
-        // We are making an assumption that the controller is 'usable' and
-        // the next notification will inform this object that the controller
-        // has become unusable, there is no support for cases when the
-        // controller is already in an 'unusable' state.
-
-        _pmDisabled = false;
-
-        if ( ctr )
-        {
-            // Register to receive PM notifications for controller power
-            // state changes.
-
-            ctr->registerInterestedDriver( this );
-        
-            if ( ctr->doEnable( this ) != kIOReturnSuccess )
-            {
-                ctr->deRegisterInterestedDriver( this );
-                break;
-            }
-        }
-
-        // After the target has been opened, complete the registration.
-
-        IOLog("%s: Debugger attached\n", getName());
-        registerHandler( _target, _txHandler, _rxHandler );
-
-        // Remember the client.
-
-        _client = forClient;
-
-        ret = true;
-    }
-    while (0);
-
-    if ( ret == false )
-    {
-        registerHandler( 0 );
-        _target->close( this );
-    }
-
-    return ret;
-}
-
-//---------------------------------------------------------------------------
-// Called by IOService::close() with the arbitration lock held.
-
-void IOKernelDebugger::handleClose( IOService *   forClient,
-                                    IOOptionBits  options )
-{
-    IONetworkController * ctr = OSDynamicCast(IONetworkController, _target);
-
-    if ( _client && ( _client == forClient ) )
-    {
-        // There is no KDP un-registration. The best we can do is to
-        // register dummy handlers.
-
-        registerHandler( 0 );
-
-        if ( ctr )
-        {
-            // Disable controller if it is not already disabled.
-
-            if ( _pmDisabled == false )
-            {
-                ctr->doDisable( this );
-            }
-
-            // Before closing the controller, remove interest in receiving
-            // notifications about controller power state changes.
-
-            ctr->deRegisterInterestedDriver( this );
-        }
-
-        _client = 0;
-
-        _target->close( this );
-    }
-}
-
-//---------------------------------------------------------------------------
-// Called by IOService::isOpen() with the arbitration lock held.
-
-bool IOKernelDebugger::handleIsOpen( const IOService * forClient ) const
-{
-    if ( forClient == 0 )
-        return ( forClient != _client );
-    else
-        return ( forClient == _client );
-}
-
-//---------------------------------------------------------------------------
-// Free the IOKernelDebugger object.
-
-void IOKernelDebugger::free()
-{
-    // IOLog("IOKernelDebugger::%s %p\n", __FUNCTION__, this);
-    super::free();
-}
-
-#define PM_SECS(x)    ((x) * 1000 * 1000)
-
-//---------------------------------------------------------------------------
-// Handle controller's power state change notitifications.
-
-IOReturn
-IOKernelDebugger::powerStateWillChangeTo( IOPMPowerFlags  flags,
-                                          unsigned long   stateNumber,
-                                          IOService *     policyMaker )
-{
-    IOReturn ret = IOPMAckImplied;
-
-    if ( ( flags & IOPMDeviceUsable ) == 0 )
-    {
-        // Controller is about to transition to an un-usable state.
-        // The debugger nub should be disabled.
-
-        this->retain();
-
-        thread_call_func( (thread_call_func_t) pmDisableDebugger,
-                          this,    /* parameter */
-                          FALSE ); /* disable unique call filter */
-
-        ret = PM_SECS(3);  /* Must ACK within 3 seconds */
-    }
-
-    return ret;
-}
-
-IOReturn
-IOKernelDebugger::powerStateDidChangeTo( IOPMPowerFlags  flags,
-                                         unsigned long   stateNumber,
-                                         IOService *     policyMaker )
-{
-    IOReturn ret = IOPMAckImplied;
-
-    if ( flags & IOPMDeviceUsable )
-    {
-        // Controller has transitioned to an usable state.
-        // The debugger nub should be enabled if necessary.
-
-        this->retain();
-
-        thread_call_func( (thread_call_func_t) pmEnableDebugger,
-                          this,    /* parameter */
-                          FALSE ); /* disable unique call filter */
-
-        ret = PM_SECS(3);  /* Must ACK within 3 seconds */
-    }
-
-    return ret;
-}
-
-//---------------------------------------------------------------------------
-// Static member function: Enable the debugger nub after the controller
-// transitions into an usable state.
-
-void IOKernelDebugger::pmEnableDebugger( IOKernelDebugger * debugger )
-{
-    IONetworkController * ctr;
-    assert( debugger );
-
-    ctr = OSDynamicCast( IONetworkController, debugger->_target );
-
-    debugger->lockForArbitration();
-
-    if ( debugger->_client && ( debugger->_pmDisabled == true ) )
-    {
-        if ( ctr && ( ctr->doEnable( debugger ) != kIOReturnSuccess ) )
-        {
-            // This is bad, unable to re-enable the controller after sleep.
-            IOLog("IOKernelDebugger: Unable to re-enable controller\n");
-        }
-        else
-        {
-            registerHandler( debugger->_target, debugger->_txHandler, 
-                                                debugger->_rxHandler );
-
-            debugger->_pmDisabled = false;
-        }
-    }
-
-    debugger->unlockForArbitration();
-
-    // Ack the power state change.
-    debugger->_target->acknowledgePowerChange( debugger );
-
-    debugger->release();
-}
-
-//---------------------------------------------------------------------------
-// Static member function: Disable the debugger nub before the controller
-// transitions into an unusable state.
-
-void IOKernelDebugger::pmDisableDebugger( IOKernelDebugger * debugger )
-{
-    IONetworkController * ctr;
-    assert( debugger );
-
-    ctr = OSDynamicCast( IONetworkController, debugger->_target );
-
-    debugger->lockForArbitration();
-
-    if ( debugger->_client && ( debugger->_pmDisabled == false ) )
-    {
-        // Keep an open on the controller, but inhibit access to the
-        // controller's debugger handlers, and disable controller's
-        // hardware support for the debugger.
-
-        registerHandler( 0 );
-        if ( ctr ) ctr->doDisable( debugger );
-
-        debugger->_pmDisabled = true;
-    }
-
-    debugger->unlockForArbitration();
-
-    // Ack the power state change.
-    debugger->_target->acknowledgePowerChange( debugger );
-
-    debugger->release();
-}