]> git.proxmox.com Git - mirror_qemu.git/blob - hw/block/nvme.h
hw/block/nvme: move msix table and pba to BAR 0
[mirror_qemu.git] / hw / block / nvme.h
1 #ifndef HW_NVME_H
2 #define HW_NVME_H
3
4 #include "block/nvme.h"
5 #include "nvme-ns.h"
6
7 #define NVME_MAX_NAMESPACES 256
8
9 #define NVME_DEFAULT_ZONE_SIZE (128 * MiB)
10 #define NVME_DEFAULT_MAX_ZA_SIZE (128 * KiB)
11
12 typedef struct NvmeParams {
13 char *serial;
14 uint32_t num_queues; /* deprecated since 5.1 */
15 uint32_t max_ioqpairs;
16 uint16_t msix_qsize;
17 uint32_t cmb_size_mb;
18 uint8_t aerl;
19 uint32_t aer_max_queued;
20 uint8_t mdts;
21 bool use_intel_id;
22 uint32_t zasl_bs;
23 } NvmeParams;
24
25 typedef struct NvmeAsyncEvent {
26 QTAILQ_ENTRY(NvmeAsyncEvent) entry;
27 NvmeAerResult result;
28 } NvmeAsyncEvent;
29
30 typedef struct NvmeRequest {
31 struct NvmeSQueue *sq;
32 struct NvmeNamespace *ns;
33 BlockAIOCB *aiocb;
34 uint16_t status;
35 void *opaque;
36 NvmeCqe cqe;
37 NvmeCmd cmd;
38 BlockAcctCookie acct;
39 QEMUSGList qsg;
40 QEMUIOVector iov;
41 QTAILQ_ENTRY(NvmeRequest)entry;
42 } NvmeRequest;
43
44 static inline const char *nvme_adm_opc_str(uint8_t opc)
45 {
46 switch (opc) {
47 case NVME_ADM_CMD_DELETE_SQ: return "NVME_ADM_CMD_DELETE_SQ";
48 case NVME_ADM_CMD_CREATE_SQ: return "NVME_ADM_CMD_CREATE_SQ";
49 case NVME_ADM_CMD_GET_LOG_PAGE: return "NVME_ADM_CMD_GET_LOG_PAGE";
50 case NVME_ADM_CMD_DELETE_CQ: return "NVME_ADM_CMD_DELETE_CQ";
51 case NVME_ADM_CMD_CREATE_CQ: return "NVME_ADM_CMD_CREATE_CQ";
52 case NVME_ADM_CMD_IDENTIFY: return "NVME_ADM_CMD_IDENTIFY";
53 case NVME_ADM_CMD_ABORT: return "NVME_ADM_CMD_ABORT";
54 case NVME_ADM_CMD_SET_FEATURES: return "NVME_ADM_CMD_SET_FEATURES";
55 case NVME_ADM_CMD_GET_FEATURES: return "NVME_ADM_CMD_GET_FEATURES";
56 case NVME_ADM_CMD_ASYNC_EV_REQ: return "NVME_ADM_CMD_ASYNC_EV_REQ";
57 default: return "NVME_ADM_CMD_UNKNOWN";
58 }
59 }
60
61 static inline const char *nvme_io_opc_str(uint8_t opc)
62 {
63 switch (opc) {
64 case NVME_CMD_FLUSH: return "NVME_NVM_CMD_FLUSH";
65 case NVME_CMD_WRITE: return "NVME_NVM_CMD_WRITE";
66 case NVME_CMD_READ: return "NVME_NVM_CMD_READ";
67 case NVME_CMD_COMPARE: return "NVME_NVM_CMD_COMPARE";
68 case NVME_CMD_WRITE_ZEROES: return "NVME_NVM_CMD_WRITE_ZEROES";
69 case NVME_CMD_DSM: return "NVME_NVM_CMD_DSM";
70 case NVME_CMD_ZONE_MGMT_SEND: return "NVME_ZONED_CMD_MGMT_SEND";
71 case NVME_CMD_ZONE_MGMT_RECV: return "NVME_ZONED_CMD_MGMT_RECV";
72 case NVME_CMD_ZONE_APPEND: return "NVME_ZONED_CMD_ZONE_APPEND";
73 default: return "NVME_NVM_CMD_UNKNOWN";
74 }
75 }
76
77 typedef struct NvmeSQueue {
78 struct NvmeCtrl *ctrl;
79 uint16_t sqid;
80 uint16_t cqid;
81 uint32_t head;
82 uint32_t tail;
83 uint32_t size;
84 uint64_t dma_addr;
85 QEMUTimer *timer;
86 NvmeRequest *io_req;
87 QTAILQ_HEAD(, NvmeRequest) req_list;
88 QTAILQ_HEAD(, NvmeRequest) out_req_list;
89 QTAILQ_ENTRY(NvmeSQueue) entry;
90 } NvmeSQueue;
91
92 typedef struct NvmeCQueue {
93 struct NvmeCtrl *ctrl;
94 uint8_t phase;
95 uint16_t cqid;
96 uint16_t irq_enabled;
97 uint32_t head;
98 uint32_t tail;
99 uint32_t vector;
100 uint32_t size;
101 uint64_t dma_addr;
102 QEMUTimer *timer;
103 QTAILQ_HEAD(, NvmeSQueue) sq_list;
104 QTAILQ_HEAD(, NvmeRequest) req_list;
105 } NvmeCQueue;
106
107 #define TYPE_NVME_BUS "nvme-bus"
108 #define NVME_BUS(obj) OBJECT_CHECK(NvmeBus, (obj), TYPE_NVME_BUS)
109
110 typedef struct NvmeBus {
111 BusState parent_bus;
112 } NvmeBus;
113
114 #define TYPE_NVME "nvme"
115 #define NVME(obj) \
116 OBJECT_CHECK(NvmeCtrl, (obj), TYPE_NVME)
117
118 typedef struct NvmeFeatureVal {
119 struct {
120 uint16_t temp_thresh_hi;
121 uint16_t temp_thresh_low;
122 };
123 uint32_t async_config;
124 } NvmeFeatureVal;
125
126 typedef struct NvmeCtrl {
127 PCIDevice parent_obj;
128 MemoryRegion bar0;
129 MemoryRegion iomem;
130 MemoryRegion ctrl_mem;
131 NvmeBar bar;
132 NvmeParams params;
133 NvmeBus bus;
134 BlockConf conf;
135
136 bool qs_created;
137 uint32_t page_size;
138 uint16_t page_bits;
139 uint16_t max_prp_ents;
140 uint16_t cqe_size;
141 uint16_t sqe_size;
142 uint32_t reg_size;
143 uint32_t num_namespaces;
144 uint32_t max_q_ents;
145 uint8_t outstanding_aers;
146 uint8_t *cmbuf;
147 uint32_t irq_status;
148 uint64_t host_timestamp; /* Timestamp sent by the host */
149 uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
150 uint64_t starttime_ms;
151 uint16_t temperature;
152 uint8_t smart_critical_warning;
153
154 HostMemoryBackend *pmrdev;
155
156 uint8_t aer_mask;
157 NvmeRequest **aer_reqs;
158 QTAILQ_HEAD(, NvmeAsyncEvent) aer_queue;
159 int aer_queued;
160
161 uint8_t zasl;
162
163 NvmeNamespace namespace;
164 NvmeNamespace *namespaces[NVME_MAX_NAMESPACES];
165 NvmeSQueue **sq;
166 NvmeCQueue **cq;
167 NvmeSQueue admin_sq;
168 NvmeCQueue admin_cq;
169 NvmeIdCtrl id_ctrl;
170 NvmeFeatureVal features;
171 } NvmeCtrl;
172
173 static inline NvmeNamespace *nvme_ns(NvmeCtrl *n, uint32_t nsid)
174 {
175 if (!nsid || nsid > n->num_namespaces) {
176 return NULL;
177 }
178
179 return n->namespaces[nsid - 1];
180 }
181
182 static inline NvmeCQueue *nvme_cq(NvmeRequest *req)
183 {
184 NvmeSQueue *sq = req->sq;
185 NvmeCtrl *n = sq->ctrl;
186
187 return n->cq[sq->cqid];
188 }
189
190 static inline NvmeCtrl *nvme_ctrl(NvmeRequest *req)
191 {
192 NvmeSQueue *sq = req->sq;
193 return sq->ctrl;
194 }
195
196 int nvme_register_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp);
197
198 #endif /* HW_NVME_H */