Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/i386/i386 Add transmeta crusoe cpu support from tos...
details: https://anonhg.NetBSD.org/src/rev/8da91a79ffd7
branches: trunk
changeset: 517694:8da91a79ffd7
user: christos <christos%NetBSD.org@localhost>
date: Sat Nov 17 08:20:58 2001 +0000
description:
Add transmeta crusoe cpu support from toshi's fiva patches.
diffstat:
sys/arch/i386/i386/machdep.c | 258 ++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 255 insertions(+), 3 deletions(-)
diffs (truncated from 314 to 300 lines):
diff -r bf0d20343acf -r 8da91a79ffd7 sys/arch/i386/i386/machdep.c
--- a/sys/arch/i386/i386/machdep.c Sat Nov 17 07:22:34 2001 +0000
+++ b/sys/arch/i386/i386/machdep.c Sat Nov 17 08:20:58 2001 +0000
@@ -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.
@@ -76,7 +76,7 @@
*/
#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_ddb.h"
@@ -213,6 +213,8 @@
int i386_has_sse;
int i386_has_sse2;
+int tmx86_has_longrun;
+
#define CPUID2FAMILY(cpuid) (((cpuid) >> 8) & 15)
#define CPUID2MODEL(cpuid) (((cpuid) >> 4) & 15)
#define CPUID2STEPPING(cpuid) ((cpuid) & 15)
@@ -273,6 +275,7 @@
void cyrix6x86_cpu_setup __P((void));
void winchip_cpu_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 amd_cpuid_cpu_cacheinfo __P((struct cpu_info *));
@@ -883,6 +886,55 @@
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 @@
}
}
+/*
+ * 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 *
cache_info_lookup(const struct i386_cache_info *cai, int count, u_int8_t desc)
{
@@ -1597,6 +1821,7 @@
{
dev_t consdev;
struct btinfo_bootpath *bibp;
+ int error, mode;
/* all sysctl names at this level are terminal */
if (namelen != 1)
@@ -1640,7 +1865,34 @@
return (sysctl_rdint(oldp, oldlenp, newp, i386_has_sse));
case CPU_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();
Home |
Main Index |
Thread Index |
Old Index