2 Legacy Interrupt 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 "LegacyInterrupt.h"
19 // Handle for the Legacy Interrupt Protocol instance produced by this driver
21 STATIC EFI_HANDLE mLegacyInterruptHandle
= NULL
;
24 // Legacy Interrupt Device number (0x01 on piix4, 0x1f on q35/mch)
26 STATIC UINT8 mLegacyInterruptDevice
;
29 // The Legacy Interrupt Protocol instance produced by this driver
31 STATIC EFI_LEGACY_INTERRUPT_PROTOCOL mLegacyInterrupt
= {
38 STATIC UINT8 PirqReg
[MAX_PIRQ_NUMBER
] = { PIRQA
, PIRQB
, PIRQC
, PIRQD
, PIRQE
, PIRQF
, PIRQG
, PIRQH
};
42 Return the number of PIRQs supported by this chipset.
44 @param[in] This Pointer to LegacyInterrupt Protocol
45 @param[out] NumberPirqs The pointer to return the max IRQ number supported
47 @retval EFI_SUCCESS Max PIRQs successfully returned
53 IN EFI_LEGACY_INTERRUPT_PROTOCOL
*This
,
54 OUT UINT8
*NumberPirqs
57 *NumberPirqs
= MAX_PIRQ_NUMBER
;
64 Return PCI location of this device.
65 $PIR table requires this info.
67 @param[in] This - Protocol instance pointer.
68 @param[out] Bus - PCI Bus
69 @param[out] Device - PCI Device
70 @param[out] Function - PCI Function
72 @retval EFI_SUCCESS Bus/Device/Function returned
78 IN EFI_LEGACY_INTERRUPT_PROTOCOL
*This
,
84 *Bus
= LEGACY_INT_BUS
;
85 *Device
= mLegacyInterruptDevice
;
86 *Function
= LEGACY_INT_FUNC
;
93 Builds the PCI configuration address for the register specified by PirqNumber
95 @param[in] PirqNumber - The PIRQ number to build the PCI configuration address for
97 @return The PCI Configuration address for the PIRQ
104 return PCI_LIB_ADDRESS(
106 mLegacyInterruptDevice
,
113 Read the given PIRQ register
115 @param[in] This Protocol instance pointer
116 @param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
117 @param[out] PirqData Value read
119 @retval EFI_SUCCESS Decoding change affected.
120 @retval EFI_INVALID_PARAMETER Invalid PIRQ number
126 IN EFI_LEGACY_INTERRUPT_PROTOCOL
*This
,
131 if (PirqNumber
>= MAX_PIRQ_NUMBER
) {
132 return EFI_INVALID_PARAMETER
;
135 *PirqData
= PciRead8 (GetAddress (PirqNumber
));
136 *PirqData
= (UINT8
) (*PirqData
& 0x7f);
143 Write the given PIRQ register
145 @param[in] This Protocol instance pointer
146 @param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
147 @param[out] PirqData Value to write
149 @retval EFI_SUCCESS Decoding change affected.
150 @retval EFI_INVALID_PARAMETER Invalid PIRQ number
156 IN EFI_LEGACY_INTERRUPT_PROTOCOL
*This
,
161 if (PirqNumber
>= MAX_PIRQ_NUMBER
) {
162 return EFI_INVALID_PARAMETER
;
165 PciWrite8 (GetAddress (PirqNumber
), PirqData
);
171 Initialize Legacy Interrupt support
173 @retval EFI_SUCCESS Successfully initialized
177 LegacyInterruptInstall (
181 UINT16 HostBridgeDevId
;
185 // Make sure the Legacy Interrupt Protocol is not already installed in the system
187 ASSERT_PROTOCOL_ALREADY_INSTALLED(NULL
, &gEfiLegacyInterruptProtocolGuid
);
190 // Query Host Bridge DID to determine platform type, then set device number
192 HostBridgeDevId
= PcdGet16 (PcdOvmfHostBridgePciDevId
);
193 switch (HostBridgeDevId
) {
194 case INTEL_82441_DEVICE_ID
:
195 mLegacyInterruptDevice
= LEGACY_INT_DEV_PIIX4
;
197 case INTEL_Q35_MCH_DEVICE_ID
:
198 mLegacyInterruptDevice
= LEGACY_INT_DEV_Q35
;
201 DEBUG ((EFI_D_ERROR
, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
202 __FUNCTION__
, HostBridgeDevId
));
204 return EFI_UNSUPPORTED
;
208 // Make a new handle and install the protocol
210 Status
= gBS
->InstallMultipleProtocolInterfaces (
211 &mLegacyInterruptHandle
,
212 &gEfiLegacyInterruptProtocolGuid
,
216 ASSERT_EFI_ERROR(Status
);