1/* 2 * Copyright (c) 1998-2008 Apple 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 * IOKernelDebugger.cpp 24 * 25 * HISTORY 26 */ 27 28#include <IOKit/assert.h> 29#include <IOKit/IOLib.h> 30#include <IOKit/IOMessage.h> 31#include <IOKit/IOLocks.h> 32#include <IOKit/network/IONetworkController.h> 33#include <IOKit/network/IOKernelDebugger.h> 34#include <IOKit/IOBSD.h> //for kIOBSDNameKey 35#include <libkern/OSAtomic.h> 36#include "IONetworkControllerPrivate.h" 37 38#define kIOPrimaryDebugPortKey "IOPrimaryDebugPort" 39 40#define kMatchNameArg "kdp_match_name" 41#define kMatchMacArg "kdp_match_mac" 42 43//--------------------------------------------------------------------------- 44// IOKDP 45 46class IOKDP : public IOService 47{ 48 OSDeclareDefaultStructors( IOKDP ) 49 50public: 51 /*! @function probe 52 @abstract verify controller meets criteria for debugger 53 @discussion This checks that the controller that is attaching the debugger 54 meets the criteria set by the user on the kernel command line. Current boot-args 55 are kdp_match_mac=001122334455 to match against a specific MAC address and 56 kdp_match_name=bsdname to match against interfaces with the specified BSD interface 57 name (for example, en1) 58 */ 59 60 virtual IOService *probe(IOService *provider, SInt32 *score); 61 62 virtual bool start( IOService * provider ); 63 64 virtual void stop( IOService * provider ); 65 66 virtual IOReturn message( UInt32 type, 67 IOService * provider, 68 void * argument = 0 ); 69}; 70 71//--------------------------------------------------------------------------- 72// IOKDP defined globals. 73 74static IOLock * gIOKDPLock = 0; 75static IOKDP * gIOKDP = 0; 76static UInt32 gDebugBootArg = 0; 77 78class IOKDPGlobals 79{ 80public: 81 IOKDPGlobals(); 82 ~IOKDPGlobals(); 83 84 inline bool isValid() const; 85}; 86 87static IOKDPGlobals gIOKDPGlobals; 88 89IOKDPGlobals::IOKDPGlobals() 90{ 91 gIOKDPLock = IOLockAlloc(); 92 93 PE_parse_boot_argn( "debug", &gDebugBootArg, sizeof (gDebugBootArg) ); 94} 95 96IOKDPGlobals::~IOKDPGlobals() 97{ 98 if ( gIOKDPLock ) 99 { 100 IOLockFree( gIOKDPLock ); 101 gIOKDPLock = 0; 102 } 103} 104 105bool IOKDPGlobals::isValid() const 106{ 107 return ( gIOKDPLock ); 108} 109 110#define super IOService 111OSDefineMetaClassAndStructors( IOKDP, IOService ) 112 113//--------------------------------------------------------------------------- 114// start/stop/message. 115IOService *IOKDP::probe(IOService *provider, SInt32 *score) 116{ 117 char textBuffer[32]; 118 119 // we expect our provider is an IOKernelDebugger and that its provider is an IONetworkController. 120 // If the controller has an IONetworkInterface client (it should) we can use info in it to 121 // determine if this is the best match for a debugger. 122 IONetworkInterface *interface = 0; 123 OSObject *client; 124 IOService *controller = provider->getProvider(); 125 126// IOLog("_kdp_ probing...\n"); 127 if (controller) 128 { 129 OSIterator *clients = controller->getClientIterator(); 130 //try to find a network interface on the provider 131 while ((client = clients->getNextObject())) 132 { 133 if ((interface = OSDynamicCast(IONetworkInterface, client))) 134 break; 135 } 136 clients->release(); 137 138 } 139 140 do 141 { 142 if(PE_parse_boot_argn( kMatchNameArg, textBuffer, sizeof(textBuffer))) 143 { 144 if(!interface) //user wants name match but we're not on a controller with an interface 145 { 146 //IOLog("_kdp_ no interface\n"); 147 return 0; 148 } 149 OSString *bsdname = OSDynamicCast(OSString, interface->getProperty(kIOBSDNameKey)); 150 if(!bsdname) 151 { 152 //IOLog("_kdp_ no bsd property\n"); 153 return 0; 154 } 155 if(bsdname->isEqualTo(textBuffer) == false) 156 { 157 //IOLog("_kdp_ name doesn't match %s\n", textBuffer); 158 return 0; 159 } 160 break; 161 } 162 163 if(PE_parse_boot_argn( kMatchMacArg, textBuffer, sizeof(textBuffer))) 164 { 165 char ctrMac[13]; 166 if(!controller) //looking for mac match, but the debugger isn't on a controller (!?) 167 { 168 //IOLog("_kdp_ no controller\n"); 169 return 0; 170 } 171 OSData * macAddr = OSDynamicCast(OSData, controller->getProperty(kIOMACAddress)); 172 if ( (macAddr == 0) || (macAddr->getLength() != 6) ) 173 { 174 //IOLog("_kdp_ bad mac\n"); 175 return 0; 176 } 177 178 //make sure command line mac is in upper case 179 for(int i=0; i<12; i++) 180 textBuffer[i] = textBuffer[i] >= 'a' && textBuffer[i] <= 'z' ? textBuffer[i] - 32 : textBuffer[i]; 181 182 // now convert the controller mac property to a string 183 unsigned char *macData = (unsigned char *)macAddr->getBytesNoCopy(); 184 snprintf(ctrMac, sizeof(ctrMac), "%02X%02X%02X%02X%02X%02X", macData[0], macData[1], macData[2], macData[3], macData[4], macData[5]); 185 186 //now see if they match... 187 if(strncmp(ctrMac, textBuffer, 12)) 188 { 189 //IOLog("_kdp_ mac doesn't match %s\n", textBuffer); 190 return 0; 191 } 192 break; 193 } 194 195 //else default to old plist metric: the IOKernelDebugger has IOPrimaryDebugPort property 196 OSBoolean *pdp = OSDynamicCast(OSBoolean, provider->getProperty(kIOPrimaryDebugPortKey)); 197 if(!pdp || pdp->isFalse()) 198 { 199 //IOLog("_kdp_ not primary debug port\n"); 200 return 0; 201 } 202 break; 203 }while(false); 204 205 //IOLog("_kdp_ MATCHED!\n"); 206 207 //make sure the super is ok with this. 208 IOService *ret = super::probe(provider, score); 209 return ret; 210} 211 212bool IOKDP::start( IOService * provider ) 213{ 214 bool ret = false; 215 216 if ( super::start(provider) == false ) 217 return false; 218 219 if ( gIOKDPGlobals.isValid() == false ) 220 return false; 221 222 IOLockLock( gIOKDPLock ); 223 224 do { 225 if ( gIOKDP ) 226 break; 227 228 if ( provider->open(this) == false ) 229 break; 230 231 gIOKDP = this; 232 ret = true; 233 } 234 while ( false ); 235 236 IOLockUnlock( gIOKDPLock ); 237 238 if ( ret ) registerService(); 239 240 return ret; 241} 242 243void IOKDP::stop( IOService * provider ) 244{ 245 provider->close(this); 246 247 IOLockLock( gIOKDPLock ); 248 249 if ( gIOKDP == this ) gIOKDP = 0; 250 251 IOLockUnlock( gIOKDPLock ); 252 253 super::stop(provider); 254} 255 256IOReturn IOKDP::message( UInt32 type, 257 IOService * provider, 258 void * argument ) 259{ 260 if ( type == kIOMessageServiceIsTerminated ) 261 { 262 provider->close(this); 263 } 264 return kIOReturnSuccess; 265} 266 267 268//--------------------------------------------------------------------------- 269// IOKernelDebugger 270 271extern "C" { 272// 273// Defined in osfmk/kdp/kdp_en_debugger.h, but the header file is not 274// exported, thus the definition is replicated here. 275// 276typedef void (*kdp_send_t)( void * pkt, UInt pkt_len ); 277typedef void (*kdp_receive_t)( void * pkt, UInt * pkt_len, UInt timeout ); 278typedef UInt32 (*kdp_link_t)(void); 279typedef boolean_t (*kdp_mode_t)(boolean_t active); 280void kdp_register_send_receive( kdp_send_t send, kdp_receive_t receive ); 281void kdp_unregister_send_receive( kdp_send_t send, kdp_receive_t receive ); 282void kdp_register_link( kdp_link_t link, kdp_mode_t mode ); 283void kdp_unregister_link( kdp_link_t link, kdp_mode_t mode ); 284void kdp_set_interface(void *, const void *); 285} 286 287#undef super 288#define super IOService 289OSDefineMetaClassAndStructors( IOKernelDebugger, IOService ) 290OSMetaClassDefineReservedUnused( IOKernelDebugger, 0 ); 291OSMetaClassDefineReservedUnused( IOKernelDebugger, 1 ); 292OSMetaClassDefineReservedUnused( IOKernelDebugger, 2 ); 293OSMetaClassDefineReservedUnused( IOKernelDebugger, 3 ); 294 295// IOKernelDebugger global variables. 296// 297IOService * gIODebuggerDevice = 0; 298IODebuggerTxHandler gIODebuggerTxHandler = 0; 299IODebuggerRxHandler gIODebuggerRxHandler = 0; 300IODebuggerLinkStatusHandler gIODebuggerLinkStatusHandler = 0; 301IODebuggerSetModeHandler gIODebuggerSetModeHandler = 0; 302UInt32 gIODebuggerTxBytes = 0; 303UInt32 gIODebuggerRxBytes = 0; 304SInt32 gIODebuggerSemaphore = 0; 305UInt32 gIODebuggerFlag = 0; 306UInt8 gIODebuggerSignalled = 0; 307 308// Global debugger flags. 309// 310enum { 311 kIODebuggerFlagRegistered = 0x01, 312 kIODebuggerFlagWarnNullHandler = 0x02 313}; 314 315// Expansion variables. 316// 317#define _state _reserved->stateVars[0] 318#define _activationChangeThreadCall _reserved->activationChangeThreadCall 319#define _interfaceNotifier _reserved->interfaceNotifier 320#define _linkStatusHandler _reserved->linkStatusHandler 321#define _setModeHandler _reserved->setModeHandler 322#define EARLY_DEBUG_SUPPORT (gDebugBootArg != 0) 323 324static void handleActivationChange( IOKernelDebugger * debugger, 325 void * change ); 326 327bool IOKernelDebugger::interfacePublished( 328 void * target, void *param, IOService * service, IONotifier * notifier ) 329{ 330 IOService *debugger = (IOService *)target; 331 IONetworkInterface *interface = OSDynamicCast(IONetworkInterface, service); 332 333 //IOLog("new (or changes on) interface detected\n"); 334 //only reregister ourselves if the interface has the same controller (provider) as we do. 335 if(debugger && service && debugger->getProvider() == service->getProvider()) 336 { 337 //IOLog("it's on our controller- reregister\n"); 338 debugger->registerService(); 339 if (interface) 340 interface->debuggerRegistered(); 341 } 342 return true; 343} 344 345//--------------------------------------------------------------------------- 346// The KDP receive dispatch function. Dispatches KDP receive requests to the 347// registered receive handler. This function is registered with KDP via 348// kdp_register_send_receive(). 349 350void IOKernelDebugger::kdpReceiveDispatcher( void * buffer, 351 UInt32 * length, 352 UInt32 timeout ) 353{ 354 *length = 0; // return a zero length field by default. 355 356 if ( gIODebuggerSemaphore ) return; // FIXME - Driver is busy! 357 358 (*gIODebuggerRxHandler)( gIODebuggerDevice, buffer, length, timeout ); 359 360 gIODebuggerRxBytes += *length; 361} 362 363//--------------------------------------------------------------------------- 364// The KDP transmit dispatch function. Dispatches KDP transmit requests to the 365// registered transmit handler. This function is registered with KDP via 366// kdp_register_send_receive(). 367 368void IOKernelDebugger::kdpTransmitDispatcher( void * buffer, UInt32 length ) 369{ 370 if ( gIODebuggerSemaphore ) return; // FIXME - Driver is busy! 371 372 (*gIODebuggerTxHandler)( gIODebuggerDevice, buffer, length ); 373 374 gIODebuggerTxBytes += length; 375} 376 377//--------------------------------------------------------------------------- 378// The KDP link up dispatch function. Dispatches KDP link up queries to the 379// registered link up handler. This function is registered with KDP via 380// kdp_register_link(). 381 382UInt32 IOKernelDebugger::kdpLinkStatusDispatcher( void ) 383{ 384 if ( gIODebuggerSemaphore ) 385 return 0; // FIXME - Driver is busy! 386 387 return (*gIODebuggerLinkStatusHandler)( gIODebuggerDevice); 388} 389 390 391//--------------------------------------------------------------------------- 392// The KDP set mode dispatch function. Dispatches KDP set mode commands to the 393// registered setMode handler. This function is registered with KDP via 394// kdp_register_link(). 395 396boolean_t IOKernelDebugger::kdpSetModeDispatcher(boolean_t active) 397{ 398 if ( gIODebuggerSemaphore ) 399 return FALSE; // FIXME - Driver is busy! 400 401 if ((*gIODebuggerSetModeHandler)( gIODebuggerDevice, active == TRUE ? true : false) == true) 402 return TRUE; 403 404 return FALSE; 405} 406 407 408//--------------------------------------------------------------------------- 409// Null debugger handlers. 410 411void IOKernelDebugger::nullTxHandler( IOService * target, 412 void * buffer, 413 UInt32 length ) 414{ 415} 416 417void IOKernelDebugger::nullRxHandler( IOService * target, 418 void * buffer, 419 UInt32 * length, 420 UInt32 timeout ) 421{ 422 if ( gIODebuggerFlag & kIODebuggerFlagWarnNullHandler ) 423 { 424 IOLog("IOKernelDebugger::%s no debugger device\n", __FUNCTION__); 425 gIODebuggerFlag &= ~kIODebuggerFlagWarnNullHandler; 426 } 427} 428 429UInt32 IOKernelDebugger::nullLinkStatusHandler(__unused IOService * target) 430{ 431 return kIONetworkLinkValid | kIONetworkLinkActive; /* default is link up. */ 432} 433 434bool IOKernelDebugger::nullSetModeHandler(__unused IOService * target, 435 __unused bool active) 436{ 437 return true; 438} 439 440 441 442//--------------------------------------------------------------------------- 443// Take the debugger lock conditionally. 444 445IODebuggerLockState IOKernelDebugger::lock( IOService * object ) 446{ 447 if ( gIODebuggerDevice == object ) 448 { 449 OSIncrementAtomic( &gIODebuggerSemaphore ); 450 return kIODebuggerLockTaken; 451 } 452 return (IODebuggerLockState) 0; 453} 454 455inline static void invokeDebugger(void) 456{ 457 if ( gIODebuggerSemaphore ) 458 return; 459 460 if (OSTestAndClear(0, &gIODebuggerSignalled) == false) { 461 Debugger("remote NMI"); 462 } 463} 464 465//--------------------------------------------------------------------------- 466// Release the debugger lock if the kIODebuggerLockTaken flag is set. 467 468void IOKernelDebugger::unlock( IODebuggerLockState state ) 469{ 470 if ( state & kIODebuggerLockTaken ) { 471 OSDecrementAtomic( &gIODebuggerSemaphore ); 472 473 invokeDebugger(); 474 } 475} 476 477//--------------------------------------------------------------------------- 478// drop into the Debugger when safe 479void IOKernelDebugger::signalDebugger(void) 480{ 481 OSTestAndSet(0, &gIODebuggerSignalled); 482 invokeDebugger(); 483} 484 485//--------------------------------------------------------------------------- 486// Initialize an IOKernelDebugger instance. 487 488bool IOKernelDebugger::init( IOService * target, 489 IODebuggerTxHandler txHandler, 490 IODebuggerRxHandler rxHandler, 491 IODebuggerLinkStatusHandler linkStatusHandler, 492 IODebuggerSetModeHandler setModeHandler) 493{ 494 if ( ( super::init() == false ) || 495 ( OSDynamicCast(IOService, target) == 0 ) || 496 ( txHandler == 0 ) || 497 ( rxHandler == 0 ) ) 498 { 499 return false; 500 } 501 502 // Allocate memory for the ExpansionData structure. 503 504 _reserved = IONew( ExpansionData, 1 ); 505 if ( _reserved == 0 ) 506 { 507 return false; 508 } 509 510 _activationChangeThreadCall = thread_call_allocate( 511 (thread_call_func_t) handleActivationChange, 512 (thread_call_param_t) this ); 513 514 // if user wants bsd name matching, odds are good that the interface won't 515 // have been named at the time IOKDP is matching on us...fortunately IONetworkStack 516 // reregisters the interface service when it gets named, so we can add a notifier 517 // and reregister ourselves at that time in order to try matching IOKDP again. 518 char textBuffer[64]; 519 if (PE_parse_boot_argn( kMatchNameArg, textBuffer, sizeof(textBuffer))) 520 { 521 OSDictionary * matching = serviceMatching(kIONetworkInterfaceClass); 522 if (matching) 523 { 524 _interfaceNotifier = addMatchingNotification( 525 /* type */ gIOPublishNotification, 526 /* match */ matching, 527 /* action */ interfacePublished, 528 /* param */ this ); 529 matching->release(); 530 } 531 } 532 else _interfaceNotifier = 0; 533 534 if ( !_activationChangeThreadCall ) 535 { 536 return false; 537 } 538 539 // Cache the target and handlers provided. 540 541 _target = target; 542 _txHandler = txHandler; 543 _rxHandler = rxHandler; 544 _linkStatusHandler = linkStatusHandler; 545 _setModeHandler = setModeHandler; 546 _state = 0; 547 548 return true; 549} 550 551//--------------------------------------------------------------------------- 552// Factory method which performs allocation and initialization of an 553// IOKernelDebugger instance. 554 555IOKernelDebugger * IOKernelDebugger::debugger( IOService * target, 556 IODebuggerTxHandler txHandler, 557 IODebuggerRxHandler rxHandler, 558 IODebuggerLinkStatusHandler linkStatusHandler, 559 IODebuggerSetModeHandler setModeHandler) 560{ 561 IOKernelDebugger * debugger = new IOKernelDebugger; 562 563 if (debugger && (debugger->init( target, txHandler, rxHandler, linkStatusHandler, setModeHandler ) == false)) 564 { 565 debugger->release(); 566 return 0; 567 } 568 569 // determine if this debugger is the "primary" debugger- the one KDP will attach to unless told otherwise 570 IOService * device = target->getProvider(); //get info from our provider's provider 571 //the debugger is primary if... 572 if ( device && device->getProperty( "built-in" )) // ...it is a built in controller... 573 { 574 OSObject *locationProperty = device->copyProperty("location"); 575 OSData *locationAsData = OSDynamicCast(OSData, locationProperty); 576 if(!locationAsData || // ...AND we don't know anything else about its location..... 577 (strcmp( (char *)locationAsData->getBytesNoCopy(), "1")== 0) ) // ...OR we do know its location and it is 'slot' 1 578 debugger->setProperty( kIOPrimaryDebugPortKey, true ); 579 else 580 debugger->setProperty( kIOPrimaryDebugPortKey, false ); 581 if(locationProperty) 582 locationProperty->release(); 583 } 584 return debugger; 585} 586 587//--------------------------------------------------------------------------- 588// Register the debugger handlers. 589 590void IOKernelDebugger::registerHandler( IOService * target, 591 IODebuggerTxHandler txHandler, 592 IODebuggerRxHandler rxHandler, 593 IODebuggerLinkStatusHandler linkStatusHandler, 594 IODebuggerSetModeHandler setModeHandler) 595{ 596 bool doRegister; 597 598 assert( ( target == gIODebuggerDevice ) || 599 ( target == 0 ) || 600 ( gIODebuggerDevice == 0 ) ); 601 602 doRegister = ( target && ( txHandler != 0 ) && ( rxHandler != 0 ) ); 603 604 if ( !doRegister && ( gIODebuggerFlag & kIODebuggerFlagRegistered ) ) 605 { 606 // Unregister the polling functions from KDP. 607 kdp_unregister_send_receive( (kdp_send_t) kdpTransmitDispatcher, 608 (kdp_receive_t) kdpReceiveDispatcher); 609 kdp_unregister_link( (kdp_link_t) kdpLinkStatusDispatcher, (kdp_mode_t) kdpSetModeDispatcher); 610 611 gIODebuggerFlag &= ~kIODebuggerFlagRegistered; 612 } 613 614 if ( txHandler == 0 ) txHandler = &IOKernelDebugger::nullTxHandler; 615 if ( rxHandler == 0 ) rxHandler = &IOKernelDebugger::nullRxHandler; 616 if ( linkStatusHandler == 0 ) linkStatusHandler = &IOKernelDebugger::nullLinkStatusHandler; 617 if ( setModeHandler == 0 ) setModeHandler = &IOKernelDebugger::nullSetModeHandler; 618 619 OSIncrementAtomic( &gIODebuggerSemaphore ); 620 621 gIODebuggerDevice = target; 622 gIODebuggerTxHandler = txHandler; 623 gIODebuggerRxHandler = rxHandler; 624 gIODebuggerLinkStatusHandler = linkStatusHandler; 625 gIODebuggerSetModeHandler = setModeHandler; 626 gIODebuggerFlag |= kIODebuggerFlagWarnNullHandler; 627 628 OSDecrementAtomic( &gIODebuggerSemaphore ); 629 630 if ( doRegister && (( gIODebuggerFlag & kIODebuggerFlagRegistered ) == 0) ) 631 { 632 // if we're on a controller that has an interfacet(we should be), we can register 633 // the IONetworkInterface * as an identifier so that the bsd portion 634 // knows when to assign an ip to kdp 635 IONetworkInterface *interface = 0; 636 OSIterator *clients = target->getClientIterator(); 637 //try to find a network interface on the target 638 while (OSObject *client = clients->getNextObject()) 639 { 640 if ((interface = OSDynamicCast(IONetworkInterface, client))) 641 break; 642 } 643 clients->release(); 644 645 if (interface) { 646 OSData *mac = OSDynamicCast(OSData, 647 interface->getController()->getProperty(kIOMACAddress)); 648 649 kdp_set_interface(interface, mac ? mac->getBytesNoCopy() : NULL); 650 interface->debuggerRegistered(); 651 } 652 653 // Register dispatch function, these in turn will call the 654 // handlers when the debugger is active. 655 // 656 // Note: The following call may trigger an immediate break 657 // to the debugger. 658 kdp_register_link((kdp_link_t) kdpLinkStatusDispatcher, (kdp_mode_t) kdpSetModeDispatcher); 659 kdp_register_send_receive( (kdp_send_t) kdpTransmitDispatcher, 660 (kdp_receive_t) kdpReceiveDispatcher); 661 662 // Limit ourself to a single real KDP registration. 663 664 gIODebuggerFlag |= kIODebuggerFlagRegistered; 665 666 publishResource("kdp"); 667 } 668} 669 670//--------------------------------------------------------------------------- 671// enableTarget / disableTarget 672 673enum { 674 kEventClientOpen = 0x0001, 675 kEventTargetUsable = 0x0002, 676 kEventDebuggerActive = 0x0004, 677 kTargetIsEnabled = 0x0100, 678 kTargetWasEnabled = 0x0200, 679}; 680 681static void enableTarget( IOKernelDebugger * self, 682 IOService * target, 683 UInt32 * state, 684 UInt32 event ) 685{ 686 IONetworkController * ctr = OSDynamicCast( IONetworkController, target ); 687 688 #define kReadyMask ( kEventClientOpen | \ 689 kEventTargetUsable | \ 690 kEventDebuggerActive ) 691 692 *state |= event; 693 *state &= ~kTargetWasEnabled; 694 695 if ( ( *state & kReadyMask ) == kReadyMask ) 696 { 697 if ( !ctr || ( *state & kTargetIsEnabled ) || 698 ctr->doEnable( self ) == kIOReturnSuccess ) 699 { 700 if ( ( *state & kTargetIsEnabled ) == 0 ) 701 *state |= kTargetWasEnabled; 702 *state |= kTargetIsEnabled; 703 } 704 } 705} 706 707static void disableTarget( IOKernelDebugger * self, 708 IOService * target, 709 UInt32 * state, 710 UInt32 event ) 711{ 712 IONetworkController * ctr = OSDynamicCast( IONetworkController, target ); 713 UInt32 on = *state & kTargetIsEnabled; 714 715 *state &= ~( event | kTargetIsEnabled | kTargetWasEnabled ); 716 717 if ( ctr && on ) ctr->doDisable( self ); 718} 719 720//--------------------------------------------------------------------------- 721// Called by open() with the arbitration lock held. 722 723bool IOKernelDebugger::handleOpen( IOService * forClient, 724 IOOptionBits options, 725 void * arg ) 726{ 727 bool ret = false; 728 729 do { 730 // Only a single client at a time. 731 732 if ( _client || !_target ) break; 733 734 // Register the target to prime the lock()/unlock() functionality 735 // before opening the target. 736 737 registerHandler( _target ); 738 739 // While the target is opened/enabled, it must block any thread 740 // which may acquire the debugger lock in its execution path. 741 742 if ( _target->open( this ) == false ) 743 break; 744 745 // For early debugging, the debugger must become active and enable 746 // the controller as early as possible. Otherwise, the debugger is 747 // not activated until the controller is enabled by BSD. 748 749 if ( EARLY_DEBUG_SUPPORT ) 750 _state |= kEventDebuggerActive; 751 752 // Register interest in receiving notifications about controller 753 // power state changes. The controller is usable if it is power 754 // managed, and is in an usable state, or if the controller is 755 // not power managed. 756 757 if ( _target->registerInterestedDriver(this) & 758 ( kIOPMDeviceUsable | kIOPMNotPowerManaged ) ) 759 _state |= kEventTargetUsable; 760 761 // Enable the target if possible. 762 763 enableTarget( this, _target, &_state, kEventClientOpen ); 764 if ( _state & kTargetWasEnabled ) 765 { 766 // If the target was enabled, complete the registration. 767 IOLog("%s: registering debugger\n", getName()); 768 registerHandler( _target, _txHandler, _rxHandler, _linkStatusHandler, _setModeHandler ); 769 } 770 771 // Remember the client. 772 773 _client = forClient; 774 775 ret = true; 776 } 777 while (0); 778 779 if ( ret == false ) 780 { 781 registerHandler( 0 ); 782 _target->close( this ); 783 } 784 785 return ret; 786} 787 788//--------------------------------------------------------------------------- 789// Called by IOService::close() with the arbitration lock held. 790 791void IOKernelDebugger::handleClose( IOService * forClient, 792 IOOptionBits options ) 793{ 794 if ( _target && _client && ( _client == forClient ) ) 795 { 796 // There is no KDP un-registration. The best we can do is to 797 // register dummy handlers. 798 799 registerHandler( 0 ); 800 801 disableTarget( this, _target, &_state, kEventClientOpen ); 802 803 // Before closing the controller, remove interest in receiving 804 // notifications about controller power state changes. 805 806 _target->deRegisterInterestedDriver( this ); 807 808 _client = 0; 809 810 _target->close( this ); 811 } 812} 813 814//--------------------------------------------------------------------------- 815// Called by IOService::isOpen() with the arbitration lock held. 816 817bool IOKernelDebugger::handleIsOpen( const IOService * forClient ) const 818{ 819 if ( forClient == 0 ) 820 return ( forClient != _client ); 821 else 822 return ( forClient == _client ); 823} 824 825//--------------------------------------------------------------------------- 826// Free the IOKernelDebugger object. 827 828void IOKernelDebugger::free() 829{ 830 if ( _reserved ) 831 { 832 if ( _activationChangeThreadCall ) 833 thread_call_free( _activationChangeThreadCall ); 834 835 if ( _interfaceNotifier ) 836 _interfaceNotifier->remove(); 837 838 IODelete( _reserved, ExpansionData, 1 ); 839 _reserved = 0; 840 } 841 842 super::free(); 843} 844 845//--------------------------------------------------------------------------- 846// Handle controller's power state change notitifications. 847 848IOReturn 849IOKernelDebugger::powerStateWillChangeTo( IOPMPowerFlags flags, 850 unsigned long stateNumber, 851 IOService * policyMaker ) 852{ 853 if ((flags & IOPMDeviceUsable) == 0) 854 { 855 // Controller is about to transition to an un-usable state. 856 // The debugger nub should be disabled. 857 858 lockForArbitration(); 859 860 // Keep an open on the controller, but inhibit access to the 861 // controller's debugger handlers, and disable controller's 862 // hardware support for the debugger. 863 864 if ( _client ) registerHandler( 0 ); 865 disableTarget( this, _target, &_state, kEventTargetUsable ); 866 867 unlockForArbitration(); 868 } 869 870 return IOPMAckImplied; 871} 872 873IOReturn 874IOKernelDebugger::powerStateDidChangeTo( IOPMPowerFlags flags, 875 unsigned long stateNumber, 876 IOService * policyMaker ) 877{ 878 if ( flags & IOPMDeviceUsable ) 879 { 880 // Controller has transitioned to an usable state. 881 // The debugger nub should be enabled if necessary. 882 883 lockForArbitration(); 884 885 enableTarget( this, _target, &_state, kEventTargetUsable ); 886 if ( _state & kTargetWasEnabled ) 887 registerHandler( _target, _txHandler, _rxHandler, _linkStatusHandler, _setModeHandler ); 888 889 unlockForArbitration(); 890 } 891 892 return IOPMAckImplied; 893} 894 895//--------------------------------------------------------------------------- 896// handleActivationChange 897 898static void 899handleActivationChange( IOKernelDebugger * debugger, void * change ) 900{ 901 debugger->message( kMessageDebuggerActivationChange, 0, change ); 902 debugger->release(); 903} 904 905//--------------------------------------------------------------------------- 906// message() 907 908IOReturn IOKernelDebugger::message( UInt32 type, IOService * provider, 909 void * argument ) 910{ 911 IOReturn ret = kIOReturnSuccess; 912 913 switch ( type ) 914 { 915 case kMessageControllerWasEnabledForBSD: 916 case kMessageControllerWasDisabledForBSD: 917 // For early debugging support, these messages are ignored. 918 // The debugger will enable the controller independently 919 // from BSD. 920 921 if ( EARLY_DEBUG_SUPPORT ) break; 922 923 // Process this change in another thread to avoid deadlocks 924 // between the controller's work loop, and our arbitration 925 // lock. 926 927 retain(); 928 if ( thread_call_enter1( _activationChangeThreadCall, 929 (void *)(uintptr_t) type ) == TRUE ) 930 release(); 931 932 break; 933 934 case kMessageControllerWillShutdown: 935 // Disable controller before system shutdown and restart. 936 // Intentional fall-through to next case. 937 938 case kMessageDebuggerActivationChange: 939 lockForArbitration(); 940 941 // If controller was enabled, activate the debugger. 942 // Otherwise make the debugger inactive. 943 944 if ( (void *) kMessageControllerWasEnabledForBSD == argument ) 945 { 946 enableTarget( this, _target, &_state, kEventDebuggerActive ); 947 if ( _state & kTargetWasEnabled ) 948 registerHandler( _target, _txHandler, _rxHandler, _linkStatusHandler, _setModeHandler ); 949 } 950 else 951 { 952 if ( _client ) registerHandler( 0 ); 953 disableTarget( this, _target, &_state, kEventDebuggerActive ); 954 } 955 956 unlockForArbitration(); 957 break; 958 959 default: 960 ret = super::message( type, provider, argument ); 961 } 962 963 return ret; 964} 965