Statistics
| Branch: | Revision:

root / hw / block / nvme.h @ f3c507ad

History | View | Annotate | Download (20.9 kB)

1
#ifndef HW_NVME_H
2
#define HW_NVME_H
3

    
4
typedef struct NvmeBar {
5
    uint64_t    cap;
6
    uint32_t    vs;
7
    uint32_t    intms;
8
    uint32_t    intmc;
9
    uint32_t    cc;
10
    uint32_t    rsvd1;
11
    uint32_t    csts;
12
    uint32_t    nssrc;
13
    uint32_t    aqa;
14
    uint64_t    asq;
15
    uint64_t    acq;
16
} NvmeBar;
17

    
18
enum NvmeCapShift {
19
    CAP_MQES_SHIFT     = 0,
20
    CAP_CQR_SHIFT      = 16,
21
    CAP_AMS_SHIFT      = 17,
22
    CAP_TO_SHIFT       = 24,
23
    CAP_DSTRD_SHIFT    = 32,
24
    CAP_NSSRS_SHIFT    = 33,
25
    CAP_CSS_SHIFT      = 37,
26
    CAP_MPSMIN_SHIFT   = 48,
27
    CAP_MPSMAX_SHIFT   = 52,
28
};
29

    
30
enum NvmeCapMask {
31
    CAP_MQES_MASK      = 0xffff,
32
    CAP_CQR_MASK       = 0x1,
33
    CAP_AMS_MASK       = 0x3,
34
    CAP_TO_MASK        = 0xff,
35
    CAP_DSTRD_MASK     = 0xf,
36
    CAP_NSSRS_MASK     = 0x1,
37
    CAP_CSS_MASK       = 0xff,
38
    CAP_MPSMIN_MASK    = 0xf,
39
    CAP_MPSMAX_MASK    = 0xf,
40
};
41

    
42
#define NVME_CAP_MQES(cap)  (((cap) >> CAP_MQES_SHIFT)   & CAP_MQES_MASK)
43
#define NVME_CAP_CQR(cap)   (((cap) >> CAP_CQR_SHIFT)    & CAP_CQR_MASK)
44
#define NVME_CAP_AMS(cap)   (((cap) >> CAP_AMS_SHIFT)    & CAP_AMS_MASK)
45
#define NVME_CAP_TO(cap)    (((cap) >> CAP_TO_SHIFT)     & CAP_TO_MASK)
46
#define NVME_CAP_DSTRD(cap) (((cap) >> CAP_DSTRD_SHIFT)  & CAP_DSTRD_MASK)
47
#define NVME_CAP_NSSRS(cap) (((cap) >> CAP_NSSRS_SHIFT)  & CAP_NSSRS_MASK)
48
#define NVME_CAP_CSS(cap)   (((cap) >> CAP_CSS_SHIFT)    & CAP_CSS_MASK)
49
#define NVME_CAP_MPSMIN(cap)(((cap) >> CAP_MPSMIN_SHIFT) & CAP_MPSMIN_MASK)
50
#define NVME_CAP_MPSMAX(cap)(((cap) >> CAP_MPSMAX_SHIFT) & CAP_MPSMAX_MASK)
51

    
52
#define NVME_CAP_SET_MQES(cap, val)   (cap |= (uint64_t)(val & CAP_MQES_MASK)  \
53
                                                           << CAP_MQES_SHIFT)
54
#define NVME_CAP_SET_CQR(cap, val)    (cap |= (uint64_t)(val & CAP_CQR_MASK)   \
55
                                                           << CAP_CQR_SHIFT)
56
#define NVME_CAP_SET_AMS(cap, val)    (cap |= (uint64_t)(val & CAP_AMS_MASK)   \
57
                                                           << CAP_AMS_SHIFT)
58
#define NVME_CAP_SET_TO(cap, val)     (cap |= (uint64_t)(val & CAP_TO_MASK)    \
59
                                                           << CAP_TO_SHIFT)
60
#define NVME_CAP_SET_DSTRD(cap, val)  (cap |= (uint64_t)(val & CAP_DSTRD_MASK) \
61
                                                           << CAP_DSTRD_SHIFT)
62
#define NVME_CAP_SET_NSSRS(cap, val)  (cap |= (uint64_t)(val & CAP_NSSRS_MASK) \
63
                                                           << CAP_NSSRS_SHIFT)
64
#define NVME_CAP_SET_CSS(cap, val)    (cap |= (uint64_t)(val & CAP_CSS_MASK)   \
65
                                                           << CAP_CSS_SHIFT)
66
#define NVME_CAP_SET_MPSMIN(cap, val) (cap |= (uint64_t)(val & CAP_MPSMIN_MASK)\
67
                                                           << CAP_MPSMIN_SHIFT)
68
#define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\
69
                                                            << CAP_MPSMAX_SHIFT)
70

    
71
enum NvmeCcShift {
72
    CC_EN_SHIFT     = 0,
73
    CC_CSS_SHIFT    = 4,
74
    CC_MPS_SHIFT    = 7,
75
    CC_AMS_SHIFT    = 11,
76
    CC_SHN_SHIFT    = 14,
77
    CC_IOSQES_SHIFT = 16,
78
    CC_IOCQES_SHIFT = 20,
79
};
80

    
81
enum NvmeCcMask {
82
    CC_EN_MASK      = 0x1,
83
    CC_CSS_MASK     = 0x7,
84
    CC_MPS_MASK     = 0xf,
85
    CC_AMS_MASK     = 0x7,
86
    CC_SHN_MASK     = 0x3,
87
    CC_IOSQES_MASK  = 0xf,
88
    CC_IOCQES_MASK  = 0xf,
89
};
90

    
91
#define NVME_CC_EN(cc)     ((cc >> CC_EN_SHIFT)     & CC_EN_MASK)
92
#define NVME_CC_CSS(cc)    ((cc >> CC_CSS_SHIFT)    & CC_CSS_MASK)
93
#define NVME_CC_MPS(cc)    ((cc >> CC_MPS_SHIFT)    & CC_MPS_MASK)
94
#define NVME_CC_AMS(cc)    ((cc >> CC_AMS_SHIFT)    & CC_AMS_MASK)
95
#define NVME_CC_SHN(cc)    ((cc >> CC_SHN_SHIFT)    & CC_SHN_MASK)
96
#define NVME_CC_IOSQES(cc) ((cc >> CC_IOSQES_SHIFT) & CC_IOSQES_MASK)
97
#define NVME_CC_IOCQES(cc) ((cc >> CC_IOCQES_SHIFT) & CC_IOCQES_MASK)
98

    
99
enum NvmeCstsShift {
100
    CSTS_RDY_SHIFT      = 0,
101
    CSTS_CFS_SHIFT      = 1,
102
    CSTS_SHST_SHIFT     = 2,
103
    CSTS_NSSRO_SHIFT    = 4,
104
};
105

    
106
enum NvmeCstsMask {
107
    CSTS_RDY_MASK   = 0x1,
108
    CSTS_CFS_MASK   = 0x1,
109
    CSTS_SHST_MASK  = 0x3,
110
    CSTS_NSSRO_MASK = 0x1,
111
};
112

    
113
enum NvmeCsts {
114
    NVME_CSTS_READY         = 1 << CSTS_RDY_SHIFT,
115
    NVME_CSTS_FAILED        = 1 << CSTS_CFS_SHIFT,
116
    NVME_CSTS_SHST_NORMAL   = 0 << CSTS_SHST_SHIFT,
117
    NVME_CSTS_SHST_PROGRESS = 1 << CSTS_SHST_SHIFT,
118
    NVME_CSTS_SHST_COMPLETE = 2 << CSTS_SHST_SHIFT,
119
    NVME_CSTS_NSSRO         = 1 << CSTS_NSSRO_SHIFT,
120
};
121

    
122
#define NVME_CSTS_RDY(csts)     ((csts >> CSTS_RDY_SHIFT)   & CSTS_RDY_MASK)
123
#define NVME_CSTS_CFS(csts)     ((csts >> CSTS_CFS_SHIFT)   & CSTS_CFS_MASK)
124
#define NVME_CSTS_SHST(csts)    ((csts >> CSTS_SHST_SHIFT)  & CSTS_SHST_MASK)
125
#define NVME_CSTS_NSSRO(csts)   ((csts >> CSTS_NSSRO_SHIFT) & CSTS_NSSRO_MASK)
126

    
127
enum NvmeAqaShift {
128
    AQA_ASQS_SHIFT  = 0,
129
    AQA_ACQS_SHIFT  = 16,
130
};
131

    
132
enum NvmeAqaMask {
133
    AQA_ASQS_MASK   = 0xfff,
134
    AQA_ACQS_MASK   = 0xfff,
135
};
136

    
137
#define NVME_AQA_ASQS(aqa) ((aqa >> AQA_ASQS_SHIFT) & AQA_ASQS_MASK)
138
#define NVME_AQA_ACQS(aqa) ((aqa >> AQA_ACQS_SHIFT) & AQA_ACQS_MASK)
139

    
140
typedef struct NvmeCmd {
141
    uint8_t     opcode;
142
    uint8_t     fuse;
143
    uint16_t    cid;
144
    uint32_t    nsid;
145
    uint64_t    res1;
146
    uint64_t    mptr;
147
    uint64_t    prp1;
148
    uint64_t    prp2;
149
    uint32_t    cdw10;
150
    uint32_t    cdw11;
151
    uint32_t    cdw12;
152
    uint32_t    cdw13;
153
    uint32_t    cdw14;
154
    uint32_t    cdw15;
155
} NvmeCmd;
156

    
157
enum NvmeAdminCommands {
158
    NVME_ADM_CMD_DELETE_SQ      = 0x00,
159
    NVME_ADM_CMD_CREATE_SQ      = 0x01,
160
    NVME_ADM_CMD_GET_LOG_PAGE   = 0x02,
161
    NVME_ADM_CMD_DELETE_CQ      = 0x04,
162
    NVME_ADM_CMD_CREATE_CQ      = 0x05,
163
    NVME_ADM_CMD_IDENTIFY       = 0x06,
164
    NVME_ADM_CMD_ABORT          = 0x08,
165
    NVME_ADM_CMD_SET_FEATURES   = 0x09,
166
    NVME_ADM_CMD_GET_FEATURES   = 0x0a,
167
    NVME_ADM_CMD_ASYNC_EV_REQ   = 0x0c,
168
    NVME_ADM_CMD_ACTIVATE_FW    = 0x10,
169
    NVME_ADM_CMD_DOWNLOAD_FW    = 0x11,
170
    NVME_ADM_CMD_FORMAT_NVM     = 0x80,
171
    NVME_ADM_CMD_SECURITY_SEND  = 0x81,
172
    NVME_ADM_CMD_SECURITY_RECV  = 0x82,
173
};
174

    
175
enum NvmeIoCommands {
176
    NVME_CMD_FLUSH              = 0x00,
177
    NVME_CMD_WRITE              = 0x01,
178
    NVME_CMD_READ               = 0x02,
179
    NVME_CMD_WRITE_UNCOR        = 0x04,
180
    NVME_CMD_COMPARE            = 0x05,
181
    NVME_CMD_DSM                = 0x09,
182
};
183

    
184
typedef struct NvmeDeleteQ {
185
    uint8_t     opcode;
186
    uint8_t     flags;
187
    uint16_t    cid;
188
    uint32_t    rsvd1[9];
189
    uint16_t    qid;
190
    uint16_t    rsvd10;
191
    uint32_t    rsvd11[5];
192
} NvmeDeleteQ;
193

    
194
typedef struct NvmeCreateCq {
195
    uint8_t     opcode;
196
    uint8_t     flags;
197
    uint16_t    cid;
198
    uint32_t    rsvd1[5];
199
    uint64_t    prp1;
200
    uint64_t    rsvd8;
201
    uint16_t    cqid;
202
    uint16_t    qsize;
203
    uint16_t    cq_flags;
204
    uint16_t    irq_vector;
205
    uint32_t    rsvd12[4];
206
} NvmeCreateCq;
207

    
208
#define NVME_CQ_FLAGS_PC(cq_flags)  (cq_flags & 0x1)
209
#define NVME_CQ_FLAGS_IEN(cq_flags) ((cq_flags >> 1) & 0x1)
210

    
211
typedef struct NvmeCreateSq {
212
    uint8_t     opcode;
213
    uint8_t     flags;
214
    uint16_t    cid;
215
    uint32_t    rsvd1[5];
216
    uint64_t    prp1;
217
    uint64_t    rsvd8;
218
    uint16_t    sqid;
219
    uint16_t    qsize;
220
    uint16_t    sq_flags;
221
    uint16_t    cqid;
222
    uint32_t    rsvd12[4];
223
} NvmeCreateSq;
224

    
225
#define NVME_SQ_FLAGS_PC(sq_flags)      (sq_flags & 0x1)
226
#define NVME_SQ_FLAGS_QPRIO(sq_flags)   ((sq_flags >> 1) & 0x3)
227

    
228
enum NvmeQueueFlags {
229
    NVME_Q_PC           = 1,
230
    NVME_Q_PRIO_URGENT  = 0,
231
    NVME_Q_PRIO_HIGH    = 1,
232
    NVME_Q_PRIO_NORMAL  = 2,
233
    NVME_Q_PRIO_LOW     = 3,
234
};
235

    
236
typedef struct NvmeIdentify {
237
    uint8_t     opcode;
238
    uint8_t     flags;
239
    uint16_t    cid;
240
    uint32_t    nsid;
241
    uint64_t    rsvd2[2];
242
    uint64_t    prp1;
243
    uint64_t    prp2;
244
    uint32_t    cns;
245
    uint32_t    rsvd11[5];
246
} NvmeIdentify;
247

    
248
typedef struct NvmeRwCmd {
249
    uint8_t     opcode;
250
    uint8_t     flags;
251
    uint16_t    cid;
252
    uint32_t    nsid;
253
    uint64_t    rsvd2;
254
    uint64_t    mptr;
255
    uint64_t    prp1;
256
    uint64_t    prp2;
257
    uint64_t    slba;
258
    uint16_t    nlb;
259
    uint16_t    control;
260
    uint32_t    dsmgmt;
261
    uint32_t    reftag;
262
    uint16_t    apptag;
263
    uint16_t    appmask;
264
} NvmeRwCmd;
265

    
266
enum {
267
    NVME_RW_LR                  = 1 << 15,
268
    NVME_RW_FUA                 = 1 << 14,
269
    NVME_RW_DSM_FREQ_UNSPEC     = 0,
270
    NVME_RW_DSM_FREQ_TYPICAL    = 1,
271
    NVME_RW_DSM_FREQ_RARE       = 2,
272
    NVME_RW_DSM_FREQ_READS      = 3,
273
    NVME_RW_DSM_FREQ_WRITES     = 4,
274
    NVME_RW_DSM_FREQ_RW         = 5,
275
    NVME_RW_DSM_FREQ_ONCE       = 6,
276
    NVME_RW_DSM_FREQ_PREFETCH   = 7,
277
    NVME_RW_DSM_FREQ_TEMP       = 8,
278
    NVME_RW_DSM_LATENCY_NONE    = 0 << 4,
279
    NVME_RW_DSM_LATENCY_IDLE    = 1 << 4,
280
    NVME_RW_DSM_LATENCY_NORM    = 2 << 4,
281
    NVME_RW_DSM_LATENCY_LOW     = 3 << 4,
282
    NVME_RW_DSM_SEQ_REQ         = 1 << 6,
283
    NVME_RW_DSM_COMPRESSED      = 1 << 7,
284
    NVME_RW_PRINFO_PRACT        = 1 << 13,
285
    NVME_RW_PRINFO_PRCHK_GUARD  = 1 << 12,
286
    NVME_RW_PRINFO_PRCHK_APP    = 1 << 11,
287
    NVME_RW_PRINFO_PRCHK_REF    = 1 << 10,
288
};
289

    
290
typedef struct NvmeDsmCmd {
291
    uint8_t     opcode;
292
    uint8_t     flags;
293
    uint16_t    cid;
294
    uint32_t    nsid;
295
    uint64_t    rsvd2[2];
296
    uint64_t    prp1;
297
    uint64_t    prp2;
298
    uint32_t    nr;
299
    uint32_t    attributes;
300
    uint32_t    rsvd12[4];
301
} NvmeDsmCmd;
302

    
303
enum {
304
    NVME_DSMGMT_IDR = 1 << 0,
305
    NVME_DSMGMT_IDW = 1 << 1,
306
    NVME_DSMGMT_AD  = 1 << 2,
307
};
308

    
309
typedef struct NvmeDsmRange {
310
    uint32_t    cattr;
311
    uint32_t    nlb;
312
    uint64_t    slba;
313
} NvmeDsmRange;
314

    
315
enum NvmeAsyncEventRequest {
316
    NVME_AER_TYPE_ERROR                     = 0,
317
    NVME_AER_TYPE_SMART                     = 1,
318
    NVME_AER_TYPE_IO_SPECIFIC               = 6,
319
    NVME_AER_TYPE_VENDOR_SPECIFIC           = 7,
320
    NVME_AER_INFO_ERR_INVALID_SQ            = 0,
321
    NVME_AER_INFO_ERR_INVALID_DB            = 1,
322
    NVME_AER_INFO_ERR_DIAG_FAIL             = 2,
323
    NVME_AER_INFO_ERR_PERS_INTERNAL_ERR     = 3,
324
    NVME_AER_INFO_ERR_TRANS_INTERNAL_ERR    = 4,
325
    NVME_AER_INFO_ERR_FW_IMG_LOAD_ERR       = 5,
326
    NVME_AER_INFO_SMART_RELIABILITY         = 0,
327
    NVME_AER_INFO_SMART_TEMP_THRESH         = 1,
328
    NVME_AER_INFO_SMART_SPARE_THRESH        = 2,
329
};
330

    
331
typedef struct NvmeAerResult {
332
    uint8_t event_type;
333
    uint8_t event_info;
334
    uint8_t log_page;
335
    uint8_t resv;
336
} NvmeAerResult;
337

    
338
typedef struct NvmeCqe {
339
    uint32_t    result;
340
    uint32_t    rsvd;
341
    uint16_t    sq_head;
342
    uint16_t    sq_id;
343
    uint16_t    cid;
344
    uint16_t    status;
345
} NvmeCqe;
346

    
347
enum NvmeStatusCodes {
348
    NVME_SUCCESS                = 0x0000,
349
    NVME_INVALID_OPCODE         = 0x0001,
350
    NVME_INVALID_FIELD          = 0x0002,
351
    NVME_CID_CONFLICT           = 0x0003,
352
    NVME_DATA_TRAS_ERROR        = 0x0004,
353
    NVME_POWER_LOSS_ABORT       = 0x0005,
354
    NVME_INTERNAL_DEV_ERROR     = 0x0006,
355
    NVME_CMD_ABORT_REQ          = 0x0007,
356
    NVME_CMD_ABORT_SQ_DEL       = 0x0008,
357
    NVME_CMD_ABORT_FAILED_FUSE  = 0x0009,
358
    NVME_CMD_ABORT_MISSING_FUSE = 0x000a,
359
    NVME_INVALID_NSID           = 0x000b,
360
    NVME_CMD_SEQ_ERROR          = 0x000c,
361
    NVME_LBA_RANGE              = 0x0080,
362
    NVME_CAP_EXCEEDED           = 0x0081,
363
    NVME_NS_NOT_READY           = 0x0082,
364
    NVME_NS_RESV_CONFLICT       = 0x0083,
365
    NVME_INVALID_CQID           = 0x0100,
366
    NVME_INVALID_QID            = 0x0101,
367
    NVME_MAX_QSIZE_EXCEEDED     = 0x0102,
368
    NVME_ACL_EXCEEDED           = 0x0103,
369
    NVME_RESERVED               = 0x0104,
370
    NVME_AER_LIMIT_EXCEEDED     = 0x0105,
371
    NVME_INVALID_FW_SLOT        = 0x0106,
372
    NVME_INVALID_FW_IMAGE       = 0x0107,
373
    NVME_INVALID_IRQ_VECTOR     = 0x0108,
374
    NVME_INVALID_LOG_ID         = 0x0109,
375
    NVME_INVALID_FORMAT         = 0x010a,
376
    NVME_FW_REQ_RESET           = 0x010b,
377
    NVME_INVALID_QUEUE_DEL      = 0x010c,
378
    NVME_FID_NOT_SAVEABLE       = 0x010d,
379
    NVME_FID_NOT_NSID_SPEC      = 0x010f,
380
    NVME_FW_REQ_SUSYSTEM_RESET  = 0x0110,
381
    NVME_CONFLICTING_ATTRS      = 0x0180,
382
    NVME_INVALID_PROT_INFO      = 0x0181,
383
    NVME_WRITE_TO_RO            = 0x0182,
384
    NVME_WRITE_FAULT            = 0x0280,
385
    NVME_UNRECOVERED_READ       = 0x0281,
386
    NVME_E2E_GUARD_ERROR        = 0x0282,
387
    NVME_E2E_APP_ERROR          = 0x0283,
388
    NVME_E2E_REF_ERROR          = 0x0284,
389
    NVME_CMP_FAILURE            = 0x0285,
390
    NVME_ACCESS_DENIED          = 0x0286,
391
    NVME_MORE                   = 0x2000,
392
    NVME_DNR                    = 0x4000,
393
    NVME_NO_COMPLETE            = 0xffff,
394
};
395

    
396
typedef struct NvmeFwSlotInfoLog {
397
    uint8_t     afi;
398
    uint8_t     reserved1[7];
399
    uint8_t     frs1[8];
400
    uint8_t     frs2[8];
401
    uint8_t     frs3[8];
402
    uint8_t     frs4[8];
403
    uint8_t     frs5[8];
404
    uint8_t     frs6[8];
405
    uint8_t     frs7[8];
406
    uint8_t     reserved2[448];
407
} NvmeFwSlotInfoLog;
408

    
409
typedef struct NvmeErrorLog {
410
    uint64_t    error_count;
411
    uint16_t    sqid;
412
    uint16_t    cid;
413
    uint16_t    status_field;
414
    uint16_t    param_error_location;
415
    uint64_t    lba;
416
    uint32_t    nsid;
417
    uint8_t     vs;
418
    uint8_t     resv[35];
419
} NvmeErrorLog;
420

    
421
typedef struct NvmeSmartLog {
422
    uint8_t     critical_warning;
423
    uint8_t     temperature[2];
424
    uint8_t     available_spare;
425
    uint8_t     available_spare_threshold;
426
    uint8_t     percentage_used;
427
    uint8_t     reserved1[26];
428
    uint64_t    data_units_read[2];
429
    uint64_t    data_units_written[2];
430
    uint64_t    host_read_commands[2];
431
    uint64_t    host_write_commands[2];
432
    uint64_t    controller_busy_time[2];
433
    uint64_t    power_cycles[2];
434
    uint64_t    power_on_hours[2];
435
    uint64_t    unsafe_shutdowns[2];
436
    uint64_t    media_errors[2];
437
    uint64_t    number_of_error_log_entries[2];
438
    uint8_t     reserved2[320];
439
} NvmeSmartLog;
440

    
441
enum NvmeSmartWarn {
442
    NVME_SMART_SPARE                  = 1 << 0,
443
    NVME_SMART_TEMPERATURE            = 1 << 1,
444
    NVME_SMART_RELIABILITY            = 1 << 2,
445
    NVME_SMART_MEDIA_READ_ONLY        = 1 << 3,
446
    NVME_SMART_FAILED_VOLATILE_MEDIA  = 1 << 4,
447
};
448

    
449
enum LogIdentifier {
450
    NVME_LOG_ERROR_INFO     = 0x01,
451
    NVME_LOG_SMART_INFO     = 0x02,
452
    NVME_LOG_FW_SLOT_INFO   = 0x03,
453
};
454

    
455
typedef struct NvmePSD {
456
    uint16_t    mp;
457
    uint16_t    reserved;
458
    uint32_t    enlat;
459
    uint32_t    exlat;
460
    uint8_t     rrt;
461
    uint8_t     rrl;
462
    uint8_t     rwt;
463
    uint8_t     rwl;
464
    uint8_t     resv[16];
465
} NvmePSD;
466

    
467
typedef struct NvmeIdCtrl {
468
    uint16_t    vid;
469
    uint16_t    ssvid;
470
    uint8_t     sn[20];
471
    uint8_t     mn[40];
472
    uint8_t     fr[8];
473
    uint8_t     rab;
474
    uint8_t     ieee[3];
475
    uint8_t     cmic;
476
    uint8_t     mdts;
477
    uint8_t     rsvd255[178];
478
    uint16_t    oacs;
479
    uint8_t     acl;
480
    uint8_t     aerl;
481
    uint8_t     frmw;
482
    uint8_t     lpa;
483
    uint8_t     elpe;
484
    uint8_t     npss;
485
    uint8_t     rsvd511[248];
486
    uint8_t     sqes;
487
    uint8_t     cqes;
488
    uint16_t    rsvd515;
489
    uint32_t    nn;
490
    uint16_t    oncs;
491
    uint16_t    fuses;
492
    uint8_t     fna;
493
    uint8_t     vwc;
494
    uint16_t    awun;
495
    uint16_t    awupf;
496
    uint8_t     rsvd703[174];
497
    uint8_t     rsvd2047[1344];
498
    NvmePSD     psd[32];
499
    uint8_t     vs[1024];
500
} NvmeIdCtrl;
501

    
502
enum NvmeIdCtrlOacs {
503
    NVME_OACS_SECURITY  = 1 << 0,
504
    NVME_OACS_FORMAT    = 1 << 1,
505
    NVME_OACS_FW        = 1 << 2,
506
};
507

    
508
enum NvmeIdCtrlOncs {
509
    NVME_ONCS_COMPARE       = 1 << 0,
510
    NVME_ONCS_WRITE_UNCORR  = 1 << 1,
511
    NVME_ONCS_DSM           = 1 << 2,
512
    NVME_ONCS_WRITE_ZEROS   = 1 << 3,
513
    NVME_ONCS_FEATURES      = 1 << 4,
514
    NVME_ONCS_RESRVATIONS   = 1 << 5,
515
};
516

    
517
#define NVME_CTRL_SQES_MIN(sqes) ((sqes) & 0xf)
518
#define NVME_CTRL_SQES_MAX(sqes) (((sqes) >> 4) & 0xf)
519
#define NVME_CTRL_CQES_MIN(cqes) ((cqes) & 0xf)
520
#define NVME_CTRL_CQES_MAX(cqes) (((cqes) >> 4) & 0xf)
521

    
522
typedef struct NvmeFeatureVal {
523
    uint32_t    arbitration;
524
    uint32_t    power_mgmt;
525
    uint32_t    temp_thresh;
526
    uint32_t    err_rec;
527
    uint32_t    volatile_wc;
528
    uint32_t    num_queues;
529
    uint32_t    int_coalescing;
530
    uint32_t    *int_vector_config;
531
    uint32_t    write_atomicity;
532
    uint32_t    async_config;
533
    uint32_t    sw_prog_marker;
534
} NvmeFeatureVal;
535

    
536
#define NVME_ARB_AB(arb)    (arb & 0x7)
537
#define NVME_ARB_LPW(arb)   ((arb >> 8) & 0xff)
538
#define NVME_ARB_MPW(arb)   ((arb >> 16) & 0xff)
539
#define NVME_ARB_HPW(arb)   ((arb >> 24) & 0xff)
540

    
541
#define NVME_INTC_THR(intc)     (intc & 0xff)
542
#define NVME_INTC_TIME(intc)    ((intc >> 8) & 0xff)
543

    
544
enum NvmeFeatureIds {
545
    NVME_ARBITRATION                = 0x1,
546
    NVME_POWER_MANAGEMENT           = 0x2,
547
    NVME_LBA_RANGE_TYPE             = 0x3,
548
    NVME_TEMPERATURE_THRESHOLD      = 0x4,
549
    NVME_ERROR_RECOVERY             = 0x5,
550
    NVME_VOLATILE_WRITE_CACHE       = 0x6,
551
    NVME_NUMBER_OF_QUEUES           = 0x7,
552
    NVME_INTERRUPT_COALESCING       = 0x8,
553
    NVME_INTERRUPT_VECTOR_CONF      = 0x9,
554
    NVME_WRITE_ATOMICITY            = 0xa,
555
    NVME_ASYNCHRONOUS_EVENT_CONF    = 0xb,
556
    NVME_SOFTWARE_PROGRESS_MARKER   = 0x80
557
};
558

    
559
typedef struct NvmeRangeType {
560
    uint8_t     type;
561
    uint8_t     attributes;
562
    uint8_t     rsvd2[14];
563
    uint64_t    slba;
564
    uint64_t    nlb;
565
    uint8_t     guid[16];
566
    uint8_t     rsvd48[16];
567
} NvmeRangeType;
568

    
569
typedef struct NvmeLBAF {
570
    uint16_t    ms;
571
    uint8_t     ds;
572
    uint8_t     rp;
573
} NvmeLBAF;
574

    
575
typedef struct NvmeIdNs {
576
    uint64_t    nsze;
577
    uint64_t    ncap;
578
    uint64_t    nuse;
579
    uint8_t     nsfeat;
580
    uint8_t     nlbaf;
581
    uint8_t     flbas;
582
    uint8_t     mc;
583
    uint8_t     dpc;
584
    uint8_t     dps;
585
    uint8_t     res30[98];
586
    NvmeLBAF    lbaf[16];
587
    uint8_t     res192[192];
588
    uint8_t     vs[3712];
589
} NvmeIdNs;
590

    
591
#define NVME_ID_NS_NSFEAT_THIN(nsfeat)      ((nsfeat & 0x1))
592
#define NVME_ID_NS_FLBAS_EXTENDED(flbas)    ((flbas >> 4) & 0x1)
593
#define NVME_ID_NS_FLBAS_INDEX(flbas)       ((flbas & 0xf))
594
#define NVME_ID_NS_MC_SEPARATE(mc)          ((mc >> 1) & 0x1)
595
#define NVME_ID_NS_MC_EXTENDED(mc)          ((mc & 0x1))
596
#define NVME_ID_NS_DPC_LAST_EIGHT(dpc)      ((dpc >> 4) & 0x1)
597
#define NVME_ID_NS_DPC_FIRST_EIGHT(dpc)     ((dpc >> 3) & 0x1)
598
#define NVME_ID_NS_DPC_TYPE_3(dpc)          ((dpc >> 2) & 0x1)
599
#define NVME_ID_NS_DPC_TYPE_2(dpc)          ((dpc >> 1) & 0x1)
600
#define NVME_ID_NS_DPC_TYPE_1(dpc)          ((dpc & 0x1))
601
#define NVME_ID_NS_DPC_TYPE_MASK            0x7
602

    
603
enum NvmeIdNsDps {
604
    DPS_TYPE_NONE   = 0,
605
    DPS_TYPE_1      = 1,
606
    DPS_TYPE_2      = 2,
607
    DPS_TYPE_3      = 3,
608
    DPS_TYPE_MASK   = 0x7,
609
    DPS_FIRST_EIGHT = 8,
610
};
611

    
612
static inline void _nvme_check_size(void)
613
{
614
    QEMU_BUILD_BUG_ON(sizeof(NvmeAerResult) != 4);
615
    QEMU_BUILD_BUG_ON(sizeof(NvmeCqe) != 16);
616
    QEMU_BUILD_BUG_ON(sizeof(NvmeDsmRange) != 16);
617
    QEMU_BUILD_BUG_ON(sizeof(NvmeCmd) != 64);
618
    QEMU_BUILD_BUG_ON(sizeof(NvmeDeleteQ) != 64);
619
    QEMU_BUILD_BUG_ON(sizeof(NvmeCreateCq) != 64);
620
    QEMU_BUILD_BUG_ON(sizeof(NvmeCreateSq) != 64);
621
    QEMU_BUILD_BUG_ON(sizeof(NvmeIdentify) != 64);
622
    QEMU_BUILD_BUG_ON(sizeof(NvmeRwCmd) != 64);
623
    QEMU_BUILD_BUG_ON(sizeof(NvmeDsmCmd) != 64);
624
    QEMU_BUILD_BUG_ON(sizeof(NvmeRangeType) != 64);
625
    QEMU_BUILD_BUG_ON(sizeof(NvmeErrorLog) != 64);
626
    QEMU_BUILD_BUG_ON(sizeof(NvmeFwSlotInfoLog) != 512);
627
    QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLog) != 512);
628
    QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrl) != 4096);
629
    QEMU_BUILD_BUG_ON(sizeof(NvmeIdNs) != 4096);
630
}
631

    
632
typedef struct NvmeAsyncEvent {
633
    QSIMPLEQ_ENTRY(NvmeAsyncEvent) entry;
634
    NvmeAerResult result;
635
} NvmeAsyncEvent;
636

    
637
typedef struct NvmeRequest {
638
    struct NvmeSQueue       *sq;
639
    BlockDriverAIOCB        *aiocb;
640
    uint16_t                status;
641
    NvmeCqe                 cqe;
642
    BlockAcctCookie         acct;
643
    QEMUSGList              qsg;
644
    QTAILQ_ENTRY(NvmeRequest)entry;
645
} NvmeRequest;
646

    
647
typedef struct NvmeSQueue {
648
    struct NvmeCtrl *ctrl;
649
    uint16_t    sqid;
650
    uint16_t    cqid;
651
    uint32_t    head;
652
    uint32_t    tail;
653
    uint32_t    size;
654
    uint64_t    dma_addr;
655
    QEMUTimer   *timer;
656
    NvmeRequest *io_req;
657
    QTAILQ_HEAD(sq_req_list, NvmeRequest) req_list;
658
    QTAILQ_HEAD(out_req_list, NvmeRequest) out_req_list;
659
    QTAILQ_ENTRY(NvmeSQueue) entry;
660
} NvmeSQueue;
661

    
662
typedef struct NvmeCQueue {
663
    struct NvmeCtrl *ctrl;
664
    uint8_t     phase;
665
    uint16_t    cqid;
666
    uint16_t    irq_enabled;
667
    uint32_t    head;
668
    uint32_t    tail;
669
    uint32_t    vector;
670
    uint32_t    size;
671
    uint64_t    dma_addr;
672
    QEMUTimer   *timer;
673
    QTAILQ_HEAD(sq_list, NvmeSQueue) sq_list;
674
    QTAILQ_HEAD(cq_req_list, NvmeRequest) req_list;
675
} NvmeCQueue;
676

    
677
typedef struct NvmeNamespace {
678
    NvmeIdNs        id_ns;
679
} NvmeNamespace;
680

    
681
#define TYPE_NVME "nvme"
682
#define NVME(obj) \
683
        OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
684

    
685
typedef struct NvmeCtrl {
686
    PCIDevice    parent_obj;
687
    MemoryRegion iomem;
688
    NvmeBar      bar;
689
    BlockConf    conf;
690

    
691
    uint16_t    page_size;
692
    uint16_t    page_bits;
693
    uint16_t    max_prp_ents;
694
    uint16_t    cqe_size;
695
    uint16_t    sqe_size;
696
    uint32_t    reg_size;
697
    uint32_t    num_namespaces;
698
    uint32_t    num_queues;
699
    uint32_t    max_q_ents;
700
    uint64_t    ns_size;
701

    
702
    char            *serial;
703
    NvmeNamespace   *namespaces;
704
    NvmeSQueue      **sq;
705
    NvmeCQueue      **cq;
706
    NvmeSQueue      admin_sq;
707
    NvmeCQueue      admin_cq;
708
    NvmeIdCtrl      id_ctrl;
709
} NvmeCtrl;
710

    
711
#endif /* HW_NVME_H */