Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenkdcom.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: GPL, see COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: drivers/base/kddll/kdcom.c 00005 * PURPOSE: COM port functions for the kernel debugger. 00006 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@ewactos.org) 00007 */ 00008 00009 #include "kddll.h" 00010 #include "kdcom.h" 00011 00012 /* serial debug connection */ 00013 #define DEFAULT_DEBUG_PORT 2 /* COM2 */ 00014 #define DEFAULT_DEBUG_COM1_IRQ 4 /* COM1 IRQ */ 00015 #define DEFAULT_DEBUG_COM2_IRQ 3 /* COM2 IRQ */ 00016 #define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */ 00017 00018 #define DEFAULT_BAUD_RATE 19200 00019 00020 00021 #if defined(_M_IX86) || defined(_M_AMD64) 00022 const ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8}; 00023 #elif defined(_M_PPC) 00024 const ULONG BaseArray[2] = {0, 0x800003f8}; 00025 #elif defined(_M_MIPS) 00026 const ULONG BaseArray[3] = {0, 0x80006000, 0x80007000}; 00027 #elif defined(_M_ARM) 00028 const ULONG BaseArray[2] = {0, 0xF1012000}; 00029 #else 00030 #error Unknown architecture 00031 #endif 00032 00033 /* GLOBALS ********************************************************************/ 00034 00035 PUCHAR ComPortBase; 00036 ULONG ComPortNumber = DEFAULT_DEBUG_PORT; 00037 ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE; 00038 ULONG ComPortIrq = 0; 00039 00040 00041 NTSTATUS 00042 NTAPI 00043 KdpPortInitialize() 00044 { 00045 ULONG Mode; 00046 00047 KDDBGPRINT("KdpPortInitialize, Port = COM%ld\n", ComPortNumber); 00048 00049 /* Enable loop mode (set Bit 4 of the MCR) */ 00050 WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_LOOP); 00051 00052 /* Clear all modem output bits */ 00053 WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_LOOP); 00054 00055 /* The upper nibble of the MSR (modem output bits) must be 00056 * equal to the lower nibble of the MCR (modem input bits) */ 00057 if ((READ_PORT_UCHAR(ComPortBase + COM_MSR) & 0xF0) != 0x00) 00058 { 00059 return STATUS_INVALID_PARAMETER; 00060 } 00061 00062 /* Set all modem output bits */ 00063 WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_ALL); 00064 00065 /* The upper nibble of the MSR (modem output bits) must be 00066 * equal to the lower nibble of the MCR (modem input bits) */ 00067 if ((READ_PORT_UCHAR(ComPortBase + COM_MSR) & 0xF0) != 0xF0) 00068 { 00069 return STATUS_INVALID_PARAMETER; 00070 } 00071 00072 /* Enable FIFO */ 00073 WRITE_PORT_UCHAR(ComPortBase + COM_FCR, 00074 FCR_ENABLE_FIFO | FCR_CLEAR_RCVR | FCR_CLEAR_XMIT); 00075 00076 /* Disable interrupts */ 00077 WRITE_PORT_UCHAR(ComPortBase + COM_LCR, 0); 00078 WRITE_PORT_UCHAR(ComPortBase + COM_IEN, 0); 00079 00080 /* Enable on DTR and RTS */ 00081 WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_DTR | MCR_RTS); 00082 00083 /* Set DLAB */ 00084 WRITE_PORT_UCHAR(ComPortBase + COM_LCR, LCR_DLAB); 00085 00086 /* Set baud rate */ 00087 Mode = 115200 / ComPortBaudRate; 00088 WRITE_PORT_UCHAR(ComPortBase + COM_DLL, (UCHAR)(Mode & 0xff)); 00089 WRITE_PORT_UCHAR(ComPortBase + COM_DLM, (UCHAR)((Mode >> 8) & 0xff)); 00090 00091 /* Reset DLAB and set 8 data bits, 1 stop bit, no parity, no break */ 00092 WRITE_PORT_UCHAR(ComPortBase + COM_LCR, LCR_CS8 | LCR_ST1 | LCR_PNO); 00093 00094 /* Check for 16450/16550 scratch register */ 00095 WRITE_PORT_UCHAR(ComPortBase + COM_SCR, 0xff); 00096 if (READ_PORT_UCHAR(ComPortBase + COM_SCR) != 0xff) 00097 { 00098 return STATUS_INVALID_PARAMETER; 00099 } 00100 WRITE_PORT_UCHAR(ComPortBase + COM_SCR, 0x00); 00101 if (READ_PORT_UCHAR(ComPortBase + COM_SCR) != 0x00) 00102 { 00103 return STATUS_INVALID_PARAMETER; 00104 } 00105 00106 return STATUS_SUCCESS; 00107 } 00108 00109 /****************************************************************************** 00110 * \name KdDebuggerInitialize0 00111 * \brief Phase 0 initialization. 00112 * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL. 00113 * \return Status 00114 */ 00115 NTSTATUS 00116 NTAPI 00117 KdDebuggerInitialize0( 00118 IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL) 00119 { 00120 PCHAR CommandLine, PortString, BaudString, IrqString; 00121 ULONG Value; 00122 00123 /* Check if e have a LoaderBlock */ 00124 if (LoaderBlock) 00125 { 00126 /* HACK */ 00127 KdpDbgPrint = LoaderBlock->u.I386.CommonDataArea; 00128 KDDBGPRINT("KdDebuggerInitialize0\n"); 00129 00130 /* Get the Command Line */ 00131 CommandLine = LoaderBlock->LoadOptions; 00132 00133 /* Upcase it */ 00134 _strupr(CommandLine); 00135 00136 /* Get the port and baud rate */ 00137 PortString = strstr(CommandLine, "DEBUGPORT"); 00138 BaudString = strstr(CommandLine, "BAUDRATE"); 00139 IrqString = strstr(CommandLine, "IRQ"); 00140 00141 /* Check if we got the /DEBUGPORT parameter */ 00142 if (PortString) 00143 { 00144 /* Move past the actual string, to reach the port*/ 00145 PortString += strlen("DEBUGPORT"); 00146 00147 /* Now get past any spaces and skip the equal sign */ 00148 while (*PortString == ' ') PortString++; 00149 PortString++; 00150 00151 /* Do we have a serial port? */ 00152 if (strncmp(PortString, "COM", 3) != 0) 00153 { 00154 return STATUS_INVALID_PARAMETER; 00155 } 00156 00157 /* Gheck for a valid Serial Port */ 00158 PortString += 3; 00159 Value = atol(PortString); 00160 if (Value > 4) 00161 { 00162 return STATUS_INVALID_PARAMETER; 00163 } 00164 00165 /* Set the port to use */ 00166 ComPortNumber = Value; 00167 } 00168 00169 /* Check if we got a baud rate */ 00170 if (BaudString) 00171 { 00172 /* Move past the actual string, to reach the rate */ 00173 BaudString += strlen("BAUDRATE"); 00174 00175 /* Now get past any spaces */ 00176 while (*BaudString == ' ') BaudString++; 00177 00178 /* And make sure we have a rate */ 00179 if (*BaudString) 00180 { 00181 /* Read and set it */ 00182 Value = atol(BaudString + 1); 00183 if (Value) ComPortBaudRate = Value; 00184 } 00185 } 00186 00187 /* Check Serial Port Settings [IRQ] */ 00188 if (IrqString) 00189 { 00190 /* Move past the actual string, to reach the rate */ 00191 IrqString += strlen("IRQ"); 00192 00193 /* Now get past any spaces */ 00194 while (*IrqString == ' ') IrqString++; 00195 00196 /* And make sure we have an IRQ */ 00197 if (*IrqString) 00198 { 00199 /* Read and set it */ 00200 Value = atol(IrqString + 1); 00201 if (Value) ComPortIrq = Value; 00202 } 00203 } 00204 } 00205 00206 /* Get base address */ 00207 ComPortBase = UlongToPtr(BaseArray[ComPortNumber]); 00208 KdComPortInUse = ComPortBase; 00209 00210 /* Initialize the port */ 00211 return KdpPortInitialize(); 00212 } 00213 00214 VOID 00215 NTAPI 00216 KdpSendByte(IN BYTE Byte) 00217 { 00218 /* Wait for the port to be ready */ 00219 while ((READ_PORT_UCHAR(ComPortBase + COM_LSR) & LSR_TBE) == 0); 00220 00221 /* This is needed due to subtle timing issues */ 00222 READ_PORT_UCHAR(ComPortBase + COM_MSR); 00223 while ((READ_PORT_UCHAR(ComPortBase + COM_LSR) & LSR_TBE) == 0); 00224 READ_PORT_UCHAR(ComPortBase + COM_MSR); 00225 00226 /* Send the byte */ 00227 WRITE_PORT_UCHAR(ComPortBase + COM_DAT, Byte); 00228 } 00229 00230 KDP_STATUS 00231 NTAPI 00232 KdpPollByte(OUT PBYTE OutByte) 00233 { 00234 READ_PORT_UCHAR(ComPortBase + COM_MSR); // Timing 00235 00236 /* Check if data is available */ 00237 if ((READ_PORT_UCHAR(ComPortBase + COM_LSR) & LSR_DR)) 00238 { 00239 /* Yes, return the byte */ 00240 *OutByte = READ_PORT_UCHAR(ComPortBase + COM_DAT); 00241 return KDP_PACKET_RECEIVED; 00242 } 00243 00244 /* Timed out */ 00245 return KDP_PACKET_TIMEOUT; 00246 } 00247 00248 KDP_STATUS 00249 NTAPI 00250 KdpReceiveByte(OUT PBYTE OutByte) 00251 { 00252 ULONG Repeats = KdpStallScaleFactor * 100; 00253 00254 while (Repeats--) 00255 { 00256 /* Check if data is available */ 00257 if (KdpPollByte(OutByte) == KDP_PACKET_RECEIVED) 00258 { 00259 /* We successfully got a byte */ 00260 return KDP_PACKET_RECEIVED; 00261 } 00262 } 00263 00264 /* Timed out */ 00265 return KDP_PACKET_TIMEOUT; 00266 } 00267 00268 KDP_STATUS 00269 NTAPI 00270 KdpPollBreakIn() 00271 { 00272 UCHAR Byte; 00273 if (KdpPollByte(&Byte) == KDP_PACKET_RECEIVED) 00274 { 00275 if (Byte == BREAKIN_PACKET_BYTE) 00276 { 00277 return KDP_PACKET_RECEIVED; 00278 } 00279 } 00280 return KDP_PACKET_TIMEOUT; 00281 } 00282 00283 NTSTATUS 00284 NTAPI 00285 KdSave( 00286 IN BOOLEAN SleepTransition) 00287 { 00288 /* Nothing to do on COM ports */ 00289 return STATUS_SUCCESS; 00290 } 00291 00292 NTSTATUS 00293 NTAPI 00294 KdRestore( 00295 IN BOOLEAN SleepTransition) 00296 { 00297 /* Nothing to do on COM ports */ 00298 return STATUS_SUCCESS; 00299 } 00300 Generated on Sat May 26 2012 04:25:42 for ReactOS by
1.7.6.1
|