/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* @OSF_COPYRIGHT@
*/
-#include <platforms.h>
-#include <mach_kdb.h>
+
#include <pexpert/pexpert.h>
#include "cpuid.h"
-#if MACH_KDB
-#include <i386/db_machdep.h>
-#include <ddb/db_aout.h>
-#include <ddb/db_access.h>
-#include <ddb/db_sym.h>
-#include <ddb/db_variables.h>
-#include <ddb/db_command.h>
-#include <ddb/db_output.h>
-#include <ddb/db_expr.h>
-#endif
#define min(a,b) ((a) < (b) ? (a) : (b))
-#define quad(hi,lo) (((uint64_t)(hi)) << 32 | (lo))
-
-#define bit(n) (1UL << (n))
-#define bitmask(h,l) ((bit(h)|(bit(h)-1)) & ~(bit(l)-1))
-#define bitfield(x,h,l) (((x) & bitmask(h,l)) >> l)
/*
* CPU identification routines.
/* do cpuid 0 to get vendor */
do_cpuid(0, cpuid_result);
- cpuid_maxcpuid = cpuid_result[eax];
- bcopy((char *)&cpuid_result[ebx], &info_p->cpuid_vendor[0], 4); /* ug */
- bcopy((char *)&cpuid_result[ecx], &info_p->cpuid_vendor[8], 4);
- bcopy((char *)&cpuid_result[edx], &info_p->cpuid_vendor[4], 4);
+ cpuid_maxcpuid = cpuid_result[0];
+ bcopy((char *)&cpuid_result[1], &info_p->cpuid_vendor[0], 4); /* ugh */
+ bcopy((char *)&cpuid_result[2], &info_p->cpuid_vendor[8], 4);
+ bcopy((char *)&cpuid_result[3], &info_p->cpuid_vendor[4], 4);
info_p->cpuid_vendor[12] = 0;
/* look up vendor */
"Unified L2 cache, 1M, 4-way set associative, 32byte line size"),
CACHE_DESC(CPUID_CACHE_UCACHE_2M, L2U, 2*1024*1024, 32, \
"Unified L2 cache, 2M, 4-way set associative, 32byte line size"),
-CACHE_DESC(CPUID_CACHE_UCACHE_4M, L2U, 4*1024*1024, 64, \
- "Unified L2 cache, 4M, 16-way set associative, 64byte line size"),
CACHE_DESC(CPUID_CACHE_UCACHE_128K_64, L2U, 128*1024, 64, \
"Unified L2 cache, 128K, 8-way set associative, 64byte line size"),
CACHE_DESC(CPUID_CACHE_UCACHE_256K_64, L2U, 256*1024, 64, \
(char *)0),
};
-static const char * get_intel_model_string( i386_cpu_info_t * info_p, cpu_type_t* type, cpu_subtype_t* subtype)
+static const char * get_intel_model_string( i386_cpu_info_t * info_p )
{
- *type = CPU_TYPE_X86;
- *subtype = CPU_SUBTYPE_X86_ARCH1;
-
- /* check for brand id string */
+ /* check for brand id */
switch(info_p->cpuid_brand) {
case CPUID_BRAND_UNSUPPORTED:
/* brand ID not supported; use alternate method. */
default:
return "Unknown Intel P6 Family";
}
+ case CPUID_FAMILY_ITANIUM:
+ return "Intel Itanium";
case CPUID_FAMILY_EXTENDED:
switch (info_p->cpuid_extfamily) {
case CPUID_EXTFAMILY_PENTIUM4:
- *subtype = CPU_SUBTYPE_PENTIUM_4;
return "Intel Pentium 4";
- default:
- return "Unknown Intel Extended Family";
+ case CPUID_EXTFAMILY_ITANIUM2:
+ return "Intel Itanium 2";
}
default:
return "Unknown Intel Family";
case CPUID_BRAND_PENTIUM_III_4:
return "Pentium III";
case CPUID_BRAND_PIII_XEON:
- if (info_p->cpuid_signature == 0x6B1) {
- return "Intel Celeron";
- } else {
- return "Intel Pentium III Xeon";
- }
+ if (info_p->cpuid_signature == 0x6B1)
+ return "Intel Celeron";
+ else
+ return "Intel Pentium III Xeon";
case CPUID_BRAND_PENTIUM_III_M:
return "Mobile Intel Pentium III-M";
case CPUID_BRAND_M_CELERON_7:
return "Mobile Intel Celeron";
case CPUID_BRAND_PENTIUM4_8:
case CPUID_BRAND_PENTIUM4_9:
- *subtype = CPU_SUBTYPE_PENTIUM_4;
return "Intel Pentium 4";
case CPUID_BRAND_XEON:
return "Intel Xeon";
case CPUID_BRAND_XEON_MP:
return "Intel Xeon MP";
case CPUID_BRAND_PENTIUM4_M:
- if (info_p->cpuid_signature == 0xF13) {
- return "Intel Xeon";
- } else {
- *subtype = CPU_SUBTYPE_PENTIUM_4;
- return "Mobile Intel Pentium 4";
- }
+ if (info_p->cpuid_signature == 0xF13)
+ return "Intel Xeon";
+ else
+ return "Mobile Intel Pentium 4";
case CPUID_BRAND_CELERON_M:
return "Intel Celeron M";
case CPUID_BRAND_PENTIUM_M:
case CPUID_BRAND_MOBILE_17:
return "Mobile Intel";
}
+
return "Unknown Intel";
}
/* If we have no L2 cache, use the L1 data cache line size */
if (info_p->cache_size[L2U] == 0)
info_p->cache_linesize = l1d_cache_linesize;
-
- /*
- * Get cache sharing info if available.
- */
- do_cpuid(0, cpuid_result);
- if (cpuid_result[eax] >= 4) {
- uint32_t reg[4];
- uint32_t index;
- for (index = 0;; index++) {
- /*
- * Scan making calls for cpuid with %eax = 4
- * to get info about successive cache levels
- * until a null type is returned.
- */
- cache_type_t type = Lnone;
- uint32_t cache_type;
- uint32_t cache_level;
- uint32_t cache_sharing;
-
- reg[eax] = 4; /* cpuid request 4 */
- reg[ecx] = index; /* index starting at 0 */
- cpuid(reg);
-//kprintf("cpuid(4) index=%d eax=%p\n", index, reg[eax]);
- cache_type = bitfield(reg[eax], 4, 0);
- if (cache_type == 0)
- break; /* done with cache info */
- cache_level = bitfield(reg[eax], 7, 5);
- cache_sharing = bitfield(reg[eax], 25, 14);
- info_p->cpuid_cores_per_package =
- bitfield(reg[eax], 31, 26) + 1;
- switch (cache_level) {
- case 1:
- type = cache_type == 1 ? L1D :
- cache_type == 2 ? L1I :
- Lnone;
- break;
- case 2:
- type = cache_type == 3 ? L2U :
- Lnone;
- break;
- case 3:
- type = cache_type == 3 ? L3U :
- Lnone;
- }
- if (type != Lnone)
- info_p->cache_sharing[type] = cache_sharing + 1;
- }
- }
}
static void set_cpu_intel( i386_cpu_info_t * info_p )
{
set_cpu_generic(info_p);
set_intel_cache_info(info_p);
- info_p->cpuid_model_string = get_intel_model_string(info_p, &info_p->cpuid_cpu_type, &info_p->cpuid_cpu_subtype);
+ info_p->cpuid_model_string = get_intel_model_string(info_p);
}
-static const char * get_amd_model_string( i386_cpu_info_t * info_p, cpu_type_t* type, cpu_subtype_t* subtype )
+static const char * get_amd_model_string( i386_cpu_info_t * info_p )
{
- *type = CPU_TYPE_X86;
- *subtype = CPU_SUBTYPE_X86_ARCH1;
-
- /* check for brand id string */
switch (info_p->cpuid_family)
{
case CPUID_FAMILY_486:
/* (ignore) */
/* ECX: L1 Data Cache Information */
- info_p->cache_size[L1D] = ((cpuid_result[ecx] >> 24) & 0xFF) * 1024;
- info_p->cache_linesize = (cpuid_result[ecx] & 0xFF);
+ info_p->cache_size[L1D] = ((cpuid_result[2] >> 24) & 0xFF) * 1024;
+ info_p->cache_linesize = (cpuid_result[2] & 0xFF);
/* EDX: L1 Instruction Cache Information */
- info_p->cache_size[L1I] = ((cpuid_result[edx] >> 24) & 0xFF) * 1024;
+ info_p->cache_size[L1I] = ((cpuid_result[3] >> 24) & 0xFF) * 1024;
/* L2 Cache Information */
do_cpuid(0x80000006, cpuid_result);
/* (ignore) */
/* ECX: L2 Cache Information */
- info_p->cache_size[L2U] = ((cpuid_result[ecx] >> 16) & 0xFFFF) * 1024;
+ info_p->cache_size[L2U] = ((cpuid_result[2] >> 16) & 0xFFFF) * 1024;
if (info_p->cache_size[L2U] > 0)
- info_p->cache_linesize = cpuid_result[ecx] & 0xFF;
+ info_p->cache_linesize = cpuid_result[2] & 0xFF;
}
static void set_cpu_amd( i386_cpu_info_t * info_p )
{
set_cpu_generic(info_p);
set_amd_cache_info(info_p);
- info_p->cpuid_model_string = get_amd_model_string(info_p, &info_p->cpuid_cpu_type, &info_p->cpuid_cpu_subtype);
+ info_p->cpuid_model_string = get_amd_model_string(info_p);
}
static void set_cpu_nsc( i386_cpu_info_t * info_p )
set_cpu_generic(info_p);
set_amd_cache_info(info_p);
- /* check for brand id string */
- if (info_p->cpuid_family == CPUID_FAMILY_586 && info_p->cpuid_model == CPUID_MODEL_GX1) {
+ if (info_p->cpuid_family == CPUID_FAMILY_586 && info_p->cpuid_model == CPUID_MODEL_GX1)
info_p->cpuid_model_string = "AMD Geode GX1";
- } else if (info_p->cpuid_family == CPUID_FAMILY_586 && info_p->cpuid_model == CPUID_MODEL_GX2) {
+ else if (info_p->cpuid_family == CPUID_FAMILY_586 && info_p->cpuid_model == CPUID_MODEL_GX2)
info_p->cpuid_model_string = "AMD Geode GX";
- } else {
+ else
info_p->cpuid_model_string = "Unknown National Semiconductor";
- }
- info_p->cpuid_cpu_type = CPU_TYPE_X86;
- info_p->cpuid_cpu_subtype = CPU_SUBTYPE_X86_ARCH1;
}
static void
/* get extended cpuid results */
do_cpuid(0x80000000, cpuid_result);
- max_extid = cpuid_result[eax];
+ max_extid = cpuid_result[0];
/* check to see if we can get brand string */
if (max_extid >= 0x80000004) {
/* get processor signature and decode */
do_cpuid(1, cpuid_result);
- info_p->cpuid_signature = cpuid_result[eax];
- info_p->cpuid_stepping = bitfield(cpuid_result[eax], 3, 0);
- info_p->cpuid_model = bitfield(cpuid_result[eax], 7, 4);
- info_p->cpuid_family = bitfield(cpuid_result[eax], 11, 8);
- info_p->cpuid_type = bitfield(cpuid_result[eax], 13, 12);
- info_p->cpuid_extmodel = bitfield(cpuid_result[eax], 19, 16);
- info_p->cpuid_extfamily = bitfield(cpuid_result[eax], 27, 20);
- info_p->cpuid_brand = bitfield(cpuid_result[ebx], 7, 0);
- info_p->cpuid_logical_per_package =
- bitfield(cpuid_result[ebx], 23, 16);
- info_p->cpuid_features = quad(cpuid_result[ecx], cpuid_result[edx]);
-
- if (max_extid >= 0x80000001) {
- do_cpuid(0x80000001, cpuid_result);
- info_p->cpuid_extfeatures =
- quad(cpuid_result[ecx], cpuid_result[edx]);
- }
+ info_p->cpuid_signature = cpuid_result[0];
+ info_p->cpuid_stepping = cpuid_result[0] & 0x0f;
+ info_p->cpuid_model = (cpuid_result[0] >> 4) & 0x0f;
+ info_p->cpuid_family = (cpuid_result[0] >> 8) & 0x0f;
+ info_p->cpuid_type = (cpuid_result[0] >> 12) & 0x03;
+ info_p->cpuid_extmodel = (cpuid_result[0] >> 16) & 0x0f;
+ info_p->cpuid_extfamily = (cpuid_result[0] >> 20) & 0xff;
+ info_p->cpuid_brand = cpuid_result[1] & 0xff;
+ info_p->cpuid_features = cpuid_result[3];
return;
}
static struct {
- uint64_t mask;
+ uint32_t mask;
const char *name;
-} feature_map[] = {
+} feature_names[] = {
{CPUID_FEATURE_FPU, "FPU",},
{CPUID_FEATURE_VME, "VME",},
{CPUID_FEATURE_DE, "DE",},
{CPUID_FEATURE_SS, "SS",},
{CPUID_FEATURE_HTT, "HTT",},
{CPUID_FEATURE_TM, "TM",},
- {CPUID_FEATURE_SSE3, "SSE3"},
- {CPUID_FEATURE_MONITOR, "MON"},
- {CPUID_FEATURE_DSCPL, "DSCPL"},
- {CPUID_FEATURE_VMX, "VMX"},
- {CPUID_FEATURE_SMX, "SMX"},
- {CPUID_FEATURE_EST, "EST"},
- {CPUID_FEATURE_TM2, "TM2"},
- {CPUID_FEATURE_MNI, "MNI"},
- {CPUID_FEATURE_CID, "CID"},
- {CPUID_FEATURE_CX16, "CX16"},
- {CPUID_FEATURE_xTPR, "TPR"},
- {0, 0}
-},
-extfeature_map[] = {
- {CPUID_EXTFEATURE_SYSCALL, "SYSCALL"},
- {CPUID_EXTFEATURE_XD, "XD"},
- {CPUID_EXTFEATURE_EM64T, "EM64T"},
- {CPUID_EXTFEATURE_LAHF, "LAHF"},
{0, 0}
};
char *
-cpuid_get_feature_names(uint64_t features, char *buf, unsigned buf_len)
+cpuid_get_feature_names(uint32_t feature, char *buf, unsigned buf_len)
{
- int len = -1;
- char *p = buf;
int i;
-
- for (i = 0; feature_map[i].mask != 0; i++) {
- if ((features & feature_map[i].mask) == 0)
- continue;
- if (len > 0)
- *p++ = ' ';
- len = min(strlen(feature_map[i].name), (buf_len-1) - (p-buf));
- if (len == 0)
- break;
- bcopy(feature_map[i].name, p, len);
- p += len;
- }
- *p = '\0';
- return buf;
-}
-
-char *
-cpuid_get_extfeature_names(uint64_t extfeatures, char *buf, unsigned buf_len)
-{
- int len = -1;
+ int len;
char *p = buf;
- int i;
- for (i = 0; extfeature_map[i].mask != 0; i++) {
- if ((extfeatures & extfeature_map[i].mask) == 0)
+ for (i = 0; feature_names[i].mask != 0; i++) {
+ if ((feature & feature_names[i].mask) == 0)
continue;
- if (len > 0)
+ if (i > 0)
*p++ = ' ';
- len = min(strlen(extfeature_map[i].name), (buf_len-1)-(p-buf));
+ len = min(strlen(feature_names[i].name), (buf_len-1) - (p-buf));
if (len == 0)
break;
- bcopy(extfeature_map[i].name, p, len);
+ bcopy(feature_names[i].name, p, len);
p += len;
}
*p = '\0';
void
cpuid_feature_display(
- const char *header)
-{
- char buf[256];
-
- kprintf("%s: %s\n", header,
- cpuid_get_feature_names(cpuid_features(),
- buf, sizeof(buf)));
- if (cpuid_features() & CPUID_FEATURE_HTT) {
-#define s_if_plural(n) ((n > 1) ? "s" : "")
- kprintf(" HTT: %d core%s per package;"
- " %d logical cpu%s per package\n",
- cpuid_cpu_info.cpuid_cores_per_package,
- s_if_plural(cpuid_cpu_info.cpuid_cores_per_package),
- cpuid_cpu_info.cpuid_logical_per_package,
- s_if_plural(cpuid_cpu_info.cpuid_logical_per_package));
- }
-}
-
-void
-cpuid_extfeature_display(
- const char *header)
+ const char *header,
+ __unused int my_cpu)
{
char buf[256];
- kprintf("%s: %s\n", header,
- cpuid_get_extfeature_names(cpuid_extfeatures(),
- buf, sizeof(buf)));
+ printf("%s: %s\n", header,
+ cpuid_get_feature_names(cpuid_features(), buf, sizeof(buf)));
}
void
cpuid_cpu_display(
- const char *header)
+ const char *header,
+ __unused int my_cpu)
{
if (cpuid_cpu_info.cpuid_brand_string[0] != '\0') {
- kprintf("%s: %s\n", header, cpuid_cpu_info.cpuid_brand_string);
+ printf("%s: %s\n", header,
+ cpuid_cpu_info.cpuid_brand_string);
}
}
return cpuid_cpu_info.cpuid_family;
}
-cpu_type_t
-cpuid_cputype(void)
-{
- return cpuid_cpu_info.cpuid_cpu_type;
-}
-
-cpu_subtype_t
-cpuid_cpusubtype(void)
-{
- return cpuid_cpu_info.cpuid_cpu_subtype;
-}
-
-uint64_t
+unsigned int
cpuid_features(void)
{
static int checked = 0;
return cpuid_cpu_info.cpuid_features;
}
-uint64_t
-cpuid_extfeatures(void)
-{
- return cpuid_cpu_info.cpuid_extfeatures;
-}
-
i386_cpu_info_t *
cpuid_info(void)
{
return &cpuid_cpu_info;
}
+/* XXX for temporary compatibility */
void
-cpuid_set_info(void)
+set_cpu_model(void)
{
cpuid_get_info(&cpuid_cpu_info);
+ cpuid_feature = cpuid_cpu_info.cpuid_features; /* XXX compat */
}
-#if MACH_KDB
-
-/*
- * Display the cpuid
- * *
- * cp
- */
-void
-db_cpuid(__unused db_expr_t addr,
- __unused int have_addr,
- __unused db_expr_t count,
- __unused char *modif)
-{
-
- uint32_t i, mid;
- uint32_t cpid[4];
-
- do_cpuid(0, cpid); /* Get the first cpuid which is the number of
- * basic ids */
- db_printf("%08X - %08X %08X %08X %08X\n",
- 0, cpid[eax], cpid[ebx], cpid[ecx], cpid[edx]);
-
- mid = cpid[eax]; /* Set the number */
- for (i = 1; i <= mid; i++) { /* Dump 'em out */
- do_cpuid(i, cpid); /* Get the next */
- db_printf("%08X - %08X %08X %08X %08X\n",
- i, cpid[eax], cpid[ebx], cpid[ecx], cpid[edx]);
- }
- db_printf("\n");
-
- do_cpuid(0x80000000, cpid); /* Get the first extended cpuid which
- * is the number of extended ids */
- db_printf("%08X - %08X %08X %08X %08X\n",
- 0x80000000, cpid[eax], cpid[ebx], cpid[ecx], cpid[edx]);
-
- mid = cpid[eax]; /* Set the number */
- for (i = 0x80000001; i <= mid; i++) { /* Dump 'em out */
- do_cpuid(i, cpid); /* Get the next */
- db_printf("%08X - %08X %08X %08X %08X\n",
- i, cpid[eax], cpid[ebx], cpid[ecx], cpid[edx]);
- }
-}
-
-#endif