uefibiosvideo.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,161 行 · 第 1/5 页
C
2,161 行
ParentDevicePath,
RemainingDevicePath
);
Done:
if (EFI_ERROR (Status)) {
if (PciIo != NULL) {
//
// Release PCI I/O Protocols on the controller handle.
//
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
}
}
return Status;
}
EFI_STATUS
EFIAPI
BiosVideoDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Stop.
Arguments:
This - Pointer to driver binding protocol
Controller - Controller handle to connect
NumberOfChilren - Number of children handle created by this driver
ChildHandleBuffer - Buffer containing child handle created
Returns:
EFI_SUCCESS - Driver disconnected successfully from controller
EFI_UNSUPPORTED - Cannot find BIOS_VIDEO_DEV structure
--*/
{
EFI_STATUS Status;
BIOS_VIDEO_DEV *BiosVideoPrivate;
BOOLEAN AllChildrenStopped;
UINTN Index;
BiosVideoPrivate = NULL;
if (NumberOfChildren == 0) {
//
// Close PCI I/O protocol on the controller handle
//
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_SUCCESS;
}
AllChildrenStopped = TRUE;
for (Index = 0; Index < NumberOfChildren; Index++) {
Status = BiosVideoChildHandleUninstall (This, Controller, ChildHandleBuffer[Index]);
if (EFI_ERROR (Status)) {
AllChildrenStopped = FALSE;
}
}
if (!AllChildrenStopped) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
EFI_STATUS
BiosVideoChildHandleInstall (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ParentHandle,
IN EFI_PCI_IO_PROTOCOL *ParentPciIo,
IN EFI_LEGACY_BIOS_THUNK_PROTOCOL *ParentLegacyBios,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Install child handles if the Handle supports MBR format.
Arguments:
This - Calling context.
Handle - Parent Handle
PciIo - Parent PciIo interface
LegacyBios - Parent LegacyBios interface
DevicePath - Parent Device Path
Returns:
EFI_SUCCESS - If a child handle was added
other - A child handle was not added
--*/
{
EFI_STATUS Status;
BIOS_VIDEO_DEV *BiosVideoPrivate;
ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
//
// Allocate the private device structure for video device
//
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (BIOS_VIDEO_DEV),
&BiosVideoPrivate
);
if (EFI_ERROR (Status)) {
goto Done;
}
EfiZeroMem (BiosVideoPrivate, sizeof (BIOS_VIDEO_DEV));
if (!BiosVideoIsVga (ParentPciIo)) {
Status = EFI_UNSUPPORTED;
goto Done;
}
BiosVideoPrivate->VgaCompatible = TRUE;
//
// Initialize the child private structure
//
BiosVideoPrivate->Signature = BIOS_VIDEO_DEV_SIGNATURE;
BiosVideoPrivate->Handle = NULL;
Status = gBS->CreateEvent (
EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
EFI_TPL_NOTIFY,
BiosVideoExitBootServices,
BiosVideoPrivate,
&BiosVideoPrivate->ExitBootServicesEvent
);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// Fill in Graphics Output specific mode structures
//
BiosVideoPrivate->HardwareNeedsStarting = TRUE;
BiosVideoPrivate->ModeData = NULL;
BiosVideoPrivate->LineBuffer = NULL;
BiosVideoPrivate->VgaFrameBuffer = NULL;
BiosVideoPrivate->VbeFrameBuffer = NULL;
//
// Fill in the VGA Mini Port Protocol fields
//
BiosVideoPrivate->VgaMiniPort.SetMode = BiosVideoVgaMiniPortSetMode;
BiosVideoPrivate->VgaMiniPort.VgaMemoryOffset = 0xb8000;
BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterOffset = 0x3d4;
BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterOffset = 0x3d5;
BiosVideoPrivate->VgaMiniPort.VgaMemoryBar = EFI_PCI_IO_PASS_THROUGH_BAR;
BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR;
BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR;
//
// Assume that Graphics Output Protocol will be produced until proven otherwise
//
BiosVideoPrivate->ProduceGraphicsOutput = TRUE;
//
// Child handle need to consume the Legacy Bios protocol
//
BiosVideoPrivate->LegacyBios = ParentLegacyBios;
//
// When check for VBE, PCI I/O protocol is needed, so use parent's protocol interface temporally
//
BiosVideoPrivate->PciIo = ParentPciIo;
//
// Check for VESA BIOS Extensions for modes that are compatible with Graphics Output
//
Status = BiosVideoCheckForVbe (BiosVideoPrivate);
if (EFI_ERROR (Status)) {
//
// The VESA BIOS Extensions are not compatible with Graphics Output, so check for support
// for the standard 640x480 16 color VGA mode
//
if (BiosVideoPrivate->VgaCompatible) {
Status = BiosVideoCheckForVga (BiosVideoPrivate);
}
if (EFI_ERROR (Status)) {
//
// Neither VBE nor the standard 640x480 16 color VGA mode are supported, so do
// not produce the Graphics Output protocol. Instead, produce the VGA MiniPort Protocol.
//
BiosVideoPrivate->ProduceGraphicsOutput = FALSE;
//
// INT services are available, so on the 80x25 and 80x50 text mode are supported
//
BiosVideoPrivate->VgaMiniPort.MaxMode = 2;
}
}
if (BiosVideoPrivate->ProduceGraphicsOutput) {
if (RemainingDevicePath == NULL) {
EfiZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));
AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));
BiosVideoPrivate->DevicePath = EfiAppendDevicePathNode (
ParentDevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode
);
} else {
BiosVideoPrivate->DevicePath = EfiAppendDevicePathNode (ParentDevicePath, RemainingDevicePath);
}
//
// Creat child handle and install Graphics Output Protocol,EDID Discovered/Active Protocol
//
Status = gBS->InstallMultipleProtocolInterfaces (
&BiosVideoPrivate->Handle,
&gEfiDevicePathProtocolGuid,
BiosVideoPrivate->DevicePath,
&gEfiGraphicsOutputProtocolGuid,
&BiosVideoPrivate->GraphicsOutput,
&gEfiEdidDiscoveredProtocolGuid,
&BiosVideoPrivate->EdidDiscovered,
&gEfiEdidActiveProtocolGuid,
&BiosVideoPrivate->EdidActive,
NULL
);
if (!EFI_ERROR (Status)) {
//
// Open the Parent Handle for the child
//
Status = gBS->OpenProtocol (
ParentHandle,
&gEfiPciIoProtocolGuid,
(VOID **) &BiosVideoPrivate->PciIo,
This->DriverBindingHandle,
BiosVideoPrivate->Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
goto Done;
}
}
} else {
//
// Install VGA Mini Port Protocol
//
Status = gBS->InstallMultipleProtocolInterfaces (
&BiosVideoPrivate->Handle,
&gEfiVgaMiniPortProtocolGuid,
&BiosVideoPrivate->VgaMiniPort,
NULL
);
}
Done:
if (EFI_ERROR (Status)) {
//
// Free private data structure
//
BiosVideoDeviceReleaseResource (BiosVideoPrivate);
}
return Status;
}
EFI_STATUS
BiosVideoChildHandleUninstall (
EFI_DRIVER_BINDING_PROTOCOL *This,
EFI_HANDLE Controller,
EFI_HANDLE Handle
)
/*++
Routine Description:
Deregister an video child handle and free resources
Arguments:
This - Protocol instance pointer.
Controller - Video controller handle
Handle - Video child handle
Returns:
EFI_STATUS
--*/
{
EFI_STATUS Status;
EFI_IA32_REGISTER_SET Regs;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;
BIOS_VIDEO_DEV *BiosVideoPrivate;
EFI_PCI_IO_PROTOCOL *PciIo;
BiosVideoPrivate = NULL;
Status = gBS->OpenProtocol (
Handle,
&gEfiGraphicsOutputProtocolGuid,
(VOID **) &GraphicsOutput,
This->DriverBindingHandle,
Handle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status)) {
BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);
}
Status = gBS->OpenProtocol (
Handle,
&gEfiVgaMiniPortProtocolGuid,
(VOID **) &VgaMiniPort,
This->DriverBindingHandle,
Handle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status)) {
BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS (VgaMiniPort);
}
if (BiosVideoPrivate == NULL) {
return EFI_UNSUPPORTED;
}
//
// Close PCI I/O protocol that opened by child handle
//
Status = gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Handle
);
//
// Uninstall protocols on child handle
//
if (BiosVideoPrivate->ProduceGraphicsOutput) {
Status = gBS->UninstallMultipleProtocolInterfaces (
BiosVideoPrivate->Handle,
&gEfiDevicePathProtocolGuid,
BiosVideoPrivate->DevicePath,
&gEfiGraphicsOutputProtocolGuid,
&BiosVideoPrivate->GraphicsOutput,
&gEfiEdidDiscoveredProtocolGuid,
&BiosVideoPrivate->EdidDiscovered,
&gEfiEdidActiveProtocolGuid,
&BiosVideoPrivate->EdidActive,
NULL
);
} else {
Status = gBS->UninstallMultipleProtocolInterfaces (
BiosVideoPrivate->Handle,
&gEfiVgaMiniPortProtocolGuid,
&BiosVideoPrivate->VgaMiniPort,
NULL
);
}
if (EFI_ERROR (Status)) {
gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo,
This->DriverBindingHandle,
Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
return Status;
}
//
// Set the 80x25 Text VGA Mode
//
Regs.H.AH = 0x00;
Regs.H.AL = 0x03;
BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
Regs.H.AH = 0x11;
Regs.H.AL = 0x14;
Regs.H.BL = 0;
BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
//
// Do not disable IO/memory decode since that would prevent legacy ROM from working
//
//
// Release all allocated resources
//
BiosVideoDeviceReleaseResource (BiosVideoPrivate);
return EFI_SUCCESS;
}
VOID
BiosVideoDeviceReleaseResource (
BIOS_VIDEO_DEV *BiosVideoPrivate
)
/*++
Routing Description:
Release resources of an video child device before stopping it.
Arguments:
BiosVideoPrivate - Video child device private data structure
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?