1 // NVMe datastructures and constants
2 //
3 // Copyright 2017 Amazon.com, Inc. or its affiliates.
4 //
5 // This file may be distributed under the terms of the GNU LGPLv3 license.
6 
7 #ifndef __NVME_INT_H
8 #define __NVME_INT_H
9 
10 #include "types.h" // u32
11 #include "pcidevice.h" // struct pci_device
12 
13 /* Data structures */
14 
15 /* The register file of a NVMe host controller. This struct follows the naming
16    scheme in the NVMe specification. */
17 struct nvme_reg {
18     u64 cap;                    /* controller capabilities */
19     u32 vs;                     /* version */
20     u32 intms;                  /* interrupt mask set */
21     u32 intmc;                  /* interrupt mask clear */
22     u32 cc;                     /* controller configuration */
23     u32 _res0;
24     u32 csts;                   /* controller status */
25     u32 _res1;
26     u32 aqa;                    /* admin queue attributes */
27     u64 asq;                    /* admin submission queue base address */
28     u64 acq;                    /* admin completion queue base address */
29 };
30 
31 /* Submission queue entry */
32 struct nvme_sqe {
33     union {
34         u32 dword[16];
35         struct {
36             u32 cdw0;           /* Command DWORD 0 */
37             u32 nsid;           /* Namespace ID */
38             u64 _res0;
39             u64 mptr;           /* metadata ptr */
40 
41             u64 dptr_prp1;
42             u64 dptr_prp2;
43         };
44     };
45 };
46 
47 /* Completion queue entry */
48 struct nvme_cqe {
49     union {
50         u32 dword[4];
51         struct {
52             u32 cdw0;
53             u32 _res0;
54             u16 sq_head;
55             u16 sq_id;
56             u16 cid;
57             u16 status;
58         };
59     };
60 };
61 
62 /* The common part of every submission or completion queue. */
63 struct nvme_queue {
64     u32 *dbl;                   /* doorbell */
65     u16 mask;                   /* length - 1 */
66 };
67 
68 struct nvme_cq {
69     struct nvme_queue common;
70     struct nvme_cqe *cqe;
71 
72     /* We have read upto (but not including) this entry in the queue. */
73     u16 head;
74 
75     /* The current phase bit the controller uses to indicate that it has written
76        a new entry. This is inverted after each wrap. */
77     unsigned phase : 1;
78 };
79 
80 struct nvme_sq {
81     struct nvme_queue common;
82     struct nvme_sqe *sqe;
83 
84     /* Corresponding completion queue. We only support a single SQ per CQ. */
85     struct nvme_cq *cq;
86 
87     /* The last entry the controller has fetched. */
88     u16 head;
89 
90     /* The last value we have written to the tail doorbell. */
91     u16 tail;
92 };
93 
94 struct nvme_ctrl {
95     struct pci_device *pci;
96     struct nvme_reg volatile *reg;
97 
98     u32 doorbell_stride;        /* in bytes */
99 
100     struct nvme_sq admin_sq;
101     struct nvme_cq admin_cq;
102 
103     u32 ns_count;
104     struct nvme_namespace *ns;
105 
106     struct nvme_sq io_sq;
107     struct nvme_cq io_cq;
108 };
109 
110 struct nvme_namespace {
111     struct drive_s drive;
112     struct nvme_ctrl *ctrl;
113 
114     u32 ns_id;
115 
116     u64 lba_count;              /* The total amount of sectors. */
117 
118     u32 block_size;
119     u32 metadata_size;
120 
121     /* Page aligned buffer of size NVME_PAGE_SIZE. */
122     char *dma_buffer;
123 };
124 
125 /* Data structures for NVMe admin identify commands */
126 
127 struct nvme_identify_ctrl {
128     u16 vid;
129     u16 ssvid;
130     char sn[20];
131     char mn[40];
132     char fr[8];
133 
134     char _boring[516 - 72];
135 
136     u32 nn;                     /* number of namespaces */
137 };
138 
139 struct nvme_identify_ns_list {
140     u32 ns_id[1024];
141 };
142 
143 struct nvme_lba_format {
144     u16 ms;
145     u8  lbads;
146     u8  rp;
147     u8  res;
148 };
149 
150 struct nvme_identify_ns {
151     u64 nsze;
152     u64 ncap;
153     u64 nuse;
154     u8  nsfeat;
155     u8  nlbaf;
156     u8  flbas;
157 
158     char _boring[128 - 27];
159 
160     struct nvme_lba_format lbaf[16];
161 };
162 
163 union nvme_identify {
164     struct nvme_identify_ns      ns;
165     struct nvme_identify_ctrl    ctrl;
166     struct nvme_identify_ns_list ns_list;
167 };
168 
169 /* NVMe constants */
170 
171 #define NVME_CAP_CSS_NVME (1ULL << 37)
172 
173 #define NVME_CSTS_FATAL   (1U <<  1)
174 #define NVME_CSTS_RDY     (1U <<  0)
175 
176 #define NVME_CC_EN        (1U <<  0)
177 
178 #define NVME_SQE_OPC_ADMIN_CREATE_IO_SQ 1U
179 #define NVME_SQE_OPC_ADMIN_CREATE_IO_CQ 5U
180 #define NVME_SQE_OPC_ADMIN_IDENTIFY     6U
181 
182 #define NVME_SQE_OPC_IO_WRITE 1U
183 #define NVME_SQE_OPC_IO_READ  2U
184 
185 #define NVME_ADMIN_IDENTIFY_CNS_ID_NS       0U
186 #define NVME_ADMIN_IDENTIFY_CNS_ID_CTRL     1U
187 #define NVME_ADMIN_IDENTIFY_CNS_GET_NS_LIST 2U
188 
189 #define NVME_CQE_DW3_P (1U << 16)
190 
191 #define NVME_PAGE_SIZE 4096
192 
193 /* Length for the queue entries. */
194 #define NVME_SQE_SIZE_LOG 6
195 #define NVME_CQE_SIZE_LOG 4
196 
197 #endif
198 
199 /* EOF */
200