ReactOS  0.4.14-dev-77-gd9e7c48
bootvid.c
Go to the documentation of this file.
1 #include "precomp.h"
2 
3 /* PRIVATE FUNCTIONS *********************************************************/
4 
5 static BOOLEAN
6 NTAPI
8 {
9  USHORT Cmd;
10  UCHAR Major, Minor;
11  USHORT Port;
12  USHORT Count;
13  UCHAR Index;
14  UCHAR Value;
15  USHORT ShortValue;
16 
17  /* First make sure that we have a Command Stream */
18  if (!CmdStream) return TRUE;
19 
20  /* Loop as long as we have commands */
21  while (*CmdStream != EOD)
22  {
23  /* Get the next command and its Major and Minor functions */
24  Cmd = *CmdStream++;
25  Major = Cmd & 0xF0;
26  Minor = Cmd & 0x0F;
27 
28  /* Check which major function this is */
29  if (Major == INOUT)
30  {
31  /* Check the minor function */
32  if (Minor & IO /* CMD_STREAM_READ */)
33  {
34  /* Check the sub-type */
35  if (Minor & BW /* CMD_STREAM_USHORT */)
36  {
37  /* Get the port and read an USHORT from it */
38  Port = *CmdStream++;
39  ShortValue = __inpw(Port);
40  }
41  else // if (Minor & CMD_STREAM_WRITE)
42  {
43  /* Get the port and read an UCHAR from it */
44  Port = *CmdStream++;
45  Value = __inpb(Port);
46  }
47  }
48  else if (Minor & MULTI /* CMD_STREAM_WRITE_ARRAY */)
49  {
50  /* Check the sub-type */
51  if (Minor & BW /* CMD_STREAM_USHORT */)
52  {
53  /* Get the port and the count of elements */
54  Port = *CmdStream++;
55  Count = *CmdStream++;
56 
57  /* Write the USHORT to the port; the buffer is what's in the command stream */
59 
60  /* Move past the buffer in the command stream */
61  CmdStream += Count;
62  }
63  else // if (Minor & CMD_STREAM_WRITE)
64  {
65  /* Get the port and the count of elements */
66  Port = *CmdStream++;
67  Count = *CmdStream++;
68 
69  /* Loop the command array */
70  for (; Count; --Count, ++CmdStream)
71  {
72  /* Get the UCHAR and write it to the port */
73  Value = (UCHAR)*CmdStream;
74  __outpb(Port, Value);
75  }
76  }
77  }
78  else if (Minor & BW /* CMD_STREAM_USHORT */)
79  {
80  /* Get the port */
81  Port = *CmdStream++;
82 
83  /* Get the USHORT and write it to the port */
84  ShortValue = *CmdStream++;
85  __outpw(Port, ShortValue);
86  }
87  else // if (Minor & CMD_STREAM_WRITE)
88  {
89  /* Get the port */
90  Port = *CmdStream++;
91 
92  /* Get the UCHAR and write it to the port */
93  Value = (UCHAR)*CmdStream++;
94  __outpb(Port, Value);
95  }
96  }
97  else if (Major == METAOUT)
98  {
99  /* Check the minor function. Note these are not flags. */
100  switch (Minor)
101  {
102  case INDXOUT:
103  {
104  /* Get the port, the count of elements and the start index */
105  Port = *CmdStream++;
106  Count = *CmdStream++;
107  Index = (UCHAR)*CmdStream++;
108 
109  /* Loop the command array */
110  for (; Count; --Count, ++Index, ++CmdStream)
111  {
112  /* Get the USHORT and write it to the port */
113  ShortValue = (USHORT)Index + ((*CmdStream) << 8);
114  __outpw(Port, ShortValue);
115  }
116  break;
117  }
118 
119  case ATCOUT:
120  {
121  /* Get the port, the count of elements and the start index */
122  Port = *CmdStream++;
123  Count = *CmdStream++;
124  Index = (UCHAR)*CmdStream++;
125 
126  /* Loop the command array */
127  for (; Count; --Count, ++Index, ++CmdStream)
128  {
129  /* Write the index */
130  __outpb(Port, Index);
131 
132  /* Get the UCHAR and write it to the port */
133  Value = (UCHAR)*CmdStream;
134  __outpb(Port, Value);
135  }
136  break;
137  }
138 
139  case MASKOUT:
140  {
141  /* Get the port */
142  Port = *CmdStream++;
143 
144  /* Read the current value and add the stream data */
145  Value = __inpb(Port);
146  Value &= *CmdStream++;
147  Value ^= *CmdStream++;
148 
149  /* Write the value */
150  __outpb(Port, Value);
151  break;
152  }
153 
154  default:
155  /* Unknown command, fail */
156  return FALSE;
157  }
158  }
159  else if (Major != NCMD)
160  {
161  /* Unknown major function, fail */
162  return FALSE;
163  }
164  }
165 
166  /* If we got here, return success */
167  return TRUE;
168 }
169 
170 static BOOLEAN
171 NTAPI
173 {
174  UCHAR OrgGCAddr, OrgReadMap, OrgBitMask;
175  UCHAR OrgSCAddr, OrgMemMode;
176  UCHAR i;
177 
178  /* Remember the original state of the Graphics Controller Address register */
180 
181  /*
182  * Write the Read Map register with a known state so we can verify
183  * that it isn't changed after we fool with the Bit Mask. This ensures
184  * that we're dealing with indexed registers, since both the Read Map and
185  * the Bit Mask are addressed at GRAPH_DATA_PORT.
186  */
188 
189  /*
190  * If we can't read back the Graphics Address register setting we just
191  * performed, it's not readable and this isn't a VGA.
192  */
194  return FALSE;
195 
196  /*
197  * Set the Read Map register to a known state.
198  */
199  OrgReadMap = __inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT);
201 
202  /* Read it back... it should be the same */
204  {
205  /*
206  * The Read Map setting we just performed can't be read back; not a
207  * VGA. Restore the default Read Map state and fail.
208  */
210  return FALSE;
211  }
212 
213  /* Remember the original setting of the Bit Mask register */
215 
216  /* Read it back... it should be the same */
218  {
219  /*
220  * The Graphics Address register setting we just made can't be read
221  * back; not a VGA. Restore the default Read Map state and fail.
222  */
225  return FALSE;
226  }
227 
228  /* Read the VGA Data Register */
229  OrgBitMask = __inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT);
230 
231  /*
232  * Set up the initial test mask we'll write to and read from the Bit Mask,
233  * and loop on the bitmasks.
234  */
235  for (i = 0xBB; i; i >>= 1)
236  {
237  /* Write the test mask to the Bit Mask */
239 
240  /* Read it back... it should be the same */
242  {
243  /*
244  * The Bit Mask is not properly writable and readable; not a VGA.
245  * Restore the Bit Mask and Read Map to their default states and fail.
246  */
250  return FALSE;
251  }
252  }
253 
254  /*
255  * There's something readable at GRAPH_DATA_PORT; now switch back and
256  * make sure that the Read Map register hasn't changed, to verify that
257  * we're dealing with indexed registers.
258  */
260 
261  /* Read it back */
263  {
264  /*
265  * The Read Map is not properly writable and readable; not a VGA.
266  * Restore the Bit Mask and Read Map to their default states, in case
267  * this is an EGA, so subsequent writes to the screen aren't garbled.
268  * Then fail.
269  */
273  return FALSE;
274  }
275 
276  /*
277  * We've pretty surely verified the existence of the Bit Mask register.
278  * Put the Graphics Controller back to the original state.
279  */
284 
285  /*
286  * Now, check for the existence of the Chain4 bit.
287  */
288 
289  /*
290  * Remember the original states of the Sequencer Address and Memory Mode
291  * registers.
292  */
295 
296  /* Read it back... it should be the same */
298  {
299  /*
300  * Couldn't read back the Sequencer Address register setting
301  * we just performed, fail.
302  */
303  return FALSE;
304  }
305 
306  /* Read sequencer Data */
307  OrgMemMode = __inpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT);
308 
309  /*
310  * Toggle the Chain4 bit and read back the result. This must be done during
311  * sync reset, since we're changing the chaining state.
312  */
313 
314  /* Begin sync reset */
316 
317  /* Toggle the Chain4 bit */
320 
321  /* Read it back... it should be the same */
322  if (__inpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT) != (OrgMemMode ^ CHAIN4_MASK))
323  {
324  /*
325  * Chain4 bit is not there, not a VGA.
326  * Set text mode default for Memory Mode register.
327  */
329 
330  /* End sync reset */
332 
333  /* Fail */
334  return FALSE;
335  }
336 
337  /*
338  * It's a VGA.
339  */
340 
341  /* Restore the original Memory Mode setting */
342  __outpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT, OrgMemMode);
343 
344  /* End sync reset */
346 
347  /* Restore the original Sequencer Address setting */
349 
350  /* VGA is present! */
351  return TRUE;
352 }
353 
354 /* PUBLIC FUNCTIONS **********************************************************/
355 
356 /*
357  * @implemented
358  */
359 BOOLEAN
360 NTAPI
362 {
363  ULONG_PTR Context = 0;
365  PHYSICAL_ADDRESS NullAddress = {{0, 0}}, VgaAddress;
367  BOOLEAN Result;
368  ULONG_PTR Base;
369 
370  /* Make sure that we have a bus translation function */
371  if (!HalFindBusAddressTranslation) return FALSE;
372 
373  /* Loop trying to find possible VGA base addresses */
374  while (TRUE)
375  {
376  /* Get the VGA Register address */
377  AddressSpace = 1;
378  Result = HalFindBusAddressTranslation(NullAddress,
379  &AddressSpace,
381  &Context,
382  TRUE);
383  if (!Result) return FALSE;
384 
385  /* See if this is I/O Space, which we need to map */
386  if (!AddressSpace)
387  {
388  /* Map it */
390  }
391  else
392  {
393  /* The base is the translated address, no need to map I/O space */
395  }
396 
397  /* Try to see if this is VGA */
399  if (VgaIsPresent())
400  {
401  /* Translate the VGA Memory Address */
402  VgaAddress.LowPart = MEM_VGA;
403  VgaAddress.HighPart = 0;
404  AddressSpace = 0;
406  &AddressSpace,
408  &Context,
409  FALSE);
410  if (Result) break;
411  }
412  else
413  {
414  /* It's not, so unmap the I/O space if we mapped it */
416  }
417 
418  /* Continue trying to see if there's any other address */
419  }
420 
421  /* Success! See if this is I/O Space, which we need to map */
422  if (!AddressSpace)
423  {
424  /* Map it */
426  MEM_VGA_SIZE,
427  MmNonCached);
428  }
429  else
430  {
431  /* The base is the translated address, no need to map I/O space */
433  }
434 
435  /* Set the VGA Memory Base */
436  VgaBase = Base;
437 
438  /* Now check if we have to set the mode */
439  if (SetMode)
440  {
441  /* Clear the current position */
442  curr_x = 0;
443  curr_y = 0;
444 
445  /* Reset the display and initialize it */
446  if (HalResetDisplay())
447  {
448  /* The HAL handled the display, re-initialize only the AC registers */
450  }
451  else
452  {
453  /* The HAL didn't handle the display, fully re-initialize the VGA */
455  }
456  }
457 
458  /* VGA is ready */
459  return TRUE;
460 }
461 
462 /*
463  * @implemented
464  */
465 VOID
466 NTAPI
468 {
469  /* Clear the current position */
470  curr_x = 0;
471  curr_y = 0;
472 
473  /* Clear the screen with HAL if we were asked to */
474  if (HalReset)
475  {
476  if (!HalResetDisplay())
477  {
478  /* The HAL didn't handle the display, fully re-initialize the VGA */
480  }
481  }
482 
483  /* Always re-initialize the AC registers */
485 
486  /* Re-initialize the palette and fill the screen black */
488  VidSolidColorFill(0, 0, 639, 479, 0);
489 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
_Out_opt_ PULONG Minor
Definition: cmfuncs.h:44
#define HalResetDisplay
Definition: halfuncs.h:45
#define METAOUT
Definition: cmdcnst.h:62
CPPORT Port[4]
Definition: headless.c:34
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define IND_MEMORY_MODE
Definition: vga.h:117
#define MULTI
Definition: cmdcnst.h:69
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
BOOLEAN NTAPI VidInitialize(IN BOOLEAN SetMode)
Definition: bootvid.c:278
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
#define BIT_MASK_DEFAULT
Definition: vga.h:167
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define END_SYNC_RESET_VALUE
Definition: vga.h:125
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG _Out_ PPHYSICAL_ADDRESS TranslatedAddress
Definition: iofuncs.h:2268
#define IND_READ_MAP
Definition: vga.h:111
#define IND_SYNC_RESET
Definition: vga.h:115
#define READ_MAP_DEFAULT
Definition: vga.h:168
#define BW
Definition: cmdcnst.h:70
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG_PTR VgaRegisterBase
Definition: vga.c:66
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define MEMORY_MODE_TEXT_DEFAULT
Definition: vga.h:166
USHORT AT_Initialization[]
Definition: bootdata.c:7
#define VGA_BASE_IO_PORT
Definition: vga.h:38
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define START_SYNC_RESET_VALUE
Definition: vga.h:123
#define CHAIN4_MASK
Definition: vga.h:151
#define SEQ_DATA_PORT
Definition: vga.h:70
static BOOLEAN NTAPI VgaInterpretCmdStream(IN PUSHORT CmdStream)
Definition: bootvid.c:7
#define MASKOUT
Definition: cmdcnst.h:77
#define READ_MAP_TEST_SETTING
Definition: vga.h:159
static BOOLEAN NTAPI VgaIsPresent(VOID)
Definition: bootvid.c:172
VOID NTAPI VidResetDisplay(IN BOOLEAN HalReset)
Definition: bootvid.c:313
#define IND_BIT_MASK
Definition: vga.h:114
VOID NTAPI InitializePalette(VOID)
Definition: vga.c:295
#define GRAPH_ADDRESS_PORT
Definition: vga.h:81
static const UCHAR Index[8]
Definition: usbohci.c:18
#define __inpw(Port)
Definition: precomp.h:55
unsigned char UCHAR
Definition: xmlstorage.h:181
Definition: sacdrv.h:277
#define INDXOUT
Definition: cmdcnst.h:75
#define INOUT
Definition: cmdcnst.h:61
#define __inpb(Port)
Definition: precomp.h:52
ULONG LowPart
Definition: typedefs.h:104
#define IO
Definition: cmdcnst.h:71
#define SEQ_ADDR_MASK
Definition: vga.h:145
#define __outpw(Port, Value)
Definition: precomp.h:61
#define SEQ_ADDRESS_PORT
Definition: vga.h:69
VOID NTAPI VidSolidColorFill(IN ULONG Left, IN ULONG Top, IN ULONG Right, IN ULONG Bottom, IN UCHAR Color)
Definition: bootvid.c:538
ULONG curr_y
Definition: vga.c:69
#define MEM_VGA_SIZE
Definition: vga.h:22
ULONG_PTR VgaBase
Definition: vga.c:67
unsigned short USHORT
Definition: pedump.c:61
#define HalFindBusAddressTranslation
Definition: halfuncs.h:44
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
#define ATCOUT
Definition: cmdcnst.h:76
#define NCMD
Definition: cmdcnst.h:63
#define EOD
Definition: cmdcnst.h:60
unsigned int ULONG
Definition: retypes.h:1
#define __outpb(Port, Value)
Definition: precomp.h:58
#define ULONG_PTR
Definition: config.h:101
ULONG curr_x
Definition: vga.c:68
#define MEM_VGA
Definition: vga.h:21
#define GRAPH_DATA_PORT
Definition: vga.h:82
#define GRAPH_ADDR_MASK
Definition: vga.h:144
unsigned short * PUSHORT
Definition: retypes.h:2
VOID NTAPI WRITE_PORT_BUFFER_USHORT(IN PUSHORT Port, IN PUSHORT Buffer, IN ULONG Count)
Definition: portio.c:87
USHORT VGA_640x480[]
Definition: bootdata.c:38