ReactOS  0.4.14-dev-358-gbef841c
display.c
Go to the documentation of this file.
1 /*
2  * ReactOS kernel
3  * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 /*
20  * COPYRIGHT: See COPYING in the top level directory
21  * PROJECT: ReactOS kernel
22  * FILE: hal/halppc/generic/display.c
23  * PURPOSE: Blue screen display
24  * PROGRAMMER: Eric Kohl
25  * UPDATE HISTORY:
26  * Created 08/10/99
27  */
28 
29 /*
30  * Portions of this code are from the XFree86 Project and available from the
31  * following license:
32  *
33  * Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
34  *
35  * Permission is hereby granted, free of charge, to any person obtaining a copy
36  * of this software and associated documentation files (the "Software"), to
37  * deal in the Software without restriction, including without limitation the
38  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
39  * sell copies of the Software, and to permit persons to whom the Software is
40  * furnished to do so, subject to the following conditions:
41  *
42  * The above copyright notice and this permission notice shall be included in
43  * all copies or substantial portions of the Software.
44  *
45  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48  * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
49  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
50  * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
51  *
52  * Except as contained in this notice, the name of the XFree86 Project shall
53  * not be used in advertising or otherwise to promote the sale, use or other
54  * dealings in this Software without prior written authorization from the
55  * XFree86 Project.
56 */
57 
58 /* DISPLAY OWNERSHIP
59  *
60  * So, who owns the physical display and is allowed to write to it?
61  *
62  * In MS NT, upon boot HAL owns the display. Somewhere in the boot
63  * sequence (haven't figured out exactly where or by who), some
64  * component calls HalAcquireDisplayOwnership. From that moment on,
65  * the display is owned by that component and is switched to graphics
66  * mode. The display is not supposed to return to text mode, except
67  * in case of a bug check. The bug check will call HalDisplayString
68  * to output a string to the text screen. HAL will notice that it
69  * currently doesn't own the display and will re-take ownership, by
70  * calling the callback function passed to HalAcquireDisplayOwnership.
71  * After the bugcheck, execution is halted. So, under NT, the only
72  * possible sequence of display modes is text mode -> graphics mode ->
73  * text mode (the latter hopefully happening very infrequently).
74  *
75  * Things are a little bit different in the current state of ReactOS.
76  * We want to have a functional interactive text mode. We should be
77  * able to switch from text mode to graphics mode when a GUI app is
78  * started and switch back to text mode when it's finished. Then, when
79  * another GUI app is started, another switch to and from graphics mode
80  * is possible. Also, when the system bugchecks in graphics mode we want
81  * to switch back to text mode to show the registers and stack trace.
82  * Last but not least, HalDisplayString is used a lot more in ReactOS,
83  * e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option
84  * is present.
85  * 3 Components are involved in ReactOS: HAL, BLUE.SYS and VIDEOPRT.SYS.
86  * As in NT, on boot HAL owns the display. When entering the text mode
87  * command interpreter, BLUE.SYS kicks in. It will write directly to the
88  * screen, more or less behind HALs back.
89  * When a GUI app is started, WIN32K.SYS will open the DISPLAY device.
90  * This open call will end up in VIDEOPRT.SYS. That component will then
91  * take ownership of the display by calling HalAcquireDisplayOwnership.
92  * When the GUI app terminates (WIN32K.SYS will close the DISPLAY device),
93  * we want to give ownership of the display back to HAL. Using the
94  * standard exported HAL functions, that's a bit of a problem, because
95  * there is no function defined to do that. In NT, this is handled by
96  * HalDisplayString, but that solution isn't satisfactory in ReactOS,
97  * because HalDisplayString is (in some cases) also used to output debug
98  * messages. If we do it the NT way, the first debug message output while
99  * in graphics mode would switch the display back to text mode.
100  * So, instead, if HalDisplayString detects that HAL doesn't have ownership
101  * of the display, it doesn't do anything.
102  * To return ownership to HAL, a new function is exported,
103  * HalReleaseDisplayOwnership. This function is called by the DISPLAY
104  * device Close routine in VIDEOPRT.SYS. It is also called at the beginning
105  * of a bug check, so HalDisplayString is activated again.
106  * Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS
107  * should also refrain from writing to the screen buffer. The text mode
108  * screen buffer might overlap the graphics mode screen buffer, so changing
109  * something in the text mode buffer might mess up the graphics screen. To
110  * allow BLUE.SYS to detect if HAL owns the display, another new function is
111  * exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to
112  * check if it's allowed to touch the text mode buffer.
113  *
114  * In an ideal world, when HAL takes ownership of the display, it should set
115  * up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10
116  * calls. Unfortunately, this will require HAL to setup a real-mode interrupt
117  * table etc. So, we chickened out of that by having the loader set up the
118  * display before switching to protected mode. If HAL is given back ownership
119  * after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS,
120  * since there is already support for them via the VideoPortInt10 routine.
121  */
122 
123 #include <hal.h>
124 #include <ppcboot.h>
125 #include <ppcdebug.h>
126 
127 #define NDEBUG
128 #include <debug.h>
129 
130 boot_infos_t PpcEarlybootInfo;
131 
132 #define SCREEN_SYNCHRONIZATION
133 
134 /* VARIABLES ****************************************************************/
135 
136 static ULONG CursorX = 0; /* Cursor Position */
137 static ULONG CursorY = 0;
138 static ULONG SizeX = 80; /* Display size */
139 static ULONG SizeY = 25;
140 
144 static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
145 
146 extern UCHAR XboxFont8x16[];
147 extern void SetPhys( ULONG Addr, ULONG Data );
148 extern ULONG GetPhys( ULONG Addr );
149 extern void SetPhysByte( ULONG Addr, ULONG Data );
150 
151 /* PRIVATE FUNCTIONS *********************************************************/
152 
154 HalClearDisplay (UCHAR CharAttribute)
155 {
156  ULONG i;
157  ULONG deviceSize =
158  PpcEarlybootInfo.dispDeviceRowBytes *
159  PpcEarlybootInfo.dispDeviceRect[3];
160  for(i = 0; i < deviceSize; i += sizeof(int) )
161  SetPhys(GraphVideoBuffer + i, CharAttribute);
162 
163  CursorX = 0;
164  CursorY = 0;
165 }
166 
167 
168 /* STATIC FUNCTIONS *********************************************************/
169 
170 VOID STATIC
172 {
173  ULONG i, deviceSize =
174  PpcEarlybootInfo.dispDeviceRowBytes *
175  PpcEarlybootInfo.dispDeviceRect[3];
176  ULONG Dest = (ULONG)GraphVideoBuffer,
177  Src = (ULONG)(GraphVideoBuffer + (16 * PpcEarlybootInfo.dispDeviceRowBytes));
178  ULONG End = (ULONG)
180  (PpcEarlybootInfo.dispDeviceRowBytes *
181  (PpcEarlybootInfo.dispDeviceRect[3]-16));
182 
183  while( Src < End )
184  {
185  SetPhys((ULONG)Dest, GetPhys(Src));
186  Src += 4; Dest += 4;
187  }
188 
189  /* Clear the bottom row */
190  for(i = End; i < deviceSize; i += sizeof(int) )
191  SetPhys(GraphVideoBuffer + i, 1);
192 }
193 
196 {
197  WRITE_PORT_UCHAR((PVOID)0x3f8, Character);
198 #if 0
199  int i,j,k;
200  ULONG Dest =
202  (16 * PpcEarlybootInfo.dispDeviceRowBytes * CursorY) +
203  (8 * (PpcEarlybootInfo.dispDeviceDepth / 8) * CursorX)), RowDest;
204  UCHAR ByteToPlace;
205 
206  for( i = 0; i < 16; i++ ) {
207  RowDest = Dest;
208  for( j = 0; j < 8; j++ ) {
209  ByteToPlace = ((128 >> j) & (XboxFont8x16[(16 * Character) + i])) ? 0xff : 1;
210  for( k = 0; k < PpcEarlybootInfo.dispDeviceDepth / 8; k++, RowDest++ ) {
211  SetPhysByte(RowDest, ByteToPlace);
212  }
213  }
214  Dest += PpcEarlybootInfo.dispDeviceRowBytes;
215  }
216 #endif
217 }
218 
219 /* PRIVATE FUNCTIONS ********************************************************/
220 
222 HalInitializeDisplay (PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
223 /*
224  * FUNCTION: Initialize the display
225  * ARGUMENTS:
226  * InitParameters = Parameters setup by the boot loader
227  */
228 {
229  if (! DisplayInitialized)
230  {
231  boot_infos_t *XBootInfo = (boot_infos_t *)LoaderBlock->ArchExtra;
232  GraphVideoBuffer = (ULONG)XBootInfo->dispDeviceBase;
233  memcpy(&PpcEarlybootInfo, XBootInfo, sizeof(*XBootInfo));
234 
235  /* Set cursor position */
236  CursorX = 0;
237  CursorY = 0;
238 
239  SizeX = XBootInfo->dispDeviceRowBytes / XBootInfo->dispDeviceDepth;
240  SizeY = XBootInfo->dispDeviceRect[3] / 16;
241 
242  HalClearDisplay(1);
243 
245  }
246 }
247 
248 
249 /* PUBLIC FUNCTIONS *********************************************************/
250 
251 VOID NTAPI
253 /*
254  * FUNCTION: Release ownership of display back to HAL
255  */
256 {
258  return;
259 
260  if (HalOwnsDisplay != FALSE)
261  return;
262 
264  HalClearDisplay(0);
265 }
266 
267 
268 VOID NTAPI
269 HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
270 /*
271  * FUNCTION:
272  * ARGUMENTS:
273  * ResetDisplayParameters = Pointer to a driver specific
274  * reset routine.
275  */
276 {
278  HalResetDisplayParameters = ResetDisplayParameters;
279 }
280 
281 VOID NTAPI
283 /*
284  * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
285  * already and displays a string
286  * ARGUMENT:
287  * string = ASCII string to display
288  * NOTE: Use with care because there is no support for returning from BSOD
289  * mode
290  */
291 {
292  PCH pch;
293  //static KSPIN_LOCK Lock;
294  KIRQL OldIrql;
295  BOOLEAN InterruptsEnabled = __readmsr();
296 
297  /* See comment at top of file */
299  {
300  return;
301  }
302 
303  pch = String;
304 
306  //KiAcquireSpinLock(&Lock);
307 
308  _disable();
309 
310  while (*pch != 0)
311  {
312  if (*pch == '\n')
313  {
314  CursorY++;
315  CursorX = 0;
316  }
317  else if (*pch == '\b')
318  {
319  if (CursorX > 0)
320  {
321  CursorX--;
322  }
323  }
324  else if (*pch != '\r')
325  {
326  HalPutCharacter (*pch);
327  CursorX++;
328 
329  if (CursorX >= SizeX)
330  {
331  CursorY++;
332  CursorX = 0;
333  }
334  }
335 
336  if (CursorY >= SizeY)
337  {
338  HalScrollDisplay ();
339  CursorY = SizeY - 1;
340  }
341 
342  pch++;
343  }
344 
345  __writemsr(InterruptsEnabled);
346 
347  //KiReleaseSpinLock(&Lock);
349 }
350 
351 VOID NTAPI
353  OUT PULONG DispSizeY,
354  OUT PULONG CursorPosX,
355  OUT PULONG CursorPosY)
356 {
357  if (DispSizeX)
358  *DispSizeX = SizeX;
359  if (DispSizeY)
360  *DispSizeY = SizeY;
361  if (CursorPosX)
362  *CursorPosX = CursorX;
363  if (CursorPosY)
364  *CursorPosY = CursorY;
365 }
366 
367 
368 VOID NTAPI
370  IN ULONG CursorPosY)
371 {
372  CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
373  CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
374 }
375 
376 
379 {
380  return !HalOwnsDisplay;
381 }
382 
383 /* EOF */
#define IN
Definition: typedefs.h:38
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
VOID NTAPI HalDisplayString(IN PCH String)
Definition: display.c:32
char CHAR
Definition: xmlstorage.h:175
static ULONG CursorY
Definition: display.c:137
UCHAR XboxFont8x16[]
Definition: xboxfont.c:23
static WCHAR String[]
Definition: stringtable.c:55
static ULONG SizeX
Definition: display.c:138
#define FASTCALL
Definition: nt_native.h:50
VOID NTAPI HalReleaseDisplayOwnership(VOID)
Definition: display.c:252
#define pch(ap)
Definition: match.c:418
UCHAR KIRQL
Definition: env_spec_w32.h:591
static ULONG GraphVideoBuffer
Definition: display.c:143
boot_infos_t PpcEarlybootInfo
Definition: display.c:130
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
CHAR * PCH
Definition: ntbasedef.h:398
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
VOID NTAPI HalQueryDisplayParameters(OUT PULONG DispSizeX, OUT PULONG DispSizeY, OUT PULONG CursorPosX, OUT PULONG CursorPosY)
Definition: display.c:43
VOID STATIC HalScrollDisplay(VOID)
Definition: display.c:171
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 GLint GLint j
Definition: glfuncs.h:250
static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters
Definition: display.c:144
VOID STATIC FASTCALL HalPutCharacter(CHAR Character)
Definition: display.c:195
ULONG GetPhys(ULONG Addr)
unsigned char UCHAR
Definition: xmlstorage.h:181
static ULONG CursorX
Definition: display.c:136
VOID NTAPI HalSetDisplayParameters(IN ULONG CursorPosX, IN ULONG CursorPosY)
Definition: display.c:57
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define STATIC
Definition: options.h:116
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
VOID FASTCALL HalClearDisplay(UCHAR CharAttribute)
Definition: display.c:154
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
BOOLEAN NTAPI HalQueryDisplayOwnership(VOID)
Definition: display.c:378
static BOOLEAN HalOwnsDisplay
Definition: display.c:142
unsigned int * PULONG
Definition: retypes.h:1
static BOOLEAN DisplayInitialized
Definition: display.c:141
VOID FASTCALL HalInitializeDisplay(PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
Definition: display.c:222
#define OUT
Definition: typedefs.h:39
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
void SetPhys(ULONG Addr, ULONG Data)
void SetPhysByte(ULONG Addr, ULONG Data)
int k
Definition: mpi.c:3369
static ULONG SizeY
Definition: display.c:139
VOID NTAPI HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
Definition: display.c:21
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31