Annotation of XNU/iokit/Families/IONetworking/IOKernelDebugger.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:  * IOKernelDebugger.cpp
                     26:  *
                     27:  * Kernel debugger nub. This object interfaces with the KDP module and
                     28:  * dispatches KDP requests to its provider. The provider, named the
                     29:  * debugger device, must implement a pair of handler functions that are
                     30:  * called to handle KDP transmit and receive requests. A debugger lock,
                     31:  * allocated by the IOKernelDebugger, can be used by the debugger device
                     32:  * to block calls to its handler functions during critical sections.
                     33:  *
                     34:  * The debugger device is usually a subclass of IOEthernetController.
                     35:  * However, any IOService can attach an IOKernelDebugger client,
                     36:  * implement the two polled mode handlers, and transport the KDP
                     37:  * packets through a data channel. Having said this, the KDP assumes
                     38:  * that the debugger device is an Ethernet interface and therefore
                     39:  * it will always send, and expect to receive, an Ethernet frame.
                     40:  *
                     41:  * HISTORY
                     42:  */
                     43: 
                     44: #include <IOKit/assert.h>
                     45: #include <IOKit/IOLib.h>
                     46: #include <IOKit/IOMessage.h>
                     47: #include <IOKit/network/IONetworkController.h>
                     48: #include <IOKit/network/IOKernelDebugger.h>
                     49: 
                     50: extern "C" {
                     51: 
                     52: // Defined in osfmk/kdp/kdp_en_debugger.h,
                     53: // but the header file is not exported,
                     54: // thus the definition is replicated here.
                     55: 
                     56: typedef void (*kdp_send_t)(void * pkt, UInt pkt_len);
                     57: typedef void (*kdp_receive_t)(void * pkt, UInt * pkt_len, UInt timeout);
                     58: void kdp_register_send_receive(kdp_send_t send, kdp_receive_t receive);
                     59: }
                     60: 
                     61: #define super IOService
                     62: OSDefineMetaClassAndStructorsWithInit(IOKernelDebugger,
                     63:                                       IOService,
                     64:                                       IOKernelDebugger::initialize())
                     65: 
                     66: // Debugger global variables.
                     67: //
                     68: IOSimpleLock *       gIODebuggerLock       = 0;
                     69: UInt32               gIODebuggerFlag       = 0;
                     70: IOService *          gIODebuggerDevice     = 0;
                     71: IOKernelDebugger *   gIODebuggerNub        = 0;
                     72: IODebuggerTxHandler  gIODebuggerTxHandler  = 0;
                     73: IODebuggerRxHandler  gIODebuggerRxHandler  = 0;
                     74: UInt32               gIODebuggerTxBytes    = 0;
                     75: UInt32               gIODebuggerRxBytes    = 0;
                     76: UInt32               gIODebuggerSemaphore  = 0;   // deprecated
                     77: IOInterruptState     gIODebuggerInterruptState;
                     78: 
                     79: // Flags to indicate debugger state.
                     80: // 
                     81: enum {
                     82:     kIODebuggerFlagEnabled     = 0x01,
                     83:     kIODebuggerFlagRegistered  = 0x02,
                     84: };
                     85: 
                     86: #define KDP_GRAB_LOCK        IOSimpleLockLock(gIODebuggerLock)
                     87: #define KDP_RELEASE_LOCK     IOSimpleLockUnlock(gIODebuggerLock)
                     88: 
                     89: #define IOTakeDebuggerLock(s)    \
                     90:         ((s) = IOSimpleLockLockDisableInterrupt(gIODebuggerLock))
                     91: 
                     92: #define IOReleaseDebuggerLock(s)  \
                     93:         IOSimpleLockUnlockEnableInterrupt(gIODebuggerLock, (s))
                     94: 
                     95: //---------------------------------------------------------------------------
                     96: // The KDP receive dispatch function. Handles KDP receive requests during
                     97: // a debugging session, then dispatches the call to the registered handler.
                     98: // This function is registered with KDP via kdp_register_send_receive().
                     99: //
                    100: // pkt: KDP receive buffer. The buffer allocated has room for 1518 bytes.
                    101: //      Never overflow the buffer!
                    102: //
                    103: // pkt_len: The amount of data placed into the receive buffer. Set to
                    104: //          0 if no frame was received during the timeout interval.
                    105: //
                    106: // timeout: The registered handler must poll for a maximum period of
                    107: //          �timeout� milliseconds while waiting for a frame to arrive.
                    108: 
                    109: void IOKernelDebugger::kdpReceiveDispatcher(void *  pkt,
                    110:                                             UInt *  pkt_len, 
                    111:                                             UInt    timeout)
                    112: {
                    113:     *pkt_len = 0;    // return length field is zero by default.
                    114: 
                    115: #ifdef __USE_DEBUGGER_LOCK
                    116:     KDP_GRAB_LOCK;
                    117: 
                    118:     // Warning: We are holding a simple_lock, the handler must not block.
                    119: 
                    120:     (*gIODebuggerRxHandler)(gIODebuggerDevice, pkt, pkt_len, timeout);
                    121:     gIODebuggerRxBytes += *pkt_len;
                    122: 
                    123:     KDP_RELEASE_LOCK;
                    124: #else
                    125:     if (gIODebuggerSemaphore)
                    126:         return;
                    127: 
                    128:     (*gIODebuggerRxHandler)(gIODebuggerDevice, pkt, pkt_len, timeout);
                    129:     gIODebuggerRxBytes += *pkt_len;
                    130: #endif
                    131: }
                    132: 
                    133: //---------------------------------------------------------------------------
                    134: // The KDP transmit dispatch function. Handles KDP transmit requests during
                    135: // a debugging session, then dispatches the call to the registered handler.
                    136: // This function is registered with KDP via kdp_register_send_receive().
                    137: //
                    138: // pkt: KDP transmit buffer. This buffer contains a KDP frame to be sent
                    139: //      on the wire.
                    140: //
                    141: // pkt_len: The number of bytes in the transmit buffer.
                    142: 
                    143: void IOKernelDebugger::kdpTransmitDispatcher(void * pkt, UInt pkt_len)
                    144: {
                    145: #ifdef __USE_DEBUGGER_LOCK
                    146:     KDP_GRAB_LOCK;
                    147: 
                    148:     // Warning: We are holding a simple_lock, the handler must not block.
                    149: 
                    150:     (*gIODebuggerTxHandler)(gIODebuggerDevice, pkt, pkt_len);
                    151:     gIODebuggerTxBytes += pkt_len;
                    152: 
                    153:     KDP_RELEASE_LOCK;
                    154: #else
                    155:     if (gIODebuggerSemaphore)
                    156:         return;
                    157: 
                    158:     (*gIODebuggerTxHandler)(gIODebuggerDevice, pkt, pkt_len);
                    159:     gIODebuggerTxBytes += pkt_len;
                    160: #endif
                    161: }
                    162: 
                    163: //---------------------------------------------------------------------------
                    164: // Null request handlers. Those gets registered when an IOKernelDebugger
                    165: // instance becomes detached from its debugger device, and before a new 
                    166: // debugger device takes over the debugging responsibilities.
                    167: 
                    168: void IOKernelDebugger::nullTxHandler(IOService * provider,
                    169:                                      void *      buffer,
                    170:                                      UInt        length)
                    171: {
                    172:     IOLog("IOKernelDebugger::%s no debugger device\n", __FUNCTION__);
                    173: }
                    174: 
                    175: void IOKernelDebugger::nullRxHandler(IOService * provider,
                    176:                                      void *      buffer,
                    177:                                      UInt *      length,
                    178:                                      UInt        timeout)
                    179: {
                    180:     IOLog("IOKernelDebugger::%s no debugger device\n", __FUNCTION__);
                    181: }
                    182: 
                    183: //---------------------------------------------------------------------------
                    184: // Take the debugger lock conditionally.
                    185: // The debugger lock is taken only if the provider given is the current
                    186: // registered debugger device. The debugger device is registered via the
                    187: // openProvider() method, and unregistered via closeProvider().
                    188: //
                    189: // Returns kIODebuggerLocked if the lock was taken, or
                    190: // 0 if the lock was not taken. 
                    191: 
                    192: IODebuggerLockState IOKernelDebugger::lock(IOService * provider)
                    193: {
                    194: #ifdef __USE_DEBUGGER_LOCK
                    195: 
                    196:     if (gIODebuggerDevice == provider)
                    197:     {
                    198:         IOInterruptState irqState;
                    199: 
                    200:         IOTakeDebuggerLock(irqState);
                    201: 
                    202:         if (gIODebuggerDevice == provider)
                    203:         {
                    204:             gIODebuggerInterruptState = irqState;
                    205:             return kIODebuggerLockTaken;
                    206:         }
                    207:         else {
                    208:             IOReleaseDebuggerLock(irqState);
                    209:         }
                    210:     }
                    211:     return (IODebuggerLockState) 0;
                    212: 
                    213: #else /* !__USE_DEBUGGER_LOCK */
                    214: 
                    215:     if (gIODebuggerDevice == provider)
                    216:     {
                    217:         if (gIODebuggerSemaphore)
                    218:             IOLog("IOKernelDebugger::lock: already locked\n");
                    219: 
                    220:         gIODebuggerSemaphore++;
                    221:         return kIODebuggerLockTaken;
                    222:     }
                    223:     return (IODebuggerLockState) 0;
                    224: 
                    225: #endif
                    226: }
                    227: 
                    228: //---------------------------------------------------------------------------
                    229: // Release the debugger lock if the kIODebuggerLockTaken flag is set.
                    230: //
                    231: // state: The saved return from a previous IOKernelDebugger::lock() call.
                    232: 
                    233: void IOKernelDebugger::unlock(IODebuggerLockState state)
                    234: {
                    235: #ifdef __USE_DEBUGGER_LOCK
                    236: 
                    237:     if (state & kIODebuggerLockTaken)
                    238:         IOReleaseDebuggerLock(gIODebuggerInterruptState);
                    239: 
                    240: #else /* !__USE_DEBUGGER_LOCK */
                    241: 
                    242:     if (state & kIODebuggerLockTaken)
                    243:         gIODebuggerSemaphore--;
                    244: 
                    245: #endif
                    246: }
                    247: 
                    248: //---------------------------------------------------------------------------
                    249: // IOKernelDebugger class initializer. The debugger lock is allocated and
                    250: // initialized.
                    251: 
                    252: void IOKernelDebugger::initialize()
                    253: {
                    254:     // Allocate and initialize the debugger lock (simple_lock).
                    255: 
                    256:     gIODebuggerLock = IOSimpleLockAlloc();
                    257:     assert(gIODebuggerLock);
                    258:     IOSimpleLockInit(gIODebuggerLock);
                    259: }
                    260: 
                    261: //---------------------------------------------------------------------------
                    262: // The IOKernelDebugger initializer.
                    263: //
                    264: // provider:  The provider of the IOKernelDebugger object.
                    265: // txHandler: The transmit handler. A pointer to a C function.
                    266: // rxHandler: The receive handler. A pointer to a C function.
                    267: //
                    268: // Returns true if the instance initialized successfully, false otherwise.
                    269: 
                    270: bool IOKernelDebugger::init(IOService *          provider,
                    271:                             IODebuggerTxHandler  txHandler,
                    272:                             IODebuggerRxHandler  rxHandler)
                    273: {
                    274:     if (!OSDynamicCast(IOService, provider) || !txHandler || !rxHandler)
                    275:         return false;
                    276: 
                    277:     if (!super::init())
                    278:         return false;
                    279: 
                    280:     // Register the provider and handlers provided.
                    281: 
                    282:     _provider  = provider;
                    283:     _txHandler = txHandler;
                    284:     _rxHandler = rxHandler;
                    285: 
                    286:     return true;
                    287: }
                    288: 
                    289: //---------------------------------------------------------------------------
                    290: // A factory method that performs allocation and initialization.
                    291: //
                    292: // provider:  The provider of the IOKernelDebugger object.
                    293: // txHandler: The transmit handler. A pointer to a C function.
                    294: // rxHandler: The receive handler. A pointer to a C function.
                    295: //
                    296: // Returns an IOKernelDebugger instance on success, 0 otherwise.
                    297: 
                    298: IOKernelDebugger * IOKernelDebugger::debugger(IOService *          provider,
                    299:                                               IODebuggerTxHandler  txHandler,
                    300:                                               IODebuggerRxHandler  rxHandler)
                    301: {
                    302:     IOKernelDebugger * debugger = new IOKernelDebugger;
                    303: 
                    304:     if (debugger && !debugger->init(provider, txHandler, rxHandler))
                    305:     {
                    306:         debugger->release();
                    307:         debugger = 0;
                    308:     }
                    309: 
                    310:     return debugger;
                    311: }
                    312: 
                    313: //---------------------------------------------------------------------------
                    314: // Open the attached provider, register the dispatch and handler functions.
                    315: //
                    316: // provider: The provider object. This object is registered as the debugger
                    317: //           device.
                    318: //
                    319: // Returns true on sucess, or false if the controller open failed, or there
                    320: // is a previously registered IOKernelDebugger instance.
                    321: 
                    322: bool IOKernelDebugger::openProvider(IOService * provider)
                    323: {
                    324:     bool              ret = false;
                    325:     bool              doOpen;
                    326:     bool              wasOpen;
                    327:     bool              doRegistration = false;
                    328:     IOInterruptState  state;
                    329: 
                    330:     IOTakeDebuggerLock(state);
                    331:     if (gIODebuggerNub)
                    332:     {
                    333:         // Debugger nub already registered. Sorry, only
                    334:         // a single debugger nub at any given time.
                    335: 
                    336:         doOpen = false;
                    337:     }
                    338:     else
                    339:     {
                    340:         assert(gIODebuggerDevice == 0);
                    341:         assert((gIODebuggerFlag & kIODebuggerFlagEnabled) == 0);
                    342:         assert(provider == _provider);
                    343: 
                    344:         // Make reservation.
                    345: 
                    346:         gIODebuggerNub = this;
                    347:         doOpen         = true;
                    348:     }
                    349:     IOReleaseDebuggerLock(state);
                    350: 
                    351:     // If doOpen is true, then proceed and open the provider,
                    352:     // otherwise we were unable to make reservation, so
                    353:     // we give up and return false.
                    354: 
                    355:     do {
                    356:         if (!doOpen) break;
                    357: 
                    358:         wasOpen = provider->open(this);
                    359: 
                    360:         // Take the debugger lock again and commit the reservation.
                    361:         // Make sure nothing has happened to cause us to loose the
                    362:         // initial reservation.
                    363: 
                    364:         IOTakeDebuggerLock(state);
                    365: 
                    366:         if (wasOpen && (gIODebuggerNub == this))
                    367:         {
                    368:             gIODebuggerTxHandler  = _txHandler;
                    369:             gIODebuggerRxHandler  = _rxHandler;
                    370:             gIODebuggerDevice     = provider;
                    371:             gIODebuggerFlag      |= kIODebuggerFlagEnabled;
                    372: 
                    373:             if ((gIODebuggerFlag & kIODebuggerFlagRegistered) == 0)
                    374:             {
                    375:                 // Our static dispatch functions have not yet been
                    376:                 // registered with kdp, set doRegistration to
                    377:                 // perform registration after releasing the lock.
                    378:                 // The act of registering may trigger kdp to call
                    379:                 // our dispatch functions, so we should not be
                    380:                 // holding the debugger lock.
                    381: 
                    382:                 gIODebuggerFlag |= kIODebuggerFlagRegistered;
                    383:                 doRegistration = true;
                    384:             }
                    385:         }
                    386:         else
                    387:         {
                    388:             // Either we were unable to open provider,
                    389:             // or perhaps we lost reservation.
                    390: 
                    391:             if (gIODebuggerNub == this)
                    392:             {
                    393:                 // Unable to open provider, remove our
                    394:                 // reservation.
                    395: 
                    396:                 gIODebuggerNub = 0;
                    397:             }
                    398:             IOReleaseDebuggerLock(state);
                    399:             break;
                    400:         }
                    401: 
                    402:         IOReleaseDebuggerLock(state);
                    403: 
                    404:         // NOTE: Once the provider has accepted an open from this
                    405:         // object, it must be prepared to handle kdp requests
                    406:         // immediately after its open method returns.
                    407:         //
                    408:         // Register the dispatch functions, that will route the
                    409:         // kdp request to our provider�s registered handlers.
                    410: 
                    411:         if (doRegistration)
                    412:             kdp_register_send_receive(kdpTransmitDispatcher,
                    413:                                       kdpReceiveDispatcher);
                    414: 
                    415:         ret = true;        // success
                    416:     }
                    417:     while (0);
                    418: 
                    419:     if (doOpen && !ret)
                    420:     {
                    421:         // Make sure the provider is closed.    
                    422:         provider->close(this);
                    423:     }
                    424: 
                    425:     return ret;
                    426: }
                    427: 
                    428: //---------------------------------------------------------------------------
                    429: // Close our provider, and unregister the handler functions provided to
                    430: // init(). Another IOKernelDebugger instance that comes along will be
                    431: // able to assume the debugging responsibilities.
                    432: //
                    433: // provider: The provider object. This object is unregistered as the
                    434: //           debugger device.
                    435: 
                    436: void IOKernelDebugger::closeProvider(IOService * provider)
                    437: {
                    438:     bool              doClose = false;
                    439:     IOInterruptState  state;
                    440: 
                    441:     IOTakeDebuggerLock(state);
                    442: 
                    443:     if (gIODebuggerNub == this)
                    444:     {
                    445:         // There is no kdp unregistration. Thus setup the handlers
                    446:         // to point to dummy functions to avoid a system panic
                    447:         // when the debugger device gives up its responsibilities
                    448:         // and the debugger is activated.
                    449:         // Until the next debugger device comes along, nothing will
                    450:         // happen when the debugger is activated, which is not good.
                    451: 
                    452:         gIODebuggerFlag      &= ~kIODebuggerFlagEnabled;
                    453:         gIODebuggerDevice     = 0;
                    454:         gIODebuggerNub        = 0;
                    455:         gIODebuggerTxHandler  = &IOKernelDebugger::nullTxHandler;
                    456:         gIODebuggerRxHandler  = &IOKernelDebugger::nullRxHandler;
                    457:         doClose               = true;
                    458:     }
                    459:     IOReleaseDebuggerLock(state);
                    460: 
                    461:     if (doClose)
                    462:         provider->close(this);
                    463: }
                    464: 
                    465: //---------------------------------------------------------------------------
                    466: // Attach to our provider, then call openProvider().
                    467: //
                    468: // provider: The provider object.
                    469: //
                    470: // Returns true on success, false otherwise.
                    471: 
                    472: bool IOKernelDebugger::attach(IOService * provider)
                    473: {
                    474:     bool ret = false;
                    475: 
                    476:     assert(provider == _provider);
                    477: 
                    478:     if (!super::attach(provider))
                    479:         return false;        // cannot attach to provider.
                    480: 
                    481:     ret = openProvider(provider);
                    482: 
                    483:     return ret;
                    484: }
                    485: 
                    486: //---------------------------------------------------------------------------
                    487: // Call closeProvider() then detach from our provider.
                    488: //
                    489: // provider: The provider object.
                    490: 
                    491: void IOKernelDebugger::detach(IOService * provider)
                    492: {
                    493: //  IOLog("IOKernelDebugger::%s provider:%x\n", __FUNCTION__, (UInt) provider);
                    494: 
                    495:     assert(provider == _provider);
                    496: 
                    497:     closeProvider(provider);
                    498: 
                    499:     super::detach(provider);
                    500: }
                    501: 
                    502: //---------------------------------------------------------------------------
                    503: // Final termination notification. Ensure that the closeProvider() is
                    504: // called before the object is terminated.
                    505: //
                    506: // options: termination options, not used.
                    507: 
                    508: bool IOKernelDebugger::finalize(IOOptionBits options)
                    509: {
                    510: //  IOLog("IOKernelDebugger::%s options:%x\n", __FUNCTION__, (UInt) options);
                    511: 
                    512:     closeProvider(_provider);
                    513:     return super::finalize(options);
                    514: }
                    515: 
                    516: //---------------------------------------------------------------------------
                    517: // Facility provided by IOService for general purpose provider-to-client 
                    518: // notification. We catch the kIOMessageServiceIsTerminated message to
                    519: // detect when our provider becomes inactive, and call closeProvider().
                    520: //
                    521: // type: message tupe.
                    522: // provider: The provider object.
                    523: // argument: message argument. Not used.
                    524: //
                    525: // Returns kIOReturnSuccess for kIOMessageServiceIsTerminated messages,
                    526: // kIOReturnUnsupported otherwise.
                    527: 
                    528: IOReturn IOKernelDebugger::message(UInt32       type,
                    529:                                    IOService *  provider,
                    530:                                    void *       argument = 0)
                    531: {
                    532: //  IOLog("IOKernelDebugger::%s type:%x provider:%x\n",
                    533: //        __FUNCTION__, (UInt) type, (UInt) provider);
                    534: 
                    535:     assert(provider == _provider);
                    536: 
                    537:     if (type == kIOMessageServiceIsTerminated)
                    538:     {
                    539:         // Close our provider when it becomes inactive.
                    540: 
                    541:         closeProvider(provider);
                    542:         return kIOReturnSuccess;
                    543:     }
                    544: 
                    545:     return kIOReturnUnsupported;
                    546: }
                    547: 
                    548: //---------------------------------------------------------------------------
                    549: // Free the IOKernelDebugger instance.
                    550: 
                    551: void IOKernelDebugger::free()
                    552: {
                    553: //  IOLog("IOKernelDebugger::%s %08lx\n", __FUNCTION__, (UInt32) this);
                    554:     super::free();
                    555: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.