UpdateAcpiTable.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /** @file
  2. Copyright (c) 2016, Hisilicon Limited. All rights reserved.
  3. This program and the accompanying materials are licensed and made available
  4. under the terms and conditions of the BSD License which accompanies this
  5. distribution. The full text of the license may be found at
  6. http://opensource.org/licenses/bsd-license.php
  7. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
  8. WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  9. **/
  10. #include <PlatformArch.h>
  11. #include <IndustryStandard/Acpi.h>
  12. #include <Library/AcpiNextLib.h>
  13. #include <Library/BaseLib.h>
  14. #include <Library/BaseMemoryLib.h>
  15. #include <Library/DebugLib.h>
  16. #include <Library/HobLib.h>
  17. #include <Library/HwMemInitLib.h>
  18. #include <Library/OemMiscLib.h>
  19. #include <Library/UefiBootServicesTableLib.h>
  20. #include <Library/UefiLib.h>
  21. #define CORE_NUM_PER_SOCKET 32
  22. #define NODE_IN_SOCKET 2
  23. #define CORECOUNT(X) ((X) * CORE_NUM_PER_SOCKET)
  24. STATIC
  25. VOID
  26. RemoveUnusedMemoryNode (
  27. IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *Table,
  28. IN UINTN MemoryNodeNum
  29. )
  30. {
  31. UINTN CurrPtr, NewPtr;
  32. if (MemoryNodeNum >= EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT) {
  33. return;
  34. }
  35. CurrPtr = (UINTN) &(Table->Memory[EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT]);
  36. NewPtr = (UINTN) &(Table->Memory[MemoryNodeNum]);
  37. CopyMem ((VOID *)NewPtr, (VOID *)CurrPtr, (UINTN)Table + Table->Header.Header.Length - CurrPtr);
  38. Table->Header.Header.Length -= CurrPtr - NewPtr;
  39. return;
  40. }
  41. STATIC
  42. EFI_STATUS
  43. UpdateSrat (
  44. IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *Table
  45. )
  46. {
  47. UINT8 Skt = 0;
  48. UINTN Index = 0;
  49. VOID *HobList;
  50. GBL_DATA *Gbl_Data;
  51. UINTN Base;
  52. UINTN Size;
  53. UINT8 NodeId;
  54. UINT32 ScclInterleaveEn;
  55. UINTN MemoryNode = 0;
  56. DEBUG((DEBUG_INFO, "SRAT: Updating SRAT memory information.\n"));
  57. HobList = GetHobList();
  58. if (HobList == NULL) {
  59. return EFI_UNSUPPORTED;
  60. }
  61. Gbl_Data = (GBL_DATA*)GetNextGuidHob(&gHisiEfiMemoryMapGuid, HobList);
  62. if (Gbl_Data == NULL) {
  63. DEBUG((DEBUG_ERROR, "Get next Guid HOb fail.\n"));
  64. return EFI_NOT_FOUND;
  65. }
  66. Gbl_Data = GET_GUID_HOB_DATA(Gbl_Data);
  67. for(Skt = 0; Skt < MAX_SOCKET; Skt++) {
  68. for(Index = 0; Index < MAX_NUM_PER_TYPE; Index++) {
  69. NodeId = Gbl_Data->NumaInfo[Skt][Index].NodeId;
  70. Base = Gbl_Data->NumaInfo[Skt][Index].Base;
  71. Size = Gbl_Data->NumaInfo[Skt][Index].Length;
  72. DEBUG((DEBUG_INFO, "Skt %d Index %d: NodeId = %d, Base = 0x%lx, Size = 0x%lx\n", Skt, Index, NodeId, Base, Size));
  73. if (Size > 0) {
  74. Table->Memory[MemoryNode].ProximityDomain = NodeId;
  75. Table->Memory[MemoryNode].AddressBaseLow = Base;
  76. Table->Memory[MemoryNode].AddressBaseHigh = Base >> 32;
  77. Table->Memory[MemoryNode].LengthLow = Size;
  78. Table->Memory[MemoryNode].LengthHigh = Size >> 32;
  79. MemoryNode = MemoryNode + 1;
  80. }
  81. }
  82. ScclInterleaveEn = Gbl_Data->NumaInfo[Skt][0].ScclInterleaveEn;
  83. DEBUG((DEBUG_INFO, "ScclInterleaveEn = %d\n", ScclInterleaveEn));
  84. //update gicc structure
  85. if (ScclInterleaveEn != 0) {
  86. DEBUG((DEBUG_INFO, "SRAT: Updating SRAT Gicc information.\n"));
  87. for (Index = CORECOUNT (Skt); Index < CORECOUNT (Skt + 1); Index++) {
  88. Table->Gicc[Index].ProximityDomain = Skt * NODE_IN_SOCKET;
  89. }
  90. }
  91. }
  92. //remove invalid memory node
  93. RemoveUnusedMemoryNode (Table, MemoryNode);
  94. return EFI_SUCCESS;
  95. }
  96. STATIC
  97. EFI_STATUS
  98. UpdateSlit (
  99. IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table
  100. )
  101. {
  102. return EFI_SUCCESS;
  103. }
  104. EFI_STATUS
  105. UpdateAcpiTable (
  106. IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader
  107. )
  108. {
  109. EFI_STATUS Status = EFI_SUCCESS;
  110. switch (TableHeader->Signature) {
  111. case EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE:
  112. Status = UpdateSrat ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) TableHeader);
  113. break;
  114. case EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
  115. Status = UpdateSlit (TableHeader);
  116. break;
  117. }
  118. return Status;
  119. }