Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendisplay.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* $Id: display.c 23907 2006-09-04 05:52:23Z arty $ 00020 * 00021 * COPYRIGHT: See COPYING in the top level directory 00022 * PROJECT: ReactOS kernel 00023 * FILE: ntoskrnl/hal/x86/display.c 00024 * PURPOSE: Blue screen display 00025 * PROGRAMMER: Eric Kohl 00026 * UPDATE HISTORY: 00027 * Created 08/10/99 00028 */ 00029 00030 /* 00031 * Portions of this code are from the XFree86 Project and available from the 00032 * following license: 00033 * 00034 * Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved. 00035 * 00036 * Permission is hereby granted, free of charge, to any person obtaining a copy 00037 * of this software and associated documentation files (the "Software"), to 00038 * deal in the Software without restriction, including without limitation the 00039 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 00040 * sell copies of the Software, and to permit persons to whom the Software is 00041 * furnished to do so, subject to the following conditions: 00042 * 00043 * The above copyright notice and this permission notice shall be included in 00044 * all copies or substantial portions of the Software. 00045 * 00046 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00047 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00048 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00049 * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 00050 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- 00051 * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00052 * 00053 * Except as contained in this notice, the name of the XFree86 Project shall 00054 * not be used in advertising or otherwise to promote the sale, use or other 00055 * dealings in this Software without prior written authorization from the 00056 * XFree86 Project. 00057 */ 00058 00059 /* DISPLAY OWNERSHIP 00060 * 00061 * So, who owns the physical display and is allowed to write to it? 00062 * 00063 * In MS NT, upon boot HAL owns the display. Somewhere in the boot 00064 * sequence (haven't figured out exactly where or by who), some 00065 * component calls HalAcquireDisplayOwnership. From that moment on, 00066 * the display is owned by that component and is switched to graphics 00067 * mode. The display is not supposed to return to text mode, except 00068 * in case of a bug check. The bug check will call HalDisplayString 00069 * to output a string to the text screen. HAL will notice that it 00070 * currently doesn't own the display and will re-take ownership, by 00071 * calling the callback function passed to HalAcquireDisplayOwnership. 00072 * After the bugcheck, execution is halted. So, under NT, the only 00073 * possible sequence of display modes is text mode -> graphics mode -> 00074 * text mode (the latter hopefully happening very infrequently). 00075 * 00076 * Things are a little bit different in the current state of ReactOS. 00077 * We want to have a functional interactive text mode. We should be 00078 * able to switch from text mode to graphics mode when a GUI app is 00079 * started and switch back to text mode when it's finished. Then, when 00080 * another GUI app is started, another switch to and from graphics mode 00081 * is possible. Also, when the system bugchecks in graphics mode we want 00082 * to switch back to text mode to show the registers and stack trace. 00083 * Last but not least, HalDisplayString is used a lot more in ReactOS, 00084 * e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option 00085 * is present. 00086 * 3 Components are involved in Reactos: HAL, BLUE.SYS and VIDEOPRT.SYS. 00087 * As in NT, on boot HAL owns the display. When entering the text mode 00088 * command interpreter, BLUE.SYS kicks in. It will write directly to the 00089 * screen, more or less behind HALs back. 00090 * When a GUI app is started, WIN32K.SYS will open the DISPLAY device. 00091 * This open call will end up in VIDEOPRT.SYS. That component will then 00092 * take ownership of the display by calling HalAcquireDisplayOwnership. 00093 * When the GUI app terminates (WIN32K.SYS will close the DISPLAY device), 00094 * we want to give ownership of the display back to HAL. Using the 00095 * standard exported HAL functions, that's a bit of a problem, because 00096 * there is no function defined to do that. In NT, this is handled by 00097 * HalDisplayString, but that solution isn't satisfactory in ReactOS, 00098 * because HalDisplayString is (in some cases) also used to output debug 00099 * messages. If we do it the NT way, the first debug message output while 00100 * in graphics mode would switch the display back to text mode. 00101 * So, instead, if HalDisplayString detects that HAL doesn't have ownership 00102 * of the display, it doesn't do anything. 00103 * To return ownership to HAL, a new function is exported, 00104 * HalReleaseDisplayOwnership. This function is called by the DISPLAY 00105 * device Close routine in VIDEOPRT.SYS. It is also called at the beginning 00106 * of a bug check, so HalDisplayString is activated again. 00107 * Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS 00108 * should also refrain from writing to the screen buffer. The text mode 00109 * screen buffer might overlap the graphics mode screen buffer, so changing 00110 * something in the text mode buffer might mess up the graphics screen. To 00111 * allow BLUE.SYS to detect if HAL owns the display, another new function is 00112 * exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to 00113 * check if it's allowed to touch the text mode buffer. 00114 * 00115 * In an ideal world, when HAL takes ownership of the display, it should set 00116 * up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10 00117 * calls. Unfortunately, this will require HAL to setup a real-mode interrupt 00118 * table etc. So, we chickened out of that by having the loader set up the 00119 * display before switching to protected mode. If HAL is given back ownership 00120 * after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS, 00121 * since there is already support for them via the VideoPortInt10 routine. 00122 */ 00123 00124 #include <hal.h> 00125 #include <ppcboot.h> 00126 #include <ppcdebug.h> 00127 00128 #define NDEBUG 00129 #include <debug.h> 00130 00131 boot_infos_t PpcEarlybootInfo; 00132 00133 #define SCREEN_SYNCHRONIZATION 00134 00135 /* VARIABLES ****************************************************************/ 00136 00137 static ULONG CursorX = 0; /* Cursor Position */ 00138 static ULONG CursorY = 0; 00139 static ULONG SizeX = 80; /* Display size */ 00140 static ULONG SizeY = 25; 00141 00142 static BOOLEAN DisplayInitialized = FALSE; 00143 static BOOLEAN HalOwnsDisplay = TRUE; 00144 static ULONG GraphVideoBuffer = 0; 00145 static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL; 00146 00147 extern UCHAR XboxFont8x16[]; 00148 extern void SetPhys( ULONG Addr, ULONG Data ); 00149 extern ULONG GetPhys( ULONG Addr ); 00150 extern void SetPhysByte( ULONG Addr, ULONG Data ); 00151 00152 /* PRIVATE FUNCTIONS *********************************************************/ 00153 00154 VOID FASTCALL 00155 HalClearDisplay (UCHAR CharAttribute) 00156 { 00157 ULONG i; 00158 ULONG deviceSize = 00159 PpcEarlybootInfo.dispDeviceRowBytes * 00160 PpcEarlybootInfo.dispDeviceRect[3]; 00161 for(i = 0; i < deviceSize; i += sizeof(int) ) 00162 SetPhys(GraphVideoBuffer + i, CharAttribute); 00163 00164 CursorX = 0; 00165 CursorY = 0; 00166 } 00167 00168 00169 /* STATIC FUNCTIONS *********************************************************/ 00170 00171 VOID STATIC 00172 HalScrollDisplay (VOID) 00173 { 00174 ULONG i, deviceSize = 00175 PpcEarlybootInfo.dispDeviceRowBytes * 00176 PpcEarlybootInfo.dispDeviceRect[3]; 00177 ULONG Dest = (ULONG)GraphVideoBuffer, 00178 Src = (ULONG)(GraphVideoBuffer + (16 * PpcEarlybootInfo.dispDeviceRowBytes)); 00179 ULONG End = (ULONG) 00180 GraphVideoBuffer + 00181 (PpcEarlybootInfo.dispDeviceRowBytes * 00182 (PpcEarlybootInfo.dispDeviceRect[3]-16)); 00183 00184 while( Src < End ) 00185 { 00186 SetPhys((ULONG)Dest, GetPhys(Src)); 00187 Src += 4; Dest += 4; 00188 } 00189 00190 /* Clear the bottom row */ 00191 for(i = End; i < deviceSize; i += sizeof(int) ) 00192 SetPhys(GraphVideoBuffer + i, 1); 00193 } 00194 00195 VOID STATIC FASTCALL 00196 HalPutCharacter (CHAR Character) 00197 { 00198 WRITE_PORT_UCHAR((PVOID)0x3f8, Character); 00199 #if 0 00200 int i,j,k; 00201 ULONG Dest = 00202 (GraphVideoBuffer + 00203 (16 * PpcEarlybootInfo.dispDeviceRowBytes * CursorY) + 00204 (8 * (PpcEarlybootInfo.dispDeviceDepth / 8) * CursorX)), RowDest; 00205 UCHAR ByteToPlace; 00206 00207 for( i = 0; i < 16; i++ ) { 00208 RowDest = Dest; 00209 for( j = 0; j < 8; j++ ) { 00210 ByteToPlace = ((128 >> j) & (XboxFont8x16[(16 * Character) + i])) ? 0xff : 1; 00211 for( k = 0; k < PpcEarlybootInfo.dispDeviceDepth / 8; k++, RowDest++ ) { 00212 SetPhysByte(RowDest, ByteToPlace); 00213 } 00214 } 00215 Dest += PpcEarlybootInfo.dispDeviceRowBytes; 00216 } 00217 #endif 00218 } 00219 00220 /* PRIVATE FUNCTIONS ********************************************************/ 00221 00222 VOID FASTCALL 00223 HalInitializeDisplay (PROS_LOADER_PARAMETER_BLOCK LoaderBlock) 00224 /* 00225 * FUNCTION: Initalize the display 00226 * ARGUMENTS: 00227 * InitParameters = Parameters setup by the boot loader 00228 */ 00229 { 00230 if (! DisplayInitialized) 00231 { 00232 boot_infos_t *XBootInfo = (boot_infos_t *)LoaderBlock->ArchExtra; 00233 GraphVideoBuffer = (ULONG)XBootInfo->dispDeviceBase; 00234 memcpy(&PpcEarlybootInfo, XBootInfo, sizeof(*XBootInfo)); 00235 00236 /* Set cursor position */ 00237 CursorX = 0; 00238 CursorY = 0; 00239 00240 SizeX = XBootInfo->dispDeviceRowBytes / XBootInfo->dispDeviceDepth; 00241 SizeY = XBootInfo->dispDeviceRect[3] / 16; 00242 00243 HalClearDisplay(1); 00244 00245 DisplayInitialized = TRUE; 00246 } 00247 } 00248 00249 00250 /* PUBLIC FUNCTIONS *********************************************************/ 00251 00252 VOID NTAPI 00253 HalReleaseDisplayOwnership(VOID) 00254 /* 00255 * FUNCTION: Release ownership of display back to HAL 00256 */ 00257 { 00258 if (HalResetDisplayParameters == NULL) 00259 return; 00260 00261 if (HalOwnsDisplay == TRUE) 00262 return; 00263 00264 HalOwnsDisplay = TRUE; 00265 HalClearDisplay(0); 00266 } 00267 00268 00269 VOID NTAPI 00270 HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters) 00271 /* 00272 * FUNCTION: 00273 * ARGUMENTS: 00274 * ResetDisplayParameters = Pointer to a driver specific 00275 * reset routine. 00276 */ 00277 { 00278 HalOwnsDisplay = FALSE; 00279 HalResetDisplayParameters = ResetDisplayParameters; 00280 } 00281 00282 VOID NTAPI 00283 HalDisplayString(IN PCH String) 00284 /* 00285 * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there 00286 * already and displays a string 00287 * ARGUMENT: 00288 * string = ASCII string to display 00289 * NOTE: Use with care because there is no support for returning from BSOD 00290 * mode 00291 */ 00292 { 00293 PCH pch; 00294 //static KSPIN_LOCK Lock; 00295 KIRQL OldIrql; 00296 BOOLEAN InterruptsEnabled = __readmsr(); 00297 00298 /* See comment at top of file */ 00299 if (! HalOwnsDisplay || ! DisplayInitialized) 00300 { 00301 return; 00302 } 00303 00304 pch = String; 00305 00306 KeRaiseIrql(HIGH_LEVEL, &OldIrql); 00307 //KiAcquireSpinLock(&Lock); 00308 00309 _disable(); 00310 00311 while (*pch != 0) 00312 { 00313 if (*pch == '\n') 00314 { 00315 CursorY++; 00316 CursorX = 0; 00317 } 00318 else if (*pch == '\b') 00319 { 00320 if (CursorX > 0) 00321 { 00322 CursorX--; 00323 } 00324 } 00325 else if (*pch != '\r') 00326 { 00327 HalPutCharacter (*pch); 00328 CursorX++; 00329 00330 if (CursorX >= SizeX) 00331 { 00332 CursorY++; 00333 CursorX = 0; 00334 } 00335 } 00336 00337 if (CursorY >= SizeY) 00338 { 00339 HalScrollDisplay (); 00340 CursorY = SizeY - 1; 00341 } 00342 00343 pch++; 00344 } 00345 00346 __writemsr(InterruptsEnabled); 00347 00348 //KiReleaseSpinLock(&Lock); 00349 KeLowerIrql(OldIrql); 00350 } 00351 00352 VOID NTAPI 00353 HalQueryDisplayParameters(OUT PULONG DispSizeX, 00354 OUT PULONG DispSizeY, 00355 OUT PULONG CursorPosX, 00356 OUT PULONG CursorPosY) 00357 { 00358 if (DispSizeX) 00359 *DispSizeX = SizeX; 00360 if (DispSizeY) 00361 *DispSizeY = SizeY; 00362 if (CursorPosX) 00363 *CursorPosX = CursorX; 00364 if (CursorPosY) 00365 *CursorPosY = CursorY; 00366 } 00367 00368 00369 VOID NTAPI 00370 HalSetDisplayParameters(IN ULONG CursorPosX, 00371 IN ULONG CursorPosY) 00372 { 00373 CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1; 00374 CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1; 00375 } 00376 00377 00378 BOOLEAN NTAPI 00379 HalQueryDisplayOwnership(VOID) 00380 { 00381 return !HalOwnsDisplay; 00382 } 00383 00384 /* EOF */ Generated on Wed May 23 2012 04:14:56 for ReactOS by
1.7.6.1
|