• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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