TianoCore EDK2 master
Loading...
Searching...
No Matches
SratGenerator.c
Go to the documentation of this file.
1
15#include <Library/AcpiLib.h>
16#include <Library/BaseLib.h>
17#include <Library/DebugLib.h>
19#include <Protocol/AcpiTable.h>
20
21// Module specific include files.
22#include <AcpiTableGenerator.h>
27
28#include "SratGenerator.h"
29
49 );
50
59 );
60
69 );
70
79 );
80
92UINT16
95 )
96{
97 UINT16 Bdf;
98
99 Bdf = (UINT16)DeviceHandlePci->BusNumber << 8;
100 Bdf |= (DeviceHandlePci->DeviceNumber & 0x1F) << 3;
101 Bdf |= DeviceHandlePci->FunctionNumber & 0x7;
102 return Bdf;
103}
104
117STATIC
122 IN CONST UINT32 MemAffOffset,
124 IN UINT32 MemAffCount
125 )
126{
128
129 ASSERT (Srat != NULL);
130 ASSERT (MemAffInfo != NULL);
131
132 MemAff = (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *)((UINT8 *)Srat +
133 MemAffOffset);
134
135 while (MemAffCount-- != 0) {
136 DEBUG ((DEBUG_INFO, "SRAT: MemAff = 0x%p\n", MemAff));
137
138 MemAff->Type = EFI_ACPI_6_3_MEMORY_AFFINITY;
139 MemAff->Length = sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE);
140 MemAff->ProximityDomain = MemAffInfo->ProximityDomain;
141 MemAff->Reserved1 = EFI_ACPI_RESERVED_WORD;
142 MemAff->AddressBaseLow = (UINT32)(MemAffInfo->BaseAddress & MAX_UINT32);
143 MemAff->AddressBaseHigh = (UINT32)(MemAffInfo->BaseAddress >> 32);
144 MemAff->LengthLow = (UINT32)(MemAffInfo->Length & MAX_UINT32);
145 MemAff->LengthHigh = (UINT32)(MemAffInfo->Length >> 32);
146 MemAff->Reserved2 = EFI_ACPI_RESERVED_DWORD;
147 MemAff->Flags = MemAffInfo->Flags;
148 MemAff->Reserved3 = EFI_ACPI_RESERVED_QWORD;
149
150 // Next
151 MemAff++;
152 MemAffInfo++;
153 }// while
154
155 return EFI_SUCCESS;
156}
157
177STATIC
182 IN CONST UINT32 GenInitAffOff,
184 IN UINT32 GenInitAffCount
185 )
186{
187 EFI_STATUS Status;
189 CM_ARCH_COMMON_DEVICE_HANDLE_ACPI *DeviceHandleAcpi;
190 CM_ARCH_COMMON_DEVICE_HANDLE_PCI *DeviceHandlePci;
191 UINT32 DeviceHandleCount;
192
193 ASSERT (Srat != NULL);
194 ASSERT (GenInitAffInfo != NULL);
195
197 (UINT8 *)Srat + GenInitAffOff);
198
199 while (GenInitAffCount-- != 0) {
200 DEBUG ((DEBUG_INFO, "SRAT: GenInitAff = 0x%p\n", GenInitAff));
201
202 GenInitAff->Type = EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY;
203 GenInitAff->Length =
205 GenInitAff->Reserved1 = EFI_ACPI_RESERVED_WORD;
206 GenInitAff->DeviceHandleType = GenInitAffInfo->DeviceHandleType;
207 GenInitAff->ProximityDomain = GenInitAffInfo->ProximityDomain;
208
209 if (GenInitAffInfo->DeviceHandleToken == CM_NULL_TOKEN) {
210 DEBUG ((
211 DEBUG_ERROR,
212 "ERROR: SRAT: Invalid Device Handle Token.\n"
213 ));
214 ASSERT (0);
215 return EFI_INVALID_PARAMETER;
216 }
217
218 if (GenInitAffInfo->DeviceHandleType == EFI_ACPI_6_3_ACPI_DEVICE_HANDLE) {
219 Status = GetEArchCommonObjDeviceHandleAcpi (
220 CfgMgrProtocol,
221 GenInitAffInfo->DeviceHandleToken,
222 &DeviceHandleAcpi,
223 &DeviceHandleCount
224 );
225 if (EFI_ERROR (Status)) {
226 DEBUG ((
227 DEBUG_ERROR,
228 "ERROR: SRAT: Failed to get ACPI Device Handle Inf."
229 " DeviceHandleToken = %p."
230 " Status = %r\n",
231 GenInitAffInfo->DeviceHandleToken,
232 Status
233 ));
234 return Status;
235 }
236
237 // We are expecting only one device handle.
238 ASSERT (DeviceHandleCount == 1);
239
240 // Populate the ACPI device handle information.
241 GenInitAff->DeviceHandle.Acpi.AcpiHid = DeviceHandleAcpi->Hid;
242 GenInitAff->DeviceHandle.Acpi.AcpiUid = DeviceHandleAcpi->Uid;
243 GenInitAff->DeviceHandle.Acpi.Reserved[0] = EFI_ACPI_RESERVED_BYTE;
244 GenInitAff->DeviceHandle.Acpi.Reserved[1] = EFI_ACPI_RESERVED_BYTE;
245 GenInitAff->DeviceHandle.Acpi.Reserved[2] = EFI_ACPI_RESERVED_BYTE;
246 GenInitAff->DeviceHandle.Acpi.Reserved[3] = EFI_ACPI_RESERVED_BYTE;
247 } else if (GenInitAffInfo->DeviceHandleType ==
248 EFI_ACPI_6_3_PCI_DEVICE_HANDLE)
249 {
250 Status = GetEArchCommonObjDeviceHandlePci (
251 CfgMgrProtocol,
252 GenInitAffInfo->DeviceHandleToken,
253 &DeviceHandlePci,
254 &DeviceHandleCount
255 );
256 if (EFI_ERROR (Status)) {
257 DEBUG ((
258 DEBUG_ERROR,
259 "ERROR: SRAT: Failed to get ACPI Device Handle Inf."
260 " DeviceHandleToken = %p."
261 " Status = %r\n",
262 GenInitAffInfo->DeviceHandleToken,
263 Status
264 ));
265 return Status;
266 }
267
268 // We are expecting only one device handle
269 ASSERT (DeviceHandleCount == 1);
270
271 // Populate the ACPI device handle information.
272 GenInitAff->DeviceHandle.Pci.PciSegment = DeviceHandlePci->SegmentNumber;
273 GenInitAff->DeviceHandle.Pci.PciBdfNumber = GetBdf (DeviceHandlePci);
274
275 GenInitAff->DeviceHandle.Pci.Reserved[0] = EFI_ACPI_RESERVED_BYTE;
276 GenInitAff->DeviceHandle.Pci.Reserved[1] = EFI_ACPI_RESERVED_BYTE;
277 GenInitAff->DeviceHandle.Pci.Reserved[2] = EFI_ACPI_RESERVED_BYTE;
278 GenInitAff->DeviceHandle.Pci.Reserved[3] = EFI_ACPI_RESERVED_BYTE;
279 GenInitAff->DeviceHandle.Pci.Reserved[4] = EFI_ACPI_RESERVED_BYTE;
280 GenInitAff->DeviceHandle.Pci.Reserved[5] = EFI_ACPI_RESERVED_BYTE;
281 GenInitAff->DeviceHandle.Pci.Reserved[6] = EFI_ACPI_RESERVED_BYTE;
282 GenInitAff->DeviceHandle.Pci.Reserved[7] = EFI_ACPI_RESERVED_BYTE;
283 GenInitAff->DeviceHandle.Pci.Reserved[8] = EFI_ACPI_RESERVED_BYTE;
284 GenInitAff->DeviceHandle.Pci.Reserved[9] = EFI_ACPI_RESERVED_BYTE;
285 GenInitAff->DeviceHandle.Pci.Reserved[10] = EFI_ACPI_RESERVED_BYTE;
286 GenInitAff->DeviceHandle.Pci.Reserved[11] = EFI_ACPI_RESERVED_BYTE;
287 } else {
288 DEBUG ((
289 DEBUG_ERROR,
290 "ERROR: SRAT: Invalid Device Handle Type.\n"
291 ));
292 ASSERT (0);
293 return EFI_INVALID_PARAMETER;
294 }
295
296 GenInitAff->Flags = GenInitAffInfo->Flags;
297 GenInitAff->Reserved2[0] = EFI_ACPI_RESERVED_BYTE;
298 GenInitAff->Reserved2[1] = EFI_ACPI_RESERVED_BYTE;
299
300 // Next
301 GenInitAff++;
302 GenInitAffInfo++;
303 }// while
304
305 return EFI_SUCCESS;
306}
307
331STATIC
333EFIAPI
339 )
340{
341 EFI_STATUS Status;
342 UINT32 TableSize;
343 UINT32 MemAffCount;
344 UINT32 GenInitiatorAffCount;
345
346 UINT32 MemAffOffset;
347 UINT32 GenInitiatorAffOffset;
348
351
353
354 ASSERT (
355 (This != NULL) &&
356 (AcpiTableInfo != NULL) &&
357 (CfgMgrProtocol != NULL) &&
358 (Table != NULL) &&
359 (AcpiTableInfo->TableGeneratorId == This->GeneratorID) &&
360 (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature)
361 );
362
363 if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||
364 (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision))
365 {
366 DEBUG ((
367 DEBUG_ERROR,
368 "ERROR: SRAT: Requested table revision = %d is not supported. "
369 "Supported table revisions: Minimum = %d. Maximum = %d\n",
370 AcpiTableInfo->AcpiTableRevision,
371 This->MinAcpiTableRevision,
372 This->AcpiTableRevision
373 ));
374 return EFI_INVALID_PARAMETER;
375 }
376
377 *Table = NULL;
378
379 Status = GetEArchCommonObjMemoryAffinityInfo (
380 CfgMgrProtocol,
382 &MemAffInfo,
383 &MemAffCount
384 );
385 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
386 DEBUG ((
387 DEBUG_ERROR,
388 "ERROR: SRAT: Failed to get Memory Affinity Info. Status = %r\n",
389 Status
390 ));
391 goto error_handler;
392 }
393
394 Status = GetEArchCommonObjGenericInitiatorAffinityInfo (
395 CfgMgrProtocol,
397 &GenInitiatorAffInfo,
398 &GenInitiatorAffCount
399 );
400 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
401 DEBUG ((
402 DEBUG_ERROR,
403 "ERROR: SRAT: Failed to get Generic Initiator Affinity Info."
404 " Status = %r\n",
405 Status
406 ));
407 goto error_handler;
408 }
409
410 // Calculate the size of the SRAT table
412
413 // Place the Arch specific subtables/structures first and
414 // reserve the offsets. The common subtables/structures
415 // are placed next.
416 Status = ArchReserveOffsets (CfgMgrProtocol, &TableSize);
417 if (EFI_ERROR (Status)) {
418 DEBUG ((
419 DEBUG_ERROR,
420 "ERROR: SRAT: Failed to reserve arch offsets."
421 " Status = %r\n",
422 Status
423 ));
424 goto error_handler;
425 }
426
427 if (MemAffCount != 0) {
428 MemAffOffset = TableSize;
429 TableSize += (sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE) *
430 MemAffCount);
431 }
432
433 if (GenInitiatorAffCount != 0) {
434 GenInitiatorAffOffset = TableSize;
436 GenInitiatorAffCount);
437 }
438
439 // Allocate the Buffer for SRAT table
440 *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize);
441 if (*Table == NULL) {
442 Status = EFI_OUT_OF_RESOURCES;
443 DEBUG ((
444 DEBUG_ERROR,
445 "ERROR: SRAT: Failed to allocate memory for SRAT Table, Size = %d," \
446 " Status = %r\n",
447 TableSize,
448 Status
449 ));
450 goto error_handler;
451 }
452
454
455 DEBUG ((
456 DEBUG_INFO,
457 "SRAT: Srat = 0x%p TableSize = 0x%x\n",
458 Srat,
459 TableSize
460 ));
461
462 Status = AddAcpiHeader (
463 CfgMgrProtocol,
464 This,
465 &Srat->Header,
466 AcpiTableInfo,
467 TableSize
468 );
469 if (EFI_ERROR (Status)) {
470 DEBUG ((
471 DEBUG_ERROR,
472 "ERROR: SRAT: Failed to add ACPI header. Status = %r\n",
473 Status
474 ));
475 goto error_handler;
476 }
477
478 // Setup the Reserved fields
479 // Reserved1 must be set to 1 for backward compatibility
480 Srat->Reserved1 = 1;
481 Srat->Reserved2 = EFI_ACPI_RESERVED_QWORD;
482
483 Status = AddArchObjects (CfgMgrProtocol, Srat);
484 if (EFI_ERROR (Status)) {
485 DEBUG ((
486 DEBUG_ERROR,
487 "ERROR: SRAT: Failed to add arch objects header. Status = %r\n",
488 Status
489 ));
490 goto error_handler;
491 }
492
493 if (MemAffCount != 0) {
494 Status = AddMemoryAffinity (
495 CfgMgrProtocol,
496 Srat,
497 MemAffOffset,
498 MemAffInfo,
499 MemAffCount
500 );
501 if (EFI_ERROR (Status)) {
502 DEBUG ((
503 DEBUG_ERROR,
504 "ERROR: SRAT: Failed to add Memory Affinity structures. Status = %r\n",
505 Status
506 ));
507 goto error_handler;
508 }
509 }
510
511 if (GenInitiatorAffCount != 0) {
513 CfgMgrProtocol,
514 Srat,
515 GenInitiatorAffOffset,
516 GenInitiatorAffInfo,
517 GenInitiatorAffCount
518 );
519 if (EFI_ERROR (Status)) {
520 DEBUG ((
521 DEBUG_ERROR,
522 "ERROR: SRAT: Failed to add Generic Initiator Affinity structures."
523 " Status = %r\n",
524 Status
525 ));
526 goto error_handler;
527 }
528 }
529
530 return Status;
531
532error_handler:
533
534 if (*Table != NULL) {
535 FreePool (*Table);
536 *Table = NULL;
537 }
538
539 return Status;
540}
541
553STATIC
555EFIAPI
561 )
562{
563 ASSERT (
564 (This != NULL) &&
565 (AcpiTableInfo != NULL) &&
566 (CfgMgrProtocol != NULL) &&
567 (AcpiTableInfo->TableGeneratorId == This->GeneratorID) &&
568 (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature)
569 );
570
571 if ((Table == NULL) || (*Table == NULL)) {
572 DEBUG ((DEBUG_ERROR, "ERROR: SRAT: Invalid Table Pointer\n"));
573 ASSERT (0);
574 return EFI_INVALID_PARAMETER;
575 }
576
577 FreePool (*Table);
578 *Table = NULL;
579 return EFI_SUCCESS;
580}
581
584#define SRAT_GENERATOR_REVISION CREATE_REVISION (1, 0)
585
588STATIC
589CONST
591 // Generator ID
593 // Generator Description
594 L"ACPI.STD.SRAT.GENERATOR",
595 // ACPI Table Signature
597 // ACPI Table Revision supported by this Generator
599 // Minimum supported ACPI Table Revision
601 // Creator ID
603 // Creator Revision
605 // Build Table function
607 // Free Resource function
609 // Extended build function not needed
610 NULL,
611 // Extended build function not implemented by the generator.
612 // Hence extended free resource function is not required.
613 NULL
614};
615
627EFIAPI
629 IN EFI_HANDLE ImageHandle,
630 IN EFI_SYSTEM_TABLE *SystemTable
631 )
632{
633 EFI_STATUS Status;
634
636 DEBUG ((DEBUG_INFO, "SRAT: Register Generator. Status = %r\n", Status));
637 ASSERT_EFI_ERROR (Status);
638 return Status;
639}
640
651EFIAPI
653 IN EFI_HANDLE ImageHandle,
654 IN EFI_SYSTEM_TABLE *SystemTable
655 )
656{
657 EFI_STATUS Status;
658
660 DEBUG ((DEBUG_INFO, "SRAT: Deregister Generator. Status = %r\n", Status));
661 ASSERT_EFI_ERROR (Status);
662 return Status;
663}
#define EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION
Definition: Acpi63.h:648
#define EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE
Definition: Acpi63.h:2826
EFI_STATUS EFIAPI RegisterAcpiTableGenerator(IN CONST ACPI_TABLE_GENERATOR *CONST Generator)
EFI_STATUS EFIAPI DeregisterAcpiTableGenerator(IN CONST ACPI_TABLE_GENERATOR *CONST Generator)
#define CREATE_STD_ACPI_TABLE_GEN_ID(TableId)
#define TABLE_GENERATOR_CREATOR_ID
@ EStdAcpiTableIdSrat
SRAT Generator.
@ EArchCommonObjGenericInitiatorAffinityInfo
14 - Generic Initiator Affinity
@ EArchCommonObjDeviceHandleAcpi
12 - Device Handle Acpi
@ EArchCommonObjDeviceHandlePci
13 - Device Handle Pci
@ EArchCommonObjMemoryAffinityInfo
11 - Memory Affinity Info
EFI_STATUS EFIAPI AddArchObjects(IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat)
EFI_STATUS EFIAPI ArchReserveOffsets(IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN OUT UINT32 *ArchOffset)
#define GET_OBJECT_LIST(CmObjectNameSpace, CmObjectId, Type)
@ EObjNameSpaceArchCommon
Arch Common Objects Namespace.
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define SRAT_GENERATOR_REVISION
STATIC EFI_STATUS AddGenericInitiatorAffinity(IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, IN CONST UINT32 GenInitAffOff, IN CONST CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO *GenInitAffInfo, IN UINT32 GenInitAffCount)
STATIC EFI_STATUS EFIAPI BuildSratTable(IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table)
EFI_STATUS EFIAPI AcpiSratLibDestructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI AcpiSratLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC CONST ACPI_TABLE_GENERATOR SratGenerator
STATIC EFI_STATUS EFIAPI FreeSratTableResources(IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table)
STATIC EFI_STATUS AddMemoryAffinity(IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat, IN CONST UINT32 MemAffOffset, IN CONST CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo, IN UINT32 MemAffCount)
STATIC UINT16 GetBdf(IN CONST CM_ARCH_COMMON_DEVICE_HANDLE_PCI *DeviceHandlePci)
Definition: SratGenerator.c:93
#define CM_NULL_TOKEN
EFI_STATUS EFIAPI AddAcpiHeader(IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CONST ACPI_TABLE_GENERATOR *CONST Generator, IN OUT EFI_ACPI_DESCRIPTION_HEADER *CONST AcpiHeader, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST UINT32 Length)
Definition: TableHelper.c:114
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
UINT16 SegmentNumber
PCI Segment Number.