1 /** @file
2   NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows
3   NVM Express specification.
4 
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.
10 
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.
13 
14 **/
15 
16 #ifndef _NVME_HCI_H_
17 #define _NVME_HCI_H_
18 
19 #define NVME_BAR                 0
20 
21 //
22 // controller register offsets
23 //
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
36 
37 //
38 // These register offsets are defined as 0x1000 + (N * (4 << CAP.DSTRD))
39 // Get the doorbell stride bit shift value from the controller capabilities.
40 //
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
43 
44 
45 #pragma pack(1)
46 
47 //
48 // 3.1.1 Offset 00h: CAP - Controller Capabilities
49 //
50 typedef struct {
51   UINT16 Mqes;      // Maximum Queue Entries Supported
52   UINT8  Cqr:1;     // Contiguous Queues Required
53   UINT8  Ams:2;     // Arbitration Mechanism Supported
54   UINT8  Rsvd1:5;
55   UINT8  To;        // Timeout
56   UINT16 Dstrd:4;
57   UINT16 Nssrs:1;   // NVM Subsystem Reset Supported NSSRS
58   UINT16 Css:4;     // Command Sets Supported - Bit 37
59   UINT16 Rsvd3:7;
60   UINT8  Mpsmin:4;
61   UINT8  Mpsmax:4;
62   UINT8  Rsvd4;
63 } NVME_CAP;
64 
65 //
66 // 3.1.2 Offset 08h: VS - Version
67 //
68 typedef struct {
69   UINT16 Mnr;       // Minor version number
70   UINT16 Mjr;       // Major version number
71 } NVME_VER;
72 
73 //
74 // 3.1.5 Offset 14h: CC - Controller Configuration
75 //
76 typedef struct {
77   UINT16 En:1;       // Enable
78   UINT16 Rsvd1:3;
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
85   UINT8  Rsvd2;
86 } NVME_CC;
87 
88 //
89 // 3.1.6 Offset 1Ch: CSTS - Controller Status
90 //
91 typedef struct {
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
96   UINT32 Rsvd1:27;
97 } NVME_CSTS;
98 
99 //
100 // 3.1.8 Offset 24h: AQA - Admin Queue Attributes
101 //
102 typedef struct {
103   UINT16 Asqs:12;    // Submission Queue Size
104   UINT16 Rsvd1:4;
105   UINT16 Acqs:12;    // Completion Queue Size
106   UINT16 Rsvd2:4;
107 } NVME_AQA;
108 
109 //
110 // 3.1.9 Offset 28h: ASQ - Admin Submission Queue Base Address
111 //
112 #define NVME_ASQ      UINT64
113 //
114 // 3.1.10 Offset 30h: ACQ - Admin Completion Queue Base Address
115 //
116 #define NVME_ACQ      UINT64
117 
118 //
119 // 3.1.11 Offset (1000h + ((2y) * (4 << CAP.DSTRD))): SQyTDBL - Submission Queue y Tail Doorbell
120 //
121 typedef struct {
122   UINT16 Sqt;
123   UINT16 Rsvd1;
124 } NVME_SQTDBL;
125 
126 //
127 // 3.1.12 Offset (1000h + ((2y + 1) * (4 << CAP.DSTRD))): CQyHDBL - Completion Queue y Head Doorbell
128 //
129 typedef struct {
130   UINT16 Cqh;
131   UINT16 Rsvd1;
132 } NVME_CQHDBL;
133 
134 //
135 // NVM command set structures
136 //
137 // Read Command
138 //
139 typedef struct {
140   //
141   // CDW 10, 11
142   //
143   UINT64 Slba;                /* Starting Sector Address */
144   //
145   // CDW 12
146   //
147   UINT16 Nlb;                 /* Number of Sectors */
148   UINT16 Rsvd1:10;
149   UINT16 Prinfo:4;            /* Protection Info Check */
150   UINT16 Fua:1;               /* Force Unit Access */
151   UINT16 Lr:1;                /* Limited Retry */
152   //
153   // CDW 13
154   //
155   UINT32 Af:4;                /* Access Frequency */
156   UINT32 Al:2;                /* Access Latency */
157   UINT32 Sr:1;                /* Sequential Request */
158   UINT32 In:1;                /* Incompressible */
159   UINT32 Rsvd2:24;
160   //
161   // CDW 14
162   //
163   UINT32 Eilbrt;              /* Expected Initial Logical Block Reference Tag */
164   //
165   // CDW 15
166   //
167   UINT16 Elbat;               /* Expected Logical Block Application Tag */
168   UINT16 Elbatm;              /* Expected Logical Block Application Tag Mask */
169 } NVME_READ;
170 
171 //
172 // Write Command
173 //
174 typedef struct {
175   //
176   // CDW 10, 11
177   //
178   UINT64 Slba;                /* Starting Sector Address */
179   //
180   // CDW 12
181   //
182   UINT16 Nlb;                 /* Number of Sectors */
183   UINT16 Rsvd1:10;
184   UINT16 Prinfo:4;            /* Protection Info Check */
185   UINT16 Fua:1;               /* Force Unit Access */
186   UINT16 Lr:1;                /* Limited Retry */
187   //
188   // CDW 13
189   //
190   UINT32 Af:4;                /* Access Frequency */
191   UINT32 Al:2;                /* Access Latency */
192   UINT32 Sr:1;                /* Sequential Request */
193   UINT32 In:1;                /* Incompressible */
194   UINT32 Rsvd2:24;
195   //
196   // CDW 14
197   //
198   UINT32 Ilbrt;               /* Initial Logical Block Reference Tag */
199   //
200   // CDW 15
201   //
202   UINT16 Lbat;                /* Logical Block Application Tag */
203   UINT16 Lbatm;               /* Logical Block Application Tag Mask */
204 } NVME_WRITE;
205 
206 //
207 // Flush
208 //
209 typedef struct {
210   //
211   // CDW 10
212   //
213   UINT32 Flush;               /* Flush */
214 } NVME_FLUSH;
215 
216 //
217 // Write Uncorrectable command
218 //
219 typedef struct {
220   //
221   // CDW 10, 11
222   //
223   UINT64 Slba;                /* Starting LBA */
224   //
225   // CDW 12
226   //
227   UINT32 Nlb:16;              /* Number of  Logical Blocks */
228   UINT32 Rsvd1:16;
229 } NVME_WRITE_UNCORRECTABLE;
230 
231 //
232 // Write Zeroes command
233 //
234 typedef struct {
235   //
236   // CDW 10, 11
237   //
238   UINT64 Slba;                /* Starting LBA */
239   //
240   // CDW 12
241   //
242   UINT16 Nlb;                 /* Number of Logical Blocks */
243   UINT16 Rsvd1:10;
244   UINT16 Prinfo:4;            /* Protection Info Check */
245   UINT16 Fua:1;               /* Force Unit Access */
246   UINT16 Lr:1;                /* Limited Retry */
247   //
248   // CDW 13
249   //
250   UINT32 Rsvd2;
251   //
252   // CDW 14
253   //
254   UINT32 Ilbrt;               /* Initial Logical Block Reference Tag */
255   //
256   // CDW 15
257   //
258   UINT16 Lbat;                /* Logical Block Application Tag */
259   UINT16 Lbatm;               /* Logical Block Application Tag Mask */
260 } NVME_WRITE_ZEROES;
261 
262 //
263 // Compare command
264 //
265 typedef struct {
266   //
267   // CDW 10, 11
268   //
269   UINT64 Slba;                /* Starting LBA */
270   //
271   // CDW 12
272   //
273   UINT16 Nlb;                 /* Number of Logical Blocks */
274   UINT16 Rsvd1:10;
275   UINT16 Prinfo:4;            /* Protection Info Check */
276   UINT16 Fua:1;               /* Force Unit Access */
277   UINT16 Lr:1;                /* Limited Retry */
278   //
279   // CDW 13
280   //
281   UINT32 Rsvd2;
282   //
283   // CDW 14
284   //
285   UINT32 Eilbrt;              /* Expected Initial Logical Block Reference Tag */
286   //
287   // CDW 15
288   //
289   UINT16 Elbat;               /* Expected Logical Block Application Tag */
290   UINT16 Elbatm;              /* Expected Logical Block Application Tag Mask */
291 } NVME_COMPARE;
292 
293 typedef union {
294   NVME_READ                   Read;
295   NVME_WRITE                  Write;
296   NVME_FLUSH                  Flush;
297   NVME_WRITE_UNCORRECTABLE    WriteUncorrectable;
298   NVME_WRITE_ZEROES           WriteZeros;
299   NVME_COMPARE                Compare;
300 } NVME_CMD;
301 
302 typedef struct {
303   UINT16 Mp;                /* Maximum Power */
304   UINT8  Rsvd1;             /* Reserved as of Nvm Express 1.1 Spec */
305   UINT8  Mps:1;             /* Max Power Scale */
306   UINT8  Nops:1;            /* Non-Operational State */
307   UINT8  Rsvd2:6;           /* Reserved as of Nvm Express 1.1 Spec */
308   UINT32 Enlat;             /* Entry Latency */
309   UINT32 Exlat;             /* Exit Latency */
310   UINT8  Rrt:5;             /* Relative Read Throughput */
311   UINT8  Rsvd3:3;           /* Reserved as of Nvm Express 1.1 Spec */
312   UINT8  Rrl:5;             /* Relative Read Leatency */
313   UINT8  Rsvd4:3;           /* Reserved as of Nvm Express 1.1 Spec */
314   UINT8  Rwt:5;             /* Relative Write Throughput */
315   UINT8  Rsvd5:3;           /* Reserved as of Nvm Express 1.1 Spec */
316   UINT8  Rwl:5;             /* Relative Write Leatency */
317   UINT8  Rsvd6:3;           /* Reserved as of Nvm Express 1.1 Spec */
318   UINT8  Rsvd7[16];         /* Reserved as of Nvm Express 1.1 Spec */
319 } NVME_PSDESCRIPTOR;
320 
321 //
322 //  Identify Controller Data
323 //
324 typedef struct {
325   //
326   // Controller Capabilities and Features 0-255
327   //
328   UINT16 Vid;                 /* PCI Vendor ID */
329   UINT16 Ssvid;               /* PCI sub-system vendor ID */
330   UINT8  Sn[20];              /* Product serial number */
331 
332   UINT8  Mn[40];              /* Proeduct model number */
333   UINT8  Fr[8];               /* Firmware Revision */
334   UINT8  Rab;                 /* Recommended Arbitration Burst */
335   UINT8  Ieee_oui[3];         /* Organization Unique Identifier */
336   UINT8  Cmic;                /* Multi-interface Capabilities */
337   UINT8  Mdts;                /* Maximum Data Transfer Size */
338   UINT8  Cntlid[2];           /* Controller ID */
339   UINT8  Rsvd1[176];          /* Reserved as of Nvm Express 1.1 Spec */
340   //
341   // Admin Command Set Attributes
342   //
343   UINT16 Oacs;                /* Optional Admin Command Support */
344     #define NAMESPACE_MANAGEMENT_SUPPORTED  BIT3
345     #define FW_DOWNLOAD_ACTIVATE_SUPPORTED  BIT2
346     #define FORMAT_NVM_SUPPORTED            BIT1
347     #define SECURITY_SEND_RECEIVE_SUPPORTED BIT0
348   UINT8  Acl;                 /* Abort Command Limit */
349   UINT8  Aerl;                /* Async Event Request Limit */
350   UINT8  Frmw;                /* Firmware updates */
351   UINT8  Lpa;                 /* Log Page Attributes */
352   UINT8  Elpe;                /* Error Log Page Entries */
353   UINT8  Npss;                /* Number of Power States Support */
354   UINT8  Avscc;               /* Admin Vendor Specific Command Configuration */
355   UINT8  Apsta;               /* Autonomous Power State Transition Attributes */
356   UINT8  Rsvd2[246];          /* Reserved as of Nvm Express 1.1 Spec */
357   //
358   // NVM Command Set Attributes
359   //
360   UINT8  Sqes;                /* Submission Queue Entry Size */
361   UINT8  Cqes;                /* Completion Queue Entry Size */
362   UINT16 Rsvd3;               /* Reserved as of Nvm Express 1.1 Spec */
363   UINT32 Nn;                  /* Number of Namespaces */
364   UINT16 Oncs;                /* Optional NVM Command Support */
365   UINT16 Fuses;               /* Fused Operation Support */
366   UINT8  Fna;                 /* Format NVM Attributes */
367   UINT8  Vwc;                 /* Volatile Write Cache */
368   UINT16 Awun;                /* Atomic Write Unit Normal */
369   UINT16 Awupf;               /* Atomic Write Unit Power Fail */
370   UINT8  Nvscc;               /* NVM Vendor Specific Command Configuration */
371   UINT8  Rsvd4;               /* Reserved as of Nvm Express 1.1 Spec */
372   UINT16 Acwu;                /* Atomic Compare & Write Unit */
373   UINT16 Rsvd5;               /* Reserved as of Nvm Express 1.1 Spec */
374   UINT32 Sgls;                /* SGL Support  */
375   UINT8  Rsvd6[164];          /* Reserved as of Nvm Express 1.1 Spec */
376   //
377   // I/O Command set Attributes
378   //
379   UINT8 Rsvd7[1344];          /* Reserved as of Nvm Express 1.1 Spec */
380   //
381   // Power State Descriptors
382   //
383   NVME_PSDESCRIPTOR PsDescriptor[32];
384 
385   UINT8  VendorData[1024];    /* Vendor specific data */
386 } NVME_ADMIN_CONTROLLER_DATA;
387 
388 typedef struct {
389   UINT16 Ms;                /* Metadata Size */
390   UINT8  Lbads;             /* LBA Data Size */
391   UINT8  Rp:2;              /* Relative Performance */
392     #define LBAF_RP_BEST      00b
393     #define LBAF_RP_BETTER    01b
394     #define LBAF_RP_GOOD      10b
395     #define LBAF_RP_DEGRADED  11b
396   UINT8  Rsvd1:6;           /* Reserved as of Nvm Express 1.1 Spec */
397 } NVME_LBAFORMAT;
398 
399 //
400 // Identify Namespace Data
401 //
402 typedef struct {
403   //
404   // NVM Command Set Specific
405   //
406   UINT64 Nsze;                /* Namespace Size (total number of blocks in formatted namespace) */
407   UINT64 Ncap;                /* Namespace Capacity (max number of logical blocks) */
408   UINT64 Nuse;                /* Namespace Utilization */
409   UINT8  Nsfeat;              /* Namespace Features */
410   UINT8  Nlbaf;               /* Number of LBA Formats */
411   UINT8  Flbas;               /* Formatted LBA size */
412   UINT8  Mc;                  /* Metadata Capabilities */
413   UINT8  Dpc;                 /* End-to-end Data Protection capabilities */
414   UINT8  Dps;                 /* End-to-end Data Protection Type Settings */
415   UINT8  Nmic;                /* Namespace Multi-path I/O and Namespace Sharing Capabilities */
416   UINT8  Rescap;              /* Reservation Capabilities */
417   UINT8  Rsvd1[88];           /* Reserved as of Nvm Express 1.1 Spec */
418   UINT64 Eui64;               /* IEEE Extended Unique Identifier */
419   //
420   // LBA Format
421   //
422   NVME_LBAFORMAT LbaFormat[16];
423 
424   UINT8 Rsvd2[192];           /* Reserved as of Nvm Express 1.1 Spec */
425   UINT8 VendorData[3712];     /* Vendor specific data */
426 } NVME_ADMIN_NAMESPACE_DATA;
427 
428 //
429 // NvmExpress Admin Identify Cmd
430 //
431 typedef struct {
432   //
433   // CDW 10
434   //
435   UINT32 Cns:2;
436   UINT32 Rsvd1:30;
437 } NVME_ADMIN_IDENTIFY;
438 
439 //
440 // NvmExpress Admin Create I/O Completion Queue
441 //
442 typedef struct {
443   //
444   // CDW 10
445   //
446   UINT32 Qid:16;              /* Queue Identifier */
447   UINT32 Qsize:16;            /* Queue Size */
448 
449   //
450   // CDW 11
451   //
452   UINT32 Pc:1;                /* Physically Contiguous */
453   UINT32 Ien:1;               /* Interrupts Enabled */
454   UINT32 Rsvd1:14;            /* reserved as of Nvm Express 1.1 Spec */
455   UINT32 Iv:16;               /* Interrupt Vector for MSI-X or MSI*/
456 } NVME_ADMIN_CRIOCQ;
457 
458 //
459 // NvmExpress Admin Create I/O Submission Queue
460 //
461 typedef struct {
462   //
463   // CDW 10
464   //
465   UINT32 Qid:16;              /* Queue Identifier */
466   UINT32 Qsize:16;            /* Queue Size */
467 
468   //
469   // CDW 11
470   //
471   UINT32 Pc:1;                /* Physically Contiguous */
472   UINT32 Qprio:2;             /* Queue Priority */
473   UINT32 Rsvd1:13;            /* Reserved as of Nvm Express 1.1 Spec */
474   UINT32 Cqid:16;             /* Completion Queue ID */
475 } NVME_ADMIN_CRIOSQ;
476 
477 //
478 // NvmExpress Admin Delete I/O Completion Queue
479 //
480 typedef struct {
481   //
482   // CDW 10
483   //
484   UINT16 Qid;
485   UINT16 Rsvd1;
486 } NVME_ADMIN_DEIOCQ;
487 
488 //
489 // NvmExpress Admin Delete I/O Submission Queue
490 //
491 typedef struct {
492   //
493   // CDW 10
494   //
495   UINT16 Qid;
496   UINT16 Rsvd1;
497 } NVME_ADMIN_DEIOSQ;
498 
499 //
500 // NvmExpress Admin Abort Command
501 //
502 typedef struct {
503   //
504   // CDW 10
505   //
506   UINT32 Sqid:16;             /* Submission Queue identifier */
507   UINT32 Cid:16;              /* Command Identifier */
508 } NVME_ADMIN_ABORT;
509 
510 //
511 // NvmExpress Admin Firmware Activate Command
512 //
513 typedef struct {
514   //
515   // CDW 10
516   //
517   UINT32 Fs:3;                /* Submission Queue identifier */
518   UINT32 Aa:2;                /* Command Identifier */
519   UINT32 Rsvd1:27;
520 } NVME_ADMIN_FIRMWARE_ACTIVATE;
521 
522 //
523 // NvmExpress Admin Firmware Image Download Command
524 //
525 typedef struct {
526   //
527   // CDW 10
528   //
529   UINT32 Numd;                /* Number of Dwords */
530   //
531   // CDW 11
532   //
533   UINT32 Ofst;                /* Offset */
534 } NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD;
535 
536 //
537 // NvmExpress Admin Get Features Command
538 //
539 typedef struct {
540   //
541   // CDW 10
542   //
543   UINT32 Fid:8;                /* Feature Identifier */
544   UINT32 Sel:3;                /* Select */
545   UINT32 Rsvd1:21;
546 } NVME_ADMIN_GET_FEATURES;
547 
548 //
549 // NvmExpress Admin Get Log Page Command
550 //
551 typedef struct {
552   //
553   // CDW 10
554   //
555   UINT32 Lid:8;               /* Log Page Identifier */
556     #define LID_ERROR_INFO   0x1
557     #define LID_SMART_INFO   0x2
558     #define LID_FW_SLOT_INFO 0x3
559   UINT32 Rsvd1:8;
560   UINT32 Numd:12;             /* Number of Dwords */
561   UINT32 Rsvd2:4;             /* Reserved as of Nvm Express 1.1 Spec */
562 } NVME_ADMIN_GET_LOG_PAGE;
563 
564 //
565 // NvmExpress Admin Set Features Command
566 //
567 typedef struct {
568   //
569   // CDW 10
570   //
571   UINT32 Fid:8;               /* Feature Identifier */
572   UINT32 Rsvd1:23;
573   UINT32 Sv:1;                /* Save */
574 } NVME_ADMIN_SET_FEATURES;
575 
576 //
577 // NvmExpress Admin Format NVM Command
578 //
579 typedef struct {
580   //
581   // CDW 10
582   //
583   UINT32 Lbaf:4;              /* LBA Format */
584   UINT32 Ms:1;                /* Metadata Settings */
585   UINT32 Pi:3;                /* Protection Information */
586   UINT32 Pil:1;               /* Protection Information Location */
587   UINT32 Ses:3;               /* Secure Erase Settings */
588   UINT32 Rsvd1:20;
589 } NVME_ADMIN_FORMAT_NVM;
590 
591 //
592 // NvmExpress Admin Security Receive Command
593 //
594 typedef struct {
595   //
596   // CDW 10
597   //
598   UINT32 Rsvd1:8;
599   UINT32 Spsp:16;             /* SP Specific */
600   UINT32 Secp:8;              /* Security Protocol */
601   //
602   // CDW 11
603   //
604   UINT32 Al;                  /* Allocation Length */
605 } NVME_ADMIN_SECURITY_RECEIVE;
606 
607 //
608 // NvmExpress Admin Security Send Command
609 //
610 typedef struct {
611   //
612   // CDW 10
613   //
614   UINT32 Rsvd1:8;
615   UINT32 Spsp:16;             /* SP Specific */
616   UINT32 Secp:8;              /* Security Protocol */
617   //
618   // CDW 11
619   //
620   UINT32 Tl;                  /* Transfer Length */
621 } NVME_ADMIN_SECURITY_SEND;
622 
623 typedef union {
624   NVME_ADMIN_IDENTIFY                   Identify;
625   NVME_ADMIN_CRIOCQ                     CrIoCq;
626   NVME_ADMIN_CRIOSQ                     CrIoSq;
627   NVME_ADMIN_DEIOCQ                     DeIoCq;
628   NVME_ADMIN_DEIOSQ                     DeIoSq;
629   NVME_ADMIN_ABORT                      Abort;
630   NVME_ADMIN_FIRMWARE_ACTIVATE          Activate;
631   NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD    FirmwareImageDownload;
632   NVME_ADMIN_GET_FEATURES               GetFeatures;
633   NVME_ADMIN_GET_LOG_PAGE               GetLogPage;
634   NVME_ADMIN_SET_FEATURES               SetFeatures;
635   NVME_ADMIN_FORMAT_NVM                 FormatNvm;
636   NVME_ADMIN_SECURITY_RECEIVE           SecurityReceive;
637   NVME_ADMIN_SECURITY_SEND              SecuritySend;
638 } NVME_ADMIN_CMD;
639 
640 typedef struct {
641   UINT32 Cdw10;
642   UINT32 Cdw11;
643   UINT32 Cdw12;
644   UINT32 Cdw13;
645   UINT32 Cdw14;
646   UINT32 Cdw15;
647 } NVME_RAW;
648 
649 typedef union {
650   NVME_ADMIN_CMD Admin;   // Union of Admin commands
651   NVME_CMD       Nvm;     // Union of Nvm commands
652   NVME_RAW       Raw;
653 } NVME_PAYLOAD;
654 
655 //
656 // Submission Queue
657 //
658 typedef struct {
659   //
660   // CDW 0, Common to all comnmands
661   //
662   UINT8  Opc;               // Opcode
663   UINT8  Fuse:2;            // Fused Operation
664   UINT8  Rsvd1:5;
665   UINT8  Psdt:1;            // PRP or SGL for Data Transfer
666   UINT16 Cid;               // Command Identifier
667 
668   //
669   // CDW 1
670   //
671   UINT32 Nsid;              // Namespace Identifier
672 
673   //
674   // CDW 2,3
675   //
676   UINT64 Rsvd2;
677 
678   //
679   // CDW 4,5
680   //
681   UINT64 Mptr;              // Metadata Pointer
682 
683   //
684   // CDW 6-9
685   //
686   UINT64 Prp[2];            // First and second PRP entries
687 
688   NVME_PAYLOAD Payload;
689 
690 } NVME_SQ;
691 
692 //
693 // Completion Queue
694 //
695 typedef struct {
696   //
697   // CDW 0
698   //
699   UINT32 Dword0;
700   //
701   // CDW 1
702   //
703   UINT32 Rsvd1;
704   //
705   // CDW 2
706   //
707   UINT16 Sqhd;              // Submission Queue Head Pointer
708   UINT16 Sqid;              // Submission Queue Identifier
709   //
710   // CDW 3
711   //
712   UINT16 Cid;               // Command Identifier
713   UINT16 Pt:1;              // Phase Tag
714   UINT16 Sc:8;              // Status Code
715   UINT16 Sct:3;             // Status Code Type
716   UINT16 Rsvd2:2;
717   UINT16 Mo:1;              // More
718   UINT16 Dnr:1;             // Do Not Retry
719 } NVME_CQ;
720 
721 //
722 // Nvm Express Admin cmd opcodes
723 //
724 #define NVME_ADMIN_DEIOSQ_CMD                0x00
725 #define NVME_ADMIN_CRIOSQ_CMD                0x01
726 #define NVME_ADMIN_GET_LOG_PAGE_CMD          0x02
727 #define NVME_ADMIN_DEIOCQ_CMD                0x04
728 #define NVME_ADMIN_CRIOCQ_CMD                0x05
729 #define NVME_ADMIN_IDENTIFY_CMD              0x06
730 #define NVME_ADMIN_ABORT_CMD                 0x08
731 #define NVME_ADMIN_SET_FEATURES_CMD          0x09
732 #define NVME_ADMIN_GET_FEATURES_CMD          0x0A
733 #define NVME_ADMIN_ASYNC_EVENT_REQUEST_CMD   0x0C
734 #define NVME_ADMIN_NAMESACE_MANAGEMENT_CMD   0x0D
735 #define NVME_ADMIN_FW_COMMIT_CMD             0x10
736 #define NVME_ADMIN_FW_IAMGE_DOWNLOAD_CMD     0x11
737 #define NVME_ADMIN_NAMESACE_ATTACHMENT_CMD   0x15
738 #define NVME_ADMIN_FORMAT_NVM_CMD            0x80
739 #define NVME_ADMIN_SECURITY_SEND_CMD         0x81
740 #define NVME_ADMIN_SECURITY_RECEIVE_CMD      0x82
741 
742 #define NVME_IO_FLUSH_OPC                    0
743 #define NVME_IO_WRITE_OPC                    1
744 #define NVME_IO_READ_OPC                     2
745 
746 //
747 // Offset from the beginning of private data queue buffer
748 //
749 #define NVME_ASQ_BUF_OFFSET                  EFI_PAGE_SIZE
750 
751 /**
752   Initialize the Nvm Express controller.
753 
754   @param[in] Private                 The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.
755 
756   @retval EFI_SUCCESS                The NVM Express Controller is initialized successfully.
757   @retval Others                     A device error occurred while initializing the controller.
758 
759 **/
760 EFI_STATUS
761 NvmeControllerInit (
762   IN NVME_CONTROLLER_PRIVATE_DATA    *Private
763   );
764 
765 /**
766   Get identify controller data.
767 
768   @param  Private          The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.
769   @param  Buffer           The buffer used to store the identify controller data.
770 
771   @return EFI_SUCCESS      Successfully get the identify controller data.
772   @return EFI_DEVICE_ERROR Fail to get the identify controller data.
773 
774 **/
775 EFI_STATUS
776 NvmeIdentifyController (
777   IN NVME_CONTROLLER_PRIVATE_DATA       *Private,
778   IN VOID                               *Buffer
779   );
780 
781 /**
782   Get specified identify namespace data.
783 
784   @param  Private          The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.
785   @param  NamespaceId      The specified namespace identifier.
786   @param  Buffer           The buffer used to store the identify namespace data.
787 
788   @return EFI_SUCCESS      Successfully get the identify namespace data.
789   @return EFI_DEVICE_ERROR Fail to get the identify namespace data.
790 
791 **/
792 EFI_STATUS
793 NvmeIdentifyNamespace (
794   IN NVME_CONTROLLER_PRIVATE_DATA      *Private,
795   IN UINT32                            NamespaceId,
796   IN VOID                              *Buffer
797   );
798 
799 #pragma pack()
800 
801 #endif
802 
803