Home | History | Annotate | Download | only in NvmExpressDxe
      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