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
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
9 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10 **/
11 #include <PlatformArch.h>
12 #include <IndustryStandard/Acpi.h>
13 #include <Library/AcpiNextLib.h>
14 #include <Library/BaseLib.h>
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/HobLib.h>
18 #include <Library/HwMemInitLib.h>
19 #include <Library/OemMiscLib.h>
20 #include <Library/UefiBootServicesTableLib.h>
21 #include <Library/UefiLib.h>
22
23 #define CORE_NUM_PER_SOCKET 32
24 #define NODE_IN_SOCKET 2
25 #define CORECOUNT(X) ((X) * CORE_NUM_PER_SOCKET)
26
27 STATIC
28 VOID
RemoveUnusedMemoryNode(IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE * Table,IN UINTN MemoryNodeNum)29 RemoveUnusedMemoryNode (
30 IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *Table,
31 IN UINTN MemoryNodeNum
32 )
33 {
34 UINTN CurrPtr, NewPtr;
35
36 if (MemoryNodeNum >= EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT) {
37 return;
38 }
39
40 CurrPtr = (UINTN) &(Table->Memory[EFI_ACPI_MEMORY_AFFINITY_STRUCTURE_COUNT]);
41 NewPtr = (UINTN) &(Table->Memory[MemoryNodeNum]);
42
43 CopyMem ((VOID *)NewPtr, (VOID *)CurrPtr, (UINTN)Table + Table->Header.Header.Length - CurrPtr);
44
45 Table->Header.Header.Length -= CurrPtr - NewPtr;
46
47 return;
48 }
49
50 STATIC
51 EFI_STATUS
UpdateSrat(IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE * Table)52 UpdateSrat (
53 IN OUT EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *Table
54 )
55 {
56 UINT8 Skt = 0;
57 UINTN Index = 0;
58 VOID *HobList;
59 GBL_DATA *Gbl_Data;
60 UINTN Base;
61 UINTN Size;
62 UINT8 NodeId;
63 UINT32 ScclInterleaveEn;
64 UINTN MemoryNode = 0;
65
66 DEBUG((DEBUG_INFO, "SRAT: Updating SRAT memory information.\n"));
67
68 HobList = GetHobList();
69 if (HobList == NULL) {
70 return EFI_UNSUPPORTED;
71 }
72 Gbl_Data = (GBL_DATA*)GetNextGuidHob(&gHisiEfiMemoryMapGuid, HobList);
73 if (Gbl_Data == NULL) {
74 DEBUG((DEBUG_ERROR, "Get next Guid HOb fail.\n"));
75 return EFI_NOT_FOUND;
76 }
77 Gbl_Data = GET_GUID_HOB_DATA(Gbl_Data);
78 for(Skt = 0; Skt < MAX_SOCKET; Skt++) {
79 for(Index = 0; Index < MAX_NUM_PER_TYPE; Index++) {
80 NodeId = Gbl_Data->NumaInfo[Skt][Index].NodeId;
81 Base = Gbl_Data->NumaInfo[Skt][Index].Base;
82 Size = Gbl_Data->NumaInfo[Skt][Index].Length;
83 DEBUG((DEBUG_INFO, "Skt %d Index %d: NodeId = %d, Base = 0x%lx, Size = 0x%lx\n", Skt, Index, NodeId, Base, Size));
84 if (Size > 0) {
85 Table->Memory[MemoryNode].ProximityDomain = NodeId;
86 Table->Memory[MemoryNode].AddressBaseLow = Base;
87 Table->Memory[MemoryNode].AddressBaseHigh = Base >> 32;
88 Table->Memory[MemoryNode].LengthLow = Size;
89 Table->Memory[MemoryNode].LengthHigh = Size >> 32;
90 MemoryNode = MemoryNode + 1;
91 }
92 }
93 ScclInterleaveEn = Gbl_Data->NumaInfo[Skt][0].ScclInterleaveEn;
94 DEBUG((DEBUG_INFO, "ScclInterleaveEn = %d\n", ScclInterleaveEn));
95 //update gicc structure
96 if (ScclInterleaveEn != 0) {
97 DEBUG((DEBUG_INFO, "SRAT: Updating SRAT Gicc information.\n"));
98 for (Index = CORECOUNT (Skt); Index < CORECOUNT (Skt + 1); Index++) {
99 Table->Gicc[Index].ProximityDomain = Skt * NODE_IN_SOCKET;
100 }
101 }
102 }
103
104 //remove invalid memory node
105 RemoveUnusedMemoryNode (Table, MemoryNode);
106
107 return EFI_SUCCESS;
108 }
109
110 STATIC
111 EFI_STATUS
UpdateSlit(IN OUT EFI_ACPI_DESCRIPTION_HEADER * Table)112 UpdateSlit (
113 IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table
114 )
115 {
116 return EFI_SUCCESS;
117 }
118
119 EFI_STATUS
UpdateAcpiTable(IN OUT EFI_ACPI_DESCRIPTION_HEADER * TableHeader)120 UpdateAcpiTable (
121 IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader
122 )
123 {
124 EFI_STATUS Status = EFI_SUCCESS;
125
126 switch (TableHeader->Signature) {
127
128 case EFI_ACPI_6_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE:
129 Status = UpdateSrat ((EFI_ACPI_STATIC_RESOURCE_AFFINITY_TABLE *) TableHeader);
130 break;
131
132 case EFI_ACPI_6_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
133 Status = UpdateSlit (TableHeader);
134 break;
135 }
136 return Status;
137 }
138