===================================================================
@@ -1,7 +1,7 @@
/*
* inteltool - dump all registers on an Intel CPU + chipset based system.
*
- * Copyright (C) 2008 by coresystems GmbH
+ * Copyright (C) 2008-2011 by coresystems GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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;
===================================================================
@@ -1,7 +1,7 @@
/*
* inteltool - dump all registers on an Intel CPU + chipset based system.
*
- * Copyright (C) 2008-2010 by coresystems GmbH
+ * Copyright (C) 2008-2011 by coresystems GmbH
* Copyright (C) 2009 Carl-Daniel Hailfinger
*
* This program is free software; you can redistribute it and/or modify
@@ -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);
===================================================================
@@ -1,7 +1,7 @@
/*
* inteltool - dump all registers on an Intel CPU + chipset based system.
*
- * Copyright (C) 2008-2010 by coresystems GmbH
+ * Copyright (C) 2008-2011 by coresystems GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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,58 @@
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);
+ }
+
+ /* Machine-readable output */
+
+ 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 {
+ }
}
}
}
===================================================================
@@ -0,0 +1,40 @@
+/*
+ * inteltool - dump all registers on an Intel CPU + chipset based system.
+ *
+ * Copyright ()C) 2008-2011 by coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include "inteltool.h"
+
+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
+
+#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
+}
+
===================================================================
@@ -1,7 +1,7 @@
/*
* inteltool - dump all registers on an Intel CPU + chipset based system.
*
- * Copyright (C) 2008-2010 by coresystems GmbH
+ * Copyright (C) 2008-2011 by coresystems GmbH
* written by Stefan Reinauer <stepan@coresystems.de>
*
* This program is free software; you can redistribute it and/or modify
@@ -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;
===================================================================
@@ -49,13 +49,14 @@
#ifndef __DARWIN__
int msr_readerror = 0;
-msr_t rdmsr(int addr)
+msr_t rdmsr(int addr, int machine_readable)
{
uint8_t buf[8];
msr_t msr = { 0xffffffff, 0xffffffff };
if (lseek(fd_msr, (off_t) addr, SEEK_SET) == -1) {
- perror("Could not lseek() to MSR");
+ if (machine_readable == 0)
+ perror("Could not lseek() to MSR");
close(fd_msr);
exit(1);
}
@@ -68,11 +69,13 @@
}
if (errno == 5) {
- printf(" (*)"); // Not all bits of the MSR could be read
+ if (machine_readable == 0)
+ printf(" (*)"); // Not all bits of the MSR could be read
msr_readerror = 1;
} else {
// A severe error.
- perror("Could not read() MSR");
+ if (machine_readable == 0)
+ perror("Could not read() MSR");
close(fd_msr);
exit(1);
}
@@ -81,10 +84,11 @@
}
#endif
-int print_intel_core_msrs(void)
+int print_intel_core_msrs(int machine_readable)
{
unsigned int i, core, id;
msr_t msr;
+ reg_t tmp;
#define IA32_PLATFORM_ID 0x0017
#define EBL_CR_POWERON 0x002a
@@ -730,6 +734,159 @@
};
+ /*
+ * Intel Xeon Processor 5200, 5400 series, Intel Core 2 Quad
+ * processors 8000, 9000 series
+ * Volume B3
+ *
+ * Chapter B.2
+ */
+ static const msr_entry_t model617x_global_msrs[] = {
+ { 0x17, "IA32_PLATFORM_ID" },
+ { 0x2a, "MSR_EBL_CR_POWERON" },
+ { 0xcd, "MSR_FSB_FREQ" },
+ { 0x11, "MSR_BBL_CR_CTL3" },
+ { 0x198, "IA32_PERF_STATUS" },
+ { 0x1a0, "IA32_MISC_ENABLE" }
+ };
+
+ static const msr_entry_t model617x_per_core_msrs[] = {
+ { 0x0, "IA32_P5_MC_ADDR" },
+ { 0x1, "IA32_P5_MC_TYPE" },
+ { 0x6, "IA32_MONITOR_FILTER_SIZE" },
+ { 0x10, "IA32_TIME_STEP_COUNTER" },
+ { 0x1b, "IA32_APIC_BASE" },
+ { 0x3a, "IA32_FEATURE_CONTROL" },
+ { 0x40, "MSR_LASTBRANCH_0_FROM_IP" },
+ { 0x41, "MSR_LASTBRANCH_1_FROM_IP" },
+ { 0x42, "MSR_LASTBRANCH_2_FROM_IP" },
+ { 0x43, "MSR_LASTBRANCH_3_FROM_IP" },
+ { 0x60, "MSR_LASTBRANCH_0_TO_LIP" },
+ { 0x61, "MSR_LASTBRANCH_1_TO_LIP" },
+ { 0x62, "MSR_LASTBRANCH_2_TO_LIP" },
+ { 0x63, "MSR_LASTBRANCH_3_TO_LIP" },
+ { 0x79, "IA32_BIOS_UPDT_TRIG" },
+ { 0x8b, "IA32_BIOS_SIGN_ID" },
+ { 0xa0, "MSR_SMRR_PHYS_BASE" },
+ { 0xa1, "MSR_SMRR_PHYS_MASK" },
+ { 0xc1, "IA32_PMC0" },
+ { 0xc2, "IA32_PMC1" },
+ { 0xe7, "IA32_MPERF" },
+ { 0xe8, "IA32_APERF" },
+ { 0xfe, "IA32_MTRRCAP" },
+ { 0x174, "IA32_SYSENTER_CS" },
+ { 0x175, "IA32_SYSENTER_ESP" },
+ { 0x176, "IA32_SYSENTER_EIP" },
+ { 0x179, "IA32_MCG_CAP" },
+ { 0x17a, "IA32_MCG_STATUS" },
+ { 0x186, "IA32_PERFEVTSEL0" },
+ { 0x187, "IA32_PERFEVTSEL1" },
+ { 0x198, "IA32_PERF_STATUS" },
+ { 0x199, "IA32_PERF_CTL" },
+ { 0x19a, "IA32_CLOCK_MODULATION" },
+ { 0x19b, "IA32_THERM_INTERRUPT" },
+ { 0x19c, "IA32_THERM_STATUS" },
+ { 0x19d, "MSR_THERM2_CTL" },
+ { 0x1a0, "IA32_MISC_ENABLE" },
+ { 0x1c9, "MSR_LASTBRANCH_TOS" },
+ { 0x1d9, "IA32_DEBUGCTL" },
+ { 0x1dd, "MSR_LER_FROM_LIP" },
+ { 0x1de, "MSR_LER_TO_LIP" },
+ { 0x200, "IA32_MTRR_PHYS_BASE0" },
+ { 0x201, "IA32_MTRR_PHYS_MASK0" },
+ { 0x202, "IA32_MTRR_PHYS_BASE1" },
+ { 0x203, "IA32_MTRR_PHYS_MASK1" },
+ { 0x204, "IA32_MTRR_PHYS_BASE2" },
+ { 0x205, "IA32_MTRR_PHYS_MASK2" },
+ { 0x206, "IA32_MTRR_PHYS_BASE3" },
+ { 0x207, "IA32_MTRR_PHYS_MASK3" },
+ { 0x208, "IA32_MTRR_PHYS_BASE4" },
+ { 0x209, "IA32_MTRR_PHYS_MASK4" },
+ { 0x20a, "IA32_MTRR_PHYS_BASE5" },
+ { 0x20b, "IA32_MTRR_PHYS_MASK5" },
+ { 0x20c, "IA32_MTRR_PHYS_BASE6" },
+ { 0x20d, "IA32_MTRR_PHYS_MASK6" },
+ { 0x20e, "IA32_MTRR_PHYS_BASE7" },
+ { 0x20f, "IA32_MTRR_PHYS_MASK7" },
+ { 0x250, "IA32_MTRR_FIX64K_00000" },
+ { 0x258, "IA32_MTRR_FIX16K_80000" },
+ { 0x259, "IA32_MTRR_FIX16K_A0000" },
+ { 0x268, "IA32_MTRR_FIX4K_C0000" },
+ { 0x269, "IA32_MTRR_FIX4K_C8000" },
+ { 0x26a, "IA32_MTRR_FIX4K_D0000" },
+ { 0x26b, "IA32_MTRR_FIX4K_D8000" },
+ { 0x26c, "IA32_MTRR_FIX4K_E0000" },
+ { 0x26d, "IA32_MTRR_FIX4K_E8000" },
+ { 0x26e, "IA32_MTRR_FIX4K_F0000" },
+ { 0x26f, "IA32_MTRR_FIX4K_F8000" },
+ { 0x277, "IA32_PAT" },
+ { 0x2ff, "IA32_MTRR_DEF_TYPE" },
+ { 0x309, "IA32_FIXED_CTR0" },
+ { 0x30a, "IA32_FIXED_CTR1" },
+ { 0x30b, "IA32_FIXED_CTR2" },
+ { 0x345, "IA32_PERF_CAPABILITIES" },
+ { 0x38d, "IA32_FIXED_CTR_CTRL" },
+ { 0x38e, "IA32_PERF_GLOBAL_STATUS" },
+ { 0x38f, "IA32_PERF_GLOBAL_CTL" },
+ { 0x390, "IA32_PERF_GLOBAL_OVF_CTL" },
+ { 0x3f1, "IA32_PEBS_ENABLE" },
+ { 0x400, "IA32_MCO_CTL" },
+ { 0x401, "IA32_MCO_STATUS" },
+ { 0x402, "IA32_MCO_ADDR" },
+ { 0x403, "IA32_MC0_MISC" },
+ { 0x404, "IA32_MC1_CTL" },
+ { 0x405, "IA32_MC1_STATUS" },
+ { 0x406, "IA32_MC1_ADDR" },
+ { 0x407, "IA32_MC1_MISC" },
+ { 0x408, "IA32_MC2_CTL" },
+ { 0x409, "IA32_MC2_STATUS" },
+ { 0x40a, "IA32_MC2_ADDR" },
+ { 0x40b, "IA32_MC2_MISC" },
+ { 0x40c, "IA32_MC4_CTL" },
+ { 0x40d, "IA32_MC4_STATUS" },
+ { 0x40e, "IA32_MC4_ADDR" },
+ { 0x40f, "IA32_MC4_MISC" },
+ { 0x410, "IA32_MC3_CTL" },
+ { 0x411, "IA32_MC3_STATUS" },
+ { 0x412, "IA32_MC3_ADDR" },
+ { 0x413, "IA32_MC3_MISC" },
+ { 0x414, "IA32_MC5_CTL" },
+ { 0x415, "IA32_MC5_STATUS" },
+ { 0x416, "IA32_MC5_ADDR" },
+ { 0x417, "IA32_MC5_MISC" },
+ { 0x418, "IA32_MC6_CTL" }, // Intel Xeon 7400 only
+ { 0x419, "IA32_MC6_STATUS" }, // Intel Xeon 7400 only
+ { 0x480, "IA32_VMX_BASIC" },
+ { 0x481, "IA32_PINBASED_CTLS" },
+ { 0x482, "IA32_PROCBASED_CTLS" },
+ { 0x483, "IA32_VMX_EXIT_CTLS" },
+ { 0x484, "IA32_VMX_ENTRY_CTLS" },
+ { 0x485, "IA32_VMX_MISC" },
+ { 0x486, "IA32_VMX_CR0_FIXED0" },
+ { 0x487, "IA32_VMX_CR0_FIXED1" },
+ { 0x488, "IA32_VMX_CR4_FIXED0" },
+ { 0x489, "IA32_VMX_CR4_FIXED1" },
+ { 0x48a, "IA32_VMX_VMCS_ENUM" },
+ { 0x48b, "IA32_VMX_PROCBASED_CTLS2" },
+ { 0x600, "IA32_DS_AREA" },
+ { 0x107cc, "MSR_EMON_L3_CTR_CTL0" }, // Intel Xeon 7400 only
+ { 0x107cd, "MSR_EMON_L3_CTR_CTL1" }, // Intel Xeon 7400 only
+ { 0x107ce, "MSR_EMON_L3_CTR_CTL2" }, // Intel Xeon 7400 only
+ { 0x107cf, "MSR_EMON_L3_CTR_CTL3" }, // Intel Xeon 7400 only
+ { 0x107d0, "MSR_EMON_L3_CTR_CTL4" }, // Intel Xeon 7400 only
+ { 0x107d1, "MSR_EMON_L3_CTR_CTL5" }, // Intel Xeon 7400 only
+ { 0x107d2, "MSR_EMON_L3_CTR_CTL6" }, // Intel Xeon 7400 only
+ { 0x107d3, "MSR_EMON_L3_CTR_CTL7" }, // Intel Xeon 7400 only
+ { 0x107d8, "MSR_EMON_L3_GL_CTL" }, // Intel Xeon 7400 only
+ { 0xc0000080, "IA32_EFER" },
+ { 0xc0000081, "IA32_STAR" },
+ { 0xc0000082, "IA32_LSTAR" },
+ { 0xc0000084, "IA32_FMASK" },
+ { 0xc0000100, "IA32_FS_BASE" },
+ { 0xc0000101, "IA32_GS_BASE" },
+ { 0xc0000102, "IA32_KERNEL_GS_BASE" }
+ };
+
typedef struct {
unsigned int model;
const msr_entry_t *global_msrs;
@@ -739,6 +896,7 @@
} cpu_t;
cpu_t cpulist[] = {
+ { 0x10670, model617x_global_msrs, ARRAY_SIZE(model617x_global_msrs), model617x_per_core_msrs, ARRAY_SIZE(model617x_per_core_msrs)},
{ 0x00670, model67x_global_msrs, ARRAY_SIZE(model67x_global_msrs), NULL, 0 },
{ 0x006b0, model6bx_global_msrs, ARRAY_SIZE(model6bx_global_msrs), NULL, 0 },
{ 0x006e0, model6ex_global_msrs, ARRAY_SIZE(model6ex_global_msrs), model6ex_per_core_msrs, ARRAY_SIZE(model6ex_per_core_msrs) },
@@ -761,26 +919,43 @@
}
if (!cpu) {
- printf("Error: Dumping MSRs on this CPU (0x%06x) is not (yet) supported.\n", id);
+ if (machine_readable == 0)
+ printf("Error: Dumping MSRs on this CPU (0x%06x) is not (yet) supported.\n", id);
return -1;
}
#ifndef __DARWIN__
fd_msr = open("/dev/cpu/0/msr", O_RDWR);
if (fd_msr < 0) {
- perror("Error while opening /dev/cpu/0/msr");
- printf("Did you run 'modprobe msr'?\n");
+ if (machine_readable == 0) {
+ perror("Error while opening /dev/cpu/0/msr");
+ printf("Did you run 'modprobe msr'?\n");
+ }
return -1;
}
#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);
+ msr = rdmsr(cpu->global_msrs[i].number, machine_readable);
+ 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 {
+ tmp.domain = "MSR";
+ tmp.base_addr = 0xFFFFFFFF;
+ tmp.offset = cpu->global_msrs[i].number;
+ tmp.size = 8;
+ tmp.name = cpu->global_msrs[i].name;
+ tmp.desc = "";
+ tmp.value = msr.lo;
+ machine_readable_printf(&tmp);
+ }
}
close(fd_msr);
@@ -800,13 +975,27 @@
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);
+ msr = rdmsr(cpu->per_core_msrs[i].number, machine_readable);
+ 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 {
+ tmp.domain = "MSR";
+ tmp.base_addr = 0xFFFFFFFF;
+ tmp.offset = cpu->per_core_msrs[i].number;
+ tmp.size = 8;
+ tmp.name = cpu->per_core_msrs[i].name;
+ tmp.desc = "";
+ tmp.value = msr.lo;
+ machine_readable_printf(&tmp);
+ }
}
#ifndef __DARWIN__
close(fd_msr);
===================================================================
@@ -1,7 +1,7 @@
/*
* inteltool - dump all registers on an Intel CPU + chipset based system.
*
- * Copyright (C) 2008 by coresystems GmbH
+ * Copyright (C) 2008-2011 by coresystems GmbH
* written by Stefan Reinauer <stepan@coresystems.de>
*
* This program is free software; you can redistribute it and/or modify
@@ -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);
===================================================================
@@ -1,7 +1,7 @@
/*
* inteltool - dump all registers on an Intel CPU + chipset based system.
*
- * Copyright (C) 2008-2010 by coresystems GmbH
+ * Copyright (C) 2008-2011 by coresystems GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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;
}
===================================================================
@@ -1,7 +1,7 @@
/*
* inteltool - dump all registers on an Intel CPU + chipset based system.
*
- * Copyright (C) 2008-2010 by coresystems GmbH
+ * Copyright (C) 2008-2011 by coresystems GmbH
* written by Stefan Reinauer <stepan@coresystems.de>
* Copyright (C) 2009 Carl-Daniel Hailfinger
*
@@ -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:
@@ -293,63 +336,66 @@
* left-shifted "Extended Model" fields.
* http://download.intel.com/design/processor/applnots/24161832.pdf
*/
- printf("Intel CPU: Processor Type: %x, Family %x, Model %x, Stepping %x\n",
+ if (machine_readable == 0) {
+ printf("Intel CPU: Processor Type: %x, Family %x, Model %x, Stepping %x\n",
(id >> 12) & 0x3, ((id >> 8) & 0xf) + ((id >> 20) & 0xff),
((id >> 12) & 0xf0) + ((id >> 4) & 0xf), (id & 0xf));
- /* Determine names */
- for (i = 0; i < ARRAY_SIZE(supported_chips_list); i++)
- if (nb->device_id == supported_chips_list[i].device_id)
- nbname = supported_chips_list[i].name;
- for (i = 0; i < ARRAY_SIZE(supported_chips_list); i++)
- if (sb->device_id == supported_chips_list[i].device_id)
- sbname = supported_chips_list[i].name;
+ /* Determine names */
+ for (i = 0; i < ARRAY_SIZE(supported_chips_list); i++)
+ if (nb->device_id == supported_chips_list[i].device_id)
+ nbname = supported_chips_list[i].name;
+ for (i = 0; i < ARRAY_SIZE(supported_chips_list); i++)
+ if (sb->device_id == supported_chips_list[i].device_id)
+ sbname = supported_chips_list[i].name;
+
+ printf("Intel Northbridge: %04x:%04x (%s)\n",
+ nb->vendor_id, nb->device_id, nbname);
+
+ printf("Intel Southbridge: %04x:%04x (%s)\n",
+ sb->vendor_id, sb->device_id, sbname);
+
+ }
- printf("Intel Northbridge: %04x:%04x (%s)\n",
- nb->vendor_id, nb->device_id, nbname);
-
- printf("Intel Southbridge: %04x:%04x (%s)\n",
- sb->vendor_id, sb->device_id, sbname);
-
/* 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");
}
===================================================================
@@ -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)
inteltool: first preview for machine-readable output, fixes Signed-off-by: Anton Kochkov <anton.kochkov@gmail.com> --- This is only for preview and discussion, it's still ugly and dont safe/clear.