123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710 |
- /** @file
- ACPI Platform Library HMAT
- @copyright
- Copyright 2016 - 2020 Intel Corporation. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- //
- // Statements that include other files
- //
- #include "AcpiPlatformLibLocal.h"
- #include <Library/MemTypeLib.h>
- #include <Protocol/Smbios.h>
- #include <IndustryStandard/SmBios.h>
- //
- // The represented latency/bandwidth in 'System Locality Latency and Bandwidth
- // Information Structure' is expressed in multiples of Entry Base Unit.
- // Unit of latency is picoseconds and bandwidth is megabytes per second
- // Below #defines are be base units and values for calcualting the latency/bandwidth
- // For example: read latency of DDRT is 180ns which is 180000 picoseconds.
- // This is expressed as DDRT_LATENCY_BASE_UNIT of 1000 and DDRT_READ_LATENCY of 180
- //
- #define MEMORY_LATENCY_BASE_UNIT 100
- #define MEMORY_BANDWIDTH_BASE_UNIT 1
- #define DDR2LMCACHE_LATENCY_BASE_UNIT 100
- #define DDR2LMCACHE_BANDWIDTH_BASE_UNIT 1
- #define XSOCKET_LATENCY_BASE_UNIT 100
- #define XSOCKET_BANDWIDTH_BASE_UNIT 1
- //
- // DDRT values
- //
- #define DDRT_ACCESS_LATENCY 0
- #define DDRT_1LM_READ_LATENCY 2535
- #define DDRT_2LM_READ_LATENCY 3285
- #define DDRT_1LM_WRITE_LATENCY 2535
- #define DDRT_2LM_WRITE_LATENCY 3285
- #define DDRT_ACCESS_BANDWIDTH 0
- #define DDRT_1LM_READ_BANDWIDTH 4625
- #define DDRT_2LM_READ_BANDWIDTH 4625
- #define DDRT_1LM_WRITE_BANDWIDTH 1375
- #define DDRT_2LM_WRITE_BANDWIDTH 1375
- //
- // X-SOCKET values
- //
- #define XSOCKET_DDRT_1LM_ACCESS_LATENCY 0
- #define XSOCKET_DDRT_1LM_READ_LATENCY 3160
- #define XSOCKET_DDRT_1LM_WRITE_LATENCY 3160
- #define XSOCKET_DDRT_1LM_ACCESS_BANDWIDTH 0
- #define XSOCKET_DDRT_1LM_READ_BANDWIDTH 4625
- #define XSOCKET_DDRT_1LM_WRITE_BANDWIDTH 1375
- #define XSOCKET_DDRT_2LM_ACCESS_LATENCY 0
- #define XSOCKET_DDRT_2LM_READ_LATENCY 3885
- #define XSOCKET_DDRT_2LM_WRITE_LATENCY 3885
- #define XSOCKET_DDRT_2LM_ACCESS_BANDWIDTH 0
- #define XSOCKET_DDRT_2LM_READ_BANDWIDTH 4625
- #define XSOCKET_DDRT_2LM_WRITE_BANDWIDTH 1375
- //
- // DDR values 1LM or flat mode
- //
- #define DDR_ACCESS_LATENCY 0
- #define DDR_READ_LATENCY 760
- #define DDR_WRITE_LATENCY 760
- #define DDR_ACCESS_BANDWIDTH 0
- #define DDR_READ_BANDWIDTH 17900
- #define DDR_WRITE_BANDWIDTH 19100
- //
- // X-Socket DDR values 1LM or flat mode
- //
- #define XSOCKET_DDR_ACCESS_LATENCY 0
- #define XSOCKET_DDR_READ_LATENCY 1356
- #define XSOCKET_DDR_WRITE_LATENCY 1356
- #define XSOCKET_DDR_ACCESS_BANDWIDTH 0
- #define XSOCKET_DDR_READ_BANDWIDTH 17900
- #define XSOCKET_DDR_WRITE_BANDWIDTH 19100
- //
- // DDR/X-Socket DDR values 2LM when acting as cache
- //
- #define DDR2LMCACHE_ACCESS_LATENCY 0
- #define DDR2LMCACHE_READ_LATENCY 760
- #define DDR2LMCACHE_WRITE_LATENCY 760
- #define DDR2LMCACHE_ACCESS_BANDWIDTH 0
- #define DDR2LMCACHE_READ_BANDWIDTH 17900
- #define DDR2LMCACHE_WRITE_BANDWIDTH 12691
- extern struct SystemMemoryMapHob *mSystemMemoryMap;
- extern EFI_IIO_UDS_PROTOCOL *mIioUds;
- extern SOCKET_MEMORY_CONFIGURATION mSocketMemoryConfiguration;
- extern CPU_CSR_ACCESS_VAR *mCpuCsrAccessVarPtr;
- UINT8 SkippedEntries = 0;
- typedef enum {
- DDR = 0x00,
- DDRT,
- DDR2LMCACHE
- } MemoryType;
- /**
- Dump HMAT Header
- @param [in] HdrPtr Pointer to HMAT Header
- @retval None
- **/
- VOID
- DumpHeader (
- EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER *HdrPtr
- )
- {
- DEBUG ((DEBUG_INFO, "=========== HMAT header ==========\n"));
- DEBUG ((DEBUG_INFO, " Signature: %.4a\n", (CHAR8 *)&HdrPtr->Header.Signature));
- DEBUG ((DEBUG_INFO, " Length: %d\n", HdrPtr->Header.Length));
- DEBUG ((DEBUG_INFO, " Revision: %Xh\n", HdrPtr->Header.Revision));
- DEBUG ((DEBUG_INFO, " Checksum: N/A - CHECKSUM ADDED LATER\n"));
- DEBUG ((DEBUG_INFO, " OemId: %.6a\n", HdrPtr->Header.OemId));
- DEBUG ((DEBUG_INFO, " OemTableId: %.8a\n", (CHAR8 *)&HdrPtr->Header.OemTableId));
- DEBUG ((DEBUG_INFO, " OemRevision: %Xh\n", HdrPtr->Header.OemRevision));
- DEBUG ((DEBUG_INFO, " CreatorId: %.4a\n", (CHAR8 *)&HdrPtr->Header.CreatorId));
- DEBUG ((DEBUG_INFO, " CreatorRevision: %Xh\n", HdrPtr->Header.CreatorRevision));
- DEBUG ((DEBUG_INFO, "==================================\n"));
- DEBUG ((DEBUG_INFO, "\n"));
- }
- /**
- Dump MSARS Structure
- @param [in] MsarsPtr Pointer to MSARS Structure
- @retval None
- **/
- VOID
- DumpMsars (
- MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *MsarsPtr
- )
- {
- DEBUG ((DEBUG_INFO, "=========== MSARS Table =============================\n"));
- DEBUG ((DEBUG_INFO, " Type: %d\n", MsarsPtr->Type));
- DEBUG ((DEBUG_INFO, " Length: %d\n", MsarsPtr->Length));
- DEBUG ((DEBUG_INFO, " ProcessorDomainValid: %d\n", MsarsPtr->Flags.Bits.ProcessorDomainValid));
- DEBUG ((DEBUG_INFO, " MemoryDomainValid: %d\n", MsarsPtr->Flags.Bits.MemoryDomainValid));
- DEBUG ((DEBUG_INFO, " ReservationHint: %d\n", MsarsPtr->Flags.Bits.ReservationHint));
- DEBUG ((DEBUG_INFO, " ProcessorProximityDomain: %Xh\n", MsarsPtr->ProcessorProximityDomain));
- DEBUG ((DEBUG_INFO, " MemoryProximityDomain: %Xh\n", MsarsPtr->MemoryProximityDomain));
- DEBUG ((DEBUG_INFO, " SystemPhysicalAddressRangeBase: %llXh\n", MsarsPtr->AddrBase));
- DEBUG ((DEBUG_INFO, " SystemPhysicalAddressRangeLength: %llXh\n", MsarsPtr->AddrLength));
- DEBUG ((DEBUG_INFO, "=====================================================\n"));
- DEBUG ((DEBUG_INFO, "\n"));
- }
- /**
- Dump HSCIS Structure
- @param [in] MscisPtr Pointer to HSCIS Structure
- @retval None
- **/
- VOID
- DumpMscis (
- MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE *MscisPtr
- )
- {
- UINT8 SmbiosHandleIndex;
- DEBUG ((DEBUG_INFO, "=========== MSCIS Table =============================\n"));
- DEBUG ((DEBUG_INFO, " Type: %d\n", MscisPtr->Type));
- DEBUG ((DEBUG_INFO, " Length: %d\n", MscisPtr->Length));
- DEBUG ((DEBUG_INFO, " MemoryProximityDomain: %Xh\n", MscisPtr->MemoryProximityDomain));
- DEBUG ((DEBUG_INFO, " MemorySideCacheSize: %llXh\n", MscisPtr->MemorySideCacheSize));
- DEBUG ((DEBUG_INFO, " TotalCacheLevels: %d\n", MscisPtr->CacheAttributes.Bits.TotalCacheLevels));
- DEBUG ((DEBUG_INFO, " CacheLevel: %d\n", MscisPtr->CacheAttributes.Bits.CacheLevel));
- DEBUG ((DEBUG_INFO, " CacheAssociativity: %d\n", MscisPtr->CacheAttributes.Bits.CacheAssociativity));
- DEBUG ((DEBUG_INFO, " WritePolicy: %d\n", MscisPtr->CacheAttributes.Bits.WritePolicy));
- DEBUG ((DEBUG_INFO, " CacheLineSize: %d\n", MscisPtr->CacheAttributes.Bits.CacheLineSize));
- DEBUG ((DEBUG_INFO, " NumSmbiosHandles: %d\n", MscisPtr->NumSmbiosHandles));
- for (SmbiosHandleIndex = 0; SmbiosHandleIndex < MscisPtr->NumSmbiosHandles; SmbiosHandleIndex++) {
- DEBUG ((DEBUG_INFO, " SmbiosHandle[%d]: %xh\n", SmbiosHandleIndex + 1 ,MscisPtr->SmbiosHandles[SmbiosHandleIndex]));
- }
- DEBUG ((DEBUG_INFO, "=====================================================\n"));
- DEBUG ((DEBUG_INFO, "\n"));
- }
- /**
- Dump LBIS Structure
- @param [in] LbisPtr Pointer to LBIS Structure
- @retval None
- **/
- VOID
- DumpLbis (
- LATENCY_BANDWIDTH_INFO_STRUCTURE *LbisPtr
- )
- {
- UINTN Index, Index1;
- UINT32 *TargetProximityDomainList;
- UINT16 *Entry;
- DEBUG ((DEBUG_INFO, "=========== MLBIS Table =============================\n"));
- DEBUG ((DEBUG_INFO, " Type: %d\n", LbisPtr->Type));
- DEBUG ((DEBUG_INFO, " Length: %d\n", LbisPtr->Length));
- DEBUG ((DEBUG_INFO, " Flags: %d\n", LbisPtr->Flags));
- DEBUG ((DEBUG_INFO, " DataType: %d\n", LbisPtr->DataType));
- DEBUG ((DEBUG_INFO, " InitiatorProximityDomainsNumber: %d\n", LbisPtr->InitiatorProximityDomainsNumber));
- DEBUG ((DEBUG_INFO, " TargetProximityDomainsNumber: %d\n", LbisPtr->TargetProximityDomainsNumber));
- DEBUG ((DEBUG_INFO, " EntryBaseUnit: %lXh\n", LbisPtr->EntryBaseUnit));
- DEBUG ((DEBUG_INFO, " InitiatorProximityDomainList:\n"));
- for (Index = 0; Index < LbisPtr->InitiatorProximityDomainsNumber; Index++) {
- DEBUG ((DEBUG_INFO, " %d ", LbisPtr->InitiatorProximityDomainList[Index]));
- }
- TargetProximityDomainList = (UINT32*)&(LbisPtr->InitiatorProximityDomainList[Index]);
- DEBUG ((DEBUG_INFO, "\n"));
- DEBUG ((DEBUG_INFO, " TargetProximityDomainList:\n"));
- for (Index = 0; Index < LbisPtr->TargetProximityDomainsNumber; Index++) {
- DEBUG ((DEBUG_INFO, " %d ", TargetProximityDomainList[Index]));
- }
- Entry = (UINT16*)(TargetProximityDomainList + Index);
- DEBUG ((DEBUG_INFO, "\n"));
- DEBUG ((DEBUG_INFO, "RelativeDistanceEntry:\n"));
- for (Index = 0; Index < LbisPtr->InitiatorProximityDomainsNumber; Index++) {
- for (Index1 = 0; Index1 < LbisPtr->TargetProximityDomainsNumber; Index1++) {
- DEBUG ((DEBUG_INFO, " %d ", *(Entry + (Index * LbisPtr->TargetProximityDomainsNumber) + Index1)));
- }
- DEBUG ((DEBUG_INFO, "\n"));
- }
- DEBUG ((DEBUG_INFO, "\n"));
- DEBUG ((DEBUG_INFO, "=====================================================\n"));
- DEBUG ((DEBUG_INFO, "\n"));
- }
- /**
- Dump HMAT table
- @param [in] HmatAcpiTable Pointer to HMAT table.
- @retval None
- **/
- VOID
- DumpHmat (
- EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE *HmatAcpiTable
- )
- {
- UINT32 TotalLength = HmatAcpiTable->HmatHeader.Header.Length;
- UINT8 *Table = (UINT8 *)HmatAcpiTable;
- UINT32 Length;
- UINT16 Type;
- DumpHeader (&HmatAcpiTable->HmatHeader);
- Length = sizeof (EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER);
- Table += Length;
- TotalLength -= Length;
- //
- // Dump tables
- //
- while (TotalLength) {
- Type = ((MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *)Table)->Type;
- //
- // For HBM will need to add LBIS structure
- //
- if (Type == MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE_TYPE) {
- DumpMsars ((MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *)Table);
- } else if (Type == MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE_TYPE) {
- DumpMscis ((MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE *)Table);
- } else {
- DumpLbis ((LATENCY_BANDWIDTH_INFO_STRUCTURE *)Table);
- }
- //
- // Goto next entry
- //
- Length = ((MEMORY_SUBSYSTEM_ADDRESS_RANGE_STRUCTURE *)Table)->Length;
- Table += Length;
- TotalLength -= Length;
- }
- }
- /**
- Update SMBIOS handles and number of SMBIOS handles which is related to specified NodeId to MEMORY_DOMAIN_LIST_INFO
- SMBIOS Type 17 handles are formed in sequence order. First handle is S0 C0 D0, Second handle is S0 C0 D1 and so on.
- So we loop in this order to find the handles of DDR which is part of the specific 2LM cache memory.
- @param [in] HmatData Points to HMAT structure
- @param [in] NodeId SMBIOS handles related to this NodeId will be retrieved
- @retval None
- **/
- VOID
- UpdateSmbiosHandles(
- IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData,
- IN UINT32 NodeId,
- IN UINT8 Socket,
- IN UINT32 ImcBitMap
- )
- {
- EFI_STATUS Status;
- STATIC EFI_SMBIOS_PROTOCOL *Smbios = NULL;
- SMBIOS_TABLE_TYPE17 *Type17Record;
- EFI_SMBIOS_TABLE_HEADER *SmbiosRecord;
- EFI_SMBIOS_HANDLE SmbiosHandle;
- EFI_SMBIOS_TYPE SmbiosType;
- UINT8 Loop = 1;
- UINT8 SlotsPerImc = MAX_DIMM * MAX_MC_CH;
- UINT8 DimmsPerImc = 0;
- Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &Smbios);
- if (EFI_ERROR (Status)) {
- return ;
- }
- SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
- SmbiosType = 17;
- //
- // Adjust ImcBitMap according to the socket number
- //
- if (Socket != 0) {
- ImcBitMap <<= (Socket * SlotsPerImc);
- }
- if (!PcdGetBool (PcdHalfWidth)) {
- DimmsPerImc = SlotsPerImc;
- } else {
- DimmsPerImc = SlotsPerImc - 1;
- }
- do {
- Status = Smbios->GetNext(Smbios, &SmbiosHandle, &SmbiosType, &SmbiosRecord, NULL);
- if (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED)) {
- Type17Record = (SMBIOS_TABLE_TYPE17 *)SmbiosRecord;
- //
- // 1) check whether the Memory device of this record is cache capable(ie, 2LM DDR cache) and
- // 2) this memory handle is to the current looping IMC
- //
- if ((Type17Record->TypeDetail.CacheDram) && (ImcBitMap & BIT0)) {
- HmatData->MemoryDomainList[NodeId].SmbiosHandles[HmatData->MemoryDomainList[NodeId].NumSmbiosHandles] = Type17Record->Hdr.Handle ;
- HmatData->MemoryDomainList[NodeId].NumSmbiosHandles++;
- }
- }
- //
- // if loop done for this IMC then move for next
- //
- if (Loop % DimmsPerImc == 0) {
- ImcBitMap >>= 1;
- }
- ++Loop;
- } while (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED) && (ImcBitMap != 0));
- }
- /**
- Remove slack by moving this substructure lower which removes unused memory.
- @param [in] SlackSize Points to cumulative unused memory size
- @param [in] Src Points to memory to move
- @param [in] SrcLen Size of memory to move
- @retval None
- **/
- VOID
- RemoveSlack (
- IN UINTN *SlackSize,
- IN VOID *Src,
- IN UINTN SrcLen
- )
- {
- VOID *Dst;
- Dst = (UINT8 *)Src - (*SlackSize);
- CopyMem (Dst, Src, SrcLen);
- }
- /**
- Calculate the Memory Proximity Domain Number and generate its associate list.
- @param [in, out] HmatData Pointer to HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be filled
- @retval None.
- **/
- VOID
- GetMemoryDomains (
- IN OUT HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData
- )
- {
- UINT64 MemorySideCacheSize;
- UINT32 NodeId;
- UINT32 LastDomainId = 0;
- UINT8 Index;
- UINT8 PrevIndex;
- UINT8 LastIndex = 0;
- UINT8 Mc;
- UINT8 Socket;
- UINT8 McBitmap[EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS];
- UINT32 PmemEntry[EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS];
- UINT64 MemoryAddressStore[EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS];
- UINT64 MemoryAddress;
- UINT8 MaxEnabledImc = 0;
- UINTN ImcIndex;
- UINT8 MemSocketBitmap = 0;
- UINT8 NoMemSocketBitmap;
- BOOLEAN SkipEntry;
- BOOLEAN UpdateSmbiosHandle = FALSE;
- EFI_STATUS Status = EFI_SUCCESS;
- DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, (VOID **) &DynamicSiLibraryProtocol2);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return;
- }
- HmatData->MemoryDomainNumber = 0;
- ZeroMem (McBitmap, sizeof(McBitmap));
- ZeroMem (MemoryAddressStore, sizeof(MemoryAddressStore));
- //
- // Memory Proximity Domain must match the Domain in the SRAT Memory Affinity structure
- //
- for (Index = 0; Index < mSystemMemoryMap->numberEntries; Index++) {
- //
- // Skip any memory region marked reserved
- //
- if (DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->Element[Index].Type)) {
- continue;
- }
- if (!DynamicSiLibraryProtocol2->IsMemTypeVolatile (mSystemMemoryMap->Element[Index].Type)) {
- //
- // Skip all non volatile regions
- //
- PmemEntry[SkippedEntries] = Index;
- SkippedEntries++;
- continue;
- }
- SkipEntry = FALSE;
- MemoryAddress = LShiftU64 (mSystemMemoryMap->Element[Index].BaseAddress, MEM_ADDR_SHFT_VAL);
- //
- // Skip duplicate entries
- //
- if (Index) {
- for (PrevIndex = 0; PrevIndex < Index; PrevIndex++) {
- if (MemoryAddress == MemoryAddressStore[PrevIndex]) {
- SkipEntry = TRUE;
- break;
- }
- }
- }
- if (SkipEntry) {
- continue;
- }
- MemoryAddressStore[Index] = MemoryAddress;
- LastIndex = Index;
- for (ImcIndex = 0, MaxEnabledImc = 0; ImcIndex < MAX_IMC; ImcIndex++) {
- if (mSystemMemoryMap->Socket[mSystemMemoryMap->Element[Index].SocketId].imcEnabled[ImcIndex] != 0) {
- MaxEnabledImc ++;
- }
- }
- //
- // Update bitmap for sockets with memory populated
- //
- MemSocketBitmap |= BIT0 << mSystemMemoryMap->Element[Index].SocketId;
- //
- // Get memory domain (must match SRAT memory domain)
- //
- NodeId = ProximityDomainOf (
- mSystemMemoryMap->Element[Index].SocketId,
- mSystemMemoryMap->Element[Index].Type,
- MaxEnabledImc,
- HmatData->SncEnabled,
- HmatData->SncNumOfCluster,
- mSystemMemoryMap->Element[Index].ImcInterBitmap,
- mSystemMemoryMap->volMemMode,
- LastDomainId
- );
- NodeId = (NodeId * HmatData->VirtualNumOfCluster) + (Index % HmatData->VirtualNumOfCluster);
- if (LastDomainId < NodeId) {
- LastDomainId = NodeId;
- }
- if (NodeId >= EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS) {
- DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Invalid Memory Proximity Domain (0x%x)\n", NodeId));
- ASSERT (FALSE);
- }
- //
- // Update map of indexes included in this memory domain
- //
- HmatData->MemoryDomainList[NodeId].MemMapIndexMap |= LShiftU64 (BIT0, Index);
- //
- // Update Memory domain count and set domain to valid
- // Prevent counting repeated entries with the same Proximity Domain ID
- //
- if ((Index == 0) || (HmatData->MemoryDomainList[NodeId].Valid == 0)) {
- HmatData->MemoryDomainNumber++;
- HmatData->MemoryDomainList[NodeId].PhysicalSocketId = mSystemMemoryMap->Element[Index].SocketId;
- HmatData->MemoryDomainList[NodeId].Valid = 1;
- McBitmap[NodeId] = 0;
- }
- if (HmatData->MemoryDomainList[NodeId].Valid) {
- if (mSystemMemoryMap->Element[Index].Type == MemType2lmDdrCacheMemoryMode) {
- //
- // Set up side cache info for 2LM
- //
- HmatData->MemoryDomainList[NodeId].Cacheable = 1;
- //
- // Calculate MemorySideCacheSize
- // MemorySideCacheSize for each MC is the DDR4 memSize
- //
- MemorySideCacheSize = 0;
- UpdateSmbiosHandle = FALSE;
- for (Mc = 0; Mc < MAX_IMC; Mc++) {
- if ((mSystemMemoryMap->Element[Index].ImcInterBitmap & (BIT0 << Mc)) && !(McBitmap[NodeId] & (BIT0 << Mc))) {
- UpdateSmbiosHandle = TRUE;
- if (mSystemMemoryMap->volMemMode == VOL_MEM_MODE_2LM) {
- MemorySideCacheSize += mSystemMemoryMap->Socket[mSystemMemoryMap->Element[Index].SocketId].imc[Mc].MemSize;
- } else{ // VOL_MEM_MODE_MIX_1LM2LM
- MemorySideCacheSize += mSystemMemoryMap->DdrCacheSize[mSystemMemoryMap->Element[Index].SocketId][Mc];
- }
- }
- }
- if (UpdateSmbiosHandle) {
- UpdateSmbiosHandles (
- HmatData,
- NodeId,
- mSystemMemoryMap->Element[Index].SocketId,
- mSystemMemoryMap->Element[Index].ImcInterBitmap
- );
- }
- HmatData->MemoryDomainList[NodeId].MemorySideCacheSize += MemorySideCacheSize;
- }
- McBitmap[NodeId] |= mSystemMemoryMap->Element[Index].ImcInterBitmap;
- }
- DEBUG ((DEBUG_INFO, "MemoryDomainList[%x] Valid = %x Cacheable = %x MemorySideCacheSize = %x\n",
- NodeId,
- HmatData->MemoryDomainList[NodeId].Valid,
- HmatData->MemoryDomainList[NodeId].Cacheable,
- HmatData->MemoryDomainList[NodeId].MemorySideCacheSize
- ));
- }
- //
- // Update LastDomainId for enabled sockets with no memory
- //
- NoMemSocketBitmap = mCpuCsrAccessVarPtr->socketPresentBitMap & ~MemSocketBitmap;
- for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
- if ((BIT0 << Socket) & NoMemSocketBitmap) {
- LastDomainId += HmatData->SncNumOfCluster;
- }
- }
- //
- // Add skipped entries
- //
- for (Index = 0; Index < SkippedEntries; Index++) {
- SkipEntry = FALSE;
- MemoryAddress = LShiftU64 (mSystemMemoryMap->Element[PmemEntry[Index]].BaseAddress, MEM_ADDR_SHFT_VAL);
- //
- // Skip duplicate entries
- //
- for (PrevIndex = 0; PrevIndex < LastIndex; PrevIndex++) {
- if (MemoryAddress == MemoryAddressStore[PrevIndex]) {
- SkipEntry = TRUE;
- break;
- }
- }
- if (SkipEntry) {
- continue;
- }
- MemoryAddressStore[LastIndex++] = MemoryAddress;
- //
- // Get memory domain (must match SRAT memory domain)
- //
- NodeId = ProximityDomainOf (
- mSystemMemoryMap->Element[PmemEntry[Index]].SocketId,
- mSystemMemoryMap->Element[PmemEntry[Index]].Type,
- MaxEnabledImc,
- HmatData->SncEnabled,
- HmatData->SncNumOfCluster,
- mSystemMemoryMap->Element[PmemEntry[Index]].ImcInterBitmap,
- mSystemMemoryMap->volMemMode,
- LastDomainId
- );
- NodeId = (NodeId * HmatData->VirtualNumOfCluster) + (Index % HmatData->VirtualNumOfCluster);
- if (LastDomainId < NodeId) {
- LastDomainId = NodeId;
- }
- if (NodeId >= EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS) {
- DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Invalid Memory Proximity Domain (0x%x)\n", NodeId));
- ASSERT (FALSE);
- }
- //
- // Update map of indexes included in this memory domain
- //
- HmatData->MemoryDomainList[NodeId].MemMapIndexMap |= LShiftU64 (BIT0, PmemEntry[Index]);
- //
- // Update Memory domain count and set domain to valid
- // Prevent counting repeated entries with the same Proximity Domain ID
- //
- if ((PmemEntry[Index] == 0) || (HmatData->MemoryDomainList[NodeId].Valid == 0)) {
- HmatData->MemoryDomainNumber++;
- HmatData->MemoryDomainList[NodeId].PhysicalSocketId = mSystemMemoryMap->Element[PmemEntry[Index]].SocketId;
- HmatData->MemoryDomainList[NodeId].Valid = 1;
- }
- DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) MemoryDomainList[%x] Valid = %x Cacheable = %x MemorySideCacheSize = %x\n",
- NodeId,
- HmatData->MemoryDomainList[NodeId].Valid,
- HmatData->MemoryDomainList[NodeId].Cacheable,
- HmatData->MemoryDomainList[NodeId].MemorySideCacheSize
- ));
- }
- }
- /**
- Calculate the Processor Proximity Domain Number and generate its associate list.
- @param [in, out] HmatData Pointer to HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be filled
- @retval None.
- **/
- VOID
- GetProcessorDomains (
- IN OUT HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData
- )
- {
- UINT32 NodeId;
- UINT8 Index;
- INTN FirstImc;
- UINT8 SocketId;
- UINT8 SocketLogicalId;
- UINT8 MemSocketBitmap;
- UINT8 NoMemSocketBitmap;
- EFI_STATUS Status = EFI_SUCCESS;
- DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, (VOID **) &DynamicSiLibraryProtocol2);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return;
- }
- MemSocketBitmap = 0;
- NoMemSocketBitmap = 0;
- HmatData->ProcessorDomainNumber = 0;
- //
- // Processor Proximity Domain must match the Domain in the SRAT APIC or X2APIC Affinity Structure
- //
- for (Index = 0; Index < mSystemMemoryMap->numberEntries; Index++) {
- //
- // Skip any memory region marked reserved or FPGA
- //
- if (DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->Element[Index].Type) || DynamicSiLibraryProtocol2->IsMemTypeFpga (mSystemMemoryMap->Element[Index].Type)) {
- continue;
- }
- SocketId = mSystemMemoryMap->Element[Index].SocketId;
- SocketLogicalId = GetSocketLogicalId (SocketId);
- //
- // Get processor proximity domain
- //
- if (HmatData->SncEnabled || HmatData->VirtualNumaEnabled) {
- FirstImc = LowBitSet32 (mSystemMemoryMap->Element[Index].ImcInterBitmap);
- if (FirstImc == -1) {
- FirstImc = 0;
- }
- //
- // Find the 1st IMC according the interbitmap
- //
- if (MAX_IMC <= HmatData->SncNumOfCluster) {
- NodeId = (SocketLogicalId * HmatData->SncNumOfCluster) + (UINT32)FirstImc;
- } else {
- NodeId = (SocketLogicalId * HmatData->SncNumOfCluster) + ((UINT32)FirstImc) / HmatData->SncNumOfCluster;
- }
- NodeId = (NodeId * HmatData->VirtualNumOfCluster) + (Index % HmatData->VirtualNumOfCluster);
- DEBUG ((DEBUG_INFO, "%a: SocketId: 0x%x SncNumOfCluster: 0x%x ImcInterBitmap:0x%x and NodeId:0x%x\n",
- __FUNCTION__, mSystemMemoryMap->Element[Index].SocketId, HmatData->SncNumOfCluster, mSystemMemoryMap->Element[Index].ImcInterBitmap, NodeId));
- } else {
- NodeId = SocketLogicalId;
- }
- if (NodeId >= EFI_ACPI_HMAT_NUMBER_OF_PROCESSOR_DOMAINS) {
- DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Invalid Processor Proximity Domain (0x%x)\n", NodeId));
- return;
- }
- //
- // Update processor domain count and set domain to valid
- // Prevent counting repeated entries with the same Proximity Domain ID
- //
- if ((Index == 0) || (HmatData->ProcessorDomainList[NodeId] == 0)) {
- HmatData->ProcessorDomainNumber++;
- HmatData->ProcessorDomainSocketIdList[NodeId] = SocketId;
- HmatData->ProcessorDomainList[NodeId] = 1; // Domain is valid
- MemSocketBitmap |= (BIT0 << mSystemMemoryMap->Element[Index].SocketId);
- }
- DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) ProcessorDomainList[%x] Valid = %x\n", NodeId, HmatData->ProcessorDomainList[NodeId]));
- }
- //
- // Update processor domain for enabled sockets without memory
- //
- NoMemSocketBitmap = mCpuCsrAccessVarPtr->socketPresentBitMap & ~MemSocketBitmap;
- for (SocketId = 0; SocketId < MAX_SOCKET; SocketId++) {
- if ((BIT0 << SocketId) & NoMemSocketBitmap) {
- for (Index = 0; Index < (HmatData->SncNumOfCluster * HmatData->VirtualNumOfCluster); Index++) {
- NodeId = GetSocketLogicalId (SocketId) * HmatData->SncNumOfCluster * HmatData->VirtualNumOfCluster + Index;
- HmatData->ProcessorDomainNumber++;
- HmatData->ProcessorDomainSocketIdList[NodeId] = SocketId;
- HmatData->ProcessorDomainList[NodeId] = 1;
- }
- }
- }
- }
- /**
- Initialize HMAT Data to be consumed when populating tables.
- This Functions allocates buffer for HMAT Data, so it is caller responsibility to free it.
- @param None.
- @retval Pointer to allocated HMAT Data if it was initialized correctly.
- @retval NULL if not allocated and not initialized correctly.
- **/
- UINTN *
- InitializeHmatData (
- VOID
- )
- {
- HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData = NULL;
- HmatData = AllocateZeroPool (sizeof (HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE));
- if (HmatData == NULL) {
- DEBUG ((DEBUG_ERROR, "[ACPI] (HMAT) ERROR: Could not allocate HmatData structure pointer\n"));
- return (UINTN *) HmatData;
- }
- if (mIioUds->IioUdsPtr->SystemStatus.OutSncEn) {
- HmatData->SncEnabled = 1;
- HmatData->SncNumOfCluster = mIioUds->IioUdsPtr->SystemStatus.OutNumOfCluster;
- } else {
- HmatData->SncNumOfCluster = 1;
- }
- if (mSystemMemoryMap->VirtualNumaEnable) {
- HmatData->VirtualNumaEnabled = 1;
- HmatData->VirtualNumOfCluster = mSystemMemoryMap->VirtualNumOfCluster;
- } else {
- HmatData->VirtualNumOfCluster = 1;
- }
- GetProcessorDomains (HmatData);
- GetMemoryDomains (HmatData);
- return (UINTN *)HmatData;
- }
- /**
- Patch HMAT MSARS substructure.
- @param [in, out] HmatAcpiTable Points to HMAT table to be modified
- @param [in, out] SlackSize Points to cumulative slack size
- @param [in] HmatData HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be consumed
- @retval None
- **/
- VOID
- PatchHmatMsars (
- IN OUT EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE *HmatAcpiTable,
- IN OUT UINTN *SlackSize,
- IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData
- )
- {
- UINT32 Index;
- UINT32 PrevIndex;
- UINT32 MemoryNodeId;
- UINT32 ProcessorNodeId;
- UINT32 Count = 0;
- UINT32 UnusedCount;
- UINT8 MemoryNodeValid;
- UINT16 ProcessorNodeValid;
- UINT64 MemoryAddress;
- BOOLEAN SkipEntry;
- INTN FirstImc;
- UINT8 SocketLogicalId;
- EFI_STATUS Status = EFI_SUCCESS;
- DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, (VOID **) &DynamicSiLibraryProtocol2);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return;
- }
- DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Populating Memory Subsystem Address Range Structure\n"));
- for (Index = 0; Index < mSystemMemoryMap->numberEntries; Index++) {
- //
- // Skip any memory region marked reserved
- //
- DEBUG ((DEBUG_INFO, "[ACPI] mSystemMemoryMap->Element[%d].Type = 0x%x\n",Index, mSystemMemoryMap->Element[Index].Type));
- if (DynamicSiLibraryProtocol2->IsMemTypeReserved (mSystemMemoryMap->Element[Index].Type)) {
- continue;
- }
- if (Count >= EFI_ACPI_HMAT_MSARS_COUNT) {
- DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Invalid MSARS entry with Index = 0x%x\n", Count));
- ASSERT (FALSE);
- break;
- }
- SkipEntry = FALSE;
- //
- // Skip duplicate entries
- //
- MemoryAddress = LShiftU64 (mSystemMemoryMap->Element[Index].BaseAddress, MEM_ADDR_SHFT_VAL);
- if (Count) {
- for (PrevIndex = 0; PrevIndex < Count; PrevIndex++) {
- if (MemoryAddress == HmatAcpiTable->Msars[PrevIndex].AddrBase) {
- SkipEntry = TRUE;
- break;
- }
- }
- }
- if (SkipEntry) {
- continue;
- }
- //
- // Find memory domain for this index
- //
- for (MemoryNodeId = 0; MemoryNodeId < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS; MemoryNodeId++) {
- if (HmatData->MemoryDomainList[MemoryNodeId].MemMapIndexMap & LShiftU64(BIT0, Index)) {
- break;
- }
- }
- //
- // Fill in valid field
- //
- if (MemoryNodeId < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS) {
- MemoryNodeValid = HmatData->MemoryDomainList[MemoryNodeId].Valid;
- } else {
- MemoryNodeValid = 0;
- }
- //
- // Get processor domain for this index
- //
- if (DynamicSiLibraryProtocol2->IsMemTypeFpga (mSystemMemoryMap->Element[Index].Type)) {
- ProcessorNodeValid = 0; // There is no processor for FPGA.
- ProcessorNodeId = 0; // This field will be ingored for FPGA.
- } else {
- SocketLogicalId = GetSocketLogicalId (mSystemMemoryMap->Element[Index].SocketId);
- if (HmatData->SncEnabled || HmatData->VirtualNumaEnabled) {
- FirstImc = LowBitSet32 (mSystemMemoryMap->Element[Index].ImcInterBitmap);
- if (FirstImc == -1) {
- FirstImc = 0;
- }
- //
- // Find the 1st IMC according the interbitmap
- //
- if (MAX_IMC <= HmatData->SncNumOfCluster) {
- ProcessorNodeId = (SocketLogicalId * HmatData->SncNumOfCluster) + (UINT32)FirstImc;
- } else {
- ProcessorNodeId = (SocketLogicalId * HmatData->SncNumOfCluster) + ((UINT32)FirstImc) / HmatData->SncNumOfCluster;
- }
- ProcessorNodeId = (ProcessorNodeId * HmatData->VirtualNumOfCluster) + (Index % HmatData->VirtualNumOfCluster);
- DEBUG ((DEBUG_INFO, "%a: SocketId: 0x%x SncNumOfCluster: 0x%x ImcInterBitmap:0x%x and NodeId:0x%x \n",
- __FUNCTION__, mSystemMemoryMap->Element[Index].SocketId, HmatData->SncNumOfCluster, mSystemMemoryMap->Element[Index].ImcInterBitmap, ProcessorNodeId));
- } else {
- ProcessorNodeId = SocketLogicalId;
- }
- //
- // Fill in valid field
- //
- if (ProcessorNodeId < EFI_ACPI_HMAT_NUMBER_OF_PROCESSOR_DOMAINS) {
- ProcessorNodeValid = HmatData->ProcessorDomainList[ProcessorNodeId];
- } else {
- ProcessorNodeValid = 0;
- }
- }
- //
- // The HOB has base addr in 64 MB chunks
- //
- HmatAcpiTable->Msars[Count].AddrBase = MemoryAddress;
- HmatAcpiTable->Msars[Count].AddrLength = LShiftU64 (mSystemMemoryMap->Element[Index].ElementSize, MEM_ADDR_SHFT_VAL);
- HmatAcpiTable->Msars[Count].Flags.Value = 0;
- //
- // Fill in Proximity Domains
- //
- HmatAcpiTable->Msars[Count].ProcessorProximityDomain = ProcessorNodeId;
- HmatAcpiTable->Msars[Count].Flags.Bits.ProcessorDomainValid = ProcessorNodeValid;
- HmatAcpiTable->Msars[Count].MemoryProximityDomain = MemoryNodeId;
- HmatAcpiTable->Msars[Count].Flags.Bits.MemoryDomainValid = MemoryNodeValid;
- DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) MSARS[%x] AddrBase = 0x%lx, AddrLength = 0x%lx, MemDomain = %x, ProcDomain = %x\n",
- Count,
- HmatAcpiTable->Msars[Count].AddrBase,
- HmatAcpiTable->Msars[Count].AddrLength,
- MemoryNodeId,
- ProcessorNodeId
- ));
- Count++;
- }
- //
- // Update SlackSize for unused MSARS entries
- //
- UnusedCount = EFI_ACPI_HMAT_MSARS_COUNT - Count;
- *SlackSize += UnusedCount * sizeof(HmatAcpiTable->Msars[0]);
- }
- /**
- Prints HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE for debug purposes.
- @param [in] Lbis Points to HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE to be printed.
- @retval None.
- **/
- VOID
- PrintLbisHmat (
- IN LATENCY_BANDWIDTH_INFO_STRUCTURE *Lbis
- )
- {
- UINT32 Row = 0;
- UINT32 Col = 0;
- UINT32 RowBaseIndex = 0;
- UINT16 *Entry;
- Entry = (UINT16 *) Lbis->RelativeDistanceEntry;
- DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) SLLBIS Data: "));
- DEBUG ((DEBUG_INFO, "InitiatorNumber = %d, TargetNumber = %d. ", Lbis->InitiatorProximityDomainsNumber, Lbis->TargetProximityDomainsNumber));
- DEBUG ((DEBUG_INFO, "Entry Base Unit = %d \n", Lbis->EntryBaseUnit));
- DEBUG ((DEBUG_INFO, " "));
- for (Col = 0; Col < Lbis->TargetProximityDomainsNumber; Col++) {
- DEBUG ((DEBUG_INFO, "%02d ", Lbis->TargetProximityDomainList[Col]));
- }
- DEBUG ((DEBUG_INFO, "\n"));
- for (Row = 0; Row < Lbis->InitiatorProximityDomainsNumber; Row++) {
- RowBaseIndex = Row * Lbis->TargetProximityDomainsNumber;
- DEBUG ((DEBUG_INFO, "%02d ", Lbis->InitiatorProximityDomainList[Row]));
- for (Col = 0; Col < Lbis->TargetProximityDomainsNumber; Col++) {
- DEBUG ((DEBUG_INFO, "%08d ", Entry[RowBaseIndex + Col]));
- }
- DEBUG ((DEBUG_INFO, "\n"));
- }
- }
- /**
- Get the Read/Write/Access bandwidth value of the memory type.
- @param [in] DataType Type of bandwidth value that is required. (Read/Write/Access)
- @param [in] Type Type of memory for which Bandwidth is required. (DDR/DDRT)
- @retval Value of the bandwidth associated with memory type.
- @retval 0xFF Input parameters are invalid.
- **/
- UINT16
- GetMemoryBandWidth (
- IN UINT8 DataType,
- IN MemoryType Type,
- IN UINT8 volMemMode
- )
- {
- if (Type == DDRT) { // MemoryType == DDRT
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_BANDWIDTH :
- return DDRT_ACCESS_BANDWIDTH;
- case EFI_ACPI_HMAT_READ_BANDWIDTH :
- if (volMemMode == VOL_MEM_MODE_1LM) {
- return DDRT_1LM_READ_BANDWIDTH;
- } else {
- return DDRT_2LM_READ_BANDWIDTH;
- }
- case EFI_ACPI_HMAT_WRITE_BANDWIDTH :
- if (volMemMode == VOL_MEM_MODE_1LM) {
- return DDRT_1LM_WRITE_BANDWIDTH;
- } else {
- return DDRT_2LM_WRITE_BANDWIDTH;
- }
- default:
- return 0xFF;
- }
- } else if (Type == DDR2LMCACHE) {
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_BANDWIDTH :
- return DDR2LMCACHE_ACCESS_BANDWIDTH;
- case EFI_ACPI_HMAT_READ_BANDWIDTH :
- return DDR2LMCACHE_READ_BANDWIDTH;
- case EFI_ACPI_HMAT_WRITE_BANDWIDTH :
- return DDR2LMCACHE_WRITE_BANDWIDTH;
- default:
- return 0xFF;
- }
- } else {
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_BANDWIDTH :
- return DDR_ACCESS_BANDWIDTH;
- case EFI_ACPI_HMAT_READ_BANDWIDTH :
- return DDR_READ_BANDWIDTH;
- case EFI_ACPI_HMAT_WRITE_BANDWIDTH :
- return DDR_WRITE_BANDWIDTH;
- default:
- return 0xFF;
- }
- }
- }
- /**
- Get the Read/Write/Access bandwidth value of the memory type across sockets.
- @param [in] DataType Type of bandwidth value that is required. (Read/Write/Access)
- @param [in] Type Type of memory for which Bandwidth is required. (DDR/DDRT)
- @retval Value of the bandwidth associated with memory type.
- @retval 0xFF Input parameters are invalid.
- **/
- UINT16
- GetXSocketMemoryBandWidth (
- IN UINT8 DataType,
- IN MemoryType Type,
- IN UINT8 volMemMode
- )
- {
- if (Type == DDRT) { // MemoryType == DDRT
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_BANDWIDTH:
- return DDRT_ACCESS_BANDWIDTH;
- case EFI_ACPI_HMAT_READ_BANDWIDTH:
- if (volMemMode == VOL_MEM_MODE_1LM) {
- return XSOCKET_DDRT_1LM_READ_BANDWIDTH;
- } else {
- return XSOCKET_DDRT_2LM_READ_BANDWIDTH;
- }
- case EFI_ACPI_HMAT_WRITE_BANDWIDTH:
- if (volMemMode == VOL_MEM_MODE_1LM) {
- return XSOCKET_DDRT_1LM_WRITE_BANDWIDTH;
- } else {
- return XSOCKET_DDRT_2LM_WRITE_BANDWIDTH;
- }
- default:
- return 0xFF;
- }
- } else if (Type == DDR2LMCACHE) {
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_BANDWIDTH:
- return DDR2LMCACHE_ACCESS_BANDWIDTH;
- case EFI_ACPI_HMAT_READ_BANDWIDTH:
- return DDR2LMCACHE_READ_BANDWIDTH;
- case EFI_ACPI_HMAT_WRITE_BANDWIDTH:
- return DDR2LMCACHE_WRITE_BANDWIDTH;
- default:
- return 0xFF;
- }
- } else {
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_BANDWIDTH:
- return XSOCKET_DDR_ACCESS_BANDWIDTH;
- case EFI_ACPI_HMAT_READ_BANDWIDTH:
- return XSOCKET_DDR_READ_BANDWIDTH;
- case EFI_ACPI_HMAT_WRITE_BANDWIDTH:
- return XSOCKET_DDR_WRITE_BANDWIDTH;
- default:
- return 0xFF;
- }
- }
- }
- /**
- Get the Read/Write/Access Latency value of the memory type.
- @param [in] DataType Type of latency value that is required (Read/Write/Access)
- @param [in] Type Type of memory for which Latency is required. (DDR/DDRT)
- @retval Value of the Latency associated with memory type.
- @retval 0xFF Input parameters are invalid.
- **/
- UINT16
- GetMemoryLatency (
- IN UINT8 DataType,
- IN MemoryType Type,
- IN UINT8 volMemMode
- )
- {
- if (Type == DDRT) { // MemoryType == DDRT
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_LATENCY :
- return DDRT_ACCESS_LATENCY;
- case EFI_ACPI_HMAT_READ_LATENCY :
- if (volMemMode == VOL_MEM_MODE_1LM) {
- return DDRT_1LM_READ_LATENCY;
- } else {
- return DDRT_2LM_READ_LATENCY;
- }
- case EFI_ACPI_HMAT_WRITE_LATENCY :
- if (volMemMode == VOL_MEM_MODE_1LM) {
- return DDRT_1LM_WRITE_LATENCY;
- } else {
- return DDRT_2LM_WRITE_LATENCY;
- }
- default:
- return 0xFF;
- }
- } else if (Type == DDR2LMCACHE){
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_LATENCY :
- return DDR2LMCACHE_ACCESS_LATENCY;
- case EFI_ACPI_HMAT_READ_LATENCY :
- return DDR2LMCACHE_READ_LATENCY;
- case EFI_ACPI_HMAT_WRITE_LATENCY :
- return DDR2LMCACHE_WRITE_LATENCY;
- default:
- return 0xFF;
- }
- } else {
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_LATENCY :
- return DDR_ACCESS_LATENCY;
- case EFI_ACPI_HMAT_READ_LATENCY :
- return DDR_READ_LATENCY;
- case EFI_ACPI_HMAT_WRITE_LATENCY :
- return DDR_WRITE_LATENCY;
- default:
- return 0xFF;
- }
- }
- }
- /**
- Get the Read/Write/Access Latency value of the memory type between sockets.
- @param [in] DataType Type of latency value that is required (Read/Write/Access)
- @param [in] Type Type of memory for which Latency is required. (DDR/DDRT)
- @retval Value of the Latency associated with memory type.
- @retval 0xFF Input parameters are invalid.
- **/
- UINT16
- GetXSocketMemoryLatency (
- IN UINT8 DataType,
- IN MemoryType Type,
- IN UINT8 volMemMode
- )
- {
- if (Type == DDRT) { // MemoryType == DDRT
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_LATENCY :
- return DDRT_ACCESS_LATENCY;
- case EFI_ACPI_HMAT_READ_LATENCY :
- if (volMemMode == VOL_MEM_MODE_1LM) {
- return XSOCKET_DDRT_1LM_READ_LATENCY;
- } else {
- return XSOCKET_DDRT_2LM_READ_LATENCY;
- }
- case EFI_ACPI_HMAT_WRITE_LATENCY :
- if (volMemMode == VOL_MEM_MODE_1LM) {
- return XSOCKET_DDRT_1LM_WRITE_LATENCY;
- } else {
- return XSOCKET_DDRT_2LM_WRITE_LATENCY;
- }
- default:
- return 0xFF;
- }
- } else if (Type == DDR2LMCACHE){
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_LATENCY :
- return DDR2LMCACHE_ACCESS_LATENCY;
- case EFI_ACPI_HMAT_READ_LATENCY :
- return DDR2LMCACHE_READ_LATENCY;
- case EFI_ACPI_HMAT_WRITE_LATENCY :
- return DDR2LMCACHE_WRITE_LATENCY;
- default:
- return 0xFF;
- }
- } else {
- switch (DataType) {
- case EFI_ACPI_HMAT_ACCESS_LATENCY :
- return XSOCKET_DDR_ACCESS_LATENCY;
- case EFI_ACPI_HMAT_READ_LATENCY :
- return XSOCKET_DDR_READ_LATENCY;
- case EFI_ACPI_HMAT_WRITE_LATENCY :
- return XSOCKET_DDR_WRITE_LATENCY;
- default:
- return 0xFF;
- }
- }
- }
- /**
- Patch HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE structure.
- @param [in] Lbis Points to HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE to be modified
- @param [in, out] LibsSlackSize Points to cummulative LIBS slack size
- @param [in] HmatData HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be consumed
- @retval None
- **/
- VOID
- PatchBandWidthLbis (
- IN LATENCY_BANDWIDTH_INFO_STRUCTURE **LbisPtr,
- IN OUT UINTN *LibsSlackSize,
- IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData,
- IN UINT8 DataType,
- IN MemoryType Type,
- IN UINT8 volMemMode
- )
- {
- UINT32 Row = 0;
- UINT32 Col = 0;
- UINT32 RowSocketId = 0;
- UINT32 ColSocketId = 0;
- UINT32 RowBaseIndex = 0;
- UINT32 StructSize = 0;
- UINT32 InitiatorIndex = 0;
- UINT32 TargetIndex = 0;
- LATENCY_BANDWIDTH_INFO_STRUCTURE *Lbis = *LbisPtr;
- UINT32 *InitiatorProximityDomainList = (UINT32*)Lbis;
- UINT32 *TargetProximityDomainList = (UINT32*)Lbis;
- UINT16 *RelativeDistanceEntry = (UINT16*)Lbis;
- Lbis->Type = SYSTEM_LOCALITY_LATENCY_BANDWIDTH_INFORMATION_STRUCTURE_TYPE;
- Lbis->DataType = DataType;
- Lbis->InitiatorProximityDomainsNumber = HmatData->ProcessorDomainNumber;
- Lbis->TargetProximityDomainsNumber = HmatData->MemoryDomainNumber;
- switch (Type) {
- case DDR2LMCACHE:
- Lbis->EntryBaseUnit = DDR2LMCACHE_BANDWIDTH_BASE_UNIT;
- Lbis->Flags = EFI_ACPI_HMAT_MEMORY_HIERACHY_LAST_LEVEL_MEMORY;
- break;
- default:
- Lbis->EntryBaseUnit = MEMORY_BANDWIDTH_BASE_UNIT;
- Lbis->Flags = EFI_ACPI_HMAT_MEMORY_HIERACHY_MEMORY;
- }
- InitiatorProximityDomainList = (UINT32*)&(Lbis->InitiatorProximityDomainList[0]);
- StructSize = (UINT32)((UINT8*)InitiatorProximityDomainList - (UINT8*)Lbis);
- StructSize += (Lbis->InitiatorProximityDomainsNumber * (sizeof (UINT32)));
- TargetProximityDomainList = (UINT32*)((UINT8*)TargetProximityDomainList + StructSize);
- StructSize += (Lbis->TargetProximityDomainsNumber * (sizeof (UINT32)));
- RelativeDistanceEntry = (UINT16*)((UINT8*)RelativeDistanceEntry + StructSize);
- StructSize += (Lbis->InitiatorProximityDomainsNumber * Lbis->TargetProximityDomainsNumber * (sizeof (UINT16)));
- Lbis->Length = StructSize;
- for (Row = 0; Row < Lbis->InitiatorProximityDomainsNumber; Row++) {
- *(InitiatorProximityDomainList + Row) = Row;
- }
- for (Row = 0; Row < Lbis->TargetProximityDomainsNumber; Row++) {
- *(TargetProximityDomainList + Row) = Row;
- }
- Row = 0;
- for (InitiatorIndex = 0; InitiatorIndex < EFI_ACPI_HMAT_NUMBER_OF_PROCESSOR_DOMAINS; InitiatorIndex++) {
- if (HmatData->ProcessorDomainList[InitiatorIndex] == 1) {
- RowSocketId = HmatData->ProcessorDomainSocketIdList[InitiatorIndex];
- RowBaseIndex = Row * Lbis->TargetProximityDomainsNumber;
- Col = 0;
- for (TargetIndex = 0; TargetIndex < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS; TargetIndex++) {
- if (HmatData->MemoryDomainList[TargetIndex].Valid == 1) {
- ColSocketId = HmatData->MemoryDomainList[TargetIndex].PhysicalSocketId;
- if (Type == DDR2LMCACHE) {
- //
- // DDR acting as cache for DDRT
- //SocketsLinked
- //
- if (SocketsLinked (RowSocketId, ColSocketId)) {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryBandWidth (DataType, Type, volMemMode);
- } else {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryBandWidth (DataType, Type, volMemMode);
- }
- } else if (mSystemMemoryMap->volMemMode == VOL_MEM_MODE_2LM) {
- //
- // Add only details for DDRT as entire DDR is acting as Cache
- //
- if (SocketsLinked (RowSocketId, ColSocketId)) {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryBandWidth (DataType, DDRT, volMemMode);
- } else {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryBandWidth (DataType, DDRT, volMemMode);
- }
- } else {
- //
- // Neither cache nor 2LM, we need to add details for both DDR and DDRT
- //
- if ((Col / (HmatData->MemoryDomainNumber- SkippedEntries)) == 0) {
- //
- // DDR entries
- //
- if (SocketsLinked (RowSocketId, ColSocketId)) {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryBandWidth (DataType, DDR, volMemMode);
- } else {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryBandWidth (DataType, DDR, volMemMode);
- }
- } else {
- //
- // DDRT entries
- //
- if (SocketsLinked (RowSocketId, ColSocketId)) {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryBandWidth (DataType, DDRT, volMemMode);
- } else {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryBandWidth (DataType, DDRT, volMemMode);
- }
- }
- }
- Col++;
- } //if (HmatData->MemoryDomainList[TargetIndex].Valid == 1)
- } // for (TargetIndex)
- Row++;
- } // if (HmatData->ProcessorDomainList[InitiatorIndex] == 1)
- } //for (InitiatorIndex)
- *LibsSlackSize += StructSize;
- *LbisPtr = (LATENCY_BANDWIDTH_INFO_STRUCTURE *)((UINT8*)Lbis + StructSize);
- }
- /**
- Patch HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE structure.
- @param [in] Lbis Points to HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE to be modified
- @param [in, out] LibsSlackSize Points to cumulative LIBS slack size
- @param [in] HmatData HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be consumed
- @retval None
- **/
- VOID
- PatchMemoryLatencyLbis (
- IN LATENCY_BANDWIDTH_INFO_STRUCTURE **LbisPtr,
- IN OUT UINTN *LibsSlackSize,
- IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData,
- IN UINT8 DataType,
- IN MemoryType Type,
- IN UINT8 volMemMode
- )
- {
- UINT32 Row = 0;
- UINT32 Col = 0;
- UINT32 RowSocketId = 0;
- UINT32 ColSocketId = 0;
- UINT32 RowBaseIndex = 0;
- UINT32 StructSize = 0;
- UINT32 InitiatorIndex = 0;
- UINT32 TargetIndex = 0;
- LATENCY_BANDWIDTH_INFO_STRUCTURE *Lbis = *LbisPtr;
- UINT32 *InitiatorProximityDomainList = (UINT32*)Lbis;
- UINT32 *TargetProximityDomainList = (UINT32*)Lbis;
- UINT16 *RelativeDistanceEntry = (UINT16*)Lbis;
- Lbis->Type = SYSTEM_LOCALITY_LATENCY_BANDWIDTH_INFORMATION_STRUCTURE_TYPE;
- Lbis->DataType = DataType;
- Lbis->InitiatorProximityDomainsNumber = HmatData->ProcessorDomainNumber;
- Lbis->TargetProximityDomainsNumber = HmatData->MemoryDomainNumber;
- switch (Type) {
- case DDR2LMCACHE:
- Lbis->EntryBaseUnit = DDR2LMCACHE_BANDWIDTH_BASE_UNIT;
- Lbis->Flags = EFI_ACPI_HMAT_MEMORY_HIERACHY_LAST_LEVEL_MEMORY;
- break;
- default:
- Lbis->EntryBaseUnit = MEMORY_LATENCY_BASE_UNIT;
- Lbis->Flags = EFI_ACPI_HMAT_MEMORY_HIERACHY_MEMORY;
- }
- InitiatorProximityDomainList = (UINT32*)&(Lbis->InitiatorProximityDomainList[0]);
- StructSize = (UINT32)((UINT8*)InitiatorProximityDomainList - (UINT8*)Lbis);
- StructSize += (Lbis->InitiatorProximityDomainsNumber * (sizeof (UINT32)));
- TargetProximityDomainList = (UINT32*)((UINT8*)TargetProximityDomainList + StructSize);
- StructSize += (Lbis->TargetProximityDomainsNumber * (sizeof (UINT32)));
- RelativeDistanceEntry = (UINT16*)((UINT8*)RelativeDistanceEntry + StructSize);
- StructSize += (Lbis->InitiatorProximityDomainsNumber * Lbis->TargetProximityDomainsNumber * (sizeof (UINT16)));
- Lbis->Length = StructSize;
- for (Row = 0; Row < Lbis->InitiatorProximityDomainsNumber; Row++) {
- *(InitiatorProximityDomainList + Row) = Row;
- }
- for (Row = 0; Row < Lbis->TargetProximityDomainsNumber; Row++) {
- *(TargetProximityDomainList + Row) = Row;
- }
- Row = 0;
- for (InitiatorIndex = 0; InitiatorIndex < EFI_ACPI_HMAT_NUMBER_OF_PROCESSOR_DOMAINS; InitiatorIndex++) {
- if (HmatData->ProcessorDomainList[InitiatorIndex] == 1) {
- RowSocketId = HmatData->ProcessorDomainSocketIdList[InitiatorIndex];
- RowBaseIndex = Row * Lbis->TargetProximityDomainsNumber;
- Col = 0;
- for (TargetIndex = 0; TargetIndex < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS; TargetIndex++) {
- if (HmatData->MemoryDomainList[TargetIndex].Valid == 1) {
- ColSocketId = HmatData->MemoryDomainList[TargetIndex].PhysicalSocketId;
- if (Type == DDR2LMCACHE) {
- //
- // DDR acting as cache for DDRT
- //
- if (SocketsLinked (RowSocketId, ColSocketId)) {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryLatency (DataType, Type, volMemMode);
- } else {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryLatency (DataType, Type, volMemMode);
- }
- } else if (mSystemMemoryMap->volMemMode == VOL_MEM_MODE_2LM) {
- //
- // Add only details for DDRT as entire DDR is acting as Cache
- //
- if (SocketsLinked (RowSocketId, ColSocketId)) {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryLatency (DataType, DDRT, volMemMode);
- } else {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryLatency (DataType, DDRT, volMemMode);
- }
- } else {
- //
- // Neither cache nor 2LM, we need to add details for both DDR and DDRT
- //
- if ((Col / (HmatData->MemoryDomainNumber - SkippedEntries)) == 0) {
- //
- // DDR entries
- //
- if (SocketsLinked (RowSocketId, ColSocketId)) {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryLatency (DataType, DDR, volMemMode);
- } else {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryLatency (DataType, DDR, volMemMode);
- }
- } else {
- //
- // DDRT entries
- //
- if (SocketsLinked (RowSocketId, ColSocketId)) {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetXSocketMemoryLatency (DataType, DDRT, volMemMode);
- } else {
- RelativeDistanceEntry[RowBaseIndex + Col] = GetMemoryLatency (DataType, DDRT, volMemMode);
- }
- }
- }
- Col++;
- } //if (HmatData->MemoryDomainList[TargetIndex].Valid == 1)
- } // for (TargetIndex)
- Row++;
- } // if (HmatData->ProcessorDomainList[InitiatorIndex] == 1)
- } //for (InitiatorIndex)
- *LibsSlackSize += StructSize;
- *LbisPtr = (LATENCY_BANDWIDTH_INFO_STRUCTURE *)((UINT8*)Lbis + StructSize);
- }
- /**
- Patch HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE structure.
- @param [in] Lbis Points to HMAT LATENCY_BANDWIDTH_INFO_STRUCTURE to be modified
- @param [in, out] SlackSize Points to cummulative slack size
- @param [in] HmatData HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be consumed
- @retval None
- **/
- VOID
- PatchHmatLbis (
- IN LATENCY_BANDWIDTH_INFO_STRUCTURE *Lbis,
- IN OUT UINTN *SlackSize,
- IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData
- )
- {
- UINTN LibsStructSize=0;
- UINT8 volMemMode;
- LATENCY_BANDWIDTH_INFO_STRUCTURE *OrginalLbis = Lbis;
- volMemMode = mSystemMemoryMap->volMemMode;
- DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Populating System Locality Latency and Bandwidth Information Structure\n"));
- PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_READ_LATENCY, DDR, volMemMode);
- PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_WRITE_LATENCY, DDR, volMemMode);
- PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_READ_BANDWIDTH, DDR, volMemMode);
- PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_WRITE_BANDWIDTH, DDR, volMemMode);
- if (mSystemMemoryMap->volMemMode != VOL_MEM_MODE_1LM) {
- PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_READ_LATENCY, DDR2LMCACHE, volMemMode);
- PatchMemoryLatencyLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_WRITE_LATENCY, DDR2LMCACHE, volMemMode);
- PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_READ_BANDWIDTH, DDR2LMCACHE, volMemMode);
- PatchBandWidthLbis (&Lbis, &LibsStructSize, HmatData, EFI_ACPI_HMAT_WRITE_BANDWIDTH, DDR2LMCACHE, volMemMode);
- }
- RemoveSlack (SlackSize, OrginalLbis, LibsStructSize);
- *SlackSize += EFI_ACPI_HMAT_LBIS_COUNT * sizeof(Lbis[0]) - LibsStructSize;
- }
- /**
- Get Type 17 Handles for HBM devices used as cache.
- @param [in, out] SmbiosHandles Points to SmbiosHandles array to be modified
- @param [in] NumaNode Value for NUMA Node whose memory is being cached for the specific HBM devices
- @retval None
- **/
- VOID
- GetHbmCacheHandles (
- IN UINT16 *SmbiosHandles,
- IN UINT8 NumaNode
- )
- {
- EFI_STATUS Status = EFI_SUCCESS;
- SMBIOS_TABLE_TYPE17 *SmbiosType17Record;
- EFI_SMBIOS_HANDLE SmbiosHandle = 0;
- EFI_SMBIOS_PROTOCOL *mSmbios;
- EFI_SMBIOS_TYPE SmbiosType = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
- EFI_SMBIOS_TABLE_HEADER *SmbiosRecord;
- UINT8 HbmHandleCount = 0;
- Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &mSmbios);
- if (!(EFI_ERROR (Status))) {
- while ((!(EFI_ERROR (Status))) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED) ){
- Status = mSmbios->GetNext (mSmbios, &SmbiosHandle, &SmbiosType, &SmbiosRecord, NULL);
- SmbiosType17Record = (SMBIOS_TABLE_TYPE17 *) SmbiosRecord;
- if ((SmbiosType17Record->TypeDetail.CacheDram == 1) && (SmbiosType17Record->DeviceSet == NumaNode) ) {
- SmbiosHandles[HbmHandleCount] = SmbiosType17Record->Hdr.Handle;
- HbmHandleCount++;
- }
- }
- }
- }
- /**
- Patch HMAT MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE substructure.
- @param [in, out] Mscis Points to HMAT MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE to be modified
- @param [in, out] SlackSize Points to cumulative slack size
- @param [in] HmatData HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE to be consumed
- @retval None
- **/
- VOID
- PatchHmatMscis (
- IN OUT MEMORY_SIDE_CACHE_INFORMATION_STRUCTURE *Mscis,
- IN OUT UINTN *SlackSize,
- IN HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData
- )
- {
- UINT32 Index;
- UINT32 Count = 0;
- UINT32 UnusedCount;
- UINT8 SmbiosHandleIndex;
- DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) Populating Memory Side Cache Information Structure\n"));
- for (Index = 0; Index < EFI_ACPI_HMAT_NUMBER_OF_MEMORY_DOMAINS; Index++) {
- if ((HmatData->MemoryDomainList[Index].Valid == 0) || (HmatData->MemoryDomainList[Index].Cacheable == 0)) {
- continue;
- }
- //
- // Fill in fields for Cached Memory Domains
- //
- Mscis[Count].MemoryProximityDomain = Index;
- Mscis[Count].CacheAttributes.Bits.TotalCacheLevels = EFI_ACPI_HMAT_ONE_LEVEL_CACHE;
- Mscis[Count].CacheAttributes.Bits.CacheLevel = EFI_ACPI_HMAT_ONE_LEVEL_CACHE;
- Mscis[Count].CacheAttributes.Bits.CacheLineSize = DDR4_CACHE_LINE_SIZE;
- Mscis[Count].CacheAttributes.Bits.CacheAssociativity = EFI_ACPI_HMAT_CACHE_ASSOCIATIVITY_DIRECT_MAPPED;
- Mscis[Count].CacheAttributes.Bits.WritePolicy = EFI_ACPI_HMAT_WRITE_POLICY_WB;
- Mscis[Count].MemorySideCacheSize = LShiftU64 (HmatData->MemoryDomainList[Index].MemorySideCacheSize, MEM_ADDR_SHFT_VAL);
- Mscis[Count].NumSmbiosHandles = HmatData->MemoryDomainList[Index].NumSmbiosHandles;
- for(SmbiosHandleIndex = 0 ; SmbiosHandleIndex < HmatData->MemoryDomainList[Index].NumSmbiosHandles; SmbiosHandleIndex++){
- Mscis[Count].SmbiosHandles[SmbiosHandleIndex] = HmatData->MemoryDomainList[Index].SmbiosHandles[SmbiosHandleIndex];
- }
- DEBUG ((DEBUG_INFO, "[ACPI] (HMAT) MSCIS[%x] MemorySideCacheSize = 0x%lx, ProximityDomain = %x\n", Count, Mscis[Count].MemorySideCacheSize, Index));
- Count++;
- }
- //
- // Move MSCIS entries up to replace removed MSARS entries
- //
- if (*SlackSize && Count) {
- RemoveSlack (SlackSize, Mscis, Count * sizeof(Mscis[0]));
- }
- //
- // Update SlackSize for unused MSCIS entries
- //
- UnusedCount = EFI_ACPI_HMAT_MSCIS_COUNT - Count;
- *SlackSize += UnusedCount * sizeof(Mscis[0]);
- }
- /**
- Update the HMAT table.
- @param [in, out] HmatAcpiTable The table to be set.
- @retval EFI SUCCESS Procedure returned successfully.
- **/
- EFI_STATUS
- PatchHmatAcpiTable (
- IN OUT EFI_ACPI_COMMON_HEADER *Table
- )
- {
- UINTN SlackSize = 0;
- HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *HmatData = NULL;
- EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE *HmatAcpiTable;
- if (mSystemMemoryMap == NULL) {
- ASSERT (FALSE);
- return EFI_UNSUPPORTED;
- }
- HmatAcpiTable = (EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE *)Table;
- HmatData = (HMAT_PROXIMITY_DOMAIN_DATA_STRUCTURE *) InitializeHmatData ();
- if (HmatData == NULL) {
- DEBUG ((DEBUG_ERROR, "ACPI (HMAT) HMAT Data could not be initialized... skipping HMAT Patch\n"));
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Patch the MSARS, SLLBIS, and MSCIS Structure from HMAT Table.
- //
- PatchHmatMsars (HmatAcpiTable, &SlackSize, HmatData);
- PatchHmatLbis (HmatAcpiTable->Lbis, &SlackSize, HmatData);
- PatchHmatMscis (HmatAcpiTable->MemSideCache, &SlackSize, HmatData);
- if (HmatData != NULL) {
- FreePool (HmatData);
- }
- //
- // Update HMAT table size
- //
- HmatAcpiTable->HmatHeader.Header.Length -= (UINT32)SlackSize;
- //
- // Dump HMAT
- //
- DumpHmat (HmatAcpiTable);
- return EFI_SUCCESS;
- }
|