123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530 |
- /** @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;
- }
|