Author: sir_richard
Date: Mon Sep 13 20:36:49 2010
New Revision: 48768
URL:
http://svn.reactos.org/svn/reactos?rev=48768&view=rev
Log:
Patch by Anton Yarotsky:
[FREELDR]: Implement support for /redirect=comX (usebiossettings not yet supported) and
/redirectbaudrate. Uses cportlib. Tested, serial output works and kernel reports
"Headless support is not yet implemented". Future revisions should support ACPI
SRT for PCI-based serial ports on server systems.
Added:
trunk/reactos/boot/freeldr/freeldr/windows/headless.c (with props)
Modified:
trunk/reactos/boot/freeldr/freeldr/freeldr.rbuild
trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild
trunk/reactos/boot/freeldr/freeldr/setupldr.rbuild
trunk/reactos/boot/freeldr/freeldr/windows/winldr.c
Modified: trunk/reactos/boot/freeldr/freeldr/freeldr.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/freel…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/freeldr.rbuild [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/freeldr.rbuild [iso-8859-1] Mon Sep 13 20:36:49
2010
@@ -32,5 +32,6 @@
<library>cmlib</library>
<library>rtl</library>
<library>libcntpr</library>
+ <library>cportlib</library>
</module>
</ifnot>
Modified: trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/freel…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild [iso-8859-1] Mon Sep 13
20:36:49 2010
@@ -75,6 +75,7 @@
<file>winldr.c</file>
<file>wlmemory.c</file>
<file>wlregistry.c</file>
+ <file>headless.c</file>
</directory>
<file>freeldr.c</file>
<file>debug.c</file>
Modified: trunk/reactos/boot/freeldr/freeldr/setupldr.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/setup…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/setupldr.rbuild [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/setupldr.rbuild [iso-8859-1] Mon Sep 13 20:36:49
2010
@@ -14,6 +14,7 @@
<library>setupldr_main</library>
<library>rossym</library>
<library>cmlib</library>
+ <library>cportlib</library>
<library>rtl</library>
<library>libcntpr</library>
</module>
Added: trunk/reactos/boot/freeldr/freeldr/windows/headless.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/windo…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/windows/headless.c (added)
+++ trunk/reactos/boot/freeldr/freeldr/windows/headless.c [iso-8859-1] Mon Sep 13 20:36:49
2010
@@ -1,0 +1,313 @@
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/freeldr/windows/headless.c
+ * PURPOSE: Provides support for Windows Emergency Management Services
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <freeldr.h>
+#include <cportlib/cportlib.h>
+
+/* Note: Move these to some smbios.h header */
+#define SYSID_TYPE_UUID "_UUID_"
+#define SYSID_UUID_DATA_SIZE 16
+#include <pshpack1.h>
+typedef struct _SYSID_UUID_ENTRY
+{
+ UCHAR Type[6];
+ UCHAR Checksum;
+ USHORT Length;
+ UCHAR UUID[SYSID_UUID_DATA_SIZE];
+} SYSID_UUID_ENTRY, *PSYSID_UUID_ENTRY;
+#include <poppack.h>
+
+/* GLOBALS ********************************************************************/
+
+HEADLESS_LOADER_BLOCK LoaderRedirectionInformation;
+BOOLEAN WinLdrTerminalConnected;
+ULONG WinLdrTerminalDeviceId;
+ULONG WinLdrTerminalDelay;
+
+CPPORT Port[4] =
+{
+ {NULL, 0, TRUE},
+ {NULL, 0, TRUE},
+ {NULL, 0, TRUE},
+ {NULL, 0, TRUE}
+};
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+WinLdrLoadGUID(OUT PGUID SystemGuid)
+{
+ PSYSID_UUID_ENTRY CurrentAddress;
+
+ CurrentAddress = (PSYSID_UUID_ENTRY)0xE0000;
+ while (CurrentAddress < (PSYSID_UUID_ENTRY)0x100000)
+ {
+ if (RtlCompareMemory(&CurrentAddress->Type, SYSID_TYPE_UUID, 6) == 6)
+ {
+ RtlCopyMemory(SystemGuid, &CurrentAddress->UUID, SYSID_UUID_DATA_SIZE);
+ return;
+ }
+ CurrentAddress = (PSYSID_UUID_ENTRY)((ULONG_PTR)CurrentAddress + 1);
+ }
+
+ RtlZeroMemory(SystemGuid, SYSID_UUID_DATA_SIZE);
+}
+
+BOOLEAN
+WinLdrPortInitialize(IN ULONG BaudRate,
+ IN ULONG PortNumber,
+ IN PUCHAR PortAddress,
+ IN BOOLEAN TerminalConnected,
+ OUT PULONG PortId)
+{
+ /* 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;
+ }
+ }
+
+ /* Not yet supported */
+ ASSERT(LoaderRedirectionInformation.IsMMIODevice == FALSE);
+
+ /* Check if port exists */
+ if ((CpDoesPortExist(PortAddress)) || (CpDoesPortExist(PortAddress)))
+ {
+ /* Initialize port for first time, or re-initialize if specified */
+ if (((TerminalConnected) && (Port[PortNumber - 1].Address)) ||
+ !(Port[PortNumber - 1].Address))
+ {
+ /* Initialize the port, return it */
+ CpInitialize(&Port[PortNumber - 1], PortAddress, BaudRate);
+ *PortId = PortNumber - 1;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+VOID
+WinLdrPortPutByte(IN ULONG PortId,
+ IN UCHAR Data)
+{
+ CpPutByte(&Port[PortId], Data);
+}
+
+BOOLEAN
+WinLdrPortGetByte(IN ULONG PortId,
+ OUT PUCHAR Data)
+{
+ return CpGetByte(&Port[PortId], Data, TRUE, FALSE) == CP_GET_SUCCESS;
+}
+
+BOOLEAN
+WinLdrPortPollOnly(IN ULONG PortId)
+{
+ UCHAR Dummy;
+
+ return CpGetByte(&Port[PortId], &Dummy, FALSE, TRUE) == CP_GET_SUCCESS;
+}
+
+VOID
+WinLdrEnableFifo(IN ULONG PortId,
+ IN BOOLEAN Enable)
+{
+ CpEnableFifo(Port[PortId].Address, Enable);
+}
+
+VOID
+WinLdrInitializeHeadlessPort(VOID)
+{
+ ULONG PortNumber, BaudRate;
+ PUCHAR PortAddress;
+ PCHAR AnsiReset = "\x1B[m";
+ ULONG i;
+
+ PortNumber = LoaderRedirectionInformation.PortNumber;
+ PortAddress = LoaderRedirectionInformation.PortAddress;
+ BaudRate = LoaderRedirectionInformation.BaudRate;
+
+ /* Pick a port address */
+ if (PortNumber)
+ {
+ if (!PortAddress)
+ {
+ switch (PortNumber)
+ {
+ case 2:
+ LoaderRedirectionInformation.PortAddress = (PUCHAR)0x2F8;
+ break;
+
+ case 3:
+ LoaderRedirectionInformation.PortAddress = (PUCHAR)0x3E8;
+ break;
+
+ case 4:
+ LoaderRedirectionInformation.PortAddress = (PUCHAR)0x2E8;
+ break;
+
+ default:
+ LoaderRedirectionInformation.PortAddress = (PUCHAR)0x3F8;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* No number, so no EMS */
+ WinLdrTerminalConnected = FALSE;
+ return;
+ }
+
+ /* Call arch code to initialize the port */
+ PortAddress = LoaderRedirectionInformation.PortAddress;
+ WinLdrTerminalConnected = WinLdrPortInitialize(
+ BaudRate,
+ PortNumber,
+ PortAddress,
+ WinLdrTerminalConnected,
+ &WinLdrTerminalDeviceId);
+
+ if (WinLdrTerminalConnected)
+ {
+ /* Port seems usable, set it up and get the BIOS GUID */
+ WinLdrEnableFifo(WinLdrTerminalDeviceId, TRUE);
+
+ WinLdrLoadGUID(&LoaderRedirectionInformation.SystemGUID);
+
+ /* Calculate delay in us based on the baud, assume 9600 if none given */
+ if (!BaudRate)
+ {
+ BaudRate = 9600;
+ LoaderRedirectionInformation.BaudRate = BaudRate;
+ }
+
+ WinLdrTerminalDelay = (10 * 1000 * 1000) / (BaudRate / 10) / 6;
+
+ /* Sent an ANSI reset sequence to get the terminal up and running */
+ for (i = 0; i < strlen(AnsiReset); i++)
+ {
+ WinLdrPortPutByte(WinLdrTerminalDeviceId, AnsiReset[i]);
+ StallExecutionProcessor(WinLdrTerminalDelay);
+ }
+ }
+ else
+ {
+ /* The port was bogus, so don't give any information to the kernel */
+ RtlZeroMemory(&LoaderRedirectionInformation, sizeof(HEADLESS_LOADER_BLOCK));
+ }
+}
+
+VOID
+WinLdrSetupEms(IN PCHAR BootOptions)
+{
+ PCHAR RedirectPort;
+
+ /* Use a direction port if one was given, or use ACPI to detect one instead */
+ RedirectPort = strstr(BootOptions, "/redirect=");
+
+ if (RedirectPort)
+ {
+ RedirectPort = strstr(RedirectPort, "com");
+ if (RedirectPort)
+ {
+ RedirectPort += sizeof("com") - 1;
+ LoaderRedirectionInformation.PortNumber = atoi(RedirectPort);
+ }
+ else
+ {
+ RedirectPort = strstr(RedirectPort, "usebiossettings");
+ if (RedirectPort)
+ {
+ UiDrawStatusText("ACPI SRT Table Not Supported...");
+ }
+ else
+ {
+ LoaderRedirectionInformation.PortAddress = (PUCHAR)strtoul(RedirectPort, 0, 16);
+ if (LoaderRedirectionInformation.PortAddress)
+ {
+ LoaderRedirectionInformation.PortNumber = 3;
+ }
+ }
+ }
+ }
+
+ /* Use a direction baudrate if one was given */
+ RedirectPort = strstr(BootOptions, "/redirectbaudrate=");
+ if (RedirectPort)
+ {
+ if (strstr(RedirectPort, "115200"))
+ {
+ LoaderRedirectionInformation.BaudRate = 115200;
+ }
+ else if (strstr(RedirectPort, "57600"))
+ {
+ LoaderRedirectionInformation.BaudRate = 57600;
+ }
+ else if (strstr(RedirectPort, "19200"))
+ {
+ LoaderRedirectionInformation.BaudRate = 19200;
+ }
+ else
+ {
+ LoaderRedirectionInformation.BaudRate = 9600;
+ }
+ }
+
+ /* Enable headless support if parameters were found */
+ if (LoaderRedirectionInformation.PortNumber)
+ {
+ if (!LoaderRedirectionInformation.BaudRate)
+ {
+ LoaderRedirectionInformation.BaudRate = 9600;
+ }
+
+ WinLdrInitializeHeadlessPort();
+ }
+}
Propchange: trunk/reactos/boot/freeldr/freeldr/windows/headless.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/boot/freeldr/freeldr/windows/winldr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/windo…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/windows/winldr.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/windows/winldr.c [iso-8859-1] Mon Sep 13 20:36:49
2010
@@ -513,6 +513,10 @@
/* Allocate and minimalistic-initialize LPB */
AllocateAndInitLPB(&LoaderBlock);
+
+ /* Setup redirection support */
+ extern void WinLdrSetupEms(IN PCHAR BootOptions);
+ WinLdrSetupEms(BootOptions);
/* Detect hardware */
UseRealHeap = TRUE;
@@ -597,6 +601,10 @@
/* Save final value of LoaderPagesSpanned */
LoaderBlockVA->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
+
+ /* Set headless block pointer */
+ extern HEADLESS_LOADER_BLOCK LoaderRedirectionInformation;
+ LoaderBlockVA->Extension->HeadlessLoaderBlock =
PaToVa(&LoaderRedirectionInformation);
DPRINTM(DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA
%p!\n",
KiSystemStartup, LoaderBlockVA);