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