Message ID | 20200630043122.1307043-2-its@irrelevant.dk |
---|---|
State | New |
Headers | show |
Series | hw/block/nvme: bump to v1.4 | expand |
On 6/30/20 6:31 AM, Klaus Jensen wrote: > From: Klaus Jensen <k.jensen@samsung.com> > > Add new fields from NVM Express v1.4. > > Signed-off-by: Klaus Jensen <klaus.jensen@cnexlabs.com> > --- > hw/block/nvme.c | 3 +- > include/block/nvme.h | 195 +++++++++++++++++++++++++++++++++++++------ > 2 files changed, 172 insertions(+), 26 deletions(-) > > diff --git a/hw/block/nvme.c b/hw/block/nvme.c > index 8e147b667c81..07ac409f37c9 100644 > --- a/hw/block/nvme.c > +++ b/hw/block/nvme.c > @@ -60,7 +60,7 @@ > #define NVME_MAX_IOQPAIRS 0xffff > #define NVME_REG_SIZE 0x1000 > #define NVME_DB_SIZE 4 > -#define NVME_SPEC_VER 0x00010300 > +#define NVME_SPEC_VER 0x00010400 > #define NVME_CMB_BIR 2 > #define NVME_PMR_BIR 2 > #define NVME_TEMPERATURE 0x143 > @@ -2910,6 +2910,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev) > id->ieee[2] = 0xb3; > id->mdts = n->params.mdts; > id->ver = cpu_to_le32(NVME_SPEC_VER); > + id->cntrltype = 0x1; > id->oacs = cpu_to_le16(0); > > /* > diff --git a/include/block/nvme.h b/include/block/nvme.h > index 2a9c5e95bfd2..b27be237cd33 100644 > --- a/include/block/nvme.h > +++ b/include/block/nvme.h > @@ -7,7 +7,7 @@ typedef struct NvmeBar { > uint32_t intms; > uint32_t intmc; > uint32_t cc; > - uint32_t rsvd1; > + uint8_t rsvd24[4]; > uint32_t csts; > uint32_t nssrc; > uint32_t aqa; > @@ -15,14 +15,20 @@ typedef struct NvmeBar { > uint64_t acq; > uint32_t cmbloc; > uint32_t cmbsz; > - uint8_t padding[3520]; /* not used by QEMU */ > + uint32_t bpinfo; > + uint32_t bprsel; > + uint64_t bpmbl; > + uint64_t cmbmsc; > + uint32_t cmbsts; > + uint8_t rsvd92[3492]; > uint32_t pmrcap; > uint32_t pmrctl; > uint32_t pmrsts; > uint32_t pmrebs; > uint32_t pmrswtp; > - uint32_t pmrmsc; > -} NvmeBar; > + uint64_t pmrmsc; > + uint8_t rsvd3612[484]; > +} QEMU_PACKED NvmeBar; > > enum NvmeCapShift { > CAP_MQES_SHIFT = 0, > @@ -34,7 +40,8 @@ enum NvmeCapShift { > CAP_CSS_SHIFT = 37, > CAP_MPSMIN_SHIFT = 48, > CAP_MPSMAX_SHIFT = 52, > - CAP_PMR_SHIFT = 56, > + CAP_PMRS_SHIFT = 56, > + CAP_CMBS_SHIFT = 57, > }; > > enum NvmeCapMask { > @@ -47,7 +54,8 @@ enum NvmeCapMask { > CAP_CSS_MASK = 0xff, > CAP_MPSMIN_MASK = 0xf, > CAP_MPSMAX_MASK = 0xf, > - CAP_PMR_MASK = 0x1, > + CAP_PMRS_MASK = 0x1, > + CAP_CMBS_MASK = 0x1, > }; > > #define NVME_CAP_MQES(cap) (((cap) >> CAP_MQES_SHIFT) & CAP_MQES_MASK) > @@ -59,6 +67,8 @@ enum NvmeCapMask { > #define NVME_CAP_CSS(cap) (((cap) >> CAP_CSS_SHIFT) & CAP_CSS_MASK) > #define NVME_CAP_MPSMIN(cap)(((cap) >> CAP_MPSMIN_SHIFT) & CAP_MPSMIN_MASK) > #define NVME_CAP_MPSMAX(cap)(((cap) >> CAP_MPSMAX_SHIFT) & CAP_MPSMAX_MASK) > +#define NVME_CAP_PMRS(cap) (((cap) >> CAP_PMRS_SHIFT) & CAP_PMRS_MASK) > +#define NVME_CAP_CMBS(cap) (((cap) >> CAP_CMBS_SHIFT) & CAP_CMBS_MASK) > > #define NVME_CAP_SET_MQES(cap, val) (cap |= (uint64_t)(val & CAP_MQES_MASK) \ > << CAP_MQES_SHIFT) > @@ -78,8 +88,10 @@ enum NvmeCapMask { > << CAP_MPSMIN_SHIFT) > #define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\ > << CAP_MPSMAX_SHIFT) > -#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\ > - << CAP_PMR_SHIFT) > +#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMRS_MASK)\ > + << CAP_PMRS_SHIFT) > +#define NVME_CAP_SET_CMBS(cap, val) (cap |= (uint64_t)(val & CAP_CMBS_MASK)\ > + << CAP_CMBS_SHIFT) > > enum NvmeCcShift { > CC_EN_SHIFT = 0, > @@ -151,22 +163,58 @@ enum NvmeAqaMask { > #define NVME_AQA_ACQS(aqa) ((aqa >> AQA_ACQS_SHIFT) & AQA_ACQS_MASK) > > enum NvmeCmblocShift { > - CMBLOC_BIR_SHIFT = 0, > - CMBLOC_OFST_SHIFT = 12, > + CMBLOC_BIR_SHIFT = 0, > + CMBLOC_CQMMS_SHIFT = 3, > + CMBLOC_CQPDS_SHIFT = 4, > + CMBLOC_CDPMLS_SHIFT = 5, > + CMBLOC_CDPCILS_SHIFT = 6, > + CMBLOC_CDMMMS_SHIFT = 7, > + CMBLOC_CQDA_SHIFT = 8, > + CMBLOC_OFST_SHIFT = 12, > }; > > enum NvmeCmblocMask { > - CMBLOC_BIR_MASK = 0x7, > - CMBLOC_OFST_MASK = 0xfffff, > + CMBLOC_BIR_MASK = 0x7, > + CMBLOC_CQMMS_MASK = 0x1, > + CMBLOC_CQPDS_MASK = 0x1, > + CMBLOC_CDPMLS_MASK = 0x1, > + CMBLOC_CDPCILS_MASK = 0x1, > + CMBLOC_CDMMMS_MASK = 0x1, > + CMBLOC_CQDA_MASK = 0x1, > + CMBLOC_OFST_MASK = 0xfffff, > }; > > -#define NVME_CMBLOC_BIR(cmbloc) ((cmbloc >> CMBLOC_BIR_SHIFT) & \ > - CMBLOC_BIR_MASK) > -#define NVME_CMBLOC_OFST(cmbloc)((cmbloc >> CMBLOC_OFST_SHIFT) & \ > - CMBLOC_OFST_MASK) > +#define NVME_CMBLOC_BIR(cmbloc) \ > + ((cmbloc >> CMBLOC_BIR_SHIFT) & CMBLOC_BIR_MASK) > +#define NVME_CMBLOC_CQMMS(cmbloc) \ > + ((cmbloc >> CMBLOC_CQMMS_SHIFT) & CMBLOC_CQMMS_MASK) > +#define NVME_CMBLOC_CQPDS(cmbloc) \ > + ((cmbloc >> CMBLOC_CQPDS_SHIFT) & CMBLOC_CQPDS_MASK) > +#define NVME_CMBLOC_CDPMLS(cmbloc) \ > + ((cmbloc >> CMBLOC_CDPMLS_SHIFT) & CMBLOC_CDPMLS_MASK) > +#define NVME_CMBLOC_CDPCILS(cmbloc) \ > + ((cmbloc >> CMBLOC_CDPCILS_SHIFT) & CMBLOC_CDPCILS_MASK) > +#define NVME_CMBLOC_CDMMS(cmbloc) \ > + ((cmbloc >> CMBLOC_CDMMS_SHIFT) & CMBLOC_CDMMS_MASK) > +#define NVME_CMBLOC_CQDA(cmbloc) \ > + ((cmbloc >> CMBLOC_CQDA_SHIFT) & CMBLOC_CQDA_MASK) > +#define NVME_CMBLOC_OFST(cmbloc) \ > + ((cmbloc >> CMBLOC_OFST_SHIFT) & CMBLOC_OFST_MASK) > > -#define NVME_CMBLOC_SET_BIR(cmbloc, val) \ > +#define NVME_CMBLOC_SET_BIR(cmbloc, val) \ > (cmbloc |= (uint64_t)(val & CMBLOC_BIR_MASK) << CMBLOC_BIR_SHIFT) > +#define NVME_CMBLOC_SET_CQMMS(cmbloc, val) \ > + (cmbloc |= (uint64_t)(val & CMBLOC_CQMMS_MASK) << CMBLOC_CQMMS_SHIFT) > +#define NVME_CMBLOC_SET_CQPDS(cmbloc, val) \ > + (cmbloc |= (uint64_t)(val & CMBLOC_CQPDS_MASK) << CMBLOC_CQPDS_SHIFT) > +#define NVME_CMBLOC_SET_CDPMLS(cmbloc, val) \ > + (cmbloc |= (uint64_t)(val & CMBLOC_CDPMLS_MASK) << CMBLOC_CDPMLS_SHIFT) > +#define NVME_CMBLOC_SET_CDPCILS(cmbloc, val) \ > + (cmbloc |= (uint64_t)(val & CMBLOC_CDPCILS_MASK) << CMBLOC_CDPCILS_SHIFT) > +#define NVME_CMBLOC_SET_CDMMS(cmbloc, val) \ > + (cmbloc |= (uint64_t)(val & CMBLOC_CDMMS_MASK) << CMBLOC_CDMMS_SHIFT) > +#define NVME_CMBLOC_SET_CQDA(cmbloc, val) \ > + (cmbloc |= (uint64_t)(val & CMBLOC_CQDA_MASK) << CMBLOC_CQDA_SHIFT) > #define NVME_CMBLOC_SET_OFST(cmbloc, val) \ > (cmbloc |= (uint64_t)(val & CMBLOC_OFST_MASK) << CMBLOC_OFST_SHIFT) > > @@ -377,6 +425,35 @@ enum NvmePmrmscMask { > #define NVME_PMRMSC_SET_CBA(pmrmsc, val) \ > (pmrmsc |= (uint64_t)(val & PMRMSC_CBA_MASK) << PMRMSC_CBA_SHIFT) > > +enum NvmeCmbmscShift { > + CMBMSC_CRE_SHIFT = 0, > + CMBMSC_CMSE_SHIFT = 1, > + CMBMSC_CBA_SHIFT = 12, > +}; > + > +enum NvmeCmbmscMask { > + CMBMSC_CRE_MASK = 0x1, > + CMBMSC_CMSE_MASK = 0x1, > +}; > + > +#define CMBMSC_CBA_MASK ((1 << 52) - 1) > + > +#define NVME_CMBMSC_CRE(cmbmsc) \ > + ((cmbmsc >> CMBMSC_CRE_SHIFT) & CMBMSC_CRE_MASK) > +#define NVME_CMBMSC_CMSE(cmbmsc) \ > + ((cmbmsc >> CMBMSC_CMSE_SHIFT) & CMBMSC_CMSE_MASK) > +#define NVME_CMBMSC_CBA(cmbmsc) \ > + ((cmbmsc >> CMBMSC_CBA_SHIFT) & CMBMSC_CBA_MASK) > + > +#define NVME_CMBMSC_SET_CRE(cmbmsc, val) \ > + (cmbmsc |= (uint64_t)(val & CMBMSC_CRE_MASK) << CMBMSC_CRE_SHIFT) > +#define NVME_CMBMSC_SET_CMSE(cmbmsc, val) \ > + (cmbmsc |= (uint64_t)(val & CMBMSC_CMSE_MASK) << CMBMSC_CMSE_SHIFT) > +#define NVME_CMBMSC_SET_CBA(cmbmsc, val) \ > + (cmbmsc |= (uint64_t)(val & CMBMSC_CBA_MASK) << CMBMSC_CBA_SHIFT) > + > +#define NVME_CMBSTS_CBAI(cmbsts) (cmsts & 0x1) > + > enum NvmeSglDescriptorType { > NVME_SGL_DESCR_TYPE_DATA_BLOCK = 0x0, > NVME_SGL_DESCR_TYPE_BIT_BUCKET = 0x1, > @@ -523,8 +600,12 @@ typedef struct NvmeIdentify { > uint64_t rsvd2[2]; > uint64_t prp1; > uint64_t prp2; > - uint32_t cns; > - uint32_t rsvd11[5]; > + uint8_t cns; > + uint8_t rsvd3; > + uint16_t cntid; > + uint16_t nvmsetid; > + uint16_t rsvd4; > + uint32_t rsvd11[4]; > } NvmeIdentify; > > typedef struct NvmeRwCmd { > @@ -681,6 +762,23 @@ enum NvmeStatusCodes { > NVME_NO_COMPLETE = 0xffff, > }; > > +typedef struct NvmeNvmSetAttributes { > + uint16_t nvmsetid; > + uint16_t endgid; > + uint8_t rsvd7[4]; > + uint32_t rrt; > + uint32_t ows; > + uint8_t tnvmsetcap[16]; > + uint8_t unvmsetcap[16]; > + uint8_t rsvd127[80]; > +} NvmeNvmSetAttributes; > + > +typedef struct NvmeIdNvmSetList { > + uint8_t nid; > + uint8_t rsvd127[127]; > + NvmeNvmSetAttributes sets[31]; > +} NvmeIdNvmSetList; > + > typedef struct NvmeFwSlotInfoLog { > uint8_t afi; > uint8_t reserved1[7]; > @@ -734,6 +832,24 @@ enum NvmeSmartWarn { > NVME_SMART_FAILED_VOLATILE_MEDIA = 1 << 4, > }; > > +typedef struct NvmeEnduranceGroupLog { > + uint8_t critical_warning; > + uint8_t rsvd2[2]; > + uint8_t available_spare; > + uint8_t available_spare_threshold; > + uint8_t percentage_used; > + uint8_t rsvd31[26]; > + uint8_t endurance_estimate[16]; > + uint8_t data_units_read[16]; > + uint8_t data_units_written[16]; > + uint8_t media_units_written[16]; > + uint8_t host_read_commands[16]; > + uint8_t host_write_commands[16]; > + uint8_t media_and_data_integrity_errors[16]; > + uint8_t number_of_error_information_log_entries[16]; > + uint8_t rsvd511[352]; > +} NvmeEnduranceGroupLog; > + > enum NvmeLogIdentifier { > NVME_LOG_ERROR_INFO = 0x01, > NVME_LOG_SMART_INFO = 0x02, > @@ -777,9 +893,14 @@ typedef struct NvmeIdCtrl { > uint32_t rtd3e; > uint32_t oaes; > uint32_t ctratt; > - uint8_t rsvd100[12]; > + uint16_t rrls; > + uint8_t rsvd102[9]; > + uint8_t cntrltype; > uint8_t fguid[16]; > - uint8_t rsvd128[128]; > + uint16_t crdt1; > + uint16_t crdt2; > + uint16_t crdt3; > + uint8_t rsvd134[122]; > uint16_t oacs; > uint8_t acl; > uint8_t aerl; > @@ -805,7 +926,16 @@ typedef struct NvmeIdCtrl { > uint16_t mntmt; > uint16_t mxtmt; > uint32_t sanicap; > - uint8_t rsvd332[180]; > + uint32_t hmminds; > + uint16_t hmmaxd; > + uint16_t nsetidmax; > + uint16_t endgidmax; > + uint8_t anatt; > + uint8_t anacap; > + uint32_t anagrpmax; > + uint32_t nanagrpid; > + uint32_t pels; > + uint8_t rsvd356[156]; > uint8_t sqes; > uint8_t cqes; > uint16_t maxcmd; > @@ -817,11 +947,12 @@ typedef struct NvmeIdCtrl { > uint16_t awun; > uint16_t awupf; > uint8_t nvscc; > - uint8_t rsvd531; > + uint8_t nwpc; > uint16_t acwu; > uint8_t rsvd534[2]; > uint32_t sgls; > - uint8_t rsvd540[228]; > + uint32_t mnan; > + uint8_t rsvd544[224]; > uint8_t subnqn[256]; > uint8_t rsvd1024[1024]; > NvmePSD psd[32]; > @@ -976,7 +1107,17 @@ typedef struct NvmeIdNs { > uint16_t nabspf; > uint16_t noiob; > uint8_t nvmcap[16]; > - uint8_t rsvd64[40]; > + uint16_t npwg; > + uint16_t npwa; > + uint16_t npdg; > + uint16_t npda; > + uint16_t nows; > + uint8_t rsvd74[18]; > + uint32_t anagrpid; > + uint8_t rsvd96[3]; > + uint8_t nsattr; > + uint16_t nvmsetid; > + uint16_t endgid; > uint8_t nguid[16]; > uint64_t eui64; > NvmeLBAF lbaf[16]; > @@ -1048,7 +1189,11 @@ static inline void _nvme_check_size(void) > QEMU_BUILD_BUG_ON(sizeof(NvmeErrorLog) != 64); > QEMU_BUILD_BUG_ON(sizeof(NvmeFwSlotInfoLog) != 512); > QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLog) != 512); > + QEMU_BUILD_BUG_ON(sizeof(NvmeEnduranceGroupLog) != 512); > QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrl) != 4096); > QEMU_BUILD_BUG_ON(sizeof(NvmeIdNs) != 4096); > + QEMU_BUILD_BUG_ON(sizeof(NvmeNvmSetAttributes) != 128); > + QEMU_BUILD_BUG_ON(sizeof(NvmeIdNvmSetList) != 4096); > + QEMU_BUILD_BUG_ON(sizeof(NvmeBar) != 4096); > } > #endif >
diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 8e147b667c81..07ac409f37c9 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -60,7 +60,7 @@ #define NVME_MAX_IOQPAIRS 0xffff #define NVME_REG_SIZE 0x1000 #define NVME_DB_SIZE 4 -#define NVME_SPEC_VER 0x00010300 +#define NVME_SPEC_VER 0x00010400 #define NVME_CMB_BIR 2 #define NVME_PMR_BIR 2 #define NVME_TEMPERATURE 0x143 @@ -2910,6 +2910,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev) id->ieee[2] = 0xb3; id->mdts = n->params.mdts; id->ver = cpu_to_le32(NVME_SPEC_VER); + id->cntrltype = 0x1; id->oacs = cpu_to_le16(0); /* diff --git a/include/block/nvme.h b/include/block/nvme.h index 2a9c5e95bfd2..b27be237cd33 100644 --- a/include/block/nvme.h +++ b/include/block/nvme.h @@ -7,7 +7,7 @@ typedef struct NvmeBar { uint32_t intms; uint32_t intmc; uint32_t cc; - uint32_t rsvd1; + uint8_t rsvd24[4]; uint32_t csts; uint32_t nssrc; uint32_t aqa; @@ -15,14 +15,20 @@ typedef struct NvmeBar { uint64_t acq; uint32_t cmbloc; uint32_t cmbsz; - uint8_t padding[3520]; /* not used by QEMU */ + uint32_t bpinfo; + uint32_t bprsel; + uint64_t bpmbl; + uint64_t cmbmsc; + uint32_t cmbsts; + uint8_t rsvd92[3492]; uint32_t pmrcap; uint32_t pmrctl; uint32_t pmrsts; uint32_t pmrebs; uint32_t pmrswtp; - uint32_t pmrmsc; -} NvmeBar; + uint64_t pmrmsc; + uint8_t rsvd3612[484]; +} QEMU_PACKED NvmeBar; enum NvmeCapShift { CAP_MQES_SHIFT = 0, @@ -34,7 +40,8 @@ enum NvmeCapShift { CAP_CSS_SHIFT = 37, CAP_MPSMIN_SHIFT = 48, CAP_MPSMAX_SHIFT = 52, - CAP_PMR_SHIFT = 56, + CAP_PMRS_SHIFT = 56, + CAP_CMBS_SHIFT = 57, }; enum NvmeCapMask { @@ -47,7 +54,8 @@ enum NvmeCapMask { CAP_CSS_MASK = 0xff, CAP_MPSMIN_MASK = 0xf, CAP_MPSMAX_MASK = 0xf, - CAP_PMR_MASK = 0x1, + CAP_PMRS_MASK = 0x1, + CAP_CMBS_MASK = 0x1, }; #define NVME_CAP_MQES(cap) (((cap) >> CAP_MQES_SHIFT) & CAP_MQES_MASK) @@ -59,6 +67,8 @@ enum NvmeCapMask { #define NVME_CAP_CSS(cap) (((cap) >> CAP_CSS_SHIFT) & CAP_CSS_MASK) #define NVME_CAP_MPSMIN(cap)(((cap) >> CAP_MPSMIN_SHIFT) & CAP_MPSMIN_MASK) #define NVME_CAP_MPSMAX(cap)(((cap) >> CAP_MPSMAX_SHIFT) & CAP_MPSMAX_MASK) +#define NVME_CAP_PMRS(cap) (((cap) >> CAP_PMRS_SHIFT) & CAP_PMRS_MASK) +#define NVME_CAP_CMBS(cap) (((cap) >> CAP_CMBS_SHIFT) & CAP_CMBS_MASK) #define NVME_CAP_SET_MQES(cap, val) (cap |= (uint64_t)(val & CAP_MQES_MASK) \ << CAP_MQES_SHIFT) @@ -78,8 +88,10 @@ enum NvmeCapMask { << CAP_MPSMIN_SHIFT) #define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\ << CAP_MPSMAX_SHIFT) -#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\ - << CAP_PMR_SHIFT) +#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMRS_MASK)\ + << CAP_PMRS_SHIFT) +#define NVME_CAP_SET_CMBS(cap, val) (cap |= (uint64_t)(val & CAP_CMBS_MASK)\ + << CAP_CMBS_SHIFT) enum NvmeCcShift { CC_EN_SHIFT = 0, @@ -151,22 +163,58 @@ enum NvmeAqaMask { #define NVME_AQA_ACQS(aqa) ((aqa >> AQA_ACQS_SHIFT) & AQA_ACQS_MASK) enum NvmeCmblocShift { - CMBLOC_BIR_SHIFT = 0, - CMBLOC_OFST_SHIFT = 12, + CMBLOC_BIR_SHIFT = 0, + CMBLOC_CQMMS_SHIFT = 3, + CMBLOC_CQPDS_SHIFT = 4, + CMBLOC_CDPMLS_SHIFT = 5, + CMBLOC_CDPCILS_SHIFT = 6, + CMBLOC_CDMMMS_SHIFT = 7, + CMBLOC_CQDA_SHIFT = 8, + CMBLOC_OFST_SHIFT = 12, }; enum NvmeCmblocMask { - CMBLOC_BIR_MASK = 0x7, - CMBLOC_OFST_MASK = 0xfffff, + CMBLOC_BIR_MASK = 0x7, + CMBLOC_CQMMS_MASK = 0x1, + CMBLOC_CQPDS_MASK = 0x1, + CMBLOC_CDPMLS_MASK = 0x1, + CMBLOC_CDPCILS_MASK = 0x1, + CMBLOC_CDMMMS_MASK = 0x1, + CMBLOC_CQDA_MASK = 0x1, + CMBLOC_OFST_MASK = 0xfffff, }; -#define NVME_CMBLOC_BIR(cmbloc) ((cmbloc >> CMBLOC_BIR_SHIFT) & \ - CMBLOC_BIR_MASK) -#define NVME_CMBLOC_OFST(cmbloc)((cmbloc >> CMBLOC_OFST_SHIFT) & \ - CMBLOC_OFST_MASK) +#define NVME_CMBLOC_BIR(cmbloc) \ + ((cmbloc >> CMBLOC_BIR_SHIFT) & CMBLOC_BIR_MASK) +#define NVME_CMBLOC_CQMMS(cmbloc) \ + ((cmbloc >> CMBLOC_CQMMS_SHIFT) & CMBLOC_CQMMS_MASK) +#define NVME_CMBLOC_CQPDS(cmbloc) \ + ((cmbloc >> CMBLOC_CQPDS_SHIFT) & CMBLOC_CQPDS_MASK) +#define NVME_CMBLOC_CDPMLS(cmbloc) \ + ((cmbloc >> CMBLOC_CDPMLS_SHIFT) & CMBLOC_CDPMLS_MASK) +#define NVME_CMBLOC_CDPCILS(cmbloc) \ + ((cmbloc >> CMBLOC_CDPCILS_SHIFT) & CMBLOC_CDPCILS_MASK) +#define NVME_CMBLOC_CDMMS(cmbloc) \ + ((cmbloc >> CMBLOC_CDMMS_SHIFT) & CMBLOC_CDMMS_MASK) +#define NVME_CMBLOC_CQDA(cmbloc) \ + ((cmbloc >> CMBLOC_CQDA_SHIFT) & CMBLOC_CQDA_MASK) +#define NVME_CMBLOC_OFST(cmbloc) \ + ((cmbloc >> CMBLOC_OFST_SHIFT) & CMBLOC_OFST_MASK) -#define NVME_CMBLOC_SET_BIR(cmbloc, val) \ +#define NVME_CMBLOC_SET_BIR(cmbloc, val) \ (cmbloc |= (uint64_t)(val & CMBLOC_BIR_MASK) << CMBLOC_BIR_SHIFT) +#define NVME_CMBLOC_SET_CQMMS(cmbloc, val) \ + (cmbloc |= (uint64_t)(val & CMBLOC_CQMMS_MASK) << CMBLOC_CQMMS_SHIFT) +#define NVME_CMBLOC_SET_CQPDS(cmbloc, val) \ + (cmbloc |= (uint64_t)(val & CMBLOC_CQPDS_MASK) << CMBLOC_CQPDS_SHIFT) +#define NVME_CMBLOC_SET_CDPMLS(cmbloc, val) \ + (cmbloc |= (uint64_t)(val & CMBLOC_CDPMLS_MASK) << CMBLOC_CDPMLS_SHIFT) +#define NVME_CMBLOC_SET_CDPCILS(cmbloc, val) \ + (cmbloc |= (uint64_t)(val & CMBLOC_CDPCILS_MASK) << CMBLOC_CDPCILS_SHIFT) +#define NVME_CMBLOC_SET_CDMMS(cmbloc, val) \ + (cmbloc |= (uint64_t)(val & CMBLOC_CDMMS_MASK) << CMBLOC_CDMMS_SHIFT) +#define NVME_CMBLOC_SET_CQDA(cmbloc, val) \ + (cmbloc |= (uint64_t)(val & CMBLOC_CQDA_MASK) << CMBLOC_CQDA_SHIFT) #define NVME_CMBLOC_SET_OFST(cmbloc, val) \ (cmbloc |= (uint64_t)(val & CMBLOC_OFST_MASK) << CMBLOC_OFST_SHIFT) @@ -377,6 +425,35 @@ enum NvmePmrmscMask { #define NVME_PMRMSC_SET_CBA(pmrmsc, val) \ (pmrmsc |= (uint64_t)(val & PMRMSC_CBA_MASK) << PMRMSC_CBA_SHIFT) +enum NvmeCmbmscShift { + CMBMSC_CRE_SHIFT = 0, + CMBMSC_CMSE_SHIFT = 1, + CMBMSC_CBA_SHIFT = 12, +}; + +enum NvmeCmbmscMask { + CMBMSC_CRE_MASK = 0x1, + CMBMSC_CMSE_MASK = 0x1, +}; + +#define CMBMSC_CBA_MASK ((1 << 52) - 1) + +#define NVME_CMBMSC_CRE(cmbmsc) \ + ((cmbmsc >> CMBMSC_CRE_SHIFT) & CMBMSC_CRE_MASK) +#define NVME_CMBMSC_CMSE(cmbmsc) \ + ((cmbmsc >> CMBMSC_CMSE_SHIFT) & CMBMSC_CMSE_MASK) +#define NVME_CMBMSC_CBA(cmbmsc) \ + ((cmbmsc >> CMBMSC_CBA_SHIFT) & CMBMSC_CBA_MASK) + +#define NVME_CMBMSC_SET_CRE(cmbmsc, val) \ + (cmbmsc |= (uint64_t)(val & CMBMSC_CRE_MASK) << CMBMSC_CRE_SHIFT) +#define NVME_CMBMSC_SET_CMSE(cmbmsc, val) \ + (cmbmsc |= (uint64_t)(val & CMBMSC_CMSE_MASK) << CMBMSC_CMSE_SHIFT) +#define NVME_CMBMSC_SET_CBA(cmbmsc, val) \ + (cmbmsc |= (uint64_t)(val & CMBMSC_CBA_MASK) << CMBMSC_CBA_SHIFT) + +#define NVME_CMBSTS_CBAI(cmbsts) (cmsts & 0x1) + enum NvmeSglDescriptorType { NVME_SGL_DESCR_TYPE_DATA_BLOCK = 0x0, NVME_SGL_DESCR_TYPE_BIT_BUCKET = 0x1, @@ -523,8 +600,12 @@ typedef struct NvmeIdentify { uint64_t rsvd2[2]; uint64_t prp1; uint64_t prp2; - uint32_t cns; - uint32_t rsvd11[5]; + uint8_t cns; + uint8_t rsvd3; + uint16_t cntid; + uint16_t nvmsetid; + uint16_t rsvd4; + uint32_t rsvd11[4]; } NvmeIdentify; typedef struct NvmeRwCmd { @@ -681,6 +762,23 @@ enum NvmeStatusCodes { NVME_NO_COMPLETE = 0xffff, }; +typedef struct NvmeNvmSetAttributes { + uint16_t nvmsetid; + uint16_t endgid; + uint8_t rsvd7[4]; + uint32_t rrt; + uint32_t ows; + uint8_t tnvmsetcap[16]; + uint8_t unvmsetcap[16]; + uint8_t rsvd127[80]; +} NvmeNvmSetAttributes; + +typedef struct NvmeIdNvmSetList { + uint8_t nid; + uint8_t rsvd127[127]; + NvmeNvmSetAttributes sets[31]; +} NvmeIdNvmSetList; + typedef struct NvmeFwSlotInfoLog { uint8_t afi; uint8_t reserved1[7]; @@ -734,6 +832,24 @@ enum NvmeSmartWarn { NVME_SMART_FAILED_VOLATILE_MEDIA = 1 << 4, }; +typedef struct NvmeEnduranceGroupLog { + uint8_t critical_warning; + uint8_t rsvd2[2]; + uint8_t available_spare; + uint8_t available_spare_threshold; + uint8_t percentage_used; + uint8_t rsvd31[26]; + uint8_t endurance_estimate[16]; + uint8_t data_units_read[16]; + uint8_t data_units_written[16]; + uint8_t media_units_written[16]; + uint8_t host_read_commands[16]; + uint8_t host_write_commands[16]; + uint8_t media_and_data_integrity_errors[16]; + uint8_t number_of_error_information_log_entries[16]; + uint8_t rsvd511[352]; +} NvmeEnduranceGroupLog; + enum NvmeLogIdentifier { NVME_LOG_ERROR_INFO = 0x01, NVME_LOG_SMART_INFO = 0x02, @@ -777,9 +893,14 @@ typedef struct NvmeIdCtrl { uint32_t rtd3e; uint32_t oaes; uint32_t ctratt; - uint8_t rsvd100[12]; + uint16_t rrls; + uint8_t rsvd102[9]; + uint8_t cntrltype; uint8_t fguid[16]; - uint8_t rsvd128[128]; + uint16_t crdt1; + uint16_t crdt2; + uint16_t crdt3; + uint8_t rsvd134[122]; uint16_t oacs; uint8_t acl; uint8_t aerl; @@ -805,7 +926,16 @@ typedef struct NvmeIdCtrl { uint16_t mntmt; uint16_t mxtmt; uint32_t sanicap; - uint8_t rsvd332[180]; + uint32_t hmminds; + uint16_t hmmaxd; + uint16_t nsetidmax; + uint16_t endgidmax; + uint8_t anatt; + uint8_t anacap; + uint32_t anagrpmax; + uint32_t nanagrpid; + uint32_t pels; + uint8_t rsvd356[156]; uint8_t sqes; uint8_t cqes; uint16_t maxcmd; @@ -817,11 +947,12 @@ typedef struct NvmeIdCtrl { uint16_t awun; uint16_t awupf; uint8_t nvscc; - uint8_t rsvd531; + uint8_t nwpc; uint16_t acwu; uint8_t rsvd534[2]; uint32_t sgls; - uint8_t rsvd540[228]; + uint32_t mnan; + uint8_t rsvd544[224]; uint8_t subnqn[256]; uint8_t rsvd1024[1024]; NvmePSD psd[32]; @@ -976,7 +1107,17 @@ typedef struct NvmeIdNs { uint16_t nabspf; uint16_t noiob; uint8_t nvmcap[16]; - uint8_t rsvd64[40]; + uint16_t npwg; + uint16_t npwa; + uint16_t npdg; + uint16_t npda; + uint16_t nows; + uint8_t rsvd74[18]; + uint32_t anagrpid; + uint8_t rsvd96[3]; + uint8_t nsattr; + uint16_t nvmsetid; + uint16_t endgid; uint8_t nguid[16]; uint64_t eui64; NvmeLBAF lbaf[16]; @@ -1048,7 +1189,11 @@ static inline void _nvme_check_size(void) QEMU_BUILD_BUG_ON(sizeof(NvmeErrorLog) != 64); QEMU_BUILD_BUG_ON(sizeof(NvmeFwSlotInfoLog) != 512); QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLog) != 512); + QEMU_BUILD_BUG_ON(sizeof(NvmeEnduranceGroupLog) != 512); QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrl) != 4096); QEMU_BUILD_BUG_ON(sizeof(NvmeIdNs) != 4096); + QEMU_BUILD_BUG_ON(sizeof(NvmeNvmSetAttributes) != 128); + QEMU_BUILD_BUG_ON(sizeof(NvmeIdNvmSetList) != 4096); + QEMU_BUILD_BUG_ON(sizeof(NvmeBar) != 4096); } #endif