1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <assert.h>
8 #include <stdint.h>
9 
10 // Registers in PCIE BAR0 MMIO Space
11 #define NVME_REG_CAP              0x00 // Capabilities
12 #define NVME_REG_VS               0x08 // Version
13 #define NVME_REG_INTMS            0x0C // Interrupt Mask Set
14 #define NVME_REG_INTMC            0x10 // Interrupt Mask clear
15 #define NVME_REG_CC               0x14 // Controller Configuration
16 #define NVME_REG_CSTS             0x1C // Controller Status
17 #define NVME_REG_NSSR             0x20 // NVM Subsystem Reset (Optional)
18 #define NVME_REG_AQA              0x24 // Admin Queue Attributes
19 #define NVME_REG_ASQ              0x28 // Admin Submission Queue Base Addr
20 #define NVME_REG_ACQ              0x30 // Admin Completion Queue Base Addr
21 #define NVME_REG_CMBLOC           0x38 // Controller Memory Block Location (Optional)
22 #define NVME_REG_CMBSZ            0x3C // Controller Memory Block Size (Optional)
23 
24 // Submission/Completion Queue Tail/Head are computed based on capabilities
25 #define NVME_REG_SQnTDBL(n, cap)  (0x1000 + (2*(n) + 0) * (4 << (NVME_CAP_DSTRD(cap) - 2)))
26 #define NVME_REG_CQnHDBL(n, cap)  (0x1000 + (2*(n) + 1) * (4 << (NVME_CAP_DSTRD(cap) - 2)))
27 
28 #define NVME_CAP_MPSMAX(n)        ((((n) >> 52) & 0xF) + 12)   // 2^x bytes
29 #define NVME_CAP_MPSMIN(n)        ((((n) >> 48) & 0xF) + 12)   // 2^x bytes
30 #define NVME_CAP_BPS(n)           (((n) >> 45) & 1)
31 #define NVME_CAP_CSS_NVM(n)       (((n) >> 37) & 1)
32 #define NVME_CAP_NSSRS(n)         (((n) >> 36) & 1)
33 #define NVME_CAP_DSTRD(n)         ((((n) >> 32) & 0xF) + 2)    // 2^x bytes
34 #define NVME_CAP_TO(n)            ((((n) >> 24) & 0xFF) * 500)   // milliseconds
35 #define NVME_CAP_AMS_WRR(n)       (((n) >> 17) & 1)
36 #define NVME_CAP_AMS_VS(n)        (((n) >> 18) & 1)
37 #define NVME_CAP_CQR(n)           (((n) >> 16) & 1)
38 #define NVME_CAP_MQES(n)          ((n) & 0xFFFF)
39 
40 #define NVME_CC_IOCQES(n)         (((n) & 0xF) << 20) // IO Completion Entry Size 2^n
41 #define NVME_CC_IOSQES(n)         (((n) & 0xF) << 16) // IO Submission Entry Size 2^n
42 #define NVME_CC_SHN_NORMAL        (1 << 14) // Request Normal Shutdown
43 #define NVME_CC_SHN_ABRUPT        (2 << 14) // Request Abrupt Shutdown
44 #define NVME_CC_SHN_MASK          (3 << 14)
45 #define NVME_CC_AMS_RR            (0 << 11) // Arbitration: Round-Robin
46 #define NVME_CC_AMS_WRR           (1 << 11) // Arbitration: Weighted-Round-Robin
47 #define NVME_CC_AMS_VS            (7 << 11) // Arbitration: Vendor Specific
48 #define NVME_CC_MPS(n)            (((n) & 0xF) << 7) // Memory Page Size (2^(n + 12))
49 #define NVME_CC_EN                (1 << 0) // Enable
50 
51 #define NVME_CSTS_PP              (1 << 5)  // Processing Paused
52 #define NVME_CSTS_NSSRO           (1 << 4)  // Subsystem Reset Occurred (W1C)
53 #define NVME_CSTS_SHN_MASK        (3 << 2)
54 #define NVME_CSTS_SHN_NORMAL_OP   (0 << 2)  // not shutting done
55 #define NVME_CSTS_SHN_IN_PROGRESS (1 << 2)  // Shutdown is in progress
56 #define NVME_CSTS_SHN_COMPLETE    (2 << 2)  // Shutdown is complete
57 #define NVME_CSTS_CFS             (1 << 1)  // Controller Fatal Status
58 #define NVME_CSTS_RDY             (1 << 0)  // Ready
59 
60 #define NVME_AQA_ACQS(n)          (((n) & 0xFFF) << 16) // Admin Completion Queue Size
61 #define NVME_AQA_ASQS(n)          (((n) & 0xFFF) << 0)  // Admin Submission Queue Size
62 
63 
64 // Completion Queue Entry
65 typedef struct {
66     uint32_t cmd;
67     uint32_t reserved;
68     uint16_t sq_head;
69     uint16_t sq_id;
70     uint16_t cmd_id;
71     uint16_t status;
72 } nvme_cpl_t;
73 
74 #define NVME_CPL_SIZE 16
75 #define NVME_CPL_SHIFT 4
76 static_assert(sizeof(nvme_cpl_t) == NVME_CPL_SIZE, "");
77 static_assert(sizeof(nvme_cpl_t) == (1 << NVME_CPL_SHIFT), "");
78 
79 #define NVME_CPL_STATUS_CODE(n) (((n) >> 1) & 0x7FF)
80 
81 
82 // Submission Queue Entry
83 typedef struct {
84     uint32_t cmd;
85     uint32_t nsid;
86     uint64_t reserved;
87     uint64_t mptr;
88     union {
89         uint64_t prp[2];
90     } dptr;
91     union {
92         uint32_t raw[6];
93         struct {
94             uint64_t start_lba;
95             uint16_t block_count; // minus 1
96             uint16_t flags;
97             uint32_t dsm;
98             uint32_t eilbrt;
99             uint32_t elbat;
100         } rw;
101     } u;
102 } nvme_cmd_t;
103 
104 #define NVME_CMD_SIZE 64
105 #define NVME_CMD_SHIFT 6
106 static_assert(sizeof(nvme_cmd_t) == NVME_CMD_SIZE, "");
107 static_assert(sizeof(nvme_cmd_t) == (1 << NVME_CMD_SHIFT), "");
108 
109 // Common
110 #define NVME_CMD_CID(n)    (((n) & 0xFFFF) << 16)
111 
112 #define NVME_CMD_PRP       (0 << 14) // dptr uses PRP, mptr is raw addr
113 #define NVME_CMD_SGL       (1 << 14) // dptr uses SGL, mptr is raw addr
114 #define NVME_CMD_SGL_MSGL  (2 << 14) // dptr uses SGL, mptr points at SGL[1]
115 
116 #define NVME_CMD_NORMAL    (0 << 8) // non-fused command
117 #define NVME_CMD_FUSED_1ST (1 << 8) // 1st part of fused command
118 #define NVME_CMD_FUSED_2ND (2 << 8) // 2nd part of fused command
119 
120 #define NVME_CMD_OPC(n)    ((n) & 0xFF)
121 
122 
123 
124 // Admin Opcodes
125 #define NVME_ADMIN_OP_DELETE_IOSQ   0x00
126 #define NVME_ADMIN_OP_CREATE_IOSQ   0x01
127 #define NVME_ADMIN_OP_DELETE_IOCQ   0x04
128 #define NVME_ADMIN_OP_CREATE_IOCQ   0x05
129 #define NVME_ADMIN_OP_IDENTIFY      0x06
130 #define NVME_ADMIN_OP_ABORT         0x08
131 #define NVME_ADMIN_OP_SET_FEATURE   0x09
132 #define NVME_ADMIN_OP_GET_FEATURE   0x0A
133 #define NVME_ADMIN_OP_ASYNC_EVENT   0x0C
134 
135 #define NVME_FEATURE_SEL_CURRENT   (0 << 8)
136 #define NVME_FEATURE_SEL_DEFAULT   (1 << 8)
137 #define NVME_FEATURE_SEL_SAVED     (2 << 8)
138 #define NVME_FEATURE_SEL_SUPPORTED (3 << 8)
139 
140 #define NVME_FEATURE_NUMBER_OF_QUEUES 0x07
141 
142 
143 #define NVME_LBAFMT_RP(n)      (((n) >> 24) & 3)
144 #define NVME_LBAFMT_LBADS(n)   (((n) >> 16) & 0xFF)  // 2^n bytes
145 #define NVME_LBAFMT_MS(n)      ((n) & 0xFFFF)
146 
147 // NVM Opcodes
148 #define NVME_OP_FLUSH       0x00
149 #define NVME_OP_WRITE       0x01
150 #define NVME_OP_READ        0x02
151 
152 #define NVME_RW_FLAG_LR     (1 << 15)
153 #define NVME_RW_FLAG_FUA    (1 << 14)
154 
155 
156 // Identify Page for Controllers
157 typedef struct {
158     uint32_t w[8];
159 } nvme_psd_t;
160 
161 typedef struct {
162     //--------------------- // Controller Capabilities and Features
163     uint16_t VID;           // PCI Vendor ID
164     uint16_t SSVID;         // PCI Subsystem Vendor ID
165     uint8_t  SN[20];        // Serial Number
166     uint8_t  MN[40];        // Model Number
167     uint8_t  FR[8];         // Firmware Revision
168     uint8_t  RAB;           // Recommended Arbitrartion Burst
169     uint8_t  IEEE[3];       // IEEE OUI Identifier
170     uint8_t  CMIC;          // Controller Multi-Path IO and Namespace Sharing Caps
171     uint8_t  MDTS;          // Maximum Data Transfer Size
172     uint16_t CNTLID;        // Controller ID
173     uint32_t VER;           // Version
174     uint32_t RTD3R;         // RTD3 Resume Latency (uS)
175     uint32_t RTD3E;         // RTD3 ENtry Latency (uS)
176     uint32_t OAES;          // Optional Asynch Events Supported;
177     uint32_t CTRATT;        // Controller Attributes
178     uint8_t  zz0[12];       // Reserved
179     uint8_t  FGUID[16];     // Field Replaceable Unit GUID
180     uint8_t  zz1[112];      // Reserved
181     uint8_t  zz2[16];       // Refer to NVMe MI Spec
182 
183     // -------------------- // Admin Command Set Attributes and Capabilities
184     uint16_t OACS;          // Optional Admin Command Support
185     uint8_t  ACL;           // Abort Command Limit
186     uint8_t  AERL;          // Async Event Request Limit
187     uint8_t  FRMW;          // Firmware Updates
188     uint8_t  LPA;           // Log Page Attributes;
189     uint8_t  ELPE;          // Error Log Page Entries
190     uint8_t  NPSS;          // Number of Power States Supported
191     uint8_t  AVSCC;         // Admin Vendor Specific Command Config
192     uint8_t  APSTA;         // Autonomous Power State Transition Attrs
193     uint16_t WCTEMP;        // Warning Composite Temp Threshold
194     uint16_t CCTEMP;        // Critical Composite Temp Threshold
195     uint16_t MTFA;          // Max Time for Firmware Activation (x 100mS, 0 = undef)
196     uint32_t HMPRE;         // Host Memory Buffer Preferred Size (4K pages)
197     uint32_t HMMIN;         // Host Memory Buffer Minimum Size (4K pages)
198     uint64_t TNVMCAP_LO;    // Total NVM Capacity (bytes)
199     uint64_t TNVMCAP_HI;
200     uint64_t UNVMCAP_LO;    // Unallocated NVM Capacity (bytes)
201     uint64_t UNVMCAP_HI;
202     uint32_t RPMBS;         // Replay Protected Memory Block Support
203     uint16_t EDSTT;         // Extended Device SelfTest Time
204     uint8_t  DSTO;          // Devcie SelfTest Options
205     uint8_t  FWUG;          // Firmware Upgreade Granularity
206     uint16_t KAS;           // Keep Alive Support
207     uint16_t HCTMA;         // Host Controlled Thermal Management Attrs
208     uint16_t MNTMT;         // Minimum Thermal Management Temp
209     uint16_t MXTMT;         // Maximum Thermal Management Temp
210     uint32_t SANICAP;       // Sanitize Capabilities
211     uint8_t  zz3[180];      // Reserved
212 
213     // -------------------- // NVM Command Set Attributes
214     uint8_t  SQES;          // Submission Queue Entry Size
215     uint8_t  CQES;          // Completion Queue Entry Size
216     uint16_t MAXCMD;        // Max Outstanding Commands
217     uint32_t NN;            // Number of Namespaces
218     uint16_t ONCS;          // Optional NVM Command Support
219     uint16_t FUSES;         // Fused Operation Support
220     uint8_t  FNA;           // Format NVM Attributes
221     uint8_t  VWC;           // Volatile Write Cache
222     uint16_t AWUN;          // Atomic Write Unit Normal
223     uint16_t AWUPF;         // Atomic Write Unit Power Fail
224     uint8_t  NVSCC;         // NVM Vendor Specific Command Config
225     uint8_t  zz4;           // Reserved
226     uint16_t ACWU;          // Atomic Compare and Write Unit
227     uint16_t zz5;           // Reserved
228     uint32_t SGLS;          // Scatter Gather List Support
229     uint8_t  zz6[228];      // Reserved
230     uint8_t  SUBNQN[256];   // NVM Subsystem NVMe Qualified Name
231     uint8_t  zz7[768];      // Reserved
232     uint8_t  zz8[256];      // Refer to NVME over Fabrics Spec
233 
234     // -------------------- // Power State Descriptors
235     nvme_psd_t PSD[32];
236 
237     // -------------------- // Vendor Specific
238     uint8_t  vendor[1024];
239 } nvme_identify_t;
240 
241 static_assert(sizeof(nvme_identify_t) == 4096, "");
242 
243 #define OACS_DOORBELL_BUFFER_CONFIG     (1 << 8)
244 #define OACS_VIRTUALIZATION_MANAGEMENT  (1 << 7)
245 #define OACS_NVME_MI_SEND_RECV          (1 << 6)
246 #define OACS_DIRECTIVE_SEND_RECV        (1 << 5)
247 #define OACS_DEVICE_SELF_TEST           (1 << 4)
248 #define OACS_NAMESPACE_MANAGEMENT       (1 << 3)
249 #define OACS_FIRMWARE_DOWNLOAD_COMMIT   (1 << 2)
250 #define OACS_FORMAT_NVM                 (1 << 1)
251 #define OACS_SECURITY_SEND_RECV         (1 << 0)
252 
253 #define ONCS_TIMESTAMP                  (1 << 6)
254 #define ONCS_RESERVATIONS               (1 << 5)
255 #define ONCS_SAVE_SELECT_NONZERO        (1 << 4)
256 #define ONCS_WRITE_ZEROES               (1 << 3)
257 #define ONCS_DATASET_MANAGEMENT         (1 << 2)
258 #define ONCS_WRITE_UNCORRECTABLE        (1 << 1)
259 #define ONCS_COMPARE                    (1 << 0)
260 
261 
262 // Identify Page for Namespaces
263 #define NSFEAT_GUIDS_NOT_REUSED         (1 << 3)
264 #define NSFEAT_DEALLOC_BLOCK_ERROR      (1 << 2)
265 #define NSFEAT_LOCAL_ATOMIC_SIZES       (1 << 1)
266 #define NSFEAT_THING_PROVISIONING       (1 << 0)
267 
268 
269 typedef struct {
270     // -------------------- // Vendor Specific
271     uint64_t NSSZ;          // Namespace Size (blocks)
272     uint64_t NCAP;          // Namespace Capacity (blocks)
273     uint64_t NUSE;          // Namespace Utilization (blocks)
274     uint8_t  NSFEAT;        // Namespace Features
275     uint8_t  NLBAF;         // Number of LBA Formats
276     uint8_t  FLBAS;         // Formatted LBA Size
277     uint8_t  MC;            // Metadata Capabilities
278     uint8_t  DPC;           // End-to-End Data Protection Capabilities
279     uint8_t  DPS;           // End-to-End Data Protection Type Settings
280     uint8_t  NMIC;          // Namespace MultiPath IO and Sharing Caps
281     uint8_t  RESCAP;        // Reservation Capabilities
282     uint8_t  FPI;           // Format Progress Indicator
283     uint8_t  DLFEAT;        // Deallocate Logical Block Features
284     uint16_t NAWUN;         // Namespace Atomic Write Unit Normal
285     uint16_t NAWUPF;        // Namespace Atomic Write Unit Power Fail
286     uint16_t NACWUN;        // Namespace Atomic Compare and Write Unit
287     uint16_t NABSN;         // Namespace Atomic Boundary Size Normal
288     uint16_t NABO;          // Namespace Atomic Boundary Offset
289     uint16_t NABSPF;        // Namespace Atomic Boundary Size Power Fail
290     uint16_t NOIOB;         // Namespace Optimal IO Boundary
291     uint64_t NVMCAP_LO;     // NVM Capacity (bytes)
292     uint64_t NVMCAP_HI;
293     uint8_t  zz0[40];       // Reserved
294     uint8_t  NGUID[16];     // Namespace GUID
295     uint8_t  EUI64[8];      // IEEE Extended Unique Identifier
296     uint32_t LBAF[16];      // LBA Format Support 0..15
297     uint8_t  zz1[192];      // Reserved
298     uint8_t  zz2[3712];     // Reserved
299 } nvme_identify_ns_t;
300 
301 static_assert(sizeof(nvme_identify_ns_t) == 4096, "");
302 
303 #define NSFEAT_GUIDS_NOT_REUSED         (1 << 3)
304 #define NSFEAT_DEALLOC_BLOCK_ERROR      (1 << 2)
305 #define NSFEAT_LOCAL_ATOMIC_SIZES       (1 << 1)
306 #define NSFEAT_THING_PROVISIONING       (1 << 0)
307