return block;
}
-static void get_registers(struct nvme_bar **bar)
+static void *get_registers(void)
{
int pci_fd;
char *base, path[512];
fprintf(stderr, "%s failed to map\n", base);
exit(ENODEV);
}
- *bar = membase;
+ return membase;
}
static void print_list_item(struct list_item list_item)
return err;
}
-static void print_lo_hi_64(uint32_t *val)
+static inline uint32_t mmio_read32(void *addr)
{
- printf("%x%08x\n", val[1], val[0]);
+ __le32 *p = addr;
+
+ return le32_to_cpu(*p);
+}
+
+/* Access 64-bit registers as 2 32-bit; Some devices fail 64-bit MMIO. */
+static inline __u64 mmio_read64(void *addr)
+{
+ __le32 *p = addr;
+
+ return le32_to_cpu(*p) | ((uint64_t)le32_to_cpu(*(p + 1)) << 32);
}
static int show_registers(int argc, char **argv, struct command *cmd, struct plugin *plugin)
const char *desc = "Reads and shows the defined NVMe controller registers "\
"in binary or human-readable format";
const char *human_readable = "show info in readable format";
- struct nvme_bar *bar;
+ uint64_t cap, asq, acq;
+ uint32_t vs, intms, intmc, cc, csts, nssr, aqa, cmbsz, cmbloc;
+ void *bar;
struct config {
int human_readable;
parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
- get_registers(&bar);
+ bar = get_registers();
+ cap = mmio_read64(bar + NVME_REG_CAP);
+ vs = mmio_read32(bar + NVME_REG_VS);
+ intms = mmio_read32(bar + NVME_REG_INTMS);
+ intmc = mmio_read32(bar + NVME_REG_INTMC);
+ cc = mmio_read32(bar + NVME_REG_CC);
+ csts = mmio_read32(bar + NVME_REG_CSTS);
+ nssr = mmio_read32(bar + NVME_REG_NSSR);
+ aqa = mmio_read32(bar + NVME_REG_AQA);
+ asq = mmio_read64(bar + NVME_REG_ASQ);
+ acq = mmio_read64(bar + NVME_REG_ACQ);
+ cmbloc = mmio_read32(bar + NVME_REG_CMBLOC);
+ cmbsz = mmio_read32(bar + NVME_REG_CMBSZ);
if (cfg.human_readable) {
- printf("cap : ");
- print_lo_hi_64((uint32_t *)&bar->cap);
- show_registers_cap((struct nvme_bar_cap *)&bar->cap);
+ printf("cap : %"PRIx64"\n", cap);
+ show_registers_cap((struct nvme_bar_cap *)&cap);
- printf("version : %x\n", bar->vs);
- show_registers_version(bar->vs);
-
- printf("intms : %x\n", bar->intms);
- printf("\tInterrupt Vector Mask Set (IVMS): %x\n\n", bar->intms);
+ printf("version : %x\n", vs);
+ show_registers_version(vs);
+
+ printf("intms : %x\n", intms);
+ printf("\tInterrupt Vector Mask Set (IVMS): %x\n\n", intms);
- printf("intmc : %x\n", bar->intmc);
- printf("\tInterrupt Vector Mask Clear (IVMC): %x\n\n", bar->intmc);
+ printf("intmc : %x\n", intmc);
+ printf("\tInterrupt Vector Mask Clear (IVMC): %x\n\n", intmc);
- printf("cc : %x\n", bar->cc);
- show_registers_cc(bar->cc);
+ printf("cc : %x\n", cc);
+ show_registers_cc(cc);
- printf("csts : %x\n", bar->csts);
- show_registers_csts(bar->csts);
+ printf("csts : %x\n", csts);
+ show_registers_csts(csts);
- printf("nssr : %x\n", bar->nssr);
- printf("\tNVM Subsystem Reset Control (NSSRC): %u\n\n", bar->nssr);
+ printf("nssr : %x\n", nssr);
+ printf("\tNVM Subsystem Reset Control (NSSRC): %u\n\n", nssr);
- printf("aqa : %x\n", bar->aqa);
- show_registers_aqa(bar->aqa);
+ printf("aqa : %x\n", aqa);
+ show_registers_aqa(aqa);
- printf("asq : ");
- print_lo_hi_64((uint32_t *)&bar->asq);
- printf("\tAdmin Submission Queue Base (ASQB): ");
- print_lo_hi_64((uint32_t *)&bar->asq);
- printf("\n");
+ printf("asq : %"PRIx64"\n", asq);
+ printf("\tAdmin Submission Queue Base (ASQB): %"PRIx64"\n",
+ asq);
- printf("acq : ");
- print_lo_hi_64((uint32_t *)&bar->acq);
- printf("\tAdmin Completion Queue Base (ACQB): ");
- print_lo_hi_64((uint32_t *)&bar->acq);
- printf("\n");
+ printf("acq : %"PRIx64"\n", acq);
+ printf("\tAdmin Completion Queue Base (ACQB): %"PRIx64"\n",
+ acq);
- printf("cmbloc : %x\n", bar->cmbloc);
- show_registers_cmbloc(bar->cmbloc, bar->cmbsz);
+ printf("cmbloc : %x\n", cmbloc);
+ show_registers_cmbloc(cmbloc, cmbsz);
- printf("cmbsz : %x\n", bar->cmbsz);
- show_registers_cmbsz(bar->cmbsz);
- }
- else {
- printf("cap : ");
- print_lo_hi_64((uint32_t *)&bar->cap);
-
- printf("version : %x\n", bar->vs);
- printf("intms : %x\n", bar->intms);
- printf("intmc : %x\n", bar->intmc);
- printf("cc : %x\n", bar->cc);
- printf("csts : %x\n", bar->csts);
- printf("nssr : %x\n", bar->nssr);
- printf("aqa : %x\n", bar->aqa);
- printf("asq : ");
- print_lo_hi_64((uint32_t *)&bar->asq);
-
- printf("acq : ");
- print_lo_hi_64((uint32_t *)&bar->acq);
-
- printf("cmbloc : %x\n", bar->cmbloc);
- printf("cmbsz : %x\n", bar->cmbsz);
+ printf("cmbsz : %x\n", cmbsz);
+ show_registers_cmbsz(cmbsz);
+ } else {
+ printf("cap : %"PRIx64"\n", cap);
+ printf("version : %x\n", vs);
+ printf("intms : %x\n", intms);
+ printf("intmc : %x\n", intmc);
+ printf("cc : %x\n", cc);
+ printf("csts : %x\n", csts);
+ printf("nssr : %x\n", nssr);
+ printf("aqa : %x\n", aqa);
+ printf("asq : %"PRIx64"\n", asq);
+ printf("acq : %"PRIx64"\n", acq);
+ printf("cmbloc : %x\n", cmbloc);
+ printf("cmbsz : %x\n", cmbsz);
}
return 0;