mirror of https://github.com/acidanthera/audk.git
OvmfPkg: remove LegacyBiosDxe
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 <ardb+tianocore@kernel.org> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4588 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20231110235820.644381-16-lersek@redhat.com> Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org> Acked-by: Corvin Köhne <corvink@FreeBSD.org> Acked-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
209480b047
commit
f0c5d652d9
|
@ -1,63 +0,0 @@
|
||||||
;; @file
|
|
||||||
; Interrupt Redirection Template
|
|
||||||
;
|
|
||||||
; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
|
||||||
;
|
|
||||||
; 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
|
|
||||||
|
|
|
@ -1,530 +0,0 @@
|
||||||
/** @file
|
|
||||||
|
|
||||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "LegacyBiosInterface.h"
|
|
||||||
#include <IndustryStandard/Pci.h>
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
|
@ -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.<BR>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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.<BR>
|
|
||||||
#
|
|
||||||
# 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
|
|
|
@ -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.<BR>
|
|
||||||
//
|
|
||||||
// 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."
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
// /** @file
|
|
||||||
// LegacyBiosDxe Localized Strings and Content
|
|
||||||
//
|
|
||||||
// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
//
|
|
||||||
// **/
|
|
||||||
|
|
||||||
#string STR_PROPERTIES_MODULE_NAME
|
|
||||||
#language en-US
|
|
||||||
"Legacy BIOS Support DXE Driver"
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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.<BR>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,315 +0,0 @@
|
||||||
/** @file
|
|
||||||
Collect IDE information from Native EFI Driver
|
|
||||||
|
|
||||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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.<BR>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -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.<BR>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
;; @file
|
|
||||||
; Interrupt Redirection Template
|
|
||||||
;
|
|
||||||
; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
|
||||||
;
|
|
||||||
; 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
|
|
||||||
|
|
Loading…
Reference in New Issue