Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-6]: src/sys/arch/x86/x86 Pull up the following, requested by msai...
details: https://anonhg.NetBSD.org/src/rev/ca6090e74c60
branches: netbsd-6
changeset: 776886:ca6090e74c60
user: martin <martin%NetBSD.org@localhost>
date: Mon Jan 26 14:02:40 2015 +0000
description:
Pull up the following, requested by msaitoh in ticket #1241:
sys/arch/x86/x86/identcpu.c 1.35-1.39
- Check cpuid leaf 4 for newer Intel CPU to know the cache information.
This code might improve performance because it changes the number of
page colors.
- Fix calculation of the cpu model (display model) in
cpu_probe_amd_cache().
- CPUID leaf 2 and 4 are only for Intel processors.
diffstat:
sys/arch/x86/x86/identcpu.c | 170 ++++++++++++++++++++++++++++++-------------
1 files changed, 117 insertions(+), 53 deletions(-)
diffs (275 lines):
diff -r 45aebe76a579 -r ca6090e74c60 sys/arch/x86/x86/identcpu.c
--- a/sys/arch/x86/x86/identcpu.c Mon Jan 26 13:58:05 2015 +0000
+++ b/sys/arch/x86/x86/identcpu.c Mon Jan 26 14:02:40 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: identcpu.c,v 1.29.2.2 2012/05/07 16:37:19 riz Exp $ */
+/* $NetBSD: identcpu.c,v 1.29.2.3 2015/01/26 14:02:40 martin Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.29.2.2 2012/05/07 16:37:19 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.29.2.3 2015/01/26 14:02:40 martin Exp $");
#include "opt_xen.h"
@@ -97,6 +97,103 @@
return (NULL);
}
+static void
+cpu_probe_intel_cache(struct cpu_info *ci)
+{
+ const struct x86_cache_info *cai;
+ u_int descs[4];
+ int iterations, i, j;
+ uint8_t desc;
+
+ if (cpuid_level >= 2) {
+ /* Parse the cache info from `cpuid leaf 2', if we have it. */
+ x86_cpuid(2, descs);
+ iterations = descs[0] & 0xff;
+ while (iterations-- > 0) {
+ for (i = 0; i < 4; i++) {
+ if (descs[i] & 0x80000000)
+ continue;
+ for (j = 0; j < 4; j++) {
+ if (i == 0 && j == 0)
+ continue;
+ desc = (descs[i] >> (j * 8)) & 0xff;
+ if (desc == 0)
+ continue;
+ cai = cache_info_lookup(
+ intel_cpuid_cache_info, desc);
+ if (cai != NULL) {
+ ci->ci_cinfo[cai->cai_index] =
+ *cai;
+ }
+ }
+ }
+ }
+ }
+
+ if (cpuid_level >= 4) {
+ int type, level;
+ int ways, partitions, linesize, sets;
+ int caitype = -1;
+ int totalsize;
+
+ /* Parse the cache info from `cpuid leaf 4', if we have it. */
+ for (i = 0; ; i++) {
+ x86_cpuid2(4, i, descs);
+ type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE);
+ if (type == CPUID_DCP_CACHETYPE_N)
+ break;
+ level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL);
+ switch (level) {
+ case 1:
+ if (type == CPUID_DCP_CACHETYPE_I)
+ caitype = CAI_ICACHE;
+ else if (type == CPUID_DCP_CACHETYPE_D)
+ caitype = CAI_DCACHE;
+ else
+ caitype = -1;
+ break;
+ case 2:
+ if (type == CPUID_DCP_CACHETYPE_U)
+ caitype = CAI_L2CACHE;
+ else
+ caitype = -1;
+ break;
+ case 3:
+ if (type == CPUID_DCP_CACHETYPE_U)
+ caitype = CAI_L3CACHE;
+ else
+ caitype = -1;
+ break;
+ default:
+ caitype = -1;
+ break;
+ }
+ if (caitype == -1)
+ continue;
+
+ ways = __SHIFTOUT(descs[1], CPUID_DCP_WAYS) + 1;
+ partitions =__SHIFTOUT(descs[1], CPUID_DCP_PARTITIONS)
+ + 1;
+ linesize = __SHIFTOUT(descs[1], CPUID_DCP_LINESIZE)
+ + 1;
+ sets = descs[2] + 1;
+ totalsize = ways * partitions * linesize * sets;
+ ci->ci_cinfo[caitype].cai_totalsize = totalsize;
+ ci->ci_cinfo[caitype].cai_associativity = ways;
+ ci->ci_cinfo[caitype].cai_linesize = linesize;
+ }
+ }
+}
+
+static void
+cpu_probe_intel(struct cpu_info *ci)
+{
+
+ if (cpu_vendor != CPUVENDOR_INTEL)
+ return;
+
+ cpu_probe_intel_cache(ci);
+}
static void
cpu_probe_amd_cache(struct cpu_info *ci)
@@ -107,8 +204,8 @@
u_int descs[4];
u_int lfunc;
- family = CPUID2FAMILY(ci->ci_signature);
- model = CPUID2MODEL(ci->ci_signature);
+ family = CPUID_TO_FAMILY(ci->ci_signature);
+ model = CPUID_TO_MODEL(ci->ci_signature);
/*
* K5 model 0 has none of this info.
@@ -117,14 +214,6 @@
return;
/*
- * Get extended values for K8 and up.
- */
- if (family == 0xf) {
- family += CPUID2EXTFAMILY(ci->ci_signature);
- model += CPUID2EXTMODEL(ci->ci_signature);
- }
-
- /*
* Determine the largest extended function value.
*/
x86_cpuid(0x80000000, descs);
@@ -248,10 +337,10 @@
int flag;
if (cpu_vendor != CPUVENDOR_AMD ||
- CPUID2FAMILY(ci->ci_signature) != 5)
+ CPUID_TO_FAMILY(ci->ci_signature) != 5)
return;
- if (CPUID2MODEL(ci->ci_signature) == 0) {
+ if (CPUID_TO_MODEL(ci->ci_signature) == 0) {
/*
* According to the AMD Processor Recognition App Note,
* the AMD-K5 Model 0 uses the wrong bit to indicate
@@ -273,7 +362,7 @@
uint32_t descs[4];
if (cpu_vendor != CPUVENDOR_AMD ||
- CPUID2FAMILY(ci->ci_signature) < 6)
+ CPUID_TO_FAMILY(ci->ci_signature) < 6)
return;
/* Determine the extended feature flags. */
@@ -369,8 +458,8 @@
{
if (cpu_vendor != CPUVENDOR_CYRIX ||
- CPUID2FAMILY(ci->ci_signature) < 4 ||
- CPUID2FAMILY(ci->ci_signature) > 6)
+ CPUID_TO_FAMILY(ci->ci_signature) < 4 ||
+ CPUID_TO_FAMILY(ci->ci_signature) > 6)
return;
cpu_probe_cyrix_cmn(ci);
@@ -383,10 +472,10 @@
if (cpu_vendor != CPUVENDOR_IDT)
return;
- switch (CPUID2FAMILY(ci->ci_signature)) {
+ switch (CPUID_TO_FAMILY(ci->ci_signature)) {
case 5:
/* WinChip C6 */
- if (CPUID2MODEL(ci->ci_signature) == 4)
+ if (CPUID_TO_MODEL(ci->ci_signature) == 4)
ci->ci_feat_val[0] &= ~CPUID_TSC;
break;
case 6:
@@ -415,12 +504,12 @@
struct x86_cache_info *cai;
if (cpu_vendor != CPUVENDOR_IDT ||
- CPUID2FAMILY(ci->ci_signature) < 6)
+ CPUID_TO_FAMILY(ci->ci_signature) < 6)
return;
- family = CPUID2FAMILY(ci->ci_signature);
- model = CPUID2MODEL(ci->ci_signature);
- stepping = CPUID2STEPPING(ci->ci_signature);
+ family = CPUID_TO_FAMILY(ci->ci_signature);
+ model = CPUID_TO_MODEL(ci->ci_signature);
+ stepping = CPUID_TO_STEPPING(ci->ci_signature);
/* Determine the largest extended function value. */
x86_cpuid(0x80000000, descs);
@@ -555,7 +644,7 @@
{
if (memcmp("Geode by NSC", ci->ci_vendor, 12) != 0 ||
- CPUID2FAMILY(ci->ci_signature) != 5)
+ CPUID_TO_FAMILY(ci->ci_signature) != 5)
return;
cpu_probe_cyrix_cmn(ci);
@@ -606,10 +695,8 @@
void
cpu_probe(struct cpu_info *ci)
{
- const struct x86_cache_info *cai;
u_int descs[4];
- int iterations, i, j;
- uint8_t desc;
+ int i;
uint32_t miscbytes;
uint32_t brand[12];
@@ -667,7 +754,8 @@
ci->ci_feat_val[0] = descs[3];
/* Determine family + class. */
- cpu_class = CPUID2FAMILY(ci->ci_signature) + (CPUCLASS_386 - 3);
+ cpu_class = CPUID_TO_FAMILY(ci->ci_signature)
+ + (CPUCLASS_386 - 3);
if (cpu_class > CPUCLASS_686)
cpu_class = CPUCLASS_686;
@@ -677,31 +765,7 @@
ci->ci_initapicid = (miscbytes >> 24) & 0xff;
}
- if (cpuid_level >= 2) {
- /* Parse the cache info from `cpuid', if we have it. */
- x86_cpuid(2, descs);
- iterations = descs[0] & 0xff;
- while (iterations-- > 0) {
- for (i = 0; i < 4; i++) {
- if (descs[i] & 0x80000000)
- continue;
- for (j = 0; j < 4; j++) {
- if (i == 0 && j == 0)
- continue;
- desc = (descs[i] >> (j * 8)) & 0xff;
- if (desc == 0)
- continue;
- cai = cache_info_lookup(
- intel_cpuid_cache_info, desc);
- if (cai != NULL) {
- ci->ci_cinfo[cai->cai_index] =
- *cai;
- }
- }
- }
- }
- }
-
+ cpu_probe_intel(ci);
cpu_probe_k5(ci);
cpu_probe_k678(ci);
cpu_probe_cyrix(ci);
Home |
Main Index |
Thread Index |
Old Index