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 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Ppi/SmmAccess.h>
18 #include <Guid/SmramMemoryReserve.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/HobLib.h>
23 #include <Library/PciLib.h>
24 #include <Library/PeiServicesLib.h>
25 #include <Library/QNCSmmLib.h>
26 #include <QNCAccess.h>
28 #define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
31 SMM_ACCESS_PRIVATE_DATA, \
33 SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
36 #define MAX_CPU_SOCKET 1
37 #define MAX_SMRAM_RANGES 4
42 PEI_SMM_ACCESS_PPI SmmAccess
;
44 EFI_SMRAM_DESCRIPTOR SmramDesc
[MAX_SMRAM_RANGES
];
47 UINT8 SocketPopulated
[MAX_CPU_SOCKET
];
48 UINT8 SocketBusNum
[MAX_CPU_SOCKET
];
49 } SMM_ACCESS_PRIVATE_DATA
;
51 #define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('i', 's', 'm', 'a')
57 IN EFI_PEI_SERVICES
**PeiServices
,
58 IN PEI_SMM_ACCESS_PPI
*This
,
59 IN UINTN DescriptorIndex
65 This routine accepts a request to "open" a region of SMRAM. The
66 region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
67 The use of "open" means that the memory is visible from all PEIM
72 PeiServices - General purpose services available to every PEIM.
73 This - Pointer to the SMM Access Interface.
74 DescriptorIndex - Region of SMRAM to Open.
78 EFI_SUCCESS - The region was successfully opened.
79 EFI_DEVICE_ERROR - The region could not be opened because locked by
81 EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
85 SMM_ACCESS_PRIVATE_DATA
*SmmAccess
;
87 SmmAccess
= SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This
);
89 if (DescriptorIndex
>= SmmAccess
->NumberRegions
) {
90 return EFI_INVALID_PARAMETER
;
91 } else if (SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
& EFI_SMRAM_LOCKED
) {
92 return EFI_DEVICE_ERROR
;
98 if (!QNCOpenSmramRegion ()) {
99 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
|= EFI_SMRAM_LOCKED
;
100 return EFI_DEVICE_ERROR
;
103 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
&= ~(EFI_SMRAM_CLOSED
| EFI_ALLOCATED
);
104 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
|= EFI_SMRAM_OPEN
;
105 SmmAccess
->SmmAccess
.OpenState
= TRUE
;
113 IN EFI_PEI_SERVICES
**PeiServices
,
114 IN PEI_SMM_ACCESS_PPI
*This
,
115 IN UINTN DescriptorIndex
121 This routine accepts a request to "close" a region of SMRAM. This is valid for
122 compatible SMRAM region.
126 PeiServices - General purpose services available to every PEIM.
127 This - Pointer to the SMM Access Interface.
128 DescriptorIndex - Region of SMRAM to Close.
132 EFI_SUCCESS - The region was successfully closed.
133 EFI_DEVICE_ERROR - The region could not be closed because locked by
135 EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
139 SMM_ACCESS_PRIVATE_DATA
*SmmAccess
;
144 SmmAccess
= SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This
);
146 if (DescriptorIndex
>= SmmAccess
->NumberRegions
) {
147 return EFI_INVALID_PARAMETER
;
148 } else if (SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
& EFI_SMRAM_LOCKED
) {
149 return EFI_DEVICE_ERROR
;
152 if (SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
& EFI_SMRAM_CLOSED
) {
153 return EFI_DEVICE_ERROR
;
159 if (!QNCCloseSmramRegion ()) {
160 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
|= EFI_SMRAM_LOCKED
;
161 return EFI_DEVICE_ERROR
;
164 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
&= ~EFI_SMRAM_OPEN
;
165 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
|= (EFI_SMRAM_CLOSED
| EFI_ALLOCATED
);
168 // Find out if any regions are still open
171 for (Index
= 0; Index
< SmmAccess
->NumberRegions
; Index
++) {
172 if ((SmmAccess
->SmramDesc
[Index
].RegionState
& EFI_SMRAM_OPEN
) == EFI_SMRAM_OPEN
) {
177 SmmAccess
->SmmAccess
.OpenState
= OpenState
;
185 IN EFI_PEI_SERVICES
**PeiServices
,
186 IN PEI_SMM_ACCESS_PPI
*This
,
187 IN UINTN DescriptorIndex
193 This routine accepts a request to "lock" SMRAM. The
194 region could be legacy AB or TSEG near top of physical memory.
195 The use of "lock" means that the memory can no longer be opened
200 PeiServices - General purpose services available to every PEIM.
201 This - Pointer to the SMM Access Interface.
202 DescriptorIndex - Region of SMRAM to Lock.
206 EFI_SUCCESS - The region was successfully locked.
207 EFI_DEVICE_ERROR - The region could not be locked because at least
208 one range is still open.
209 EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
213 SMM_ACCESS_PRIVATE_DATA
*SmmAccess
;
215 SmmAccess
= SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This
);
217 if (DescriptorIndex
>= SmmAccess
->NumberRegions
) {
218 return EFI_INVALID_PARAMETER
;
219 } else if (SmmAccess
->SmmAccess
.OpenState
) {
220 return EFI_DEVICE_ERROR
;
223 SmmAccess
->SmramDesc
[DescriptorIndex
].RegionState
|= EFI_SMRAM_LOCKED
;
224 SmmAccess
->SmmAccess
.LockState
= TRUE
;
229 QNCLockSmramRegion ();
237 IN EFI_PEI_SERVICES
**PeiServices
,
238 IN PEI_SMM_ACCESS_PPI
*This
,
239 IN OUT UINTN
*SmramMapSize
,
240 IN OUT EFI_SMRAM_DESCRIPTOR
*SmramMap
246 This routine services a user request to discover the SMRAM
247 capabilities of this platform. This will report the possible
248 ranges that are possible for SMRAM access, based upon the
249 memory controller capabilities.
253 PeiServices - General purpose services available to every PEIM.
254 This - Pointer to the SMRAM Access Interface.
255 SmramMapSize - Pointer to the variable containing size of the
256 buffer to contain the description information.
257 SmramMap - Buffer containing the data describing the Smram
261 EFI_BUFFER_TOO_SMALL - The user did not provide a sufficient buffer.
262 EFI_SUCCESS - The user provided a sufficiently-sized buffer.
267 SMM_ACCESS_PRIVATE_DATA
*SmmAccess
;
270 SmmAccess
= SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This
);
271 BufferSize
= SmmAccess
->NumberRegions
* sizeof (EFI_SMRAM_DESCRIPTOR
);
273 if (*SmramMapSize
< BufferSize
) {
274 Status
= EFI_BUFFER_TOO_SMALL
;
276 CopyMem (SmramMap
, SmmAccess
->SmramDesc
, *SmramMapSize
);
277 Status
= EFI_SUCCESS
;
280 *SmramMapSize
= BufferSize
;
288 SmmAccessPeiEntryPoint (
289 IN EFI_PEI_FILE_HANDLE FileHandle
,
290 IN CONST EFI_PEI_SERVICES
**PeiServices
296 This is the constructor for the SMM Access Ppi
300 FfsHeader - FfsHeader.
301 PeiServices - General purpose services available to every PEIM.
305 EFI_SUCCESS - Protocol successfully started and installed.
306 EFI_UNSUPPORTED - Protocol can't be started.
312 EFI_SMRAM_HOB_DESCRIPTOR_BLOCK
*DescriptorBlock
;
313 SMM_ACCESS_PRIVATE_DATA
*SmmAccessPrivate
;
314 EFI_PEI_PPI_DESCRIPTOR
*PpiList
;
315 EFI_HOB_GUID_TYPE
*GuidHob
;
318 // Initialize private data
320 SmmAccessPrivate
= AllocatePool (sizeof(*SmmAccessPrivate
));
321 ASSERT(SmmAccessPrivate
);
323 PpiList
= AllocatePool (sizeof(*PpiList
));
327 // Build SMM related information
329 SmmAccessPrivate
->Signature
= SMM_ACCESS_PRIVATE_DATA_SIGNATURE
;
334 GuidHob
= GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid
);
335 DescriptorBlock
= GET_GUID_HOB_DATA (GuidHob
);
336 ASSERT (DescriptorBlock
);
338 // Get CPU Max bus number
340 SmmAccessPrivate
->MaxBusNumber
= PCI_BUS_NUMBER_QNC
;
341 for (Index
= 0; Index
< MAX_CPU_SOCKET
; Index
++) {
342 SmmAccessPrivate
->SocketPopulated
[Index
] = TRUE
;
343 SmmAccessPrivate
->SocketBusNum
[Index
] = PCI_BUS_NUMBER_QNC
;
347 // Use the hob to publish SMRAM capabilities
349 ASSERT (DescriptorBlock
->NumberOfSmmReservedRegions
<= MAX_SMRAM_RANGES
);
350 for (Index
= 0; Index
< DescriptorBlock
->NumberOfSmmReservedRegions
; Index
++) {
351 SmmAccessPrivate
->SmramDesc
[Index
].PhysicalStart
= DescriptorBlock
->Descriptor
[Index
].PhysicalStart
;
352 SmmAccessPrivate
->SmramDesc
[Index
].CpuStart
= DescriptorBlock
->Descriptor
[Index
].CpuStart
;
353 SmmAccessPrivate
->SmramDesc
[Index
].PhysicalSize
= DescriptorBlock
->Descriptor
[Index
].PhysicalSize
;
354 SmmAccessPrivate
->SmramDesc
[Index
].RegionState
= DescriptorBlock
->Descriptor
[Index
].RegionState
;
357 SmmAccessPrivate
->NumberRegions
= Index
;
358 SmmAccessPrivate
->SmmAccess
.Open
= Open
;
359 SmmAccessPrivate
->SmmAccess
.Close
= Close
;
360 SmmAccessPrivate
->SmmAccess
.Lock
= Lock
;
361 SmmAccessPrivate
->SmmAccess
.GetCapabilities
= GetCapabilities
;
362 SmmAccessPrivate
->SmmAccess
.LockState
= FALSE
;
363 SmmAccessPrivate
->SmmAccess
.OpenState
= FALSE
;
365 PpiList
->Flags
= (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
);
366 PpiList
->Guid
= &gPeiSmmAccessPpiGuid
;
367 PpiList
->Ppi
= &SmmAccessPrivate
->SmmAccess
;
369 Status
= (**PeiServices
).InstallPpi (PeiServices
, PpiList
);
370 ASSERT_EFI_ERROR(Status
);
373 (EFI_D_INFO
, "SMM Base:Size %08X:%08X\n",
374 (UINTN
)(SmmAccessPrivate
->SmramDesc
[SmmAccessPrivate
->NumberRegions
-1].PhysicalStart
),
375 (UINTN
)(SmmAccessPrivate
->SmramDesc
[SmmAccessPrivate
->NumberRegions
-1].PhysicalSize
)
378 SmmAccessPrivate
->TsegSize
= (UINT8
)(SmmAccessPrivate
->SmramDesc
[SmmAccessPrivate
->NumberRegions
-1].PhysicalSize
);