2 Legacy Interrupt Support
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "LegacyInterrupt.h"
13 // Handle for the Legacy Interrupt Protocol instance produced by this driver
15 STATIC EFI_HANDLE mLegacyInterruptHandle
= NULL
;
18 // Legacy Interrupt Device number (0x01 on piix4, 0x1f on q35/mch)
20 STATIC UINT8 mLegacyInterruptDevice
;
23 // The Legacy Interrupt Protocol instance produced by this driver
25 STATIC EFI_LEGACY_INTERRUPT_PROTOCOL mLegacyInterrupt
= {
32 STATIC UINT8 PirqReg
[MAX_PIRQ_NUMBER
] = { PIRQA
, PIRQB
, PIRQC
, PIRQD
, PIRQE
, PIRQF
, PIRQG
, PIRQH
};
36 Return the number of PIRQs supported by this chipset.
38 @param[in] This Pointer to LegacyInterrupt Protocol
39 @param[out] NumberPirqs The pointer to return the max IRQ number supported
41 @retval EFI_SUCCESS Max PIRQs successfully returned
47 IN EFI_LEGACY_INTERRUPT_PROTOCOL
*This
,
48 OUT UINT8
*NumberPirqs
51 *NumberPirqs
= MAX_PIRQ_NUMBER
;
58 Return PCI location of this device.
59 $PIR table requires this info.
61 @param[in] This - Protocol instance pointer.
62 @param[out] Bus - PCI Bus
63 @param[out] Device - PCI Device
64 @param[out] Function - PCI Function
66 @retval EFI_SUCCESS Bus/Device/Function returned
72 IN EFI_LEGACY_INTERRUPT_PROTOCOL
*This
,
78 *Bus
= LEGACY_INT_BUS
;
79 *Device
= mLegacyInterruptDevice
;
80 *Function
= LEGACY_INT_FUNC
;
87 Builds the PCI configuration address for the register specified by PirqNumber
89 @param[in] PirqNumber - The PIRQ number to build the PCI configuration address for
91 @return The PCI Configuration address for the PIRQ
98 return PCI_LIB_ADDRESS(
100 mLegacyInterruptDevice
,
107 Read the given PIRQ register
109 @param[in] This Protocol instance pointer
110 @param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
111 @param[out] PirqData Value read
113 @retval EFI_SUCCESS Decoding change affected.
114 @retval EFI_INVALID_PARAMETER Invalid PIRQ number
120 IN EFI_LEGACY_INTERRUPT_PROTOCOL
*This
,
125 if (PirqNumber
>= MAX_PIRQ_NUMBER
) {
126 return EFI_INVALID_PARAMETER
;
129 *PirqData
= PciRead8 (GetAddress (PirqNumber
));
130 *PirqData
= (UINT8
) (*PirqData
& 0x7f);
137 Write the given PIRQ register
139 @param[in] This Protocol instance pointer
140 @param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
141 @param[out] PirqData Value to write
143 @retval EFI_SUCCESS Decoding change affected.
144 @retval EFI_INVALID_PARAMETER Invalid PIRQ number
150 IN EFI_LEGACY_INTERRUPT_PROTOCOL
*This
,
155 if (PirqNumber
>= MAX_PIRQ_NUMBER
) {
156 return EFI_INVALID_PARAMETER
;
159 PciWrite8 (GetAddress (PirqNumber
), PirqData
);
165 Initialize Legacy Interrupt support
167 @retval EFI_SUCCESS Successfully initialized
171 LegacyInterruptInstall (
175 UINT16 HostBridgeDevId
;
179 // Make sure the Legacy Interrupt Protocol is not already installed in the system
181 ASSERT_PROTOCOL_ALREADY_INSTALLED(NULL
, &gEfiLegacyInterruptProtocolGuid
);
184 // Query Host Bridge DID to determine platform type, then set device number
186 HostBridgeDevId
= PcdGet16 (PcdOvmfHostBridgePciDevId
);
187 switch (HostBridgeDevId
) {
188 case INTEL_82441_DEVICE_ID
:
189 mLegacyInterruptDevice
= LEGACY_INT_DEV_PIIX4
;
191 case INTEL_Q35_MCH_DEVICE_ID
:
192 mLegacyInterruptDevice
= LEGACY_INT_DEV_Q35
;
195 DEBUG ((EFI_D_ERROR
, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
196 __FUNCTION__
, HostBridgeDevId
));
198 return EFI_UNSUPPORTED
;
202 // Make a new handle and install the protocol
204 Status
= gBS
->InstallMultipleProtocolInterfaces (
205 &mLegacyInterruptHandle
,
206 &gEfiLegacyInterruptProtocolGuid
,
210 ASSERT_EFI_ERROR(Status
);