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#ifndef _IOKERNELDEBUGGER_H
24#define _IOKERNELDEBUGGER_H
25
26#include <IOKit/IOService.h>
27
28/*! @typedef IODebuggerRxHandler
29    @discussion Defines the receive handler that must be implemented
30    by the target to service KDP receive requests. This handler is called
31    by kdpReceiveDispatcher().
32    @param target The target object.
33    @param buffer KDP receive buffer. The buffer allocated has room for
34           1518 bytes. The receive handler must not overflow this buffer.
35    @param length The amount of data received and placed into the buffer.
36           Set to 0 if no frame was received during the poll interval.
37    @param timeout The amount of time to poll in milliseconds while waiting
38           for a frame to arrive. */
39
40typedef void (*IODebuggerRxHandler)( IOService * target,
41                                     void *      buffer,
42                                     UInt32 *    length,
43                                     UInt32      timeout );
44
45/*! @typedef IODebuggerTxHandler
46    @discussion Defines the transmit handler that must be implemented
47    by the target to service KDP transmit requests. This handler is called
48    by kdpTransmitDispatcher().
49    @param target The target object.
50    @param buffer KDP transmit buffer. This buffer contains a KDP frame
51           to be sent on the network.
52    @param length The number of bytes in the transmit buffer. */
53
54typedef void (*IODebuggerTxHandler)( IOService * target,
55                                     void *      buffer,
56                                     UInt32      length );
57
58/*! @typedef IODebuggerLinkStatusHandler
59    @discussion Defines the link up handler that must be implemented
60    by the target to service KDP link status requests. This handler is called
61    by kdpLinkStatusDispatcher().
62    @param target The target object.
63    @result Return link status.
64*/
65
66typedef UInt32 (*IODebuggerLinkStatusHandler)( IOService * target);
67
68/*! @typedef IODebuggerSetModeHandler
69    @discussion Defines the mode handler that must be implemented
70    by the target to service KDP link status requests. This handler is called
71    by kdpSetModeDispatcher().
72    @param target The target object.
73    @param active True if entering KDP and false if exiting KDP.
74    @result Return true on success and false on failure.
75*/
76
77typedef bool (*IODebuggerSetModeHandler)( IOService * target, bool active);
78
79/*! @typedef IODebuggerLockState
80    @discussion Defines flags returned by IOKernelDebugger::lock().
81    @constant kIODebuggerLockTaken Set if the debugger lock was taken. */
82
83typedef enum {
84    kIODebuggerLockTaken = 0x1
85} IODebuggerLockState;
86
87/*! @class IOKernelDebugger
88    @abstract Kernel debugger nub.
89    @discussion This object interfaces with the KDP
90    (kernel debugger protocol) module and dispatches KDP requests to its
91    target (provider). The target, designated as the debugger device, must
92    implement a pair of handler functions that are called to handle KDP
93    transmit and receive requests during a debugging session. Only a single
94    IOKernelDebugger in the system can be active at a given time. The
95    active IOKernelDebugger is the one that has an IOKDP object attached
96    as a client.
97
98    The debugger device is usually a subclass of IOEthernetController.
99    However, any IOService can service an IOKernelDebugger client,
100    implement the two polled mode handlers, and transport the KDP
101    packets through a data channel. However, KDP assumes that the
102    debugger device is an Ethernet interface and therefore it will
103    always send, and expect to receive, an Ethernet frame. */
104
105class IOKernelDebugger : public IOService
106{
107    OSDeclareDefaultStructors( IOKernelDebugger )
108
109protected:
110    IOService *             _target;      // target (provider)
111    IODebuggerTxHandler     _txHandler;   // target's transmit handler.
112    IODebuggerRxHandler     _rxHandler;   // target's receive handler.
113    IOService *             _client;      // client that has opened us.
114    bool                    _pmDisabled;  // true if disabled by PM.
115
116    struct ExpansionData {
117        thread_call_t  activationChangeThreadCall;
118        UInt32         stateVars[2];
119        IONotifier  *  interfaceNotifier;
120        IODebuggerLinkStatusHandler linkStatusHandler; // target's link status handler.
121        IODebuggerSetModeHandler setModeHandler; // target's KDP mode handler.
122    };
123
124    /*! @var reserved
125        Reserved for future use.  (Internal use only)  */
126    ExpansionData *         _reserved;
127
128/*! @function kdpReceiveDispatcher
129    @abstract The KDP receive dispatch function.
130    @discussion Field KDP receives requests, then dispatches the call to the
131    registered receiver handler.
132    @param buffer KDP receive buffer. The buffer allocated by KDP has room
133           for 1518 bytes. The receive handler must not overflow this buffer.
134    @param length The amount of data received and placed into the buffer.
135           Set to 0 if a frame was not received during the poll interval.
136    @param timeout The amount of time to poll in milliseconds while waiting
137           for a frame to arrive.
138*/
139
140    static void kdpReceiveDispatcher(void *   buffer,
141                                     UInt32 * length,
142                                     UInt32   timeout);
143
144/*! @function kdpTransmitDispatcher
145    @abstract The KDP transmit dispatch function.
146    @discussion Field KDP transmit requests, then dispatches the call to the
147    registered transmit handler.
148    @param buffer KDP transmit buffer. This buffer contains a KDP frame to
149           be sent on the network.
150    @param length The number of bytes in the transmit buffer.
151*/
152
153    static void kdpTransmitDispatcher(void * buffer, UInt32 length);
154
155/*! @function kdpLinkStatusDispatcher
156    @abstract The KDP link status dispatch function.
157    @discussion Field KDP link status requests, then dispatches the call to the
158    registered link up handler.
159    @result Return link status.
160*/
161
162    static UInt32 kdpLinkStatusDispatcher(void);
163
164
165/*! @function kdpSetModeDispatcher
166    @abstract The KDP set mode dispatch function.
167    @discussion Field KDP set mode requests, then dispatches the call to the
168    registered set mode handler.
169    @param active TRUE if entering KDP. FALSE if leaving KDP.
170    @result Return TRUE if the link is up and data can be sent/received. Otherwise,
171            return FALSE.
172*/
173
174    static boolean_t kdpSetModeDispatcher(boolean_t active);
175
176/*! @function free
177    @abstract Frees the IOKernelDebugger instance. */
178
179    virtual void free();
180
181/*! @function nullTxHandler
182    @abstract Null transmit handler.
183    @discussion This function is registered as the transmit handler when an
184    IOKernelDebugger object surrenders its status as the active debugger nub.
185    Until another IOKernelDebugger object gets promoted, this function will
186    handle polled transmit requests from KDP. This function does nothing
187    useful.
188*/
189
190    static void nullTxHandler( IOService * target,
191                               void *      buffer,
192                               UInt32      length );
193
194/*! @function nullRxHandler
195    @abstract Null receive handler.
196    @discussion This function is registered as the receive handler when an
197    IOKernelDebugger object surrenders its status as the active debugger nub.
198    Until another IOKernelDebugger object gets promoted, this function will
199    handle polled receive requests from KDP. This function does nothing
200    except to log a warning message.
201*/
202
203    static void nullRxHandler( IOService * target,
204                               void *      buffer,
205                               UInt32 *    length,
206                               UInt32      timeout );
207
208/*! @function nullLinkStatusHandler
209    @abstract Null link status handler.
210    @discussion This function is registered as the link status handler when an
211    IOKernelDebugger object surrenders its status as the active debugger nub.
212    Until another IOKernelDebugger object gets promoted, this function will
213    handle polled link status requests from KDP.
214    @result This function will always report link up.
215*/
216
217    static UInt32 nullLinkStatusHandler( IOService * target);
218
219/*! @function nullSetModeHandler
220    @abstract Null set mode handler.
221    @discussion This function is registered as the set mode handler when an
222    IOKernelDebugger object surrenders its status as the active debugger nub.
223    Until another IOKernelDebugger object gets promoted, this function will
224    handle set mode requests from KDP.
225    @result This function will always return true.
226*/
227
228    static bool nullSetModeHandler( IOService * target, bool active);
229
230/*! @function registerHandler
231    @abstract Registers the target and the handler functions.
232    @discussion This method is called by handleOpen() and handleClose()
233    to register or unregister the target and its handler functions.
234    @param target The target object.
235    @param txHandler The transmit handler function. The null handler is
236    registered if the argument is zero.
237    @param rxHandler The receive handler function. The null handler is
238    @param linkUpHandler The linkup handler function. The null handler is
239    registered if the argument is zero.
240*/
241
242    static void registerHandler( IOService *                 target,
243                                 IODebuggerTxHandler         txHandler = 0,
244                                 IODebuggerRxHandler         rxHandler = 0,
245                                 IODebuggerLinkStatusHandler linkUpHandler = 0,
246                                 IODebuggerSetModeHandler    setModeHandler = 0);
247
248/*! @function powerStateWillChangeTo
249    @abstract Handles notification that the network controller will change
250    power state.
251    @discussion If the controller is about to become unusable, then the
252    controller's handlers are unregistered, and the controller is disabled.
253    @param flags Describe the capability of the controller in the new power
254           state.
255    @param stateNumber The number of the state in the state array that the
256           controller is switching to.
257    @param policyMaker The policy maker that manages the controller's
258           power state.
259    @result Returns the constant 3000000, to indicate a maximum of 3 seconds for the
260            preparation to complete, and an acknowledgement delivered to the
261            policy maker.
262*/
263
264    virtual IOReturn powerStateWillChangeTo( IOPMPowerFlags  flags,
265                                             unsigned long   stateNumber,
266                                             IOService *     policyMaker );
267
268/*! @function powerStateDidChangeTo
269    @abstract Handles notification that the network controller did change
270    power state.
271    @discussion If the controller became usable, then the controller is
272    re-enabled, and the controller's handlers are re-registered.
273    @param flags Description of the capability of the controller in the new power
274           state.
275    @param stateNumber The number of the state in the state array that the
276           controller is switching to.
277    @param policyMaker The policy maker that manages the controller's
278           power state.
279    @result Returns the constant 3000000, to indicate a maximum of 3 seconds for the
280            preparation to complete, and an acknowledgement delivered to the
281            policy maker.
282*/
283
284    virtual IOReturn powerStateDidChangeTo( IOPMPowerFlags  flags,
285                                            unsigned long   stateNumber,
286                                            IOService *     policyMaker );
287
288/*! @function handleOpen
289    @abstract Handles a client open.
290    @discussion This method is called by IOService::open() to handle an
291    open from a client (IOKDP) with the arbitration lock held.
292    @param forClient The client (IOKDP) requesting the open.
293    @param options Options passed to the open() call. Not used.
294    @param arg A family defined argument passed to the open() call. Not used.
295    @result Returns true on success, false otherwise.
296*/
297
298    virtual bool handleOpen( IOService *    forClient,
299                             IOOptionBits   options,
300                             void *         arg );
301
302/*! @function handleClose
303    @abstract Handles a client close.
304    @discussion This method is called by IOService::close() to handle a
305    close from a client with the arbitration lock held.
306    @param forClient The client (IOKDP) requesting the close.
307    @param options Options passed to the close() call. Not used.
308*/
309
310    virtual void handleClose( IOService *   forClient,
311                              IOOptionBits  options );
312
313/*! @function handleIsOpen
314    @abstract Queries whether a client has an open on this object.
315    @discussion This method is called by IOService::isOpen() with the
316    arbitration lock held.
317    @result Returns true if the specified client, or any client if none (0) is
318    specified, presently has an open on this object.
319*/
320
321    virtual bool handleIsOpen( const IOService * forClient ) const;
322
323	static bool interfacePublished(
324        void *target, void *param, IOService *service, IONotifier *notifier );
325
326public:
327
328/*! @function lock
329    @abstract Takes the debugger lock conditionally.
330    @discussion This method takes the debugger lock if the object given matches the
331    target registered by registerHandler().
332    @param target The target or provider of an IOKernelDebugger object.
333    @result Returns kIODebuggerLockTaken if the lock was taken, or 0 otherwise.
334*/
335
336    static IODebuggerLockState lock( IOService * target );
337
338/*! @function unlock
339    @abstract Releases the debugger lock.
340    @discussion This method releases the debugger lock if the kIODebuggerLockTaken flag is
341    set in the argument.
342*/
343
344    static void unlock( IODebuggerLockState state );
345
346/*! @function init
347    @abstract Initializes an IOKernelDebugger instance.
348    @param target The target object that implements the debugger handlers.
349    @param txHandler The target's transmit handler. A pointer to a 'C' function.
350    @param rxHandler The target's receive handler. A pointer to a 'C' function.
351    @param linkStatusHandler The target's link status handler. A pointer to a 'C' function.
352    @param setModeHandler The target's set mode handler. A pointer to a 'C' function.
353    @result Returns true if the instance initialized successfully, false otherwise.
354*/
355
356    virtual bool init( IOService *                 target,
357                       IODebuggerTxHandler         txHandler,
358                       IODebuggerRxHandler         rxHandler,
359                       IODebuggerLinkStatusHandler linkUpHandler,
360                       IODebuggerSetModeHandler    setModeHandler);
361
362/*! @function debugger
363    @abstract Factory method that performs allocation and initialization
364    of an IOKernelDebugger object.
365    @param target The target object that implements the debugger handlers.
366    @param txHandler The target's transmit handler. A pointer to a 'C' function.
367    @param rxHandler The target's receive handler. A pointer to a 'C' function.
368    @param linkStatusHandler The target's link status handler. A pointer to a 'C' function.
369    @param setModeHandler The target's set mode handler. A pointer to a 'C' function.
370    @result Returns an IOKernelDebugger instance on success, 0 otherwise.
371*/
372
373    static IOKernelDebugger * debugger( IOService *                 target,
374                                        IODebuggerTxHandler         txHandler,
375                                        IODebuggerRxHandler         rxHandler,
376                                        IODebuggerLinkStatusHandler linkStatusHandler,
377                                        IODebuggerSetModeHandler    setModeHandler);
378
379    /*
380     * Entry point for generic messages delivered from the provider.
381     */
382
383    virtual IOReturn message( UInt32 type, IOService * provider, void * arg );
384
385/*! @function signalDebugger
386    @abstract Signal the kernel to enter the debugger when safe.
387*/
388    static void signalDebugger(void);
389
390    // Virtual function padding
391    OSMetaClassDeclareReservedUnused( IOKernelDebugger,  0);
392    OSMetaClassDeclareReservedUnused( IOKernelDebugger,  1);
393    OSMetaClassDeclareReservedUnused( IOKernelDebugger,  2);
394    OSMetaClassDeclareReservedUnused( IOKernelDebugger,  3);
395};
396
397// Concise form of the lock()/unlock() static member functions.
398//
399#define IODebuggerLock    IOKernelDebugger::lock
400#define IODebuggerUnlock  IOKernelDebugger::unlock
401
402#endif /* !_IOKERNELDEBUGGER_H */
403