tests/avocado: add RISC-V OpenSBI boot test
[qemu.git] / hw / nvme / nvme.h
blob16da27a69bfbfd3b8710e46dc3a20b8a24ff8e7f
1 /*
2 * QEMU NVM Express
4 * Copyright (c) 2012 Intel Corporation
5 * Copyright (c) 2021 Minwoo Im
6 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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>
15 * This code is licensed under the GNU GPL v2 or later.
18 #ifndef HW_NVME_NVME_H
19 #define HW_NVME_NVME_H
21 #include "qemu/uuid.h"
22 #include "hw/pci/pci_device.h"
23 #include "hw/block/block.h"
25 #include "block/nvme.h"
27 #define NVME_MAX_CONTROLLERS 256
28 #define NVME_MAX_NAMESPACES 256
29 #define NVME_EUI64_DEFAULT ((uint64_t)0x5254000000000000)
31 QEMU_BUILD_BUG_ON(NVME_MAX_NAMESPACES > NVME_NSID_BROADCAST - 1);
33 typedef struct NvmeCtrl NvmeCtrl;
34 typedef struct NvmeNamespace NvmeNamespace;
36 #define TYPE_NVME_BUS "nvme-bus"
37 OBJECT_DECLARE_SIMPLE_TYPE(NvmeBus, NVME_BUS)
39 typedef struct NvmeBus {
40 BusState parent_bus;
41 } NvmeBus;
43 #define TYPE_NVME_SUBSYS "nvme-subsys"
44 #define NVME_SUBSYS(obj) \
45 OBJECT_CHECK(NvmeSubsystem, (obj), TYPE_NVME_SUBSYS)
46 #define SUBSYS_SLOT_RSVD (void *)0xFFFF
48 typedef struct NvmeSubsystem {
49 DeviceState parent_obj;
50 NvmeBus bus;
51 uint8_t subnqn[256];
52 char *serial;
54 NvmeCtrl *ctrls[NVME_MAX_CONTROLLERS];
55 NvmeNamespace *namespaces[NVME_MAX_NAMESPACES + 1];
57 struct {
58 char *nqn;
59 } params;
60 } NvmeSubsystem;
62 int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp);
63 void nvme_subsys_unregister_ctrl(NvmeSubsystem *subsys, NvmeCtrl *n);
65 static inline NvmeCtrl *nvme_subsys_ctrl(NvmeSubsystem *subsys,
66 uint32_t cntlid)
68 if (!subsys || cntlid >= NVME_MAX_CONTROLLERS) {
69 return NULL;
72 if (subsys->ctrls[cntlid] == SUBSYS_SLOT_RSVD) {
73 return NULL;
76 return subsys->ctrls[cntlid];
79 static inline NvmeNamespace *nvme_subsys_ns(NvmeSubsystem *subsys,
80 uint32_t nsid)
82 if (!subsys || !nsid || nsid > NVME_MAX_NAMESPACES) {
83 return NULL;
86 return subsys->namespaces[nsid];
89 #define TYPE_NVME_NS "nvme-ns"
90 #define NVME_NS(obj) \
91 OBJECT_CHECK(NvmeNamespace, (obj), TYPE_NVME_NS)
93 typedef struct NvmeZone {
94 NvmeZoneDescr d;
95 uint64_t w_ptr;
96 QTAILQ_ENTRY(NvmeZone) entry;
97 } NvmeZone;
99 typedef struct NvmeNamespaceParams {
100 bool detached;
101 bool shared;
102 uint32_t nsid;
103 QemuUUID uuid;
104 uint64_t eui64;
105 bool eui64_default;
107 uint16_t ms;
108 uint8_t mset;
109 uint8_t pi;
110 uint8_t pil;
111 uint8_t pif;
113 uint16_t mssrl;
114 uint32_t mcl;
115 uint8_t msrc;
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;
125 uint32_t numzrwa;
126 uint64_t zrwas;
127 uint64_t zrwafg;
128 } NvmeNamespaceParams;
130 typedef struct NvmeNamespace {
131 DeviceState parent_obj;
132 BlockConf blkconf;
133 int32_t bootindex;
134 int64_t size;
135 int64_t moff;
136 NvmeIdNs id_ns;
137 NvmeIdNsNvm id_ns_nvm;
138 NvmeLBAF lbaf;
139 unsigned int nlbaf;
140 size_t lbasz;
141 const uint32_t *iocs;
142 uint8_t csi;
143 uint16_t status;
144 int attached;
145 uint8_t pif;
147 struct {
148 uint16_t zrwas;
149 uint16_t zrwafg;
150 uint32_t numzrwa;
151 } zns;
153 QTAILQ_ENTRY(NvmeNamespace) entry;
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;
169 NvmeNamespaceParams params;
171 struct {
172 uint32_t err_rec;
173 } features;
174 } NvmeNamespace;
176 static inline uint32_t nvme_nsid(NvmeNamespace *ns)
178 if (ns) {
179 return ns->params.nsid;
182 return 0;
185 static inline size_t nvme_l2b(NvmeNamespace *ns, uint64_t lba)
187 return lba << ns->lbaf.ds;
190 static inline size_t nvme_m2b(NvmeNamespace *ns, uint64_t lba)
192 return ns->lbaf.ms * lba;
195 static inline int64_t nvme_moff(NvmeNamespace *ns, uint64_t lba)
197 return ns->moff + nvme_m2b(ns, lba);
200 static inline bool nvme_ns_ext(NvmeNamespace *ns)
202 return !!NVME_ID_NS_FLBAS_EXTENDED(ns->id_ns.flbas);
205 static inline NvmeZoneState nvme_get_zone_state(NvmeZone *zone)
207 return zone->d.zs >> 4;
210 static inline void nvme_set_zone_state(NvmeZone *zone, NvmeZoneState state)
212 zone->d.zs = state << 4;
215 static inline uint64_t nvme_zone_rd_boundary(NvmeNamespace *ns, NvmeZone *zone)
217 return zone->d.zslba + ns->zone_size;
220 static inline uint64_t nvme_zone_wr_boundary(NvmeZone *zone)
222 return zone->d.zslba + zone->d.zcap;
225 static inline bool nvme_wp_is_valid(NvmeZone *zone)
227 uint8_t st = nvme_get_zone_state(zone);
229 return st != NVME_ZONE_STATE_FULL &&
230 st != NVME_ZONE_STATE_READ_ONLY &&
231 st != NVME_ZONE_STATE_OFFLINE;
234 static inline uint8_t *nvme_get_zd_extension(NvmeNamespace *ns,
235 uint32_t zone_idx)
237 return &ns->zd_extensions[zone_idx * ns->params.zd_extension_size];
240 static inline void nvme_aor_inc_open(NvmeNamespace *ns)
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);
249 static inline void nvme_aor_dec_open(NvmeNamespace *ns)
251 if (ns->params.max_open_zones) {
252 assert(ns->nr_open_zones > 0);
253 ns->nr_open_zones--;
255 assert(ns->nr_open_zones >= 0);
258 static inline void nvme_aor_inc_active(NvmeNamespace *ns)
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);
267 static inline void nvme_aor_dec_active(NvmeNamespace *ns)
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);
274 assert(ns->nr_active_zones >= 0);
277 void nvme_ns_init_format(NvmeNamespace *ns);
278 int nvme_ns_setup(NvmeNamespace *ns, Error **errp);
279 void nvme_ns_drain(NvmeNamespace *ns);
280 void nvme_ns_shutdown(NvmeNamespace *ns);
281 void nvme_ns_cleanup(NvmeNamespace *ns);
283 typedef struct NvmeAsyncEvent {
284 QTAILQ_ENTRY(NvmeAsyncEvent) entry;
285 NvmeAerResult result;
286 } NvmeAsyncEvent;
288 enum {
289 NVME_SG_ALLOC = 1 << 0,
290 NVME_SG_DMA = 1 << 1,
293 typedef struct NvmeSg {
294 int flags;
296 union {
297 QEMUSGList qsg;
298 QEMUIOVector iov;
300 } NvmeSg;
302 typedef enum NvmeTxDirection {
303 NVME_TX_DIRECTION_TO_DEVICE = 0,
304 NVME_TX_DIRECTION_FROM_DEVICE = 1,
305 } NvmeTxDirection;
307 typedef struct NvmeRequest {
308 struct NvmeSQueue *sq;
309 struct NvmeNamespace *ns;
310 BlockAIOCB *aiocb;
311 uint16_t status;
312 void *opaque;
313 NvmeCqe cqe;
314 NvmeCmd cmd;
315 BlockAcctCookie acct;
316 NvmeSg sg;
317 QTAILQ_ENTRY(NvmeRequest)entry;
318 } NvmeRequest;
320 typedef struct NvmeBounceContext {
321 NvmeRequest *req;
323 struct {
324 QEMUIOVector iov;
325 uint8_t *bounce;
326 } data, mdata;
327 } NvmeBounceContext;
329 static inline const char *nvme_adm_opc_str(uint8_t opc)
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";
342 case NVME_ADM_CMD_NS_ATTACHMENT: return "NVME_ADM_CMD_NS_ATTACHMENT";
343 case NVME_ADM_CMD_VIRT_MNGMT: return "NVME_ADM_CMD_VIRT_MNGMT";
344 case NVME_ADM_CMD_DBBUF_CONFIG: return "NVME_ADM_CMD_DBBUF_CONFIG";
345 case NVME_ADM_CMD_FORMAT_NVM: return "NVME_ADM_CMD_FORMAT_NVM";
346 default: return "NVME_ADM_CMD_UNKNOWN";
350 static inline const char *nvme_io_opc_str(uint8_t opc)
352 switch (opc) {
353 case NVME_CMD_FLUSH: return "NVME_NVM_CMD_FLUSH";
354 case NVME_CMD_WRITE: return "NVME_NVM_CMD_WRITE";
355 case NVME_CMD_READ: return "NVME_NVM_CMD_READ";
356 case NVME_CMD_COMPARE: return "NVME_NVM_CMD_COMPARE";
357 case NVME_CMD_WRITE_ZEROES: return "NVME_NVM_CMD_WRITE_ZEROES";
358 case NVME_CMD_DSM: return "NVME_NVM_CMD_DSM";
359 case NVME_CMD_VERIFY: return "NVME_NVM_CMD_VERIFY";
360 case NVME_CMD_COPY: return "NVME_NVM_CMD_COPY";
361 case NVME_CMD_ZONE_MGMT_SEND: return "NVME_ZONED_CMD_MGMT_SEND";
362 case NVME_CMD_ZONE_MGMT_RECV: return "NVME_ZONED_CMD_MGMT_RECV";
363 case NVME_CMD_ZONE_APPEND: return "NVME_ZONED_CMD_ZONE_APPEND";
364 default: return "NVME_NVM_CMD_UNKNOWN";
368 typedef struct NvmeSQueue {
369 struct NvmeCtrl *ctrl;
370 uint16_t sqid;
371 uint16_t cqid;
372 uint32_t head;
373 uint32_t tail;
374 uint32_t size;
375 uint64_t dma_addr;
376 uint64_t db_addr;
377 uint64_t ei_addr;
378 QEMUBH *bh;
379 EventNotifier notifier;
380 bool ioeventfd_enabled;
381 NvmeRequest *io_req;
382 QTAILQ_HEAD(, NvmeRequest) req_list;
383 QTAILQ_HEAD(, NvmeRequest) out_req_list;
384 QTAILQ_ENTRY(NvmeSQueue) entry;
385 } NvmeSQueue;
387 typedef struct NvmeCQueue {
388 struct NvmeCtrl *ctrl;
389 uint8_t phase;
390 uint16_t cqid;
391 uint16_t irq_enabled;
392 uint32_t head;
393 uint32_t tail;
394 uint32_t vector;
395 uint32_t size;
396 uint64_t dma_addr;
397 uint64_t db_addr;
398 uint64_t ei_addr;
399 QEMUBH *bh;
400 EventNotifier notifier;
401 bool ioeventfd_enabled;
402 QTAILQ_HEAD(, NvmeSQueue) sq_list;
403 QTAILQ_HEAD(, NvmeRequest) req_list;
404 } NvmeCQueue;
406 #define TYPE_NVME "nvme"
407 #define NVME(obj) \
408 OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
410 typedef struct NvmeParams {
411 char *serial;
412 uint32_t num_queues; /* deprecated since 5.1 */
413 uint32_t max_ioqpairs;
414 uint16_t msix_qsize;
415 uint32_t cmb_size_mb;
416 uint8_t aerl;
417 uint32_t aer_max_queued;
418 uint8_t mdts;
419 uint8_t vsl;
420 bool use_intel_id;
421 uint8_t zasl;
422 bool auto_transition_zones;
423 bool legacy_cmb;
424 bool ioeventfd;
425 uint8_t sriov_max_vfs;
426 uint16_t sriov_vq_flexible;
427 uint16_t sriov_vi_flexible;
428 uint8_t sriov_max_vq_per_vf;
429 uint8_t sriov_max_vi_per_vf;
430 } NvmeParams;
432 typedef struct NvmeCtrl {
433 PCIDevice parent_obj;
434 MemoryRegion bar0;
435 MemoryRegion iomem;
436 NvmeBar bar;
437 NvmeParams params;
438 NvmeBus bus;
440 uint16_t cntlid;
441 bool qs_created;
442 uint32_t page_size;
443 uint16_t page_bits;
444 uint16_t max_prp_ents;
445 uint16_t cqe_size;
446 uint16_t sqe_size;
447 uint32_t max_q_ents;
448 uint8_t outstanding_aers;
449 uint32_t irq_status;
450 int cq_pending;
451 uint64_t host_timestamp; /* Timestamp sent by the host */
452 uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
453 uint64_t starttime_ms;
454 uint16_t temperature;
455 uint8_t smart_critical_warning;
456 uint32_t conf_msix_qsize;
457 uint32_t conf_ioqpairs;
458 uint64_t dbbuf_dbs;
459 uint64_t dbbuf_eis;
460 bool dbbuf_enabled;
462 struct {
463 MemoryRegion mem;
464 uint8_t *buf;
465 bool cmse;
466 hwaddr cba;
467 } cmb;
469 struct {
470 HostMemoryBackend *dev;
471 bool cmse;
472 hwaddr cba;
473 } pmr;
475 uint8_t aer_mask;
476 NvmeRequest **aer_reqs;
477 QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue;
478 int aer_queued;
480 uint32_t dmrsl;
482 /* Namespace ID is started with 1 so bitmap should be 1-based */
483 #define NVME_CHANGED_NSID_SIZE (NVME_MAX_NAMESPACES + 1)
484 DECLARE_BITMAP(changed_nsids, NVME_CHANGED_NSID_SIZE);
486 NvmeSubsystem *subsys;
488 NvmeNamespace namespace;
489 NvmeNamespace *namespaces[NVME_MAX_NAMESPACES + 1];
490 NvmeSQueue **sq;
491 NvmeCQueue **cq;
492 NvmeSQueue admin_sq;
493 NvmeCQueue admin_cq;
494 NvmeIdCtrl id_ctrl;
496 struct {
497 struct {
498 uint16_t temp_thresh_hi;
499 uint16_t temp_thresh_low;
502 uint32_t async_config;
503 NvmeHostBehaviorSupport hbs;
504 } features;
506 NvmePriCtrlCap pri_ctrl_cap;
507 NvmeSecCtrlList sec_ctrl_list;
508 struct {
509 uint16_t vqrfap;
510 uint16_t virfap;
511 } next_pri_ctrl_cap; /* These override pri_ctrl_cap after reset */
512 } NvmeCtrl;
514 typedef enum NvmeResetType {
515 NVME_RESET_FUNCTION = 0,
516 NVME_RESET_CONTROLLER = 1,
517 } NvmeResetType;
519 static inline NvmeNamespace *nvme_ns(NvmeCtrl *n, uint32_t nsid)
521 if (!nsid || nsid > NVME_MAX_NAMESPACES) {
522 return NULL;
525 return n->namespaces[nsid];
528 static inline NvmeCQueue *nvme_cq(NvmeRequest *req)
530 NvmeSQueue *sq = req->sq;
531 NvmeCtrl *n = sq->ctrl;
533 return n->cq[sq->cqid];
536 static inline NvmeCtrl *nvme_ctrl(NvmeRequest *req)
538 NvmeSQueue *sq = req->sq;
539 return sq->ctrl;
542 static inline uint16_t nvme_cid(NvmeRequest *req)
544 if (!req) {
545 return 0xffff;
548 return le16_to_cpu(req->cqe.cid);
551 static inline NvmeSecCtrlEntry *nvme_sctrl(NvmeCtrl *n)
553 PCIDevice *pci_dev = &n->parent_obj;
554 NvmeCtrl *pf = NVME(pcie_sriov_get_pf(pci_dev));
556 if (pci_is_vf(pci_dev)) {
557 return &pf->sec_ctrl_list.sec[pcie_sriov_vf_number(pci_dev)];
560 return NULL;
563 static inline NvmeSecCtrlEntry *nvme_sctrl_for_cntlid(NvmeCtrl *n,
564 uint16_t cntlid)
566 NvmeSecCtrlList *list = &n->sec_ctrl_list;
567 uint8_t i;
569 for (i = 0; i < list->numcntl; i++) {
570 if (le16_to_cpu(list->sec[i].scid) == cntlid) {
571 return &list->sec[i];
575 return NULL;
578 void nvme_attach_ns(NvmeCtrl *n, NvmeNamespace *ns);
579 uint16_t nvme_bounce_data(NvmeCtrl *n, void *ptr, uint32_t len,
580 NvmeTxDirection dir, NvmeRequest *req);
581 uint16_t nvme_bounce_mdata(NvmeCtrl *n, void *ptr, uint32_t len,
582 NvmeTxDirection dir, NvmeRequest *req);
583 void nvme_rw_complete_cb(void *opaque, int ret);
584 uint16_t nvme_map_dptr(NvmeCtrl *n, NvmeSg *sg, size_t len,
585 NvmeCmd *cmd);
587 #endif /* HW_NVME_NVME_H */