2 Legacy BIOS Platform support
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "LegacyPlatform.h"
12 EFI_SETUP_BBS_MAP mSetupBbsMap
[] = {
13 { 1, 2, 1, 1 }, // ATA HardDrive
14 { 2, 3, 1, 1 }, // ATAPI CDROM
15 { 3, 0x80, 2, 0 }, // PXE
16 { 4, 1, 0, 6 }, // USB Floppy
17 { 4, 2, 0, 6 }, // USB HDD
18 { 4, 3, 0, 6 }, // USB CD
19 { 4, 1, 0, 0 }, // USB ZIP Bugbug since Class/SubClass code is uninitialized
20 { 4, 2, 0, 0 } // USB ZIP Bugbug since Class/SubClass code is uninitialized
24 // Global variables for System ROMs
26 #define SYSTEM_ROM_FILE_GUID \
27 { 0x1547B4F3, 0x3E8A, 0x4FEF, { 0x81, 0xC8, 0x32, 0x8E, 0xD6, 0x47, 0xAB, 0x1A } }
29 #define NULL_ROM_FILE_GUID \
30 { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
32 SYSTEM_ROM_TABLE mSystemRomTable
[] = {
33 { SYSTEM_ROM_FILE_GUID
, 1 },
34 { NULL_ROM_FILE_GUID
, 0 }
37 EFI_HANDLE mVgaHandles
[0x20];
38 EFI_HANDLE mDiskHandles
[0x20];
39 EFI_HANDLE mIsaHandles
[0x20];
41 EFI_LEGACY_IRQ_PRIORITY_TABLE_ENTRY IrqPriorityTable
[MAX_IRQ_PRIORITY_ENTRIES
] = {
53 // - Slot numbering will be used to update the bus number and determine bridge
54 // to check to get bus number. The Slot number - 1 is an index into a decode
55 // table to get the bridge information.
57 EFI_LEGACY_PIRQ_TABLE PirqTableHead
= {
59 EFI_LEGACY_PIRQ_TABLE_SIGNATURE
, // UINT32 Signature
60 0x00, // UINT8 MinorVersion
61 0x01, // UINT8 MajorVersion
62 0x0000, // UINT16 TableSize
65 0x0000, // UINT16 PciOnlyIrq
66 0x8086, // UINT16 CompatibleVid
67 0x122e, // UINT16 CompatibleDid
68 0x00000000, // UINT32 Miniport
69 { // UINT8 Reserved[11]
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, // UINT8 Checksum
76 // -- Pin 1 -- -- Pin 2 -- -- Pin 3 -- -- Pin 4 --
77 // Bus Dev Reg Map Reg Map Reg Map Reg Map
79 {0x00,0x08,{{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8}},0x00,0x00},
80 {0x00,0x10,{{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8}},0x01,0x00},
81 {0x00,0x18,{{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8},{0x61,0xDEB8}},0x02,0x00},
82 {0x00,0x20,{{0x63,0xDEB8},{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8}},0x03,0x00},
83 {0x00,0x28,{{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8}},0x04,0x00},
84 {0x00,0x30,{{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8}},0x05,0x00},
88 LEGACY_BIOS_PLATFORM_INSTANCE mPrivateData
;
89 EFI_HANDLE mImageHandle
= NULL
;
92 Return the handles and assorted information for the specified PCI Class code
94 @param[in] PciClasses Array of PCI_CLASS_RECORD to find terminated with ClassCode 0xff
95 @param[in,out] DeviceTable Table to place handles etc in.
96 @param[in,out] DeviceIndex Number of devices found
97 @param[in] DeviceFlags FALSE if a valid legacy ROM is required, TRUE otherwise.
99 @retval EFI_SUCCESS One or more devices found
100 @retval EFI_NOT_FOUND No device found
105 IN PCI_CLASS_RECORD
*PciClasses
,
106 IN OUT DEVICE_STRUCTURE
*DeviceTable
,
107 IN OUT UINT16
*DeviceIndex
,
108 IN BOOLEAN DeviceFlags
112 EFI_HANDLE
*HandleBuffer
;
115 PCI_TYPE00 PciConfigHeader
;
116 EFI_PCI_IO_PROTOCOL
*PciIo
;
117 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
123 // Get legacy BIOS protocol as it is required to deal with Option ROMs.
125 StartIndex
= *DeviceIndex
;
126 Status
= gBS
->LocateProtocol (
127 &gEfiLegacyBiosProtocolGuid
,
131 ASSERT_EFI_ERROR (Status
);
134 // Get all PCI handles and check them to generate a list of matching devices.
136 gBS
->LocateHandleBuffer (
138 &gEfiPciIoProtocolGuid
,
143 for (Index
= 0; Index
< HandleCount
; Index
++) {
144 gBS
->HandleProtocol (
146 &gEfiPciIoProtocolGuid
,
153 sizeof (PciConfigHeader
) / sizeof (UINT32
),
156 for (Index2
= 0; PciClasses
[Index2
].Class
!= 0xff; Index2
++) {
157 if ((PciConfigHeader
.Hdr
.ClassCode
[2] == PciClasses
[Index2
].Class
) &&
158 (PciConfigHeader
.Hdr
.ClassCode
[1] == PciClasses
[Index2
].SubClass
)) {
159 LegacyBios
->CheckPciRom (
168 // Verify that results of OPROM check match request.
169 // The two valid requests are:
170 // DeviceFlags = 0 require a valid legacy ROM
171 // DeviceFlags = 1 require either no ROM or a valid legacy ROM
174 ((DeviceFlags
!= 0) && (Flags
== NO_ROM
)) ||
175 ((Flags
& (ROM_FOUND
| VALID_LEGACY_ROM
)) == (ROM_FOUND
| VALID_LEGACY_ROM
))
177 DeviceTable
->Handle
= HandleBuffer
[Index
];
178 DeviceTable
->Vid
= PciConfigHeader
.Hdr
.VendorId
;
179 DeviceTable
->Did
= PciConfigHeader
.Hdr
.DeviceId
;
180 DeviceTable
->SvId
= PciConfigHeader
.Device
.SubsystemVendorID
;
181 DeviceTable
->SysId
= PciConfigHeader
.Device
.SubsystemID
;
190 // Free any allocated buffers
192 gBS
->FreePool (HandleBuffer
);
194 if (*DeviceIndex
!= StartIndex
) {
197 return EFI_NOT_FOUND
;
202 Load and initialize the Legacy BIOS SMM handler.
204 @param This The protocol instance pointer.
205 @param EfiToLegacy16BootTable A pointer to Legacy16 boot table.
207 @retval EFI_SUCCESS SMM code loaded.
208 @retval EFI_DEVICE_ERROR SMM code failed to load
214 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
215 IN VOID
*EfiToLegacy16BootTable
222 Finds the device path that should be used as the primary display adapter.
224 @param VgaHandle - The handle of the video device
228 GetSelectedVgaDeviceInfo (
229 OUT EFI_HANDLE
*VgaHandle
234 EFI_HANDLE
*HandleBuffer
;
236 EFI_PCI_IO_PROTOCOL
*PciIo
;
244 UINTN SelectedAddress
;
245 UINTN CurrentAddress
;
248 // Initialize return to 'not found' state
253 // Initialize variable states. This is important for selecting the VGA
254 // device if multiple devices exist behind a single bridge.
258 SelectedAddress
= PCI_LIB_ADDRESS(0xff, 0x1f, 0x7, 0);
261 // The bus range to search for a VGA device in.
266 // Start to check all the pci io to find all possible VGA device
270 Status
= gBS
->LocateHandleBuffer (
272 &gEfiPciIoProtocolGuid
,
277 if (EFI_ERROR (Status
)) {
281 for (Index
= 0; Index
< HandleCount
; Index
++) {
282 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiPciIoProtocolGuid
, (VOID
**)&PciIo
);
283 if (!EFI_ERROR (Status
)) {
285 // Detemine if this is in the correct bus range.
287 Status
= PciIo
->GetLocation (PciIo
, &Segment
, &Bus
, &Device
, &Function
);
288 if (EFI_ERROR(Status
) || (Bus
< MinBus
|| Bus
> MaxBus
)) {
293 // Read device information.
295 Status
= PciIo
->Pci
.Read (
299 sizeof (Pci
) / sizeof (UINT32
),
302 if (EFI_ERROR (Status
)) {
307 // Make sure the device is a VGA device.
309 if (!IS_PCI_VGA (&Pci
)) {
313 "PCI VGA: 0x%04x:0x%04x\n",
319 // Currently we use the lowest numbered bus/device/function if multiple
320 // devices are found in the target bus range.
322 CurrentAddress
= PCI_LIB_ADDRESS(Bus
, Device
, Function
, 0);
323 if (CurrentAddress
< SelectedAddress
) {
324 SelectedAddress
= CurrentAddress
;
325 *VgaHandle
= HandleBuffer
[Index
];
330 FreePool (HandleBuffer
);
335 Returns a buffer of handles for the requested subfunction.
337 @param This The protocol instance pointer.
338 @param Mode Specifies what handle to return. See EFI_GET_PLATFORM_HANDLE_MODE enum.
339 @param Type Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
340 @param HandleBuffer Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
341 @param HandleCount Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
342 @param AdditionalData Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
344 @retval EFI_SUCCESS Handle is valid.
345 @retval EFI_UNSUPPORTED Mode is not supported on the platform.
346 @retval EFI_NOT_FOUND Handle is not known.
352 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
353 IN EFI_GET_PLATFORM_HANDLE_MODE Mode
,
355 OUT EFI_HANDLE
**HandleBuffer
,
356 OUT UINTN
*HandleCount
,
357 OUT VOID
**AdditionalData OPTIONAL
360 DEVICE_STRUCTURE LocalDevice
[0x40];
363 DEVICE_STRUCTURE TempDevice
;
365 EFI_PCI_IO_PROTOCOL
*PciIo
;
371 PCI_TYPE00 PciConfigHeader
;
373 EFI_HANDLE IdeHandle
;
374 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
375 PCI_CLASS_RECORD ClassLists
[10];
378 static BOOLEAN bConnected
= FALSE
;
384 Status
= gBS
->LocateProtocol (
385 &gEfiLegacyBiosProtocolGuid
,
391 // Process mode specific operations
394 case EfiGetPlatformVgaHandle
:
396 // Get the handle for the currently selected VGA device.
398 GetSelectedVgaDeviceInfo (&mVgaHandles
[0]);
399 *HandleBuffer
= &mVgaHandles
[0];
400 *HandleCount
= (mVgaHandles
[0] != NULL
) ? 1 : 0;
402 case EfiGetPlatformIdeHandle
:
404 if (AdditionalData
!= NULL
) {
405 HddInfo
= (HDD_INFO
*) *AdditionalData
;
409 // Locate all found block io devices
411 ClassLists
[0].Class
= PCI_CLASS_MASS_STORAGE
;
412 ClassLists
[0].SubClass
= PCI_CLASS_MASS_STORAGE_SCSI
;
413 ClassLists
[1].Class
= PCI_CLASS_MASS_STORAGE
;
414 ClassLists
[1].SubClass
= PCI_CLASS_MASS_STORAGE_IDE
;
415 ClassLists
[2].Class
= PCI_CLASS_MASS_STORAGE
;
416 ClassLists
[2].SubClass
= PCI_CLASS_MASS_STORAGE_RAID
;
417 ClassLists
[3].Class
= PCI_CLASS_MASS_STORAGE
;
418 ClassLists
[3].SubClass
= PCI_CLASS_MASS_STORAGE_SATADPA
;
419 ClassLists
[4].Class
= 0xff;
420 FindAllDeviceTypes (ClassLists
, LocalDevice
, (UINT16
*) &LocalIndex
, TRUE
);
421 if (LocalIndex
== 0) {
422 return EFI_NOT_FOUND
;
426 // Make sure all IDE controllers are connected. This is necessary
427 // in NO_CONFIG_CHANGE boot path to ensure IDE controller is correctly
428 // initialized and all IDE drives are enumerated
431 for (Index
= 0; Index
< LocalIndex
; Index
++) {
432 gBS
->ConnectController (LocalDevice
[Index
].Handle
, NULL
, NULL
, TRUE
);
437 // Locate onboard controllers.
439 for (Index
= 0; Index
< LocalIndex
; Index
++) {
440 if (LocalDevice
[Index
].Vid
== V_INTEL_VENDOR_ID
) {
441 if (LocalDevice
[Index
].Did
== V_PIIX4_IDE_DEVICE_ID
) {
442 IdeHandle
= LocalDevice
[Index
].Handle
;
448 // Set the IDE contorller as primary devices.
451 for (Index
= 0; Index
< LocalIndex
; Index
++) {
452 if (LocalDevice
[Index
].Handle
== IdeHandle
&& PriorityIndex
== 0) {
453 TempDevice
= LocalDevice
[PriorityIndex
];
454 LocalDevice
[PriorityIndex
] = LocalDevice
[Index
];
455 LocalDevice
[Index
] = TempDevice
;
462 // Copy over handles and update return values.
464 for (Index
= 0; Index
< LocalIndex
; Index
++) {
465 mDiskHandles
[Index
] = LocalDevice
[Index
].Handle
;
467 *HandleBuffer
= &mDiskHandles
[0];
468 *HandleCount
= LocalIndex
;
471 // We have connected all IDE controllers once. No more needed
476 // Log all onboard controllers.
478 for (Index
= 0; (Index
< LocalIndex
) && (AdditionalData
!= NULL
); Index
++) {
479 if ((LocalDevice
[Index
].Handle
!= NULL
) &&
480 (LocalDevice
[Index
].Handle
== IdeHandle
)) {
481 Status
= gBS
->HandleProtocol (
482 LocalDevice
[Index
].Handle
,
483 &gEfiPciIoProtocolGuid
,
490 sizeof (PciConfigHeader
) / sizeof (UINT32
),
493 if (!EFI_ERROR (Status
)) {
503 // Be sure to only fill out correct information based on platform
506 HddInfo
[HddIndex
].Status
|= HDD_PRIMARY
;
507 HddInfo
[HddIndex
].Bus
= (UINT32
)Bus
;
508 HddInfo
[HddIndex
].Device
= (UINT32
)Device
;
509 HddInfo
[HddIndex
].Function
= (UINT32
)Function
;
510 HddInfo
[HddIndex
+ 1].Status
|= HDD_SECONDARY
;
511 HddInfo
[HddIndex
+ 1].Bus
= (UINT32
)Bus
;
512 HddInfo
[HddIndex
+ 1].Device
= (UINT32
)Device
;
513 HddInfo
[HddIndex
+ 1].Function
= (UINT32
)Function
;
516 // Primary controller data
518 if ((PciConfigHeader
.Hdr
.ClassCode
[0] & 0x01) != 0) {
519 HddInfo
[HddIndex
].CommandBaseAddress
=
520 (UINT16
)(PciConfigHeader
.Device
.Bar
[0] & 0xfffc);
521 HddInfo
[HddIndex
].ControlBaseAddress
=
522 (UINT16
)((PciConfigHeader
.Device
.Bar
[1] & 0xfffc)+2);
523 HddInfo
[HddIndex
].BusMasterAddress
=
524 (UINT16
)(PciConfigHeader
.Device
.Bar
[4] & 0xfffc);
525 HddInfo
[HddIndex
].HddIrq
= PciConfigHeader
.Device
.InterruptLine
;
527 HddInfo
[HddIndex
].HddIrq
= 14;
528 HddInfo
[HddIndex
].CommandBaseAddress
= 0x1f0;
529 HddInfo
[HddIndex
].ControlBaseAddress
= 0x3f6;
530 HddInfo
[HddIndex
].BusMasterAddress
= 0;
535 // Secondary controller data
537 if ((PciConfigHeader
.Hdr
.ClassCode
[0] & 0x04) != 0) {
538 HddInfo
[HddIndex
].CommandBaseAddress
=
539 (UINT16
)(PciConfigHeader
.Device
.Bar
[2] & 0xfffc);
540 HddInfo
[HddIndex
].ControlBaseAddress
=
541 (UINT16
)((PciConfigHeader
.Device
.Bar
[3] & 0xfffc)+2);
542 HddInfo
[HddIndex
].BusMasterAddress
=
543 (UINT16
)(HddInfo
[HddIndex
].BusMasterAddress
+ 8);
544 HddInfo
[HddIndex
].HddIrq
= PciConfigHeader
.Device
.InterruptLine
;
546 HddInfo
[HddIndex
].HddIrq
= 15;
547 HddInfo
[HddIndex
].CommandBaseAddress
= 0x170;
548 HddInfo
[HddIndex
].ControlBaseAddress
= 0x376;
549 HddInfo
[HddIndex
].BusMasterAddress
= 0;
556 case EfiGetPlatformIsaBusHandle
:
557 ClassLists
[0].Class
= (UINT8
) PCI_CLASS_BRIDGE
;
558 ClassLists
[0].SubClass
= (UINT8
) PCI_CLASS_BRIDGE_ISA_PDECODE
;
559 ClassLists
[1].Class
= (UINT8
) PCI_CLASS_BRIDGE
;
560 ClassLists
[1].SubClass
= (UINT8
) PCI_CLASS_BRIDGE_ISA
;
561 ClassLists
[2].Class
= 0xff;
564 // Locate all found block io devices
566 FindAllDeviceTypes (ClassLists
, LocalDevice
, (UINT16
*) (&LocalIndex
), TRUE
);
567 if (LocalIndex
== 0) {
568 return EFI_NOT_FOUND
;
572 // Find our ISA bridge.
574 for (Index
= 0; Index
< LocalIndex
; Index
++) {
575 if (LocalDevice
[Index
].Vid
== V_INTEL_VENDOR_ID
) {
576 TempDevice
= LocalDevice
[0];
577 LocalDevice
[0] = LocalDevice
[Index
];
578 LocalDevice
[Index
] = TempDevice
;
583 // Perform copy and update return values.
585 for (Index
= 0; Index
< LocalIndex
; Index
++) {
586 mIsaHandles
[Index
] = LocalDevice
[Index
].Handle
;
588 *HandleBuffer
= &mIsaHandles
[0];
589 *HandleCount
= LocalIndex
;
591 case EfiGetPlatformUsbHandle
:
593 return EFI_UNSUPPORTED
;
598 Allows platform to perform any required action after a LegacyBios operation.
599 Invokes the specific sub function specified by Mode.
601 @param This The protocol instance pointer.
602 @param Mode Specifies what handle to return. See EFI_GET_PLATFORM_HOOK_MODE enum.
603 @param Type Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.
604 @param DeviceHandle Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.
605 @param ShadowAddress Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.
606 @param Compatibility16Table Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.
607 @param AdditionalData Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.
609 @retval EFI_SUCCESS The operation performed successfully. Mode specific.
610 @retval EFI_UNSUPPORTED Mode is not supported on the platform.
616 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
617 IN EFI_GET_PLATFORM_HOOK_MODE Mode
,
619 OUT EFI_HANDLE DeviceHandle
, OPTIONAL
620 IN OUT UINTN
*Shadowaddress
, OPTIONAL
621 IN EFI_COMPATIBILITY16_TABLE
*Compatibility16Table
, OPTIONAL
622 OUT VOID
**AdditionalData OPTIONAL
625 EFI_IA32_REGISTER_SET Regs
;
626 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
630 case EfiPlatformHookPrepareToScanRom
:
631 Status
= gBS
->LocateProtocol (
632 &gEfiLegacyBiosProtocolGuid
,
638 // Set the 80x25 Text VGA Mode
642 Status
= LegacyBios
->Int86 (LegacyBios
, 0x10, &Regs
);
644 case EfiPlatformHookShadowServiceRoms
:
646 case EfiPlatformHookAfterRomInit
:
648 return EFI_UNSUPPORTED
;
653 Returns information associated with PCI IRQ routing.
654 This function returns the following information associated with PCI IRQ routing:
655 * An IRQ routing table and number of entries in the table.
656 * The $PIR table and its size.
657 * A list of PCI IRQs and the priority order to assign them.
659 @param This The protocol instance pointer.
660 @param RoutingTable The pointer to PCI IRQ Routing table.
661 This location is the $PIR table minus the header.
662 @param RoutingTableEntries The number of entries in table.
663 @param LocalPirqTable $PIR table.
664 @param PirqTableSize $PIR table size.
665 @param LocalIrqPriorityTable A list of interrupts in priority order to assign.
666 @param IrqPriorityTableEntries The number of entries in the priority table.
668 @retval EFI_SUCCESS Data was successfully returned.
674 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
675 OUT VOID
**RoutingTable
,
676 OUT UINTN
*RoutingTableEntries
,
677 OUT VOID
**LocalPirqTable
, OPTIONAL
678 OUT UINTN
*PirqTableSize
, OPTIONAL
679 OUT VOID
**LocalIrqPriorityTable
, OPTIONAL
680 OUT UINTN
*IrqPriorityTableEntries OPTIONAL
691 EFI_LEGACY_INTERRUPT_PROTOCOL
*LegacyInterrupt
;
695 if (LocalPirqTable
!= NULL
) {
696 PTableSize
= sizeof (EFI_LEGACY_PIRQ_TABLE_HEADER
) +
697 sizeof (EFI_LEGACY_IRQ_ROUTING_ENTRY
) * MAX_IRQ_ROUTING_ENTRIES
;
699 Status
= gBS
->LocateProtocol (
700 &gEfiLegacyInterruptProtocolGuid
,
702 (VOID
**)&LegacyInterrupt
704 ASSERT_EFI_ERROR (Status
);
705 LegacyInterrupt
->GetLocation (
713 // Update fields in $PIR table header
715 PirqTableHead
.PirqTable
.TableSize
= PTableSize
;
716 PirqTableHead
.PirqTable
.Bus
= Bus
;
717 PirqTableHead
.PirqTable
.DevFun
= (UINT8
) ((Device
<< 3) + Function
);
718 Ptr
= (UINT8
*) (&PirqTableHead
);
721 // Calculate checksum.
723 for (Index
= 0; Index
< PTableSize
; Index
++) {
724 Checksum
= (UINT8
) (Checksum
+ (UINT8
) *Ptr
);
727 Checksum
= (UINT8
) (0x00 - Checksum
);
728 PirqTableHead
.PirqTable
.Checksum
= Checksum
;
731 // Update return values.
733 *LocalPirqTable
= (VOID
*) (&PirqTableHead
);
734 *PirqTableSize
= PTableSize
;
738 // More items to return.
740 *RoutingTable
= PirqTableHead
.IrqRoutingEntry
;
741 *RoutingTableEntries
= MAX_IRQ_ROUTING_ENTRIES
;
742 if (LocalIrqPriorityTable
!= NULL
) {
743 *LocalIrqPriorityTable
= IrqPriorityTable
;
744 *IrqPriorityTableEntries
= MAX_IRQ_PRIORITY_ENTRIES
;
751 Finds the binary data or other platform information.
753 @param This The protocol instance pointer.
754 @param Mode Specifies what data to return. See See EFI_GET_PLATFORM_INFO_MODE enum.
755 @param Table Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
756 @param TableSize Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
757 @param Location Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
758 @param Alignment Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
759 @param LegacySegment Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
760 @param LegacyOffset Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.
762 @retval EFI_SUCCESS Data returned successfully.
763 @retval EFI_UNSUPPORTED Mode is not supported on the platform.
764 @retval EFI_NOT_FOUND Binary image or table not found.
770 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
771 IN EFI_GET_PLATFORM_INFO_MODE Mode
,
773 OUT UINTN
*TableSize
,
775 OUT UINTN
*Alignment
,
776 IN UINT16 LegacySegment
,
777 IN UINT16 LegacyOffset
784 case EfiGetPlatformBinarySystemRom
:
786 // Loop through table of System rom descriptions
788 for (Index
= 0; mSystemRomTable
[Index
].Valid
!= 0; Index
++) {
789 Status
= GetSectionFromFv (
790 &mSystemRomTable
[Index
].FileName
,
796 if (EFI_ERROR (Status
)) {
802 return EFI_NOT_FOUND
;
803 case EfiGetPlatformBinaryOem16Data
:
804 case EfiGetPlatformBinaryMpTable
:
805 case EfiGetPlatformBinaryOemIntData
:
806 case EfiGetPlatformBinaryOem32Data
:
807 case EfiGetPlatformBinaryTpmBinary
:
808 case EfiGetPlatformPciExpressBase
:
810 return EFI_UNSUPPORTED
;
815 Translates the given PIRQ accounting for bridge.
816 This function translates the given PIRQ back through all buses, if required,
817 and returns the true PIRQ and associated IRQ.
819 @param This The protocol instance pointer.
820 @param PciBus The PCI bus number for this device.
821 @param PciDevice The PCI device number for this device.
822 @param PciFunction The PCI function number for this device.
823 @param Pirq Input is PIRQ reported by device, and output is true PIRQ.
824 @param PciIrq The IRQ already assigned to the PIRQ, or the IRQ to be
825 assigned to the PIRQ.
827 @retval EFI_SUCCESS The PIRQ was translated.
833 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
836 IN UINTN PciFunction
,
841 EFI_LEGACY_INTERRUPT_PROTOCOL
*LegacyInterrupt
;
849 Status
= gBS
->LocateProtocol (
850 &gEfiLegacyInterruptProtocolGuid
,
852 (VOID
**)&LegacyInterrupt
854 ASSERT_EFI_ERROR (Status
);
855 LocalPirq
= (UINT8
) (*Pirq
);
857 for (Index
= 0; Index
< MAX_IRQ_ROUTING_ENTRIES
; Index
++) {
858 if ((PirqTableHead
.IrqRoutingEntry
[Index
].Bus
== PciBus
) &&
859 (PirqTableHead
.IrqRoutingEntry
[Index
].Device
== PciDevice
)) {
860 LocalPirq
= (UINT8
) (PirqTableHead
.IrqRoutingEntry
[Index
].PirqEntry
[LocalPirq
].Pirq
& 0x0f);
865 LegacyInterrupt
->ReadPirq (LegacyInterrupt
, LocalPirq
, &PirqData
);
866 MatchData
= PCI_UNUSED
;
867 while (PirqData
== 0) {
868 for (Index1
= 0; Index1
< MAX_IRQ_PRIORITY_ENTRIES
; Index1
++) {
869 if ((IrqPriorityTable
[Index1
].Used
== MatchData
) &&
870 (IrqPriorityTable
[Index1
].Irq
!= 0)) {
871 PirqData
= IrqPriorityTable
[Index1
].Irq
;
872 IrqPriorityTable
[Index1
].Used
= 0xff;
873 LegacyInterrupt
->WritePirq (
885 // No unused interrpts, so start reusing them.
887 MatchData
= (UINT8
) (~MatchData
);
901 Attempt to legacy boot the BootOption. If the EFI contexted has been
902 compromised this function will not return.
904 @param This The protocol instance pointer.
905 @param BbsDevicePath The EFI Device Path from BootXXXX variable.
906 @param BbsTable The Internal BBS table.
907 @param LoadOptionSize The size of LoadOption in size.
908 @param LoadOption The LoadOption from BootXXXX variable
909 @param EfiToLegacy16BootTable A pointer to BootTable structure
911 @retval EFI_SUCCESS Ready to boot.
917 IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
*This
,
918 IN BBS_BBS_DEVICE_PATH
*BbsDevicePath
,
920 IN UINT32 LoadOptionsSize
,
921 IN VOID
*LoadOptions
,
922 IN VOID
*EfiToLegacy16BootTable
925 BBS_TABLE
*LocalBbsTable
;
926 EFI_TO_COMPATIBILITY16_BOOT_TABLE
*Legacy16BootTable
;
927 DEVICE_PRODUCER_DATA_HEADER
*SioPtr
;
928 UINT16 DevicePathType
;
936 Legacy16BootTable
= (EFI_TO_COMPATIBILITY16_BOOT_TABLE
*) EfiToLegacy16BootTable
;
939 // Set how Gate A20 is gated by hardware
941 SioPtr
= &Legacy16BootTable
->SioData
;
942 SioPtr
->Flags
.A20Kybd
= 1;
943 SioPtr
->Flags
.A20Port90
= 1;
944 SioPtr
->MousePresent
= 1;
946 LocalBbsTable
= BbsTable
;
949 // There are 2 cases that must be covered.
950 // Case 1: Booting to a legacy OS - BbsDevicePath is non-NULL.
951 // Case 2: Booting to an EFI aware OS - BbsDevicePath is NULL.
952 // We need to perform the PrepareToBoot function to assign
953 // drive numbers to HDD devices to allow the shell or EFI
956 if (BbsDevicePath
!= NULL
) {
957 DevicePathType
= BbsDevicePath
->DeviceType
;
959 DevicePathType
= BBS_HARDDISK
;
963 // Skip the boot devices where priority is set by BDS and set the next one
965 for (Index
= 0; Index
< Legacy16BootTable
->NumberBbsEntries
; Index
++) {
966 if ((LocalBbsTable
[Index
].BootPriority
!= BBS_UNPRIORITIZED_ENTRY
) &&
967 (LocalBbsTable
[Index
].BootPriority
!= BBS_IGNORE_ENTRY
) &&
968 (LocalBbsTable
[Index
].BootPriority
!= BBS_LOWEST_PRIORITY
) &&
969 (Priority
<= LocalBbsTable
[Index
].BootPriority
)) {
970 Priority
= (UINT16
) (LocalBbsTable
[Index
].BootPriority
+ 1);
974 switch (DevicePathType
) {
978 case BBS_EMBED_NETWORK
:
979 for (Index
= 0; Index
< Legacy16BootTable
->NumberBbsEntries
; Index
++) {
980 if ((LocalBbsTable
[Index
].BootPriority
== BBS_UNPRIORITIZED_ENTRY
) &&
981 (LocalBbsTable
[Index
].DeviceType
== DevicePathType
)) {
982 LocalBbsTable
[Index
].BootPriority
= Priority
;
988 for (Index
= 0; Index
< Legacy16BootTable
->NumberBbsEntries
; Index
++) {
989 if ((LocalBbsTable
[Index
].BootPriority
== BBS_UNPRIORITIZED_ENTRY
) &&
990 (LocalBbsTable
[Index
].Class
== 01) &&
991 (LocalBbsTable
[Index
].SubClass
== 01)) {
992 LocalBbsTable
[Index
].BootPriority
= Priority
;
1005 // Set priority for rest of devices
1007 for (Index
= 0; Index
< Legacy16BootTable
->NumberBbsEntries
; Index
++) {
1008 if (LocalBbsTable
[Index
].BootPriority
== BBS_UNPRIORITIZED_ENTRY
) {
1009 LocalBbsTable
[Index
].BootPriority
= Priority
;
1019 Initialize Legacy Platform support
1021 @retval EFI_SUCCESS Successfully initialized
1025 LegacyBiosPlatformInstall (
1030 LEGACY_BIOS_PLATFORM_INSTANCE
*Private
;
1032 mImageHandle
= gImageHandle
;
1033 Private
= &mPrivateData
;
1036 // Grab a copy of all the protocols we depend on.
1038 Private
->Signature
= LEGACY_BIOS_PLATFORM_INSTANCE_SIGNATURE
;
1039 Private
->LegacyBiosPlatform
.GetPlatformInfo
= GetPlatformInfo
;
1040 Private
->LegacyBiosPlatform
.GetPlatformHandle
= GetPlatformHandle
;
1041 Private
->LegacyBiosPlatform
.SmmInit
= SmmInit
;
1042 Private
->LegacyBiosPlatform
.PlatformHooks
= PlatformHooks
;
1043 Private
->LegacyBiosPlatform
.GetRoutingTable
= GetRoutingTable
;
1044 Private
->LegacyBiosPlatform
.TranslatePirq
= TranslatePirq
;
1045 Private
->LegacyBiosPlatform
.PrepareToBoot
= PrepareToBoot
;
1046 Private
->ImageHandle
= gImageHandle
;
1049 // Make a new handle and install the protocol
1051 Private
->Handle
= NULL
;
1052 Status
= gBS
->InstallProtocolInterface (
1054 &gEfiLegacyBiosPlatformProtocolGuid
,
1055 EFI_NATIVE_INTERFACE
,
1056 &Private
->LegacyBiosPlatform