diff options
-rw-r--r-- | util/viatool/Makefile | 99 | ||||
-rw-r--r-- | util/viatool/README | 12 | ||||
-rw-r--r-- | util/viatool/cpu.c | 980 | ||||
-rw-r--r-- | util/viatool/quirks/quirks.c | 118 | ||||
-rw-r--r-- | util/viatool/quirks/quirks.h | 38 | ||||
-rw-r--r-- | util/viatool/quirks/vx900_quirks.c | 84 | ||||
-rw-r--r-- | util/viatool/viatool.c | 256 | ||||
-rw-r--r-- | util/viatool/viatool.h | 78 |
8 files changed, 1665 insertions, 0 deletions
diff --git a/util/viatool/Makefile b/util/viatool/Makefile new file mode 100644 index 0000000000..5124a73dc3 --- /dev/null +++ b/util/viatool/Makefile @@ -0,0 +1,99 @@ +# +# Makefile for viatool utility +# +# Copyright (C) 2008 by coresystems GmbH +# written by Stefan Reinauer <stepan@coresystems.de> +# Copyright (C) 2013 Alexandru Gagniuc +# +# 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; either version 2 of the License, or +# (at your option) any later version. +# +# 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. +# + +PROGRAM = viatool + +CC ?= gcc +INSTALL ?= /usr/bin/install +PREFIX ?= /usr/local +CFLAGS ?= -O2 -g -Wall -W -I$(shell pwd) +LDFLAGS += -lpci -lz + +SRCS = viatool.c \ + cpu.c \ + quirks/quirks.c \ + quirks/vx900_quirks.c + +OBJS = $(sort ${SRCS:.c=.o}) + +OS_ARCH = $(shell uname) +ifeq ($(OS_ARCH), Darwin) +LDFLAGS += -framework DirectHW +endif +ifeq ($(OS_ARCH), FreeBSD) +CFLAGS += -I/usr/local/include +LDFLAGS += -L/usr/local/lib +LIBS = -lz +endif + +all: pciutils dep $(PROGRAM) + +$(PROGRAM): $(OBJS) + $(CC) $(CFLAGS) -o $(PROGRAM) $(OBJS) $(LDFLAGS) + +clean: + # Remove build results + rm -f $(PROGRAM) $(OBJS) + # Remove backup files created by some editors + find ./ |grep *~ |xargs rm -f + +distclean: clean + rm -f .dependencies + +dep: + @$(CC) $(CFLAGS) -MM *.c > .dependencies + +define LIBPCI_TEST +/* Avoid a failing test due to libpci header symbol shadowing breakage */ +#define index shadow_workaround_index +#include <pci/pci.h> +struct pci_access *pacc; +int main(int argc, char **argv) +{ + (void) argc; + (void) argv; + pacc = pci_alloc(); + return 0; +} +endef +export LIBPCI_TEST + +pciutils: + @printf "\nChecking for pciutils and zlib... " + @echo "$$LIBPCI_TEST" > .test.c + @$(CC) $(CFLAGS) .test.c -o .test $(LDFLAGS) >/dev/null 2>&1 && \ + printf "found.\n" || ( printf "not found.\n\n"; \ + printf "Please install pciutils-devel and zlib-devel.\n"; \ + printf "See README for more information.\n\n"; \ + rm -f .test.c .test; exit 1) + @rm -rf .test.c .test .test.dSYM + +install: $(PROGRAM) + mkdir -p $(DESTDIR)$(PREFIX)/sbin + $(INSTALL) $(PROGRAM) $(DESTDIR)$(PREFIX)/sbin + mkdir -p $(DESTDIR)$(PREFIX)/share/man/man8 + $(INSTALL) $(PROGRAM).8 $(DESTDIR)$(PREFIX)/share/man/man8 + +.PHONY: all clean distclean dep pciutils + +-include .dependencies + diff --git a/util/viatool/README b/util/viatool/README new file mode 100644 index 0000000000..5a007be3db --- /dev/null +++ b/util/viatool/README @@ -0,0 +1,12 @@ +viatool is a utility for extracting useful for extracting certain configuration +bits on VIA chipsets and CPUs. It is a fork of inteltool. + +viatool is currently focused on "quirks". Quirks are device configurations that +cannot be accessed directly. They are implemented as hierarchical configurations +in the PCI or memory address spaces (index/data register pairs). Such +configurations refer to hardware parameters that are board specific. Those +parameters would otherwise be difficult to extract from a system running the +vendor's firmware. + +viatool also preserves inteltool's MSR dumps. VIA CPU and Intel CPU MSRs are +nearly identical. diff --git a/util/viatool/cpu.c b/util/viatool/cpu.c new file mode 100644 index 0000000000..4c7c9e6638 --- /dev/null +++ b/util/viatool/cpu.c @@ -0,0 +1,980 @@ +/* + * inteltool - dump all registers on an Intel CPU + chipset based system. + * + * Copyright (C) 2008-2010 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 <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "viatool.h" + +#ifdef __x86_64__ +# define BREG "%%rbx" +#else +# define BREG "%%ebx" +#endif + +int fd_msr; + +unsigned int cpuid(unsigned int op) +{ + uint32_t ret; + +#if defined(__PIC__) || defined(__DARWIN__) && !defined(__LP64__) + asm volatile ( + "push " BREG "\n\t" + "cpuid\n\t" + "pop " BREG "\n\t" + : "=a" (ret) : "a" (op) : "%ecx", "%edx" + ); +#else + asm ("cpuid" : "=a" (ret) : "a" (op) : "%ebx", "%ecx", "%edx"); +#endif + + return ret; +} + +#ifndef __DARWIN__ +int msr_readerror = 0; + +msr_t rdmsr(int addr) +{ + uint32_t buf[2]; + msr_t msr = { 0xffffffff, 0xffffffff }; + + if (lseek(fd_msr, (off_t) addr, SEEK_SET) == -1) { + perror("Could not lseek() to MSR"); + close(fd_msr); + exit(1); + } + + if (read(fd_msr, buf, 8) == 8) { + msr.lo = buf[0]; + msr.hi = buf[1]; + return msr; + } + + if (errno == 5) { + printf(" (*)"); // Not all bits of the MSR could be read + msr_readerror = 1; + } else { + // A severe error. + perror("Could not read() MSR"); + close(fd_msr); + exit(1); + } + + return msr; +} +#endif + +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; + + /* Pentium III */ + static const msr_entry_t model67x_global_msrs[] = { + { 0x0000, "IA32_P5_MC_ADDR" }, + { 0x0001, "IA32_P5_MC_TYPE" }, + { 0x0010, "IA32_TIME_STAMP_COUNTER" }, + { 0x0017, "IA32_PLATFORM_ID" }, + { 0x001b, "IA32_APIC_BASE" }, + { 0x002a, "EBL_CR_POWERON" }, + { 0x0033, "TEST_CTL" }, + //{ 0x0079, "IA32_BIOS_UPDT_TRIG" }, // Seems to be RO + { 0x0088, "BBL_CR_D0" }, + { 0x0089, "BBL_CR_D1" }, + { 0x008a, "BBL_CR_D2" }, + { 0x008b, "IA32_BIOS_SIGN_ID" }, + { 0x00c1, "PERFCTR0" }, + { 0x00c2, "PERFCTR1" }, + { 0x00fe, "IA32_MTRRCAP" }, + { 0x0116, "BBL_CR_ADDR" }, + { 0x0118, "BBL_CR_DECC" }, + { 0x0119, "BBL_CR_CTL" }, + //{ 0x011a, "BBL_CR_TRIG" }, + { 0x011b, "BBL_CR_BUSY" }, + { 0x011e, "BBL_CR_CTL3" }, + { 0x0174, "IA32_SYSENTER_CS" }, + { 0x0175, "IA32_SYSENTER_ESP" }, + { 0x0176, "IA32_SYSENTER_EIP" }, + { 0x0179, "IA32_MCG_CAP" }, + { 0x017a, "IA32_MCG_STATUS" }, + { 0x017b, "IA32_MCG_CTL" }, + { 0x0186, "IA32_PERF_EVNTSEL0" }, + { 0x0187, "IA32_PERF_EVNTSEL1" }, + { 0x01d9, "IA32_DEBUGCTL" }, + { 0x01db, "MSR_LASTBRANCHFROMIP" }, + { 0x01dc, "MSR_LASTBRANCHTOIP" }, + { 0x01dd, "MSR_LASTINTFROMIP" }, + { 0x01de, "MSR_LASTINTTOIP" }, + { 0x01e0, "MSR_ROB_CR_BKUPTMPDR6" }, + { 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 + { 0x0404, "IA32_MC1_CTL" }, + { 0x0405, "IA32_MC1_STATUS" }, + { 0x0406, "IA32_MC1_ADDR" }, + //{ 0x0407, "IA32_MC1_MISC" }, // Seems to be RO + { 0x0408, "IA32_MC2_CTL" }, + { 0x0409, "IA32_MC2_STATUS" }, + { 0x040a, "IA32_MC2_ADDR" }, + //{ 0x040b, "IA32_MC2_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 + { 0x0410, "IA32_MC3_CTL" }, + { 0x0411, "IA32_MC3_STATUS" }, + { 0x0412, "IA32_MC3_ADDR" }, + //{ 0x0413, "IA32_MC3_MISC" }, // Seems to be RO + }; + + 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, B-7 + */ + static const msr_entry_t modelf2x_global_msrs[] = { + { 0x0000, "IA32_P5_MC_ADDR" }, + { 0x0001, "IA32_P5_MC_TYPE" }, + /* 0x6: Not available in model 2. */ + { 0x0017, "IA32_PLATFORM_ID" }, + { 0x002a, "MSR_EBC_HARD_POWERON" }, + { 0x002b, "MSR_EBC_SOFT_POWRON" }, + /* 0x2c: Not available in model 2. */ +// WRITE ONLY { 0x0079, "IA32_BIOS_UPDT_TRIG" }, + { 0x019c, "IA32_THERM_STATUS" }, + /* 0x19d: Not available in model 2. */ + { 0x01a0, "IA32_MISC_ENABLE" }, + /* 0x1a1: Not available in model 2. */ + { 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" }, + { 0x0304, "MSR_MS_COUNTER0" }, + { 0x0305, "MSR_MS_COUNTER1" }, + { 0x0306, "MSR_MS_COUNTER2" }, + { 0x0307, "MSR_MS_COUNTER3" }, + { 0x0308, "MSR_FLAME_COUNTER0" }, + { 0x0309, "MSR_FLAME_COUNTER1" }, + { 0x030a, "MSR_FLAME_COUNTER2" }, + { 0x030b, "MSR_FLAME_COUNTER3" }, + { 0x030c, "MSR_IQ_COUNTER0" }, + { 0x030d, "MSR_IQ_COUNTER1" }, + { 0x030e, "MSR_IQ_COUNTER2" }, + { 0x030f, "MSR_IQ_COUNTER3" }, + { 0x0310, "MSR_IQ_COUNTER4" }, + { 0x0311, "MSR_IQ_COUNTER5" }, + { 0x0360, "MSR_BPU_CCCR0" }, + { 0x0361, "MSR_BPU_CCCR1" }, + { 0x0362, "MSR_BPU_CCCR2" }, + { 0x0363, "MSR_BPU_CCCR3" }, + { 0x0364, "MSR_MS_CCCR0" }, + { 0x0365, "MSR_MS_CCCR1" }, + { 0x0366, "MSR_MS_CCCR2" }, + { 0x0367, "MSR_MS_CCCR3" }, + { 0x0368, "MSR_FLAME_CCCR0" }, + { 0x0369, "MSR_FLAME_CCCR1" }, + { 0x036a, "MSR_FLAME_CCCR2" }, + { 0x036b, "MSR_FLAME_CCCR3" }, + { 0x036c, "MSR_IQ_CCCR0" }, + { 0x036d, "MSR_IQ_CCCR1" }, + { 0x036e, "MSR_IQ_CCCR2" }, + { 0x036f, "MSR_IQ_CCCR3" }, + { 0x0370, "MSR_IQ_CCCR4" }, + { 0x0371, "MSR_IQ_CCCR5" }, + { 0x03a0, "MSR_BSU_ESCR0" }, + { 0x03a1, "MSR_BSU_ESCR1" }, + { 0x03a2, "MSR_FSB_ESCR0" }, + { 0x03a3, "MSR_FSB_ESCR1" }, + { 0x03a4, "MSR_FIRM_ESCR0" }, + { 0x03a5, "MSR_FIRM_ESCR1" }, + { 0x03a6, "MSR_FLAME_ESCR0" }, + { 0x03a7, "MSR_FLAME_ESCR1" }, + { 0x03a8, "MSR_DAC_ESCR0" }, + { 0x03a9, "MSR_DAC_ESCR1" }, + { 0x03aa, "MSR_MOB_ESCR0" }, + { 0x03ab, "MSR_MOB_ESCR1" }, + { 0x03ac, "MSR_PMH_ESCR0" }, + { 0x03ad, "MSR_PMH_ESCR1" }, + { 0x03ae, "MSR_SAAT_ESCR0" }, + { 0x03af, "MSR_SAAT_ESCR1" }, + { 0x03b0, "MSR_U2L_ESCR0" }, + { 0x03b1, "MSR_U2L_ESCR1" }, + { 0x03b2, "MSR_BPU_ESCR0" }, + { 0x03b3, "MSR_BPU_ESCR1" }, + { 0x03b4, "MSR_IS_ESCR0" }, + { 0x03b5, "MSR_BPU_ESCR1" }, + { 0x03b6, "MSR_ITLB_ESCR0" }, + { 0x03b7, "MSR_ITLB_ESCR1" }, + { 0x03b8, "MSR_CRU_ESCR0" }, + { 0x03b9, "MSR_CRU_ESCR1" }, + { 0x03ba, "MSR_IQ_ESCR0" }, + { 0x03bb, "MSR_IQ_ESCR1" }, + { 0x03bc, "MSR_RAT_ESCR0" }, + { 0x03bd, "MSR_RAT_ESCR1" }, + { 0x03be, "MSR_SSU_ESCR0" }, + { 0x03c0, "MSR_MS_ESCR0" }, + { 0x03c1, "MSR_MS_ESCR1" }, + { 0x03c2, "MSR_TBPU_ESCR0" }, + { 0x03c3, "MSR_TBPU_ESCR1" }, + { 0x03c4, "MSR_TC_ESCR0" }, + { 0x03c5, "MSR_TC_ESCR1" }, + { 0x03c8, "MSR_IX_ESCR0" }, + { 0x03c9, "MSR_IX_ESCR1" }, + { 0x03ca, "MSR_ALF_ESCR0" }, + { 0x03cb, "MSR_ALF_ESCR1" }, + { 0x03cc, "MSR_CRU_ESCR2" }, + { 0x03cd, "MSR_CRU_ESCR3" }, + { 0x03e0, "MSR_CRU_ESCR4" }, + { 0x03e1, "MSR_CRU_ESCR5" }, + { 0x03f0, "MSR_TC_PRECISE_EVENT" }, + { 0x03f1, "MSR_PEBS_ENABLE" }, + { 0x03f2, "MSR_PEBS_MATRIX_VERT" }, + + /* + * 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 modelf2x_per_core_msrs[] = { + { 0x0010, "IA32_TIME_STAMP_COUNTER" }, + { 0x001b, "IA32_APIC_BASE" }, + /* 0x3a: Not available in model 2. */ + { 0x008b, "IA32_BIOS_SIGN_ID" }, + /* 0x9b: Not available in model 2. */ + { 0x00fe, "IA32_MTRRCAP" }, + { 0x0174, "IA32_SYSENTER_CS" }, + { 0x0175, "IA32_SYSENTER_ESP" }, + { 0x0176, "IA32_SYSENTER_EIP" }, + { 0x0179, "IA32_MCG_CAP" }, + { 0x017a, "IA32_MCG_STATUS" }, + { 0x017b, "IA32_MCG_CTL" }, + { 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-0x18f: 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" }, + /* 0x198: Not available in model 2. */ + /* 0x199: Not available in model 2. */ + { 0x019a, "IA32_CLOCK_MODULATION" }, + { 0x019b, "IA32_THERM_INTERRUPT" }, + { 0x01a0, "IA32_MISC_ENABLE" }, + { 0x01d7, "MSR_LER_FROM_LIP" }, + { 0x01d8, "MSR_LER_TO_LIP" }, + { 0x01d9, "MSR_DEBUGCTLA" }, + { 0x01da, "MSR_LASTBRANCH_TOS" }, + { 0x01db, "MSR_LASTBRANCH_0" }, + { 0x01dd, "MSR_LASTBRANCH_2" }, + { 0x01de, "MSR_LASTBRANCH_3" }, + { 0x0277, "IA32_PAT" }, + /* 0x480-0x48b : Not available in model 2. */ + { 0x0600, "IA32_DS_AREA" }, + /* 0x0680 - 0x06cf Branch Records Skipped */ + }; + + 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 */ + + }; + + /* Atom N455 + * + * This should apply to the following processors: + * 06_1CH + * 06_26H + * 06_27H + * 06_35 + * 06_36 + */ + /* + * All MSRs per + * + * Intel 64 and IA-32 Architectures Software Developer's Manual + * Volume 3C: System Programming Guide, Part 3 + * Order Number 326019 + * January 2013 + * + * Table 35-4, 35-5 + * + * For now it has only been tested with 06_1CH. + */ + static const msr_entry_t model6_atom_global_msrs[] = { + { 0x0000, "IA32_P5_MC_ADDR" }, + { 0x0001, "IA32_P5_MC_TYPE" }, + { 0x0010, "IA32_TIME_STAMP_COUNTER" }, + { 0x0017, "IA32_PLATFORM_ID" }, + { 0x002a, "MSR_EBC_HARD_POWERON" }, + { 0x00cd, "MSR_FSB_FREQ" }, + { 0x00fe, "IA32_MTRRCAP" }, + { 0x011e, "MSR_BBL_CR_CTL3" }, + { 0x0198, "IA32_PERF_STATUS" }, + { 0x019d, "MSR_THERM2_CTL" }, + { 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" }, + { 0x0345, "IA32_PERF_CAPABILITIES" }, + { 0x400, "IA32_MC0_CTL" }, + { 0x401, "IA32_MC0_STATUS" }, + { 0x402, "IA32_MC0_ADDR" }, + { 0x404, "IA32_MC1_CTL" }, + { 0x405, "IA32_MC1_STATUS" }, + { 0x408, "IA32_MC2_CTL" }, + { 0x409, "IA32_MC2_STATUS" }, + { 0x40a, "IA32_MC2_ADDR" }, + { 0x40c, "IA32_MC3_CTL" }, + { 0x40d, "IA32_MC3_STATUS" }, + { 0x40e, "IA32_MC3_ADDR" }, + { 0x410, "IA32_MC4_CTL" }, + { 0x411, "IA32_MC4_STATUS" }, + { 0x412, "IA32_MC4_ADDR" }, + /* + * Only 06_27C has the following MSRs + */ + /* + { 0x03f8, "MSR_PKG_C2_RESIDENCY" }, + { 0x03f9, "MSR_PKG_C4_RESIDENCY" }, + { 0x03fa, "MSR_PKG_C6_RESIDENCY" }, + */ + }; + + static const msr_entry_t model6_atom_per_core_msrs[] = { + { 0x0006, "IA32_MONITOR_FILTER_SIZE" }, + { 0x0010, "IA32_TIME_STAMP_COUNTER" }, + { 0x001b, "IA32_APIC_BASE" }, + { 0x003a, "IA32_FEATURE_CONTROL" }, + { 0x0040, "MSR_LASTBRANCH_0_FROM_IP" }, + { 0x0041, "MSR_LASTBRANCH_1_FROM_IP" }, + { 0x0042, "MSR_LASTBRANCH_2_FROM_IP" }, + { 0x0043, "MSR_LASTBRANCH_3_FROM_IP" }, + { 0x0044, "MSR_LASTBRANCH_4_FROM_IP" }, + { 0x0045, "MSR_LASTBRANCH_5_FROM_IP" }, + { 0x0046, "MSR_LASTBRANCH_6_FROM_IP" }, + { 0x0047, "MSR_LASTBRANCH_7_FROM_IP" }, + { 0x0060, "MSR_LASTBRANCH_0_TO_IP" }, + { 0x0061, "MSR_LASTBRANCH_1_TO_IP" }, + { 0x0062, "MSR_LASTBRANCH_2_TO_IP" }, + { 0x0063, "MSR_LASTBRANCH_3_TO_IP" }, + { 0x0064, "MSR_LASTBRANCH_4_TO_IP" }, + { 0x0065, "MSR_LASTBRANCH_5_TO_IP" }, + { 0x0066, "MSR_LASTBRANCH_6_TO_IP" }, + { 0x0067, "MSR_LASTBRANCH_7_TO_IP" }, + /* Write register */ + /* + { 0x0079, "IA32_BIOS_UPDT_TRIG" }, + */ + { 0x008b, "IA32_BIOS_SIGN_ID" }, + { 0x00c1, "IA32_PMC0" }, + { 0x00c2, "IA32_PMC1" }, + { 0x00e7, "IA32_MPERF" }, + { 0x00e8, "IA32_APERF" }, + { 0x0174, "IA32_SYSENTER_CS" }, + { 0x0175, "IA32_SYSENTER_ESP" }, + { 0x0176, "IA32_SYSENTER_EIP" }, + { 0x017a, "IA32_MCG_STATUS" }, + { 0x0186, "IA32_PERF_EVNTSEL0" }, + { 0x0187, "IA32_PERF_EVNTSEL1" }, + { 0x0199, "IA32_PERF_CONTROL" }, + { 0x019a, "IA32_CLOCK_MODULATION" }, + { 0x019b, "IA32_THERM_INTERRUPT" }, + { 0x019c, "IA32_THERM_STATUS" }, + { 0x01a0, "IA32_MISC_ENABLES" }, + { 0x01c9, "MSR_LASTBRANCH_TOS" }, + { 0x01d9, "IA32_DEBUGCTL" }, + { 0x01dd, "MSR_LER_FROM_LIP" }, + { 0x01de, "MSR_LER_TO_LIP" }, + { 0x0277, "IA32_PAT" }, + { 0x0309, "IA32_FIXED_CTR0" }, + { 0x030a, "IA32_FIXED_CTR1" }, + { 0x030b, "IA32_FIXED_CTR2" }, + { 0x038d, "IA32_FIXED_CTR_CTRL" }, + { 0x038e, "IA32_PERF_GLOBAL_STATUS" }, + { 0x038f, "IA32_PERF_GLOBAL_CTRL" }, + { 0x0390, "IA32_PERF_GLOBAL_OVF_CTRL" }, + { 0x03f1, "MSR_PEBS_ENABLE" }, + { 0x0480, "IA32_VMX_BASIC" }, + { 0x0481, "IA32_VMX_PINBASED_CTLS" }, + { 0x0482, "IA32_VMX_PROCBASED_CTLS" }, + { 0x0483, "IA32_VMX_EXIT_CTLS" }, + { 0x0484, "IA32_VMX_ENTRY_CTLS" }, + { 0x0485, "IA32_VMX_MISC" }, + { 0x0486, "IA32_VMX_CR0_FIXED0" }, + { 0x0487, "IA32_VMX_CR0_FIXED1" }, + { 0x0488, "IA32_VMX_CR4_FIXED0" }, + { 0x0489, "IA32_VMX_CR4_FIXED1" }, + { 0x048a, "IA32_VMX_VMCS_ENUM" }, + { 0x048b, "IA32_VMX_PROCBASED_CTLS2" }, + { 0x0600, "IA32_DS_AREA" }, + }; + + 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[] = { + { 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) }, + { 0x006f0, model6fx_global_msrs, ARRAY_SIZE(model6fx_global_msrs), model6fx_per_core_msrs, ARRAY_SIZE(model6fx_per_core_msrs) }, + { 0x00f20, modelf2x_global_msrs, ARRAY_SIZE(modelf2x_global_msrs), modelf2x_per_core_msrs, ARRAY_SIZE(modelf2x_per_core_msrs) }, + { 0x00f40, modelf4x_global_msrs, ARRAY_SIZE(modelf4x_global_msrs), modelf4x_per_core_msrs, ARRAY_SIZE(modelf4x_per_core_msrs) }, + { 0x106c0, model6_atom_global_msrs, ARRAY_SIZE(model6_atom_global_msrs), model6_atom_per_core_msrs, ARRAY_SIZE(model6_atom_per_core_msrs) }, + }; + + cpu_t *cpu = NULL; + + /* Get CPU family and model, not the stepping + * (TODO: extended family/model) + */ + id = cpuid(1) & 0xfffff0; + for (i = 0; i < ARRAY_SIZE(cpulist); i++) { + if(cpulist[i].model == id) { + cpu = &cpulist[i]; + break; + } + } + + if (!cpu) { + 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"); + return -1; + } +#endif + + 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); + } + + close(fd_msr); + + for (core = 0; core < 8; core++) { +#ifndef __DARWIN__ + char msrfilename[64]; + memset(msrfilename, 0, 64); + sprintf(msrfilename, "/dev/cpu/%u/msr", core); + + fd_msr = open(msrfilename, O_RDWR); + + /* If the file is not there, we're probably through. No error, + * since we successfully opened /dev/cpu/0/msr before. + */ + if (fd_msr < 0) + break; +#endif + if (cpu->num_per_core_msrs) + printf("\n====================== UNIQUE MSRs (core %u) ======================\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); + } +#ifndef __DARWIN__ + close(fd_msr); +#endif + } + +#ifndef __DARWIN__ + if (msr_readerror) + printf("\n(*) Some MSRs could not be read. The marked values are unreliable.\n"); +#endif + return 0; +} diff --git a/util/viatool/quirks/quirks.c b/util/viatool/quirks/quirks.c new file mode 100644 index 0000000000..c1bd33204f --- /dev/null +++ b/util/viatool/quirks/quirks.c @@ -0,0 +1,118 @@ +/* + * viatool - dump all registers on a VIA CPU + chipset based system. + * + * Copyright (C) 2013 Alexandru Gagniuc + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * 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 + * a long with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "quirks.h" +#include <viatool.h> +#include <stdio.h> +#include <stddef.h> + +extern struct quirk_list vx900_sb_quirk_list; + +struct quirk_list *sb_quirks[] = { + &vx900_sb_quirk_list, + 0, +}; + +struct quirk_list *nb_quirks[] = { + 0, +}; + +int print_quirks(struct pci_dev *sb, struct pci_access *pacc, + struct quirk_list **qlists); + +int print_quirks_north(struct pci_dev *nb, struct pci_access *pacc) +{ + printf("\n====== Northbridge Quirks =======\n\n"); + return print_quirks(nb, pacc, nb_quirks); +} + +int print_quirks_south(struct pci_dev *sb, struct pci_access *pacc) +{ + printf("\n====== Southbridge Quirks =======\n\n"); + return print_quirks(sb, pacc, sb_quirks); +} + +int print_quirks(struct pci_dev *sb, struct pci_access *pacc, + struct quirk_list **qlists) +{ + size_t i, j; + struct quirk *q; + struct quirk_list *qlist; + struct pci_dev *dev; + + for (i = 0; ; i++) + { + qlist = qlists[i]; + + if (qlist == NULL) { + /* OOPS. We've tried all we know, but no quirk */ + printf("No quirks supported.\n"); + break; + } + + /* Is this the right device ? */ + if ( (qlist->pci_vendor_id != sb->vendor_id) || + qlist->pci_device_id != sb->device_id) + continue; + + for (j = 0; ; j++) + { + q = &qlist->dev_quirks[j]; + + if(q->pci_device_id == 0) + break; + + printf("Probing PCI device %i:%.2x.%i\n", + q->pci_bus, q->pci_dev, q->pci_func); + + dev = pci_get_dev(pacc, q->pci_domain, q->pci_bus, + q->pci_dev, q->pci_func); + + if (!dev) { + perror("Error: no device found\n"); + continue; + } + + pci_fill_info(dev, PCI_FILL_IDENT | + PCI_FILL_BASES | + PCI_FILL_SIZES | + PCI_FILL_CLASS ); + + if (dev->device_id != q->pci_device_id) { + printf("Expected %.4x:%.4x, got %.4x:%.4x\n", + q->pci_vendor_id, q->pci_device_id, + dev->vendor_id, dev->device_id); + continue; + } + + if (!q->quirk_func) { + perror("BUG: Quirk missing.\n"); + continue; + } + + q->quirk_func(dev); + /* On to next quirk */ + } + + /* Done. No need to go through the remainder of the list */ + break; + } + + return 0; +} diff --git a/util/viatool/quirks/quirks.h b/util/viatool/quirks/quirks.h new file mode 100644 index 0000000000..a5a47915d5 --- /dev/null +++ b/util/viatool/quirks/quirks.h @@ -0,0 +1,38 @@ +/* + * viatool - dump all registers on a VIA CPU + chipset based system. + * + * Copyright (C) 2013 Alexandru Gagniuc + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * 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 + * a long with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <viatool.h> + +struct quirk { + int pci_domain; + int pci_bus; + int pci_dev; + int pci_func; + int pci_vendor_id; + int pci_device_id; + int (*quirk_func)(struct pci_dev *dev); +}; + +struct quirk_list { + int pci_vendor_id; + int pci_device_id; + /* NULL-terminated list of quirks */ + struct quirk *dev_quirks; +}; + diff --git a/util/viatool/quirks/vx900_quirks.c b/util/viatool/quirks/vx900_quirks.c new file mode 100644 index 0000000000..dffd2c82fa --- /dev/null +++ b/util/viatool/quirks/vx900_quirks.c @@ -0,0 +1,84 @@ +/* + * viatool - dump all registers on a VIA CPU + chipset based system. + * + * Copyright (C) 2013 Alexandru Gagniuc + * + * 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; either version 2 + * of the License, or (at your option) any later version. + * + * 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 + * a long with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "quirks.h" + +#include <stdio.h> + +typedef u8 sata_phy_config[64]; + +static u32 sata_phy_read32(struct pci_dev *dev, u8 index) +{ + /* The SATA PHY control registers are accessed by a funny index/value + * scheme. Each byte (0,1,2,3) has its own 4-bit index */ + index = (index >> 2) & 0xf; + u16 i16 = index | (index << 4) | (index << 8)| (index << 12); + /* The index */ + pci_write_word(dev, 0x68, i16); + /* The value */ + return pci_read_long(dev, 0x64); +} + +static void vx900_sata_read_phy_config(struct pci_dev *dev, sata_phy_config cfg) +{ + size_t i; + u32* data = (u32*)cfg; + for (i = 0; i < ( sizeof(sata_phy_config) ) >> 2; i++) { + data[i] = sata_phy_read32(dev, i<<2); + } +} + +static int quirk_vx900_sata(struct pci_dev *dev) +{ + sata_phy_config ephy; + + /* Get all the info in one pass */ + vx900_sata_read_phy_config(dev, ephy); + + /* Put it on the terminal for the user to read and be done with it */ + printf("SATA PHY config:\n"); + unsigned int i; + for (i = 0; i < sizeof(sata_phy_config); i++) { + if ((i & 0x0f) == 0) { + printf("%.2x :", i); + } + if( (i & 0x0f) == 0x08 ) + printf("| "); + printf("%.2x ", ephy[i]); + if ((i & 0x0f) == 0x0f) { + printf("\n"); + } + } + return 0; +} + + + + +static struct quirk vx900_sb_quirks[] = { + {0, 0, 0x0f, 0, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX900_SATA, + quirk_vx900_sata }, + {0, 0, 0, 0, 0, 0, 0}, +}; + +struct quirk_list vx900_sb_quirk_list = { + .pci_vendor_id = PCI_VENDOR_ID_VIA, + .pci_device_id = PCI_DEVICE_ID_VIA_VX900_LPC, + .dev_quirks = vx900_sb_quirks +};
\ No newline at end of file diff --git a/util/viatool/viatool.c b/util/viatool/viatool.c new file mode 100644 index 0000000000..3f19f2819c --- /dev/null +++ b/util/viatool/viatool.c @@ -0,0 +1,256 @@ +/* + * viatool - dump all registers on an Intel CPU + chipset based system. + * + * Copyright (C) 2008-2010 by coresystems GmbH + * written by Stefan Reinauer <stepan@coresystems.de> + * Copyright (C) 2009 Carl-Daniel Hailfinger + * Copyright (C) 2013 Alexandru Gagniuc + * + * 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 <stdlib.h> +#include <inttypes.h> +#include <getopt.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <unistd.h> +#include "viatool.h" + +/* + * http://pci-ids.ucw.cz/read/PC/8086 + * http://en.wikipedia.org/wiki/Intel_Tick-Tock + * http://en.wikipedia.org/wiki/List_of_Intel_chipsets + * http://en.wikipedia.org/wiki/Intel_Xeon_chipsets + */ +static const struct { + uint16_t vendor_id, device_id; + char *name; +} supported_chips_list[] = { + { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX900_SATA, "VX900 SATA"}, + /* Host bridges/DRAM controllers (Northbridges) */ + { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX900, "VX900"}, + /* Southbridges (LPC controllers) */ + { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX900_LPC, "VX900" }, +}; + +#ifndef __DARWIN__ +static int fd_mem; + +void *map_physical(uint64_t phys_addr, size_t len) +{ + void *virt_addr; + + virt_addr = mmap(0, len, PROT_WRITE | PROT_READ, MAP_SHARED, + fd_mem, (off_t) phys_addr); + + if (virt_addr == MAP_FAILED) { + printf("Error mapping physical memory 0x%08" PRIx64 "[0x%zx]\n", + phys_addr, len); + return NULL; + } + + return virt_addr; +} + +void unmap_physical(void *virt_addr, size_t len) +{ + munmap(virt_addr, len); +} +#endif + +void print_version(void) +{ + printf("inteltool v%s -- ", VIATOOL_VERSION); + printf("Copyright (C) 2013 Alexandru Gagniuc\n\n"); + printf( + "This program is free software: you can redistribute it and/or modify\n" + "it under the terms of the GNU General Public License as published by\n" + "the Free Software Foundation, version 2 of the License.\n\n" + "This program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n\n" + "You should have received a copy of the GNU General Public License\n" + "along with this program. If not, see <http://www.gnu.org/licenses/>.\n\n"); +} + +void print_usage(const char *name) +{ + printf("usage: %s [-vh?gGrpmedPMa]\n", name); + printf("\n" + " -v | --version: print the version\n" + " -h | --help: print this help\n\n" + " -M | --msrs: dump CPU MSRs\n" + " -a | --all: dump all known registers\n" + " -q | --quirks: dump hierarchical configs\n" + "\n"); + exit(1); +} + +int main(int argc, char *argv[]) +{ + 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"; + + int dump_coremsrs = 0, dump_quirks = 0; + + static struct option long_options[] = { + {"version", 0, 0, 'v'}, + {"help", 0, 0, 'h'}, + {"mchbar", 0, 0, 'm'}, + {"msrs", 0, 0, 'M'}, + {"quirks", 0, 0, 'q'}, + {"all", 0, 0, 'a'}, + {0, 0, 0, 0} + }; + + while ((opt = getopt_long(argc, argv, "vh?gGrpmedPMaA", + long_options, &option_index)) != EOF) { + switch (opt) { + case 'v': + print_version(); + exit(0); + break; + case 'M': + dump_coremsrs = 1; + break; + case 'q': + dump_quirks = 1; + break; + case 'a': + dump_coremsrs = 1; + dump_quirks = 1; + break; + case 'h': + case '?': + default: + print_usage(argv[0]); + exit(0); + break; + } + } + +#if defined(__FreeBSD__) + if (open("/dev/io", O_RDWR) < 0) { + perror("/dev/io"); +#else + if (iopl(3)) { + perror("iopl"); +#endif + printf("You need to be root.\n"); + exit(1); + } + +#ifndef __DARWIN__ + if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) { + perror("Can not open /dev/mem"); + exit(1); + } +#endif + + pacc = pci_alloc(); + pci_init(pacc); + pci_scan_bus(pacc); + + /* Find the required devices */ + for (dev = pacc->devices; dev; dev = dev->next) { + pci_fill_info(dev, PCI_FILL_CLASS); + /* The ISA/LPC bridge can be 0x1f, 0x07, or 0x04 so we probe. */ + if (dev->device_class == 0x0601) { /* ISA/LPC bridge */ + if (sb == NULL) + sb = dev; + else + fprintf(stderr, "Multiple devices with class ID" + " 0x0601, using %02x%02x:%02x.%02x\n", + dev->domain, dev->bus, dev->dev, + dev->func); + } + } + + if (!sb) { + printf("No southbridge found.\n"); + exit(1); + } + + pci_fill_info(sb, PCI_FILL_IDENT|PCI_FILL_BASES|PCI_FILL_SIZES|PCI_FILL_CLASS); + + if (sb->vendor_id != PCI_VENDOR_ID_VIA) { + printf("Not a VIA southbridge.\n"); + exit(1); + } + + nb = pci_get_dev(pacc, 0, 0, 0x00, 0); + if (!nb) { + printf("No northbridge found.\n"); + exit(1); + } + + pci_fill_info(nb, PCI_FILL_IDENT|PCI_FILL_BASES|PCI_FILL_SIZES|PCI_FILL_CLASS); + + if (nb->vendor_id != PCI_VENDOR_ID_VIA) { + printf("Not a VIA northbridge.\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("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; + + printf("Northbridge: %04x:%04x (%s)\n", + nb->vendor_id, nb->device_id, nbname); + + printf("Southbridge: %04x:%04x (%s)\n", + sb->vendor_id, sb->device_id, sbname); + + /* Now do the deed */ + + if (dump_coremsrs) { + print_intel_core_msrs(); + printf("\n\n"); + } + + if (dump_quirks) { + print_quirks_north(nb, pacc); + print_quirks_south(sb, pacc); + } + + /* Clean up */ + pci_free_dev(nb); + // pci_free_dev(sb); // TODO: glibc detected "double free or corruption" + pci_cleanup(pacc); + + return 0; +} diff --git a/util/viatool/viatool.h b/util/viatool/viatool.h new file mode 100644 index 0000000000..ed90112c18 --- /dev/null +++ b/util/viatool/viatool.h @@ -0,0 +1,78 @@ +/* + * viatool - dump all registers on an Intel CPU + chipset based system. + * + * Copyright (C) 2008-2010 by coresystems GmbH + * Copyright (C) 2009 Carl-Daniel Hailfinger + * Copyright (C) 2013 Alexandru Gagniuc + * + * 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 <stdint.h> + +#ifndef _VIATOOL_H +#define _VIATOOL_H + +#if defined(__GLIBC__) +#include <sys/io.h> +#endif +#if (defined(__MACH__) && defined(__APPLE__)) +/* DirectHW is available here: http://www.coreboot.org/DirectHW */ +#define __DARWIN__ +#include <DirectHW/DirectHW.h> +#endif +#include <pci/pci.h> + +/* This #include is needed for freebsd_{rd,wr}msr. */ +#if defined(__FreeBSD__) +#include <machine/cpufunc.h> +#endif + +#include <stdlib.h> + +#define VIATOOL_VERSION "1.0" + +/* Tested chipsets: */ +#define PCI_VENDOR_ID_VIA 0x1106 +#define PCI_DEVICE_ID_VIA_VX900 0x0410 +#define PCI_DEVICE_ID_VIA_VX900_SATA 0x9001 +#define PCI_DEVICE_ID_VIA_VX900_LPC 0x8410 + + +#define ARRAY_SIZE(a) ((int)(sizeof(a) / sizeof((a)[0]))) + +#if !defined(__DARWIN__) && !defined(__FreeBSD__) +typedef struct { uint32_t hi, lo; } msr_t; +#endif +#if defined (__FreeBSD__) +/* FreeBSD already has conflicting definitions for wrmsr/rdmsr. */ +#undef rdmsr +#undef wrmsr +#define rdmsr freebsd_rdmsr +#define wrmsr freebsd_wrmsr +typedef struct { uint32_t hi, lo; } msr_t; +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; + +void *map_physical(uint64_t 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_quirks_north(struct pci_dev *nb, struct pci_access *pacc); +int print_quirks_south(struct pci_dev *sb, struct pci_access *pacc); + +#endif /* _VIATOOL_H */ |