2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/kd/kdio.c
5 * PURPOSE: NT Kernel Debugger Input/Output Functions
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
10 /* INCLUDES ******************************************************************/
13 #include <internal/debug.h>
15 /* GLOBALS *******************************************************************/
17 #define BufferSize 32*1024
19 HANDLE KdbLogFileHandle
;
20 BOOLEAN KdpLogInitialized
;
21 CHAR DebugBuffer
[BufferSize
];
22 ULONG CurrentPosition
;
23 WORK_QUEUE_ITEM KdpDebugLogQueue
;
25 KD_PORT_INFORMATION SerialPortInfo
= {DEFAULT_DEBUG_PORT
, DEFAULT_DEBUG_BAUD_RATE
, 0};
27 /* Current Port in use. FIXME: Do we support more then one? */
30 /* DEBUG LOG FUNCTIONS *******************************************************/
34 KdpPrintToLogInternal(PVOID Context
)
38 /* Write to the Debug Log */
39 NtWriteFile(KdbLogFileHandle
,
49 /* Clear the Current Position */
52 /* A new item can be queued now */
58 KdpPrintToLog(PCH String
,
62 if ((CurrentPosition
+ StringLength
) > BufferSize
) return;
64 /* Add the string to the buffer */
65 RtlMoveMemory(&DebugBuffer
[CurrentPosition
], String
, StringLength
);
67 /* Update the Current Position */
68 CurrentPosition
+= StringLength
;
70 /* Make sure we are initialized and can queue */
71 if (!KdpLogInitialized
|| (ItemQueued
)) return;
75 * Note that we don't want to queue if we are > DISPATCH_LEVEL...
76 * The message is in the buffer and will simply be taken care of at
77 * the next time we are at <= DISPATCH, so it won't be lost.
79 if (KeGetCurrentIrql() <= DISPATCH_LEVEL
)
81 ExQueueWorkItem(&KdpDebugLogQueue
, HyperCriticalWorkQueue
);
88 KdpInitDebugLog(PKD_DISPATCH_TABLE DispatchTable
,
92 OBJECT_ATTRIBUTES ObjectAttributes
;
93 UNICODE_STRING FileName
;
96 if (!KdpDebugMode
.File
) return;
100 /* Write out the functions that we support for now */
101 DispatchTable
->KdpInitRoutine
= KdpInitDebugLog
;
102 DispatchTable
->KdpPrintRoutine
= KdpPrintToLog
;
104 /* Register as a Provider */
105 InsertTailList(&KdProviders
, &DispatchTable
->KdProvidersList
);
107 else if (BootPhase
== 2)
109 HalDisplayString("\n File log debugging enabled\n\n");
111 else if (BootPhase
== 3)
113 /* Setup the Log Name */
114 RtlInitUnicodeString(&FileName
, L
"\\SystemRoot\\debug.log");
115 InitializeObjectAttributes(&ObjectAttributes
,
121 /* Create the Log File */
122 Status
= NtCreateFile(&KdbLogFileHandle
,
127 FILE_ATTRIBUTE_NORMAL
,
130 FILE_WRITE_THROUGH
| FILE_SYNCHRONOUS_IO_NONALERT
,
134 /* Allow it to be used */
135 ExInitializeWorkItem(&KdpDebugLogQueue
, &KdpPrintToLogInternal
, NULL
);
136 KdpLogInitialized
= TRUE
;
140 /* SERIAL FUNCTIONS **********************************************************/
144 KdpSerialDebugPrint(LPSTR Message
,
147 PCHAR pch
= (PCHAR
) Message
;
153 KdPortPutByteEx(&SerialPortInfo
, '\r');
155 KdPortPutByteEx(&SerialPortInfo
, *pch
);
162 KdpSerialInit(PKD_DISPATCH_TABLE DispatchTable
,
165 if (!KdpDebugMode
.Serial
) return;
169 /* Write out the functions that we support for now */
170 DispatchTable
->KdpInitRoutine
= KdpSerialInit
;
171 DispatchTable
->KdpPrintRoutine
= KdpSerialDebugPrint
;
173 /* Initialize the Port */
174 if (!KdPortInitializeEx(&SerialPortInfo
, 0, 0))
176 KdpDebugMode
.Serial
= FALSE
;
180 /* Register as a Provider */
181 InsertTailList(&KdProviders
, &DispatchTable
->KdProvidersList
);
183 else if (BootPhase
== 2)
185 HalDisplayString("\n Serial debugging enabled\n\n");
189 /* SCREEN FUNCTIONS **********************************************************/
193 KdpScreenPrint(LPSTR Message
,
197 HalDisplayString(Message
);
202 KdpScreenInit(PKD_DISPATCH_TABLE DispatchTable
,
205 if (!KdpDebugMode
.Screen
) return;
209 /* Write out the functions that we support for now */
210 DispatchTable
->KdpInitRoutine
= KdpScreenInit
;
211 DispatchTable
->KdpPrintRoutine
= KdpScreenPrint
;
213 /* Register as a Provider */
214 InsertTailList(&KdProviders
, &DispatchTable
->KdProvidersList
);
216 else if (BootPhase
== 2)
218 HalDisplayString("\n Screen debugging enabled\n\n");
222 /* GENERAL FUNCTIONS *********************************************************/
226 KdpDetectConflicts(PCM_RESOURCE_LIST DriverList
)
228 ULONG ComPortBase
= 0;
230 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor
;
232 /* Select the COM Port Base */
235 case 1: ComPortBase
= 0x3f8; break;
236 case 2: ComPortBase
= 0x2f8; break;
237 case 3: ComPortBase
= 0x3e8; break;
238 case 4: ComPortBase
= 0x2e8; break;
241 /* search for this port address in DriverList */
242 for (i
= 0; i
< DriverList
->List
[0].PartialResourceList
.Count
; i
++)
244 ResourceDescriptor
= &DriverList
->List
[0].PartialResourceList
.PartialDescriptors
[i
];
245 if (ResourceDescriptor
->Type
== CmResourceTypePort
)
247 if ((ResourceDescriptor
->u
.Port
.Start
.u
.LowPart
<= ComPortBase
) &&
248 (ResourceDescriptor
->u
.Port
.Start
.u
.LowPart
+
249 ResourceDescriptor
->u
.Port
.Length
> ComPortBase
))
263 KdpPrintString(LPSTR String
,
266 if (!KdpDebugMode
.Value
) return 0;
267 PLIST_ENTRY CurrentEntry
;
268 PKD_DISPATCH_TABLE CurrentTable
;
270 /* Call the registered handlers */
271 CurrentEntry
= KdProviders
.Flink
;
272 while (CurrentEntry
!= &KdProviders
)
274 /* Get the current table */
275 CurrentTable
= CONTAINING_RECORD(CurrentEntry
,
280 CurrentTable
->KdpPrintRoutine(String
, Length
);
283 CurrentEntry
= CurrentEntry
->Flink
;
286 /* Call the Wrapper Routine */
287 if (WrapperInitRoutine
) WrapperTable
.KdpPrintRoutine(String
, Length
);
289 /* Return the Length */