2 This is the driver that publishes the SMM Access Ppi
3 instance for the Quark SOC.
5 Copyright (c) 2013-2015 Intel Corporation.
7 SPDX-License-Identifier: BSD-2-Clause-Patent
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>
22 #define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
25 SMM_ACCESS_PRIVATE_DATA, \
27 SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
30 #define MAX_CPU_SOCKET 1
31 #define MAX_SMRAM_RANGES 4
36 PEI_SMM_ACCESS_PPI SmmAccess
;
38 EFI_SMRAM_DESCRIPTOR SmramDesc
[MAX_SMRAM_RANGES
];
41 UINT8 SocketPopulated
[MAX_CPU_SOCKET
];
42 UINT8 SocketBusNum
[MAX_CPU_SOCKET
];
43 } SMM_ACCESS_PRIVATE_DATA
;
45 #define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('i', 's', 'm', 'a')
51 IN EFI_PEI_SERVICES
**PeiServices
,
52 IN PEI_SMM_ACCESS_PPI
*This
,
53 IN UINTN DescriptorIndex
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
66 PeiServices - General purpose services available to every PEIM.
67 This - Pointer to the SMM Access Interface.
68 DescriptorIndex - Region of SMRAM to Open.
72 EFI_SUCCESS - The region was successfully opened.
73 EFI_DEVICE_ERROR - The region could not be opened because locked by
75 EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
79 SMM_ACCESS_PRIVATE_DATA
*SmmAccess
;
81 SmmAccess
= SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This
);
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
;
92 if (!QNCOpenSmramRegion ()) {
93 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
|= EFI_SMRAM_LOCKED
;
94 return EFI_DEVICE_ERROR
;
97 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
&= ~(EFI_SMRAM_CLOSED
| EFI_ALLOCATED
);
98 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
|= EFI_SMRAM_OPEN
;
99 SmmAccess
->SmmAccess
.OpenState
= TRUE
;
107 IN EFI_PEI_SERVICES
**PeiServices
,
108 IN PEI_SMM_ACCESS_PPI
*This
,
109 IN UINTN DescriptorIndex
115 This routine accepts a request to "close" a region of SMRAM. This is valid for
116 compatible SMRAM region.
120 PeiServices - General purpose services available to every PEIM.
121 This - Pointer to the SMM Access Interface.
122 DescriptorIndex - Region of SMRAM to Close.
126 EFI_SUCCESS - The region was successfully closed.
127 EFI_DEVICE_ERROR - The region could not be closed because locked by
129 EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
133 SMM_ACCESS_PRIVATE_DATA
*SmmAccess
;
138 SmmAccess
= SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This
);
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
;
146 if (SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
& EFI_SMRAM_CLOSED
) {
147 return EFI_DEVICE_ERROR
;
153 if (!QNCCloseSmramRegion ()) {
154 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
|= EFI_SMRAM_LOCKED
;
155 return EFI_DEVICE_ERROR
;
158 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
&= ~EFI_SMRAM_OPEN
;
159 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
|= (EFI_SMRAM_CLOSED
| EFI_ALLOCATED
);
162 // Find out if any regions are still open
165 for (Index
= 0; Index
< SmmAccess
->NumberRegions
; Index
++) {
166 if ((SmmAccess
->SmramDesc
[Index
].RegionState
& EFI_SMRAM_OPEN
) == EFI_SMRAM_OPEN
) {
171 SmmAccess
->SmmAccess
.OpenState
= OpenState
;
179 IN EFI_PEI_SERVICES
**PeiServices
,
180 IN PEI_SMM_ACCESS_PPI
*This
,
181 IN UINTN DescriptorIndex
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
194 PeiServices - General purpose services available to every PEIM.
195 This - Pointer to the SMM Access Interface.
196 DescriptorIndex - Region of SMRAM to Lock.
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.
207 SMM_ACCESS_PRIVATE_DATA
*SmmAccess
;
209 SmmAccess
= SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This
);
211 if (DescriptorIndex
>= SmmAccess
->NumberRegions
) {
212 return EFI_INVALID_PARAMETER
;
213 } else if (SmmAccess
->SmmAccess
.OpenState
) {
214 return EFI_DEVICE_ERROR
;
217 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
|= EFI_SMRAM_LOCKED
;
218 SmmAccess
->SmmAccess
.LockState
= TRUE
;
223 QNCLockSmramRegion ();
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
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.
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
255 EFI_BUFFER_TOO_SMALL - The user did not provide a sufficient buffer.
256 EFI_SUCCESS - The user provided a sufficiently-sized buffer.
261 SMM_ACCESS_PRIVATE_DATA
*SmmAccess
;
264 SmmAccess
= SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This
);
265 BufferSize
= SmmAccess
->NumberRegions
* sizeof (EFI_SMRAM_DESCRIPTOR
);
267 if (*SmramMapSize
< BufferSize
) {
268 Status
= EFI_BUFFER_TOO_SMALL
;
270 CopyMem (SmramMap
, SmmAccess
->SmramDesc
, *SmramMapSize
);
271 Status
= EFI_SUCCESS
;
274 *SmramMapSize
= BufferSize
;
282 SmmAccessPeiEntryPoint (
283 IN EFI_PEI_FILE_HANDLE FileHandle
,
284 IN CONST EFI_PEI_SERVICES
**PeiServices
290 This is the constructor for the SMM Access Ppi
294 FfsHeader - FfsHeader.
295 PeiServices - General purpose services available to every PEIM.
299 EFI_SUCCESS - Protocol successfully started and installed.
300 EFI_UNSUPPORTED - Protocol can't be started.
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
;
312 // Initialize private data
314 SmmAccessPrivate
= AllocatePool (sizeof(*SmmAccessPrivate
));
315 ASSERT(SmmAccessPrivate
);
317 PpiList
= AllocatePool (sizeof(*PpiList
));
321 // Build SMM related information
323 SmmAccessPrivate
->Signature
= SMM_ACCESS_PRIVATE_DATA_SIGNATURE
;
328 GuidHob
= GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid
);
329 DescriptorBlock
= GET_GUID_HOB_DATA (GuidHob
);
330 ASSERT (DescriptorBlock
);
332 // Get CPU Max bus number
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
;
341 // Use the hob to publish SMRAM capabilities
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
;
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
;
359 PpiList
->Flags
= (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
);
360 PpiList
->Guid
= &gPeiSmmAccessPpiGuid
;
361 PpiList
->Ppi
= &SmmAccessPrivate
->SmmAccess
;
363 Status
= (**PeiServices
).InstallPpi (PeiServices
, PpiList
);
364 ASSERT_EFI_ERROR(Status
);
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
)
372 SmmAccessPrivate
->TsegSize
= (UINT8
)(SmmAccessPrivate
->SmramDesc
[SmmAccessPrivate
->NumberRegions
-1].PhysicalSize
);