blob: 98035bedd58f4ee369351ccf0c13a07b04ba3911 [file] [log] [blame]
/** @file
This file contains Madt Talbe initialized work.
Copyright (c) 2013-2015 Intel Corporation.
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.
**/
//
// Statements that include other files
//
#include "AcpiPlatform.h"
VOID
InitMadtConfigData (MADT_CONFIG_DATA *mConfigData)
{
mConfigData->MadtInterruptSetting[0].Enable = PcdGet8 (PcdInterruptOverrideSettingTable0Enable);
mConfigData->MadtInterruptSetting[0].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable0SourceIrq);
mConfigData->MadtInterruptSetting[0].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable0Polarity);
mConfigData->MadtInterruptSetting[0].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable0TrigerMode);
mConfigData->MadtInterruptSetting[0].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable0GlobalIrq);
mConfigData->MadtInterruptSetting[1].Enable = PcdGet8 (PcdInterruptOverrideSettingTable1Enable);
mConfigData->MadtInterruptSetting[1].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable1SourceIrq);
mConfigData->MadtInterruptSetting[1].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable1Polarity);
mConfigData->MadtInterruptSetting[1].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable1TrigerMode);
mConfigData->MadtInterruptSetting[1].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable1GlobalIrq);
mConfigData->MadtInterruptSetting[2].Enable = PcdGet8 (PcdInterruptOverrideSettingTable2Enable);
mConfigData->MadtInterruptSetting[2].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable2SourceIrq);
mConfigData->MadtInterruptSetting[2].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable2Polarity);
mConfigData->MadtInterruptSetting[2].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable2TrigerMode);
mConfigData->MadtInterruptSetting[2].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable2GlobalIrq);
mConfigData->MadtInterruptSetting[3].Enable = PcdGet8 (PcdInterruptOverrideSettingTable3Enable);
mConfigData->MadtInterruptSetting[3].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable3SourceIrq);
mConfigData->MadtInterruptSetting[3].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable3Polarity);
mConfigData->MadtInterruptSetting[3].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable3TrigerMode);
mConfigData->MadtInterruptSetting[3].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable3GlobalIrq);
mConfigData->MadtInterruptSetting[4].Enable = PcdGet8 (PcdInterruptOverrideSettingTable4Enable);
mConfigData->MadtInterruptSetting[4].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable4SourceIrq);
mConfigData->MadtInterruptSetting[4].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable4Polarity);
mConfigData->MadtInterruptSetting[4].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable4TrigerMode);
mConfigData->MadtInterruptSetting[4].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable4GlobalIrq);
mConfigData->MadtInterruptSetting[5].Enable = PcdGet8 (PcdInterruptOverrideSettingTable5Enable);
mConfigData->MadtInterruptSetting[5].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable5SourceIrq);
mConfigData->MadtInterruptSetting[5].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable5Polarity);
mConfigData->MadtInterruptSetting[5].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable5TrigerMode);
mConfigData->MadtInterruptSetting[5].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable5GlobalIrq);
mConfigData->MadtInterruptSetting[6].Enable = PcdGet8 (PcdInterruptOverrideSettingTable6Enable);
mConfigData->MadtInterruptSetting[6].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable6SourceIrq);
mConfigData->MadtInterruptSetting[6].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable6Polarity);
mConfigData->MadtInterruptSetting[6].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable6TrigerMode);
mConfigData->MadtInterruptSetting[6].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable6GlobalIrq);
mConfigData->MadtInterruptSetting[7].Enable = PcdGet8 (PcdInterruptOverrideSettingTable7Enable);
mConfigData->MadtInterruptSetting[7].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable7SourceIrq);
mConfigData->MadtInterruptSetting[7].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable7Polarity);
mConfigData->MadtInterruptSetting[7].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable7TrigerMode);
mConfigData->MadtInterruptSetting[7].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable7GlobalIrq);
mConfigData->MadtInterruptSetting[8].Enable = PcdGet8 (PcdInterruptOverrideSettingTable8Enable);
mConfigData->MadtInterruptSetting[8].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable8SourceIrq);
mConfigData->MadtInterruptSetting[8].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable8Polarity);
mConfigData->MadtInterruptSetting[8].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable8TrigerMode);
mConfigData->MadtInterruptSetting[8].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable8GlobalIrq);
mConfigData->MadtInterruptSetting[9].Enable = PcdGet8 (PcdInterruptOverrideSettingTable9Enable);
mConfigData->MadtInterruptSetting[9].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable9SourceIrq);
mConfigData->MadtInterruptSetting[9].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable9Polarity);
mConfigData->MadtInterruptSetting[9].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable9TrigerMode);
mConfigData->MadtInterruptSetting[9].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable9GlobalIrq);
mConfigData->MadtInterruptSetting[10].Enable = PcdGet8 (PcdInterruptOverrideSettingTable10Enable);
mConfigData->MadtInterruptSetting[10].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable10SourceIrq);
mConfigData->MadtInterruptSetting[10].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable10Polarity);
mConfigData->MadtInterruptSetting[10].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable10TrigerMode);
mConfigData->MadtInterruptSetting[10].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable10GlobalIrq);
mConfigData->MadtInterruptSetting[11].Enable = PcdGet8 (PcdInterruptOverrideSettingTable11Enable);
mConfigData->MadtInterruptSetting[11].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable11SourceIrq);
mConfigData->MadtInterruptSetting[11].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable11Polarity);
mConfigData->MadtInterruptSetting[11].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable11TrigerMode);
mConfigData->MadtInterruptSetting[11].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable11GlobalIrq);
mConfigData->MadtInterruptSetting[12].Enable = PcdGet8 (PcdInterruptOverrideSettingTable12Enable);
mConfigData->MadtInterruptSetting[12].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable12SourceIrq);
mConfigData->MadtInterruptSetting[12].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable12Polarity);
mConfigData->MadtInterruptSetting[12].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable12TrigerMode);
mConfigData->MadtInterruptSetting[12].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable12GlobalIrq);
mConfigData->MadtInterruptSetting[13].Enable = PcdGet8 (PcdInterruptOverrideSettingTable13Enable);
mConfigData->MadtInterruptSetting[13].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable13SourceIrq);
mConfigData->MadtInterruptSetting[13].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable13Polarity);
mConfigData->MadtInterruptSetting[13].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable13TrigerMode);
mConfigData->MadtInterruptSetting[13].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable13GlobalIrq);
mConfigData->MadtInterruptSetting[14].Enable = PcdGet8 (PcdInterruptOverrideSettingTable14Enable);
mConfigData->MadtInterruptSetting[14].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable14SourceIrq);
mConfigData->MadtInterruptSetting[14].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable14Polarity);
mConfigData->MadtInterruptSetting[14].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable14TrigerMode);
mConfigData->MadtInterruptSetting[14].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable14GlobalIrq);
mConfigData->MadtInterruptSetting[15].Enable = PcdGet8 (PcdInterruptOverrideSettingTable15Enable);
mConfigData->MadtInterruptSetting[15].SourceIrq = PcdGet8 (PcdInterruptOverrideSettingTable15SourceIrq);
mConfigData->MadtInterruptSetting[15].Polarity = PcdGet8 (PcdInterruptOverrideSettingTable15Polarity);
mConfigData->MadtInterruptSetting[15].TrigerMode = PcdGet8 (PcdInterruptOverrideSettingTable15TrigerMode);
mConfigData->MadtInterruptSetting[15].GlobalIrq = PcdGet32 (PcdInterruptOverrideSettingTable15GlobalIrq);
mConfigData->MadtIoApicSetting.IoApicAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress);
mConfigData->MadtIoApicSetting.GlobalInterruptBase = PcdGet32 (PcdIoApicSettingGlobalInterruptBase);
mConfigData->MadtIoApicSetting.IoApicId = PcdGet8 (PcdIoApicSettingIoApicId);
mConfigData->MadtIoApicSetting.NmiEnable = PcdGet8 (PcdIoApicSettingNmiEnable);
mConfigData->MadtIoApicSetting.NmiSource = PcdGet8 (PcdIoApicSettingNmiSource);
mConfigData->MadtIoApicSetting.Polarity = PcdGet8 (PcdIoApicSettingPolarity);
mConfigData->MadtIoApicSetting.TrigerMode = PcdGet8 (PcdIoApicSettingTrigerMode);
mConfigData->MadtLocalApicSetting.NmiEnabelApicIdMask = PcdGet8 (PcdLocalApicSettingNmiEnabelApicIdMask);
mConfigData->MadtLocalApicSetting.AddressOverrideEnable = PcdGet8 (PcdLocalApicSettingAddressOverrideEnable);
mConfigData->MadtLocalApicSetting.Polarity = PcdGet8 (PcdLocalApicSettingPolarity);
mConfigData->MadtLocalApicSetting.TrigerMode = PcdGet8 (PcdLocalApicSettingTrigerMode);
mConfigData->MadtLocalApicSetting.LocalApicLint = PcdGet8 (PcdLocalApicSettingLocalApicLint);
mConfigData->MadtLocalApicSetting.LocalApicAddressOverride = PcdGet64 (PcdLocalApicAddressOverride);
mConfigData->MadtLocalApicSetting.LocalApicAddress = PcdGet32 (PcdCpuLocalApicBaseAddress);
}
UINT32
GetAcutalMadtTableSize (
IN MADT_CONFIG_DATA * MadtConfigData,
IN INTN NumberOfCPUs
)
{
UINT32 MadtSize;
UINT8 Index;
MadtSize = (UINT32)(sizeof (EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER) +
sizeof (EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE) * NumberOfCPUs +
sizeof (EFI_ACPI_2_0_IO_APIC_STRUCTURE) +
sizeof (EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE) * (MadtConfigData->MadtLocalApicSetting.AddressOverrideEnable != 0?1:0)
);
for (Index = 0; Index < EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT_MAX; Index ++ ) {
if (MadtConfigData->MadtInterruptSetting[Index].Enable != 0) {
MadtSize += sizeof (EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE);
}
}
for (Index = 0; Index < NumberOfCPUs; Index ++ ) {
if (0 != (MadtConfigData->MadtLocalApicSetting.NmiEnabelApicIdMask & (1 << Index))) {
MadtSize += sizeof (EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE);
}
}
if (0 != MadtConfigData->MadtIoApicSetting.NmiEnable) {
MadtSize += sizeof (EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE);
}
return MadtSize;
}
//
// Init Multiple APIC Description Table
//
EFI_STATUS
MadtTableInitialize (
OUT EFI_ACPI_COMMON_HEADER **MadtTable,
OUT UINTN *Size
)
{
EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt;
EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE *ProcLocalApic;
EFI_ACPI_2_0_IO_APIC_STRUCTURE *IoApic;
EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *InterruptSourceOverride;
EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE *IoApicNmiSource;
EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE *LocalApicNmiSource;
EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE *LocalApicAddressOverride;
EFI_MP_SERVICES_PROTOCOL *MpService;
UINTN NumberOfCPUs;
UINTN NumberOfEnabledCPUs;
MADT_CONFIG_DATA MadtConfigData;
UINT32 MadtSize;
UINTN Index;
EFI_STATUS Status;
ASSERT (NULL != MadtTable);
ASSERT (NULL != Size);
//
// Init Madt table data
//
InitMadtConfigData (&MadtConfigData);
//
// Find the MP Protocol. This is an MP platform, so MP protocol must be
// there.
//
Status = gBS->LocateProtocol (
&gEfiMpServiceProtocolGuid,
NULL,
(VOID **)&MpService
);
ASSERT_EFI_ERROR (Status);
//
// Determine the number of processors
//
MpService->GetNumberOfProcessors (
MpService,
&NumberOfCPUs,
&NumberOfEnabledCPUs
);
//ASSERT (NumberOfCPUs <= 2 && NumberOfCPUs > 0);
MadtSize = GetAcutalMadtTableSize (&MadtConfigData, NumberOfCPUs);
Madt = (EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)AllocateZeroPool (MadtSize);
ASSERT (Madt != NULL);
//
// Initialize MADT Header information
//
Madt->Header.Signature = EFI_ACPI_2_0_MULTIPLE_SAPIC_DESCRIPTION_TABLE_SIGNATURE;
Madt->Header.Length = MadtSize;
Madt->Header.Revision = EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION;
Madt->Header.OemTableId = EFI_ACPI_OEM_TABLE_ID;
Madt->Header.OemRevision = EFI_ACPI_OEM_MADT_REVISION;
Madt->Header.CreatorId = EFI_ACPI_CREATOR_ID;
Madt->LocalApicAddress = MadtConfigData.MadtLocalApicSetting.LocalApicAddress;
Madt->Flags = EFI_ACPI_2_0_MULTIPLE_APIC_FLAGS;
CopyMem (Madt->Header.OemId, EFI_ACPI_OEM_ID, 6);
ProcLocalApic = (EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE *) (Madt + 1);
//
// Initialization of Processor's local APICs
//
for (Index = 0;Index < NumberOfCPUs; Index++) {
ProcLocalApic[Index].Type = EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC;
ProcLocalApic[Index].Length = sizeof (EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE);
ProcLocalApic[Index].AcpiProcessorId = (UINT8)(Index + 1);
ProcLocalApic[Index].ApicId = 0xff;
ProcLocalApic[Index].Flags = 0;
}
//
// Initialization of IO APIC.
// Note: Here assumes that there must be one and only one IO APIC in platform.
//
IoApic = (EFI_ACPI_2_0_IO_APIC_STRUCTURE *) (&ProcLocalApic[Index]);
IoApic->Type = EFI_ACPI_2_0_IO_APIC;
IoApic->Length = sizeof (EFI_ACPI_2_0_IO_APIC_STRUCTURE);
IoApic->IoApicId = MadtConfigData.MadtIoApicSetting.IoApicId;
IoApic->IoApicAddress = MadtConfigData.MadtIoApicSetting.IoApicAddress;
IoApic->GlobalSystemInterruptBase = MadtConfigData.MadtIoApicSetting.GlobalInterruptBase;
InterruptSourceOverride = (EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *) (IoApic + 1);
for (Index = 0;Index < EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT_MAX; Index++ ){
if (MadtConfigData.MadtInterruptSetting[Index].Enable) {
InterruptSourceOverride->Type = EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE;
InterruptSourceOverride->Length = sizeof (EFI_ACPI_2_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE);
InterruptSourceOverride->Bus = 0;
InterruptSourceOverride->Source = MadtConfigData.MadtInterruptSetting[Index].SourceIrq;
InterruptSourceOverride->Flags = ((MadtConfigData.MadtInterruptSetting[Index].TrigerMode & 0x03) << 2) | (MadtConfigData.MadtInterruptSetting[Index].Polarity & 0x03);
InterruptSourceOverride->GlobalSystemInterrupt = MadtConfigData.MadtInterruptSetting[Index].GlobalIrq;
InterruptSourceOverride++;
}
}
//
// support NMI source configuration.
//
IoApicNmiSource = (EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE *) InterruptSourceOverride;
if ((BOOLEAN) MadtConfigData.MadtIoApicSetting.NmiEnable) {
IoApicNmiSource->Type = EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE;
IoApicNmiSource->Length = sizeof (EFI_ACPI_2_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE);
IoApicNmiSource->Flags = ((MadtConfigData.MadtIoApicSetting.TrigerMode & 0x03) << 2) | (MadtConfigData.MadtIoApicSetting.Polarity & 0x03);
IoApicNmiSource->GlobalSystemInterrupt = MadtConfigData.MadtIoApicSetting.NmiSource;
IoApicNmiSource ++;
}
//
// Assume each processor has same NMI interrupt source.
//
LocalApicNmiSource = (EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE *) IoApicNmiSource;
for (Index = 0;Index < NumberOfCPUs; Index++) {
if (0 != (MadtConfigData.MadtLocalApicSetting.NmiEnabelApicIdMask & (1 << Index))){
LocalApicNmiSource->Type = EFI_ACPI_2_0_LOCAL_APIC_NMI;
LocalApicNmiSource->Length = sizeof (EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE);
LocalApicNmiSource->LocalApicLint = MadtConfigData.MadtLocalApicSetting.LocalApicLint;
LocalApicNmiSource->Flags = ((MadtConfigData.MadtLocalApicSetting.TrigerMode & 0x03) << 2) | (MadtConfigData.MadtLocalApicSetting.Polarity & 0x03);
LocalApicNmiSource->AcpiProcessorId = (UINT8)(Index + 1);
LocalApicNmiSource++;
}
}
LocalApicAddressOverride = (EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE *) LocalApicNmiSource;
if ((BOOLEAN) MadtConfigData.MadtLocalApicSetting.AddressOverrideEnable) {
LocalApicAddressOverride->Type = EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE;
LocalApicAddressOverride->Length = sizeof (EFI_ACPI_2_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE);
LocalApicAddressOverride->LocalApicAddress = MadtConfigData.MadtLocalApicSetting.LocalApicAddressOverride;
LocalApicAddressOverride++;
}
*Size = MadtSize;
*MadtTable = (EFI_ACPI_COMMON_HEADER *) Madt;
return EFI_SUCCESS;
}