]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / NvmExpressPei / NvmExpressPei.h
CommitLineData
b8b69433
HW
1/** @file\r
2 The NvmExpressPei driver is used to manage non-volatile memory subsystem\r
3 which follows NVM Express specification at PEI phase.\r
4\r
4104423a 5 Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>\r
b8b69433 6\r
9d510e61 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
b8b69433
HW
8\r
9**/\r
10\r
11#ifndef _NVM_EXPRESS_PEI_H_\r
12#define _NVM_EXPRESS_PEI_H_\r
13\r
14#include <PiPei.h>\r
15\r
16#include <IndustryStandard/Nvme.h>\r
9ca7ece8 17#include <IndustryStandard/Pci.h>\r
b8b69433
HW
18\r
19#include <Ppi/NvmExpressHostController.h>\r
20#include <Ppi/BlockIo.h>\r
21#include <Ppi/BlockIo2.h>\r
2e15b750 22#include <Ppi/StorageSecurityCommand.h>\r
ba3aa1c4 23#include <Ppi/NvmExpressPassThru.h>\r
b8b69433
HW
24#include <Ppi/IoMmu.h>\r
25#include <Ppi/EndOfPeiPhase.h>\r
9ca7ece8 26#include <Ppi/PciDevice.h>\r
b8b69433
HW
27\r
28#include <Library/DebugLib.h>\r
29#include <Library/PeiServicesLib.h>\r
30#include <Library/MemoryAllocationLib.h>\r
31#include <Library/BaseMemoryLib.h>\r
32#include <Library/IoLib.h>\r
b8b69433 33#include <Library/TimerLib.h>\r
9ca7ece8 34#include <Library/DevicePathLib.h>\r
b8b69433
HW
35\r
36//\r
37// Structure forward declarations\r
38//\r
39typedef struct _PEI_NVME_NAMESPACE_INFO PEI_NVME_NAMESPACE_INFO;\r
40typedef struct _PEI_NVME_CONTROLLER_PRIVATE_DATA PEI_NVME_CONTROLLER_PRIVATE_DATA;\r
41\r
9ca7ece8
CX
42/**\r
43 Macro that checks whether device is a NVMHCI Interface.\r
44\r
45 @param _p Specified device.\r
46\r
47 @retval TRUE Device is a NVMHCI Interface.\r
48 @retval FALSE Device is not a NVMHCI Interface.\r
49\r
50**/\r
51#define IS_PCI_NVMHCI(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SOLID_STATE, PCI_IF_MASS_STORAGE_SOLID_STATE_ENTERPRISE_NVMHCI)\r
52\r
b8b69433
HW
53#include "NvmExpressPeiHci.h"\r
54#include "NvmExpressPeiPassThru.h"\r
55#include "NvmExpressPeiBlockIo.h"\r
2e15b750 56#include "NvmExpressPeiStorageSecurity.h"\r
b8b69433
HW
57\r
58//\r
59// NVME PEI driver implementation related definitions\r
60//\r
1436aea4
MK
61#define NVME_MAX_QUEUES 2 // Number of I/O queues supported by the driver, 1 for AQ, 1 for CQ\r
62#define NVME_ASQ_SIZE 1 // Number of admin submission queue entries, which is 0-based\r
63#define NVME_ACQ_SIZE 1 // Number of admin completion queue entries, which is 0-based\r
64#define NVME_CSQ_SIZE 63 // Number of I/O submission queue entries, which is 0-based\r
65#define NVME_CCQ_SIZE 63 // Number of I/O completion queue entries, which is 0-based\r
66#define NVME_PRP_SIZE (8) // Pages of PRP list\r
b8b69433
HW
67\r
68#define NVME_MEM_MAX_PAGES \\r
69 ( \\r
1436aea4
MK
70 1 /* ASQ */ + \\r
71 1 /* ACQ */ + \\r
72 1 /* SQs */ + \\r
73 1 /* CQs */ + \\r
b8b69433
HW
74 NVME_PRP_SIZE) /* PRPs */\r
75\r
1436aea4
MK
76#define NVME_ADMIN_QUEUE 0x00\r
77#define NVME_IO_QUEUE 0x01\r
78#define NVME_GENERIC_TIMEOUT 5000000 // Generic PassThru command timeout value, in us unit\r
79#define NVME_POLL_INTERVAL 100 // Poll interval for PassThru command, in us unit\r
b8b69433
HW
80\r
81//\r
82// Nvme namespace data structure.\r
83//\r
84struct _PEI_NVME_NAMESPACE_INFO {\r
1436aea4
MK
85 UINT32 NamespaceId;\r
86 UINT64 NamespaceUuid;\r
87 EFI_PEI_BLOCK_IO2_MEDIA Media;\r
b8b69433 88\r
1436aea4 89 PEI_NVME_CONTROLLER_PRIVATE_DATA *Controller;\r
b8b69433
HW
90};\r
91\r
1436aea4 92#define NVME_CONTROLLER_NSID 0\r
ba3aa1c4 93\r
b8b69433
HW
94//\r
95// Unique signature for private data structure.\r
96//\r
1436aea4 97#define NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('N','V','P','C')\r
b8b69433
HW
98\r
99//\r
100// Nvme controller private data structure.\r
101//\r
102struct _PEI_NVME_CONTROLLER_PRIVATE_DATA {\r
1436aea4
MK
103 UINT32 Signature;\r
104 UINTN MmioBase;\r
105 EFI_NVM_EXPRESS_PASS_THRU_MODE PassThruMode;\r
106 UINTN DevicePathLength;\r
107 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
108\r
109 EFI_PEI_RECOVERY_BLOCK_IO_PPI BlkIoPpi;\r
110 EFI_PEI_RECOVERY_BLOCK_IO2_PPI BlkIo2Ppi;\r
111 EDKII_PEI_STORAGE_SECURITY_CMD_PPI StorageSecurityPpi;\r
112 EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI NvmePassThruPpi;\r
113 EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList;\r
114 EFI_PEI_PPI_DESCRIPTOR BlkIo2PpiList;\r
115 EFI_PEI_PPI_DESCRIPTOR StorageSecurityPpiList;\r
116 EFI_PEI_PPI_DESCRIPTOR NvmePassThruPpiList;\r
117 EFI_PEI_NOTIFY_DESCRIPTOR EndOfPeiNotifyList;\r
b8b69433
HW
118\r
119 //\r
120 // Pointer to identify controller data\r
121 //\r
1436aea4 122 NVME_ADMIN_CONTROLLER_DATA *ControllerData;\r
b8b69433
HW
123\r
124 //\r
125 // (4 + NVME_PRP_SIZE) x 4kB aligned buffers will be carved out of this buffer\r
126 // 1st 4kB boundary is the start of the admin submission queue\r
127 // 2nd 4kB boundary is the start of the admin completion queue\r
128 // 3rd 4kB boundary is the start of I/O submission queue\r
129 // 4th 4kB boundary is the start of I/O completion queue\r
130 // 5th 4kB boundary is the start of PRP list buffers\r
131 //\r
1436aea4
MK
132 VOID *Buffer;\r
133 VOID *BufferMapping;\r
b8b69433
HW
134\r
135 //\r
136 // Pointers to 4kB aligned submission & completion queues\r
137 //\r
1436aea4
MK
138 NVME_SQ *SqBuffer[NVME_MAX_QUEUES];\r
139 NVME_CQ *CqBuffer[NVME_MAX_QUEUES];\r
b8b69433
HW
140\r
141 //\r
142 // Submission and completion queue indices\r
143 //\r
1436aea4
MK
144 NVME_SQTDBL SqTdbl[NVME_MAX_QUEUES];\r
145 NVME_CQHDBL CqHdbl[NVME_MAX_QUEUES];\r
b8b69433 146\r
1436aea4
MK
147 UINT8 Pt[NVME_MAX_QUEUES];\r
148 UINT16 Cid[NVME_MAX_QUEUES];\r
b8b69433
HW
149\r
150 //\r
151 // Nvme controller capabilities\r
152 //\r
1436aea4 153 NVME_CAP Cap;\r
b8b69433
HW
154\r
155 //\r
156 // Namespaces information on the controller\r
157 //\r
1436aea4
MK
158 UINT32 ActiveNamespaceNum;\r
159 PEI_NVME_NAMESPACE_INFO *NamespaceInfo;\r
b8b69433
HW
160};\r
161\r
2e15b750 162#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO(a) \\r
b8b69433 163 CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, BlkIoPpi, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)\r
2e15b750 164#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2(a) \\r
b8b69433 165 CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, BlkIo2Ppi, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)\r
2e15b750
HW
166#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY(a) \\r
167 CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, StorageSecurityPpi, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)\r
ba3aa1c4
MC
168#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NVME_PASSTHRU(a) \\r
169 CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, NvmePassThruPpi, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)\r
2e15b750 170#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a) \\r
b8b69433
HW
171 CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, EndOfPeiNotifyList, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)\r
172\r
4104423a
HW
173//\r
174// Internal functions\r
175//\r
b8b69433
HW
176\r
177/**\r
178 Allocates pages that are suitable for an OperationBusMasterCommonBuffer or\r
179 OperationBusMasterCommonBuffer64 mapping.\r
180\r
181 @param Pages The number of pages to allocate.\r
182 @param HostAddress A pointer to store the base system memory address of the\r
183 allocated range.\r
184 @param DeviceAddress The resulting map address for the bus master PCI controller to use to\r
185 access the hosts HostAddress.\r
186 @param Mapping A resulting value to pass to Unmap().\r
187\r
188 @retval EFI_SUCCESS The requested memory pages were allocated.\r
189 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are\r
190 MEMORY_WRITE_COMBINE and MEMORY_CACHED.\r
191 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
192 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
193\r
194**/\r
195EFI_STATUS\r
196IoMmuAllocateBuffer (\r
197 IN UINTN Pages,\r
198 OUT VOID **HostAddress,\r
199 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
200 OUT VOID **Mapping\r
201 );\r
202\r
203/**\r
204 Frees memory that was allocated with AllocateBuffer().\r
205\r
206 @param Pages The number of pages to free.\r
207 @param HostAddress The base system memory address of the allocated range.\r
208 @param Mapping The mapping value returned from Map().\r
209\r
210 @retval EFI_SUCCESS The requested memory pages were freed.\r
211 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages\r
212 was not allocated with AllocateBuffer().\r
213\r
214**/\r
215EFI_STATUS\r
216IoMmuFreeBuffer (\r
1436aea4
MK
217 IN UINTN Pages,\r
218 IN VOID *HostAddress,\r
219 IN VOID *Mapping\r
b8b69433
HW
220 );\r
221\r
222/**\r
223 Provides the controller-specific addresses required to access system memory from a\r
224 DMA bus master.\r
225\r
226 @param Operation Indicates if the bus master is going to read or write to system memory.\r
227 @param HostAddress The system memory address to map to the PCI controller.\r
228 @param NumberOfBytes On input the number of bytes to map. On output the number of bytes\r
229 that were mapped.\r
230 @param DeviceAddress The resulting map address for the bus master PCI controller to use to\r
231 access the hosts HostAddress.\r
232 @param Mapping A resulting value to pass to Unmap().\r
233\r
234 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.\r
235 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.\r
236 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
237 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
238 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.\r
239\r
240**/\r
241EFI_STATUS\r
242IoMmuMap (\r
1436aea4
MK
243 IN EDKII_IOMMU_OPERATION Operation,\r
244 IN VOID *HostAddress,\r
245 IN OUT UINTN *NumberOfBytes,\r
246 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
247 OUT VOID **Mapping\r
b8b69433
HW
248 );\r
249\r
250/**\r
251 Completes the Map() operation and releases any corresponding resources.\r
252\r
253 @param Mapping The mapping value returned from Map().\r
254\r
255 @retval EFI_SUCCESS The range was unmapped.\r
256 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().\r
257 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.\r
258**/\r
259EFI_STATUS\r
260IoMmuUnmap (\r
1436aea4 261 IN VOID *Mapping\r
b8b69433
HW
262 );\r
263\r
264/**\r
265 One notified function to cleanup the allocated resources at the end of PEI.\r
266\r
267 @param[in] PeiServices Pointer to PEI Services Table.\r
268 @param[in] NotifyDescriptor Pointer to the descriptor for the Notification\r
269 event that caused this function to execute.\r
270 @param[in] Ppi Pointer to the PPI data associated with this function.\r
271\r
272 @retval EFI_SUCCESS The function completes successfully\r
273\r
274**/\r
275EFI_STATUS\r
276EFIAPI\r
277NvmePeimEndOfPei (\r
278 IN EFI_PEI_SERVICES **PeiServices,\r
279 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
280 IN VOID *Ppi\r
281 );\r
282\r
05fd2a92
HW
283/**\r
284 Get the size of the current device path instance.\r
285\r
286 @param[in] DevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL\r
287 structure.\r
288 @param[out] InstanceSize The size of the current device path instance.\r
289 @param[out] EntireDevicePathEnd Indicate whether the instance is the last\r
290 one in the device path strucure.\r
291\r
292 @retval EFI_SUCCESS The size of the current device path instance is fetched.\r
293 @retval Others Fails to get the size of the current device path instance.\r
294\r
295**/\r
296EFI_STATUS\r
297GetDevicePathInstanceSize (\r
1436aea4
MK
298 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
299 OUT UINTN *InstanceSize,\r
300 OUT BOOLEAN *EntireDevicePathEnd\r
05fd2a92
HW
301 );\r
302\r
2e15b750
HW
303/**\r
304 Check the validity of the device path of a NVM Express host controller.\r
305\r
306 @param[in] DevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL\r
307 structure.\r
308 @param[in] DevicePathLength The length of the device path.\r
309\r
310 @retval EFI_SUCCESS The device path is valid.\r
311 @retval EFI_INVALID_PARAMETER The device path is invalid.\r
312\r
313**/\r
314EFI_STATUS\r
315NvmeIsHcDevicePathValid (\r
1436aea4
MK
316 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
317 IN UINTN DevicePathLength\r
2e15b750
HW
318 );\r
319\r
320/**\r
321 Build the device path for an Nvm Express device with given namespace identifier\r
322 and namespace extended unique identifier.\r
323\r
324 @param[in] Private A pointer to the PEI_NVME_CONTROLLER_PRIVATE_DATA\r
325 data structure.\r
326 @param[in] NamespaceId The given namespace identifier.\r
327 @param[in] NamespaceUuid The given namespace extended unique identifier.\r
328 @param[out] DevicePathLength The length of the device path in bytes specified\r
329 by DevicePath.\r
330 @param[out] DevicePath The device path of Nvm Express device.\r
331\r
332 @retval EFI_SUCCESS The operation succeeds.\r
333 @retval EFI_INVALID_PARAMETER The parameters are invalid.\r
334 @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of resources.\r
335\r
336**/\r
337EFI_STATUS\r
338NvmeBuildDevicePath (\r
1436aea4
MK
339 IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private,\r
340 IN UINT32 NamespaceId,\r
341 IN UINT64 NamespaceUuid,\r
342 OUT UINTN *DevicePathLength,\r
343 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
2e15b750
HW
344 );\r
345\r
05fd2a92
HW
346/**\r
347 Determine if a specific NVM Express controller can be skipped for S3 phase.\r
348\r
349 @param[in] HcDevicePath Device path of the controller.\r
350 @param[in] HcDevicePathLength Length of the device path specified by\r
351 HcDevicePath.\r
352\r
353 @retval The number of ports that need to be enumerated.\r
354\r
355**/\r
356BOOLEAN\r
357NvmeS3SkipThisController (\r
1436aea4
MK
358 IN EFI_DEVICE_PATH_PROTOCOL *HcDevicePath,\r
359 IN UINTN HcDevicePathLength\r
05fd2a92
HW
360 );\r
361\r
9ca7ece8
CX
362/**\r
363 Callback for EDKII_PCI_DEVICE_PPI installation.\r
364\r
365 @param[in] PeiServices Pointer to PEI Services Table.\r
366 @param[in] NotifyDescriptor Pointer to the descriptor for the Notification\r
367 event that caused this function to execute.\r
368 @param[in] Ppi Pointer to the PPI data associated with this function.\r
369\r
370 @retval EFI_SUCCESS The function completes successfully\r
371 @retval Others Cannot initialize Nvme controller from given PCI_DEVICE_PPI\r
372\r
373**/\r
374EFI_STATUS\r
375EFIAPI\r
376NvmePciDevicePpiInstallationCallback (\r
377 IN EFI_PEI_SERVICES **PeiServices,\r
378 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
379 IN VOID *Ppi\r
380 );\r
381\r
382/**\r
383 Callback for EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI installation.\r
384\r
385 @param[in] PeiServices Pointer to PEI Services Table.\r
386 @param[in] NotifyDescriptor Pointer to the descriptor for the Notification\r
387 event that caused this function to execute.\r
388 @param[in] Ppi Pointer to the PPI data associated with this function.\r
389\r
390 @retval EFI_SUCCESS The function completes successfully\r
391 @retval Others Cannot initialize Nvme controller from given EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI\r
392\r
393**/\r
394EFI_STATUS\r
395EFIAPI\r
396NvmeHostControllerPpiInstallationCallback (\r
397 IN EFI_PEI_SERVICES **PeiServices,\r
398 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
399 IN VOID *Ppi\r
400 );\r
401\r
b8b69433 402#endif\r