nvme/pcie: register CMB with spdk_mem_register()

Enable address translation for I/O buffers within the controller memory
buffer region by registering the CMB using spdk_mem_register().

Change-Id: I44829757ad15fbc3ea96fa494b9fb32dd67a7138
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
Signed-off-by: Stephen Bates <sbates@raithlin.com>
Reviewed-on: https://review.gerrithub.io/397035
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Daniel Verkamp 2017-04-21 16:23:05 -07:00 committed by Jim Harris
parent 35a331a949
commit f185e4ecf8
2 changed files with 35 additions and 0 deletions

View File

@ -88,6 +88,9 @@ struct nvme_pcie_ctrlr {
/* Current offset of controller memory buffer */
uint64_t cmb_current_offset;
void *cmb_mem_register_addr;
size_t cmb_mem_register_size;
/** stride in uint32_t units between doorbell registers (1 = 4 bytes, 2 = 8 bytes, ...) */
uint32_t doorbell_stride_u32;
@ -442,6 +445,7 @@ nvme_pcie_ctrlr_map_cmb(struct nvme_pcie_ctrlr *pctrlr)
union spdk_nvme_cmbsz_register cmbsz;
union spdk_nvme_cmbloc_register cmbloc;
uint64_t size, unit_size, offset, bar_size, bar_phys_addr;
uint64_t mem_register_start, mem_register_end;
if (nvme_pcie_ctrlr_get_cmbsz(pctrlr, &cmbsz) ||
nvme_pcie_ctrlr_get_cmbloc(pctrlr, &cmbloc)) {
@ -489,6 +493,30 @@ nvme_pcie_ctrlr_map_cmb(struct nvme_pcie_ctrlr *pctrlr)
pctrlr->ctrlr.opts.use_cmb_sqs = false;
}
/* If only SQS is supported use legacy mapping */
if (cmbsz.bits.sqs && !(cmbsz.bits.wds || cmbsz.bits.rds)) {
return;
}
/* If CMB is less than 4MiB in size then abort CMB mapping */
if (pctrlr->cmb_size < (1ULL << 22)) {
goto exit;
}
mem_register_start = (((uintptr_t)pctrlr->cmb_bar_virt_addr + offset + 0x1fffff) & ~(0x200000 - 1));
mem_register_end = ((uintptr_t)pctrlr->cmb_bar_virt_addr + offset + pctrlr->cmb_size);
mem_register_end &= ~(uint64_t)(0x200000 - 1);
pctrlr->cmb_mem_register_addr = (void *)mem_register_start;
pctrlr->cmb_mem_register_size = mem_register_end - mem_register_start;
rc = spdk_mem_register(pctrlr->cmb_mem_register_addr, pctrlr->cmb_mem_register_size);
if (rc) {
SPDK_ERRLOG("spdk_mem_register() failed\n");
goto exit;
}
pctrlr->cmb_current_offset = mem_register_start - ((uint64_t)pctrlr->cmb_bar_virt_addr + offset);
return;
exit:
pctrlr->cmb_bar_virt_addr = NULL;
@ -504,6 +532,10 @@ nvme_pcie_ctrlr_unmap_cmb(struct nvme_pcie_ctrlr *pctrlr)
void *addr = pctrlr->cmb_bar_virt_addr;
if (addr) {
if (pctrlr->cmb_mem_register_addr) {
spdk_mem_unregister(pctrlr->cmb_mem_register_addr, pctrlr->cmb_mem_register_size);
}
if (nvme_pcie_ctrlr_get_cmbloc(pctrlr, &cmbloc)) {
SPDK_ERRLOG("get_cmbloc() failed\n");
return -EIO;

View File

@ -39,6 +39,9 @@
#include "nvme/nvme_pcie.c"
DEFINE_STUB(spdk_mem_register, int, (void *vaddr, size_t len), 0);
DEFINE_STUB(spdk_mem_unregister, int, (void *vaddr, size_t len), 0);
struct spdk_trace_flag SPDK_LOG_NVME = {
.name = "nvme",
.enabled = false,