vgaclass.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,318 行 · 第 1/2 页

C
1,318
字号
/*++

Copyright (c) 2006 Intel Corporation. All rights reserved
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.             


Module Name:

    VgaClass.c
    
Abstract: 
    This driver produces a VGA console.
    
--*/

#include "VgaClass.h"

//
// EFI Driver Binding Protocol for the VGA Class Driver
//
EFI_DRIVER_BINDING_PROTOCOL gVgaClassDriverBinding = {
  VgaClassDriverBindingSupported,
  VgaClassDriverBindingStart,
  VgaClassDriverBindingStop,
  0x10,
  NULL,
  NULL
};

//
// 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
};

//
// 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
  );

//
// Driver Entry Point
//
EFI_DRIVER_ENTRY_POINT (VgaClassDriverEntryPoint)

EFI_STATUS
EFIAPI
VgaClassDriverEntryPoint (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
/*++
  
  Routine Description:
  
    Driver Entry Point.
        
  Arguments:
  
    (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
  
  Returns:
    EFI_STATUS
--*/
// GC_TODO:    ImageHandle - add argument and description to function comment
// GC_TODO:    SystemTable - add argument and description to function comment
{
  return INSTALL_ALL_DRIVER_PROTOCOLS (
          ImageHandle,
          SystemTable,
          &gVgaClassDriverBinding,
          ImageHandle,
          &gVgaClassComponentName,
          NULL,
          NULL
          );
}

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,
                  &DevicePath
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Report that VGA Class driver is being enabled
  //
  ReportStatusCodeWithDevicePath (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_ENABLE,
    0,
    &gEfiCallerIdGuid,
    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),
                  &VgaClassPrivate
                  );
  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
          Controller,
          &gEfiVgaMiniPortProtocolGuid,
          This->DriverBindingHandle,
          Controller
          );
    return EFI_OUT_OF_RESOURCES;
  }

  EfiZeroMem (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:
  ReportStatusCodeWithDevicePath (
    EFI_ERROR_CODE | EFI_ERROR_MINOR,
    EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,
    0,
    &gEfiCallerIdGuid,
    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_OUT_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
  //
  ReportStatusCodeWithDevicePath (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_DISABLE,
    0,
    &gEfiCallerIdGuid,
    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_OUT_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);

  ReportStatusCodeWithDevicePath (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_RESET,
    0,
    &gEfiCallerIdGuid,
    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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?