1 /** @file
2
3 Copyright (c) 2014 - 2016, AMD Inc. All rights reserved.<BR>
4
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <PiPei.h>
16 #include <Library/DebugLib.h>
17 #include <Library/PcdLib.h>
18 #include <Library/PeimEntryPoint.h>
19 #include <Library/PeiServicesLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/HobLib.h>
22 #include <Library/ArmLib.h>
23 #include <Guid/ArmMpCoreInfo.h>
24
25 #include <Ppi/IscpPpi.h>
26 #include <Iscp.h>
27
28 /*----------------------------------------------------------------------------------------
29 * G L O B A L S
30 *----------------------------------------------------------------------------------------
31 */
32 //
33 // CoreInfo table
34 //
35 STATIC ARM_CORE_INFO mAmdMpCoreInfoTable[] = {
36 {
37 // Cluster 0, Core 0
38 0x0, 0x0,
39 },
40 {
41 // Cluster 0, Core 1
42 0x0, 0x1,
43 },
44 {
45 // Cluster 1, Core 0
46 0x1, 0x0,
47 },
48 {
49 // Cluster 1, Core 1
50 0x1, 0x1,
51 },
52 {
53 // Cluster 2, Core 0
54 0x2, 0x0,
55 },
56 {
57 // Cluster 2, Core 1
58 0x2, 0x1,
59 },
60 {
61 // Cluster 3, Core 0
62 0x3, 0x0,
63 },
64 {
65 // Cluster 3, Core 1
66 0x3, 0x1,
67 }
68 };
69
70 //
71 // Core count
72 //
73 STATIC UINTN mAmdCoreCount = sizeof (mAmdMpCoreInfoTable) / sizeof (ARM_CORE_INFO);
74
75
76 /*----------------------------------------------------------------------------------------
77 * P P I L I S T
78 *----------------------------------------------------------------------------------------
79 */
80 STATIC EFI_PEI_ISCP_PPI *PeiIscpPpi;
81
82
83 /*----------------------------------------------------------------------------------------
84 * P P I D E S C R I P T O R
85 *----------------------------------------------------------------------------------------
86 */
87 STATIC EFI_PEI_PPI_DESCRIPTOR mPlatInitPpiDescriptor =
88 {
89 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
90 &gAmdStyxPlatInitPpiGuid,
91 NULL
92 };
93
94
95 /**
96 *---------------------------------------------------------------------------------------
97 * PlatInitPeiEntryPoint
98 *
99 * Description:
100 * Entry point of the PlatInit PEI module.
101 *
102 * Control flow:
103 * Query platform parameters via ISCP.
104 *
105 * Parameters:
106 * @param[in] FfsHeader EFI_PEI_FILE_HANDLE
107 * @param[in] **PeiServices Pointer to the PEI Services Table.
108 *
109 * @return EFI_STATUS
110 *
111 *---------------------------------------------------------------------------------------
112 */
113 EFI_STATUS
114 EFIAPI
PlatInitPeiEntryPoint(IN EFI_PEI_FILE_HANDLE FfsHeader,IN CONST EFI_PEI_SERVICES ** PeiServices)115 PlatInitPeiEntryPoint (
116 IN EFI_PEI_FILE_HANDLE FfsHeader,
117 IN CONST EFI_PEI_SERVICES **PeiServices
118 )
119 {
120 EFI_STATUS Status = EFI_SUCCESS;
121 AMD_MEMORY_RANGE_DESCRIPTOR IscpMemDescriptor = {0};
122 ISCP_FUSE_INFO IscpFuseInfo = {0};
123 ISCP_CPU_RESET_INFO CpuResetInfo = {0};
124 #if DO_XGBE == 1
125 ISCP_MAC_INFO MacAddrInfo = {0};
126 UINT64 MacAddr0, MacAddr1;
127 #endif
128 UINTN CpuCoreCount, CpuMap, CpuMapSize;
129 UINTN Index, CoreNum;
130 UINT32 *CpuIdReg = (UINT32 *)FixedPcdGet32 (PcdCpuIdRegister);
131
132 DEBUG ((EFI_D_ERROR, "PlatInit PEIM Loaded\n"));
133
134 // CPUID
135 PcdSet32 (PcdSocCpuId, *CpuIdReg);
136 DEBUG ((EFI_D_ERROR, "SocCpuId = 0x%X\n", PcdGet32 (PcdSocCpuId)));
137
138 // Update core count based on PCD option
139 if (mAmdCoreCount > PcdGet32 (PcdSocCoreCount)) {
140 mAmdCoreCount = PcdGet32 (PcdSocCoreCount);
141 }
142
143 if (FixedPcdGetBool (PcdIscpSupport)) {
144 Status = PeiServicesLocatePpi (&gPeiIscpPpiGuid, 0, NULL, (VOID**)&PeiIscpPpi);
145 ASSERT_EFI_ERROR (Status);
146
147 // Get fuse information from ISCP
148 Status = PeiIscpPpi->ExecuteFuseTransaction (PeiServices, &IscpFuseInfo);
149 ASSERT_EFI_ERROR (Status);
150
151 CpuMap = IscpFuseInfo.SocConfiguration.CpuMap;
152 CpuCoreCount = IscpFuseInfo.SocConfiguration.CpuCoreCount;
153 CpuMapSize = sizeof (IscpFuseInfo.SocConfiguration.CpuMap) * 8;
154
155 ASSERT (CpuMap != 0);
156 ASSERT (CpuCoreCount != 0);
157 ASSERT (CpuCoreCount <= CpuMapSize);
158
159 // Update core count based on fusing
160 if (mAmdCoreCount > CpuCoreCount) {
161 mAmdCoreCount = CpuCoreCount;
162 }
163 }
164
165 //
166 // Update per-core information from ISCP
167 //
168 if (!FixedPcdGetBool (PcdIscpSupport)) {
169 DEBUG ((EFI_D_ERROR, "Warning: Could not get CPU info via ISCP, using default values.\n"));
170 } else {
171 //
172 // Walk CPU map to enumerate active cores
173 //
174 for (CoreNum = 0, Index = 0; CoreNum < CpuMapSize && Index < mAmdCoreCount; ++CoreNum) {
175 if (CpuMap & 1) {
176 CpuResetInfo.CoreNum = CoreNum;
177 Status = PeiIscpPpi->ExecuteCpuRetrieveIdTransaction (
178 PeiServices, &CpuResetInfo );
179 ASSERT_EFI_ERROR (Status);
180 ASSERT (CpuResetInfo.CoreStatus.Status != CPU_CORE_DISABLED);
181 ASSERT (CpuResetInfo.CoreStatus.Status != CPU_CORE_UNDEFINED);
182
183 mAmdMpCoreInfoTable[Index].ClusterId = CpuResetInfo.CoreStatus.ClusterId;
184 mAmdMpCoreInfoTable[Index].CoreId = CpuResetInfo.CoreStatus.CoreId;
185
186 DEBUG ((EFI_D_ERROR, "Core[%d]: ClusterId = %d CoreId = %d\n",
187 Index, mAmdMpCoreInfoTable[Index].ClusterId,
188 mAmdMpCoreInfoTable[Index].CoreId));
189
190 // Next core in Table
191 ++Index;
192 }
193 // Next core in Map
194 CpuMap >>= 1;
195 }
196
197 // Update core count based on CPU map
198 if (mAmdCoreCount > Index) {
199 mAmdCoreCount = Index;
200 }
201 }
202
203 // Update SocCoreCount on Dynamic PCD
204 if (PcdGet32 (PcdSocCoreCount) != mAmdCoreCount) {
205 PcdSet32 (PcdSocCoreCount, mAmdCoreCount);
206 }
207
208 DEBUG ((EFI_D_ERROR, "SocCoreCount = %d\n", PcdGet32 (PcdSocCoreCount)));
209
210 // Build AmdMpCoreInfo HOB
211 BuildGuidDataHob (&gAmdStyxMpCoreInfoGuid, mAmdMpCoreInfoTable, sizeof (ARM_CORE_INFO) * mAmdCoreCount);
212
213 // Get SystemMemorySize from ISCP
214 IscpMemDescriptor.Size0 = 0;
215 if (FixedPcdGetBool (PcdIscpSupport)) {
216 Status = PeiIscpPpi->ExecuteMemoryTransaction (PeiServices, &IscpMemDescriptor);
217 ASSERT_EFI_ERROR (Status);
218
219 // Update SystemMemorySize on Dynamic PCD
220 if (IscpMemDescriptor.Size0) {
221 PcdSet64 (PcdSystemMemorySize, IscpMemDescriptor.Size0);
222 }
223 }
224 if (IscpMemDescriptor.Size0 == 0) {
225 DEBUG ((EFI_D_ERROR, "Warning: Could not get SystemMemorySize via ISCP, using default value.\n"));
226 }
227
228 DEBUG ((EFI_D_ERROR, "SystemMemorySize = %ld\n", PcdGet64 (PcdSystemMemorySize)));
229
230 #if DO_XGBE == 1
231 // Get MAC Address from ISCP
232 if (FixedPcdGetBool (PcdIscpSupport)) {
233 Status = PeiIscpPpi->ExecuteGetMacAddressTransaction (
234 PeiServices, &MacAddrInfo );
235 ASSERT_EFI_ERROR (Status);
236
237 MacAddr0 = MacAddr1 = 0;
238 for (Index = 0; Index < 6; ++Index) {
239 MacAddr0 |= (UINT64)MacAddrInfo.MacAddress0[Index] << (Index * 8);
240 MacAddr1 |= (UINT64)MacAddrInfo.MacAddress1[Index] << (Index * 8);
241 }
242 PcdSet64 (PcdEthMacA, MacAddr0);
243 PcdSet64 (PcdEthMacB, MacAddr1);
244 }
245
246 DEBUG ((EFI_D_ERROR, "EthMacA = 0x%lX\n", PcdGet64 (PcdEthMacA)));
247 DEBUG ((EFI_D_ERROR, "EthMacB = 0x%lX\n", PcdGet64 (PcdEthMacB)));
248 #endif
249
250 // Let other PEI modules know we're done!
251 Status = (*PeiServices)->InstallPpi (PeiServices, &mPlatInitPpiDescriptor);
252 ASSERT_EFI_ERROR (Status);
253
254 return Status;
255 }
256
257