]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.c
QuarkSocPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / QuarkSocPkg / QuarkNorthCluster / Smm / Pei / SmmAccessPei / SmmAccessPei.c
CommitLineData
9b6bbcdb
MK
1/** @file\r
2This is the driver that publishes the SMM Access Ppi\r
3instance for the Quark SOC.\r
4\r
5Copyright (c) 2013-2015 Intel Corporation.\r
6\r
c9f231d0 7SPDX-License-Identifier: BSD-2-Clause-Patent\r
9b6bbcdb
MK
8\r
9**/\r
10#include <PiPei.h>\r
11#include <Ppi/SmmAccess.h>\r
12#include <Guid/SmramMemoryReserve.h>\r
13#include <Library/BaseMemoryLib.h>\r
14#include <Library/MemoryAllocationLib.h>\r
15#include <Library/DebugLib.h>\r
16#include <Library/HobLib.h>\r
17#include <Library/PciLib.h>\r
18#include <Library/PeiServicesLib.h>\r
19#include <Library/QNCSmmLib.h>\r
20#include <QNCAccess.h>\r
21\r
22#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \\r
23 CR ( \\r
24 a, \\r
25 SMM_ACCESS_PRIVATE_DATA, \\r
26 SmmAccess, \\r
27 SMM_ACCESS_PRIVATE_DATA_SIGNATURE \\r
28 )\r
29\r
30#define MAX_CPU_SOCKET 1\r
31#define MAX_SMRAM_RANGES 4\r
32\r
33typedef struct {\r
34 UINTN Signature;\r
35 EFI_HANDLE Handle;\r
36 PEI_SMM_ACCESS_PPI SmmAccess;\r
37 UINTN NumberRegions;\r
38 EFI_SMRAM_DESCRIPTOR SmramDesc[MAX_SMRAM_RANGES];\r
39 UINT8 TsegSize;\r
40 UINT8 MaxBusNumber;\r
41 UINT8 SocketPopulated[MAX_CPU_SOCKET];\r
42 UINT8 SocketBusNum[MAX_CPU_SOCKET];\r
43} SMM_ACCESS_PRIVATE_DATA;\r
44\r
45#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('i', 's', 'm', 'a')\r
46\r
47\r
48EFI_STATUS\r
49EFIAPI\r
50Open (\r
51 IN EFI_PEI_SERVICES **PeiServices,\r
52 IN PEI_SMM_ACCESS_PPI *This,\r
53 IN UINTN DescriptorIndex\r
54 )\r
55/*++\r
56\r
57Routine Description:\r
58\r
59 This routine accepts a request to "open" a region of SMRAM. The\r
60 region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.\r
61 The use of "open" means that the memory is visible from all PEIM\r
62 and SMM agents.\r
63\r
64Arguments:\r
65\r
66 PeiServices - General purpose services available to every PEIM.\r
67 This - Pointer to the SMM Access Interface.\r
68 DescriptorIndex - Region of SMRAM to Open.\r
69\r
70Returns:\r
71\r
72 EFI_SUCCESS - The region was successfully opened.\r
73 EFI_DEVICE_ERROR - The region could not be opened because locked by\r
74 chipset.\r
75 EFI_INVALID_PARAMETER - The descriptor index was out of bounds.\r
76\r
77--*/\r
78{\r
79 SMM_ACCESS_PRIVATE_DATA *SmmAccess;\r
80\r
81 SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);\r
82\r
83 if (DescriptorIndex >= SmmAccess->NumberRegions) {\r
84 return EFI_INVALID_PARAMETER;\r
85 } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {\r
86 return EFI_DEVICE_ERROR;\r
87 }\r
88\r
89 //\r
90 // Open TSEG\r
91 //\r
92 if (!QNCOpenSmramRegion ()) {\r
93 SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;\r
94 return EFI_DEVICE_ERROR;\r
95 }\r
96\r
97 SmmAccess->SmramDesc[DescriptorIndex].RegionState &= ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);\r
98 SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_OPEN;\r
99 SmmAccess->SmmAccess.OpenState = TRUE;\r
100\r
101 return EFI_SUCCESS;\r
102}\r
103\r
104EFI_STATUS\r
105EFIAPI\r
106Close (\r
107 IN EFI_PEI_SERVICES **PeiServices,\r
108 IN PEI_SMM_ACCESS_PPI *This,\r
109 IN UINTN DescriptorIndex\r
110 )\r
111/*++\r
112\r
113Routine Description:\r
114\r
115 This routine accepts a request to "close" a region of SMRAM. This is valid for\r
116 compatible SMRAM region.\r
117\r
118Arguments:\r
119\r
120 PeiServices - General purpose services available to every PEIM.\r
121 This - Pointer to the SMM Access Interface.\r
122 DescriptorIndex - Region of SMRAM to Close.\r
123\r
124Returns:\r
125\r
126 EFI_SUCCESS - The region was successfully closed.\r
127 EFI_DEVICE_ERROR - The region could not be closed because locked by\r
128 chipset.\r
129 EFI_INVALID_PARAMETER - The descriptor index was out of bounds.\r
130\r
131--*/\r
132{\r
133 SMM_ACCESS_PRIVATE_DATA *SmmAccess;\r
134 BOOLEAN OpenState;\r
135 UINTN Index;\r
136\r
137\r
138 SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);\r
139\r
140 if (DescriptorIndex >= SmmAccess->NumberRegions) {\r
141 return EFI_INVALID_PARAMETER;\r
142 } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {\r
143 return EFI_DEVICE_ERROR;\r
144 }\r
145\r
146 if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_CLOSED) {\r
147 return EFI_DEVICE_ERROR;\r
148 }\r
149\r
150 //\r
151 // Close TSEG\r
152 //\r
153 if (!QNCCloseSmramRegion ()) {\r
154 SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;\r
155 return EFI_DEVICE_ERROR;\r
156 }\r
157\r
158 SmmAccess->SmramDesc[DescriptorIndex].RegionState &= ~EFI_SMRAM_OPEN;\r
159 SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (EFI_SMRAM_CLOSED | EFI_ALLOCATED);\r
160\r
161 //\r
162 // Find out if any regions are still open\r
163 //\r
164 OpenState = FALSE;\r
165 for (Index = 0; Index < SmmAccess->NumberRegions; Index++) {\r
166 if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) == EFI_SMRAM_OPEN) {\r
167 OpenState = TRUE;\r
168 }\r
169 }\r
170\r
171 SmmAccess->SmmAccess.OpenState = OpenState;\r
172\r
173 return EFI_SUCCESS;\r
174}\r
175\r
176EFI_STATUS\r
177EFIAPI\r
178Lock (\r
179 IN EFI_PEI_SERVICES **PeiServices,\r
180 IN PEI_SMM_ACCESS_PPI *This,\r
181 IN UINTN DescriptorIndex\r
182 )\r
183/*++\r
184\r
185Routine Description:\r
186\r
187 This routine accepts a request to "lock" SMRAM. The\r
188 region could be legacy AB or TSEG near top of physical memory.\r
189 The use of "lock" means that the memory can no longer be opened\r
190 to PEIM.\r
191\r
192Arguments:\r
193\r
194 PeiServices - General purpose services available to every PEIM.\r
195 This - Pointer to the SMM Access Interface.\r
196 DescriptorIndex - Region of SMRAM to Lock.\r
197\r
198Returns:\r
199\r
200 EFI_SUCCESS - The region was successfully locked.\r
201 EFI_DEVICE_ERROR - The region could not be locked because at least\r
202 one range is still open.\r
203 EFI_INVALID_PARAMETER - The descriptor index was out of bounds.\r
204\r
205--*/\r
206{\r
207 SMM_ACCESS_PRIVATE_DATA *SmmAccess;\r
208\r
209 SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);\r
210\r
211 if (DescriptorIndex >= SmmAccess->NumberRegions) {\r
212 return EFI_INVALID_PARAMETER;\r
213 } else if (SmmAccess->SmmAccess.OpenState) {\r
214 return EFI_DEVICE_ERROR;\r
215 }\r
216\r
217 SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;\r
218 SmmAccess->SmmAccess.LockState = TRUE;\r
219\r
220 //\r
221 // Lock TSEG\r
222 //\r
223 QNCLockSmramRegion ();\r
224\r
225 return EFI_SUCCESS;\r
226}\r
227\r
228EFI_STATUS\r
229EFIAPI\r
230GetCapabilities (\r
231 IN EFI_PEI_SERVICES **PeiServices,\r
232 IN PEI_SMM_ACCESS_PPI *This,\r
233 IN OUT UINTN *SmramMapSize,\r
234 IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap\r
235 )\r
236/*++\r
237\r
238Routine Description:\r
239\r
240 This routine services a user request to discover the SMRAM\r
241 capabilities of this platform. This will report the possible\r
242 ranges that are possible for SMRAM access, based upon the\r
243 memory controller capabilities.\r
244\r
245Arguments:\r
246\r
247 PeiServices - General purpose services available to every PEIM.\r
248 This - Pointer to the SMRAM Access Interface.\r
249 SmramMapSize - Pointer to the variable containing size of the\r
250 buffer to contain the description information.\r
251 SmramMap - Buffer containing the data describing the Smram\r
252 region descriptors.\r
253Returns:\r
254\r
255 EFI_BUFFER_TOO_SMALL - The user did not provide a sufficient buffer.\r
256 EFI_SUCCESS - The user provided a sufficiently-sized buffer.\r
257\r
258--*/\r
259{\r
260 EFI_STATUS Status;\r
261 SMM_ACCESS_PRIVATE_DATA *SmmAccess;\r
262 UINTN BufferSize;\r
263\r
264 SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);\r
265 BufferSize = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR);\r
266\r
267 if (*SmramMapSize < BufferSize) {\r
268 Status = EFI_BUFFER_TOO_SMALL;\r
269 } else {\r
270 CopyMem (SmramMap, SmmAccess->SmramDesc, *SmramMapSize);\r
271 Status = EFI_SUCCESS;\r
272 }\r
273\r
274 *SmramMapSize = BufferSize;\r
275\r
276 return Status;\r
277}\r
278\r
279\r
280EFI_STATUS\r
281EFIAPI\r
282SmmAccessPeiEntryPoint (\r
283 IN EFI_PEI_FILE_HANDLE FileHandle,\r
284 IN CONST EFI_PEI_SERVICES **PeiServices\r
285 )\r
286/*++\r
287\r
288Routine Description:\r
289\r
290 This is the constructor for the SMM Access Ppi\r
291\r
292Arguments:\r
293\r
294 FfsHeader - FfsHeader.\r
295 PeiServices - General purpose services available to every PEIM.\r
296\r
297Returns:\r
298\r
299 EFI_SUCCESS - Protocol successfully started and installed.\r
300 EFI_UNSUPPORTED - Protocol can't be started.\r
301--*/\r
302{\r
303\r
304 EFI_STATUS Status;\r
305 UINTN Index;\r
306 EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock;\r
307 SMM_ACCESS_PRIVATE_DATA *SmmAccessPrivate;\r
308 EFI_PEI_PPI_DESCRIPTOR *PpiList;\r
309 EFI_HOB_GUID_TYPE *GuidHob;\r
310\r
311 //\r
312 // Initialize private data\r
313 //\r
314 SmmAccessPrivate = AllocatePool (sizeof(*SmmAccessPrivate));\r
315 ASSERT(SmmAccessPrivate);\r
316\r
317 PpiList = AllocatePool (sizeof(*PpiList));\r
318 ASSERT (PpiList);\r
319\r
320 //\r
321 // Build SMM related information\r
322 //\r
323 SmmAccessPrivate->Signature = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;\r
324\r
325 //\r
326 // Get Hob list\r
327 //\r
328 GuidHob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);\r
329 DescriptorBlock = GET_GUID_HOB_DATA (GuidHob);\r
330 ASSERT (DescriptorBlock);\r
331\r
332 // Get CPU Max bus number\r
333\r
334 SmmAccessPrivate->MaxBusNumber = PCI_BUS_NUMBER_QNC;\r
335 for (Index = 0; Index < MAX_CPU_SOCKET; Index++) {\r
336 SmmAccessPrivate->SocketPopulated[Index] = TRUE;\r
337 SmmAccessPrivate->SocketBusNum[Index] = PCI_BUS_NUMBER_QNC;\r
338 }\r
339\r
340 //\r
341 // Use the hob to publish SMRAM capabilities\r
342 //\r
343 ASSERT (DescriptorBlock->NumberOfSmmReservedRegions <= MAX_SMRAM_RANGES);\r
344 for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {\r
345 SmmAccessPrivate->SmramDesc[Index].PhysicalStart = DescriptorBlock->Descriptor[Index].PhysicalStart;\r
346 SmmAccessPrivate->SmramDesc[Index].CpuStart = DescriptorBlock->Descriptor[Index].CpuStart;\r
347 SmmAccessPrivate->SmramDesc[Index].PhysicalSize = DescriptorBlock->Descriptor[Index].PhysicalSize;\r
348 SmmAccessPrivate->SmramDesc[Index].RegionState = DescriptorBlock->Descriptor[Index].RegionState;\r
349 }\r
350\r
351 SmmAccessPrivate->NumberRegions = Index;\r
352 SmmAccessPrivate->SmmAccess.Open = Open;\r
353 SmmAccessPrivate->SmmAccess.Close = Close;\r
354 SmmAccessPrivate->SmmAccess.Lock = Lock;\r
355 SmmAccessPrivate->SmmAccess.GetCapabilities = GetCapabilities;\r
356 SmmAccessPrivate->SmmAccess.LockState = FALSE;\r
357 SmmAccessPrivate->SmmAccess.OpenState = FALSE;\r
358\r
359 PpiList->Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
360 PpiList->Guid = &gPeiSmmAccessPpiGuid;\r
361 PpiList->Ppi = &SmmAccessPrivate->SmmAccess;\r
362\r
363 Status = (**PeiServices).InstallPpi (PeiServices, PpiList);\r
364 ASSERT_EFI_ERROR(Status);\r
365\r
366 DEBUG (\r
367 (EFI_D_INFO, "SMM Base:Size %08X:%08X\n",\r
368 (UINTN)(SmmAccessPrivate->SmramDesc[SmmAccessPrivate->NumberRegions-1].PhysicalStart),\r
369 (UINTN)(SmmAccessPrivate->SmramDesc[SmmAccessPrivate->NumberRegions-1].PhysicalSize)\r
370 ));\r
371\r
372 SmmAccessPrivate->TsegSize = (UINT8)(SmmAccessPrivate->SmramDesc[SmmAccessPrivate->NumberRegions-1].PhysicalSize);\r
373\r
374 return EFI_SUCCESS;\r
375}\r
376\r