3 * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
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.
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.
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.
19 /* $Id: display.c 23907 2006-09-04 05:52:23Z arty $
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: ntoskrnl/hal/x86/display.c
24 * PURPOSE: Blue screen display
25 * PROGRAMMER: Eric Kohl
31 * Portions of this code are from the XFree86 Project and available from the
34 * Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
36 * Permission is hereby granted, free of charge, to any person obtaining a copy
37 * of this software and associated documentation files (the "Software"), to
38 * deal in the Software without restriction, including without limitation the
39 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
40 * sell copies of the Software, and to permit persons to whom the Software is
41 * furnished to do so, subject to the following conditions:
43 * The above copyright notice and this permission notice shall be included in
44 * all copies or substantial portions of the Software.
46 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49 * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
50 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
51 * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
53 * Except as contained in this notice, the name of the XFree86 Project shall
54 * not be used in advertising or otherwise to promote the sale, use or other
55 * dealings in this Software without prior written authorization from the
61 * So, who owns the physical display and is allowed to write to it?
63 * In MS NT, upon boot HAL owns the display. Somewhere in the boot
64 * sequence (haven't figured out exactly where or by who), some
65 * component calls HalAcquireDisplayOwnership. From that moment on,
66 * the display is owned by that component and is switched to graphics
67 * mode. The display is not supposed to return to text mode, except
68 * in case of a bug check. The bug check will call HalDisplayString
69 * to output a string to the text screen. HAL will notice that it
70 * currently doesn't own the display and will re-take ownership, by
71 * calling the callback function passed to HalAcquireDisplayOwnership.
72 * After the bugcheck, execution is halted. So, under NT, the only
73 * possible sequence of display modes is text mode -> graphics mode ->
74 * text mode (the latter hopefully happening very infrequently).
76 * Things are a little bit different in the current state of ReactOS.
77 * We want to have a functional interactive text mode. We should be
78 * able to switch from text mode to graphics mode when a GUI app is
79 * started and switch back to text mode when it's finished. Then, when
80 * another GUI app is started, another switch to and from graphics mode
81 * is possible. Also, when the system bugchecks in graphics mode we want
82 * to switch back to text mode to show the registers and stack trace.
83 * Last but not least, HalDisplayString is used a lot more in ReactOS,
84 * e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option
86 * 3 Components are involved in Reactos: HAL, BLUE.SYS and VIDEOPRT.SYS.
87 * As in NT, on boot HAL owns the display. When entering the text mode
88 * command interpreter, BLUE.SYS kicks in. It will write directly to the
89 * screen, more or less behind HALs back.
90 * When a GUI app is started, WIN32K.SYS will open the DISPLAY device.
91 * This open call will end up in VIDEOPRT.SYS. That component will then
92 * take ownership of the display by calling HalAcquireDisplayOwnership.
93 * When the GUI app terminates (WIN32K.SYS will close the DISPLAY device),
94 * we want to give ownership of the display back to HAL. Using the
95 * standard exported HAL functions, that's a bit of a problem, because
96 * there is no function defined to do that. In NT, this is handled by
97 * HalDisplayString, but that solution isn't satisfactory in ReactOS,
98 * because HalDisplayString is (in some cases) also used to output debug
99 * messages. If we do it the NT way, the first debug message output while
100 * in graphics mode would switch the display back to text mode.
101 * So, instead, if HalDisplayString detects that HAL doesn't have ownership
102 * of the display, it doesn't do anything.
103 * To return ownership to HAL, a new function is exported,
104 * HalReleaseDisplayOwnership. This function is called by the DISPLAY
105 * device Close routine in VIDEOPRT.SYS. It is also called at the beginning
106 * of a bug check, so HalDisplayString is activated again.
107 * Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS
108 * should also refrain from writing to the screen buffer. The text mode
109 * screen buffer might overlap the graphics mode screen buffer, so changing
110 * something in the text mode buffer might mess up the graphics screen. To
111 * allow BLUE.SYS to detect if HAL owns the display, another new function is
112 * exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to
113 * check if it's allowed to touch the text mode buffer.
115 * In an ideal world, when HAL takes ownership of the display, it should set
116 * up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10
117 * calls. Unfortunately, this will require HAL to setup a real-mode interrupt
118 * table etc. So, we chickened out of that by having the loader set up the
119 * display before switching to protected mode. If HAL is given back ownership
120 * after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS,
121 * since there is already support for them via the VideoPortInt10 routine.
127 #include <ppcdebug.h>
132 boot_infos_t PpcEarlybootInfo
;
134 #define SCREEN_SYNCHRONIZATION
136 /* VARIABLES ****************************************************************/
138 static ULONG CursorX
= 0; /* Cursor Position */
139 static ULONG CursorY
= 0;
140 static ULONG SizeX
= 80; /* Display size */
141 static ULONG SizeY
= 25;
143 static BOOLEAN DisplayInitialized
= FALSE
;
144 static BOOLEAN HalOwnsDisplay
= TRUE
;
145 static ULONG GraphVideoBuffer
= 0;
146 static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters
= NULL
;
148 extern UCHAR XboxFont8x16
[];
149 extern void SetPhys( ULONG Addr
, ULONG Data
);
150 extern ULONG
GetPhys( ULONG Addr
);
151 extern void SetPhysByte( ULONG Addr
, ULONG Data
);
153 /* PRIVATE FUNCTIONS *********************************************************/
156 HalClearDisplay (UCHAR CharAttribute
)
160 PpcEarlybootInfo
.dispDeviceRowBytes
*
161 PpcEarlybootInfo
.dispDeviceRect
[3];
162 for(i
= 0; i
< deviceSize
; i
+= sizeof(int) )
163 SetPhys(GraphVideoBuffer
+ i
, CharAttribute
);
170 /* STATIC FUNCTIONS *********************************************************/
173 HalScrollDisplay (VOID
)
175 ULONG i
, deviceSize
=
176 PpcEarlybootInfo
.dispDeviceRowBytes
*
177 PpcEarlybootInfo
.dispDeviceRect
[3];
178 ULONG Dest
= (ULONG
)GraphVideoBuffer
,
179 Src
= (ULONG
)(GraphVideoBuffer
+ (16 * PpcEarlybootInfo
.dispDeviceRowBytes
));
182 (PpcEarlybootInfo
.dispDeviceRowBytes
*
183 (PpcEarlybootInfo
.dispDeviceRect
[3]-16));
187 SetPhys((ULONG
)Dest
, GetPhys(Src
));
191 /* Clear the bottom row */
192 for(i
= End
; i
< deviceSize
; i
+= sizeof(int) )
193 SetPhys(GraphVideoBuffer
+ i
, 1);
197 HalPutCharacter (CHAR Character
)
199 WRITE_PORT_UCHAR((PVOID
)0x3f8, Character
);
204 (16 * PpcEarlybootInfo
.dispDeviceRowBytes
* CursorY
) +
205 (8 * (PpcEarlybootInfo
.dispDeviceDepth
/ 8) * CursorX
)), RowDest
;
208 for( i
= 0; i
< 16; i
++ ) {
210 for( j
= 0; j
< 8; j
++ ) {
211 ByteToPlace
= ((128 >> j
) & (XboxFont8x16
[(16 * Character
) + i
])) ? 0xff : 1;
212 for( k
= 0; k
< PpcEarlybootInfo
.dispDeviceDepth
/ 8; k
++, RowDest
++ ) {
213 SetPhysByte(RowDest
, ByteToPlace
);
216 Dest
+= PpcEarlybootInfo
.dispDeviceRowBytes
;
221 /* PRIVATE FUNCTIONS ********************************************************/
224 HalInitializeDisplay (PROS_LOADER_PARAMETER_BLOCK LoaderBlock
)
226 * FUNCTION: Initalize the display
228 * InitParameters = Parameters setup by the boot loader
231 if (! DisplayInitialized
)
233 boot_infos_t
*XBootInfo
= (boot_infos_t
*)LoaderBlock
->ArchExtra
;
234 GraphVideoBuffer
= (ULONG
)XBootInfo
->dispDeviceBase
;
235 memcpy(&PpcEarlybootInfo
, XBootInfo
, sizeof(*XBootInfo
));
237 /* Set cursor position */
241 SizeX
= XBootInfo
->dispDeviceRowBytes
/ XBootInfo
->dispDeviceDepth
;
242 SizeY
= XBootInfo
->dispDeviceRect
[3] / 16;
246 DisplayInitialized
= TRUE
;
251 /* PUBLIC FUNCTIONS *********************************************************/
254 HalReleaseDisplayOwnership(VOID
)
256 * FUNCTION: Release ownership of display back to HAL
259 if (HalResetDisplayParameters
== NULL
)
262 if (HalOwnsDisplay
== TRUE
)
265 HalOwnsDisplay
= TRUE
;
271 HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters
)
275 * ResetDisplayParameters = Pointer to a driver specific
279 HalOwnsDisplay
= FALSE
;
280 HalResetDisplayParameters
= ResetDisplayParameters
;
284 HalDisplayString(IN PCH String
)
286 * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
287 * already and displays a string
289 * string = ASCII string to display
290 * NOTE: Use with care because there is no support for returning from BSOD
295 //static KSPIN_LOCK Lock;
297 BOOLEAN InterruptsEnabled
= __readmsr();
299 /* See comment at top of file */
300 if (! HalOwnsDisplay
|| ! DisplayInitialized
)
307 KeRaiseIrql(HIGH_LEVEL
, &OldIrql
);
308 //KiAcquireSpinLock(&Lock);
319 else if (*pch
== '\b')
326 else if (*pch
!= '\r')
328 HalPutCharacter (*pch
);
331 if (CursorX
>= SizeX
)
338 if (CursorY
>= SizeY
)
347 __writemsr(InterruptsEnabled
);
349 //KiReleaseSpinLock(&Lock);
350 KeLowerIrql(OldIrql
);
354 HalQueryDisplayParameters(OUT PULONG DispSizeX
,
355 OUT PULONG DispSizeY
,
356 OUT PULONG CursorPosX
,
357 OUT PULONG CursorPosY
)
364 *CursorPosX
= CursorX
;
366 *CursorPosY
= CursorY
;
371 HalSetDisplayParameters(IN ULONG CursorPosX
,
374 CursorX
= (CursorPosX
< SizeX
) ? CursorPosX
: SizeX
- 1;
375 CursorY
= (CursorPosY
< SizeY
) ? CursorPosY
: SizeY
- 1;
380 HalQueryDisplayOwnership(VOID
)
382 return !HalOwnsDisplay
;