> WARNING: 16384 bytes not available for msgbuf in last cluster (4096 > used) > [ using 682848 bytes of bsd ELF symbol table ]
for now you can put 'option MSGBUFSIZE=4096' in your kernel config just to stop it from misbehaving. > The P8600 Core2Duo is not regognized by the speedstep code. > > Adding the model 0x7 to est.c results in: > cpu0: unknown Enhanced SpeedStep CPU, msr 0x0617091f06000091f > cpu0: using only highest and lowest powerstates > cpu0: Enhanced SpeedStep 2400 MHz (1196mV): speeds: 2400, 2600 MHz > > Now i just have to find out how to populate fqlist with the right data. try this, it works on my x200 and gives me 2400, 2133, 1867, and 1600 mhz. Index: est.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/est.c,v retrieving revision 1.7 diff -u -r1.7 est.c --- est.c 6 Aug 2008 05:24:44 -0000 1.7 +++ est.c 22 Sep 2008 17:42:33 -0000 @@ -55,6 +55,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/malloc.h> #include <sys/sysctl.h> #include <machine/cpu.h> @@ -77,10 +78,11 @@ #define BUS266 26667 #define BUS333 33333 -#define MSR2MHZ(msr, bus) \ - (((((int) (msr) >> 8) & 0xff) * (bus) + 50) / 100) -#define MSR2MV(msr) \ - (((int) (msr) & 0xff) * 16 + 700) +#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) struct fqlist { int vendor: 5; @@ -91,7 +93,7 @@ static const struct fqlist *est_fqlist; -static u_int16_t fake_table[3]; +static u_int16_t *fake_table; static struct fqlist fake_fqlist; extern int setperf_prio; @@ -158,6 +160,7 @@ model = (ci->ci_signature >> 4) & 15; switch (model) { case 0xe: /* Core Duo/Solo */ + case 0x7: /* Core 2 Duo */ case 0xf: /* Core Xeon */ msr = rdmsr(MSR_FSB_FREQ); bus = (msr >> 0) & 0x7; @@ -244,29 +247,74 @@ return; } if (est_fqlist == NULL) { - printf("%s: unknown Enhanced SpeedStep CPU, msr 0x%016llx\n", - cpu_device, msr); + int j, tablesize, freq, volt; + int minfreq, minvolt, maxfreq, maxvolt, freqinc, voltinc; - /* - * Generate a fake table with the power states we know. - */ - fake_table[0] = idhi; - if (cur == idhi || cur == idlo) { - printf("%s: using only highest and lowest power " - "states\n", cpu_device); - - fake_table[1] = idlo; - fake_fqlist.n = 2; - } else { - printf("%s: using only highest, current and lowest " - "power states\n", cpu_device); - - fake_table[1] = cur; - fake_table[2] = idlo; - fake_fqlist.n = 3; +#ifdef EST_DEBUG + printf("%s: bus_clock = %d\n", __func__, bus_clock); + printf("%s: idlo = 0x%x\n", __func__, idlo); + printf("%s: lo %4d mV, %4d MHz\n", __func__, + MSR2MV(idlo), MSR2MHZ(idlo, bus_clock)); + printf("%s: raw %4d , %4d \n", __func__, + (idlo & 0xff), ((idlo >> 8) & 0xff)); + printf("%s: idhi = 0x%x\n", __func__, idhi); + printf("%s: hi %4d mV, %4d MHz\n", __func__, + MSR2MV(idhi), MSR2MHZ(idhi, bus_clock)); + printf("%s: raw %4d , %4d \n", __func__, + (idhi & 0xff), ((idhi >> 8) & 0xff)); + printf("%s: cur = 0x%x\n", __func__, cur); +#endif + + /* + * Generate a fake table with the power states we know, + * interpolating the voltages and frequencies between the + * high and low values. The (milli)voltages are always + * rounded up when computing the table. + */ + minfreq = MSR2FREQINC(idlo); + maxfreq = MSR2FREQINC(idhi); + minvolt = MSR2VOLTINC(idlo); + maxvolt = MSR2VOLTINC(idhi); + freqinc = maxfreq - minfreq; + voltinc = maxvolt - minvolt; + + /* Avoid diving by zero. */ + if (freqinc == 0 || voltinc == 0) + return; + + if (freqinc < voltinc || voltinc == 0) { + tablesize = maxfreq - minfreq + 1; + if (voltinc != 0) + voltinc = voltinc * 100 / freqinc - 1; + freqinc = 100; + } else { + tablesize = maxvolt - minvolt + 1; + freqinc = freqinc * 100 / voltinc - 1; + voltinc = 100; } - fake_fqlist.vendor = vendor; - fake_fqlist.table = fake_table; + + 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 * 100; + volt = maxvolt * 100; + for (j = 0; j < tablesize; j++) { + fake_table[j] = (((freq + 99) / 100) << 8) + + (volt + 99) / 100; +#ifdef EST_DEBUG + printf("%s: fake entry %d: %4d mV, %4d MHz " + "MSR*100 mV = %4d freq = %4d\n", + __func__, j, MSR2MV(fake_table[j]), + MSR2MHZ(fake_table[j], bus_clock), + volt, freq); +#endif /* EST_DEBUG */ + freq -= freqinc; + volt -= voltinc; + } + fake_fqlist.vendor = vendor; + fake_fqlist.table = fake_table; est_fqlist = &fake_fqlist; }