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 <machine/psl.h>	/* 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 */