Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenkdbg.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: drivers/base/kdcom/kdbg.c 00005 * PURPOSE: Serial i/o functions for the kernel debugger. 00006 * PROGRAMMER: Alex Ionescu 00007 * Hervé Poussineau 00008 */ 00009 00010 /* INCLUDES *****************************************************************/ 00011 00012 #define NOEXTAPI 00013 #include <ntifs.h> 00014 #define NDEBUG 00015 #include <halfuncs.h> 00016 #include <stdio.h> 00017 #include <debug.h> 00018 #include "arc/arc.h" 00019 #include "windbgkd.h" 00020 #include <kddll.h> 00021 #include <ioaccess.h> /* port intrinsics */ 00022 00023 typedef struct _KD_PORT_INFORMATION 00024 { 00025 ULONG ComPort; 00026 ULONG BaudRate; 00027 ULONG BaseAddress; 00028 } KD_PORT_INFORMATION, *PKD_PORT_INFORMATION; 00029 00030 BOOLEAN 00031 NTAPI 00032 KdPortInitializeEx( 00033 IN PKD_PORT_INFORMATION PortInformation, 00034 IN ULONG Unknown1, 00035 IN ULONG Unknown2); 00036 00037 BOOLEAN 00038 NTAPI 00039 KdPortGetByteEx( 00040 IN PKD_PORT_INFORMATION PortInformation, 00041 OUT PUCHAR ByteReceived); 00042 00043 BOOLEAN 00044 NTAPI 00045 KdPortPollByteEx( 00046 IN PKD_PORT_INFORMATION PortInformation, 00047 OUT PUCHAR ByteReceived); 00048 00049 VOID 00050 NTAPI 00051 KdPortPutByteEx( 00052 IN PKD_PORT_INFORMATION PortInformation, 00053 IN UCHAR ByteToSend); 00054 00055 #define DEFAULT_BAUD_RATE 19200 00056 00057 #ifdef _M_IX86 00058 const ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8}; 00059 #elif defined(_M_PPC) 00060 const ULONG BaseArray[2] = {0, 0x800003f8}; 00061 #elif defined(_M_MIPS) 00062 const ULONG BaseArray[3] = {0, 0x80006000, 0x80007000}; 00063 #elif defined(_M_ARM) 00064 const ULONG BaseArray[2] = {0, 0xF1012000}; 00065 #else 00066 #error Unknown architecture 00067 #endif 00068 00069 /* MACROS *******************************************************************/ 00070 00071 #define SER_RBR(x) ((PUCHAR)(x)+0) 00072 #define SER_THR(x) ((PUCHAR)(x)+0) 00073 #define SER_DLL(x) ((PUCHAR)(x)+0) 00074 #define SER_IER(x) ((PUCHAR)(x)+1) 00075 #define SR_IER_ERDA 0x01 00076 #define SR_IER_ETHRE 0x02 00077 #define SR_IER_ERLSI 0x04 00078 #define SR_IER_EMS 0x08 00079 #define SR_IER_ALL 0x0F 00080 #define SER_DLM(x) ((PUCHAR)(x)+1) 00081 #define SER_IIR(x) ((PUCHAR)(x)+2) 00082 #define SER_FCR(x) ((PUCHAR)(x)+2) 00083 #define SR_FCR_ENABLE_FIFO 0x01 00084 #define SR_FCR_CLEAR_RCVR 0x02 00085 #define SR_FCR_CLEAR_XMIT 0x04 00086 #define SER_LCR(x) ((PUCHAR)(x)+3) 00087 #define SR_LCR_CS5 0x00 00088 #define SR_LCR_CS6 0x01 00089 #define SR_LCR_CS7 0x02 00090 #define SR_LCR_CS8 0x03 00091 #define SR_LCR_ST1 0x00 00092 #define SR_LCR_ST2 0x04 00093 #define SR_LCR_PNO 0x00 00094 #define SR_LCR_POD 0x08 00095 #define SR_LCR_PEV 0x18 00096 #define SR_LCR_PMK 0x28 00097 #define SR_LCR_PSP 0x38 00098 #define SR_LCR_BRK 0x40 00099 #define SR_LCR_DLAB 0x80 00100 #define SER_MCR(x) ((PUCHAR)(x)+4) 00101 #define SR_MCR_DTR 0x01 00102 #define SR_MCR_RTS 0x02 00103 #define SR_MCR_OUT1 0x04 00104 #define SR_MCR_OUT2 0x08 00105 #define SR_MCR_LOOP 0x10 00106 #define SER_LSR(x) ((PUCHAR)(x)+5) 00107 #define SR_LSR_DR 0x01 00108 #define SR_LSR_TBE 0x20 00109 #define SER_MSR(x) ((PUCHAR)(x)+6) 00110 #define SR_MSR_CTS 0x10 00111 #define SR_MSR_DSR 0x20 00112 #define SER_SCR(x) ((PUCHAR)(x)+7) 00113 00114 00115 /* GLOBAL VARIABLES *********************************************************/ 00116 00117 /* STATIC VARIABLES *********************************************************/ 00118 00119 static KD_PORT_INFORMATION DefaultPort = { 0, 0, 0 }; 00120 00121 /* The com port must only be initialized once! */ 00122 static BOOLEAN PortInitialized = FALSE; 00123 00124 00125 /* STATIC FUNCTIONS *********************************************************/ 00126 00127 static BOOLEAN 00128 KdpDoesComPortExist( 00129 IN ULONG BaseAddress) 00130 { 00131 BOOLEAN found; 00132 UCHAR mcr; 00133 UCHAR msr; 00134 00135 found = FALSE; 00136 00137 /* save Modem Control Register (MCR) */ 00138 mcr = READ_PORT_UCHAR(SER_MCR(BaseAddress)); 00139 00140 /* enable loop mode (set Bit 4 of the MCR) */ 00141 WRITE_PORT_UCHAR(SER_MCR(BaseAddress), SR_MCR_LOOP); 00142 00143 /* clear all modem output bits */ 00144 WRITE_PORT_UCHAR(SER_MCR(BaseAddress), SR_MCR_LOOP); 00145 00146 /* read the Modem Status Register */ 00147 msr = READ_PORT_UCHAR(SER_MSR(BaseAddress)); 00148 00149 /* 00150 * the upper nibble of the MSR (modem output bits) must be 00151 * equal to the lower nibble of the MCR (modem input bits) 00152 */ 00153 if ((msr & 0xF0) == 0x00) 00154 { 00155 /* set all modem output bits */ 00156 WRITE_PORT_UCHAR(SER_MCR(BaseAddress), SR_MCR_DTR | SR_MCR_RTS | SR_MCR_OUT1 | SR_MCR_OUT2 | SR_MCR_LOOP); 00157 00158 /* read the Modem Status Register */ 00159 msr = READ_PORT_UCHAR(SER_MSR(BaseAddress)); 00160 00161 /* 00162 * the upper nibble of the MSR (modem output bits) must be 00163 * equal to the lower nibble of the MCR (modem input bits) 00164 */ 00165 if ((msr & 0xF0) == 0xF0) 00166 { 00167 /* 00168 * setup a resonable state for the port: 00169 * enable fifo and clear recieve/transmit buffers 00170 */ 00171 WRITE_PORT_UCHAR(SER_FCR(BaseAddress), 00172 (SR_FCR_ENABLE_FIFO | SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT)); 00173 WRITE_PORT_UCHAR(SER_FCR(BaseAddress), 0); 00174 READ_PORT_UCHAR(SER_RBR(BaseAddress)); 00175 WRITE_PORT_UCHAR(SER_IER(BaseAddress), 0); 00176 found = TRUE; 00177 } 00178 } 00179 00180 /* restore MCR */ 00181 WRITE_PORT_UCHAR(SER_MCR(BaseAddress), mcr); 00182 00183 return found; 00184 } 00185 00186 00187 /* FUNCTIONS ****************************************************************/ 00188 00189 /* HAL.KdPortInitialize */ 00190 BOOLEAN 00191 NTAPI 00192 KdPortInitialize( 00193 IN PKD_PORT_INFORMATION PortInformation, 00194 IN ULONG Unknown1, 00195 IN ULONG Unknown2) 00196 { 00197 SIZE_T i; 00198 CHAR buffer[80]; 00199 00200 if (!PortInitialized) 00201 { 00202 DefaultPort.BaudRate = PortInformation->BaudRate; 00203 00204 if (PortInformation->ComPort == 0) 00205 { 00206 for (i = sizeof(BaseArray) / sizeof(BaseArray[0]) - 1; i > 0; i--) 00207 { 00208 if (KdpDoesComPortExist(BaseArray[i])) 00209 { 00210 DefaultPort.BaseAddress = BaseArray[i]; 00211 DefaultPort.ComPort = i; 00212 PortInformation->BaseAddress = DefaultPort.BaseAddress; 00213 PortInformation->ComPort = DefaultPort.ComPort; 00214 break; 00215 } 00216 } 00217 if (i == 0) 00218 { 00219 sprintf(buffer, 00220 "\nKernel Debugger: No COM port found!\n\n"); 00221 HalDisplayString(buffer); 00222 return FALSE; 00223 } 00224 } 00225 00226 PortInitialized = TRUE; 00227 } 00228 00229 /* initialize port */ 00230 if (!KdPortInitializeEx(&DefaultPort, Unknown1, Unknown2)) 00231 return FALSE; 00232 00233 /* set global info */ 00234 KdComPortInUse = (PUCHAR)DefaultPort.BaseAddress; 00235 00236 return TRUE; 00237 } 00238 00239 00240 /* HAL.KdPortInitializeEx */ 00241 BOOLEAN 00242 NTAPI 00243 KdPortInitializeEx( 00244 IN PKD_PORT_INFORMATION PortInformation, 00245 IN ULONG Unknown1, 00246 IN ULONG Unknown2) 00247 { 00248 ULONG ComPortBase; 00249 CHAR buffer[80]; 00250 ULONG divisor; 00251 UCHAR lcr; 00252 00253 #ifdef _ARM_ 00254 UNIMPLEMENTED; 00255 return FALSE; 00256 #endif 00257 00258 if (PortInformation->BaudRate == 0) 00259 PortInformation->BaudRate = DEFAULT_BAUD_RATE; 00260 00261 if (PortInformation->ComPort != 0) 00262 { 00263 if (!KdpDoesComPortExist(BaseArray[PortInformation->ComPort])) 00264 { 00265 sprintf(buffer, 00266 "\nKernel Debugger: Serial port not found!\n\n"); 00267 HalDisplayString(buffer); 00268 return FALSE; 00269 } 00270 00271 ComPortBase = BaseArray[PortInformation->ComPort]; 00272 PortInformation->BaseAddress = ComPortBase; 00273 } 00274 else 00275 { 00276 ComPortBase = PortInformation->BaseAddress; 00277 } 00278 00279 if (ComPortBase == 0) 00280 return FALSE; 00281 00282 #ifndef NDEBUG 00283 sprintf(buffer, 00284 "\nSerial port COM%ld found at 0x%lx\n", 00285 PortInformation->ComPort, 00286 ComPortBase); 00287 HalDisplayString(buffer); 00288 #endif /* NDEBUG */ 00289 00290 /* set baud rate and data format (8N1) */ 00291 00292 /* turn on DTR and RTS */ 00293 WRITE_PORT_UCHAR(SER_MCR(ComPortBase), SR_MCR_DTR | SR_MCR_RTS); 00294 00295 /* set DLAB */ 00296 lcr = READ_PORT_UCHAR(SER_LCR(ComPortBase)) | SR_LCR_DLAB; 00297 WRITE_PORT_UCHAR(SER_LCR(ComPortBase), lcr); 00298 00299 /* set baud rate */ 00300 divisor = 115200 / PortInformation->BaudRate; 00301 WRITE_PORT_UCHAR(SER_DLL(ComPortBase), (UCHAR)(divisor & 0xff)); 00302 WRITE_PORT_UCHAR(SER_DLM(ComPortBase), (UCHAR)((divisor >> 8) & 0xff)); 00303 00304 /* reset DLAB and set 8N1 format */ 00305 WRITE_PORT_UCHAR(SER_LCR(ComPortBase), 00306 SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO); 00307 00308 /* read junk out of the RBR */ 00309 lcr = READ_PORT_UCHAR(SER_RBR(ComPortBase)); 00310 00311 #ifndef NDEBUG 00312 /* print message to blue screen */ 00313 sprintf(buffer, 00314 "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n", 00315 PortInformation->ComPort, 00316 ComPortBase, 00317 PortInformation->BaudRate); 00318 00319 HalDisplayString(buffer); 00320 #endif /* NDEBUG */ 00321 00322 return TRUE; 00323 } 00324 00325 00326 /* HAL.KdPortGetByte */ 00327 BOOLEAN 00328 NTAPI 00329 KdPortGetByte( 00330 OUT PUCHAR ByteReceived) 00331 { 00332 if (!PortInitialized) 00333 return FALSE; 00334 return KdPortGetByteEx(&DefaultPort, ByteReceived); 00335 } 00336 00337 00338 /* HAL.KdPortGetByteEx */ 00339 BOOLEAN 00340 NTAPI 00341 KdPortGetByteEx( 00342 IN PKD_PORT_INFORMATION PortInformation, 00343 OUT PUCHAR ByteReceived) 00344 { 00345 PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress; 00346 00347 if ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR)) 00348 { 00349 *ByteReceived = READ_PORT_UCHAR(SER_RBR(ComPortBase)); 00350 return TRUE; 00351 } 00352 00353 return FALSE; 00354 } 00355 00356 00357 /* HAL.KdPortPollByte */ 00358 BOOLEAN 00359 NTAPI 00360 KdPortPollByte( 00361 OUT PUCHAR ByteReceived) 00362 { 00363 if (!PortInitialized) 00364 return FALSE; 00365 return KdPortPollByteEx(&DefaultPort, ByteReceived); 00366 } 00367 00368 00369 /* HAL.KdPortPollByteEx */ 00370 BOOLEAN 00371 NTAPI 00372 KdPortPollByteEx( 00373 IN PKD_PORT_INFORMATION PortInformation, 00374 OUT PUCHAR ByteReceived) 00375 { 00376 PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress; 00377 00378 while ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR) == 0) 00379 ; 00380 00381 *ByteReceived = READ_PORT_UCHAR(SER_RBR(ComPortBase)); 00382 00383 return TRUE; 00384 } 00385 00386 00387 /* HAL.KdPortPutByte */ 00388 VOID 00389 NTAPI 00390 KdPortPutByte( 00391 IN UCHAR ByteToSend) 00392 { 00393 if (!PortInitialized) 00394 return; 00395 KdPortPutByteEx(&DefaultPort, ByteToSend); 00396 } 00397 00398 /* HAL.KdPortPutByteEx */ 00399 VOID 00400 NTAPI 00401 KdPortPutByteEx( 00402 IN PKD_PORT_INFORMATION PortInformation, 00403 IN UCHAR ByteToSend) 00404 { 00405 PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress; 00406 00407 while ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0) 00408 ; 00409 00410 WRITE_PORT_UCHAR(SER_THR(ComPortBase), ByteToSend); 00411 } 00412 00413 00414 /* HAL.KdPortRestore */ 00415 VOID 00416 NTAPI 00417 KdPortRestore(VOID) 00418 { 00419 UNIMPLEMENTED; 00420 } 00421 00422 00423 /* HAL.KdPortSave */ 00424 VOID 00425 NTAPI 00426 KdPortSave(VOID) 00427 { 00428 UNIMPLEMENTED; 00429 } 00430 00431 00432 /* HAL.KdPortDisableInterrupts */ 00433 BOOLEAN 00434 NTAPI 00435 KdPortDisableInterrupts(VOID) 00436 { 00437 UCHAR ch; 00438 00439 if (!PortInitialized) 00440 return FALSE; 00441 00442 ch = READ_PORT_UCHAR(SER_MCR(DefaultPort.BaseAddress)); 00443 ch &= (~(SR_MCR_OUT1 | SR_MCR_OUT2)); 00444 WRITE_PORT_UCHAR(SER_MCR(DefaultPort.BaseAddress), ch); 00445 00446 ch = READ_PORT_UCHAR(SER_IER(DefaultPort.BaseAddress)); 00447 ch &= (~SR_IER_ALL); 00448 WRITE_PORT_UCHAR(SER_IER(DefaultPort.BaseAddress), ch); 00449 00450 return TRUE; 00451 } 00452 00453 00454 /* HAL.KdPortEnableInterrupts */ 00455 BOOLEAN 00456 NTAPI 00457 KdPortEnableInterrupts(VOID) 00458 { 00459 UCHAR ch; 00460 00461 if (PortInitialized == FALSE) 00462 return FALSE; 00463 00464 ch = READ_PORT_UCHAR(SER_IER(DefaultPort.BaseAddress)); 00465 ch &= (~SR_IER_ALL); 00466 ch |= SR_IER_ERDA; 00467 WRITE_PORT_UCHAR(SER_IER(DefaultPort.BaseAddress), ch); 00468 00469 ch = READ_PORT_UCHAR(SER_MCR(DefaultPort.BaseAddress)); 00470 ch &= (~SR_MCR_LOOP); 00471 ch |= (SR_MCR_OUT1 | SR_MCR_OUT2); 00472 WRITE_PORT_UCHAR(SER_MCR(DefaultPort.BaseAddress), ch); 00473 00474 return TRUE; 00475 } 00476 00477 /* 00478 * @unimplemented 00479 */ 00480 NTSTATUS 00481 NTAPI 00482 KdDebuggerInitialize0( 00483 IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL) 00484 { 00485 return STATUS_NOT_IMPLEMENTED; 00486 } 00487 00488 /* 00489 * @unimplemented 00490 */ 00491 NTSTATUS 00492 NTAPI 00493 KdDebuggerInitialize1( 00494 IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL) 00495 { 00496 return STATUS_NOT_IMPLEMENTED; 00497 } 00498 00499 /* 00500 * @implemented 00501 */ 00502 NTSTATUS 00503 NTAPI 00504 KdSave( 00505 IN BOOLEAN SleepTransition) 00506 { 00507 /* Nothing to do on COM ports */ 00508 return STATUS_SUCCESS; 00509 } 00510 00511 /* 00512 * @implemented 00513 */ 00514 NTSTATUS 00515 NTAPI 00516 KdRestore( 00517 IN BOOLEAN SleepTransition) 00518 { 00519 /* Nothing to do on COM ports */ 00520 return STATUS_SUCCESS; 00521 } 00522 00523 /* 00524 * @unimplemented 00525 */ 00526 VOID 00527 NTAPI 00528 KdSendPacket( 00529 IN ULONG PacketType, 00530 IN PSTRING MessageHeader, 00531 IN PSTRING MessageData, 00532 IN OUT PKD_CONTEXT Context) 00533 { 00534 UNIMPLEMENTED; 00535 return; 00536 } 00537 00538 /* 00539 * @unimplemented 00540 */ 00541 KDSTATUS 00542 NTAPI 00543 KdReceivePacket( 00544 IN ULONG PacketType, 00545 OUT PSTRING MessageHeader, 00546 OUT PSTRING MessageData, 00547 OUT PULONG DataLength, 00548 IN OUT PKD_CONTEXT Context) 00549 { 00550 UNIMPLEMENTED; 00551 return 0; 00552 } 00553 00554 /* EOF */ Generated on Sat May 26 2012 04:25:42 for ReactOS by
1.7.6.1
|