25 IN OUT VOID *MemBuffer,
37 *((UINT32 *)MemBuffer) =
MmioRead32 (MmioAddr);
41 *((UINT64 *)MemBuffer) =
MmioRead64 (MmioAddr);
45 *((UINT16 *)MemBuffer) =
MmioRead16 (MmioAddr);
49 *((UINT8 *)MemBuffer) =
MmioRead8 (MmioAddr);
53 Ptr = (UINT8 *)MemBuffer;
54 for (Offset = 0; Offset < Size; Offset += 1) {
105 Ptr = (UINT8 *)MemBuffer;
106 for (Offset = 0; Offset < Size; Offset += 1) {
132 UINT32 PageSizeList[5];
138 PageSizeList[4] = NVME_PRP_SIZE;
140 if (BaseMemIndex > MAX_BASEMEM_COUNT) {
141 DEBUG ((DEBUG_ERROR,
"%a: The input BaseMem index is invalid.\n", __func__));
147 for (Index = 0; Index < BaseMemIndex; Index++) {
148 Pages += PageSizeList[Index];
179 if (Private->Cap.To == 0) {
182 Timeout = Private->Cap.To;
186 for (Index = (Timeout * 500); Index != 0; --Index) {
192 Status = NVME_GET_CSTS (Private, &Csts);
193 if (EFI_ERROR (Status)) {
194 DEBUG ((DEBUG_ERROR,
"%a: NVME_GET_CSTS fail, Status - %r\n", __func__, Status));
198 if ((BOOLEAN)Csts.Rdy == WaitReady) {
204 Status = EFI_TIMEOUT;
228 Status = NVME_GET_CSTS (Private, &Csts);
233 Status = NVME_GET_CC (Private, &Cc);
234 if (EFI_ERROR (Status)) {
235 DEBUG ((DEBUG_ERROR,
"%a: NVME_GET_CC fail, Status - %r\n", __func__, Status));
244 Status = NVME_SET_CC (Private, &Cc);
245 if (EFI_ERROR (Status)) {
246 DEBUG ((DEBUG_ERROR,
"%a: NVME_SET_CC fail, Status - %r\n", __func__, Status));
252 if (EFI_ERROR (Status)) {
253 DEBUG ((DEBUG_ERROR,
"%a: NvmeWaitController fail, Status - %r\n", __func__, Status));
260 DEBUG ((DEBUG_ERROR,
"%a fail, Status - %r\n", __func__, Status));
290 Status = NVME_SET_CC (Private, &Cc);
291 if (EFI_ERROR (Status)) {
292 DEBUG ((DEBUG_ERROR,
"%a: NVME_SET_CC fail, Status - %r\n", __func__, Status));
297 if (EFI_ERROR (Status)) {
298 DEBUG ((DEBUG_ERROR,
"%a: NvmeWaitController fail, Status - %r\n", __func__, Status));
305 DEBUG ((DEBUG_ERROR,
"%a fail, Status: %r\n", __func__, Status));
334 Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD;
341 CommandPacket.NvmeCmd = &Command;
342 CommandPacket.NvmeCompletion = &Completion;
343 CommandPacket.TransferBuffer = Buffer;
345 CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
346 CommandPacket.QueueType = NVME_ADMIN_QUEUE;
350 CommandPacket.NvmeCmd->Cdw10 = 1;
351 CommandPacket.NvmeCmd->Flags = CDW10_VALID;
355 NVME_CONTROLLER_NSID,
375 IN UINT32 NamespaceId,
388 Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD;
389 Command.Nsid = NamespaceId;
391 CommandPacket.NvmeCmd = &Command;
392 CommandPacket.NvmeCompletion = &Completion;
393 CommandPacket.TransferBuffer = Buffer;
395 CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
396 CommandPacket.QueueType = NVME_ADMIN_QUEUE;
400 CommandPacket.NvmeCmd->Cdw10 = 0;
401 CommandPacket.NvmeCmd->Flags = CDW10_VALID;
425 CopyMem (Sn, ControllerData->Sn, sizeof (ControllerData->Sn));
427 CopyMem (Mn, ControllerData->Mn, sizeof (ControllerData->Mn));
430 DEBUG ((DEBUG_INFO,
" == NVME IDENTIFY CONTROLLER DATA ==\n"));
431 DEBUG ((DEBUG_INFO,
" PCI VID : 0x%x\n", ControllerData->Vid));
432 DEBUG ((DEBUG_INFO,
" PCI SSVID : 0x%x\n", ControllerData->Ssvid));
433 DEBUG ((DEBUG_INFO,
" SN : %a\n", Sn));
434 DEBUG ((DEBUG_INFO,
" MN : %a\n", Mn));
435 DEBUG ((DEBUG_INFO,
" FR : 0x%lx\n", *((UINT64 *)ControllerData->Fr)));
436 DEBUG ((DEBUG_INFO,
" RAB : 0x%x\n", ControllerData->Rab));
437 DEBUG ((DEBUG_INFO,
" IEEE : 0x%x\n", *(UINT32 *)ControllerData->Ieee_oui));
438 DEBUG ((DEBUG_INFO,
" AERL : 0x%x\n", ControllerData->Aerl));
439 DEBUG ((DEBUG_INFO,
" SQES : 0x%x\n", ControllerData->Sqes));
440 DEBUG ((DEBUG_INFO,
" CQES : 0x%x\n", ControllerData->Cqes));
441 DEBUG ((DEBUG_INFO,
" NN : 0x%x\n", ControllerData->Nn));
470 CommandPacket.NvmeCmd = &Command;
471 CommandPacket.NvmeCompletion = &Completion;
473 Command.Cdw0.Opcode = NVME_ADMIN_CRIOCQ_CMD;
474 CommandPacket.TransferBuffer = Private->CqBuffer[NVME_IO_QUEUE];
475 CommandPacket.TransferLength = EFI_PAGE_SIZE;
476 CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
477 CommandPacket.QueueType = NVME_ADMIN_QUEUE;
479 CrIoCq.Qid = NVME_IO_QUEUE;
480 CrIoCq.Qsize = NVME_CCQ_SIZE;
483 CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
487 NVME_CONTROLLER_NSID,
518 CommandPacket.NvmeCmd = &Command;
519 CommandPacket.NvmeCompletion = &Completion;
521 Command.Cdw0.Opcode = NVME_ADMIN_CRIOSQ_CMD;
522 CommandPacket.TransferBuffer = Private->SqBuffer[NVME_IO_QUEUE];
523 CommandPacket.TransferLength = EFI_PAGE_SIZE;
524 CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
525 CommandPacket.QueueType = NVME_ADMIN_QUEUE;
527 CrIoSq.Qid = NVME_IO_QUEUE;
528 CrIoSq.Qsize = NVME_CSQ_SIZE;
530 CrIoSq.Cqid = NVME_IO_QUEUE;
533 CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID;
537 NVME_CONTROLLER_NSID,
567 NVME_GET_VER (Private, &Ver);
568 DEBUG ((DEBUG_INFO,
"NVME controller implementation version: %d.%d\n", Ver.Mjr, Ver.Mnr));
573 NVME_GET_CAP (Private, &Private->Cap);
574 if ((Private->Cap.Css & BIT0) == 0) {
575 DEBUG ((DEBUG_ERROR,
"%a: The NVME controller doesn't support NVMe command set.\n", __func__));
576 return EFI_UNSUPPORTED;
582 if ((Private->Cap.Mpsmin + 12) > EFI_PAGE_SHIFT) {
583 DEBUG ((DEBUG_ERROR,
"%a: The driver doesn't support page size other than 4K.\n", __func__));
585 return EFI_UNSUPPORTED;
588 for (Index = 0; Index < NVME_MAX_QUEUES; Index++) {
589 Private->Pt[Index] = 0;
590 Private->Cid[Index] = 0;
595 ZeroMem (Private->Buffer, EFI_PAGE_SIZE * NVME_MEM_MAX_PAGES);
601 if (EFI_ERROR (Status)) {
602 DEBUG ((DEBUG_ERROR,
"%a: NvmeDisableController fail, Status - %r\n", __func__, Status));
609 Aqa.Asqs = NVME_ASQ_SIZE;
611 Aqa.Acqs = NVME_ACQ_SIZE;
617 Asq = (UINT64)(
UINTN)(NVME_ASQ_BASE (Private) & ~0xFFF);
618 Acq = (UINT64)(
UINTN)(NVME_ACQ_BASE (Private) & ~0xFFF);
623 Private->SqBuffer[0] = (
NVME_SQ *)(
UINTN)NVME_ASQ_BASE (Private);
624 Private->CqBuffer[0] = (
NVME_CQ *)(
UINTN)NVME_ACQ_BASE (Private);
625 Private->SqBuffer[1] = (
NVME_SQ *)(
UINTN)NVME_SQ_BASE (Private, 0);
626 Private->CqBuffer[1] = (
NVME_CQ *)(
UINTN)NVME_CQ_BASE (Private, 0);
627 DEBUG ((DEBUG_INFO,
"Admin Submission Queue Size (Aqa.Asqs) = [%08X]\n", Aqa.Asqs));
628 DEBUG ((DEBUG_INFO,
"Admin Completion Queue Size (Aqa.Acqs) = [%08X]\n", Aqa.Acqs));
629 DEBUG ((DEBUG_INFO,
"Admin Submission Queue (SqBuffer[0]) = [%08X]\n", Private->SqBuffer[0]));
630 DEBUG ((DEBUG_INFO,
"Admin Completion Queue (CqBuffer[0]) = [%08X]\n", Private->CqBuffer[0]));
631 DEBUG ((DEBUG_INFO,
"I/O Submission Queue (SqBuffer[1]) = [%08X]\n", Private->SqBuffer[1]));
632 DEBUG ((DEBUG_INFO,
"I/O Completion Queue (CqBuffer[1]) = [%08X]\n", Private->CqBuffer[1]));
637 NVME_SET_AQA (Private, &Aqa);
642 NVME_SET_ASQ (Private, &Asq);
643 NVME_SET_ACQ (Private, &Acq);
649 if (EFI_ERROR (Status)) {
650 DEBUG ((DEBUG_ERROR,
"%a: NvmeEnableController fail, Status - %r\n", __func__, Status));
657 if (Private->ControllerData ==
NULL) {
659 if (Private->ControllerData ==
NULL) {
660 return EFI_OUT_OF_RESOURCES;
665 if (EFI_ERROR (Status)) {
666 DEBUG ((DEBUG_ERROR,
"%a: NvmeIdentifyController fail, Status - %r\n", __func__, Status));
678 "%a: Number of Namespaces field in Identify Controller data not supported by the driver.\n",
681 return EFI_UNSUPPORTED;
688 if (EFI_ERROR (Status)) {
689 DEBUG ((DEBUG_ERROR,
"%a: Create IO completion queue fail, Status - %r\n", __func__, Status));
694 if (EFI_ERROR (Status)) {
695 DEBUG ((DEBUG_ERROR,
"%a: Create IO submission queue fail, Status - %r\n", __func__, Status));
712 ASSERT (Private !=
NULL);
714 if (Private->BufferMapping !=
NULL) {
718 Private->BufferMapping
EFI_STATUS IoMmuFreeBuffer(IN UINTN Pages, IN VOID *HostAddress, IN VOID *Mapping)
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
UINT64 EFIAPI MmioWrite64(IN UINTN Address, IN UINT64 Value)
UINT64 EFIAPI MmioRead64(IN UINTN Address)
UINT16 EFIAPI MmioRead16(IN UINTN Address)
UINT8 EFIAPI MmioRead8(IN UINTN Address)
UINT8 EFIAPI MmioWrite8(IN UINTN Address, IN UINT8 Value)
UINT32 EFIAPI MmioRead32(IN UINTN Address)
UINT16 EFIAPI MmioWrite16(IN UINTN Address, IN UINT16 Value)
UINT32 EFIAPI MmioWrite32(IN UINTN Address, IN UINT32 Value)
#define DEBUG(Expression)
EFI_STATUS NvmeDisableController(IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private)
VOID NvmeFreeDmaResource(IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private)
EFI_STATUS NvmeControllerInit(IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private)
EFI_STATUS NvmeMmioRead(IN OUT VOID *MemBuffer, IN UINTN MmioAddr, IN UINTN Size)
UINT32 NvmeBaseMemPageOffset(IN UINTN BaseMemIndex)
EFI_STATUS NvmeCreateIoCompletionQueue(IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private)
VOID NvmeDumpControllerData(IN NVME_ADMIN_CONTROLLER_DATA *ControllerData)
EFI_STATUS NvmeMmioWrite(IN OUT UINTN MmioAddr, IN VOID *MemBuffer, IN UINTN Size)
EFI_STATUS NvmeIdentifyNamespace(IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private, IN UINT32 NamespaceId, IN VOID *Buffer)
EFI_STATUS NvmeWaitController(IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private, IN BOOLEAN WaitReady)
EFI_STATUS NvmeCreateIoSubmissionQueue(IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private)
EFI_STATUS NvmeIdentifyController(IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private, IN VOID *Buffer)
EFI_STATUS NvmeEnableController(IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private)
EFI_STATUS NvmePassThruExecute(IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private, IN UINT32 NamespaceId, IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet)