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
)
60 ULONG StringLength
= strlen(String
);
63 if ((CurrentPosition
+ StringLength
) > BufferSize
) return;
65 /* Add the string to the buffer */
66 RtlMoveMemory(&DebugBuffer
[CurrentPosition
], String
, StringLength
);
68 /* Update the Current Position */
69 CurrentPosition
+= StringLength
;
71 /* Make sure we are initialized and can queue */
72 if (!KdpLogInitialized
|| (ItemQueued
)) return;
74 /* Queue the work item */
75 ExQueueWorkItem(&KdpDebugLogQueue
, HyperCriticalWorkQueue
);
81 KdpInitDebugLog(PKD_DISPATCH_TABLE DispatchTable
,
84 if (!KdpDebugMode
.File
) return;
86 OBJECT_ATTRIBUTES ObjectAttributes
;
87 UNICODE_STRING FileName
;
92 /* Write out the functions that we support for now */
93 DispatchTable
->KdpInitRoutine
= KdpInitDebugLog
;
94 DispatchTable
->KdpPrintRoutine
= KdpPrintToLog
;
96 /* Register as a Provider */
97 InsertTailList(&KdProviders
, &DispatchTable
->KdProvidersList
);
99 else if (BootPhase
== 2)
101 HalDisplayString("\n File log debugging enabled\n\n");
103 else if (BootPhase
== 3)
105 /* Setup the Log Name */
106 RtlInitUnicodeString(&FileName
, L
"\\SystemRoot\\debug.log");
107 InitializeObjectAttributes(&ObjectAttributes
,
113 /* Create the Log File */
114 Status
= NtCreateFile(&KdbLogFileHandle
,
119 FILE_ATTRIBUTE_NORMAL
,
122 FILE_WRITE_THROUGH
| FILE_SYNCHRONOUS_IO_NONALERT
,
126 /* Allow it to be used */
127 ExInitializeWorkItem(&KdpDebugLogQueue
, &KdpPrintToLogInternal
, NULL
);
128 KdpLogInitialized
= TRUE
;
132 /* SERIAL FUNCTIONS **********************************************************/
136 KdpSerialDebugPrint(LPSTR Message
)
138 PCHAR pch
= (PCHAR
) Message
;
144 KdPortPutByteEx(&SerialPortInfo
, '\r');
146 KdPortPutByteEx(&SerialPortInfo
, *pch
);
153 KdpSerialInit(PKD_DISPATCH_TABLE DispatchTable
,
156 if (!KdpDebugMode
.Serial
) return;
160 /* Write out the functions that we support for now */
161 DispatchTable
->KdpInitRoutine
= KdpSerialInit
;
162 DispatchTable
->KdpPrintRoutine
= KdpSerialDebugPrint
;
164 /* Initialize the Port */
165 KdPortInitializeEx(&SerialPortInfo
, 0, 0);
167 /* Register as a Provider */
168 InsertTailList(&KdProviders
, &DispatchTable
->KdProvidersList
);
170 else if (BootPhase
== 2)
172 HalDisplayString("\n Serial debugging enabled\n\n");
176 /* SCREEN FUNCTIONS **********************************************************/
180 KdpScreenInit(PKD_DISPATCH_TABLE DispatchTable
,
183 if (!KdpDebugMode
.Screen
) return;
187 /* Write out the functions that we support for now */
188 DispatchTable
->KdpInitRoutine
= KdpScreenInit
;
189 DispatchTable
->KdpPrintRoutine
= HalDisplayString
;
191 /* Register as a Provider */
192 InsertTailList(&KdProviders
, &DispatchTable
->KdProvidersList
);
194 else if (BootPhase
== 2)
196 HalDisplayString("\n Screen debugging enabled\n\n");
200 /* GENERAL FUNCTIONS *********************************************************/
204 KdpDetectConflicts(PCM_RESOURCE_LIST DriverList
)
206 ULONG ComPortBase
= 0;
208 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor
;
210 /* Select the COM Port Base */
213 case 1: ComPortBase
= 0x3f8; break;
214 case 2: ComPortBase
= 0x2f8; break;
215 case 3: ComPortBase
= 0x3e8; break;
216 case 4: ComPortBase
= 0x2e8; break;
219 /* search for this port address in DriverList */
220 for (i
= 0; i
< DriverList
->List
[0].PartialResourceList
.Count
; i
++)
222 ResourceDescriptor
= &DriverList
->List
[0].PartialResourceList
.PartialDescriptors
[i
];
223 if (ResourceDescriptor
->Type
== CmResourceTypePort
)
225 if ((ResourceDescriptor
->u
.Port
.Start
.u
.LowPart
<= ComPortBase
) &&
226 (ResourceDescriptor
->u
.Port
.Start
.u
.LowPart
+
227 ResourceDescriptor
->u
.Port
.Length
> ComPortBase
))
241 KdpPrintString(PANSI_STRING String
)
243 if (!KdpDebugMode
.Value
) return 0;
244 PCH pch
= String
->Buffer
;
245 PLIST_ENTRY CurrentEntry
;
246 PKD_DISPATCH_TABLE CurrentTable
;
248 /* Call the registered handlers */
249 CurrentEntry
= KdProviders
.Flink
;
250 while (CurrentEntry
!= &KdProviders
)
252 /* Get the current table */
253 CurrentTable
= CONTAINING_RECORD(CurrentEntry
,
258 CurrentTable
->KdpPrintRoutine(pch
);
261 CurrentEntry
= CurrentEntry
->Flink
;
264 /* Call the Wrapper Routine */
265 if (WrapperInitRoutine
) WrapperTable
.KdpPrintRoutine(pch
);
267 /* Return the Length */
268 return((ULONG
)String
->Length
);