consplitter.c

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

C
2,436
字号
/*++

Copyright (c) 2004 - 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.             

Module Name:

  ConSplitter.c

Abstract:

  Console Splitter Driver. Any Handle that attatched
  EFI_CONSOLE_IDENTIFIER_PROTOCOL can be bound by this driver.

  So far it works like any other driver by opening a SimpleTextIn and/or
  SimpleTextOut protocol with EFI_OPEN_PROTOCOL_BY_DRIVER attributes. The big
  difference is this driver does not layer a protocol on the passed in
  handle, or construct a child handle like a standard device or bus driver.
  This driver produces three virtual handles as children, one for console input
  splitter, one for console output splitter and one for error output splitter.
  EFI_CONSOLE_SPLIT_PROTOCOL will be attatched onto each virtual handle to
  identify the splitter type.

  Each virtual handle, that supports both the EFI_CONSOLE_SPLIT_PROTOCOL
  and Console I/O protocol, will be produced in the driver entry point.
  The virtual handle are added on driver entry and never removed.
  Such design ensures sytem function well during none console device situation.

--*/

#include "ConSplitter.h"

//
// Global Variables
//
STATIC TEXT_IN_SPLITTER_PRIVATE_DATA  mConIn = {
  TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE,
  (EFI_HANDLE) NULL,
  {
    ConSplitterTextInReset,
    ConSplitterTextInReadKeyStroke,
    (EFI_EVENT) NULL
  },
  0,
  (EFI_SIMPLE_TEXT_IN_PROTOCOL **) NULL,
  0,

  {
    ConSplitterSimplePointerReset,
    ConSplitterSimplePointerGetState,
    (EFI_EVENT) NULL,
    (EFI_SIMPLE_POINTER_MODE *) NULL
  },
  {
    0x10000,
    0x10000,
    0x10000,
    TRUE,
    TRUE
  },
  0,
  (EFI_SIMPLE_POINTER_PROTOCOL **) NULL,
  0,

  FALSE,
  {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  0,
  {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  (EFI_EVENT) NULL,

  FALSE,
  FALSE
};

STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {
  TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,
  (EFI_HANDLE) NULL,
  {
    ConSplitterTextOutReset,
    ConSplitterTextOutOutputString,
    ConSplitterTextOutTestString,
    ConSplitterTextOutQueryMode,
    ConSplitterTextOutSetMode,
    ConSplitterTextOutSetAttribute,
    ConSplitterTextOutClearScreen,
    ConSplitterTextOutSetCursorPosition,
    ConSplitterTextOutEnableCursor,
    (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL
  },
  {
    1,
    0,
    0,
    0,
    0,
    FALSE,
  },
#if (EFI_SPECIFICATION_VERSION < 0x00020000)
  {
    ConSpliterUgaDrawGetMode,
    ConSpliterUgaDrawSetMode,
    ConSpliterUgaDrawBlt
  },
  0,
  0,
  0,
  0,
  (EFI_UGA_PIXEL *) NULL,
#else
  {
    ConSpliterGraphicsOutputQueryMode,
    ConSpliterGraphicsOutputSetMode,
    ConSpliterGraphicsOutputBlt,
    NULL
  },
  (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,
  (TEXT_OUT_GOP_MODE *) NULL,
  0,
  TRUE,
#endif
  {
    ConSpliterConsoleControlGetMode,
    ConSpliterConsoleControlSetMode,
    ConSpliterConsoleControlLockStdIn
  },

  0,
  (TEXT_OUT_AND_GOP_DATA *) NULL,
  0,
  (TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,
  0,
  (INT32 *) NULL,

  EfiConsoleControlScreenText,
  0,
  0,
  (CHAR16 *) NULL,
  (INT32 *) NULL
};

STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {
  TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,
  (EFI_HANDLE) NULL,
  {
    ConSplitterTextOutReset,
    ConSplitterTextOutOutputString,
    ConSplitterTextOutTestString,
    ConSplitterTextOutQueryMode,
    ConSplitterTextOutSetMode,
    ConSplitterTextOutSetAttribute,
    ConSplitterTextOutClearScreen,
    ConSplitterTextOutSetCursorPosition,
    ConSplitterTextOutEnableCursor,
    (EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL
  },
  {
    1,
    0,
    0,
    0,
    0,
    FALSE,
  },
#if (EFI_SPECIFICATION_VERSION < 0x00020000)
  {
    ConSpliterUgaDrawGetMode,
    ConSpliterUgaDrawSetMode,
    ConSpliterUgaDrawBlt
  },
  0,
  0,
  0,
  0,
  (EFI_UGA_PIXEL *) NULL,
#else
  {
    ConSpliterGraphicsOutputQueryMode,
    ConSpliterGraphicsOutputSetMode,
    ConSpliterGraphicsOutputBlt,
    NULL
  },
  (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,
  (TEXT_OUT_GOP_MODE *) NULL,
  0,
  TRUE,
#endif
  {
    ConSpliterConsoleControlGetMode,
    ConSpliterConsoleControlSetMode,
    ConSpliterConsoleControlLockStdIn
  },

  0,
  (TEXT_OUT_AND_GOP_DATA *) NULL,
  0,
  (TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,
  0,
  (INT32 *) NULL,

  EfiConsoleControlScreenText,
  0,
  0,
  (CHAR16 *) NULL,
  (INT32 *) NULL
};

EFI_DRIVER_BINDING_PROTOCOL           gConSplitterConInDriverBinding = {
  ConSplitterConInDriverBindingSupported,
  ConSplitterConInDriverBindingStart,
  ConSplitterConInDriverBindingStop,
  0x10,
  NULL,
  NULL
};

EFI_DRIVER_BINDING_PROTOCOL           gConSplitterSimplePointerDriverBinding = {
  ConSplitterSimplePointerDriverBindingSupported,
  ConSplitterSimplePointerDriverBindingStart,
  ConSplitterSimplePointerDriverBindingStop,
  0x10,
  NULL,
  NULL
};

EFI_DRIVER_BINDING_PROTOCOL           gConSplitterConOutDriverBinding = {
  ConSplitterConOutDriverBindingSupported,
  ConSplitterConOutDriverBindingStart,
  ConSplitterConOutDriverBindingStop,
  0x10,
  NULL,
  NULL
};

EFI_DRIVER_BINDING_PROTOCOL           gConSplitterStdErrDriverBinding = {
  ConSplitterStdErrDriverBindingSupported,
  ConSplitterStdErrDriverBindingStart,
  ConSplitterStdErrDriverBindingStop,
  0x10,
  NULL,
  NULL
};

EFI_DRIVER_ENTRY_POINT (ConSplitterDriverEntry)

EFI_STATUS
EFIAPI
ConSplitterDriverEntry (
  IN EFI_HANDLE                       ImageHandle,
  IN EFI_SYSTEM_TABLE                 *SystemTable
  )
/*++

Routine Description:
  Intialize a virtual console device to act as an agrigator of physical console
  devices.

Arguments:
  ImageHandle - (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
  SystemTable - (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

Returns:
  EFI_SUCCESS

--*/
{
  EFI_STATUS  Status;

  //
  // Initialize the EFI Driver Library and install the
  // EFI Driver Binding Protocols
  //
  Status = EfiLibInstallAllDriverProtocols (
            ImageHandle,
            SystemTable,
            &gConSplitterConInDriverBinding,
            ImageHandle,
            &gConSplitterConInComponentName,
            NULL,
            NULL
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = EfiLibInstallAllDriverProtocols (
            ImageHandle,
            SystemTable,
            &gConSplitterSimplePointerDriverBinding,
            NULL,
            &gConSplitterSimplePointerComponentName,
            NULL,
            NULL
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = EfiLibInstallAllDriverProtocols (
            ImageHandle,
            SystemTable,
            &gConSplitterConOutDriverBinding,
            NULL,
            &gConSplitterConOutComponentName,
            NULL,
            NULL
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = EfiLibInstallAllDriverProtocols (
            ImageHandle,
            SystemTable,
            &gConSplitterStdErrDriverBinding,
            NULL,
            &gConSplitterStdErrComponentName,
            NULL,
            NULL
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // The driver creates virtual handles for ConIn, ConOut, and StdErr.
  // The virtual handles will always exist even if no console exist in the
  // system. This is need to support hotplug devices like USB.
  //
  //
  // Create virtual device handle for StdErr Splitter
  //
  Status = ConSplitterTextOutConstructor (&mStdErr);
  if (!EFI_ERROR (Status)) {
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &mStdErr.VirtualHandle,
                    &gEfiSimpleTextOutProtocolGuid,
                    &mStdErr.TextOut,
                    &gEfiPrimaryStandardErrorDeviceGuid,
                    NULL,
                    NULL
                    );
  }
  //
  // Create virtual device handle for ConIn Splitter
  //
  Status = ConSplitterTextInConstructor (&mConIn);
  if (!EFI_ERROR (Status)) {
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &mConIn.VirtualHandle,
                    &gEfiSimpleTextInProtocolGuid,
                    &mConIn.TextIn,
                    &gEfiSimplePointerProtocolGuid,
                    &mConIn.SimplePointer,
                    &gEfiPrimaryConsoleInDeviceGuid,
                    NULL,
                    NULL
                    );
    if (!EFI_ERROR (Status)) {
      //
      // Update the EFI System Table with new virtual console
      //
      gST->ConsoleInHandle  = mConIn.VirtualHandle;
      gST->ConIn            = &mConIn.TextIn;
    }
  }
  //
  // Create virtual device handle for ConOut Splitter
  //
  Status = ConSplitterTextOutConstructor (&mConOut);
  if (!EFI_ERROR (Status)) {
#if (EFI_SPECIFICATION_VERSION < 0x00020000)
    //
    // In EFI mode, UGA Draw protocol is installed
    //
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &mConOut.VirtualHandle,
                    &gEfiSimpleTextOutProtocolGuid,
                    &mConOut.TextOut,
                    &gEfiUgaDrawProtocolGuid,
                    &mConOut.UgaDraw,
                    &gEfiConsoleControlProtocolGuid,
                    &mConOut.ConsoleControl,
                    &gEfiPrimaryConsoleOutDeviceGuid,
                    NULL,
                    NULL
                    );
#else
    //
    // In UEFI mode, Graphics Output Protocol is installed on virtual handle.
    //
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &mConOut.VirtualHandle,
                    &gEfiSimpleTextOutProtocolGuid,
                    &mConOut.TextOut,
                    &gEfiGraphicsOutputProtocolGuid,
                    &mConOut.GraphicsOutput,
                    &gEfiConsoleControlProtocolGuid,
                    &mConOut.ConsoleControl,
                    &gEfiPrimaryConsoleOutDeviceGuid,
                    NULL,
                    NULL
                    );
#endif

    if (!EFI_ERROR (Status)) {
      //
      // Update the EFI System Table with new virtual console
      //
      gST->ConsoleOutHandle = mConOut.VirtualHandle;
      gST->ConOut           = &mConOut.TextOut;
    }

  }
  //
  // Update the CRC32 in the EFI System Table header
  //
  gST->Hdr.CRC32 = 0;
  gBS->CalculateCrc32 (
        (UINT8 *) &gST->Hdr,
        gST->Hdr.HeaderSize,
        &gST->Hdr.CRC32
        );

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
ConSplitterTextInConstructor (
  TEXT_IN_SPLITTER_PRIVATE_DATA       *ConInPrivate
  )
/*++

Routine Description:

  Construct the ConSplitter.

Arguments:

  ConInPrivate    - A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA structure.

Returns:
  EFI_OUT_OF_RESOURCES - Out of resources.

--*/
{
  EFI_STATUS  Status;

  //
  // Initilize console input splitter's private data.
  //
  Status = ConSplitterGrowBuffer (
            sizeof (EFI_SIMPLE_TEXT_IN_PROTOCOL *),
            &ConInPrivate->TextInListCount,
            (VOID **) &ConInPrivate->TextInList
            );
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Create Event to support locking StdIn Device
  //
  Status = gBS->CreateEvent (
                  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
                  EFI_TPL_CALLBACK,
                  ConSpliterConsoleControlLockStdInEvent,
                  NULL,
                  &ConInPrivate->LockEvent
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->CreateEvent (
                  EFI_EVENT_NOTIFY_WAIT,

⌨️ 快捷键说明

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