diff options
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchIoApic.c')
-rw-r--r-- | ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchIoApic.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchIoApic.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchIoApic.c new file mode 100644 index 0000000..ba0b94f --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchIoApic.c @@ -0,0 +1,134 @@ +/** @file + Initializes PCH IO APIC Device. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement +**/ +#include "PchInit.h" + +/** + Configure IoApic Controler + + @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance + @param[in] RootComplexBar RootComplexBar address of this PCH device + + @retval EFI_SUCCESS The function completed successfully +**/ +EFI_STATUS +ConfigureIoApic ( + IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy, + IN UINT32 RootComplexBar + ) +{ + UINT8 RegData8; + UINT16 RegData16; + UINT32 RegData32; + UINTN PciD31F0RegBase; + UINT32 IoApicAddress; + PCH_IO_APIC_CONFIG *IoApicConfig; + PCH_LPC_HPET_CONFIG *HpetConfig; + UINT8 Index; + + DEBUG ((EFI_D_INFO, "ConfigureIoApic() Start\n")); + + /// + /// Get LPC base address + /// + PciD31F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 0, 0); + IoApicConfig = PchPlatformPolicy->IoApicConfig; + + /// + /// PCH BIOS Spec Rev 0.5.0, Section 6.6.2.1 + /// 1. Enable the IOAPIC by setting the APIC Enable bit, RCBA + offset 31FFh, Bit[0] if the + /// system needs to use the IOxAPIC. The APIC Enable bits needs read back after the bit is written. + /// Done in PchInitPeim.c PchIoApicInit() + /// + /// 2. Build the MP table and/or ACPI APIC table for the OS + /// This will be done in ACPI code. + /// + /// 3. Maximum Redirection Entries (MRE) in APIC Version Register (VER), offset 01h, + /// [23:16] has to be written once for Microsoft Windows OS. + /// The address bits 19:12 of IOAPIC INDEX and DATA are programmable + /// through OIC register at RCBA + 31FEh[7:0]. + /// + IoApicAddress = (UINT32) MmioRead8 (RootComplexBar + R_PCH_RCRB_OIC); + IoApicAddress = IoApicAddress << N_PCH_IO_APIC_ASEL; + RegData8 = 0x01; + MmioWrite8 ((UINTN) (R_PCH_IO_APIC_INDEX | IoApicAddress), RegData8); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint8, + (UINTN) (R_PCH_IO_APIC_INDEX | IoApicAddress), + 1, + &RegData8 + ); + RegData32 = 0x170020; + if (GetPchSeries() == PchLp) { + if (IoApicConfig->IoApicEntry24_39 == PCH_DEVICE_ENABLE) { + RegData32 = 0x270020; + } + } + MmioWrite32 ((R_PCH_IO_APIC_DATA | IoApicAddress), RegData32); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint32, + (UINTN) (R_PCH_IO_APIC_DATA | IoApicAddress), + 1, + &RegData32 + ); + + /// + /// Program this field to provide a unique bus:device:function number for the internal IOxAPIC + /// + if (IoApicConfig->BdfValid) { + RegData16 = ((UINT16) (IoApicConfig->BusNumber) << 8) & B_PCH_LPC_IOXAPIC_BUS; + RegData16 |= ((UINT16) (IoApicConfig->DeviceNumber) << 3) & B_PCH_LPC_IOXAPIC_DEVICE; + RegData16 |= (UINT16) (IoApicConfig->FunctionNumber) & B_PCH_LPC_IOXAPIC_FUNC; + MmioWrite16 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_IOXAPIC), RegData16); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint16, + (UINTN) (PciD31F0RegBase + R_PCH_LPC_IOXAPIC), + 1, + &RegData16 + ); + } + /// + /// Program this field accordingly if unique bus:device:function number is required for the + /// corresponding HPET + /// + HpetConfig = PchPlatformPolicy->HpetConfig; + if (HpetConfig->BdfValid) { + for (Index = 0; Index < PCH_HPET_BDF_MAX; Index++) { + RegData16 = ((UINT16) (HpetConfig->Hpet[Index].BusNumber) << 8) & B_PCH_LPC_HPET0_BUS; + RegData16 |= ((UINT16) (HpetConfig->Hpet[Index].DeviceNumber) << 3) & B_PCH_LPC_HPET0_DEVICE; + RegData16 |= (UINT16) (HpetConfig->Hpet[Index].FunctionNumber) & B_PCH_LPC_HPET0_FUNC; + MmioWrite16 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_HPET0 + Index * 2), RegData16); + SCRIPT_MEM_WRITE ( + EFI_ACPI_S3_RESUME_SCRIPT_TABLE, + EfiBootScriptWidthUint16, + (UINTN) (PciD31F0RegBase + R_PCH_LPC_HPET0 + Index * 2), + 1, + &RegData16 + ); + } + } + + DEBUG ((EFI_D_INFO, "ConfigureIoApic() End\n")); + + return EFI_SUCCESS; +} |