Chameleon

Chameleon Svn Source Tree

Root/branches/slice/old749m/i386/libsaio/cpu.h

1/*
2 * Copyright 2008 Islam Ahmed Zaid. All rights reserved. <azismed@gmail.com>
3 * AsereBLN: 2009: cleanup and bugfix
4 */
5
6#ifndef __LIBSAIO_CPU_H
7#define __LIBSAIO_CPU_H
8
9#include "libsaio.h"
10
11#define CPU_VIA_C30x07
12#define CPU_VIA_C3_Ezra_T0x08
13
14#define CPU_VIA_NANO0x0F
15
16
17
18extern void scan_cpu(); //PlatformInfo_t *);
19
20#define min(a,b) ((a) < (b) ? (a) : (b))
21#define quad(hi,lo) (((uint64_t)(hi)) << 32 | (lo))
22
23
24#define bit(n)(1UL << (n))
25#define bitmask(h,l)((bit(h)|(bit(h)-1)) & ~(bit(l)-1))
26#define bitfield(x,h,l)(((x) & bitmask(h,l)) >> l)
27
28#defineCPUID_VID_INTEL"GenuineIntel"
29#defineCPUID_VID_AMD"AuthenticAMD"
30
31#define CPUID_STRING_UNKNOWN "Unknown CPU Typ"
32
33#define _Bit(n)(1ULL << n)
34#define _HBit(n)(1ULL << ((n)+32))
35
36/*
37 * The CPUID_FEATURE_XXX values define 64-bit values
38 * returned in %ecx:%edx to a CPUID request with %eax of 1:
39 */
40#defineCPUID_FEATURE_FPU _Bit(0)/* Floating point unit on-chip */
41#defineCPUID_FEATURE_VME _Bit(1)/* Virtual Mode Extension */
42#defineCPUID_FEATURE_DE _Bit(2)/* Debugging Extension */
43#defineCPUID_FEATURE_PSE _Bit(3)/* Page Size Extension */
44#defineCPUID_FEATURE_TSC _Bit(4)/* Time Stamp Counter */
45#defineCPUID_FEATURE_MSR _Bit(5)/* Model Specific Registers */
46#define CPUID_FEATURE_PAE _Bit(6)/* Physical Address Extension */
47#defineCPUID_FEATURE_MCE _Bit(7)/* Machine Check Exception */
48#defineCPUID_FEATURE_CX8 _Bit(8)/* CMPXCHG8B */
49#defineCPUID_FEATURE_APIC _Bit(9)/* On-chip APIC */
50#define CPUID_FEATURE_SEP _Bit(11)/* Fast System Call */
51#defineCPUID_FEATURE_MTRR _Bit(12)/* Memory Type Range Register */
52#defineCPUID_FEATURE_PGE _Bit(13)/* Page Global Enable */
53#defineCPUID_FEATURE_MCA _Bit(14)/* Machine Check Architecture */
54#defineCPUID_FEATURE_CMOV _Bit(15)/* Conditional Move Instruction */
55#define CPUID_FEATURE_PAT _Bit(16)/* Page Attribute Table */
56#define CPUID_FEATURE_PSE36 _Bit(17)/* 36-bit Page Size Extension */
57#define CPUID_FEATURE_PSN _Bit(18)/* Processor Serial Number */
58#define CPUID_FEATURE_CLFSH _Bit(19)/* CLFLUSH Instruction supported */
59#define CPUID_FEATURE_DS _Bit(21)/* Debug Store */
60#define CPUID_FEATURE_ACPI _Bit(22)/* Thermal monitor and Clock Ctrl */
61#define CPUID_FEATURE_MMX _Bit(23)/* MMX supported */
62#define CPUID_FEATURE_FXSR _Bit(24)/* Fast floating pt save/restore */
63#define CPUID_FEATURE_SSE _Bit(25)/* Streaming SIMD extensions */
64#define CPUID_FEATURE_SSE2 _Bit(26)/* Streaming SIMD extensions 2 */
65#define CPUID_FEATURE_SS _Bit(27)/* Self-Snoop */
66#define CPUID_FEATURE_HTT _Bit(28)/* Hyper-Threading Technology */
67#define CPUID_FEATURE_TM _Bit(29)/* Thermal Monitor (TM1) */
68#define CPUID_FEATURE_PBE _Bit(31)/* Pend Break Enable */
69
70#define CPUID_FEATURE_SSE3 _HBit(0)/* Streaming SIMD extensions 3 */
71#define CPUID_FEATURE_PCLMULQDQ _HBit(1) /* PCLMULQDQ Instruction */
72
73#define CPUID_FEATURE_MONITOR _HBit(3)/* Monitor/mwait */
74#define CPUID_FEATURE_DSCPL _HBit(4)/* Debug Store CPL */
75#define CPUID_FEATURE_VMX _HBit(5)/* VMX */
76#define CPUID_FEATURE_SMX _HBit(6)/* SMX */
77#define CPUID_FEATURE_EST _HBit(7)/* Enhanced SpeedsTep (GV3) */
78#define CPUID_FEATURE_TM2 _HBit(8)/* Thermal Monitor 2 */
79#define CPUID_FEATURE_SSSE3 _HBit(9)/* Supplemental SSE3 instructions */
80#define CPUID_FEATURE_CID _HBit(10)/* L1 Context ID */
81
82#define CPUID_FEATURE_CX16 _HBit(13)/* CmpXchg16b instruction */
83#define CPUID_FEATURE_xTPR _HBit(14)/* Send Task PRiority msgs */
84#define CPUID_FEATURE_PDCM _HBit(15)/* Perf/Debug Capability MSR */
85
86#define CPUID_FEATURE_DCA _HBit(18)/* Direct Cache Access */
87#define CPUID_FEATURE_SSE4_1 _HBit(19)/* Streaming SIMD extensions 4.1 */
88#define CPUID_FEATURE_SSE4_2 _HBit(20)/* Streaming SIMD extensions 4.2 */
89#define CPUID_FEATURE_xAPIC _HBit(21)/* Extended APIC Mode */
90#define CPUID_FEATURE_POPCNT _HBit(23)/* POPCNT instruction */
91#define CPUID_FEATURE_AES _HBit(25)/* AES instructions */
92#define CPUID_FEATURE_VMM _HBit(31)/* VMM (Hypervisor) present */
93
94/*
95 * The CPUID_EXTFEATURE_XXX values define 64-bit values
96 * returned in %ecx:%edx to a CPUID request with %eax of 0x80000001:
97 */
98#define CPUID_EXTFEATURE_SYSCALL _Bit(11)/* SYSCALL/sysret */
99#define CPUID_EXTFEATURE_XD _Bit(20)/* eXecute Disable */
100#define CPUID_EXTFEATURE_1GBPAGE _Bit(26) /* 1G-Byte Page support */
101#define CPUID_EXTFEATURE_RDTSCP _Bit(27)/* RDTSCP */
102#define CPUID_EXTFEATURE_EM64T _Bit(29)/* Extended Mem 64 Technology */
103
104//#define CPUID_EXTFEATURE_LAHF _HBit(20)/* LAFH/SAHF instructions */
105// New definition with Snow kernel
106#define CPUID_EXTFEATURE_LAHF _HBit(0)/* LAHF/SAHF instructions */
107/*
108 * The CPUID_EXTFEATURE_XXX values define 64-bit values
109 * returned in %ecx:%edx to a CPUID request with %eax of 0x80000007:
110 */
111#define CPUID_EXTFEATURE_TSCI _Bit(8)/* TSC Invariant */
112
113#defineCPUID_CACHE_SIZE16/* Number of descriptor values */
114
115#define CPUID_MWAIT_EXTENSION_Bit(0)/* enumeration of WMAIT extensions */
116#define CPUID_MWAIT_BREAK_Bit(1)/* interrupts are break events */
117
118
119
120
121#define MSR_IA32_PLATFORM_ID0x0017
122#define MSR_P4_EBC_FREQUENCY_ID0x002C
123#define MSR_CORE_THREAD_COUNT0x0035
124#defineMSR_IA32_PERF_STATUS0x0198
125#define MSR_IA32_PERF_CONTROL0x0199
126#define MSR_IA32_EXT_CONFIG0x00EE
127#define MSR_FLEX_RATIO0x0194 //Slice - not used
128#define MSR_FSB_FREQ0x00CD //Slice - not used
129#defineMSR_PLATFORM_INFO0x00CE// for i7 it gives min and max
130#define MSR_TURBO_RATIO0x01AD //Slice - for i7
131#define MSR_IA32_EBL_CR_POWERON0x002A //Meklort - for VIA
132#define K8_FIDVID_STATUS0xC0010042
133#define K10_COFVID_STATUS0xC0010071
134
135/* Centaur-Hauls/IDT defined MSRs. */
136#define MSR_IDT_FCR10x00000107
137#define MSR_IDT_FCR20x00000108
138#define MSR_IDT_FCR30x00000109
139#define MSR_IDT_FCR40x0000010a
140
141#define MSR_IDT_MCR00x00000110
142#define MSR_IDT_MCR10x00000111
143#define MSR_IDT_MCR20x00000112
144#define MSR_IDT_MCR30x00000113
145#define MSR_IDT_MCR40x00000114
146#define MSR_IDT_MCR50x00000115
147#define MSR_IDT_MCR60x00000116
148#define MSR_IDT_MCR70x00000117
149#define MSR_IDT_MCR_CTRL0x00000120
150
151/* VIA Nano defined MSTs */
152#define MSR_NANO_FCR1 0x1204 // This MSR contains control bits and family, model, etc.
153#define MSR_NANO_FCR2 0x1206 // This MSR contains part of the vendor string
154#define MSR_NANO_FCR3 0x1207 // This MSR contains part of the vendor string
155#define VIA_ALTERNATIVE_VENDOR_BIT (1 << 8) // This bit in MSR_IDT_FCR1 enables alternative vendor string
156
157/* VIA Cyrix defined MSRs */
158#define MSR_VIA_FCR0x00001107
159#define MSR_VIA_LONGHAUL0x0000110a
160#define MSR_VIA_RNG0x0000110b
161#define MSR_VIA_BCR20x00001147
162
163
164
165#define DEFAULT_FSB100000 /* for now, hardcoding 100MHz for old CPUs */
166
167// DFE: This constant comes from older xnu:
168#define CLKNUM1193182/* formerly 1193167 */
169
170// DFE: These two constants come from Linux except CLOCK_TICK_RATE replaced with CLKNUM
171#define CALIBRATE_TIME_MSEC30/* 30 msecs */
172#define CALIBRATE_LATCH((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000)
173
174typedef enum { eax, ebx, ecx, edx } cpuid_register_t;
175/*
176 * Cache ID descriptor structure, used to parse CPUID leaf 2.
177 * Note: not used in kernel.
178 */
179typedef enum { Lnone, L1I, L1D, L2U, L3U, LCACHE_MAX } cache_type_t ;
180typedef struct {
181unsigned charvalue; /* Descriptor value */
182cache_type_t type; /* Cache type */
183unsigned int size; /* Cache size */
184unsigned int linesize; /* Cache line size */
185const char*description; /* Cache description */
186} cpuid_cache_desc_t;
187
188
189#define CACHE_DESC(value,type,size,linesize,text) \
190{ value, type, size, linesize, text }
191
192/* Physical CPU info - this is exported out of the kernel (kexts), so be wary of changes */
193typedef struct {
194charcpuid_vendor[16];
195charcpuid_brand_string[48];
196const char*cpuid_model_string;
197
198cpu_type_tcpuid_type;/* this is *not* a cpu_type_t in our <mach/machine.h> */
199uint8_tcpuid_family;
200uint8_tcpuid_model;
201uint8_tcpuid_extmodel;
202uint8_tcpuid_extfamily;
203uint8_tcpuid_stepping;
204uint64_tcpuid_features;
205uint64_tcpuid_extfeatures;
206uint32_tcpuid_signature;
207uint8_t cpuid_brand;
208
209uint32_tcache_size[LCACHE_MAX];
210uint32_tcache_linesize;
211
212uint8_tcache_info[64]; /* list of cache descriptors */
213
214uint32_tcpuid_cores_per_package;
215uint32_tcpuid_logical_per_package;
216uint32_tcache_sharing[LCACHE_MAX];
217uint32_tcache_partitions[LCACHE_MAX];
218
219cpu_type_tcpuid_cpu_type;/* <mach/machine.h> */
220cpu_subtype_tcpuid_cpu_subtype;/* <mach/machine.h> */
221
222/* Monitor/mwait Leaf: */
223uint32_tcpuid_mwait_linesize_min;
224uint32_tcpuid_mwait_linesize_max;
225uint32_tcpuid_mwait_extensions;
226uint32_tcpuid_mwait_sub_Cstates;
227
228/* Thermal and Power Management Leaf: */
229boolean_tcpuid_thermal_sensor;
230boolean_tcpuid_thermal_dynamic_acceleration;
231uint32_tcpuid_thermal_thresholds;
232boolean_tcpuid_thermal_ACNT_MCNT;
233
234/* Architectural Performance Monitoring Leaf: */
235uint8_tcpuid_arch_perf_version;
236uint8_tcpuid_arch_perf_number;
237uint8_tcpuid_arch_perf_width;
238uint8_tcpuid_arch_perf_events_number;
239uint32_tcpuid_arch_perf_events;
240uint8_tcpuid_arch_perf_fixed_number;
241uint8_tcpuid_arch_perf_fixed_width;
242
243/* Cache details: */
244uint32_tcpuid_cache_linesize;
245uint32_tcpuid_cache_L2_associativity;
246uint32_tcpuid_cache_size;
247
248/* Virtual and physical address aize: */
249uint32_tcpuid_address_bits_physical;
250uint32_tcpuid_address_bits_virtual;
251
252uint32_tcpuid_microcode_version;
253
254/* Numbers of tlbs per processor [i|d, small|large, level0|level1] */
255uint32_tcpuid_tlb[2][2][2];
256#defineTLB_INST0
257#defineTLB_DATA1
258#defineTLB_SMALL0
259#defineTLB_LARGE1
260uint32_tcpuid_stlb;
261
262uint32_tcore_count;
263uint32_tthread_count;
264
265/* Max leaf ids available from CPUID */
266uint32_tcpuid_max_basic;
267uint32_tcpuid_max_ext;
268} i386_cpu_info_t;
269
270static i386_cpu_info_t cpuid_cpu_info;
271
272static i386_cpu_info_t*cpuid_info(void)
273{
274return &cpuid_cpu_info;
275}
276
277
278static inline uint64_t rdtsc64(void)
279{
280uint64_t ret;
281__asm__ volatile("rdtsc" : "=A" (ret));
282return ret;
283}
284
285static inline uint64_t rdmsr64(uint32_t msr)
286{
287 uint64_t ret;
288 __asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr));
289 return ret;
290}
291
292static inline void wrmsr64(uint32_t msr, uint64_t val)
293{
294__asm__ volatile("wrmsr" : : "c" (msr), "A" (val));
295}
296
297static inline void intel_waitforsts(void) {
298uint32_t inline_timeout = 100000;
299while (rdmsr64(MSR_IA32_PERF_STATUS) & (1 << 21)) { if (!inline_timeout--) break; }
300}
301
302static inline void do_cpuid(uint32_t selector, uint32_t *data)
303{
304asm volatile ("cpuid"
305 : "=a" (data[0]),
306 "=b" (data[1]),
307 "=c" (data[2]),
308 "=d" (data[3])
309 : "a" (selector));
310}
311
312static inline void do_cpuid2(uint32_t selector, uint32_t selector2, uint32_t *data)
313{
314asm volatile ("cpuid"
315 : "=a" (data[0]),
316 "=b" (data[1]),
317 "=c" (data[2]),
318 "=d" (data[3])
319 : "a" (selector), "c" (selector2));
320}
321
322// DFE: enable_PIT2 and disable_PIT2 come from older xnu
323
324/*
325 * Enable or disable timer 2.
326 * Port 0x61 controls timer 2:
327 * bit 0 gates the clock,
328 * bit 1 gates output to speaker.
329 */
330static inline void enable_PIT2(void)
331{
332 /* Enable gate, disable speaker */
333 __asm__ volatile(
334 " inb $0x61,%%al \n\t"
335 " and $0xFC,%%al \n\t" /* & ~0x03 */
336 " or $1,%%al \n\t"
337 " outb %%al,$0x61 \n\t"
338 : : : "%al" );
339}
340
341static inline void disable_PIT2(void)
342{
343 /* Disable gate and output to speaker */
344 __asm__ volatile(
345 " inb $0x61,%%al \n\t"
346 " and $0xFC,%%al \n\t"/* & ~0x03 */
347 " outb %%al,$0x61 \n\t"
348 : : : "%al" );
349}
350
351// DFE: set_PIT2_mode0, poll_PIT2_gate, and measure_tsc_frequency are
352// roughly based on Linux code
353
354/* Set the 8254 channel 2 to mode 0 with the specified value.
355 In mode 0, the counter will initially set its gate low when the
356 timer expires. For this to be useful, you ought to set it high
357 before calling this function. The enable_PIT2 function does this.
358 */
359static inline void set_PIT2_mode0(uint16_t value)
360{
361 __asm__ volatile(
362 " movb $0xB0,%%al \n\t"
363 " outb%%al,$0x43\n\t"
364 " movb%%dl,%%al\n\t"
365 " outb%%al,$0x42\n\t"
366 " movb%%dh,%%al\n\t"
367 " outb%%al,$0x42"
368 : : "d"(value) /*: no clobber */ );
369}
370
371/* Returns the number of times the loop ran before the PIT2 signaled */
372static inline unsigned long poll_PIT2_gate(void)
373{
374 unsigned long count = 0;
375 unsigned char nmi_sc_val;
376 do {
377 ++count;
378 __asm__ volatile(
379 "inb$0x61,%0"
380 : "=q"(nmi_sc_val) /*:*/ /* no input */ /*:*/ /* no clobber */);
381 } while( (nmi_sc_val & 0x20) == 0);
382 return count;
383}
384
385static void cpuid_update_generic_info()
386{
387 uint32_t cpuid_reg[4];
388 uint32_t max_extid;
389 char str[128];
390 char* p;
391i386_cpu_info_t* info_p = cpuid_info();
392
393 /* Get vendor */
394 do_cpuid(0, cpuid_reg);
395 bcopy((char *)&cpuid_reg[ebx], &info_p->cpuid_vendor[0], 4); /* ug */
396 bcopy((char *)&cpuid_reg[ecx], &info_p->cpuid_vendor[8], 4);
397 bcopy((char *)&cpuid_reg[edx], &info_p->cpuid_vendor[4], 4);
398 info_p->cpuid_vendor[12] = 0;
399
400 /* Get extended CPUID results */
401 do_cpuid(0x80000000, cpuid_reg);
402 max_extid = cpuid_reg[eax];
403
404 /* Check to see if we can get the brand string */
405 if (max_extid >= 0x80000004) {
406 /*
407 * The brand string is up to 48 bytes and is guaranteed to be
408 * NUL terminated.
409 */
410 do_cpuid(0x80000002, cpuid_reg);
411 bcopy((char *)cpuid_reg, &str[0], 16);
412 do_cpuid(0x80000003, cpuid_reg);
413 bcopy((char *)cpuid_reg, &str[16], 16);
414 do_cpuid(0x80000004, cpuid_reg);
415 bcopy((char *)cpuid_reg, &str[32], 16);
416 for (p = str; *p != '\0'; p++) {
417 if (*p != ' ') break;
418 }
419 strncpy(info_p->cpuid_brand_string, p,
420 sizeof(info_p->cpuid_brand_string));
421
422 if (!strncmp(info_p->cpuid_brand_string, CPUID_STRING_UNKNOWN,
423 min(sizeof(info_p->cpuid_brand_string),
424 strlen(CPUID_STRING_UNKNOWN) + 1))) {
425 /*
426 * This string means we have a firmware-programmable brand string,
427 * and the firmware couldn't figure out what sort of CPU we have.
428 */
429 info_p->cpuid_brand_string[0] = '\0';
430 }
431 }
432
433 /* Get cache and addressing info */
434 if (max_extid >= 0x80000006) {
435 do_cpuid(0x80000006, cpuid_reg);
436 info_p->cpuid_cache_linesize = bitfield(cpuid_reg[ecx], 7, 0);
437 info_p->cpuid_cache_L2_associativity = bitfield(cpuid_reg[ecx], 15, 12);
438 info_p->cpuid_cache_size = bitfield(cpuid_reg[ecx], 31, 16);
439 do_cpuid(0x80000008, cpuid_reg);
440 info_p->cpuid_address_bits_physical = bitfield(cpuid_reg[eax], 7, 0);
441 info_p->cpuid_address_bits_virtual = bitfield(cpuid_reg[eax], 15, 8);
442 }
443
444 /* Get processor signature and decode */
445 do_cpuid(1, cpuid_reg);
446 info_p->cpuid_signature = cpuid_reg[eax];
447 info_p->cpuid_stepping = bitfield(cpuid_reg[eax], 3, 0);
448 info_p->cpuid_model = bitfield(cpuid_reg[eax], 7, 4);
449 info_p->cpuid_family = bitfield(cpuid_reg[eax], 11, 8);
450 info_p->cpuid_type = bitfield(cpuid_reg[eax], 13, 12);
451 info_p->cpuid_extmodel = bitfield(cpuid_reg[eax], 19, 16);
452 info_p->cpuid_extfamily = bitfield(cpuid_reg[eax], 27, 20);
453 info_p->cpuid_brand = bitfield(cpuid_reg[ebx], 7, 0);
454 info_p->cpuid_features = quad(cpuid_reg[ecx], cpuid_reg[edx]);
455
456 /* Fold extensions into family/model */
457 if (info_p->cpuid_family == 0x0f) {
458 info_p->cpuid_family += info_p->cpuid_extfamily;
459 }
460 if (info_p->cpuid_family == 0x0f || info_p->cpuid_family== 0x06) {
461 info_p->cpuid_model += (info_p->cpuid_extmodel << 4);
462 }
463
464 if (info_p->cpuid_features & CPUID_FEATURE_HTT) {
465 info_p->cpuid_logical_per_package = bitfield(cpuid_reg[ebx], 23, 16);
466 } else {
467 info_p->cpuid_logical_per_package = 1;
468 }
469
470 if (max_extid >= 0x80000001) {
471 do_cpuid(0x80000001, cpuid_reg);
472 info_p->cpuid_extfeatures = quad(cpuid_reg[ecx], cpuid_reg[edx]);
473 }
474
475 if (info_p->cpuid_extfeatures & CPUID_FEATURE_MONITOR) {
476
477 do_cpuid(5, cpuid_reg);
478 info_p->cpuid_mwait_linesize_min = cpuid_reg[eax];
479 info_p->cpuid_mwait_linesize_max = cpuid_reg[ebx];
480 info_p->cpuid_mwait_extensions = cpuid_reg[ecx];
481 info_p->cpuid_mwait_sub_Cstates = cpuid_reg[edx];
482
483 do_cpuid(6, cpuid_reg);
484 info_p->cpuid_thermal_sensor = bitfield(cpuid_reg[eax], 0, 0);
485 info_p->cpuid_thermal_dynamic_acceleration =
486bitfield(cpuid_reg[eax], 1, 1);
487 info_p->cpuid_thermal_thresholds = bitfield(cpuid_reg[ebx], 3, 0);
488 info_p->cpuid_thermal_ACNT_MCNT = bitfield(cpuid_reg[ecx], 0, 0);
489
490 do_cpuid(0xa, cpuid_reg);
491 info_p->cpuid_arch_perf_version = bitfield(cpuid_reg[eax], 7, 0);
492 info_p->cpuid_arch_perf_number = bitfield(cpuid_reg[eax],15, 8);
493 info_p->cpuid_arch_perf_width = bitfield(cpuid_reg[eax],23,16);
494 info_p->cpuid_arch_perf_events_number = bitfield(cpuid_reg[eax],31,24);
495 info_p->cpuid_arch_perf_events = cpuid_reg[ebx];
496 info_p->cpuid_arch_perf_fixed_number = bitfield(cpuid_reg[edx], 4, 0);
497 info_p->cpuid_arch_perf_fixed_width = bitfield(cpuid_reg[edx],12, 5);
498
499 }
500
501do_cpuid(4, cpuid_reg);
502info_p->cpuid_cores_per_package = bitfield(cpuid_reg[eax], 31, 26) + 1;
503
504if (info_p->cpuid_cores_per_package == 0) {
505info_p->cpuid_cores_per_package = 1;
506
507}
508
509switch (info_p->cpuid_model)
510{
511case 0x1C:
512{
513//uint64_t msr = rdmsr64(MSR_CORE_THREAD_COUNT);
514info_p->core_count = 1; //bitfield((uint32_t)msr, 19, 16);
515info_p->thread_count = 2; //bitfield((uint32_t)msr, 15, 0);
516}
517break;
518case 0x19: // some i5 ???
519case 0x1A: // Intel Core i7 LGA1366 (45nm)
520case 0x1E: // Intel Core i5, i7 LGA1156 (45nm)
521case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm)
522{
523uint64_t msr = rdmsr64(MSR_CORE_THREAD_COUNT);
524info_p->core_count = bitfield((uint32_t)msr, 31, 16);
525info_p->thread_count = bitfield((uint32_t)msr, 15, 0);
526} break;
527case 0x2C: // Intel Core i7 LGA1366 (32nm) 6 Core
528case 0x1F:
529case 0x2F:
530{
531uint64_t msr = rdmsr64(MSR_CORE_THREAD_COUNT);
532info_p->core_count = bitfield((uint32_t)msr, 19, 16);
533info_p->thread_count = bitfield((uint32_t)msr, 15, 0);
534break;
535}
536
537default:
538{
539do_cpuid(1, cpuid_reg);
540info_p->core_count = bitfield(cpuid_reg[1], 23, 16);
541} break;
542}
543if (info_p->core_count == 0) {
544info_p->core_count = info_p->cpuid_cores_per_package;
545info_p->thread_count = info_p->cpuid_logical_per_package;
546}
547
548}
549
550
551#endif /* !__LIBSAIO_CPU_H */
552

Archive Download this file

Revision: 1174