* Do not change struct powernow_pst_s (I added another member in my

previous patch) and this MUST be of that size, otherwise the tables
  won't be found.

* powernow_k8.c moved into x86/x86, it should work both i386 and amd64.

* Added more DPRINTFs needed to found the first problem.

* Create "machdep.powernow.frequency" again, I can't remember why I
  removed frequency... it should work with estd now.

* Do not try to call k[78]_powernow_init() if cpu is not AMD (thanks
  to christos).

And more things I can't remember, but this time it will work in
Athlon 64 cpus and it won't crash in EM64T cpus.
This commit is contained in:
xtraeme 2006-08-07 20:58:23 +00:00
parent 5145dd52fa
commit a4a1d218d3
8 changed files with 108 additions and 61 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: identcpu.c,v 1.5 2006/08/06 15:37:21 xtraeme Exp $ */
/* $NetBSD: identcpu.c,v 1.6 2006/08/07 20:58:23 xtraeme Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.5 2006/08/06 15:37:21 xtraeme Exp $");
__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.6 2006/08/07 20:58:23 xtraeme Exp $");
#include "opt_powernow_k8.h"
@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.5 2006/08/06 15:37:21 xtraeme Exp $")
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <x86/include/cpuvar.h>
#include <x86/include/powernow.h>
/* sysctl wants this. */
@ -102,15 +103,16 @@ identifycpu(struct cpu_info *ci)
x86_print_cacheinfo(ci);
#ifdef POWERNOW_K8
uint32_t rval;
int featflag;
rval = powernow_probe(ci, 0xf00);
if (rval) {
featflag = powernow_extflags(ci, rval);
if (featflag)
k8_powernow_init();
if (cpu_model[0] == 'A' || cpu_model[0] == 'O') {
uint32_t rval;
uint8_t featflag;
rval = powernow_probe(ci, 0xf00);
if (rval) {
featflag = powernow_extflags(ci, rval);
if (featflag)
k8_powernow_init();
}
}
#endif
}

View File

@ -1,4 +1,4 @@
# $NetBSD: files.amd64,v 1.26 2006/08/06 15:37:21 xtraeme Exp $
# $NetBSD: files.amd64,v 1.27 2006/08/07 20:58:23 xtraeme Exp $
#
# new style config file for amd64 architecture
#
@ -17,10 +17,6 @@ defflag LARGEPAGES
# The REAL{BASE,EXT}MEM options
defparam opt_realmem.h REALBASEMEM REALEXTMEM
# AMD Powernow/Cool`n'Quiet Technology
defflag opt_powernow_k8.h POWERNOW_K8
#
# XXX these are just here at the moment so that we can share files
# with the i386 (they include the opt_*.h for these)
@ -38,7 +34,6 @@ file arch/amd64/amd64/db_trace.c ddb
file arch/amd64/amd64/kgdb_machdep.c kgdb
file kern/subr_disk_mbr.c disk
file arch/amd64/amd64/gdt.c
file arch/amd64/amd64/powernow_k8.c powernow_k8
#
# XXXfvdl write the optimized versions for these.
#

View File

@ -1,4 +1,4 @@
/* $NetBSD: identcpu.c,v 1.35 2006/08/07 17:41:54 oster Exp $ */
/* $NetBSD: identcpu.c,v 1.36 2006/08/07 20:58:23 xtraeme Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -37,11 +37,12 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.35 2006/08/07 17:41:54 oster Exp $");
__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.36 2006/08/07 20:58:23 xtraeme Exp $");
#include "opt_cputype.h"
#include "opt_enhanced_speedstep.h"
#include "opt_powernow_k7.h"
#include "opt_powernow_k8.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -53,6 +54,8 @@ __KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.35 2006/08/07 17:41:54 oster Exp $");
#include <machine/pio.h>
#include <machine/cpu.h>
#include <x86/cacheinfo.h>
#include <x86/include/cpuvar.h>
#include <x86/include/powernow.h>
static const struct x86_cache_info
intel_cpuid_cache_info[] = {
@ -1446,17 +1449,26 @@ identifycpu(struct cpu_info *ci)
}
#endif /* ENHANCED_SPEEDSTEP */
#ifdef POWERNOW_K7
#include <x86/include/powernow.h>
uint32_t rval;
int featflag;
#if defined(POWERNOW_K7) || defined(POWERNOW_K8)
if (vendor == CPUVENDOR_AMD) {
uint32_t rval;
uint8_t featflag;
rval = powernow_probe(ci, 0x600);
if (rval) {
featflag = powernow_extflags(ci, rval);
if (featflag)
k7_powernow_init();
rval = powernow_probe(ci, 0x600);
if (rval) {
featflag = powernow_extflags(ci, rval);
switch (featflag) {
case 6:
k7_powernow_init();
break;
case 15:
k8_powernow_init();
break;
default:
break;
}
}
}
#endif /* POWERNOW_K7 */
#endif /* POWERNOW_K7 || POWERNOW_K8 */
}

View File

@ -1,4 +1,4 @@
# $NetBSD: files.x86,v 1.18 2006/08/06 15:37:21 xtraeme Exp $
# $NetBSD: files.x86,v 1.19 2006/08/07 20:58:23 xtraeme Exp $
# options for MP configuration through the MP spec
defflag opt_mpbios.h MPBIOS MPVERBOSE MPDEBUG MPBIOS_SCANPCI
@ -10,6 +10,9 @@ defflag MTRR
defflag opt_pcifixup.h PCI_ADDR_FIXUP PCI_BUS_FIXUP
PCI_INTR_FIXUP PCI_INTR_FIXUP_FORCE
# AMD Powernow/Cool`n'Quiet Technology
defflag opt_powernow_k8.h POWERNOW_K8
define cpubus { [apid = -1] }
file arch/x86/x86/apic.c ioapic | lapic
@ -49,4 +52,5 @@ file arch/x86/isa/isa_machdep.c isa
file arch/x86/pci/pciide_machdep.c pciide_common
# Powernow common functions
file arch/x86/x86/powernow_k8.c powernow_k8
file arch/x86/x86/powernow_common.c powernow_k8 | powernow_k7

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpuvar.h,v 1.3 2003/10/27 13:43:48 junyoung Exp $ */
/* $NetBSD: cpuvar.h,v 1.4 2006/08/07 20:58:23 xtraeme Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -107,4 +107,10 @@ void identifycpu(struct cpu_info *);
void cpu_init(struct cpu_info *);
void cpu_init_first(void);
#include "opt_powernow_k8.h"
#ifdef POWERNOW_K8
void k8_powernow_init(void);
#endif
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: powernow.h,v 1.1 2006/08/06 15:37:21 xtraeme Exp $ */
/* $NetBSD: powernow.h,v 1.2 2006/08/07 20:58:23 xtraeme Exp $ */
/*-
* Copyright (c) 2004 Martin Végiard.
@ -140,22 +140,21 @@
#define POWERNOW_MAX_STATES 16
struct powernow_state {
unsigned int freq;
int freq;
uint8_t fid;
uint8_t vid;
};
struct powernow_cpu_state {
struct powernow_state state_table[POWERNOW_MAX_STATES];
unsigned int flags;
unsigned int fsb;
unsigned int irt;
unsigned int mvs;
unsigned int n_states;
unsigned int pll;
unsigned int rvo;
unsigned int sgtc;
unsigned int vst;
unsigned int mvs;
unsigned int pll;
unsigned int rvo;
unsigned int irt;
int low;
};
@ -170,7 +169,6 @@ struct powernow_psb_s {
struct powernow_pst_s {
uint32_t signature;
uint8_t fsb;
uint8_t pll;
uint8_t fid;
uint8_t vid;

View File

@ -1,4 +1,4 @@
/* $NetBSD: powernow_common.c,v 1.1 2006/08/06 15:37:21 xtraeme Exp $ */
/* $NetBSD: powernow_common.c,v 1.2 2006/08/07 20:58:23 xtraeme Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: powernow_common.c,v 1.1 2006/08/06 15:37:21 xtraeme Exp $");
__KERNEL_RCSID(0, "$NetBSD: powernow_common.c,v 1.2 2006/08/07 20:58:23 xtraeme Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -93,9 +93,12 @@ powernow_probe(struct cpu_info *ci, uint32_t val)
int
powernow_extflags(struct cpu_info *ci, uint32_t feature_flag)
{
int j;
int family, j, rval;
char *cpuname;
rval = 0;
family = (ci->ci_signature >> 8) & 15;
cpuname = ci->ci_dev->dv_xname;
/* Print out available cpuid extended features. */
@ -111,8 +114,19 @@ powernow_extflags(struct cpu_info *ci, uint32_t feature_flag)
* are available, it's ok to continue enabling powernow.
*/
if ((feature_flag & pnow_extflag[1].mask) &&
(feature_flag & pnow_extflag[2].mask))
return 1;
(feature_flag & pnow_extflag[2].mask)) {
switch (family) {
case 6:
rval = 6;
break;
case 15:
rval = 15;
break;
default:
rval = 0;
break;
}
}
return 0;
return rval;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: powernow_k8.c,v 1.3 2006/08/07 11:39:30 cube Exp $ */
/* $NetBSD: powernow_k8.c,v 1.1 2006/08/07 20:58:23 xtraeme Exp $ */
/* $OpenBSD: powernow-k8.c,v 1.8 2006/06/16 05:58:50 gwk Exp $ */
/*-
@ -89,7 +89,7 @@
/* AMD POWERNOW K8 driver */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: powernow_k8.c,v 1.3 2006/08/07 11:39:30 cube Exp $");
__KERNEL_RCSID(0, "$NetBSD: powernow_k8.c,v 1.1 2006/08/07 20:58:23 xtraeme Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -97,6 +97,7 @@ __KERNEL_RCSID(0, "$NetBSD: powernow_k8.c,v 1.3 2006/08/07 11:39:30 cube Exp $")
#include <sys/malloc.h>
#include <sys/sysctl.h>
#include <x86/include/cpuvar.h>
#include <x86/include/powernow.h>
#include <dev/isa/isareg.h>
@ -318,9 +319,12 @@ k8pnow_states(struct powernow_cpu_state *cstate, uint32_t cpusig,
uint8_t *p;
int i;
DPRINTF(("%s: before the for loop\n", __func__));
for (p = (uint8_t *)ISA_HOLE_VADDR(BIOS_START);
p < (uint8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN); p += 16) {
if (memcmp(p, "AMDK7PNOW!", 10) == 0) {
DPRINTF(("%s: inside the for loop\n", __func__));
psb = (struct powernow_psb_s *)p;
if (psb->version != 0x14) {
DPRINTF(("%s: psb->version != 0x14\n",
@ -342,15 +346,18 @@ k8pnow_states(struct powernow_cpu_state *cstate, uint32_t cpusig,
cstate->n_states = pst->n_states;
if (cpusig == pst->signature &&
pst->fid == fid && pst->vid == vid) {
DPRINTF(("%s: cpusig = signature\n",
__func__));
return (k8pnow_decode_pst(cstate,
p+= sizeof(struct powernow_pst_s)));
}
p += sizeof(struct powernow_pst_s) + 2 *
cstate->n_states;
p += sizeof(struct powernow_pst_s) +
2 * cstate->n_states;
}
}
}
DPRINTF(("%s: returns 0!\n", __func__));
return 0;
}
@ -360,7 +367,7 @@ k8_powernow_init(void)
{
uint64_t status;
uint32_t maxfid, maxvid, i;
const struct sysctlnode *node, *pnownode;
const struct sysctlnode *freqnode, *node, *pnownode;
struct powernow_cpu_state *cstate;
struct cpu_info *ci;
char *cpuname;
@ -416,9 +423,11 @@ k8_powernow_init(void)
k8pnow_current_state = cstate;
DPRINTF(("%s: freq_names=%s\n", __func__, freq_names));
}
}
} else
DPRINTF(("%s: returned 0!\n", __func__));
if (k8pnow_current_state == NULL) {
DPRINTF(("%s: k8pnow_current_state is NULL!\n", __func__));
free(cstate, M_DEVBUF);
if (freq_names)
free(freq_names, M_SYSCTLDATA);
@ -426,43 +435,50 @@ k8_powernow_init(void)
}
/* Create sysctl machdep.powernow.frequency. */
if ((sysctl_createv(NULL, 0, NULL, &node,
if (sysctl_createv(NULL, 0, NULL, &node,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "machdep", NULL,
NULL, 0, NULL, 0,
CTL_MACHDEP, CTL_EOL)) != 0)
CTL_MACHDEP, CTL_EOL) != 0)
goto err;
if ((sysctl_createv(NULL, 0, &node, &pnownode,
if (sysctl_createv(NULL, 0, &node, &pnownode,
0,
CTLTYPE_NODE, "powernow", NULL,
NULL, 0, NULL, 0,
CTL_CREATE, CTL_EOL)) != 0)
CTL_CREATE, CTL_EOL) != 0)
goto err;
if ((sysctl_createv(NULL, 0, &pnownode, &node,
if (sysctl_createv(NULL, 0, &pnownode, &freqnode,
0,
CTLTYPE_NODE, "frequency", NULL,
NULL, 0, NULL, 0,
CTL_CREATE, CTL_EOL) != 0)
goto err;
if (sysctl_createv(NULL, 0, &freqnode, &node,
CTLFLAG_READWRITE,
CTLTYPE_INT, "target", NULL,
k8pnow_sysctl_helper, 0, NULL, 0,
CTL_CREATE, CTL_EOL)) != 0)
CTL_CREATE, CTL_EOL) != 0)
goto err;
powernow_node_target = node->sysctl_num;
if ((sysctl_createv(NULL, 0, &pnownode, &node,
if (sysctl_createv(NULL, 0, &freqnode, &node,
0,
CTLTYPE_INT, "current", NULL,
k8pnow_sysctl_helper, 0, NULL, 0,
CTL_CREATE, CTL_EOL)) != 0)
CTL_CREATE, CTL_EOL) != 0)
goto err;
powernow_node_current = node->sysctl_num;
if ((sysctl_createv(NULL, 0, &pnownode, &node,
if (sysctl_createv(NULL, 0, &pnownode, &node,
0,
CTLTYPE_STRING, "available", NULL,
NULL, 0, freq_names, freq_names_len,
CTL_CREATE, CTL_EOL)) != 0)
CTL_CREATE, CTL_EOL) != 0)
goto err;
cur_freq = cstate->state_table[cstate->n_states-1].freq;