ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

display.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.