Patch by Anton Yarotsky:

[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
This commit is contained in:
Sir Richard
2010-09-15 07:46:28 +00:00
parent c806e95592
commit b52bd79196
7 changed files with 422 additions and 12 deletions
+117 -10
View File
@@ -1,9 +1,9 @@
/*
* 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
* PROGRAMMERS: Alex Ionescu ([email protected])
* PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES ******************************************************************/
@@ -13,20 +13,127 @@
/* GLOBALS *******************************************************************/
PHEADLESS_GLOBALS HeadlessGlobals;
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
HeadlessInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
HdlspSendStringAtBaud(
IN PCHAR String
)
{
PHEADLESS_LOADER_BLOCK HeadlessBlock;
/* Send every byte */
while (*String++ != ANSI_NULL)
{
InbvPortPutByte(HeadlessGlobals->TerminalPort, *String);
}
}
/* Get the headless loader block */
HeadlessBlock = LoaderBlock->Extension->HeadlessLoaderBlock;
if (HeadlessBlock)
{
DPRINT1("ReactOS does not currently have Headless Terminal support!\n");
}
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
)
{
//UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* EOF */
+7 -2
View File
@@ -259,8 +259,13 @@ InbvDisplayString(IN PCHAR 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();
+121
View File
@@ -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;
}
+144
View File
@@ -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"
+30
View File
@@ -71,4 +71,34 @@ InbvIndicateProgress(
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;
@@ -88,6 +88,7 @@
#include "inbv.h"
#include "vdm.h"
#include "hal.h"
#include "hdl.h"
#include "arch/intrin_i.h"
/*
+2
View File
@@ -31,6 +31,7 @@
<library>bootvid</library>
<library>wdmguid</library>
<library>ioevent</library>
<library>cportlib</library>
<dependency>bugcodes</dependency>
<directory name="include">
<pch>ntoskrnl.h</pch>
@@ -263,6 +264,7 @@
</directory>
<directory name="inbv">
<file>inbv.c</file>
<file>inbvport.c</file>
</directory>
<directory name="io">
<directory name="iomgr">