Add transmeta crusoe cpu support from toshi's fiva patches.
This commit is contained in:
parent
f809eb7333
commit
79f74a0b0f
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: machdep.c,v 1.460 2001/11/15 07:03:30 lukem Exp $ */
|
/* $NetBSD: machdep.c,v 1.461 2001/11/17 08:20:58 christos Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
|
* Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
|
||||||
@ -76,7 +76,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.460 2001/11/15 07:03:30 lukem Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.461 2001/11/17 08:20:58 christos Exp $");
|
||||||
|
|
||||||
#include "opt_cputype.h"
|
#include "opt_cputype.h"
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
@ -213,6 +213,8 @@ int i386_use_fxsave;
|
|||||||
int i386_has_sse;
|
int i386_has_sse;
|
||||||
int i386_has_sse2;
|
int i386_has_sse2;
|
||||||
|
|
||||||
|
int tmx86_has_longrun;
|
||||||
|
|
||||||
#define CPUID2FAMILY(cpuid) (((cpuid) >> 8) & 15)
|
#define CPUID2FAMILY(cpuid) (((cpuid) >> 8) & 15)
|
||||||
#define CPUID2MODEL(cpuid) (((cpuid) >> 4) & 15)
|
#define CPUID2MODEL(cpuid) (((cpuid) >> 4) & 15)
|
||||||
#define CPUID2STEPPING(cpuid) ((cpuid) & 15)
|
#define CPUID2STEPPING(cpuid) ((cpuid) & 15)
|
||||||
@ -273,6 +275,7 @@ static int exec_nomid __P((struct proc *, struct exec_package *));
|
|||||||
void cyrix6x86_cpu_setup __P((void));
|
void cyrix6x86_cpu_setup __P((void));
|
||||||
void winchip_cpu_setup __P((void));
|
void winchip_cpu_setup __P((void));
|
||||||
void amd_family5_setup __P((void));
|
void amd_family5_setup __P((void));
|
||||||
|
void transmeta_cpu_setup __P((void));
|
||||||
|
|
||||||
void intel_cpuid_cpu_cacheinfo __P((struct cpu_info *));
|
void intel_cpuid_cpu_cacheinfo __P((struct cpu_info *));
|
||||||
void amd_cpuid_cpu_cacheinfo __P((struct cpu_info *));
|
void amd_cpuid_cpu_cacheinfo __P((struct cpu_info *));
|
||||||
@ -883,6 +886,55 @@ const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = {
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
} }
|
} }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GenuineTMx86",
|
||||||
|
CPUVENDOR_TRANSMETA,
|
||||||
|
"Transmeta",
|
||||||
|
/* Family 4, Transmeta never had any of these */
|
||||||
|
{ {
|
||||||
|
CPUCLASS_486,
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
"486 compatible" /* Default */
|
||||||
|
},
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
/* Family 5 */
|
||||||
|
{
|
||||||
|
CPUCLASS_586,
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
"Crusoe" /* Default */
|
||||||
|
},
|
||||||
|
transmeta_cpu_setup,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
/* Family 6, not yet available from Transmeta */
|
||||||
|
{
|
||||||
|
CPUCLASS_686,
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
"Pentium Pro compatible" /* Default */
|
||||||
|
},
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
/* Family > 6, not yet available from Transmeta */
|
||||||
|
{
|
||||||
|
CPUCLASS_686,
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
"Pentium Pro compatible" /* Default */
|
||||||
|
},
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
} }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -978,6 +1030,178 @@ amd_family5_setup(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transmeta Crusoe LongRun Support by Tamotsu Hattori.
|
||||||
|
* Port from FreeBSD-current(August, 2001) to NetBSD by tshiozak.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MSR_TMx86_LONGRUN 0x80868010
|
||||||
|
#define MSR_TMx86_LONGRUN_FLAGS 0x80868011
|
||||||
|
|
||||||
|
#define LONGRUN_MODE_MASK(x) ((x) & 0x000000007f)
|
||||||
|
#define LONGRUN_MODE_RESERVED(x) ((x) & 0xffffff80)
|
||||||
|
#define LONGRUN_MODE_WRITE(x, y) (LONGRUN_MODE_RESERVED(x) | LONGRUN_MODE_MASK(y))
|
||||||
|
|
||||||
|
#define LONGRUN_MODE_MINFREQUENCY 0x00
|
||||||
|
#define LONGRUN_MODE_ECONOMY 0x01
|
||||||
|
#define LONGRUN_MODE_PERFORMANCE 0x02
|
||||||
|
#define LONGRUN_MODE_MAXFREQUENCY 0x03
|
||||||
|
#define LONGRUN_MODE_UNKNOWN 0x04
|
||||||
|
#define LONGRUN_MODE_MAX 0x04
|
||||||
|
|
||||||
|
union msrinfo {
|
||||||
|
u_int64_t msr;
|
||||||
|
u_int32_t regs[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
u_int32_t longrun_modes[LONGRUN_MODE_MAX][3] = {
|
||||||
|
/* MSR low, MSR high, flags bit0 */
|
||||||
|
{ 0, 0, 0}, /* LONGRUN_MODE_MINFREQUENCY */
|
||||||
|
{ 0, 100, 0}, /* LONGRUN_MODE_ECONOMY */
|
||||||
|
{ 0, 100, 1}, /* LONGRUN_MODE_PERFORMANCE */
|
||||||
|
{ 100, 100, 1}, /* LONGRUN_MODE_MAXFREQUENCY */
|
||||||
|
};
|
||||||
|
|
||||||
|
static u_int
|
||||||
|
tmx86_get_longrun_mode(void)
|
||||||
|
{
|
||||||
|
u_long eflags;
|
||||||
|
union msrinfo msrinfo;
|
||||||
|
u_int low, high, flags, mode;
|
||||||
|
|
||||||
|
eflags = read_eflags();
|
||||||
|
disable_intr();
|
||||||
|
|
||||||
|
msrinfo.msr = rdmsr(MSR_TMx86_LONGRUN);
|
||||||
|
low = LONGRUN_MODE_MASK(msrinfo.regs[0]);
|
||||||
|
high = LONGRUN_MODE_MASK(msrinfo.regs[1]);
|
||||||
|
flags = rdmsr(MSR_TMx86_LONGRUN_FLAGS) & 0x01;
|
||||||
|
|
||||||
|
for (mode = 0; mode < LONGRUN_MODE_MAX; mode++) {
|
||||||
|
if (low == longrun_modes[mode][0] &&
|
||||||
|
high == longrun_modes[mode][1] &&
|
||||||
|
flags == longrun_modes[mode][2]) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mode = LONGRUN_MODE_UNKNOWN;
|
||||||
|
out:
|
||||||
|
write_eflags(eflags);
|
||||||
|
return (mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u_int
|
||||||
|
tmx86_get_longrun_status(u_int * frequency, u_int * voltage, u_int * percentage)
|
||||||
|
{
|
||||||
|
u_long eflags;
|
||||||
|
u_int regs[4];
|
||||||
|
|
||||||
|
eflags = read_eflags();
|
||||||
|
disable_intr();
|
||||||
|
|
||||||
|
do_cpuid(0x80860007, regs);
|
||||||
|
*frequency = regs[0];
|
||||||
|
*voltage = regs[1];
|
||||||
|
*percentage = regs[2];
|
||||||
|
|
||||||
|
write_eflags(eflags);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u_int
|
||||||
|
tmx86_set_longrun_mode(u_int mode)
|
||||||
|
{
|
||||||
|
u_long eflags;
|
||||||
|
union msrinfo msrinfo;
|
||||||
|
|
||||||
|
if (mode >= LONGRUN_MODE_UNKNOWN) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
eflags = read_eflags();
|
||||||
|
disable_intr();
|
||||||
|
|
||||||
|
/* Write LongRun mode values to Model Specific Register. */
|
||||||
|
msrinfo.msr = rdmsr(MSR_TMx86_LONGRUN);
|
||||||
|
msrinfo.regs[0] = LONGRUN_MODE_WRITE(msrinfo.regs[0],
|
||||||
|
longrun_modes[mode][0]);
|
||||||
|
msrinfo.regs[1] = LONGRUN_MODE_WRITE(msrinfo.regs[1],
|
||||||
|
longrun_modes[mode][1]);
|
||||||
|
wrmsr(MSR_TMx86_LONGRUN, msrinfo.msr);
|
||||||
|
|
||||||
|
/* Write LongRun mode flags to Model Specific Register. */
|
||||||
|
msrinfo.msr = rdmsr(MSR_TMx86_LONGRUN_FLAGS);
|
||||||
|
msrinfo.regs[0] = (msrinfo.regs[0] & ~0x01) | longrun_modes[mode][2];
|
||||||
|
wrmsr(MSR_TMx86_LONGRUN_FLAGS, msrinfo.msr);
|
||||||
|
|
||||||
|
write_eflags(eflags);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u_int crusoe_longrun;
|
||||||
|
static u_int crusoe_frequency;
|
||||||
|
static u_int crusoe_voltage;
|
||||||
|
static u_int crusoe_percentage;
|
||||||
|
|
||||||
|
static void
|
||||||
|
tmx86_get_longrun_status_all(void)
|
||||||
|
{
|
||||||
|
tmx86_get_longrun_status(&crusoe_frequency,
|
||||||
|
&crusoe_voltage, &crusoe_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_transmeta_info(void)
|
||||||
|
{
|
||||||
|
u_int regs[4], nreg = 0;
|
||||||
|
|
||||||
|
do_cpuid(0x80860000, regs);
|
||||||
|
nreg = regs[0];
|
||||||
|
if (nreg >= 0x80860001) {
|
||||||
|
do_cpuid(0x80860001, regs);
|
||||||
|
printf(" Processor revision %u.%u.%u.%u\n",
|
||||||
|
(regs[1] >> 24) & 0xff,
|
||||||
|
(regs[1] >> 16) & 0xff,
|
||||||
|
(regs[1] >> 8) & 0xff,
|
||||||
|
regs[1] & 0xff);
|
||||||
|
}
|
||||||
|
if (nreg >= 0x80860002) {
|
||||||
|
do_cpuid(0x80860002, regs);
|
||||||
|
printf(" Code Morphing Software revision %u.%u.%u-%u-%u\n",
|
||||||
|
(regs[1] >> 24) & 0xff,
|
||||||
|
(regs[1] >> 16) & 0xff,
|
||||||
|
(regs[1] >> 8) & 0xff,
|
||||||
|
regs[1] & 0xff,
|
||||||
|
regs[2]);
|
||||||
|
}
|
||||||
|
if (nreg >= 0x80860006) {
|
||||||
|
char info[65];
|
||||||
|
do_cpuid(0x80860003, (u_int*) &info[0]);
|
||||||
|
do_cpuid(0x80860004, (u_int*) &info[16]);
|
||||||
|
do_cpuid(0x80860005, (u_int*) &info[32]);
|
||||||
|
do_cpuid(0x80860006, (u_int*) &info[48]);
|
||||||
|
info[64] = 0;
|
||||||
|
printf(" %s\n", info);
|
||||||
|
}
|
||||||
|
|
||||||
|
crusoe_longrun = tmx86_get_longrun_mode();
|
||||||
|
tmx86_get_longrun_status(&crusoe_frequency,
|
||||||
|
&crusoe_voltage, &crusoe_percentage);
|
||||||
|
printf(" LongRun mode: %d <%dMHz %dmV %d%%>\n", crusoe_longrun,
|
||||||
|
crusoe_frequency, crusoe_voltage, crusoe_percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
transmeta_cpu_setup(void)
|
||||||
|
{
|
||||||
|
tmx86_has_longrun = 1;
|
||||||
|
print_transmeta_info();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
static const struct i386_cache_info *
|
static const struct i386_cache_info *
|
||||||
cache_info_lookup(const struct i386_cache_info *cai, int count, u_int8_t desc)
|
cache_info_lookup(const struct i386_cache_info *cai, int count, u_int8_t desc)
|
||||||
{
|
{
|
||||||
@ -1597,6 +1821,7 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
|
|||||||
{
|
{
|
||||||
dev_t consdev;
|
dev_t consdev;
|
||||||
struct btinfo_bootpath *bibp;
|
struct btinfo_bootpath *bibp;
|
||||||
|
int error, mode;
|
||||||
|
|
||||||
/* all sysctl names at this level are terminal */
|
/* all sysctl names at this level are terminal */
|
||||||
if (namelen != 1)
|
if (namelen != 1)
|
||||||
@ -1640,7 +1865,34 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
|
|||||||
return (sysctl_rdint(oldp, oldlenp, newp, i386_has_sse));
|
return (sysctl_rdint(oldp, oldlenp, newp, i386_has_sse));
|
||||||
case CPU_SSE2:
|
case CPU_SSE2:
|
||||||
return (sysctl_rdint(oldp, oldlenp, newp, i386_has_sse2));
|
return (sysctl_rdint(oldp, oldlenp, newp, i386_has_sse2));
|
||||||
|
case CPU_TMLR_MODE:
|
||||||
|
if (!tmx86_has_longrun)
|
||||||
|
return (EOPNOTSUPP);
|
||||||
|
mode = (int)(crusoe_longrun = tmx86_get_longrun_mode());
|
||||||
|
error = sysctl_int(oldp, oldlenp, newp, newlen, &mode);
|
||||||
|
if (!error && (u_int)mode!=crusoe_longrun) {
|
||||||
|
if (tmx86_set_longrun_mode(mode)) {
|
||||||
|
crusoe_longrun = (u_int)mode;
|
||||||
|
} else {
|
||||||
|
error = EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (error);
|
||||||
|
case CPU_TMLR_FREQUENCY:
|
||||||
|
if (!tmx86_has_longrun)
|
||||||
|
return (EOPNOTSUPP);
|
||||||
|
tmx86_get_longrun_status_all();
|
||||||
|
return (sysctl_rdint(oldp, oldlenp, newp, crusoe_frequency));
|
||||||
|
case CPU_TMLR_VOLTAGE:
|
||||||
|
if (!tmx86_has_longrun)
|
||||||
|
return (EOPNOTSUPP);
|
||||||
|
tmx86_get_longrun_status_all();
|
||||||
|
return (sysctl_rdint(oldp, oldlenp, newp, crusoe_voltage));
|
||||||
|
case CPU_TMLR_PERCENTAGE:
|
||||||
|
if (!tmx86_has_longrun)
|
||||||
|
return (EOPNOTSUPP);
|
||||||
|
tmx86_get_longrun_status_all();
|
||||||
|
return (sysctl_rdint(oldp, oldlenp, newp, crusoe_percentage));
|
||||||
default:
|
default:
|
||||||
return (EOPNOTSUPP);
|
return (EOPNOTSUPP);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user