1 /** @file
2   Definitions based on NVMe spec. version 1.1.
3 
4   (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
5   Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
6   SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8   @par Specification Reference:
9   NVMe Specification 1.1
10 
11 **/
12 
13 #ifndef __NVM_E_H__
14 #define __NVM_E_H__
15 
16 #pragma pack(1)
17 
18 //
19 // controller register offsets
20 //
21 #define NVME_CAP_OFFSET          0x0000  // Controller Capabilities
22 #define NVME_VER_OFFSET          0x0008  // Version
23 #define NVME_INTMS_OFFSET        0x000c  // Interrupt Mask Set
24 #define NVME_INTMC_OFFSET        0x0010  // Interrupt Mask Clear
25 #define NVME_CC_OFFSET           0x0014  // Controller Configuration
26 #define NVME_CSTS_OFFSET         0x001c  // Controller Status
27 #define NVME_NSSR_OFFSET         0x0020  // NVM Subsystem Reset
28 #define NVME_AQA_OFFSET          0x0024  // Admin Queue Attributes
29 #define NVME_ASQ_OFFSET          0x0028  // Admin Submission Queue Base Address
30 #define NVME_ACQ_OFFSET          0x0030  // Admin Completion Queue Base Address
31 #define NVME_SQ0_OFFSET          0x1000  // Submission Queue 0 (admin) Tail Doorbell
32 #define NVME_CQ0_OFFSET          0x1004  // Completion Queue 0 (admin) Head Doorbell
33 
34 //
35 // These register offsets are defined as 0x1000 + (N * (4 << CAP.DSTRD))
36 // Get the doorbell stride bit shift value from the controller capabilities.
37 //
38 #define NVME_SQTDBL_OFFSET(QID, DSTRD)    0x1000 + ((2 * (QID)) * (4 << (DSTRD)))       // Submission Queue y (NVM) Tail Doorbell
39 #define NVME_CQHDBL_OFFSET(QID, DSTRD)    0x1000 + (((2 * (QID)) + 1) * (4 << (DSTRD))) // Completion Queue y (NVM) Head Doorbell
40 
41 
42 #pragma pack(1)
43 
44 //
45 // 3.1.1 Offset 00h: CAP - Controller Capabilities
46 //
47 typedef struct {
48   UINT16 Mqes;      // Maximum Queue Entries Supported
49   UINT8  Cqr:1;     // Contiguous Queues Required
50   UINT8  Ams:2;     // Arbitration Mechanism Supported
51   UINT8  Rsvd1:5;
52   UINT8  To;        // Timeout
53   UINT16 Dstrd:4;
54   UINT16 Nssrs:1;   // NVM Subsystem Reset Supported NSSRS
55   UINT16 Css:4;     // Command Sets Supported - Bit 37
56   UINT16 Rsvd3:7;
57   UINT8  Mpsmin:4;
58   UINT8  Mpsmax:4;
59   UINT8  Rsvd4;
60 } NVME_CAP;
61 
62 //
63 // 3.1.2 Offset 08h: VS - Version
64 //
65 typedef struct {
66   UINT16 Mnr;       // Minor version number
67   UINT16 Mjr;       // Major version number
68 } NVME_VER;
69 
70 //
71 // 3.1.5 Offset 14h: CC - Controller Configuration
72 //
73 typedef struct {
74   UINT16 En:1;       // Enable
75   UINT16 Rsvd1:3;
76   UINT16 Css:3;      // I/O Command Set Selected
77   UINT16 Mps:4;      // Memory Page Size
78   UINT16 Ams:3;      // Arbitration Mechanism Selected
79   UINT16 Shn:2;      // Shutdown Notification
80   UINT8  Iosqes:4;   // I/O Submission Queue Entry Size
81   UINT8  Iocqes:4;   // I/O Completion Queue Entry Size
82   UINT8  Rsvd2;
83 } NVME_CC;
84 #define NVME_CC_SHN_NORMAL_SHUTDOWN    1
85 #define NVME_CC_SHN_ABRUPT_SHUTDOWN    2
86 
87 //
88 // 3.1.6 Offset 1Ch: CSTS - Controller Status
89 //
90 typedef struct {
91   UINT32 Rdy:1;      // Ready
92   UINT32 Cfs:1;      // Controller Fatal Status
93   UINT32 Shst:2;     // Shutdown Status
94   UINT32 Nssro:1;    // NVM Subsystem Reset Occurred
95   UINT32 Rsvd1:27;
96 } NVME_CSTS;
97 #define NVME_CSTS_SHST_SHUTDOWN_OCCURRING 1
98 #define NVME_CSTS_SHST_SHUTDOWN_COMPLETED 2
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 typedef enum {
747   DeleteIOSubmissionQueueOpcode = NVME_ADMIN_DEIOSQ_CMD,
748   CreateIOSubmissionQueueOpcode = NVME_ADMIN_CRIOSQ_CMD,
749   GetLogPageOpcode = NVME_ADMIN_GET_LOG_PAGE_CMD,
750   DeleteIOCompletionQueueOpcode = NVME_ADMIN_DEIOCQ_CMD,
751   CreateIOCompletionQueueOpcode = NVME_ADMIN_CRIOCQ_CMD,
752   IdentifyOpcode = NVME_ADMIN_IDENTIFY_CMD,
753   AbortOpcode = NVME_ADMIN_ABORT_CMD,
754   SetFeaturesOpcode = NVME_ADMIN_SET_FEATURES_CMD,
755   GetFeaturesOpcode = NVME_ADMIN_GET_FEATURES_CMD,
756   AsyncEventRequestOpcode = NVME_ADMIN_ASYNC_EVENT_REQUEST_CMD,
757   NamespaceManagementOpcode = NVME_ADMIN_NAMESACE_MANAGEMENT_CMD,
758   FirmwareCommitOpcode = NVME_ADMIN_FW_COMMIT_CMD,
759   FirmwareImageDownloadOpcode = NVME_ADMIN_FW_IAMGE_DOWNLOAD_CMD,
760   NamespaceAttachmentOpcode = NVME_ADMIN_NAMESACE_ATTACHMENT_CMD,
761   FormatNvmOpcode = NVME_ADMIN_FORMAT_NVM_CMD,
762   SecuritySendOpcode = NVME_ADMIN_SECURITY_SEND_CMD,
763   SecurityReceiveOpcode = NVME_ADMIN_SECURITY_RECEIVE_CMD
764 } NVME_ADMIN_COMMAND_OPCODE;
765 
766 //
767 // Controller or Namespace Structure (CNS) field
768 // (ref. spec. v1.1 figure 82).
769 //
770 typedef enum {
771 IdentifyNamespaceCns = 0x0,
772 IdentifyControllerCns = 0x1,
773 IdentifyActiveNsListCns = 0x2
774 } NVME_ADMIN_IDENTIFY_CNS;
775 
776 //
777 // Commit Action
778 // (ref. spec. 1.1 figure 60).
779 //
780 typedef enum {
781   ActivateActionReplace = 0x0,
782   ActivateActionReplaceActivate = 0x1,
783   ActivateActionActivate = 0x2
784 } NVME_FW_ACTIVATE_ACTION;
785 
786 //
787 // Firmware Slot
788 // (ref. spec. 1.1 Figure 60).
789 //
790 typedef enum {
791   FirmwareSlotCtrlChooses = 0x0,
792   FirmwareSlot1 = 0x1,
793   FirmwareSlot2 = 0x2,
794   FirmwareSlot3 = 0x3,
795   FirmwareSlot4 = 0x4,
796   FirmwareSlot5 = 0x5,
797   FirmwareSlot6 = 0x6,
798   FirmwareSlot7 = 0x7
799 } NVME_FW_ACTIVATE_SLOT;
800 
801 //
802 // Get Log Page ? Log Page Identifiers
803 // (ref. spec. v1.1 Figure 73).
804 //
805 typedef enum {
806   ErrorInfoLogID = LID_ERROR_INFO,
807   SmartHealthInfoLogID = LID_SMART_INFO,
808   FirmwareSlotInfoLogID = LID_FW_SLOT_INFO
809 } NVME_LOG_ID;
810 
811 //
812 // Get Log Page ? Firmware Slot Information Log
813 // (ref. spec. v1.1 Figure 77).
814 //
815 typedef struct {
816   //
817   // Indicates the firmware slot from which the actively running firmware revision was loaded.
818   //
819   UINT8 ActivelyRunningFwSlot:3;
820   UINT8 :1;
821   //
822   // Indicates the firmware slot that is going to be activated at the next controller reset. If this field is 0h, then the controller does not indicate the firmware slot that is going to be activated at the next controller reset.
823   //
824   UINT8 NextActiveFwSlot:3;
825   UINT8 :1;
826 } NVME_ACTIVE_FW_INFO;
827 
828 //
829 // Get Log Page ? Firmware Slot Information Log
830 // (ref. spec. v1.1 Figure 77).
831 //
832 typedef struct {
833   //
834   // Specifies information about the active firmware revision.
835   //s
836   NVME_ACTIVE_FW_INFO  ActiveFwInfo;
837   UINT8                Reserved1[7];
838   //
839   // Contains the revision of the firmware downloaded to firmware slot 1/7. If no valid firmware revision is present or if this slot is unsupported, all zeros shall be returned.
840   //
841   CHAR8                FwRevisionSlot[7][8];
842   UINT8                Reserved2[448];
843 } NVME_FW_SLOT_INFO_LOG;
844 
845 //
846 // SMART / Health Information (Log Identifier 02h)
847 // (ref. spec. v1.1 5.10.1.2)
848 //
849 typedef struct {
850   //
851   // This field indicates critical warnings for the state of the controller.
852   //
853   UINT8  CriticalWarningAvailableSpare:1;
854   UINT8  CriticalWarningTemperature:1;
855   UINT8  CriticalWarningReliability:1;
856   UINT8  CriticalWarningMediaReadOnly:1;
857   UINT8  CriticalWarningVolatileBackup:1;
858   UINT8  CriticalWarningReserved:3;
859   //
860   // Contains a value corresponding to a temperature in degrees Kelvin that represents the current composite temperature of the controller and namespace(s) associated with that controller. The manner in which this value is computed is implementation specific and may not represent the actual temperature of any physical point in the NVM subsystem.
861   //
862   UINT16 CompositeTemp;
863   //
864   // Contains a normalized percentage (0 to 100%) of the remaining spare capacity available.
865   //
866   UINT8  AvailableSpare;
867   //
868   // When the Available Spare falls below the threshold indicated in this field, an asynchronous event completion may occur. The value is indicated as a normalized percentage (0 to 100%).
869   //
870   UINT8  AvailableSpareThreshold;
871   //
872   // Contains a vendor specific estimate of the percentage of NVM subsystem life used based on the actual usage and the manufacturer?s prediction of NVM life. A value of 100 indicates that the estimated endurance of the NVM in the NVM subsystem has been consumed, but may not indicate an NVM subsystem failure. The value is allowed to exceed 100. Percentages greater than 254 shall be represented as 255. This value shall be updated once per power-on hour (when the controller is not in a sleep state).
873   //
874   UINT8  PercentageUsed;
875   UINT8  Reserved1[26];
876   //
877   // Contains the number of 512 byte data units the host has read from the controller; this value does not include metadata.
878   //
879   UINT8  DataUnitsRead[16];
880   //
881   // Contains the number of 512 byte data units the host has written to the controller; this value does not include metadata.
882   //
883   UINT8  DataUnitsWritten[16];
884   //
885   // Contains the number of read commands completed by the controller.
886   //
887   UINT8  HostReadCommands[16];
888   //
889   // Contains the number of write commands completed by the controller.
890   //
891   UINT8  HostWriteCommands[16];
892   //
893   // Contains the amount of time the controller is busy with I/O commands. This value is reported in minutes.
894   //
895   UINT8  ControllerBusyTime[16];
896   //
897   // Contains the number of power cycles.
898   //
899   UINT8  PowerCycles[16];
900   //
901   // Contains the number of power-on hours.
902   //
903   UINT8  PowerOnHours[16];
904   //
905   // Contains the number of unsafe shutdowns.
906   //
907   UINT8  UnsafeShutdowns[16];
908   //
909   // Contains the number of occurrences where the controller detected an unrecovered data integrity error.
910   //
911   UINT8  MediaAndDataIntegrityErrors[16];
912   //
913   // Contains the number of Error Information log entries over the life of the controller.
914   //
915   UINT8  NumberErrorInformationLogEntries[16];
916   //
917   // Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than or equal to the Warning Composite Temperature Threshold (WCTEMP) field and less than the Critical Composite Temperature Threshold (CCTEMP) field in the Identify Controller data structure in Figure 90.
918   //
919   UINT32 WarningCompositeTemperatureTime;
920   //
921   // Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater the Critical Composite Temperature Threshold (CCTEMP) field in the Identify Controller data structure in Figure 90.
922   //
923   UINT32 CriticalCompositeTemperatureTime;
924   //
925   // Contains the current temperature in degrees Kelvin reported by the temperature sensor.  An implementation that does not implement the temperature sensor reports a temperature of zero degrees Kelvin.
926   //
927   UINT16 TemperatureSensor[8];
928   UINT8  Reserved2[296];
929 } NVME_SMART_HEALTH_INFO_LOG;
930 
931 #pragma pack()
932 
933 #endif
934