lightconsplitter.c

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

C
2,392
字号
            &ConOutPrivate->TextOutQueryDataCount,
            (VOID **) &ConOutPrivate->TextOutQueryData
            );
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Setup the DevNullTextOut console to 80 x 25
  //
  ConOutPrivate->TextOutQueryData[0].Columns  = 80;
  ConOutPrivate->TextOutQueryData[0].Rows     = 25;
  DevNullTextOutSetMode (ConOutPrivate, 0);

#if (EFI_SPECIFICATION_VERSION < 0x00020000)
  //
  // Setup the DevNullUgaDraw to 800 x 600 x 32 bits per pixel
  //
  ConSpliterUgaDrawSetMode (&ConOutPrivate->UgaDraw, 800, 600, 32, 60);
#else
  //
  // Setup resource for mode information in Graphics Output Protocol interface
  //
  if ((ConOutPrivate->GraphicsOutput.Mode = EfiLibAllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE))) == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  if ((ConOutPrivate->GraphicsOutput.Mode->Info = EfiLibAllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel
  //
  if ((ConOutPrivate->GraphicsOutputModeBuffer = EfiLibAllocateZeroPool (sizeof (TEXT_OUT_GOP_MODE))) == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  ConOutPrivate->GraphicsOutputModeBuffer[0].HorizontalResolution = 800;
  ConOutPrivate->GraphicsOutputModeBuffer[0].VerticalResolution = 600;

  //
  // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()
  //  GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat
  //  GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
  //
  ConOutPrivate->GraphicsOutput.Mode->Info->Version = 0;
  ConOutPrivate->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly;
  ConOutPrivate->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
  ConOutPrivate->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;
  ConOutPrivate->GraphicsOutput.Mode->FrameBufferSize = 0;

  ConOutPrivate->GraphicsOutput.Mode->MaxMode = 1;
  //
  // Initial current mode to unknow state, and then set to mode 0
  //
  ConOutPrivate->GraphicsOutput.Mode->Mode = 0xffff;
  ConOutPrivate->GraphicsOutput.SetMode (&ConOutPrivate->GraphicsOutput, 0);  
#endif

  return Status;
}

STATIC
EFI_STATUS
ConSplitterSupported (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      ControllerHandle,
  IN  EFI_GUID                        *Guid
  )
/*++

Routine Description:
  Generic Supported Check

Arguments:
  This              - Pointer to protocol.
  ControllerHandle  - Controller Handle.
  Guid              - Guid.

Returns:

  EFI_UNSUPPORTED - unsupported.
  EFI_SUCCESS     - operation is OK.

--*/
{
  EFI_STATUS  Status;
  VOID        *Instance;

  //
  // Make sure the Console Splitter does not attempt to attach to itself
  //
  if (ControllerHandle == mConIn.VirtualHandle) {
    return EFI_UNSUPPORTED;
  }

  if (ControllerHandle == mConOut.VirtualHandle) {
    return EFI_UNSUPPORTED;
  }

  if (ControllerHandle == mStdErr.VirtualHandle) {
    return EFI_UNSUPPORTED;
  }
  //
  // Check to see whether the handle has the ConsoleInDevice GUID on it
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  Guid,
                  &Instance,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  gBS->CloseProtocol (
        ControllerHandle,
        Guid,
        This->DriverBindingHandle,
        ControllerHandle
        );

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
ConSplitterConInDriverBindingSupported (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
  )
/*++

Routine Description:
  Console In Supported Check

Arguments:
  This              - Pointer to protocol.
  ControllerHandle  - Controller handle.
  RemainingDevicePath  - Remaining device path.

Returns:

  EFI_STATUS

--*/
{
  return ConSplitterSupported (
          This,
          ControllerHandle,
          &gEfiConsoleInDeviceGuid
          );
}

STATIC
EFI_STATUS
EFIAPI
ConSplitterConOutDriverBindingSupported (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
  )
/*++

Routine Description:
  Console Out Supported Check

Arguments:
  This              - Pointer to protocol.
  ControllerHandle  - Controller handle.
  RemainingDevicePath  - Remaining device path.

Returns:

  EFI_STATUS

--*/
{
  return ConSplitterSupported (
          This,
          ControllerHandle,
          &gEfiConsoleOutDeviceGuid
          );
}

STATIC
EFI_STATUS
EFIAPI
ConSplitterStdErrDriverBindingSupported (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
  )
/*++

Routine Description:
  Standard Error Supported Check

Arguments:
  This              - Pointer to protocol.
  ControllerHandle  - Controller handle.
  RemainingDevicePath  - Remaining device path.

Returns:

  EFI_STATUS

--*/
{
  return ConSplitterSupported (
          This,
          ControllerHandle,
          &gEfiStandardErrorDeviceGuid
          );
}

STATIC
EFI_STATUS
EFIAPI
ConSplitterStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      ControllerHandle,
  IN  EFI_HANDLE                      ConSplitterVirtualHandle,
  IN  EFI_GUID                        *DeviceGuid,
  IN  EFI_GUID                        *InterfaceGuid,
  IN  VOID                            **Interface
  )
/*++

Routine Description:
  Start ConSplitter on ControllerHandle, and create the virtual
  agrogated console device on first call Start for a SimpleTextIn handle.

Arguments:
  (Standard DriverBinding Protocol Start() function)

Returns:
  EFI_ERROR if a SimpleTextIn protocol is not started.

--*/
{
  EFI_STATUS  Status;
  VOID        *Instance;

  //
  // Check to see whether the handle has the ConsoleInDevice GUID on it
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  DeviceGuid,
                  &Instance,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  DeviceGuid,
                  &Instance,
                  This->DriverBindingHandle,
                  ConSplitterVirtualHandle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return gBS->OpenProtocol (
                ControllerHandle,
                InterfaceGuid,
                Interface,
                This->DriverBindingHandle,
                ConSplitterVirtualHandle,
                EFI_OPEN_PROTOCOL_GET_PROTOCOL
                );
}

STATIC
EFI_STATUS
EFIAPI
ConSplitterConInDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
  )
/*++

Routine Description:
  Start ConSplitter on ControllerHandle, and create the virtual
  agrogated console device on first call Start for a SimpleTextIn handle.

Arguments:
  This              - Pointer to protocol.
  ControllerHandle  - Controller handle.
  RemainingDevicePath  - Remaining device path.

Returns:

  EFI_STATUS
  EFI_ERROR if a SimpleTextIn protocol is not started.

--*/
{
  EFI_STATUS                  Status;
  EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn;

  //
  // Start ConSplitter on ControllerHandle, and create the virtual
  // agrogated console device on first call Start for a SimpleTextIn handle.
  //
  Status = ConSplitterStart (
            This,
            ControllerHandle,
            mConIn.VirtualHandle,
            &gEfiConsoleInDeviceGuid,
            &gEfiSimpleTextInProtocolGuid,
            (VOID **) &TextIn
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return ConSplitterTextInAddDevice (&mConIn, TextIn);
}

STATIC
EFI_STATUS
EFIAPI
ConSplitterConOutDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
  )
/*++

Routine Description:
  Start ConSplitter on ControllerHandle, and create the virtual
  agrogated console device on first call Start for a SimpleTextIn handle.

Arguments:
  This              - Pointer to protocol.
  ControllerHandle  - Controller handle.
  RemainingDevicePath  - Remaining device path.

Returns:
  EFI_ERROR if a SimpleTextIn protocol is not started.

--*/
{
  EFI_STATUS                    Status;
  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *TextOut;
  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;
  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;

  Status = ConSplitterStart (
            This,
            ControllerHandle,
            mConOut.VirtualHandle,
            &gEfiConsoleOutDeviceGuid,
            &gEfiSimpleTextOutProtocolGuid,
            (VOID **) &TextOut
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Try to Open Graphics Output protocol
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiGraphicsOutputProtocolGuid,
                  &GraphicsOutput,
                  This->DriverBindingHandle,
                  mConOut.VirtualHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    GraphicsOutput = NULL;
  }
  //
  // Open UGA_DRAW protocol
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiUgaDrawProtocolGuid,
                  &UgaDraw,
                  This->DriverBindingHandle,
                  mConOut.VirtualHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    UgaDraw = NULL;
  }
  //
  // If both ConOut and StdErr incorporate the same Text Out device,
  // their MaxMode and QueryData should be the intersection of both.
  //
  Status = ConSplitterTextOutAddDevice (&mConOut, TextOut, GraphicsOutput, UgaDraw);
  ConSplitterTextOutSetAttribute (&mConOut.TextOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));

#if (EFI_SPECIFICATION_VERSION < 0x00020000)
  //
  // Match the UGA mode data of ConOut with the current mode
  //
  if (UgaDraw != NULL) {
    UgaDraw->GetMode (
               UgaDraw,
               &mConOut.UgaHorizontalResolution,
               &mConOut.UgaVerticalResolution,
               &mConOut.UgaColorDepth,
               &mConOut.UgaRefreshRate
               );
  }
#endif

  return Status;
}

STATIC
EFI_STATUS
EFIAPI
ConSplitterStdErrDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
  )
/*++

Routine Description:
  Start ConSplitter on ControllerHandle, and create the virtual
  agrogated console device on first call Start for a SimpleTextIn handle.

Arguments:
  This              - Pointer to protocol.
  ControllerHandle  - Controller handle.
  RemainingDevicePath  - Remaining device path.

Returns:
  EFI_ERROR if a SimpleTextIn protocol is not started.

--*/
{
  EFI_STATUS                    Status;
  EFI_SIMPLE_TEXT_OUT_PROTOCOL  *TextOut;

  Status = ConSplitterStart (
            This,
            ControllerHandle,
            mStdErr.VirtualHandle,
            &gEfiStandardErrorDeviceGuid,
            &gEfiSimpleTextOutProtocolGuid,
            (VOID **) &TextOut
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // If both ConOut and StdErr incorporate the same Text Out device,
  // their MaxMode and QueryData should be the intersection of both.
  //
  Status = ConSplitterTextOutAddDevice (&mStdErr, TextOut, NULL, NULL);
  ConSplitterTextOutSetAttribute (&mStdErr.TextOut, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (mStdErr.CurrentNumberOfConsoles == 1) {
    gST->StandardErrorHandle  = mStdErr.VirtualHandle;
    gST->StdErr               = &mStdErr.TextOut;
    //
    // Update the CRC32 in the EFI System Table header
    //

⌨️ 快捷键说明

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