]> git.proxmox.com Git - mirror_qemu.git/blame - hw/nvme/nvme.h
hw/nvme: clear aen mask on reset
[mirror_qemu.git] / hw / nvme / nvme.h
CommitLineData
d88e784f
KJ
1/*
2 * QEMU NVM Express
3 *
4 * Copyright (c) 2012 Intel Corporation
5 * Copyright (c) 2021 Minwoo Im
6 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
7 *
8 * Authors:
9 * Keith Busch <kbusch@kernel.org>
10 * Klaus Jensen <k.jensen@samsung.com>
11 * Gollu Appalanaidu <anaidu.gollu@samsung.com>
12 * Dmitry Fomichev <dmitry.fomichev@wdc.com>
13 * Minwoo Im <minwoo.im.dev@gmail.com>
14 *
15 * This code is licensed under the GNU GPL v2 or later.
16 */
17
52581c71
MA
18#ifndef HW_NVME_NVME_H
19#define HW_NVME_NVME_H
1065abfb 20
d88e784f 21#include "qemu/uuid.h"
146f720c 22#include "hw/pci/pci.h"
d88e784f
KJ
23#include "hw/block/block.h"
24
25#include "block/nvme.h"
7f0f1ace 26
44c2c094 27#define NVME_MAX_CONTROLLERS 256
d88e784f 28#define NVME_MAX_NAMESPACES 256
3276dde4 29#define NVME_EUI64_DEFAULT ((uint64_t)0x5254000000000000)
a479335b 30
38f4ac65
KJ
31QEMU_BUILD_BUG_ON(NVME_MAX_NAMESPACES > NVME_NSID_BROADCAST - 1);
32
d88e784f
KJ
33typedef struct NvmeCtrl NvmeCtrl;
34typedef struct NvmeNamespace NvmeNamespace;
35
5ffbaeed
KJ
36#define TYPE_NVME_BUS "nvme-bus"
37OBJECT_DECLARE_SIMPLE_TYPE(NvmeBus, NVME_BUS)
38
39typedef struct NvmeBus {
40 BusState parent_bus;
41} NvmeBus;
42
d88e784f
KJ
43#define TYPE_NVME_SUBSYS "nvme-subsys"
44#define NVME_SUBSYS(obj) \
45 OBJECT_CHECK(NvmeSubsystem, (obj), TYPE_NVME_SUBSYS)
99f48ae7 46#define SUBSYS_SLOT_RSVD (void *)0xFFFF
d88e784f
KJ
47
48typedef struct NvmeSubsystem {
49 DeviceState parent_obj;
5ffbaeed 50 NvmeBus bus;
d88e784f 51 uint8_t subnqn[256];
a859eb9f 52 char *serial;
d88e784f
KJ
53
54 NvmeCtrl *ctrls[NVME_MAX_CONTROLLERS];
55 NvmeNamespace *namespaces[NVME_MAX_NAMESPACES + 1];
56
57 struct {
58 char *nqn;
59 } params;
60} NvmeSubsystem;
61
62int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp);
b0fde9e8 63void nvme_subsys_unregister_ctrl(NvmeSubsystem *subsys, NvmeCtrl *n);
d88e784f
KJ
64
65static inline NvmeCtrl *nvme_subsys_ctrl(NvmeSubsystem *subsys,
66 uint32_t cntlid)
67{
68 if (!subsys || cntlid >= NVME_MAX_CONTROLLERS) {
69 return NULL;
70 }
71
99f48ae7
LM
72 if (subsys->ctrls[cntlid] == SUBSYS_SLOT_RSVD) {
73 return NULL;
74 }
75
d88e784f
KJ
76 return subsys->ctrls[cntlid];
77}
78
79static inline NvmeNamespace *nvme_subsys_ns(NvmeSubsystem *subsys,
80 uint32_t nsid)
81{
82 if (!subsys || !nsid || nsid > NVME_MAX_NAMESPACES) {
83 return NULL;
84 }
85
86 return subsys->namespaces[nsid];
87}
88
89#define TYPE_NVME_NS "nvme-ns"
90#define NVME_NS(obj) \
91 OBJECT_CHECK(NvmeNamespace, (obj), TYPE_NVME_NS)
92
93typedef struct NvmeZone {
94 NvmeZoneDescr d;
95 uint64_t w_ptr;
96 QTAILQ_ENTRY(NvmeZone) entry;
97} NvmeZone;
98
99typedef struct NvmeNamespaceParams {
100 bool detached;
101 bool shared;
102 uint32_t nsid;
103 QemuUUID uuid;
6870cfb8 104 uint64_t eui64;
3276dde4 105 bool eui64_default;
d88e784f
KJ
106
107 uint16_t ms;
108 uint8_t mset;
109 uint8_t pi;
110 uint8_t pil;
44219b60 111 uint8_t pif;
d88e784f
KJ
112
113 uint16_t mssrl;
114 uint32_t mcl;
115 uint8_t msrc;
116
117 bool zoned;
118 bool cross_zone_read;
119 uint64_t zone_size_bs;
120 uint64_t zone_cap_bs;
121 uint32_t max_active_zones;
122 uint32_t max_open_zones;
123 uint32_t zd_extension_size;
e321b4cd
KJ
124
125 uint32_t numzrwa;
126 uint64_t zrwas;
127 uint64_t zrwafg;
d88e784f
KJ
128} NvmeNamespaceParams;
129
130typedef struct NvmeNamespace {
131 DeviceState parent_obj;
132 BlockConf blkconf;
133 int32_t bootindex;
134 int64_t size;
3ef73f94 135 int64_t moff;
d88e784f 136 NvmeIdNs id_ns;
44219b60 137 NvmeIdNsNvm id_ns_nvm;
6146f3dd 138 NvmeLBAF lbaf;
763c05df 139 unsigned int nlbaf;
6146f3dd 140 size_t lbasz;
d88e784f
KJ
141 const uint32_t *iocs;
142 uint8_t csi;
143 uint16_t status;
144 int attached;
44219b60 145 uint8_t pif;
d88e784f 146
e321b4cd
KJ
147 struct {
148 uint16_t zrwas;
149 uint16_t zrwafg;
150 uint32_t numzrwa;
151 } zns;
152
d88e784f
KJ
153 QTAILQ_ENTRY(NvmeNamespace) entry;
154
155 NvmeIdNsZoned *id_ns_zoned;
156 NvmeZone *zone_array;
157 QTAILQ_HEAD(, NvmeZone) exp_open_zones;
158 QTAILQ_HEAD(, NvmeZone) imp_open_zones;
159 QTAILQ_HEAD(, NvmeZone) closed_zones;
160 QTAILQ_HEAD(, NvmeZone) full_zones;
161 uint32_t num_zones;
162 uint64_t zone_size;
163 uint64_t zone_capacity;
164 uint32_t zone_size_log2;
165 uint8_t *zd_extensions;
166 int32_t nr_open_zones;
167 int32_t nr_active_zones;
168
169 NvmeNamespaceParams params;
170
171 struct {
172 uint32_t err_rec;
173 } features;
174} NvmeNamespace;
175
d88e784f
KJ
176static inline uint32_t nvme_nsid(NvmeNamespace *ns)
177{
178 if (ns) {
179 return ns->params.nsid;
180 }
181
182 return 0;
183}
184
d88e784f
KJ
185static inline size_t nvme_l2b(NvmeNamespace *ns, uint64_t lba)
186{
6146f3dd 187 return lba << ns->lbaf.ds;
d88e784f
KJ
188}
189
190static inline size_t nvme_m2b(NvmeNamespace *ns, uint64_t lba)
191{
6146f3dd 192 return ns->lbaf.ms * lba;
d88e784f
KJ
193}
194
3ef73f94
KJ
195static inline int64_t nvme_moff(NvmeNamespace *ns, uint64_t lba)
196{
197 return ns->moff + nvme_m2b(ns, lba);
198}
199
d88e784f
KJ
200static inline bool nvme_ns_ext(NvmeNamespace *ns)
201{
202 return !!NVME_ID_NS_FLBAS_EXTENDED(ns->id_ns.flbas);
203}
204
d88e784f
KJ
205static inline NvmeZoneState nvme_get_zone_state(NvmeZone *zone)
206{
207 return zone->d.zs >> 4;
208}
209
210static inline void nvme_set_zone_state(NvmeZone *zone, NvmeZoneState state)
211{
212 zone->d.zs = state << 4;
213}
214
215static inline uint64_t nvme_zone_rd_boundary(NvmeNamespace *ns, NvmeZone *zone)
216{
217 return zone->d.zslba + ns->zone_size;
218}
219
220static inline uint64_t nvme_zone_wr_boundary(NvmeZone *zone)
221{
222 return zone->d.zslba + zone->d.zcap;
223}
224
225static inline bool nvme_wp_is_valid(NvmeZone *zone)
226{
227 uint8_t st = nvme_get_zone_state(zone);
228
229 return st != NVME_ZONE_STATE_FULL &&
230 st != NVME_ZONE_STATE_READ_ONLY &&
231 st != NVME_ZONE_STATE_OFFLINE;
232}
233
234static inline uint8_t *nvme_get_zd_extension(NvmeNamespace *ns,
235 uint32_t zone_idx)
236{
237 return &ns->zd_extensions[zone_idx * ns->params.zd_extension_size];
238}
239
240static inline void nvme_aor_inc_open(NvmeNamespace *ns)
241{
242 assert(ns->nr_open_zones >= 0);
243 if (ns->params.max_open_zones) {
244 ns->nr_open_zones++;
245 assert(ns->nr_open_zones <= ns->params.max_open_zones);
246 }
247}
248
249static inline void nvme_aor_dec_open(NvmeNamespace *ns)
250{
251 if (ns->params.max_open_zones) {
252 assert(ns->nr_open_zones > 0);
253 ns->nr_open_zones--;
254 }
255 assert(ns->nr_open_zones >= 0);
256}
257
258static inline void nvme_aor_inc_active(NvmeNamespace *ns)
259{
260 assert(ns->nr_active_zones >= 0);
261 if (ns->params.max_active_zones) {
262 ns->nr_active_zones++;
263 assert(ns->nr_active_zones <= ns->params.max_active_zones);
264 }
265}
266
267static inline void nvme_aor_dec_active(NvmeNamespace *ns)
268{
269 if (ns->params.max_active_zones) {
270 assert(ns->nr_active_zones > 0);
271 ns->nr_active_zones--;
272 assert(ns->nr_active_zones >= ns->nr_open_zones);
273 }
274 assert(ns->nr_active_zones >= 0);
275}
276
277void nvme_ns_init_format(NvmeNamespace *ns);
5e4f6bcc 278int nvme_ns_setup(NvmeNamespace *ns, Error **errp);
d88e784f
KJ
279void nvme_ns_drain(NvmeNamespace *ns);
280void nvme_ns_shutdown(NvmeNamespace *ns);
281void nvme_ns_cleanup(NvmeNamespace *ns);
1065abfb 282
f3c507ad 283typedef struct NvmeAsyncEvent {
5d5a5330 284 QTAILQ_ENTRY(NvmeAsyncEvent) entry;
f3c507ad
KB
285 NvmeAerResult result;
286} NvmeAsyncEvent;
287
f80a1c33
KJ
288enum {
289 NVME_SG_ALLOC = 1 << 0,
290 NVME_SG_DMA = 1 << 1,
291};
292
293typedef struct NvmeSg {
294 int flags;
295
296 union {
297 QEMUSGList qsg;
298 QEMUIOVector iov;
299 };
300} NvmeSg;
301
d88e784f
KJ
302typedef enum NvmeTxDirection {
303 NVME_TX_DIRECTION_TO_DEVICE = 0,
304 NVME_TX_DIRECTION_FROM_DEVICE = 1,
305} NvmeTxDirection;
306
f3c507ad
KB
307typedef struct NvmeRequest {
308 struct NvmeSQueue *sq;
3143df3d 309 struct NvmeNamespace *ns;
7c84b1b8 310 BlockAIOCB *aiocb;
f3c507ad 311 uint16_t status;
2605257a 312 void *opaque;
f3c507ad 313 NvmeCqe cqe;
3143df3d 314 NvmeCmd cmd;
f3c507ad 315 BlockAcctCookie acct;
f80a1c33 316 NvmeSg sg;
f3c507ad
KB
317 QTAILQ_ENTRY(NvmeRequest)entry;
318} NvmeRequest;
319
146f720c
KJ
320typedef struct NvmeBounceContext {
321 NvmeRequest *req;
322
323 struct {
324 QEMUIOVector iov;
325 uint8_t *bounce;
326 } data, mdata;
327} NvmeBounceContext;
328
e2f79209
KJ
329static inline const char *nvme_adm_opc_str(uint8_t opc)
330{
331 switch (opc) {
332 case NVME_ADM_CMD_DELETE_SQ: return "NVME_ADM_CMD_DELETE_SQ";
333 case NVME_ADM_CMD_CREATE_SQ: return "NVME_ADM_CMD_CREATE_SQ";
334 case NVME_ADM_CMD_GET_LOG_PAGE: return "NVME_ADM_CMD_GET_LOG_PAGE";
335 case NVME_ADM_CMD_DELETE_CQ: return "NVME_ADM_CMD_DELETE_CQ";
336 case NVME_ADM_CMD_CREATE_CQ: return "NVME_ADM_CMD_CREATE_CQ";
337 case NVME_ADM_CMD_IDENTIFY: return "NVME_ADM_CMD_IDENTIFY";
338 case NVME_ADM_CMD_ABORT: return "NVME_ADM_CMD_ABORT";
339 case NVME_ADM_CMD_SET_FEATURES: return "NVME_ADM_CMD_SET_FEATURES";
340 case NVME_ADM_CMD_GET_FEATURES: return "NVME_ADM_CMD_GET_FEATURES";
341 case NVME_ADM_CMD_ASYNC_EV_REQ: return "NVME_ADM_CMD_ASYNC_EV_REQ";
349bf41d 342 case NVME_ADM_CMD_NS_ATTACHMENT: return "NVME_ADM_CMD_NS_ATTACHMENT";
11871f53 343 case NVME_ADM_CMD_VIRT_MNGMT: return "NVME_ADM_CMD_VIRT_MNGMT";
dc04d25e 344 case NVME_ADM_CMD_FORMAT_NVM: return "NVME_ADM_CMD_FORMAT_NVM";
e2f79209
KJ
345 default: return "NVME_ADM_CMD_UNKNOWN";
346 }
347}
348
349static inline const char *nvme_io_opc_str(uint8_t opc)
350{
351 switch (opc) {
352 case NVME_CMD_FLUSH: return "NVME_NVM_CMD_FLUSH";
353 case NVME_CMD_WRITE: return "NVME_NVM_CMD_WRITE";
354 case NVME_CMD_READ: return "NVME_NVM_CMD_READ";
cd42771a 355 case NVME_CMD_COMPARE: return "NVME_NVM_CMD_COMPARE";
e2f79209 356 case NVME_CMD_WRITE_ZEROES: return "NVME_NVM_CMD_WRITE_ZEROES";
2605257a 357 case NVME_CMD_DSM: return "NVME_NVM_CMD_DSM";
3e1da158 358 case NVME_CMD_VERIFY: return "NVME_NVM_CMD_VERIFY";
e4e430b3 359 case NVME_CMD_COPY: return "NVME_NVM_CMD_COPY";
cd42771a
KJ
360 case NVME_CMD_ZONE_MGMT_SEND: return "NVME_ZONED_CMD_MGMT_SEND";
361 case NVME_CMD_ZONE_MGMT_RECV: return "NVME_ZONED_CMD_MGMT_RECV";
362 case NVME_CMD_ZONE_APPEND: return "NVME_ZONED_CMD_ZONE_APPEND";
e2f79209
KJ
363 default: return "NVME_NVM_CMD_UNKNOWN";
364 }
365}
366
f3c507ad
KB
367typedef struct NvmeSQueue {
368 struct NvmeCtrl *ctrl;
369 uint16_t sqid;
370 uint16_t cqid;
371 uint32_t head;
372 uint32_t tail;
373 uint32_t size;
374 uint64_t dma_addr;
375 QEMUTimer *timer;
376 NvmeRequest *io_req;
b58deb34
PB
377 QTAILQ_HEAD(, NvmeRequest) req_list;
378 QTAILQ_HEAD(, NvmeRequest) out_req_list;
f3c507ad
KB
379 QTAILQ_ENTRY(NvmeSQueue) entry;
380} NvmeSQueue;
381
382typedef struct NvmeCQueue {
383 struct NvmeCtrl *ctrl;
384 uint8_t phase;
385 uint16_t cqid;
386 uint16_t irq_enabled;
387 uint32_t head;
388 uint32_t tail;
389 uint32_t vector;
390 uint32_t size;
391 uint64_t dma_addr;
392 QEMUTimer *timer;
b58deb34
PB
393 QTAILQ_HEAD(, NvmeSQueue) sq_list;
394 QTAILQ_HEAD(, NvmeRequest) req_list;
f3c507ad
KB
395} NvmeCQueue;
396
f3c507ad
KB
397#define TYPE_NVME "nvme"
398#define NVME(obj) \
399 OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
400
d88e784f
KJ
401typedef struct NvmeParams {
402 char *serial;
403 uint32_t num_queues; /* deprecated since 5.1 */
404 uint32_t max_ioqpairs;
405 uint16_t msix_qsize;
406 uint32_t cmb_size_mb;
407 uint8_t aerl;
408 uint32_t aer_max_queued;
409 uint8_t mdts;
410 uint8_t vsl;
411 bool use_intel_id;
412 uint8_t zasl;
cccc2651 413 bool auto_transition_zones;
d88e784f 414 bool legacy_cmb;
44c2c094 415 uint8_t sriov_max_vfs;
746d42b1
ŁG
416 uint16_t sriov_vq_flexible;
417 uint16_t sriov_vi_flexible;
418 uint8_t sriov_max_vq_per_vf;
419 uint8_t sriov_max_vi_per_vf;
d88e784f 420} NvmeParams;
46ac29c3 421
f3c507ad
KB
422typedef struct NvmeCtrl {
423 PCIDevice parent_obj;
1901b496 424 MemoryRegion bar0;
f3c507ad
KB
425 MemoryRegion iomem;
426 NvmeBar bar;
1065abfb 427 NvmeParams params;
7f0f1ace 428 NvmeBus bus;
f3c507ad 429
e36a261d 430 uint16_t cntlid;
9e7ecdca 431 bool qs_created;
be0677a9 432 uint32_t page_size;
f3c507ad
KB
433 uint16_t page_bits;
434 uint16_t max_prp_ents;
435 uint16_t cqe_size;
436 uint16_t sqe_size;
f3c507ad 437 uint32_t max_q_ents;
5d5a5330 438 uint8_t outstanding_aers;
ca247d35 439 uint32_t irq_status;
83d7ed5c 440 int cq_pending;
3036a626
KH
441 uint64_t host_timestamp; /* Timestamp sent by the host */
442 uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
94a7897c
KJ
443 uint64_t starttime_ms;
444 uint16_t temperature;
4714791b 445 uint8_t smart_critical_warning;
decc0261
ŁG
446 uint32_t conf_msix_qsize;
447 uint32_t conf_ioqpairs;
f3c507ad 448
f4319477
PK
449 struct {
450 MemoryRegion mem;
451 uint8_t *buf;
452 bool cmse;
453 hwaddr cba;
454 } cmb;
455
7ec9f2ee
NN
456 struct {
457 HostMemoryBackend *dev;
458 bool cmse;
459 hwaddr cba;
460 } pmr;
6cf94132 461
5d5a5330
KJ
462 uint8_t aer_mask;
463 NvmeRequest **aer_reqs;
464 QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue;
465 int aer_queued;
466
67ce28a1
GA
467 uint32_t dmrsl;
468
f432fdfa
MI
469 /* Namespace ID is started with 1 so bitmap should be 1-based */
470#define NVME_CHANGED_NSID_SIZE (NVME_MAX_NAMESPACES + 1)
471 DECLARE_BITMAP(changed_nsids, NVME_CHANGED_NSID_SIZE);
472
982ed66b
MI
473 NvmeSubsystem *subsys;
474
7f0f1ace 475 NvmeNamespace namespace;
72ea5c2c 476 NvmeNamespace *namespaces[NVME_MAX_NAMESPACES + 1];
f3c507ad
KB
477 NvmeSQueue **sq;
478 NvmeCQueue **cq;
479 NvmeSQueue admin_sq;
480 NvmeCQueue admin_cq;
481 NvmeIdCtrl id_ctrl;
d88e784f
KJ
482
483 struct {
484 struct {
485 uint16_t temp_thresh_hi;
486 uint16_t temp_thresh_low;
487 };
d0c0697b
NN
488
489 uint32_t async_config;
490 NvmeHostBehaviorSupport hbs;
d88e784f 491 } features;
5e6f963f
LM
492
493 NvmePriCtrlCap pri_ctrl_cap;
99f48ae7 494 NvmeSecCtrlList sec_ctrl_list;
11871f53
ŁG
495 struct {
496 uint16_t vqrfap;
497 uint16_t virfap;
498 } next_pri_ctrl_cap; /* These override pri_ctrl_cap after reset */
f3c507ad
KB
499} NvmeCtrl;
500
1e9c685e
ŁG
501typedef enum NvmeResetType {
502 NVME_RESET_FUNCTION = 0,
503 NVME_RESET_CONTROLLER = 1,
504} NvmeResetType;
505
7f0f1ace 506static inline NvmeNamespace *nvme_ns(NvmeCtrl *n, uint32_t nsid)
3adee1c2 507{
d88e784f 508 if (!nsid || nsid > NVME_MAX_NAMESPACES) {
7f0f1ace
KJ
509 return NULL;
510 }
511
72ea5c2c 512 return n->namespaces[nsid];
3adee1c2
KJ
513}
514
6a09a3d7
KJ
515static inline NvmeCQueue *nvme_cq(NvmeRequest *req)
516{
517 NvmeSQueue *sq = req->sq;
518 NvmeCtrl *n = sq->ctrl;
519
520 return n->cq[sq->cqid];
521}
522
523static inline NvmeCtrl *nvme_ctrl(NvmeRequest *req)
524{
525 NvmeSQueue *sq = req->sq;
526 return sq->ctrl;
527}
528
146f720c
KJ
529static inline uint16_t nvme_cid(NvmeRequest *req)
530{
531 if (!req) {
532 return 0xffff;
533 }
534
535 return le16_to_cpu(req->cqe.cid);
536}
537
99f48ae7
LM
538static inline NvmeSecCtrlEntry *nvme_sctrl(NvmeCtrl *n)
539{
540 PCIDevice *pci_dev = &n->parent_obj;
541 NvmeCtrl *pf = NVME(pcie_sriov_get_pf(pci_dev));
542
543 if (pci_is_vf(pci_dev)) {
544 return &pf->sec_ctrl_list.sec[pcie_sriov_vf_number(pci_dev)];
545 }
546
547 return NULL;
548}
549
11871f53
ŁG
550static inline NvmeSecCtrlEntry *nvme_sctrl_for_cntlid(NvmeCtrl *n,
551 uint16_t cntlid)
552{
553 NvmeSecCtrlList *list = &n->sec_ctrl_list;
554 uint8_t i;
555
556 for (i = 0; i < list->numcntl; i++) {
557 if (le16_to_cpu(list->sec[i].scid) == cntlid) {
558 return &list->sec[i];
559 }
560 }
561
562 return NULL;
563}
564
e5489356 565void nvme_attach_ns(NvmeCtrl *n, NvmeNamespace *ns);
8d3a17be 566uint16_t nvme_bounce_data(NvmeCtrl *n, void *ptr, uint32_t len,
146f720c 567 NvmeTxDirection dir, NvmeRequest *req);
8d3a17be 568uint16_t nvme_bounce_mdata(NvmeCtrl *n, void *ptr, uint32_t len,
146f720c
KJ
569 NvmeTxDirection dir, NvmeRequest *req);
570void nvme_rw_complete_cb(void *opaque, int ret);
571uint16_t nvme_map_dptr(NvmeCtrl *n, NvmeSg *sg, size_t len,
572 NvmeCmd *cmd);
7f0f1ace 573
52581c71 574#endif /* HW_NVME_NVME_H */