ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

kdcom.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.