Patch by Anton Yarotsky:
authorSir Richard <sir_richard@svn.reactos.org>
Wed, 15 Sep 2010 07:46:28 +0000 (07:46 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Wed, 15 Sep 2010 07:46:28 +0000 (07:46 +0000)
[NTOSKRNL]: Implement basic Headless support in the kernel. Implement missing InbvPort routines based on WinLdrPort (using cportlib). Add header for Hdl. Terminal initializes now on COM2. Added misisng code to InbvDisplayString to also display on Headless Terminal (requires unimplemented HeadlessDispatch). Next steps are to implement the kernel log buffer, and HeadlessCmdPutString to see boot strings.

svn path=/trunk/; revision=48773

reactos/ntoskrnl/ex/hdlsterm.c
reactos/ntoskrnl/inbv/inbv.c
reactos/ntoskrnl/inbv/inbvport.c [new file with mode: 0644]
reactos/ntoskrnl/include/internal/hdl.h [new file with mode: 0644]
reactos/ntoskrnl/include/internal/inbv.h
reactos/ntoskrnl/include/internal/ntoskrnl.h
reactos/ntoskrnl/ntoskrnl-generic.rbuild

index ed857f4..c36b058 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * PROJECT:         ReactOS Kernel
 /*
  * PROJECT:         ReactOS Kernel
- * LICENSE:         GPL - See COPYING in the top level directory
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
  * FILE:            ntoskrnl/ex/hdlsterm.c
  * PURPOSE:         Headless Terminal Support
  * FILE:            ntoskrnl/ex/hdlsterm.c
  * PURPOSE:         Headless Terminal Support
- * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
+ * PROGRAMMERS:     ReactOS Portable Systems Group
  */
 
 /* INCLUDES ******************************************************************/
  */
 
 /* INCLUDES ******************************************************************/
 
 /* GLOBALS *******************************************************************/
 
 
 /* GLOBALS *******************************************************************/
 
+PHEADLESS_GLOBALS HeadlessGlobals;
+
 /* FUNCTIONS *****************************************************************/
 
 VOID
 NTAPI
 /* FUNCTIONS *****************************************************************/
 
 VOID
 NTAPI
-HeadlessInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+HdlspSendStringAtBaud(
+       IN PCHAR String
+       )
+{
+       /* Send every byte */
+       while (*String++ != ANSI_NULL)
+       {
+               InbvPortPutByte(HeadlessGlobals->TerminalPort, *String);
+       }
+}
+
+NTSTATUS
+NTAPI
+HdlspEnableTerminal(
+       IN BOOLEAN Enable
+       )
+{
+       /* Enable if requested, as long as this isn't a PCI serial port crashing */
+       if ((Enable) &&
+               !(HeadlessGlobals->TerminalEnabled) &&
+               !((HeadlessGlobals->IsMMIODevice) && (HeadlessGlobals->InBugCheck)))
+       {
+               /* Initialize the COM port with cportlib */
+               HeadlessGlobals->TerminalEnabled = InbvPortInitialize(
+                       HeadlessGlobals->TerminalBaudRate,
+                       HeadlessGlobals->TerminalPortNumber,
+                       HeadlessGlobals->TerminalPortAddress,
+                       &HeadlessGlobals->TerminalPort,
+                       HeadlessGlobals->IsMMIODevice);
+        if (!HeadlessGlobals->TerminalEnabled) return STATUS_UNSUCCESSFUL;
+
+               /* Cleanup the screen and reset the cursor */
+               HdlspSendStringAtBaud("\x1B[2J");
+               HdlspSendStringAtBaud("\x1B[H");
+
+               /* Enable FIFO */
+               InbvPortEnableFifo(HeadlessGlobals->TerminalPort, TRUE);
+       }
+       else if (!Enable)
+       {
+               /* Specific case when headless is being disabled */
+               InbvPortTerminate(HeadlessGlobals->TerminalPort);
+               HeadlessGlobals->TerminalPort = 0;
+               HeadlessGlobals->TerminalEnabled = FALSE;
+       }
+       return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+HeadlessInit(
+       IN PLOADER_PARAMETER_BLOCK LoaderBlock
+       )
+{
+       PHEADLESS_LOADER_BLOCK HeadlessBlock;
+
+       HeadlessBlock = LoaderBlock->Extension->HeadlessLoaderBlock;
+       if (!HeadlessBlock) return;
+       if ((HeadlessBlock->PortNumber > 4) && (HeadlessBlock->UsedBiosSettings)) return;
+
+       HeadlessGlobals = ExAllocatePoolWithTag(
+               NonPagedPool,
+               sizeof(HEADLESS_GLOBALS),
+               'sldH');
+       if (!HeadlessGlobals) return;
+
+       /* Zero and copy loader data */
+       RtlZeroMemory(HeadlessGlobals, sizeof(HEADLESS_GLOBALS));
+       HeadlessGlobals->TerminalPortNumber = HeadlessBlock->PortNumber;
+       HeadlessGlobals->TerminalPortAddress = HeadlessBlock->PortAddress;
+       HeadlessGlobals->TerminalBaudRate = HeadlessBlock->BaudRate;
+       HeadlessGlobals->TerminalParity = HeadlessBlock->Parity;
+       HeadlessGlobals->TerminalStopBits = HeadlessBlock->StopBits;
+       HeadlessGlobals->UsedBiosSettings = HeadlessBlock->UsedBiosSettings;
+       HeadlessGlobals->IsMMIODevice = HeadlessBlock->IsMMIODevice;
+       HeadlessGlobals->TerminalType = HeadlessBlock->TerminalType;
+       HeadlessGlobals->SystemGUID = HeadlessBlock->SystemGUID;
+
+       /* These two are opposites of each other */
+       if (HeadlessGlobals->IsMMIODevice) HeadlessGlobals->IsNonLegacyDevice = TRUE;
+
+       /* Check for a PCI device, warn that this isn't supported */
+       if (HeadlessBlock->PciDeviceId != PCI_INVALID_VENDORID)
+       {
+               DPRINT1("PCI Serial Ports not supported\n");
+       }
+
+       /* Log entries are not yet supported */
+       DPRINT1("FIXME: No Headless logging support\n");
+
+       /* Windows seems to apply some special hacks for 9600 bps */
+       if (HeadlessGlobals->TerminalBaudRate == 9600)
+       {
+               DPRINT1("Please use other baud rate than 9600bps for now\n");
+       }
+
+       /* Enable the terminal */
+       HdlspEnableTerminal(TRUE);
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+HeadlessDispatch(
+    IN HEADLESS_CMD Command,
+    IN PVOID InputBuffer,
+    IN SIZE_T InputBufferSize,
+    OUT PVOID OutputBuffer,
+    OUT PSIZE_T OutputBufferSize
+       )
 {
 {
-    PHEADLESS_LOADER_BLOCK HeadlessBlock;
-
-    /* Get the headless loader block */
-    HeadlessBlock = LoaderBlock->Extension->HeadlessLoaderBlock;
-    if (HeadlessBlock)
-    {
-        DPRINT1("ReactOS does not currently have Headless Terminal support!\n");
-    }
+       //UNIMPLEMENTED;
+       return STATUS_NOT_IMPLEMENTED;
 }
 
 /* EOF */
 }
 
 /* EOF */
index cdae54a..a324fad 100644 (file)
@@ -259,8 +259,13 @@ InbvDisplayString(IN PCHAR String)
         /* Make sure we're installed and display the string */
         if (InbvBootDriverInstalled) VidDisplayString((PUCHAR) String);
 
         /* Make sure we're installed and display the string */
         if (InbvBootDriverInstalled) VidDisplayString((PUCHAR) String);
 
-        /* Call Headless (We don't support headless for now)
-        HeadlessDispatch(DISPLAY_STRING); */
+        /* Print the string on the EMS port */
+               HeadlessDispatch(
+                       HeadlessCmdPutString,
+                       String,
+                       strlen(String) + sizeof(ANSI_NULL),
+                       NULL,
+                       NULL);
 
         /* Release the lock */
         InbvReleaseLock();
 
         /* Release the lock */
         InbvReleaseLock();
diff --git a/reactos/ntoskrnl/inbv/inbvport.c b/reactos/ntoskrnl/inbv/inbvport.c
new file mode 100644 (file)
index 0000000..839d6fe
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            ntoskrnl/inbv/inbvport.c
+ * PURPOSE:         Serial Port Boot Driver for Headless Terminal Support
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+CPPORT Port[4] =
+{
+       {NULL, 0, TRUE},
+       {NULL, 0, TRUE},
+       {NULL, 0, TRUE},
+       {NULL, 0, TRUE}
+};
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+NTAPI
+InbvPortEnableFifo(
+       IN ULONG PortId,
+       IN BOOLEAN Enable
+       )
+{
+       /* Set FIFO as requested */
+       CpEnableFifo(Port[PortId].Address, Enable);
+}
+
+VOID
+NTAPI
+InbvPortPutByte(
+       IN ULONG PortId,
+       IN BOOLEAN Output
+       )
+{
+       /* Send the byte */
+       CpPutByte(&Port[PortId], Output);
+}
+
+VOID
+NTAPI
+InbvPortTerminate(
+       IN ULONG PortId
+       )
+{
+       /* The port is now available */
+       Port[PortId].Address = NULL;
+}
+
+BOOLEAN
+NTAPI
+InbvPortInitialize(
+       IN ULONG BaudRate,
+       IN ULONG PortNumber,
+       IN PUCHAR PortAddress,
+       OUT PULONG PortId,
+       IN BOOLEAN IsMMIODevice
+       )
+{
+       /* Not yet supported */
+       ASSERT(IsMMIODevice == FALSE);
+
+       /* Set default baud rate */
+    if (BaudRate == 0) BaudRate = 19200;
+
+       /* Check if port or address given */
+       if (PortNumber)
+       {
+               /* Pick correct address for port */
+          if (!PortAddress)
+               {
+            switch (PortNumber)
+                       {
+                               case 1:
+                                       PortAddress = (PUCHAR)0x3F8;
+                                       break;
+
+                               case 2:
+                                       PortAddress = (PUCHAR)0x2F8;
+                                       break;
+
+                               case 3:
+                                       PortAddress = (PUCHAR)0x3E8;
+                                       break;
+
+                               default:
+                                       PortNumber = 4;
+                                       PortAddress = (PUCHAR)0x2E8;
+                       }
+               }
+    }
+       else
+       {
+               /* Pick correct port for address */
+               PortAddress = (PUCHAR)0x2F8;
+               if (CpDoesPortExist(PortAddress))
+               {
+                       PortNumber = 2;
+        }
+               else
+               {
+                       PortAddress = (PUCHAR)0x3F8;
+                       if (!CpDoesPortExist(PortAddress)) return FALSE;
+                       PortNumber = 1;
+               }
+       }
+
+       /* Initialize the port unless it's already up, and then return it */
+       if (Port[PortNumber - 1].Address) return FALSE;
+       CpInitialize(&Port[PortNumber - 1], PortAddress, BaudRate);
+       *PortId = PortNumber - 1;
+       return TRUE;
+}
diff --git a/reactos/ntoskrnl/include/internal/hdl.h b/reactos/ntoskrnl/include/internal/hdl.h
new file mode 100644 (file)
index 0000000..5afd40f
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            ntoskrnl/include/internal/hdl.h
+ * PURPOSE:         Internal header for the Configuration Manager
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+#define _HDL_
+#include <cportlib/cportlib.h>
+
+//
+// Define this if you want debugging support
+//
+#define _HDL_DEBUG_                                     0x00
+
+//
+// These define the Debug Masks Supported
+//
+#define HDL_XXX_DEBUG                                  0x01
+
+//
+// Debug/Tracing support
+//
+#if _HDL_DEBUG_
+#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
+#define HDLTRACE DbgPrintEx
+#else
+#define HDLTRACE(x, ...)                                 \
+    if (x & HdlpTraceLevel) DbgPrint(__VA_ARGS__)
+#endif
+#else
+#define HDLTRACE(x, ...) DPRINT(__VA_ARGS__)
+#endif
+
+//
+// Headless Log Entry
+//
+typedef struct _HEADLESS_LOG_ENTRY
+{
+       SYSTEM_TIMEOFDAY_INFORMATION TimeOfEntry;
+       PWCHAR String;
+} HEADLESS_LOG_ENTRY, *PHEADLESS_LOG_ENTRY;
+
+//
+// Headless Bugcheck Information
+//
+typedef struct _HEADLESS_BLUE_SCREEN_DATA
+{
+       PUCHAR Property;
+       PUCHAR XMLData;
+       struct _HEADLESS_BLUE_SCREEN_DATA *Next;
+} HEADLESS_BLUE_SCREEN_DATA, * PHEADLESS_BLUE_SCREEN_DATA;
+
+//
+// Headless Control Structure, mostly for !SAC
+//
+typedef struct _HEADLESS_GLOBALS
+{
+       KSPIN_LOCK SpinLock;
+       HANDLE PageLockHandle;
+       PHEADLESS_LOG_ENTRY LogEntries;
+       PUCHAR TmpBuffer;
+       PUCHAR InputBuffer;
+       PHEADLESS_BLUE_SCREEN_DATA BlueScreenData;
+       union
+       {
+               struct
+               {
+                       ULONG TerminalEnabled:1;
+                       ULONG InBugCheck:1;
+                       ULONG NewLogEntryAdded:1;
+                       ULONG UsedBiosSettings:1;
+                       ULONG InputProcessing:1;
+                       ULONG InputLineDone:1;
+                       ULONG ProcessingCmd:1;
+                       ULONG TerminalParity:1;
+                       ULONG TerminalStopBits:1;
+                       ULONG TerminalPortNumber:3;
+                       ULONG IsNonLegacyDevice:1;
+               };
+               ULONG AllFlags;
+       };
+       ULONG TerminalBaudRate;
+       ULONG TerminalPort;
+       PUCHAR TerminalPortAddress;
+       LARGE_INTEGER DelayTime;
+       ULONG MicroSecondsDelayTime;
+       UCHAR TerminalType;
+       SIZE_T InputBufferIndex;
+       USHORT LogEntryLast;
+       USHORT LogEntryStart;
+       GUID SystemGUID;
+       BOOLEAN IsMMIODevice;
+       BOOLEAN IsLastCharCR;
+} HEADLESS_GLOBALS, *PHEADLESS_GLOBALS;
+
+//
+// FIXME: A public header in the NDK? Ask Alex
+//
+typedef enum _HEADLESS_CMD
+{
+       HeadlessCmdEnableTerminal = 1,
+       HeadlessCmdCheckForReboot,
+       HeadlessCmdPutString,
+       HeadlessCmdClearDisplay,
+       HeadlessCmdClearToEndOfDisplay,
+       HeadlessCmdClearToEndOfLine,
+       HeadlessCmdDisplayAttributesOff,
+       HeadlessCmdDisplayInverseVideo,
+       HeadlessCmdSetColor,
+       HeadlessCmdPositionCursor,
+       HeadlessCmdTerminalPoll,
+       HeadlessCmdGetByte,
+       HeadlessCmdGetLine,
+       HeadlessCmdStartBugCheck,
+       HeadlessCmdDoBugCheckProcessing,
+       HeadlessCmdQueryInformation,
+       HeadlessCmdAddLogEntry,
+       HeadlessCmdDisplayLog,
+       HeadlessCmdSetBlueScreenData,
+       HeadlessCmdSendBlueScreenData,
+       HeadlessCmdQueryGUID,
+       HeadlessCmdPutData
+} HEADLESS_CMD, *PHEADLESS_CMD;
+
+NTSTATUS
+NTAPI
+HeadlessDispatch(
+       IN HEADLESS_CMD Command,
+       IN PVOID InputBuffer,
+       IN SIZE_T InputBufferSize,
+       OUT PVOID OutputBuffer,
+       OUT PSIZE_T OutputBufferSize
+);
+
+//
+// Global variables accessible from all of Hdl
+//
+extern PHEADLESS_GLOBALS HeadlessGlobals;
+
+//
+// Inlined functions
+//
+//#include "hdl_x.h"
index eb87f83..9d9e737 100644 (file)
@@ -71,4 +71,34 @@ InbvIndicateProgress(
     VOID
 );
            
     VOID
 );
            
+VOID
+NTAPI
+InbvPortEnableFifo(
+       IN ULONG PortId,
+       IN BOOLEAN Enable
+);
+
+VOID
+NTAPI
+InbvPortPutByte(
+       IN ULONG PortId,
+       IN BOOLEAN Output
+);
+
+VOID
+NTAPI
+InbvPortTerminate(
+       IN ULONG PortId
+);
+
+BOOLEAN
+NTAPI
+InbvPortInitialize(
+       IN ULONG BaudRate,
+       IN ULONG PortNumber,
+       IN PUCHAR PortAddress,
+       OUT PULONG PortId,
+       IN BOOLEAN IsMMIODevice
+);
+
 extern BOOLEAN InbvBootDriverInstalled;
 extern BOOLEAN InbvBootDriverInstalled;
index 004ce9a..f5354ee 100644 (file)
@@ -88,6 +88,7 @@
 #include "inbv.h"
 #include "vdm.h"
 #include "hal.h"
 #include "inbv.h"
 #include "vdm.h"
 #include "hal.h"
+#include "hdl.h"
 #include "arch/intrin_i.h"
 
 /*
 #include "arch/intrin_i.h"
 
 /*
index 6b7cc84..2dfca50 100644 (file)
@@ -31,6 +31,7 @@
        <library>bootvid</library>
        <library>wdmguid</library>
        <library>ioevent</library>
        <library>bootvid</library>
        <library>wdmguid</library>
        <library>ioevent</library>
+       <library>cportlib</library>
        <dependency>bugcodes</dependency>
        <directory name="include">
                <pch>ntoskrnl.h</pch>
        <dependency>bugcodes</dependency>
        <directory name="include">
                <pch>ntoskrnl.h</pch>
        </directory>
        <directory name="inbv">
                <file>inbv.c</file>
        </directory>
        <directory name="inbv">
                <file>inbv.c</file>
+               <file>inbvport.c</file>
        </directory>
        <directory name="io">
                <directory name="iomgr">
        </directory>
        <directory name="io">
                <directory name="iomgr">