summaryrefslogtreecommitdiffstats
path: root/test/register.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/register.c')
-rw-r--r--test/register.c233
1 files changed, 233 insertions, 0 deletions
diff --git a/test/register.c b/test/register.c
new file mode 100644
index 0000000..8a41628
--- /dev/null
+++ b/test/register.c
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/**
+ * This file is part of libnvme.
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors: Keith Busch <keith.busch@wdc.com>
+ */
+
+/**
+ * Prints the values of the nvme register map. Use the nvme controller resource
+ * for your pci device found in /sys/class/nvme/nvmeX/device/resource0
+ */
+
+#define __SANE_USERSPACE_TYPES__
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <libnvme.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+
+#include <ccan/endian/endian.h>
+
+static inline uint32_t nvme_mmio_read32(volatile void *addr)
+{
+ uint32_t *p = (__le32 *)addr;
+
+ return le32_to_cpu(*p);
+}
+
+static inline uint64_t nvme_mmio_read64(volatile void *addr)
+{
+ volatile __u32 *p = (__u32 *)addr;
+ uint32_t low, high;
+
+ low = nvme_mmio_read32(p);
+ high = nvme_mmio_read32(p + 1);
+
+ return low + ((uint64_t)high << 32);
+}
+
+void nvme_print_registers(void *regs)
+{
+ __u64 cap = nvme_mmio_read64(regs + NVME_REG_CAP);
+ __u32 vs = nvme_mmio_read32(regs + NVME_REG_VS);
+ __u32 intms = nvme_mmio_read32(regs + NVME_REG_INTMS);
+ __u32 intmc = nvme_mmio_read32(regs + NVME_REG_INTMC);
+ __u32 cc = nvme_mmio_read32(regs + NVME_REG_CC);
+ __u32 csts = nvme_mmio_read32(regs + NVME_REG_CSTS);
+ __u32 nssr = nvme_mmio_read32(regs + NVME_REG_NSSR);
+ __u32 aqa = nvme_mmio_read32(regs + NVME_REG_AQA);
+ __u64 asq = nvme_mmio_read64(regs + NVME_REG_ASQ);
+ __u64 acq = nvme_mmio_read64(regs + NVME_REG_ACQ);
+ __u32 cmbloc = nvme_mmio_read32(regs + NVME_REG_CMBLOC);
+ __u32 cmbsz = nvme_mmio_read32(regs + NVME_REG_CMBSZ);
+ __u32 bpinfo = nvme_mmio_read32(regs + NVME_REG_BPINFO);
+ __u32 bprsel = nvme_mmio_read32(regs + NVME_REG_BPRSEL);
+ __u64 bpmbl = nvme_mmio_read64(regs + NVME_REG_BPMBL);
+ __u64 cmbmsc = nvme_mmio_read64(regs + NVME_REG_CMBMSC);
+ __u32 cmbsts = nvme_mmio_read32(regs + NVME_REG_CMBSTS);
+ __u32 pmrcap = nvme_mmio_read32(regs + NVME_REG_PMRCAP);
+ __u32 pmrctl = nvme_mmio_read32(regs + NVME_REG_PMRCTL);
+ __u32 pmrsts = nvme_mmio_read32(regs + NVME_REG_PMRSTS);
+ __u32 pmrebs = nvme_mmio_read32(regs + NVME_REG_PMREBS);
+ __u32 pmrswtp = nvme_mmio_read32(regs + NVME_REG_PMRSWTP);
+ __u64 pmrmsc = nvme_mmio_read32(regs + NVME_REG_PMRMSCL) |
+ (__u64)nvme_mmio_read64(regs + NVME_REG_PMRMSCU) << 32;
+
+ printf("%-10s : %llx\n", "CAP", cap);
+ printf(" %-8s : %llx\n", "MQES", NVME_CAP_MQES(cap));
+ printf(" %-8s : %llx\n", "CQRS", NVME_CAP_CQR(cap));
+ printf(" %-8s : %llx\n", "AMS", NVME_CAP_AMS(cap));
+ printf(" %-8s : %llx\n", "TO", NVME_CAP_TO(cap));
+ printf(" %-8s : %llx\n", "DSTRD", NVME_CAP_DSTRD(cap));
+ printf(" %-8s : %llx\n", "NSSRC", NVME_CAP_NSSRC(cap));
+ printf(" %-8s : %llx\n", "CSS", NVME_CAP_CSS(cap));
+ printf(" %-8s : %llx\n", "BPS", NVME_CAP_BPS(cap));
+ printf(" %-8s : %llx\n", "MPSMIN", NVME_CAP_MPSMIN(cap));
+ printf(" %-8s : %llx\n", "MPSMAX", NVME_CAP_MPSMAX(cap));
+ printf(" %-8s : %llx\n", "CMBS", NVME_CAP_CMBS(cap));
+ printf(" %-8s : %llx\n", "PMRS", NVME_CAP_PMRS(cap));
+
+ printf("%-10s : %x\n", "VS", vs);
+ printf(" %-8s : %x\n", "MJR", NVME_VS_TER(vs));
+ printf(" %-8s : %x\n", "MNR", NVME_VS_MNR(vs));
+ printf(" %-8s : %x\n", "TER", NVME_VS_MJR(vs));
+
+ printf("%-10s : %x\n", "INTMS", intms);
+ printf("%-10s : %x\n", "INTMC", intmc);
+
+ printf("%-10s : %x\n", "CC", cc);
+ printf(" %-8s : %x\n", "EN", NVME_CC_EN(cc));
+ printf(" %-8s : %x\n", "CSS", NVME_CC_CSS(cc));
+ printf(" %-8s : %x\n", "MPS", NVME_CC_MPS(cc));
+ printf(" %-8s : %x\n", "AMS", NVME_CC_AMS(cc));
+ printf(" %-8s : %x\n", "SHN", NVME_CC_SHN(cc));
+ printf(" %-8s : %x\n", "IOSQES", NVME_CC_IOSQES(cc));
+ printf(" %-8s : %x\n", "IOCQES", NVME_CC_IOCQES(cc));
+
+ printf("%-10s : %x\n", "CSTS", csts);
+ printf(" %-8s : %x\n", "RDY", NVME_CSTS_RDY(csts));
+ printf(" %-8s : %x\n", "CFS", NVME_CSTS_CFS(csts));
+ printf(" %-8s : %x\n", "SHST", NVME_CSTS_SHST(csts));
+ printf(" %-8s : %x\n", "NSSRO", NVME_CSTS_NSSRO(csts));
+ printf(" %-8s : %x\n", "PP", NVME_CSTS_PP(csts));
+
+ printf("%-10s : %x\n", "NSSR", nssr);
+
+ printf("%-10s : %x\n", "AQA", aqa);
+ printf(" %-8s : %x\n", "ASQS", NVME_AQA_ASQS(aqa));
+ printf(" %-8s : %x\n", "ACQS", NVME_AQA_ACQS(aqa));
+
+ printf("%-10s : %llx\n", "ASQ", asq);
+ printf("%-10s : %llx\n", "ACQ", acq);
+
+ printf("%-10s : %x\n", "CMBLOC", cmbloc);
+ printf(" %-8s : %x\n", "BIR", NVME_CMBLOC_BIR(cmbloc));
+ printf(" %-8s : %x\n", "CQMMS", NVME_CMBLOC_CQMMS(cmbloc));
+ printf(" %-8s : %x\n", "CQPDS", NVME_CMBLOC_CQPDS(cmbloc));
+ printf(" %-8s : %x\n", "CDPLMS", NVME_CMBLOC_CDPLMS(cmbloc));
+ printf(" %-8s : %x\n", "CDPCILS", NVME_CMBLOC_CDPCILS(cmbloc));
+ printf(" %-8s : %x\n", "CDMMMS", NVME_CMBLOC_CDMMMS(cmbloc));
+ printf(" %-8s : %x\n", "CQDA", NVME_CMBLOC_CQDA(cmbloc));
+ printf(" %-8s : %x\n", "OFST", NVME_CMBLOC_OFST(cmbloc));
+
+ printf("%-10s : %x\n", "CMBSZ", cmbsz);
+ printf(" %-8s : %x\n", "SQS", NVME_CMBSZ_SQS(cmbsz));
+ printf(" %-8s : %x\n", "CQS", NVME_CMBSZ_CQS(cmbsz));
+ printf(" %-8s : %x\n", "LISTS", NVME_CMBSZ_LISTS(cmbsz));
+ printf(" %-8s : %x\n", "RDS", NVME_CMBSZ_RDS(cmbsz));
+ printf(" %-8s : %x\n", "WDS", NVME_CMBSZ_WDS(cmbsz));
+ printf(" %-8s : %x\n", "SZU", NVME_CMBSZ_SZU(cmbsz));
+ printf(" %-8s : %x\n", "SZ", NVME_CMBSZ_SZ(cmbsz));
+ printf(" %-8s : %llx\n", "bytes", nvme_cmb_size(cmbsz));
+
+ printf("%-10s : %x\n", "BPINFO", bpinfo);
+ printf(" %-8s : %x\n", "BPSZ", NVME_BPINFO_BPSZ(bpinfo));
+ printf(" %-8s : %x\n", "BRS", NVME_BPINFO_BRS(bpinfo));
+ printf(" %-8s : %x\n", "ABPID", NVME_BPINFO_ABPID(bpinfo));
+
+ printf("%-10s : %x\n", "BPRSEL", bprsel);
+ printf(" %-8s : %x\n", "BPRSZ", NVME_BPRSEL_BPRSZ(bprsel));
+ printf(" %-8s : %x\n", "BPROF", NVME_BPRSEL_BPROF(bprsel));
+ printf(" %-8s : %x\n", "BPID", NVME_BPRSEL_BPID(bprsel));
+
+ printf("%-10s : %llx\n", "BPMBL", bpmbl);
+
+ printf("%-10s : %llx\n", "CMBMSC", cmbmsc);
+ printf(" %-8s : %llx\n", "CRE", NVME_CMBMSC_CRE(cmbmsc));
+ printf(" %-8s : %llx\n", "CMSE", NVME_CMBMSC_CMSE(cmbmsc));
+ printf(" %-8s : %llx\n", "CBA", NVME_CMBMSC_CBA(cmbmsc));
+
+ printf("%-10s : %x\n", "CMBSTS", cmbsts);
+ printf(" %-8s : %x\n", "CBAI", NVME_CMBSTS_CBAI(cmbsts));
+
+ printf("%-10s : %x\n", "PMRCAP", pmrcap);
+ printf(" %-8s : %x\n", "RDS", NVME_PMRCAP_RDS(pmrcap));
+ printf(" %-8s : %x\n", "WDS", NVME_PMRCAP_WDS(pmrcap));
+ printf(" %-8s : %x\n", "BIR", NVME_PMRCAP_BIR(pmrcap));
+ printf(" %-8s : %x\n", "PMRTU", NVME_PMRCAP_PMRTU(pmrcap));
+ printf(" %-8s : %x\n", "PMRWMB", NVME_PMRCAP_PMRWMB(pmrcap));
+ printf(" %-8s : %x\n", "PMRTO", NVME_PMRCAP_PMRTO(pmrcap));
+ printf(" %-8s : %x\n", "CMSS", NVME_PMRCAP_CMSS(pmrcap));
+
+ printf("%-10s : %x\n", "PMRCTL", pmrctl);
+ printf(" %-8s : %x\n", "EN", NVME_PMRCTL_EN(pmrctl));
+
+ printf("%-10s : %x\n", "PMRSTS", pmrsts);
+ printf(" %-8s : %x\n", "ERR", NVME_PMRSTS_ERR(pmrsts));
+ printf(" %-8s : %x\n", "NRDY", NVME_PMRSTS_NRDY(pmrsts));
+ printf(" %-8s : %x\n", "HSTS", NVME_PMRSTS_HSTS(pmrsts));
+ printf(" %-8s : %x\n", "CBAI", NVME_PMRSTS_CBAI(pmrsts));
+
+ printf("%-10s : %x\n", "PMREBS", pmrebs);
+ printf(" %-8s : %x\n", "PMRSZU", NVME_PMREBS_PMRSZU(pmrebs));
+ printf(" %-8s : %x\n", "RBB", NVME_PMREBS_RBB(pmrebs));
+ printf(" %-8s : %x\n", "PMRWBZ", NVME_PMREBS_PMRWBZ(pmrebs));
+ printf(" %-8s : %llx\n", "bytes", nvme_pmr_size(pmrebs));
+
+ printf("%-10s : %x\n", "PMRSWTP", pmrswtp);
+ printf(" %-8s : %x\n", "PMRSWTU", NVME_PMRSWTP_PMRSWTU(pmrswtp));
+ printf(" %-8s : %x\n", "PMRSWTV", NVME_PMRSWTP_PMRSWTV(pmrswtp));
+ printf(" %-8s : %llx\n", "tput", nvme_pmr_throughput(pmrswtp));
+
+ printf("%-10s : %llx\n", "PMRMSC", pmrmsc);
+ printf(" %-8s : %llx\n", "CMSE", NVME_PMRMSC_CMSE(pmrmsc));
+ printf(" %-8s : %llx\n", "CBA", NVME_PMRMSC_CBA(pmrmsc));
+}
+
+int main(int argc, char **argv)
+{
+ int ret, fd;
+ char *path;
+ void *regs;
+
+ if (argc != 2) {
+ fprintf(stderr, "%s nvme<X>\n", argv[0]);
+ return 1;
+ }
+
+ ret = asprintf(&path, "/sys/class/nvme/%s/device/resource0", argv[1]);
+ if (ret < 0)
+ return 0;
+
+ printf("open %s\n", path);
+ fd = open(path, O_RDONLY | O_SYNC);
+ if (fd < 0) {
+ fprintf(stderr, "failed to open %s\n", path);
+ free(path);
+ return 1;
+ }
+
+ regs = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED, fd, 0);
+ if (regs == MAP_FAILED) {
+ fprintf(stderr, "failed to map device BAR\n");
+ fprintf(stderr, "did your kernel enable CONFIG_IO_STRICT_DEVMEM?\n");
+ free(path);
+ close(fd);
+ return 1;
+ }
+
+ nvme_print_registers(regs);
+ munmap(regs, getpagesize());
+ free(path);
+ close(fd);
+
+ return 0;
+}
+