From f0c5d652d93b01cb7fce2272045f632a6af79765 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Sat, 11 Nov 2023 00:57:58 +0100 Subject: [PATCH] OvmfPkg: remove LegacyBiosDxe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LegacyBiosDxe is not used by any platform at this point, remove it. This patch removes mentions of the following CSM resources from the source code [*] [**]: - GUIDs (protocols or otherwise): - gEfiIsaIoProtocolGuid - gEfiLegacy8259ProtocolGuid - gEfiLegacyBiosGuid - gEfiLegacyBiosPlatformProtocolGuid - gEfiLegacyBiosProtocolGuid - gEfiLegacyInterruptProtocolGuid - headers: - FrameworkDxe.h - Guid/LegacyBios.h - Protocol/IsaIo.h - Protocol/Legacy8259.h - Protocol/LegacyBios.h - Protocol/LegacyBiosPlatform.h - Protocol/LegacyInterrupt.h - PCDs: - PcdEbdaReservedMemorySize - PcdEndOpromShadowAddress - PcdHighPmmMemorySize - PcdLegacyBiosCacheLegacyRegion - PcdLowPmmMemorySize - PcdOpromReservedMemoryBase - PcdOpromReservedMemorySize which extends the list of resources scheduled for removal to: - GUIDs (protocols or otherwise): - gEfiIsaIoProtocolGuid - gEfiLegacy8259ProtocolGuid - gEfiLegacyBiosGuid - gEfiLegacyBiosPlatformProtocolGuid - gEfiLegacyBiosProtocolGuid - gEfiLegacyInterruptProtocolGuid - headers: - FrameworkDxe.h - Guid/LegacyBios.h - Protocol/IsaIo.h - Protocol/Legacy8259.h - Protocol/LegacyBios.h - Protocol/LegacyBiosPlatform.h - Protocol/LegacyInterrupt.h - PCDs: - PcdEbdaReservedMemorySize - PcdEndOpromShadowAddress - PcdHighPmmMemorySize - PcdLegacyBiosCacheLegacyRegion - PcdLowPmmMemorySize - PcdOpromReservedMemoryBase - PcdOpromReservedMemorySize [*] Note that gEfiGenericMemTestProtocolGuid, while not a CSM-related protocol, also becomes useless in the OVMF platforms, so we'll deal with that later in the series as well. [**] Note that gEfiLegacyRegion2ProtocolGuid, while a CSM-related protocol, cannot be scheduled for removal, because the protocol GUID is defined in "MdePkg.dec", and it's not only "OvmfPkg/Csm/CsmSupportLib" that produces it in all of edk2, but also "MdeModulePkg/Universal/LegacyRegion2Dxe" (not used by OVMF). For the same reason, the "Protocol/LegacyRegion2.h" header (from MdePkg) cannot be scheduled for removal. Cc: Ard Biesheuvel Cc: Gerd Hoffmann Cc: Jiewen Yao Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4588 Signed-off-by: Laszlo Ersek Message-Id: <20231110235820.644381-16-lersek@redhat.com> Reviewed-by: Jiewen Yao Reviewed-by: Ard Biesheuvel Acked-by: Corvin Köhne Acked-by: Gerd Hoffmann --- .../LegacyBiosDxe/IA32/InterruptTable.nasm | 63 - OvmfPkg/Csm/LegacyBiosDxe/LegacyBbs.c | 530 --- OvmfPkg/Csm/LegacyBiosDxe/LegacyBda.c | 62 - OvmfPkg/Csm/LegacyBiosDxe/LegacyBios.c | 1227 ------- OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf | 129 - OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.uni | 16 - .../Csm/LegacyBiosDxe/LegacyBiosDxeExtra.uni | 14 - .../Csm/LegacyBiosDxe/LegacyBiosInterface.h | 1435 -------- OvmfPkg/Csm/LegacyBiosDxe/LegacyBootSupport.c | 2212 ------------ OvmfPkg/Csm/LegacyBiosDxe/LegacyCmos.c | 117 - OvmfPkg/Csm/LegacyBiosDxe/LegacyIde.c | 315 -- OvmfPkg/Csm/LegacyBiosDxe/LegacyPci.c | 3114 ----------------- OvmfPkg/Csm/LegacyBiosDxe/LegacySio.c | 489 --- OvmfPkg/Csm/LegacyBiosDxe/Thunk.c | 422 --- .../Csm/LegacyBiosDxe/X64/InterruptTable.nasm | 64 - 15 files changed, 10209 deletions(-) delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/IA32/InterruptTable.nasm delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacyBbs.c delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacyBda.c delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacyBios.c delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.uni delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxeExtra.uni delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacyBootSupport.c delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacyCmos.c delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacyIde.c delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacyPci.c delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/LegacySio.c delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/Thunk.c delete mode 100644 OvmfPkg/Csm/LegacyBiosDxe/X64/InterruptTable.nasm diff --git a/OvmfPkg/Csm/LegacyBiosDxe/IA32/InterruptTable.nasm b/OvmfPkg/Csm/LegacyBiosDxe/IA32/InterruptTable.nasm deleted file mode 100644 index 90bfdffb0b..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/IA32/InterruptTable.nasm +++ /dev/null @@ -1,63 +0,0 @@ -;; @file -; Interrupt Redirection Template -; -; Copyright (c) 2016, Intel Corporation. All rights reserved.
-; -; SPDX-License-Identifier: BSD-2-Clause-Patent -; -;; - -SECTION .text - -;---------------------------------------------------------------------------- -; Procedure: InterruptRedirectionTemplate: Redirects interrupts 0x68-0x6F -; -; Input: None -; -; Output: None -; -; Prototype: VOID -; InterruptRedirectionTemplate ( -; VOID -; ); -; -; Saves: None -; -; Modified: None -; -; Description: Contains the code that is copied into low memory (below 640K). -; This code reflects interrupts 0x68-0x6f to interrupts 0x08-0x0f. -; This template must be copied into low memory, and the IDT entries -; 0x68-0x6F must be point to the low memory copy of this code. Each -; entry is 4 bytes long, so IDT entries 0x68-0x6F can be easily -; computed. -; -;---------------------------------------------------------------------------- - -global ASM_PFX(InterruptRedirectionTemplate) -ASM_PFX(InterruptRedirectionTemplate): - int 0x8 - DB 0xcf ; IRET - nop - int 0x9 - DB 0xcf ; IRET - nop - int 0xa - DB 0xcf ; IRET - nop - int 0xb - DB 0xcf ; IRET - nop - int 0xc - DB 0xcf ; IRET - nop - int 0xd - DB 0xcf ; IRET - nop - int 0xe - DB 0xcf ; IRET - nop - int 0xf - DB 0xcf ; IRET - nop - diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBbs.c b/OvmfPkg/Csm/LegacyBiosDxe/LegacyBbs.c deleted file mode 100644 index cd80720a1d..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBbs.c +++ /dev/null @@ -1,530 +0,0 @@ -/** @file - -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "LegacyBiosInterface.h" -#include - -// Give floppy 3 states -// FLOPPY_PRESENT_WITH_MEDIA = Floppy controller present and media is inserted -// FLOPPY_NOT_PRESENT = No floppy controller present -// FLOPPY_PRESENT_NO_MEDIA = Floppy controller present but no media inserted -// -#define FLOPPY_NOT_PRESENT 0 -#define FLOPPY_PRESENT_WITH_MEDIA 1 -#define FLOPPY_PRESENT_NO_MEDIA 2 - -BBS_TABLE *mBbsTable; -BOOLEAN mBbsTableDoneFlag = FALSE; -BOOLEAN IsHaveMediaInFloppy = TRUE; - -/** - Checks the state of the floppy and if media is inserted. - - This routine checks the state of the floppy and if media is inserted. - There are 3 cases: - No floppy present - Set BBS entry to ignore - Floppy present & no media - Set BBS entry to lowest priority. We cannot - set it to ignore since 16-bit CSM will - indicate no floppy and thus drive A: is - unusable. CSM-16 will not try floppy since - lowest priority and thus not incur boot - time penality. - Floppy present & media - Set BBS entry to some priority. - - @return State of floppy media - -**/ -UINT8 -HasMediaInFloppy ( - VOID - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - EFI_ISA_IO_PROTOCOL *IsaIo; - EFI_BLOCK_IO_PROTOCOL *BlkIo; - - HandleBuffer = NULL; - HandleCount = 0; - - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiIsaIoProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - - // - // If don't find any ISA/IO protocol assume no floppy. Need for floppy - // free system - // - if (HandleCount == 0) { - return FLOPPY_NOT_PRESENT; - } - - ASSERT (HandleBuffer != NULL); - - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiIsaIoProtocolGuid, - (VOID **)&IsaIo - ); - if (EFI_ERROR (Status)) { - continue; - } - - if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x604)) { - continue; - } - - // - // Update blockio in case the floppy is inserted in during BdsTimeout - // - Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); - - if (EFI_ERROR (Status)) { - continue; - } - - Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); - - if (EFI_ERROR (Status)) { - continue; - } - - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiBlockIoProtocolGuid, - (VOID **)&BlkIo - ); - if (EFI_ERROR (Status)) { - continue; - } - - if (BlkIo->Media->MediaPresent) { - FreePool (HandleBuffer); - return FLOPPY_PRESENT_WITH_MEDIA; - } else { - FreePool (HandleBuffer); - return FLOPPY_PRESENT_NO_MEDIA; - } - } - - FreePool (HandleBuffer); - - return FLOPPY_NOT_PRESENT; -} - -/** - Complete build of BBS TABLE. - - @param Private Legacy BIOS Instance data - @param BbsTable BBS Table passed to 16-bit code - - @retval EFI_SUCCESS Removable media not present - -**/ -EFI_STATUS -LegacyBiosBuildBbs ( - IN LEGACY_BIOS_INSTANCE *Private, - IN BBS_TABLE *BbsTable - ) -{ - UINTN BbsIndex; - HDD_INFO *HddInfo; - UINTN HddIndex; - UINTN Index; - EFI_HANDLE *BlockIoHandles; - UINTN NumberBlockIoHandles; - UINTN BlockIndex; - EFI_STATUS Status; - - // - // First entry is floppy. - // Next 2*MAX_IDE_CONTROLLER entries are for onboard IDE. - // Next n entries are filled in after each ROM is dispatched. - // Entry filled in if follow BBS spec. See LegacyPci.c - // Next entries are for non-BBS compliant ROMS. They are filled in by - // 16-bit code during Legacy16UpdateBbs invocation. Final BootPriority - // occurs after that invocation. - // - // Floppy - // Set default state. - // - IsHaveMediaInFloppy = HasMediaInFloppy (); - if (IsHaveMediaInFloppy == FLOPPY_PRESENT_WITH_MEDIA) { - BbsTable[0].BootPriority = BBS_UNPRIORITIZED_ENTRY; - } else { - if (IsHaveMediaInFloppy == FLOPPY_PRESENT_NO_MEDIA) { - BbsTable[0].BootPriority = BBS_LOWEST_PRIORITY; - } else { - BbsTable[0].BootPriority = BBS_IGNORE_ENTRY; - } - } - - BbsTable[0].Bus = 0xff; - BbsTable[0].Device = 0xff; - BbsTable[0].Function = 0xff; - BbsTable[0].DeviceType = BBS_FLOPPY; - BbsTable[0].Class = 01; - BbsTable[0].SubClass = 02; - BbsTable[0].StatusFlags.OldPosition = 0; - BbsTable[0].StatusFlags.Reserved1 = 0; - BbsTable[0].StatusFlags.Enabled = 0; - BbsTable[0].StatusFlags.Failed = 0; - BbsTable[0].StatusFlags.MediaPresent = 0; - BbsTable[0].StatusFlags.Reserved2 = 0; - - // - // Onboard HDD - Note Each HDD controller controls 2 drives - // Master & Slave - // - HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0]; - // - // Get IDE Drive Info - // - LegacyBiosBuildIdeData (Private, &HddInfo, 0); - - for (HddIndex = 0; HddIndex < MAX_IDE_CONTROLLER; HddIndex++) { - BbsIndex = HddIndex * 2 + 1; - for (Index = 0; Index < 2; ++Index) { - BbsTable[BbsIndex + Index].Bus = HddInfo[HddIndex].Bus; - BbsTable[BbsIndex + Index].Device = HddInfo[HddIndex].Device; - BbsTable[BbsIndex + Index].Function = HddInfo[HddIndex].Function; - BbsTable[BbsIndex + Index].Class = 01; - BbsTable[BbsIndex + Index].SubClass = 01; - BbsTable[BbsIndex + Index].StatusFlags.OldPosition = 0; - BbsTable[BbsIndex + Index].StatusFlags.Reserved1 = 0; - BbsTable[BbsIndex + Index].StatusFlags.Enabled = 0; - BbsTable[BbsIndex + Index].StatusFlags.Failed = 0; - BbsTable[BbsIndex + Index].StatusFlags.MediaPresent = 0; - BbsTable[BbsIndex + Index].StatusFlags.Reserved2 = 0; - - // - // If no controller found or no device found set to ignore - // else set to unprioritized and set device type - // - if (HddInfo[HddIndex].CommandBaseAddress == 0) { - BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; - } else { - if (Index == 0) { - if ((HddInfo[HddIndex].Status & (HDD_MASTER_IDE | HDD_MASTER_ATAPI_CDROM | HDD_MASTER_ATAPI_ZIPDISK)) != 0) { - BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY; - if ((HddInfo[HddIndex].Status & HDD_MASTER_IDE) != 0) { - BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; - } else if ((HddInfo[HddIndex].Status & HDD_MASTER_ATAPI_CDROM) != 0) { - BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM; - } else { - // - // for ZIPDISK - // - BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; - } - } else { - BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; - } - } else { - if ((HddInfo[HddIndex].Status & (HDD_SLAVE_IDE | HDD_SLAVE_ATAPI_CDROM | HDD_SLAVE_ATAPI_ZIPDISK)) != 0) { - BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY; - if ((HddInfo[HddIndex].Status & HDD_SLAVE_IDE) != 0) { - BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; - } else if ((HddInfo[HddIndex].Status & HDD_SLAVE_ATAPI_CDROM) != 0) { - BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM; - } else { - // - // for ZIPDISK - // - BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; - } - } else { - BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; - } - } - } - } - } - - // - // Add non-IDE block devices - // - BbsIndex = HddIndex * 2 + 1; - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiBlockIoProtocolGuid, - NULL, - &NumberBlockIoHandles, - &BlockIoHandles - ); - - if (!EFI_ERROR (Status)) { - UINTN Removable; - EFI_BLOCK_IO_PROTOCOL *BlkIo; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; - EFI_HANDLE PciHandle; - UINTN SegNum; - UINTN BusNum; - UINTN DevNum; - UINTN FuncNum; - - for (Removable = 0; Removable < 2; Removable++) { - for (BlockIndex = 0; BlockIndex < NumberBlockIoHandles; BlockIndex++) { - Status = gBS->HandleProtocol ( - BlockIoHandles[BlockIndex], - &gEfiBlockIoProtocolGuid, - (VOID **)&BlkIo - ); - - if (EFI_ERROR (Status)) { - continue; - } - - // - // Skip the logical partitions - // - if (BlkIo->Media->LogicalPartition) { - continue; - } - - // - // Skip the fixed block io then the removable block io - // - if (BlkIo->Media->RemovableMedia == ((Removable == 0) ? FALSE : TRUE)) { - continue; - } - - // - // Get Device Path - // - Status = gBS->HandleProtocol ( - BlockIoHandles[BlockIndex], - &gEfiDevicePathProtocolGuid, - (VOID **)&DevicePath - ); - if (EFI_ERROR (Status)) { - continue; - } - - // - // Skip ATA devices as they have already been handled - // - DevicePathNode = DevicePath; - while (!IsDevicePathEnd (DevicePathNode)) { - if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) && - (DevicePathSubType (DevicePathNode) == MSG_ATAPI_DP)) - { - break; - } - - DevicePathNode = NextDevicePathNode (DevicePathNode); - } - - if (!IsDevicePathEnd (DevicePathNode)) { - continue; - } - - // - // Locate which PCI device - // - Status = gBS->LocateDevicePath ( - &gEfiPciIoProtocolGuid, - &DevicePath, - &PciHandle - ); - if (EFI_ERROR (Status)) { - continue; - } - - Status = gBS->HandleProtocol ( - PciHandle, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - if (EFI_ERROR (Status)) { - continue; - } - - Status = PciIo->GetLocation ( - PciIo, - &SegNum, - &BusNum, - &DevNum, - &FuncNum - ); - if (EFI_ERROR (Status)) { - continue; - } - - if (SegNum != 0) { - DEBUG (( - DEBUG_WARN, - "CSM cannot use PCI devices in segment %Lu\n", - (UINT64)SegNum - )); - continue; - } - - DEBUG (( - DEBUG_INFO, - "Add Legacy Bbs entry for PCI %d/%d/%d\n", - BusNum, - DevNum, - FuncNum - )); - - BbsTable[BbsIndex].Bus = BusNum; - BbsTable[BbsIndex].Device = DevNum; - BbsTable[BbsIndex].Function = FuncNum; - BbsTable[BbsIndex].Class = 1; - BbsTable[BbsIndex].SubClass = 0x80; - BbsTable[BbsIndex].StatusFlags.OldPosition = 0; - BbsTable[BbsIndex].StatusFlags.Reserved1 = 0; - BbsTable[BbsIndex].StatusFlags.Enabled = 0; - BbsTable[BbsIndex].StatusFlags.Failed = 0; - BbsTable[BbsIndex].StatusFlags.MediaPresent = 0; - BbsTable[BbsIndex].StatusFlags.Reserved2 = 0; - BbsTable[BbsIndex].DeviceType = BBS_HARDDISK; - BbsTable[BbsIndex].BootPriority = BBS_UNPRIORITIZED_ENTRY; - BbsIndex++; - - if (BbsIndex == MAX_BBS_ENTRIES) { - Removable = 2; - break; - } - } - } - - FreePool (BlockIoHandles); - } - - return EFI_SUCCESS; -} - -/** - Get all BBS info - - @param This Protocol instance pointer. - @param HddCount Number of HDD_INFO structures - @param HddInfo Onboard IDE controller information - @param BbsCount Number of BBS_TABLE structures - @param BbsTable List BBS entries - - @retval EFI_SUCCESS Tables returned - @retval EFI_NOT_FOUND resource not found - @retval EFI_DEVICE_ERROR can not get BBS table - -**/ -EFI_STATUS -EFIAPI -LegacyBiosGetBbsInfo ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - OUT UINT16 *HddCount, - OUT HDD_INFO **HddInfo, - OUT UINT16 *BbsCount, - OUT BBS_TABLE **BbsTable - ) -{ - LEGACY_BIOS_INSTANCE *Private; - EFI_IA32_REGISTER_SET Regs; - EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; - // HDD_INFO *LocalHddInfo; - // IN BBS_TABLE *LocalBbsTable; - UINTN NumHandles; - EFI_HANDLE *HandleBuffer; - UINTN Index; - UINTN TempData; - UINT32 Granularity; - - HandleBuffer = NULL; - - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; - // LocalHddInfo = EfiToLegacy16BootTable->HddInfo; - // LocalBbsTable = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable; - - if (!mBbsTableDoneFlag) { - mBbsTable = Private->BbsTablePtr; - - // - // Always enable disk controllers so 16-bit CSM code has valid information for all - // drives. - // - // - // Get PciRootBridgeIO protocol - // - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciRootBridgeIoProtocolGuid, - NULL, - &NumHandles, - &HandleBuffer - ); - - if (NumHandles == 0) { - return EFI_NOT_FOUND; - } - - mBbsTableDoneFlag = TRUE; - for (Index = 0; Index < NumHandles; Index++) { - // - // Connect PciRootBridgeIO protocol handle with FALSE parameter to let - // PCI bus driver enumerate all subsequent handles - // - gBS->ConnectController (HandleBuffer[Index], NULL, NULL, FALSE); - } - - LegacyBiosBuildBbs (Private, mBbsTable); - - Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xe0000, 0x20000, &Granularity); - - // - // Call into Legacy16 code to add to BBS table for non BBS compliant OPROMs. - // - ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); - Regs.X.AX = Legacy16UpdateBbs; - - // - // Pass in handoff data - // - TempData = (UINTN)EfiToLegacy16BootTable; - Regs.X.ES = NORMALIZE_EFI_SEGMENT ((UINT32)TempData); - Regs.X.BX = NORMALIZE_EFI_OFFSET ((UINT32)TempData); - - Private->LegacyBios.FarCall86 ( - This, - Private->Legacy16CallSegment, - Private->Legacy16CallOffset, - &Regs, - NULL, - 0 - ); - - Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate); - Private->LegacyRegion->Lock (Private->LegacyRegion, 0xe0000, 0x20000, &Granularity); - - if (Regs.X.AX != 0) { - return EFI_DEVICE_ERROR; - } - } - - if (HandleBuffer != NULL) { - FreePool (HandleBuffer); - } - - *HddCount = MAX_IDE_CONTROLLER; - *HddInfo = EfiToLegacy16BootTable->HddInfo; - *BbsTable = (BBS_TABLE *)(UINTN)EfiToLegacy16BootTable->BbsTable; - *BbsCount = (UINT16)(sizeof (Private->IntThunk->BbsTable) / sizeof (BBS_TABLE)); - return EFI_SUCCESS; -} diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBda.c b/OvmfPkg/Csm/LegacyBiosDxe/LegacyBda.c deleted file mode 100644 index a873015d06..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBda.c +++ /dev/null @@ -1,62 +0,0 @@ -/** @file - This code fills in BDA (0x400) and EBDA (pointed to by 0x4xx) - information. There is support for doing initializeation before - Legacy16 is loaded and before a legacy boot is attempted. - -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "LegacyBiosInterface.h" - -/** - Fill in the standard BDA and EBDA stuff before Legacy16 load - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosInitBda ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - BDA_STRUC *Bda; - UINT8 *Ebda; - - Bda = (BDA_STRUC *)((UINTN)0x400); - Ebda = (UINT8 *)((UINTN)0x9fc00); - - ACCESS_PAGE0_CODE ( - ZeroMem (Bda, 0x100); - // - // 640k-1k for EBDA - // - Bda->MemSize = 0x27f; - Bda->KeyHead = 0x1e; - Bda->KeyTail = 0x1e; - Bda->FloppyData = 0x00; - Bda->FloppyTimeout = 0xff; - - Bda->KeyStart = 0x001E; - Bda->KeyEnd = 0x003E; - Bda->KeyboardStatus = 0x10; - Bda->Ebda = 0x9fc0; - - // - // Move LPT time out here and zero out LPT4 since some SCSI OPROMS - // use this as scratch pad (LPT4 is Reserved) - // - Bda->Lpt1_2Timeout = 0x1414; - Bda->Lpt3_4Timeout = 0x1400; - - ); - - ZeroMem (Ebda, 0x400); - *Ebda = 0x01; - - return EFI_SUCCESS; -} diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBios.c b/OvmfPkg/Csm/LegacyBiosDxe/LegacyBios.c deleted file mode 100644 index d587b55e3b..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBios.c +++ /dev/null @@ -1,1227 +0,0 @@ -/** @file - -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "LegacyBiosInterface.h" - -#define PHYSICAL_ADDRESS_TO_POINTER(Address) ((VOID *) ((UINTN) Address)) - -// -// define maximum number of HDD system supports -// -#define MAX_HDD_ENTRIES 0x30 - -// -// Module Global: -// Since this driver will only ever produce one instance of the Private Data -// protocol you are not required to dynamically allocate the PrivateData. -// -LEGACY_BIOS_INSTANCE mPrivateData; - -// -// The SMBIOS table in EfiRuntimeServicesData memory -// -VOID *mRuntimeSmbiosEntryPoint = NULL; - -// -// The SMBIOS table in EfiReservedMemoryType memory -// -EFI_PHYSICAL_ADDRESS mReserveSmbiosEntryPoint = 0; -EFI_PHYSICAL_ADDRESS mStructureTableAddress = 0; -UINTN mStructureTablePages = 0; -BOOLEAN mEndOfDxe = FALSE; - -/** - Allocate memory for legacy usage. The memory is executable. - - @param AllocateType The type of allocation to perform. - @param MemoryType The type of memory to allocate. - @param StartPageAddress Start address of range - @param Pages Number of pages to allocate - @param Result Result of allocation - - @retval EFI_SUCCESS Legacy memory is allocated successfully. - @retval Other Legacy memory is not allocated. - -**/ -EFI_STATUS -AllocateLegacyMemory ( - IN EFI_ALLOCATE_TYPE AllocateType, - IN EFI_MEMORY_TYPE MemoryType, - IN EFI_PHYSICAL_ADDRESS StartPageAddress, - IN UINTN Pages, - OUT EFI_PHYSICAL_ADDRESS *Result - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS MemPage; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; - - // - // Allocate Pages of memory less <= StartPageAddress - // - MemPage = (EFI_PHYSICAL_ADDRESS)(UINTN)StartPageAddress; - Status = gBS->AllocatePages ( - AllocateType, - MemoryType, - Pages, - &MemPage - ); - // - // Do not ASSERT on Status error but let caller decide since some cases - // memory is already taken but that is ok. - // - if (!EFI_ERROR (Status)) { - if (MemoryType != EfiBootServicesCode) { - // - // Make sure that the buffer can be used to store code. - // - Status = gDS->GetMemorySpaceDescriptor (MemPage, &MemDesc); - if (!EFI_ERROR (Status) && ((MemDesc.Attributes & EFI_MEMORY_XP) != 0)) { - Status = gDS->SetMemorySpaceAttributes ( - MemPage, - EFI_PAGES_TO_SIZE (Pages), - MemDesc.Attributes & (~EFI_MEMORY_XP) - ); - } - - if (EFI_ERROR (Status)) { - gBS->FreePages (MemPage, Pages); - } - } - } - - if (!EFI_ERROR (Status)) { - *Result = (EFI_PHYSICAL_ADDRESS)(UINTN)MemPage; - } - - return Status; -} - -/** - This function is called when EFI needs to reserve an area in the 0xE0000 or 0xF0000 - 64 KB blocks. - - Note: inconsistency with the Framework CSM spec. Per the spec, this function may be - invoked only once. This limitation is relaxed to allow multiple calls in this implementation. - - @param This Protocol instance pointer. - @param LegacyMemorySize Size of required region - @param Region Region to use. 00 = Either 0xE0000 or 0xF0000 - block Bit0 = 1 0xF0000 block Bit1 = 1 0xE0000 - block - @param Alignment Address alignment. Bit mapped. First non-zero - bit from right is alignment. - @param LegacyMemoryAddress Region Assigned - - @retval EFI_SUCCESS Region assigned - @retval EFI_ACCESS_DENIED Procedure previously invoked - @retval Other Region not assigned - -**/ -EFI_STATUS -EFIAPI -LegacyBiosGetLegacyRegion ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINTN LegacyMemorySize, - IN UINTN Region, - IN UINTN Alignment, - OUT VOID **LegacyMemoryAddress - ) -{ - LEGACY_BIOS_INSTANCE *Private; - EFI_IA32_REGISTER_SET Regs; - EFI_STATUS Status; - UINT32 Granularity; - - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xE0000, 0x20000, &Granularity); - - ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); - Regs.X.AX = Legacy16GetTableAddress; - Regs.X.BX = (UINT16)Region; - Regs.X.CX = (UINT16)LegacyMemorySize; - Regs.X.DX = (UINT16)Alignment; - Private->LegacyBios.FarCall86 ( - &Private->LegacyBios, - Private->Legacy16CallSegment, - Private->Legacy16CallOffset, - &Regs, - NULL, - 0 - ); - - if (Regs.X.AX == 0) { - *LegacyMemoryAddress = (VOID *)(((UINTN)Regs.X.DS << 4) + Regs.X.BX); - Status = EFI_SUCCESS; - } else { - Status = EFI_OUT_OF_RESOURCES; - } - - Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate); - Private->LegacyRegion->Lock (Private->LegacyRegion, 0xE0000, 0x20000, &Granularity); - - return Status; -} - -/** - This function is called when copying data to the region assigned by - EFI_LEGACY_BIOS_PROTOCOL.GetLegacyRegion(). - - @param This Protocol instance pointer. - @param LegacyMemorySize Size of data to copy - @param LegacyMemoryAddress Legacy Region destination address Note: must - be in region assigned by - LegacyBiosGetLegacyRegion - @param LegacyMemorySourceAddress Source of data - - @retval EFI_SUCCESS The data was copied successfully. - @retval EFI_ACCESS_DENIED Either the starting or ending address is out of bounds. -**/ -EFI_STATUS -EFIAPI -LegacyBiosCopyLegacyRegion ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINTN LegacyMemorySize, - IN VOID *LegacyMemoryAddress, - IN VOID *LegacyMemorySourceAddress - ) -{ - LEGACY_BIOS_INSTANCE *Private; - UINT32 Granularity; - - if ((LegacyMemoryAddress < (VOID *)(UINTN)0xE0000) || - ((UINTN)LegacyMemoryAddress + LegacyMemorySize > (UINTN)0x100000) - ) - { - return EFI_ACCESS_DENIED; - } - - // - // There is no protection from writes over lapping if this function is - // called multiple times. - // - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xE0000, 0x20000, &Granularity); - CopyMem (LegacyMemoryAddress, LegacyMemorySourceAddress, LegacyMemorySize); - - Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate); - Private->LegacyRegion->Lock (Private->LegacyRegion, 0xE0000, 0x20000, &Granularity); - - return EFI_SUCCESS; -} - -/** - Find Legacy16 BIOS image in the FLASH device and shadow it into memory. Find - the $EFI table in the shadow area. Thunk into the Legacy16 code after it had - been shadowed. - - @param Private Legacy BIOS context data - - @retval EFI_SUCCESS Legacy16 code loaded - @retval Other No protocol installed, unload driver. - -**/ -EFI_STATUS -ShadowAndStartLegacy16 ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - EFI_STATUS Status; - UINT8 *Ptr; - UINT8 *PtrEnd; - BOOLEAN Done; - EFI_COMPATIBILITY16_TABLE *Table; - UINT8 CheckSum; - EFI_IA32_REGISTER_SET Regs; - EFI_TO_COMPATIBILITY16_INIT_TABLE *EfiToLegacy16InitTable; - EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; - VOID *LegacyBiosImage; - UINTN LegacyBiosImageSize; - UINTN E820Size; - UINT32 *ClearPtr; - BBS_TABLE *BbsTable; - LEGACY_EFI_HDD_TABLE *LegacyEfiHddTable; - UINTN Index; - UINT32 TpmPointer; - VOID *TpmBinaryImage; - UINTN TpmBinaryImageSize; - UINTN Location; - UINTN Alignment; - UINTN TempData; - EFI_PHYSICAL_ADDRESS Address; - UINT16 OldMask; - UINT16 NewMask; - UINT32 Granularity; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; - - Location = 0; - Alignment = 0; - - // - // we allocate the C/D/E/F segment as RT code so no one will use it any more. - // - Address = 0xC0000; - gDS->GetMemorySpaceDescriptor (Address, &Descriptor); - if (Descriptor.GcdMemoryType == EfiGcdMemoryTypeSystemMemory) { - // - // If it is already reserved, we should be safe, or else we allocate it. - // - Status = gBS->AllocatePages ( - AllocateAddress, - EfiRuntimeServicesCode, - 0x40000/EFI_PAGE_SIZE, - &Address - ); - if (EFI_ERROR (Status)) { - // - // Bugbug: need to figure out whether C/D/E/F segment should be marked as reserved memory. - // - DEBUG ((DEBUG_ERROR, "Failed to allocate the C/D/E/F segment Status = %r", Status)); - } - } - - // - // start testtest - // GetTimerValue (&Ticker); - // - // gRT->SetVariable (L"StartLegacy", - // &gEfiGlobalVariableGuid, - // EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - // sizeof (UINT64), - // (VOID *)&Ticker - // ); - // end testtest - // - EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; - Status = Private->LegacyBiosPlatform->GetPlatformInfo ( - Private->LegacyBiosPlatform, - EfiGetPlatformBinarySystemRom, - &LegacyBiosImage, - &LegacyBiosImageSize, - &Location, - &Alignment, - 0, - 0 - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Private->BiosStart = (UINT32)(0x100000 - LegacyBiosImageSize); - Private->OptionRom = 0xc0000; - Private->LegacyBiosImageSize = (UINT32)LegacyBiosImageSize; - - // - // Can only shadow into memory allocated for legacy usage. - // - ASSERT (Private->BiosStart > Private->OptionRom); - - // - // Shadow Legacy BIOS. Turn on memory and copy image - // - Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xc0000, 0x40000, &Granularity); - - ClearPtr = (VOID *)((UINTN)0xc0000); - - // - // Initialize region from 0xc0000 to start of BIOS to all ffs. This allows unused - // regions to be used by EMM386 etc. - // - SetMem ((VOID *)ClearPtr, (UINTN)(0x40000 - LegacyBiosImageSize), 0xff); - - TempData = Private->BiosStart; - - CopyMem ( - (VOID *)TempData, - LegacyBiosImage, - (UINTN)LegacyBiosImageSize - ); - - Private->Cpu->FlushDataCache (Private->Cpu, 0xc0000, 0x40000, EfiCpuFlushTypeWriteBackInvalidate); - - // - // Search for Legacy16 table in Shadowed ROM - // - Done = FALSE; - Table = NULL; - for (Ptr = (UINT8 *)TempData; Ptr < (UINT8 *)((UINTN)0x100000) && !Done; Ptr += 0x10) { - if (*(UINT32 *)Ptr == SIGNATURE_32 ('I', 'F', 'E', '$')) { - Table = (EFI_COMPATIBILITY16_TABLE *)Ptr; - PtrEnd = Ptr + Table->TableLength; - for (CheckSum = 0; Ptr < PtrEnd; Ptr++) { - CheckSum = (UINT8)(CheckSum +*Ptr); - } - - Done = TRUE; - } - } - - if (Table == NULL) { - DEBUG ((DEBUG_ERROR, "No Legacy16 table found\n")); - return EFI_NOT_FOUND; - } - - if (!Done) { - // - // Legacy16 table header checksum error. - // - DEBUG ((DEBUG_ERROR, "Legacy16 table found with bad talbe header checksum\n")); - } - - // - // Remember location of the Legacy16 table - // - Private->Legacy16Table = Table; - Private->Legacy16CallSegment = Table->Compatibility16CallSegment; - Private->Legacy16CallOffset = Table->Compatibility16CallOffset; - EfiToLegacy16InitTable = &Private->IntThunk->EfiToLegacy16InitTable; - Private->Legacy16InitPtr = EfiToLegacy16InitTable; - Private->Legacy16BootPtr = &Private->IntThunk->EfiToLegacy16BootTable; - Private->InternalIrqRoutingTable = NULL; - Private->NumberIrqRoutingEntries = 0; - Private->BbsTablePtr = NULL; - Private->LegacyEfiHddTable = NULL; - Private->DiskEnd = 0; - Private->Disk4075 = 0; - Private->HddTablePtr = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo; - Private->NumberHddControllers = MAX_IDE_CONTROLLER; - Private->Dump[0] = 'D'; - Private->Dump[1] = 'U'; - Private->Dump[2] = 'M'; - Private->Dump[3] = 'P'; - - ZeroMem ( - Private->Legacy16BootPtr, - sizeof (EFI_TO_COMPATIBILITY16_BOOT_TABLE) - ); - - // - // Store away a copy of the EFI System Table - // - Table->EfiSystemTable = (UINT32)(UINTN)gST; - - // - // IPF CSM integration -Bug - // - // Construct the Legacy16 boot memory map. This sets up number of - // E820 entries. - // - LegacyBiosBuildE820 (Private, &E820Size); - // - // Initialize BDA and EBDA standard values needed to load Legacy16 code - // - LegacyBiosInitBda (Private); - LegacyBiosInitCmos (Private); - - // - // All legacy interrupt should be masked when do initialization work from legacy 16 code. - // - Private->Legacy8259->GetMask (Private->Legacy8259, &OldMask, NULL, NULL, NULL); - NewMask = 0xFFFF; - Private->Legacy8259->SetMask (Private->Legacy8259, &NewMask, NULL, NULL, NULL); - - // - // Call into Legacy16 code to do an INIT - // - ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); - Regs.X.AX = Legacy16InitializeYourself; - Regs.X.ES = EFI_SEGMENT (*((UINT32 *)&EfiToLegacy16InitTable)); - Regs.X.BX = EFI_OFFSET (*((UINT32 *)&EfiToLegacy16InitTable)); - - Private->LegacyBios.FarCall86 ( - &Private->LegacyBios, - Table->Compatibility16CallSegment, - Table->Compatibility16CallOffset, - &Regs, - NULL, - 0 - ); - - // - // Restore original legacy interrupt mask value - // - Private->Legacy8259->SetMask (Private->Legacy8259, &OldMask, NULL, NULL, NULL); - - if (Regs.X.AX != 0) { - return EFI_DEVICE_ERROR; - } - - // - // start testtest - // GetTimerValue (&Ticker); - // - // gRT->SetVariable (L"BackFromInitYourself", - // &gEfiGlobalVariableGuid, - // EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - // sizeof (UINT64), - // (VOID *)&Ticker - // ); - // end testtest - // - // Copy E820 table after InitializeYourself is completed - // - ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); - Regs.X.AX = Legacy16GetTableAddress; - Regs.X.CX = (UINT16)E820Size; - Regs.X.DX = 1; - Private->LegacyBios.FarCall86 ( - &Private->LegacyBios, - Table->Compatibility16CallSegment, - Table->Compatibility16CallOffset, - &Regs, - NULL, - 0 - ); - - Table->E820Pointer = (UINT32)(Regs.X.DS * 16 + Regs.X.BX); - Table->E820Length = (UINT32)E820Size; - if (Regs.X.AX != 0) { - DEBUG ((DEBUG_ERROR, "Legacy16 E820 length insufficient\n")); - } else { - TempData = Table->E820Pointer; - CopyMem ((VOID *)TempData, Private->E820Table, E820Size); - } - - // - // Get PnPInstallationCheck Info. - // - Private->PnPInstallationCheckSegment = Table->PnPInstallationCheckSegment; - Private->PnPInstallationCheckOffset = Table->PnPInstallationCheckOffset; - - // - // Check if PCI Express is supported. If yes, Save base address. - // - Status = Private->LegacyBiosPlatform->GetPlatformInfo ( - Private->LegacyBiosPlatform, - EfiGetPlatformPciExpressBase, - NULL, - NULL, - &Location, - &Alignment, - 0, - 0 - ); - if (!EFI_ERROR (Status)) { - Private->Legacy16Table->PciExpressBase = (UINT32)Location; - Location = 0; - } - - // - // Check if TPM is supported. If yes get a region in E0000,F0000 to copy it - // into, copy it and update pointer to binary image. This needs to be - // done prior to any OPROM for security purposes. - // - Status = Private->LegacyBiosPlatform->GetPlatformInfo ( - Private->LegacyBiosPlatform, - EfiGetPlatformBinaryTpmBinary, - &TpmBinaryImage, - &TpmBinaryImageSize, - &Location, - &Alignment, - 0, - 0 - ); - if (!EFI_ERROR (Status)) { - ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); - Regs.X.AX = Legacy16GetTableAddress; - Regs.X.CX = (UINT16)TpmBinaryImageSize; - Regs.X.DX = 1; - Private->LegacyBios.FarCall86 ( - &Private->LegacyBios, - Table->Compatibility16CallSegment, - Table->Compatibility16CallOffset, - &Regs, - NULL, - 0 - ); - - TpmPointer = (UINT32)(Regs.X.DS * 16 + Regs.X.BX); - if (Regs.X.AX != 0) { - DEBUG ((DEBUG_ERROR, "TPM cannot be loaded\n")); - } else { - CopyMem ((VOID *)(UINTN)TpmPointer, TpmBinaryImage, TpmBinaryImageSize); - Table->TpmSegment = Regs.X.DS; - Table->TpmOffset = Regs.X.BX; - } - } - - // - // Lock the Legacy BIOS region - // - Private->Cpu->FlushDataCache (Private->Cpu, Private->BiosStart, (UINT32)LegacyBiosImageSize, EfiCpuFlushTypeWriteBackInvalidate); - Private->LegacyRegion->Lock (Private->LegacyRegion, Private->BiosStart, (UINT32)LegacyBiosImageSize, &Granularity); - - // - // Get the BbsTable from LOW_MEMORY_THUNK - // - BbsTable = (BBS_TABLE *)(UINTN)Private->IntThunk->BbsTable; - ZeroMem ((VOID *)BbsTable, sizeof (Private->IntThunk->BbsTable)); - - EfiToLegacy16BootTable->BbsTable = (UINT32)(UINTN)BbsTable; - Private->BbsTablePtr = (VOID *)BbsTable; - - // - // Populate entire table with BBS_IGNORE_ENTRY - // - EfiToLegacy16BootTable->NumberBbsEntries = MAX_BBS_ENTRIES; - - for (Index = 0; Index < MAX_BBS_ENTRIES; Index++) { - BbsTable[Index].BootPriority = BBS_IGNORE_ENTRY; - } - - // - // Allocate space for Legacy HDD table - // - LegacyEfiHddTable = (LEGACY_EFI_HDD_TABLE *)AllocateZeroPool ((UINTN)MAX_HDD_ENTRIES * sizeof (LEGACY_EFI_HDD_TABLE)); - ASSERT (LegacyEfiHddTable); - - Private->LegacyEfiHddTable = LegacyEfiHddTable; - Private->LegacyEfiHddTableIndex = 0x00; - - // - // start testtest - // GetTimerValue (&Ticker); - // - // gRT->SetVariable (L"EndOfLoadFv", - // &gEfiGlobalVariableGuid, - // EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - // sizeof (UINT64), - // (VOID *)&Ticker - // ); - // end testtest - // - return EFI_SUCCESS; -} - -/** - Shadow all legacy16 OPROMs that haven't been shadowed. - Warning: Use this with caution. This routine disconnects all EFI - drivers. If used externally then caller must re-connect EFI - drivers. - - @param This Protocol instance pointer. - - @retval EFI_SUCCESS OPROMs shadowed - -**/ -EFI_STATUS -EFIAPI -LegacyBiosShadowAllLegacyOproms ( - IN EFI_LEGACY_BIOS_PROTOCOL *This - ) -{ - LEGACY_BIOS_INSTANCE *Private; - - // - // EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform; - // EFI_LEGACY16_TABLE *Legacy16Table; - // - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - - // - // LegacyBiosPlatform = Private->LegacyBiosPlatform; - // Legacy16Table = Private->Legacy16Table; - // - // Shadow PCI ROMs. We must do this near the end since this will kick - // of Native EFI drivers that may be needed to collect info for Legacy16 - // - // WARNING: PciIo is gone after this call. - // - PciProgramAllInterruptLineRegisters (Private); - - PciShadowRoms (Private); - - // - // Shadow PXE base code, BIS etc. - // - // LegacyBiosPlatform->ShadowServiceRoms (LegacyBiosPlatform, - // &Private->OptionRom, - // Legacy16Table); - // - return EFI_SUCCESS; -} - -/** - Get the PCI BIOS interface version. - - @param Private Driver private data. - - @return The PCI interface version number in Binary Coded Decimal (BCD) format. - E.g.: 0x0210 indicates 2.10, 0x0300 indicates 3.00 - -**/ -UINT16 -GetPciInterfaceVersion ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - EFI_IA32_REGISTER_SET Reg; - BOOLEAN ThunkFailed; - UINT16 PciInterfaceVersion; - - PciInterfaceVersion = 0; - - Reg.X.AX = 0xB101; - Reg.E.EDI = 0; - - ThunkFailed = Private->LegacyBios.Int86 (&Private->LegacyBios, 0x1A, &Reg); - if (!ThunkFailed) { - // - // From PCI Firmware 3.0 Specification: - // If the CARRY FLAG [CF] is cleared and AH is set to 00h, it is still necessary to examine the - // contents of [EDX] for the presence of the string "PCI" + (trailing space) to fully validate the - // presence of the PCI function set. [BX] will further indicate the version level, with enough - // granularity to allow for incremental changes in the code that don't affect the function interface. - // Version numbers are stored as Binary Coded Decimal (BCD) values. For example, Version 2.10 - // would be returned as a 02h in the [BH] registers and 10h in the [BL] registers. - // - if ((Reg.X.Flags.CF == 0) && (Reg.H.AH == 0) && (Reg.E.EDX == SIGNATURE_32 ('P', 'C', 'I', ' '))) { - PciInterfaceVersion = Reg.X.BX; - } - } - - return PciInterfaceVersion; -} - -/** - Callback function to calculate SMBIOS table size, and allocate memory for SMBIOS table. - SMBIOS table will be copied into EfiReservedMemoryType memory in legacy boot path. - - @param Event Event whose notification function is being invoked. - @param Context The pointer to the notification function's context, - which is implementation-dependent. - -**/ -VOID -EFIAPI -InstallSmbiosEventCallback ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure; - - // - // Get SMBIOS table from EFI configuration table - // - Status = EfiGetSystemConfigurationTable ( - &gEfiSmbiosTableGuid, - &mRuntimeSmbiosEntryPoint - ); - if ((EFI_ERROR (Status)) || (mRuntimeSmbiosEntryPoint == NULL)) { - return; - } - - EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *)mRuntimeSmbiosEntryPoint; - - // - // Allocate memory for SMBIOS Entry Point Structure. - // CSM framework spec requires SMBIOS table below 4GB in EFI_TO_COMPATIBILITY16_BOOT_TABLE. - // - if (mReserveSmbiosEntryPoint == 0) { - // - // Entrypoint structure with fixed size is allocated only once. - // - mReserveSmbiosEntryPoint = SIZE_4GB - 1; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiReservedMemoryType, - EFI_SIZE_TO_PAGES ((UINTN)(EntryPointStructure->EntryPointLength)), - &mReserveSmbiosEntryPoint - ); - if (EFI_ERROR (Status)) { - mReserveSmbiosEntryPoint = 0; - return; - } - - DEBUG ((DEBUG_INFO, "Allocate memory for Smbios Entry Point Structure\n")); - } - - if ((mStructureTableAddress != 0) && - (mStructureTablePages < EFI_SIZE_TO_PAGES ((UINT32)EntryPointStructure->TableLength))) - { - // - // If original buffer is not enough for the new SMBIOS table, free original buffer and re-allocate - // - gBS->FreePages (mStructureTableAddress, mStructureTablePages); - mStructureTableAddress = 0; - mStructureTablePages = 0; - DEBUG ((DEBUG_INFO, "Original size is not enough. Re-allocate the memory.\n")); - } - - if (mStructureTableAddress == 0) { - // - // Allocate reserved memory below 4GB. - // Smbios spec requires the structure table is below 4GB. - // - mStructureTableAddress = SIZE_4GB - 1; - mStructureTablePages = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength); - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiReservedMemoryType, - mStructureTablePages, - &mStructureTableAddress - ); - if (EFI_ERROR (Status)) { - gBS->FreePages ( - mReserveSmbiosEntryPoint, - EFI_SIZE_TO_PAGES ((UINTN)(EntryPointStructure->EntryPointLength)) - ); - mReserveSmbiosEntryPoint = 0; - mStructureTableAddress = 0; - mStructureTablePages = 0; - return; - } - - DEBUG ((DEBUG_INFO, "Allocate memory for Smbios Structure Table\n")); - } -} - -/** - Callback function to toggle EndOfDxe status. NULL pointer detection needs - this status to decide if it's necessary to change attributes of page 0. - - @param Event Event whose notification function is being invoked. - @param Context The pointer to the notification function's context, - which is implementation-dependent. - -**/ -VOID -EFIAPI -ToggleEndOfDxeStatus ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - mEndOfDxe = TRUE; - return; -} - -/** - Install Driver to produce Legacy BIOS protocol. - - @param ImageHandle Handle of driver image. - @param SystemTable Pointer to system table. - - @retval EFI_SUCCESS Legacy BIOS protocol installed - @retval No protocol installed, unload driver. - -**/ -EFI_STATUS -EFIAPI -LegacyBiosInstall ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - LEGACY_BIOS_INSTANCE *Private; - EFI_TO_COMPATIBILITY16_INIT_TABLE *EfiToLegacy16InitTable; - EFI_PHYSICAL_ADDRESS MemoryAddress; - EFI_PHYSICAL_ADDRESS EbdaReservedBaseAddress; - VOID *MemoryPtr; - EFI_PHYSICAL_ADDRESS MemoryAddressUnder1MB; - UINTN Index; - UINT32 *BaseVectorMaster; - EFI_PHYSICAL_ADDRESS StartAddress; - UINT32 *ClearPtr; - EFI_PHYSICAL_ADDRESS MemStart; - UINT32 IntRedirCode; - UINT32 Granularity; - BOOLEAN DecodeOn; - UINT32 MemorySize; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; - UINT64 Length; - UINT8 *SecureBoot; - EFI_EVENT InstallSmbiosEvent; - EFI_EVENT EndOfDxeEvent; - - // - // Load this driver's image to memory - // - Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // When UEFI Secure Boot is enabled, CSM module will not start any more. - // - SecureBoot = NULL; - GetEfiGlobalVariable2 (EFI_SECURE_BOOT_MODE_NAME, (VOID **)&SecureBoot, NULL); - if ((SecureBoot != NULL) && (*SecureBoot == SECURE_BOOT_MODE_ENABLE)) { - FreePool (SecureBoot); - return EFI_SECURITY_VIOLATION; - } - - if (SecureBoot != NULL) { - FreePool (SecureBoot); - } - - Private = &mPrivateData; - ZeroMem (Private, sizeof (LEGACY_BIOS_INSTANCE)); - - // - // Grab a copy of all the protocols we depend on. Any error would - // be a dispatcher bug!. - // - Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Private->Cpu); - ASSERT_EFI_ERROR (Status); - - Status = gBS->LocateProtocol (&gEfiTimerArchProtocolGuid, NULL, (VOID **)&Private->Timer); - ASSERT_EFI_ERROR (Status); - - Status = gBS->LocateProtocol (&gEfiLegacyRegion2ProtocolGuid, NULL, (VOID **)&Private->LegacyRegion); - ASSERT_EFI_ERROR (Status); - - Status = gBS->LocateProtocol (&gEfiLegacyBiosPlatformProtocolGuid, NULL, (VOID **)&Private->LegacyBiosPlatform); - ASSERT_EFI_ERROR (Status); - - Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **)&Private->Legacy8259); - ASSERT_EFI_ERROR (Status); - - Status = gBS->LocateProtocol (&gEfiLegacyInterruptProtocolGuid, NULL, (VOID **)&Private->LegacyInterrupt); - ASSERT_EFI_ERROR (Status); - - // - // Locate Memory Test Protocol if exists - // - Status = gBS->LocateProtocol ( - &gEfiGenericMemTestProtocolGuid, - NULL, - (VOID **)&Private->GenericMemoryTest - ); - ASSERT_EFI_ERROR (Status); - - // - // Make sure all memory from 0-640K is tested - // - for (StartAddress = 0; StartAddress < 0xa0000; ) { - gDS->GetMemorySpaceDescriptor (StartAddress, &Descriptor); - if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeReserved) { - StartAddress = Descriptor.BaseAddress + Descriptor.Length; - continue; - } - - Length = MIN (Descriptor.Length, 0xa0000 - StartAddress); - Private->GenericMemoryTest->CompatibleRangeTest ( - Private->GenericMemoryTest, - StartAddress, - Length - ); - StartAddress = StartAddress + Length; - } - - // - // Make sure all memory from 1MB to 16MB is tested and added to memory map - // - for (StartAddress = BASE_1MB; StartAddress < BASE_16MB; ) { - gDS->GetMemorySpaceDescriptor (StartAddress, &Descriptor); - if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeReserved) { - StartAddress = Descriptor.BaseAddress + Descriptor.Length; - continue; - } - - Length = MIN (Descriptor.Length, BASE_16MB - StartAddress); - Private->GenericMemoryTest->CompatibleRangeTest ( - Private->GenericMemoryTest, - StartAddress, - Length - ); - StartAddress = StartAddress + Length; - } - - Private->Signature = LEGACY_BIOS_INSTANCE_SIGNATURE; - - Private->LegacyBios.Int86 = LegacyBiosInt86; - Private->LegacyBios.FarCall86 = LegacyBiosFarCall86; - Private->LegacyBios.CheckPciRom = LegacyBiosCheckPciRom; - Private->LegacyBios.InstallPciRom = LegacyBiosInstallPciRom; - Private->LegacyBios.LegacyBoot = LegacyBiosLegacyBoot; - Private->LegacyBios.UpdateKeyboardLedStatus = LegacyBiosUpdateKeyboardLedStatus; - Private->LegacyBios.GetBbsInfo = LegacyBiosGetBbsInfo; - Private->LegacyBios.ShadowAllLegacyOproms = LegacyBiosShadowAllLegacyOproms; - Private->LegacyBios.PrepareToBootEfi = LegacyBiosPrepareToBootEfi; - Private->LegacyBios.GetLegacyRegion = LegacyBiosGetLegacyRegion; - Private->LegacyBios.CopyLegacyRegion = LegacyBiosCopyLegacyRegion; - Private->LegacyBios.BootUnconventionalDevice = LegacyBiosBootUnconventionalDevice; - - Private->ImageHandle = ImageHandle; - - // - // Enable read attribute of legacy region. - // - DecodeOn = TRUE; - Private->LegacyRegion->Decode ( - Private->LegacyRegion, - 0xc0000, - 0x40000, - &Granularity, - &DecodeOn - ); - // - // Set Cachebility for legacy region - // BUGBUG: Comments about this legacy region cacheability setting - // This setting will make D865GCHProduction CSM Unhappy - // - if (PcdGetBool (PcdLegacyBiosCacheLegacyRegion)) { - gDS->SetMemorySpaceAttributes ( - 0x0, - 0xA0000, - EFI_MEMORY_WB - ); - gDS->SetMemorySpaceAttributes ( - 0xc0000, - 0x40000, - EFI_MEMORY_WB - ); - } - - gDS->SetMemorySpaceAttributes ( - 0xA0000, - 0x20000, - EFI_MEMORY_UC - ); - - // - // Allocate 0 - 4K for real mode interrupt vectors and BDA. - // - AllocateLegacyMemory ( - AllocateAddress, - EfiReservedMemoryType, - 0, - 1, - &MemoryAddress - ); - ASSERT (MemoryAddress == 0x000000000); - - ClearPtr = (VOID *)((UINTN)0x0000); - - // - // Initialize region from 0x0000 to 4k. This initializes interrupt vector - // range. - // - ACCESS_PAGE0_CODE ( - gBS->SetMem ((VOID *)ClearPtr, 0x400, INITIAL_VALUE_BELOW_1K); - ZeroMem ((VOID *)((UINTN)ClearPtr + 0x400), 0xC00); - ); - - // - // Allocate pages for OPROM usage - // - MemorySize = PcdGet32 (PcdEbdaReservedMemorySize); - ASSERT ((MemorySize & 0xFFF) == 0); - - Status = AllocateLegacyMemory ( - AllocateAddress, - EfiReservedMemoryType, - CONVENTIONAL_MEMORY_TOP - MemorySize, - EFI_SIZE_TO_PAGES (MemorySize), - &MemoryAddress - ); - ASSERT_EFI_ERROR (Status); - - ZeroMem ((VOID *)((UINTN)MemoryAddress), MemorySize); - - // - // Allocate all 32k chunks from 0x60000 ~ 0x88000 for Legacy OPROMs that - // don't use PMM but look for zeroed memory. Note that various non-BBS - // OpROMs expect different areas to be free - // - EbdaReservedBaseAddress = MemoryAddress; - MemoryAddress = PcdGet32 (PcdOpromReservedMemoryBase); - MemorySize = PcdGet32 (PcdOpromReservedMemorySize); - // - // Check if base address and size for reserved memory are 4KB aligned. - // - ASSERT ((MemoryAddress & 0xFFF) == 0); - ASSERT ((MemorySize & 0xFFF) == 0); - // - // Check if the reserved memory is below EBDA reserved range. - // - ASSERT ((MemoryAddress < EbdaReservedBaseAddress) && ((MemoryAddress + MemorySize - 1) < EbdaReservedBaseAddress)); - for (MemStart = MemoryAddress; MemStart < MemoryAddress + MemorySize; MemStart += 0x1000) { - Status = AllocateLegacyMemory ( - AllocateAddress, - EfiBootServicesCode, - MemStart, - 1, - &StartAddress - ); - if (!EFI_ERROR (Status)) { - MemoryPtr = (VOID *)((UINTN)StartAddress); - ZeroMem (MemoryPtr, 0x1000); - } else { - DEBUG ((DEBUG_ERROR, "WARNING: Allocate legacy memory fail for SCSI card - %x\n", MemStart)); - } - } - - // - // Allocate low PMM memory and zero it out - // - MemorySize = PcdGet32 (PcdLowPmmMemorySize); - ASSERT ((MemorySize & 0xFFF) == 0); - Status = AllocateLegacyMemory ( - AllocateMaxAddress, - EfiBootServicesCode, - CONVENTIONAL_MEMORY_TOP, - EFI_SIZE_TO_PAGES (MemorySize), - &MemoryAddressUnder1MB - ); - ASSERT_EFI_ERROR (Status); - - ZeroMem ((VOID *)((UINTN)MemoryAddressUnder1MB), MemorySize); - - // - // Allocate space for thunker and Init Thunker - // - Status = AllocateLegacyMemory ( - AllocateMaxAddress, - EfiReservedMemoryType, - CONVENTIONAL_MEMORY_TOP, - (sizeof (LOW_MEMORY_THUNK) / EFI_PAGE_SIZE) + 2, - &MemoryAddress - ); - ASSERT_EFI_ERROR (Status); - Private->IntThunk = (LOW_MEMORY_THUNK *)(UINTN)MemoryAddress; - EfiToLegacy16InitTable = &Private->IntThunk->EfiToLegacy16InitTable; - EfiToLegacy16InitTable->ThunkStart = (UINT32)(EFI_PHYSICAL_ADDRESS)(UINTN)MemoryAddress; - EfiToLegacy16InitTable->ThunkSizeInBytes = (UINT32)(sizeof (LOW_MEMORY_THUNK)); - - Status = LegacyBiosInitializeThunk (Private); - ASSERT_EFI_ERROR (Status); - - // - // Init the legacy memory map in memory < 1 MB. - // - EfiToLegacy16InitTable->BiosLessThan1MB = (UINT32)MemoryAddressUnder1MB; - EfiToLegacy16InitTable->LowPmmMemory = (UINT32)MemoryAddressUnder1MB; - EfiToLegacy16InitTable->LowPmmMemorySizeInBytes = MemorySize; - - MemorySize = PcdGet32 (PcdHighPmmMemorySize); - ASSERT ((MemorySize & 0xFFF) == 0); - // - // Allocate high PMM Memory under 16 MB - // - Status = AllocateLegacyMemory ( - AllocateMaxAddress, - EfiBootServicesCode, - 0x1000000, - EFI_SIZE_TO_PAGES (MemorySize), - &MemoryAddress - ); - if (EFI_ERROR (Status)) { - // - // If it fails, allocate high PMM Memory under 4GB - // - Status = AllocateLegacyMemory ( - AllocateMaxAddress, - EfiBootServicesCode, - 0xFFFFFFFF, - EFI_SIZE_TO_PAGES (MemorySize), - &MemoryAddress - ); - } - - if (!EFI_ERROR (Status)) { - EfiToLegacy16InitTable->HiPmmMemory = (UINT32)(EFI_PHYSICAL_ADDRESS)(UINTN)MemoryAddress; - EfiToLegacy16InitTable->HiPmmMemorySizeInBytes = MemorySize; - } - - // - // ShutdownAPs(); - // - // Start the Legacy BIOS; - // - Status = ShadowAndStartLegacy16 (Private); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Initialize interrupt redirection code and entries; - // IDT Vectors 0x68-0x6f must be redirected to IDT Vectors 0x08-0x0f. - // - CopyMem ( - Private->IntThunk->InterruptRedirectionCode, - (VOID *)(UINTN)InterruptRedirectionTemplate, - sizeof (Private->IntThunk->InterruptRedirectionCode) - ); - - // - // Save Unexpected interrupt vector so can restore it just prior to boot - // - ACCESS_PAGE0_CODE ( - BaseVectorMaster = (UINT32 *)(sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER); - Private->BiosUnexpectedInt = BaseVectorMaster[0]; - IntRedirCode = (UINT32)(UINTN)Private->IntThunk->InterruptRedirectionCode; - for (Index = 0; Index < 8; Index++) { - BaseVectorMaster[Index] = (EFI_SEGMENT (IntRedirCode + Index * 4) << 16) | EFI_OFFSET (IntRedirCode + Index * 4); - } - - ); - - // - // Save EFI value - // - Private->ThunkSeg = (UINT16)(EFI_SEGMENT (IntRedirCode)); - - // - // Allocate reserved memory for SMBIOS table used in legacy boot if SMBIOS table exists - // - InstallSmbiosEventCallback (NULL, NULL); - - // - // Create callback function to update the size of reserved memory after LegacyBiosDxe starts - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - InstallSmbiosEventCallback, - NULL, - &gEfiSmbiosTableGuid, - &InstallSmbiosEvent - ); - ASSERT_EFI_ERROR (Status); - - // - // Create callback to update status of EndOfDxe, which is needed by NULL - // pointer detection - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - ToggleEndOfDxeStatus, - NULL, - &gEfiEndOfDxeEventGroupGuid, - &EndOfDxeEvent - ); - ASSERT_EFI_ERROR (Status); - - // - // Make a new handle and install the protocol - // - Private->Handle = NULL; - Status = gBS->InstallProtocolInterface ( - &Private->Handle, - &gEfiLegacyBiosProtocolGuid, - EFI_NATIVE_INTERFACE, - &Private->LegacyBios - ); - Private->Csm16PciInterfaceVersion = GetPciInterfaceVersion (Private); - - DEBUG (( - DEBUG_INFO, - "CSM16 PCI BIOS Interface Version: %02x.%02x\n", - (UINT8)(Private->Csm16PciInterfaceVersion >> 8), - (UINT8)Private->Csm16PciInterfaceVersion - )); - ASSERT (Private->Csm16PciInterfaceVersion != 0); - return Status; -} diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf b/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf deleted file mode 100644 index f6379dcc46..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf +++ /dev/null @@ -1,129 +0,0 @@ -## @file -# Legacy Bios Module to support CSM. -# -# This driver installs Legacy Bios Protocol to support CSM module work in EFI system. -# -# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = LegacyBiosDxe - MODULE_UNI_FILE = LegacyBiosDxe.uni - FILE_GUID = 46482D14-7CA1-4977-9DDB-64D747E13DE6 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - - ENTRY_POINT = LegacyBiosInstall - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - LegacyCmos.c - LegacyIde.c - LegacyBios.c - LegacyBda.c - LegacyBiosInterface.h - LegacyPci.c - -[Sources.Ia32] - IA32/InterruptTable.nasm - Thunk.c - LegacyBootSupport.c - LegacyBbs.c - LegacySio.c - -[Sources.X64] - X64/InterruptTable.nasm - Thunk.c - LegacyBootSupport.c - LegacyBbs.c - LegacySio.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - OvmfPkg/OvmfPkg.dec - -[LibraryClasses] - DevicePathLib - UefiBootServicesTableLib - MemoryAllocationLib - UefiDriverEntryPoint - BaseMemoryLib - UefiLib - DebugLib - DxeServicesTableLib - PcdLib - ReportStatusCodeLib - DebugAgentLib - -[LibraryClasses.IA32] - IoLib - HobLib - UefiRuntimeServicesTableLib - BaseLib - -[LibraryClasses.X64] - IoLib - HobLib - UefiRuntimeServicesTableLib - BaseLib - -[Guids] - gEfiDiskInfoIdeInterfaceGuid ## SOMETIMES_CONSUMES ##GUID #Used in LegacyBiosBuildIdeData() to assure device is a disk - gEfiSmbiosTableGuid ## SOMETIMES_CONSUMES ##SystemTable - gEfiLegacyBiosGuid ## SOMETIMES_CONSUMES ##GUID #Used in LegacyBiosInstallVgaRom() to locate handle buffer - gEfiEndOfDxeEventGroupGuid ## CONSUMES - -[Guids.IA32] - gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ##SystemTable - gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ##SystemTable - -[Guids.X64] - gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ##SystemTable - gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ##SystemTable - - -[Protocols] - gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES - gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES - gEfiPciRootBridgeIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiCpuArchProtocolGuid ## CONSUMES - gEfiTimerArchProtocolGuid ## CONSUMES - gEfiIsaIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiGenericMemTestProtocolGuid ## CONSUMES - gEfiDiskInfoProtocolGuid ## SOMETIMES_CONSUMES - gEfiSimpleTextInProtocolGuid ## SOMETIMES_CONSUMES - gEfiLegacy8259ProtocolGuid ## CONSUMES - gEfiLegacyBiosPlatformProtocolGuid ## CONSUMES - gEfiLegacyInterruptProtocolGuid ## CONSUMES - gEfiLegacyRegion2ProtocolGuid ## CONSUMES - gEfiLegacyBiosProtocolGuid ## PRODUCES - gEfiSerialIoProtocolGuid ## CONSUMES - gEfiSioProtocolGuid ## CONSUMES - gEdkiiIoMmuProtocolGuid ## CONSUMES - -[Pcd] - gUefiOvmfPkgTokenSpaceGuid.PcdLegacyBiosCacheLegacyRegion ## CONSUMES - gUefiOvmfPkgTokenSpaceGuid.PcdEbdaReservedMemorySize ## CONSUMES - gUefiOvmfPkgTokenSpaceGuid.PcdEndOpromShadowAddress ## SOMETIMES_CONSUMES - gUefiOvmfPkgTokenSpaceGuid.PcdLowPmmMemorySize ## CONSUMES - gUefiOvmfPkgTokenSpaceGuid.PcdHighPmmMemorySize ## CONSUMES - gUefiOvmfPkgTokenSpaceGuid.PcdOpromReservedMemoryBase ## CONSUMES - gUefiOvmfPkgTokenSpaceGuid.PcdOpromReservedMemorySize ## CONSUMES - -[Depex] - gEfiLegacyRegion2ProtocolGuid AND gEfiLegacyInterruptProtocolGuid AND gEfiLegacyBiosPlatformProtocolGuid AND gEfiLegacy8259ProtocolGuid AND gEfiGenericMemTestProtocolGuid AND gEfiCpuArchProtocolGuid AND gEfiTimerArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid - -[UserExtensions.TianoCore."ExtraFiles"] - LegacyBiosDxeExtra.uni diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.uni b/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.uni deleted file mode 100644 index 1a41d6d856..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.uni +++ /dev/null @@ -1,16 +0,0 @@ -// /** @file -// Legacy Bios Module to support CSM. -// -// This driver installs Legacy Bios Protocol to support CSM module work in EFI system. -// -// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
-// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Legacy Bios Module to support CSM" - -#string STR_MODULE_DESCRIPTION #language en-US "This driver installs Legacy Bios Protocol to support CSM module work in a EFI system." - diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxeExtra.uni b/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxeExtra.uni deleted file mode 100644 index a02e783d94..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxeExtra.uni +++ /dev/null @@ -1,14 +0,0 @@ -// /** @file -// LegacyBiosDxe Localized Strings and Content -// -// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
-// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"Legacy BIOS Support DXE Driver" - - diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h b/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h deleted file mode 100644 index 5a706d9ea6..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h +++ /dev/null @@ -1,1435 +0,0 @@ -/** @file - -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _LEGACY_BIOS_INTERFACE_ -#define _LEGACY_BIOS_INTERFACE_ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// BUGBUG: This entry maybe changed to PCD in future and wait for -// redesign of BDS library -// -#define MAX_BBS_ENTRIES 0x100 - -// -// Thunk Status Codes -// (These apply only to errors with the thunk and not to the code that was -// thunked to.) -// -#define THUNK_OK 0x00 -#define THUNK_ERR_A20_UNSUP 0x01 -#define THUNK_ERR_A20_FAILED 0x02 - -// -// Vector base definitions -// -// -// 8259 Hardware definitions -// -#define LEGACY_MODE_BASE_VECTOR_MASTER 0x08 -#define LEGACY_MODE_BASE_VECTOR_SLAVE 0x70 - -// -// The original PC used INT8-F for master PIC. Since these mapped over -// processor exceptions TIANO moved the master PIC to INT68-6F. -// -// The vector base for slave PIC is set as 0x70 for PC-AT compatibility. -// -#define PROTECTED_MODE_BASE_VECTOR_MASTER 0x68 -#define PROTECTED_MODE_BASE_VECTOR_SLAVE 0x70 - -// -// When we call CSM16 functions, some CSM16 use es:[offset + 0xabcd] to get data passed from CSM32, -// offset + 0xabcd could overflow which exceeds 0xFFFF which is invalid in real mode. -// So this will keep offset as small as possible to avoid offset overflow in real mode. -// -#define NORMALIZE_EFI_SEGMENT(_Adr) (UINT16) (((UINTN) (_Adr)) >> 4) -#define NORMALIZE_EFI_OFFSET(_Adr) (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xf) - -// -// Trace defines -// -// -#define LEGACY_BDA_TRACE 0x000 -#define LEGACY_BIOS_TRACE 0x040 -#define LEGACY_BOOT_TRACE 0x080 -#define LEGACY_CMOS_TRACE 0x0C0 -#define LEGACY_IDE_TRACE 0x100 -#define LEGACY_MP_TRACE 0x140 -#define LEGACY_PCI_TRACE 0x180 -#define LEGACY_SIO_TRACE 0x1C0 - -#define LEGACY_PCI_TRACE_000 LEGACY_PCI_TRACE + 0x00 -#define LEGACY_PCI_TRACE_001 LEGACY_PCI_TRACE + 0x01 -#define LEGACY_PCI_TRACE_002 LEGACY_PCI_TRACE + 0x02 -#define LEGACY_PCI_TRACE_003 LEGACY_PCI_TRACE + 0x03 -#define LEGACY_PCI_TRACE_004 LEGACY_PCI_TRACE + 0x04 -#define LEGACY_PCI_TRACE_005 LEGACY_PCI_TRACE + 0x05 -#define LEGACY_PCI_TRACE_006 LEGACY_PCI_TRACE + 0x06 -#define LEGACY_PCI_TRACE_007 LEGACY_PCI_TRACE + 0x07 -#define LEGACY_PCI_TRACE_008 LEGACY_PCI_TRACE + 0x08 -#define LEGACY_PCI_TRACE_009 LEGACY_PCI_TRACE + 0x09 -#define LEGACY_PCI_TRACE_00A LEGACY_PCI_TRACE + 0x0A -#define LEGACY_PCI_TRACE_00B LEGACY_PCI_TRACE + 0x0B -#define LEGACY_PCI_TRACE_00C LEGACY_PCI_TRACE + 0x0C -#define LEGACY_PCI_TRACE_00D LEGACY_PCI_TRACE + 0x0D -#define LEGACY_PCI_TRACE_00E LEGACY_PCI_TRACE + 0x0E -#define LEGACY_PCI_TRACE_00F LEGACY_PCI_TRACE + 0x0F - -#define BDA_VIDEO_MODE 0x49 - -#define IDE_PI_REGISTER_PNE BIT0 -#define IDE_PI_REGISTER_SNE BIT2 - -typedef struct { - UINTN PciSegment; - UINTN PciBus; - UINTN PciDevice; - UINTN PciFunction; - UINT32 ShadowAddress; - UINT32 ShadowedSize; - UINT8 DiskStart; - UINT8 DiskEnd; -} ROM_INSTANCE_ENTRY; - -// -// Values for RealModeGdt -// -#if defined (MDE_CPU_IA32) - -#define NUM_REAL_GDT_ENTRIES 3 -#define CONVENTIONAL_MEMORY_TOP 0xA0000 // 640 KB -#define INITIAL_VALUE_BELOW_1K 0x0 - -#elif defined (MDE_CPU_X64) - -#define NUM_REAL_GDT_ENTRIES 8 -#define CONVENTIONAL_MEMORY_TOP 0xA0000 // 640 KB -#define INITIAL_VALUE_BELOW_1K 0x0 - -#endif - -#pragma pack(1) - -// -// Define what a processor GDT looks like -// -typedef struct { - UINT32 LimitLo : 16; - UINT32 BaseLo : 16; - UINT32 BaseMid : 8; - UINT32 Type : 4; - UINT32 System : 1; - UINT32 Dpl : 2; - UINT32 Present : 1; - UINT32 LimitHi : 4; - UINT32 Software : 1; - UINT32 Reserved : 1; - UINT32 DefaultSize : 1; - UINT32 Granularity : 1; - UINT32 BaseHi : 8; -} GDT32; - -typedef struct { - UINT16 LimitLow; - UINT16 BaseLow; - UINT8 BaseMid; - UINT8 Attribute; - UINT8 LimitHi; - UINT8 BaseHi; -} GDT64; - -// -// Define what a processor descriptor looks like -// This data structure must be kept in sync with ASM STRUCT in Thunk.inc -// -typedef struct { - UINT16 Limit; - UINT64 Base; -} DESCRIPTOR64; - -typedef struct { - UINT16 Limit; - UINT32 Base; -} DESCRIPTOR32; - -// -// Low stub lay out -// -#define LOW_STACK_SIZE (8 * 1024) // 8k? -#define EFI_MAX_E820_ENTRY 100 -#define FIRST_INSTANCE 1 -#define NOT_FIRST_INSTANCE 0 - -#if defined (MDE_CPU_IA32) -typedef struct { - // - // Space for the code - // The address of Code is also the beginning of the relocated Thunk code - // - CHAR8 Code[4096]; // ? - // - // The address of the Reverse Thunk code - // Note that this member CONTAINS the address of the relocated reverse thunk - // code unlike the member variable 'Code', which IS the address of the Thunk - // code. - // - UINT32 LowReverseThunkStart; - - // - // Data for the code (cs releative) - // - DESCRIPTOR32 GdtDesc; // Protected mode GDT - DESCRIPTOR32 IdtDesc; // Protected mode IDT - UINT32 FlatSs; - UINT32 FlatEsp; - - UINT32 LowCodeSelector; // Low code selector in GDT - UINT32 LowDataSelector; // Low data selector in GDT - UINT32 LowStack; - DESCRIPTOR32 RealModeIdtDesc; - - // - // real-mode GDT (temporary GDT with two real mode segment descriptors) - // - GDT32 RealModeGdt[NUM_REAL_GDT_ENTRIES]; - DESCRIPTOR32 RealModeGdtDesc; - - // - // Members specifically for the reverse thunk - // The RevReal* members are used to store the current state of real mode - // before performing the reverse thunk. The RevFlat* members must be set - // before calling the reverse thunk assembly code. - // - UINT16 RevRealDs; - UINT16 RevRealSs; - UINT32 RevRealEsp; - DESCRIPTOR32 RevRealIdtDesc; - UINT16 RevFlatDataSelector; // Flat data selector in GDT - UINT32 RevFlatStack; - - // - // A low memory stack - // - CHAR8 Stack[LOW_STACK_SIZE]; - - // - // Stack for flat mode after reverse thunk - // @bug - This may no longer be necessary if the reverse thunk interface - // is changed to have the flat stack in a different location. - // - CHAR8 RevThunkStack[LOW_STACK_SIZE]; - - // - // Legacy16 Init memory map info - // - EFI_TO_COMPATIBILITY16_INIT_TABLE EfiToLegacy16InitTable; - - EFI_TO_COMPATIBILITY16_BOOT_TABLE EfiToLegacy16BootTable; - - CHAR8 InterruptRedirectionCode[32]; - EFI_LEGACY_INSTALL_PCI_HANDLER PciHandler; - EFI_DISPATCH_OPROM_TABLE DispatchOpromTable; - BBS_TABLE BbsTable[MAX_BBS_ENTRIES]; -} LOW_MEMORY_THUNK; - -#elif defined (MDE_CPU_X64) - -typedef struct { - // - // Space for the code - // The address of Code is also the beginning of the relocated Thunk code - // - CHAR8 Code[4096]; // ? - - // - // Data for the code (cs releative) - // - DESCRIPTOR64 X64GdtDesc; // Protected mode GDT - DESCRIPTOR64 X64IdtDesc; // Protected mode IDT - UINTN X64Ss; - UINTN X64Esp; - - UINTN RealStack; - DESCRIPTOR32 RealModeIdtDesc; - DESCRIPTOR32 RealModeGdtDesc; - - // - // real-mode GDT (temporary GDT with two real mode segment descriptors) - // - GDT64 RealModeGdt[NUM_REAL_GDT_ENTRIES]; - UINT64 PageMapLevel4; - - // - // A low memory stack - // - CHAR8 Stack[LOW_STACK_SIZE]; - - // - // Legacy16 Init memory map info - // - EFI_TO_COMPATIBILITY16_INIT_TABLE EfiToLegacy16InitTable; - - EFI_TO_COMPATIBILITY16_BOOT_TABLE EfiToLegacy16BootTable; - - CHAR8 InterruptRedirectionCode[32]; - EFI_LEGACY_INSTALL_PCI_HANDLER PciHandler; - EFI_DISPATCH_OPROM_TABLE DispatchOpromTable; - BBS_TABLE BbsTable[MAX_BBS_ENTRIES]; -} LOW_MEMORY_THUNK; - -#endif - -// -// PnP Expansion Header -// -typedef struct { - UINT32 PnpSignature; - UINT8 Revision; - UINT8 Length; - UINT16 NextHeader; - UINT8 Reserved1; - UINT8 Checksum; - UINT32 DeviceId; - UINT16 MfgPointer; - UINT16 ProductNamePointer; - UINT8 Class; - UINT8 SubClass; - UINT8 Interface; - UINT8 DeviceIndicators; - UINT16 Bcv; - UINT16 DisconnectVector; - UINT16 Bev; - UINT16 Reserved2; - UINT16 StaticResourceVector; -} LEGACY_PNP_EXPANSION_HEADER; - -typedef struct { - UINT8 PciSegment; - UINT8 PciBus; - UINT8 PciDevice; - UINT8 PciFunction; - UINT16 Vid; - UINT16 Did; - UINT16 SysSid; - UINT16 SVid; - UINT8 Class; - UINT8 SubClass; - UINT8 Interface; - UINT8 Reserved; - UINTN RomStart; - UINTN ManufacturerString; - UINTN ProductNameString; -} LEGACY_ROM_AND_BBS_TABLE; - -// -// Structure how EFI has mapped a devices HDD drive numbers. -// Boot to EFI aware OS or shell requires this mapping when -// 16-bit CSM assigns drive numbers. -// This mapping is ignored booting to a legacy OS. -// -typedef struct { - UINT8 PciSegment; - UINT8 PciBus; - UINT8 PciDevice; - UINT8 PciFunction; - UINT8 StartDriveNumber; - UINT8 EndDriveNumber; -} LEGACY_EFI_HDD_TABLE; - -// -// This data is passed to Leacy16Boot -// -typedef enum { - EfiAcpiAddressRangeMemory = 1, - EfiAcpiAddressRangeReserved = 2, - EfiAcpiAddressRangeACPI = 3, - EfiAcpiAddressRangeNVS = 4, - EfiAddressRangePersistentMemory = 7 -} EFI_ACPI_MEMORY_TYPE; - -typedef struct { - UINT64 BaseAddr; - UINT64 Length; - EFI_ACPI_MEMORY_TYPE Type; -} EFI_E820_ENTRY64; - -typedef struct { - UINT32 BassAddrLow; - UINT32 BaseAddrHigh; - UINT32 LengthLow; - UINT32 LengthHigh; - EFI_ACPI_MEMORY_TYPE Type; -} EFI_E820_ENTRY; - -#pragma pack() - -extern BBS_TABLE *mBbsTable; - -extern EFI_GENERIC_MEMORY_TEST_PROTOCOL *gGenMemoryTest; - -extern BOOLEAN mEndOfDxe; - -#define PORT_70 0x70 -#define PORT_71 0x71 - -#define CMOS_0A 0x0a ///< Status register A -#define CMOS_0D 0x0d ///< Status register D -#define CMOS_0E 0x0e ///< Diagnostic Status -#define CMOS_0F 0x0f ///< Shutdown status -#define CMOS_10 0x10 ///< Floppy type -#define CMOS_12 0x12 ///< IDE type -#define CMOS_14 0x14 ///< Same as BDA 40:10 -#define CMOS_15 0x15 ///< Low byte of base memory in 1k increments -#define CMOS_16 0x16 ///< High byte of base memory in 1k increments -#define CMOS_17 0x17 ///< Low byte of 1MB+ memory in 1k increments - max 15 MB -#define CMOS_18 0x18 ///< High byte of 1MB+ memory in 1k increments - max 15 MB -#define CMOS_19 0x19 ///< C: extended drive type -#define CMOS_1A 0x1a ///< D: extended drive type -#define CMOS_2E 0x2e ///< Most significient byte of standard checksum -#define CMOS_2F 0x2f ///< Least significient byte of standard checksum -#define CMOS_30 0x30 ///< CMOS 0x17 -#define CMOS_31 0x31 ///< CMOS 0x18 -#define CMOS_32 0x32 ///< Century byte - -// -// 8254 Timer registers -// -#define TIMER0_COUNT_PORT 0x40 -#define TIMER1_COUNT_PORT 0x41 -#define TIMER2_COUNT_PORT 0x42 -#define TIMER_CONTROL_PORT 0x43 - -// -// Timer 0, Read/Write LSB then MSB, Square wave output, binary count use. -// -#define TIMER0_CONTROL_WORD 0x36 - -#define LEGACY_BIOS_INSTANCE_SIGNATURE SIGNATURE_32 ('L', 'B', 'I', 'T') -typedef struct { - UINTN Signature; - - EFI_HANDLE Handle; - EFI_LEGACY_BIOS_PROTOCOL LegacyBios; - - EFI_HANDLE ImageHandle; - - // - // CPU Architectural Protocol - // - EFI_CPU_ARCH_PROTOCOL *Cpu; - - // - // Timer Architectural Protocol - // - EFI_TIMER_ARCH_PROTOCOL *Timer; - BOOLEAN TimerUses8254; - - // - // Protocol to Lock and Unlock 0xc0000 - 0xfffff - // - EFI_LEGACY_REGION2_PROTOCOL *LegacyRegion; - - EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform; - - // - // Interrupt control for thunk and PCI IRQ - // - EFI_LEGACY_8259_PROTOCOL *Legacy8259; - - // - // PCI Interrupt PIRQ control - // - EFI_LEGACY_INTERRUPT_PROTOCOL *LegacyInterrupt; - - // - // Generic Memory Test - // - EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenericMemoryTest; - - // - // TRUE if PCI Interrupt Line registers have been programmed. - // - BOOLEAN PciInterruptLine; - - // - // Code space below 1MB needed by thunker to transition to real mode. - // Contains stack and real mode code fragments - // - LOW_MEMORY_THUNK *IntThunk; - - // - // Starting shadow address of the Legacy BIOS - // - UINT32 BiosStart; - UINT32 LegacyBiosImageSize; - - // - // Start of variables used by CsmItp.mac ITP macro file and/os LegacyBios - // - UINT8 Dump[4]; - - // - // $EFI Legacy16 code entry info in memory < 1 MB; - // - EFI_COMPATIBILITY16_TABLE *Legacy16Table; - VOID *Legacy16InitPtr; - VOID *Legacy16BootPtr; - VOID *InternalIrqRoutingTable; - UINT32 NumberIrqRoutingEntries; - VOID *BbsTablePtr; - VOID *HddTablePtr; - UINT32 NumberHddControllers; - - // - // Cached copy of Legacy16 entry point - // - UINT16 Legacy16CallSegment; - UINT16 Legacy16CallOffset; - - // - // Returned from $EFI and passed in to OPROMS - // - UINT16 PnPInstallationCheckSegment; - UINT16 PnPInstallationCheckOffset; - - // - // E820 table - // - EFI_E820_ENTRY E820Table[EFI_MAX_E820_ENTRY]; - UINT32 NumberE820Entries; - - // - // True if legacy VGA INT 10h handler installed - // - BOOLEAN VgaInstalled; - - // - // Number of IDE drives - // - UINT8 IdeDriveCount; - - // - // Current Free Option ROM space. An option ROM must NOT go past - // BiosStart. - // - UINT32 OptionRom; - - // - // Save Legacy16 unexpected interrupt vector. Reprogram INT 68-6F from - // EFI values to legacy value just before boot. - // - UINT32 BiosUnexpectedInt; - UINT32 ThunkSavedInt[8]; - UINT16 ThunkSeg; - LEGACY_EFI_HDD_TABLE *LegacyEfiHddTable; - UINT16 LegacyEfiHddTableIndex; - UINT8 DiskEnd; - UINT8 Disk4075; - UINT16 TraceIndex; - UINT16 Trace[0x200]; - - // - // Indicate that whether GenericLegacyBoot is entered or not - // - BOOLEAN LegacyBootEntered; - - // - // CSM16 PCI Interface Version - // - UINT16 Csm16PciInterfaceVersion; -} LEGACY_BIOS_INSTANCE; - -#pragma pack(1) - -/* - 40:00-01 Com1 - 40:02-03 Com2 - 40:04-05 Com3 - 40:06-07 Com4 - 40:08-09 Lpt1 - 40:0A-0B Lpt2 - 40:0C-0D Lpt3 - 40:0E-0E Ebda segment - 40:10-11 MachineConfig - 40:12 Bda12 - skip - 40:13-14 MemSize below 1MB - 40:15-16 Bda15_16 - skip - 40:17 Keyboard Shift status - 40:18-19 Bda18_19 - skip - 40:1A-1B Key buffer head - 40:1C-1D Key buffer tail - 40:1E-3D Bda1E_3D- key buffer -skip - 40:3E-3F FloppyData 3E = Calibration status 3F = Motor status - 40:40 FloppyTimeout - 40:41-74 Bda41_74 - skip - 40:75 Number of HDD drives - 40:76-77 Bda76_77 - skip - 40:78-79 78 = Lpt1 timeout, 79 = Lpt2 timeout - 40:7A-7B 7A = Lpt3 timeout, 7B = Lpt4 timeout - 40:7C-7D 7C = Com1 timeout, 7D = Com2 timeout - 40:7E-7F 7E = Com3 timeout, 7F = Com4 timeout - 40:80-81 Pointer to start of key buffer - 40:82-83 Pointer to end of key buffer - 40:84-87 Bda84_87 - skip - 40:88 HDD Data Xmit rate - 40:89-8f skip - 40:90 Floppy data rate - 40:91-95 skip - 40:96 Keyboard Status - 40:97 LED Status - 40:98-101 skip -*/ -typedef struct { - UINT16 Com1; - UINT16 Com2; - UINT16 Com3; - UINT16 Com4; - UINT16 Lpt1; - UINT16 Lpt2; - UINT16 Lpt3; - UINT16 Ebda; - UINT16 MachineConfig; - UINT8 Bda12; - UINT16 MemSize; - UINT8 Bda15_16[0x02]; - UINT8 ShiftStatus; - UINT8 Bda18_19[0x02]; - UINT16 KeyHead; - UINT16 KeyTail; - UINT16 Bda1E_3D[0x10]; - UINT16 FloppyData; - UINT8 FloppyTimeout; - UINT8 Bda41_74[0x34]; - UINT8 NumberOfDrives; - UINT8 Bda76_77[0x02]; - UINT16 Lpt1_2Timeout; - UINT16 Lpt3_4Timeout; - UINT16 Com1_2Timeout; - UINT16 Com3_4Timeout; - UINT16 KeyStart; - UINT16 KeyEnd; - UINT8 Bda84_87[0x4]; - UINT8 DataXmit; - UINT8 Bda89_8F[0x07]; - UINT8 FloppyXRate; - UINT8 Bda91_95[0x05]; - UINT8 KeyboardStatus; - UINT8 LedStatus; -} BDA_STRUC; -#pragma pack() - -#define LEGACY_BIOS_INSTANCE_FROM_THIS(this) CR (this, LEGACY_BIOS_INSTANCE, LegacyBios, LEGACY_BIOS_INSTANCE_SIGNATURE) - -/** - Thunk to 16-bit real mode and execute a software interrupt with a vector - of BiosInt. Regs will contain the 16-bit register context on entry and - exit. - - @param This Protocol instance pointer. - @param BiosInt Processor interrupt vector to invoke - @param Regs Register contexted passed into (and returned) from thunk to - 16-bit mode - - @retval FALSE Thunk completed, and there were no BIOS errors in the target code. - See Regs for status. - @retval TRUE There was a BIOS erro in the target code. - -**/ -BOOLEAN -EFIAPI -LegacyBiosInt86 ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINT8 BiosInt, - IN EFI_IA32_REGISTER_SET *Regs - ); - -/** - Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the - 16-bit register context on entry and exit. Arguments can be passed on - the Stack argument - - @param This Protocol instance pointer. - @param Segment Segment of 16-bit mode call - @param Offset Offset of 16-bit mdoe call - @param Regs Register contexted passed into (and returned) from - thunk to 16-bit mode - @param Stack Caller allocated stack used to pass arguments - @param StackSize Size of Stack in bytes - - @retval FALSE Thunk completed, and there were no BIOS errors in - the target code. See Regs for status. - @retval TRUE There was a BIOS erro in the target code. - -**/ -BOOLEAN -EFIAPI -LegacyBiosFarCall86 ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINT16 Segment, - IN UINT16 Offset, - IN EFI_IA32_REGISTER_SET *Regs, - IN VOID *Stack, - IN UINTN StackSize - ); - -/** - Test to see if a legacy PCI ROM exists for this device. Optionally return - the Legacy ROM instance for this PCI device. - - @param This Protocol instance pointer. - @param PciHandle The PCI PC-AT OPROM from this devices ROM BAR will - be loaded - @param RomImage Return the legacy PCI ROM for this device - @param RomSize Size of ROM Image - @param Flags Indicates if ROM found and if PC-AT. - - @retval EFI_SUCCESS Legacy Option ROM available for this device - @retval EFI_UNSUPPORTED Legacy Option ROM not supported. - -**/ -EFI_STATUS -EFIAPI -LegacyBiosCheckPciRom ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN EFI_HANDLE PciHandle, - OUT VOID **RomImage OPTIONAL, - OUT UINTN *RomSize OPTIONAL, - OUT UINTN *Flags - ); - -/** - Assign drive number to legacy HDD drives prior to booting an EFI - aware OS so the OS can access drives without an EFI driver. - Note: BBS compliant drives ARE NOT available until this call by - either shell or EFI. - - @param This Protocol instance pointer. - @param BbsCount Number of BBS_TABLE structures - @param BbsTable List BBS entries - - @retval EFI_SUCCESS Drive numbers assigned - -**/ -EFI_STATUS -EFIAPI -LegacyBiosPrepareToBootEfi ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - OUT UINT16 *BbsCount, - OUT BBS_TABLE **BbsTable - ); - -/** - To boot from an unconventional device like parties and/or execute - HDD diagnostics. - - @param This Protocol instance pointer. - @param Attributes How to interpret the other input parameters - @param BbsEntry The 0-based index into the BbsTable for the parent - device. - @param BeerData Pointer to the 128 bytes of ram BEER data. - @param ServiceAreaData Pointer to the 64 bytes of raw Service Area data. - The caller must provide a pointer to the specific - Service Area and not the start all Service Areas. - EFI_INVALID_PARAMETER if error. Does NOT return if no error. - -**/ -EFI_STATUS -EFIAPI -LegacyBiosBootUnconventionalDevice ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UDC_ATTRIBUTES Attributes, - IN UINTN BbsEntry, - IN VOID *BeerData, - IN VOID *ServiceAreaData - ); - -/** - Load a legacy PC-AT OPROM on the PciHandle device. Return information - about how many disks were added by the OPROM and the shadow address and - size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C: - - @param This Protocol instance pointer. - @param PciHandle The PCI PC-AT OPROM from this devices ROM BAR will - be loaded. This value is NULL if RomImage is - non-NULL. This is the normal case. - @param RomImage A PCI PC-AT ROM image. This argument is non-NULL - if there is no hardware associated with the ROM - and thus no PciHandle, otherwise is must be NULL. - Example is PXE base code. - @param Flags Indicates if ROM found and if PC-AT. - @param DiskStart Disk number of first device hooked by the ROM. If - DiskStart is the same as DiskEnd no disked were - hooked. - @param DiskEnd Disk number of the last device hooked by the ROM. - @param RomShadowAddress Shadow address of PC-AT ROM - @param RomShadowedSize Size of RomShadowAddress in bytes - - @retval EFI_SUCCESS Legacy ROM loaded for this device - @retval EFI_INVALID_PARAMETER PciHandle not found - @retval EFI_UNSUPPORTED There is no PCI ROM in the ROM BAR or no onboard - ROM - -**/ -EFI_STATUS -EFIAPI -LegacyBiosInstallPciRom ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN EFI_HANDLE PciHandle, - IN VOID **RomImage, - OUT UINTN *Flags, - OUT UINT8 *DiskStart OPTIONAL, - OUT UINT8 *DiskEnd OPTIONAL, - OUT VOID **RomShadowAddress OPTIONAL, - OUT UINT32 *RomShadowedSize OPTIONAL - ); - -/** - Fill in the standard BDA for Keyboard LEDs - - @param This Protocol instance pointer. - @param Leds Current LED status - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -EFIAPI -LegacyBiosUpdateKeyboardLedStatus ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINT8 Leds - ); - -/** - Get all BBS info - - @param This Protocol instance pointer. - @param HddCount Number of HDD_INFO structures - @param HddInfo Onboard IDE controller information - @param BbsCount Number of BBS_TABLE structures - @param BbsTable List BBS entries - - @retval EFI_SUCCESS Tables returned - @retval EFI_NOT_FOUND resource not found - @retval EFI_DEVICE_ERROR can not get BBS table - -**/ -EFI_STATUS -EFIAPI -LegacyBiosGetBbsInfo ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - OUT UINT16 *HddCount, - OUT HDD_INFO **HddInfo, - OUT UINT16 *BbsCount, - OUT BBS_TABLE **BbsTable - ); - -/** - Shadow all legacy16 OPROMs that haven't been shadowed. - Warning: Use this with caution. This routine disconnects all EFI - drivers. If used externally then caller must re-connect EFI - drivers. - - @param This Protocol instance pointer. - - @retval EFI_SUCCESS OPROMs shadowed - -**/ -EFI_STATUS -EFIAPI -LegacyBiosShadowAllLegacyOproms ( - IN EFI_LEGACY_BIOS_PROTOCOL *This - ); - -/** - Attempt to legacy boot the BootOption. If the EFI contexted has been - compromised this function will not return. - - @param This Protocol instance pointer. - @param BbsDevicePath EFI Device Path from BootXXXX variable. - @param LoadOptionsSize Size of LoadOption in size. - @param LoadOptions LoadOption from BootXXXX variable - - @retval EFI_SUCCESS Removable media not present - -**/ -EFI_STATUS -EFIAPI -LegacyBiosLegacyBoot ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN BBS_BBS_DEVICE_PATH *BbsDevicePath, - IN UINT32 LoadOptionsSize, - IN VOID *LoadOptions - ); - -/** - Allocate memory < 1 MB and copy the thunker code into low memory. Se up - all the descriptors. - - @param Private Private context for Legacy BIOS - - @retval EFI_SUCCESS Should only pass. - -**/ -EFI_STATUS -LegacyBiosInitializeThunk ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -/** - Fill in the standard BDA and EBDA stuff before Legacy16 load - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosInitBda ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -/** - Collect IDE Inquiry data from the IDE disks - - @param Private Legacy BIOS Instance data - @param HddInfo Hdd Information - @param Flag Reconnect IdeController or not - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosBuildIdeData ( - IN LEGACY_BIOS_INSTANCE *Private, - IN HDD_INFO **HddInfo, - IN UINT16 Flag - ); - -/** - Enable ide controller. This gets disabled when LegacyBoot.c is about - to run the Option ROMs. - - @param Private Legacy BIOS Instance data - - -**/ -VOID -EnableIdeController ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -/** - If the IDE channel is in compatibility (legacy) mode, remove all - PCI I/O BAR addresses from the controller. - - @param IdeController The handle of target IDE controller - - -**/ -VOID -InitLegacyIdeController ( - IN EFI_HANDLE IdeController - ); - -/** - Program the interrupt routing register in all the PCI devices. On a PC AT system - this register contains the 8259 IRQ vector that matches its PCI interrupt. - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS Succeed. - @retval EFI_ALREADY_STARTED All PCI devices have been processed. - -**/ -EFI_STATUS -PciProgramAllInterruptLineRegisters ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -/** - Collect EFI Info about legacy devices. - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosBuildSioData ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -/** - Shadow all the PCI legacy ROMs. Use data from the Legacy BIOS Protocol - to chose the order. Skip any devices that have already have legacy - BIOS run. - - @param Private Protocol instance pointer. - - @retval EFI_SUCCESS Succeed. - @retval EFI_UNSUPPORTED Cannot get VGA device handle. - -**/ -EFI_STATUS -PciShadowRoms ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -/** - Fill in the standard BDA and EBDA stuff prior to legacy Boot - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosCompleteBdaBeforeBoot ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -/** - Fill in the standard CMOS stuff before Legacy16 load - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosInitCmos ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -/** - Fill in the standard CMOS stuff prior to legacy Boot - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosCompleteStandardCmosBeforeBoot ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -/** - Contains the code that is copied into low memory (below 640K). - This code reflects interrupts 0x68-0x6f to interrupts 0x08-0x0f. - This template must be copied into low memory, and the IDT entries - 0x68-0x6F must be point to the low memory copy of this code. Each - entry is 4 bytes long, so IDT entries 0x68-0x6F can be easily - computed. - -**/ -VOID -InterruptRedirectionTemplate ( - VOID - ); - -/** - Build the E820 table. - - @param Private Legacy BIOS Instance data - @param Size Size of E820 Table - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosBuildE820 ( - IN LEGACY_BIOS_INSTANCE *Private, - OUT UINTN *Size - ); - -/** - This function is to put all AP in halt state. - - @param Private Legacy BIOS Instance data - -**/ -VOID -ShutdownAPs ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -/** - Worker function for LegacyBiosGetFlatDescs, retrieving content of - specific registers. - - @param IntThunk Pointer to IntThunk of Legacy BIOS context. - -**/ -VOID -GetRegisters ( - LOW_MEMORY_THUNK *IntThunk - ); - -/** - Routine for calling real thunk code. - - @param RealCode The address of thunk code. - @param BiosInt The Bios interrupt vector number. - @param CallAddress The address of 16-bit mode call. - - @return Status returned by real thunk code - -**/ -UINTN -CallRealThunkCode ( - UINT8 *RealCode, - UINT8 BiosInt, - UINT32 CallAddress - ); - -/** - Routine for generating soft interrupt. - - @param Vector The interrupt vector number. - -**/ -VOID -GenerateSoftInit ( - UINT8 Vector - ); - -/** - Allocate memory for legacy usage. - - @param AllocateType The type of allocation to perform. - @param MemoryType The type of memory to allocate. - @param StartPageAddress Start address of range - @param Pages Number of pages to allocate - @param Result Result of allocation - - @retval EFI_SUCCESS Legacy16 code loaded - @retval Other No protocol installed, unload driver. - -**/ -EFI_STATUS -AllocateLegacyMemory ( - IN EFI_ALLOCATE_TYPE AllocateType, - IN EFI_MEMORY_TYPE MemoryType, - IN EFI_PHYSICAL_ADDRESS StartPageAddress, - IN UINTN Pages, - OUT EFI_PHYSICAL_ADDRESS *Result - ); - -/** - Get a region from the LegacyBios for Tiano usage. Can only be invoked once. - - @param This Protocol instance pointer. - @param LegacyMemorySize Size of required region - @param Region Region to use. 00 = Either 0xE0000 or 0xF0000 - block Bit0 = 1 0xF0000 block Bit1 = 1 0xE0000 - block - @param Alignment Address alignment. Bit mapped. First non-zero - bit from right is alignment. - @param LegacyMemoryAddress Region Assigned - - @retval EFI_SUCCESS Region assigned - @retval EFI_ACCESS_DENIED Procedure previously invoked - @retval Other Region not assigned - -**/ -EFI_STATUS -EFIAPI -LegacyBiosGetLegacyRegion ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINTN LegacyMemorySize, - IN UINTN Region, - IN UINTN Alignment, - OUT VOID **LegacyMemoryAddress - ); - -/** - Get a region from the LegacyBios for Tiano usage. Can only be invoked once. - - @param This Protocol instance pointer. - @param LegacyMemorySize Size of data to copy - @param LegacyMemoryAddress Legacy Region destination address Note: must - be in region assigned by - LegacyBiosGetLegacyRegion - @param LegacyMemorySourceAddress Source of data - - @retval EFI_SUCCESS Region assigned - @retval EFI_ACCESS_DENIED Destination outside assigned region - -**/ -EFI_STATUS -EFIAPI -LegacyBiosCopyLegacyRegion ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINTN LegacyMemorySize, - IN VOID *LegacyMemoryAddress, - IN VOID *LegacyMemorySourceAddress - ); - -/** - Find Legacy16 BIOS image in the FLASH device and shadow it into memory. Find - the $EFI table in the shadow area. Thunk into the Legacy16 code after it had - been shadowed. - - @param Private Legacy BIOS context data - - @retval EFI_SUCCESS Legacy16 code loaded - @retval Other No protocol installed, unload driver. - -**/ -EFI_STATUS -ShadowAndStartLegacy16 ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -/** - Checks the state of the floppy and if media is inserted. - - This routine checks the state of the floppy and if media is inserted. - There are 3 cases: - No floppy present - Set BBS entry to ignore - Floppy present & no media - Set BBS entry to lowest priority. We cannot - set it to ignore since 16-bit CSM will - indicate no floppy and thus drive A: is - unusable. CSM-16 will not try floppy since - lowest priority and thus not incur boot - time penality. - Floppy present & media - Set BBS entry to some priority. - - @return State of floppy media - -**/ -UINT8 -HasMediaInFloppy ( - VOID - ); - -/** - Identify drive data must be updated to actual parameters before boot. - This requires updating the checksum, if it exists. - - @param IdentifyDriveData ATA Identify Data - @param Checksum checksum of the ATA Identify Data - - @retval EFI_SUCCESS checksum calculated - @retval EFI_SECURITY_VIOLATION IdentifyData invalid - -**/ -EFI_STATUS -CalculateIdentifyDriveChecksum ( - IN UINT8 *IdentifyDriveData, - OUT UINT8 *Checksum - ); - -/** - Identify drive data must be updated to actual parameters before boot. - - @param IdentifyDriveData ATA Identify Data - -**/ -VOID -UpdateIdentifyDriveData ( - IN UINT8 *IdentifyDriveData - ); - -/** - Complete build of BBS TABLE. - - @param Private Legacy BIOS Instance data - @param BbsTable BBS Table passed to 16-bit code - - @retval EFI_SUCCESS Removable media not present - -**/ -EFI_STATUS -LegacyBiosBuildBbs ( - IN LEGACY_BIOS_INSTANCE *Private, - IN BBS_TABLE *BbsTable - ); - -/** - Read CMOS register through index/data port. - - @param[in] Index The index of the CMOS register to read. - - @return The data value from the CMOS register specified by Index. - -**/ -UINT8 -LegacyReadStandardCmos ( - IN UINT8 Index - ); - -/** - Write CMOS register through index/data port. - - @param[in] Index The index of the CMOS register to write. - @param[in] Value The value of CMOS register to write. - - @return The value written to the CMOS register specified by Index. - -**/ -UINT8 -LegacyWriteStandardCmos ( - IN UINT8 Index, - IN UINT8 Value - ); - -/** - Calculate the new standard CMOS checksum and write it. - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS Calculate 16-bit checksum successfully - -**/ -EFI_STATUS -LegacyCalculateWriteStandardCmosChecksum ( - VOID - ); - -/** - Test to see if a legacy PCI ROM exists for this device. Optionally return - the Legacy ROM instance for this PCI device. - - @param[in] This Protocol instance pointer. - @param[in] PciHandle The PCI PC-AT OPROM from this devices ROM BAR will be loaded - @param[out] RomImage Return the legacy PCI ROM for this device - @param[out] RomSize Size of ROM Image - @param[out] RuntimeImageLength Runtime size of ROM Image - @param[out] Flags Indicates if ROM found and if PC-AT. - @param[out] OpromRevision Revision of the PCI Rom - @param[out] ConfigUtilityCodeHeaderPointer of Configuration Utility Code Header - - @return EFI_SUCCESS Legacy Option ROM available for this device - @return EFI_ALREADY_STARTED This device is already managed by its Oprom - @return EFI_UNSUPPORTED Legacy Option ROM not supported. - -**/ -EFI_STATUS -LegacyBiosCheckPciRomEx ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN EFI_HANDLE PciHandle, - OUT VOID **RomImage OPTIONAL, - OUT UINTN *RomSize OPTIONAL, - OUT UINTN *RuntimeImageLength OPTIONAL, - OUT UINTN *Flags OPTIONAL, - OUT UINT8 *OpromRevision OPTIONAL, - OUT VOID **ConfigUtilityCodeHeader OPTIONAL - ); - -/** - Relocate this image under 4G memory for IPF. - - @param ImageHandle Handle of driver image. - @param SystemTable Pointer to system table. - - @retval EFI_SUCCESS Image successfully relocated. - @retval EFI_ABORTED Failed to relocate image. - -**/ -EFI_STATUS -RelocateImageUnder4GIfNeeded ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - -/** - Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the - 16-bit register context on entry and exit. Arguments can be passed on - the Stack argument - - @param This Protocol instance pointer. - @param Segment Segment of 16-bit mode call - @param Offset Offset of 16-bit mdoe call - @param Regs Register contexted passed into (and returned) from thunk to - 16-bit mode - @param Stack Caller allocated stack used to pass arguments - @param StackSize Size of Stack in bytes - - @retval FALSE Thunk completed, and there were no BIOS errors in the target code. - See Regs for status. - @retval TRUE There was a BIOS erro in the target code. - -**/ -BOOLEAN -EFIAPI -InternalLegacyBiosFarCall ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINT16 Segment, - IN UINT16 Offset, - IN EFI_IA32_REGISTER_SET *Regs, - IN VOID *Stack, - IN UINTN StackSize - ); - -/** - Load a legacy PC-AT OpROM for VGA controller. - - @param Private Driver private data. - - @retval EFI_SUCCESS Legacy ROM successfully installed for this device. - @retval EFI_DEVICE_ERROR No VGA device handle found, or native EFI video - driver cannot be successfully disconnected, or VGA - thunk driver cannot be successfully connected. - -**/ -EFI_STATUS -LegacyBiosInstallVgaRom ( - IN LEGACY_BIOS_INSTANCE *Private - ); - -#endif diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBootSupport.c b/OvmfPkg/Csm/LegacyBiosDxe/LegacyBootSupport.c deleted file mode 100644 index 83d94cf289..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacyBootSupport.c +++ /dev/null @@ -1,2212 +0,0 @@ -/** @file - -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "LegacyBiosInterface.h" -#include - -#define BOOT_LEGACY_OS 0 -#define BOOT_EFI_OS 1 -#define BOOT_UNCONVENTIONAL_DEVICE 2 - -UINT32 mLoadOptionsSize = 0; -UINTN mBootMode = BOOT_LEGACY_OS; -VOID *mLoadOptions = NULL; -BBS_BBS_DEVICE_PATH *mBbsDevicePathPtr = NULL; -BBS_BBS_DEVICE_PATH mBbsDevicePathNode; -UDC_ATTRIBUTES mAttributes = { 0, 0, 0, 0 }; -UINTN mBbsEntry = 0; -VOID *mBeerData = NULL; -VOID *mServiceAreaData = NULL; -UINT64 mLowWater = 0xffffffffffffffffULL; - -extern BBS_TABLE *mBbsTable; - -extern VOID *mRuntimeSmbiosEntryPoint; -extern EFI_PHYSICAL_ADDRESS mReserveSmbiosEntryPoint; -extern EFI_PHYSICAL_ADDRESS mStructureTableAddress; - -/** - Print the BBS Table. - - @param BbsTable The BBS table. - - -**/ -VOID -PrintBbsTable ( - IN BBS_TABLE *BbsTable - ) -{ - UINT16 Index; - UINT16 SubIndex; - CHAR8 *String; - - DEBUG ((DEBUG_INFO, "\n")); - DEBUG ((DEBUG_INFO, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs mfgs:mfgo dess:deso\n")); - DEBUG ((DEBUG_INFO, "=================================================================\n")); - for (Index = 0; Index < MAX_BBS_ENTRIES; Index++) { - // - // Filter - // - if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) { - continue; - } - - DEBUG (( - DEBUG_INFO, - " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x", - (UINTN)Index, - (UINTN)BbsTable[Index].BootPriority, - (UINTN)BbsTable[Index].Bus, - (UINTN)BbsTable[Index].Device, - (UINTN)BbsTable[Index].Function, - (UINTN)BbsTable[Index].Class, - (UINTN)BbsTable[Index].SubClass, - (UINTN)BbsTable[Index].DeviceType, - (UINTN)*(UINT16 *)&BbsTable[Index].StatusFlags - )); - DEBUG (( - DEBUG_INFO, - " %04x:%04x %04x:%04x %04x:%04x", - (UINTN)BbsTable[Index].BootHandlerSegment, - (UINTN)BbsTable[Index].BootHandlerOffset, - (UINTN)BbsTable[Index].MfgStringSegment, - (UINTN)BbsTable[Index].MfgStringOffset, - (UINTN)BbsTable[Index].DescStringSegment, - (UINTN)BbsTable[Index].DescStringOffset - )); - - // - // Print DescString - // - String = (CHAR8 *)(((UINTN)BbsTable[Index].DescStringSegment << 4) + BbsTable[Index].DescStringOffset); - if (String != NULL) { - DEBUG ((DEBUG_INFO, " (")); - for (SubIndex = 0; String[SubIndex] != 0; SubIndex++) { - DEBUG ((DEBUG_INFO, "%c", String[SubIndex])); - } - - DEBUG ((DEBUG_INFO, ")")); - } - - DEBUG ((DEBUG_INFO, "\n")); - } - - DEBUG ((DEBUG_INFO, "\n")); - - return; -} - -/** - Print the BBS Table. - - @param HddInfo The HddInfo table. - - -**/ -VOID -PrintHddInfo ( - IN HDD_INFO *HddInfo - ) -{ - UINTN Index; - - DEBUG ((DEBUG_INFO, "\n")); - for (Index = 0; Index < MAX_IDE_CONTROLLER; Index++) { - DEBUG ((DEBUG_INFO, "Index - %04x\n", Index)); - DEBUG ((DEBUG_INFO, " Status - %04x\n", (UINTN)HddInfo[Index].Status)); - DEBUG ((DEBUG_INFO, " B/D/F - %02x/%02x/%02x\n", (UINTN)HddInfo[Index].Bus, (UINTN)HddInfo[Index].Device, (UINTN)HddInfo[Index].Function)); - DEBUG ((DEBUG_INFO, " Command - %04x\n", HddInfo[Index].CommandBaseAddress)); - DEBUG ((DEBUG_INFO, " Control - %04x\n", HddInfo[Index].ControlBaseAddress)); - DEBUG ((DEBUG_INFO, " BusMaster - %04x\n", HddInfo[Index].BusMasterAddress)); - DEBUG ((DEBUG_INFO, " HddIrq - %02x\n", HddInfo[Index].HddIrq)); - DEBUG ((DEBUG_INFO, " IdentifyDrive[0].Raw[0] - %x\n", HddInfo[Index].IdentifyDrive[0].Raw[0])); - DEBUG ((DEBUG_INFO, " IdentifyDrive[1].Raw[0] - %x\n", HddInfo[Index].IdentifyDrive[1].Raw[0])); - } - - DEBUG ((DEBUG_INFO, "\n")); - - return; -} - -/** - Print the PCI Interrupt Line and Interrupt Pin registers. -**/ -VOID -PrintPciInterruptRegister ( - VOID - ) -{ - EFI_STATUS Status; - UINTN Index; - EFI_HANDLE *Handles; - UINTN HandleNum; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 Interrupt[2]; - UINTN Segment; - UINTN Bus; - UINTN Device; - UINTN Function; - - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &HandleNum, - &Handles - ); - - Bus = 0; - Device = 0; - Function = 0; - - DEBUG ((DEBUG_INFO, "\n")); - DEBUG ((DEBUG_INFO, " bb/dd/ff interrupt line interrupt pin\n")); - DEBUG ((DEBUG_INFO, "======================================\n")); - for (Index = 0; Index < HandleNum; Index++) { - Status = gBS->HandleProtocol (Handles[Index], &gEfiPciIoProtocolGuid, (VOID **)&PciIo); - if (!EFI_ERROR (Status)) { - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - PCI_INT_LINE_OFFSET, - 2, - Interrupt - ); - } - - if (!EFI_ERROR (Status)) { - Status = PciIo->GetLocation ( - PciIo, - &Segment, - &Bus, - &Device, - &Function - ); - } - - if (!EFI_ERROR (Status)) { - DEBUG (( - DEBUG_INFO, - " %02x/%02x/%02x 0x%02x 0x%02x\n", - Bus, - Device, - Function, - Interrupt[0], - Interrupt[1] - )); - } - } - - DEBUG ((DEBUG_INFO, "\n")); - - if (Handles != NULL) { - FreePool (Handles); - } -} - -/** - Identify drive data must be updated to actual parameters before boot. - - @param IdentifyDriveData ATA Identify Data - -**/ -VOID -UpdateIdentifyDriveData ( - IN UINT8 *IdentifyDriveData - ); - -/** - Update SIO data. - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS Removable media not present - -**/ -EFI_STATUS -UpdateSioData ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - EFI_STATUS Status; - UINTN Index; - UINTN Index1; - UINT8 LegacyInterrupts[16]; - EFI_LEGACY_IRQ_ROUTING_ENTRY *RoutingTable; - UINTN RoutingTableEntries; - EFI_LEGACY_IRQ_PRIORITY_TABLE_ENTRY *IrqPriorityTable; - UINTN NumberPriorityEntries; - EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; - UINT8 HddIrq; - UINT16 LegacyInt; - UINT16 LegMask; - UINT32 Register; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - EFI_ISA_IO_PROTOCOL *IsaIo; - - LegacyInt = 0; - HandleBuffer = NULL; - - EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; - LegacyBiosBuildSioData (Private); - SetMem (LegacyInterrupts, sizeof (LegacyInterrupts), 0); - - // - // Create list of legacy interrupts. - // - for (Index = 0; Index < 4; Index++) { - LegacyInterrupts[Index] = EfiToLegacy16BootTable->SioData.Serial[Index].Irq; - } - - for (Index = 4; Index < 7; Index++) { - LegacyInterrupts[Index] = EfiToLegacy16BootTable->SioData.Parallel[Index - 4].Irq; - } - - LegacyInterrupts[7] = EfiToLegacy16BootTable->SioData.Floppy.Irq; - - // - // Get Legacy Hdd IRQs. If native mode treat as PCI - // - for (Index = 0; Index < 2; Index++) { - HddIrq = EfiToLegacy16BootTable->HddInfo[Index].HddIrq; - if ((HddIrq != 0) && ((HddIrq == 15) || (HddIrq == 14))) { - LegacyInterrupts[Index + 8] = HddIrq; - } - } - - Private->LegacyBiosPlatform->GetRoutingTable ( - Private->LegacyBiosPlatform, - (VOID *)&RoutingTable, - &RoutingTableEntries, - NULL, - NULL, - (VOID **)&IrqPriorityTable, - &NumberPriorityEntries - ); - // - // Remove legacy interrupts from the list of PCI interrupts available. - // - for (Index = 0; Index <= 0x0b; Index++) { - for (Index1 = 0; Index1 <= NumberPriorityEntries; Index1++) { - if (LegacyInterrupts[Index] != 0) { - LegacyInt = (UINT16)(LegacyInt | (1 << LegacyInterrupts[Index])); - if (LegacyInterrupts[Index] == IrqPriorityTable[Index1].Irq) { - IrqPriorityTable[Index1].Used = LEGACY_USED; - } - } - } - } - - Private->Legacy8259->GetMask ( - Private->Legacy8259, - &LegMask, - NULL, - NULL, - NULL - ); - - // - // Set SIO interrupts and disable mouse. Let mouse driver - // re-enable it. - // - LegMask = (UINT16)((LegMask &~LegacyInt) | 0x1000); - Private->Legacy8259->SetMask ( - Private->Legacy8259, - &LegMask, - NULL, - NULL, - NULL - ); - - // - // Disable mouse in keyboard controller - // - Register = 0xA7; - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiIsaIoProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return Status; - } - - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiIsaIoProtocolGuid, - (VOID **)&IsaIo - ); - ASSERT_EFI_ERROR (Status); - IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, 0x64, 1, &Register); - } - - if (HandleBuffer != NULL) { - FreePool (HandleBuffer); - } - - return EFI_SUCCESS; -} - -/** - Identify drive data must be updated to actual parameters before boot. - This requires updating the checksum, if it exists. - - @param IdentifyDriveData ATA Identify Data - @param Checksum checksum of the ATA Identify Data - - @retval EFI_SUCCESS checksum calculated - @retval EFI_SECURITY_VIOLATION IdentifyData invalid - -**/ -EFI_STATUS -CalculateIdentifyDriveChecksum ( - IN UINT8 *IdentifyDriveData, - OUT UINT8 *Checksum - ) -{ - UINTN Index; - UINT8 LocalChecksum; - - LocalChecksum = 0; - *Checksum = 0; - if (IdentifyDriveData[510] != 0xA5) { - return EFI_SECURITY_VIOLATION; - } - - for (Index = 0; Index < 512; Index++) { - LocalChecksum = (UINT8)(LocalChecksum + IdentifyDriveData[Index]); - } - - *Checksum = LocalChecksum; - return EFI_SUCCESS; -} - -/** - Identify drive data must be updated to actual parameters before boot. - - @param IdentifyDriveData ATA Identify Data - - -**/ -VOID -UpdateIdentifyDriveData ( - IN UINT8 *IdentifyDriveData - ) -{ - UINT16 NumberCylinders; - UINT16 NumberHeads; - UINT16 NumberSectorsTrack; - UINT32 CapacityInSectors; - UINT8 OriginalChecksum; - UINT8 FinalChecksum; - EFI_STATUS Status; - ATAPI_IDENTIFY *ReadInfo; - - // - // Status indicates if Integrity byte is correct. Checksum should be - // 0 if valid. - // - ReadInfo = (ATAPI_IDENTIFY *)IdentifyDriveData; - Status = CalculateIdentifyDriveChecksum (IdentifyDriveData, &OriginalChecksum); - if (OriginalChecksum != 0) { - Status = EFI_SECURITY_VIOLATION; - } - - // - // If NumberCylinders = 0 then do data(Controller present but don drive attached). - // - NumberCylinders = ReadInfo->Raw[1]; - if (NumberCylinders != 0) { - ReadInfo->Raw[54] = NumberCylinders; - - NumberHeads = ReadInfo->Raw[3]; - ReadInfo->Raw[55] = NumberHeads; - - NumberSectorsTrack = ReadInfo->Raw[6]; - ReadInfo->Raw[56] = NumberSectorsTrack; - - // - // Copy Multisector info and set valid bit. - // - ReadInfo->Raw[59] = (UINT16)(ReadInfo->Raw[47] + 0x100); - CapacityInSectors = (UINT32)((UINT32)(NumberCylinders) * (UINT32)(NumberHeads) * (UINT32)(NumberSectorsTrack)); - ReadInfo->Raw[57] = (UINT16)(CapacityInSectors >> 16); - ReadInfo->Raw[58] = (UINT16)(CapacityInSectors & 0xffff); - if (Status == EFI_SUCCESS) { - // - // Forece checksum byte to 0 and get new checksum. - // - ReadInfo->Raw[255] &= 0xff; - CalculateIdentifyDriveChecksum (IdentifyDriveData, &FinalChecksum); - - // - // Force new checksum such that sum is 0. - // - FinalChecksum = (UINT8)((UINT8)0 - FinalChecksum); - ReadInfo->Raw[255] = (UINT16)(ReadInfo->Raw[255] | (FinalChecksum << 8)); - } - } -} - -/** - Identify drive data must be updated to actual parameters before boot. - Do for all drives. - - @param Private Legacy BIOS Instance data - - -**/ -VOID -UpdateAllIdentifyDriveData ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - UINTN Index; - HDD_INFO *HddInfo; - - HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0]; - - for (Index = 0; Index < MAX_IDE_CONTROLLER; Index++) { - // - // Each controller can have 2 devices. Update for each device - // - if ((HddInfo[Index].Status & HDD_MASTER_IDE) != 0) { - UpdateIdentifyDriveData ((UINT8 *)(&HddInfo[Index].IdentifyDrive[0].Raw[0])); - } - - if ((HddInfo[Index].Status & HDD_SLAVE_IDE) != 0) { - UpdateIdentifyDriveData ((UINT8 *)(&HddInfo[Index].IdentifyDrive[1].Raw[0])); - } - } -} - -/** - Enable ide controller. This gets disabled when LegacyBoot.c is about - to run the Option ROMs. - - @param Private Legacy BIOS Instance data - - -**/ -VOID -EnableIdeController ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - EFI_HANDLE IdeController; - UINT8 ByteBuffer; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - - Status = Private->LegacyBiosPlatform->GetPlatformHandle ( - Private->LegacyBiosPlatform, - EfiGetPlatformIdeHandle, - 0, - &HandleBuffer, - &HandleCount, - NULL - ); - if (!EFI_ERROR (Status)) { - IdeController = HandleBuffer[0]; - Status = gBS->HandleProtocol ( - IdeController, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - ByteBuffer = 0x1f; - if (!EFI_ERROR (Status)) { - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x04, 1, &ByteBuffer); - } - } -} - -/** - Enable ide controller. This gets disabled when LegacyBoot.c is about - to run the Option ROMs. - - @param Private Legacy BIOS Instance data - - -**/ -VOID -EnableAllControllers ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - EFI_PCI_IO_PROTOCOL *PciIo; - PCI_TYPE01 PciConfigHeader; - EFI_STATUS Status; - - // - // - // - EnableIdeController (Private); - - // - // Assumption is table is built from low bus to high bus numbers. - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - ASSERT_EFI_ERROR (Status); - - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - ASSERT_EFI_ERROR (Status); - - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - 0, - sizeof (PciConfigHeader) / sizeof (UINT32), - &PciConfigHeader - ); - - // - // We do not enable PPB here. This is for HotPlug Consideration. - // The Platform HotPlug Driver is responsible for Padding enough hot plug - // resources. It is also responsible for enable this bridge. If it - // does not pad it. It will cause some early Windows fail to installation. - // If the platform driver does not pad resource for PPB, PPB should be in - // un-enabled state to let Windows know that this PPB is not configured by - // BIOS. So Windows will allocate default resource for PPB. - // - // The reason for why we enable the command register is: - // The CSM will use the IO bar to detect some IRQ status, if the command - // is disabled, the IO resource will be out of scope. - // For example: - // We installed a legacy IRQ handle for a PCI IDE controller. When IRQ - // comes up, the handle will check the IO space to identify is the - // controller generated the IRQ source. - // If the IO command is not enabled, the IRQ handler will has wrong - // information. It will cause IRQ storm when the correctly IRQ handler fails - // to run. - // - if (!(IS_PCI_VGA (&PciConfigHeader) || - IS_PCI_OLD_VGA (&PciConfigHeader) || - IS_PCI_IDE (&PciConfigHeader) || - IS_PCI_P2P (&PciConfigHeader) || - IS_PCI_P2P_SUB (&PciConfigHeader) || - IS_PCI_LPC (&PciConfigHeader))) - { - PciConfigHeader.Hdr.Command |= 0x1f; - - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 4, 1, &PciConfigHeader.Hdr.Command); - } - } -} - -/** - The following routines are identical in operation, so combine - for code compaction: - EfiGetPlatformBinaryGetMpTable - EfiGetPlatformBinaryGetOemIntData - EfiGetPlatformBinaryGetOem32Data - EfiGetPlatformBinaryGetOem16Data - - @param This Protocol instance pointer. - @param Id Table/Data identifier - - @retval EFI_SUCCESS Success - @retval EFI_INVALID_PARAMETER Invalid ID - @retval EFI_OUT_OF_RESOURCES no resource to get data or table - -**/ -EFI_STATUS -LegacyGetDataOrTable ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN EFI_GET_PLATFORM_INFO_MODE Id - ) -{ - VOID *Table; - UINT32 TablePtr; - UINTN TableSize; - UINTN Alignment; - UINTN Location; - EFI_STATUS Status; - EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform; - EFI_COMPATIBILITY16_TABLE *Legacy16Table; - EFI_IA32_REGISTER_SET Regs; - LEGACY_BIOS_INSTANCE *Private; - - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - - LegacyBiosPlatform = Private->LegacyBiosPlatform; - Legacy16Table = Private->Legacy16Table; - - // - // Phase 1 - get an address allocated in 16-bit code - // - while (TRUE) { - switch (Id) { - case EfiGetPlatformBinaryMpTable: - case EfiGetPlatformBinaryOemIntData: - case EfiGetPlatformBinaryOem32Data: - case EfiGetPlatformBinaryOem16Data: - { - Status = LegacyBiosPlatform->GetPlatformInfo ( - LegacyBiosPlatform, - Id, - (VOID *)&Table, - &TableSize, - &Location, - &Alignment, - 0, - 0 - ); - DEBUG ((DEBUG_INFO, "LegacyGetDataOrTable - ID: %x, %r\n", (UINTN)Id, Status)); - DEBUG ((DEBUG_INFO, " Table - %x, Size - %x, Location - %x, Alignment - %x\n", (UINTN)Table, (UINTN)TableSize, (UINTN)Location, (UINTN)Alignment)); - break; - } - - default: - { - return EFI_INVALID_PARAMETER; - } - } - - if (EFI_ERROR (Status)) { - return Status; - } - - ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); - Regs.X.AX = Legacy16GetTableAddress; - Regs.X.CX = (UINT16)TableSize; - Regs.X.BX = (UINT16)Location; - Regs.X.DX = (UINT16)Alignment; - Private->LegacyBios.FarCall86 ( - This, - Private->Legacy16CallSegment, - Private->Legacy16CallOffset, - &Regs, - NULL, - 0 - ); - - if (Regs.X.AX != 0) { - DEBUG ((DEBUG_ERROR, "Table ID %x length insufficient\n", Id)); - return EFI_OUT_OF_RESOURCES; - } else { - break; - } - } - - // - // Phase 2 Call routine second time with address to allow address adjustment - // - Status = LegacyBiosPlatform->GetPlatformInfo ( - LegacyBiosPlatform, - Id, - (VOID *)&Table, - &TableSize, - &Location, - &Alignment, - Regs.X.DS, - Regs.X.BX - ); - switch (Id) { - case EfiGetPlatformBinaryMpTable: - { - Legacy16Table->MpTablePtr = (UINT32)(Regs.X.DS * 16 + Regs.X.BX); - Legacy16Table->MpTableLength = (UINT32)TableSize; - DEBUG ((DEBUG_INFO, "MP table in legacy region - %x\n", (UINTN)Legacy16Table->MpTablePtr)); - break; - } - - case EfiGetPlatformBinaryOemIntData: - { - Legacy16Table->OemIntSegment = Regs.X.DS; - Legacy16Table->OemIntOffset = Regs.X.BX; - DEBUG ((DEBUG_INFO, "OemInt table in legacy region - %04x:%04x\n", (UINTN)Legacy16Table->OemIntSegment, (UINTN)Legacy16Table->OemIntOffset)); - break; - } - - case EfiGetPlatformBinaryOem32Data: - { - Legacy16Table->Oem32Segment = Regs.X.DS; - Legacy16Table->Oem32Offset = Regs.X.BX; - DEBUG ((DEBUG_INFO, "Oem32 table in legacy region - %04x:%04x\n", (UINTN)Legacy16Table->Oem32Segment, (UINTN)Legacy16Table->Oem32Offset)); - break; - } - - case EfiGetPlatformBinaryOem16Data: - { - // - // Legacy16Table->Oem16Segment = Regs.X.DS; - // Legacy16Table->Oem16Offset = Regs.X.BX; - DEBUG ((DEBUG_INFO, "Oem16 table in legacy region - %04x:%04x\n", (UINTN)Legacy16Table->Oem16Segment, (UINTN)Legacy16Table->Oem16Offset)); - break; - } - - default: - { - return EFI_INVALID_PARAMETER; - } - } - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Phase 3 Copy table to final location - // - TablePtr = (UINT32)(Regs.X.DS * 16 + Regs.X.BX); - - CopyMem ( - (VOID *)(UINTN)TablePtr, - Table, - TableSize - ); - - return EFI_SUCCESS; -} - -/** - Copy SMBIOS table to EfiReservedMemoryType of memory for legacy boot. - -**/ -VOID -CreateSmbiosTableInReservedMemory ( - VOID - ) -{ - SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure; - - if ((mRuntimeSmbiosEntryPoint == NULL) || - (mReserveSmbiosEntryPoint == 0) || - (mStructureTableAddress == 0)) - { - return; - } - - EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *)mRuntimeSmbiosEntryPoint; - - // - // Copy SMBIOS Entry Point Structure - // - CopyMem ( - (VOID *)(UINTN)mReserveSmbiosEntryPoint, - EntryPointStructure, - EntryPointStructure->EntryPointLength - ); - - // - // Copy SMBIOS Structure Table into EfiReservedMemoryType memory - // - CopyMem ( - (VOID *)(UINTN)mStructureTableAddress, - (VOID *)(UINTN)EntryPointStructure->TableAddress, - EntryPointStructure->TableLength - ); - - // - // Update TableAddress in Entry Point Structure - // - EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)mReserveSmbiosEntryPoint; - EntryPointStructure->TableAddress = (UINT32)(UINTN)mStructureTableAddress; - - // - // Fixup checksums in the Entry Point Structure - // - EntryPointStructure->IntermediateChecksum = 0; - EntryPointStructure->EntryPointStructureChecksum = 0; - - EntryPointStructure->IntermediateChecksum = - CalculateCheckSum8 ( - (UINT8 *)EntryPointStructure + OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString), - EntryPointStructure->EntryPointLength - OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString) - ); - EntryPointStructure->EntryPointStructureChecksum = - CalculateCheckSum8 ((UINT8 *)EntryPointStructure, EntryPointStructure->EntryPointLength); -} - -/** - Assign drive number to legacy HDD drives prior to booting an EFI - aware OS so the OS can access drives without an EFI driver. - Note: BBS compliant drives ARE NOT available until this call by - either shell or EFI. - - @param This Protocol instance pointer. - - @retval EFI_SUCCESS Drive numbers assigned - -**/ -EFI_STATUS -GenericLegacyBoot ( - IN EFI_LEGACY_BIOS_PROTOCOL *This - ) -{ - EFI_STATUS Status; - LEGACY_BIOS_INSTANCE *Private; - EFI_IA32_REGISTER_SET Regs; - EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; - EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform; - UINTN CopySize; - VOID *AcpiPtr; - HDD_INFO *HddInfo; - HDD_INFO *LocalHddInfo; - UINTN Index; - EFI_COMPATIBILITY16_TABLE *Legacy16Table; - UINT32 *BdaPtr; - UINT16 HddCount; - UINT16 BbsCount; - BBS_TABLE *LocalBbsTable; - UINT32 *BaseVectorMaster; - EFI_TIME BootTime; - UINT32 LocalTime; - EFI_HANDLE IdeController; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - VOID *AcpiTable; - UINTN ShadowAddress; - UINT32 Granularity; - - LocalHddInfo = NULL; - HddCount = 0; - BbsCount = 0; - LocalBbsTable = NULL; - - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - DEBUG_CODE ( - DEBUG ((DEBUG_ERROR, "Start of legacy boot\n")); - ); - - Legacy16Table = Private->Legacy16Table; - EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; - HddInfo = &EfiToLegacy16BootTable->HddInfo[0]; - - LegacyBiosPlatform = Private->LegacyBiosPlatform; - - EfiToLegacy16BootTable->MajorVersion = EFI_TO_LEGACY_MAJOR_VERSION; - EfiToLegacy16BootTable->MinorVersion = EFI_TO_LEGACY_MINOR_VERSION; - - // - // If booting to a legacy OS then force HDD drives to the appropriate - // boot mode by calling GetIdeHandle. - // A reconnect -r can force all HDDs back to native mode. - // - IdeController = NULL; - if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) { - Status = LegacyBiosPlatform->GetPlatformHandle ( - Private->LegacyBiosPlatform, - EfiGetPlatformIdeHandle, - 0, - &HandleBuffer, - &HandleCount, - NULL - ); - if (!EFI_ERROR (Status)) { - IdeController = HandleBuffer[0]; - } - } - - // - // Unlock the Legacy BIOS region - // - Private->LegacyRegion->UnLock ( - Private->LegacyRegion, - 0xE0000, - 0x20000, - &Granularity - ); - - // - // Reconstruct the Legacy16 boot memory map - // - LegacyBiosBuildE820 (Private, &CopySize); - if (CopySize > Private->Legacy16Table->E820Length) { - ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); - Regs.X.AX = Legacy16GetTableAddress; - Regs.X.BX = (UINT16)0x0; // Any region - Regs.X.CX = (UINT16)CopySize; - Regs.X.DX = (UINT16)0x4; // Alignment - Private->LegacyBios.FarCall86 ( - &Private->LegacyBios, - Private->Legacy16Table->Compatibility16CallSegment, - Private->Legacy16Table->Compatibility16CallOffset, - &Regs, - NULL, - 0 - ); - - Private->Legacy16Table->E820Pointer = (UINT32)(Regs.X.DS * 16 + Regs.X.BX); - Private->Legacy16Table->E820Length = (UINT32)CopySize; - if (Regs.X.AX != 0) { - DEBUG ((DEBUG_ERROR, "Legacy16 E820 length insufficient\n")); - return EFI_OUT_OF_RESOURCES; - } else { - CopyMem ( - (VOID *)(UINTN)Private->Legacy16Table->E820Pointer, - Private->E820Table, - CopySize - ); - } - } else { - CopyMem ( - (VOID *)(UINTN)Private->Legacy16Table->E820Pointer, - Private->E820Table, - CopySize - ); - Private->Legacy16Table->E820Length = (UINT32)CopySize; - } - - // - // We do not ASSERT if SmbiosTable not found. It is possible that a platform does not produce SmbiosTable. - // - if (mReserveSmbiosEntryPoint == 0) { - DEBUG ((DEBUG_INFO, "Smbios table is not found!\n")); - } - - CreateSmbiosTableInReservedMemory (); - EfiToLegacy16BootTable->SmbiosTable = (UINT32)(UINTN)mReserveSmbiosEntryPoint; - - AcpiTable = NULL; - Status = EfiGetSystemConfigurationTable ( - &gEfiAcpi20TableGuid, - &AcpiTable - ); - if (EFI_ERROR (Status)) { - Status = EfiGetSystemConfigurationTable ( - &gEfiAcpi10TableGuid, - &AcpiTable - ); - } - - // - // We do not ASSERT if AcpiTable not found. It is possible that a platform does not produce AcpiTable. - // - if (AcpiTable == NULL) { - DEBUG ((DEBUG_INFO, "ACPI table is not found!\n")); - } - - EfiToLegacy16BootTable->AcpiTable = (UINT32)(UINTN)AcpiTable; - - // - // Get RSD Ptr table rev at offset 15 decimal - // Rev = 0 Length is 20 decimal - // Rev != 0 Length is UINT32 at offset 20 decimal - // - if (AcpiTable != NULL) { - AcpiPtr = AcpiTable; - if (*((UINT8 *)AcpiPtr + 15) == 0) { - CopySize = 20; - } else { - AcpiPtr = ((UINT8 *)AcpiPtr + 20); - CopySize = (*(UINT32 *)AcpiPtr); - } - - CopyMem ( - (VOID *)(UINTN)Private->Legacy16Table->AcpiRsdPtrPointer, - AcpiTable, - CopySize - ); - } - - // - // Make sure all PCI Interrupt Line register are programmed to match 8259 - // - PciProgramAllInterruptLineRegisters (Private); - - // - // Unlock the Legacy BIOS region as PciProgramAllInterruptLineRegisters - // can lock it. - // - Private->LegacyRegion->UnLock ( - Private->LegacyRegion, - Private->BiosStart, - Private->LegacyBiosImageSize, - &Granularity - ); - - // - // Configure Legacy Device Magic - // - // Only do this code if booting legacy OS - // - if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) { - UpdateSioData (Private); - } - - // - // Setup BDA and EBDA standard areas before Legacy Boot - // - ACCESS_PAGE0_CODE ( - LegacyBiosCompleteBdaBeforeBoot (Private); - ); - LegacyBiosCompleteStandardCmosBeforeBoot (Private); - - // - // We must build IDE data, if it hasn't been done, before PciShadowRoms - // to insure EFI drivers are connected. - // - LegacyBiosBuildIdeData (Private, &HddInfo, 1); - UpdateAllIdentifyDriveData (Private); - - // - // Clear IO BAR, if IDE controller in legacy mode. - // - InitLegacyIdeController (IdeController); - - // - // Generate number of ticks since midnight for BDA. DOS requires this - // for its time. We have to make assumptions as to how long following - // code takes since after PciShadowRoms PciIo is gone. Place result in - // 40:6C-6F - // - // Adjust value by 1 second. - // - gRT->GetTime (&BootTime, NULL); - LocalTime = BootTime.Hour * 3600 + BootTime.Minute * 60 + BootTime.Second; - LocalTime += 1; - - // - // Multiply result by 18.2 for number of ticks since midnight. - // Use 182/10 to avoid floating point math. - // - LocalTime = (LocalTime * 182) / 10; - ACCESS_PAGE0_CODE ( - BdaPtr = (UINT32 *)(UINTN)0x46C; - *BdaPtr = LocalTime; - ); - - // - // Shadow PCI ROMs. We must do this near the end since this will kick - // of Native EFI drivers that may be needed to collect info for Legacy16 - // - // WARNING: PciIo is gone after this call. - // - PciShadowRoms (Private); - - // - // Shadow PXE base code, BIS etc. - // - Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xc0000, 0x40000, &Granularity); - ShadowAddress = Private->OptionRom; - Private->LegacyBiosPlatform->PlatformHooks ( - Private->LegacyBiosPlatform, - EfiPlatformHookShadowServiceRoms, - 0, - 0, - &ShadowAddress, - Legacy16Table, - NULL - ); - Private->OptionRom = (UINT32)ShadowAddress; - // - // Register Legacy SMI Handler - // - LegacyBiosPlatform->SmmInit ( - LegacyBiosPlatform, - EfiToLegacy16BootTable - ); - - // - // Let platform code know the boot options - // - LegacyBiosGetBbsInfo ( - This, - &HddCount, - &LocalHddInfo, - &BbsCount, - &LocalBbsTable - ); - - DEBUG_CODE ( - PrintPciInterruptRegister (); - PrintBbsTable (LocalBbsTable); - PrintHddInfo (LocalHddInfo); - ); - // - // If drive wasn't spun up then BuildIdeData may have found new drives. - // Need to update BBS boot priority. - // - for (Index = 0; Index < MAX_IDE_CONTROLLER; Index++) { - if ((LocalHddInfo[Index].IdentifyDrive[0].Raw[0] != 0) && - (LocalBbsTable[2 * Index + 1].BootPriority == BBS_IGNORE_ENTRY) - ) - { - LocalBbsTable[2 * Index + 1].BootPriority = BBS_UNPRIORITIZED_ENTRY; - } - - if ((LocalHddInfo[Index].IdentifyDrive[1].Raw[0] != 0) && - (LocalBbsTable[2 * Index + 2].BootPriority == BBS_IGNORE_ENTRY) - ) - { - LocalBbsTable[2 * Index + 2].BootPriority = BBS_UNPRIORITIZED_ENTRY; - } - } - - Private->LegacyRegion->UnLock ( - Private->LegacyRegion, - 0xc0000, - 0x40000, - &Granularity - ); - - LegacyBiosPlatform->PrepareToBoot ( - LegacyBiosPlatform, - mBbsDevicePathPtr, - mBbsTable, - mLoadOptionsSize, - mLoadOptions, - (VOID *)&Private->IntThunk->EfiToLegacy16BootTable - ); - - // - // If no boot device return to BDS - // - if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) { - for (Index = 0; Index < BbsCount; Index++) { - if ((LocalBbsTable[Index].BootPriority != BBS_DO_NOT_BOOT_FROM) && - (LocalBbsTable[Index].BootPriority != BBS_UNPRIORITIZED_ENTRY) && - (LocalBbsTable[Index].BootPriority != BBS_IGNORE_ENTRY)) - { - break; - } - } - - if (Index == BbsCount) { - return EFI_DEVICE_ERROR; - } - } - - // - // Let the Legacy16 code know the device path type for legacy boot - // - EfiToLegacy16BootTable->DevicePathType = mBbsDevicePathPtr->DeviceType; - - // - // Copy MP table, if it exists. - // - LegacyGetDataOrTable (This, EfiGetPlatformBinaryMpTable); - - if (!Private->LegacyBootEntered) { - // - // Copy OEM INT Data, if it exists. Note: This code treats any data - // as a bag of bits and knows nothing of the contents nor cares. - // Contents are IBV specific. - // - LegacyGetDataOrTable (This, EfiGetPlatformBinaryOemIntData); - - // - // Copy OEM16 Data, if it exists.Note: This code treats any data - // as a bag of bits and knows nothing of the contents nor cares. - // Contents are IBV specific. - // - LegacyGetDataOrTable (This, EfiGetPlatformBinaryOem16Data); - - // - // Copy OEM32 Data, if it exists.Note: This code treats any data - // as a bag of bits and knows nothing of the contents nor cares. - // Contents are IBV specific. - // - LegacyGetDataOrTable (This, EfiGetPlatformBinaryOem32Data); - } - - // - // Call into Legacy16 code to prepare for INT 19h - // - ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); - Regs.X.AX = Legacy16PrepareToBoot; - - // - // Pass in handoff data - // - Regs.X.ES = NORMALIZE_EFI_SEGMENT ((UINTN)EfiToLegacy16BootTable); - Regs.X.BX = NORMALIZE_EFI_OFFSET ((UINTN)EfiToLegacy16BootTable); - - Private->LegacyBios.FarCall86 ( - This, - Private->Legacy16CallSegment, - Private->Legacy16CallOffset, - &Regs, - NULL, - 0 - ); - - if (Regs.X.AX != 0) { - return EFI_DEVICE_ERROR; - } - - // - // Lock the Legacy BIOS region - // - Private->LegacyRegion->Lock ( - Private->LegacyRegion, - 0xc0000, - 0x40000, - &Granularity - ); - - if ((Private->Legacy16Table->TableLength >= OFFSET_OF (EFI_COMPATIBILITY16_TABLE, HiPermanentMemoryAddress)) && - ((Private->Legacy16Table->UmaAddress != 0) && (Private->Legacy16Table->UmaSize != 0))) - { - // - // Here we could reduce UmaAddress down as far as Private->OptionRom, taking into - // account the granularity of the access control. - // - DEBUG (( - DEBUG_INFO, - "Unlocking UMB RAM region 0x%x-0x%x\n", - Private->Legacy16Table->UmaAddress, - Private->Legacy16Table->UmaAddress + Private->Legacy16Table->UmaSize - )); - - Private->LegacyRegion->UnLock ( - Private->LegacyRegion, - Private->Legacy16Table->UmaAddress, - Private->Legacy16Table->UmaSize, - &Granularity - ); - } - - // - // Lock attributes of the Legacy Region if chipset supports - // - Private->LegacyRegion->BootLock ( - Private->LegacyRegion, - 0xc0000, - 0x40000, - &Granularity - ); - - // - // Call into Legacy16 code to do the INT 19h - // - EnableAllControllers (Private); - if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) { - // - // Signal all the events that are waiting on EVT_SIGNAL_LEGACY_BOOT - // - EfiSignalEventLegacyBoot (); - - // - // Report Status Code to indicate legacy boot event was signalled - // - REPORT_STATUS_CODE ( - EFI_PROGRESS_CODE, - (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT) - ); - - DEBUG ((DEBUG_INFO, "Legacy INT19 Boot...\n")); - - // - // Disable DXE Timer while executing in real mode - // - Private->Timer->SetTimerPeriod (Private->Timer, 0); - - // - // Save and disable interrupt of debug timer - // - SaveAndSetDebugTimerInterrupt (FALSE); - - // - // Put the 8259 into its legacy mode by reprogramming the vector bases - // - Private->Legacy8259->SetVectorBase (Private->Legacy8259, LEGACY_MODE_BASE_VECTOR_MASTER, LEGACY_MODE_BASE_VECTOR_SLAVE); - // - // PC History - // The original PC used INT8-F for master PIC. Since these mapped over - // processor exceptions TIANO moved the master PIC to INT68-6F. - // We need to set these back to the Legacy16 unexpected interrupt(saved - // in LegacyBios.c) since some OS see that these have values different from - // what is expected and invoke them. Since the legacy OS corrupts EFI - // memory, there is no handler for these interrupts and OS blows up. - // - // We need to save the TIANO values for the rare case that the Legacy16 - // code cannot boot but knows memory hasn't been destroyed. - // - // To compound the problem, video takes over one of these INTS and must be - // be left. - // @bug - determine if video hooks INT(in which case we must find new - // set of TIANO vectors) or takes it over. - // - // - ACCESS_PAGE0_CODE ( - BaseVectorMaster = (UINT32 *)(sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER); - for (Index = 0; Index < 8; Index++) { - Private->ThunkSavedInt[Index] = BaseVectorMaster[Index]; - if (Private->ThunkSeg == (UINT16)(BaseVectorMaster[Index] >> 16)) { - BaseVectorMaster[Index] = (UINT32)(Private->BiosUnexpectedInt); - } - } - - ); - - ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); - Regs.X.AX = Legacy16Boot; - - Private->LegacyBios.FarCall86 ( - This, - Private->Legacy16CallSegment, - Private->Legacy16CallOffset, - &Regs, - NULL, - 0 - ); - - ACCESS_PAGE0_CODE ( - BaseVectorMaster = (UINT32 *)(sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER); - for (Index = 0; Index < 8; Index++) { - BaseVectorMaster[Index] = Private->ThunkSavedInt[Index]; - } - - ); - } - - Private->LegacyBootEntered = TRUE; - if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) { - // - // Should never return unless never passed control to 0:7c00(first stage - // OS loader) and only then if no bootable device found. - // - return EFI_DEVICE_ERROR; - } else { - // - // If boot to EFI then expect to return to caller - // - return EFI_SUCCESS; - } -} - -/** - Assign drive number to legacy HDD drives prior to booting an EFI - aware OS so the OS can access drives without an EFI driver. - Note: BBS compliant drives ARE NOT available until this call by - either shell or EFI. - - @param This Protocol instance pointer. - @param BbsCount Number of BBS_TABLE structures - @param BbsTable List BBS entries - - @retval EFI_SUCCESS Drive numbers assigned - -**/ -EFI_STATUS -EFIAPI -LegacyBiosPrepareToBootEfi ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - OUT UINT16 *BbsCount, - OUT BBS_TABLE **BbsTable - ) -{ - EFI_STATUS Status; - EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; - LEGACY_BIOS_INSTANCE *Private; - - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; - mBootMode = BOOT_EFI_OS; - mBbsDevicePathPtr = NULL; - Status = GenericLegacyBoot (This); - *BbsTable = (BBS_TABLE *)(UINTN)EfiToLegacy16BootTable->BbsTable; - *BbsCount = (UINT16)(sizeof (Private->IntThunk->BbsTable) / sizeof (BBS_TABLE)); - return Status; -} - -/** - To boot from an unconventional device like parties and/or execute HDD diagnostics. - - @param This Protocol instance pointer. - @param Attributes How to interpret the other input parameters - @param BbsEntry The 0-based index into the BbsTable for the parent - device. - @param BeerData Pointer to the 128 bytes of ram BEER data. - @param ServiceAreaData Pointer to the 64 bytes of raw Service Area data. The - caller must provide a pointer to the specific Service - Area and not the start all Service Areas. - - @retval EFI_INVALID_PARAMETER if error. Does NOT return if no error. - -***/ -EFI_STATUS -EFIAPI -LegacyBiosBootUnconventionalDevice ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UDC_ATTRIBUTES Attributes, - IN UINTN BbsEntry, - IN VOID *BeerData, - IN VOID *ServiceAreaData - ) -{ - EFI_STATUS Status; - EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; - LEGACY_BIOS_INSTANCE *Private; - UD_TABLE *UcdTable; - UINTN Index; - UINT16 BootPriority; - BBS_TABLE *BbsTable; - - BootPriority = 0; - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - mBootMode = BOOT_UNCONVENTIONAL_DEVICE; - mBbsDevicePathPtr = &mBbsDevicePathNode; - mAttributes = Attributes; - mBbsEntry = BbsEntry; - mBeerData = BeerData, mServiceAreaData = ServiceAreaData; - - EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; - - // - // Do input parameter checking - // - if ((Attributes.DirectoryServiceValidity == 0) && - (Attributes.RabcaUsedFlag == 0) && - (Attributes.ExecuteHddDiagnosticsFlag == 0) - ) - { - return EFI_INVALID_PARAMETER; - } - - if (((Attributes.DirectoryServiceValidity != 0) && (ServiceAreaData == NULL)) || - (((Attributes.DirectoryServiceValidity | Attributes.RabcaUsedFlag) != 0) && (BeerData == NULL)) - ) - { - return EFI_INVALID_PARAMETER; - } - - UcdTable = (UD_TABLE *)AllocatePool ( - sizeof (UD_TABLE) - ); - if (NULL == UcdTable) { - return EFI_OUT_OF_RESOURCES; - } - - EfiToLegacy16BootTable->UnconventionalDeviceTable = (UINT32)(UINTN)UcdTable; - UcdTable->Attributes = Attributes; - UcdTable->BbsTableEntryNumberForParentDevice = (UINT8)BbsEntry; - // - // Force all existing BBS entries to DoNotBoot. This allows 16-bit CSM - // to assign drive numbers but bot boot from. Only newly created entries - // will be valid. - // - BbsTable = (BBS_TABLE *)(UINTN)EfiToLegacy16BootTable->BbsTable; - for (Index = 0; Index < EfiToLegacy16BootTable->NumberBbsEntries; Index++) { - BbsTable[Index].BootPriority = BBS_DO_NOT_BOOT_FROM; - } - - // - // If parent is onboard IDE then assign controller & device number - // else they are 0. - // - if (BbsEntry < MAX_IDE_CONTROLLER * 2) { - UcdTable->DeviceNumber = (UINT8)((BbsEntry - 1) % 2); - } - - if (BeerData != NULL) { - CopyMem ( - (VOID *)UcdTable->BeerData, - BeerData, - (UINTN)128 - ); - } - - if (ServiceAreaData != NULL) { - CopyMem ( - (VOID *)UcdTable->ServiceAreaData, - ServiceAreaData, - (UINTN)64 - ); - } - - // - // For each new entry do the following: - // 1. Increment current number of BBS entries - // 2. Copy parent entry to new entry. - // 3. Zero out BootHandler Offset & segment - // 4. Set appropriate device type. BEV(0x80) for HDD diagnostics - // and Floppy(0x01) for PARTIES boot. - // 5. Assign new priority. - // - if ((Attributes.ExecuteHddDiagnosticsFlag) != 0) { - EfiToLegacy16BootTable->NumberBbsEntries += 1; - - CopyMem ( - (VOID *)&BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority, - (VOID *)&BbsTable[BbsEntry].BootPriority, - sizeof (BBS_TABLE) - ); - - BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerOffset = 0; - BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerSegment = 0; - BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].DeviceType = 0x80; - - UcdTable->BbsTableEntryNumberForHddDiag = (UINT8)(EfiToLegacy16BootTable->NumberBbsEntries - 1); - - BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority = BootPriority; - BootPriority += 1; - - // - // Set device type as BBS_TYPE_DEV for PARTIES diagnostic - // - mBbsDevicePathNode.DeviceType = BBS_TYPE_BEV; - } - - if (((Attributes.DirectoryServiceValidity | Attributes.RabcaUsedFlag)) != 0) { - EfiToLegacy16BootTable->NumberBbsEntries += 1; - CopyMem ( - (VOID *)&BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority, - (VOID *)&BbsTable[BbsEntry].BootPriority, - sizeof (BBS_TABLE) - ); - - BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerOffset = 0; - BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerSegment = 0; - BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].DeviceType = 0x01; - UcdTable->BbsTableEntryNumberForBoot = (UINT8)(EfiToLegacy16BootTable->NumberBbsEntries - 1); - BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority = BootPriority; - - // - // Set device type as BBS_TYPE_FLOPPY for PARTIES boot as floppy - // - mBbsDevicePathNode.DeviceType = BBS_TYPE_FLOPPY; - } - - // - // Build the BBS Device Path for this boot selection - // - mBbsDevicePathNode.Header.Type = BBS_DEVICE_PATH; - mBbsDevicePathNode.Header.SubType = BBS_BBS_DP; - SetDevicePathNodeLength (&mBbsDevicePathNode.Header, sizeof (BBS_BBS_DEVICE_PATH)); - mBbsDevicePathNode.StatusFlag = 0; - mBbsDevicePathNode.String[0] = 0; - - Status = GenericLegacyBoot (This); - return Status; -} - -/** - Attempt to legacy boot the BootOption. If the EFI contexted has been - compromised this function will not return. - - @param This Protocol instance pointer. - @param BbsDevicePath EFI Device Path from BootXXXX variable. - @param LoadOptionsSize Size of LoadOption in size. - @param LoadOptions LoadOption from BootXXXX variable - - @retval EFI_SUCCESS Removable media not present - -**/ -EFI_STATUS -EFIAPI -LegacyBiosLegacyBoot ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN BBS_BBS_DEVICE_PATH *BbsDevicePath, - IN UINT32 LoadOptionsSize, - IN VOID *LoadOptions - ) -{ - EFI_STATUS Status; - - mBbsDevicePathPtr = BbsDevicePath; - mLoadOptionsSize = LoadOptionsSize; - mLoadOptions = LoadOptions; - mBootMode = BOOT_LEGACY_OS; - Status = GenericLegacyBoot (This); - - return Status; -} - -/** - Convert EFI Memory Type to E820 Memory Type. - - @param Type EFI Memory Type - - @return ACPI Memory Type for EFI Memory Type - -**/ -EFI_ACPI_MEMORY_TYPE -EfiMemoryTypeToE820Type ( - IN UINT32 Type - ) -{ - switch (Type) { - case EfiLoaderCode: - case EfiLoaderData: - case EfiBootServicesCode: - case EfiBootServicesData: - case EfiConventionalMemory: - // - // The memory of EfiRuntimeServicesCode and EfiRuntimeServicesData are - // usable memory for legacy OS, because legacy OS is not aware of EFI runtime concept. - // In ACPI specification, EfiRuntimeServiceCode and EfiRuntimeServiceData - // should be mapped to AddressRangeReserved. This statement is for UEFI OS, not for legacy OS. - // - case EfiRuntimeServicesCode: - case EfiRuntimeServicesData: - return EfiAcpiAddressRangeMemory; - - case EfiPersistentMemory: - return EfiAddressRangePersistentMemory; - - case EfiACPIReclaimMemory: - return EfiAcpiAddressRangeACPI; - - case EfiACPIMemoryNVS: - return EfiAcpiAddressRangeNVS; - - // - // All other types map to reserved. - // Adding the code just waists FLASH space. - // - // case EfiReservedMemoryType: - // case EfiUnusableMemory: - // case EfiMemoryMappedIO: - // case EfiMemoryMappedIOPortSpace: - // case EfiPalCode: - // - default: - return EfiAcpiAddressRangeReserved; - } -} - -/** - Build the E820 table. - - @param Private Legacy BIOS Instance data - @param Size Size of E820 Table - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosBuildE820 ( - IN LEGACY_BIOS_INSTANCE *Private, - OUT UINTN *Size - ) -{ - EFI_STATUS Status; - EFI_E820_ENTRY64 *E820Table; - EFI_MEMORY_DESCRIPTOR *EfiMemoryMap; - EFI_MEMORY_DESCRIPTOR *EfiMemoryMapEnd; - EFI_MEMORY_DESCRIPTOR *EfiEntry; - EFI_MEMORY_DESCRIPTOR *NextEfiEntry; - EFI_MEMORY_DESCRIPTOR TempEfiEntry; - UINTN EfiMemoryMapSize; - UINTN EfiMapKey; - UINTN EfiDescriptorSize; - UINT32 EfiDescriptorVersion; - UINTN Index; - EFI_PEI_HOB_POINTERS Hob; - EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; - UINTN TempIndex; - UINTN IndexSort; - UINTN TempNextIndex; - EFI_E820_ENTRY64 TempE820; - EFI_ACPI_MEMORY_TYPE TempType; - BOOLEAN ChangedFlag; - UINTN Above1MIndex; - UINT64 MemoryBlockLength; - - E820Table = (EFI_E820_ENTRY64 *)Private->E820Table; - - // - // Get the EFI memory map. - // - EfiMemoryMapSize = 0; - EfiMemoryMap = NULL; - Status = gBS->GetMemoryMap ( - &EfiMemoryMapSize, - EfiMemoryMap, - &EfiMapKey, - &EfiDescriptorSize, - &EfiDescriptorVersion - ); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - do { - // - // Use size returned for the AllocatePool. - // We don't just multiply by 2 since the "for" loop below terminates on - // EfiMemoryMapEnd which is dependent upon EfiMemoryMapSize. Otherwise - // we process bogus entries and create bogus E820 entries. - // - EfiMemoryMap = (EFI_MEMORY_DESCRIPTOR *)AllocatePool (EfiMemoryMapSize); - ASSERT (EfiMemoryMap != NULL); - Status = gBS->GetMemoryMap ( - &EfiMemoryMapSize, - EfiMemoryMap, - &EfiMapKey, - &EfiDescriptorSize, - &EfiDescriptorVersion - ); - if (EFI_ERROR (Status)) { - FreePool (EfiMemoryMap); - } - } while (Status == EFI_BUFFER_TOO_SMALL); - - ASSERT_EFI_ERROR (Status); - - // - // Punch in the E820 table for memory less than 1 MB. - // Assume ZeroMem () has been done on data structure. - // - // - // First entry is 0 to (640k - EBDA) - // - ACCESS_PAGE0_CODE ( - E820Table[0].BaseAddr = 0; - E820Table[0].Length = (UINT64)((*(UINT16 *)(UINTN)0x40E) << 4); - E820Table[0].Type = EfiAcpiAddressRangeMemory; - ); - - // - // Second entry is (640k - EBDA) to 640k - // - E820Table[1].BaseAddr = E820Table[0].Length; - E820Table[1].Length = (UINT64)((640 * 1024) - E820Table[0].Length); - E820Table[1].Type = EfiAcpiAddressRangeReserved; - - // - // Third Entry is legacy BIOS - // DO NOT CLAIM region from 0xA0000-0xDFFFF. OS can use free areas - // to page in memory under 1MB. - // Omit region from 0xE0000 to start of BIOS, if any. This can be - // used for a multiple reasons including OPROMS. - // - - // - // The CSM binary image size is not the actually size that CSM binary used, - // to avoid memory corrupt, we declare the 0E0000 - 0FFFFF is used by CSM binary. - // - E820Table[2].BaseAddr = 0xE0000; - E820Table[2].Length = 0x20000; - E820Table[2].Type = EfiAcpiAddressRangeReserved; - - Above1MIndex = 2; - - // - // Process the EFI map to produce E820 map; - // - - // - // Sort memory map from low to high - // - EfiEntry = EfiMemoryMap; - NextEfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize); - EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)EfiMemoryMap + EfiMemoryMapSize); - while (EfiEntry < EfiMemoryMapEnd) { - while (NextEfiEntry < EfiMemoryMapEnd) { - if (EfiEntry->PhysicalStart > NextEfiEntry->PhysicalStart) { - CopyMem (&TempEfiEntry, EfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); - CopyMem (EfiEntry, NextEfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); - CopyMem (NextEfiEntry, &TempEfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); - } - - NextEfiEntry = NEXT_MEMORY_DESCRIPTOR (NextEfiEntry, EfiDescriptorSize); - } - - EfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize); - NextEfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize); - } - - EfiEntry = EfiMemoryMap; - EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)EfiMemoryMap + EfiMemoryMapSize); - for (Index = Above1MIndex; (EfiEntry < EfiMemoryMapEnd) && (Index < EFI_MAX_E820_ENTRY - 1); ) { - MemoryBlockLength = (UINT64)(LShiftU64 (EfiEntry->NumberOfPages, 12)); - if ((EfiEntry->PhysicalStart + MemoryBlockLength) < 0x100000) { - // - // Skip the memory block if under 1MB - // - } else { - if (EfiEntry->PhysicalStart < 0x100000) { - // - // When the memory block spans below 1MB, ensure the memory block start address is at least 1MB - // - MemoryBlockLength -= 0x100000 - EfiEntry->PhysicalStart; - EfiEntry->PhysicalStart = 0x100000; - } - - // - // Convert memory type to E820 type - // - TempType = EfiMemoryTypeToE820Type (EfiEntry->Type); - - if ((E820Table[Index].Type == TempType) && (EfiEntry->PhysicalStart == (E820Table[Index].BaseAddr + E820Table[Index].Length))) { - // - // Grow an existing entry - // - E820Table[Index].Length += MemoryBlockLength; - } else { - // - // Make a new entry - // - ++Index; - E820Table[Index].BaseAddr = EfiEntry->PhysicalStart; - E820Table[Index].Length = MemoryBlockLength; - E820Table[Index].Type = TempType; - } - } - - EfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize); - } - - FreePool (EfiMemoryMap); - - // - // Process the reserved memory map to produce E820 map ; - // - for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { - if ((Hob.Raw != NULL) && (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR)) { - ResourceHob = Hob.ResourceDescriptor; - if (((ResourceHob->ResourceType == EFI_RESOURCE_MEMORY_MAPPED_IO) || - (ResourceHob->ResourceType == EFI_RESOURCE_FIRMWARE_DEVICE) || - (ResourceHob->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) && - (ResourceHob->PhysicalStart > 0x100000) && - (Index < EFI_MAX_E820_ENTRY - 1)) - { - ++Index; - E820Table[Index].BaseAddr = ResourceHob->PhysicalStart; - E820Table[Index].Length = ResourceHob->ResourceLength; - E820Table[Index].Type = EfiAcpiAddressRangeReserved; - } - } - } - - Index++; - Private->IntThunk->EfiToLegacy16InitTable.NumberE820Entries = (UINT32)Index; - Private->IntThunk->EfiToLegacy16BootTable.NumberE820Entries = (UINT32)Index; - Private->NumberE820Entries = (UINT32)Index; - *Size = (UINTN)(Index * sizeof (EFI_E820_ENTRY64)); - - // - // Sort E820Table from low to high - // - for (TempIndex = 0; TempIndex < Index; TempIndex++) { - ChangedFlag = FALSE; - for (TempNextIndex = 1; TempNextIndex < Index - TempIndex; TempNextIndex++) { - if (E820Table[TempNextIndex - 1].BaseAddr > E820Table[TempNextIndex].BaseAddr) { - ChangedFlag = TRUE; - TempE820.BaseAddr = E820Table[TempNextIndex - 1].BaseAddr; - TempE820.Length = E820Table[TempNextIndex - 1].Length; - TempE820.Type = E820Table[TempNextIndex - 1].Type; - - E820Table[TempNextIndex - 1].BaseAddr = E820Table[TempNextIndex].BaseAddr; - E820Table[TempNextIndex - 1].Length = E820Table[TempNextIndex].Length; - E820Table[TempNextIndex - 1].Type = E820Table[TempNextIndex].Type; - - E820Table[TempNextIndex].BaseAddr = TempE820.BaseAddr; - E820Table[TempNextIndex].Length = TempE820.Length; - E820Table[TempNextIndex].Type = TempE820.Type; - } - } - - if (!ChangedFlag) { - break; - } - } - - // - // Remove the overlap range - // - for (TempIndex = 1; TempIndex < Index; TempIndex++) { - if ((E820Table[TempIndex - 1].BaseAddr <= E820Table[TempIndex].BaseAddr) && - ((E820Table[TempIndex - 1].BaseAddr + E820Table[TempIndex - 1].Length) >= - (E820Table[TempIndex].BaseAddr +E820Table[TempIndex].Length))) - { - // - // Overlap range is found - // - ASSERT (E820Table[TempIndex - 1].Type == E820Table[TempIndex].Type); - - if (TempIndex == Index - 1) { - E820Table[TempIndex].BaseAddr = 0; - E820Table[TempIndex].Length = 0; - E820Table[TempIndex].Type = (EFI_ACPI_MEMORY_TYPE)0; - Index--; - break; - } else { - for (IndexSort = TempIndex; IndexSort < Index - 1; IndexSort++) { - E820Table[IndexSort].BaseAddr = E820Table[IndexSort + 1].BaseAddr; - E820Table[IndexSort].Length = E820Table[IndexSort + 1].Length; - E820Table[IndexSort].Type = E820Table[IndexSort + 1].Type; - } - - Index--; - } - } - } - - Private->IntThunk->EfiToLegacy16InitTable.NumberE820Entries = (UINT32)Index; - Private->IntThunk->EfiToLegacy16BootTable.NumberE820Entries = (UINT32)Index; - Private->NumberE820Entries = (UINT32)Index; - *Size = (UINTN)(Index * sizeof (EFI_E820_ENTRY64)); - - // - // Determine OS usable memory above 1MB - // - Private->IntThunk->EfiToLegacy16BootTable.OsMemoryAbove1Mb = 0x0000; - for (TempIndex = Above1MIndex; TempIndex < Index; TempIndex++) { - if ((E820Table[TempIndex].BaseAddr >= 0x100000) && (E820Table[TempIndex].BaseAddr < 0x100000000ULL)) { - // not include above 4G memory - // - // ACPIReclaimMemory is also usable memory for ACPI OS, after OS dumps all ACPI tables. - // - if ((E820Table[TempIndex].Type == EfiAcpiAddressRangeMemory) || (E820Table[TempIndex].Type == EfiAcpiAddressRangeACPI)) { - Private->IntThunk->EfiToLegacy16BootTable.OsMemoryAbove1Mb += (UINT32)(E820Table[TempIndex].Length); - } else { - break; // break at first not normal memory, because SMM may use reserved memory. - } - } - } - - Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb = Private->IntThunk->EfiToLegacy16BootTable.OsMemoryAbove1Mb; - - // - // Print DEBUG information - // - for (TempIndex = 0; TempIndex < Index; TempIndex++) { - DEBUG (( - DEBUG_INFO, - "E820[%2d]: 0x%016lx - 0x%016lx, Type = %d\n", - TempIndex, - E820Table[TempIndex].BaseAddr, - (E820Table[TempIndex].BaseAddr + E820Table[TempIndex].Length), - E820Table[TempIndex].Type - )); - } - - return EFI_SUCCESS; -} - -/** - Fill in the standard BDA and EBDA stuff prior to legacy Boot - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosCompleteBdaBeforeBoot ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - BDA_STRUC *Bda; - UINT16 MachineConfig; - DEVICE_PRODUCER_DATA_HEADER *SioPtr; - - Bda = (BDA_STRUC *)((UINTN)0x400); - MachineConfig = 0; - - SioPtr = &(Private->IntThunk->EfiToLegacy16BootTable.SioData); - Bda->Com1 = SioPtr->Serial[0].Address; - Bda->Com2 = SioPtr->Serial[1].Address; - Bda->Com3 = SioPtr->Serial[2].Address; - Bda->Com4 = SioPtr->Serial[3].Address; - - if (SioPtr->Serial[0].Address != 0x00) { - MachineConfig += 0x200; - } - - if (SioPtr->Serial[1].Address != 0x00) { - MachineConfig += 0x200; - } - - if (SioPtr->Serial[2].Address != 0x00) { - MachineConfig += 0x200; - } - - if (SioPtr->Serial[3].Address != 0x00) { - MachineConfig += 0x200; - } - - Bda->Lpt1 = SioPtr->Parallel[0].Address; - Bda->Lpt2 = SioPtr->Parallel[1].Address; - Bda->Lpt3 = SioPtr->Parallel[2].Address; - - if (SioPtr->Parallel[0].Address != 0x00) { - MachineConfig += 0x4000; - } - - if (SioPtr->Parallel[1].Address != 0x00) { - MachineConfig += 0x4000; - } - - if (SioPtr->Parallel[2].Address != 0x00) { - MachineConfig += 0x4000; - } - - Bda->NumberOfDrives = (UINT8)(Bda->NumberOfDrives + Private->IdeDriveCount); - if (SioPtr->Floppy.NumberOfFloppy != 0x00) { - MachineConfig = (UINT16)(MachineConfig + 0x01 + (SioPtr->Floppy.NumberOfFloppy - 1) * 0x40); - Bda->FloppyXRate = 0x07; - } - - Bda->Lpt1_2Timeout = 0x1414; - Bda->Lpt3_4Timeout = 0x1414; - Bda->Com1_2Timeout = 0x0101; - Bda->Com3_4Timeout = 0x0101; - - // - // Force VGA and Coprocessor, indicate 101/102 keyboard - // - MachineConfig = (UINT16)(MachineConfig + 0x00 + 0x02 + (SioPtr->MousePresent * 0x04)); - Bda->MachineConfig = MachineConfig; - - return EFI_SUCCESS; -} - -/** - Fill in the standard BDA for Keyboard LEDs - - @param This Protocol instance pointer. - @param Leds Current LED status - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -EFIAPI -LegacyBiosUpdateKeyboardLedStatus ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINT8 Leds - ) -{ - LEGACY_BIOS_INSTANCE *Private; - BDA_STRUC *Bda; - UINT8 LocalLeds; - EFI_IA32_REGISTER_SET Regs; - - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - - ACCESS_PAGE0_CODE ( - Bda = (BDA_STRUC *)((UINTN)0x400); - LocalLeds = Leds; - Bda->LedStatus = (UINT8)((Bda->LedStatus &~0x07) | LocalLeds); - LocalLeds = (UINT8)(LocalLeds << 4); - Bda->ShiftStatus = (UINT8)((Bda->ShiftStatus &~0x70) | LocalLeds); - LocalLeds = (UINT8)(Leds & 0x20); - Bda->KeyboardStatus = (UINT8)((Bda->KeyboardStatus &~0x20) | LocalLeds); - ); - - // - // Call into Legacy16 code to allow it to do any processing - // - ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); - Regs.X.AX = Legacy16SetKeyboardLeds; - Regs.H.CL = Leds; - - Private->LegacyBios.FarCall86 ( - &Private->LegacyBios, - Private->Legacy16Table->Compatibility16CallSegment, - Private->Legacy16Table->Compatibility16CallOffset, - &Regs, - NULL, - 0 - ); - - return EFI_SUCCESS; -} - -/** - Fill in the standard CMOS stuff prior to legacy Boot - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosCompleteStandardCmosBeforeBoot ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - UINT8 Bda; - UINT8 Floppy; - UINT32 Size; - - // - // Update CMOS locations - // 10 floppy - // 12,19,1A - ignore as OS don't use them and there is no standard due - // to large capacity drives - // CMOS 14 = BDA 40:10 plus bit 3(display enabled) - // - ACCESS_PAGE0_CODE ( - Bda = (UINT8)(*((UINT8 *)((UINTN)0x410)) | BIT3); - ); - - // - // Force display enabled - // - Floppy = 0x00; - if ((Bda & BIT0) != 0) { - Floppy = BIT6; - } - - // - // Check if 2.88MB floppy set - // - if ((Bda & (BIT7 | BIT6)) != 0) { - Floppy = (UINT8)(Floppy | BIT1); - } - - LegacyWriteStandardCmos (CMOS_10, Floppy); - LegacyWriteStandardCmos (CMOS_14, Bda); - - // - // Force Status Register A to set rate selection bits and divider - // - LegacyWriteStandardCmos (CMOS_0A, 0x26); - - // - // redo memory size since it can change - // - Size = (15 * SIZE_1MB) >> 10; - if (Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb < (15 * SIZE_1MB)) { - Size = Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb >> 10; - } - - LegacyWriteStandardCmos (CMOS_17, (UINT8)(Size & 0xFF)); - LegacyWriteStandardCmos (CMOS_30, (UINT8)(Size & 0xFF)); - LegacyWriteStandardCmos (CMOS_18, (UINT8)(Size >> 8)); - LegacyWriteStandardCmos (CMOS_31, (UINT8)(Size >> 8)); - - LegacyCalculateWriteStandardCmosChecksum (); - - return EFI_SUCCESS; -} - -/** - Relocate this image under 4G memory for IPF. - - @param ImageHandle Handle of driver image. - @param SystemTable Pointer to system table. - - @retval EFI_SUCCESS Image successfully relocated. - @retval EFI_ABORTED Failed to relocate image. - -**/ -EFI_STATUS -RelocateImageUnder4GIfNeeded ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - return EFI_SUCCESS; -} diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacyCmos.c b/OvmfPkg/Csm/LegacyBiosDxe/LegacyCmos.c deleted file mode 100644 index 7220d8e65a..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacyCmos.c +++ /dev/null @@ -1,117 +0,0 @@ -/** @file - This code fills in standard CMOS values and updates the standard CMOS - checksum. The Legacy16 code or LegacyBiosPlatform.c is responsible for - non-standard CMOS locations and non-standard checksums. - -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "LegacyBiosInterface.h" - -/** - Read CMOS register through index/data port. - - @param[in] Index The index of the CMOS register to read. - - @return The data value from the CMOS register specified by Index. - -**/ -UINT8 -LegacyReadStandardCmos ( - IN UINT8 Index - ) -{ - IoWrite8 (PORT_70, Index); - return IoRead8 (PORT_71); -} - -/** - Write CMOS register through index/data port. - - @param[in] Index The index of the CMOS register to write. - @param[in] Value The value of CMOS register to write. - - @return The value written to the CMOS register specified by Index. - -**/ -UINT8 -LegacyWriteStandardCmos ( - IN UINT8 Index, - IN UINT8 Value - ) -{ - IoWrite8 (PORT_70, Index); - return IoWrite8 (PORT_71, Value); -} - -/** - Calculate the new standard CMOS checksum and write it. - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS Calculate 16-bit checksum successfully - -**/ -EFI_STATUS -LegacyCalculateWriteStandardCmosChecksum ( - VOID - ) -{ - UINT8 Register; - UINT16 Checksum; - - for (Checksum = 0, Register = 0x10; Register < 0x2e; Register++) { - Checksum = (UINT16)(Checksum + LegacyReadStandardCmos (Register)); - } - - LegacyWriteStandardCmos (CMOS_2E, (UINT8)(Checksum >> 8)); - LegacyWriteStandardCmos (CMOS_2F, (UINT8)(Checksum & 0xff)); - return EFI_SUCCESS; -} - -/** - Fill in the standard CMOS stuff before Legacy16 load - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosInitCmos ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - UINT32 Size; - - // - // Clear all errors except RTC lost power - // - LegacyWriteStandardCmos (CMOS_0E, (UINT8)(LegacyReadStandardCmos (CMOS_0E) & BIT7)); - - // - // Update CMOS locations 15,16,17,18,30,31 and 32 - // CMOS 16,15 = 640Kb = 0x280 - // CMOS 18,17 = 31,30 = 15Mb max in 1Kb increments =0x3C00 max - // CMOS 32 = 0x20 - // - LegacyWriteStandardCmos (CMOS_15, 0x80); - LegacyWriteStandardCmos (CMOS_16, 0x02); - - Size = 15 * SIZE_1MB; - if (Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb < (15 * SIZE_1MB)) { - Size = Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb >> 10; - } - - LegacyWriteStandardCmos (CMOS_17, (UINT8)(Size & 0xFF)); - LegacyWriteStandardCmos (CMOS_30, (UINT8)(Size & 0xFF)); - LegacyWriteStandardCmos (CMOS_18, (UINT8)(Size >> 8)); - LegacyWriteStandardCmos (CMOS_31, (UINT8)(Size >> 8)); - - LegacyCalculateWriteStandardCmosChecksum (); - - return EFI_SUCCESS; -} diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacyIde.c b/OvmfPkg/Csm/LegacyBiosDxe/LegacyIde.c deleted file mode 100644 index 323f76c970..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacyIde.c +++ /dev/null @@ -1,315 +0,0 @@ -/** @file - Collect IDE information from Native EFI Driver - -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "LegacyBiosInterface.h" - -BOOLEAN mIdeDataBuiltFlag = FALSE; - -/** - Collect IDE Inquiry data from the IDE disks - - @param Private Legacy BIOS Instance data - @param HddInfo Hdd Information - @param Flag Reconnect IdeController or not - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosBuildIdeData ( - IN LEGACY_BIOS_INSTANCE *Private, - IN HDD_INFO **HddInfo, - IN UINT16 Flag - ) -{ - EFI_STATUS Status; - EFI_HANDLE IdeController; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - EFI_DISK_INFO_PROTOCOL *DiskInfo; - UINT32 IdeChannel; - UINT32 IdeDevice; - UINT32 Size; - UINT8 *InquiryData; - UINT32 InquiryDataSize; - HDD_INFO *LocalHddInfo; - UINT32 PciIndex; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePathNode; - PCI_DEVICE_PATH *PciDevicePath; - - // - // Only build data once - // We have a problem with GetBbsInfo in that it can be invoked two - // places. Once in BDS, when all EFI drivers are connected and once in - // LegacyBoot after all EFI drivers are disconnected causing this routine - // to hang. In LegacyBoot this function is also called before EFI drivers - // are disconnected. - // Cases covered - // GetBbsInfo invoked in BDS. Both invocations in LegacyBoot ignored. - // GetBbsInfo not invoked in BDS. First invocation of this function - // proceeds normally and second via GetBbsInfo ignored. - // - PciDevicePath = NULL; - LocalHddInfo = *HddInfo; - Status = Private->LegacyBiosPlatform->GetPlatformHandle ( - Private->LegacyBiosPlatform, - EfiGetPlatformIdeHandle, - 0, - &HandleBuffer, - &HandleCount, - (VOID *)&LocalHddInfo - ); - if (!EFI_ERROR (Status)) { - IdeController = HandleBuffer[0]; - // - // Force IDE drive spin up! - // - if (Flag != 0) { - gBS->DisconnectController ( - IdeController, - NULL, - NULL - ); - } - - gBS->ConnectController (IdeController, NULL, NULL, FALSE); - - // - // Do GetIdeHandle twice since disconnect/reconnect will switch to native mode - // And GetIdeHandle will switch to Legacy mode, if required. - // - Private->LegacyBiosPlatform->GetPlatformHandle ( - Private->LegacyBiosPlatform, - EfiGetPlatformIdeHandle, - 0, - &HandleBuffer, - &HandleCount, - (VOID *)&LocalHddInfo - ); - } - - mIdeDataBuiltFlag = TRUE; - - // - // Get Identity command from all drives - // - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiDiskInfoProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - - Private->IdeDriveCount = (UINT8)HandleCount; - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiDiskInfoProtocolGuid, - (VOID **)&DiskInfo - ); - ASSERT_EFI_ERROR (Status); - - if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoIdeInterfaceGuid)) { - // - // Locate which PCI device - // - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiDevicePathProtocolGuid, - (VOID *)&DevicePath - ); - ASSERT_EFI_ERROR (Status); - - DevicePathNode = DevicePath; - while (!IsDevicePathEnd (DevicePathNode)) { - TempDevicePathNode = NextDevicePathNode (DevicePathNode); - if ((DevicePathType (DevicePathNode) == HARDWARE_DEVICE_PATH) && - (DevicePathSubType (DevicePathNode) == HW_PCI_DP) && - (DevicePathType (TempDevicePathNode) == MESSAGING_DEVICE_PATH) && - (DevicePathSubType (TempDevicePathNode) == MSG_ATAPI_DP)) - { - PciDevicePath = (PCI_DEVICE_PATH *)DevicePathNode; - break; - } - - DevicePathNode = NextDevicePathNode (DevicePathNode); - } - - if (PciDevicePath == NULL) { - continue; - } - - // - // Find start of PCI device in HddInfo. The assumption of the data - // structure is 2 controllers(channels) per PCI device and each - // controller can have 2 drives(devices). - // HddInfo[PciIndex+0].[0] = Channel[0].Device[0] Primary Master - // HddInfo[PciIndex+0].[1] = Channel[0].Device[1] Primary Slave - // HddInfo[PciIndex+1].[0] = Channel[1].Device[0] Secondary Master - // HddInfo[PciIndex+1].[1] = Channel[1].Device[1] Secondary Slave - // @bug eventually need to pass in max number of entries - // for end of for loop - // - for (PciIndex = 0; PciIndex < 8; PciIndex++) { - if ((PciDevicePath->Device == LocalHddInfo[PciIndex].Device) && - (PciDevicePath->Function == LocalHddInfo[PciIndex].Function) - ) - { - break; - } - } - - if (PciIndex == 8) { - continue; - } - - Status = DiskInfo->WhichIde (DiskInfo, &IdeChannel, &IdeDevice); - if (!EFI_ERROR (Status)) { - Size = sizeof (ATAPI_IDENTIFY); - DiskInfo->Identify ( - DiskInfo, - &LocalHddInfo[PciIndex + IdeChannel].IdentifyDrive[IdeDevice], - &Size - ); - if (IdeChannel == 0) { - LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_PRIMARY; - } else if (IdeChannel == 1) { - LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SECONDARY; - } - - InquiryData = NULL; - InquiryDataSize = 0; - Status = DiskInfo->Inquiry ( - DiskInfo, - NULL, - &InquiryDataSize - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - InquiryData = (UINT8 *)AllocatePool ( - InquiryDataSize - ); - if (InquiryData != NULL) { - Status = DiskInfo->Inquiry ( - DiskInfo, - InquiryData, - &InquiryDataSize - ); - } - } else { - Status = EFI_DEVICE_ERROR; - } - - // - // If ATAPI device then Inquiry will pass and ATA fail. - // - if (!EFI_ERROR (Status)) { - ASSERT (InquiryData != NULL); - // - // If IdeDevice = 0 then set master bit, else slave bit - // - if (IdeDevice == 0) { - if ((InquiryData[0] & 0x1f) == 0x05) { - LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_ATAPI_CDROM; - } else if ((InquiryData[0] & 0x1f) == 0x00) { - LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_ATAPI_ZIPDISK; - } - } else { - if ((InquiryData[0] & 0x1f) == 0x05) { - LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_ATAPI_CDROM; - } else if ((InquiryData[0] & 0x1f) == 0x00) { - LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_ATAPI_ZIPDISK; - } - } - - FreePool (InquiryData); - } else { - if (IdeDevice == 0) { - LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_IDE; - } else { - LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_IDE; - } - } - } - } - } - - if (HandleBuffer != NULL) { - FreePool (HandleBuffer); - } - - return EFI_SUCCESS; -} - -/** - If the IDE channel is in compatibility (legacy) mode, remove all - PCI I/O BAR addresses from the controller. - - @param IdeController The handle of target IDE controller - - -**/ -VOID -InitLegacyIdeController ( - IN EFI_HANDLE IdeController - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT32 IOBarClear; - EFI_STATUS Status; - PCI_TYPE00 PciData; - - // - // If the IDE channel is in compatibility (legacy) mode, remove all - // PCI I/O BAR addresses from the controller. Some software gets - // confused if an IDE controller is in compatibility (legacy) mode - // and has PCI I/O resources allocated - // - Status = gBS->HandleProtocol ( - IdeController, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - if (EFI_ERROR (Status)) { - return; - } - - Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (PciData), &PciData); - if (EFI_ERROR (Status)) { - return; - } - - // - // Check whether this is IDE - // - if ((PciData.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE) || - (PciData.Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE)) - { - return; - } - - // - // Clear bar for legacy IDE - // - IOBarClear = 0x00; - if ((PciData.Hdr.ClassCode[0] & IDE_PI_REGISTER_PNE) == 0) { - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x10, 1, &IOBarClear); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x14, 1, &IOBarClear); - } - - if ((PciData.Hdr.ClassCode[0] & IDE_PI_REGISTER_SNE) == 0) { - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x18, 1, &IOBarClear); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1C, 1, &IOBarClear); - } - - return; -} diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacyPci.c b/OvmfPkg/Csm/LegacyBiosDxe/LegacyPci.c deleted file mode 100644 index 07ee5ab099..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacyPci.c +++ /dev/null @@ -1,3114 +0,0 @@ -/** @file - -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "LegacyBiosInterface.h" -#include - -#define PCI_START_ADDRESS(x) (((x) + 0x7ff) & ~0x7ff) - -#define MAX_BRIDGE_INDEX 0x20 -typedef struct { - UINTN PciSegment; - UINTN PciBus; - UINTN PciDevice; - UINTN PciFunction; - UINT8 PrimaryBus; - UINT8 SecondaryBus; - UINT8 SubordinateBus; -} BRIDGE_TABLE; - -#define ROM_MAX_ENTRIES 24 -BRIDGE_TABLE Bridges[MAX_BRIDGE_INDEX]; -UINTN SortedBridgeIndex[MAX_BRIDGE_INDEX]; -UINTN NumberOfBridges; -LEGACY_PNP_EXPANSION_HEADER *mBasePnpPtr; -UINT16 mBbsRomSegment; -UINTN mHandleCount; -EFI_HANDLE mVgaHandle; -BOOLEAN mIgnoreBbsUpdateFlag; -BOOLEAN mVgaInstallationInProgress = FALSE; -UINT32 mRomCount = 0x00; -ROM_INSTANCE_ENTRY mRomEntry[ROM_MAX_ENTRIES]; -EDKII_IOMMU_PROTOCOL *mIoMmu; - -/** - Query shadowed legacy ROM parameters registered by RomShadow() previously. - - @param PciHandle PCI device whos ROM has been shadowed - @param DiskStart DiskStart value from EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom - @param DiskEnd DiskEnd value from EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom - @param RomShadowAddress Address where ROM was shadowed - @param ShadowedSize Runtime size of ROM - - @retval EFI_SUCCESS Query Logging successful. - @retval EFI_NOT_FOUND No logged data found about PciHandle. - -**/ -EFI_STATUS -GetShadowedRomParameters ( - IN EFI_HANDLE PciHandle, - OUT UINT8 *DiskStart OPTIONAL, - OUT UINT8 *DiskEnd OPTIONAL, - OUT VOID **RomShadowAddress OPTIONAL, - OUT UINTN *ShadowedSize OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - UINTN Index; - UINTN PciSegment; - UINTN PciBus; - UINTN PciDevice; - UINTN PciFunction; - - // - // Get the PCI I/O Protocol on PciHandle - // - Status = gBS->HandleProtocol ( - PciHandle, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the location of the PCI device - // - PciIo->GetLocation ( - PciIo, - &PciSegment, - &PciBus, - &PciDevice, - &PciFunction - ); - - for (Index = 0; Index < mRomCount; Index++) { - if ((mRomEntry[Index].PciSegment == PciSegment) && - (mRomEntry[Index].PciBus == PciBus) && - (mRomEntry[Index].PciDevice == PciDevice) && - (mRomEntry[Index].PciFunction == PciFunction)) - { - break; - } - } - - if (Index == mRomCount) { - return EFI_NOT_FOUND; - } - - if (DiskStart != NULL) { - *DiskStart = mRomEntry[Index].DiskStart; - } - - if (DiskEnd != NULL) { - *DiskEnd = mRomEntry[Index].DiskEnd; - } - - if (RomShadowAddress != NULL) { - *RomShadowAddress = (VOID *)(UINTN)mRomEntry[Index].ShadowAddress; - } - - if (ShadowedSize != NULL) { - *ShadowedSize = mRomEntry[Index].ShadowedSize; - } - - return EFI_SUCCESS; -} - -/** - Every legacy ROM that is shadowed by the Legacy BIOS driver will be - registered into this API so that the policy code can know what has - happend - - @param PciHandle PCI device whos ROM is being shadowed - @param ShadowAddress Address that ROM was shadowed - @param ShadowedSize Runtime size of ROM - @param DiskStart DiskStart value from - EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom - @param DiskEnd DiskEnd value from - EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom - - @retval EFI_SUCCESS Logging successful. - @retval EFI_OUT_OF_RESOURCES No remaining room for registering another option - ROM. - -**/ -EFI_STATUS -RomShadow ( - IN EFI_HANDLE PciHandle, - IN UINT32 ShadowAddress, - IN UINT32 ShadowedSize, - IN UINT8 DiskStart, - IN UINT8 DiskEnd - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - - // - // See if there is room to register another option ROM - // - if (mRomCount >= ROM_MAX_ENTRIES) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Get the PCI I/O Protocol on PciHandle - // - Status = gBS->HandleProtocol ( - PciHandle, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the location of the PCI device - // - PciIo->GetLocation ( - PciIo, - &mRomEntry[mRomCount].PciSegment, - &mRomEntry[mRomCount].PciBus, - &mRomEntry[mRomCount].PciDevice, - &mRomEntry[mRomCount].PciFunction - ); - mRomEntry[mRomCount].ShadowAddress = ShadowAddress; - mRomEntry[mRomCount].ShadowedSize = ShadowedSize; - mRomEntry[mRomCount].DiskStart = DiskStart; - mRomEntry[mRomCount].DiskEnd = DiskEnd; - - mRomCount++; - - return EFI_SUCCESS; -} - -/** - Return EFI_SUCCESS if PciHandle has had a legacy BIOS ROM shadowed. This - information represents every call to RomShadow () - - @param PciHandle PCI device to get status for - - @retval EFI_SUCCESS Legacy ROM loaded for this device - @retval EFI_NOT_FOUND No Legacy ROM loaded for this device - -**/ -EFI_STATUS -IsLegacyRom ( - IN EFI_HANDLE PciHandle - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - UINTN Index; - UINTN Segment; - UINTN Bus; - UINTN Device; - UINTN Function; - - // - // Get the PCI I/O Protocol on PciHandle - // - Status = gBS->HandleProtocol ( - PciHandle, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the location of the PCI device - // - PciIo->GetLocation ( - PciIo, - &Segment, - &Bus, - &Device, - &Function - ); - - // - // See if the option ROM from PciHandle has been previously posted - // - for (Index = 0; Index < mRomCount; Index++) { - if ((mRomEntry[Index].PciSegment == Segment) && - (mRomEntry[Index].PciBus == Bus) && - (mRomEntry[Index].PciDevice == Device) && - (mRomEntry[Index].PciFunction == Function) - ) - { - return EFI_SUCCESS; - } - } - - return EFI_NOT_FOUND; -} - -/** - Find the PC-AT ROM Image in the raw PCI Option ROM. Also return the - related information from the header. - - @param Csm16Revision The PCI interface version of underlying CSM16 - @param VendorId Vendor ID of the PCI device - @param DeviceId Device ID of the PCI device - @param Rom On input pointing to beginning of the raw PCI OpROM - On output pointing to the first legacy PCI OpROM - @param ImageSize On input is the size of Raw PCI Rom - On output is the size of the first legacy PCI ROM - @param MaxRuntimeImageLength The max runtime image length only valid if OpRomRevision >= 3 - @param OpRomRevision Revision of the PCI Rom - @param ConfigUtilityCodeHeader Pointer to Configuration Utility Code Header - - @retval EFI_SUCCESS Successfully find the legacy PCI ROM - @retval EFI_NOT_FOUND Failed to find the legacy PCI ROM - -**/ -EFI_STATUS -GetPciLegacyRom ( - IN UINT16 Csm16Revision, - IN UINT16 VendorId, - IN UINT16 DeviceId, - IN OUT VOID **Rom, - IN OUT UINTN *ImageSize, - OUT UINTN *MaxRuntimeImageLength OPTIONAL, - OUT UINT8 *OpRomRevision OPTIONAL, - OUT VOID **ConfigUtilityCodeHeader OPTIONAL - ) -{ - BOOLEAN Match; - UINT16 *DeviceIdList; - EFI_PCI_ROM_HEADER RomHeader; - PCI_3_0_DATA_STRUCTURE *Pcir; - VOID *BackupImage; - VOID *BestImage; - - if (*ImageSize < sizeof (EFI_PCI_ROM_HEADER)) { - return EFI_NOT_FOUND; - } - - BestImage = NULL; - BackupImage = NULL; - RomHeader.Raw = *Rom; - while (RomHeader.Generic->Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE) { - if ((RomHeader.Generic->PcirOffset == 0) || - ((RomHeader.Generic->PcirOffset & 3) != 0) || - (*ImageSize < RomHeader.Raw - (UINT8 *)*Rom + RomHeader.Generic->PcirOffset + sizeof (PCI_DATA_STRUCTURE))) - { - break; - } - - Pcir = (PCI_3_0_DATA_STRUCTURE *)(RomHeader.Raw + RomHeader.Generic->PcirOffset); - // - // Check signature in the PCI Data Structure. - // - if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) { - break; - } - - if (((UINTN)RomHeader.Raw - (UINTN)*Rom) + Pcir->ImageLength * 512 > *ImageSize) { - break; - } - - if (Pcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) { - Match = FALSE; - if (Pcir->VendorId == VendorId) { - if (Pcir->DeviceId == DeviceId) { - Match = TRUE; - } else if ((Pcir->Revision >= 3) && (Pcir->DeviceListOffset != 0)) { - DeviceIdList = (UINT16 *)(((UINT8 *)Pcir) + Pcir->DeviceListOffset); - // - // Checking the device list - // - while (*DeviceIdList != 0) { - if (*DeviceIdList == DeviceId) { - Match = TRUE; - break; - } - - DeviceIdList++; - } - } - } - - if (Match) { - if (Csm16Revision >= 0x0300) { - // - // Case 1: CSM16 3.0 - // - if (Pcir->Revision >= 3) { - // - // case 1.1: meets OpRom 3.0 - // Perfect!!! - // - BestImage = RomHeader.Raw; - break; - } else { - // - // case 1.2: meets OpRom 2.x - // Store it and try to find the OpRom 3.0 - // - BackupImage = RomHeader.Raw; - } - } else { - // - // Case 2: CSM16 2.x - // - if (Pcir->Revision >= 3) { - // - // case 2.1: meets OpRom 3.0 - // Store it and try to find the OpRom 2.x - // - BackupImage = RomHeader.Raw; - } else { - // - // case 2.2: meets OpRom 2.x - // Perfect!!! - // - BestImage = RomHeader.Raw; - break; - } - } - } else { - DEBUG ((DEBUG_ERROR, "GetPciLegacyRom - OpRom not match (%04x-%04x)\n", (UINTN)VendorId, (UINTN)DeviceId)); - } - } - - if ((Pcir->Indicator & 0x80) == 0x80) { - break; - } else { - RomHeader.Raw += 512 * Pcir->ImageLength; - } - } - - if (BestImage == NULL) { - if (BackupImage == NULL) { - return EFI_NOT_FOUND; - } - - // - // The versions of CSM16 and OpRom don't match exactly - // - BestImage = BackupImage; - } - - RomHeader.Raw = BestImage; - Pcir = (PCI_3_0_DATA_STRUCTURE *)(RomHeader.Raw + RomHeader.Generic->PcirOffset); - *Rom = BestImage; - *ImageSize = Pcir->ImageLength * 512; - - if (MaxRuntimeImageLength != NULL) { - if (Pcir->Revision < 3) { - *MaxRuntimeImageLength = 0; - } else { - *MaxRuntimeImageLength = Pcir->MaxRuntimeImageLength * 512; - } - } - - if (OpRomRevision != NULL) { - // - // Optional return PCI Data Structure revision - // - if (Pcir->Length >= 0x1C) { - *OpRomRevision = Pcir->Revision; - } else { - *OpRomRevision = 0; - } - } - - if (ConfigUtilityCodeHeader != NULL) { - // - // Optional return ConfigUtilityCodeHeaderOffset supported by the PC-AT ROM - // - if ((Pcir->Revision < 3) || (Pcir->ConfigUtilityCodeHeaderOffset == 0)) { - *ConfigUtilityCodeHeader = NULL; - } else { - *ConfigUtilityCodeHeader = RomHeader.Raw + Pcir->ConfigUtilityCodeHeaderOffset; - } - } - - return EFI_SUCCESS; -} - -/** - Build a table of bridge info for PIRQ translation. - - @param RoutingTable RoutingTable obtained from Platform. - @param RoutingTableEntries Number of RoutingTable entries. - - @retval EFI_SUCCESS New Subordinate bus. - @retval EFI_NOT_FOUND No more Subordinate busses. - -**/ -EFI_STATUS -CreateBridgeTable ( - IN EFI_LEGACY_IRQ_ROUTING_ENTRY *RoutingTable, - IN UINTN RoutingTableEntries - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN BridgeIndex; - UINTN Index; - UINTN Index1; - EFI_PCI_IO_PROTOCOL *PciIo; - PCI_TYPE01 PciConfigHeader; - BRIDGE_TABLE SlotBridges[MAX_BRIDGE_INDEX]; - UINTN SlotBridgeIndex; - - BridgeIndex = 0x00; - SlotBridgeIndex = 0x00; - - // - // Assumption is table is built from low bus to high bus numbers. - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - if (EFI_ERROR (Status)) { - continue; - } - - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - 0, - sizeof (PciConfigHeader) / sizeof (UINT32), - &PciConfigHeader - ); - - if (IS_PCI_P2P (&PciConfigHeader) && (BridgeIndex < MAX_BRIDGE_INDEX)) { - PciIo->GetLocation ( - PciIo, - &Bridges[BridgeIndex].PciSegment, - &Bridges[BridgeIndex].PciBus, - &Bridges[BridgeIndex].PciDevice, - &Bridges[BridgeIndex].PciFunction - ); - - Bridges[BridgeIndex].PrimaryBus = PciConfigHeader.Bridge.PrimaryBus; - - Bridges[BridgeIndex].SecondaryBus = PciConfigHeader.Bridge.SecondaryBus; - - Bridges[BridgeIndex].SubordinateBus = PciConfigHeader.Bridge.SubordinateBus; - - for (Index1 = 0; Index1 < RoutingTableEntries; Index1++) { - // - // Test whether we have found the Bridge in the slot, must be the one that directly interfaced to the board - // Once we find one, store it in the SlotBridges[] - // - if ( (RoutingTable[Index1].Slot != 0) && (Bridges[BridgeIndex].PrimaryBus == RoutingTable[Index1].Bus) - && ((Bridges[BridgeIndex].PciDevice << 3) == RoutingTable[Index1].Device)) - { - CopyMem (&SlotBridges[SlotBridgeIndex], &Bridges[BridgeIndex], sizeof (BRIDGE_TABLE)); - SlotBridgeIndex++; - - break; - } - } - - ++BridgeIndex; - } - } - - // - // Pack up Bridges by removing those useless ones - // - for (Index = 0; Index < BridgeIndex;) { - for (Index1 = 0; Index1 < SlotBridgeIndex; Index1++) { - if (((Bridges[Index].PciBus == SlotBridges[Index1].PrimaryBus) && (Bridges[Index].PciDevice == SlotBridges[Index1].PciDevice)) || - ((Bridges[Index].PciBus >= SlotBridges[Index1].SecondaryBus) && (Bridges[Index].PciBus <= SlotBridges[Index1].SubordinateBus))) - { - // - // We have found one that meets our criteria - // - Index++; - break; - } - } - - // - // This one doesn't meet criteria, pack it - // - if (Index1 >= SlotBridgeIndex) { - for (Index1 = Index; BridgeIndex > 1 && Index1 < BridgeIndex - 1; Index1++) { - CopyMem (&Bridges[Index1], &Bridges[Index1 + 1], sizeof (BRIDGE_TABLE)); - } - - BridgeIndex--; - } - } - - NumberOfBridges = BridgeIndex; - - // - // Sort bridges low to high by Secondary bus followed by subordinate bus - // - if (NumberOfBridges > 1) { - Index = 0; - do { - SortedBridgeIndex[Index] = Index; - ++Index; - } while (Index < NumberOfBridges); - - for (Index = 0; Index < NumberOfBridges - 1; Index++) { - for (Index1 = Index + 1; Index1 < NumberOfBridges; Index1++) { - if (Bridges[Index].SecondaryBus > Bridges[Index1].SecondaryBus) { - SortedBridgeIndex[Index] = Index1; - SortedBridgeIndex[Index1] = Index; - } - - if ((Bridges[Index].SecondaryBus == Bridges[Index1].SecondaryBus) && - (Bridges[Index].SubordinateBus > Bridges[Index1].SubordinateBus) - ) - { - SortedBridgeIndex[Index] = Index1; - SortedBridgeIndex[Index1] = Index; - } - } - } - } - - FreePool (HandleBuffer); - return EFI_SUCCESS; -} - -/** - Find base Bridge for device. - - @param Private Legacy BIOS Instance data - @param PciBus Input = Bus of device. - @param PciDevice Input = Device. - @param RoutingTable The platform specific routing table - @param RoutingTableEntries Number of entries in table - - @retval EFI_SUCCESS At base bus. - @retval EFI_NOT_FOUND Behind a bridge. - -**/ -EFI_STATUS -GetBaseBus ( - IN LEGACY_BIOS_INSTANCE *Private, - IN UINTN PciBus, - IN UINTN PciDevice, - IN EFI_LEGACY_IRQ_ROUTING_ENTRY *RoutingTable, - IN UINTN RoutingTableEntries - ) -{ - UINTN Index; - - for (Index = 0; Index < RoutingTableEntries; Index++) { - if ((RoutingTable[Index].Bus == PciBus) && (RoutingTable[Index].Device == (PciDevice << 3))) { - return EFI_SUCCESS; - } - } - - return EFI_NOT_FOUND; -} - -/** - Translate PIRQ through busses - - @param Private Legacy BIOS Instance data - @param PciBus Input = Bus of device. Output = Translated Bus - @param PciDevice Input = Device. Output = Translated Device - @param PciFunction Input = Function. Output = Translated Function - @param PirqIndex Input = Original PIRQ index. If single function - device then 0, otherwise 0-3. - Output = Translated Index - - @retval EFI_SUCCESS Pirq successfully translated. - @retval EFI_NOT_FOUND The device is not behind any known bridge. - -**/ -EFI_STATUS -TranslateBusPirq ( - IN LEGACY_BIOS_INSTANCE *Private, - IN OUT UINTN *PciBus, - IN OUT UINTN *PciDevice, - IN OUT UINTN *PciFunction, - IN OUT UINT8 *PirqIndex - ) -{ - /* - This routine traverses the PCI busses from base slot - and translates the PIRQ register to the appropriate one. - - Example: - - Bus 0, Device 1 is PCI-PCI bridge that all PCI slots reside on. - Primary bus# = 0 - Secondary bus # = 1 - Subordinate bus # is highest bus # behind this bus - Bus 1, Device 0 is Slot 0 and is not a bridge. - Bus 1, Device 1 is Slot 1 and is a bridge. - Slot PIRQ routing is A,B,C,D. - Primary bus # = 1 - Secondary bus # = 2 - Subordinate bus # = 5 - Bus 2, Device 6 is a bridge. It has no bridges behind it. - Primary bus # = 2 - Secondary bus # = 3 - Subordinate bus # = 3 - Bridge PIRQ routing is C,D,A,B - Bus 2, Device 7 is a bridge. It has 1 bridge behind it. - Primary bus # = 2 - Secondary bus = 4 Device 6 takes bus 2. - Subordinate bus = 5. - Bridge PIRQ routing is D,A,B,C - Bus 4, Device 2 is a bridge. It has no bridges behind it. - Primary bus # = 4 - Secondary bus # = 5 - Subordinate bus = 5 - Bridge PIRQ routing is B,C,D,A - Bus 5, Device 1 is to be programmed. - Device PIRQ routing is C,D,A,B - - -Search busses starting from slot bus for final bus >= Secondary bus and -final bus <= Subordinate bus. Assumption is bus entries increase in bus -number. -Starting PIRQ is A,B,C,D. -Bus 2, Device 7 satisfies search criteria. Rotate (A,B,C,D) left by device - 7 modulo 4 giving (D,A,B,C). -Bus 4, Device 2 satisfies search criteria. Rotate (D,A,B,C) left by 2 giving - (B,C,D,A). -No other busses match criteria. Device to be programmed is Bus 5, Device 1. -Rotate (B,C,D,A) by 1 giving C,D,A,B. Translated PIRQ is C. - -*/ - UINTN LocalBus; - UINTN LocalDevice; - UINTN BaseBus; - UINTN BaseDevice; - UINTN BaseFunction; - UINT8 LocalPirqIndex; - BOOLEAN BaseIndexFlag; - UINTN BridgeIndex; - UINTN SBridgeIndex; - - BaseIndexFlag = FALSE; - BridgeIndex = 0x00; - - LocalPirqIndex = *PirqIndex; - LocalBus = *PciBus; - LocalDevice = *PciDevice; - BaseBus = *PciBus; - BaseDevice = *PciDevice; - BaseFunction = *PciFunction; - - // - // LocalPirqIndex list PIRQs in rotated fashion - // = 0 A,B,C,D - // = 1 B,C,D,A - // = 2 C,D,A,B - // = 3 D,A,B,C - // - - for (BridgeIndex = 0; BridgeIndex < NumberOfBridges; BridgeIndex++) { - SBridgeIndex = SortedBridgeIndex[BridgeIndex]; - // - // Check if device behind this bridge - // - if ((LocalBus >= Bridges[SBridgeIndex].SecondaryBus) && (LocalBus <= Bridges[SBridgeIndex].SubordinateBus)) { - // - // If BaseIndexFlag = FALSE then have found base bridge, i.e - // bridge in slot. Save info for use by IRQ routing table. - // - if (!BaseIndexFlag) { - BaseBus = Bridges[SBridgeIndex].PciBus; - BaseDevice = Bridges[SBridgeIndex].PciDevice; - BaseFunction = Bridges[SBridgeIndex].PciFunction; - BaseIndexFlag = TRUE; - } else { - LocalPirqIndex = (UINT8)((LocalPirqIndex + (UINT8)Bridges[SBridgeIndex].PciDevice)%4); - } - - // - // Check if at device. If not get new PCI location & PIRQ - // - if (Bridges[SBridgeIndex].SecondaryBus == (UINT8)LocalBus) { - // - // Translate PIRQ - // - LocalPirqIndex = (UINT8)((LocalPirqIndex + (UINT8)(LocalDevice)) % 4); - break; - } - } - } - - // - // In case we fail to find the Bridge just above us, this is some potential error and we want to warn the user - // - if (BridgeIndex >= NumberOfBridges) { - DEBUG ((DEBUG_ERROR, "Cannot Find IRQ Routing for Bus %d, Device %d, Function %d\n", *PciBus, *PciDevice, *PciFunction)); - } - - *PirqIndex = LocalPirqIndex; - *PciBus = BaseBus; - *PciDevice = BaseDevice; - *PciFunction = BaseFunction; - - return EFI_SUCCESS; -} - -/** - Copy the $PIR table as required. - - @param Private Legacy BIOS Instance data - @param RoutingTable Pointer to IRQ routing table - @param RoutingTableEntries IRQ routing table entries - @param PirqTable Pointer to $PIR table - @param PirqTableSize Length of table - -**/ -VOID -CopyPirqTable ( - IN LEGACY_BIOS_INSTANCE *Private, - IN EFI_LEGACY_IRQ_ROUTING_ENTRY *RoutingTable, - IN UINTN RoutingTableEntries, - IN EFI_LEGACY_PIRQ_TABLE_HEADER *PirqTable, - IN UINTN PirqTableSize - ) -{ - EFI_IA32_REGISTER_SET Regs; - UINT32 Granularity; - - // - // Copy $PIR table, if it exists. - // - if (PirqTable != NULL) { - Private->LegacyRegion->UnLock ( - Private->LegacyRegion, - 0xE0000, - 0x20000, - &Granularity - ); - - Private->InternalIrqRoutingTable = RoutingTable; - Private->NumberIrqRoutingEntries = (UINT16)(RoutingTableEntries); - ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); - - Regs.X.AX = Legacy16GetTableAddress; - Regs.X.CX = (UINT16)PirqTableSize; - // - // Allocate at F segment according to PCI IRQ Routing Table Specification - // - Regs.X.BX = (UINT16)0x1; - // - // 16-byte boundary alignment requirement according to - // PCI IRQ Routing Table Specification - // - Regs.X.DX = 0x10; - Private->LegacyBios.FarCall86 ( - &Private->LegacyBios, - Private->Legacy16CallSegment, - Private->Legacy16CallOffset, - &Regs, - NULL, - 0 - ); - - Private->Legacy16Table->IrqRoutingTablePointer = (UINT32)(Regs.X.DS * 16 + Regs.X.BX); - if (Regs.X.AX != 0) { - DEBUG ((DEBUG_ERROR, "PIRQ table length insufficient - %x\n", PirqTableSize)); - } else { - DEBUG ((DEBUG_INFO, "PIRQ table in legacy region - %x\n", Private->Legacy16Table->IrqRoutingTablePointer)); - Private->Legacy16Table->IrqRoutingTableLength = (UINT32)PirqTableSize; - CopyMem ( - (VOID *)(UINTN)Private->Legacy16Table->IrqRoutingTablePointer, - PirqTable, - PirqTableSize - ); - } - - Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate); - Private->LegacyRegion->Lock ( - Private->LegacyRegion, - 0xE0000, - 0x20000, - &Granularity - ); - } - - Private->PciInterruptLine = TRUE; - mHandleCount = 0; -} - -/** - Dump EFI_LEGACY_INSTALL_PCI_HANDLER structure information. - - @param PciHandle The pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure - -**/ -VOID -DumpPciHandle ( - IN EFI_LEGACY_INSTALL_PCI_HANDLER *PciHandle - ) -{ - DEBUG ((DEBUG_INFO, "PciBus - %02x\n", (UINTN)PciHandle->PciBus)); - DEBUG ((DEBUG_INFO, "PciDeviceFun - %02x\n", (UINTN)PciHandle->PciDeviceFun)); - DEBUG ((DEBUG_INFO, "PciSegment - %02x\n", (UINTN)PciHandle->PciSegment)); - DEBUG ((DEBUG_INFO, "PciClass - %02x\n", (UINTN)PciHandle->PciClass)); - DEBUG ((DEBUG_INFO, "PciSubclass - %02x\n", (UINTN)PciHandle->PciSubclass)); - DEBUG ((DEBUG_INFO, "PciInterface - %02x\n", (UINTN)PciHandle->PciInterface)); - - DEBUG ((DEBUG_INFO, "PrimaryIrq - %02x\n", (UINTN)PciHandle->PrimaryIrq)); - DEBUG ((DEBUG_INFO, "PrimaryReserved - %02x\n", (UINTN)PciHandle->PrimaryReserved)); - DEBUG ((DEBUG_INFO, "PrimaryControl - %04x\n", (UINTN)PciHandle->PrimaryControl)); - DEBUG ((DEBUG_INFO, "PrimaryBase - %04x\n", (UINTN)PciHandle->PrimaryBase)); - DEBUG ((DEBUG_INFO, "PrimaryBusMaster - %04x\n", (UINTN)PciHandle->PrimaryBusMaster)); - - DEBUG ((DEBUG_INFO, "SecondaryIrq - %02x\n", (UINTN)PciHandle->SecondaryIrq)); - DEBUG ((DEBUG_INFO, "SecondaryReserved - %02x\n", (UINTN)PciHandle->SecondaryReserved)); - DEBUG ((DEBUG_INFO, "SecondaryControl - %04x\n", (UINTN)PciHandle->SecondaryControl)); - DEBUG ((DEBUG_INFO, "SecondaryBase - %04x\n", (UINTN)PciHandle->SecondaryBase)); - DEBUG ((DEBUG_INFO, "SecondaryBusMaster - %04x\n", (UINTN)PciHandle->SecondaryBusMaster)); - return; -} - -/** - Copy the $PIR table as required. - - @param Private Legacy BIOS Instance data - @param PciIo Pointer to PCI_IO protocol - @param PciIrq Pci IRQ number - @param PciConfigHeader Type00 Pci configuration header - -**/ -VOID -InstallLegacyIrqHandler ( - IN LEGACY_BIOS_INSTANCE *Private, - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT8 PciIrq, - IN PCI_TYPE00 *PciConfigHeader - ) -{ - EFI_IA32_REGISTER_SET Regs; - UINT16 LegMask; - UINTN PciSegment; - UINTN PciBus; - UINTN PciDevice; - UINTN PciFunction; - EFI_LEGACY_8259_PROTOCOL *Legacy8259; - UINT16 PrimaryMaster; - UINT16 SecondaryMaster; - UINTN TempData; - UINTN RegisterAddress; - UINT32 Granularity; - - PrimaryMaster = 0; - SecondaryMaster = 0; - Legacy8259 = Private->Legacy8259; - // - // Disable interrupt in PIC, in case shared, to prevent an - // interrupt from occurring. - // - Legacy8259->GetMask ( - Legacy8259, - &LegMask, - NULL, - NULL, - NULL - ); - - LegMask = (UINT16)(LegMask | (UINT16)(1 << PciIrq)); - - Legacy8259->SetMask ( - Legacy8259, - &LegMask, - NULL, - NULL, - NULL - ); - - PciIo->GetLocation ( - PciIo, - &PciSegment, - &PciBus, - &PciDevice, - &PciFunction - ); - Private->IntThunk->PciHandler.PciBus = (UINT8)PciBus; - Private->IntThunk->PciHandler.PciDeviceFun = (UINT8)((PciDevice << 3) + PciFunction); - Private->IntThunk->PciHandler.PciSegment = (UINT8)PciSegment; - Private->IntThunk->PciHandler.PciClass = PciConfigHeader->Hdr.ClassCode[2]; - Private->IntThunk->PciHandler.PciSubclass = PciConfigHeader->Hdr.ClassCode[1]; - Private->IntThunk->PciHandler.PciInterface = PciConfigHeader->Hdr.ClassCode[0]; - - // - // Use native mode base address registers in two cases: - // 1. Programming Interface (PI) register indicates Primary Controller is - // in native mode OR - // 2. PCI device Sub Class Code is not IDE - // - Private->IntThunk->PciHandler.PrimaryBusMaster = (UINT16)(PciConfigHeader->Device.Bar[4] & 0xfffc); - if (((PciConfigHeader->Hdr.ClassCode[0] & 0x01) != 0) || (PciConfigHeader->Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE)) { - Private->IntThunk->PciHandler.PrimaryIrq = PciIrq; - Private->IntThunk->PciHandler.PrimaryBase = (UINT16)(PciConfigHeader->Device.Bar[0] & 0xfffc); - Private->IntThunk->PciHandler.PrimaryControl = (UINT16)((PciConfigHeader->Device.Bar[1] & 0xfffc) + 2); - } else { - Private->IntThunk->PciHandler.PrimaryIrq = 14; - Private->IntThunk->PciHandler.PrimaryBase = 0x1f0; - Private->IntThunk->PciHandler.PrimaryControl = 0x3f6; - } - - // - // Secondary controller data - // - if (Private->IntThunk->PciHandler.PrimaryBusMaster != 0) { - Private->IntThunk->PciHandler.SecondaryBusMaster = (UINT16)((PciConfigHeader->Device.Bar[4] & 0xfffc) + 8); - PrimaryMaster = (UINT16)(Private->IntThunk->PciHandler.PrimaryBusMaster + 2); - SecondaryMaster = (UINT16)(Private->IntThunk->PciHandler.SecondaryBusMaster + 2); - - // - // Clear pending interrupts in Bus Master registers - // - IoWrite16 (PrimaryMaster, 0x04); - IoWrite16 (SecondaryMaster, 0x04); - } - - // - // Use native mode base address registers in two cases: - // 1. Programming Interface (PI) register indicates Secondary Controller is - // in native mode OR - // 2. PCI device Sub Class Code is not IDE - // - if (((PciConfigHeader->Hdr.ClassCode[0] & 0x04) != 0) || (PciConfigHeader->Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE)) { - Private->IntThunk->PciHandler.SecondaryIrq = PciIrq; - Private->IntThunk->PciHandler.SecondaryBase = (UINT16)(PciConfigHeader->Device.Bar[2] & 0xfffc); - Private->IntThunk->PciHandler.SecondaryControl = (UINT16)((PciConfigHeader->Device.Bar[3] & 0xfffc) + 2); - } else { - Private->IntThunk->PciHandler.SecondaryIrq = 15; - Private->IntThunk->PciHandler.SecondaryBase = 0x170; - Private->IntThunk->PciHandler.SecondaryControl = 0x376; - } - - // - // Clear pending interrupts in IDE Command Block Status reg before we - // Thunk to CSM16 below. Don't want a pending Interrupt before we - // install the handlers as wierd corruption would occur and hang system. - // - // - // Read IDE CMD blk status reg to clear out any pending interrupts. - // Do here for Primary and Secondary IDE channels - // - RegisterAddress = (UINT16)Private->IntThunk->PciHandler.PrimaryBase + 0x07; - IoRead8 (RegisterAddress); - RegisterAddress = (UINT16)Private->IntThunk->PciHandler.SecondaryBase + 0x07; - IoRead8 (RegisterAddress); - - Private->IntThunk->PciHandler.PrimaryReserved = 0; - Private->IntThunk->PciHandler.SecondaryReserved = 0; - Private->LegacyRegion->UnLock ( - Private->LegacyRegion, - 0xE0000, - 0x20000, - &Granularity - ); - - Regs.X.AX = Legacy16InstallPciHandler; - TempData = (UINTN)&Private->IntThunk->PciHandler; - Regs.X.ES = EFI_SEGMENT ((UINT32)TempData); - Regs.X.BX = EFI_OFFSET ((UINT32)TempData); - - DumpPciHandle (&Private->IntThunk->PciHandler); - - Private->LegacyBios.FarCall86 ( - &Private->LegacyBios, - Private->Legacy16CallSegment, - Private->Legacy16CallOffset, - &Regs, - NULL, - 0 - ); - - Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate); - Private->LegacyRegion->Lock ( - Private->LegacyRegion, - 0xE0000, - 0x20000, - &Granularity - ); -} - -/** - Program the interrupt routing register in all the PCI devices. On a PC AT system - this register contains the 8259 IRQ vector that matches its PCI interrupt. - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS Succeed. - @retval EFI_ALREADY_STARTED All PCI devices have been processed. - -**/ -EFI_STATUS -PciProgramAllInterruptLineRegisters ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_LEGACY_8259_PROTOCOL *Legacy8259; - EFI_LEGACY_INTERRUPT_PROTOCOL *LegacyInterrupt; - EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform; - UINT8 InterruptPin; - UINTN Index; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN MassStorageHandleCount; - EFI_HANDLE *MassStorageHandleBuffer; - UINTN MassStorageHandleIndex; - UINT8 PciIrq; - UINT16 Command; - UINTN PciSegment; - UINTN PciBus; - UINTN PciDevice; - UINTN PciFunction; - EFI_LEGACY_IRQ_ROUTING_ENTRY *RoutingTable; - UINTN RoutingTableEntries; - UINT16 LegMask; - UINT16 LegEdgeLevel; - PCI_TYPE00 PciConfigHeader; - EFI_LEGACY_PIRQ_TABLE_HEADER *PirqTable; - UINTN PirqTableSize; - UINTN Flags; - HDD_INFO *HddInfo; - UINT64 Supports; - - // - // Note - This routine use to return immediately if Private->PciInterruptLine - // was true. Routine changed since resets etc can cause not all - // PciIo protocols to be registered the first time through. - // New algorithm is to do the copy $PIR table on first pass and save - // HandleCount on first pass. If subsequent passes LocateHandleBuffer gives - // a larger handle count then proceed with body of function else return - // EFI_ALREADY_STARTED. In addition check if PCI device InterruptLine != 0. - // If zero then function unprogrammed else skip function. - // - Legacy8259 = Private->Legacy8259; - LegacyInterrupt = Private->LegacyInterrupt; - LegacyBiosPlatform = Private->LegacyBiosPlatform; - - LegacyBiosPlatform->GetRoutingTable ( - Private->LegacyBiosPlatform, - (VOID *)&RoutingTable, - &RoutingTableEntries, - (VOID *)&PirqTable, - &PirqTableSize, - NULL, - NULL - ); - CreateBridgeTable (RoutingTable, RoutingTableEntries); - - if (!Private->PciInterruptLine) { - CopyPirqTable ( - Private, - RoutingTable, - RoutingTableEntries, - PirqTable, - PirqTableSize - ); - } - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - if (HandleCount == mHandleCount) { - FreePool (HandleBuffer); - return EFI_ALREADY_STARTED; - } - - if (mHandleCount == 0x00) { - mHandleCount = HandleCount; - } - - for (Index = 0; Index < HandleCount; Index++) { - // - // If VGA then only do VGA to allow drives fore time to spin up - // otherwise assign PCI IRQs to all potential devices. - // - if ((mVgaInstallationInProgress) && (HandleBuffer[Index] != mVgaHandle)) { - continue; - } else { - // - // Force code to go through all handles next time called if video. - // This will catch case where HandleCount doesn't change but want - // to get drive info etc. - // - mHandleCount = 0x00; - } - - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - ASSERT_EFI_ERROR (Status); - - // - // Test whether the device can be enabled or not. - // If it can't be enabled, then just skip it to avoid further operation. - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - 0, - sizeof (PciConfigHeader) / sizeof (UINT32), - &PciConfigHeader - ); - Command = PciConfigHeader.Hdr.Command; - - // - // Note PciIo->Attributes does not program the PCI command register - // - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - if (!EFI_ERROR (Status)) { - Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - } - - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x04, 1, &Command); - - if (EFI_ERROR (Status)) { - continue; - } - - InterruptPin = PciConfigHeader.Device.InterruptPin; - - if ((InterruptPin != 0) && (PciConfigHeader.Device.InterruptLine == PCI_INT_LINE_UNKNOWN)) { - PciIo->GetLocation ( - PciIo, - &PciSegment, - &PciBus, - &PciDevice, - &PciFunction - ); - // - // Translate PIRQ index back thru busses to slot bus with InterruptPin - // zero based - // - InterruptPin -= 1; - - Status = GetBaseBus ( - Private, - PciBus, - PciDevice, - RoutingTable, - RoutingTableEntries - ); - - if (Status == EFI_NOT_FOUND) { - TranslateBusPirq ( - Private, - &PciBus, - &PciDevice, - &PciFunction, - &InterruptPin - ); - } - - // - // Translate InterruptPin(0-3) into PIRQ - // - Status = LegacyBiosPlatform->TranslatePirq ( - LegacyBiosPlatform, - PciBus, - (PciDevice << 3), - PciFunction, - &InterruptPin, - &PciIrq - ); - // - // TranslatePirq() should never fail or we are in trouble - // If it does return failure status, check your PIRQ routing table to see if some item is missing or incorrect - // - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Translate Pirq Failed - Status = %r\n ", Status)); - continue; - } - - LegacyInterrupt->WritePirq ( - LegacyInterrupt, - InterruptPin, - PciIrq - ); - - // - // Check if device has an OPROM associated with it. - // If not invoke special 16-bit function, to allow 16-bit - // code to install an interrupt handler. - // - Status = LegacyBiosCheckPciRom ( - &Private->LegacyBios, - HandleBuffer[Index], - NULL, - NULL, - &Flags - ); - if ((EFI_ERROR (Status)) && (PciConfigHeader.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE)) { - // - // Device has no OPROM associated with it and is a mass storage - // device. It needs to have an PCI IRQ handler installed. To - // correctly install the handler we need to insure device is - // connected. The device may just have register itself but not - // been connected. Re-read PCI config space after as it can - // change - // - // - // Get IDE Handle. If matches handle then skip ConnectController - // since ConnectController may force native mode and we don't - // want that for primary IDE controller - // - MassStorageHandleCount = 0; - MassStorageHandleBuffer = NULL; - LegacyBiosPlatform->GetPlatformHandle ( - Private->LegacyBiosPlatform, - EfiGetPlatformIdeHandle, - 0, - &MassStorageHandleBuffer, - &MassStorageHandleCount, - NULL - ); - - HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0]; - - LegacyBiosBuildIdeData (Private, &HddInfo, 0); - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - 0, - sizeof (PciConfigHeader) / sizeof (UINT32), - &PciConfigHeader - ); - - for (MassStorageHandleIndex = 0; MassStorageHandleIndex < MassStorageHandleCount; MassStorageHandleIndex++) { - if (MassStorageHandleBuffer[MassStorageHandleIndex] == HandleBuffer[Index]) { - // - // InstallLegacyIrqHandler according to Platform requirement - // - InstallLegacyIrqHandler ( - Private, - PciIo, - PciIrq, - &PciConfigHeader - ); - break; - } - } - } - - // - // Write InterruptPin and enable 8259. - // - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint8, - 0x3c, - 1, - &PciIrq - ); - Private->IntThunk->EfiToLegacy16BootTable.PciIrqMask = (UINT16)(Private->IntThunk->EfiToLegacy16BootTable.PciIrqMask | (UINT16)(1 << PciIrq)); - - Legacy8259->GetMask ( - Legacy8259, - &LegMask, - &LegEdgeLevel, - NULL, - NULL - ); - - LegMask = (UINT16)(LegMask & (UINT16) ~(1 << PciIrq)); - LegEdgeLevel = (UINT16)(LegEdgeLevel | (UINT16)(1 << PciIrq)); - Legacy8259->SetMask ( - Legacy8259, - &LegMask, - &LegEdgeLevel, - NULL, - NULL - ); - } - } - - FreePool (HandleBuffer); - return EFI_SUCCESS; -} - -/** - Find & verify PnP Expansion header in ROM image - - @param Private Protocol instance pointer. - @param FirstHeader 1 = Find first header, 0 = Find successive headers - @param PnpPtr Input Rom start if FirstHeader =1, Current Header - otherwise Output Next header, if it exists - - @retval EFI_SUCCESS Next Header found at BasePnpPtr - @retval EFI_NOT_FOUND No more headers - -**/ -EFI_STATUS -FindNextPnpExpansionHeader ( - IN LEGACY_BIOS_INSTANCE *Private, - IN BOOLEAN FirstHeader, - IN OUT LEGACY_PNP_EXPANSION_HEADER **PnpPtr - - ) -{ - UINTN TempData; - LEGACY_PNP_EXPANSION_HEADER *LocalPnpPtr; - - LocalPnpPtr = *PnpPtr; - if (FirstHeader == FIRST_INSTANCE) { - mBasePnpPtr = LocalPnpPtr; - mBbsRomSegment = (UINT16)((UINTN)mBasePnpPtr >> 4); - // - // Offset 0x1a gives offset to PnP expansion header for the first - // instance, there after the structure gives the offset to the next - // structure - // - LocalPnpPtr = (LEGACY_PNP_EXPANSION_HEADER *)((UINT8 *)LocalPnpPtr + 0x1a); - TempData = (*((UINT16 *)LocalPnpPtr)); - } else { - TempData = (UINT16)LocalPnpPtr->NextHeader; - } - - LocalPnpPtr = (LEGACY_PNP_EXPANSION_HEADER *)(((UINT8 *)mBasePnpPtr + TempData)); - - // - // Search for PnP table in Shadowed ROM - // - *PnpPtr = LocalPnpPtr; - if (*(UINT32 *)LocalPnpPtr == SIGNATURE_32 ('$', 'P', 'n', 'P')) { - return EFI_SUCCESS; - } else { - return EFI_NOT_FOUND; - } -} - -/** - Update list of Bev or BCV table entries. - - @param Private Protocol instance pointer. - @param RomStart Table of ROM start address in RAM/ROM. PciIo _ - Handle to PCI IO for this device - @param PciIo Instance of PCI I/O Protocol - - @retval EFI_SUCCESS Always should succeed. - -**/ -EFI_STATUS -UpdateBevBcvTable ( - IN LEGACY_BIOS_INSTANCE *Private, - IN EFI_LEGACY_EXPANSION_ROM_HEADER *RomStart, - IN EFI_PCI_IO_PROTOCOL *PciIo - ) -{ - VOID *RomEnd; - BBS_TABLE *BbsTable; - UINTN BbsIndex; - EFI_LEGACY_EXPANSION_ROM_HEADER *PciPtr; - LEGACY_PNP_EXPANSION_HEADER *PnpPtr; - BOOLEAN Instance; - EFI_STATUS Status; - UINTN Segment; - UINTN Bus; - UINTN Device; - UINTN Function; - UINT8 Class; - UINT16 DeviceType; - - Segment = 0; - Bus = 0; - Device = 0; - Function = 0; - Class = 0; - DeviceType = BBS_UNKNOWN; - - // - // Skip floppy and 2*onboard IDE controller entries(Master/Slave per - // controller). - // - BbsIndex = Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries; - - BbsTable = (BBS_TABLE *)(UINTN)Private->IntThunk->EfiToLegacy16BootTable.BbsTable; - PnpPtr = (LEGACY_PNP_EXPANSION_HEADER *)RomStart; - PciPtr = (EFI_LEGACY_EXPANSION_ROM_HEADER *)RomStart; - - RomEnd = (VOID *)(PciPtr->Size512 * 512 + (UINTN)PciPtr); - Instance = FIRST_INSTANCE; - // - // OPROMs like PXE may not be tied to a piece of hardware and thus - // don't have a PciIo associated with them - // - if (PciIo != NULL) { - PciIo->GetLocation ( - PciIo, - &Segment, - &Bus, - &Device, - &Function - ); - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - 0x0b, - 1, - &Class - ); - - if (Class == PCI_CLASS_MASS_STORAGE) { - DeviceType = BBS_HARDDISK; - } else { - if (Class == PCI_CLASS_NETWORK) { - DeviceType = BBS_EMBED_NETWORK; - } - } - } - - while (TRUE) { - Status = FindNextPnpExpansionHeader (Private, Instance, &PnpPtr); - Instance = NOT_FIRST_INSTANCE; - if (EFI_ERROR (Status)) { - break; - } - - // - // There can be additional $PnP headers within the OPROM. - // Example: SCSI can have one per drive. - // - BbsTable[BbsIndex].BootPriority = BBS_UNPRIORITIZED_ENTRY; - BbsTable[BbsIndex].DeviceType = DeviceType; - BbsTable[BbsIndex].Bus = (UINT32)Bus; - BbsTable[BbsIndex].Device = (UINT32)Device; - BbsTable[BbsIndex].Function = (UINT32)Function; - BbsTable[BbsIndex].StatusFlags.OldPosition = 0; - BbsTable[BbsIndex].StatusFlags.Reserved1 = 0; - BbsTable[BbsIndex].StatusFlags.Enabled = 0; - BbsTable[BbsIndex].StatusFlags.Failed = 0; - BbsTable[BbsIndex].StatusFlags.MediaPresent = 0; - BbsTable[BbsIndex].StatusFlags.Reserved2 = 0; - BbsTable[BbsIndex].Class = PnpPtr->Class; - BbsTable[BbsIndex].SubClass = PnpPtr->SubClass; - BbsTable[BbsIndex].DescStringOffset = PnpPtr->ProductNamePointer; - BbsTable[BbsIndex].DescStringSegment = mBbsRomSegment; - BbsTable[BbsIndex].MfgStringOffset = PnpPtr->MfgPointer; - BbsTable[BbsIndex].MfgStringSegment = mBbsRomSegment; - BbsTable[BbsIndex].BootHandlerSegment = mBbsRomSegment; - - // - // Have seen case where PXE base code have PnP expansion ROM - // header but no Bcv or Bev vectors. - // - if (PnpPtr->Bcv != 0) { - BbsTable[BbsIndex].BootHandlerOffset = PnpPtr->Bcv; - ++BbsIndex; - } - - if (PnpPtr->Bev != 0) { - BbsTable[BbsIndex].BootHandlerOffset = PnpPtr->Bev; - BbsTable[BbsIndex].DeviceType = BBS_BEV_DEVICE; - ++BbsIndex; - } - - if ((PnpPtr == (LEGACY_PNP_EXPANSION_HEADER *)PciPtr) || (PnpPtr > (LEGACY_PNP_EXPANSION_HEADER *)RomEnd)) { - break; - } - } - - BbsTable[BbsIndex].BootPriority = BBS_IGNORE_ENTRY; - Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries = (UINT32)BbsIndex; - return EFI_SUCCESS; -} - -/** - Shadow all the PCI legacy ROMs. Use data from the Legacy BIOS Protocol - to chose the order. Skip any devices that have already have legacy - BIOS run. - - @param Private Protocol instance pointer. - - @retval EFI_SUCCESS Succeed. - @retval EFI_UNSUPPORTED Cannot get VGA device handle. - -**/ -EFI_STATUS -PciShadowRoms ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - PCI_TYPE00 Pci; - UINTN Index; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - EFI_HANDLE VgaHandle; - EFI_HANDLE FirstHandle; - VOID **RomStart; - UINTN Flags; - PCI_TYPE00 PciConfigHeader; - UINT16 *Command; - UINT64 Supports; - - // - // Make the VGA device first - // - Status = Private->LegacyBiosPlatform->GetPlatformHandle ( - Private->LegacyBiosPlatform, - EfiGetPlatformVgaHandle, - 0, - &HandleBuffer, - &HandleCount, - NULL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - VgaHandle = HandleBuffer[0]; - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Place the VGA handle as first. - // - for (Index = 0; Index < HandleCount; Index++) { - if (HandleBuffer[Index] == VgaHandle) { - FirstHandle = HandleBuffer[0]; - HandleBuffer[0] = HandleBuffer[Index]; - HandleBuffer[Index] = FirstHandle; - break; - } - } - - // - // Allocate memory to save Command WORD from each device. We do this - // to restore devices to same state as EFI after switching to legacy. - // - Command = (UINT16 *)AllocatePool ( - sizeof (UINT16) * (HandleCount + 1) - ); - if (NULL == Command) { - FreePool (HandleBuffer); - return EFI_OUT_OF_RESOURCES; - } - - // - // Disconnect all EFI devices first. This covers cases where alegacy BIOS - // may control multiple PCI devices. - // - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - ASSERT_EFI_ERROR (Status); - - // - // Save command register for "connect" loop - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - 0, - sizeof (PciConfigHeader) / sizeof (UINT32), - &PciConfigHeader - ); - Command[Index] = PciConfigHeader.Hdr.Command; - // - // Skip any device that already has a legacy ROM run - // - Status = IsLegacyRom (HandleBuffer[Index]); - if (!EFI_ERROR (Status)) { - continue; - } - - // - // Stop EFI Drivers with oprom. - // - gBS->DisconnectController ( - HandleBuffer[Index], - NULL, - NULL - ); - } - - // - // For every device that has not had a legacy ROM started. Start a legacy ROM. - // - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - - ASSERT_EFI_ERROR (Status); - - // - // Here make sure if one VGA have been shadowed, - // then wil not shadowed another one. - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - 0, - sizeof (Pci) / sizeof (UINT32), - &Pci - ); - - // - // Only one Video OPROM can be given control in BIOS phase. If there are multiple Video devices, - // one will work in legacy mode (OPROM will be given control) and - // other Video devices will work in native mode (OS driver will handle these devices). - // - if (IS_PCI_DISPLAY (&Pci) && (Index != 0)) { - continue; - } - - // - // Skip any device that already has a legacy ROM run - // - Status = IsLegacyRom (HandleBuffer[Index]); - if (!EFI_ERROR (Status)) { - continue; - } - - // - // If legacy VBIOS Oprom has not been dispatched before, install legacy VBIOS here. - // - if (IS_PCI_DISPLAY (&Pci) && (Index == 0)) { - Status = LegacyBiosInstallVgaRom (Private); - // - // A return status of EFI_NOT_FOUND is considered valid (No EFI - // driver is controlling video). - // - ASSERT ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)); - continue; - } - - // - // Install legacy ROM - // - Status = LegacyBiosInstallPciRom ( - &Private->LegacyBios, - HandleBuffer[Index], - NULL, - &Flags, - NULL, - NULL, - (VOID **)&RomStart, - NULL - ); - if (EFI_ERROR (Status)) { - if (!((Status == EFI_UNSUPPORTED) && (Flags == NO_ROM))) { - continue; - } - } - - // - // Restore Command register so legacy has same devices enabled or disabled - // as EFI. - // If Flags = NO_ROM use command register as is. This covers the - // following cases: - // Device has no ROMs associated with it. - // Device has ROM associated with it but was already - // installed. - // = ROM_FOUND but not VALID_LEGACY_ROM, disable it. - // = ROM_FOUND and VALID_LEGACY_ROM, enable it. - // - if ((Flags & ROM_FOUND) == ROM_FOUND) { - if ((Flags & VALID_LEGACY_ROM) == 0) { - Command[Index] = 0; - } else { - // - // For several VGAs, only one of them can be enabled. - // - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - if (!EFI_ERROR (Status)) { - Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - } - - if (!EFI_ERROR (Status)) { - Command[Index] = 0x1f; - } - } - } - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - 0x04, - 1, - &Command[Index] - ); - } - - FreePool (Command); - FreePool (HandleBuffer); - return EFI_SUCCESS; -} - -/** - Test to see if a legacy PCI ROM exists for this device. Optionally return - the Legacy ROM instance for this PCI device. - - @param This Protocol instance pointer. - @param PciHandle The PCI PC-AT OPROM from this devices ROM BAR will - be loaded - @param RomImage Return the legacy PCI ROM for this device - @param RomSize Size of ROM Image - @param Flags Indicates if ROM found and if PC-AT. - - @retval EFI_SUCCESS Legacy Option ROM available for this device - @retval EFI_UNSUPPORTED Legacy Option ROM not supported. - -**/ -EFI_STATUS -EFIAPI -LegacyBiosCheckPciRom ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN EFI_HANDLE PciHandle, - OUT VOID **RomImage OPTIONAL, - OUT UINTN *RomSize OPTIONAL, - OUT UINTN *Flags - ) -{ - return LegacyBiosCheckPciRomEx ( - This, - PciHandle, - RomImage, - RomSize, - NULL, - Flags, - NULL, - NULL - ); -} - -/** - - Routine Description: - Test to see if a legacy PCI ROM exists for this device. Optionally return - the Legacy ROM instance for this PCI device. - - @param[in] This Protocol instance pointer. - @param[in] PciHandle The PCI PC-AT OPROM from this devices ROM BAR will be loaded - @param[out] RomImage Return the legacy PCI ROM for this device - @param[out] RomSize Size of ROM Image - @param[out] RuntimeImageLength Runtime size of ROM Image - @param[out] Flags Indicates if ROM found and if PC-AT. - @param[out] OpromRevision Revision of the PCI Rom - @param[out] ConfigUtilityCodeHeaderPointer of Configuration Utility Code Header - - @return EFI_SUCCESS Legacy Option ROM available for this device - @return EFI_ALREADY_STARTED This device is already managed by its Oprom - @return EFI_UNSUPPORTED Legacy Option ROM not supported. - -**/ -EFI_STATUS -LegacyBiosCheckPciRomEx ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN EFI_HANDLE PciHandle, - OUT VOID **RomImage OPTIONAL, - OUT UINTN *RomSize OPTIONAL, - OUT UINTN *RuntimeImageLength OPTIONAL, - OUT UINTN *Flags OPTIONAL, - OUT UINT8 *OpromRevision OPTIONAL, - OUT VOID **ConfigUtilityCodeHeader OPTIONAL - ) -{ - EFI_STATUS Status; - LEGACY_BIOS_INSTANCE *Private; - EFI_PCI_IO_PROTOCOL *PciIo; - UINTN LocalRomSize; - VOID *LocalRomImage; - PCI_TYPE00 PciConfigHeader; - VOID *LocalConfigUtilityCodeHeader; - - LocalConfigUtilityCodeHeader = NULL; - *Flags = NO_ROM; - Status = gBS->HandleProtocol ( - PciHandle, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // See if the option ROM for PciHandle has already been executed - // - Status = IsLegacyRom (PciHandle); - if (!EFI_ERROR (Status)) { - *Flags |= (UINTN)(ROM_FOUND | VALID_LEGACY_ROM); - return EFI_SUCCESS; - } - - // - // Check for PCI ROM Bar - // - LocalRomSize = (UINTN)PciIo->RomSize; - LocalRomImage = PciIo->RomImage; - if (LocalRomSize != 0) { - *Flags |= ROM_FOUND; - } - - // - // PCI specification states you should check VendorId and Device Id. - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - 0, - sizeof (PciConfigHeader) / sizeof (UINT32), - &PciConfigHeader - ); - - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - Status = GetPciLegacyRom ( - Private->Csm16PciInterfaceVersion, - PciConfigHeader.Hdr.VendorId, - PciConfigHeader.Hdr.DeviceId, - &LocalRomImage, - &LocalRomSize, - RuntimeImageLength, - OpromRevision, - &LocalConfigUtilityCodeHeader - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - *Flags |= VALID_LEGACY_ROM; - - // - // See if Configuration Utility Code Header valid - // - if (LocalConfigUtilityCodeHeader != NULL) { - *Flags |= ROM_WITH_CONFIG; - } - - if (ConfigUtilityCodeHeader != NULL) { - *ConfigUtilityCodeHeader = LocalConfigUtilityCodeHeader; - } - - if (RomImage != NULL) { - *RomImage = LocalRomImage; - } - - if (RomSize != NULL) { - *RomSize = LocalRomSize; - } - - return EFI_SUCCESS; -} - -/** - Load a legacy PC-AT OPROM on the PciHandle device. Return information - about how many disks were added by the OPROM and the shadow address and - size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C: - - @retval EFI_SUCCESS Legacy ROM loaded for this device - @retval EFI_NOT_FOUND No PS2 Keyboard found - -**/ -EFI_STATUS -EnablePs2Keyboard ( - VOID - ) -{ - EFI_STATUS Status; - EFI_HANDLE *HandleBuffer; - UINTN HandleCount; - EFI_ISA_IO_PROTOCOL *IsaIo; - UINTN Index; - - // - // Get SimpleTextIn and find PS2 controller - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleTextInProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - for (Index = 0; Index < HandleCount; Index++) { - // - // Open the IO Abstraction(s) needed to perform the supported test - // - Status = gBS->OpenProtocol ( - HandleBuffer[Index], - &gEfiIsaIoProtocolGuid, - (VOID **)&IsaIo, - NULL, - HandleBuffer[Index], - EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - ); - - if (!EFI_ERROR (Status)) { - // - // Use the ISA I/O Protocol to see if Controller is the Keyboard - // controller - // - if ((IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x303)) || (IsaIo->ResourceList->Device.UID != 0)) { - Status = EFI_UNSUPPORTED; - } - - gBS->CloseProtocol ( - HandleBuffer[Index], - &gEfiIsaIoProtocolGuid, - NULL, - HandleBuffer[Index] - ); - } - - if (!EFI_ERROR (Status)) { - gBS->ConnectController (HandleBuffer[Index], NULL, NULL, FALSE); - } - } - - FreePool (HandleBuffer); - return EFI_SUCCESS; -} - -/** - Load a legacy PC-AT OpROM for VGA controller. - - @param Private Driver private data. - - @retval EFI_SUCCESS Legacy ROM successfully installed for this device. - @retval EFI_DEVICE_ERROR No VGA device handle found, or native EFI video - driver cannot be successfully disconnected, or VGA - thunk driver cannot be successfully connected. - -**/ -EFI_STATUS -LegacyBiosInstallVgaRom ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - EFI_STATUS Status; - EFI_HANDLE VgaHandle; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - EFI_HANDLE *ConnectHandleBuffer; - EFI_PCI_IO_PROTOCOL *PciIo; - PCI_TYPE00 PciConfigHeader; - UINT64 Supports; - EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; - UINTN EntryCount; - UINTN Index; - VOID *Interface; - - // - // EfiLegacyBiosGuild attached to a device implies that there is a legacy - // BIOS associated with that device. - // - // There are 3 cases to consider. - // Case 1: No EFI driver is controlling the video. - // Action: Return EFI_SUCCESS from DisconnectController, search - // video thunk driver, and connect it. - // Case 2: EFI driver is controlling the video and EfiLegacyBiosGuid is - // not on the image handle. - // Action: Disconnect EFI driver. - // ConnectController for video thunk - // Case 3: EFI driver is controlling the video and EfiLegacyBiosGuid is - // on the image handle. - // Action: Do nothing and set Private->VgaInstalled = TRUE. - // Then this routine is not called any more. - // - // - // Get the VGA device. - // - Status = Private->LegacyBiosPlatform->GetPlatformHandle ( - Private->LegacyBiosPlatform, - EfiGetPlatformVgaHandle, - 0, - &HandleBuffer, - &HandleCount, - NULL - ); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - VgaHandle = HandleBuffer[0]; - - // - // Check whether video thunk driver already starts. - // - Status = gBS->OpenProtocolInformation ( - VgaHandle, - &gEfiPciIoProtocolGuid, - &OpenInfoBuffer, - &EntryCount - ); - if (EFI_ERROR (Status)) { - return Status; - } - - for (Index = 0; Index < EntryCount; Index++) { - if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { - Status = gBS->HandleProtocol ( - OpenInfoBuffer[Index].AgentHandle, - &gEfiLegacyBiosGuid, - (VOID **)&Interface - ); - if (!EFI_ERROR (Status)) { - // - // This should be video thunk driver which is managing video device - // So it need not start again - // - DEBUG ((DEBUG_INFO, "Video thunk driver already start! Return!\n")); - Private->VgaInstalled = TRUE; - return EFI_SUCCESS; - } - } - } - - // - // Kick off the native EFI driver - // - Status = gBS->DisconnectController ( - VgaHandle, - NULL, - NULL - ); - if (EFI_ERROR (Status)) { - if (Status != EFI_NOT_FOUND) { - return EFI_DEVICE_ERROR; - } else { - return Status; - } - } - - // - // Find all the Thunk Driver - // - HandleBuffer = NULL; - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiLegacyBiosGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - ASSERT_EFI_ERROR (Status); - ConnectHandleBuffer = (EFI_HANDLE *)AllocatePool (sizeof (EFI_HANDLE) * (HandleCount + 1)); - ASSERT (ConnectHandleBuffer != NULL); - - CopyMem ( - ConnectHandleBuffer, - HandleBuffer, - sizeof (EFI_HANDLE) * HandleCount - ); - ConnectHandleBuffer[HandleCount] = NULL; - - FreePool (HandleBuffer); - - // - // Enable the device and make sure VGA cycles are being forwarded to this VGA device - // - Status = gBS->HandleProtocol ( - VgaHandle, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - ASSERT_EFI_ERROR (Status); - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - 0, - sizeof (PciConfigHeader) / sizeof (UINT32), - &PciConfigHeader - ); - - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - if (!EFI_ERROR (Status)) { - Supports &= (UINT64)(EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | \ - EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16); - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - } - - if (Status == EFI_SUCCESS) { - Private->VgaInstalled = TRUE; - - // - // Attach the VGA thunk driver. - // Assume the video is installed. This prevents potential of infinite recursion. - // - Status = gBS->ConnectController ( - VgaHandle, - ConnectHandleBuffer, - NULL, - TRUE - ); - } - - FreePool (ConnectHandleBuffer); - - if (EFI_ERROR (Status)) { - Private->VgaInstalled = FALSE; - - // - // Reconnect the EFI VGA driver. - // - gBS->ConnectController (VgaHandle, NULL, NULL, TRUE); - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - Load a legacy PC-AT OpROM. - - @param This Protocol instance pointer. - @param Private Driver's private data. - @param PciHandle The EFI handle for the PCI device. It could be - NULL if the OpROM image is not associated with - any device. - @param OpromRevision The revision of PCI PC-AT ROM image. - @param RomImage Pointer to PCI PC-AT ROM image header. It must not - be NULL. - @param ImageSize Size of the PCI PC-AT ROM image. - @param RuntimeImageLength On input is the max runtime image length indicated by the PCIR structure - On output is the actual runtime image length - @param DiskStart Disk number of first device hooked by the ROM. If - DiskStart is the same as DiskEnd no disked were - hooked. - @param DiskEnd Disk number of the last device hooked by the ROM. - @param RomShadowAddress Shadow address of PC-AT ROM - - @retval EFI_SUCCESS Legacy ROM loaded for this device - @retval EFI_OUT_OF_RESOURCES No more space for this ROM - -**/ -EFI_STATUS -EFIAPI -LegacyBiosInstallRom ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN LEGACY_BIOS_INSTANCE *Private, - IN EFI_HANDLE PciHandle, - IN UINT8 OpromRevision, - IN VOID *RomImage, - IN UINTN ImageSize, - IN OUT UINTN *RuntimeImageLength, - OUT UINT8 *DiskStart OPTIONAL, - OUT UINT8 *DiskEnd OPTIONAL, - OUT VOID **RomShadowAddress OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_STATUS PciEnableStatus; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 LocalDiskStart; - UINT8 LocalDiskEnd; - UINTN Segment; - UINTN Bus; - UINTN Device; - UINTN Function; - EFI_IA32_REGISTER_SET Regs; - UINT8 VideoMode; - UINT8 OldVideoMode; - EFI_TIME BootTime; - UINT32 *BdaPtr; - UINT32 LocalTime; - UINT32 StartBbsIndex; - UINT32 EndBbsIndex; - UINT32 MaxRomAddr; - UINTN TempData; - UINTN InitAddress; - UINTN RuntimeAddress; - EFI_PHYSICAL_ADDRESS PhysicalAddress; - UINT32 Granularity; - - PciIo = NULL; - LocalDiskStart = 0; - LocalDiskEnd = 0; - Segment = 0; - Bus = 0; - Device = 0; - Function = 0; - VideoMode = 0; - OldVideoMode = 0; - PhysicalAddress = 0; - MaxRomAddr = PcdGet32 (PcdEndOpromShadowAddress); - - if ((Private->Legacy16Table->TableLength >= OFFSET_OF (EFI_COMPATIBILITY16_TABLE, HiPermanentMemoryAddress)) && - (Private->Legacy16Table->UmaAddress != 0) && - (Private->Legacy16Table->UmaSize != 0) && - (MaxRomAddr > (Private->Legacy16Table->UmaAddress))) - { - MaxRomAddr = Private->Legacy16Table->UmaAddress; - } - - PciProgramAllInterruptLineRegisters (Private); - - if ((OpromRevision >= 3) && (Private->Csm16PciInterfaceVersion >= 0x0300)) { - // - // CSM16 3.0 meets PCI 3.0 OpROM - // first test if there is enough space for its INIT code - // - PhysicalAddress = CONVENTIONAL_MEMORY_TOP; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiBootServicesCode, - EFI_SIZE_TO_PAGES (ImageSize), - &PhysicalAddress - ); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", DEBUG_LINE_NUMBER)); - // - // Report Status Code to indicate that there is no enough space for OpROM - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE) - ); - return EFI_OUT_OF_RESOURCES; - } - - InitAddress = (UINTN)PhysicalAddress; - // - // then test if there is enough space for its RT code - // - RuntimeAddress = Private->OptionRom; - if (RuntimeAddress + *RuntimeImageLength > MaxRomAddr) { - DEBUG ((DEBUG_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", DEBUG_LINE_NUMBER)); - gBS->FreePages (PhysicalAddress, EFI_SIZE_TO_PAGES (ImageSize)); - // - // Report Status Code to indicate that there is no enough space for OpROM - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE) - ); - return EFI_OUT_OF_RESOURCES; - } - } else { - // CSM16 3.0 meets PCI 2.x OpROM - // CSM16 2.x meets PCI 2.x/3.0 OpROM - // test if there is enough space for its INIT code - // - InitAddress = PCI_START_ADDRESS (Private->OptionRom); - if (InitAddress + ImageSize > MaxRomAddr) { - DEBUG ((DEBUG_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", DEBUG_LINE_NUMBER)); - // - // Report Status Code to indicate that there is no enough space for OpROM - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE) - ); - return EFI_OUT_OF_RESOURCES; - } - - RuntimeAddress = InitAddress; - } - - Private->LegacyRegion->UnLock ( - Private->LegacyRegion, - 0xE0000, - 0x20000, - &Granularity - ); - - Private->LegacyRegion->UnLock ( - Private->LegacyRegion, - (UINT32)RuntimeAddress, - (UINT32)ImageSize, - &Granularity - ); - - DEBUG ((DEBUG_INFO, " Shadowing OpROM init/runtime/isize = %x/%x/%x\n", InitAddress, RuntimeAddress, ImageSize)); - - CopyMem ((VOID *)InitAddress, RomImage, ImageSize); - - // - // Read the highest disk number "installed: and assume a new disk will - // show up on the first drive past the current value. - // There are several considerations here: - // 1. Non-BBS compliant drives will change 40:75 but 16-bit CSM will undo - // the change until boot selection time frame. - // 2. BBS compliants drives will not change 40:75 until boot time. - // 3. Onboard IDE controllers will change 40:75 - // - ACCESS_PAGE0_CODE ( - LocalDiskStart = (UINT8)((*(UINT8 *)((UINTN)0x475)) + 0x80); - if ((Private->Disk4075 + 0x80) < LocalDiskStart) { - // - // Update table since onboard IDE drives found - // - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciSegment = 0xff; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciBus = 0xff; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciDevice = 0xff; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciFunction = 0xff; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].StartDriveNumber = (UINT8)(Private->Disk4075 + 0x80); - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].EndDriveNumber = LocalDiskStart; - Private->LegacyEfiHddTableIndex++; - Private->Disk4075 = (UINT8)(LocalDiskStart & 0x7f); - Private->DiskEnd = LocalDiskStart; - } - - if (PciHandle != mVgaHandle) { - EnablePs2Keyboard (); - - // - // Store current mode settings since PrepareToScanRom may change mode. - // - VideoMode = *(UINT8 *)((UINTN)(0x400 + BDA_VIDEO_MODE)); - } - - ); - - // - // Notify the platform that we are about to scan the ROM - // - Status = Private->LegacyBiosPlatform->PlatformHooks ( - Private->LegacyBiosPlatform, - EfiPlatformHookPrepareToScanRom, - 0, - PciHandle, - &InitAddress, - NULL, - NULL - ); - - // - // If Status returned is EFI_UNSUPPORTED then abort due to platform - // policy. - // - if (Status == EFI_UNSUPPORTED) { - goto Done; - } - - // - // Report corresponding status code - // - REPORT_STATUS_CODE ( - EFI_PROGRESS_CODE, - (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_CSM_LEGACY_ROM_INIT) - ); - - // - // Generate number of ticks since midnight for BDA. Some OPROMs require - // this. Place result in 40:6C-6F - // - gRT->GetTime (&BootTime, NULL); - LocalTime = BootTime.Hour * 3600 + BootTime.Minute * 60 + BootTime.Second; - - // - // Multiply result by 18.2 for number of ticks since midnight. - // Use 182/10 to avoid floating point math. - // - ACCESS_PAGE0_CODE ( - LocalTime = (LocalTime * 182) / 10; - BdaPtr = (UINT32 *)((UINTN)0x46C); - *BdaPtr = LocalTime; - ); - - // - // Pass in handoff data - // - PciEnableStatus = EFI_UNSUPPORTED; - ZeroMem (&Regs, sizeof (Regs)); - if (PciHandle != NULL) { - Status = gBS->HandleProtocol ( - PciHandle, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - ASSERT_EFI_ERROR (Status); - - // - // Enable command register. - // - PciEnableStatus = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - EFI_PCI_DEVICE_ENABLE, - NULL - ); - - PciIo->GetLocation ( - PciIo, - &Segment, - &Bus, - &Device, - &Function - ); - DEBUG ((DEBUG_INFO, "Shadowing OpROM on the PCI device %x/%x/%x\n", Bus, Device, Function)); - } - - mIgnoreBbsUpdateFlag = FALSE; - Regs.X.AX = Legacy16DispatchOprom; - - // - // Generate DispatchOpRomTable data - // - Private->IntThunk->DispatchOpromTable.PnPInstallationCheckSegment = Private->Legacy16Table->PnPInstallationCheckSegment; - Private->IntThunk->DispatchOpromTable.PnPInstallationCheckOffset = Private->Legacy16Table->PnPInstallationCheckOffset; - Private->IntThunk->DispatchOpromTable.OpromSegment = (UINT16)(InitAddress >> 4); - Private->IntThunk->DispatchOpromTable.PciBus = (UINT8)Bus; - Private->IntThunk->DispatchOpromTable.PciDeviceFunction = (UINT8)((Device << 3) | Function); - Private->IntThunk->DispatchOpromTable.NumberBbsEntries = (UINT8)Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries; - Private->IntThunk->DispatchOpromTable.BbsTablePointer = (UINT32)(UINTN)Private->BbsTablePtr; - Private->IntThunk->DispatchOpromTable.RuntimeSegment = (UINT16)((OpromRevision < 3) ? 0xffff : (RuntimeAddress >> 4)); - TempData = (UINTN)&Private->IntThunk->DispatchOpromTable; - Regs.X.ES = EFI_SEGMENT ((UINT32)TempData); - Regs.X.BX = EFI_OFFSET ((UINT32)TempData); - // - // Skip dispatching ROM for those PCI devices that can not be enabled by PciIo->Attributes - // Otherwise, it may cause the system to hang in some cases - // - if (!EFI_ERROR (PciEnableStatus)) { - DEBUG ((DEBUG_INFO, " Legacy16DispatchOprom - %02x/%02x/%02x\n", Bus, Device, Function)); - Private->LegacyBios.FarCall86 ( - &Private->LegacyBios, - Private->Legacy16CallSegment, - Private->Legacy16CallOffset, - &Regs, - NULL, - 0 - ); - } else { - Regs.X.BX = 0; - } - - if (Private->IntThunk->DispatchOpromTable.NumberBbsEntries != (UINT8)Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries) { - Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries = (UINT8)Private->IntThunk->DispatchOpromTable.NumberBbsEntries; - mIgnoreBbsUpdateFlag = TRUE; - } - - // - // Check if non-BBS compliant drives found - // - if (Regs.X.BX != 0) { - LocalDiskEnd = (UINT8)(LocalDiskStart + Regs.H.BL); - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciSegment = (UINT8)Segment; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciBus = (UINT8)Bus; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciDevice = (UINT8)Device; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciFunction = (UINT8)Function; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].StartDriveNumber = Private->DiskEnd; - Private->DiskEnd = LocalDiskEnd; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].EndDriveNumber = Private->DiskEnd; - Private->LegacyEfiHddTableIndex += 1; - } - - // - // Skip video mode set, if installing VGA - // - if (PciHandle != mVgaHandle) { - // - // Set mode settings since PrepareToScanRom may change mode - // - ACCESS_PAGE0_CODE ( - { - OldVideoMode = *(UINT8 *)((UINTN)(0x400 + BDA_VIDEO_MODE)); - } - ); - - if (VideoMode != OldVideoMode) { - // - // The active video mode is changed, restore it to original mode. - // - Regs.H.AH = 0x00; - Regs.H.AL = VideoMode; - Private->LegacyBios.Int86 (&Private->LegacyBios, 0x10, &Regs); - } - } - - // - // Regs.X.AX from the adapter initializion is ignored since some adapters - // do not follow the standard of setting AX = 0 on success. - // - // - // The ROM could have updated its size so we need to read again. - // - if (((EFI_LEGACY_EXPANSION_ROM_HEADER *)RuntimeAddress)->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { - // - // Now we check the signature (0xaa55) to judge whether the run-time code is truly generated by INIT function. - // If signature is not valid, that means the INIT function didn't copy the run-time code to RuntimeAddress. - // - *RuntimeImageLength = 0; - } else { - *RuntimeImageLength = ((EFI_LEGACY_EXPANSION_ROM_HEADER *)RuntimeAddress)->Size512 * 512; - } - - DEBUG ((DEBUG_INFO, " fsize = %x\n", *RuntimeImageLength)); - - // - // If OpROM runs in 2.0 mode - // - if (PhysicalAddress == 0) { - if (*RuntimeImageLength < ImageSize) { - // - // Make area from end of shadowed rom to end of original rom all ffs - // - gBS->SetMem ((VOID *)(InitAddress + *RuntimeImageLength), ImageSize - *RuntimeImageLength, 0xff); - } - } - - ACCESS_PAGE0_CODE ( - LocalDiskEnd = (UINT8)((*(UINT8 *)((UINTN)0x475)) + 0x80); - ); - - // - // Allow platform to perform any required actions after the - // OPROM has been initialized. - // - Status = Private->LegacyBiosPlatform->PlatformHooks ( - Private->LegacyBiosPlatform, - EfiPlatformHookAfterRomInit, - 0, - PciHandle, - &RuntimeAddress, - NULL, - NULL - ); - if (PciHandle != NULL) { - // - // If no PCI Handle then no header or Bevs. - // - if ((*RuntimeImageLength != 0) && (!mIgnoreBbsUpdateFlag)) { - StartBbsIndex = Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries; - TempData = RuntimeAddress; - UpdateBevBcvTable ( - Private, - (EFI_LEGACY_EXPANSION_ROM_HEADER *)TempData, - PciIo - ); - EndBbsIndex = Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries; - LocalDiskEnd = (UINT8)(LocalDiskStart + (UINT8)(EndBbsIndex - StartBbsIndex)); - if (LocalDiskEnd != LocalDiskStart) { - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciSegment = (UINT8)Segment; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciBus = (UINT8)Bus; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciDevice = (UINT8)Device; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciFunction = (UINT8)Function; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].StartDriveNumber = Private->DiskEnd; - Private->DiskEnd = LocalDiskEnd; - Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].EndDriveNumber = Private->DiskEnd; - Private->LegacyEfiHddTableIndex += 1; - } - } - - // - // Mark PCI device as having a legacy BIOS ROM loaded. - // - RomShadow ( - PciHandle, - (UINT32)RuntimeAddress, - (UINT32)*RuntimeImageLength, - LocalDiskStart, - LocalDiskEnd - ); - } - - // - // Stuff caller's OPTIONAL return parameters. - // - if (RomShadowAddress != NULL) { - *RomShadowAddress = (VOID *)RuntimeAddress; - } - - if (DiskStart != NULL) { - *DiskStart = LocalDiskStart; - } - - if (DiskEnd != NULL) { - *DiskEnd = LocalDiskEnd; - } - - Private->OptionRom = (UINT32)(RuntimeAddress + *RuntimeImageLength); - - Status = EFI_SUCCESS; - -Done: - if (PhysicalAddress != 0) { - // - // Free pages when OpROM is 3.0 - // - gBS->FreePages (PhysicalAddress, EFI_SIZE_TO_PAGES (ImageSize)); - } - - // - // Insure all shadowed areas are locked - // - Private->LegacyRegion->Lock ( - Private->LegacyRegion, - 0xC0000, - 0x40000, - &Granularity - ); - - return Status; -} - -/** - Let IOMMU grant DMA access for the PCI device. - - @param PciHandle The EFI handle for the PCI device. - @param HostAddress The system memory address to map to the PCI controller. - @param NumberOfBytes The number of bytes to map. - - @retval EFI_SUCCESS The DMA access is granted. -**/ -EFI_STATUS -IoMmuGrantAccess ( - IN EFI_HANDLE PciHandle, - IN EFI_PHYSICAL_ADDRESS HostAddress, - IN UINTN NumberOfBytes - ) -{ - EFI_PHYSICAL_ADDRESS DeviceAddress; - VOID *Mapping; - EFI_STATUS Status; - - if (PciHandle == NULL) { - return EFI_UNSUPPORTED; - } - - Status = EFI_SUCCESS; - if (mIoMmu == NULL) { - gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **)&mIoMmu); - } - - if (mIoMmu != NULL) { - Status = mIoMmu->Map ( - mIoMmu, - EdkiiIoMmuOperationBusMasterCommonBuffer, - (VOID *)(UINTN)HostAddress, - &NumberOfBytes, - &DeviceAddress, - &Mapping - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "LegacyPci - IoMmuMap - %r\n", Status)); - } else { - ASSERT (DeviceAddress == HostAddress); - Status = mIoMmu->SetAttribute ( - mIoMmu, - PciHandle, - Mapping, - EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "LegacyPci - IoMmuSetAttribute - %r\n", Status)); - } - } - } - - return Status; -} - -/** - Load a legacy PC-AT OPROM on the PciHandle device. Return information - about how many disks were added by the OPROM and the shadow address and - size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C: - - @param This Protocol instance pointer. - @param PciHandle The PCI PC-AT OPROM from this devices ROM BAR will - be loaded. This value is NULL if RomImage is - non-NULL. This is the normal case. - @param RomImage A PCI PC-AT ROM image. This argument is non-NULL - if there is no hardware associated with the ROM - and thus no PciHandle, otherwise is must be NULL. - Example is PXE base code. - @param Flags Indicates if ROM found and if PC-AT. - @param DiskStart Disk number of first device hooked by the ROM. If - DiskStart is the same as DiskEnd no disked were - hooked. - @param DiskEnd Disk number of the last device hooked by the ROM. - @param RomShadowAddress Shadow address of PC-AT ROM - @param RomShadowedSize Size of RomShadowAddress in bytes - - @retval EFI_SUCCESS Legacy ROM loaded for this device - @retval EFI_INVALID_PARAMETER PciHandle not found - @retval EFI_UNSUPPORTED There is no PCI ROM in the ROM BAR or no onboard - ROM - -**/ -EFI_STATUS -EFIAPI -LegacyBiosInstallPciRom ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN EFI_HANDLE PciHandle, - IN VOID **RomImage, - OUT UINTN *Flags, - OUT UINT8 *DiskStart OPTIONAL, - OUT UINT8 *DiskEnd OPTIONAL, - OUT VOID **RomShadowAddress OPTIONAL, - OUT UINT32 *RomShadowedSize OPTIONAL - ) -{ - EFI_STATUS Status; - LEGACY_BIOS_INSTANCE *Private; - VOID *LocalRomImage; - UINTN ImageSize; - UINTN RuntimeImageLength; - EFI_PCI_IO_PROTOCOL *PciIo; - PCI_TYPE01 PciConfigHeader; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN PciSegment; - UINTN PciBus; - UINTN PciDevice; - UINTN PciFunction; - UINTN LastBus; - UINTN Index; - UINT8 OpromRevision; - UINT32 Granularity; - PCI_3_0_DATA_STRUCTURE *Pcir; - - OpromRevision = 0; - - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - if (Private->Legacy16Table->LastPciBus == 0) { - // - // Get last bus number if not already found - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - - LastBus = 0; - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - if (EFI_ERROR (Status)) { - continue; - } - - Status = PciIo->GetLocation ( - PciIo, - &PciSegment, - &PciBus, - &PciDevice, - &PciFunction - ); - if (PciBus > LastBus) { - LastBus = PciBus; - } - } - - Private->LegacyRegion->UnLock ( - Private->LegacyRegion, - 0xE0000, - 0x20000, - &Granularity - ); - Private->Legacy16Table->LastPciBus = (UINT8)LastBus; - Private->LegacyRegion->Lock ( - Private->LegacyRegion, - 0xE0000, - 0x20000, - &Granularity - ); - } - - *Flags = 0; - if ((PciHandle != NULL) && (RomImage == NULL)) { - // - // If PciHandle has OpRom to Execute - // and OpRom are all associated with Hardware - // - Status = gBS->HandleProtocol ( - PciHandle, - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - - if (!EFI_ERROR (Status)) { - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - 0, - sizeof (PciConfigHeader) / sizeof (UINT32), - &PciConfigHeader - ); - - // - // if video installed & OPROM is video return - // - if ( - ( - ((PciConfigHeader.Hdr.ClassCode[2] == PCI_CLASS_OLD) && - (PciConfigHeader.Hdr.ClassCode[1] == PCI_CLASS_OLD_VGA)) - || - ((PciConfigHeader.Hdr.ClassCode[2] == PCI_CLASS_DISPLAY) && - (PciConfigHeader.Hdr.ClassCode[1] == PCI_CLASS_DISPLAY_VGA)) - ) - && - (!Private->VgaInstalled) - ) - { - mVgaInstallationInProgress = TRUE; - - // - // return EFI_UNSUPPORTED; - // - } - } - - // - // To run any legacy image, the VGA needs to be installed first. - // if installing the video, then don't need the thunk as already installed. - // - Status = Private->LegacyBiosPlatform->GetPlatformHandle ( - Private->LegacyBiosPlatform, - EfiGetPlatformVgaHandle, - 0, - &HandleBuffer, - &HandleCount, - NULL - ); - - if (!EFI_ERROR (Status)) { - mVgaHandle = HandleBuffer[0]; - if ((!Private->VgaInstalled) && (PciHandle != mVgaHandle)) { - // - // A return status of EFI_NOT_FOUND is considered valid (No EFI - // driver is controlling video. - // - mVgaInstallationInProgress = TRUE; - Status = LegacyBiosInstallVgaRom (Private); - if (EFI_ERROR (Status)) { - if (Status != EFI_NOT_FOUND) { - mVgaInstallationInProgress = FALSE; - return Status; - } - } else { - mVgaInstallationInProgress = FALSE; - } - } - } - - // - // See if the option ROM for PciHandle has already been executed - // - Status = IsLegacyRom (PciHandle); - - if (!EFI_ERROR (Status)) { - mVgaInstallationInProgress = FALSE; - GetShadowedRomParameters ( - PciHandle, - DiskStart, - DiskEnd, - RomShadowAddress, - (UINTN *)RomShadowedSize - ); - return EFI_SUCCESS; - } - - Status = LegacyBiosCheckPciRomEx ( - &Private->LegacyBios, - PciHandle, - &LocalRomImage, - &ImageSize, - &RuntimeImageLength, - Flags, - &OpromRevision, - NULL - ); - if (EFI_ERROR (Status)) { - // - // There is no PCI ROM in the ROM BAR or no onboard ROM - // - mVgaInstallationInProgress = FALSE; - return EFI_UNSUPPORTED; - } - } else { - if ((RomImage == NULL) || (*RomImage == NULL)) { - // - // If PciHandle is NULL, and no OpRom is to be associated - // - mVgaInstallationInProgress = FALSE; - return EFI_UNSUPPORTED; - } - - Status = Private->LegacyBiosPlatform->GetPlatformHandle ( - Private->LegacyBiosPlatform, - EfiGetPlatformVgaHandle, - 0, - &HandleBuffer, - &HandleCount, - NULL - ); - if ((!EFI_ERROR (Status)) && (!Private->VgaInstalled)) { - // - // A return status of EFI_NOT_FOUND is considered valid (No EFI - // driver is controlling video. - // - mVgaInstallationInProgress = TRUE; - Status = LegacyBiosInstallVgaRom (Private); - if (EFI_ERROR (Status)) { - if (Status != EFI_NOT_FOUND) { - mVgaInstallationInProgress = FALSE; - return Status; - } - } else { - mVgaInstallationInProgress = FALSE; - } - } - - LocalRomImage = *RomImage; - if ((((PCI_EXPANSION_ROM_HEADER *)LocalRomImage)->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) || - (((PCI_EXPANSION_ROM_HEADER *)LocalRomImage)->PcirOffset == 0) || - ((((PCI_EXPANSION_ROM_HEADER *)LocalRomImage)->PcirOffset & 3) != 0)) - { - mVgaInstallationInProgress = FALSE; - return EFI_UNSUPPORTED; - } - - Pcir = (PCI_3_0_DATA_STRUCTURE *) - ((UINT8 *)LocalRomImage + ((PCI_EXPANSION_ROM_HEADER *)LocalRomImage)->PcirOffset); - - if ((Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) || (Pcir->CodeType != PCI_CODE_TYPE_PCAT_IMAGE)) { - mVgaInstallationInProgress = FALSE; - return EFI_UNSUPPORTED; - } - - ImageSize = Pcir->ImageLength * 512; - if (Pcir->Length >= 0x1C) { - OpromRevision = Pcir->Revision; - } else { - OpromRevision = 0; - } - - if (Pcir->Revision < 3) { - RuntimeImageLength = 0; - } else { - RuntimeImageLength = Pcir->MaxRuntimeImageLength * 512; - } - } - - // - // Grant access for below 1M - // BDA/EBDA/LowPMM and scratch memory for OPROM. - // - IoMmuGrantAccess (PciHandle, 0, SIZE_1MB); - // - // Grant access for HiPmm - // - IoMmuGrantAccess ( - PciHandle, - Private->IntThunk->EfiToLegacy16InitTable.HiPmmMemory, - Private->IntThunk->EfiToLegacy16InitTable.HiPmmMemorySizeInBytes - ); - - // - // Shadow and initialize the OpROM. - // - ASSERT (Private->TraceIndex < 0x200); - Private->Trace[Private->TraceIndex] = LEGACY_PCI_TRACE_000; - Private->TraceIndex++; - Private->TraceIndex = (UINT16)(Private->TraceIndex % 0x200); - Status = LegacyBiosInstallRom ( - This, - Private, - PciHandle, - OpromRevision, - LocalRomImage, - ImageSize, - &RuntimeImageLength, - DiskStart, - DiskEnd, - RomShadowAddress - ); - if (RomShadowedSize != NULL) { - *RomShadowedSize = (UINT32)RuntimeImageLength; - } - - mVgaInstallationInProgress = FALSE; - return Status; -} diff --git a/OvmfPkg/Csm/LegacyBiosDxe/LegacySio.c b/OvmfPkg/Csm/LegacyBiosDxe/LegacySio.c deleted file mode 100644 index 0cb48fa8ab..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/LegacySio.c +++ /dev/null @@ -1,489 +0,0 @@ -/** @file - Collect Sio information from Native EFI Drivers. - Sio is floppy, parallel, serial, ... hardware - -Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "LegacyBiosInterface.h" - -/** - Collect EFI Info about legacy devices through Super IO interface. - - @param SioPtr Pointer to SIO data. - - @retval EFI_SUCCESS When SIO data is got successfully. - @retval EFI_NOT_FOUND When ISA IO interface is absent. - -**/ -EFI_STATUS -LegacyBiosBuildSioDataFromSio ( - IN DEVICE_PRODUCER_DATA_HEADER *SioPtr - ) -{ - EFI_STATUS Status; - DEVICE_PRODUCER_SERIAL *SioSerial; - DEVICE_PRODUCER_PARALLEL *SioParallel; - DEVICE_PRODUCER_FLOPPY *SioFloppy; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - UINTN ChildIndex; - EFI_SIO_PROTOCOL *Sio; - ACPI_RESOURCE_HEADER_PTR Resources; - EFI_ACPI_IO_PORT_DESCRIPTOR *IoResource; - EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *FixedIoResource; - EFI_ACPI_DMA_DESCRIPTOR *DmaResource; - EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR *IrqResource; - UINT16 Address; - UINT8 Dma; - UINT8 Irq; - UINTN EntryCount; - EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_SERIAL_IO_PROTOCOL *SerialIo; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - ACPI_HID_DEVICE_PATH *Acpi; - - // - // Get the list of ISA controllers in the system - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSioProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - // - // Collect legacy information from each of the ISA controllers in the system - // - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSioProtocolGuid, (VOID **)&Sio); - if (EFI_ERROR (Status)) { - continue; - } - - Address = MAX_UINT16; - Dma = MAX_UINT8; - Irq = MAX_UINT8; - Status = Sio->GetResources (Sio, &Resources); - if (!EFI_ERROR (Status)) { - // - // Get the base address information from ACPI resource descriptor. - // - while (Resources.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) { - switch (Resources.SmallHeader->Byte) { - case ACPI_IO_PORT_DESCRIPTOR: - IoResource = (EFI_ACPI_IO_PORT_DESCRIPTOR *)Resources.SmallHeader; - Address = IoResource->BaseAddressMin; - break; - - case ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR: - FixedIoResource = (EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *)Resources.SmallHeader; - Address = FixedIoResource->BaseAddress; - break; - - case ACPI_DMA_DESCRIPTOR: - DmaResource = (EFI_ACPI_DMA_DESCRIPTOR *)Resources.SmallHeader; - Dma = (UINT8)LowBitSet32 (DmaResource->ChannelMask); - break; - - case ACPI_IRQ_DESCRIPTOR: - case ACPI_IRQ_NOFLAG_DESCRIPTOR: - IrqResource = (EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR *)Resources.SmallHeader; - Irq = (UINT8)LowBitSet32 (IrqResource->Mask); - break; - - default: - break; - } - - if (Resources.SmallHeader->Bits.Type == 0) { - Resources.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *)((UINT8 *)Resources.SmallHeader - + Resources.SmallHeader->Bits.Length - + sizeof (*Resources.SmallHeader)); - } else { - Resources.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *)((UINT8 *)Resources.LargeHeader - + Resources.LargeHeader->Length - + sizeof (*Resources.LargeHeader)); - } - } - } - - DEBUG ((DEBUG_INFO, "LegacySio: Address/Dma/Irq = %x/%d/%d\n", Address, Dma, Irq)); - - DevicePath = DevicePathFromHandle (HandleBuffer[Index]); - if (DevicePath == NULL) { - continue; - } - - Acpi = NULL; - while (!IsDevicePathEnd (DevicePath)) { - Acpi = (ACPI_HID_DEVICE_PATH *)DevicePath; - DevicePath = NextDevicePathNode (DevicePath); - } - - if ((Acpi == NULL) || (DevicePathType (Acpi) != ACPI_DEVICE_PATH) || - ((DevicePathSubType (Acpi) != ACPI_DP) && (DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)) - ) - { - continue; - } - - // - // See if this is an ISA serial port - // - // Ignore DMA resource since it is always returned NULL - // - if ((Acpi->HID == EISA_PNP_ID (0x500)) || (Acpi->HID == EISA_PNP_ID (0x501))) { - if ((Acpi->UID < 4) && (Address != MAX_UINT16) && (Irq != MAX_UINT8)) { - // - // Get the handle of the child device that has opened the Super I/O Protocol - // - Status = gBS->OpenProtocolInformation ( - HandleBuffer[Index], - &gEfiSioProtocolGuid, - &OpenInfoBuffer, - &EntryCount - ); - if (EFI_ERROR (Status)) { - continue; - } - - for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) { - if ((OpenInfoBuffer[ChildIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { - Status = gBS->HandleProtocol (OpenInfoBuffer[ChildIndex].ControllerHandle, &gEfiSerialIoProtocolGuid, (VOID **)&SerialIo); - if (!EFI_ERROR (Status)) { - SioSerial = &SioPtr->Serial[Acpi->UID]; - SioSerial->Address = Address; - SioSerial->Irq = Irq; - SioSerial->Mode = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF; - break; - } - } - } - - FreePool (OpenInfoBuffer); - } - } - - // - // See if this is an ISA parallel port - // - // Ignore DMA resource since it is always returned NULL, port - // only used in output mode. - // - if ((Acpi->HID == EISA_PNP_ID (0x400)) || (Acpi->HID == EISA_PNP_ID (0x401))) { - if ((Acpi->UID < 3) && (Address != MAX_UINT16) && (Irq != MAX_UINT8) && (Dma != MAX_UINT8)) { - SioParallel = &SioPtr->Parallel[Acpi->UID]; - SioParallel->Address = Address; - SioParallel->Irq = Irq; - SioParallel->Dma = Dma; - SioParallel->Mode = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY; - } - } - - // - // See if this is an ISA floppy controller - // - if (Acpi->HID == EISA_PNP_ID (0x604)) { - if ((Address != MAX_UINT16) && (Irq != MAX_UINT8) && (Dma != MAX_UINT8)) { - Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo); - if (!EFI_ERROR (Status)) { - SioFloppy = &SioPtr->Floppy; - SioFloppy->Address = Address; - SioFloppy->Irq = Irq; - SioFloppy->Dma = Dma; - SioFloppy->NumberOfFloppy++; - } - } - } - - // - // See if this is a mouse - // Always set mouse found so USB hot plug will work - // - // Ignore lower byte of HID. Pnp0fxx is any type of mouse. - // - // Hid = ResourceList->Device.HID & 0xff00ffff; - // PnpId = EISA_PNP_ID(0x0f00); - // if (Hid == PnpId) { - // if (ResourceList->Device.UID == 1) { - // Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimplePointerProtocolGuid, &SimplePointer); - // if (!EFI_ERROR (Status)) { - // - SioPtr->MousePresent = 0x01; - // - // } - // } - // } - // - } - - FreePool (HandleBuffer); - return EFI_SUCCESS; -} - -/** - Collect EFI Info about legacy devices through ISA IO interface. - - @param SioPtr Pointer to SIO data. - - @retval EFI_SUCCESS When SIO data is got successfully. - @retval EFI_NOT_FOUND When ISA IO interface is absent. - -**/ -EFI_STATUS -LegacyBiosBuildSioDataFromIsaIo ( - IN DEVICE_PRODUCER_DATA_HEADER *SioPtr - ) -{ - EFI_STATUS Status; - DEVICE_PRODUCER_SERIAL *SioSerial; - DEVICE_PRODUCER_PARALLEL *SioParallel; - DEVICE_PRODUCER_FLOPPY *SioFloppy; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - UINTN ResourceIndex; - UINTN ChildIndex; - EFI_ISA_IO_PROTOCOL *IsaIo; - EFI_ISA_ACPI_RESOURCE_LIST *ResourceList; - EFI_ISA_ACPI_RESOURCE *IoResource; - EFI_ISA_ACPI_RESOURCE *DmaResource; - EFI_ISA_ACPI_RESOURCE *InterruptResource; - UINTN EntryCount; - EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_SERIAL_IO_PROTOCOL *SerialIo; - - // - // Get the list of ISA controllers in the system - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiIsaIoProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - // - // Collect legacy information from each of the ISA controllers in the system - // - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiIsaIoProtocolGuid, (VOID **)&IsaIo); - if (EFI_ERROR (Status)) { - continue; - } - - ResourceList = IsaIo->ResourceList; - - if (ResourceList == NULL) { - continue; - } - - // - // Collect the resource types neededto fill in the SIO data structure - // - IoResource = NULL; - DmaResource = NULL; - InterruptResource = NULL; - for (ResourceIndex = 0; - ResourceList->ResourceItem[ResourceIndex].Type != EfiIsaAcpiResourceEndOfList; - ResourceIndex++ - ) - { - switch (ResourceList->ResourceItem[ResourceIndex].Type) { - case EfiIsaAcpiResourceIo: - IoResource = &ResourceList->ResourceItem[ResourceIndex]; - break; - - case EfiIsaAcpiResourceMemory: - break; - - case EfiIsaAcpiResourceDma: - DmaResource = &ResourceList->ResourceItem[ResourceIndex]; - break; - - case EfiIsaAcpiResourceInterrupt: - InterruptResource = &ResourceList->ResourceItem[ResourceIndex]; - break; - - default: - break; - } - } - - // - // See if this is an ISA serial port - // - // Ignore DMA resource since it is always returned NULL - // - if ((ResourceList->Device.HID == EISA_PNP_ID (0x500)) || (ResourceList->Device.HID == EISA_PNP_ID (0x501))) { - if ((ResourceList->Device.UID <= 3) && - (IoResource != NULL) && - (InterruptResource != NULL) - ) - { - // - // Get the handle of the child device that has opened the ISA I/O Protocol - // - Status = gBS->OpenProtocolInformation ( - HandleBuffer[Index], - &gEfiIsaIoProtocolGuid, - &OpenInfoBuffer, - &EntryCount - ); - if (EFI_ERROR (Status)) { - continue; - } - - // - // We want resource for legacy even if no 32-bit driver installed - // - for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) { - if ((OpenInfoBuffer[ChildIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { - Status = gBS->HandleProtocol (OpenInfoBuffer[ChildIndex].ControllerHandle, &gEfiSerialIoProtocolGuid, (VOID **)&SerialIo); - if (!EFI_ERROR (Status)) { - SioSerial = &SioPtr->Serial[ResourceList->Device.UID]; - SioSerial->Address = (UINT16)IoResource->StartRange; - SioSerial->Irq = (UINT8)InterruptResource->StartRange; - SioSerial->Mode = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF; - break; - } - } - } - - FreePool (OpenInfoBuffer); - } - } - - // - // See if this is an ISA parallel port - // - // Ignore DMA resource since it is always returned NULL, port - // only used in output mode. - // - if ((ResourceList->Device.HID == EISA_PNP_ID (0x400)) || (ResourceList->Device.HID == EISA_PNP_ID (0x401))) { - if ((ResourceList->Device.UID <= 2) && - (IoResource != NULL) && - (InterruptResource != NULL) && - (DmaResource != NULL) - ) - { - SioParallel = &SioPtr->Parallel[ResourceList->Device.UID]; - SioParallel->Address = (UINT16)IoResource->StartRange; - SioParallel->Irq = (UINT8)InterruptResource->StartRange; - SioParallel->Dma = (UINT8)DmaResource->StartRange; - SioParallel->Mode = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY; - } - } - - // - // See if this is an ISA floppy controller - // - if (ResourceList->Device.HID == EISA_PNP_ID (0x604)) { - if ((IoResource != NULL) && (InterruptResource != NULL) && (DmaResource != NULL)) { - Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo); - if (!EFI_ERROR (Status)) { - SioFloppy = &SioPtr->Floppy; - SioFloppy->Address = (UINT16)IoResource->StartRange; - SioFloppy->Irq = (UINT8)InterruptResource->StartRange; - SioFloppy->Dma = (UINT8)DmaResource->StartRange; - SioFloppy->NumberOfFloppy++; - } - } - } - - // - // See if this is a mouse - // Always set mouse found so USB hot plug will work - // - // Ignore lower byte of HID. Pnp0fxx is any type of mouse. - // - // Hid = ResourceList->Device.HID & 0xff00ffff; - // PnpId = EISA_PNP_ID(0x0f00); - // if (Hid == PnpId) { - // if (ResourceList->Device.UID == 1) { - // Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimplePointerProtocolGuid, &SimplePointer); - // if (!EFI_ERROR (Status)) { - // - SioPtr->MousePresent = 0x01; - // - // } - // } - // } - // - } - - FreePool (HandleBuffer); - return EFI_SUCCESS; -} - -/** - Collect EFI Info about legacy devices. - - @param Private Legacy BIOS Instance data - - @retval EFI_SUCCESS It should always work. - -**/ -EFI_STATUS -LegacyBiosBuildSioData ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - EFI_STATUS Status; - DEVICE_PRODUCER_DATA_HEADER *SioPtr; - EFI_HANDLE IsaBusController; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - - // - // Get the pointer to the SIO data structure - // - SioPtr = &Private->IntThunk->EfiToLegacy16BootTable.SioData; - - // - // Zero the data in the SIO data structure - // - gBS->SetMem (SioPtr, sizeof (DEVICE_PRODUCER_DATA_HEADER), 0); - - // - // Find the ISA Bus Controller used for legacy - // - Status = Private->LegacyBiosPlatform->GetPlatformHandle ( - Private->LegacyBiosPlatform, - EfiGetPlatformIsaBusHandle, - 0, - &HandleBuffer, - &HandleCount, - NULL - ); - IsaBusController = HandleBuffer[0]; - if (!EFI_ERROR (Status)) { - // - // Force ISA Bus Controller to produce all ISA devices - // - gBS->ConnectController (IsaBusController, NULL, NULL, TRUE); - } - - Status = LegacyBiosBuildSioDataFromIsaIo (SioPtr); - if (EFI_ERROR (Status)) { - LegacyBiosBuildSioDataFromSio (SioPtr); - } - - return EFI_SUCCESS; -} diff --git a/OvmfPkg/Csm/LegacyBiosDxe/Thunk.c b/OvmfPkg/Csm/LegacyBiosDxe/Thunk.c deleted file mode 100644 index 62f19b6519..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/Thunk.c +++ /dev/null @@ -1,422 +0,0 @@ -/** @file - Call into 16-bit BIOS code, Use AsmThunk16 function of BaseLib. - -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "LegacyBiosInterface.h" - -THUNK_CONTEXT mThunkContext; - -/** - Sets the counter value for Timer #0 in a legacy 8254 timer. - - @param Count - The 16-bit counter value to program into Timer #0 of the legacy 8254 timer. - -**/ -VOID -SetPitCount ( - IN UINT16 Count - ) -{ - IoWrite8 (TIMER_CONTROL_PORT, TIMER0_CONTROL_WORD); - IoWrite8 (TIMER0_COUNT_PORT, (UINT8)(Count & 0xFF)); - IoWrite8 (TIMER0_COUNT_PORT, (UINT8)((Count>>8) & 0xFF)); -} - -/** - Thunk to 16-bit real mode and execute a software interrupt with a vector - of BiosInt. Regs will contain the 16-bit register context on entry and - exit. - - @param This Protocol instance pointer. - @param BiosInt Processor interrupt vector to invoke - @param Regs Register contexted passed into (and returned) from thunk to - 16-bit mode - - @retval FALSE Thunk completed, and there were no BIOS errors in the target code. - See Regs for status. - @retval TRUE There was a BIOS erro in the target code. - -**/ -BOOLEAN -EFIAPI -LegacyBiosInt86 ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINT8 BiosInt, - IN EFI_IA32_REGISTER_SET *Regs - ) -{ - UINT16 Segment; - UINT16 Offset; - - Regs->X.Flags.Reserved1 = 1; - Regs->X.Flags.Reserved2 = 0; - Regs->X.Flags.Reserved3 = 0; - Regs->X.Flags.Reserved4 = 0; - Regs->X.Flags.IOPL = 3; - Regs->X.Flags.NT = 0; - Regs->X.Flags.IF = 0; - Regs->X.Flags.TF = 0; - Regs->X.Flags.CF = 0; - // - // The base address of legacy interrupt vector table is 0. - // We use this base address to get the legacy interrupt handler. - // - ACCESS_PAGE0_CODE ( - Segment = (UINT16)(((UINT32 *)0)[BiosInt] >> 16); - Offset = (UINT16)((UINT32 *)0)[BiosInt]; - ); - - return InternalLegacyBiosFarCall ( - This, - Segment, - Offset, - Regs, - &Regs->X.Flags, - sizeof (Regs->X.Flags) - ); -} - -/** - Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the - 16-bit register context on entry and exit. Arguments can be passed on - the Stack argument - - @param This Protocol instance pointer. - @param Segment Segemnt of 16-bit mode call - @param Offset Offset of 16-bit mdoe call - @param Regs Register contexted passed into (and returned) from - thunk to 16-bit mode - @param Stack Caller allocated stack used to pass arguments - @param StackSize Size of Stack in bytes - - @retval FALSE Thunk completed, and there were no BIOS errors in - the target code. See Regs for status. - @retval TRUE There was a BIOS erro in the target code. - -**/ -BOOLEAN -EFIAPI -LegacyBiosFarCall86 ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINT16 Segment, - IN UINT16 Offset, - IN EFI_IA32_REGISTER_SET *Regs, - IN VOID *Stack, - IN UINTN StackSize - ) -{ - Regs->X.Flags.Reserved1 = 1; - Regs->X.Flags.Reserved2 = 0; - Regs->X.Flags.Reserved3 = 0; - Regs->X.Flags.Reserved4 = 0; - Regs->X.Flags.IOPL = 3; - Regs->X.Flags.NT = 0; - Regs->X.Flags.IF = 1; - Regs->X.Flags.TF = 0; - Regs->X.Flags.CF = 0; - - return InternalLegacyBiosFarCall (This, Segment, Offset, Regs, Stack, StackSize); -} - -/** - Provide NULL interrupt handler which is used to check - if there is more than one HW interrupt registers with the CPU AP. - - @param InterruptType - The type of interrupt that occurred - @param SystemContext - A pointer to the system context when the interrupt occurred - -**/ -VOID -EFIAPI -LegacyBiosNullInterruptHandler ( - IN EFI_EXCEPTION_TYPE InterruptType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ -} - -/** - Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the - 16-bit register context on entry and exit. Arguments can be passed on - the Stack argument - - @param This Protocol instance pointer. - @param Segment Segemnt of 16-bit mode call - @param Offset Offset of 16-bit mdoe call - @param Regs Register contexted passed into (and returned) from thunk to - 16-bit mode - @param Stack Caller allocated stack used to pass arguments - @param StackSize Size of Stack in bytes - - @retval FALSE Thunk completed, and there were no BIOS errors in the target code. - See Regs for status. - @retval TRUE There was a BIOS erro in the target code. - -**/ -BOOLEAN -EFIAPI -InternalLegacyBiosFarCall ( - IN EFI_LEGACY_BIOS_PROTOCOL *This, - IN UINT16 Segment, - IN UINT16 Offset, - IN EFI_IA32_REGISTER_SET *Regs, - IN VOID *Stack, - IN UINTN StackSize - ) -{ - UINTN Status; - LEGACY_BIOS_INSTANCE *Private; - UINT16 *Stack16; - EFI_TPL OriginalTpl; - IA32_REGISTER_SET ThunkRegSet; - BOOLEAN InterruptState; - UINT64 TimerPeriod; - - Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); - - ZeroMem (&ThunkRegSet, sizeof (ThunkRegSet)); - ThunkRegSet.X.DI = Regs->X.DI; - ThunkRegSet.X.SI = Regs->X.SI; - ThunkRegSet.X.BP = Regs->X.BP; - ThunkRegSet.X.BX = Regs->X.BX; - ThunkRegSet.X.DX = Regs->X.DX; - // - // Sometimes, ECX is used to pass in 32 bit data. For example, INT 1Ah, AX = B10Dh is - // "PCI BIOS v2.0c + Write Configuration DWORD" and ECX has the dword to write. - // - ThunkRegSet.E.ECX = Regs->E.ECX; - ThunkRegSet.X.AX = Regs->X.AX; - ThunkRegSet.E.DS = Regs->X.DS; - ThunkRegSet.E.ES = Regs->X.ES; - - CopyMem (&(ThunkRegSet.E.EFLAGS.UintN), &(Regs->X.Flags), sizeof (Regs->X.Flags)); - - // - // Clear the error flag; thunk code may set it. Stack16 should be the high address - // Make Statk16 address the low 16 bit must be not zero. - // - Stack16 = (UINT16 *)((UINT8 *)mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize - sizeof (UINT16)); - - // - // Save current rate of DXE Timer - // - Private->Timer->GetTimerPeriod (Private->Timer, &TimerPeriod); - - // - // Disable DXE Timer while executing in real mode - // - Private->Timer->SetTimerPeriod (Private->Timer, 0); - - // - // Save and disable interrupt of debug timer - // - InterruptState = SaveAndSetDebugTimerInterrupt (FALSE); - - // - // The call to Legacy16 is a critical section to EFI - // - OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - - // - // Check to see if there is more than one HW interrupt registers with the CPU AP. - // If there is, then ASSERT() since that is not compatible with the CSM because - // interupts other than the Timer interrupt that was disabled above can not be - // handled properly from real mode. - // - DEBUG_CODE_BEGIN (); - UINTN Vector; - UINTN Count; - - for (Vector = 0x20, Count = 0; Vector < 0x100; Vector++) { - Status = Private->Cpu->RegisterInterruptHandler (Private->Cpu, Vector, LegacyBiosNullInterruptHandler); - if (Status == EFI_ALREADY_STARTED) { - Count++; - } - - if (Status == EFI_SUCCESS) { - Private->Cpu->RegisterInterruptHandler (Private->Cpu, Vector, NULL); - } - } - - if (Count >= 2) { - DEBUG ((DEBUG_ERROR, "ERROR: More than one HW interrupt active with CSM enabled\n")); - } - - ASSERT (Count < 2); - DEBUG_CODE_END (); - - // - // If the Timer AP has enabled the 8254 timer IRQ and the current 8254 timer - // period is less than the CSM required rate of 54.9254, then force the 8254 - // PIT counter to 0, which is the CSM required rate of 54.9254 ms - // - if (Private->TimerUses8254 && (TimerPeriod < 549254)) { - SetPitCount (0); - } - - if ((Stack != NULL) && (StackSize != 0)) { - // - // Copy Stack to low memory stack - // - Stack16 -= StackSize / sizeof (UINT16); - CopyMem (Stack16, Stack, StackSize); - } - - ThunkRegSet.E.SS = (UINT16)(((UINTN)Stack16 >> 16) << 12); - ThunkRegSet.E.ESP = (UINT16)(UINTN)Stack16; - ThunkRegSet.E.CS = Segment; - ThunkRegSet.E.Eip = Offset; - - mThunkContext.RealModeState = &ThunkRegSet; - - // - // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases. - // - Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259LegacyMode, NULL, NULL); - ASSERT_EFI_ERROR (Status); - - AsmThunk16 (&mThunkContext); - - if ((Stack != NULL) && (StackSize != 0)) { - // - // Copy low memory stack to Stack - // - CopyMem (Stack, Stack16, StackSize); - } - - // - // Restore protected mode interrupt state - // - Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259ProtectedMode, NULL, NULL); - ASSERT_EFI_ERROR (Status); - - mThunkContext.RealModeState = NULL; - - // - // Enable and restore rate of DXE Timer - // - Private->Timer->SetTimerPeriod (Private->Timer, TimerPeriod); - - // - // End critical section - // - gBS->RestoreTPL (OriginalTpl); - - // - // OPROM may allocate EBDA range by itself and change EBDA base and EBDA size. - // Get the current EBDA base address, and compared with pre-allocate minimum - // EBDA base address, if the current EBDA base address is smaller, it indicates - // PcdEbdaReservedMemorySize should be adjusted to larger for more OPROMs. - // - DEBUG_CODE_BEGIN (); - { - UINTN EbdaBaseAddress; - UINTN ReservedEbdaBaseAddress; - - ACCESS_PAGE0_CODE ( - EbdaBaseAddress = (*(UINT16 *)(UINTN)0x40E) << 4; - ReservedEbdaBaseAddress = CONVENTIONAL_MEMORY_TOP - - PcdGet32 (PcdEbdaReservedMemorySize); - ASSERT (ReservedEbdaBaseAddress <= EbdaBaseAddress); - ); - } - DEBUG_CODE_END (); - - // - // Restore interrupt of debug timer - // - SaveAndSetDebugTimerInterrupt (InterruptState); - - Regs->E.EDI = ThunkRegSet.E.EDI; - Regs->E.ESI = ThunkRegSet.E.ESI; - Regs->E.EBP = ThunkRegSet.E.EBP; - Regs->E.EBX = ThunkRegSet.E.EBX; - Regs->E.EDX = ThunkRegSet.E.EDX; - Regs->E.ECX = ThunkRegSet.E.ECX; - Regs->E.EAX = ThunkRegSet.E.EAX; - Regs->X.SS = ThunkRegSet.E.SS; - Regs->X.CS = ThunkRegSet.E.CS; - Regs->X.DS = ThunkRegSet.E.DS; - Regs->X.ES = ThunkRegSet.E.ES; - - CopyMem (&(Regs->X.Flags), &(ThunkRegSet.E.EFLAGS.UintN), sizeof (Regs->X.Flags)); - - return (BOOLEAN)(Regs->X.Flags.CF == 1); -} - -/** - Allocate memory < 1 MB and copy the thunker code into low memory. Se up - all the descriptors. - - @param Private Private context for Legacy BIOS - - @retval EFI_SUCCESS Should only pass. - -**/ -EFI_STATUS -LegacyBiosInitializeThunk ( - IN LEGACY_BIOS_INSTANCE *Private - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS MemoryAddress; - UINT8 TimerVector; - - MemoryAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Private->IntThunk; - - mThunkContext.RealModeBuffer = (VOID *)(UINTN)(MemoryAddress + ((sizeof (LOW_MEMORY_THUNK) / EFI_PAGE_SIZE) + 1) * EFI_PAGE_SIZE); - mThunkContext.RealModeBufferSize = EFI_PAGE_SIZE; - mThunkContext.ThunkAttributes = THUNK_ATTRIBUTE_BIG_REAL_MODE | THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15; - - AsmPrepareThunk16 (&mThunkContext); - - // - // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver - // - TimerVector = 0; - Status = Private->Legacy8259->GetVector (Private->Legacy8259, Efi8259Irq0, &TimerVector); - ASSERT_EFI_ERROR (Status); - - // - // Check to see if the Timer AP has hooked the IRQ0 from the 8254 PIT - // - Status = Private->Cpu->RegisterInterruptHandler ( - Private->Cpu, - TimerVector, - LegacyBiosNullInterruptHandler - ); - if (Status == EFI_SUCCESS) { - // - // If the Timer AP has not enabled the 8254 timer IRQ, then force the 8254 PIT - // counter to 0, which is the CSM required rate of 54.9254 ms - // - Private->Cpu->RegisterInterruptHandler ( - Private->Cpu, - TimerVector, - NULL - ); - SetPitCount (0); - - // - // Save status that the Timer AP is not using the 8254 PIT - // - Private->TimerUses8254 = FALSE; - } else if (Status == EFI_ALREADY_STARTED) { - // - // Save status that the Timer AP is using the 8254 PIT - // - Private->TimerUses8254 = TRUE; - } else { - // - // Unexpected status from CPU AP RegisterInterruptHandler() - // - ASSERT (FALSE); - } - - return EFI_SUCCESS; -} diff --git a/OvmfPkg/Csm/LegacyBiosDxe/X64/InterruptTable.nasm b/OvmfPkg/Csm/LegacyBiosDxe/X64/InterruptTable.nasm deleted file mode 100644 index afc2f0e639..0000000000 --- a/OvmfPkg/Csm/LegacyBiosDxe/X64/InterruptTable.nasm +++ /dev/null @@ -1,64 +0,0 @@ -;; @file -; Interrupt Redirection Template -; -; Copyright (c) 2016, Intel Corporation. All rights reserved.
-; -; SPDX-License-Identifier: BSD-2-Clause-Patent -; -;; - - DEFAULT REL - SECTION .text - -;---------------------------------------------------------------------------- -; Procedure: InterruptRedirectionTemplate: Redirects interrupts 0x68-0x6F -; -; Input: None -; -; Output: None -; -; Prototype: VOID -; InterruptRedirectionTemplate ( -; VOID -; ); -; -; Saves: None -; -; Modified: None -; -; Description: Contains the code that is copied into low memory (below 640K). -; This code reflects interrupts 0x68-0x6f to interrupts 0x08-0x0f. -; This template must be copied into low memory, and the IDT entries -; 0x68-0x6F must be point to the low memory copy of this code. Each -; entry is 4 bytes long, so IDT entries 0x68-0x6F can be easily -; computed. -; -;---------------------------------------------------------------------------- - -global ASM_PFX(InterruptRedirectionTemplate) -ASM_PFX(InterruptRedirectionTemplate): - int 0x8 - DB 0xcf ; IRET - nop - int 0x9 - DB 0xcf ; IRET - nop - int 0xa - DB 0xcf ; IRET - nop - int 0xb - DB 0xcf ; IRET - nop - int 0xc - DB 0xcf ; IRET - nop - int 0xd - DB 0xcf ; IRET - nop - int 0xe - DB 0xcf ; IRET - nop - int 0xf - DB 0xcf ; IRET - nop -