Patchwork [inteltool] added initial support of CPU extended information and non-Intel CPU's

login
register
about
Submitter Антон Кочков
Date 2010-08-25 17:34:24
Message ID <AANLkTi=SuywzhAnOHVO=x7c+G+p10aoN2uM2A4-K27Ok@mail.gmail.com>
Download mbox | patch
Permalink /patch/1800/
State New
Headers show

Comments

Антон Кочков - 2010-08-25 17:34:24
inteltool: added initial support of cpu_info extended information
inteltool: added initial support for other cpu's
inteltool: dumping MSR registers for Intel Celeron M 743
Signed-off-by: Anton Kochkov <anton.kochkov@gmail.com>
---
Property changes on: .
Stefan Reinauer - 2010-08-26 11:21:22
On 8/25/10 7:34 PM, Антон Кочков wrote:
> inteltool: added initial support of cpu_info extended information
> inteltool: added initial support for other cpu's
> inteltool: dumping MSR registers for Intel Celeron M 743
> Signed-off-by: Anton Kochkov <anton.kochkov@gmail.com>
Hi Anton,

just some thoughts...

I don't think we should add parsing of CPUID features into inteltool
because there are excellent tools for Linux doing an excellent job
already, like Dave Jones' x86info.
See http://www.codemonkey.org.uk/projects/x86info/ for more information.

Also, EPBAR, DMIBAR, MCHBAR, etc are very intel specific terms, so it
will be hard to add support for other chipset vendors without making the
tool (unnecessarily?) complex.
I'd like to hear from other people on this issue, though...

As for the CPUID part, I don't think that all CPUs with 0x10670 are
Intel Celeron M 743 1.3 GHz. There might be other Celeron Ms with that
ID too. Also, I think the supported MSRs are different between the Core
2 Duo (6fx) and Celeron M (10670)

Stefan

Patch

Index: inteltool.h
===================================================================
--- inteltool.h	(revision 5721)
+++ inteltool.h	(working copy)
@@ -31,8 +31,18 @@ 
 
 #define INTELTOOL_VERSION "1.0"
 
+/* Chipset vendors: */
+#define PCI_VENDOR_ID_INTEL			0x8086
+#define PCI_VENDOR_ID_VIA			0x1106
+#define PCI_VENDOR_ID_ATI_AMD			0x1002
+#define PCI_VENDOR_ID_AMD			0x1022
+#define PCI_VENDOR_ID_SIS			0x1039
+#define PCI_VENDOR_ID_NVIDIA			0x10DE
+
 /* Tested chipsets: */
-#define PCI_VENDOR_ID_INTEL			0x8086
+
+/* INTEL CHIPSETS */
+
 #define PCI_DEVICE_ID_INTEL_ICH			0x2410
 #define PCI_DEVICE_ID_INTEL_ICH0		0x2420
 #define PCI_DEVICE_ID_INTEL_ICH2		0x2440
@@ -74,18 +84,16 @@ 
 #define PCI_DEVICE_ID_INTEL_X58			0x3405
 #define PCI_DEVICE_ID_INTEL_SCH_POULSBO		0x8100
 #define PCI_DEVICE_ID_INTEL_ATOM_DXXX		0xa000
-
-/* untested, but almost identical to D-series */
-#define PCI_DEVICE_ID_INTEL_ATOM_NXXX		0xa010
-
+#define PCI_DEVICE_ID_INTEL_ATOM_NXXX		0xa010 /* untested, but almost identical to D-series */
 #define PCI_DEVICE_ID_INTEL_82443LX		0x7180
-/* 82443BX has a different device ID if AGP is disabled (hardware-wise). */
-#define PCI_DEVICE_ID_INTEL_82443BX		0x7190
+#define PCI_DEVICE_ID_INTEL_82443BX		0x7190 /* 82443BX has a different device ID if AGP is disabled (hardware-wise). */
 #define PCI_DEVICE_ID_INTEL_82443BX_NO_AGP	0x7192
+#define PCI_DEVICE_ID_INTEL_82371XX		0x7110 /* 82371AB/EB/MB use the same device ID value. */
 
-/* 82371AB/EB/MB use the same device ID value. */
-#define PCI_DEVICE_ID_INTEL_82371XX		0x7110
+/* VIA CHIPSETS */
 
+#define PCI_DEVICE_ID_VIA_VT8235		0x3059
+
 #define ARRAY_SIZE(a) ((int)(sizeof(a) / sizeof((a)[0])))
 
 #ifndef __DARWIN__
@@ -97,6 +105,7 @@ 
 void unmap_physical(void *virt_addr, size_t len);
 
 unsigned int cpuid(unsigned int op);
+int print_cpu_info(void);
 int print_intel_core_msrs(void);
 int print_mchbar(struct pci_dev *nb);
 int print_pmbase(struct pci_dev *sb);
Index: cpu.c
===================================================================
--- cpu.c	(revision 5721)
+++ cpu.c	(working copy)
@@ -26,8 +26,592 @@ 
 
 #include "inteltool.h"
 
+#define CPU_VENDOR_ID_INTEL		0x01
+#define CPU_VENDOR_ID_AMD		0x02
+#define CPU_VENDOR_ID_VIA		0x03
+#define CPU_VENDOR_ID_TRANSMETA		0x04
+#define CPU_VENDOR_ID_NVIDIA		0x05
+#define CPU_VENDOR_ID_CYRIX		0x06
+#define CPU_VENDOR_ID_IDT		0x07
+#define CPU_VENDOR_ID_NEXGEN		0x08
+#define CPU_VENDOR_ID_RISE		0x09
+#define CPU_VENDOR_ID_SIS		0x0A
+#define CPU_VENDOR_ID_UMC		0x0B
+#define CPU_VENDOR_ID_CENTAUR		0x0C
+
+#define INTEL_IA32_PLATFORM_ID		0x0017
+#define INTEL_EBL_CR_POWERON		0x002a
+#define INTEL_UCODE_REV			0x008b
+#define INTEL_FSB_CLK_STS		0x00cd
+#define INTEL_IA32_TIME_STAMP_COUNTER	0x0010
+#define INTEL_IA32_APIC_BASE		0x001b
+
+typedef struct {
+	unsigned int vendor_id;
+	uint32_t reg_ebx;
+	uint32_t reg_edx;
+	uint32_t reg_ecx;
+	char *name;
+} cpu_vendor_t;
+
+typedef struct {
+	unsigned int model;
+	char *name;
+} cpu_model_t;
+
+typedef struct {
+        unsigned int feature_bit;
+        char *name;
+        char *description;
+} cpu_feature_t;
+
+typedef struct {
+	cpu_model_t *model;
+        cpu_feature_t features_edx[64];
+        cpu_feature_t features_ecx[64];
+} cpu_info_t;
+
+static const cpu_vendor_t cpu_vendors[] = {
+	{ 0, 0x0, 0x0, 0x0, "Unknown"},
+	{ CPU_VENDOR_ID_INTEL, 0x756E6547, 0x49656E69, 0x6C65746E, "Intel"},
+	{ CPU_VENDOR_ID_AMD, 0x68747541, 0x69746E65, 0x444D4163, "AMD"},
+	{ CPU_VENDOR_ID_TRANSMETA, 0x756E6547, 0x54656E69, 0x3638784D, "Transmeta"},
+	{ CPU_VENDOR_ID_CYRIX, 0x69727943, 0x736E4978, 0x64616574, "Cyrix"},
+	{ CPU_VENDOR_ID_NEXGEN, 0x4778654E, 0x72446E65, 0x6E657669, "NexGen"},
+	{ CPU_VENDOR_ID_RISE, 0x65736952, 0x65736952, 0x65736952, "Rise"},
+	{ CPU_VENDOR_ID_SIS, 0x20536953, 0x20536953, 0x20536953, "SiS"},
+	{ CPU_VENDOR_ID_UMC, 0x20434D55, 0x20434D55, 0x20434D55, "UMC"},
+};
+
+static const cpu_feature_t intel_features_edx[] = {
+        { 0, "fpu", "Floating-point Unit On-Chip" },
+        { 1, "vme", "Virtual Mode Extension" },
+        { 2, "de", "Debugging Extension" },
+        { 3, "pse", "Page Size Extension" },
+        { 4, "tsc", "Time Stamp Counter" },
+        { 5, "msr", "Model Specific Registers" },
+        { 6, "pae", "Physical Address Extension" },
+        { 7, "mce", "Machine-Check Exception" },
+        { 8, "cx8", "CMPXCHG8 Instruction" },
+        { 9, "apic", "On-chip APIC Hardware" },
+//        { 10, "", "Reserved" },
+        { 11, "sep", "Fast System Call" },
+        { 12, "mtrr", "Memory Type Range Registers" },
+        { 13, "pge", "Page Global Enable" },
+        { 14, "mca", "Machine-Check Architecture" },
+        { 15, "cmov", "Conditional Move Instruction" },
+        { 16, "pat", "Page Attribute Table" },
+        { 17, "pse-36", "36-bit Page Size Extension " },
+        { 18, "psn", "Processor serial number is presented and enabled" },
+        { 19, "clfsh", "CLFLUSH Instruction" },
+//        { 20, "", "Reserved" },
+        { 21, "ds", "Debug Store" },
+        { 22, "acpi", "Thermal Monitor and Software Controlled Clock Facilities" },
+        { 23, "mmx", "MMX technology" },
+        { 24, "fxsr", "FXSAVE and FXSTOR Instructions" },
+        { 25, "sse", "Streaming SIMD Extensions" },
+        { 26, "sse2", "Streaming SIMD Extensions 2" },
+        { 27, "ss", "Self-Snoop" },
+        { 28, "htt", "Multi-Threading" },
+        { 29, "tm", "Thermal Monitor" },
+ //       { 30, "", "Reserved" },
+        { 31, "pbe", "Pending Break Enable" }
+};
+
+static const cpu_feature_t intel_features_ecx[] = {
+        { 0, "sse3", "Streaming SIMD Extensions 3" },
+        { 1, "pclmuldq", "PCLMULDQ Instruction" },
+        { 2, "dtes64", "64-Bit Debug Store" },
+        { 3, "monitor", "MONITOR/MWAIT" },
+        { 4, "ds-cpl", "CPL Qualified Debug Store" },
+        { 5, "vmx", "Virtual Machine Extensions" },
+        { 6, "smx", "Safer Mode Extensions" },
+        { 7, "est", "Enhanced Intel SpeedStep Technology" },
+        { 8, "tm2", "Thermal Monitor 2" },
+        { 9, "ssse3", "Supplemental Streaming SIMD Extensions 3" },
+        { 10, "cnxt-id", "L1 Context ID" },
+//        { 11, "", "Reserved" },
+//        { 12, "", "Reserved" },
+        { 13, "cx16", "CMPXCHG16B" },
+        { 14, "xtpr", "xTPR Update Control" },
+        { 15, "pdcm", "Perfmon and Debug Capability" },
+//        { 16, "", "Reserved" },
+//        { 17, "", "Reserved" },
+        { 18, "dca", "Direct Cache Access" },
+        { 19, "sse4.1", "Streaming SIMD Extensions 4.1" },
+        { 20, "sse4.2", "Streaming SIMD Extensions 4.2" },
+        { 21, "x2apic", "Extended xAPIC Support" },
+        { 22, "movbe", "MOVBE Instruction" },
+        { 23, "popcnt", "POPCNT Instruction" },
+//       { 24, "", "Reserved" },
+        { 25, "aes", "AES Instruction" },
+        { 26, "xsave", "XSAVE/XSTOR States" },
+        { 27, "osxsave", "OS-Enabled Extended State Management" },
+//        { 28, "", "Reserved" },
+//        { 29, "", "Reserved" },
+//        { 30, "", "Reserved" },
+//        { 31, "", "Reserved" }
+};
+
+static const cpu_feature_t amd_features_edx[] = {
+        { 0, "fpu", "Floating-point Unit On-Chip" },
+        { 1, "vme", "Virtual Mode Extension" },
+        { 2, "de", "Debugging Extension" },
+        { 3, "pse", "Page Size Extension" },
+        { 4, "tsc", "Time Stamp Counter" },
+        { 5, "msr", "Model Specific Registers" },
+        { 6, "pae", "Physical Address Extension" },
+        { 7, "mce", "Machine-Check Exception" },
+        { 8, "cx8", "CMPXCHG8 Instruction" },
+        { 9, "apic", "On-chip APIC Hardware" },
+//        { 10, "", "Reserved" },
+        { 11, "sese", "SYSENTER and SYSEXIT instructions " },
+        { 12, "mtrr", "Memory Type Range Registers" },
+        { 13, "pge", "Page Global Enable" },
+        { 14, "mca", "Machine-Check Architecture" },
+        { 15, "cmov", "Conditional Move Instruction" },
+        { 16, "pat", "Page Attribute Table" },
+        { 17, "pse-36", "36-bit Page Size Extension " },
+//        { 18, "", "Reserved" },
+        { 19, "clfsh", "CLFLUSH Instruction" },
+//        { 20, "", "Reserved" },
+//        { 21, "", "Reserved" },
+//        { 22, "", "Reserved" },
+        { 23, "mmx", "MMX technology" },
+        { 24, "fxsr", "FXSAVE and FXSTOR Instructions" },
+        { 25, "sse", "Streaming SIMD Extensions" },
+        { 26, "sse2", "Streaming SIMD Extensions 2" },
+//        { 27, "", "Reserved" },
+        { 28, "htt", "Multi-Threading" },
+//        { 29, "", "Reserved" },
+//        { 30, "", "Reserved" },
+//        { 31, "", "Reserved" }
+};
+
+static const cpu_feature_t amd_features_ecx[] = {
+        { 0, "sse3", "Streaming SIMD Extensions 3" },
+//        { 1, "", "Reserved" },
+//        { 2, "", "Reserved" },
+        { 3, "monitor", "MONITOR/MWAIT" },
+//        { 4, "", "Reserved" },
+//        { 5, "", "Reserved" },
+//        { 6, "", "Reserved" },
+//        { 7, "", "Reserved" },
+//        { 8, "", "Reserved" },
+        { 9, "ssse3", "Supplemental Streaming SIMD Extensions 3" },
+//        { 10, "", "Reserved" },
+//        { 11, "", "Reserved" },
+//        { 12, "", "Reserved" },
+        { 13, "cx16", "CMPXCHG16B" },
+//        { 14, "", "Reserved" },
+//        { 15, "", "Reserved" },
+//        { 16, "", "Reserved" },
+//        { 17, "", "Reserved" },
+//        { 18, "", "Reserved" },
+        { 19, "sse4.1", "Streaming SIMD Extensions 4.1" },
+        { 20, "sse4.2", "Streaming SIMD Extensions 4.2" },
+//        { 21, "", "Reserved" },
+//        { 22, "", "Reserved" },
+        { 23, "popcnt", "POPCNT Instruction" },
+//        { 24, "", "Reserved" },
+//        { 25, "", "Reserved" },
+//        { 26, "", "Reserved" },
+//        { 27, "", "Reserved" },
+//        { 28, "", "Reserved" },
+//        { 29, "", "Reserved" },
+//        { 30, "", "Reserved" },
+//        { 31, "", "Reserved" }
+};
+
+static const cpu_model_t cpuid_table[] = {
+	{ 0x10670, "Intel Celeron M 743 1.3 GHz" },
+};
+
+typedef struct {
+	int number;
+	char *name;
+} msr_entry_t;
+
+static const msr_entry_t model6bx_global_msrs[] = {
+	{ 0x0010, "IA32_TIME_STAMP_COUNTER" },
+	{ 0x0017, "IA32_PLATFORM_ID" },
+	{ 0x001b, "IA32_APIC_BASE" },
+	{ 0x002a, "EBL_CR_POWERON" },
+	{ 0x0033, "TEST_CTL" },
+	{ 0x003f, "THERM_DIODE_OFFSET" },
+	//{ 0x0079, "IA32_BIOS_UPDT_TRIG" }, // Seems to be RO
+	{ 0x008b, "IA32_BIOS_SIGN_ID" },
+	{ 0x00c1, "PERFCTR0" },
+	{ 0x00c2, "PERFCTR1" },
+	{ 0x011e, "BBL_CR_CTL3" },
+	{ 0x0179, "IA32_MCG_CAP" },
+	{ 0x017a, "IA32_MCG_STATUS" },
+	{ 0x0198, "IA32_PERF_STATUS" },
+	{ 0x0199, "IA32_PERF_CONTROL" },
+	{ 0x019a, "IA32_CLOCK_MODULATION" },
+	{ 0x01a0, "IA32_MISC_ENABLES" },
+	{ 0x01d9, "IA32_DEBUGCTL" },
+	{ 0x0200, "IA32_MTRR_PHYSBASE0" },
+	{ 0x0201, "IA32_MTRR_PHYSMASK0" },
+	{ 0x0202, "IA32_MTRR_PHYSBASE1" },
+	{ 0x0203, "IA32_MTRR_PHYSMASK1" },
+	{ 0x0204, "IA32_MTRR_PHYSBASE2" },
+	{ 0x0205, "IA32_MTRR_PHYSMASK2" },
+	{ 0x0206, "IA32_MTRR_PHYSBASE3" },
+	{ 0x0207, "IA32_MTRR_PHYSMASK3" },
+	{ 0x0208, "IA32_MTRR_PHYSBASE4" },
+	{ 0x0209, "IA32_MTRR_PHYSMASK4" },
+	{ 0x020a, "IA32_MTRR_PHYSBASE5" },
+	{ 0x020b, "IA32_MTRR_PHYSMASK5" },
+	{ 0x020c, "IA32_MTRR_PHYSBASE6" },
+	{ 0x020d, "IA32_MTRR_PHYSMASK6" },
+	{ 0x020e, "IA32_MTRR_PHYSBASE7" },
+	{ 0x020f, "IA32_MTRR_PHYSMASK7" },
+	{ 0x0250, "IA32_MTRR_FIX64K_00000" },
+	{ 0x0258, "IA32_MTRR_FIX16K_80000" },
+	{ 0x0259, "IA32_MTRR_FIX16K_A0000" },
+	{ 0x0268, "IA32_MTRR_FIX4K_C0000" },
+	{ 0x0269, "IA32_MTRR_FIX4K_C8000" },
+	{ 0x026a, "IA32_MTRR_FIX4K_D0000" },
+	{ 0x026b, "IA32_MTRR_FIX4K_D8000" },
+	{ 0x026c, "IA32_MTRR_FIX4K_E0000" },
+	{ 0x026d, "IA32_MTRR_FIX4K_E8000" },
+	{ 0x026e, "IA32_MTRR_FIX4K_F0000" },
+	{ 0x026f, "IA32_MTRR_FIX4K_F8000" },
+	{ 0x02ff, "IA32_MTRR_DEF_TYPE" },
+	{ 0x0400, "IA32_MC0_CTL" },
+	{ 0x0401, "IA32_MC0_STATUS" },
+	{ 0x0402, "IA32_MC0_ADDR" },
+	//{ 0x0403, "IA32_MC0_MISC" }, // Seems to be RO
+	{ 0x040c, "IA32_MC4_CTL" },
+	{ 0x040d, "IA32_MC4_STATUS" },
+	{ 0x040e, "IA32_MC4_ADDR" },
+	//{ 0x040f, "IA32_MC4_MISC" } // Seems to be RO
+};
+
+static const msr_entry_t model6ex_global_msrs[] = {
+	{ 0x0017, "IA32_PLATFORM_ID" },
+	{ 0x002a, "EBL_CR_POWERON" },
+	{ 0x00cd, "FSB_CLOCK_STS" },
+	{ 0x00ce, "FSB_CLOCK_VCC" },
+	{ 0x00e2, "CLOCK_CST_CONFIG_CONTROL" },
+	{ 0x00e3, "PMG_IO_BASE_ADDR" },
+	{ 0x00e4, "PMG_IO_CAPTURE_ADDR" },
+	{ 0x00ee, "EXT_CONFIG" },
+	{ 0x011e, "BBL_CR_CTL3" },
+	{ 0x0194, "CLOCK_FLEX_MAX" },
+	{ 0x0198, "IA32_PERF_STATUS" },
+	{ 0x01a0, "IA32_MISC_ENABLES" },
+	{ 0x01aa, "PIC_SENS_CFG" },
+	{ 0x0400, "IA32_MC0_CTL" },
+	{ 0x0401, "IA32_MC0_STATUS" },
+	{ 0x0402, "IA32_MC0_ADDR" },
+	//{ 0x0403, "IA32_MC0_MISC" }, // Seems to be RO
+	{ 0x040c, "IA32_MC4_CTL" },
+	{ 0x040d, "IA32_MC4_STATUS" },
+	{ 0x040e, "IA32_MC4_ADDR" },
+	//{ 0x040f, "IA32_MC4_MISC" } // Seems to be RO
+};
+
+static const msr_entry_t model6ex_per_core_msrs[] = {
+	{ 0x0010, "IA32_TIME_STAMP_COUNTER" },
+	{ 0x001b, "IA32_APIC_BASE" },
+	{ 0x003a, "IA32_FEATURE_CONTROL" },
+	{ 0x003f, "IA32_TEMPERATURE_OFFSET" },
+	//{ 0x0079, "IA32_BIOS_UPDT_TRIG" }, // Seems to be RO
+	{ 0x008b, "IA32_BIOS_SIGN_ID" },
+	{ 0x00e7, "IA32_MPERF" },
+	{ 0x00e8, "IA32_APERF" },
+	{ 0x00fe, "IA32_MTRRCAP" },
+	{ 0x015f, "DTS_CAL_CTRL" },
+	{ 0x0179, "IA32_MCG_CAP" },
+	{ 0x017a, "IA32_MCG_STATUS" },
+	{ 0x0199, "IA32_PERF_CONTROL" },
+	{ 0x019a, "IA32_CLOCK_MODULATION" },
+	{ 0x019b, "IA32_THERM_INTERRUPT" },
+	{ 0x019c, "IA32_THERM_STATUS" },
+	{ 0x019d, "GV_THERM" },
+	{ 0x01d9, "IA32_DEBUGCTL" },
+	{ 0x0200, "IA32_MTRR_PHYSBASE0" },
+	{ 0x0201, "IA32_MTRR_PHYSMASK0" },
+	{ 0x0202, "IA32_MTRR_PHYSBASE1" },
+	{ 0x0203, "IA32_MTRR_PHYSMASK1" },
+	{ 0x0204, "IA32_MTRR_PHYSBASE2" },
+	{ 0x0205, "IA32_MTRR_PHYSMASK2" },
+	{ 0x0206, "IA32_MTRR_PHYSBASE3" },
+	{ 0x0207, "IA32_MTRR_PHYSMASK3" },
+	{ 0x0208, "IA32_MTRR_PHYSBASE4" },
+	{ 0x0209, "IA32_MTRR_PHYSMASK4" },
+	{ 0x020a, "IA32_MTRR_PHYSBASE5" },
+	{ 0x020b, "IA32_MTRR_PHYSMASK5" },
+	{ 0x020c, "IA32_MTRR_PHYSBASE6" },
+	{ 0x020d, "IA32_MTRR_PHYSMASK6" },
+	{ 0x020e, "IA32_MTRR_PHYSBASE7" },
+	{ 0x020f, "IA32_MTRR_PHYSMASK7" },
+	{ 0x0250, "IA32_MTRR_FIX64K_00000" },
+	{ 0x0258, "IA32_MTRR_FIX16K_80000" },
+	{ 0x0259, "IA32_MTRR_FIX16K_A0000" },
+	{ 0x0268, "IA32_MTRR_FIX4K_C0000" },
+	{ 0x0269, "IA32_MTRR_FIX4K_C8000" },
+	{ 0x026a, "IA32_MTRR_FIX4K_D0000" },
+	{ 0x026b, "IA32_MTRR_FIX4K_D8000" },
+	{ 0x026c, "IA32_MTRR_FIX4K_E0000" },
+	{ 0x026d, "IA32_MTRR_FIX4K_E8000" },
+	{ 0x026e, "IA32_MTRR_FIX4K_F0000" },
+	{ 0x026f, "IA32_MTRR_FIX4K_F8000" },
+	{ 0x02ff, "IA32_MTRR_DEF_TYPE" },
+	//{ 0x00c000080, "IA32_CR_EFER" }, // Seems to be RO
+};
+
+static const msr_entry_t model6fx_global_msrs[] = {
+	{ 0x0017, "IA32_PLATFORM_ID" },
+	{ 0x002a, "EBL_CR_POWERON" },
+	{ 0x003f, "IA32_TEMPERATURE_OFFSET" },
+	{ 0x00a8, "EMTTM_CR_TABLE0" },
+	{ 0x00a9, "EMTTM_CR_TABLE1" },
+	{ 0x00aa, "EMTTM_CR_TABLE2" },
+	{ 0x00ab, "EMTTM_CR_TABLE3" },
+	{ 0x00ac, "EMTTM_CR_TABLE4" },
+	{ 0x00ad, "EMTTM_CR_TABLE5" },
+	{ 0x00cd, "FSB_CLOCK_STS" },
+	{ 0x00e2, "PMG_CST_CONFIG_CONTROL" },
+	{ 0x00e3, "PMG_IO_BASE_ADDR" },
+	{ 0x00e4, "PMG_IO_CAPTURE_ADDR" },
+	{ 0x00ee, "EXT_CONFIG" },
+	{ 0x011e, "BBL_CR_CTL3" },
+	{ 0x0194, "CLOCK_FLEX_MAX" },
+	{ 0x0198, "IA32_PERF_STATUS" },
+	{ 0x01a0, "IA32_MISC_ENABLES" },
+	{ 0x01aa, "PIC_SENS_CFG" },
+	{ 0x0400, "IA32_MC0_CTL" },
+	{ 0x0401, "IA32_MC0_STATUS" },
+	{ 0x0402, "IA32_MC0_ADDR" },
+	//{ 0x0403, "IA32_MC0_MISC" }, // Seems to be RO
+	{ 0x040c, "IA32_MC4_CTL" },
+	{ 0x040d, "IA32_MC4_STATUS" },
+	{ 0x040e, "IA32_MC4_ADDR" },
+	//{ 0x040f, "IA32_MC4_MISC" } // Seems to be RO
+};
+
+static const msr_entry_t model6fx_per_core_msrs[] = {
+	{ 0x0010, "IA32_TIME_STAMP_COUNTER" },
+	{ 0x001b, "IA32_APIC_BASE" },
+	{ 0x003a, "IA32_FEATURE_CONTROL" },
+	//{ 0x0079, "IA32_BIOS_UPDT_TRIG" }, // Seems to be RO
+	{ 0x008b, "IA32_BIOS_SIGN_ID" },
+	{ 0x00e1, "SMM_CST_MISC_INFO" },
+	{ 0x00e7, "IA32_MPERF" },
+	{ 0x00e8, "IA32_APERF" },
+	{ 0x00fe, "IA32_MTRRCAP" },
+	{ 0x0179, "IA32_MCG_CAP" },
+	{ 0x017a, "IA32_MCG_STATUS" },
+	{ 0x0199, "IA32_PERF_CONTROL" },
+	{ 0x019a, "IA32_THERM_CTL" },
+	{ 0x019b, "IA32_THERM_INTERRUPT" },
+	{ 0x019c, "IA32_THERM_STATUS" },
+	{ 0x019d, "MSR_THERM2_CTL" },
+	{ 0x01d9, "IA32_DEBUGCTL" },
+	{ 0x0200, "IA32_MTRR_PHYSBASE0" },
+	{ 0x0201, "IA32_MTRR_PHYSMASK0" },
+	{ 0x0202, "IA32_MTRR_PHYSBASE1" },
+	{ 0x0203, "IA32_MTRR_PHYSMASK1" },
+	{ 0x0204, "IA32_MTRR_PHYSBASE2" },
+	{ 0x0205, "IA32_MTRR_PHYSMASK2" },
+	{ 0x0206, "IA32_MTRR_PHYSBASE3" },
+	{ 0x0207, "IA32_MTRR_PHYSMASK3" },
+	{ 0x0208, "IA32_MTRR_PHYSBASE4" },
+	{ 0x0209, "IA32_MTRR_PHYSMASK4" },
+	{ 0x020a, "IA32_MTRR_PHYSBASE5" },
+	{ 0x020b, "IA32_MTRR_PHYSMASK5" },
+	{ 0x020c, "IA32_MTRR_PHYSBASE6" },
+	{ 0x020d, "IA32_MTRR_PHYSMASK6" },
+	{ 0x020e, "IA32_MTRR_PHYSBASE7" },
+	{ 0x020f, "IA32_MTRR_PHYSMASK7" },
+	{ 0x0250, "IA32_MTRR_FIX64K_00000" },
+	{ 0x0258, "IA32_MTRR_FIX16K_80000" },
+	{ 0x0259, "IA32_MTRR_FIX16K_A0000" },
+	{ 0x0268, "IA32_MTRR_FIX4K_C0000" },
+	{ 0x0269, "IA32_MTRR_FIX4K_C8000" },
+	{ 0x026a, "IA32_MTRR_FIX4K_D0000" },
+	{ 0x026b, "IA32_MTRR_FIX4K_D8000" },
+	{ 0x026c, "IA32_MTRR_FIX4K_E0000" },
+	{ 0x026d, "IA32_MTRR_FIX4K_E8000" },
+	{ 0x026e, "IA32_MTRR_FIX4K_F0000" },
+	{ 0x026f, "IA32_MTRR_FIX4K_F8000" },
+	{ 0x02ff, "IA32_MTRR_DEF_TYPE" },
+	//{ 0x00c000080, "IA32_CR_EFER" }, // Seems to be RO
+};
+
+/* Pentium 4 and XEON */
+/*
+ * All MSRs per
+ *
+ * Intel� 64 and IA-32 Architectures
+ * Software Developer.s Manual
+ * Volume 3B:
+ * System Programming Guide, Part 2
+ *
+ * Table B-5
+ */
+static const msr_entry_t modelf4x_global_msrs[] = {
+	{ 0x0000, "IA32_P5_MC_ADDR" },
+	{ 0x0001, "IA32_P5_MC_TYPE" },
+	{ 0x0006, "IA32_MONITOR_FILTER_LINE_SIZE" },
+	{ 0x0017, "IA32_PLATFORM_ID" },
+	{ 0x002a, "MSR_EBC_HARD_POWERON" },
+	{ 0x002b, "MSR_EBC_SOFT_POWRON" },
+	{ 0x002c, "MSR_EBC_FREQUENCY_ID" },
+// WRITE ONLY	{ 0x0079, "IA32_BIOS_UPDT_TRIG" },
+	{ 0x019c, "IA32_THERM_STATUS" },
+	{ 0x019d, "MSR_THERM2_CTL" },
+	{ 0x01a0, "IA32_MISC_ENABLE" },
+	{ 0x01a1, "MSR_PLATFORM_BRV" },
+	{ 0x0200, "IA32_MTRR_PHYSBASE0" },
+	{ 0x0201, "IA32_MTRR_PHYSMASK0" },
+	{ 0x0202, "IA32_MTRR_PHYSBASE1" },
+	{ 0x0203, "IA32_MTRR_PHYSMASK1" },
+	{ 0x0204, "IA32_MTRR_PHYSBASE2" },
+	{ 0x0205, "IA32_MTRR_PHYSMASK2" },
+	{ 0x0206, "IA32_MTRR_PHYSBASE3" },
+	{ 0x0207, "IA32_MTRR_PHYSMASK3" },
+	{ 0x0208, "IA32_MTRR_PHYSBASE4" },
+	{ 0x0209, "IA32_MTRR_PHYSMASK4" },
+	{ 0x020a, "IA32_MTRR_PHYSBASE5" },
+	{ 0x020b, "IA32_MTRR_PHYSMASK5" },
+	{ 0x020c, "IA32_MTRR_PHYSBASE6" },
+	{ 0x020d, "IA32_MTRR_PHYSMASK6" },
+	{ 0x020e, "IA32_MTRR_PHYSBASE7" },
+	{ 0x020f, "IA32_MTRR_PHYSMASK7" },
+	{ 0x0250, "IA32_MTRR_FIX64K_00000" },
+	{ 0x0258, "IA32_MTRR_FIX16K_80000" },
+	{ 0x0259, "IA32_MTRR_FIX16K_A0000" },
+	{ 0x0268, "IA32_MTRR_FIX4K_C0000" },
+	{ 0x0269, "IA32_MTRR_FIX4K_C8000" },
+	{ 0x026a, "IA32_MTRR_FIX4K_D0000" },
+	{ 0x026b, "IA32_MTRR_FIX4K_D8000" },
+	{ 0x026c, "IA32_MTRR_FIX4K_E0000" },
+	{ 0x026d, "IA32_MTRR_FIX4K_E8000" },
+	{ 0x026e, "IA32_MTRR_FIX4K_F0000" },
+	{ 0x026f, "IA32_MTRR_FIX4K_F8000" },
+	{ 0x02ff, "IA32_MTRR_DEF_TYPE" },
+	{ 0x0300, "MSR_BPU_COUNTER0" },
+	{ 0x0301, "MSR_BPU_COUNTER1" },
+	{ 0x0302, "MSR_BPU_COUNTER2" },
+	{ 0x0303, "MSR_BPU_COUNTER3" },
+	/* Skipped through 0x3ff  for now*/
+	/* All MCX_ADDR AND MCX_MISC MSRs depend on a bit being
+	 * set in MCX_STATUS */
+	{ 0x400, "IA32_MC0_CTL" },
+	{ 0x401, "IA32_MC0_STATUS" },
+	{ 0x402, "IA32_MC0_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_MC3_CTL" },
+	{ 0x40d, "IA32_MC3_STATUS" },
+	{ 0x40e, "IA32_MC3_ADDR" },
+	{ 0x40f, "IA32_MC3_MISC" },
+	{ 0x410, "IA32_MC4_CTL" },
+	{ 0x411, "IA32_MC4_STATUS" },
+	{ 0x412, "IA32_MC4_ADDR" },
+	{ 0x413, "IA32_MC4_MISC" },
+};
+
+static const msr_entry_t modelf4x_per_core_msrs[] = {
+	{ 0x0010, "IA32_TIME_STAMP_COUNTER" },
+	{ 0x001b, "IA32_APIC_BASE" },
+	{ 0x003a, "IA32_FEATURE_CONTROL" },
+	{ 0x008b, "IA32_BIOS_SIGN_ID" },
+	{ 0x009b, "IA32_SMM_MONITOR_CTL" },
+	{ 0x00fe, "IA32_MTRRCAP" },
+	{ 0x0174, "IA32_SYSENTER_CS" },
+	{ 0x0175, "IA32_SYSENTER_ESP" },
+	{ 0x0176, "IA32_SYSENTER_EIP" },
+	{ 0x0179, "IA32_MCG_CAP" },
+	{ 0x017a, "IA32_MCG_STATUS" },
+	{ 0x0180, "MSR_MCG_RAX" },
+	{ 0x0181, "MSR_MCG_RBX" },
+	{ 0x0182, "MSR_MCG_RCX" },
+	{ 0x0183, "MSR_MCG_RDX" },
+	{ 0x0184, "MSR_MCG_RSI" },
+	{ 0x0185, "MSR_MCG_RDI" },
+	{ 0x0186, "MSR_MCG_RBP" },
+	{ 0x0187, "MSR_MCG_RSP" },
+	{ 0x0188, "MSR_MCG_RFLAGS" },
+	{ 0x0189, "MSR_MCG_RIP" },
+	{ 0x018a, "MSR_MCG_MISC" },
+	// 0x18b-f Reserved
+	{ 0x0190, "MSR_MCG_R8" },
+	{ 0x0191, "MSR_MCG_R9" },
+	{ 0x0192, "MSR_MCG_R10" },
+	{ 0x0193, "MSR_MCG_R11" },
+	{ 0x0194, "MSR_MCG_R12" },
+	{ 0x0195, "MSR_MCG_R13" },
+	{ 0x0196, "MSR_MCG_R14" },
+	{ 0x0197, "MSR_MCG_R15" },
+	{ 0x0198, "IA32_PERF_STATUS" },
+	{ 0x0199, "IA32_PERF_CTL" },
+	{ 0x019a, "IA32_CLOCK_MODULATION" },
+	{ 0x019b, "IA32_THERM_INTERRUPT" },
+	{ 0x01a0, "IA32_MISC_ENABLE" }, // Bit 34 is Core Specific
+	{ 0x01d7, "MSR_LER_FROM_LIP" },
+	{ 0x01d8, "MSR_LER_TO_LIP" },
+	{ 0x01d9, "MSR_DEBUGCTLA" },
+	{ 0x01da, "MSR_LASTBRANCH_TOS" },
+	{ 0x0277, "IA32_PAT" },
+	/** Virtualization
+	{ 0x480, "IA32_VMX_BASIC" },
+	  through
+	{ 0x48b, "IA32_VMX_PROCBASED_CTLS2" },
+	  Not implemented in my CPU
+	*/
+	{ 0x0600, "IA32_DS_AREA" },
+	/* 0x0680 - 0x06cf Branch Records Skipped */
+};
+
+typedef struct {
+	unsigned int model;
+	const msr_entry_t *global_msrs;
+	unsigned int num_global_msrs;
+	const msr_entry_t *per_core_msrs;
+	unsigned int num_per_core_msrs;
+} cpu_t;
+
+cpu_t cpulist[] = {
+        { 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) },
+	{ 0x006f0, model6fx_global_msrs, ARRAY_SIZE(model6fx_global_msrs), model6fx_per_core_msrs, ARRAY_SIZE(model6fx_per_core_msrs) },
+	{ 0x00f40, modelf4x_global_msrs, ARRAY_SIZE(modelf4x_global_msrs), modelf4x_per_core_msrs, ARRAY_SIZE(modelf4x_per_core_msrs) },
+        { 0x10670, model6fx_global_msrs, ARRAY_SIZE(model6fx_global_msrs), model6fx_per_core_msrs, ARRAY_SIZE(model6fx_per_core_msrs) },
+};
+
+
 int fd_msr;
+int msr_available = 0;
 
+unsigned int cpu_features(unsigned int function, uint32_t *reg_eax, uint32_t *reg_ebx, uint32_t *reg_ecx, uint32_t *reg_edx)
+{
+    unsigned int a = 0, b = 0, c = 0, d = 0;
+    if ((function == 0x01) || (function == 0x00)) {
+        if (reg_eax != NULL)  a = *reg_eax;
+        if (reg_ebx != NULL)  b = *reg_ebx;
+        if (reg_ecx != NULL)  c = *reg_ecx;
+        if (reg_edx != NULL)  d = *reg_edx;
+        asm volatile ("cpuid" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (function));
+        if (reg_eax!=NULL) *reg_eax = a;
+        if (reg_ebx!=NULL) *reg_ebx = b;
+        if (reg_ecx!=NULL) *reg_ecx = c;
+        if (reg_edx!=NULL) *reg_edx = d;
+    }
+    return 0;
+}
+
 unsigned int cpuid(unsigned int op)
 {
 	uint32_t ret;
@@ -81,384 +665,119 @@ 
 }
 #endif
 
+int get_cpu_vendor_id(void) {
+	unsigned int i = 0, ret = 0;
+	uint32_t reg_eax = 0, reg_ebx = 0, reg_ecx = 0, reg_edx = 0;
+	
+	cpu_features(0, &reg_eax, &reg_ebx, &reg_ecx, &reg_edx);
+	for (i = 0; i < ARRAY_SIZE(cpu_vendors); i++) {
+                if((cpu_vendors[i].reg_ebx == reg_ebx) && (cpu_vendors[i].reg_edx == reg_edx) && (cpu_vendors[i].reg_ecx == reg_ecx)) {
+			ret = cpu_vendors[i].vendor_id;
+			break;
+		}
+	}
+	return ret;
+}
+
+char* get_cpu_vendor_string(unsigned int cpu_vendor_id) {
+	unsigned int i = 0;
+	char *ret = NULL;
+	
+	for (i = 0; i < ARRAY_SIZE(cpu_vendors); i++) {
+                if((cpu_vendors[i].vendor_id == cpu_vendor_id)) {
+			ret = cpu_vendors[i].name;
+			break;
+		}
+	}
+	return ret;
+}
+
+int print_cpu_info(void)
+{
+        unsigned int i, id, cpu_vendor_id = 0;
+        uint32_t reg_eax = 0, reg_ebx = 0, reg_ecx = 0, reg_edx = 0;
+	uint32_t u_rev = 0;
+	msr_t msr;
+        cpu_info_t cpu;
+        
+        id = cpuid(1) & 0xfffff0;
+	for (i = 0; i < ARRAY_SIZE(cpuid_table); i++) {
+                if(cpuid_table[i].model == id) {
+			cpu.model = &cpuid_table[i];
+			break;
+		}
+	}
+        
+        id = cpuid(1);
+        cpu_features(1, &reg_eax, &reg_ebx, &reg_ecx, &reg_edx);
+	if ((1 << intel_features_edx[5].feature_bit) & reg_edx) msr_available = 1;
+	cpu_vendor_id = get_cpu_vendor_id();
+	
+        printf("\n===================== CPU INFORMATION =====================\n\n");
+	printf("CPU Vendor: %s\n", get_cpu_vendor_string(cpu_vendor_id));
+	printf("CPU Model: 0x%06X\n", cpu.model->model);
+	printf("CPU Name: %s\n", cpu.model->name);
+        printf("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));
+        
+	if (msr_available) {
+		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");
+		    return -1;
+		}
+		msr = rdmsr(INTEL_UCODE_REV);
+		u_rev = msr.hi;
+		printf("Microcode version: 0x%016x\n", u_rev);
+		close(fd_msr);
+	}
+        // Call 0x01 CPUID function
+        printf("\n FEATURES TABLE\n\n");
+        printf("  feature  | description \n");
+        printf("-----------------------\n");
+	switch (cpu_vendor_id) {
+		case CPU_VENDOR_ID_INTEL:
+		    for (i = 0; i < ARRAY_SIZE(intel_features_edx); i++) {
+			if ((1 << intel_features_edx[i].feature_bit) & reg_edx) {
+			    printf("%10s | %s\n", intel_features_edx[i].name, intel_features_edx[i].description);
+			}
+		    }
+		    for (i = 0; i < ARRAY_SIZE(intel_features_ecx); i++) {
+			if ((1 << intel_features_ecx[i].feature_bit) & reg_ecx) {
+			    printf("%10s | %s\n", intel_features_ecx[i].name, intel_features_ecx[i].description);
+			}
+		    }
+		    break;
+		case CPU_VENDOR_ID_AMD:
+		    for (i = 0; i < ARRAY_SIZE(amd_features_edx); i++) {
+			if ((1 << amd_features_edx[i].feature_bit) & reg_edx) {
+			    printf("%10s | %s\n", amd_features_edx[i].name, amd_features_edx[i].description);
+			}
+		    }
+		    for (i = 0; i < ARRAY_SIZE(amd_features_ecx); i++) {
+			if ((1 << amd_features_ecx[i].feature_bit) & reg_ecx) {
+			    printf("%10s | %s\n", amd_features_ecx[i].name, amd_features_ecx[i].description);
+			}
+		    }
+		    break;
+		case CPU_VENDOR_ID_NVIDIA:
+		case CPU_VENDOR_ID_CYRIX:
+		case CPU_VENDOR_ID_TRANSMETA:
+		case CPU_VENDOR_ID_SIS:
+		case CPU_VENDOR_ID_VIA:
+		default:
+			printf("Features recognition on this CPU not yet supported!\n");
+		}
+        
+        return 0;
+}
+
 int print_intel_core_msrs(void)
 {
 	unsigned int i, core, id;
 	msr_t msr;
-
-#define IA32_PLATFORM_ID		0x0017
-#define EBL_CR_POWERON			0x002a
-#define FSB_CLK_STS			0x00cd
-#define IA32_TIME_STAMP_COUNTER		0x0010
-#define IA32_APIC_BASE			0x001b
-
-	typedef struct {
-		int number;
-		char *name;
-	} msr_entry_t;
-
-	static const msr_entry_t model6bx_global_msrs[] = {
-		{ 0x0010, "IA32_TIME_STAMP_COUNTER" },
-		{ 0x0017, "IA32_PLATFORM_ID" },
-		{ 0x001b, "IA32_APIC_BASE" },
-		{ 0x002a, "EBL_CR_POWERON" },
-		{ 0x0033, "TEST_CTL" },
-		{ 0x003f, "THERM_DIODE_OFFSET" },
-		//{ 0x0079, "IA32_BIOS_UPDT_TRIG" }, // Seems to be RO
-		{ 0x008b, "IA32_BIOS_SIGN_ID" },
-		{ 0x00c1, "PERFCTR0" },
-		{ 0x00c2, "PERFCTR1" },
-		{ 0x011e, "BBL_CR_CTL3" },
-		{ 0x0179, "IA32_MCG_CAP" },
-		{ 0x017a, "IA32_MCG_STATUS" },
-		{ 0x0198, "IA32_PERF_STATUS" },
-		{ 0x0199, "IA32_PERF_CONTROL" },
-		{ 0x019a, "IA32_CLOCK_MODULATION" },
-		{ 0x01a0, "IA32_MISC_ENABLES" },
-		{ 0x01d9, "IA32_DEBUGCTL" },
-		{ 0x0200, "IA32_MTRR_PHYSBASE0" },
-		{ 0x0201, "IA32_MTRR_PHYSMASK0" },
-		{ 0x0202, "IA32_MTRR_PHYSBASE1" },
-		{ 0x0203, "IA32_MTRR_PHYSMASK1" },
-		{ 0x0204, "IA32_MTRR_PHYSBASE2" },
-		{ 0x0205, "IA32_MTRR_PHYSMASK2" },
-		{ 0x0206, "IA32_MTRR_PHYSBASE3" },
-		{ 0x0207, "IA32_MTRR_PHYSMASK3" },
-		{ 0x0208, "IA32_MTRR_PHYSBASE4" },
-		{ 0x0209, "IA32_MTRR_PHYSMASK4" },
-		{ 0x020a, "IA32_MTRR_PHYSBASE5" },
-		{ 0x020b, "IA32_MTRR_PHYSMASK5" },
-		{ 0x020c, "IA32_MTRR_PHYSBASE6" },
-		{ 0x020d, "IA32_MTRR_PHYSMASK6" },
-		{ 0x020e, "IA32_MTRR_PHYSBASE7" },
-		{ 0x020f, "IA32_MTRR_PHYSMASK7" },
-		{ 0x0250, "IA32_MTRR_FIX64K_00000" },
-		{ 0x0258, "IA32_MTRR_FIX16K_80000" },
-		{ 0x0259, "IA32_MTRR_FIX16K_A0000" },
-		{ 0x0268, "IA32_MTRR_FIX4K_C0000" },
-		{ 0x0269, "IA32_MTRR_FIX4K_C8000" },
-		{ 0x026a, "IA32_MTRR_FIX4K_D0000" },
-		{ 0x026b, "IA32_MTRR_FIX4K_D8000" },
-		{ 0x026c, "IA32_MTRR_FIX4K_E0000" },
-		{ 0x026d, "IA32_MTRR_FIX4K_E8000" },
-		{ 0x026e, "IA32_MTRR_FIX4K_F0000" },
-		{ 0x026f, "IA32_MTRR_FIX4K_F8000" },
-		{ 0x02ff, "IA32_MTRR_DEF_TYPE" },
-		{ 0x0400, "IA32_MC0_CTL" },
-		{ 0x0401, "IA32_MC0_STATUS" },
-		{ 0x0402, "IA32_MC0_ADDR" },
-		//{ 0x0403, "IA32_MC0_MISC" }, // Seems to be RO
-		{ 0x040c, "IA32_MC4_CTL" },
-		{ 0x040d, "IA32_MC4_STATUS" },
-		{ 0x040e, "IA32_MC4_ADDR" },
-		//{ 0x040f, "IA32_MC4_MISC" } // Seems to be RO
-	};
-
-	static const msr_entry_t model6ex_global_msrs[] = {
-		{ 0x0017, "IA32_PLATFORM_ID" },
-		{ 0x002a, "EBL_CR_POWERON" },
-		{ 0x00cd, "FSB_CLOCK_STS" },
-		{ 0x00ce, "FSB_CLOCK_VCC" },
-		{ 0x00e2, "CLOCK_CST_CONFIG_CONTROL" },
-		{ 0x00e3, "PMG_IO_BASE_ADDR" },
-		{ 0x00e4, "PMG_IO_CAPTURE_ADDR" },
-		{ 0x00ee, "EXT_CONFIG" },
-		{ 0x011e, "BBL_CR_CTL3" },
-		{ 0x0194, "CLOCK_FLEX_MAX" },
-		{ 0x0198, "IA32_PERF_STATUS" },
-		{ 0x01a0, "IA32_MISC_ENABLES" },
-		{ 0x01aa, "PIC_SENS_CFG" },
-		{ 0x0400, "IA32_MC0_CTL" },
-		{ 0x0401, "IA32_MC0_STATUS" },
-		{ 0x0402, "IA32_MC0_ADDR" },
-		//{ 0x0403, "IA32_MC0_MISC" }, // Seems to be RO
-		{ 0x040c, "IA32_MC4_CTL" },
-		{ 0x040d, "IA32_MC4_STATUS" },
-		{ 0x040e, "IA32_MC4_ADDR" },
-		//{ 0x040f, "IA32_MC4_MISC" } // Seems to be RO
-	};
-
-	static const msr_entry_t model6ex_per_core_msrs[] = {
-		{ 0x0010, "IA32_TIME_STAMP_COUNTER" },
-		{ 0x001b, "IA32_APIC_BASE" },
-		{ 0x003a, "IA32_FEATURE_CONTROL" },
-		{ 0x003f, "IA32_TEMPERATURE_OFFSET" },
-		//{ 0x0079, "IA32_BIOS_UPDT_TRIG" }, // Seems to be RO
-		{ 0x008b, "IA32_BIOS_SIGN_ID" },
-		{ 0x00e7, "IA32_MPERF" },
-		{ 0x00e8, "IA32_APERF" },
-		{ 0x00fe, "IA32_MTRRCAP" },
-		{ 0x015f, "DTS_CAL_CTRL" },
-		{ 0x0179, "IA32_MCG_CAP" },
-		{ 0x017a, "IA32_MCG_STATUS" },
-		{ 0x0199, "IA32_PERF_CONTROL" },
-		{ 0x019a, "IA32_CLOCK_MODULATION" },
-		{ 0x019b, "IA32_THERM_INTERRUPT" },
-		{ 0x019c, "IA32_THERM_STATUS" },
-		{ 0x019d, "GV_THERM" },
-		{ 0x01d9, "IA32_DEBUGCTL" },
-		{ 0x0200, "IA32_MTRR_PHYSBASE0" },
-		{ 0x0201, "IA32_MTRR_PHYSMASK0" },
-		{ 0x0202, "IA32_MTRR_PHYSBASE1" },
-		{ 0x0203, "IA32_MTRR_PHYSMASK1" },
-		{ 0x0204, "IA32_MTRR_PHYSBASE2" },
-		{ 0x0205, "IA32_MTRR_PHYSMASK2" },
-		{ 0x0206, "IA32_MTRR_PHYSBASE3" },
-		{ 0x0207, "IA32_MTRR_PHYSMASK3" },
-		{ 0x0208, "IA32_MTRR_PHYSBASE4" },
-		{ 0x0209, "IA32_MTRR_PHYSMASK4" },
-		{ 0x020a, "IA32_MTRR_PHYSBASE5" },
-		{ 0x020b, "IA32_MTRR_PHYSMASK5" },
-		{ 0x020c, "IA32_MTRR_PHYSBASE6" },
-		{ 0x020d, "IA32_MTRR_PHYSMASK6" },
-		{ 0x020e, "IA32_MTRR_PHYSBASE7" },
-		{ 0x020f, "IA32_MTRR_PHYSMASK7" },
-		{ 0x0250, "IA32_MTRR_FIX64K_00000" },
-		{ 0x0258, "IA32_MTRR_FIX16K_80000" },
-		{ 0x0259, "IA32_MTRR_FIX16K_A0000" },
-		{ 0x0268, "IA32_MTRR_FIX4K_C0000" },
-		{ 0x0269, "IA32_MTRR_FIX4K_C8000" },
-		{ 0x026a, "IA32_MTRR_FIX4K_D0000" },
-		{ 0x026b, "IA32_MTRR_FIX4K_D8000" },
-		{ 0x026c, "IA32_MTRR_FIX4K_E0000" },
-		{ 0x026d, "IA32_MTRR_FIX4K_E8000" },
-		{ 0x026e, "IA32_MTRR_FIX4K_F0000" },
-		{ 0x026f, "IA32_MTRR_FIX4K_F8000" },
-		{ 0x02ff, "IA32_MTRR_DEF_TYPE" },
-		//{ 0x00c000080, "IA32_CR_EFER" }, // Seems to be RO
-	};
-
-	static const msr_entry_t model6fx_global_msrs[] = {
-		{ 0x0017, "IA32_PLATFORM_ID" },
-		{ 0x002a, "EBL_CR_POWERON" },
-		{ 0x003f, "IA32_TEMPERATURE_OFFSET" },
-		{ 0x00a8, "EMTTM_CR_TABLE0" },
-		{ 0x00a9, "EMTTM_CR_TABLE1" },
-		{ 0x00aa, "EMTTM_CR_TABLE2" },
-		{ 0x00ab, "EMTTM_CR_TABLE3" },
-		{ 0x00ac, "EMTTM_CR_TABLE4" },
-		{ 0x00ad, "EMTTM_CR_TABLE5" },
-		{ 0x00cd, "FSB_CLOCK_STS" },
-		{ 0x00e2, "PMG_CST_CONFIG_CONTROL" },
-		{ 0x00e3, "PMG_IO_BASE_ADDR" },
-		{ 0x00e4, "PMG_IO_CAPTURE_ADDR" },
-		{ 0x00ee, "EXT_CONFIG" },
-		{ 0x011e, "BBL_CR_CTL3" },
-		{ 0x0194, "CLOCK_FLEX_MAX" },
-		{ 0x0198, "IA32_PERF_STATUS" },
-		{ 0x01a0, "IA32_MISC_ENABLES" },
-		{ 0x01aa, "PIC_SENS_CFG" },
-		{ 0x0400, "IA32_MC0_CTL" },
-		{ 0x0401, "IA32_MC0_STATUS" },
-		{ 0x0402, "IA32_MC0_ADDR" },
-		//{ 0x0403, "IA32_MC0_MISC" }, // Seems to be RO
-		{ 0x040c, "IA32_MC4_CTL" },
-		{ 0x040d, "IA32_MC4_STATUS" },
-		{ 0x040e, "IA32_MC4_ADDR" },
-		//{ 0x040f, "IA32_MC4_MISC" } // Seems to be RO
-	};
-
-	static const msr_entry_t model6fx_per_core_msrs[] = {
-		{ 0x0010, "IA32_TIME_STAMP_COUNTER" },
-		{ 0x001b, "IA32_APIC_BASE" },
-		{ 0x003a, "IA32_FEATURE_CONTROL" },
-		//{ 0x0079, "IA32_BIOS_UPDT_TRIG" }, // Seems to be RO
-		{ 0x008b, "IA32_BIOS_SIGN_ID" },
-		{ 0x00e1, "SMM_CST_MISC_INFO" },
-		{ 0x00e7, "IA32_MPERF" },
-		{ 0x00e8, "IA32_APERF" },
-		{ 0x00fe, "IA32_MTRRCAP" },
-		{ 0x0179, "IA32_MCG_CAP" },
-		{ 0x017a, "IA32_MCG_STATUS" },
-		{ 0x0199, "IA32_PERF_CONTROL" },
-		{ 0x019a, "IA32_THERM_CTL" },
-		{ 0x019b, "IA32_THERM_INTERRUPT" },
-		{ 0x019c, "IA32_THERM_STATUS" },
-		{ 0x019d, "MSR_THERM2_CTL" },
-		{ 0x01d9, "IA32_DEBUGCTL" },
-		{ 0x0200, "IA32_MTRR_PHYSBASE0" },
-		{ 0x0201, "IA32_MTRR_PHYSMASK0" },
-		{ 0x0202, "IA32_MTRR_PHYSBASE1" },
-		{ 0x0203, "IA32_MTRR_PHYSMASK1" },
-		{ 0x0204, "IA32_MTRR_PHYSBASE2" },
-		{ 0x0205, "IA32_MTRR_PHYSMASK2" },
-		{ 0x0206, "IA32_MTRR_PHYSBASE3" },
-		{ 0x0207, "IA32_MTRR_PHYSMASK3" },
-		{ 0x0208, "IA32_MTRR_PHYSBASE4" },
-		{ 0x0209, "IA32_MTRR_PHYSMASK4" },
-		{ 0x020a, "IA32_MTRR_PHYSBASE5" },
-		{ 0x020b, "IA32_MTRR_PHYSMASK5" },
-		{ 0x020c, "IA32_MTRR_PHYSBASE6" },
-		{ 0x020d, "IA32_MTRR_PHYSMASK6" },
-		{ 0x020e, "IA32_MTRR_PHYSBASE7" },
-		{ 0x020f, "IA32_MTRR_PHYSMASK7" },
-		{ 0x0250, "IA32_MTRR_FIX64K_00000" },
-		{ 0x0258, "IA32_MTRR_FIX16K_80000" },
-		{ 0x0259, "IA32_MTRR_FIX16K_A0000" },
-		{ 0x0268, "IA32_MTRR_FIX4K_C0000" },
-		{ 0x0269, "IA32_MTRR_FIX4K_C8000" },
-		{ 0x026a, "IA32_MTRR_FIX4K_D0000" },
-		{ 0x026b, "IA32_MTRR_FIX4K_D8000" },
-		{ 0x026c, "IA32_MTRR_FIX4K_E0000" },
-		{ 0x026d, "IA32_MTRR_FIX4K_E8000" },
-		{ 0x026e, "IA32_MTRR_FIX4K_F0000" },
-		{ 0x026f, "IA32_MTRR_FIX4K_F8000" },
-		{ 0x02ff, "IA32_MTRR_DEF_TYPE" },
-		//{ 0x00c000080, "IA32_CR_EFER" }, // Seems to be RO
-	};
-
-	/* Pentium 4 and XEON */
-	/*
-	 * All MSRs per
-	 *
-	 * Intel® 64 and IA-32 Architectures
-	 * Software Developer.s Manual
-	 * Volume 3B:
-	 * System Programming Guide, Part 2
-	 *
-	 * Table B-5
-	 */
-	static const msr_entry_t modelf4x_global_msrs[] = {
-		{ 0x0000, "IA32_P5_MC_ADDR" },
-		{ 0x0001, "IA32_P5_MC_TYPE" },
-		{ 0x0006, "IA32_MONITOR_FILTER_LINE_SIZE" },
-		{ 0x0017, "IA32_PLATFORM_ID" },
-		{ 0x002a, "MSR_EBC_HARD_POWERON" },
-		{ 0x002b, "MSR_EBC_SOFT_POWRON" },
-		{ 0x002c, "MSR_EBC_FREQUENCY_ID" },
-// WRITE ONLY	{ 0x0079, "IA32_BIOS_UPDT_TRIG" },
-		{ 0x019c, "IA32_THERM_STATUS" },
-		{ 0x019d, "MSR_THERM2_CTL" },
-		{ 0x01a0, "IA32_MISC_ENABLE" },
-		{ 0x01a1, "MSR_PLATFORM_BRV" },
-		{ 0x0200, "IA32_MTRR_PHYSBASE0" },
-		{ 0x0201, "IA32_MTRR_PHYSMASK0" },
-		{ 0x0202, "IA32_MTRR_PHYSBASE1" },
-		{ 0x0203, "IA32_MTRR_PHYSMASK1" },
-		{ 0x0204, "IA32_MTRR_PHYSBASE2" },
-		{ 0x0205, "IA32_MTRR_PHYSMASK2" },
-		{ 0x0206, "IA32_MTRR_PHYSBASE3" },
-		{ 0x0207, "IA32_MTRR_PHYSMASK3" },
-		{ 0x0208, "IA32_MTRR_PHYSBASE4" },
-		{ 0x0209, "IA32_MTRR_PHYSMASK4" },
-		{ 0x020a, "IA32_MTRR_PHYSBASE5" },
-		{ 0x020b, "IA32_MTRR_PHYSMASK5" },
-		{ 0x020c, "IA32_MTRR_PHYSBASE6" },
-		{ 0x020d, "IA32_MTRR_PHYSMASK6" },
-		{ 0x020e, "IA32_MTRR_PHYSBASE7" },
-		{ 0x020f, "IA32_MTRR_PHYSMASK7" },
-		{ 0x0250, "IA32_MTRR_FIX64K_00000" },
-		{ 0x0258, "IA32_MTRR_FIX16K_80000" },
-		{ 0x0259, "IA32_MTRR_FIX16K_A0000" },
-		{ 0x0268, "IA32_MTRR_FIX4K_C0000" },
-		{ 0x0269, "IA32_MTRR_FIX4K_C8000" },
-		{ 0x026a, "IA32_MTRR_FIX4K_D0000" },
-		{ 0x026b, "IA32_MTRR_FIX4K_D8000" },
-		{ 0x026c, "IA32_MTRR_FIX4K_E0000" },
-		{ 0x026d, "IA32_MTRR_FIX4K_E8000" },
-		{ 0x026e, "IA32_MTRR_FIX4K_F0000" },
-		{ 0x026f, "IA32_MTRR_FIX4K_F8000" },
-		{ 0x02ff, "IA32_MTRR_DEF_TYPE" },
-		{ 0x0300, "MSR_BPU_COUNTER0" },
-		{ 0x0301, "MSR_BPU_COUNTER1" },
-		{ 0x0302, "MSR_BPU_COUNTER2" },
-		{ 0x0303, "MSR_BPU_COUNTER3" },
-		/* Skipped through 0x3ff  for now*/
-
-	/* All MCX_ADDR AND MCX_MISC MSRs depend on a bit being
-	 * set in MCX_STATUS */
-		{ 0x400, "IA32_MC0_CTL" },
-		{ 0x401, "IA32_MC0_STATUS" },
-		{ 0x402, "IA32_MC0_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_MC3_CTL" },
-		{ 0x40d, "IA32_MC3_STATUS" },
-		{ 0x40e, "IA32_MC3_ADDR" },
-		{ 0x40f, "IA32_MC3_MISC" },
-		{ 0x410, "IA32_MC4_CTL" },
-		{ 0x411, "IA32_MC4_STATUS" },
-		{ 0x412, "IA32_MC4_ADDR" },
-		{ 0x413, "IA32_MC4_MISC" },
-	};
-
-	static const msr_entry_t modelf4x_per_core_msrs[] = {
-		{ 0x0010, "IA32_TIME_STAMP_COUNTER" },
-		{ 0x001b, "IA32_APIC_BASE" },
-		{ 0x003a, "IA32_FEATURE_CONTROL" },
-		{ 0x008b, "IA32_BIOS_SIGN_ID" },
-		{ 0x009b, "IA32_SMM_MONITOR_CTL" },
-		{ 0x00fe, "IA32_MTRRCAP" },
-		{ 0x0174, "IA32_SYSENTER_CS" },
-		{ 0x0175, "IA32_SYSENTER_ESP" },
-		{ 0x0176, "IA32_SYSENTER_EIP" },
-		{ 0x0179, "IA32_MCG_CAP" },
-		{ 0x017a, "IA32_MCG_STATUS" },
-		{ 0x0180, "MSR_MCG_RAX" },
-		{ 0x0181, "MSR_MCG_RBX" },
-		{ 0x0182, "MSR_MCG_RCX" },
-		{ 0x0183, "MSR_MCG_RDX" },
-		{ 0x0184, "MSR_MCG_RSI" },
-		{ 0x0185, "MSR_MCG_RDI" },
-		{ 0x0186, "MSR_MCG_RBP" },
-		{ 0x0187, "MSR_MCG_RSP" },
-		{ 0x0188, "MSR_MCG_RFLAGS" },
-		{ 0x0189, "MSR_MCG_RIP" },
-		{ 0x018a, "MSR_MCG_MISC" },
-		// 0x18b-f Reserved
-		{ 0x0190, "MSR_MCG_R8" },
-		{ 0x0191, "MSR_MCG_R9" },
-		{ 0x0192, "MSR_MCG_R10" },
-		{ 0x0193, "MSR_MCG_R11" },
-		{ 0x0194, "MSR_MCG_R12" },
-		{ 0x0195, "MSR_MCG_R13" },
-		{ 0x0196, "MSR_MCG_R14" },
-		{ 0x0197, "MSR_MCG_R15" },
-		{ 0x0198, "IA32_PERF_STATUS" },
-		{ 0x0199, "IA32_PERF_CTL" },
-		{ 0x019a, "IA32_CLOCK_MODULATION" },
-		{ 0x019b, "IA32_THERM_INTERRUPT" },
-		{ 0x01a0, "IA32_MISC_ENABLE" }, // Bit 34 is Core Specific
-		{ 0x01d7, "MSR_LER_FROM_LIP" },
-		{ 0x01d8, "MSR_LER_TO_LIP" },
-		{ 0x01d9, "MSR_DEBUGCTLA" },
-		{ 0x01da, "MSR_LASTBRANCH_TOS" },
-		{ 0x0277, "IA32_PAT" },
-		/** Virtualization
-		{ 0x480, "IA32_VMX_BASIC" },
-		  through
-		{ 0x48b, "IA32_VMX_PROCBASED_CTLS2" },
-		  Not implemented in my CPU
-		*/
-		{ 0x0600, "IA32_DS_AREA" },
-		/* 0x0680 - 0x06cf Branch Records Skipped */
-
-	};
-
-
-
-	typedef struct {
-		unsigned int model;
-		const msr_entry_t *global_msrs;
-		unsigned int num_global_msrs;
-		const msr_entry_t *per_core_msrs;
-		unsigned int num_per_core_msrs;
-	} cpu_t;
-
-	cpu_t cpulist[] = {
-		{ 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) },
-		{ 0x006f0, model6fx_global_msrs, ARRAY_SIZE(model6fx_global_msrs), model6fx_per_core_msrs, ARRAY_SIZE(model6fx_per_core_msrs) },
-		{ 0x00f40, modelf4x_global_msrs, ARRAY_SIZE(modelf4x_global_msrs), modelf4x_per_core_msrs, ARRAY_SIZE(modelf4x_per_core_msrs) },
-	};
-
 	cpu_t *cpu = NULL;
 
 	/* Get CPU family and model, not the stepping
Index: inteltool.c
===================================================================
--- inteltool.c	(revision 5721)
+++ inteltool.c	(working copy)
@@ -26,9 +26,23 @@ 
 #include "inteltool.h"
 
 static const struct {
+	uint16_t vendor_id;
+	char *name;
+} supported_vendor_list[] = {
+    { PCI_VENDOR_ID_INTEL, "Intel" },
+    { PCI_VENDOR_ID_VIA, "VIA" },
+    { PCI_VENDOR_ID_SIS, "SIS" },
+    { PCI_VENDOR_ID_ATI_AMD, "ATI/AMD" },
+    { PCI_VENDOR_ID_AMD, "AMD" },
+    { PCI_VENDOR_ID_NVIDIA, "NVIDIA" },
+};
+
+static const struct {
 	uint16_t vendor_id, device_id;
 	char *name;
 } supported_chips_list[] = {
+	/* INTEL CHIPSETS */
+    
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443LX, "82443LX" },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX, "82443BX" },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_NO_AGP, "82443BX without AGP" },
@@ -74,6 +88,9 @@ 
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH0, "ICH0" },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH, "ICH" },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371XX, "82371AB/EB/MB" },
+	
+	/* VIA CHIPSETS */
+	
 };
 
 #ifndef __DARWIN__
@@ -129,6 +146,7 @@ 
 	     "   -e | --epbar:                     dump northbridge EPBAR registers\n"
 	     "   -d | --dmibar:                    dump northbridge DMIBAR registers\n"
 	     "   -P | --pciexpress:                dump northbridge PCIEXBAR registers\n\n"
+             "   -c | --cpuinfo:                   dump advanced CPU information\n"
 	     "   -M | --msrs:                      dump CPU MSRs\n"
 	     "   -a | --all:                       dump all known registers\n"
 	     "\n");
@@ -140,13 +158,11 @@ 
 	struct pci_access *pacc;
 	struct pci_dev *sb = NULL, *nb, *dev;
 	int i, opt, option_index = 0;
-	unsigned int id;
 
-	char *sbname = "unknown", *nbname = "unknown";
-
+	char *sbname = "unknown", *nbname = "unknown", *nbvendor = "unknown", *sbvendor = "unknown";
 	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 dump_pciexbar = 0, dump_cpuinfo = 0, dump_coremsrs = 0;
 
 	static struct option long_options[] = {
 		{"version", 0, 0, 'v'},
@@ -158,12 +174,13 @@ 
 		{"epbar", 0, 0, 'e'},
 		{"dmibar", 0, 0, 'd'},
 		{"pciexpress", 0, 0, 'P'},
+                {"cpuinfo", 0, 0, 'c'},
 		{"msrs", 0, 0, 'M'},
 		{"all", 0, 0, 'a'},
 		{0, 0, 0, 0}
 	};
 
-	while ((opt = getopt_long(argc, argv, "vh?grpmedPMa",
+	while ((opt = getopt_long(argc, argv, "vh?grpmedPcMa",
                                   long_options, &option_index)) != EOF) {
 		switch (opt) {
 		case 'v':
@@ -191,6 +208,9 @@ 
 		case 'P':
 			dump_pciexbar = 1;
 			break;
+                case 'c':
+			dump_cpuinfo = 1;
+			break;
 		case 'M':
 			dump_coremsrs = 1;
 			break;
@@ -202,6 +222,7 @@ 
 			dump_epbar = 1;
 			dump_dmibar = 1;
 			dump_pciexbar = 1;
+                        dump_cpuinfo = 1;
 			dump_coremsrs = 1;
 			break;
 		case 'h':
@@ -251,9 +272,27 @@ 
 
 	pci_fill_info(sb, PCI_FILL_IDENT|PCI_FILL_BASES|PCI_FILL_SIZES|PCI_FILL_CLASS);
 
-	if (sb->vendor_id != PCI_VENDOR_ID_INTEL) {
-		printf("Not an Intel(R) southbridge.\n");
-		exit(1);
+	switch (sb->vendor_id) {
+		case PCI_VENDOR_ID_INTEL:
+		    break;
+		case PCI_VENDOR_ID_VIA:
+		    printf("VIA southbridges not yet supported.\n");
+		    exit(1);
+		case PCI_VENDOR_ID_SIS:
+		    printf("SiS southbridges not yet supported.\n");
+		    exit(1);
+		case PCI_VENDOR_ID_NVIDIA:
+		    printf("NVIDIA southbridges not yet supported.\n");
+		    exit(1);
+		case PCI_VENDOR_ID_ATI_AMD:
+		    printf("ATI/AMD southbridges not yet supported.\n");
+		    exit(1);
+		case PCI_VENDOR_ID_AMD:
+		    printf("AMD southbridges not yet supported.\n");
+		    exit(1);
+		default:
+		    printf("Unknown southbridges not yet supported.\n");
+		    exit(1);
 	}
 
 	nb = pci_get_dev(pacc, 0, 0, 0x00, 0);
@@ -264,24 +303,36 @@ 
 
 	pci_fill_info(nb, PCI_FILL_IDENT|PCI_FILL_BASES|PCI_FILL_SIZES|PCI_FILL_CLASS);
 
-	if (nb->vendor_id != PCI_VENDOR_ID_INTEL) {
-		printf("Not an Intel(R) northbridge.\n");
-		exit(1);
+	switch (nb->vendor_id) {
+		case PCI_VENDOR_ID_INTEL:
+		    break;
+		case PCI_VENDOR_ID_VIA:
+		    printf("VIA northbridges not yet supported.\n");
+		    exit(1);
+		case PCI_VENDOR_ID_SIS:
+		    printf("SiS northbridges not yet supported.\n");
+		    exit(1);
+		case PCI_VENDOR_ID_NVIDIA:
+		    printf("NVIDIA northbridges not yet supported.\n");
+		    exit(1);
+		case PCI_VENDOR_ID_ATI_AMD:
+		    printf("ATI/AMD northbridges not yet supported.\n");
+		    exit(1);
+		case PCI_VENDOR_ID_AMD:
+		    printf("AMD northbridges not yet supported.\n");
+		    exit(1);
+		default:
+		    printf("Unknown northbridges not yet supported.\n");
+		    exit(1);
 	}
-
-	id = cpuid(1);
-
-	/* Intel has suggested applications to display the family of a CPU as
-	 * the sum of the "Family" and the "Extended Family" fields shown
-	 * above, and the model as the sum of the "Model" and the 4-bit
-	 * 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",
-			(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_vendor_list); i++)
+		if (nb->vendor_id == supported_vendor_list[i].vendor_id)
+			nbvendor = supported_vendor_list[i].name;
+	for (i = 0; i < ARRAY_SIZE(supported_vendor_list); i++)
+		if (sb->vendor_id == supported_vendor_list[i].vendor_id)
+			sbvendor = supported_vendor_list[i].name;
 	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;
@@ -289,11 +340,11 @@ 
 		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("Northbridge: %04x:%04x | Vendor: %s | Model: %s\n",
+		nb->vendor_id, nb->device_id, nbvendor, nbname);
 
-	printf("Intel Southbridge: %04x:%04x (%s)\n",
-		sb->vendor_id, sb->device_id, sbname);
+	printf("Southbridge: %04x:%04x | Vendor: %s | Model: %s\n",
+		sb->vendor_id, sb->device_id, sbvendor, sbname);
 
 	/* Now do the deed */
 
@@ -331,6 +382,11 @@ 
 		print_pciexbar(nb);
 		printf("\n\n");
 	}
+        
+        if (dump_cpuinfo) {
+		print_cpu_info();
+		printf("\n\n");
+	}
 
 	if (dump_coremsrs) {
 		print_intel_core_msrs();