TianoCore EDK2 master
Loading...
Searching...
No Matches
NvmExpressPeiBlockIo.c
Go to the documentation of this file.
1
11#include "NvmExpressPei.h"
12
27 IN PEI_NVME_NAMESPACE_INFO *NamespaceInfo,
28 OUT UINTN Buffer,
29 IN UINT64 Lba,
30 IN UINT32 Blocks
31 )
32{
33 EFI_STATUS Status;
34 UINT32 BlockSize;
36 UINT32 Bytes;
41
42 Private = NamespaceInfo->Controller;
43 NvmePassThru = &Private->NvmePassThruPpi;
44 BlockSize = NamespaceInfo->Media.BlockSize;
45 Bytes = Blocks * BlockSize;
46
47 ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
48 ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND));
49 ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION));
50
51 CommandPacket.NvmeCmd = &Command;
52 CommandPacket.NvmeCompletion = &Completion;
53
54 CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_READ_OPC;
55 CommandPacket.NvmeCmd->Nsid = NamespaceInfo->NamespaceId;
56 CommandPacket.TransferBuffer = (VOID *)Buffer;
57
58 CommandPacket.TransferLength = Bytes;
59 CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
60 CommandPacket.QueueType = NVME_IO_QUEUE;
61
62 CommandPacket.NvmeCmd->Cdw10 = (UINT32)Lba;
63 CommandPacket.NvmeCmd->Cdw11 = (UINT32)RShiftU64 (Lba, 32);
64 CommandPacket.NvmeCmd->Cdw12 = (Blocks - 1) & 0xFFFF;
65
66 CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID;
67
68 Status = NvmePassThru->PassThru (
70 NamespaceInfo->NamespaceId,
71 &CommandPacket
72 );
73
74 return Status;
75}
76
91 IN PEI_NVME_NAMESPACE_INFO *NamespaceInfo,
92 OUT UINTN Buffer,
93 IN UINT64 Lba,
94 IN UINTN Blocks
95 )
96{
97 EFI_STATUS Status;
98 UINT32 Retries;
99 UINT32 BlockSize;
101 UINT32 MaxTransferBlocks;
102 UINTN OrginalBlocks;
103
104 Status = EFI_SUCCESS;
105 Retries = 0;
106 Private = NamespaceInfo->Controller;
107 BlockSize = NamespaceInfo->Media.BlockSize;
108 OrginalBlocks = Blocks;
109
110 if (Private->ControllerData->Mdts != 0) {
111 MaxTransferBlocks = (1 << (Private->ControllerData->Mdts)) * (1 << (Private->Cap.Mpsmin + 12)) / BlockSize;
112 } else {
113 MaxTransferBlocks = 1024;
114 }
115
116 while (Blocks > 0) {
117 Status = ReadSectors (
118 NamespaceInfo,
119 Buffer,
120 Lba,
121 Blocks > MaxTransferBlocks ? MaxTransferBlocks : (UINT32)Blocks
122 );
123 if (EFI_ERROR (Status)) {
124 Retries++;
125 MaxTransferBlocks = MaxTransferBlocks >> 1;
126
127 if ((Retries > NVME_READ_MAX_RETRY) || (MaxTransferBlocks < 1)) {
128 DEBUG ((DEBUG_ERROR, "%a: ReadSectors fail, Status - %r\n", __func__, Status));
129 break;
130 }
131
132 DEBUG ((
133 DEBUG_BLKIO,
134 "%a: ReadSectors fail, retry with smaller transfer block number - 0x%x\n",
135 __func__,
136 MaxTransferBlocks
137 ));
138 continue;
139 }
140
141 if (Blocks > MaxTransferBlocks) {
142 Blocks -= MaxTransferBlocks;
143 Buffer += (MaxTransferBlocks * BlockSize);
144 Lba += MaxTransferBlocks;
145 } else {
146 Blocks = 0;
147 }
148 }
149
150 DEBUG ((
151 DEBUG_BLKIO,
152 "%a: Lba = 0x%08Lx, Original = 0x%08Lx, "
153 "Remaining = 0x%08Lx, BlockSize = 0x%x, Status = %r\n",
154 __func__,
155 Lba,
156 (UINT64)OrginalBlocks,
157 (UINT64)Blocks,
158 BlockSize,
159 Status
160 ));
161 return Status;
162}
163
181EFIAPI
183 IN EFI_PEI_SERVICES **PeiServices,
185 OUT UINTN *NumberBlockDevices
186 )
187{
189
190 if ((This == NULL) || (NumberBlockDevices == NULL)) {
191 return EFI_INVALID_PARAMETER;
192 }
193
194 Private = GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO (This);
195 *NumberBlockDevices = Private->ActiveNamespaceNum;
196
197 return EFI_SUCCESS;
198}
199
242EFIAPI
244 IN EFI_PEI_SERVICES **PeiServices,
246 IN UINTN DeviceIndex,
247 OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo
248 )
249{
251
252 if ((This == NULL) || (MediaInfo == NULL)) {
253 return EFI_INVALID_PARAMETER;
254 }
255
256 Private = GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO (This);
257
258 if ((DeviceIndex == 0) || (DeviceIndex > Private->ActiveNamespaceNum)) {
259 return EFI_INVALID_PARAMETER;
260 }
261
262 MediaInfo->DeviceType = (EFI_PEI_BLOCK_DEVICE_TYPE)EDKII_PEI_BLOCK_DEVICE_TYPE_NVME;
263 MediaInfo->MediaPresent = TRUE;
264 MediaInfo->LastBlock = (UINTN)Private->NamespaceInfo[DeviceIndex-1].Media.LastBlock;
265 MediaInfo->BlockSize = Private->NamespaceInfo[DeviceIndex-1].Media.BlockSize;
266
267 return EFI_SUCCESS;
268}
269
305EFIAPI
307 IN EFI_PEI_SERVICES **PeiServices,
309 IN UINTN DeviceIndex,
310 IN EFI_PEI_LBA StartLBA,
311 IN UINTN BufferSize,
312 OUT VOID *Buffer
313 )
314{
316 PEI_NVME_NAMESPACE_INFO *NamespaceInfo;
317 UINT32 BlockSize;
318 UINTN NumberOfBlocks;
319
320 Private = GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO (This);
321
322 //
323 // Check parameters
324 //
325 if ((This == NULL) || (Buffer == NULL)) {
326 return EFI_INVALID_PARAMETER;
327 }
328
329 if (BufferSize == 0) {
330 return EFI_SUCCESS;
331 }
332
333 if ((DeviceIndex == 0) || (DeviceIndex > Private->ActiveNamespaceNum)) {
334 return EFI_INVALID_PARAMETER;
335 }
336
337 //
338 // Check BufferSize and StartLBA
339 //
340 NamespaceInfo = &(Private->NamespaceInfo[DeviceIndex - 1]);
341 BlockSize = NamespaceInfo->Media.BlockSize;
342 if (BufferSize % BlockSize != 0) {
343 return EFI_BAD_BUFFER_SIZE;
344 }
345
346 if (StartLBA > NamespaceInfo->Media.LastBlock) {
347 return EFI_INVALID_PARAMETER;
348 }
349
350 NumberOfBlocks = BufferSize / BlockSize;
351 if (NumberOfBlocks - 1 > NamespaceInfo->Media.LastBlock - StartLBA) {
352 return EFI_INVALID_PARAMETER;
353 }
354
355 return NvmeRead (NamespaceInfo, (UINTN)Buffer, StartLBA, NumberOfBlocks);
356}
357
375EFIAPI
377 IN EFI_PEI_SERVICES **PeiServices,
379 OUT UINTN *NumberBlockDevices
380 )
381{
383
384 if ((This == NULL) || (NumberBlockDevices == NULL)) {
385 return EFI_INVALID_PARAMETER;
386 }
387
388 Private = GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2 (This);
389 *NumberBlockDevices = Private->ActiveNamespaceNum;
390
391 return EFI_SUCCESS;
392}
393
436EFIAPI
438 IN EFI_PEI_SERVICES **PeiServices,
440 IN UINTN DeviceIndex,
442 )
443{
444 EFI_STATUS Status;
447
448 if ((This == NULL) || (MediaInfo == NULL)) {
449 return EFI_INVALID_PARAMETER;
450 }
451
452 Private = GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2 (This);
453
455 PeiServices,
456 &Private->BlkIoPpi,
457 DeviceIndex,
458 &Media
459 );
460 if (EFI_ERROR (Status)) {
461 return Status;
462 }
463
464 CopyMem (
465 MediaInfo,
466 &(Private->NamespaceInfo[DeviceIndex - 1].Media),
468 );
469
470 return EFI_SUCCESS;
471}
472
508EFIAPI
510 IN EFI_PEI_SERVICES **PeiServices,
512 IN UINTN DeviceIndex,
513 IN EFI_PEI_LBA StartLBA,
514 IN UINTN BufferSize,
515 OUT VOID *Buffer
516 )
517{
519
520 if (This == NULL) {
521 return EFI_INVALID_PARAMETER;
522 }
523
524 Private = GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2 (This);
526 PeiServices,
527 &Private->BlkIoPpi,
528 DeviceIndex,
529 StartLBA,
530 BufferSize,
531 Buffer
532 );
533}
UINT64 UINTN
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_PEI_BLOCK_DEVICE_TYPE
Definition: BlockIo.h:46
UINT64 EFI_PEI_LBA
Definition: BlockIo.h:41
EFI_STATUS EFIAPI NvmeBlockIoPeimReadBlocks(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, IN UINTN DeviceIndex, IN EFI_PEI_LBA StartLBA, IN UINTN BufferSize, OUT VOID *Buffer)
EFI_STATUS EFIAPI NvmeBlockIoPeimGetMediaInfo(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, IN UINTN DeviceIndex, OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo)
EFI_STATUS EFIAPI NvmeBlockIoPeimGetMediaInfo2(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, IN UINTN DeviceIndex, OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo)
EFI_STATUS EFIAPI NvmeBlockIoPeimReadBlocks2(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, IN UINTN DeviceIndex, IN EFI_PEI_LBA StartLBA, IN UINTN BufferSize, OUT VOID *Buffer)
EFI_STATUS ReadSectors(IN PEI_NVME_NAMESPACE_INFO *NamespaceInfo, OUT UINTN Buffer, IN UINT64 Lba, IN UINT32 Blocks)
EFI_STATUS EFIAPI NvmeBlockIoPeimGetDeviceNo(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, OUT UINTN *NumberBlockDevices)
EFI_STATUS EFIAPI NvmeBlockIoPeimGetDeviceNo2(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, OUT UINTN *NumberBlockDevices)
EFI_STATUS NvmeRead(IN PEI_NVME_NAMESPACE_INFO *NamespaceInfo, OUT UINTN Buffer, IN UINT64 Lba, IN UINTN Blocks)
EFI_STATUS EFIAPI NvmePassThru(IN EDKII_PEI_NVM_EXPRESS_PASS_THRU_PPI *This, IN UINT32 NamespaceId, IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_PEI_LBA LastBlock
Definition: BlockIo2.h:64