2 NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows
3 NVM Express specification.
5 Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 // controller register offsets
24 #define NVME_CAP_OFFSET 0x0000 // Controller Capabilities
25 #define NVME_VER_OFFSET 0x0008 // Version
26 #define NVME_INTMS_OFFSET 0x000c // Interrupt Mask Set
27 #define NVME_INTMC_OFFSET 0x0010 // Interrupt Mask Clear
28 #define NVME_CC_OFFSET 0x0014 // Controller Configuration
29 #define NVME_CSTS_OFFSET 0x001c // Controller Status
30 #define NVME_NSSR_OFFSET 0x0020 // NVM Subsystem Reset
31 #define NVME_AQA_OFFSET 0x0024 // Admin Queue Attributes
32 #define NVME_ASQ_OFFSET 0x0028 // Admin Submission Queue Base Address
33 #define NVME_ACQ_OFFSET 0x0030 // Admin Completion Queue Base Address
34 #define NVME_SQ0_OFFSET 0x1000 // Submission Queue 0 (admin) Tail Doorbell
35 #define NVME_CQ0_OFFSET 0x1004 // Completion Queue 0 (admin) Head Doorbell
38 // These register offsets are defined as 0x1000 + (N * (4 << CAP.DSTRD))
39 // Get the doorbell stride bit shift value from the controller capabilities.
41 #define NVME_SQTDBL_OFFSET(QID, DSTRD) 0x1000 + ((2 * (QID)) * (4 << (DSTRD))) // Submission Queue y (NVM) Tail Doorbell
42 #define NVME_CQHDBL_OFFSET(QID, DSTRD) 0x1000 + (((2 * (QID)) + 1) * (4 << (DSTRD))) // Completion Queue y (NVM) Head Doorbell
48 // 3.1.1 Offset 00h: CAP - Controller Capabilities
51 UINT16 Mqes
; // Maximum Queue Entries Supported
52 UINT8 Cqr
:1; // Contiguous Queues Required
53 UINT8 Ams
:2; // Arbitration Mechanism Supported
57 UINT16 Nssrs
:1; // NVM Subsystem Reset Supported NSSRS
58 UINT16 Css
:4; // Command Sets Supported - Bit 37
66 // 3.1.2 Offset 08h: VS - Version
69 UINT16 Mnr
; // Minor version number
70 UINT16 Mjr
; // Major version number
74 // 3.1.5 Offset 14h: CC - Controller Configuration
77 UINT16 En
:1; // Enable
79 UINT16 Css
:3; // I/O Command Set Selected
80 UINT16 Mps
:4; // Memory Page Size
81 UINT16 Ams
:3; // Arbitration Mechanism Selected
82 UINT16 Shn
:2; // Shutdown Notification
83 UINT8 Iosqes
:4; // I/O Submission Queue Entry Size
84 UINT8 Iocqes
:4; // I/O Completion Queue Entry Size
89 // 3.1.6 Offset 1Ch: CSTS - Controller Status
92 UINT32 Rdy
:1; // Ready
93 UINT32 Cfs
:1; // Controller Fatal Status
94 UINT32 Shst
:2; // Shutdown Status
95 UINT32 Nssro
:1; // NVM Subsystem Reset Occurred
100 // 3.1.8 Offset 24h: AQA - Admin Queue Attributes
103 UINT16 Asqs
:12; // Submission Queue Size
105 UINT16 Acqs
:12; // Completion Queue Size
110 // 3.1.9 Offset 28h: ASQ - Admin Submission Queue Base Address
114 UINT64 Asqb
:52; // Admin Submission Queue Base Address
118 // 3.1.10 Offset 30h: ACQ - Admin Completion Queue Base Address
122 UINT64 Acqb
:52; // Admin Completion Queue Base Address
126 // 3.1.11 Offset (1000h + ((2y) * (4 << CAP.DSTRD))): SQyTDBL - Submission Queue y Tail Doorbell
134 // 3.1.12 Offset (1000h + ((2y + 1) * (4 << CAP.DSTRD))): CQyHDBL - Completion Queue y Head Doorbell
142 // NVM command set structures
150 UINT64 Slba
; /* Starting Sector Address */
154 UINT16 Nlb
; /* Number of Sectors */
156 UINT16 Prinfo
:4; /* Protection Info Check */
157 UINT16 Fua
:1; /* Force Unit Access */
158 UINT16 Lr
:1; /* Limited Retry */
162 UINT32 Af
:4; /* Access Frequency */
163 UINT32 Al
:2; /* Access Latency */
164 UINT32 Sr
:1; /* Sequential Request */
165 UINT32 In
:1; /* Incompressible */
170 UINT32 Eilbrt
; /* Expected Initial Logical Block Reference Tag */
174 UINT16 Elbat
; /* Expected Logical Block Application Tag */
175 UINT16 Elbatm
; /* Expected Logical Block Application Tag Mask */
185 UINT64 Slba
; /* Starting Sector Address */
189 UINT16 Nlb
; /* Number of Sectors */
191 UINT16 Prinfo
:4; /* Protection Info Check */
192 UINT16 Fua
:1; /* Force Unit Access */
193 UINT16 Lr
:1; /* Limited Retry */
197 UINT32 Af
:4; /* Access Frequency */
198 UINT32 Al
:2; /* Access Latency */
199 UINT32 Sr
:1; /* Sequential Request */
200 UINT32 In
:1; /* Incompressible */
205 UINT32 Ilbrt
; /* Initial Logical Block Reference Tag */
209 UINT16 Lbat
; /* Logical Block Application Tag */
210 UINT16 Lbatm
; /* Logical Block Application Tag Mask */
220 UINT32 Flush
; /* Flush */
224 // Write Uncorrectable command
230 UINT64 Slba
; /* Starting LBA */
234 UINT32 Nlb
:16; /* Number of Logical Blocks */
236 } NVME_WRITE_UNCORRECTABLE
;
239 // Write Zeroes command
245 UINT64 Slba
; /* Starting LBA */
249 UINT16 Nlb
; /* Number of Logical Blocks */
251 UINT16 Prinfo
:4; /* Protection Info Check */
252 UINT16 Fua
:1; /* Force Unit Access */
253 UINT16 Lr
:1; /* Limited Retry */
261 UINT32 Ilbrt
; /* Initial Logical Block Reference Tag */
265 UINT16 Lbat
; /* Logical Block Application Tag */
266 UINT16 Lbatm
; /* Logical Block Application Tag Mask */
276 UINT64 Slba
; /* Starting LBA */
280 UINT16 Nlb
; /* Number of Logical Blocks */
282 UINT16 Prinfo
:4; /* Protection Info Check */
283 UINT16 Fua
:1; /* Force Unit Access */
284 UINT16 Lr
:1; /* Limited Retry */
292 UINT32 Eilbrt
; /* Expected Initial Logical Block Reference Tag */
296 UINT16 Elbat
; /* Expected Logical Block Application Tag */
297 UINT16 Elbatm
; /* Expected Logical Block Application Tag Mask */
304 NVME_WRITE_UNCORRECTABLE WriteUncorrectable
;
305 NVME_WRITE_ZEROES WriteZeros
;
306 NVME_COMPARE Compare
;
310 UINT16 Mp
; /* Maximum Power */
311 UINT8 Rsvd1
; /* Reserved as of Nvm Express 1.1 Spec */
312 UINT8 Mps
:1; /* Max Power Scale */
313 UINT8 Nops
:1; /* Non-Operational State */
314 UINT8 Rsvd2
:6; /* Reserved as of Nvm Express 1.1 Spec */
315 UINT32 Enlat
; /* Entry Latency */
316 UINT32 Exlat
; /* Exit Latency */
317 UINT8 Rrt
:5; /* Relative Read Throughput */
318 UINT8 Rsvd3
:3; /* Reserved as of Nvm Express 1.1 Spec */
319 UINT8 Rrl
:5; /* Relative Read Leatency */
320 UINT8 Rsvd4
:3; /* Reserved as of Nvm Express 1.1 Spec */
321 UINT8 Rwt
:5; /* Relative Write Throughput */
322 UINT8 Rsvd5
:3; /* Reserved as of Nvm Express 1.1 Spec */
323 UINT8 Rwl
:5; /* Relative Write Leatency */
324 UINT8 Rsvd6
:3; /* Reserved as of Nvm Express 1.1 Spec */
325 UINT8 Rsvd7
[16]; /* Reserved as of Nvm Express 1.1 Spec */
329 // Identify Controller Data
333 // Controller Capabilities and Features 0-255
335 UINT16 Vid
; /* PCI Vendor ID */
336 UINT16 Ssvid
; /* PCI sub-system vendor ID */
337 UINT8 Sn
[20]; /* Product serial number */
339 UINT8 Mn
[40]; /* Proeduct model number */
340 UINT8 Fr
[8]; /* Firmware Revision */
341 UINT8 Rab
; /* Recommended Arbitration Burst */
342 UINT8 Ieee_oui
[3]; /* Organization Unique Identifier */
343 UINT8 Cmic
; /* Multi-interface Capabilities */
344 UINT8 Mdts
; /* Maximum Data Transfer Size */
345 UINT8 Cntlid
[2]; /* Controller ID */
346 UINT8 Rsvd1
[176]; /* Reserved as of Nvm Express 1.1 Spec */
348 // Admin Command Set Attributes
350 UINT16 Oacs
; /* Optional Admin Command Support */
351 #define NAMESPACE_MANAGEMENT_SUPPORTED BIT3
352 #define FW_DOWNLOAD_ACTIVATE_SUPPORTED BIT2
353 #define FORMAT_NVM_SUPPORTED BIT1
354 #define SECURITY_SEND_RECEIVE_SUPPORTED BIT0
355 UINT8 Acl
; /* Abort Command Limit */
356 UINT8 Aerl
; /* Async Event Request Limit */
357 UINT8 Frmw
; /* Firmware updates */
358 UINT8 Lpa
; /* Log Page Attributes */
359 UINT8 Elpe
; /* Error Log Page Entries */
360 UINT8 Npss
; /* Number of Power States Support */
361 UINT8 Avscc
; /* Admin Vendor Specific Command Configuration */
362 UINT8 Apsta
; /* Autonomous Power State Transition Attributes */
363 UINT8 Rsvd2
[246]; /* Reserved as of Nvm Express 1.1 Spec */
365 // NVM Command Set Attributes
367 UINT8 Sqes
; /* Submission Queue Entry Size */
368 UINT8 Cqes
; /* Completion Queue Entry Size */
369 UINT16 Rsvd3
; /* Reserved as of Nvm Express 1.1 Spec */
370 UINT32 Nn
; /* Number of Namespaces */
371 UINT16 Oncs
; /* Optional NVM Command Support */
372 UINT16 Fuses
; /* Fused Operation Support */
373 UINT8 Fna
; /* Format NVM Attributes */
374 UINT8 Vwc
; /* Volatile Write Cache */
375 UINT16 Awun
; /* Atomic Write Unit Normal */
376 UINT16 Awupf
; /* Atomic Write Unit Power Fail */
377 UINT8 Nvscc
; /* NVM Vendor Specific Command Configuration */
378 UINT8 Rsvd4
; /* Reserved as of Nvm Express 1.1 Spec */
379 UINT16 Acwu
; /* Atomic Compare & Write Unit */
380 UINT16 Rsvd5
; /* Reserved as of Nvm Express 1.1 Spec */
381 UINT32 Sgls
; /* SGL Support */
382 UINT8 Rsvd6
[164]; /* Reserved as of Nvm Express 1.1 Spec */
384 // I/O Command set Attributes
386 UINT8 Rsvd7
[1344]; /* Reserved as of Nvm Express 1.1 Spec */
388 // Power State Descriptors
390 NVME_PSDESCRIPTOR PsDescriptor
[32];
392 UINT8 VendorData
[1024]; /* Vendor specific data */
393 } NVME_ADMIN_CONTROLLER_DATA
;
396 UINT16 Ms
; /* Metadata Size */
397 UINT8 Lbads
; /* LBA Data Size */
398 UINT8 Rp
:2; /* Relative Performance */
399 #define LBAF_RP_BEST 00b
400 #define LBAF_RP_BETTER 01b
401 #define LBAF_RP_GOOD 10b
402 #define LBAF_RP_DEGRADED 11b
403 UINT8 Rsvd1
:6; /* Reserved as of Nvm Express 1.1 Spec */
407 // Identify Namespace Data
411 // NVM Command Set Specific
413 UINT64 Nsze
; /* Namespace Size (total number of blocks in formatted namespace) */
414 UINT64 Ncap
; /* Namespace Capacity (max number of logical blocks) */
415 UINT64 Nuse
; /* Namespace Utilization */
416 UINT8 Nsfeat
; /* Namespace Features */
417 UINT8 Nlbaf
; /* Number of LBA Formats */
418 UINT8 Flbas
; /* Formatted LBA size */
419 UINT8 Mc
; /* Metadata Capabilities */
420 UINT8 Dpc
; /* End-to-end Data Protection capabilities */
421 UINT8 Dps
; /* End-to-end Data Protection Type Settings */
422 UINT8 Nmic
; /* Namespace Multi-path I/O and Namespace Sharing Capabilities */
423 UINT8 Rescap
; /* Reservation Capabilities */
424 UINT8 Rsvd1
[88]; /* Reserved as of Nvm Express 1.1 Spec */
425 UINT64 Eui64
; /* IEEE Extended Unique Identifier */
429 NVME_LBAFORMAT LbaFormat
[16];
431 UINT8 Rsvd2
[192]; /* Reserved as of Nvm Express 1.1 Spec */
432 UINT8 VendorData
[3712]; /* Vendor specific data */
433 } NVME_ADMIN_NAMESPACE_DATA
;
436 // NvmExpress Admin Identify Cmd
444 } NVME_ADMIN_IDENTIFY
;
447 // NvmExpress Admin Create I/O Completion Queue
453 UINT32 Qid
:16; /* Queue Identifier */
454 UINT32 Qsize
:16; /* Queue Size */
459 UINT32 Pc
:1; /* Physically Contiguous */
460 UINT32 Ien
:1; /* Interrupts Enabled */
461 UINT32 Rsvd1
:14; /* reserved as of Nvm Express 1.1 Spec */
462 UINT32 Iv
:16; /* Interrupt Vector for MSI-X or MSI*/
466 // NvmExpress Admin Create I/O Submission Queue
472 UINT32 Qid
:16; /* Queue Identifier */
473 UINT32 Qsize
:16; /* Queue Size */
478 UINT32 Pc
:1; /* Physically Contiguous */
479 UINT32 Qprio
:2; /* Queue Priority */
480 UINT32 Rsvd1
:13; /* Reserved as of Nvm Express 1.1 Spec */
481 UINT32 Cqid
:16; /* Completion Queue ID */
485 // NvmExpress Admin Delete I/O Completion Queue
496 // NvmExpress Admin Delete I/O Submission Queue
507 // NvmExpress Admin Abort Command
513 UINT32 Sqid
:16; /* Submission Queue identifier */
514 UINT32 Cid
:16; /* Command Identifier */
518 // NvmExpress Admin Firmware Activate Command
524 UINT32 Fs
:3; /* Submission Queue identifier */
525 UINT32 Aa
:2; /* Command Identifier */
527 } NVME_ADMIN_FIRMWARE_ACTIVATE
;
530 // NvmExpress Admin Firmware Image Download Command
536 UINT32 Numd
; /* Number of Dwords */
540 UINT32 Ofst
; /* Offset */
541 } NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD
;
544 // NvmExpress Admin Get Features Command
550 UINT32 Fid
:8; /* Feature Identifier */
551 UINT32 Sel
:3; /* Select */
553 } NVME_ADMIN_GET_FEATURES
;
556 // NvmExpress Admin Get Log Page Command
562 UINT32 Lid
:8; /* Log Page Identifier */
563 #define LID_ERROR_INFO 0x1
564 #define LID_SMART_INFO 0x2
565 #define LID_FW_SLOT_INFO 0x3
567 UINT32 Numd
:12; /* Number of Dwords */
568 UINT32 Rsvd2
:4; /* Reserved as of Nvm Express 1.1 Spec */
569 } NVME_ADMIN_GET_LOG_PAGE
;
572 // NvmExpress Admin Set Features Command
578 UINT32 Fid
:8; /* Feature Identifier */
580 UINT32 Sv
:1; /* Save */
581 } NVME_ADMIN_SET_FEATURES
;
584 // NvmExpress Admin Format NVM Command
590 UINT32 Lbaf
:4; /* LBA Format */
591 UINT32 Ms
:1; /* Metadata Settings */
592 UINT32 Pi
:3; /* Protection Information */
593 UINT32 Pil
:1; /* Protection Information Location */
594 UINT32 Ses
:3; /* Secure Erase Settings */
596 } NVME_ADMIN_FORMAT_NVM
;
599 // NvmExpress Admin Security Receive Command
606 UINT32 Spsp
:16; /* SP Specific */
607 UINT32 Secp
:8; /* Security Protocol */
611 UINT32 Al
; /* Allocation Length */
612 } NVME_ADMIN_SECURITY_RECEIVE
;
615 // NvmExpress Admin Security Send Command
622 UINT32 Spsp
:16; /* SP Specific */
623 UINT32 Secp
:8; /* Security Protocol */
627 UINT32 Tl
; /* Transfer Length */
628 } NVME_ADMIN_SECURITY_SEND
;
631 NVME_ADMIN_IDENTIFY Identify
;
632 NVME_ADMIN_CRIOCQ CrIoCq
;
633 NVME_ADMIN_CRIOSQ CrIoSq
;
634 NVME_ADMIN_DEIOCQ DeIoCq
;
635 NVME_ADMIN_DEIOSQ DeIoSq
;
636 NVME_ADMIN_ABORT Abort
;
637 NVME_ADMIN_FIRMWARE_ACTIVATE Activate
;
638 NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD FirmwareImageDownload
;
639 NVME_ADMIN_GET_FEATURES GetFeatures
;
640 NVME_ADMIN_GET_LOG_PAGE GetLogPage
;
641 NVME_ADMIN_SET_FEATURES SetFeatures
;
642 NVME_ADMIN_FORMAT_NVM FormatNvm
;
643 NVME_ADMIN_SECURITY_RECEIVE SecurityReceive
;
644 NVME_ADMIN_SECURITY_SEND SecuritySend
;
657 NVME_ADMIN_CMD Admin
; // Union of Admin commands
658 NVME_CMD Nvm
; // Union of Nvm commands
667 // CDW 0, Common to all comnmands
670 UINT8 Fuse
:2; // Fused Operation
672 UINT8 Psdt
:1; // PRP or SGL for Data Transfer
673 UINT16 Cid
; // Command Identifier
678 UINT32 Nsid
; // Namespace Identifier
688 UINT64 Mptr
; // Metadata Pointer
693 UINT64 Prp
[2]; // First and second PRP entries
695 NVME_PAYLOAD Payload
;
714 UINT16 Sqhd
; // Submission Queue Head Pointer
715 UINT16 Sqid
; // Submission Queue Identifier
719 UINT16 Cid
; // Command Identifier
720 UINT16 Pt
:1; // Phase Tag
721 UINT16 Sc
:8; // Status Code
722 UINT16 Sct
:3; // Status Code Type
725 UINT16 Dnr
:1; // Do Not Retry
729 // Nvm Express Admin cmd opcodes
731 #define NVME_ADMIN_DEIOSQ_CMD 0x00
732 #define NVME_ADMIN_CRIOSQ_CMD 0x01
733 #define NVME_ADMIN_GET_LOG_PAGE_CMD 0x02
734 #define NVME_ADMIN_DEIOCQ_CMD 0x04
735 #define NVME_ADMIN_CRIOCQ_CMD 0x05
736 #define NVME_ADMIN_IDENTIFY_CMD 0x06
737 #define NVME_ADMIN_ABORT_CMD 0x08
738 #define NVME_ADMIN_SET_FEATURES_CMD 0x09
739 #define NVME_ADMIN_GET_FEATURES_CMD 0x0A
740 #define NVME_ADMIN_ASYNC_EVENT_REQUEST_CMD 0x0C
741 #define NVME_ADMIN_NAMESACE_MANAGEMENT_CMD 0x0D
742 #define NVME_ADMIN_FW_COMMIT_CMD 0x10
743 #define NVME_ADMIN_FW_IAMGE_DOWNLOAD_CMD 0x11
744 #define NVME_ADMIN_NAMESACE_ATTACHMENT_CMD 0x15
745 #define NVME_ADMIN_FORMAT_NVM_CMD 0x80
746 #define NVME_ADMIN_SECURITY_SEND_CMD 0x81
747 #define NVME_ADMIN_SECURITY_RECEIVE_CMD 0x82
749 #define NVME_IO_FLUSH_OPC 0
750 #define NVME_IO_WRITE_OPC 1
751 #define NVME_IO_READ_OPC 2
754 // Offset from the beginning of private data queue buffer
756 #define NVME_ASQ_BUF_OFFSET EFI_PAGE_SIZE
759 Initialize the Nvm Express controller.
761 @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.
763 @retval EFI_SUCCESS The NVM Express Controller is initialized successfully.
764 @retval Others A device error occurred while initializing the controller.
769 IN NVME_CONTROLLER_PRIVATE_DATA
*Private
773 Get identify controller data.
775 @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.
776 @param Buffer The buffer used to store the identify controller data.
778 @return EFI_SUCCESS Successfully get the identify controller data.
779 @return EFI_DEVICE_ERROR Fail to get the identify controller data.
783 NvmeIdentifyController (
784 IN NVME_CONTROLLER_PRIVATE_DATA
*Private
,
789 Get specified identify namespace data.
791 @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.
792 @param NamespaceId The specified namespace identifier.
793 @param Buffer The buffer used to store the identify namespace data.
795 @return EFI_SUCCESS Successfully get the identify namespace data.
796 @return EFI_DEVICE_ERROR Fail to get the identify namespace data.
800 NvmeIdentifyNamespace (
801 IN NVME_CONTROLLER_PRIVATE_DATA
*Private
,
802 IN UINT32 NamespaceId
,