diff options
author | Christiano F. Haesbaert <haesbaert@cvs.openbsd.org> | 2012-03-27 02:23:05 +0000 |
---|---|---|
committer | Christiano F. Haesbaert <haesbaert@cvs.openbsd.org> | 2012-03-27 02:23:05 +0000 |
commit | 0e32e73a6835575f1f36a6b27373b8a96a360215 (patch) | |
tree | 985f8856a489b2319f3022c02e226c3da4117874 | |
parent | 919b507fdda291edc718813bd18ccbe28f5961b1 (diff) |
Run identifycpu() on its own cpu.
Discussed with many on hackers.
"Go ahead" kettenis@
"Get to it" deraadt@
-rw-r--r-- | sys/arch/amd64/amd64/cpu.c | 27 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/identcpu.c | 83 | ||||
-rw-r--r-- | sys/arch/amd64/include/cpu.h | 5 |
3 files changed, 70 insertions, 45 deletions
diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c index f8b442bce7a..b81deb3ebf5 100644 --- a/sys/arch/amd64/amd64/cpu.c +++ b/sys/arch/amd64/amd64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.45 2012/02/25 00:12:07 haesbaert Exp $ */ +/* $OpenBSD: cpu.c,v 1.46 2012/03/27 02:23:04 haesbaert Exp $ */ /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -333,7 +333,6 @@ cpu_attach(struct device *parent, struct device *self, void *aux) cpu_start_secondary(ci); ncpus++; if (ci->ci_flags & CPUF_PRESENT) { - identifycpu(ci); ci->ci_next = cpu_info_list->ci_next; cpu_info_list->ci_next = ci; } @@ -446,6 +445,17 @@ cpu_start_secondary(struct cpu_info *ci) #endif } + atomic_setbits_int(&ci->ci_flags, CPUF_IDENTIFY); + + /* + * wait for it to identify + */ + for (i = 100000; (ci->ci_flags & CPUF_IDENTIFY) && i > 0; i--) + delay(10); + + if (ci->ci_flags & CPUF_IDENTIFY) + printf("%s: failed to identify\n", ci->ci_dev->dv_xname); + CPU_START_CLEANUP(ci); } @@ -484,9 +494,6 @@ cpu_hatch(void *v) cpu_init_msrs(ci); - cpu_probe_features(ci); - cpu_feature &= ci->ci_feature_flags; - #ifdef DEBUG if (ci->ci_flags & CPUF_PRESENT) panic("%s: already running!?", ci->ci_dev->dv_xname); @@ -497,6 +504,16 @@ cpu_hatch(void *v) lapic_enable(); lapic_startclock(); + /* We need to wait until we can identify, otherwise dmesg output + * will be messy. */ + while ((ci->ci_flags & CPUF_IDENTIFY) == 0) + delay(10); + + identifycpu(ci); + + /* Signal we're done */ + atomic_clearbits_int(&ci->ci_flags, CPUF_IDENTIFY); + while ((ci->ci_flags & CPUF_GO) == 0) delay(10); #ifdef DEBUG diff --git a/sys/arch/amd64/amd64/identcpu.c b/sys/arch/amd64/amd64/identcpu.c index 8f99571c75b..77436353af2 100644 --- a/sys/arch/amd64/amd64/identcpu.c +++ b/sys/arch/amd64/amd64/identcpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: identcpu.c,v 1.34 2012/01/08 14:39:26 haesbaert Exp $ */ +/* $OpenBSD: identcpu.c,v 1.35 2012/03/27 02:23:04 haesbaert Exp $ */ /* $NetBSD: identcpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ /* @@ -303,26 +303,31 @@ identifycpu(struct cpu_info *ci) u_int32_t dummy, val, pnfeatset; u_int32_t brand[12]; u_int32_t vendor[4]; + char mycpu_model[48]; int i, max; char *brandstr_from, *brandstr_to; int skipspace; CPUID(1, ci->ci_signature, val, dummy, ci->ci_feature_flags); CPUID(0x80000000, pnfeatset, dummy, dummy, dummy); - if (pnfeatset >= 0x80000001) + if (pnfeatset >= 0x80000001) { + u_int32_t ecx; + CPUID(0x80000001, dummy, dummy, - ecpu_ecxfeature, ci->ci_feature_eflags); + ecx, ci->ci_feature_eflags); + if (ci->ci_flags & CPUF_PRIMARY) + ecpu_ecxfeature = ecx; + /* Let cpu_fature be the common bits */ + cpu_feature &= ci->ci_feature_flags; + } - vendor[3] = 0; - CPUID(0, dummy, vendor[0], vendor[2], vendor[1]); /* yup, 0 2 1 */ 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]); + strlcpy(mycpu_model, (char *)brand, sizeof(mycpu_model)); - strlcpy(cpu_model, (char *)brand, sizeof(cpu_model)); - - /* Remove leading and duplicated spaces from cpu_model */ - brandstr_from = brandstr_to = cpu_model; + /* Remove leading and duplicated spaces from mycpu_model */ + brandstr_from = brandstr_to = mycpu_model; skipspace = 1; while (*brandstr_from != '\0') { if (!skipspace || *brandstr_from != ' ') { @@ -335,8 +340,13 @@ identifycpu(struct cpu_info *ci) } *brandstr_to = '\0'; - if (cpu_model[0] == 0) - strlcpy(cpu_model, "Opteron or Athlon 64", sizeof(cpu_model)); + if (mycpu_model[0] == 0) + strlcpy(mycpu_model, "Opteron or Athlon 64", + sizeof(mycpu_model)); + + /* If primary cpu, fill in the global cpu_model used by sysctl */ + if (ci->ci_flags & CPUF_PRIMARY) + strlcpy(cpu_model, mycpu_model, sizeof(cpu_model)); ci->ci_family = (ci->ci_signature >> 8) & 0x0f; ci->ci_model = (ci->ci_signature >> 4) & 0x0f; @@ -351,13 +361,16 @@ identifycpu(struct cpu_info *ci) amd_cpu_cacheinfo(ci); - printf("%s: %s", ci->ci_dev->dv_xname, cpu_model); + printf("%s: %s", ci->ci_dev->dv_xname, mycpu_model); if (ci->ci_tsc_freq != 0) printf(", %lu.%02lu MHz", (ci->ci_tsc_freq + 4999) / 1000000, ((ci->ci_tsc_freq + 4999) / 10000) % 100); - cpuspeed = (ci->ci_tsc_freq + 4999) / 1000000; - cpu_cpuspeed = cpu_amd64speed; + + if (ci->ci_flags & CPUF_PRIMARY) { + cpuspeed = (ci->ci_tsc_freq + 4999) / 1000000; + cpu_cpuspeed = cpu_amd64speed; + } printf("\n%s: ", ci->ci_dev->dv_xname); @@ -383,25 +396,25 @@ identifycpu(struct cpu_info *ci) x86_print_cacheinfo(ci); #ifndef SMALL_KERNEL - if (pnfeatset > 0x80000007) { - CPUID(0x80000007, dummy, dummy, dummy, pnfeatset); + if (ci->ci_flags & CPUF_PRIMARY) { + if (pnfeatset > 0x80000007) { + CPUID(0x80000007, dummy, dummy, dummy, pnfeatset); - if (pnfeatset & 0x06) { - if ((ci->ci_signature & 0xF00) == 0xf00) - setperf_setup = k8_powernow_init; + if (pnfeatset & 0x06) { + if ((ci->ci_signature & 0xF00) == 0xf00) + setperf_setup = k8_powernow_init; + } + if (ci->ci_family >= 0x10) + setperf_setup = k1x_init; } - if (ci->ci_family >= 0x10) - setperf_setup = k1x_init; - } - if (cpu_ecxfeature & CPUIDECX_EST) { - setperf_setup = est_init; - } - - if (cpu_ecxfeature & CPUIDECX_AES) - amd64_has_aesni = 1; + if (cpu_ecxfeature & CPUIDECX_EST) + setperf_setup = est_init; - if (!strncmp(cpu_model, "Intel", 5)) { + if (cpu_ecxfeature & CPUIDECX_AES) + amd64_has_aesni = 1; + } + if (!strncmp(mycpu_model, "Intel", 5)) { u_int32_t cflushsz; CPUID(0x01, dummy, cflushsz, dummy, dummy); @@ -420,13 +433,14 @@ identifycpu(struct cpu_info *ci) #endif - + vendor[3] = 0; + CPUID(0, dummy, vendor[0], vendor[2], vendor[1]); /* yup, 0 2 1 */ /* AuthenticAMD: h t u A i t n e */ if (vendor[0] == 0x68747541 && vendor[1] == 0x69746e65 && vendor[2] == 0x444d4163) /* DMAc */ amd64_errata(ci); - if (strncmp(cpu_model, "VIA Nano processor", 18) == 0) { + if (strncmp(mycpu_model, "VIA Nano processor", 18) == 0) { ci->cpu_setup = via_nano_setup; #ifndef SMALL_KERNEL strlcpy(ci->ci_sensordev.xname, ci->ci_dev->dv_xname, @@ -438,10 +452,3 @@ identifycpu(struct cpu_info *ci) #endif } } - -void -cpu_probe_features(struct cpu_info *ci) -{ - ci->ci_feature_flags = cpu_feature; - ci->ci_signature = 0; -} diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index d9c0f1a0190..e3f5ff0dead 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.70 2011/12/26 23:07:04 haesbaert Exp $ */ +/* $OpenBSD: cpu.h,v 1.71 2012/03/27 02:23:04 haesbaert Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -135,6 +135,8 @@ struct cpu_info { #define CPUF_SP 0x0004 /* CPU is only processor */ #define CPUF_PRIMARY 0x0008 /* CPU is active primary processor */ +#define CPUF_IDENTIFY 0x0010 /* CPU may now identify */ + #define CPUF_PRESENT 0x1000 /* CPU is present */ #define CPUF_RUNNING 0x2000 /* CPU is running */ #define CPUF_PAUSE 0x4000 /* CPU is paused in DDB */ @@ -264,7 +266,6 @@ extern int cpuspeed; /* identcpu.c */ void identifycpu(struct cpu_info *); int cpu_amd64speed(int *); -void cpu_probe_features(struct cpu_info *); /* machdep.c */ void dumpconf(void); |