2 The NvmExpressPei driver is used to manage non-volatile memory subsystem
3 which follows NVM Express specification at PEI phase.
5 Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions
9 of the BSD License which accompanies this distribution. The
10 full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #ifndef _NVM_EXPRESS_PEI_H_
19 #define _NVM_EXPRESS_PEI_H_
23 #include <IndustryStandard/Nvme.h>
25 #include <Ppi/NvmExpressHostController.h>
26 #include <Ppi/BlockIo.h>
27 #include <Ppi/BlockIo2.h>
28 #include <Ppi/StorageSecurityCommand.h>
29 #include <Ppi/IoMmu.h>
30 #include <Ppi/EndOfPeiPhase.h>
32 #include <Library/DebugLib.h>
33 #include <Library/PeiServicesLib.h>
34 #include <Library/MemoryAllocationLib.h>
35 #include <Library/BaseMemoryLib.h>
36 #include <Library/IoLib.h>
37 #include <Library/TimerLib.h>
40 // Structure forward declarations
42 typedef struct _PEI_NVME_NAMESPACE_INFO PEI_NVME_NAMESPACE_INFO
;
43 typedef struct _PEI_NVME_CONTROLLER_PRIVATE_DATA PEI_NVME_CONTROLLER_PRIVATE_DATA
;
45 #include "NvmExpressPeiHci.h"
46 #include "NvmExpressPeiPassThru.h"
47 #include "NvmExpressPeiBlockIo.h"
48 #include "NvmExpressPeiStorageSecurity.h"
51 // NVME PEI driver implementation related definitions
53 #define NVME_MAX_QUEUES 2 // Number of I/O queues supported by the driver, 1 for AQ, 1 for CQ
54 #define NVME_ASQ_SIZE 1 // Number of admin submission queue entries, which is 0-based
55 #define NVME_ACQ_SIZE 1 // Number of admin completion queue entries, which is 0-based
56 #define NVME_CSQ_SIZE 63 // Number of I/O submission queue entries, which is 0-based
57 #define NVME_CCQ_SIZE 63 // Number of I/O completion queue entries, which is 0-based
58 #define NVME_PRP_SIZE (8) // Pages of PRP list
60 #define NVME_MEM_MAX_PAGES \
66 NVME_PRP_SIZE) /* PRPs */
68 #define NVME_ADMIN_QUEUE 0x00
69 #define NVME_IO_QUEUE 0x01
70 #define NVME_GENERIC_TIMEOUT 5000000 // Generic PassThru command timeout value, in us unit
71 #define NVME_POLL_INTERVAL 100 // Poll interval for PassThru command, in us unit
74 // Nvme namespace data structure.
76 struct _PEI_NVME_NAMESPACE_INFO
{
79 EFI_PEI_BLOCK_IO2_MEDIA Media
;
81 PEI_NVME_CONTROLLER_PRIVATE_DATA
*Controller
;
85 // Unique signature for private data structure.
87 #define NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('N','V','P','C')
90 // Nvme controller private data structure.
92 struct _PEI_NVME_CONTROLLER_PRIVATE_DATA
{
95 UINTN DevicePathLength
;
96 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
98 EFI_PEI_RECOVERY_BLOCK_IO_PPI BlkIoPpi
;
99 EFI_PEI_RECOVERY_BLOCK_IO2_PPI BlkIo2Ppi
;
100 EDKII_PEI_STORAGE_SECURITY_CMD_PPI StorageSecurityPpi
;
101 EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList
;
102 EFI_PEI_PPI_DESCRIPTOR BlkIo2PpiList
;
103 EFI_PEI_PPI_DESCRIPTOR StorageSecurityPpiList
;
104 EFI_PEI_NOTIFY_DESCRIPTOR EndOfPeiNotifyList
;
107 // Pointer to identify controller data
109 NVME_ADMIN_CONTROLLER_DATA
*ControllerData
;
112 // (4 + NVME_PRP_SIZE) x 4kB aligned buffers will be carved out of this buffer
113 // 1st 4kB boundary is the start of the admin submission queue
114 // 2nd 4kB boundary is the start of the admin completion queue
115 // 3rd 4kB boundary is the start of I/O submission queue
116 // 4th 4kB boundary is the start of I/O completion queue
117 // 5th 4kB boundary is the start of PRP list buffers
123 // Pointers to 4kB aligned submission & completion queues
125 NVME_SQ
*SqBuffer
[NVME_MAX_QUEUES
];
126 NVME_CQ
*CqBuffer
[NVME_MAX_QUEUES
];
129 // Submission and completion queue indices
131 NVME_SQTDBL SqTdbl
[NVME_MAX_QUEUES
];
132 NVME_CQHDBL CqHdbl
[NVME_MAX_QUEUES
];
134 UINT8 Pt
[NVME_MAX_QUEUES
];
135 UINT16 Cid
[NVME_MAX_QUEUES
];
138 // Nvme controller capabilities
143 // Namespaces information on the controller
145 UINT32 ActiveNamespaceNum
;
146 PEI_NVME_NAMESPACE_INFO
*NamespaceInfo
;
149 #define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO(a) \
150 CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, BlkIoPpi, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
151 #define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2(a) \
152 CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, BlkIo2Ppi, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
153 #define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY(a) \
154 CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, StorageSecurityPpi, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
155 #define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a) \
156 CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, EndOfPeiNotifyList, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
160 // Internal functions
164 Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
165 OperationBusMasterCommonBuffer64 mapping.
167 @param Pages The number of pages to allocate.
168 @param HostAddress A pointer to store the base system memory address of the
170 @param DeviceAddress The resulting map address for the bus master PCI controller to use to
171 access the hosts HostAddress.
172 @param Mapping A resulting value to pass to Unmap().
174 @retval EFI_SUCCESS The requested memory pages were allocated.
175 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
176 MEMORY_WRITE_COMBINE and MEMORY_CACHED.
177 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
178 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
182 IoMmuAllocateBuffer (
184 OUT VOID
**HostAddress
,
185 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
190 Frees memory that was allocated with AllocateBuffer().
192 @param Pages The number of pages to free.
193 @param HostAddress The base system memory address of the allocated range.
194 @param Mapping The mapping value returned from Map().
196 @retval EFI_SUCCESS The requested memory pages were freed.
197 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
198 was not allocated with AllocateBuffer().
204 IN VOID
*HostAddress
,
209 Provides the controller-specific addresses required to access system memory from a
212 @param Operation Indicates if the bus master is going to read or write to system memory.
213 @param HostAddress The system memory address to map to the PCI controller.
214 @param NumberOfBytes On input the number of bytes to map. On output the number of bytes
216 @param DeviceAddress The resulting map address for the bus master PCI controller to use to
217 access the hosts HostAddress.
218 @param Mapping A resulting value to pass to Unmap().
220 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
221 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
222 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
223 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
224 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
229 IN EDKII_IOMMU_OPERATION Operation
,
230 IN VOID
*HostAddress
,
231 IN OUT UINTN
*NumberOfBytes
,
232 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
,
237 Completes the Map() operation and releases any corresponding resources.
239 @param Mapping The mapping value returned from Map().
241 @retval EFI_SUCCESS The range was unmapped.
242 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
243 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
251 One notified function to cleanup the allocated resources at the end of PEI.
253 @param[in] PeiServices Pointer to PEI Services Table.
254 @param[in] NotifyDescriptor Pointer to the descriptor for the Notification
255 event that caused this function to execute.
256 @param[in] Ppi Pointer to the PPI data associated with this function.
258 @retval EFI_SUCCESS The function completes successfully
264 IN EFI_PEI_SERVICES
**PeiServices
,
265 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
270 Check the validity of the device path of a NVM Express host controller.
272 @param[in] DevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL
274 @param[in] DevicePathLength The length of the device path.
276 @retval EFI_SUCCESS The device path is valid.
277 @retval EFI_INVALID_PARAMETER The device path is invalid.
281 NvmeIsHcDevicePathValid (
282 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
283 IN UINTN DevicePathLength
287 Build the device path for an Nvm Express device with given namespace identifier
288 and namespace extended unique identifier.
290 @param[in] Private A pointer to the PEI_NVME_CONTROLLER_PRIVATE_DATA
292 @param[in] NamespaceId The given namespace identifier.
293 @param[in] NamespaceUuid The given namespace extended unique identifier.
294 @param[out] DevicePathLength The length of the device path in bytes specified
296 @param[out] DevicePath The device path of Nvm Express device.
298 @retval EFI_SUCCESS The operation succeeds.
299 @retval EFI_INVALID_PARAMETER The parameters are invalid.
300 @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of resources.
304 NvmeBuildDevicePath (
305 IN PEI_NVME_CONTROLLER_PRIVATE_DATA
*Private
,
306 IN UINT32 NamespaceId
,
307 IN UINT64 NamespaceUuid
,
308 OUT UINTN
*DevicePathLength
,
309 OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePath