[ros-diffs] [sir_richard] 48768: Patch by Anton Yarotsky: [FREELDR]: Implement support for /redirect=comX (usebiossettings not yet supported) and /redirectbaudrate. Uses cportlib. Tested, serial output works a...

sir_richard at svn.reactos.org sir_richard at svn.reactos.org
Mon Sep 13 20:36:50 UTC 2010


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/freeldr.rbuild?rev=48768&r1=48767&r2=48768&view=diff
==============================================================================
--- 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/freeldr_base.rbuild?rev=48768&r1=48767&r2=48768&view=diff
==============================================================================
--- 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/setupldr.rbuild?rev=48768&r1=48767&r2=48768&view=diff
==============================================================================
--- 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/windows/headless.c?rev=48768&view=auto
==============================================================================
--- 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/windows/winldr.c?rev=48768&r1=48767&r2=48768&view=diff
==============================================================================
--- 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);




More information about the Ros-diffs mailing list