Patchwork Fwd: inteltool: first preview for machine-readable output

login
register
about
Submitter Антон Кочков
Date 2011-02-11 01:32:55
Message ID <AANLkTin=3aK7aPVq4cAJJBj7rOEe_eFT1LEMxhCuBQC4@mail.gmail.com>
Download mbox | patch
Permalink /patch/2621/
State Superseded
Headers show

Comments

Антон Кочков - 2011-02-11 01:32:55
inteltool: first preview for machine-readable output
Signed-off-by: Anton Kochkov <anton.kochkov@gmail.com>
---

This is only for preview and discussion, it's still ugly and dont safe/clear.
Sven Schnelle - 2011-02-11 14:38:26
Hi,

Антон Кочков <anton.kochkov@gmail.com> writes:

At first, can you please give us a few use cases for this patch?

> inteltool: first preview for machine-readable output
> Signed-off-by: Anton Kochkov <anton.kochkov@gmail.com>
> ---
>
> This is only for preview and discussion, it's still ugly and dont safe/clear.

> void machine_readable_printf(reg_t *reg) {
>
> #ifdef XML
> 	printf("<register domain='%s' base='0x%x' offset='0x%x' size='%d' value='0x%x' name='%s' description='%s' />\n",
> 		reg->domain, reg->base_addr, reg->offset, reg->size, reg->value, reg->name, reg->desc);
> #endif

That should probably be an #else, and it should be switchable during
runtime instead of compile time.

> #ifndef XML
> 	printf("domain: %s\n", reg->domain);
> 	printf("base addr: 0x%x\n", reg->base_addr);
> 	printf("offset: 0x%x\n", reg->offset);
> 	printf("size: %d\n", reg->size);
> 	printf("value: 0x%x\n", reg->value);
> 	printf("name: %s\n", reg->name);
> 	printf("description: %s\n", reg->desc);
> #endif
> }

Patch

Index: gpio.c
===================================================================
--- gpio.c	(revision 6320)
+++ gpio.c	(working copy)
@@ -203,14 +203,17 @@ 
 	{ 0x7c, 4, "RESERVED" },
 };
 
-int print_gpios(struct pci_dev *sb)
+int print_gpios(struct pci_dev *sb, int machine_readable)
 {
 	int i, size;
 	uint16_t gpiobase;
 	const io_register_t *gpio_registers;
+	reg_t tmp;
+	
+	if (machine_readable == 0) {
+		printf("\n============= GPIOS =============\n\n");
+	}
 
-	printf("\n============= GPIOS =============\n\n");
-
 	switch (sb->device_id) {
 	case PCI_DEVICE_ID_INTEL_ICH10R:
 		gpiobase = pci_read_word(sb, 0x48) & 0xfffc;
@@ -279,30 +282,54 @@ 
 		printf("Error: Dumping GPIOs on this southbridge is not (yet) supported.\n");
 		return 1;
 	}
+	
+	/* Printing GPIOBASE */
 
-	printf("GPIOBASE = 0x%04x (IO)\n\n", gpiobase);
+	if (machine_readable == 0) {
+		printf("GPIOBASE = 0x%04x (IO)\n\n", gpiobase);
+	}
 
+	/* Printing registers */
+
 	for (i = 0; i < size; i++) {
-		switch (gpio_registers[i].size) {
-		case 4:
-			printf("gpiobase+0x%04x: 0x%08x (%s)\n",
-				gpio_registers[i].addr,
-				inl(gpiobase+gpio_registers[i].addr),
-				gpio_registers[i].name);
-			break;
-		case 2:
-			printf("gpiobase+0x%04x: 0x%04x     (%s)\n",
-				gpio_registers[i].addr,
-				inw(gpiobase+gpio_registers[i].addr),
-				gpio_registers[i].name);
-			break;
-		case 1:
-			printf("gpiobase+0x%04x: 0x%02x       (%s)\n",
-				gpio_registers[i].addr,
-				inb(gpiobase+gpio_registers[i].addr),
-				gpio_registers[i].name);
-			break;
+		
+		/* Human-readable format */
+
+		if (machine_readable == 0 ) {
+			switch (gpio_registers[i].size) {
+				case 4:
+					printf("gpiobase+0x%04x: 0x%08x (%s)\n",
+						gpio_registers[i].addr,
+						inl(gpiobase + gpio_registers[i].addr),
+						gpio_registers[i].name);
+					break;
+				case 2:
+					printf("gpiobase+0x%04x: 0x%04x     (%s)\n",
+						gpio_registers[i].addr,
+						inw(gpiobase + gpio_registers[i].addr),
+						gpio_registers[i].name);
+					break;
+				case 1:
+					printf("gpiobase+0x%04x: 0x%02x       (%s)\n",
+						gpio_registers[i].addr,
+						inb(gpiobase + gpio_registers[i].addr),
+						gpio_registers[i].name);
+					break;
+			}
 		}
+
+		/* Machine-readable format */
+
+		if (machine_readable == 1) {
+			tmp.domain = "GPIO";
+			tmp.base_addr = gpiobase;
+			tmp.offset = gpio_registers[i].addr;
+			tmp.size = gpio_registers[i].size;
+			tmp.name = gpio_registers[i].name;
+			tmp.desc = "";
+			read_reg(&tmp, 0);
+			machine_readable_printf(&tmp);
+		}
 	}
 
 	return 0;
Index: inteltool.h
===================================================================
--- inteltool.h	(revision 6320)
+++ inteltool.h	(working copy)
@@ -109,17 +109,51 @@ 
 msr_t freebsd_rdmsr(int addr);
 int freebsd_wrmsr(int addr, msr_t msr);
 #endif
+
 typedef struct { uint16_t addr; int size; char *name; } io_register_t;
 
+/* Register format definitions */
+
+struct regbitvalues {
+	uint32_t value;
+	char *text;
+};  
+
+struct regbits {
+	uint8_t start;
+	uint8_t size;
+	char *name;
+	char *desc;
+	uint8_t present;
+	struct regbitvalues bitval[32];
+};
+
+typedef struct {
+	char* domain;
+	uint32_t base_addr;
+	uint16_t offset;
+	int size;
+	uint32_t value;
+	char *name;
+	char *desc;
+	struct regbits bits[65];
+} reg_t;
+
+int read_reg(reg_t *reg, int is_mmap);
+
+/* End of register format definitions */
+
+void machine_readable_printf(reg_t *reg);
+
 void *map_physical(unsigned long phys_addr, size_t len);
 void unmap_physical(void *virt_addr, size_t len);
 
 unsigned int cpuid(unsigned int op);
-int print_intel_core_msrs(void);
-int print_mchbar(struct pci_dev *nb, struct pci_access *pacc);
-int print_pmbase(struct pci_dev *sb, struct pci_access *pacc);
-int print_rcba(struct pci_dev *sb);
-int print_gpios(struct pci_dev *sb);
-int print_epbar(struct pci_dev *nb);
-int print_dmibar(struct pci_dev *nb);
-int print_pciexbar(struct pci_dev *nb);
+int print_intel_core_msrs(int machine_readable);
+int print_mchbar(struct pci_dev *nb, struct pci_access *pacc, int machine_readable);
+int print_pmbase(struct pci_dev *sb, struct pci_access *pacc, int machine_readable);
+int print_rcba(struct pci_dev *sb, int machine_readable);
+int print_gpios(struct pci_dev *sb, int machine_readable);
+int print_epbar(struct pci_dev *nb, int machine_readable);
+int print_dmibar(struct pci_dev *nb, int machine_readable);
+int print_pciexbar(struct pci_dev *nb, int machine_readable);
Index: pcie.c
===================================================================
--- pcie.c	(revision 6320)
+++ pcie.c	(working copy)
@@ -24,13 +24,16 @@ 
 /*
  * Egress Port Root Complex MMIO configuration space
  */
-int print_epbar(struct pci_dev *nb)
+int print_epbar(struct pci_dev *nb, int machine_readable)
 {
 	int i, size = (4 * 1024);
 	volatile uint8_t *epbar;
 	uint64_t epbar_phys;
+	reg_t tmp;
 
-	printf("\n============= EPBAR =============\n\n");
+	if (machine_readable == 0) {
+		printf("\n============= EPBAR =============\n\n");
+	}
 
 	switch (nb->device_id) {
 	case PCI_DEVICE_ID_INTEL_82915:
@@ -69,11 +72,34 @@ 
 		perror("Error mapping EPBAR");
 		exit(1);
 	}
+	
+	if (machine_readable == 0) {
+		printf("EPBAR = 0x%08llx (MEM)\n\n", epbar_phys);
+	}
+	else {
+	}
 
-	printf("EPBAR = 0x%08llx (MEM)\n\n", epbar_phys);
 	for (i = 0; i < size; i += 4) {
 		if (*(uint32_t *)(epbar + i))
-			printf("0x%04x: 0x%08x\n", i, *(uint32_t *)(epbar+i));
+			
+			/* Human-readable output */
+
+			if (machine_readable == 0) {
+				printf("0x%04x: 0x%08x\n", i, *(uint32_t *)(epbar+i));
+			}
+
+			/* Machine-readable output */
+
+			else {
+				tmp.domain = "EP";
+				tmp.base_addr = epbar;
+				tmp.offset = i;
+				tmp.size = 4;
+				tmp.name = "unresolved";
+				tmp.desc = "";
+				if (!read_reg(&tmp, 1)) tmp.value = 0;
+				machine_readable_printf(&tmp);
+			}
 	}
 
 	unmap_physical((void *)epbar, size);
@@ -83,13 +109,16 @@ 
 /*
  * MCH-ICH Serial Interconnect Ingress Root Complex MMIO configuration space
  */
-int print_dmibar(struct pci_dev *nb)
+int print_dmibar(struct pci_dev *nb, int machine_readable)
 {
 	int i, size = (4 * 1024);
 	volatile uint8_t *dmibar;
 	uint64_t dmibar_phys;
+	reg_t tmp;
 
-	printf("\n============= DMIBAR ============\n\n");
+	if (machine_readable == 0) {
+		printf("\n============= DMIBAR ============\n\n");
+	}
 
 	switch (nb->device_id) {
 	case PCI_DEVICE_ID_INTEL_82915:
@@ -130,11 +159,32 @@ 
 		perror("Error mapping DMIBAR");
 		exit(1);
 	}
+	
+	if (machine_readable == 0) {
+		printf("DMIBAR = 0x%08llx (MEM)\n\n", dmibar_phys);
+	}
 
-	printf("DMIBAR = 0x%08llx (MEM)\n\n", dmibar_phys);
 	for (i = 0; i < size; i += 4) {
 		if (*(uint32_t *)(dmibar + i))
-			printf("0x%04x: 0x%08x\n", i, *(uint32_t *)(dmibar+i));
+			
+			/* Human-readable output */
+
+			if (machine_readable == 0) {
+				printf("0x%04x: 0x%08x\n", i, *(uint32_t *)(dmibar+i));
+			}
+
+			/* Machine-readable output */
+
+			else {
+				tmp.domain = "DMI";
+				tmp.base_addr = dmibar;
+				tmp.offset = i;
+				tmp.size = 4;
+				tmp.name = "unresolved";
+				tmp.desc = "";
+				if (!read_reg(&tmp, 1)) tmp.value = 0;
+				machine_readable_printf(&tmp);
+			}
 	}
 
 	unmap_physical((void *)dmibar, size);
@@ -144,15 +194,18 @@ 
 /*
  * PCIe MMIO configuration space
  */
-int print_pciexbar(struct pci_dev *nb)
+int print_pciexbar(struct pci_dev *nb, int machine_readable)
 {
 	uint64_t pciexbar_reg;
 	uint64_t pciexbar_phys;
 	volatile uint8_t *pciexbar;
 	int max_busses, devbase, i;
 	int bus, dev, fn;
+	reg_t tmp;
 
-	printf("========= PCIEXBAR ========\n\n");
+	if (machine_readable == 0) {
+		printf("========= PCIEXBAR ========\n\n");
+	}
 
 	switch (nb->device_id) {
 	case PCI_DEVICE_ID_INTEL_82915:
@@ -207,7 +260,9 @@ 
 		return 1;
 	}
 
-	printf("PCIEXBAR: 0x%08llx\n", pciexbar_phys);
+	if (machine_readable == 0) {
+		printf("PCIEXBAR: 0x%08llx\n", pciexbar_phys);
+	}
 
 	pciexbar = map_physical(pciexbar_phys, (max_busses * 1024 * 1024));
 
@@ -228,18 +283,52 @@ 
 				if( (*(uint32_t *)(pciexbar + devbase + 256) == 0xffffffff) &&
 					(*(uint32_t *)(pciexbar + devbase + 512) == 0xffffffff) ) {
 #if DEBUG
-					printf("Skipped non-PCIe device %02x:%02x.%01x\n", bus, dev, fn);
+					if (machine_readable == 0) {
+						printf("Skipped non-PCIe device %02x:%02x.%01x\n", bus, dev, fn);
+					}
 #endif
 					continue;
 				}
 
-				printf("\nPCIe %02x:%02x.%01x extended config space:", bus, dev, fn);
+				/* Human-readable output */
+
+				if (machine_readable == 0) {
+					printf("\nPCIe %02x:%02x.%01x extended config space:", bus, dev, fn);
+				}
+				else {
+					sprintf(tmp.domain, "PCIEX%02x:%02x.%01x", bus, dev, fn);
+				}
 				for (i = 0; i < 4096; i++) {
+					
+					/* Human-readable output */
+
 					if((i % 0x10) == 0)
-						printf("\n%04x:", i);
-					printf(" %02x", *(pciexbar+devbase+i));
+						if (machine_readable == 0) {
+							printf("\n%04x:", i);
+						}
+					if (machine_readable == 0) {
+						printf(" %02x", *(pciexbar+devbase+i));
+					}
+
+					/* Machine-readable output */
+
+					// This is need to be more clear, right now it is very ugly
+
+					else {
+						tmp.base_addr = pciexbar + devbase;
+						tmp.offset = i;
+						tmp.size = 1;
+						tmp.name = "";
+						tmp.desc = "";
+						if (!read_reg(&tmp, 1)) tmp.value = 0;
+						machine_readable_printf(&tmp);
+					}
 				}
-				printf("\n");
+				if (machine_readable == 0) {
+					printf("\n");
+				}
+				else {
+				}
 			}
 		}
 	}
Index: powermgt.c
===================================================================
--- powermgt.c	(revision 6320)
+++ powermgt.c	(working copy)
@@ -550,15 +550,18 @@ 
 	{ 0x37, 1, "GPOREG 3" },
 };
 
-int print_pmbase(struct pci_dev *sb, struct pci_access *pacc)
+int print_pmbase(struct pci_dev *sb, struct pci_access *pacc, int machine_readable)
 {
 	int i, size;
 	uint16_t pmbase;
 	const io_register_t *pm_registers;
 	struct pci_dev *acpi;
+	reg_t tmp;
+	
+	if (machine_readable == 0) {
+		printf("\n============= PMBASE ============\n\n");
+	}
 
-	printf("\n============= PMBASE ============\n\n");
-
 	switch (sb->device_id) {
 	case PCI_DEVICE_ID_INTEL_ICH10R:
 		pmbase = pci_read_word(sb, 0x40) & 0xff80;
@@ -633,29 +636,45 @@ 
 		return 1;
 	}
 
-	printf("PMBASE = 0x%04x (IO)\n\n", pmbase);
+	if (machine_readable == 0) {
+		printf("PMBASE = 0x%04x (IO)\n\n", pmbase);
+	}
+	else {
+	}
 
 	for (i = 0; i < size; i++) {
-		switch (pm_registers[i].size) {
-		case 4:
-			printf("pmbase+0x%04x: 0x%08x (%s)\n",
-				pm_registers[i].addr,
-				inl(pmbase+pm_registers[i].addr),
-				pm_registers[i].name);
-			break;
-		case 2:
-			printf("pmbase+0x%04x: 0x%04x     (%s)\n",
-				pm_registers[i].addr,
-				inw(pmbase+pm_registers[i].addr),
-				pm_registers[i].name);
-			break;
-		case 1:
-			printf("pmbase+0x%04x: 0x%02x       (%s)\n",
-				pm_registers[i].addr,
-				inb(pmbase+pm_registers[i].addr),
-				pm_registers[i].name);
-			break;
+		if (machine_readable == 0) {
+			switch (pm_registers[i].size) {
+				case 4:
+					printf("pmbase+0x%04x: 0x%08x (%s)\n",
+						pm_registers[i].addr,
+						inl(pmbase+pm_registers[i].addr),
+						pm_registers[i].name);
+					break;
+				case 2:
+					printf("pmbase+0x%04x: 0x%04x     (%s)\n",
+						pm_registers[i].addr,
+						inw(pmbase+pm_registers[i].addr),
+						pm_registers[i].name);
+					break;
+				case 1:
+					printf("pmbase+0x%04x: 0x%02x       (%s)\n",
+						pm_registers[i].addr,
+						inb(pmbase+pm_registers[i].addr),
+						pm_registers[i].name);
+					break;
+			}
 		}
+		else {
+			tmp.domain = "PM";
+			tmp.base_addr = pmbase;
+			tmp.offset = pm_registers[i].addr;
+			tmp.size = pm_registers[i].size;
+			tmp.name = pm_registers[i].name;
+			tmp.desc = "";
+			if (!read_reg(&tmp, 0)) tmp.value = 0;
+			machine_readable_printf(&tmp);
+		}
 	}
 
 	return 0;
Index: cpu.c
===================================================================
--- cpu.c	(revision 6320)
+++ cpu.c	(working copy)
@@ -81,7 +81,7 @@ 
 }
 #endif
 
-int print_intel_core_msrs(void)
+int print_intel_core_msrs(int machine_readable)
 {
 	unsigned int i, core, id;
 	msr_t msr;
@@ -774,13 +774,19 @@ 
 	}
 #endif
 
-	printf("\n===================== SHARED MSRs (All Cores) =====================\n");
+	if (machine_readable == 0) {
+		printf("\n===================== SHARED MSRs (All Cores) =====================\n");
+	}
 
 	for (i = 0; i < cpu->num_global_msrs; i++) {
 		msr = rdmsr(cpu->global_msrs[i].number);
-		printf(" MSR 0x%08X = 0x%08X:0x%08X (%s)\n",
-		       cpu->global_msrs[i].number, msr.hi, msr.lo,
-		       cpu->global_msrs[i].name);
+		if (machine_readable == 0) {
+			printf(" MSR 0x%08X = 0x%08X:0x%08X (%s)\n",
+				cpu->global_msrs[i].number, msr.hi, msr.lo,
+				cpu->global_msrs[i].name);
+		}
+		else {
+		}
 	}
 
 	close(fd_msr);
@@ -800,13 +806,19 @@ 
 			break;
 #endif
 		if (cpu->num_per_core_msrs)
-			printf("\n====================== UNIQUE MSRs  (core %d) ======================\n", core);
+			if (machine_readable == 0) {
+				printf("\n====================== UNIQUE MSRs  (core %d) ======================\n", core);
+			}
 
 		for (i = 0; i < cpu->num_per_core_msrs; i++) {
 			msr = rdmsr(cpu->per_core_msrs[i].number);
-			printf(" MSR 0x%08X = 0x%08X:0x%08X (%s)\n",
-			       cpu->per_core_msrs[i].number, msr.hi, msr.lo,
-			       cpu->per_core_msrs[i].name);
+			if (machine_readable == 0) {
+				printf(" MSR 0x%08X = 0x%08X:0x%08X (%s)\n",
+					cpu->per_core_msrs[i].number, msr.hi, msr.lo,
+					cpu->per_core_msrs[i].name);
+			}
+			else {
+			}
 		}
 #ifndef __DARWIN__
 		close(fd_msr);
Index: rootcmplx.c
===================================================================
--- rootcmplx.c	(revision 6320)
+++ rootcmplx.c	(working copy)
@@ -22,13 +22,16 @@ 
 #include <stdlib.h>
 #include "inteltool.h"
 
-int print_rcba(struct pci_dev *sb)
+int print_rcba(struct pci_dev *sb, int machine_readable)
 {
 	int i, size = 0x4000;
 	volatile uint8_t *rcba;
 	uint32_t rcba_phys;
+	reg_t tmp;
 
-	printf("\n============= RCBA ==============\n\n");
+	if (machine_readable == 0) {
+		printf("\n============= RCBA ==============\n\n");
+	}
 
 	switch (sb->device_id) {
 	case PCI_DEVICE_ID_INTEL_ICH6:
@@ -68,11 +71,25 @@ 
 		exit(1);
 	}
 
-	printf("RCBA = 0x%08x (MEM)\n\n", rcba_phys);
+	if (machine_readable == 0) {
+		printf("RCBA = 0x%08x (MEM)\n\n", rcba_phys);
+	}
 
 	for (i = 0; i < size; i += 4) {
 		if (*(uint32_t *)(rcba + i))
-			printf("0x%04x: 0x%08x\n", i, *(uint32_t *)(rcba + i));
+			if (machine_readable == 0) {
+				printf("0x%04x: 0x%08x\n", i, *(uint32_t *)(rcba + i));
+			}
+			else {
+				tmp.domain = "RCBA";
+				tmp.base_addr = rcba;
+				tmp.offset = i;
+				tmp.size = 4;
+				tmp.name = "unresolved";
+				tmp.desc = "";
+				if (!read_reg(&tmp, 1)) tmp.value = 0;
+				machine_readable_printf(&tmp);
+			}
 	}
 
 	unmap_physical((void *)rcba, size);
Index: memory.c
===================================================================
--- memory.c	(revision 6320)
+++ memory.c	(working copy)
@@ -25,16 +25,20 @@ 
 /*
  * (G)MCH MMIO Config Space
  */
-int print_mchbar(struct pci_dev *nb, struct pci_access *pacc)
+int print_mchbar(struct pci_dev *nb, struct pci_access *pacc, int machine_readable)
 {
 	int i, size = (16 * 1024);
 	volatile uint8_t *mchbar;
 	uint64_t mchbar_phys;
 	struct pci_dev *nb_device6; /* "overflow device" on i865 */
 	uint16_t pcicmd6;
+	const io_register_t *mch_registers = NULL;
+	reg_t tmp;
+	
+	if (machine_readable == 0) {
+		printf("\n============= MCHBAR ============\n\n");
+	}
 
-	printf("\n============= MCHBAR ============\n\n");
-
 	switch (nb->device_id) {
 	case PCI_DEVICE_ID_INTEL_82865:
 		/*
@@ -51,13 +55,19 @@ 
 
 		/* Try to enable Memory Access Enable (MAE). */
 		if (!(pcicmd6 & (1 << 1))) {
-			printf("Access to BAR6 is currently disabled, "
+			if (machine_readable == 0) {
+				printf("Access to BAR6 is currently disabled, "
 			       "attempting to enable.\n");
+			}
 			pci_write_long(nb_device6, 0x04, pcicmd6 | (1 << 1));
 			if (pci_read_long(nb_device6, 0x04) & (1 << 1))
-				printf("Enabled successfully.\n");
+				if (machine_readable == 0) {
+					printf("Enabled successfully.\n");
+				}
 			else
-				printf("Enable FAILED!\n");
+				if (machine_readable == 0) {
+					printf("Enable FAILED!\n");
+				}
 		}
 		mchbar_phys &= 0xfffff000; /* Bits 31:12 from BAR6 */
 		break;
@@ -88,18 +98,24 @@ 
 
 		if(!(mchbar_phys & 1))
 		{
-			printf("Access to the MCHBAR is currently disabled, "\
+			if (machine_readable == 0) {
+				printf("Access to the MCHBAR is currently disabled, "\
 						"attempting to enable.\n");
+			}
 			mchbar_phys |= 0x1;
 			pci_write_long(nb, 0x48, mchbar_phys);
 	 		if(pci_read_long(nb, 0x48) & 1)
-				printf("Enabled successfully.\n");
+				if (machine_readable == 0) {
+					printf("Enabled successfully.\n");
+				}
 			else
-				printf("Enable FAILED!\n");
+				if (machine_readable == 0) {
+					printf("Enable FAILED!\n");
+				}
 		}
 		mchbar_phys &= 0xfffffffe;
  		mchbar_phys |= ((uint64_t)pci_read_long(nb, 0x4c)) << 32;
- 		break;
+		break;
 	case PCI_DEVICE_ID_INTEL_82443LX:
 	case PCI_DEVICE_ID_INTEL_82443BX:
 	case PCI_DEVICE_ID_INTEL_82810:
@@ -128,15 +144,72 @@ 
 	}
 
 	if (nb->device_id == PCI_DEVICE_ID_INTEL_82865)
-		printf("BAR6 = 0x%08llx (MEM)\n\n", mchbar_phys);
+		if (machine_readable == 0) {
+			printf("BAR6 = 0x%08llx (MEM)\n\n", mchbar_phys);
+		}
 	else
-		printf("MCHBAR = 0x%08llx (MEM)\n\n", mchbar_phys);
+		if (machine_readable == 0) {
+			printf("MCHBAR = 0x%08llx (MEM)\n\n", mchbar_phys);
+		}
 
-	for (i = 0; i < size; i += 4) {
-		if (*(uint32_t *)(mchbar + i))
-			printf("0x%04x: 0x%08x\n", i, *(uint32_t *)(mchbar+i));
+	if (mch_registers != NULL) {
+		for (i = 0; i < size; i++) {
+			
+			/* Human-readable output */
+
+			if (machine_readable == 0) {
+				switch (mch_registers[i].size) {
+					case 4:
+						printf("mchbar+0x%04x: 0x%08x (%s)\n", mch_registers[i].addr, *(uint32_t *)(mchbar + mch_registers[i].addr), mch_registers[i].name);
+						break;
+					case 2:
+						printf("mchbar+0x%04x: 0x%04x (%s)\n", mch_registers[i].addr, *(uint16_t *)(mchbar + mch_registers[i].addr), mch_registers[i].name);
+						break;
+					case 1:
+						printf("mchbar+0x%04x: 0x%02x (%s)\n", mch_registers[i].addr, *(uint8_t *)(mchbar + mch_registers[i].addr), mch_registers[i].name);
+						break;
+				}
+			}
+			
+			/* Machine-readable output */
+
+			else {
+				tmp.domain = "MCH";
+				tmp.base_addr = mchbar;
+				tmp.offset = mch_registers[i].addr;
+				tmp.size = mch_registers[i].size;
+				tmp.name = mch_registers[i].name;
+				tmp.desc = "";
+				if (!read_reg(&tmp, 1)) tmp.value = 0;
+				machine_readable_printf(&tmp);
+			}
+		}
 	}
+	else {
+		for (i = 0; i < size; i += 4) {
+			if (*(uint32_t *)(mchbar + i))
 
+				/* Human-readable output */
+
+				if (machine_readable == 0) {
+					printf("0x%04x: 0x%08x\n", i, *(uint32_t *)(mchbar + i));
+				}
+				
+				/* Machine-readable output */
+
+				else {
+					tmp.domain = "MCH";
+					tmp.base_addr = mchbar;
+					tmp.offset = i;
+					tmp.size = 4;
+					tmp.name = "unresolved";
+					tmp.desc = "";
+					if (!read_reg(&tmp, 1)) tmp.value = 0;
+					machine_readable_printf(&tmp);
+				}
+		}
+	}
+
 	unmap_physical((void *)mchbar, size);
 	return 0;
 }
Index: inteltool.c
===================================================================
--- inteltool.c	(revision 6320)
+++ inteltool.c	(working copy)
@@ -82,6 +82,43 @@ 
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371XX, "82371AB/EB/MB" },
 };
 
+int read_reg(reg_t *reg, int is_mmap) {
+	if (!is_mmap) {
+		if (reg->size == 4) {
+			reg->value = inl(reg->base_addr + reg->offset);
+			return 1;
+		}
+		else if (reg->size == 2) {
+			reg->value = inw(reg->base_addr + reg->offset);
+			return 1;
+		}
+		else if (reg->size == 1) {
+			reg->value = inb(reg->base_addr + reg->offset);
+			return 1;
+		}
+		else {
+			return 0;
+		}
+	}
+	else {
+		if (reg->size == 4) {
+			reg->value = *(uint32_t *)(reg->base_addr + reg->offset);
+			return 1;
+		}
+		else if (reg->size == 2) {
+			reg->value = *(uint16_t *)(reg->base_addr + reg->offset);
+			return 1;
+		}
+		else if (reg->size == 1) {
+			reg->value = *(uint8_t *)(reg->base_addr + reg->offset);
+			return 1;
+		}
+		else {
+			return 0;
+		}
+	}
+}
+
 #ifndef __DARWIN__
 static int fd_mem;
 
@@ -124,7 +161,7 @@ 
 
 void print_usage(const char *name)
 {
-	printf("usage: %s [-vh?grpmedPMa]\n", name);
+	printf("usage: %s [-vh?grpmedPMaA]\n", name);
 	printf("\n"
 	     "   -v | --version:                   print the version\n"
 	     "   -h | --help:                      print this help\n\n"
@@ -137,6 +174,7 @@ 
 	     "   -P | --pciexpress:                dump northbridge PCIEXBAR registers\n\n"
 	     "   -M | --msrs:                      dump CPU MSRs\n"
 	     "   -a | --all:                       dump all known registers\n"
+		 "   -A | --ai:                        machine-readable output format\n"
 	     "\n");
 	exit(1);
 }
@@ -153,6 +191,7 @@ 
 	int dump_gpios = 0, dump_mchbar = 0, dump_rcba = 0;
 	int dump_pmbase = 0, dump_epbar = 0, dump_dmibar = 0;
 	int dump_pciexbar = 0, dump_coremsrs = 0;
+	int machine_readable = 0;
 
 	static struct option long_options[] = {
 		{"version", 0, 0, 'v'},
@@ -166,10 +205,11 @@ 
 		{"pciexpress", 0, 0, 'P'},
 		{"msrs", 0, 0, 'M'},
 		{"all", 0, 0, 'a'},
+		{"ai", 0, 0, 'A'},
 		{0, 0, 0, 0}
 	};
 
-	while ((opt = getopt_long(argc, argv, "vh?grpmedPMa",
+	while ((opt = getopt_long(argc, argv, "vh?grpmedPMaA",
                                   long_options, &option_index)) != EOF) {
 		switch (opt) {
 		case 'v':
@@ -210,6 +250,9 @@ 
 			dump_pciexbar = 1;
 			dump_coremsrs = 1;
 			break;
+		case 'A':
+			machine_readable = 1;
+			break;
 		case 'h':
 		case '?':
 		default:
@@ -314,42 +357,42 @@ 
 	/* Now do the deed */
 
 	if (dump_gpios) {
-		print_gpios(sb);
+		print_gpios(sb, machine_readable);
 		printf("\n\n");
 	}
 
 	if (dump_rcba) {
-		print_rcba(sb);
+		print_rcba(sb, machine_readable);
 		printf("\n\n");
 	}
 
 	if (dump_pmbase) {
-		print_pmbase(sb, pacc);
+		print_pmbase(sb, pacc, machine_readable);
 		printf("\n\n");
 	}
 
 	if (dump_mchbar) {
-		print_mchbar(nb, pacc);
+		print_mchbar(nb, pacc, machine_readable);
 		printf("\n\n");
 	}
 
 	if (dump_epbar) {
-		print_epbar(nb);
+		print_epbar(nb, machine_readable);
 		printf("\n\n");
 	}
 
 	if (dump_dmibar) {
-		print_dmibar(nb);
+		print_dmibar(nb, machine_readable);
 		printf("\n\n");
 	}
 
 	if (dump_pciexbar) {
-		print_pciexbar(nb);
+		print_pciexbar(nb, machine_readable);
 		printf("\n\n");
 	}
 
 	if (dump_coremsrs) {
-		print_intel_core_msrs();
+		print_intel_core_msrs(machine_readable);
 		printf("\n\n");
 	}
 
Index: Makefile
===================================================================
--- Makefile	(revision 6320)
+++ Makefile	(working copy)
@@ -24,10 +24,10 @@ 
 CC      = gcc
 INSTALL = /usr/bin/install
 PREFIX  = /usr/local
-CFLAGS  = -O2 -g -Wall -W
+CFLAGS  = -O2 -g -Wall -W -fno-pic -DXML
 LDFLAGS = -lpci -lz
 
-OBJS = inteltool.o cpu.o gpio.o rootcmplx.o powermgt.o memory.o pcie.o
+OBJS = inteltool.o cpu.o gpio.o rootcmplx.o powermgt.o memory.o pcie.o machine_readable.o
 
 OS_ARCH	= $(shell uname)
 ifeq ($(OS_ARCH), Darwin)