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