audk/IntelFrameworkModulePkg/Universal/Console/VgaClassDxe/VgaClass.c

1399 lines
30 KiB
C
Raw Normal View History

/**@file
This driver produces a VGA console.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "VgaClass.h"
//
// EFI Driver Binding Protocol for the VGA Class Driver
//
EFI_DRIVER_BINDING_PROTOCOL gVgaClassDriverBinding = {
VgaClassDriverBindingSupported,
VgaClassDriverBindingStart,
VgaClassDriverBindingStop,
0xa,
NULL,
NULL
};
/**
The user Entry Point for module VgaClass. The user code starts with this function.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
InitializeVgaClass(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Install driver model protocol(s).
//
Status = EfiLibInstallAllDriverProtocols (
ImageHandle,
SystemTable,
&gVgaClassDriverBinding,
ImageHandle,
&gVgaClassComponentName,
NULL,
NULL
);
ASSERT_EFI_ERROR (Status);
return Status;
}
//
// Local variables
//
static CHAR16 CrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
typedef struct {
CHAR16 Unicode;
CHAR8 PcAnsi;
CHAR8 Ascii;
} UNICODE_TO_CHAR;
//
// This list is used to define the valid extend chars.
// It also provides a mapping from Unicode to PCANSI or
// ASCII. The ASCII mapping we just made up.
//
//
STATIC UNICODE_TO_CHAR UnicodeToPcAnsiOrAscii[] = {
{
BOXDRAW_HORIZONTAL,
0xc4,
L'-'
},
{
BOXDRAW_VERTICAL,
0xb3,
L'|'
},
{
BOXDRAW_DOWN_RIGHT,
0xda,
L'/'
},
{
BOXDRAW_DOWN_LEFT,
0xbf,
L'\\'
},
{
BOXDRAW_UP_RIGHT,
0xc0,
L'\\'
},
{
BOXDRAW_UP_LEFT,
0xd9,
L'/'
},
{
BOXDRAW_VERTICAL_RIGHT,
0xc3,
L'|'
},
{
BOXDRAW_VERTICAL_LEFT,
0xb4,
L'|'
},
{
BOXDRAW_DOWN_HORIZONTAL,
0xc2,
L'+'
},
{
BOXDRAW_UP_HORIZONTAL,
0xc1,
L'+'
},
{
BOXDRAW_VERTICAL_HORIZONTAL,
0xc5,
L'+'
},
{
BOXDRAW_DOUBLE_HORIZONTAL,
0xcd,
L'-'
},
{
BOXDRAW_DOUBLE_VERTICAL,
0xba,
L'|'
},
{
BOXDRAW_DOWN_RIGHT_DOUBLE,
0xd5,
L'/'
},
{
BOXDRAW_DOWN_DOUBLE_RIGHT,
0xd6,
L'/'
},
{
BOXDRAW_DOUBLE_DOWN_RIGHT,
0xc9,
L'/'
},
{
BOXDRAW_DOWN_LEFT_DOUBLE,
0xb8,
L'\\'
},
{
BOXDRAW_DOWN_DOUBLE_LEFT,
0xb7,
L'\\'
},
{
BOXDRAW_DOUBLE_DOWN_LEFT,
0xbb,
L'\\'
},
{
BOXDRAW_UP_RIGHT_DOUBLE,
0xd4,
L'\\'
},
{
BOXDRAW_UP_DOUBLE_RIGHT,
0xd3,
L'\\'
},
{
BOXDRAW_DOUBLE_UP_RIGHT,
0xc8,
L'\\'
},
{
BOXDRAW_UP_LEFT_DOUBLE,
0xbe,
L'/'
},
{
BOXDRAW_UP_DOUBLE_LEFT,
0xbd,
L'/'
},
{
BOXDRAW_DOUBLE_UP_LEFT,
0xbc,
L'/'
},
{
BOXDRAW_VERTICAL_RIGHT_DOUBLE,
0xc6,
L'|'
},
{
BOXDRAW_VERTICAL_DOUBLE_RIGHT,
0xc7,
L'|'
},
{
BOXDRAW_DOUBLE_VERTICAL_RIGHT,
0xcc,
L'|'
},
{
BOXDRAW_VERTICAL_LEFT_DOUBLE,
0xb5,
L'|'
},
{
BOXDRAW_VERTICAL_DOUBLE_LEFT,
0xb6,
L'|'
},
{
BOXDRAW_DOUBLE_VERTICAL_LEFT,
0xb9,
L'|'
},
{
BOXDRAW_DOWN_HORIZONTAL_DOUBLE,
0xd1,
L'+'
},
{
BOXDRAW_DOWN_DOUBLE_HORIZONTAL,
0xd2,
L'+'
},
{
BOXDRAW_DOUBLE_DOWN_HORIZONTAL,
0xcb,
L'+'
},
{
BOXDRAW_UP_HORIZONTAL_DOUBLE,
0xcf,
L'+'
},
{
BOXDRAW_UP_DOUBLE_HORIZONTAL,
0xd0,
L'+'
},
{
BOXDRAW_DOUBLE_UP_HORIZONTAL,
0xca,
L'+'
},
{
BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE,
0xd8,
L'+'
},
{
BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL,
0xd7,
L'+'
},
{
BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL,
0xce,
L'+'
},
{
BLOCKELEMENT_FULL_BLOCK,
0xdb,
L'*'
},
{
BLOCKELEMENT_LIGHT_SHADE,
0xb0,
L'+'
},
{
GEOMETRICSHAPE_UP_TRIANGLE,
0x1e,
L'^'
},
{
GEOMETRICSHAPE_RIGHT_TRIANGLE,
0x10,
L'>'
},
{
GEOMETRICSHAPE_DOWN_TRIANGLE,
0x1f,
L'v'
},
{
GEOMETRICSHAPE_LEFT_TRIANGLE,
0x11,
L'<'
},
{
ARROW_LEFT,
0x3c,
L'<'
},
{
ARROW_UP,
0x18,
L'^'
},
{
ARROW_RIGHT,
0x3e,
L'>'
},
{
ARROW_DOWN,
0x19,
L'v'
},
{
0x0000,
0x00,
0x00
}
};
//
// Private worker functions
//
STATIC
VOID
SetVideoCursorPosition (
IN VGA_CLASS_DEV *VgaClassDev,
IN UINTN Column,
IN UINTN Row,
IN UINTN MaxColumn
);
STATIC
VOID
WriteCrtc (
IN VGA_CLASS_DEV *VgaClassDev,
IN UINT16 Address,
IN UINT8 Data
);
STATIC
BOOLEAN
LibIsValidTextGraphics (
IN CHAR16 Graphic,
OUT CHAR8 *PcAnsi, OPTIONAL
OUT CHAR8 *Ascii OPTIONAL
);
STATIC
BOOLEAN
IsValidAscii (
IN CHAR16 Ascii
);
STATIC
BOOLEAN
IsValidEfiCntlChar (
IN CHAR16 c
);
EFI_STATUS
EFIAPI
VgaClassDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Supported.
Arguments:
(Standard DriverBinding Protocol Supported() function)
Returns:
EFI_STATUS
--*/
// GC_TODO: This - add argument and description to function comment
// GC_TODO: Controller - add argument and description to function comment
// GC_TODO: RemainingDevicePath - add argument and description to function comment
{
EFI_STATUS Status;
EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;
//
// Open the IO Abstraction(s) needed to perform the supported test
//
Status = gBS->OpenProtocol (
Controller,
&gEfiVgaMiniPortProtocolGuid,
(VOID **) &VgaMiniPort,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Open the IO Abstraction(s) needed to perform the supported test
//
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
NULL,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
return Status;
}
EFI_STATUS
EFIAPI
VgaClassDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Layers the Simple Text Output Protocol on top of the
VGA Mini Port Protocol
Arguments:
(Standard DriverBinding Protocol Start() function)
Returns:
EFI_STATUS
--*/
// GC_TODO: This - add argument and description to function comment
// GC_TODO: Controller - add argument and description to function comment
// GC_TODO: RemainingDevicePath - add argument and description to function comment
// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
{
EFI_STATUS Status;
EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;
EFI_PCI_IO_PROTOCOL *PciIo;
VGA_CLASS_DEV *VgaClassPrivate;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
Status = gBS->HandleProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
(VOID **) &DevicePath
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Report that VGA Class driver is being enabled
//
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
EFI_PROGRESS_CODE,
EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_ENABLE,
DevicePath
);
//
// Open the IO Abstraction(s) needed
//
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->OpenProtocol (
Controller,
&gEfiVgaMiniPortProtocolGuid,
(VOID **) &VgaMiniPort,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Allocate the private device structure
//
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (VGA_CLASS_DEV),
(VOID **) &VgaClassPrivate
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
Controller,
&gEfiVgaMiniPortProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_OUT_OF_RESOURCES;
}
ZeroMem (VgaClassPrivate, sizeof (VGA_CLASS_DEV));
//
// Initialize the private device structure
//
VgaClassPrivate->Signature = VGA_CLASS_DEV_SIGNATURE;
VgaClassPrivate->Handle = Controller;
VgaClassPrivate->VgaMiniPort = VgaMiniPort;
VgaClassPrivate->PciIo = PciIo;
VgaClassPrivate->SimpleTextOut.Reset = VgaClassReset;
VgaClassPrivate->SimpleTextOut.OutputString = VgaClassOutputString;
VgaClassPrivate->SimpleTextOut.TestString = VgaClassTestString;
VgaClassPrivate->SimpleTextOut.ClearScreen = VgaClassClearScreen;
VgaClassPrivate->SimpleTextOut.SetAttribute = VgaClassSetAttribute;
VgaClassPrivate->SimpleTextOut.SetCursorPosition = VgaClassSetCursorPosition;
VgaClassPrivate->SimpleTextOut.EnableCursor = VgaClassEnableCursor;
VgaClassPrivate->SimpleTextOut.QueryMode = VgaClassQueryMode;
VgaClassPrivate->SimpleTextOut.SetMode = VgaClassSetMode;
VgaClassPrivate->SimpleTextOut.Mode = &VgaClassPrivate->SimpleTextOutputMode;
VgaClassPrivate->SimpleTextOutputMode.MaxMode = VgaMiniPort->MaxMode;
VgaClassPrivate->DevicePath = DevicePath;
Status = VgaClassPrivate->SimpleTextOut.SetAttribute (
&VgaClassPrivate->SimpleTextOut,
EFI_TEXT_ATTR (EFI_WHITE,
EFI_BLACK)
);
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
Status = VgaClassPrivate->SimpleTextOut.Reset (
&VgaClassPrivate->SimpleTextOut,
FALSE
);
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
Status = VgaClassPrivate->SimpleTextOut.EnableCursor (
&VgaClassPrivate->SimpleTextOut,
TRUE
);
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
Status = gBS->InstallMultipleProtocolInterfaces (
&Controller,
&gEfiSimpleTextOutProtocolGuid,
&VgaClassPrivate->SimpleTextOut,
NULL
);
return Status;
ErrorExit:
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
EFI_ERROR_CODE | EFI_ERROR_MINOR,
EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,
DevicePath
);
return Status;
}
EFI_STATUS
EFIAPI
VgaClassDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Stop.
Arguments:
(Standard DriverBinding Protocol Stop() function)
Returns:
EFI_STATUS
--*/
// GC_TODO: This - add argument and description to function comment
// GC_TODO: Controller - add argument and description to function comment
// GC_TODO: NumberOfChildren - add argument and description to function comment
// GC_TODO: ChildHandleBuffer - add argument and description to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
EFI_STATUS Status;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
VGA_CLASS_DEV *VgaClassPrivate;
Status = gBS->OpenProtocol (
Controller,
&gEfiSimpleTextOutProtocolGuid,
(VOID **) &SimpleTextOut,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
VgaClassPrivate = VGA_CLASS_DEV_FROM_THIS (SimpleTextOut);
//
// Report that VGA Class driver is being disabled
//
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
EFI_PROGRESS_CODE,
EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_DISABLE,
VgaClassPrivate->DevicePath
);
Status = gBS->UninstallProtocolInterface (
Controller,
&gEfiSimpleTextOutProtocolGuid,
&VgaClassPrivate->SimpleTextOut
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Release PCI I/O and VGA Mini Port Protocols on the controller handle.
//
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
gBS->CloseProtocol (
Controller,
&gEfiVgaMiniPortProtocolGuid,
This->DriverBindingHandle,
Controller
);
gBS->FreePool (VgaClassPrivate);
return EFI_SUCCESS;
}
//
// Simple Text Output Protocol Functions
//
EFI_STATUS
EFIAPI
VgaClassReset (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
ExtendedVerification - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
EFI_STATUS Status;
VGA_CLASS_DEV *VgaClassPrivate;
VgaClassPrivate = VGA_CLASS_DEV_FROM_THIS (This);
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
EFI_PROGRESS_CODE,
EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_RESET,
VgaClassPrivate->DevicePath
);
This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
Status = This->SetMode (This, 0);
if (EFI_ERROR (Status)) {
return Status;
}
return This->ClearScreen (This);
}
EFI_STATUS
EFIAPI
VgaClassOutputString (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN CHAR16 *WString
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
WString - GC_TODO: add argument description
Returns:
EFI_SUCCESS - GC_TODO: Add description for return value
--*/
{
EFI_STATUS Status;
VGA_CLASS_DEV *VgaClassDev;
EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
UINTN MaxColumn;
UINTN MaxRow;
UINT32 VideoChar;
CHAR8 GraphicChar;
VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
Mode = This->Mode;
Status = This->QueryMode (
This,
Mode->Mode,
&MaxColumn,
&MaxRow
);
if (EFI_ERROR (Status)) {
return Status;
}
for (; *WString != CHAR_NULL; WString++) {
switch (*WString) {
case CHAR_BACKSPACE:
if (Mode->CursorColumn > 0) {
Mode->CursorColumn--;
}
break;
case CHAR_LINEFEED:
if (Mode->CursorRow == (INT32) (MaxRow - 1)) {
//
// Scroll the screen by copying the contents
// of the VGA display up one line
//
VgaClassDev->PciIo->CopyMem (
VgaClassDev->PciIo,
EfiPciIoWidthUint32,
VgaClassDev->VgaMiniPort->VgaMemoryBar,
VgaClassDev->VgaMiniPort->VgaMemoryOffset,
VgaClassDev->VgaMiniPort->VgaMemoryBar,
VgaClassDev->VgaMiniPort->VgaMemoryOffset + MaxColumn * 2,
((MaxRow - 1) * MaxColumn) >> 1
);
//
// Print Blank Line of spaces with the current color attributes
//
VideoChar = (Mode->Attribute << 8) | ' ';
VideoChar = (VideoChar << 16) | VideoChar;
VgaClassDev->PciIo->Mem.Write (
VgaClassDev->PciIo,
EfiPciIoWidthFillUint32,
VgaClassDev->VgaMiniPort->VgaMemoryBar,
VgaClassDev->VgaMiniPort->VgaMemoryOffset + (MaxRow - 1) * MaxColumn * 2,
MaxColumn >> 1,
&VideoChar
);
}
if (Mode->CursorRow < (INT32) (MaxRow - 1)) {
Mode->CursorRow++;
}
break;
case CHAR_CARRIAGE_RETURN:
Mode->CursorColumn = 0;
break;
default:
if (!LibIsValidTextGraphics (*WString, &GraphicChar, NULL)) {
//
// Just convert to ASCII
//
GraphicChar = (CHAR8) *WString;
if (!IsValidAscii (GraphicChar)) {
//
// Keep the API from supporting PCANSI Graphics chars
//
GraphicChar = '?';
}
}
VideoChar = (Mode->Attribute << 8) | GraphicChar;
VgaClassDev->PciIo->Mem.Write (
VgaClassDev->PciIo,
EfiPciIoWidthUint16,
VgaClassDev->VgaMiniPort->VgaMemoryBar,
VgaClassDev->VgaMiniPort->VgaMemoryOffset + ((Mode->CursorRow * MaxColumn + Mode->CursorColumn) * 2),
1,
&VideoChar
);
if (Mode->CursorColumn >= (INT32) (MaxColumn - 1)) {
This->OutputString (This, CrLfString);
} else {
Mode->CursorColumn++;
}
break;
}
}
SetVideoCursorPosition (
VgaClassDev,
(UINTN) Mode->CursorColumn,
(UINTN) Mode->CursorRow,
MaxColumn
);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
VgaClassTestString (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN CHAR16 *WString
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
WString - GC_TODO: add argument description
Returns:
EFI_UNSUPPORTED - GC_TODO: Add description for return value
EFI_SUCCESS - GC_TODO: Add description for return value
--*/
{
while (*WString != 0x0000) {
if (!(IsValidAscii (*WString) || IsValidEfiCntlChar (*WString) || LibIsValidTextGraphics (*WString, NULL, NULL))) {
return EFI_UNSUPPORTED;
}
WString++;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
VgaClassClearScreen (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
Returns:
EFI_SUCCESS - GC_TODO: Add description for return value
--*/
{
EFI_STATUS Status;
VGA_CLASS_DEV *VgaClassDev;
UINTN MaxRow;
UINTN MaxColumn;
UINT32 VideoChar;
VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
Status = This->QueryMode (
This,
This->Mode->Mode,
&MaxColumn,
&MaxRow
);
if (EFI_ERROR (Status)) {
return Status;
}
VideoChar = (This->Mode->Attribute << 8) | ' ';
VideoChar = (VideoChar << 16) | VideoChar;
VgaClassDev->PciIo->Mem.Write (
VgaClassDev->PciIo,
EfiPciIoWidthFillUint32,
VgaClassDev->VgaMiniPort->VgaMemoryBar,
VgaClassDev->VgaMiniPort->VgaMemoryOffset,
(MaxRow * MaxColumn) >> 1,
&VideoChar
);
This->SetCursorPosition (This, 0, 0);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
VgaClassSetAttribute (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN Attribute
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
Attribute - GC_TODO: add argument description
Returns:
EFI_SUCCESS - GC_TODO: Add description for return value
EFI_UNSUPPORTED - GC_TODO: Add description for return value
--*/
{
if (Attribute <= EFI_MAX_ATTRIBUTE) {
This->Mode->Attribute = (INT32) Attribute;
return EFI_SUCCESS;
}
return EFI_UNSUPPORTED;
}
EFI_STATUS
EFIAPI
VgaClassSetCursorPosition (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN Column,
IN UINTN Row
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
Column - GC_TODO: add argument description
Row - GC_TODO: add argument description
Returns:
EFI_UNSUPPORTED - GC_TODO: Add description for return value
EFI_SUCCESS - GC_TODO: Add description for return value
--*/
{
EFI_STATUS Status;
VGA_CLASS_DEV *VgaClassDev;
UINTN MaxColumn;
UINTN MaxRow;
VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
Status = This->QueryMode (
This,
This->Mode->Mode,
&MaxColumn,
&MaxRow
);
if (EFI_ERROR (Status)) {
return Status;
}
if (Column >= MaxColumn || Row >= MaxRow) {
return EFI_UNSUPPORTED;
}
SetVideoCursorPosition (VgaClassDev, Column, Row, MaxColumn);
This->Mode->CursorColumn = (INT32) Column;
This->Mode->CursorRow = (INT32) Row;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
VgaClassEnableCursor (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN BOOLEAN Visible
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
Visible - GC_TODO: add argument description
Returns:
EFI_SUCCESS - GC_TODO: Add description for return value
--*/
{
VGA_CLASS_DEV *VgaClassDev;
VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
if (Visible) {
switch (This->Mode->Mode) {
case 1:
WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x06);
WriteCrtc (VgaClassDev, CRTC_CURSOR_END, 0x07);
break;
default:
WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x0e);
WriteCrtc (VgaClassDev, CRTC_CURSOR_END, 0x0f);
break;
}
} else {
WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x20);
}
This->Mode->CursorVisible = Visible;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
VgaClassQueryMode (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN ModeNumber,
OUT UINTN *Columns,
OUT UINTN *Rows
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
ModeNumber - GC_TODO: add argument description
Columns - GC_TODO: add argument description
Rows - GC_TODO: add argument description
Returns:
EFI_UNSUPPORTED - GC_TODO: Add description for return value
EFI_UNSUPPORTED - GC_TODO: Add description for return value
EFI_SUCCESS - GC_TODO: Add description for return value
--*/
{
if ((INT32) ModeNumber >= This->Mode->MaxMode) {
*Columns = 0;
*Rows = 0;
return EFI_UNSUPPORTED;
}
switch (ModeNumber) {
case 0:
*Columns = 80;
*Rows = 25;
break;
case 1:
*Columns = 80;
*Rows = 50;
break;
default:
*Columns = 0;
*Rows = 0;
return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
VgaClassSetMode (
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
IN UINTN ModeNumber
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
ModeNumber - GC_TODO: add argument description
Returns:
EFI_UNSUPPORTED - GC_TODO: Add description for return value
--*/
{
EFI_STATUS Status;
VGA_CLASS_DEV *VgaClassDev;
VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
if ((INT32) ModeNumber >= This->Mode->MaxMode) {
return EFI_UNSUPPORTED;
}
This->ClearScreen (This);
This->Mode->Mode = (INT32) ModeNumber;
Status = VgaClassDev->VgaMiniPort->SetMode (VgaClassDev->VgaMiniPort, ModeNumber);
return Status;
}
//
// Private Worker Functions
//
STATIC
VOID
SetVideoCursorPosition (
IN VGA_CLASS_DEV *VgaClassDev,
IN UINTN Column,
IN UINTN Row,
IN UINTN MaxColumn
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
VgaClassDev - GC_TODO: add argument description
Column - GC_TODO: add argument description
Row - GC_TODO: add argument description
MaxColumn - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
Column = Column & 0xff;
Row = Row & 0xff;
MaxColumn = MaxColumn & 0xff;
WriteCrtc (
VgaClassDev,
CRTC_CURSOR_LOCATION_HIGH,
(UINT8) ((Row * MaxColumn + Column) >> 8)
);
WriteCrtc (
VgaClassDev,
CRTC_CURSOR_LOCATION_LOW,
(UINT8) ((Row * MaxColumn + Column) & 0xff)
);
}
STATIC
VOID
WriteCrtc (
IN VGA_CLASS_DEV *VgaClassDev,
IN UINT16 Address,
IN UINT8 Data
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
VgaClassDev - GC_TODO: add argument description
Address - GC_TODO: add argument description
Data - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
VgaClassDev->PciIo->Io.Write (
VgaClassDev->PciIo,
EfiPciIoWidthUint8,
VgaClassDev->VgaMiniPort->CrtcAddressRegisterBar,
VgaClassDev->VgaMiniPort->CrtcAddressRegisterOffset,
1,
&Address
);
VgaClassDev->PciIo->Io.Write (
VgaClassDev->PciIo,
EfiPciIoWidthUint8,
VgaClassDev->VgaMiniPort->CrtcDataRegisterBar,
VgaClassDev->VgaMiniPort->CrtcDataRegisterOffset,
1,
&Data
);
}
STATIC
BOOLEAN
LibIsValidTextGraphics (
IN CHAR16 Graphic,
OUT CHAR8 *PcAnsi, OPTIONAL
OUT CHAR8 *Ascii OPTIONAL
)
/*++
Routine Description:
Detects if a Unicode char is for Box Drawing text graphics.
Arguments:
Grphic - Unicode char to test.
PcAnsi - Optional pointer to return PCANSI equivalent of Graphic.
Asci - Optional pointer to return Ascii equivalent of Graphic.
Returns:
TRUE if Gpaphic is a supported Unicode Box Drawing character.
--*/
// GC_TODO: Graphic - add argument and description to function comment
{
UNICODE_TO_CHAR *Table;
if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
//
// Unicode drawing code charts are all in the 0x25xx range,
// arrows are 0x21xx
//
return FALSE;
}
for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
if (Graphic == Table->Unicode) {
if (PcAnsi) {
*PcAnsi = Table->PcAnsi;
}
if (Ascii) {
*Ascii = Table->Ascii;
}
return TRUE;
}
}
return FALSE;
}
STATIC
BOOLEAN
IsValidAscii (
IN CHAR16 Ascii
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
Ascii - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
return TRUE;
}
return FALSE;
}
STATIC
BOOLEAN
IsValidEfiCntlChar (
IN CHAR16 c
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
c - GC_TODO: add argument description
Returns:
GC_TODO: add return values
--*/
{
if (c == CHAR_NULL || c == CHAR_BACKSPACE || c == CHAR_LINEFEED || c == CHAR_CARRIAGE_RETURN) {
return TRUE;
}
return FALSE;
}