Index: arch/i386/i386/est.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/est.c,v retrieving revision 1.25 diff -d -p -u -r1.25 est.c --- arch/i386/i386/est.c 18 Jun 2006 16:39:56 -0000 1.25 +++ arch/i386/i386/est.c 30 Aug 2006 03:42:05 -0000 @@ -103,389 +103,750 @@ __KERNEL_RCSID(0, "$NetBSD: est.c,v 1.25 #define EST_TARGET_CTLFLAG CTLFLAG_READWRITE #endif -struct fq_info { - int mhz; - int mv; -}; +/* Convert MHz and mV into IDs for passing to the MSR. */ +#define ID16(MHz, mV, bus_clk) \ + ((((MHz * 100 + 50) / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4)) + +/* Possible bus speeds (multiplied by 100 for rounding) */ +enum { BUS100 = 10000, BUS133 = 13333, BUS166 = 16666, BUS200 = 20000 }; /* Ultra Low Voltage Intel Pentium M processor 900 MHz */ -static const struct fq_info pentium_m_900[] = { - { 900, 1004 }, - { 800, 988 }, - { 600, 844 }, +static const uint16_t pm130_900_ulv[] = { + ID16( 900, 1004, BUS100), + ID16( 800, 988, BUS100), + ID16( 600, 844, BUS100), }; /* Ultra Low Voltage Intel Pentium M processor 1.00 GHz */ -static const struct fq_info pentium_m_1000[] = { - { 1000, 1004 }, - { 900, 988 }, - { 800, 972 }, - { 600, 844 }, +static const uint16_t pm130_1000_ulv[] = { + ID16(1000, 1004, BUS100), + ID16( 900, 988, BUS100), + ID16( 800, 972, BUS100), + ID16( 600, 844, BUS100), +}; + +/* Ultra Low Voltage Intel Pentium M processor 1.10 GHz */ +static const uint16_t pm130_1100_ulv[] = { + ID16(1100, 1004, BUS100), + ID16(1000, 988, BUS100), + ID16( 900, 972, BUS100), + ID16( 800, 956, BUS100), + ID16( 600, 844, BUS100), }; /* Low Voltage Intel Pentium M processor 1.10 GHz */ -static const struct fq_info pentium_m_1100[] = { - { 1100, 1180 }, - { 1000, 1164 }, - { 900, 1100 }, - { 800, 1020 }, - { 600, 956 }, +static const uint16_t pm130_1100_lv[] = { + ID16(1100, 1180, BUS100), + ID16(1000, 1164, BUS100), + ID16( 900, 1100, BUS100), + ID16( 800, 1020, BUS100), + ID16( 600, 956, BUS100), }; /* Low Voltage Intel Pentium M processor 1.20 GHz */ -static const struct fq_info pentium_m_1200[] = { - { 1200, 1180 }, - { 1100, 1164 }, - { 1000, 1100 }, - { 900, 1020 }, - { 800, 1004 }, - { 600, 956 }, +static const uint16_t pm130_1200_lv[] = { + ID16(1200, 1180, BUS100), + ID16(1100, 1164, BUS100), + ID16(1000, 1100, BUS100), + ID16( 900, 1020, BUS100), + ID16( 800, 1004, BUS100), + ID16( 600, 956, BUS100), }; /* Low Voltage Intel Pentium M processor 1.30 GHz */ -static const struct fq_info pentium_m_1300_lv[] = { - { 1300, 1180 }, - { 1200, 1164 }, - { 1100, 1100 }, - { 1000, 1020 }, - { 900, 1004 }, - { 800, 988 }, - { 600, 956 }, +static const uint16_t pm130_1300_lv[] = { + ID16(1300, 1180, BUS100), + ID16(1200, 1164, BUS100), + ID16(1100, 1100, BUS100), + ID16(1000, 1020, BUS100), + ID16( 900, 1004, BUS100), + ID16( 800, 988, BUS100), + ID16( 600, 956, BUS100), }; /* Intel Pentium M processor 1.30 GHz */ -static const struct fq_info pentium_m_1300[] = { - { 1300, 1388 }, - { 1200, 1356 }, - { 1000, 1292 }, - { 800, 1260 }, - { 600, 956 }, +static const uint16_t pm130_1300[] = { + ID16(1300, 1388, BUS100), + ID16(1200, 1356, BUS100), + ID16(1000, 1292, BUS100), + ID16( 800, 1260, BUS100), + ID16( 600, 956, BUS100), }; /* Intel Pentium M processor 1.40 GHz */ -static const struct fq_info pentium_m_1400[] = { - { 1400, 1484 }, - { 1200, 1436 }, - { 1000, 1308 }, - { 800, 1180 }, - { 600, 956 } +static const uint16_t pm130_1400[] = { + ID16(1400, 1484, BUS100), + ID16(1200, 1436, BUS100), + ID16(1000, 1308, BUS100), + ID16( 800, 1180, BUS100), + ID16( 600, 956, BUS100), }; /* Intel Pentium M processor 1.50 GHz */ -static const struct fq_info pentium_m_1500[] = { - { 1500, 1484 }, - { 1400, 1452 }, - { 1200, 1356 }, - { 1000, 1228 }, - { 800, 1116 }, - { 600, 956 } +static const uint16_t pm130_1500[] = { + ID16(1500, 1484, BUS100), + ID16(1400, 1452, BUS100), + ID16(1200, 1356, BUS100), + ID16(1000, 1228, BUS100), + ID16( 800, 1116, BUS100), + ID16( 600, 956, BUS100), }; /* Intel Pentium M processor 1.60 GHz */ -static const struct fq_info pentium_m_1600[] = { - { 1600, 1484 }, - { 1400, 1420 }, - { 1200, 1276 }, - { 1000, 1164 }, - { 800, 1036 }, - { 600, 956 } +static const uint16_t pm130_1600[] = { + ID16(1600, 1484, BUS100), + ID16(1400, 1420, BUS100), + ID16(1200, 1276, BUS100), + ID16(1000, 1164, BUS100), + ID16( 800, 1036, BUS100), + ID16( 600, 956, BUS100), }; /* Intel Pentium M processor 1.70 GHz */ -static const struct fq_info pentium_m_1700[] = { - { 1700, 1484 }, - { 1400, 1308 }, - { 1200, 1228 }, - { 1000, 1116 }, - { 800, 1004 }, - { 600, 956 } +static const uint16_t pm130_1700[] = { + ID16(1700, 1484, BUS100), + ID16(1400, 1308, BUS100), + ID16(1200, 1228, BUS100), + ID16(1000, 1116, BUS100), + ID16( 800, 1004, BUS100), + ID16( 600, 956, BUS100), }; -/* Intel Pentium M processor 723 Ultra Low Voltage 1.0 GHz */ -static const struct fq_info pentium_m_n723[] = { - { 1000, 940 }, - { 900, 908 }, - { 800, 876 }, - { 600, 812 } +/* Intel Pentium M processor 723 1.0 GHz */ +static const uint16_t pm90_n723[] = { + ID16(1000, 940, BUS100), + ID16( 900, 908, BUS100), + ID16( 800, 876, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 733 Ultra Low Voltage 1.1 GHz */ -static const struct fq_info pentium_m_n733[] = { - { 1100, 940 }, - { 1000, 924 }, - { 900, 892 }, - { 800, 876 }, - { 600, 812 } +/* Intel Pentium M processor 733 1.1 GHz, VID #G */ +static const uint16_t pm90_n733g[] = { + ID16(1100, 956, BUS100), + ID16(1000, 940, BUS100), + ID16( 900, 908, BUS100), + ID16( 800, 876, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 753 Ultra Low Voltage 1.2 GHz */ -static const struct fq_info pentium_m_n753[] = { - { 1200, 940 }, - { 1100, 924 }, - { 1000, 908 }, - { 900, 876 }, - { 800, 860 }, - { 600, 812 } +/* Intel Pentium M processor 733 1.1 GHz, VID #H */ +static const uint16_t pm90_n733h[] = { + ID16(1100, 940, BUS100), + ID16(1000, 924, BUS100), + ID16( 900, 892, BUS100), + ID16( 800, 876, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 773 Ultra Low Voltage 1.3 GHz */ -static const struct fq_info pentium_m_n773[] = { - { 1300, 940 }, - { 1200, 924 }, - { 1100, 908 }, - { 1000, 892 }, - { 900, 876 }, - { 800, 860 }, - { 600, 812 } +/* Intel Pentium M processor 733 1.1 GHz, VID #I */ +static const uint16_t pm90_n733i[] = { + ID16(1100, 924, BUS100), + ID16(1000, 908, BUS100), + ID16( 900, 892, BUS100), + ID16( 800, 860, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 738 Low Voltage 1.4 GHz */ -static const struct fq_info pentium_m_n738[] = { - { 1400, 1116 }, - { 1300, 1116 }, - { 1200, 1100 }, - { 1100, 1068 }, - { 1000, 1052 }, - { 900, 1036 }, - { 800, 1020 }, - { 600, 988 } +/* Intel Pentium M processor 733 1.1 GHz, VID #J */ +static const uint16_t pm90_n733j[] = { + ID16(1100, 908, BUS100), + ID16(1000, 892, BUS100), + ID16( 900, 876, BUS100), + ID16( 800, 860, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 758 Low Voltage 1.5 GHz */ -static const struct fq_info pentium_m_n758[] = { - { 1500, 1116 }, - { 1400, 1116 }, - { 1300, 1100 }, - { 1200, 1084 }, - { 1100, 1068 }, - { 1000, 1052 }, - { 900, 1036 }, - { 800, 1020 }, - { 600, 988 } +/* Intel Pentium M processor 733 1.1 GHz, VID #K */ +static const uint16_t pm90_n733k[] = { + ID16(1100, 892, BUS100), + ID16(1000, 876, BUS100), + ID16( 900, 860, BUS100), + ID16( 800, 844, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 778 Low Voltage 1.6 GHz */ -static const struct fq_info pentium_m_n778[] = { - { 1600, 1116 }, - { 1500, 1116 }, - { 1400, 1100 }, - { 1300, 1184 }, - { 1200, 1068 }, - { 1100, 1052 }, - { 1000, 1052 }, - { 900, 1036 }, - { 800, 1020 }, - { 600, 988 } +/* Intel Pentium M processor 733 1.1 GHz, VID #L */ +static const uint16_t pm90_n733l[] = { + ID16(1100, 876, BUS100), + ID16(1000, 876, BUS100), + ID16( 900, 860, BUS100), + ID16( 800, 844, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 710 1.4 GHz */ -static const struct fq_info pentium_m_n710[] = { - { 1400, 1340 }, - { 1200, 1228 }, - { 1000, 1148 }, - { 800, 1068 }, - { 600, 998 } +/* Intel Pentium M processor 753 1.2 GHz, VID #G */ +static const uint16_t pm90_n753g[] = { + ID16(1200, 956, BUS100), + ID16(1100, 940, BUS100), + ID16(1000, 908, BUS100), + ID16( 900, 892, BUS100), + ID16( 800, 860, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 715 1.5 GHz */ -static const struct fq_info pentium_m_n715[] = { - { 1500, 1340 }, - { 1200, 1228 }, - { 1000, 1148 }, - { 800, 1068 }, - { 600, 988 } +/* Intel Pentium M processor 753 1.2 GHz, VID #H */ +static const uint16_t pm90_n753h[] = { + ID16(1200, 940, BUS100), + ID16(1100, 924, BUS100), + ID16(1000, 908, BUS100), + ID16( 900, 876, BUS100), + ID16( 800, 860, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 725 1.6 GHz */ -static const struct fq_info pentium_m_n725[] = { - { 1600, 1340 }, - { 1400, 1276 }, - { 1200, 1212 }, - { 1000, 1132 }, - { 800, 1068 }, - { 600, 988 } +/* Intel Pentium M processor 753 1.2 GHz, VID #I */ +static const uint16_t pm90_n753i[] = { + ID16(1200, 924, BUS100), + ID16(1100, 908, BUS100), + ID16(1000, 892, BUS100), + ID16( 900, 876, BUS100), + ID16( 800, 860, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 730 1.6 GHz */ -static const struct fq_info pentium_m_n730[] = { - { 1600, 1308 }, - { 1333, 1260 }, - { 1200, 1212 }, - { 1067, 1180 }, - { 800, 988 } -}; +/* Intel Pentium M processor 753 1.2 GHz, VID #J */ +static const uint16_t pm90_n753j[] = { + ID16(1200, 908, BUS100), + ID16(1100, 892, BUS100), + ID16(1000, 876, BUS100), + ID16( 900, 860, BUS100), + ID16( 800, 844, BUS100), + ID16( 600, 812, BUS100), +}; -/* Intel Pentium M processor 735 1.7 GHz */ -static const struct fq_info pentium_m_n735[] = { - { 1700, 1340 }, - { 1400, 1244 }, - { 1200, 1180 }, - { 1000, 1116 }, - { 800, 1052 }, - { 600, 988 } +/* Intel Pentium M processor 753 1.2 GHz, VID #K */ +static const uint16_t pm90_n753k[] = { + ID16(1200, 892, BUS100), + ID16(1100, 892, BUS100), + ID16(1000, 876, BUS100), + ID16( 900, 860, BUS100), + ID16( 800, 844, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 740 1.73 GHz */ -static const struct fq_info pentium_m_n740[] = { - { 1733, 1356 }, - { 1333, 1212 }, - { 1067, 1100 }, - { 800, 988 }, +/* Intel Pentium M processor 753 1.2 GHz, VID #L */ +static const uint16_t pm90_n753l[] = { + ID16(1200, 876, BUS100), + ID16(1100, 876, BUS100), + ID16(1000, 860, BUS100), + ID16( 900, 844, BUS100), + ID16( 800, 844, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 745 1.8 GHz */ -static const struct fq_info pentium_m_n745[] = { - { 1800, 1340 }, - { 1600, 1292 }, - { 1400, 1228 }, - { 1200, 1164 }, - { 1000, 1116 }, - { 800, 1052 }, - { 600, 988 } +/* Intel Pentium M processor 773 1.3 GHz, VID #G */ +static const uint16_t pm90_n773g[] = { + ID16(1300, 956, BUS100), + ID16(1200, 940, BUS100), + ID16(1100, 924, BUS100), + ID16(1000, 908, BUS100), + ID16( 900, 876, BUS100), + ID16( 800, 860, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 750 1.86 GHz */ -/* values extracted from \_PR\NPSS (via _PSS) SDST ACPI table */ -static const struct fq_info pentium_m_n750[] = { - { 1867, 1308 }, - { 1600, 1228 }, - { 1333, 1148 }, - { 1067, 1068 }, - { 800, 988 } +/* Intel Pentium M processor 773 1.3 GHz, VID #H */ +static const uint16_t pm90_n773h[] = { + ID16(1300, 940, BUS100), + ID16(1200, 924, BUS100), + ID16(1100, 908, BUS100), + ID16(1000, 892, BUS100), + ID16( 900, 876, BUS100), + ID16( 800, 860, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 755 2.0 GHz */ -static const struct fq_info pentium_m_n755[] = { - { 2000, 1340 }, - { 1800, 1292 }, - { 1600, 1244 }, - { 1400, 1196 }, - { 1200, 1148 }, - { 1000, 1100 }, - { 800, 1052 }, - { 600, 988 } +/* Intel Pentium M processor 773 1.3 GHz, VID #I */ +static const uint16_t pm90_n773i[] = { + ID16(1300, 924, BUS100), + ID16(1200, 908, BUS100), + ID16(1100, 892, BUS100), + ID16(1000, 876, BUS100), + ID16( 900, 860, BUS100), + ID16( 800, 844, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 760 2.0 GHz */ -static const struct fq_info pentium_m_n760[] = { - { 2000, 1356 }, - { 1600, 1244 }, - { 1333, 1164 }, - { 1067, 1084 }, - { 800, 988 } +/* Intel Pentium M processor 773 1.3 GHz, VID #J */ +static const uint16_t pm90_n773j[] = { + ID16(1300, 908, BUS100), + ID16(1200, 908, BUS100), + ID16(1100, 892, BUS100), + ID16(1000, 876, BUS100), + ID16( 900, 860, BUS100), + ID16( 800, 844, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 765 2.1 GHz */ -static const struct fq_info pentium_m_n765[] = { - { 2100, 1340 }, - { 1800, 1276 }, - { 1600, 1228 }, - { 1400, 1180 }, - { 1200, 1132 }, - { 1000, 1084 }, - { 800, 1036 }, - { 600, 988 } +/* Intel Pentium M processor 773 1.3 GHz, VID #K */ +static const uint16_t pm90_n773k[] = { + ID16(1300, 892, BUS100), + ID16(1200, 892, BUS100), + ID16(1100, 876, BUS100), + ID16(1000, 860, BUS100), + ID16( 900, 860, BUS100), + ID16( 800, 844, BUS100), + ID16( 600, 812, BUS100), }; -/* Intel Pentium M processor 770 2.13 GHz */ -static const struct fq_info pentium_m_n770[] = { - { 2133, 1551 }, - { 1800, 1429 }, - { 1600, 1356 }, - { 1400, 1180 }, - { 1200, 1132 }, - { 1000, 1084 }, - { 800, 1036 }, - { 600, 988 } +/* Intel Pentium M processor 773 1.3 GHz, VID #L */ +static const uint16_t pm90_n773l[] = { + ID16(1300, 876, BUS100), + ID16(1200, 876, BUS100), + ID16(1100, 860, BUS100), + ID16(1000, 860, BUS100), + ID16( 900, 844, BUS100), + ID16( 800, 844, BUS100), + ID16( 600, 812, BUS100), }; -struct fqlist { - const char *brand_tag; - const int cpu_id; - size_t tablec; - const struct fq_info *table; - const int fsbmult; /* in multiples of 133 MHz */ +/* Intel Pentium M processor 738 1.4 GHz */ +static const uint16_t pm90_n738[] = { + ID16(1400, 1116, BUS100), + ID16(1300, 1116, BUS100), + ID16(1200, 1100, BUS100), + ID16(1100, 1068, BUS100), + ID16(1000, 1052, BUS100), + ID16( 900, 1036, BUS100), + ID16( 800, 1020, BUS100), + ID16( 600, 988, BUS100), }; -#define ENTRY(s, i, v, f) { s, i, sizeof(v) / sizeof((v)[0]), v, f } -static const struct fqlist pentium_m[] = { /* Banias */ - ENTRY(" 900", 0x0695, pentium_m_900, 3), - ENTRY("1000", 0x0695, pentium_m_1000, 3), - ENTRY("1100", 0x0695, pentium_m_1100, 3), - ENTRY("1200", 0x0695, pentium_m_1200, 3), - ENTRY("1300", 0x0695, pentium_m_1300_lv, 3), - ENTRY("1300", 0x0695, pentium_m_1300, 3), - ENTRY("1400", 0x0695, pentium_m_1400, 3), - ENTRY("1500", 0x0695, pentium_m_1500, 3), - ENTRY("1600", 0x0695, pentium_m_1600, 3), - ENTRY("1700", 0x0695, pentium_m_1700, 3), +/* Intel Pentium M processor 758 1.5 GHz */ +static const uint16_t pm90_n758[] = { + ID16(1500, 1116, BUS100), + ID16(1400, 1116, BUS100), + ID16(1300, 1100, BUS100), + ID16(1200, 1084, BUS100), + ID16(1100, 1068, BUS100), + ID16(1000, 1052, BUS100), + ID16( 900, 1036, BUS100), + ID16( 800, 1020, BUS100), + ID16( 600, 988, BUS100), }; -static const struct fqlist pentium_m_dothan[] = { +/* Intel Pentium M processor 778 1.6 GHz */ +static const uint16_t pm90_n778[] = { + ID16(1600, 1116, BUS100), + ID16(1500, 1116, BUS100), + ID16(1400, 1100, BUS100), + ID16(1300, 1184, BUS100), + ID16(1200, 1068, BUS100), + ID16(1100, 1052, BUS100), + ID16(1000, 1052, BUS100), + ID16( 900, 1036, BUS100), + ID16( 800, 1020, BUS100), + ID16( 600, 988, BUS100), +}; - /* low voltage CPUs */ - ENTRY("1.00", 0x06d8, pentium_m_n723, 3), - ENTRY("1.10", 0x06d6, pentium_m_n733, 3), - ENTRY("1.20", 0x06d8, pentium_m_n753, 3), - ENTRY("1.30", 0, pentium_m_n773, 3), /* does this exist? */ - - /* ultra low voltage CPUs */ - ENTRY("1.40", 0x06d6, pentium_m_n738, 3), - ENTRY("1.50", 0x06d8, pentium_m_n758, 3), - ENTRY("1.60", 0x06d8, pentium_m_n778, 3), +/* Intel Pentium M processor 710 1.4 GHz, 533 MHz FSB */ +static const uint16_t pm90_n710[] = { + ID16(1400, 1340, BUS133), + ID16(1200, 1228, BUS133), + ID16(1000, 1148, BUS133), + ID16( 800, 1068, BUS133), + ID16( 600, 998, BUS133), +}; - /* 'regular' 400 MHz FSB CPUs */ - ENTRY("1.40", 0x06d6, pentium_m_n710, 3), - ENTRY("1.50", 0x06d6, pentium_m_n715, 3), - ENTRY("1.60", 0x06d6, pentium_m_n725, 3), - ENTRY("1.70", 0x06d6, pentium_m_n735, 3), - ENTRY("1.80", 0x06d6, pentium_m_n745, 3), - ENTRY("2.00", 0x06d6, pentium_m_n755, 3), - ENTRY("2.10", 0x06d6, pentium_m_n765, 3), +/* Intel Pentium M processor 715 1.5 GHz, VID #A */ +static const uint16_t pm90_n715a[] = { + ID16(1500, 1340, BUS100), + ID16(1200, 1228, BUS100), + ID16(1000, 1148, BUS100), + ID16( 800, 1068, BUS100), + ID16( 600, 988, BUS100), +}; - /* 533 MHz FSB CPUs */ - ENTRY("1.60", 0x06d8, pentium_m_n730, 4), - ENTRY("1.73", 0x06d8, pentium_m_n740, 4), - ENTRY("1.86", 0x06d8, pentium_m_n750, 4), - ENTRY("2.00", 0x06d8, pentium_m_n760, 4), - ENTRY("2.13", 0x06d8, pentium_m_n770, 4), +/* Intel Pentium M processor 715 1.5 GHz, VID #B */ +static const uint16_t pm90_n715b[] = { + ID16(1500, 1324, BUS100), + ID16(1200, 1212, BUS100), + ID16(1000, 1148, BUS100), + ID16( 800, 1068, BUS100), + ID16( 600, 988, BUS100), +}; +/* Intel Pentium M processor 715 1.5 GHz, VID #C */ +static const uint16_t pm90_n715c[] = { + ID16(1500, 1308, BUS100), + ID16(1200, 1212, BUS100), + ID16(1000, 1132, BUS100), + ID16( 800, 1068, BUS100), + ID16( 600, 988, BUS100), }; -#undef ENTRY -struct est_cpu { - const char *brand_prefix; - const char *brand_suffix; - size_t listc; - const struct fqlist *list; +/* Intel Pentium M processor 715 1.5 GHz, VID #D */ +static const uint16_t pm90_n715d[] = { + ID16(1500, 1276, BUS100), + ID16(1200, 1180, BUS100), + ID16(1000, 1116, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), }; -static const struct est_cpu est_cpus[] = { - { - "Intel(R) Pentium(R) M processor ", "MHz", - (sizeof(pentium_m) / sizeof(pentium_m[0])), - pentium_m - }, - { - "Intel(R) Pentium(R) M processor ", "GHz", - (sizeof(pentium_m_dothan) / sizeof(pentium_m_dothan[0])), - pentium_m_dothan - }, +/* Intel Pentium M processor 725 1.6 GHz, VID #A */ +static const uint16_t pm90_n725a[] = { + ID16(1600, 1340, BUS100), + ID16(1400, 1276, BUS100), + ID16(1200, 1212, BUS100), + ID16(1000, 1132, BUS100), + ID16( 800, 1068, BUS100), + ID16( 600, 988, BUS100), }; -#define NESTCPUS (sizeof(est_cpus) / sizeof(est_cpus[0])) +/* Intel Pentium M processor 725 1.6 GHz, VID #B */ +static const uint16_t pm90_n725b[] = { + ID16(1600, 1324, BUS100), + ID16(1400, 1260, BUS100), + ID16(1200, 1196, BUS100), + ID16(1000, 1132, BUS100), + ID16( 800, 1068, BUS100), + ID16( 600, 988, BUS100), +}; -#define MSR2MV(msr) (((int) (msr) & 0xff) * 16 + 700) -#define MSR2MHZ(msr) (((((int) (msr) >> 8) & 0xff) * 100 * fsbmult + 1)/ 3) -#define MV2MSR(mv) ((((int) (mv) - 700) >> 4) & 0xff) -#define MHZ2MSR(mhz) (((3 * (mhz + 30) / (100 * fsbmult)) & 0xff) << 8) -/* XXX 30 is slop to deal with the 33.333 MHz roundoff values */ +/* Intel Pentium M processor 725 1.6 GHz, VID #C */ +static const uint16_t pm90_n725c[] = { + ID16(1600, 1308, BUS100), + ID16(1400, 1244, BUS100), + ID16(1200, 1180, BUS100), + ID16(1000, 1116, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), +}; -static const struct fqlist *est_fqlist; /* not NULL if functional */ -static int est_node_target, est_node_current; -static int fsbmult; +/* Intel Pentium M processor 725 1.6 GHz, VID #D */ +static const uint16_t pm90_n725d[] = { + ID16(1600, 1276, BUS100), + ID16(1400, 1228, BUS100), + ID16(1200, 1164, BUS100), + ID16(1000, 1116, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), +}; -static const char est_desc[] = "Enhanced SpeedStep"; +/* Intel Pentium M processor 730 1.6 GHz, 533 MHz FSB */ +static const uint16_t pm90_n730[] = { + ID16(1600, 1308, BUS133), + ID16(1333, 1260, BUS133), + ID16(1200, 1212, BUS133), + ID16(1067, 1180, BUS133), + ID16( 800, 988, BUS133), +}; + +/* Intel Pentium M processor 735 1.7 GHz, VID #A */ +static const uint16_t pm90_n735a[] = { + ID16(1700, 1340, BUS100), + ID16(1400, 1244, BUS100), + ID16(1200, 1180, BUS100), + ID16(1000, 1116, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 735 1.7 GHz, VID #B */ +static const uint16_t pm90_n735b[] = { + ID16(1700, 1324, BUS100), + ID16(1400, 1244, BUS100), + ID16(1200, 1180, BUS100), + ID16(1000, 1116, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 735 1.7 GHz, VID #C */ +static const uint16_t pm90_n735c[] = { + ID16(1700, 1308, BUS100), + ID16(1400, 1228, BUS100), + ID16(1200, 1164, BUS100), + ID16(1000, 1116, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 735 1.7 GHz, VID #D */ +static const uint16_t pm90_n735d[] = { + ID16(1700, 1276, BUS100), + ID16(1400, 1212, BUS100), + ID16(1200, 1148, BUS100), + ID16(1000, 1100, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 740 1.73 GHz, 533 MHz FSB */ +static const uint16_t pm90_n740[] = { + ID16(1733, 1356, BUS133), + ID16(1333, 1212, BUS133), + ID16(1067, 1100, BUS133), + ID16( 800, 988, BUS133), +}; + +/* Intel Pentium M processor 745 1.8 GHz, VID #A */ +static const uint16_t pm90_n745a[] = { + ID16(1800, 1340, BUS100), + ID16(1600, 1292, BUS100), + ID16(1400, 1228, BUS100), + ID16(1200, 1164, BUS100), + ID16(1000, 1116, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 745 1.8 GHz, VID #B */ +static const uint16_t pm90_n745b[] = { + ID16(1800, 1324, BUS100), + ID16(1600, 1276, BUS100), + ID16(1400, 1212, BUS100), + ID16(1200, 1164, BUS100), + ID16(1000, 1116, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 745 1.8 GHz, VID #C */ +static const uint16_t pm90_n745c[] = { + ID16(1800, 1308, BUS100), + ID16(1600, 1260, BUS100), + ID16(1400, 1212, BUS100), + ID16(1200, 1148, BUS100), + ID16(1000, 1100, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 745 1.8 GHz, VID #D */ +static const uint16_t pm90_n745d[] = { + ID16(1800, 1276, BUS100), + ID16(1600, 1228, BUS100), + ID16(1400, 1180, BUS100), + ID16(1200, 1132, BUS100), + ID16(1000, 1084, BUS100), + ID16( 800, 1036, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 750 1.86 GHz, 533 MHz FSB */ +/* values extracted from \_PR\NPSS (via _PSS) SDST ACPI table */ +static const uint16_t pm90_n750[] = { + ID16(1867, 1308, BUS133), + ID16(1600, 1228, BUS133), + ID16(1333, 1148, BUS133), + ID16(1067, 1068, BUS133), + ID16( 800, 988, BUS133), +}; + +/* Intel Pentium M processor 755 2.0 GHz, VID #A */ +static const uint16_t pm90_n755a[] = { + ID16(2000, 1340, BUS100), + ID16(1800, 1292, BUS100), + ID16(1600, 1244, BUS100), + ID16(1400, 1196, BUS100), + ID16(1200, 1148, BUS100), + ID16(1000, 1100, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 755 2.0 GHz, VID #B */ +static const uint16_t pm90_n755b[] = { + ID16(2000, 1324, BUS100), + ID16(1800, 1276, BUS100), + ID16(1600, 1228, BUS100), + ID16(1400, 1180, BUS100), + ID16(1200, 1132, BUS100), + ID16(1000, 1084, BUS100), + ID16( 800, 1036, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 755 2.0 GHz, VID #C */ +static const uint16_t pm90_n755c[] = { + ID16(2000, 1308, BUS100), + ID16(1800, 1276, BUS100), + ID16(1600, 1228, BUS100), + ID16(1400, 1180, BUS100), + ID16(1200, 1132, BUS100), + ID16(1000, 1084, BUS100), + ID16( 800, 1036, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 755 2.0 GHz, VID #D */ +static const uint16_t pm90_n755d[] = { + ID16(2000, 1276, BUS100), + ID16(1800, 1244, BUS100), + ID16(1600, 1196, BUS100), + ID16(1400, 1164, BUS100), + ID16(1200, 1116, BUS100), + ID16(1000, 1084, BUS100), + ID16( 800, 1036, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 760 2.0 GHz, 533 MHz FSB */ +static const uint16_t pm90_n760[] = { + ID16(2000, 1356, BUS133), + ID16(1600, 1244, BUS133), + ID16(1333, 1164, BUS133), + ID16(1067, 1084, BUS133), + ID16( 800, 988, BUS133), +}; + +/* Intel Pentium M processor 765 2.1 GHz, VID #A */ +static const uint16_t pm90_n765a[] = { + ID16(2100, 1340, BUS100), + ID16(1800, 1276, BUS100), + ID16(1600, 1228, BUS100), + ID16(1400, 1180, BUS100), + ID16(1200, 1132, BUS100), + ID16(1000, 1084, BUS100), + ID16( 800, 1036, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 765 2.1 GHz, VID #B */ +static const uint16_t pm90_n765b[] = { + ID16(2100, 1324, BUS100), + ID16(1800, 1260, BUS100), + ID16(1600, 1212, BUS100), + ID16(1400, 1180, BUS100), + ID16(1200, 1132, BUS100), + ID16(1000, 1084, BUS100), + ID16( 800, 1036, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 765 2.1 GHz, VID #C */ +static const uint16_t pm90_n765c[] = { + ID16(2100, 1308, BUS100), + ID16(1800, 1244, BUS100), + ID16(1600, 1212, BUS100), + ID16(1400, 1164, BUS100), + ID16(1200, 1116, BUS100), + ID16(1000, 1084, BUS100), + ID16( 800, 1036, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 765 2.1 GHz, VID #E */ +static const uint16_t pm90_n765e[] = { + ID16(2100, 1356, BUS100), + ID16(1800, 1292, BUS100), + ID16(1600, 1244, BUS100), + ID16(1400, 1196, BUS100), + ID16(1200, 1148, BUS100), + ID16(1000, 1100, BUS100), + ID16( 800, 1052, BUS100), + ID16( 600, 988, BUS100), +}; + +/* Intel Pentium M processor 770 2.13 GHz */ +static const uint16_t pm90_n770[] = { + ID16(2133, 1551, BUS133), + ID16(1800, 1429, BUS133), + ID16(1600, 1356, BUS133), + ID16(1400, 1180, BUS133), + ID16(1200, 1132, BUS133), + ID16(1000, 1084, BUS133), + ID16( 800, 1036, BUS133), + ID16( 600, 988, BUS133), +}; + +struct fqlist { + int vendor : 5; + unsigned bus_clk : 1; + unsigned n : 5; + const uint16_t *table; +}; + +#define NELEM(x) (sizeof(x) / sizeof((x)[0])) + +#define ENTRY(ven, bus_clk, tab) \ + { CPUVENDOR_##ven, bus_clk == BUS133 ? 1 : 0, NELEM(tab), tab } + +#define BUS_CLK(fqp) ((fqp)->bus_clk ? BUS133 : BUS100) + +static const struct fqlist est_cpus[] = { + ENTRY(INTEL, BUS100, pm130_900_ulv), + ENTRY(INTEL, BUS100, pm130_1000_ulv), + ENTRY(INTEL, BUS100, pm130_1100_ulv), + ENTRY(INTEL, BUS100, pm130_1100_lv), + ENTRY(INTEL, BUS100, pm130_1200_lv), + ENTRY(INTEL, BUS100, pm130_1300_lv), + ENTRY(INTEL, BUS100, pm130_1300), + ENTRY(INTEL, BUS100, pm130_1400), + ENTRY(INTEL, BUS100, pm130_1500), + ENTRY(INTEL, BUS100, pm130_1600), + ENTRY(INTEL, BUS100, pm130_1700), + + ENTRY(INTEL, BUS100, pm90_n723), + ENTRY(INTEL, BUS100, pm90_n733g), + ENTRY(INTEL, BUS100, pm90_n733h), + ENTRY(INTEL, BUS100, pm90_n733i), + ENTRY(INTEL, BUS100, pm90_n733j), + ENTRY(INTEL, BUS100, pm90_n733k), + ENTRY(INTEL, BUS100, pm90_n733l), + ENTRY(INTEL, BUS100, pm90_n753g), + ENTRY(INTEL, BUS100, pm90_n753h), + ENTRY(INTEL, BUS100, pm90_n753i), + ENTRY(INTEL, BUS100, pm90_n753j), + ENTRY(INTEL, BUS100, pm90_n753k), + ENTRY(INTEL, BUS100, pm90_n753l), + ENTRY(INTEL, BUS100, pm90_n773g), + ENTRY(INTEL, BUS100, pm90_n773h), + ENTRY(INTEL, BUS100, pm90_n773i), + ENTRY(INTEL, BUS100, pm90_n773j), + ENTRY(INTEL, BUS100, pm90_n773k), + ENTRY(INTEL, BUS100, pm90_n773l), + ENTRY(INTEL, BUS100, pm90_n738), + ENTRY(INTEL, BUS100, pm90_n758), + ENTRY(INTEL, BUS100, pm90_n778), + + ENTRY(INTEL, BUS133, pm90_n710), + ENTRY(INTEL, BUS100, pm90_n715a), + ENTRY(INTEL, BUS100, pm90_n715b), + ENTRY(INTEL, BUS100, pm90_n715c), + ENTRY(INTEL, BUS100, pm90_n715d), + ENTRY(INTEL, BUS100, pm90_n725a), + ENTRY(INTEL, BUS100, pm90_n725b), + ENTRY(INTEL, BUS100, pm90_n725c), + ENTRY(INTEL, BUS100, pm90_n725d), + ENTRY(INTEL, BUS133, pm90_n730), + ENTRY(INTEL, BUS100, pm90_n735a), + ENTRY(INTEL, BUS100, pm90_n735b), + ENTRY(INTEL, BUS100, pm90_n735c), + ENTRY(INTEL, BUS100, pm90_n735d), + ENTRY(INTEL, BUS133, pm90_n740), + ENTRY(INTEL, BUS100, pm90_n745a), + ENTRY(INTEL, BUS100, pm90_n745b), + ENTRY(INTEL, BUS100, pm90_n745c), + ENTRY(INTEL, BUS100, pm90_n745d), + ENTRY(INTEL, BUS133, pm90_n750), + ENTRY(INTEL, BUS100, pm90_n755a), + ENTRY(INTEL, BUS100, pm90_n755b), + ENTRY(INTEL, BUS100, pm90_n755c), + ENTRY(INTEL, BUS100, pm90_n755d), + ENTRY(INTEL, BUS133, pm90_n760), + ENTRY(INTEL, BUS100, pm90_n765a), + ENTRY(INTEL, BUS100, pm90_n765b), + ENTRY(INTEL, BUS100, pm90_n765c), + ENTRY(INTEL, BUS100, pm90_n765e), + ENTRY(INTEL, BUS133, pm90_n770) +}; + +#define MSR2FREQINC(msr) (((int) (msr) >> 8) & 0xff) +#define MSR2VOLTINC(msr) ((int) (msr) & 0xff) + +#define MSR2MHZ(msr, bus) ((MSR2FREQINC((msr)) * (bus) + 50) / 100) +#define MSR2MV(msr) (MSR2VOLTINC(msr) * 16 + 700) + +static const struct fqlist *est_fqlist; /* not NULL if functional */ +static int est_node_target, est_node_current; +static const char est_desc[] = "Enhanced SpeedStep"; +/* bus_clock is assigned in identcpu.c */ +int bus_clock; + +static int est_sysctl_helper(SYSCTLFN_PROTO); static int est_sysctl_helper(SYSCTLFN_ARGS) @@ -494,112 +855,199 @@ est_sysctl_helper(SYSCTLFN_ARGS) int fq, oldfq, error; if (est_fqlist == NULL) - return (EOPNOTSUPP); + return EOPNOTSUPP; node = *rnode; node.sysctl_data = &fq; oldfq = 0; if (rnode->sysctl_num == est_node_target) - fq = oldfq = MSR2MHZ(rdmsr(MSR_PERF_CTL)); + fq = oldfq = MSR2MHZ(rdmsr(MSR_PERF_CTL), bus_clock); else if (rnode->sysctl_num == est_node_current) - fq = MSR2MHZ(rdmsr(MSR_PERF_STATUS)); + fq = MSR2MHZ(rdmsr(MSR_PERF_STATUS), bus_clock); else - return (EOPNOTSUPP); + return EOPNOTSUPP; error = sysctl_lookup(SYSCTLFN_CALL(&node)); if (error || newp == NULL) - return (error); + return error; - /* support writing to ...frequency.target */ + /* support writing to ...frequency.target */ if (rnode->sysctl_num == est_node_target && fq != oldfq) { int i; uint64_t msr; - for (i = est_fqlist->tablec - 1; i > 0; i--) - if (est_fqlist->table[i].mhz >= fq) + for (i = est_fqlist->n - 1; i > 0; i--) + if (MSR2MHZ(est_fqlist->table[i], bus_clock) >= fq) break; - fq = est_fqlist->table[i].mhz; - msr = (rdmsr(MSR_PERF_CTL) & ~0xffffULL) | - MV2MSR(est_fqlist->table[i].mv) | - MHZ2MSR(est_fqlist->table[i].mhz); + fq = MSR2MHZ(est_fqlist->table[i], bus_clock); + msr = rdmsr(MSR_PERF_CTL); + msr &= ~0xffffULL; + msr |= est_fqlist->table[i]; wrmsr(MSR_PERF_CTL, msr); } - return (0); + return 0; } void -est_init(struct cpu_info *ci) +est_init(struct cpu_info *ci, int vendor) { - const struct est_cpu *ccpu; const struct fqlist *fql; const struct sysctlnode *node, *estnode, *freqnode; uint64_t msr; - int i, j, k, rc; + uint16_t cur, idhi, idlo; + int i, rc; int mv; size_t len, freq_len; - char *tag, *freq_names; + char *freq_names, *cpuname = ci->ci_dev->dv_xname; - if ((cpu_feature2 & CPUID2_EST) == 0) + if (bus_clock == 0) { + printf("%s: unknown system bus clock\n", __func__); + return; + } + + msr = rdmsr(MSR_PERF_STATUS); + idhi = (msr >> 32) & 0xffff; + idlo = (msr >> 48) & 0xffff; + cur = msr & 0xffff; + if (idhi == 0 || idlo == 0 || cur == 0 || + ((cur >> 8) & 0xff) < ((idlo >> 8) & 0xff) || + ((cur >> 8) & 0xff) > ((idhi >> 8) & 0xff)) { + printf("%s: strange msr value 0x%016llx\n", __func__, msr); return; + } msr = rdmsr(MSR_PERF_STATUS); mv = MSR2MV(msr); - aprint_normal("%s: %s (%d mV) ", - ci->ci_dev->dv_xname, est_desc, mv); + aprint_normal("%s: %s (%d mV) ", cpuname, est_desc, mv); + aprint_normal("%d MHz\n", MSR2MHZ(msr, bus_clock)); /* - * Look for a CPU matching cpu_brand_string. + * Find an entry which matches (vendor, bus_clock, idhi, idlo) */ - for (i = 0; est_fqlist == NULL && i < NESTCPUS; i++) { - ccpu = &est_cpus[i]; - len = strlen(ccpu->brand_prefix); - if (strncmp(ccpu->brand_prefix, cpu_brand_string, len) != 0) - continue; - tag = cpu_brand_string + len; - for (j = 0; j < ccpu->listc; j++) { - fql = &ccpu->list[j]; - len = strlen(fql->brand_tag); - if (!strncmp(fql->brand_tag, tag, len) && - !strcmp(ccpu->brand_suffix, tag + len) && - (fql->cpu_id == 0 || - fql->cpu_id == ci->ci_signature)) { - /* verify operating point is in table, because - CPUID + brand_tag still isn't unique. */ - for (k = fql->tablec - 1; k >= 0; k--) { - if (fql->table[k].mv == mv) { - est_fqlist = fql; - break; - } - } - } - if (NULL != est_fqlist) break; + for (i = 0; i < NELEM(est_cpus); i++) { + fql = &est_cpus[i]; + if (vendor == fql->vendor && bus_clock == BUS_CLK(fql) && + idhi == fql->table[0] && idlo == fql->table[fql->n - 1]) { + est_fqlist = fql; + break; } } + if (est_fqlist == NULL) { - aprint_normal(" - unknown CPU or operating point.\n"); - return; +#if 0 + aprint_normal("%s: unknown Enhanced SpeedStep CPU.\n", + cpuname); + /* + * Generate a fake table with the power states we know. + */ + fake_table[0] = idhi; + if (cur == idhi || cur == idlo) { + aprint_normal("%s: using only highest and lowest " + " power states.\n", cpuname); + + fake_table[1] = idlo; + fake_fqlist.n = 2; + } else { + aprint_normal("%s: using only highest, current " + "and lowest power states.\n", cpuname); + + fake_table[1] = cur; + fake_table[2] = idlo; + fake_fqlist.n = 3; + } + + fake_fqlist.vendor = vendor; + fake_fqlist.table = fake_table; + est_fqlist = &fake_fqlist; +#else + uint16_t *fake_table; + struct fqlist *fake_fqlist; + int j, tablesize, freq, volt; + int minfreq, minvolt, maxfreq, maxvolt, freqinc, voltinc; + + aprint_normal("%s: unknown Enhanced SpeedStep CPU.\n", + cpuname); + +#define EST_DEBUG +#ifdef EST_DEBUG + printf("%s: bus_clock = %d\n", __FUNCTION__, bus_clock); + printf("%s: idlo = 0x%x\n", __FUNCTION__, idlo); + printf("%s: lo %4d mV, %4d MHz\n", __FUNCTION__, + MSR2MV(idlo), MSR2MHZ(idlo, bus_clock)); + printf("%s: raw %4d , %4d \n", __FUNCTION__, + (idlo & 0xff), ((idlo >> 8) & 0xff)); + printf("%s: idhi = 0x%x\n", __FUNCTION__, idhi); + printf("%s: hi %4d mV, %4d MHz\n", __FUNCTION__, + MSR2MV(idhi), MSR2MHZ(idhi, bus_clock)); + printf("%s: raw %4d , %4d \n", __FUNCTION__, + (idhi & 0xff), ((idhi >> 8) & 0xff)); + printf("%s: cur = 0x%x\n", __FUNCTION__, cur); +#endif + + /* + * Generate a fake table with the power states we know. + */ + minfreq = MSR2FREQINC(idlo); + maxfreq = MSR2FREQINC(idhi); + minvolt = MSR2VOLTINC(idlo); + maxvolt = MSR2VOLTINC(idhi); + freqinc = maxfreq - minfreq; + voltinc = maxvolt - minvolt; + if (freqinc < voltinc) { + if (voltinc % freqinc != 0) + panic("%s: bad 1", __FUNCTION__); + tablesize = maxfreq - minfreq + 1; + voltinc = voltinc / freqinc; + freqinc = 1; + } else { + if (freqinc % voltinc != 0) + panic("%s: bad 2", __FUNCTION__); + tablesize = maxvolt - minvolt + 1; + freqinc = freqinc / voltinc; + voltinc = 1; + } + + fake_fqlist = malloc(sizeof(*fake_fqlist), M_DEVBUF, M_WAITOK); + fake_table = malloc(tablesize * sizeof(uint16_t), M_DEVBUF, + M_WAITOK); + fake_fqlist->n = tablesize; + + /* The frequency/voltage table is highest frequency first */ + freq = maxfreq; + volt = maxvolt; + for (j = 0; j < tablesize; j++) { + fake_table[j] = (freq << 8) + volt; +#ifdef EST_DEBUG + printf("%s: fake entry %d: %4d mV, %4d MHz\n", + __FUNCTION__, j, MSR2MV(fake_table[j]), + MSR2MHZ(fake_table[j], bus_clock)); +#endif + freq -= freqinc; + volt -= voltinc; + } + fake_fqlist->vendor = vendor; + fake_fqlist->table = fake_table; + est_fqlist = fake_fqlist; +#endif } /* * OK, tell the user the available frequencies. */ - fsbmult = est_fqlist->fsbmult; - aprint_normal("%d MHz\n", MSR2MHZ(msr)); - - freq_len = est_fqlist->tablec * (sizeof("9999 ")-1) + 1; + freq_len = est_fqlist->n * (sizeof("9999 ")-1) + 1; freq_names = malloc(freq_len, M_SYSCTLDATA, M_WAITOK); freq_names[0] = '\0'; len = 0; - for (i = 0; i < est_fqlist->tablec; i++) { + for (i = 0; i < est_fqlist->n; i++) { len += snprintf(freq_names + len, freq_len - len, "%d%s", - est_fqlist->table[i].mhz, - i < est_fqlist->tablec - 1 ? " " : ""); + MSR2MHZ(est_fqlist->table[i], bus_clock), + i < est_fqlist->n - 1 ? " " : ""); } aprint_normal("%s: %s frequencies available (MHz): %s\n", - ci->ci_dev->dv_xname, est_desc, freq_names); + cpuname, est_desc, freq_names); /* * Setup the sysctl sub-tree machdep.est.* @@ -637,6 +1085,7 @@ est_init(struct cpu_info *ci) goto err; return; + err: free(freq_names, M_SYSCTLDATA); aprint_normal("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); Index: arch/i386/i386/identcpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/identcpu.c,v retrieving revision 1.37 diff -d -p -u -r1.37 identcpu.c --- arch/i386/i386/identcpu.c 23 Aug 2006 22:59:45 -0000 1.37 +++ arch/i386/i386/identcpu.c 30 Aug 2006 03:42:05 -0000 @@ -151,6 +151,9 @@ static const char *intel_family6_name(st static void transmeta_cpu_info(struct cpu_info *); +void p3_get_bus_clock(struct cpu_info *); +void p4_get_bus_clock(struct cpu_info *); + static inline u_char cyrix_read_reg(u_char reg) { @@ -257,7 +260,11 @@ const struct cpu_cpuid_nameclass i386_cp }, NULL, NULL, +#if defined(I686_CPU) + p3_get_bus_clock, +#else NULL, +#endif }, /* Family > 6 */ { @@ -269,7 +276,7 @@ const struct cpu_cpuid_nameclass i386_cp }, NULL, intel_family_new_probe, - NULL, + p4_get_bus_clock, } } }, { @@ -1041,6 +1048,145 @@ tmx86_get_longrun_status_all(void) &crusoe_voltage, &crusoe_percentage); } +#if defined(I686_CPU) +void +p3_get_bus_clock(struct cpu_info *ci) +{ + uint64_t msr; + int model, bus; + char *cpuname = ci->ci_dev->dv_xname; + + model = (ci->ci_signature >> 4) & 15; + switch (model) { + case 0x9: /* Pentium M (130 nm, Banias) */ + bus_clock = 10000; + break; + case 0xd: /* Pentium M (90 nm, Dothan) */ + msr = rdmsr(MSR_FSB_FREQ); + bus = (msr >> 0) & 0x7; + switch (bus) { + case 0: + bus_clock = 10000; + break; + case 1: + bus_clock = 13333; + break; + default: + aprint_normal("%s: unknown Pentium M FSB_FREQ " + "value %d", cpuname, bus); + goto print_msr; + } + break; + case 0xe: /* Core Duo/Solo */ + case 0xf: /* Core Xeon */ + msr = rdmsr(MSR_FSB_FREQ); + bus = (msr >> 0) & 0x7; + switch (bus) { + case 5: + bus_clock = 10000; + break; + case 1: + bus_clock = 13333; + break; + case 3: + bus_clock = 16666; + break; + case 4: + bus_clock = 33333; + break; + default: + aprint_normal("%s: unknown Core FSB_FREQ value %d", + cpuname, bus); + goto print_msr; + } + break; + case 0x1: /* Pentium Pro, model 1 */ + case 0x3: /* Pentium II, model 3 */ + case 0x5: /* Pentium II, II Xeon, Celeron, model 5 */ + case 0x6: /* Celeron, model 6 */ + case 0x7: /* Pentium III, III Xeon, model 7 */ + case 0x8: /* Pentium III, III Xeon, Celeron, model 8 */ + case 0xa: /* Pentium III Xeon, model A */ + case 0xb: /* Pentium III, model B */ + msr = rdmsr(MSR_EBL_CR_POWERON); + bus = (msr >> 18) & 0x3; + switch (bus) { + case 0: + bus_clock = 6666; + break; + case 1: + bus_clock = 13333; + break; + case 2: + bus_clock = 10000; + break; + default: + aprint_normal("%s: unknown i686 EBL_CR_POWERON " + "value %d ", cpuname, bus); + goto print_msr; + } + break; + default: + aprint_normal("%s: unknown i686 model %d, can't get bus clock", + cpuname, model); +print_msr: + /* + * Show the EBL_CR_POWERON MSR, so we'll at least have + * some extra information, such as clock ratio, etc. + */ + aprint_normal(" (0x%llx)\n", rdmsr(MSR_EBL_CR_POWERON)); + break; + } +} + +void +p4_get_bus_clock(struct cpu_info *ci) +{ + uint64_t msr; + int model, bus; + char *cpuname = ci->ci_dev->dv_xname; + + model = (ci->ci_signature >> 4) & 15; + msr = rdmsr(MSR_EBC_FREQUENCY_ID); + if (model < 2) { + bus = (msr >> 21) & 0x7; + switch (bus) { + case 0: + bus_clock = 10000; + break; + case 1: + bus_clock = 13333; + break; + default: + aprint_normal("%s: unknown Pentium 4 (model %d) " + "EBC_FREQUENCY_ID value %d\n", + cpuname, model, bus); + break; + } + } else { + bus = (msr >> 16) & 0x7; + switch (bus) { + case 0: + bus_clock = (model == 2) ? 10000 : 26666; + break; + case 1: + bus_clock = 13333; + break; + case 2: + bus_clock = 20000; + break; + case 3: + bus_clock = 16666; + break; + default: + aprint_normal("%s: unknown Pentium 4 (model %d) " + "EBC_FREQUENCY_ID value %d\n", + cpuname, model, bus); + break; + } + } +} +#endif /* I686_CPU */ static void transmeta_cpu_info(struct cpu_info *ci) @@ -1442,7 +1588,7 @@ identifycpu(struct cpu_info *ci) #ifdef ENHANCED_SPEEDSTEP if (cpu_feature2 & CPUID2_EST) { if (rdmsr(MSR_MISC_ENABLE) & (1 << 16)) - est_init(ci); + est_init(ci, CPUVENDOR_INTEL); else aprint_normal("%s: Enhanced SpeedStep disabled by BIOS\n", cpuname); Index: arch/i386/include/cpu.h =================================================================== RCS file: /cvsroot/src/sys/arch/i386/include/cpu.h,v retrieving revision 1.127 diff -d -p -u -r1.127 cpu.h --- arch/i386/include/cpu.h 23 Aug 2006 22:59:45 -0000 1.127 +++ arch/i386/include/cpu.h 30 Aug 2006 03:42:06 -0000 void i386_proc0_tss_ldt_init(void); /* identcpu.c */ +extern int bus_clock; extern int tmx86_has_longrun; extern u_int crusoe_longrun; extern u_int crusoe_frequency; @@ -421,7 +433,7 @@ void x86_bus_space_mallocok(void); #include /* Must be after struct cpu_info declaration */ /* est.c */ -void est_init(struct cpu_info *); +void est_init(struct cpu_info *, int); #endif /* _KERNEL */ Index: arch/x86/include/specialreg.h =================================================================== RCS file: /cvsroot/src/sys/arch/x86/include/specialreg.h,v retrieving revision 1.10 diff -d -p -u -r1.10 specialreg.h --- arch/x86/include/specialreg.h 24 Aug 2006 12:55:46 -0000 1.10 +++ arch/x86/include/specialreg.h 30 Aug 2006 03:42:06 -0000 @@ -190,6 +190,7 @@ #define MSR_CTR1 0x013 /* P5 only (trap on P6) */ #define MSR_APICBASE 0x01b #define MSR_EBL_CR_POWERON 0x02a +#define MSR_EBC_FREQUENCY_ID 0x02c /* PIV only */ #define MSR_TEST_CTL 0x033 #define MSR_BIOS_UPDT_TRIG 0x079 #define MSR_BBL_CR_D0 0x088 /* PII+ only */ @@ -198,6 +199,7 @@ #define MSR_BIOS_SIGN 0x08b #define MSR_PERFCTR0 0x0c1 #define MSR_PERFCTR1 0x0c2 +#define MSR_FSB_FREQ 0x0cd /* Core Duo/Solo only */ #define MSR_MTRRcap 0x0fe #define MSR_BBL_CR_ADDR 0x116 /* PII+ only */ #define MSR_BBL_CR_DECC 0x118 /* PII+ only */