Integrate support for Enhanced SpeedStep Technology (est) that
Michael Eriksson posted to port-i386 on 20031102, with various modifications by me to work in the new sysctl(9) framework. The code is enabled with 'options ENHANCED_SPEEDSTEP', and if the CPU supports EST the following sysctl(8) nodes appear (with the values that a Dell Inspiron 8600 + WUXGA with a 1.4GHz Pentium M CPU supports): machdep.est.cpu_brand = Intel(R) Pentium(R) M processor 1400MHz machdep.est.frequency.target = 1400 machdep.est.frequency.current = 1400 machdep.est.frequency.available = 1400 1200 1000 800 600 If EST support isn't available, the "machdep.est" sysctl sub-MIB is not created. Once we have a more general "CPU frequency" control API we can migrate this code to using that. Thanks to Michael Erikkson for providing this code!
This commit is contained in:
parent
3da1e3206a
commit
2df026b026
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.i386,v 1.255 2004/04/18 18:36:56 fvdl Exp $
|
||||
# $NetBSD: files.i386,v 1.256 2004/04/30 02:05:42 lukem Exp $
|
||||
#
|
||||
# new style config file for i386 architecture
|
||||
#
|
||||
@ -61,6 +61,9 @@ defflag opt_beep.h BEEP_ONHALT
|
||||
defparam opt_beep.h BEEP_ONHALT_COUNT
|
||||
defparam opt_beep.h BEEP_ONHALT_PITCH BEEP_ONHALT_PERIOD
|
||||
|
||||
# Enhanced SpeedStep
|
||||
defflag ENHANCED_SPEEDSTEP
|
||||
|
||||
file arch/i386/i386/autoconf.c
|
||||
file arch/i386/i386/db_dbgreg.S ddb | kstack_check_dr0
|
||||
file arch/i386/i386/db_disasm.c ddb
|
||||
@ -470,4 +473,7 @@ device vesatext
|
||||
attach vesatext at vesabios
|
||||
file arch/i386/bios/vesa_text.c vesatext
|
||||
|
||||
# Enhanced SpeedStep
|
||||
file arch/i386/i386/est.c enhanced_speedstep
|
||||
|
||||
include "arch/i386/conf/majors.i386"
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cpu.c,v 1.18 2004/02/20 17:35:01 yamt Exp $ */
|
||||
/* $NetBSD: cpu.c,v 1.19 2004/04/30 02:05:43 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
@ -71,7 +71,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.18 2004/02/20 17:35:01 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.19 2004/04/30 02:05:43 lukem Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_multiprocessor.h"
|
||||
@ -580,6 +580,7 @@ cpu_hatch(void *v)
|
||||
|
||||
cpu_probe_features(ci);
|
||||
cpu_feature &= ci->ci_feature_flags;
|
||||
cpu_feature2 &= ci->ci_feature2_flags;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ci->ci_flags & CPUF_PRESENT)
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* $NetBSD: est.c,v 1.2 2004/04/30 02:05:43 lukem Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Michael Eriksson.
|
||||
* All rights reserved.
|
||||
@ -24,14 +25,45 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a driver for Intel's Enhanced SpeedStep, as implemented in
|
||||
* Pentium M processors.
|
||||
* This is a driver for Intel's Enhanced SpeedStep Technology (EST),
|
||||
* as implemented in Pentium M processors.
|
||||
*
|
||||
* Reference documentation:
|
||||
*
|
||||
*
|
||||
* - IA-32 Intel Architecture Software Developer's Manual, Volume 3:
|
||||
* System Programming Guide.
|
||||
* Section 13.14, Enhanced Intel SpeedStep technology.
|
||||
@ -46,10 +78,15 @@
|
||||
* Encoding of MSR_PERF_CTL and MSR_PERF_STATUS.
|
||||
* http://www.codemonkey.org.uk/projects/cpufreq/cpufreq-2.4.22-pre6-1.gz
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: est.c,v 1.2 2004/04/30 02:05:43 lukem Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/specialreg.h>
|
||||
|
||||
@ -144,7 +181,7 @@ static const struct fq_info pentium_m_1700[] = {
|
||||
|
||||
struct fqlist {
|
||||
const char *brand_tag;
|
||||
int n;
|
||||
size_t tablec;
|
||||
const struct fq_info *table;
|
||||
};
|
||||
|
||||
@ -166,7 +203,7 @@ static const struct fqlist pentium_m[] = {
|
||||
struct est_cpu {
|
||||
const char *brand_prefix;
|
||||
const char *brand_suffix;
|
||||
int n;
|
||||
size_t listc;
|
||||
const struct fqlist *list;
|
||||
};
|
||||
|
||||
@ -178,25 +215,72 @@ static const struct est_cpu est_cpus[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#define NCPUS (sizeof(est_cpus) / sizeof(est_cpus[0]))
|
||||
#define NESTCPUS (sizeof(est_cpus) / sizeof(est_cpus[0]))
|
||||
|
||||
|
||||
#define MSRVALUE(mhz, mv) ((((mhz) / 100) << 8) | (((mv) - 700) / 16))
|
||||
#define MSR2MHZ(msr) ((((int) (msr) >> 8) & 0xff) * 100)
|
||||
#define MSR2MV(msr) (((int) (msr) & 0xff) * 16 + 700)
|
||||
|
||||
static const struct fqlist *est_fqlist;
|
||||
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";
|
||||
|
||||
static int
|
||||
est_sysctl_helper(SYSCTLFN_ARGS)
|
||||
{
|
||||
struct sysctlnode node;
|
||||
int fq, oldfq, error;
|
||||
|
||||
if (est_fqlist == NULL)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
node = *rnode;
|
||||
node.sysctl_data = &fq;
|
||||
|
||||
oldfq = 0;
|
||||
if (rnode->sysctl_num == est_node_target)
|
||||
fq = oldfq = MSR2MHZ(rdmsr(MSR_PERF_CTL));
|
||||
else if (rnode->sysctl_num == est_node_current)
|
||||
fq = MSR2MHZ(rdmsr(MSR_PERF_STATUS));
|
||||
else
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
error = sysctl_lookup(SYSCTLFN_CALL(&node));
|
||||
if (error || newp == NULL)
|
||||
return (error);
|
||||
|
||||
/* support writing to ...frequency.target */
|
||||
if (rnode->sysctl_num == est_node_target && fq != oldfq) {
|
||||
int i;
|
||||
u_int64_t msr;
|
||||
|
||||
for (i = est_fqlist->tablec - 1; i > 0; i--)
|
||||
if (est_fqlist->table[i].mhz >= fq)
|
||||
break;
|
||||
fq = est_fqlist->table[i].mhz;
|
||||
msr = (rdmsr(MSR_PERF_CTL) & ~0xffffULL) |
|
||||
MSRVALUE(est_fqlist->table[i].mhz,
|
||||
est_fqlist->table[i].mv);
|
||||
wrmsr(MSR_PERF_CTL, msr);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
est_init(ci)
|
||||
struct cpu_info *ci;
|
||||
est_init(struct cpu_info *ci)
|
||||
{
|
||||
int i, j, n, mhz, mv;
|
||||
const struct est_cpu *cpu;
|
||||
u_int64_t msr;
|
||||
char *tag;
|
||||
const struct fqlist *fql;
|
||||
const struct est_cpu *cpu;
|
||||
const struct fqlist *fql;
|
||||
struct sysctlnode *node, *estnode, *freqnode;
|
||||
u_int64_t msr;
|
||||
int i, j, rc;
|
||||
int mhz, mv;
|
||||
size_t len, freq_len;
|
||||
char *tag, *freq_names;
|
||||
|
||||
if ((cpu_feature2 & CPUID2_EST) == 0)
|
||||
return;
|
||||
@ -204,106 +288,104 @@ est_init(ci)
|
||||
msr = rdmsr(MSR_PERF_STATUS);
|
||||
mhz = MSR2MHZ(msr);
|
||||
mv = MSR2MV(msr);
|
||||
printf("%s: Enhanced SpeedStep running at %d MHz (%d mV)\n",
|
||||
ci->ci_dev->dv_xname, mhz, mv);
|
||||
aprint_normal("%s: %s running at %d MHz (%d mV)\n",
|
||||
ci->ci_dev->dv_xname, est_desc, mhz, mv);
|
||||
|
||||
/*
|
||||
* Look for a CPU matching cpu_brand_string.
|
||||
*/
|
||||
for (i = 0; est_fqlist == NULL && i < NCPUS; i++) {
|
||||
for (i = 0; est_fqlist == NULL && i < NESTCPUS; i++) {
|
||||
cpu = &est_cpus[i];
|
||||
n = strlen(cpu->brand_prefix);
|
||||
if (strncmp(cpu->brand_prefix, cpu_brand_string, n) != 0)
|
||||
len = strlen(cpu->brand_prefix);
|
||||
if (strncmp(cpu->brand_prefix, cpu_brand_string, len) != 0)
|
||||
continue;
|
||||
tag = cpu_brand_string + n;
|
||||
for (j = 0; j < cpu->n; j++) {
|
||||
tag = cpu_brand_string + len;
|
||||
for (j = 0; j < cpu->listc; j++) {
|
||||
fql = &cpu->list[j];
|
||||
n = strlen(fql->brand_tag);
|
||||
if (!strncmp(fql->brand_tag, tag, n) &&
|
||||
!strcmp(cpu->brand_suffix, tag + n)) {
|
||||
len = strlen(fql->brand_tag);
|
||||
if (!strncmp(fql->brand_tag, tag, len) &&
|
||||
!strcmp(cpu->brand_suffix, tag + len)) {
|
||||
est_fqlist = fql;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (est_fqlist == NULL) {
|
||||
printf("%s: unknown EST cpu\n", ci->ci_dev->dv_xname);
|
||||
aprint_normal("%s: unknown %s CPU\n",
|
||||
ci->ci_dev->dv_xname, est_desc);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the current operating point is in our list.
|
||||
*/
|
||||
for (i = est_fqlist->n - 1; i >= 0; i--)
|
||||
for (i = est_fqlist->tablec - 1; i >= 0; i--)
|
||||
if (est_fqlist->table[i].mhz == mhz &&
|
||||
est_fqlist->table[i].mv == mv)
|
||||
break;
|
||||
if (i < 0) {
|
||||
printf("%s: EST operating point not in table\n",
|
||||
ci->ci_dev->dv_xname);
|
||||
aprint_normal("%s: %s operating point not in table\n",
|
||||
ci->ci_dev->dv_xname, est_desc);
|
||||
est_fqlist = NULL; /* flag as not functional */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, set the flag and tell the user the available frequencies.
|
||||
* OK, tell the user the available frequencies.
|
||||
*/
|
||||
i386_has_est = 1;
|
||||
printf("%s: available speeds: ", ci->ci_dev->dv_xname);
|
||||
for (i = 0; i < est_fqlist->n; i++)
|
||||
printf("%d%s", est_fqlist->table[i].mhz,
|
||||
i < est_fqlist->n - 1 ? ", " : " MHz\n");
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
est_get_target_fq()
|
||||
{
|
||||
return MSR2MHZ(rdmsr(MSR_PERF_CTL));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
est_set_target_fq(fq)
|
||||
int fq;
|
||||
{
|
||||
int i;
|
||||
u_int64_t msr;
|
||||
|
||||
if (est_fqlist == NULL)
|
||||
return EOPNOTSUPP;
|
||||
|
||||
for (i = est_fqlist->n - 1; i > 0; i--)
|
||||
if (est_fqlist->table[i].mhz >= fq)
|
||||
break;
|
||||
fq = est_fqlist->table[i].mhz;
|
||||
msr = (rdmsr(MSR_PERF_CTL) & ~0xffffULL) |
|
||||
MSRVALUE(est_fqlist->table[i].mhz, est_fqlist->table[i].mv);
|
||||
wrmsr(MSR_PERF_CTL, msr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
est_get_current_fq()
|
||||
{
|
||||
return MSR2MHZ(rdmsr(MSR_PERF_STATUS));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
est_get_min_fq()
|
||||
{
|
||||
if (est_fqlist == NULL)
|
||||
return 0;
|
||||
return est_fqlist->table[est_fqlist->n - 1].mhz;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
est_get_max_fq()
|
||||
{
|
||||
if (est_fqlist == NULL)
|
||||
return 0;
|
||||
return est_fqlist->table[0].mhz;
|
||||
freq_len = est_fqlist->tablec * (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++) {
|
||||
len += snprintf(freq_names + len, freq_len - len, "%d%s",
|
||||
est_fqlist->table[i].mhz,
|
||||
i < est_fqlist->tablec - 1 ? " " : "");
|
||||
}
|
||||
aprint_normal("%s: %s frequencies available (MHz): %s\n",
|
||||
ci->ci_dev->dv_xname, est_desc, freq_names);
|
||||
|
||||
/*
|
||||
* Setup the sysctl sub-tree machdep.est.*
|
||||
*/
|
||||
if ((rc = sysctl_createv(NULL, 0, NULL, &node,
|
||||
CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
|
||||
NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL)) != 0)
|
||||
goto err;
|
||||
|
||||
if ((rc = sysctl_createv(NULL, 0, &node, &estnode,
|
||||
0, CTLTYPE_NODE, "est", NULL,
|
||||
NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
|
||||
goto err;
|
||||
|
||||
if ((rc = sysctl_createv(NULL, 0, &estnode, &node,
|
||||
0, CTLTYPE_STRING, "cpu_brand", NULL,
|
||||
NULL, 0, &cpu_brand_string, 0, CTL_CREATE, CTL_EOL)) != 0)
|
||||
goto err;
|
||||
|
||||
if ((rc = sysctl_createv(NULL, 0, &estnode, &freqnode,
|
||||
0, CTLTYPE_NODE, "frequency", NULL,
|
||||
NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
|
||||
goto err;
|
||||
|
||||
if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
|
||||
CTLFLAG_READWRITE, CTLTYPE_INT, "target", NULL,
|
||||
est_sysctl_helper, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
|
||||
goto err;
|
||||
est_node_target = node->sysctl_num;
|
||||
|
||||
if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
|
||||
0, CTLTYPE_INT, "current", NULL,
|
||||
est_sysctl_helper, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
|
||||
goto err;
|
||||
est_node_current = node->sysctl_num;
|
||||
|
||||
if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
|
||||
0, CTLTYPE_STRING, "available", NULL,
|
||||
NULL, 0, freq_names, freq_len, CTL_CREATE, CTL_EOL)) != 0)
|
||||
goto err;
|
||||
|
||||
return;
|
||||
err:
|
||||
aprint_normal("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: identcpu.c,v 1.12 2004/04/22 00:34:52 itojun Exp $ */
|
||||
/* $NetBSD: identcpu.c,v 1.13 2004/04/30 02:05:43 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
|
||||
@ -37,9 +37,10 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.12 2004/04/22 00:34:52 itojun Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.13 2004/04/30 02:05:43 lukem Exp $");
|
||||
|
||||
#include "opt_cputype.h"
|
||||
#include "opt_enhanced_speedstep.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -126,6 +127,7 @@ static const char * const amd_brand[] = {
|
||||
};
|
||||
|
||||
u_int cpu_serial[3];
|
||||
char cpu_brand_string[49];
|
||||
static char amd_brand_name[48];
|
||||
|
||||
void cyrix6x86_cpu_setup(struct cpu_info *);
|
||||
@ -688,6 +690,7 @@ cpu_probe_base_features(struct cpu_info *ci)
|
||||
int iterations, i, j;
|
||||
u_int8_t desc;
|
||||
u_int32_t dummy1, dummy2, miscbytes;
|
||||
u_int32_t brand[12];
|
||||
|
||||
if (ci->ci_cpuid_level < 0)
|
||||
return;
|
||||
@ -698,10 +701,22 @@ cpu_probe_base_features(struct cpu_info *ci)
|
||||
ci->ci_vendor[1]);
|
||||
ci->ci_vendor[3] = 0;
|
||||
|
||||
CPUID(0x80000000, brand[0], brand[1], brand[2], brand[3]);
|
||||
if (brand[0] >= 0x80000004) {
|
||||
CPUID(0x80000002, brand[0], brand[1], brand[2], brand[3]);
|
||||
CPUID(0x80000003, brand[4], brand[5], brand[6], brand[7]);
|
||||
CPUID(0x80000004, brand[8], brand[9], brand[10], brand[11]);
|
||||
for (i = 0; i < 48; i++)
|
||||
if (((char *) brand)[i] != ' ')
|
||||
break;
|
||||
memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i);
|
||||
}
|
||||
|
||||
if (ci->ci_cpuid_level < 1)
|
||||
return;
|
||||
|
||||
CPUID(1, ci->ci_signature, miscbytes, dummy1, ci->ci_feature_flags);
|
||||
CPUID(1, ci->ci_signature, miscbytes, ci->ci_feature2_flags,
|
||||
ci->ci_feature_flags);
|
||||
|
||||
/* Brand is low order 8 bits of ebx */
|
||||
ci->ci_brand_id = miscbytes & 0xff;
|
||||
@ -797,7 +812,6 @@ amd_family6_probe(struct cpu_info *ci)
|
||||
{
|
||||
u_int32_t lfunc;
|
||||
u_int32_t descs[4];
|
||||
u_int32_t brand[12];
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
@ -811,15 +825,11 @@ amd_family6_probe(struct cpu_info *ci)
|
||||
ci->ci_feature_flags |= descs[3];
|
||||
}
|
||||
|
||||
if (lfunc < 0x80000004)
|
||||
if (*cpu_brand_string == '\0')
|
||||
return;
|
||||
|
||||
CPUID(0x80000002, brand[0], brand[1], brand[2], brand[3]);
|
||||
CPUID(0x80000003, brand[4], brand[5], brand[6], brand[7]);
|
||||
CPUID(0x80000004, brand[8], brand[9], brand[10], brand[11]);
|
||||
|
||||
for (i = 1; i < sizeof(amd_brand) / sizeof(amd_brand[0]); i++)
|
||||
if ((p = strstr((char *)brand, amd_brand[i])) != NULL) {
|
||||
if ((p = strstr(cpu_brand_string, amd_brand[i])) != NULL) {
|
||||
ci->ci_brand_id = i;
|
||||
strlcpy(amd_brand_name, p, sizeof(amd_brand_name));
|
||||
break;
|
||||
@ -1217,8 +1227,31 @@ identifycpu(struct cpu_info *ci)
|
||||
}
|
||||
}
|
||||
|
||||
if (ci->ci_feature2_flags) {
|
||||
bitmask_snprintf(ci->ci_feature2_flags,
|
||||
CPUID2_FLAGS, buf, sizeof(buf));
|
||||
printf("%s: features2 %s\n", cpuname, buf);
|
||||
}
|
||||
|
||||
if (*cpu_brand_string != '\0')
|
||||
printf("%s: \"%s\"\n", cpuname, cpu_brand_string);
|
||||
|
||||
x86_print_cacheinfo(ci);
|
||||
|
||||
if (cpu_feature & CPUID_TM) {
|
||||
if (rdmsr(MSR_MISC_ENABLE) & (1 << 3)) {
|
||||
if ((cpu_feature2 & CPUID2_TM2) &&
|
||||
(rdmsr(MSR_THERM2_CTL) & (1 << 16)))
|
||||
printf("%s: using thermal monitor 2\n",
|
||||
cpuname);
|
||||
else
|
||||
printf("%s: using thermal monitor 1\n",
|
||||
cpuname);
|
||||
} else
|
||||
printf("%s: running without thermal monitor!\n",
|
||||
cpuname);
|
||||
}
|
||||
|
||||
if (ci->ci_cpuid_level >= 3 && (ci->ci_feature_flags & CPUID_PN)) {
|
||||
printf("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n",
|
||||
cpuname,
|
||||
@ -1328,4 +1361,15 @@ identifycpu(struct cpu_info *ci)
|
||||
} else
|
||||
i386_use_fxsave = 0;
|
||||
#endif /* I686_CPU */
|
||||
|
||||
#ifdef ENHANCED_SPEEDSTEP
|
||||
if (cpu_feature2 & CPUID2_EST) {
|
||||
if (rdmsr(MSR_MISC_ENABLE) & (1 << 16))
|
||||
est_init(ci);
|
||||
else
|
||||
printf("%s: Enhanced SpeedStep disabled by BIOS\n",
|
||||
cpuname);
|
||||
}
|
||||
#endif /* ENHANCED_SPEEDSTEP */
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.552 2004/03/24 15:34:49 atatat Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.553 2004/04/30 02:05:43 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
|
||||
@ -72,7 +72,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.552 2004/03/24 15:34:49 atatat Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.553 2004/04/30 02:05:43 lukem Exp $");
|
||||
|
||||
#include "opt_beep.h"
|
||||
#include "opt_compat_ibcs2.h"
|
||||
@ -226,6 +226,7 @@ int physmem;
|
||||
int dumpmem_low;
|
||||
int dumpmem_high;
|
||||
unsigned int cpu_feature;
|
||||
unsigned int cpu_feature2;
|
||||
int cpu_class;
|
||||
int i386_fpu_present;
|
||||
int i386_fpu_exception;
|
||||
@ -1354,6 +1355,7 @@ init386(paddr_t first_avail)
|
||||
|
||||
cpu_probe_features(&cpu_info_primary);
|
||||
cpu_feature = cpu_info_primary.ci_feature_flags;
|
||||
cpu_feature2 = cpu_info_primary.ci_feature2_flags;
|
||||
|
||||
lwp0.l_addr = proc0paddr;
|
||||
cpu_info_primary.ci_curpcb = &lwp0.l_addr->u_pcb;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cpu.h,v 1.113 2004/02/20 17:35:01 yamt Exp $ */
|
||||
/* $NetBSD: cpu.h,v 1.114 2004/04/30 02:05:43 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
@ -118,7 +118,8 @@ struct cpu_info {
|
||||
|
||||
int32_t ci_cpuid_level;
|
||||
u_int32_t ci_signature; /* X86 cpuid type */
|
||||
u_int32_t ci_feature_flags;/* X86 CPUID feature bits */
|
||||
u_int32_t ci_feature_flags;/* X86 %edx CPUID feature bits */
|
||||
u_int32_t ci_feature2_flags;/* X86 %ecx CPUID feature bits */
|
||||
u_int32_t ci_cpu_class; /* CPU class */
|
||||
u_int32_t ci_brand_id; /* Intel brand id */
|
||||
u_int32_t ci_vendor[4]; /* vendor string */
|
||||
@ -338,8 +339,10 @@ struct cpu_cpuid_nameclass {
|
||||
extern int biosbasemem;
|
||||
extern int biosextmem;
|
||||
extern unsigned int cpu_feature;
|
||||
extern unsigned int cpu_feature2;
|
||||
extern int cpu;
|
||||
extern int cpu_class;
|
||||
extern char cpu_brand_string[];
|
||||
extern const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[];
|
||||
extern const struct cpu_cpuid_nameclass i386_cpuid_cpus[];
|
||||
|
||||
@ -430,6 +433,9 @@ 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 *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user