summaryrefslogtreecommitdiff
path: root/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c
diff options
context:
space:
mode:
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2011-11-10 22:04:19 +0000
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2011-11-10 22:04:19 +0000
commit8016da21b56d5ab1da855037cd0f0e034e2404bf (patch)
treeca1007851ca05a7f3fbd6936f6f10edffd6f2e3b /OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c
parent09bb585cb2a9d182e4f15cdd0ab020b3b82ead8a (diff)
downloadedk2-platforms-8016da21b56d5ab1da855037cd0f0e034e2404bf.tar.xz
OvmfPkg: Add CsmSupportLib
This library installs the legacy interrupt, region and platform support required for CSM support drivers. Signed-off-by: jljusten Reviewed-by: geekboy15a git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12681 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c')
-rw-r--r--OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c b/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c
new file mode 100644
index 0000000000..cd984174ab
--- /dev/null
+++ b/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.c
@@ -0,0 +1,196 @@
+/** @file
+ Legacy Interrupt Support
+
+ Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials are
+ licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "LegacyInterrupt.h"
+
+//
+// Handle for the Legacy Interrupt Protocol instance produced by this driver
+//
+STATIC EFI_HANDLE mLegacyInterruptHandle = NULL;
+
+//
+// The Legacy Interrupt Protocol instance produced by this driver
+//
+STATIC EFI_LEGACY_INTERRUPT_PROTOCOL mLegacyInterrupt = {
+ GetNumberPirqs,
+ GetLocation,
+ ReadPirq,
+ WritePirq
+};
+
+STATIC UINT8 PirqReg[MAX_PIRQ_NUMBER] = { PIRQA, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH };
+
+
+/**
+ Return the number of PIRQs supported by this chipset.
+
+ @param[in] This Pointer to LegacyInterrupt Protocol
+ @param[out] NumberPirqs The pointer to return the max IRQ number supported
+
+ @retval EFI_SUCCESS Max PIRQs successfully returned
+
+**/
+EFI_STATUS
+EFIAPI
+GetNumberPirqs (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ OUT UINT8 *NumberPirqs
+ )
+{
+ *NumberPirqs = MAX_PIRQ_NUMBER;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Return PCI location of this device.
+ $PIR table requires this info.
+
+ @param[in] This - Protocol instance pointer.
+ @param[out] Bus - PCI Bus
+ @param[out] Device - PCI Device
+ @param[out] Function - PCI Function
+
+ @retval EFI_SUCCESS Bus/Device/Function returned
+
+**/
+EFI_STATUS
+EFIAPI
+GetLocation (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ OUT UINT8 *Bus,
+ OUT UINT8 *Device,
+ OUT UINT8 *Function
+ )
+{
+ *Bus = LEGACY_INT_BUS;
+ *Device = LEGACY_INT_DEV;
+ *Function = LEGACY_INT_FUNC;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Builds the PCI configuration address for the register specified by PirqNumber
+
+ @param[in] PirqNumber - The PIRQ number to build the PCI configuration address for
+
+ @return The PCI Configuration address for the PIRQ
+**/
+UINTN
+GetAddress (
+ UINT8 PirqNumber
+ )
+{
+ return PCI_LIB_ADDRESS(
+ LEGACY_INT_BUS,
+ LEGACY_INT_DEV,
+ LEGACY_INT_FUNC,
+ PirqReg[PirqNumber]
+ );
+}
+
+/**
+ Read the given PIRQ register
+
+ @param[in] This Protocol instance pointer
+ @param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
+ @param[out] PirqData Value read
+
+ @retval EFI_SUCCESS Decoding change affected.
+ @retval EFI_INVALID_PARAMETER Invalid PIRQ number
+
+**/
+EFI_STATUS
+EFIAPI
+ReadPirq (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ IN UINT8 PirqNumber,
+ OUT UINT8 *PirqData
+ )
+{
+ if (PirqNumber >= MAX_PIRQ_NUMBER) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *PirqData = PciRead8 (GetAddress (PirqNumber));
+ *PirqData = (UINT8) (*PirqData & 0x7f);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Write the given PIRQ register
+
+ @param[in] This Protocol instance pointer
+ @param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
+ @param[out] PirqData Value to write
+
+ @retval EFI_SUCCESS Decoding change affected.
+ @retval EFI_INVALID_PARAMETER Invalid PIRQ number
+
+**/
+EFI_STATUS
+EFIAPI
+WritePirq (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ IN UINT8 PirqNumber,
+ IN UINT8 PirqData
+ )
+{
+ if (PirqNumber >= MAX_PIRQ_NUMBER) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PciWrite8 (GetAddress (PirqNumber), PirqData);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initialize Legacy Interrupt support
+
+ @retval EFI_SUCCESS Successfully initialized
+
+**/
+EFI_STATUS
+LegacyInterruptInstall (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Make sure the Legacy Interrupt Protocol is not already installed in the system
+ //
+ ASSERT_PROTOCOL_ALREADY_INSTALLED(NULL, &gEfiLegacyInterruptProtocolGuid);
+
+ //
+ // Make a new handle and install the protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mLegacyInterruptHandle,
+ &gEfiLegacyInterruptProtocolGuid,
+ &mLegacyInterrupt,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+