xref: /openbmc/qemu/include/block/nvme.h (revision 54064e51)
1a3d9a352SFam Zheng #ifndef BLOCK_NVME_H
2a3d9a352SFam Zheng #define BLOCK_NVME_H
3a3d9a352SFam Zheng 
4e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeBar {
5a3d9a352SFam Zheng     uint64_t    cap;
6a3d9a352SFam Zheng     uint32_t    vs;
7a3d9a352SFam Zheng     uint32_t    intms;
8a3d9a352SFam Zheng     uint32_t    intmc;
9a3d9a352SFam Zheng     uint32_t    cc;
10a3d9a352SFam Zheng     uint32_t    rsvd1;
11a3d9a352SFam Zheng     uint32_t    csts;
12a3d9a352SFam Zheng     uint32_t    nssrc;
13a3d9a352SFam Zheng     uint32_t    aqa;
14a3d9a352SFam Zheng     uint64_t    asq;
15a3d9a352SFam Zheng     uint64_t    acq;
16a3d9a352SFam Zheng     uint32_t    cmbloc;
17a3d9a352SFam Zheng     uint32_t    cmbsz;
186cf94132SAndrzej Jakowski     uint8_t     padding[3520]; /* not used by QEMU */
196cf94132SAndrzej Jakowski     uint32_t    pmrcap;
206cf94132SAndrzej Jakowski     uint32_t    pmrctl;
216cf94132SAndrzej Jakowski     uint32_t    pmrsts;
226cf94132SAndrzej Jakowski     uint32_t    pmrebs;
236cf94132SAndrzej Jakowski     uint32_t    pmrswtp;
24af4a367dSPhilippe Mathieu-Daudé     uint64_t    pmrmsc;
2574e18435SPhilippe Mathieu-Daudé     uint8_t     reserved[484];
26a3d9a352SFam Zheng } NvmeBar;
27a3d9a352SFam Zheng 
28a3d9a352SFam Zheng enum NvmeCapShift {
29a3d9a352SFam Zheng     CAP_MQES_SHIFT     = 0,
30a3d9a352SFam Zheng     CAP_CQR_SHIFT      = 16,
31a3d9a352SFam Zheng     CAP_AMS_SHIFT      = 17,
32a3d9a352SFam Zheng     CAP_TO_SHIFT       = 24,
33a3d9a352SFam Zheng     CAP_DSTRD_SHIFT    = 32,
34407d22ebSKlaus Jensen     CAP_NSSRS_SHIFT    = 36,
35a3d9a352SFam Zheng     CAP_CSS_SHIFT      = 37,
36a3d9a352SFam Zheng     CAP_MPSMIN_SHIFT   = 48,
37a3d9a352SFam Zheng     CAP_MPSMAX_SHIFT   = 52,
386cf94132SAndrzej Jakowski     CAP_PMR_SHIFT      = 56,
39a3d9a352SFam Zheng };
40a3d9a352SFam Zheng 
41a3d9a352SFam Zheng enum NvmeCapMask {
42a3d9a352SFam Zheng     CAP_MQES_MASK      = 0xffff,
43a3d9a352SFam Zheng     CAP_CQR_MASK       = 0x1,
44a3d9a352SFam Zheng     CAP_AMS_MASK       = 0x3,
45a3d9a352SFam Zheng     CAP_TO_MASK        = 0xff,
46a3d9a352SFam Zheng     CAP_DSTRD_MASK     = 0xf,
47a3d9a352SFam Zheng     CAP_NSSRS_MASK     = 0x1,
48a3d9a352SFam Zheng     CAP_CSS_MASK       = 0xff,
49a3d9a352SFam Zheng     CAP_MPSMIN_MASK    = 0xf,
50a3d9a352SFam Zheng     CAP_MPSMAX_MASK    = 0xf,
516cf94132SAndrzej Jakowski     CAP_PMR_MASK       = 0x1,
52a3d9a352SFam Zheng };
53a3d9a352SFam Zheng 
54a3d9a352SFam Zheng #define NVME_CAP_MQES(cap)  (((cap) >> CAP_MQES_SHIFT)   & CAP_MQES_MASK)
55a3d9a352SFam Zheng #define NVME_CAP_CQR(cap)   (((cap) >> CAP_CQR_SHIFT)    & CAP_CQR_MASK)
56a3d9a352SFam Zheng #define NVME_CAP_AMS(cap)   (((cap) >> CAP_AMS_SHIFT)    & CAP_AMS_MASK)
57a3d9a352SFam Zheng #define NVME_CAP_TO(cap)    (((cap) >> CAP_TO_SHIFT)     & CAP_TO_MASK)
58a3d9a352SFam Zheng #define NVME_CAP_DSTRD(cap) (((cap) >> CAP_DSTRD_SHIFT)  & CAP_DSTRD_MASK)
59a3d9a352SFam Zheng #define NVME_CAP_NSSRS(cap) (((cap) >> CAP_NSSRS_SHIFT)  & CAP_NSSRS_MASK)
60a3d9a352SFam Zheng #define NVME_CAP_CSS(cap)   (((cap) >> CAP_CSS_SHIFT)    & CAP_CSS_MASK)
61a3d9a352SFam Zheng #define NVME_CAP_MPSMIN(cap)(((cap) >> CAP_MPSMIN_SHIFT) & CAP_MPSMIN_MASK)
62a3d9a352SFam Zheng #define NVME_CAP_MPSMAX(cap)(((cap) >> CAP_MPSMAX_SHIFT) & CAP_MPSMAX_MASK)
63a3d9a352SFam Zheng 
64a3d9a352SFam Zheng #define NVME_CAP_SET_MQES(cap, val)   (cap |= (uint64_t)(val & CAP_MQES_MASK)  \
65a3d9a352SFam Zheng                                                            << CAP_MQES_SHIFT)
66a3d9a352SFam Zheng #define NVME_CAP_SET_CQR(cap, val)    (cap |= (uint64_t)(val & CAP_CQR_MASK)   \
67a3d9a352SFam Zheng                                                            << CAP_CQR_SHIFT)
68a3d9a352SFam Zheng #define NVME_CAP_SET_AMS(cap, val)    (cap |= (uint64_t)(val & CAP_AMS_MASK)   \
69a3d9a352SFam Zheng                                                            << CAP_AMS_SHIFT)
70a3d9a352SFam Zheng #define NVME_CAP_SET_TO(cap, val)     (cap |= (uint64_t)(val & CAP_TO_MASK)    \
71a3d9a352SFam Zheng                                                            << CAP_TO_SHIFT)
72a3d9a352SFam Zheng #define NVME_CAP_SET_DSTRD(cap, val)  (cap |= (uint64_t)(val & CAP_DSTRD_MASK) \
73a3d9a352SFam Zheng                                                            << CAP_DSTRD_SHIFT)
74a3d9a352SFam Zheng #define NVME_CAP_SET_NSSRS(cap, val)  (cap |= (uint64_t)(val & CAP_NSSRS_MASK) \
75a3d9a352SFam Zheng                                                            << CAP_NSSRS_SHIFT)
76a3d9a352SFam Zheng #define NVME_CAP_SET_CSS(cap, val)    (cap |= (uint64_t)(val & CAP_CSS_MASK)   \
77a3d9a352SFam Zheng                                                            << CAP_CSS_SHIFT)
78a3d9a352SFam Zheng #define NVME_CAP_SET_MPSMIN(cap, val) (cap |= (uint64_t)(val & CAP_MPSMIN_MASK)\
79a3d9a352SFam Zheng                                                            << CAP_MPSMIN_SHIFT)
80a3d9a352SFam Zheng #define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\
81a3d9a352SFam Zheng                                                             << CAP_MPSMAX_SHIFT)
826cf94132SAndrzej Jakowski #define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
836cf94132SAndrzej Jakowski                                                             << CAP_PMR_SHIFT)
84a3d9a352SFam Zheng 
85492f9a8dSKeith Busch enum NvmeCapCss {
86492f9a8dSKeith Busch     NVME_CAP_CSS_NVM        = 1 << 0,
878c5cea85SKeith Busch     NVME_CAP_CSS_ADMIN_ONLY = 1 << 7,
88492f9a8dSKeith Busch };
89492f9a8dSKeith Busch 
90a3d9a352SFam Zheng enum NvmeCcShift {
91a3d9a352SFam Zheng     CC_EN_SHIFT     = 0,
92a3d9a352SFam Zheng     CC_CSS_SHIFT    = 4,
93a3d9a352SFam Zheng     CC_MPS_SHIFT    = 7,
94a3d9a352SFam Zheng     CC_AMS_SHIFT    = 11,
95a3d9a352SFam Zheng     CC_SHN_SHIFT    = 14,
96a3d9a352SFam Zheng     CC_IOSQES_SHIFT = 16,
97a3d9a352SFam Zheng     CC_IOCQES_SHIFT = 20,
98a3d9a352SFam Zheng };
99a3d9a352SFam Zheng 
100a3d9a352SFam Zheng enum NvmeCcMask {
101a3d9a352SFam Zheng     CC_EN_MASK      = 0x1,
102a3d9a352SFam Zheng     CC_CSS_MASK     = 0x7,
103a3d9a352SFam Zheng     CC_MPS_MASK     = 0xf,
104a3d9a352SFam Zheng     CC_AMS_MASK     = 0x7,
105a3d9a352SFam Zheng     CC_SHN_MASK     = 0x3,
106a3d9a352SFam Zheng     CC_IOSQES_MASK  = 0xf,
107a3d9a352SFam Zheng     CC_IOCQES_MASK  = 0xf,
108a3d9a352SFam Zheng };
109a3d9a352SFam Zheng 
110a3d9a352SFam Zheng #define NVME_CC_EN(cc)     ((cc >> CC_EN_SHIFT)     & CC_EN_MASK)
111a3d9a352SFam Zheng #define NVME_CC_CSS(cc)    ((cc >> CC_CSS_SHIFT)    & CC_CSS_MASK)
112a3d9a352SFam Zheng #define NVME_CC_MPS(cc)    ((cc >> CC_MPS_SHIFT)    & CC_MPS_MASK)
113a3d9a352SFam Zheng #define NVME_CC_AMS(cc)    ((cc >> CC_AMS_SHIFT)    & CC_AMS_MASK)
114a3d9a352SFam Zheng #define NVME_CC_SHN(cc)    ((cc >> CC_SHN_SHIFT)    & CC_SHN_MASK)
115a3d9a352SFam Zheng #define NVME_CC_IOSQES(cc) ((cc >> CC_IOSQES_SHIFT) & CC_IOSQES_MASK)
116a3d9a352SFam Zheng #define NVME_CC_IOCQES(cc) ((cc >> CC_IOCQES_SHIFT) & CC_IOCQES_MASK)
117a3d9a352SFam Zheng 
1181b48e461SKlaus Jensen enum NvmeCcCss {
1191b48e461SKlaus Jensen     NVME_CC_CSS_NVM        = 0x0,
1201b48e461SKlaus Jensen     NVME_CC_CSS_ADMIN_ONLY = 0x7,
1211b48e461SKlaus Jensen };
1221b48e461SKlaus Jensen 
123a3d9a352SFam Zheng enum NvmeCstsShift {
124a3d9a352SFam Zheng     CSTS_RDY_SHIFT      = 0,
125a3d9a352SFam Zheng     CSTS_CFS_SHIFT      = 1,
126a3d9a352SFam Zheng     CSTS_SHST_SHIFT     = 2,
127a3d9a352SFam Zheng     CSTS_NSSRO_SHIFT    = 4,
128a3d9a352SFam Zheng };
129a3d9a352SFam Zheng 
130a3d9a352SFam Zheng enum NvmeCstsMask {
131a3d9a352SFam Zheng     CSTS_RDY_MASK   = 0x1,
132a3d9a352SFam Zheng     CSTS_CFS_MASK   = 0x1,
133a3d9a352SFam Zheng     CSTS_SHST_MASK  = 0x3,
134a3d9a352SFam Zheng     CSTS_NSSRO_MASK = 0x1,
135a3d9a352SFam Zheng };
136a3d9a352SFam Zheng 
137a3d9a352SFam Zheng enum NvmeCsts {
138a3d9a352SFam Zheng     NVME_CSTS_READY         = 1 << CSTS_RDY_SHIFT,
139a3d9a352SFam Zheng     NVME_CSTS_FAILED        = 1 << CSTS_CFS_SHIFT,
140a3d9a352SFam Zheng     NVME_CSTS_SHST_NORMAL   = 0 << CSTS_SHST_SHIFT,
141a3d9a352SFam Zheng     NVME_CSTS_SHST_PROGRESS = 1 << CSTS_SHST_SHIFT,
142a3d9a352SFam Zheng     NVME_CSTS_SHST_COMPLETE = 2 << CSTS_SHST_SHIFT,
143a3d9a352SFam Zheng     NVME_CSTS_NSSRO         = 1 << CSTS_NSSRO_SHIFT,
144a3d9a352SFam Zheng };
145a3d9a352SFam Zheng 
146a3d9a352SFam Zheng #define NVME_CSTS_RDY(csts)     ((csts >> CSTS_RDY_SHIFT)   & CSTS_RDY_MASK)
147a3d9a352SFam Zheng #define NVME_CSTS_CFS(csts)     ((csts >> CSTS_CFS_SHIFT)   & CSTS_CFS_MASK)
148a3d9a352SFam Zheng #define NVME_CSTS_SHST(csts)    ((csts >> CSTS_SHST_SHIFT)  & CSTS_SHST_MASK)
149a3d9a352SFam Zheng #define NVME_CSTS_NSSRO(csts)   ((csts >> CSTS_NSSRO_SHIFT) & CSTS_NSSRO_MASK)
150a3d9a352SFam Zheng 
151a3d9a352SFam Zheng enum NvmeAqaShift {
152a3d9a352SFam Zheng     AQA_ASQS_SHIFT  = 0,
153a3d9a352SFam Zheng     AQA_ACQS_SHIFT  = 16,
154a3d9a352SFam Zheng };
155a3d9a352SFam Zheng 
156a3d9a352SFam Zheng enum NvmeAqaMask {
157a3d9a352SFam Zheng     AQA_ASQS_MASK   = 0xfff,
158a3d9a352SFam Zheng     AQA_ACQS_MASK   = 0xfff,
159a3d9a352SFam Zheng };
160a3d9a352SFam Zheng 
161a3d9a352SFam Zheng #define NVME_AQA_ASQS(aqa) ((aqa >> AQA_ASQS_SHIFT) & AQA_ASQS_MASK)
162a3d9a352SFam Zheng #define NVME_AQA_ACQS(aqa) ((aqa >> AQA_ACQS_SHIFT) & AQA_ACQS_MASK)
163a3d9a352SFam Zheng 
164a3d9a352SFam Zheng enum NvmeCmblocShift {
165a3d9a352SFam Zheng     CMBLOC_BIR_SHIFT  = 0,
166a3d9a352SFam Zheng     CMBLOC_OFST_SHIFT = 12,
167a3d9a352SFam Zheng };
168a3d9a352SFam Zheng 
169a3d9a352SFam Zheng enum NvmeCmblocMask {
170a3d9a352SFam Zheng     CMBLOC_BIR_MASK  = 0x7,
171a3d9a352SFam Zheng     CMBLOC_OFST_MASK = 0xfffff,
172a3d9a352SFam Zheng };
173a3d9a352SFam Zheng 
174a3d9a352SFam Zheng #define NVME_CMBLOC_BIR(cmbloc) ((cmbloc >> CMBLOC_BIR_SHIFT)  & \
175a3d9a352SFam Zheng                                  CMBLOC_BIR_MASK)
176a3d9a352SFam Zheng #define NVME_CMBLOC_OFST(cmbloc)((cmbloc >> CMBLOC_OFST_SHIFT) & \
177a3d9a352SFam Zheng                                  CMBLOC_OFST_MASK)
178a3d9a352SFam Zheng 
179a3d9a352SFam Zheng #define NVME_CMBLOC_SET_BIR(cmbloc, val)  \
180a3d9a352SFam Zheng     (cmbloc |= (uint64_t)(val & CMBLOC_BIR_MASK) << CMBLOC_BIR_SHIFT)
181a3d9a352SFam Zheng #define NVME_CMBLOC_SET_OFST(cmbloc, val) \
182a3d9a352SFam Zheng     (cmbloc |= (uint64_t)(val & CMBLOC_OFST_MASK) << CMBLOC_OFST_SHIFT)
183a3d9a352SFam Zheng 
184a3d9a352SFam Zheng enum NvmeCmbszShift {
185a3d9a352SFam Zheng     CMBSZ_SQS_SHIFT   = 0,
186a3d9a352SFam Zheng     CMBSZ_CQS_SHIFT   = 1,
187a3d9a352SFam Zheng     CMBSZ_LISTS_SHIFT = 2,
188a3d9a352SFam Zheng     CMBSZ_RDS_SHIFT   = 3,
189a3d9a352SFam Zheng     CMBSZ_WDS_SHIFT   = 4,
190a3d9a352SFam Zheng     CMBSZ_SZU_SHIFT   = 8,
191a3d9a352SFam Zheng     CMBSZ_SZ_SHIFT    = 12,
192a3d9a352SFam Zheng };
193a3d9a352SFam Zheng 
194a3d9a352SFam Zheng enum NvmeCmbszMask {
195a3d9a352SFam Zheng     CMBSZ_SQS_MASK   = 0x1,
196a3d9a352SFam Zheng     CMBSZ_CQS_MASK   = 0x1,
197a3d9a352SFam Zheng     CMBSZ_LISTS_MASK = 0x1,
198a3d9a352SFam Zheng     CMBSZ_RDS_MASK   = 0x1,
199a3d9a352SFam Zheng     CMBSZ_WDS_MASK   = 0x1,
200a3d9a352SFam Zheng     CMBSZ_SZU_MASK   = 0xf,
201a3d9a352SFam Zheng     CMBSZ_SZ_MASK    = 0xfffff,
202a3d9a352SFam Zheng };
203a3d9a352SFam Zheng 
204a3d9a352SFam Zheng #define NVME_CMBSZ_SQS(cmbsz)  ((cmbsz >> CMBSZ_SQS_SHIFT)   & CMBSZ_SQS_MASK)
205a3d9a352SFam Zheng #define NVME_CMBSZ_CQS(cmbsz)  ((cmbsz >> CMBSZ_CQS_SHIFT)   & CMBSZ_CQS_MASK)
206a3d9a352SFam Zheng #define NVME_CMBSZ_LISTS(cmbsz)((cmbsz >> CMBSZ_LISTS_SHIFT) & CMBSZ_LISTS_MASK)
207a3d9a352SFam Zheng #define NVME_CMBSZ_RDS(cmbsz)  ((cmbsz >> CMBSZ_RDS_SHIFT)   & CMBSZ_RDS_MASK)
208a3d9a352SFam Zheng #define NVME_CMBSZ_WDS(cmbsz)  ((cmbsz >> CMBSZ_WDS_SHIFT)   & CMBSZ_WDS_MASK)
209a3d9a352SFam Zheng #define NVME_CMBSZ_SZU(cmbsz)  ((cmbsz >> CMBSZ_SZU_SHIFT)   & CMBSZ_SZU_MASK)
210a3d9a352SFam Zheng #define NVME_CMBSZ_SZ(cmbsz)   ((cmbsz >> CMBSZ_SZ_SHIFT)    & CMBSZ_SZ_MASK)
211a3d9a352SFam Zheng 
212a3d9a352SFam Zheng #define NVME_CMBSZ_SET_SQS(cmbsz, val)   \
213a3d9a352SFam Zheng     (cmbsz |= (uint64_t)(val &  CMBSZ_SQS_MASK)  << CMBSZ_SQS_SHIFT)
214a3d9a352SFam Zheng #define NVME_CMBSZ_SET_CQS(cmbsz, val)   \
215a3d9a352SFam Zheng     (cmbsz |= (uint64_t)(val & CMBSZ_CQS_MASK) << CMBSZ_CQS_SHIFT)
216a3d9a352SFam Zheng #define NVME_CMBSZ_SET_LISTS(cmbsz, val) \
217a3d9a352SFam Zheng     (cmbsz |= (uint64_t)(val & CMBSZ_LISTS_MASK) << CMBSZ_LISTS_SHIFT)
218a3d9a352SFam Zheng #define NVME_CMBSZ_SET_RDS(cmbsz, val)   \
219a3d9a352SFam Zheng     (cmbsz |= (uint64_t)(val & CMBSZ_RDS_MASK) << CMBSZ_RDS_SHIFT)
220a3d9a352SFam Zheng #define NVME_CMBSZ_SET_WDS(cmbsz, val)   \
221a3d9a352SFam Zheng     (cmbsz |= (uint64_t)(val & CMBSZ_WDS_MASK) << CMBSZ_WDS_SHIFT)
222a3d9a352SFam Zheng #define NVME_CMBSZ_SET_SZU(cmbsz, val)   \
223a3d9a352SFam Zheng     (cmbsz |= (uint64_t)(val & CMBSZ_SZU_MASK) << CMBSZ_SZU_SHIFT)
224a3d9a352SFam Zheng #define NVME_CMBSZ_SET_SZ(cmbsz, val)    \
225a3d9a352SFam Zheng     (cmbsz |= (uint64_t)(val & CMBSZ_SZ_MASK) << CMBSZ_SZ_SHIFT)
226a3d9a352SFam Zheng 
227a3d9a352SFam Zheng #define NVME_CMBSZ_GETSIZE(cmbsz) \
228a3d9a352SFam Zheng     (NVME_CMBSZ_SZ(cmbsz) * (1 << (12 + 4 * NVME_CMBSZ_SZU(cmbsz))))
229a3d9a352SFam Zheng 
2306cf94132SAndrzej Jakowski enum NvmePmrcapShift {
2316cf94132SAndrzej Jakowski     PMRCAP_RDS_SHIFT      = 3,
2326cf94132SAndrzej Jakowski     PMRCAP_WDS_SHIFT      = 4,
2336cf94132SAndrzej Jakowski     PMRCAP_BIR_SHIFT      = 5,
2346cf94132SAndrzej Jakowski     PMRCAP_PMRTU_SHIFT    = 8,
2356cf94132SAndrzej Jakowski     PMRCAP_PMRWBM_SHIFT   = 10,
2366cf94132SAndrzej Jakowski     PMRCAP_PMRTO_SHIFT    = 16,
2376cf94132SAndrzej Jakowski     PMRCAP_CMSS_SHIFT     = 24,
2386cf94132SAndrzej Jakowski };
2396cf94132SAndrzej Jakowski 
2406cf94132SAndrzej Jakowski enum NvmePmrcapMask {
2416cf94132SAndrzej Jakowski     PMRCAP_RDS_MASK      = 0x1,
2426cf94132SAndrzej Jakowski     PMRCAP_WDS_MASK      = 0x1,
2436cf94132SAndrzej Jakowski     PMRCAP_BIR_MASK      = 0x7,
2446cf94132SAndrzej Jakowski     PMRCAP_PMRTU_MASK    = 0x3,
2456cf94132SAndrzej Jakowski     PMRCAP_PMRWBM_MASK   = 0xf,
2466cf94132SAndrzej Jakowski     PMRCAP_PMRTO_MASK    = 0xff,
2476cf94132SAndrzej Jakowski     PMRCAP_CMSS_MASK     = 0x1,
2486cf94132SAndrzej Jakowski };
2496cf94132SAndrzej Jakowski 
2506cf94132SAndrzej Jakowski #define NVME_PMRCAP_RDS(pmrcap)    \
2516cf94132SAndrzej Jakowski     ((pmrcap >> PMRCAP_RDS_SHIFT)   & PMRCAP_RDS_MASK)
2526cf94132SAndrzej Jakowski #define NVME_PMRCAP_WDS(pmrcap)    \
2536cf94132SAndrzej Jakowski     ((pmrcap >> PMRCAP_WDS_SHIFT)   & PMRCAP_WDS_MASK)
2546cf94132SAndrzej Jakowski #define NVME_PMRCAP_BIR(pmrcap)    \
2556cf94132SAndrzej Jakowski     ((pmrcap >> PMRCAP_BIR_SHIFT)   & PMRCAP_BIR_MASK)
2566cf94132SAndrzej Jakowski #define NVME_PMRCAP_PMRTU(pmrcap)    \
2576cf94132SAndrzej Jakowski     ((pmrcap >> PMRCAP_PMRTU_SHIFT)   & PMRCAP_PMRTU_MASK)
2586cf94132SAndrzej Jakowski #define NVME_PMRCAP_PMRWBM(pmrcap)    \
2596cf94132SAndrzej Jakowski     ((pmrcap >> PMRCAP_PMRWBM_SHIFT)   & PMRCAP_PMRWBM_MASK)
2606cf94132SAndrzej Jakowski #define NVME_PMRCAP_PMRTO(pmrcap)    \
2616cf94132SAndrzej Jakowski     ((pmrcap >> PMRCAP_PMRTO_SHIFT)   & PMRCAP_PMRTO_MASK)
2626cf94132SAndrzej Jakowski #define NVME_PMRCAP_CMSS(pmrcap)    \
2636cf94132SAndrzej Jakowski     ((pmrcap >> PMRCAP_CMSS_SHIFT)   & PMRCAP_CMSS_MASK)
2646cf94132SAndrzej Jakowski 
2656cf94132SAndrzej Jakowski #define NVME_PMRCAP_SET_RDS(pmrcap, val)   \
2666cf94132SAndrzej Jakowski     (pmrcap |= (uint64_t)(val & PMRCAP_RDS_MASK) << PMRCAP_RDS_SHIFT)
2676cf94132SAndrzej Jakowski #define NVME_PMRCAP_SET_WDS(pmrcap, val)   \
2686cf94132SAndrzej Jakowski     (pmrcap |= (uint64_t)(val & PMRCAP_WDS_MASK) << PMRCAP_WDS_SHIFT)
2696cf94132SAndrzej Jakowski #define NVME_PMRCAP_SET_BIR(pmrcap, val)   \
2706cf94132SAndrzej Jakowski     (pmrcap |= (uint64_t)(val & PMRCAP_BIR_MASK) << PMRCAP_BIR_SHIFT)
2716cf94132SAndrzej Jakowski #define NVME_PMRCAP_SET_PMRTU(pmrcap, val)   \
2726cf94132SAndrzej Jakowski     (pmrcap |= (uint64_t)(val & PMRCAP_PMRTU_MASK) << PMRCAP_PMRTU_SHIFT)
2736cf94132SAndrzej Jakowski #define NVME_PMRCAP_SET_PMRWBM(pmrcap, val)   \
2746cf94132SAndrzej Jakowski     (pmrcap |= (uint64_t)(val & PMRCAP_PMRWBM_MASK) << PMRCAP_PMRWBM_SHIFT)
2756cf94132SAndrzej Jakowski #define NVME_PMRCAP_SET_PMRTO(pmrcap, val)   \
2766cf94132SAndrzej Jakowski     (pmrcap |= (uint64_t)(val & PMRCAP_PMRTO_MASK) << PMRCAP_PMRTO_SHIFT)
2776cf94132SAndrzej Jakowski #define NVME_PMRCAP_SET_CMSS(pmrcap, val)   \
2786cf94132SAndrzej Jakowski     (pmrcap |= (uint64_t)(val & PMRCAP_CMSS_MASK) << PMRCAP_CMSS_SHIFT)
2796cf94132SAndrzej Jakowski 
2806cf94132SAndrzej Jakowski enum NvmePmrctlShift {
2816cf94132SAndrzej Jakowski     PMRCTL_EN_SHIFT   = 0,
2826cf94132SAndrzej Jakowski };
2836cf94132SAndrzej Jakowski 
2846cf94132SAndrzej Jakowski enum NvmePmrctlMask {
2856cf94132SAndrzej Jakowski     PMRCTL_EN_MASK   = 0x1,
2866cf94132SAndrzej Jakowski };
2876cf94132SAndrzej Jakowski 
2886cf94132SAndrzej Jakowski #define NVME_PMRCTL_EN(pmrctl)  ((pmrctl >> PMRCTL_EN_SHIFT)   & PMRCTL_EN_MASK)
2896cf94132SAndrzej Jakowski 
2906cf94132SAndrzej Jakowski #define NVME_PMRCTL_SET_EN(pmrctl, val)   \
2916cf94132SAndrzej Jakowski     (pmrctl |= (uint64_t)(val & PMRCTL_EN_MASK) << PMRCTL_EN_SHIFT)
2926cf94132SAndrzej Jakowski 
2936cf94132SAndrzej Jakowski enum NvmePmrstsShift {
2946cf94132SAndrzej Jakowski     PMRSTS_ERR_SHIFT    = 0,
2956cf94132SAndrzej Jakowski     PMRSTS_NRDY_SHIFT   = 8,
2966cf94132SAndrzej Jakowski     PMRSTS_HSTS_SHIFT   = 9,
2976cf94132SAndrzej Jakowski     PMRSTS_CBAI_SHIFT   = 12,
2986cf94132SAndrzej Jakowski };
2996cf94132SAndrzej Jakowski 
3006cf94132SAndrzej Jakowski enum NvmePmrstsMask {
3016cf94132SAndrzej Jakowski     PMRSTS_ERR_MASK    = 0xff,
3026cf94132SAndrzej Jakowski     PMRSTS_NRDY_MASK   = 0x1,
3036cf94132SAndrzej Jakowski     PMRSTS_HSTS_MASK   = 0x7,
3046cf94132SAndrzej Jakowski     PMRSTS_CBAI_MASK   = 0x1,
3056cf94132SAndrzej Jakowski };
3066cf94132SAndrzej Jakowski 
3076cf94132SAndrzej Jakowski #define NVME_PMRSTS_ERR(pmrsts)     \
3086cf94132SAndrzej Jakowski     ((pmrsts >> PMRSTS_ERR_SHIFT)   & PMRSTS_ERR_MASK)
3096cf94132SAndrzej Jakowski #define NVME_PMRSTS_NRDY(pmrsts)    \
3106cf94132SAndrzej Jakowski     ((pmrsts >> PMRSTS_NRDY_SHIFT)   & PMRSTS_NRDY_MASK)
3116cf94132SAndrzej Jakowski #define NVME_PMRSTS_HSTS(pmrsts)    \
3126cf94132SAndrzej Jakowski     ((pmrsts >> PMRSTS_HSTS_SHIFT)   & PMRSTS_HSTS_MASK)
3136cf94132SAndrzej Jakowski #define NVME_PMRSTS_CBAI(pmrsts)    \
3146cf94132SAndrzej Jakowski     ((pmrsts >> PMRSTS_CBAI_SHIFT)   & PMRSTS_CBAI_MASK)
3156cf94132SAndrzej Jakowski 
3166cf94132SAndrzej Jakowski #define NVME_PMRSTS_SET_ERR(pmrsts, val)   \
3176cf94132SAndrzej Jakowski     (pmrsts |= (uint64_t)(val & PMRSTS_ERR_MASK) << PMRSTS_ERR_SHIFT)
3186cf94132SAndrzej Jakowski #define NVME_PMRSTS_SET_NRDY(pmrsts, val)   \
3196cf94132SAndrzej Jakowski     (pmrsts |= (uint64_t)(val & PMRSTS_NRDY_MASK) << PMRSTS_NRDY_SHIFT)
3206cf94132SAndrzej Jakowski #define NVME_PMRSTS_SET_HSTS(pmrsts, val)   \
3216cf94132SAndrzej Jakowski     (pmrsts |= (uint64_t)(val & PMRSTS_HSTS_MASK) << PMRSTS_HSTS_SHIFT)
3226cf94132SAndrzej Jakowski #define NVME_PMRSTS_SET_CBAI(pmrsts, val)   \
3236cf94132SAndrzej Jakowski     (pmrsts |= (uint64_t)(val & PMRSTS_CBAI_MASK) << PMRSTS_CBAI_SHIFT)
3246cf94132SAndrzej Jakowski 
3256cf94132SAndrzej Jakowski enum NvmePmrebsShift {
3266cf94132SAndrzej Jakowski     PMREBS_PMRSZU_SHIFT   = 0,
3276cf94132SAndrzej Jakowski     PMREBS_RBB_SHIFT      = 4,
3286cf94132SAndrzej Jakowski     PMREBS_PMRWBZ_SHIFT   = 8,
3296cf94132SAndrzej Jakowski };
3306cf94132SAndrzej Jakowski 
3316cf94132SAndrzej Jakowski enum NvmePmrebsMask {
3326cf94132SAndrzej Jakowski     PMREBS_PMRSZU_MASK   = 0xf,
3336cf94132SAndrzej Jakowski     PMREBS_RBB_MASK      = 0x1,
3346cf94132SAndrzej Jakowski     PMREBS_PMRWBZ_MASK   = 0xffffff,
3356cf94132SAndrzej Jakowski };
3366cf94132SAndrzej Jakowski 
3376cf94132SAndrzej Jakowski #define NVME_PMREBS_PMRSZU(pmrebs)  \
3386cf94132SAndrzej Jakowski     ((pmrebs >> PMREBS_PMRSZU_SHIFT)   & PMREBS_PMRSZU_MASK)
3396cf94132SAndrzej Jakowski #define NVME_PMREBS_RBB(pmrebs)     \
3406cf94132SAndrzej Jakowski     ((pmrebs >> PMREBS_RBB_SHIFT)   & PMREBS_RBB_MASK)
3416cf94132SAndrzej Jakowski #define NVME_PMREBS_PMRWBZ(pmrebs)  \
3426cf94132SAndrzej Jakowski     ((pmrebs >> PMREBS_PMRWBZ_SHIFT)   & PMREBS_PMRWBZ_MASK)
3436cf94132SAndrzej Jakowski 
3446cf94132SAndrzej Jakowski #define NVME_PMREBS_SET_PMRSZU(pmrebs, val)   \
3456cf94132SAndrzej Jakowski     (pmrebs |= (uint64_t)(val & PMREBS_PMRSZU_MASK) << PMREBS_PMRSZU_SHIFT)
3466cf94132SAndrzej Jakowski #define NVME_PMREBS_SET_RBB(pmrebs, val)   \
3476cf94132SAndrzej Jakowski     (pmrebs |= (uint64_t)(val & PMREBS_RBB_MASK) << PMREBS_RBB_SHIFT)
3486cf94132SAndrzej Jakowski #define NVME_PMREBS_SET_PMRWBZ(pmrebs, val)   \
3496cf94132SAndrzej Jakowski     (pmrebs |= (uint64_t)(val & PMREBS_PMRWBZ_MASK) << PMREBS_PMRWBZ_SHIFT)
3506cf94132SAndrzej Jakowski 
3516cf94132SAndrzej Jakowski enum NvmePmrswtpShift {
3526cf94132SAndrzej Jakowski     PMRSWTP_PMRSWTU_SHIFT   = 0,
3536cf94132SAndrzej Jakowski     PMRSWTP_PMRSWTV_SHIFT   = 8,
3546cf94132SAndrzej Jakowski };
3556cf94132SAndrzej Jakowski 
3566cf94132SAndrzej Jakowski enum NvmePmrswtpMask {
3576cf94132SAndrzej Jakowski     PMRSWTP_PMRSWTU_MASK   = 0xf,
3586cf94132SAndrzej Jakowski     PMRSWTP_PMRSWTV_MASK   = 0xffffff,
3596cf94132SAndrzej Jakowski };
3606cf94132SAndrzej Jakowski 
3616cf94132SAndrzej Jakowski #define NVME_PMRSWTP_PMRSWTU(pmrswtp)   \
3626cf94132SAndrzej Jakowski     ((pmrswtp >> PMRSWTP_PMRSWTU_SHIFT)   & PMRSWTP_PMRSWTU_MASK)
3636cf94132SAndrzej Jakowski #define NVME_PMRSWTP_PMRSWTV(pmrswtp)   \
3646cf94132SAndrzej Jakowski     ((pmrswtp >> PMRSWTP_PMRSWTV_SHIFT)   & PMRSWTP_PMRSWTV_MASK)
3656cf94132SAndrzej Jakowski 
3666cf94132SAndrzej Jakowski #define NVME_PMRSWTP_SET_PMRSWTU(pmrswtp, val)   \
3676cf94132SAndrzej Jakowski     (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTU_MASK) << PMRSWTP_PMRSWTU_SHIFT)
3686cf94132SAndrzej Jakowski #define NVME_PMRSWTP_SET_PMRSWTV(pmrswtp, val)   \
3696cf94132SAndrzej Jakowski     (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTV_MASK) << PMRSWTP_PMRSWTV_SHIFT)
3706cf94132SAndrzej Jakowski 
3716cf94132SAndrzej Jakowski enum NvmePmrmscShift {
3726cf94132SAndrzej Jakowski     PMRMSC_CMSE_SHIFT   = 1,
3736cf94132SAndrzej Jakowski     PMRMSC_CBA_SHIFT    = 12,
3746cf94132SAndrzej Jakowski };
3756cf94132SAndrzej Jakowski 
3766cf94132SAndrzej Jakowski enum NvmePmrmscMask {
3776cf94132SAndrzej Jakowski     PMRMSC_CMSE_MASK   = 0x1,
3786cf94132SAndrzej Jakowski     PMRMSC_CBA_MASK    = 0xfffffffffffff,
3796cf94132SAndrzej Jakowski };
3806cf94132SAndrzej Jakowski 
3816cf94132SAndrzej Jakowski #define NVME_PMRMSC_CMSE(pmrmsc)    \
3826cf94132SAndrzej Jakowski     ((pmrmsc >> PMRMSC_CMSE_SHIFT)   & PMRMSC_CMSE_MASK)
3836cf94132SAndrzej Jakowski #define NVME_PMRMSC_CBA(pmrmsc)     \
3846cf94132SAndrzej Jakowski     ((pmrmsc >> PMRMSC_CBA_SHIFT)   & PMRMSC_CBA_MASK)
3856cf94132SAndrzej Jakowski 
3866cf94132SAndrzej Jakowski #define NVME_PMRMSC_SET_CMSE(pmrmsc, val)   \
3876cf94132SAndrzej Jakowski     (pmrmsc |= (uint64_t)(val & PMRMSC_CMSE_MASK) << PMRMSC_CMSE_SHIFT)
3886cf94132SAndrzej Jakowski #define NVME_PMRMSC_SET_CBA(pmrmsc, val)   \
3896cf94132SAndrzej Jakowski     (pmrmsc |= (uint64_t)(val & PMRMSC_CBA_MASK) << PMRMSC_CBA_SHIFT)
3906cf94132SAndrzej Jakowski 
391c26f2173SKlaus Jensen enum NvmeSglDescriptorType {
392c26f2173SKlaus Jensen     NVME_SGL_DESCR_TYPE_DATA_BLOCK          = 0x0,
393c26f2173SKlaus Jensen     NVME_SGL_DESCR_TYPE_BIT_BUCKET          = 0x1,
394c26f2173SKlaus Jensen     NVME_SGL_DESCR_TYPE_SEGMENT             = 0x2,
395c26f2173SKlaus Jensen     NVME_SGL_DESCR_TYPE_LAST_SEGMENT        = 0x3,
396c26f2173SKlaus Jensen     NVME_SGL_DESCR_TYPE_KEYED_DATA_BLOCK    = 0x4,
397c26f2173SKlaus Jensen 
398c26f2173SKlaus Jensen     NVME_SGL_DESCR_TYPE_VENDOR_SPECIFIC     = 0xf,
399c26f2173SKlaus Jensen };
400c26f2173SKlaus Jensen 
401c26f2173SKlaus Jensen enum NvmeSglDescriptorSubtype {
402c26f2173SKlaus Jensen     NVME_SGL_DESCR_SUBTYPE_ADDRESS = 0x0,
403c26f2173SKlaus Jensen };
404c26f2173SKlaus Jensen 
405c26f2173SKlaus Jensen typedef struct QEMU_PACKED NvmeSglDescriptor {
406c26f2173SKlaus Jensen     uint64_t addr;
407c26f2173SKlaus Jensen     uint32_t len;
408c26f2173SKlaus Jensen     uint8_t  rsvd[3];
409c26f2173SKlaus Jensen     uint8_t  type;
410c26f2173SKlaus Jensen } NvmeSglDescriptor;
411c26f2173SKlaus Jensen 
412c26f2173SKlaus Jensen #define NVME_SGL_TYPE(type)     ((type >> 4) & 0xf)
413c26f2173SKlaus Jensen #define NVME_SGL_SUBTYPE(type)  (type & 0xf)
414c26f2173SKlaus Jensen 
415c26f2173SKlaus Jensen typedef union NvmeCmdDptr {
416c26f2173SKlaus Jensen     struct {
417c26f2173SKlaus Jensen         uint64_t    prp1;
418c26f2173SKlaus Jensen         uint64_t    prp2;
419c26f2173SKlaus Jensen     };
420c26f2173SKlaus Jensen 
421c26f2173SKlaus Jensen     NvmeSglDescriptor sgl;
422c26f2173SKlaus Jensen } NvmeCmdDptr;
423c26f2173SKlaus Jensen 
424c26f2173SKlaus Jensen enum NvmePsdt {
425cba0a8a3SKlaus Jensen     NVME_PSDT_PRP                 = 0x0,
426cba0a8a3SKlaus Jensen     NVME_PSDT_SGL_MPTR_CONTIGUOUS = 0x1,
427cba0a8a3SKlaus Jensen     NVME_PSDT_SGL_MPTR_SGL        = 0x2,
428c26f2173SKlaus Jensen };
429c26f2173SKlaus Jensen 
430e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeCmd {
431a3d9a352SFam Zheng     uint8_t     opcode;
432c26f2173SKlaus Jensen     uint8_t     flags;
433a3d9a352SFam Zheng     uint16_t    cid;
434a3d9a352SFam Zheng     uint32_t    nsid;
435a3d9a352SFam Zheng     uint64_t    res1;
436a3d9a352SFam Zheng     uint64_t    mptr;
437c26f2173SKlaus Jensen     NvmeCmdDptr dptr;
438a3d9a352SFam Zheng     uint32_t    cdw10;
439a3d9a352SFam Zheng     uint32_t    cdw11;
440a3d9a352SFam Zheng     uint32_t    cdw12;
441a3d9a352SFam Zheng     uint32_t    cdw13;
442a3d9a352SFam Zheng     uint32_t    cdw14;
443a3d9a352SFam Zheng     uint32_t    cdw15;
444a3d9a352SFam Zheng } NvmeCmd;
445a3d9a352SFam Zheng 
446c26f2173SKlaus Jensen #define NVME_CMD_FLAGS_FUSE(flags) (flags & 0x3)
447c26f2173SKlaus Jensen #define NVME_CMD_FLAGS_PSDT(flags) ((flags >> 6) & 0x3)
448c26f2173SKlaus Jensen 
449a3d9a352SFam Zheng enum NvmeAdminCommands {
450a3d9a352SFam Zheng     NVME_ADM_CMD_DELETE_SQ      = 0x00,
451a3d9a352SFam Zheng     NVME_ADM_CMD_CREATE_SQ      = 0x01,
452a3d9a352SFam Zheng     NVME_ADM_CMD_GET_LOG_PAGE   = 0x02,
453a3d9a352SFam Zheng     NVME_ADM_CMD_DELETE_CQ      = 0x04,
454a3d9a352SFam Zheng     NVME_ADM_CMD_CREATE_CQ      = 0x05,
455a3d9a352SFam Zheng     NVME_ADM_CMD_IDENTIFY       = 0x06,
456a3d9a352SFam Zheng     NVME_ADM_CMD_ABORT          = 0x08,
457a3d9a352SFam Zheng     NVME_ADM_CMD_SET_FEATURES   = 0x09,
458a3d9a352SFam Zheng     NVME_ADM_CMD_GET_FEATURES   = 0x0a,
459a3d9a352SFam Zheng     NVME_ADM_CMD_ASYNC_EV_REQ   = 0x0c,
460a3d9a352SFam Zheng     NVME_ADM_CMD_ACTIVATE_FW    = 0x10,
461a3d9a352SFam Zheng     NVME_ADM_CMD_DOWNLOAD_FW    = 0x11,
462a3d9a352SFam Zheng     NVME_ADM_CMD_FORMAT_NVM     = 0x80,
463a3d9a352SFam Zheng     NVME_ADM_CMD_SECURITY_SEND  = 0x81,
464a3d9a352SFam Zheng     NVME_ADM_CMD_SECURITY_RECV  = 0x82,
465a3d9a352SFam Zheng };
466a3d9a352SFam Zheng 
467a3d9a352SFam Zheng enum NvmeIoCommands {
468a3d9a352SFam Zheng     NVME_CMD_FLUSH              = 0x00,
469a3d9a352SFam Zheng     NVME_CMD_WRITE              = 0x01,
470a3d9a352SFam Zheng     NVME_CMD_READ               = 0x02,
471a3d9a352SFam Zheng     NVME_CMD_WRITE_UNCOR        = 0x04,
472a3d9a352SFam Zheng     NVME_CMD_COMPARE            = 0x05,
47369265150SKlaus Jensen     NVME_CMD_WRITE_ZEROES       = 0x08,
474a3d9a352SFam Zheng     NVME_CMD_DSM                = 0x09,
475a3d9a352SFam Zheng };
476a3d9a352SFam Zheng 
477e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeDeleteQ {
478a3d9a352SFam Zheng     uint8_t     opcode;
479a3d9a352SFam Zheng     uint8_t     flags;
480a3d9a352SFam Zheng     uint16_t    cid;
481a3d9a352SFam Zheng     uint32_t    rsvd1[9];
482a3d9a352SFam Zheng     uint16_t    qid;
483a3d9a352SFam Zheng     uint16_t    rsvd10;
484a3d9a352SFam Zheng     uint32_t    rsvd11[5];
485a3d9a352SFam Zheng } NvmeDeleteQ;
486a3d9a352SFam Zheng 
487e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeCreateCq {
488a3d9a352SFam Zheng     uint8_t     opcode;
489a3d9a352SFam Zheng     uint8_t     flags;
490a3d9a352SFam Zheng     uint16_t    cid;
491a3d9a352SFam Zheng     uint32_t    rsvd1[5];
492a3d9a352SFam Zheng     uint64_t    prp1;
493a3d9a352SFam Zheng     uint64_t    rsvd8;
494a3d9a352SFam Zheng     uint16_t    cqid;
495a3d9a352SFam Zheng     uint16_t    qsize;
496a3d9a352SFam Zheng     uint16_t    cq_flags;
497a3d9a352SFam Zheng     uint16_t    irq_vector;
498a3d9a352SFam Zheng     uint32_t    rsvd12[4];
499a3d9a352SFam Zheng } NvmeCreateCq;
500a3d9a352SFam Zheng 
501a3d9a352SFam Zheng #define NVME_CQ_FLAGS_PC(cq_flags)  (cq_flags & 0x1)
502a3d9a352SFam Zheng #define NVME_CQ_FLAGS_IEN(cq_flags) ((cq_flags >> 1) & 0x1)
503a3d9a352SFam Zheng 
50454248d4dSPhilippe Mathieu-Daudé enum NvmeFlagsCq {
50554248d4dSPhilippe Mathieu-Daudé     NVME_CQ_PC          = 1,
50654248d4dSPhilippe Mathieu-Daudé     NVME_CQ_IEN         = 2,
50754248d4dSPhilippe Mathieu-Daudé };
50854248d4dSPhilippe Mathieu-Daudé 
509e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeCreateSq {
510a3d9a352SFam Zheng     uint8_t     opcode;
511a3d9a352SFam Zheng     uint8_t     flags;
512a3d9a352SFam Zheng     uint16_t    cid;
513a3d9a352SFam Zheng     uint32_t    rsvd1[5];
514a3d9a352SFam Zheng     uint64_t    prp1;
515a3d9a352SFam Zheng     uint64_t    rsvd8;
516a3d9a352SFam Zheng     uint16_t    sqid;
517a3d9a352SFam Zheng     uint16_t    qsize;
518a3d9a352SFam Zheng     uint16_t    sq_flags;
519a3d9a352SFam Zheng     uint16_t    cqid;
520a3d9a352SFam Zheng     uint32_t    rsvd12[4];
521a3d9a352SFam Zheng } NvmeCreateSq;
522a3d9a352SFam Zheng 
523a3d9a352SFam Zheng #define NVME_SQ_FLAGS_PC(sq_flags)      (sq_flags & 0x1)
524a3d9a352SFam Zheng #define NVME_SQ_FLAGS_QPRIO(sq_flags)   ((sq_flags >> 1) & 0x3)
525a3d9a352SFam Zheng 
52654248d4dSPhilippe Mathieu-Daudé enum NvmeFlagsSq {
52754248d4dSPhilippe Mathieu-Daudé     NVME_SQ_PC          = 1,
52854248d4dSPhilippe Mathieu-Daudé 
52954248d4dSPhilippe Mathieu-Daudé     NVME_SQ_PRIO_URGENT = 0,
53054248d4dSPhilippe Mathieu-Daudé     NVME_SQ_PRIO_HIGH   = 1,
53154248d4dSPhilippe Mathieu-Daudé     NVME_SQ_PRIO_NORMAL = 2,
53254248d4dSPhilippe Mathieu-Daudé     NVME_SQ_PRIO_LOW    = 3,
533a3d9a352SFam Zheng };
534a3d9a352SFam Zheng 
535e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeIdentify {
536a3d9a352SFam Zheng     uint8_t     opcode;
537a3d9a352SFam Zheng     uint8_t     flags;
538a3d9a352SFam Zheng     uint16_t    cid;
539a3d9a352SFam Zheng     uint32_t    nsid;
540a3d9a352SFam Zheng     uint64_t    rsvd2[2];
541a3d9a352SFam Zheng     uint64_t    prp1;
542a3d9a352SFam Zheng     uint64_t    prp2;
543a3d9a352SFam Zheng     uint32_t    cns;
544a3d9a352SFam Zheng     uint32_t    rsvd11[5];
545a3d9a352SFam Zheng } NvmeIdentify;
546a3d9a352SFam Zheng 
547e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeRwCmd {
548a3d9a352SFam Zheng     uint8_t     opcode;
549a3d9a352SFam Zheng     uint8_t     flags;
550a3d9a352SFam Zheng     uint16_t    cid;
551a3d9a352SFam Zheng     uint32_t    nsid;
552a3d9a352SFam Zheng     uint64_t    rsvd2;
553a3d9a352SFam Zheng     uint64_t    mptr;
554c26f2173SKlaus Jensen     NvmeCmdDptr dptr;
555a3d9a352SFam Zheng     uint64_t    slba;
556a3d9a352SFam Zheng     uint16_t    nlb;
557a3d9a352SFam Zheng     uint16_t    control;
558a3d9a352SFam Zheng     uint32_t    dsmgmt;
559a3d9a352SFam Zheng     uint32_t    reftag;
560a3d9a352SFam Zheng     uint16_t    apptag;
561a3d9a352SFam Zheng     uint16_t    appmask;
562a3d9a352SFam Zheng } NvmeRwCmd;
563a3d9a352SFam Zheng 
564a3d9a352SFam Zheng enum {
565a3d9a352SFam Zheng     NVME_RW_LR                  = 1 << 15,
566a3d9a352SFam Zheng     NVME_RW_FUA                 = 1 << 14,
567a3d9a352SFam Zheng     NVME_RW_DSM_FREQ_UNSPEC     = 0,
568a3d9a352SFam Zheng     NVME_RW_DSM_FREQ_TYPICAL    = 1,
569a3d9a352SFam Zheng     NVME_RW_DSM_FREQ_RARE       = 2,
570a3d9a352SFam Zheng     NVME_RW_DSM_FREQ_READS      = 3,
571a3d9a352SFam Zheng     NVME_RW_DSM_FREQ_WRITES     = 4,
572a3d9a352SFam Zheng     NVME_RW_DSM_FREQ_RW         = 5,
573a3d9a352SFam Zheng     NVME_RW_DSM_FREQ_ONCE       = 6,
574a3d9a352SFam Zheng     NVME_RW_DSM_FREQ_PREFETCH   = 7,
575a3d9a352SFam Zheng     NVME_RW_DSM_FREQ_TEMP       = 8,
576a3d9a352SFam Zheng     NVME_RW_DSM_LATENCY_NONE    = 0 << 4,
577a3d9a352SFam Zheng     NVME_RW_DSM_LATENCY_IDLE    = 1 << 4,
578a3d9a352SFam Zheng     NVME_RW_DSM_LATENCY_NORM    = 2 << 4,
579a3d9a352SFam Zheng     NVME_RW_DSM_LATENCY_LOW     = 3 << 4,
580a3d9a352SFam Zheng     NVME_RW_DSM_SEQ_REQ         = 1 << 6,
581a3d9a352SFam Zheng     NVME_RW_DSM_COMPRESSED      = 1 << 7,
582a3d9a352SFam Zheng     NVME_RW_PRINFO_PRACT        = 1 << 13,
583a3d9a352SFam Zheng     NVME_RW_PRINFO_PRCHK_GUARD  = 1 << 12,
584a3d9a352SFam Zheng     NVME_RW_PRINFO_PRCHK_APP    = 1 << 11,
585a3d9a352SFam Zheng     NVME_RW_PRINFO_PRCHK_REF    = 1 << 10,
586a3d9a352SFam Zheng };
587a3d9a352SFam Zheng 
588e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeDsmCmd {
589a3d9a352SFam Zheng     uint8_t     opcode;
590a3d9a352SFam Zheng     uint8_t     flags;
591a3d9a352SFam Zheng     uint16_t    cid;
592a3d9a352SFam Zheng     uint32_t    nsid;
593a3d9a352SFam Zheng     uint64_t    rsvd2[2];
594c26f2173SKlaus Jensen     NvmeCmdDptr dptr;
595a3d9a352SFam Zheng     uint32_t    nr;
596a3d9a352SFam Zheng     uint32_t    attributes;
597a3d9a352SFam Zheng     uint32_t    rsvd12[4];
598a3d9a352SFam Zheng } NvmeDsmCmd;
599a3d9a352SFam Zheng 
600a3d9a352SFam Zheng enum {
601a3d9a352SFam Zheng     NVME_DSMGMT_IDR = 1 << 0,
602a3d9a352SFam Zheng     NVME_DSMGMT_IDW = 1 << 1,
603a3d9a352SFam Zheng     NVME_DSMGMT_AD  = 1 << 2,
604a3d9a352SFam Zheng };
605a3d9a352SFam Zheng 
606e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeDsmRange {
607a3d9a352SFam Zheng     uint32_t    cattr;
608a3d9a352SFam Zheng     uint32_t    nlb;
609a3d9a352SFam Zheng     uint64_t    slba;
610a3d9a352SFam Zheng } NvmeDsmRange;
611a3d9a352SFam Zheng 
612a3d9a352SFam Zheng enum NvmeAsyncEventRequest {
613a3d9a352SFam Zheng     NVME_AER_TYPE_ERROR                     = 0,
614a3d9a352SFam Zheng     NVME_AER_TYPE_SMART                     = 1,
615a3d9a352SFam Zheng     NVME_AER_TYPE_IO_SPECIFIC               = 6,
616a3d9a352SFam Zheng     NVME_AER_TYPE_VENDOR_SPECIFIC           = 7,
6175d5a5330SKlaus Jensen     NVME_AER_INFO_ERR_INVALID_DB_REGISTER   = 0,
6185d5a5330SKlaus Jensen     NVME_AER_INFO_ERR_INVALID_DB_VALUE      = 1,
619a3d9a352SFam Zheng     NVME_AER_INFO_ERR_DIAG_FAIL             = 2,
620a3d9a352SFam Zheng     NVME_AER_INFO_ERR_PERS_INTERNAL_ERR     = 3,
621a3d9a352SFam Zheng     NVME_AER_INFO_ERR_TRANS_INTERNAL_ERR    = 4,
622a3d9a352SFam Zheng     NVME_AER_INFO_ERR_FW_IMG_LOAD_ERR       = 5,
623a3d9a352SFam Zheng     NVME_AER_INFO_SMART_RELIABILITY         = 0,
624a3d9a352SFam Zheng     NVME_AER_INFO_SMART_TEMP_THRESH         = 1,
625a3d9a352SFam Zheng     NVME_AER_INFO_SMART_SPARE_THRESH        = 2,
626a3d9a352SFam Zheng };
627a3d9a352SFam Zheng 
628e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeAerResult {
629a3d9a352SFam Zheng     uint8_t event_type;
630a3d9a352SFam Zheng     uint8_t event_info;
631a3d9a352SFam Zheng     uint8_t log_page;
632a3d9a352SFam Zheng     uint8_t resv;
633a3d9a352SFam Zheng } NvmeAerResult;
634a3d9a352SFam Zheng 
635e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeCqe {
636a3d9a352SFam Zheng     uint32_t    result;
637a3d9a352SFam Zheng     uint32_t    rsvd;
638a3d9a352SFam Zheng     uint16_t    sq_head;
639a3d9a352SFam Zheng     uint16_t    sq_id;
640a3d9a352SFam Zheng     uint16_t    cid;
641a3d9a352SFam Zheng     uint16_t    status;
642a3d9a352SFam Zheng } NvmeCqe;
643a3d9a352SFam Zheng 
644a3d9a352SFam Zheng enum NvmeStatusCodes {
645a3d9a352SFam Zheng     NVME_SUCCESS                = 0x0000,
646a3d9a352SFam Zheng     NVME_INVALID_OPCODE         = 0x0001,
647a3d9a352SFam Zheng     NVME_INVALID_FIELD          = 0x0002,
648a3d9a352SFam Zheng     NVME_CID_CONFLICT           = 0x0003,
649a3d9a352SFam Zheng     NVME_DATA_TRAS_ERROR        = 0x0004,
650a3d9a352SFam Zheng     NVME_POWER_LOSS_ABORT       = 0x0005,
651a3d9a352SFam Zheng     NVME_INTERNAL_DEV_ERROR     = 0x0006,
652a3d9a352SFam Zheng     NVME_CMD_ABORT_REQ          = 0x0007,
653a3d9a352SFam Zheng     NVME_CMD_ABORT_SQ_DEL       = 0x0008,
654a3d9a352SFam Zheng     NVME_CMD_ABORT_FAILED_FUSE  = 0x0009,
655a3d9a352SFam Zheng     NVME_CMD_ABORT_MISSING_FUSE = 0x000a,
656a3d9a352SFam Zheng     NVME_INVALID_NSID           = 0x000b,
657a3d9a352SFam Zheng     NVME_CMD_SEQ_ERROR          = 0x000c,
658c26f2173SKlaus Jensen     NVME_INVALID_SGL_SEG_DESCR  = 0x000d,
659c26f2173SKlaus Jensen     NVME_INVALID_NUM_SGL_DESCRS = 0x000e,
660c26f2173SKlaus Jensen     NVME_DATA_SGL_LEN_INVALID   = 0x000f,
661c26f2173SKlaus Jensen     NVME_MD_SGL_LEN_INVALID     = 0x0010,
662c26f2173SKlaus Jensen     NVME_SGL_DESCR_TYPE_INVALID = 0x0011,
663c26f2173SKlaus Jensen     NVME_INVALID_USE_OF_CMB     = 0x0012,
66428fee5b5SGollu Appalanaidu     NVME_INVALID_PRP_OFFSET     = 0x0013,
665a3d9a352SFam Zheng     NVME_LBA_RANGE              = 0x0080,
666a3d9a352SFam Zheng     NVME_CAP_EXCEEDED           = 0x0081,
667a3d9a352SFam Zheng     NVME_NS_NOT_READY           = 0x0082,
668a3d9a352SFam Zheng     NVME_NS_RESV_CONFLICT       = 0x0083,
669a3d9a352SFam Zheng     NVME_INVALID_CQID           = 0x0100,
670a3d9a352SFam Zheng     NVME_INVALID_QID            = 0x0101,
671a3d9a352SFam Zheng     NVME_MAX_QSIZE_EXCEEDED     = 0x0102,
672a3d9a352SFam Zheng     NVME_ACL_EXCEEDED           = 0x0103,
673a3d9a352SFam Zheng     NVME_RESERVED               = 0x0104,
674a3d9a352SFam Zheng     NVME_AER_LIMIT_EXCEEDED     = 0x0105,
675a3d9a352SFam Zheng     NVME_INVALID_FW_SLOT        = 0x0106,
676a3d9a352SFam Zheng     NVME_INVALID_FW_IMAGE       = 0x0107,
677a3d9a352SFam Zheng     NVME_INVALID_IRQ_VECTOR     = 0x0108,
678a3d9a352SFam Zheng     NVME_INVALID_LOG_ID         = 0x0109,
679a3d9a352SFam Zheng     NVME_INVALID_FORMAT         = 0x010a,
680a3d9a352SFam Zheng     NVME_FW_REQ_RESET           = 0x010b,
681a3d9a352SFam Zheng     NVME_INVALID_QUEUE_DEL      = 0x010c,
682a3d9a352SFam Zheng     NVME_FID_NOT_SAVEABLE       = 0x010d,
6831302e48eSKlaus Jensen     NVME_FEAT_NOT_CHANGEABLE    = 0x010e,
6847c46310dSKlaus Jensen     NVME_FEAT_NOT_NS_SPEC       = 0x010f,
685a3d9a352SFam Zheng     NVME_FW_REQ_SUSYSTEM_RESET  = 0x0110,
686a3d9a352SFam Zheng     NVME_CONFLICTING_ATTRS      = 0x0180,
687a3d9a352SFam Zheng     NVME_INVALID_PROT_INFO      = 0x0181,
688a3d9a352SFam Zheng     NVME_WRITE_TO_RO            = 0x0182,
689a3d9a352SFam Zheng     NVME_WRITE_FAULT            = 0x0280,
690a3d9a352SFam Zheng     NVME_UNRECOVERED_READ       = 0x0281,
691a3d9a352SFam Zheng     NVME_E2E_GUARD_ERROR        = 0x0282,
692a3d9a352SFam Zheng     NVME_E2E_APP_ERROR          = 0x0283,
693a3d9a352SFam Zheng     NVME_E2E_REF_ERROR          = 0x0284,
694a3d9a352SFam Zheng     NVME_CMP_FAILURE            = 0x0285,
695a3d9a352SFam Zheng     NVME_ACCESS_DENIED          = 0x0286,
696*54064e51SKlaus Jensen     NVME_DULB                   = 0x0287,
697a3d9a352SFam Zheng     NVME_MORE                   = 0x2000,
698a3d9a352SFam Zheng     NVME_DNR                    = 0x4000,
699a3d9a352SFam Zheng     NVME_NO_COMPLETE            = 0xffff,
700a3d9a352SFam Zheng };
701a3d9a352SFam Zheng 
702e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeFwSlotInfoLog {
703a3d9a352SFam Zheng     uint8_t     afi;
704a3d9a352SFam Zheng     uint8_t     reserved1[7];
705a3d9a352SFam Zheng     uint8_t     frs1[8];
706a3d9a352SFam Zheng     uint8_t     frs2[8];
707a3d9a352SFam Zheng     uint8_t     frs3[8];
708a3d9a352SFam Zheng     uint8_t     frs4[8];
709a3d9a352SFam Zheng     uint8_t     frs5[8];
710a3d9a352SFam Zheng     uint8_t     frs6[8];
711a3d9a352SFam Zheng     uint8_t     frs7[8];
712a3d9a352SFam Zheng     uint8_t     reserved2[448];
713a3d9a352SFam Zheng } NvmeFwSlotInfoLog;
714a3d9a352SFam Zheng 
715e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeErrorLog {
716a3d9a352SFam Zheng     uint64_t    error_count;
717a3d9a352SFam Zheng     uint16_t    sqid;
718a3d9a352SFam Zheng     uint16_t    cid;
719a3d9a352SFam Zheng     uint16_t    status_field;
720a3d9a352SFam Zheng     uint16_t    param_error_location;
721a3d9a352SFam Zheng     uint64_t    lba;
722a3d9a352SFam Zheng     uint32_t    nsid;
723a3d9a352SFam Zheng     uint8_t     vs;
724a3d9a352SFam Zheng     uint8_t     resv[35];
725a3d9a352SFam Zheng } NvmeErrorLog;
726a3d9a352SFam Zheng 
727e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeSmartLog {
728a3d9a352SFam Zheng     uint8_t     critical_warning;
72994a7897cSKlaus Jensen     uint16_t    temperature;
730a3d9a352SFam Zheng     uint8_t     available_spare;
731a3d9a352SFam Zheng     uint8_t     available_spare_threshold;
732a3d9a352SFam Zheng     uint8_t     percentage_used;
733a3d9a352SFam Zheng     uint8_t     reserved1[26];
734a3d9a352SFam Zheng     uint64_t    data_units_read[2];
735a3d9a352SFam Zheng     uint64_t    data_units_written[2];
736a3d9a352SFam Zheng     uint64_t    host_read_commands[2];
737a3d9a352SFam Zheng     uint64_t    host_write_commands[2];
738a3d9a352SFam Zheng     uint64_t    controller_busy_time[2];
739a3d9a352SFam Zheng     uint64_t    power_cycles[2];
740a3d9a352SFam Zheng     uint64_t    power_on_hours[2];
741a3d9a352SFam Zheng     uint64_t    unsafe_shutdowns[2];
742a3d9a352SFam Zheng     uint64_t    media_errors[2];
743a3d9a352SFam Zheng     uint64_t    number_of_error_log_entries[2];
744a3d9a352SFam Zheng     uint8_t     reserved2[320];
745a3d9a352SFam Zheng } NvmeSmartLog;
746a3d9a352SFam Zheng 
747a3d9a352SFam Zheng enum NvmeSmartWarn {
748a3d9a352SFam Zheng     NVME_SMART_SPARE                  = 1 << 0,
749a3d9a352SFam Zheng     NVME_SMART_TEMPERATURE            = 1 << 1,
750a3d9a352SFam Zheng     NVME_SMART_RELIABILITY            = 1 << 2,
751a3d9a352SFam Zheng     NVME_SMART_MEDIA_READ_ONLY        = 1 << 3,
752a3d9a352SFam Zheng     NVME_SMART_FAILED_VOLATILE_MEDIA  = 1 << 4,
753a3d9a352SFam Zheng };
754a3d9a352SFam Zheng 
755c26f2173SKlaus Jensen enum NvmeLogIdentifier {
756a3d9a352SFam Zheng     NVME_LOG_ERROR_INFO     = 0x01,
757a3d9a352SFam Zheng     NVME_LOG_SMART_INFO     = 0x02,
758a3d9a352SFam Zheng     NVME_LOG_FW_SLOT_INFO   = 0x03,
759a3d9a352SFam Zheng };
760a3d9a352SFam Zheng 
761e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmePSD {
762a3d9a352SFam Zheng     uint16_t    mp;
763a3d9a352SFam Zheng     uint16_t    reserved;
764a3d9a352SFam Zheng     uint32_t    enlat;
765a3d9a352SFam Zheng     uint32_t    exlat;
766a3d9a352SFam Zheng     uint8_t     rrt;
767a3d9a352SFam Zheng     uint8_t     rrl;
768a3d9a352SFam Zheng     uint8_t     rwt;
769a3d9a352SFam Zheng     uint8_t     rwl;
770a3d9a352SFam Zheng     uint8_t     resv[16];
771a3d9a352SFam Zheng } NvmePSD;
772a3d9a352SFam Zheng 
7733e829fd4SKlaus Jensen #define NVME_IDENTIFY_DATA_SIZE 4096
7743e829fd4SKlaus Jensen 
7753e829fd4SKlaus Jensen enum {
7763e829fd4SKlaus Jensen     NVME_ID_CNS_NS             = 0x0,
7773e829fd4SKlaus Jensen     NVME_ID_CNS_CTRL           = 0x1,
7783e829fd4SKlaus Jensen     NVME_ID_CNS_NS_ACTIVE_LIST = 0x2,
779c26f2173SKlaus Jensen     NVME_ID_CNS_NS_DESCR_LIST  = 0x3,
7803e829fd4SKlaus Jensen };
7813e829fd4SKlaus Jensen 
782e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeIdCtrl {
783a3d9a352SFam Zheng     uint16_t    vid;
784a3d9a352SFam Zheng     uint16_t    ssvid;
785a3d9a352SFam Zheng     uint8_t     sn[20];
786a3d9a352SFam Zheng     uint8_t     mn[40];
787a3d9a352SFam Zheng     uint8_t     fr[8];
788a3d9a352SFam Zheng     uint8_t     rab;
789a3d9a352SFam Zheng     uint8_t     ieee[3];
790a3d9a352SFam Zheng     uint8_t     cmic;
791a3d9a352SFam Zheng     uint8_t     mdts;
792c26f2173SKlaus Jensen     uint16_t    cntlid;
793c26f2173SKlaus Jensen     uint32_t    ver;
794c26f2173SKlaus Jensen     uint32_t    rtd3r;
795c26f2173SKlaus Jensen     uint32_t    rtd3e;
796c26f2173SKlaus Jensen     uint32_t    oaes;
797c26f2173SKlaus Jensen     uint32_t    ctratt;
798c26f2173SKlaus Jensen     uint8_t     rsvd100[12];
799c26f2173SKlaus Jensen     uint8_t     fguid[16];
800c26f2173SKlaus Jensen     uint8_t     rsvd128[128];
801a3d9a352SFam Zheng     uint16_t    oacs;
802a3d9a352SFam Zheng     uint8_t     acl;
803a3d9a352SFam Zheng     uint8_t     aerl;
804a3d9a352SFam Zheng     uint8_t     frmw;
805a3d9a352SFam Zheng     uint8_t     lpa;
806a3d9a352SFam Zheng     uint8_t     elpe;
807a3d9a352SFam Zheng     uint8_t     npss;
808c26f2173SKlaus Jensen     uint8_t     avscc;
809c26f2173SKlaus Jensen     uint8_t     apsta;
810c26f2173SKlaus Jensen     uint16_t    wctemp;
811c26f2173SKlaus Jensen     uint16_t    cctemp;
812c26f2173SKlaus Jensen     uint16_t    mtfa;
813c26f2173SKlaus Jensen     uint32_t    hmpre;
814c26f2173SKlaus Jensen     uint32_t    hmmin;
815c26f2173SKlaus Jensen     uint8_t     tnvmcap[16];
816c26f2173SKlaus Jensen     uint8_t     unvmcap[16];
817c26f2173SKlaus Jensen     uint32_t    rpmbs;
818c26f2173SKlaus Jensen     uint16_t    edstt;
819c26f2173SKlaus Jensen     uint8_t     dsto;
820c26f2173SKlaus Jensen     uint8_t     fwug;
821c26f2173SKlaus Jensen     uint16_t    kas;
822c26f2173SKlaus Jensen     uint16_t    hctma;
823c26f2173SKlaus Jensen     uint16_t    mntmt;
824c26f2173SKlaus Jensen     uint16_t    mxtmt;
825c26f2173SKlaus Jensen     uint32_t    sanicap;
826c26f2173SKlaus Jensen     uint8_t     rsvd332[180];
827a3d9a352SFam Zheng     uint8_t     sqes;
828a3d9a352SFam Zheng     uint8_t     cqes;
829c26f2173SKlaus Jensen     uint16_t    maxcmd;
830a3d9a352SFam Zheng     uint32_t    nn;
831a3d9a352SFam Zheng     uint16_t    oncs;
832a3d9a352SFam Zheng     uint16_t    fuses;
833a3d9a352SFam Zheng     uint8_t     fna;
834a3d9a352SFam Zheng     uint8_t     vwc;
835a3d9a352SFam Zheng     uint16_t    awun;
836a3d9a352SFam Zheng     uint16_t    awupf;
837c26f2173SKlaus Jensen     uint8_t     nvscc;
838c26f2173SKlaus Jensen     uint8_t     rsvd531;
839c26f2173SKlaus Jensen     uint16_t    acwu;
840c26f2173SKlaus Jensen     uint8_t     rsvd534[2];
841c26f2173SKlaus Jensen     uint32_t    sgls;
842c26f2173SKlaus Jensen     uint8_t     rsvd540[228];
843c26f2173SKlaus Jensen     uint8_t     subnqn[256];
844c26f2173SKlaus Jensen     uint8_t     rsvd1024[1024];
845a3d9a352SFam Zheng     NvmePSD     psd[32];
846a3d9a352SFam Zheng     uint8_t     vs[1024];
847a3d9a352SFam Zheng } NvmeIdCtrl;
848a3d9a352SFam Zheng 
849a3d9a352SFam Zheng enum NvmeIdCtrlOacs {
850a3d9a352SFam Zheng     NVME_OACS_SECURITY  = 1 << 0,
851a3d9a352SFam Zheng     NVME_OACS_FORMAT    = 1 << 1,
852a3d9a352SFam Zheng     NVME_OACS_FW        = 1 << 2,
853a3d9a352SFam Zheng };
854a3d9a352SFam Zheng 
855a3d9a352SFam Zheng enum NvmeIdCtrlOncs {
856a3d9a352SFam Zheng     NVME_ONCS_COMPARE       = 1 << 0,
857a3d9a352SFam Zheng     NVME_ONCS_WRITE_UNCORR  = 1 << 1,
858a3d9a352SFam Zheng     NVME_ONCS_DSM           = 1 << 2,
85969265150SKlaus Jensen     NVME_ONCS_WRITE_ZEROES  = 1 << 3,
860a3d9a352SFam Zheng     NVME_ONCS_FEATURES      = 1 << 4,
861a3d9a352SFam Zheng     NVME_ONCS_RESRVATIONS   = 1 << 5,
8623036a626SKenneth Heitke     NVME_ONCS_TIMESTAMP     = 1 << 6,
863a3d9a352SFam Zheng };
864a3d9a352SFam Zheng 
86542a42e46SKlaus Jensen enum NvmeIdCtrlFrmw {
86642a42e46SKlaus Jensen     NVME_FRMW_SLOT1_RO = 1 << 0,
86742a42e46SKlaus Jensen };
86842a42e46SKlaus Jensen 
86994a7897cSKlaus Jensen enum NvmeIdCtrlLpa {
8702fbbecc5SKeith Busch     NVME_LPA_NS_SMART = 1 << 0,
87194a7897cSKlaus Jensen     NVME_LPA_EXTENDED = 1 << 2,
87294a7897cSKlaus Jensen };
87394a7897cSKlaus Jensen 
874a3d9a352SFam Zheng #define NVME_CTRL_SQES_MIN(sqes) ((sqes) & 0xf)
875a3d9a352SFam Zheng #define NVME_CTRL_SQES_MAX(sqes) (((sqes) >> 4) & 0xf)
876a3d9a352SFam Zheng #define NVME_CTRL_CQES_MIN(cqes) ((cqes) & 0xf)
877a3d9a352SFam Zheng #define NVME_CTRL_CQES_MAX(cqes) (((cqes) >> 4) & 0xf)
878a3d9a352SFam Zheng 
879c26f2173SKlaus Jensen #define NVME_CTRL_SGLS_SUPPORT_MASK        (0x3 <<  0)
880c26f2173SKlaus Jensen #define NVME_CTRL_SGLS_SUPPORT_NO_ALIGN    (0x1 <<  0)
881c26f2173SKlaus Jensen #define NVME_CTRL_SGLS_SUPPORT_DWORD_ALIGN (0x1 <<  1)
882c26f2173SKlaus Jensen #define NVME_CTRL_SGLS_KEYED               (0x1 <<  2)
883c26f2173SKlaus Jensen #define NVME_CTRL_SGLS_BITBUCKET           (0x1 << 16)
884c26f2173SKlaus Jensen #define NVME_CTRL_SGLS_MPTR_CONTIGUOUS     (0x1 << 17)
885c26f2173SKlaus Jensen #define NVME_CTRL_SGLS_EXCESS_LENGTH       (0x1 << 18)
886c26f2173SKlaus Jensen #define NVME_CTRL_SGLS_MPTR_SGL            (0x1 << 19)
887c26f2173SKlaus Jensen #define NVME_CTRL_SGLS_ADDR_OFFSET         (0x1 << 20)
888c26f2173SKlaus Jensen 
889a3d9a352SFam Zheng #define NVME_ARB_AB(arb)    (arb & 0x7)
8901302e48eSKlaus Jensen #define NVME_ARB_AB_NOLIMIT 0x7
891a3d9a352SFam Zheng #define NVME_ARB_LPW(arb)   ((arb >> 8) & 0xff)
892a3d9a352SFam Zheng #define NVME_ARB_MPW(arb)   ((arb >> 16) & 0xff)
893a3d9a352SFam Zheng #define NVME_ARB_HPW(arb)   ((arb >> 24) & 0xff)
894a3d9a352SFam Zheng 
895a3d9a352SFam Zheng #define NVME_INTC_THR(intc)     (intc & 0xff)
896a3d9a352SFam Zheng #define NVME_INTC_TIME(intc)    ((intc >> 8) & 0xff)
897a3d9a352SFam Zheng 
8981302e48eSKlaus Jensen #define NVME_INTVC_NOCOALESCING (0x1 << 16)
8991302e48eSKlaus Jensen 
900c26f2173SKlaus Jensen #define NVME_TEMP_THSEL(temp)  ((temp >> 20) & 0x3)
901c26f2173SKlaus Jensen #define NVME_TEMP_THSEL_OVER   0x0
902c26f2173SKlaus Jensen #define NVME_TEMP_THSEL_UNDER  0x1
903c26f2173SKlaus Jensen 
904c26f2173SKlaus Jensen #define NVME_TEMP_TMPSEL(temp)     ((temp >> 16) & 0xf)
905c26f2173SKlaus Jensen #define NVME_TEMP_TMPSEL_COMPOSITE 0x0
906c26f2173SKlaus Jensen 
907c26f2173SKlaus Jensen #define NVME_TEMP_TMPTH(temp) (temp & 0xffff)
908c26f2173SKlaus Jensen 
9095d5a5330SKlaus Jensen #define NVME_AEC_SMART(aec)         (aec & 0xff)
9105d5a5330SKlaus Jensen #define NVME_AEC_NS_ATTR(aec)       ((aec >> 8) & 0x1)
9115d5a5330SKlaus Jensen #define NVME_AEC_FW_ACTIVATION(aec) ((aec >> 9) & 0x1)
9125d5a5330SKlaus Jensen 
913*54064e51SKlaus Jensen #define NVME_ERR_REC_TLER(err_rec)  (err_rec & 0xffff)
914*54064e51SKlaus Jensen #define NVME_ERR_REC_DULBE(err_rec) (err_rec & 0x10000)
915*54064e51SKlaus Jensen 
916a3d9a352SFam Zheng enum NvmeFeatureIds {
917a3d9a352SFam Zheng     NVME_ARBITRATION                = 0x1,
918a3d9a352SFam Zheng     NVME_POWER_MANAGEMENT           = 0x2,
919a3d9a352SFam Zheng     NVME_LBA_RANGE_TYPE             = 0x3,
920a3d9a352SFam Zheng     NVME_TEMPERATURE_THRESHOLD      = 0x4,
921a3d9a352SFam Zheng     NVME_ERROR_RECOVERY             = 0x5,
922a3d9a352SFam Zheng     NVME_VOLATILE_WRITE_CACHE       = 0x6,
923a3d9a352SFam Zheng     NVME_NUMBER_OF_QUEUES           = 0x7,
924a3d9a352SFam Zheng     NVME_INTERRUPT_COALESCING       = 0x8,
925a3d9a352SFam Zheng     NVME_INTERRUPT_VECTOR_CONF      = 0x9,
926a3d9a352SFam Zheng     NVME_WRITE_ATOMICITY            = 0xa,
927a3d9a352SFam Zheng     NVME_ASYNCHRONOUS_EVENT_CONF    = 0xb,
9283036a626SKenneth Heitke     NVME_TIMESTAMP                  = 0xe,
9291302e48eSKlaus Jensen     NVME_SOFTWARE_PROGRESS_MARKER   = 0x80,
9301302e48eSKlaus Jensen     NVME_FID_MAX                    = 0x100,
931a3d9a352SFam Zheng };
932a3d9a352SFam Zheng 
9337c46310dSKlaus Jensen typedef enum NvmeFeatureCap {
9347c46310dSKlaus Jensen     NVME_FEAT_CAP_SAVE      = 1 << 0,
9357c46310dSKlaus Jensen     NVME_FEAT_CAP_NS        = 1 << 1,
9367c46310dSKlaus Jensen     NVME_FEAT_CAP_CHANGE    = 1 << 2,
9377c46310dSKlaus Jensen } NvmeFeatureCap;
9387c46310dSKlaus Jensen 
9397c46310dSKlaus Jensen typedef enum NvmeGetFeatureSelect {
9407c46310dSKlaus Jensen     NVME_GETFEAT_SELECT_CURRENT = 0x0,
9417c46310dSKlaus Jensen     NVME_GETFEAT_SELECT_DEFAULT = 0x1,
9427c46310dSKlaus Jensen     NVME_GETFEAT_SELECT_SAVED   = 0x2,
9437c46310dSKlaus Jensen     NVME_GETFEAT_SELECT_CAP     = 0x3,
9447c46310dSKlaus Jensen } NvmeGetFeatureSelect;
9457c46310dSKlaus Jensen 
9461302e48eSKlaus Jensen #define NVME_GETSETFEAT_FID_MASK 0xff
9471302e48eSKlaus Jensen #define NVME_GETSETFEAT_FID(dw10) (dw10 & NVME_GETSETFEAT_FID_MASK)
9481302e48eSKlaus Jensen 
9497c46310dSKlaus Jensen #define NVME_GETFEAT_SELECT_SHIFT 8
9507c46310dSKlaus Jensen #define NVME_GETFEAT_SELECT_MASK  0x7
9517c46310dSKlaus Jensen #define NVME_GETFEAT_SELECT(dw10) \
9527c46310dSKlaus Jensen     ((dw10 >> NVME_GETFEAT_SELECT_SHIFT) & NVME_GETFEAT_SELECT_MASK)
9537c46310dSKlaus Jensen 
9547c46310dSKlaus Jensen #define NVME_SETFEAT_SAVE_SHIFT 31
9557c46310dSKlaus Jensen #define NVME_SETFEAT_SAVE_MASK  0x1
9567c46310dSKlaus Jensen #define NVME_SETFEAT_SAVE(dw10) \
9577c46310dSKlaus Jensen     ((dw10 >> NVME_SETFEAT_SAVE_SHIFT) & NVME_SETFEAT_SAVE_MASK)
9587c46310dSKlaus Jensen 
959e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeRangeType {
960a3d9a352SFam Zheng     uint8_t     type;
961a3d9a352SFam Zheng     uint8_t     attributes;
962a3d9a352SFam Zheng     uint8_t     rsvd2[14];
963a3d9a352SFam Zheng     uint64_t    slba;
964a3d9a352SFam Zheng     uint64_t    nlb;
965a3d9a352SFam Zheng     uint8_t     guid[16];
966a3d9a352SFam Zheng     uint8_t     rsvd48[16];
967a3d9a352SFam Zheng } NvmeRangeType;
968a3d9a352SFam Zheng 
969e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeLBAF {
970a3d9a352SFam Zheng     uint16_t    ms;
971a3d9a352SFam Zheng     uint8_t     ds;
972a3d9a352SFam Zheng     uint8_t     rp;
973a3d9a352SFam Zheng } NvmeLBAF;
974a3d9a352SFam Zheng 
9757c46310dSKlaus Jensen #define NVME_NSID_BROADCAST 0xffffffff
9767c46310dSKlaus Jensen 
977e989738fSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NvmeIdNs {
978a3d9a352SFam Zheng     uint64_t    nsze;
979a3d9a352SFam Zheng     uint64_t    ncap;
980a3d9a352SFam Zheng     uint64_t    nuse;
981a3d9a352SFam Zheng     uint8_t     nsfeat;
982a3d9a352SFam Zheng     uint8_t     nlbaf;
983a3d9a352SFam Zheng     uint8_t     flbas;
984a3d9a352SFam Zheng     uint8_t     mc;
985a3d9a352SFam Zheng     uint8_t     dpc;
986a3d9a352SFam Zheng     uint8_t     dps;
987e0dd95e3SMaxim Levitsky     uint8_t     nmic;
988e0dd95e3SMaxim Levitsky     uint8_t     rescap;
989e0dd95e3SMaxim Levitsky     uint8_t     fpi;
990e0dd95e3SMaxim Levitsky     uint8_t     dlfeat;
991c26f2173SKlaus Jensen     uint16_t    nawun;
992c26f2173SKlaus Jensen     uint16_t    nawupf;
993c26f2173SKlaus Jensen     uint16_t    nacwu;
994c26f2173SKlaus Jensen     uint16_t    nabsn;
995c26f2173SKlaus Jensen     uint16_t    nabo;
996c26f2173SKlaus Jensen     uint16_t    nabspf;
997c26f2173SKlaus Jensen     uint16_t    noiob;
998c26f2173SKlaus Jensen     uint8_t     nvmcap[16];
999c26f2173SKlaus Jensen     uint8_t     rsvd64[40];
1000c26f2173SKlaus Jensen     uint8_t     nguid[16];
1001c26f2173SKlaus Jensen     uint64_t    eui64;
1002a3d9a352SFam Zheng     NvmeLBAF    lbaf[16];
1003c26f2173SKlaus Jensen     uint8_t     rsvd192[192];
1004a3d9a352SFam Zheng     uint8_t     vs[3712];
1005a3d9a352SFam Zheng } NvmeIdNs;
1006a3d9a352SFam Zheng 
1007c26f2173SKlaus Jensen typedef struct QEMU_PACKED NvmeIdNsDescr {
1008c26f2173SKlaus Jensen     uint8_t nidt;
1009c26f2173SKlaus Jensen     uint8_t nidl;
1010c26f2173SKlaus Jensen     uint8_t rsvd2[2];
1011c26f2173SKlaus Jensen } NvmeIdNsDescr;
1012c26f2173SKlaus Jensen 
1013c26f2173SKlaus Jensen enum {
1014c26f2173SKlaus Jensen     NVME_NIDT_EUI64_LEN =  8,
1015c26f2173SKlaus Jensen     NVME_NIDT_NGUID_LEN = 16,
1016c26f2173SKlaus Jensen     NVME_NIDT_UUID_LEN  = 16,
1017c26f2173SKlaus Jensen };
1018c26f2173SKlaus Jensen 
1019c26f2173SKlaus Jensen enum NvmeNsIdentifierType {
1020c26f2173SKlaus Jensen     NVME_NIDT_EUI64 = 0x1,
1021c26f2173SKlaus Jensen     NVME_NIDT_NGUID = 0x2,
1022c26f2173SKlaus Jensen     NVME_NIDT_UUID  = 0x3,
1023c26f2173SKlaus Jensen };
1024e0dd95e3SMaxim Levitsky 
1025e0dd95e3SMaxim Levitsky /*Deallocate Logical Block Features*/
1026e0dd95e3SMaxim Levitsky #define NVME_ID_NS_DLFEAT_GUARD_CRC(dlfeat)       ((dlfeat) & 0x10)
1027e0dd95e3SMaxim Levitsky #define NVME_ID_NS_DLFEAT_WRITE_ZEROES(dlfeat)    ((dlfeat) & 0x08)
1028e0dd95e3SMaxim Levitsky 
1029e0dd95e3SMaxim Levitsky #define NVME_ID_NS_DLFEAT_READ_BEHAVIOR(dlfeat)     ((dlfeat) & 0x7)
1030e0dd95e3SMaxim Levitsky #define NVME_ID_NS_DLFEAT_READ_BEHAVIOR_UNDEFINED   0
1031e0dd95e3SMaxim Levitsky #define NVME_ID_NS_DLFEAT_READ_BEHAVIOR_ZEROES      1
1032e0dd95e3SMaxim Levitsky #define NVME_ID_NS_DLFEAT_READ_BEHAVIOR_ONES        2
1033e0dd95e3SMaxim Levitsky 
1034e0dd95e3SMaxim Levitsky 
1035a3d9a352SFam Zheng #define NVME_ID_NS_NSFEAT_THIN(nsfeat)      ((nsfeat & 0x1))
1036*54064e51SKlaus Jensen #define NVME_ID_NS_NSFEAT_DULBE(nsfeat)     ((nsfeat >> 2) & 0x1)
1037a3d9a352SFam Zheng #define NVME_ID_NS_FLBAS_EXTENDED(flbas)    ((flbas >> 4) & 0x1)
1038a3d9a352SFam Zheng #define NVME_ID_NS_FLBAS_INDEX(flbas)       ((flbas & 0xf))
1039a3d9a352SFam Zheng #define NVME_ID_NS_MC_SEPARATE(mc)          ((mc >> 1) & 0x1)
1040a3d9a352SFam Zheng #define NVME_ID_NS_MC_EXTENDED(mc)          ((mc & 0x1))
1041a3d9a352SFam Zheng #define NVME_ID_NS_DPC_LAST_EIGHT(dpc)      ((dpc >> 4) & 0x1)
1042a3d9a352SFam Zheng #define NVME_ID_NS_DPC_FIRST_EIGHT(dpc)     ((dpc >> 3) & 0x1)
1043a3d9a352SFam Zheng #define NVME_ID_NS_DPC_TYPE_3(dpc)          ((dpc >> 2) & 0x1)
1044a3d9a352SFam Zheng #define NVME_ID_NS_DPC_TYPE_2(dpc)          ((dpc >> 1) & 0x1)
1045a3d9a352SFam Zheng #define NVME_ID_NS_DPC_TYPE_1(dpc)          ((dpc & 0x1))
1046a3d9a352SFam Zheng #define NVME_ID_NS_DPC_TYPE_MASK            0x7
1047a3d9a352SFam Zheng 
1048a3d9a352SFam Zheng enum NvmeIdNsDps {
1049a3d9a352SFam Zheng     DPS_TYPE_NONE   = 0,
1050a3d9a352SFam Zheng     DPS_TYPE_1      = 1,
1051a3d9a352SFam Zheng     DPS_TYPE_2      = 2,
1052a3d9a352SFam Zheng     DPS_TYPE_3      = 3,
1053a3d9a352SFam Zheng     DPS_TYPE_MASK   = 0x7,
1054a3d9a352SFam Zheng     DPS_FIRST_EIGHT = 8,
1055a3d9a352SFam Zheng };
1056a3d9a352SFam Zheng 
1057a3d9a352SFam Zheng static inline void _nvme_check_size(void)
1058a3d9a352SFam Zheng {
105974e18435SPhilippe Mathieu-Daudé     QEMU_BUILD_BUG_ON(sizeof(NvmeBar) != 4096);
1060a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeAerResult) != 4);
1061a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeCqe) != 16);
1062a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeDsmRange) != 16);
1063a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeCmd) != 64);
1064a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeDeleteQ) != 64);
1065a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeCreateCq) != 64);
1066a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeCreateSq) != 64);
1067a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeIdentify) != 64);
1068a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeRwCmd) != 64);
1069a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeDsmCmd) != 64);
1070a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeRangeType) != 64);
1071a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeErrorLog) != 64);
1072a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeFwSlotInfoLog) != 512);
1073a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLog) != 512);
1074a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrl) != 4096);
1075a3d9a352SFam Zheng     QEMU_BUILD_BUG_ON(sizeof(NvmeIdNs) != 4096);
1076c26f2173SKlaus Jensen     QEMU_BUILD_BUG_ON(sizeof(NvmeSglDescriptor) != 16);
1077c26f2173SKlaus Jensen     QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsDescr) != 4);
1078a3d9a352SFam Zheng }
1079a3d9a352SFam Zheng #endif
1080