ReactOS 0.4.16-dev-329-g9223134
headless.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/freeldr/freeldr/windows/headless.c
5 * PURPOSE: Provides support for Windows Emergency Management Services
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <freeldr.h>
12#include <cportlib/cportlib.h>
13#include "ntldropts.h"
14
15/* Note: Move these to some smbios.h header */
16#define SYSID_TYPE_UUID "_UUID_"
17#define SYSID_UUID_DATA_SIZE 16
18#include <pshpack1.h>
19typedef struct _SYSID_UUID_ENTRY
20{
26#include <poppack.h>
27
28/* GLOBALS ********************************************************************/
29
34
36{
37 {NULL, 0, TRUE},
38 {NULL, 0, TRUE},
39 {NULL, 0, TRUE},
40 {NULL, 0, TRUE}
41};
42
43/* FUNCTIONS ******************************************************************/
44
45VOID
47{
48 PSYSID_UUID_ENTRY CurrentAddress;
49
50 CurrentAddress = (PSYSID_UUID_ENTRY)0xE0000;
51 while (CurrentAddress < (PSYSID_UUID_ENTRY)0x100000)
52 {
53 if (RtlCompareMemory(&CurrentAddress->Type, SYSID_TYPE_UUID, 6) == 6)
54 {
55 RtlCopyMemory(SystemGuid, &CurrentAddress->UUID, SYSID_UUID_DATA_SIZE);
56 return;
57 }
58 CurrentAddress = (PSYSID_UUID_ENTRY)((ULONG_PTR)CurrentAddress + 1);
59 }
60
62}
63
67 IN PUCHAR PortAddress,
68 IN BOOLEAN TerminalConnected,
69 OUT PULONG PortId)
70{
71#if defined(SARCH_PC98)
72 /* Set default baud rate */
73 if (BaudRate == 0) BaudRate = 9600;
74
75 /* Check if port or address given */
76 if (PortNumber)
77 {
78 /* Pick correct address for port */
79 if (!PortAddress)
80 {
81 if (PortNumber == 1)
82 {
83 PortAddress = (PUCHAR)0x30;
84 }
85 else
86 {
87 PortAddress = (PUCHAR)0x238;
88 PortNumber = 2;
89 }
90 }
91 }
92 else
93 {
94 /* Pick correct port for address */
95 PortAddress = (PUCHAR)0x30;
96 if (CpDoesPortExist(PortAddress))
97 {
98 PortNumber = 1;
99 }
100 else
101 {
102 PortAddress = (PUCHAR)0x238;
103 if (!CpDoesPortExist(PortAddress))
104 return FALSE;
105
106 PortNumber = 2;
107 }
108 }
109#else
110 /* Set default baud rate */
111 if (BaudRate == 0) BaudRate = 19200;
112
113 /* Check if port or address given */
114 if (PortNumber)
115 {
116 /* Pick correct address for port */
117 if (!PortAddress)
118 {
119 switch (PortNumber)
120 {
121 case 1:
122 PortAddress = (PUCHAR)0x3F8;
123 break;
124
125 case 2:
126 PortAddress = (PUCHAR)0x2F8;
127 break;
128
129 case 3:
130 PortAddress = (PUCHAR)0x3E8;
131 break;
132
133 default:
134 PortNumber = 4;
135 PortAddress = (PUCHAR)0x2E8;
136 }
137 }
138 }
139 else
140 {
141 /* Pick correct port for address */
142 PortAddress = (PUCHAR)0x2F8;
143 if (CpDoesPortExist(PortAddress))
144 {
145 PortNumber = 2;
146 }
147 else
148 {
149 PortAddress = (PUCHAR)0x3F8;
150 if (!CpDoesPortExist(PortAddress)) return FALSE;
151 PortNumber = 1;
152 }
153 }
154#endif
155
156 /* Not yet supported */
158
159 /* Check if port exists */
160 if ((CpDoesPortExist(PortAddress)) || (CpDoesPortExist(PortAddress)))
161 {
162 /* Initialize port for first time, or re-initialize if specified */
163 if (((TerminalConnected) && (Port[PortNumber - 1].Address)) ||
164 !(Port[PortNumber - 1].Address))
165 {
166 /* Initialize the port, return it */
167 CpInitialize(&Port[PortNumber - 1], PortAddress, BaudRate);
168 *PortId = PortNumber - 1;
169 return TRUE;
170 }
171 }
172
173 return FALSE;
174}
175
176VOID
178 IN UCHAR Byte)
179{
180 CpPutByte(&Port[PortId], Byte);
181}
182
186{
187 return CpGetByte(&Port[PortId], Byte, TRUE, FALSE) == CP_GET_SUCCESS;
188}
189
192{
193 UCHAR Dummy;
194
195 return CpGetByte(&Port[PortId], &Dummy, FALSE, TRUE) == CP_GET_SUCCESS;
196}
197
198VOID
201{
203}
204
205VOID
207{
208 ULONG PortNumber, BaudRate;
209 PUCHAR PortAddress;
210 PCSTR AnsiReset = "\x1B[m";
211 ULONG i;
212
216
217#if defined(SARCH_PC98)
218 /* Pick a port address */
219 if (PortNumber)
220 {
221 if (!PortAddress)
222 {
223 if (PortNumber == 2)
225 else
227 }
228 }
229 else
230 {
231 /* No number, so no EMS */
233 return;
234 }
235#else
236 /* Pick a port address */
237 if (PortNumber)
238 {
239 if (!PortAddress)
240 {
241 switch (PortNumber)
242 {
243 case 2:
245 break;
246
247 case 3:
249 break;
250
251 case 4:
253 break;
254
255 default:
257 break;
258 }
259 }
260 }
261 else
262 {
263 /* No number, so no EMS */
265 return;
266 }
267#endif
268
269 /* Call arch code to initialize the port */
273 PortAddress,
277 {
278 /* Port seems usable, set it up and get the BIOS GUID */
280
282
283 /* Calculate delay in us based on the baud, assume 9600 if none given */
284 if (!BaudRate)
285 {
286 BaudRate = 9600;
288 }
289
290 WinLdrTerminalDelay = (10 * 1000 * 1000) / (BaudRate / 10) / 6;
291
292 /* Sent an ANSI reset sequence to get the terminal up and running */
293 for (i = 0; i < strlen(AnsiReset); i++)
294 {
297 }
298 }
299}
300
301VOID
303{
304 PCSTR Option;
305
306 /* Start fresh */
309
310 /* Use a direction port if one was given, or use ACPI to detect one instead */
311 Option = NtLdrGetOption(BootOptions, "redirect=");
312 if (Option)
313 {
314 Option += 9;
315 if (_strnicmp(Option, "com", 3) == 0)
316 {
317 Option += 3;
320 }
321 else if (_strnicmp(Option, "usebiossettings", 15) == 0)
322 {
323 // FIXME: TODO!
324 UiDrawStatusText("ACPI SRT/SPCR Table Not Supported...");
325 return;
326 }
327 else
328 {
331 {
333 }
334 }
335 }
336
337 /* Use a direction baudrate if one was given */
338 Option = NtLdrGetOption(BootOptions, "redirectbaudrate=");
339 if (Option)
340 {
341 Option += 17;
342 // LoaderRedirectionInformation.BaudRate = atoi(Option);
343 if (strncmp(Option, "115200", 6) == 0)
344 {
346 }
347 else if (strncmp(Option, "57600", 5) == 0)
348 {
350 }
351 else if (strncmp(Option, "19200", 5) == 0)
352 {
354 }
355 else
356 {
358 }
359 }
360
361 /* Enable headless support if parameters were found */
363 {
365 {
367 }
368
370 }
371}
372
373/* EOF */
unsigned char BOOLEAN
Type
Definition: Type.h:7
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
@ BootOptions
Definition: bl.h:898
VOID UiDrawStatusText(PCSTR StatusText)
Definition: ui.c:286
VOID NTAPI CpPutByte(IN PCPPORT Port, IN UCHAR Byte)
Definition: cport.c:303
NTSTATUS NTAPI CpInitialize(IN PCPPORT Port, IN PUCHAR Address, IN ULONG BaudRate)
Definition: cport.c:85
#define CP_GET_SUCCESS
Definition: cportlib.h:18
VOID NTAPI CpEnableFifo(IN PUCHAR Address, IN BOOLEAN Enable)
Definition: cport.c:51
USHORT NTAPI CpGetByte(IN PCPPORT Port, OUT PUCHAR Byte, IN BOOLEAN Wait, IN BOOLEAN Poll)
Definition: cport.c:253
BOOLEAN NTAPI CpDoesPortExist(IN PUCHAR Address)
Definition: cport.c:224
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
unsigned char Byte
Definition: zlib.h:37
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
CPPORT Port[4]
Definition: headless.c:35
BOOLEAN WinLdrPortInitialize(IN ULONG BaudRate, IN ULONG PortNumber, IN PUCHAR PortAddress, IN BOOLEAN TerminalConnected, OUT PULONG PortId)
Definition: headless.c:65
VOID WinLdrLoadGUID(OUT PGUID SystemGuid)
Definition: headless.c:46
#define SYSID_UUID_DATA_SIZE
Definition: headless.c:17
BOOLEAN WinLdrPortGetByte(IN ULONG PortId, OUT PUCHAR Byte)
Definition: headless.c:184
VOID WinLdrSetupEms(IN PCSTR BootOptions)
Definition: headless.c:302
struct _SYSID_UUID_ENTRY SYSID_UUID_ENTRY
VOID WinLdrInitializeHeadlessPort(VOID)
Definition: headless.c:206
#define SYSID_TYPE_UUID
Definition: headless.c:16
BOOLEAN WinLdrPortPollOnly(IN ULONG PortId)
Definition: headless.c:191
ULONG WinLdrTerminalDeviceId
Definition: headless.c:32
struct _SYSID_UUID_ENTRY * PSYSID_UUID_ENTRY
HEADLESS_LOADER_BLOCK LoaderRedirectionInformation
Definition: headless.c:30
VOID WinLdrEnableFifo(IN ULONG PortId, IN BOOLEAN Enable)
Definition: headless.c:199
ULONG WinLdrTerminalDelay
Definition: headless.c:33
VOID WinLdrPortPutByte(IN ULONG PortId, IN UCHAR Byte)
Definition: headless.c:177
BOOLEAN WinLdrTerminalConnected
Definition: headless.c:31
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define ASSERT(a)
Definition: mode.c:44
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
PCSTR NtLdrGetOption(IN PCSTR Options, IN PCSTR OptionName)
Definition: ntldropts.c:128
VOID StallExecutionProcessor(ULONG Microseconds)
Definition: pchw.c:60
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
ULONG PortNumber
Definition: storport.c:18
UCHAR IsMMIODevice
Definition: arc.h:367
PUCHAR PortAddress
Definition: arc.h:359
USHORT PciDeviceId
Definition: arc.h:360
UCHAR TerminalType
Definition: arc.h:368
Definition: headless.c:20
UCHAR Checksum
Definition: headless.c:22
UCHAR UUID[SYSID_UUID_DATA_SIZE]
Definition: headless.c:24
USHORT Length
Definition: headless.c:23
UCHAR Type[6]
Definition: headless.c:21
uint32_t * PULONG
Definition: typedefs.h:59
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3601
unsigned char UCHAR
Definition: xmlstorage.h:181