1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579 |
- /** @file
- ACPI Platform Driver
- Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "AcpiPlatform.h"
- #define MAX_CPU_NUM (FixedPcdGet32(PcdMaxCpuThreadCount) * FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuSocketCount))
- #pragma pack(1)
- typedef struct {
- UINT32 AcpiProcessorId;
- UINT32 ApicId;
- UINT32 Flags;
- UINT32 SwProcApicId;
- UINT32 SocketNum;
- } EFI_CPU_ID_ORDER_MAP;
- //
- // Private Driver Data
- //
- //
- // Define Union of IO APIC & Local APIC structure;
- //
- typedef union {
- EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE AcpiLocalApic;
- EFI_ACPI_4_0_IO_APIC_STRUCTURE AcpiIoApic;
- EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE AcpiLocalx2Apic;
- struct {
- UINT8 Type;
- UINT8 Length;
- } AcpiApicCommon;
- } ACPI_APIC_STRUCTURE_PTR;
- #pragma pack()
- extern EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE Facs;
- extern EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE Fadt;
- extern EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER Hpet;
- extern EFI_ACPI_WSMT_TABLE Wsmt;
- VOID *mLocalTable[] = {
- &Facs,
- &Fadt,
- &Hpet,
- &Wsmt,
- };
- EFI_ACPI_TABLE_PROTOCOL *mAcpiTable;
- UINT32 mNumOfBitShift = 6;
- BOOLEAN mForceX2ApicId;
- BOOLEAN mX2ApicEnabled;
- EFI_MP_SERVICES_PROTOCOL *mMpService;
- BOOLEAN mCpuOrderSorted;
- EFI_CPU_ID_ORDER_MAP mCpuApicIdOrderTable[MAX_CPU_NUM];
- UINTN mNumberOfCPUs = 0;
- UINTN mNumberOfEnabledCPUs = 0;
- //
- // following are possible APICID Map for SKX
- //
- static const UINT32 ApicIdMapA[] = { //for SKUs have number of core > 16
- //it is 14 + 14 + 14 + 14 format
- 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
- 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x00000010, 0x00000011,
- 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018, 0x00000019,
- 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x00000020, 0x00000021, 0x00000022, 0x00000023,
- 0x00000024, 0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002A, 0x0000002B,
- 0x0000002C, 0x0000002D, 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035,
- 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x0000003A, 0x0000003B, 0x0000003C, 0x0000003D
- };
- static const UINT32 ApicIdMapB[] = { //for SKUs have number of cores <= 16 use 32 ID space
- //
- //it is 16+16 format
- //
- 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
- 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F,
- 0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017,
- 0x00000018, 0x00000019, 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x0000001E, 0x0000001F,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
- };
- static const UINT32 ApicIdMapC[] = { //for SKUs have number of cores <= 16 use 64 ID space
- //
- //it is 16+0+16+0 format
- //
- 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
- 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F,
- 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000026, 0x00000027,
- 0x00000028, 0x00000029, 0x0000002A, 0x0000002B, 0x0000002C, 0x0000002D, 0x0000002E, 0x0000002F,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
- };
- static const UINT32 ApicIdMapD[] = { //for SKUs have number of cores <= 8 use 16 ID space
- //
- //it is 16 format
- //
- 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
- 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
- };
- const UINT32 *mApicIdMap = NULL;
- /**
- This function detect the APICID map and update ApicID Map pointer
- @param None
- @retval VOID
- **/
- VOID DetectApicIdMap(VOID)
- {
- UINTN CoreCount;
- CoreCount = 0;
- if(mApicIdMap != NULL) {
- return; //aleady initialized
- }
- mApicIdMap = ApicIdMapA; // default to > 16C SKUs
- CoreCount = mNumberOfEnabledCPUs / 2;
- DEBUG ((DEBUG_INFO, "CoreCount - %d\n", CoreCount));
- if(CoreCount <= 16) {
- if(mNumOfBitShift == 4) {
- mApicIdMap = ApicIdMapD;
- }
- if(mNumOfBitShift == 5) {
- mApicIdMap = ApicIdMapB;
- }
- if(mNumOfBitShift == 6) {
- mApicIdMap = ApicIdMapC;
- }
- }
- return;
- }
- /**
- This function return the CoreThreadId of ApicId from ACPI ApicId Map array
- @param ApicId
- @retval Index of ACPI ApicId Map array
- **/
- UINT32
- GetIndexFromApicId (
- UINT32 ApicId
- )
- {
- UINT32 CoreThreadId;
- UINT32 i;
- ASSERT (mApicIdMap != NULL);
- CoreThreadId = ApicId & ((1 << mNumOfBitShift) - 1);
- for(i = 0; i < (FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)); i++) {
- if(mApicIdMap[i] == CoreThreadId) {
- break;
- }
- }
- ASSERT (i <= (FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)));
- return i;
- }
- UINT32
- ApicId2SwProcApicId (
- UINT32 ApicId
- )
- {
- UINT32 Index;
- for (Index = 0; Index < MAX_CPU_NUM; Index++) {
- if ((mCpuApicIdOrderTable[Index].Flags == 1) && (mCpuApicIdOrderTable[Index].ApicId == ApicId)) {
- return Index;
- }
- }
- return (UINT32) -1;
- }
- VOID
- DebugDisplayReOrderTable(
- VOID
- )
- {
- UINT32 Index;
- DEBUG ((EFI_D_ERROR, "Index AcpiProcId ApicId Flags SwApicId Skt\n"));
- for (Index=0; Index<MAX_CPU_NUM; Index++) {
- DEBUG ((EFI_D_ERROR, " %02d 0x%02X 0x%02X %d 0x%02X %d\n",
- Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
- mCpuApicIdOrderTable[Index].ApicId,
- mCpuApicIdOrderTable[Index].Flags,
- mCpuApicIdOrderTable[Index].SwProcApicId,
- mCpuApicIdOrderTable[Index].SocketNum));
- }
- }
- EFI_STATUS
- AppendCpuMapTableEntry (
- IN VOID *ApicPtr,
- IN UINT32 LocalApicCounter
- )
- {
- EFI_STATUS Status;
- EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApicPtr;
- EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2ApicPtr;
- UINT8 Type;
- Status = EFI_SUCCESS;
- Type = ((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiApicCommon.Type;
- LocalApicPtr = (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *)(&((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalApic);
- LocalX2ApicPtr = (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)(&((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalx2Apic);
- if(Type == EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC) {
- if(!mX2ApicEnabled) {
- LocalApicPtr->Flags = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].Flags;
- LocalApicPtr->ApicId = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].ApicId;
- LocalApicPtr->AcpiProcessorId = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].AcpiProcessorId;
- } else {
- LocalApicPtr->Flags = 0;
- LocalApicPtr->ApicId = 0xFF;
- LocalApicPtr->AcpiProcessorId = (UINT8)0xFF;
- Status = EFI_UNSUPPORTED;
- }
- } else if(Type == EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC) {
- if(mX2ApicEnabled) {
- LocalX2ApicPtr->Flags = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].Flags;
- LocalX2ApicPtr->X2ApicId = mCpuApicIdOrderTable[LocalApicCounter].ApicId;
- LocalX2ApicPtr->AcpiProcessorUid = mCpuApicIdOrderTable[LocalApicCounter].AcpiProcessorId;
- } else {
- LocalX2ApicPtr->Flags = 0;
- LocalX2ApicPtr->X2ApicId = (UINT32)-1;
- LocalX2ApicPtr->AcpiProcessorUid = (UINT32)-1;
- Status = EFI_UNSUPPORTED;
- }
- } else {
- Status = EFI_UNSUPPORTED;
- }
- return Status;
- }
- EFI_STATUS
- SortCpuLocalApicInTable (
- VOID
- )
- {
- EFI_STATUS Status;
- EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;
- UINT32 Index;
- UINT32 CurrProcessor;
- UINT32 BspApicId;
- UINT32 TempVal = 0;
- EFI_CPU_ID_ORDER_MAP *CpuIdMapPtr;
- UINT32 CoreThreadMask;
- Index = 0;
- Status = EFI_SUCCESS;
- CoreThreadMask = (UINT32) ((1 << mNumOfBitShift) - 1);
- if(!mCpuOrderSorted) {
- Index = 0;
- for (CurrProcessor = 0; CurrProcessor < mNumberOfCPUs; CurrProcessor++) {
- Status = mMpService->GetProcessorInfo (
- mMpService,
- CurrProcessor,
- &ProcessorInfoBuffer
- );
- if ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0) {
- if(ProcessorInfoBuffer.ProcessorId & 1) { //is 2nd thread
- CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[(Index - 1) + MAX_CPU_NUM / 2];
- } else { //is primary thread
- CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[Index];
- Index++;
- }
- CpuIdMapPtr->ApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;
- CpuIdMapPtr->Flags = ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0);
- CpuIdMapPtr->SocketNum = (UINT32)ProcessorInfoBuffer.Location.Package;
- CpuIdMapPtr->AcpiProcessorId = (CpuIdMapPtr->SocketNum * FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)) + GetIndexFromApicId(CpuIdMapPtr->ApicId); //CpuIdMapPtr->ApicId;
- CpuIdMapPtr->SwProcApicId = ((UINT32)(ProcessorInfoBuffer.Location.Package << mNumOfBitShift) + (((UINT32)ProcessorInfoBuffer.ProcessorId) & CoreThreadMask));
- if(mX2ApicEnabled) { //if X2Apic, re-order the socket # so it starts from base 0 and contiguous
- //may not necessory!!!!!
- }
- //update processorbitMask
- if (CpuIdMapPtr->Flags == 1) {
- if(mForceX2ApicId) {
- CpuIdMapPtr->SocketNum &= 0x7;
- CpuIdMapPtr->AcpiProcessorId &= 0xFF; //keep lower 8bit due to use Proc obj in dsdt
- CpuIdMapPtr->SwProcApicId &= 0xFF;
- }
- }
- } else { //not enabled
- CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[Index];
- CpuIdMapPtr->ApicId = (UINT32)-1;
- CpuIdMapPtr->Flags = 0;
- CpuIdMapPtr->AcpiProcessorId = (UINT32)-1;
- CpuIdMapPtr->SwProcApicId = (UINT32)-1;
- CpuIdMapPtr->SocketNum = (UINT32)-1;
- } //end if PROC ENABLE
- } //end for CurrentProcessor
- //
- //keep for debug purpose
- //
- DEBUG(( EFI_D_ERROR, "::ACPI:: APIC ID Order Table Init. CoreThreadMask = %x, mNumOfBitShift = %x\n", CoreThreadMask, mNumOfBitShift));
- DebugDisplayReOrderTable();
- //
- //make sure 1st entry is BSP
- //
- if(mX2ApicEnabled) {
- BspApicId = (UINT32)AsmReadMsr64(0x802);
- } else {
- BspApicId = (*(volatile UINT32 *)(UINTN)0xFEE00020) >> 24;
- }
- DEBUG ((EFI_D_INFO, "BspApicId - 0x%x\n", BspApicId));
- if(mCpuApicIdOrderTable[0].ApicId != BspApicId) {
- //
- //check to see if 1st entry is BSP, if not swap it
- //
- Index = ApicId2SwProcApicId(BspApicId);
- if(MAX_CPU_NUM <= Index) {
- DEBUG ((EFI_D_ERROR, "Asserting the SortCpuLocalApicInTable Index Bufferflow\n"));
- ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
- }
- TempVal = mCpuApicIdOrderTable[Index].ApicId;
- mCpuApicIdOrderTable[Index].ApicId = mCpuApicIdOrderTable[0].ApicId;
- mCpuApicIdOrderTable[0].ApicId = TempVal;
- mCpuApicIdOrderTable[Index].Flags = mCpuApicIdOrderTable[0].Flags;
- mCpuApicIdOrderTable[0].Flags = 1;
- TempVal = mCpuApicIdOrderTable[Index].SwProcApicId;
- mCpuApicIdOrderTable[Index].SwProcApicId = mCpuApicIdOrderTable[0].SwProcApicId;
- mCpuApicIdOrderTable[0].SwProcApicId = TempVal;
- //
- //swap AcpiProcId
- //
- TempVal = mCpuApicIdOrderTable[Index].AcpiProcessorId;
- mCpuApicIdOrderTable[Index].AcpiProcessorId = mCpuApicIdOrderTable[0].AcpiProcessorId;
- mCpuApicIdOrderTable[0].AcpiProcessorId = TempVal;
- }
- //
- //Make sure no holes between enabled threads
- //
- for(CurrProcessor = 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++) {
- if(mCpuApicIdOrderTable[CurrProcessor].Flags == 0) {
- //
- //make sure disabled entry has ProcId set to FFs
- //
- mCpuApicIdOrderTable[CurrProcessor].ApicId = (UINT32)-1;
- mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = (UINT32)-1;
- mCpuApicIdOrderTable[CurrProcessor].SwProcApicId = (UINT32)-1;
- for(Index = CurrProcessor+1; Index < MAX_CPU_NUM; Index++) {
- if(mCpuApicIdOrderTable[Index].Flags == 1) {
- //
- //move enabled entry up
- //
- mCpuApicIdOrderTable[CurrProcessor].Flags = 1;
- mCpuApicIdOrderTable[CurrProcessor].ApicId = mCpuApicIdOrderTable[Index].ApicId;
- mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = mCpuApicIdOrderTable[Index].AcpiProcessorId;
- mCpuApicIdOrderTable[CurrProcessor].SwProcApicId = mCpuApicIdOrderTable[Index].SwProcApicId;
- mCpuApicIdOrderTable[CurrProcessor].SocketNum = mCpuApicIdOrderTable[Index].SocketNum;
- //
- //disable moved entry
- //
- mCpuApicIdOrderTable[Index].Flags = 0;
- mCpuApicIdOrderTable[Index].ApicId = (UINT32)-1;
- mCpuApicIdOrderTable[Index].AcpiProcessorId = (UINT32)-1;
- mCpuApicIdOrderTable[Index].SwProcApicId = (UINT32)-1;
- break;
- }
- }
- }
- }
- //
- //keep for debug purpose
- //
- DEBUG ((EFI_D_ERROR, "APIC ID Order Table ReOrdered\n"));
- DebugDisplayReOrderTable();
- mCpuOrderSorted = TRUE;
- }
- return Status;
- }
- /** Structure of a sub-structure of the ACPI header.
- This structure contains the type and length fields, which are common to every
- sub-structure of the ACPI tables. A pointer to any structure can be cast as this.
- **/
- typedef struct {
- UINT8 Type;
- UINT8 Length;
- } STRUCTURE_HEADER;
- STRUCTURE_HEADER mMadtStructureTable[] = {
- {EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC, sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE)},
- {EFI_ACPI_4_0_IO_APIC, sizeof (EFI_ACPI_4_0_IO_APIC_STRUCTURE)},
- {EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE, sizeof (EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE)},
- {EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE, sizeof (EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE)},
- {EFI_ACPI_4_0_LOCAL_APIC_NMI, sizeof (EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE)},
- {EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE, sizeof (EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE)},
- {EFI_ACPI_4_0_IO_SAPIC, sizeof (EFI_ACPI_4_0_IO_SAPIC_STRUCTURE)},
- {EFI_ACPI_4_0_LOCAL_SAPIC, sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE)},
- {EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES, sizeof (EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE)},
- {EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC, sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE)},
- {EFI_ACPI_4_0_LOCAL_X2APIC_NMI, sizeof (EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE)}
- };
- /**
- Get the size of the ACPI table.
- This function calculates the size needed for the ACPI Table based on the number and
- size of the sub-structures that will compose it.
- @param[in] TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
- @param[in] Structures Pointer to an array of sub-structure pointers.
- @param[in] StructureCount Number of structure pointers in the array.
- @return Total size needed for the ACPI table.
- **/
- UINT32
- GetTableSize (
- IN UINTN TableSpecificHdrLength,
- IN STRUCTURE_HEADER **Structures,
- IN UINTN StructureCount
- )
- {
- UINT32 TableLength;
- UINT32 Index;
- //
- // Compute size of the ACPI table; header plus all structures needed.
- //
- TableLength = (UINT32) TableSpecificHdrLength;
- for (Index = 0; Index < StructureCount; Index++) {
- ASSERT (Structures[Index] != NULL);
- if (Structures[Index] == NULL) {
- return 0;
- }
- TableLength += Structures[Index]->Length;
- }
- return TableLength;
- }
- /**
- Allocate the ACPI Table.
- This function allocates space for the ACPI table based on the number and size of
- the sub-structures that will compose it.
- @param[in] TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
- @param[in] Structures Pointer to an array of sub-structure pointers.
- @param[in] StructureCount Number of structure pointers in the array.
- @param[out] Table Newly allocated ACPI Table pointer.
- @retval EFI_SUCCESS Successfully allocated the Table.
- @retval EFI_OUT_OF_RESOURCES Space for the Table could not be allocated.
- **/
- EFI_STATUS
- AllocateTable (
- IN UINTN TableSpecificHdrLength,
- IN STRUCTURE_HEADER **Structures,
- IN UINTN StructureCount,
- OUT EFI_ACPI_DESCRIPTION_HEADER **Table
- )
- {
- EFI_STATUS Status;
- UINT32 Size;
- EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
- //
- // Get the size of the ACPI table and allocate memory.
- //
- Size = GetTableSize (TableSpecificHdrLength, Structures, StructureCount);
- InternalTable = (EFI_ACPI_DESCRIPTION_HEADER *) AllocatePool (Size);
- if (InternalTable == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- DEBUG ((
- DEBUG_ERROR,
- "Failed to allocate %d bytes for ACPI Table\n",
- Size
- ));
- } else {
- Status = EFI_SUCCESS;
- DEBUG ((
- DEBUG_INFO,
- "Successfully allocated %d bytes for ACPI Table at 0x%p\n",
- Size,
- InternalTable
- ));
- *Table = InternalTable;
- }
- return Status;
- }
- /**
- Initialize the header.
- This function fills in the standard table header with correct values,
- except for the length and checksum fields, which are filled in later.
- @param[in,out] Header Pointer to the header structure.
- @retval EFI_SUCCESS Successfully initialized the header.
- @retval EFI_INVALID_PARAMETER Pointer parameter was null.
- **/
- EFI_STATUS
- InitializeHeader (
- IN OUT EFI_ACPI_DESCRIPTION_HEADER *Header,
- IN UINT32 Signature,
- IN UINT8 Revision,
- IN UINT32 OemRevision
- )
- {
- UINT64 AcpiTableOemId;
- if (Header == NULL) {
- DEBUG ((DEBUG_ERROR, "Header pointer is NULL\n"));
- return EFI_INVALID_PARAMETER;
- }
- Header->Signature = Signature;
- Header->Length = 0; // filled in by Build function
- Header->Revision = Revision;
- Header->Checksum = 0; // filled in by InstallAcpiTable
- CopyMem (
- (VOID *) &Header->OemId,
- PcdGetPtr (PcdAcpiDefaultOemId),
- sizeof (Header->OemId)
- );
- AcpiTableOemId = PcdGet64 (PcdAcpiDefaultOemTableId);
- CopyMem (
- (VOID *) &Header->OemTableId,
- (VOID *) &AcpiTableOemId,
- sizeof (Header->OemTableId)
- );
- Header->OemRevision = OemRevision;
- Header->CreatorId = 0;
- Header->CreatorRevision = 0;
- return EFI_SUCCESS;
- }
- /**
- Initialize the MADT header.
- This function fills in the MADT's standard table header with correct values,
- except for the length and checksum fields, which are filled in later.
- @param[in,out] MadtHeader Pointer to the MADT header structure.
- @retval EFI_SUCCESS Successfully initialized the MADT header.
- @retval EFI_INVALID_PARAMETER Pointer parameter was null.
- **/
- EFI_STATUS
- InitializeMadtHeader (
- IN OUT EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader
- )
- {
- EFI_STATUS Status;
- if (MadtHeader == NULL) {
- DEBUG ((DEBUG_ERROR, "MADT header pointer is NULL\n"));
- return EFI_INVALID_PARAMETER;
- }
- Status = InitializeHeader (
- &MadtHeader->Header,
- EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
- 0
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- MadtHeader->LocalApicAddress = PcdGet32(PcdLocalApicAddress);
- MadtHeader->Flags = EFI_ACPI_4_0_PCAT_COMPAT;
- return EFI_SUCCESS;
- }
- /**
- Copy an ACPI sub-structure; MADT and SRAT supported
- This function validates the structure type and size of a sub-structure
- and returns a newly allocated copy of it.
- @param[in] Header Pointer to the header of the table.
- @param[in] Structure Pointer to the structure to copy.
- @param[in] NewStructure Newly allocated copy of the structure.
- @retval EFI_SUCCESS Successfully copied the structure.
- @retval EFI_INVALID_PARAMETER Pointer parameter was null.
- @retval EFI_INVALID_PARAMETER Structure type was unknown.
- @retval EFI_INVALID_PARAMETER Structure length was wrong for its type.
- @retval EFI_UNSUPPORTED Header passed in is not supported.
- **/
- EFI_STATUS
- CopyStructure (
- IN EFI_ACPI_DESCRIPTION_HEADER *Header,
- IN STRUCTURE_HEADER *Structure,
- OUT STRUCTURE_HEADER **NewStructure
- )
- {
- STRUCTURE_HEADER *NewStructureInternal;
- STRUCTURE_HEADER *StructureTable;
- UINTN TableNumEntries;
- BOOLEAN EntryFound;
- UINT8 Index;
- //
- // Initialize the number of table entries and the table based on the table header passed in.
- //
- if (Header->Signature == EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
- TableNumEntries = sizeof (mMadtStructureTable) / sizeof (STRUCTURE_HEADER);
- StructureTable = mMadtStructureTable;
- } else {
- return EFI_UNSUPPORTED;
- }
- //
- // Check the incoming structure against the table of supported structures.
- //
- EntryFound = FALSE;
- for (Index = 0; Index < TableNumEntries; Index++) {
- if (Structure->Type == StructureTable[Index].Type) {
- if (Structure->Length == StructureTable[Index].Length) {
- EntryFound = TRUE;
- } else {
- DEBUG ((
- DEBUG_ERROR,
- "Invalid length for structure type %d: expected %d, actually %d\n",
- Structure->Type,
- StructureTable[Index].Length,
- Structure->Length
- ));
- return EFI_INVALID_PARAMETER;
- }
- }
- }
- //
- // If no entry in the table matches the structure type and length passed in
- // then return invalid parameter.
- //
- if (!EntryFound) {
- DEBUG ((
- DEBUG_ERROR,
- "Unknown structure type: %d\n",
- Structure->Type
- ));
- return EFI_INVALID_PARAMETER;
- }
- NewStructureInternal = (STRUCTURE_HEADER *) AllocatePool (Structure->Length);
- if (NewStructureInternal == NULL) {
- DEBUG ((
- DEBUG_ERROR,
- "Failed to allocate %d bytes for type %d structure\n",
- Structure->Length,
- Structure->Type
- ));
- return EFI_OUT_OF_RESOURCES;
- } else {
- DEBUG ((
- DEBUG_INFO,
- "Successfully allocated %d bytes for type %d structure at 0x%p\n",
- Structure->Length,
- Structure->Type,
- NewStructureInternal
- ));
- }
- CopyMem (
- (VOID *) NewStructureInternal,
- (VOID *) Structure,
- Structure->Length
- );
- *NewStructure = NewStructureInternal;
- return EFI_SUCCESS;
- }
- /**
- Build ACPI Table. MADT tables supported.
- This function builds the ACPI table from the header plus the list of sub-structures
- passed in. The table returned by this function is ready to be installed using
- the ACPI table protocol's InstallAcpiTable function, which copies it into
- ACPI memory. After that, the caller should free the memory returned by this
- function.
- @param[in] AcpiHeader Pointer to the header structure.
- @param[in] TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
- @param[in] Structures Pointer to an array of sub-structure pointers.
- @param[in] StructureCount Number of structure pointers in the array.
- @param[out] NewTable Newly allocated and initialized pointer to the ACPI Table.
- @retval EFI_SUCCESS Successfully built the ACPI table.
- @retval EFI_INVALID_PARAMETER Pointer parameter was null.
- @retval EFI_INVALID_PARAMETER Header parameter had the wrong signature.
- @retval EFI_OUT_OF_RESOURCES Space for the ACPI Table could not be allocated.
- **/
- EFI_STATUS
- BuildAcpiTable (
- IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader,
- IN UINTN TableSpecificHdrLength,
- IN STRUCTURE_HEADER **Structures,
- IN UINTN StructureCount,
- OUT UINT8 **NewTable
- )
- {
- EFI_STATUS Status;
- EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
- UINTN Index;
- UINT8 *CurrPtr;
- UINT8 *EndOfTablePtr;
- if (AcpiHeader == NULL) {
- DEBUG ((DEBUG_ERROR, "AcpiHeader pointer is NULL\n"));
- return EFI_INVALID_PARAMETER;
- }
- if (AcpiHeader->Signature != EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
- DEBUG ((
- DEBUG_ERROR,
- "MADT header signature is expected, actually 0x%08x\n",
- AcpiHeader->Signature
- ));
- return EFI_INVALID_PARAMETER;
- }
- if (Structures == NULL) {
- DEBUG ((DEBUG_ERROR, "Structure array pointer is NULL\n"));
- return EFI_INVALID_PARAMETER;
- }
- for (Index = 0; Index < StructureCount; Index++) {
- if (Structures[Index] == NULL) {
- DEBUG ((DEBUG_ERROR, "Structure pointer %d is NULL\n", Index));
- return EFI_INVALID_PARAMETER;
- }
- }
- //
- // Allocate the memory needed for the table.
- //
- Status = AllocateTable (
- TableSpecificHdrLength,
- Structures,
- StructureCount,
- &InternalTable
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Copy Header and patch in structure length, checksum is programmed later
- // after all structures are populated.
- //
- CopyMem (
- (VOID *) InternalTable,
- (VOID *) AcpiHeader,
- TableSpecificHdrLength
- );
- InternalTable->Length = GetTableSize (TableSpecificHdrLength, Structures, StructureCount);
- //
- // Copy all the sub structures to the table.
- //
- CurrPtr = ((UINT8 *) InternalTable) + TableSpecificHdrLength;
- EndOfTablePtr = ((UINT8 *) InternalTable) + InternalTable->Length;
- for (Index = 0; Index < StructureCount; Index++) {
- ASSERT (Structures[Index] != NULL);
- if (Structures[Index] == NULL) {
- break;
- }
- CopyMem (
- (VOID *) CurrPtr,
- (VOID *) Structures[Index],
- Structures[Index]->Length
- );
- CurrPtr += Structures[Index]->Length;
- ASSERT (CurrPtr <= EndOfTablePtr);
- if (CurrPtr > EndOfTablePtr) {
- break;
- }
- }
- //
- // Update the return pointer.
- //
- *NewTable = (UINT8 *) InternalTable;
- return EFI_SUCCESS;
- }
- /**
- Build from scratch and install the MADT.
- @retval EFI_SUCCESS The MADT was installed successfully.
- @retval EFI_OUT_OF_RESOURCES Could not allocate required structures.
- **/
- EFI_STATUS
- InstallMadtFromScratch (
- VOID
- )
- {
- EFI_STATUS Status;
- UINTN Index;
- EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *NewMadtTable;
- UINTN TableHandle;
- EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER MadtTableHeader;
- EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE ProcLocalApicStruct;
- EFI_ACPI_4_0_IO_APIC_STRUCTURE IoApicStruct;
- EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE IntSrcOverrideStruct;
- EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE LocalApciNmiStruct;
- EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE ProcLocalX2ApicStruct;
- EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE LocalX2ApicNmiStruct;
- STRUCTURE_HEADER **MadtStructs;
- UINTN MaxMadtStructCount;
- UINTN MadtStructsIndex;
- UINT32 CurrentIoApicAddress = (UINT32)(PcdGet32(PcdPcIoApicAddressBase));
- UINT32 PcIoApicEnable;
- UINT32 PcIoApicMask;
- UINTN PcIoApicIndex;
- DetectApicIdMap();
- // Call for Local APIC ID Reorder
- SortCpuLocalApicInTable ();
- NewMadtTable = NULL;
- MaxMadtStructCount = (UINT32) (
- MAX_CPU_NUM + // processor local APIC structures
- MAX_CPU_NUM + // processor local x2APIC structures
- 1 + PcdGet8(PcdPcIoApicCount) + // I/O APIC structures
- 2 + // interrupt source override structures
- 1 + // local APIC NMI structures
- 1 // local x2APIC NMI structures
- ); // other structures are not used
- MadtStructs = (STRUCTURE_HEADER **) AllocateZeroPool (MaxMadtStructCount * sizeof (STRUCTURE_HEADER *));
- if (MadtStructs == NULL) {
- DEBUG ((DEBUG_ERROR, "Could not allocate MADT structure pointer array\n"));
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Initialize the next index into the structure pointer array. It is
- // incremented every time a structure of any type is copied to the array.
- //
- MadtStructsIndex = 0;
- //
- // Initialize MADT Header Structure
- //
- Status = InitializeMadtHeader (&MadtTableHeader);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "InitializeMadtHeader failed: %r\n", Status));
- goto Done;
- }
- DEBUG ((EFI_D_INFO, "Number of CPUs detected = %d \n", mNumberOfCPUs));
- //
- // Build Processor Local APIC Structures and Processor Local X2APIC Structures
- //
- ProcLocalApicStruct.Type = EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC;
- ProcLocalApicStruct.Length = sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE);
- ProcLocalX2ApicStruct.Type = EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC;
- ProcLocalX2ApicStruct.Length = sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE);
- ProcLocalX2ApicStruct.Reserved[0] = 0;
- ProcLocalX2ApicStruct.Reserved[1] = 0;
- for (Index = 0; Index < MAX_CPU_NUM; Index++) {
- //
- // If x2APIC mode is not enabled, and if it is possible to express the
- // APIC ID as a UINT8, use a processor local APIC structure. Otherwise,
- // use a processor local x2APIC structure.
- //
- if (!mX2ApicEnabled && mCpuApicIdOrderTable[Index].ApicId < MAX_UINT8) {
- ProcLocalApicStruct.Flags = (UINT8) mCpuApicIdOrderTable[Index].Flags;
- ProcLocalApicStruct.ApicId = (UINT8) mCpuApicIdOrderTable[Index].ApicId;
- ProcLocalApicStruct.AcpiProcessorId = (UINT8) mCpuApicIdOrderTable[Index].AcpiProcessorId;
- ASSERT (MadtStructsIndex < MaxMadtStructCount);
- Status = CopyStructure (
- &MadtTableHeader.Header,
- (STRUCTURE_HEADER *) &ProcLocalApicStruct,
- &MadtStructs[MadtStructsIndex++]
- );
- } else if (mCpuApicIdOrderTable[Index].ApicId != 0xFFFFFFFF) {
- ProcLocalX2ApicStruct.Flags = (UINT8) mCpuApicIdOrderTable[Index].Flags;
- ProcLocalX2ApicStruct.X2ApicId = mCpuApicIdOrderTable[Index].ApicId;
- ProcLocalX2ApicStruct.AcpiProcessorUid = mCpuApicIdOrderTable[Index].AcpiProcessorId;
- ASSERT (MadtStructsIndex < MaxMadtStructCount);
- Status = CopyStructure (
- &MadtTableHeader.Header,
- (STRUCTURE_HEADER *) &ProcLocalX2ApicStruct,
- &MadtStructs[MadtStructsIndex++]
- );
- }
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "CopyMadtStructure (local APIC/x2APIC) failed: %r\n", Status));
- goto Done;
- }
- }
- //
- // Build I/O APIC Structures
- //
- IoApicStruct.Type = EFI_ACPI_4_0_IO_APIC;
- IoApicStruct.Length = sizeof (EFI_ACPI_4_0_IO_APIC_STRUCTURE);
- IoApicStruct.Reserved = 0;
- PcIoApicEnable = PcdGet32(PcdPcIoApicEnable);
- if (FixedPcdGet32(PcdMaxCpuSocketCount) <= 4) {
- IoApicStruct.IoApicId = PcdGet8(PcdIoApicId);
- IoApicStruct.IoApicAddress = PcdGet32(PcdIoApicAddress);
- IoApicStruct.GlobalSystemInterruptBase = 0;
- ASSERT (MadtStructsIndex < MaxMadtStructCount);
- Status = CopyStructure (
- &MadtTableHeader.Header,
- (STRUCTURE_HEADER *) &IoApicStruct,
- &MadtStructs[MadtStructsIndex++]
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "CopyMadtStructure (I/O APIC) failed: %r\n", Status));
- goto Done;
- }
- }
- for (PcIoApicIndex = 0; PcIoApicIndex < PcdGet8(PcdPcIoApicCount); PcIoApicIndex++) {
- PcIoApicMask = (1 << PcIoApicIndex);
- if ((PcIoApicEnable & PcIoApicMask) == 0) {
- continue;
- }
- IoApicStruct.IoApicId = (UINT8)(PcdGet8(PcdPcIoApicIdBase) + PcIoApicIndex);
- IoApicStruct.IoApicAddress = CurrentIoApicAddress;
- CurrentIoApicAddress = (CurrentIoApicAddress & 0xFFFF8000) + 0x8000;
- IoApicStruct.GlobalSystemInterruptBase = (UINT32)(24 + (PcIoApicIndex * 8));
- ASSERT (MadtStructsIndex < MaxMadtStructCount);
- Status = CopyStructure (
- &MadtTableHeader.Header,
- (STRUCTURE_HEADER *) &IoApicStruct,
- &MadtStructs[MadtStructsIndex++]
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "CopyMadtStructure (I/O APIC) failed: %r\n", Status));
- goto Done;
- }
- }
- //
- // Build Interrupt Source Override Structures
- //
- IntSrcOverrideStruct.Type = EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE;
- IntSrcOverrideStruct.Length = sizeof (EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE);
- //
- // IRQ0=>IRQ2 Interrupt Source Override Structure
- //
- IntSrcOverrideStruct.Bus = 0x0; // Bus - ISA
- IntSrcOverrideStruct.Source = 0x0; // Source - IRQ0
- IntSrcOverrideStruct.GlobalSystemInterrupt = 0x2; // Global System Interrupt - IRQ2
- IntSrcOverrideStruct.Flags = 0x0; // Flags - Conforms to specifications of the bus
- ASSERT (MadtStructsIndex < MaxMadtStructCount);
- Status = CopyStructure (
- &MadtTableHeader.Header,
- (STRUCTURE_HEADER *) &IntSrcOverrideStruct,
- &MadtStructs[MadtStructsIndex++]
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "CopyMadtStructure (IRQ2 source override) failed: %r\n", Status));
- goto Done;
- }
- //
- // IRQ9 (SCI Active High) Interrupt Source Override Structure
- //
- IntSrcOverrideStruct.Bus = 0x0; // Bus - ISA
- IntSrcOverrideStruct.Source = 0x9; // Source - IRQ9
- IntSrcOverrideStruct.GlobalSystemInterrupt = 0x9; // Global System Interrupt - IRQ9
- IntSrcOverrideStruct.Flags = 0xD; // Flags - Level-tiggered, Active High
- ASSERT (MadtStructsIndex < MaxMadtStructCount);
- Status = CopyStructure (
- &MadtTableHeader.Header,
- (STRUCTURE_HEADER *) &IntSrcOverrideStruct,
- &MadtStructs[MadtStructsIndex++]
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "CopyMadtStructure (IRQ9 source override) failed: %r\n", Status));
- goto Done;
- }
- //
- // Build Local APIC NMI Structures
- //
- LocalApciNmiStruct.Type = EFI_ACPI_4_0_LOCAL_APIC_NMI;
- LocalApciNmiStruct.Length = sizeof (EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE);
- LocalApciNmiStruct.AcpiProcessorId = 0xFF; // Applies to all processors
- LocalApciNmiStruct.Flags = 0x000D; // Flags - Level-tiggered, Active High
- LocalApciNmiStruct.LocalApicLint = 0x1;
- ASSERT (MadtStructsIndex < MaxMadtStructCount);
- Status = CopyStructure (
- &MadtTableHeader.Header,
- (STRUCTURE_HEADER *) &LocalApciNmiStruct,
- &MadtStructs[MadtStructsIndex++]
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "CopyMadtStructure (APIC NMI) failed: %r\n", Status));
- goto Done;
- }
- //
- // Build Local x2APIC NMI Structure
- //
- LocalX2ApicNmiStruct.Type = EFI_ACPI_4_0_LOCAL_X2APIC_NMI;
- LocalX2ApicNmiStruct.Length = sizeof (EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE);
- LocalX2ApicNmiStruct.Flags = 0x000D; // Flags - Level-tiggered, Active High
- LocalX2ApicNmiStruct.AcpiProcessorUid = 0xFFFFFFFF; // Applies to all processors
- LocalX2ApicNmiStruct.LocalX2ApicLint = 0x01;
- LocalX2ApicNmiStruct.Reserved[0] = 0x00;
- LocalX2ApicNmiStruct.Reserved[1] = 0x00;
- LocalX2ApicNmiStruct.Reserved[2] = 0x00;
- ASSERT (MadtStructsIndex < MaxMadtStructCount);
- Status = CopyStructure (
- &MadtTableHeader.Header,
- (STRUCTURE_HEADER *) &LocalX2ApicNmiStruct,
- &MadtStructs[MadtStructsIndex++]
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "CopyMadtStructure (x2APIC NMI) failed: %r\n", Status));
- goto Done;
- }
- //
- // Build Madt Structure from the Madt Header and collection of pointers in MadtStructs[]
- //
- Status = BuildAcpiTable (
- (EFI_ACPI_DESCRIPTION_HEADER *) &MadtTableHeader,
- sizeof (EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER),
- MadtStructs,
- MadtStructsIndex,
- (UINT8 **)&NewMadtTable
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "BuildAcpiTable failed: %r\n", Status));
- goto Done;
- }
- //
- // Publish Madt Structure to ACPI
- //
- Status = mAcpiTable->InstallAcpiTable (
- mAcpiTable,
- NewMadtTable,
- NewMadtTable->Header.Length,
- &TableHandle
- );
- Done:
- //
- // Free memory
- //
- for (MadtStructsIndex = 0; MadtStructsIndex < MaxMadtStructCount; MadtStructsIndex++) {
- if (MadtStructs[MadtStructsIndex] != NULL) {
- FreePool (MadtStructs[MadtStructsIndex]);
- }
- }
- FreePool (MadtStructs);
- if (NewMadtTable != NULL) {
- FreePool (NewMadtTable);
- }
- return Status;
- }
- EFI_STATUS
- InstallMcfgFromScratch (
- VOID
- )
- {
- EFI_STATUS Status;
- EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *McfgTable;
- EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *Segment;
- UINTN Index;
- UINTN SegmentCount;
- PCI_SEGMENT_INFO *PciSegmentInfo;
- UINTN TableHandle;
- PciSegmentInfo = GetPciSegmentInfo (&SegmentCount);
- McfgTable = AllocateZeroPool (
- sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER) +
- sizeof(EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount
- );
- if (McfgTable == NULL) {
- DEBUG ((DEBUG_ERROR, "Could not allocate MCFG structure\n"));
- return EFI_OUT_OF_RESOURCES;
- }
- Status = InitializeHeader (
- &McfgTable->Header,
- EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,
- 0
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Set MCFG table "Length" field based on the number of PCIe segments enumerated so far
- //
- McfgTable->Header.Length = (UINT32)(sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER) +
- sizeof (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount);
- Segment = (VOID *)(McfgTable + 1);
- for (Index = 0; Index < SegmentCount; Index++) {
- Segment[Index].PciSegmentGroupNumber = PciSegmentInfo[Index].SegmentNumber;
- Segment[Index].BaseAddress = PciSegmentInfo[Index].BaseAddress;
- Segment[Index].StartBusNumber = PciSegmentInfo[Index].StartBusNumber;
- Segment[Index].EndBusNumber = PciSegmentInfo[Index].EndBusNumber;
- }
- //
- // Publish Madt Structure to ACPI
- //
- Status = mAcpiTable->InstallAcpiTable (
- mAcpiTable,
- McfgTable,
- McfgTable->Header.Length,
- &TableHandle
- );
- return Status;
- }
- /**
- This function will update any runtime platform specific information.
- This currently includes:
- Setting OEM table values, ID, table ID, creator ID and creator revision.
- Enabling the proper processor entries in the APIC tables
- It also indicates with which ACPI table version the table belongs.
- @param[in] Table The table to update
- @param[in] Version Where to install this table
- @retval EFI_SUCCESS Updated tables commplete.
- **/
- EFI_STATUS
- PlatformUpdateTables (
- IN OUT EFI_ACPI_COMMON_HEADER *Table,
- IN OUT EFI_ACPI_TABLE_VERSION *Version
- )
- {
- EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
- UINT8 *TempOemId;
- UINT64 TempOemTableId;
- EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader;
- EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *HpetTable;
- UINT32 HpetBaseAddress;
- EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_BLOCK_ID HpetBlockId;
- UINT32 HpetCapabilitiesData;
- HPET_GENERAL_CAPABILITIES_ID_REGISTER HpetCapabilities;
- TableHeader = NULL;
- //
- // By default, a table belongs in all ACPI table versions published.
- // Some tables will override this because they have different versions of the table.
- //
- TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
- //
- // Update the OEM and creator information for every table except FACS.
- //
- if (Table->Signature != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
- TempOemId = (UINT8 *)PcdGetPtr(PcdAcpiDefaultOemId);
- CopyMem (&TableHeader->OemId, TempOemId, 6);
- //
- // Skip OEM table ID and creator information for DSDT, SSDT and PSDT tables, since these are
- // created by an ASL compiler and the creator information is useful.
- //
- if (Table->Signature != EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
- Table->Signature != EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
- Table->Signature != EFI_ACPI_1_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
- ) {
- TempOemTableId = PcdGet64(PcdAcpiDefaultOemTableId);
- CopyMem (&TableHeader->OemTableId, &TempOemTableId, 8);
- //
- // Update the creator ID
- //
- TableHeader->CreatorId = PcdGet32(PcdAcpiDefaultCreatorId);
- //
- // Update the creator revision
- //
- TableHeader->CreatorRevision = PcdGet32(PcdAcpiDefaultCreatorRevision);
- }
- }
- //
- // By default, a table belongs in all ACPI table versions published.
- // Some tables will override this because they have different versions of the table.
- //
- *Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
- //
- // Update the various table types with the necessary updates
- //
- switch (Table->Signature) {
- case EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
- ASSERT(FALSE);
- break;
- case EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
- FadtHeader = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table;
- FadtHeader->PreferredPmProfile = PcdGet8 (PcdFadtPreferredPmProfile);
- FadtHeader->IaPcBootArch = PcdGet16 (PcdFadtIaPcBootArch);
- FadtHeader->Flags = PcdGet32 (PcdFadtFlags);
- FadtHeader->AcpiEnable = PcdGet8 (PcdAcpiEnableSwSmi);
- FadtHeader->AcpiDisable = PcdGet8 (PcdAcpiDisableSwSmi);
- FadtHeader->Pm1aEvtBlk = PcdGet16 (PcdAcpiPm1AEventBlockAddress);
- FadtHeader->Pm1bEvtBlk = PcdGet16 (PcdAcpiPm1BEventBlockAddress);
- FadtHeader->Pm1aCntBlk = PcdGet16 (PcdAcpiPm1AControlBlockAddress);
- FadtHeader->Pm1bCntBlk = PcdGet16 (PcdAcpiPm1BControlBlockAddress);
- FadtHeader->Pm2CntBlk = PcdGet16 (PcdAcpiPm2ControlBlockAddress);
- FadtHeader->PmTmrBlk = PcdGet16 (PcdAcpiPmTimerBlockAddress);
- FadtHeader->Gpe0Blk = PcdGet16 (PcdAcpiGpe0BlockAddress);
- FadtHeader->Gpe1Blk = PcdGet16 (PcdAcpiGpe1BlockAddress);
- FadtHeader->XPm1aEvtBlk.Address = PcdGet16 (PcdAcpiPm1AEventBlockAddress);
- FadtHeader->XPm1bEvtBlk.Address = PcdGet16 (PcdAcpiPm1BEventBlockAddress);
- if (FadtHeader->XPm1bEvtBlk.Address == 0) {
- FadtHeader->XPm1bEvtBlk.AccessSize = 0;
- }
- FadtHeader->XPm1aCntBlk.Address = PcdGet16 (PcdAcpiPm1AControlBlockAddress);
- FadtHeader->XPm1bCntBlk.Address = PcdGet16 (PcdAcpiPm1BControlBlockAddress);
- if (FadtHeader->XPm1bCntBlk.Address == 0) {
- FadtHeader->XPm1bCntBlk.AccessSize = 0;
- }
- FadtHeader->XPm2CntBlk.Address = PcdGet16 (PcdAcpiPm2ControlBlockAddress);
- //if (FadtHeader->XPm2CntBlk.Address == 0) {
- FadtHeader->XPm2CntBlk.AccessSize = 0;
- //}
- FadtHeader->XPmTmrBlk.Address = PcdGet16 (PcdAcpiPmTimerBlockAddress);
- FadtHeader->XGpe0Blk.Address = PcdGet16 (PcdAcpiGpe0BlockAddress);
- FadtHeader->XGpe1Blk.Address = PcdGet16 (PcdAcpiGpe1BlockAddress);
- if (FadtHeader->XGpe1Blk.Address == 0) {
- FadtHeader->XGpe1Blk.AccessSize = 0;
- }
- DEBUG(( EFI_D_ERROR, "ACPI FADT table @ address 0x%x\n", Table ));
- DEBUG(( EFI_D_ERROR, " IaPcBootArch 0x%x\n", FadtHeader->IaPcBootArch ));
- DEBUG(( EFI_D_ERROR, " Flags 0x%x\n", FadtHeader->Flags ));
- break;
- case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
- HpetTable = (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *)Table;
- HpetBaseAddress = PcdGet32 (PcdHpetBaseAddress);
- HpetTable->BaseAddressLower32Bit.Address = HpetBaseAddress;
- HpetTable->BaseAddressLower32Bit.RegisterBitWidth = 0;
- HpetCapabilitiesData = MmioRead32 (HpetBaseAddress + HPET_GENERAL_CAPABILITIES_ID_OFFSET);
- HpetCapabilities.Uint64 = HpetCapabilitiesData;
- HpetCapabilitiesData = MmioRead32 (HpetBaseAddress + HPET_GENERAL_CAPABILITIES_ID_OFFSET + 4);
- HpetCapabilities.Uint64 |= LShiftU64 (HpetCapabilitiesData, 32);
- HpetBlockId.Bits.Revision = HpetCapabilities.Bits.Revision;
- HpetBlockId.Bits.NumberOfTimers = HpetCapabilities.Bits.NumberOfTimers;
- HpetBlockId.Bits.CounterSize = HpetCapabilities.Bits.CounterSize;
- HpetBlockId.Bits.Reserved = 0;
- HpetBlockId.Bits.LegacyRoute = HpetCapabilities.Bits.LegacyRoute;
- HpetBlockId.Bits.VendorId = HpetCapabilities.Bits.VendorId;
- HpetTable->EventTimerBlockId = HpetBlockId.Uint32;
- HpetTable->MainCounterMinimumClockTickInPeriodicMode = (UINT16)HpetCapabilities.Bits.CounterClockPeriod;
- DEBUG(( EFI_D_ERROR, "ACPI HPET table @ address 0x%x\n", Table ));
- DEBUG(( EFI_D_ERROR, " HPET base 0x%x\n", PcdGet32 (PcdHpetBaseAddress) ));
- break;
- case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
- ASSERT(FALSE);
- break;
- default:
- break;
- }
- return EFI_SUCCESS;
- }
- /**
- This function calculates RCR based on PCI Device ID and Vendor ID from the devices
- available on the platform.
- It also includes other instances of BIOS change to calculate CRC and provides as
- HWSignature filed in FADT table.
- **/
- VOID
- IsHardwareChange (
- VOID
- )
- {
- EFI_STATUS Status;
- UINTN Index;
- UINTN HandleCount;
- EFI_HANDLE *HandleBuffer;
- EFI_PCI_IO_PROTOCOL *PciIo;
- UINT32 CRC;
- UINT32 *HWChange;
- UINTN HWChangeSize;
- UINT32 PciId;
- UINTN Handle;
- EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *FacsPtr;
- EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *pFADT;
- HandleCount = 0;
- HandleBuffer = NULL;
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiPciIoProtocolGuid,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- return; // PciIO protocol not installed yet!
- }
- //
- // Allocate memory for HWChange and add additional entrie for
- // pFADT->XDsdt
- //
- HWChangeSize = HandleCount + 1;
- HWChange = AllocateZeroPool( sizeof(UINT32) * HWChangeSize );
- ASSERT( HWChange != NULL );
- if (HWChange == NULL) return;
- //
- // add HWChange inputs: PCI devices
- //
- for (Index = 0; HandleCount > 0; HandleCount--) {
- PciId = 0;
- Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **) &PciIo);
- if (!EFI_ERROR (Status)) {
- Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &PciId);
- if (EFI_ERROR (Status)) {
- continue;
- }
- HWChange[Index++] = PciId;
- }
- }
- //
- // Locate FACP Table
- //
- Handle = 0;
- Status = LocateAcpiTableBySignature (
- EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
- (EFI_ACPI_DESCRIPTION_HEADER **) &pFADT,
- &Handle
- );
- if (EFI_ERROR (Status) || (pFADT == NULL)) {
- return; //Table not found or out of memory resource for pFADT table
- }
- //
- // add HWChange inputs: others
- //
- HWChange[Index++] = (UINT32)pFADT->XDsdt;
- //
- // Calculate CRC value with HWChange data.
- //
- Status = gBS->CalculateCrc32(HWChange, HWChangeSize, &CRC);
- DEBUG((DEBUG_INFO, "CRC = %x and Status = %r\n", CRC, Status));
- //
- // Set HardwareSignature value based on CRC value.
- //
- FacsPtr = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)pFADT->FirmwareCtrl;
- FacsPtr->HardwareSignature = CRC;
- FreePool( HWChange );
- }
- VOID
- UpdateLocalTable (
- VOID
- )
- {
- EFI_STATUS Status;
- EFI_ACPI_COMMON_HEADER *CurrentTable;
- EFI_ACPI_TABLE_VERSION Version;
- UINTN TableHandle;
- UINTN Index;
- for (Index = 0; Index < sizeof(mLocalTable)/sizeof(mLocalTable[0]); Index++) {
- CurrentTable = mLocalTable[Index];
- PlatformUpdateTables (CurrentTable, &Version);
- TableHandle = 0;
- if (Version != EFI_ACPI_TABLE_VERSION_NONE) {
- Status = mAcpiTable->InstallAcpiTable (
- mAcpiTable,
- CurrentTable,
- CurrentTable->Length,
- &TableHandle
- );
- ASSERT_EFI_ERROR (Status);
- }
- }
- }
- VOID
- EFIAPI
- AcpiEndOfDxeEvent (
- EFI_EVENT Event,
- VOID *ParentImageHandle
- )
- {
- if (Event != NULL) {
- gBS->CloseEvent(Event);
- }
- //
- // Calculate Hardware Signature value based on current platform configurations
- //
- IsHardwareChange();
- }
- /**
- ACPI Platform driver installation function.
- @param[in] ImageHandle Handle for this drivers loaded image protocol.
- @param[in] SystemTable EFI system table.
- @retval EFI_SUCCESS The driver installed without error.
- @retval EFI_ABORTED The driver encountered an error and could not complete installation of
- the ACPI tables.
- **/
- EFI_STATUS
- EFIAPI
- InstallAcpiPlatform (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- EFI_EVENT EndOfDxeEvent;
- Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&mMpService);
- ASSERT_EFI_ERROR (Status);
- Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&mAcpiTable);
- ASSERT_EFI_ERROR (Status);
- //
- // Create an End of DXE event.
- //
- Status = gBS->CreateEventEx (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- AcpiEndOfDxeEvent,
- NULL,
- &gEfiEndOfDxeEventGroupGuid,
- &EndOfDxeEvent
- );
- ASSERT_EFI_ERROR (Status);
- //
- // Determine the number of processors
- //
- mMpService->GetNumberOfProcessors (
- mMpService,
- &mNumberOfCPUs,
- &mNumberOfEnabledCPUs
- );
- ASSERT (mNumberOfCPUs <= MAX_CPU_NUM && mNumberOfEnabledCPUs >= 1);
- DEBUG ((DEBUG_INFO, "mNumberOfCPUs - %d\n", mNumberOfCPUs));
- DEBUG ((DEBUG_INFO, "mNumberOfEnabledCPUs - %d\n", mNumberOfEnabledCPUs));
- DEBUG ((DEBUG_INFO, "mX2ApicEnabled - 0x%x\n", mX2ApicEnabled));
- DEBUG ((DEBUG_INFO, "mForceX2ApicId - 0x%x\n", mForceX2ApicId));
- // support up to 64 threads/socket
- AsmCpuidEx(CPUID_EXTENDED_TOPOLOGY, 1, &mNumOfBitShift, NULL, NULL, NULL);
- mNumOfBitShift &= 0x1F;
- DEBUG ((DEBUG_INFO, "mNumOfBitShift - 0x%x\n", mNumOfBitShift));
- UpdateLocalTable ();
- InstallMadtFromScratch ();
- InstallMcfgFromScratch ();
- return EFI_SUCCESS;
- }
|