2 Legacy BIOS Platform support
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials are
7 licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "LegacyPlatform.h"
18 EFI_SETUP_BBS_MAP mSetupBbsMap
[] = {
19 { 1, 2, 1, 1 }, // ATA HardDrive
20 { 2, 3, 1, 1 }, // ATAPI CDROM
21 { 3, 0x80, 2, 0 }, // PXE
22 { 4, 1, 0, 6 }, // USB Floppy
23 { 4, 2, 0, 6 }, // USB HDD
24 { 4, 3, 0, 6 }, // USB CD
25 { 4, 1, 0, 0 }, // USB ZIP Bugbug since Class/SubClass code is uninitialized
26 { 4, 2, 0, 0 } // USB ZIP Bugbug since Class/SubClass code is uninitialized
30 // Global variables for System ROMs
32 #define SYSTEM_ROM_FILE_GUID \
33 { 0x1547B4F3, 0x3E8A, 0x4FEF, { 0x81, 0xC8, 0x32, 0x8E, 0xD6, 0x47, 0xAB, 0x1A } }
35 #define NULL_ROM_FILE_GUID \
36 { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
38 SYSTEM_ROM_TABLE mSystemRomTable
[] = {
39 { SYSTEM_ROM_FILE_GUID
, 1 },
40 { NULL_ROM_FILE_GUID
, 0 }
43 EFI_HANDLE mVgaHandles
[0x20];
44 EFI_HANDLE mDiskHandles
[0x20];
45 EFI_HANDLE mIsaHandles
[0x20];
47 EFI_LEGACY_IRQ_PRIORITY_TABLE_ENTRY IrqPriorityTable
[MAX_IRQ_PRIORITY_ENTRIES
] = {
59 // - Slot numbering will be used to update the bus number and determine bridge
60 // to check to get bus number. The Slot number - 1 is an index into a decode
61 // table to get the bridge information.
63 EFI_LEGACY_PIRQ_TABLE PirqTableHead
= {
65 EFI_LEGACY_PIRQ_TABLE_SIGNATURE
, // UINT32 Signature
66 0x00, // UINT8 MinorVersion
67 0x01, // UINT8 MajorVersion
68 0x0000, // UINT16 TableSize
71 0x0000, // UINT16 PciOnlyIrq
72 0x8086, // UINT16 CompatibleVid
73 0x122e, // UINT16 CompatibleDid
74 0x00000000, // UINT32 Miniport
75 { // UINT8 Reserved[11]
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, // UINT8 Checksum
82 // -- Pin 1 -- -- Pin 2 -- -- Pin 3 -- -- Pin 4 --
83 // Bus Dev Reg Map Reg Map Reg Map Reg Map
85 {0x00,0x08,{{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8}},0x00,0x00},
86 {0x00,0x10,{{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8}},0x01,0x00},
87 {0x00,0x18,{{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8},{0x61,0xDEB8}},0x02,0x00},
88 {0x00,0x20,{{0x63,0xDEB8},{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8}},0x03,0x00},
89 {0x00,0x28,{{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8}},0x04,0x00},
90 {0x00,0x30,{{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8}},0x05,0x00},
94 LEGACY_BIOS_PLATFORM_INSTANCE mPrivateData
;
95 EFI_HANDLE mImageHandle
= NULL
;
98 Return the handles and assorted information for the specified PCI Class code
100 @param[in] PciClasses Array of PCI_CLASS_RECORD to find terminated with ClassCode 0xff
101 @param[in,out] DeviceTable Table to place handles etc in.
102 @param[in,out] DeviceIndex Number of devices found
103 @param[in] DeviceFlags FALSE if a valid legacy ROM is required, TRUE otherwise.
105 @retval EFI_SUCCESS One or more devices found
106 @retval EFI_NOT_FOUND No device found
111 IN PCI_CLASS_RECORD
*PciClasses
,
112 IN OUT DEVICE_STRUCTURE
*DeviceTable
,
113 IN OUT UINT16
*DeviceIndex
,
114 IN BOOLEAN DeviceFlags
118 EFI_HANDLE
*HandleBuffer
;
121 PCI_TYPE00 PciConfigHeader
;
122 EFI_PCI_IO_PROTOCOL
*PciIo
;
123 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
129 // Get legacy BIOS protocol as it is required to deal with Option ROMs.
131 StartIndex
= *DeviceIndex
;
132 Status
= gBS
->LocateProtocol (
133 &gEfiLegacyBiosProtocolGuid
,
137 ASSERT_EFI_ERROR (Status
);
140 // Get all PCI handles and check them to generate a list of matching devices.
142 gBS
->LocateHandleBuffer (
144 &gEfiPciIoProtocolGuid
,
149 for (Index
= 0; Index
< HandleCount
; Index
++) {
150 gBS
->HandleProtocol (
152 &gEfiPciIoProtocolGuid
,
159 sizeof (PciConfigHeader
) / sizeof (UINT32
),
162 for (Index2
= 0; PciClasses
[Index2
].Class
!= 0xff; Index2
++) {
163 if ((PciConfigHeader
.Hdr
.ClassCode
[2] == PciClasses
[Index2
].Class
) &&
164 (PciConfigHeader
.Hdr
.ClassCode
[1] == PciClasses
[Index2
].SubClass
)) {
165 LegacyBios
->CheckPciRom (
174 // Verify that results of OPROM check match request.
175 // The two valid requests are:
176 // DeviceFlags = 0 require a valid legacy ROM
177 // DeviceFlags = 1 require either no ROM or a valid legacy ROM
180 ((DeviceFlags
!= 0) && (Flags
== NO_ROM
)) ||
181 ((Flags
& (ROM_FOUND
| VALID_LEGACY_ROM
)) == (ROM_FOUND
| VALID_LEGACY_ROM
))
183 DeviceTable
->Handle
= HandleBuffer
[Index
];
184 DeviceTable
->Vid
= PciConfigHeader
.Hdr
.VendorId
;
185 DeviceTable
->Did
= PciConfigHeader
.Hdr
.DeviceId
;
186 DeviceTable
->SvId
= PciConfigHeader
.Device
.SubsystemVendorID
;
187 DeviceTable
->SysId
= PciConfigHeader
.Device
.SubsystemID
;
196 // Free any allocated buffers
198 gBS
->FreePool (HandleBuffer
);
200 if (*DeviceIndex
!= StartIndex
) {
203 return EFI_NOT_FOUND
;
208 Load and initialize the Legacy BIOS SMM handler.
210 @param This The protocol instance pointer.
211 @param EfiToLegacy16BootTable A pointer to Legacy16 boot table.
213 @retval EFI_SUCCESS SMM code loaded.
214 @retval EFI_DEVICE_ERROR SMM code failed to load
220 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
221 IN VOID
*EfiToLegacy16BootTable
228 Finds the device path that should be used as the primary display adapter.
230 @param VgaHandle - The handle of the video device
234 GetSelectedVgaDeviceInfo (
235 OUT EFI_HANDLE
*VgaHandle
240 EFI_HANDLE
*HandleBuffer
;
242 EFI_PCI_IO_PROTOCOL
*PciIo
;
250 UINTN SelectedAddress
;
251 UINTN CurrentAddress
;
254 // Initialize return to 'not found' state
259 // Initialize variable states. This is important for selecting the VGA
260 // device if multiple devices exist behind a single bridge.
264 SelectedAddress
= PCI_LIB_ADDRESS(0xff, 0x1f, 0x7, 0);
267 // The bus range to search for a VGA device in.
272 // Start to check all the pci io to find all possible VGA device
276 Status
= gBS
->LocateHandleBuffer (
278 &gEfiPciIoProtocolGuid
,
283 if (EFI_ERROR (Status
)) {
287 for (Index
= 0; Index
< HandleCount
; Index
++) {
288 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiPciIoProtocolGuid
, (VOID
**)&PciIo
);
289 if (!EFI_ERROR (Status
)) {
291 // Detemine if this is in the correct bus range.
293 Status
= PciIo
->GetLocation (PciIo
, &Segment
, &Bus
, &Device
, &Function
);
294 if (EFI_ERROR(Status
) || (Bus
< MinBus
|| Bus
> MaxBus
)) {
299 // Read device information.
301 Status
= PciIo
->Pci
.Read (
305 sizeof (Pci
) / sizeof (UINT32
),
308 if (EFI_ERROR (Status
)) {
313 // Make sure the device is a VGA device.
315 if (!IS_PCI_VGA (&Pci
)) {
319 "PCI VGA: 0x%04x:0x%04x\n",
325 // Currently we use the lowest numbered bus/device/function if multiple
326 // devices are found in the target bus range.
328 CurrentAddress
= PCI_LIB_ADDRESS(Bus
, Device
, Function
, 0);
329 if (CurrentAddress
< SelectedAddress
) {
330 SelectedAddress
= CurrentAddress
;
331 *VgaHandle
= HandleBuffer
[Index
];
336 FreePool (HandleBuffer
);
341 Returns a buffer of handles for the requested subfunction.
343 @param This The protocol instance pointer.
344 @param Mode Specifies what handle to return. See EFI_GET_PLATFORM_HANDLE_MODE enum.
345 @param Type Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
346 @param HandleBuffer Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
347 @param HandleCount Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
348 @param AdditionalData Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
350 @retval EFI_SUCCESS Handle is valid.
351 @retval EFI_UNSUPPORTED Mode is not supported on the platform.
352 @retval EFI_NOT_FOUND Handle is not known.
358 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
359 IN EFI_GET_PLATFORM_HANDLE_MODE Mode
,
361 OUT EFI_HANDLE
**HandleBuffer
,
362 OUT UINTN
*HandleCount
,
363 OUT VOID
**AdditionalData OPTIONAL
366 DEVICE_STRUCTURE LocalDevice
[0x40];
369 DEVICE_STRUCTURE TempDevice
;
371 EFI_PCI_IO_PROTOCOL
*PciIo
;
377 PCI_TYPE00 PciConfigHeader
;
379 EFI_HANDLE IdeHandle
;
380 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
381 PCI_CLASS_RECORD ClassLists
[10];
384 static BOOLEAN bConnected
= FALSE
;
390 Status
= gBS
->LocateProtocol (
391 &gEfiLegacyBiosProtocolGuid
,
397 // Process mode specific operations
400 case EfiGetPlatformVgaHandle
:
402 // Get the handle for the currently selected VGA device.
404 GetSelectedVgaDeviceInfo (&mVgaHandles
[0]);
405 *HandleBuffer
= &mVgaHandles
[0];
406 *HandleCount
= (mVgaHandles
[0] != NULL
) ? 1 : 0;
408 case EfiGetPlatformIdeHandle
:
410 if (AdditionalData
!= NULL
) {
411 HddInfo
= (HDD_INFO
*) *AdditionalData
;
415 // Locate all found block io devices
417 ClassLists
[0].Class
= PCI_CLASS_MASS_STORAGE
;
418 ClassLists
[0].SubClass
= PCI_CLASS_MASS_STORAGE_SCSI
;
419 ClassLists
[1].Class
= PCI_CLASS_MASS_STORAGE
;
420 ClassLists
[1].SubClass
= PCI_CLASS_MASS_STORAGE_IDE
;
421 ClassLists
[2].Class
= PCI_CLASS_MASS_STORAGE
;
422 ClassLists
[2].SubClass
= PCI_CLASS_MASS_STORAGE_RAID
;
423 ClassLists
[3].Class
= PCI_CLASS_MASS_STORAGE
;
424 ClassLists
[3].SubClass
= PCI_CLASS_MASS_STORAGE_SATADPA
;
425 ClassLists
[4].Class
= 0xff;
426 FindAllDeviceTypes (ClassLists
, LocalDevice
, (UINT16
*) &LocalIndex
, TRUE
);
427 if (LocalIndex
== 0) {
428 return EFI_NOT_FOUND
;
432 // Make sure all IDE controllers are connected. This is necessary
433 // in NO_CONFIG_CHANGE boot path to ensure IDE controller is correctly
434 // initialized and all IDE drives are enumerated
437 for (Index
= 0; Index
< LocalIndex
; Index
++) {
438 gBS
->ConnectController (LocalDevice
[Index
].Handle
, NULL
, NULL
, TRUE
);
443 // Locate onboard controllers.
445 for (Index
= 0; Index
< LocalIndex
; Index
++) {
446 if (LocalDevice
[Index
].Vid
== V_INTEL_VENDOR_ID
) {
447 if (LocalDevice
[Index
].Did
== V_PIIX4_IDE_DEVICE_ID
) {
448 IdeHandle
= LocalDevice
[Index
].Handle
;
454 // Set the IDE contorller as primary devices.
457 for (Index
= 0; Index
< LocalIndex
; Index
++) {
458 if (LocalDevice
[Index
].Handle
== IdeHandle
&& PriorityIndex
== 0) {
459 TempDevice
= LocalDevice
[PriorityIndex
];
460 LocalDevice
[PriorityIndex
] = LocalDevice
[Index
];
461 LocalDevice
[Index
] = TempDevice
;
468 // Copy over handles and update return values.
470 for (Index
= 0; Index
< LocalIndex
; Index
++) {
471 mDiskHandles
[Index
] = LocalDevice
[Index
].Handle
;
473 *HandleBuffer
= &mDiskHandles
[0];
474 *HandleCount
= LocalIndex
;
477 // We have connected all IDE controllers once. No more needed
482 // Log all onboard controllers.
484 for (Index
= 0; (Index
< LocalIndex
) && (AdditionalData
!= NULL
); Index
++) {
485 if ((LocalDevice
[Index
].Handle
!= NULL
) &&
486 (LocalDevice
[Index
].Handle
== IdeHandle
)) {
487 Status
= gBS
->HandleProtocol (
488 LocalDevice
[Index
].Handle
,
489 &gEfiPciIoProtocolGuid
,
496 sizeof (PciConfigHeader
) / sizeof (UINT32
),
499 if (!EFI_ERROR (Status
)) {
509 // Be sure to only fill out correct information based on platform
512 HddInfo
[HddIndex
].Status
|= HDD_PRIMARY
;
513 HddInfo
[HddIndex
].Bus
= (UINT32
)Bus
;
514 HddInfo
[HddIndex
].Device
= (UINT32
)Device
;
515 HddInfo
[HddIndex
].Function
= (UINT32
)Function
;
516 HddInfo
[HddIndex
+ 1].Status
|= HDD_SECONDARY
;
517 HddInfo
[HddIndex
+ 1].Bus
= (UINT32
)Bus
;
518 HddInfo
[HddIndex
+ 1].Device
= (UINT32
)Device
;
519 HddInfo
[HddIndex
+ 1].Function
= (UINT32
)Function
;
522 // Primary controller data
524 if ((PciConfigHeader
.Hdr
.ClassCode
[0] & 0x01) != 0) {
525 HddInfo
[HddIndex
].CommandBaseAddress
=
526 (UINT16
)(PciConfigHeader
.Device
.Bar
[0] & 0xfffc);
527 HddInfo
[HddIndex
].ControlBaseAddress
=
528 (UINT16
)((PciConfigHeader
.Device
.Bar
[1] & 0xfffc)+2);
529 HddInfo
[HddIndex
].BusMasterAddress
=
530 (UINT16
)(PciConfigHeader
.Device
.Bar
[4] & 0xfffc);
531 HddInfo
[HddIndex
].HddIrq
= PciConfigHeader
.Device
.InterruptLine
;
533 HddInfo
[HddIndex
].HddIrq
= 14;
534 HddInfo
[HddIndex
].CommandBaseAddress
= 0x1f0;
535 HddInfo
[HddIndex
].ControlBaseAddress
= 0x3f6;
536 HddInfo
[HddIndex
].BusMasterAddress
= 0;
541 // Secondary controller data
543 if ((PciConfigHeader
.Hdr
.ClassCode
[0] & 0x04) != 0) {
544 HddInfo
[HddIndex
].CommandBaseAddress
=
545 (UINT16
)(PciConfigHeader
.Device
.Bar
[2] & 0xfffc);
546 HddInfo
[HddIndex
].ControlBaseAddress
=
547 (UINT16
)((PciConfigHeader
.Device
.Bar
[3] & 0xfffc)+2);
548 HddInfo
[HddIndex
].BusMasterAddress
=
549 (UINT16
)(HddInfo
[HddIndex
].BusMasterAddress
+ 8);
550 HddInfo
[HddIndex
].HddIrq
= PciConfigHeader
.Device
.InterruptLine
;
552 HddInfo
[HddIndex
].HddIrq
= 15;
553 HddInfo
[HddIndex
].CommandBaseAddress
= 0x170;
554 HddInfo
[HddIndex
].ControlBaseAddress
= 0x376;
555 HddInfo
[HddIndex
].BusMasterAddress
= 0;
562 case EfiGetPlatformIsaBusHandle
:
563 ClassLists
[0].Class
= (UINT8
) PCI_CLASS_BRIDGE
;
564 ClassLists
[0].SubClass
= (UINT8
) PCI_CLASS_BRIDGE_ISA_PDECODE
;
565 ClassLists
[1].Class
= (UINT8
) PCI_CLASS_BRIDGE
;
566 ClassLists
[1].SubClass
= (UINT8
) PCI_CLASS_BRIDGE_ISA
;
567 ClassLists
[2].Class
= 0xff;
570 // Locate all found block io devices
572 FindAllDeviceTypes (ClassLists
, LocalDevice
, (UINT16
*) (&LocalIndex
), TRUE
);
573 if (LocalIndex
== 0) {
574 return EFI_NOT_FOUND
;
578 // Find our ISA bridge.
580 for (Index
= 0; Index
< LocalIndex
; Index
++) {
581 if (LocalDevice
[Index
].Vid
== V_INTEL_VENDOR_ID
) {
582 TempDevice
= LocalDevice
[0];
583 LocalDevice
[0] = LocalDevice
[Index
];
584 LocalDevice
[Index
] = TempDevice
;
589 // Perform copy and update return values.
591 for (Index
= 0; Index
< LocalIndex
; Index
++) {
592 mIsaHandles
[Index
] = LocalDevice
[Index
].Handle
;
594 *HandleBuffer
= &mIsaHandles
[0];
595 *HandleCount
= LocalIndex
;
597 case EfiGetPlatformUsbHandle
:
599 return EFI_UNSUPPORTED
;
604 Allows platform to perform any required action after a LegacyBios operation.
605 Invokes the specific sub function specified by Mode.
607 @param This The protocol instance pointer.
608 @param Mode Specifies what handle to return. See EFI_GET_PLATFORM_HOOK_MODE enum.
609 @param Type Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.
610 @param DeviceHandle Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.
611 @param ShadowAddress Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.
612 @param Compatibility16Table Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.
613 @param AdditionalData Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.
615 @retval EFI_SUCCESS The operation performed successfully. Mode specific.
616 @retval EFI_UNSUPPORTED Mode is not supported on the platform.
622 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
623 IN EFI_GET_PLATFORM_HOOK_MODE Mode
,
625 OUT EFI_HANDLE DeviceHandle
, OPTIONAL
626 IN OUT UINTN
*Shadowaddress
, OPTIONAL
627 IN EFI_COMPATIBILITY16_TABLE
*Compatibility16Table
, OPTIONAL
628 OUT VOID
**AdditionalData OPTIONAL
631 EFI_IA32_REGISTER_SET Regs
;
632 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
636 case EfiPlatformHookPrepareToScanRom
:
637 Status
= gBS
->LocateProtocol (
638 &gEfiLegacyBiosProtocolGuid
,
644 // Set the 80x25 Text VGA Mode
648 Status
= LegacyBios
->Int86 (LegacyBios
, 0x10, &Regs
);
650 case EfiPlatformHookShadowServiceRoms
:
652 case EfiPlatformHookAfterRomInit
:
654 return EFI_UNSUPPORTED
;
659 Returns information associated with PCI IRQ routing.
660 This function returns the following information associated with PCI IRQ routing:
661 * An IRQ routing table and number of entries in the table.
662 * The $PIR table and its size.
663 * A list of PCI IRQs and the priority order to assign them.
665 @param This The protocol instance pointer.
666 @param RoutingTable The pointer to PCI IRQ Routing table.
667 This location is the $PIR table minus the header.
668 @param RoutingTableEntries The number of entries in table.
669 @param LocalPirqTable $PIR table.
670 @param PirqTableSize $PIR table size.
671 @param LocalIrqPriorityTable A list of interrupts in priority order to assign.
672 @param IrqPriorityTableEntries The number of entries in the priority table.
674 @retval EFI_SUCCESS Data was successfully returned.
680 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
681 OUT VOID
**RoutingTable
,
682 OUT UINTN
*RoutingTableEntries
,
683 OUT VOID
**LocalPirqTable
, OPTIONAL
684 OUT UINTN
*PirqTableSize
, OPTIONAL
685 OUT VOID
**LocalIrqPriorityTable
, OPTIONAL
686 OUT UINTN
*IrqPriorityTableEntries OPTIONAL
697 EFI_LEGACY_INTERRUPT_PROTOCOL
*LegacyInterrupt
;
701 if (LocalPirqTable
!= NULL
) {
702 PTableSize
= sizeof (EFI_LEGACY_PIRQ_TABLE_HEADER
) +
703 sizeof (EFI_LEGACY_IRQ_ROUTING_ENTRY
) * MAX_IRQ_ROUTING_ENTRIES
;
705 Status
= gBS
->LocateProtocol (
706 &gEfiLegacyInterruptProtocolGuid
,
708 (VOID
**)&LegacyInterrupt
710 ASSERT_EFI_ERROR (Status
);
711 LegacyInterrupt
->GetLocation (
719 // Update fields in $PIR table header
721 PirqTableHead
.PirqTable
.TableSize
= PTableSize
;
722 PirqTableHead
.PirqTable
.Bus
= Bus
;
723 PirqTableHead
.PirqTable
.DevFun
= (UINT8
) ((Device
<< 3) + Function
);
724 Ptr
= (UINT8
*) (&PirqTableHead
);
727 // Calculate checksum.
729 for (Index
= 0; Index
< PTableSize
; Index
++) {
730 Checksum
= (UINT8
) (Checksum
+ (UINT8
) *Ptr
);
733 Checksum
= (UINT8
) (0x00 - Checksum
);
734 PirqTableHead
.PirqTable
.Checksum
= Checksum
;
737 // Update return values.
739 *LocalPirqTable
= (VOID
*) (&PirqTableHead
);
740 *PirqTableSize
= PTableSize
;
744 // More items to return.
746 *RoutingTable
= PirqTableHead
.IrqRoutingEntry
;
747 *RoutingTableEntries
= MAX_IRQ_ROUTING_ENTRIES
;
748 if (LocalIrqPriorityTable
!= NULL
) {
749 *LocalIrqPriorityTable
= IrqPriorityTable
;
750 *IrqPriorityTableEntries
= MAX_IRQ_PRIORITY_ENTRIES
;
757 Finds the binary data or other platform information.
759 @param This The protocol instance pointer.
760 @param Mode Specifies what data to return. See See EFI_GET_PLATFORM_INFO_MODE enum.
761 @param Table Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
762 @param TableSize Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
763 @param Location Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
764 @param Alignment Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
765 @param LegacySegment Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
766 @param LegacyOffset Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
768 @retval EFI_SUCCESS Data returned successfully.
769 @retval EFI_UNSUPPORTED Mode is not supported on the platform.
770 @retval EFI_NOT_FOUND Binary image or table not found.
776 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
777 IN EFI_GET_PLATFORM_INFO_MODE Mode
,
779 OUT UINTN
*TableSize
,
781 OUT UINTN
*Alignment
,
782 IN UINT16 LegacySegment
,
783 IN UINT16 LegacyOffset
790 case EfiGetPlatformBinarySystemRom
:
792 // Loop through table of System rom descriptions
794 for (Index
= 0; mSystemRomTable
[Index
].Valid
!= 0; Index
++) {
795 Status
= GetSectionFromFv (
796 &mSystemRomTable
[Index
].FileName
,
802 if (EFI_ERROR (Status
)) {
808 return EFI_NOT_FOUND
;
809 case EfiGetPlatformBinaryOem16Data
:
810 case EfiGetPlatformBinaryMpTable
:
811 case EfiGetPlatformBinaryOemIntData
:
812 case EfiGetPlatformBinaryOem32Data
:
813 case EfiGetPlatformBinaryTpmBinary
:
814 case EfiGetPlatformPciExpressBase
:
816 return EFI_UNSUPPORTED
;
821 Translates the given PIRQ accounting for bridge.
822 This function translates the given PIRQ back through all buses, if required,
823 and returns the true PIRQ and associated IRQ.
825 @param This The protocol instance pointer.
826 @param PciBus The PCI bus number for this device.
827 @param PciDevice The PCI device number for this device.
828 @param PciFunction The PCI function number for this device.
829 @param Pirq Input is PIRQ reported by device, and output is true PIRQ.
830 @param PciIrq The IRQ already assigned to the PIRQ, or the IRQ to be
831 assigned to the PIRQ.
833 @retval EFI_SUCCESS The PIRQ was translated.
839 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
842 IN UINTN PciFunction
,
847 EFI_LEGACY_INTERRUPT_PROTOCOL
*LegacyInterrupt
;
855 Status
= gBS
->LocateProtocol (
856 &gEfiLegacyInterruptProtocolGuid
,
858 (VOID
**)&LegacyInterrupt
860 ASSERT_EFI_ERROR (Status
);
861 LocalPirq
= (UINT8
) (*Pirq
);
863 for (Index
= 0; Index
< MAX_IRQ_ROUTING_ENTRIES
; Index
++) {
864 if ((PirqTableHead
.IrqRoutingEntry
[Index
].Bus
== PciBus
) &&
865 (PirqTableHead
.IrqRoutingEntry
[Index
].Device
== PciDevice
)) {
866 LocalPirq
= (UINT8
) (PirqTableHead
.IrqRoutingEntry
[Index
].PirqEntry
[LocalPirq
].Pirq
& 0x0f);
871 LegacyInterrupt
->ReadPirq (LegacyInterrupt
, LocalPirq
, &PirqData
);
872 MatchData
= PCI_UNUSED
;
873 while (PirqData
== 0) {
874 for (Index1
= 0; Index1
< MAX_IRQ_PRIORITY_ENTRIES
; Index1
++) {
875 if ((IrqPriorityTable
[Index1
].Used
== MatchData
) &&
876 (IrqPriorityTable
[Index1
].Irq
!= 0)) {
877 PirqData
= IrqPriorityTable
[Index1
].Irq
;
878 IrqPriorityTable
[Index1
].Used
= 0xff;
879 LegacyInterrupt
->WritePirq (
891 // No unused interrpts, so start reusing them.
893 MatchData
= (UINT8
) (~MatchData
);
907 Attempt to legacy boot the BootOption. If the EFI contexted has been
908 compromised this function will not return.
910 @param This The protocol instance pointer.
911 @param BbsDevicePath The EFI Device Path from BootXXXX variable.
912 @param BbsTable The Internal BBS table.
913 @param LoadOptionSize The size of LoadOption in size.
914 @param LoadOption The LoadOption from BootXXXX variable
915 @param EfiToLegacy16BootTable A pointer to BootTable structure
917 @retval EFI_SUCCESS Ready to boot.
923 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
924 IN BBS_BBS_DEVICE_PATH
*BbsDevicePath
,
926 IN UINT32 LoadOptionsSize
,
927 IN VOID
*LoadOptions
,
928 IN VOID
*EfiToLegacy16BootTable
931 BBS_TABLE
*LocalBbsTable
;
932 EFI_TO_COMPATIBILITY16_BOOT_TABLE
*Legacy16BootTable
;
933 DEVICE_PRODUCER_DATA_HEADER
*SioPtr
;
934 UINT16 DevicePathType
;
942 Legacy16BootTable
= (EFI_TO_COMPATIBILITY16_BOOT_TABLE
*) EfiToLegacy16BootTable
;
945 // Set how Gate A20 is gated by hardware
947 SioPtr
= &Legacy16BootTable
->SioData
;
948 SioPtr
->Flags
.A20Kybd
= 1;
949 SioPtr
->Flags
.A20Port90
= 1;
950 SioPtr
->MousePresent
= 1;
952 LocalBbsTable
= BbsTable
;
955 // There are 2 cases that must be covered.
956 // Case 1: Booting to a legacy OS - BbsDevicePath is non-NULL.
957 // Case 2: Booting to an EFI aware OS - BbsDevicePath is NULL.
958 // We need to perform the PrepareToBoot function to assign
959 // drive numbers to HDD devices to allow the shell or EFI
962 if (BbsDevicePath
!= NULL
) {
963 DevicePathType
= BbsDevicePath
->DeviceType
;
965 DevicePathType
= BBS_HARDDISK
;
969 // Skip the boot devices where priority is set by BDS and set the next one
971 for (Index
= 0; Index
< Legacy16BootTable
->NumberBbsEntries
; Index
++) {
972 if ((LocalBbsTable
[Index
].BootPriority
!= BBS_UNPRIORITIZED_ENTRY
) &&
973 (LocalBbsTable
[Index
].BootPriority
!= BBS_IGNORE_ENTRY
) &&
974 (LocalBbsTable
[Index
].BootPriority
!= BBS_LOWEST_PRIORITY
) &&
975 (Priority
<= LocalBbsTable
[Index
].BootPriority
)) {
976 Priority
= (UINT16
) (LocalBbsTable
[Index
].BootPriority
+ 1);
980 switch (DevicePathType
) {
984 case BBS_EMBED_NETWORK
:
985 for (Index
= 0; Index
< Legacy16BootTable
->NumberBbsEntries
; Index
++) {
986 if ((LocalBbsTable
[Index
].BootPriority
== BBS_UNPRIORITIZED_ENTRY
) &&
987 (LocalBbsTable
[Index
].DeviceType
== DevicePathType
)) {
988 LocalBbsTable
[Index
].BootPriority
= Priority
;
994 for (Index
= 0; Index
< Legacy16BootTable
->NumberBbsEntries
; Index
++) {
995 if ((LocalBbsTable
[Index
].BootPriority
== BBS_UNPRIORITIZED_ENTRY
) &&
996 (LocalBbsTable
[Index
].Class
== 01) &&
997 (LocalBbsTable
[Index
].SubClass
== 01)) {
998 LocalBbsTable
[Index
].BootPriority
= Priority
;
1011 // Set priority for rest of devices
1013 for (Index
= 0; Index
< Legacy16BootTable
->NumberBbsEntries
; Index
++) {
1014 if (LocalBbsTable
[Index
].BootPriority
== BBS_UNPRIORITIZED_ENTRY
) {
1015 LocalBbsTable
[Index
].BootPriority
= Priority
;
1025 Initialize Legacy Platform support
1027 @retval EFI_SUCCESS Successfully initialized
1031 LegacyBiosPlatformInstall (
1036 LEGACY_BIOS_PLATFORM_INSTANCE
*Private
;
1038 mImageHandle
= gImageHandle
;
1039 Private
= &mPrivateData
;
1042 // Grab a copy of all the protocols we depend on.
1044 Private
->Signature
= LEGACY_BIOS_PLATFORM_INSTANCE_SIGNATURE
;
1045 Private
->LegacyBiosPlatform
.GetPlatformInfo
= GetPlatformInfo
;
1046 Private
->LegacyBiosPlatform
.GetPlatformHandle
= GetPlatformHandle
;
1047 Private
->LegacyBiosPlatform
.SmmInit
= SmmInit
;
1048 Private
->LegacyBiosPlatform
.PlatformHooks
= PlatformHooks
;
1049 Private
->LegacyBiosPlatform
.GetRoutingTable
= GetRoutingTable
;
1050 Private
->LegacyBiosPlatform
.TranslatePirq
= TranslatePirq
;
1051 Private
->LegacyBiosPlatform
.PrepareToBoot
= PrepareToBoot
;
1052 Private
->ImageHandle
= gImageHandle
;
1055 // Make a new handle and install the protocol
1057 Private
->Handle
= NULL
;
1058 Status
= gBS
->InstallProtocolInterface (
1060 &gEfiLegacyBiosPlatformProtocolGuid
,
1061 EFI_NATIVE_INTERFACE
,
1062 &Private
->LegacyBiosPlatform