Chameleon

Chameleon Svn Source Tree

Root/branches/Bungo/i386/libsaio/cpu.h

1/*
2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * @OSF_COPYRIGHT@
30 */
31/*
32 * Copyright 2008 Islam Ahmed Zaid. All rights reserved. <azismed@gmail.com>
33 * AsereBLN: 2009: cleanup and bugfix
34 */
35
36#ifndef __LIBSAIO_CPU_H
37#define __LIBSAIO_CPU_H
38
39#include "platform.h"
40
41extern void scan_cpu(PlatformInfo_t *);
42
43#define bit(n)(1ULL << (n))
44#define bitmask(h,l)((bit(h) | (bit(h)-1)) & ~(bit(l)-1))
45#define bitfield(x,h,l)(((x) & bitmask(h,l)) >> l)
46#define hbit(n)(1ULL << ((n)+32))
47#define min(a,b)((a) < (b) ? (a) : (b))
48#define quad32(hi,lo)((((uint32_t)(hi)) << 16) | (((uint32_t)(lo)) & 0xFFFF))
49#define quad64(hi,lo)((((uint64_t)(hi)) << 32) | (((uint64_t)(lo)) & 0xFFFFFFFFUL))
50
51#defineCPUID_VID_INTEL "GenuineIntel"
52#defineCPUID_VID_AMD "AuthenticAMD"
53#define CPU_STRING_UNKNOWN"Unknown CPU Typ"
54
55/*
56 * The CPUID_FEATURE_XXX values define 64-bit values
57 * returned in %ecx:%edx to a CPUID request with %eax of 1:
58 */
59#define CPUID_FEATURE_FPU bit(0) /* Floating point unit on-chip */
60#define CPUID_FEATURE_VME bit(1) /* Virtual Mode Extension */
61#define CPUID_FEATURE_DE bit(2) /* Debugging Extension */
62#define CPUID_FEATURE_PSE bit(3) /* Page Size Extension */
63#define CPUID_FEATURE_TSC bit(4) /* Time Stamp Counter */
64#define CPUID_FEATURE_MSR bit(5) /* Model Specific Registers */
65#define CPUID_FEATURE_PAE bit(6) /* Physical Address Extension */
66#define CPUID_FEATURE_MCE bit(7) /* Machine Check Exception */
67#define CPUID_FEATURE_CX8 bit(8) /* CMPXCHG8B */
68#define CPUID_FEATURE_APIC bit(9) /* On-chip APIC */
69#define CPUID_FEATURE_SEP bit(11) /* Fast System Call */
70#define CPUID_FEATURE_MTRR bit(12) /* Memory Type Range Register */
71#define CPUID_FEATURE_PGE bit(13) /* Page Global Enable */
72#define CPUID_FEATURE_MCA bit(14) /* Machine Check Architecture */
73#define CPUID_FEATURE_CMOV bit(15) /* Conditional Move Instruction */
74#define CPUID_FEATURE_PAT bit(16) /* Page Attribute Table */
75#define CPUID_FEATURE_PSE36 bit(17) /* 36-bit Page Size Extension */
76#define CPUID_FEATURE_PSN bit(18) /* Processor Serial Number */
77#define CPUID_FEATURE_CLFSH bit(19) /* CLFLUSH Instruction supported */
78#define CPUID_FEATURE_DS bit(21) /* Debug Store */
79#define CPUID_FEATURE_ACPI bit(22) /* Thermal monitor and Clock Ctrl */
80#define CPUID_FEATURE_MMX bit(23) /* MMX supported */
81#define CPUID_FEATURE_FXSR bit(24) /* Fast floating pt save/restore */
82#define CPUID_FEATURE_SSE bit(25) /* Streaming SIMD extensions */
83#define CPUID_FEATURE_SSE2 bit(26) /* Streaming SIMD extensions 2 */
84#define CPUID_FEATURE_SS bit(27) /* Self-Snoop */
85#define CPUID_FEATURE_HTT bit(28) /* Hyper-Threading Technology */
86#define CPUID_FEATURE_TM bit(29) /* Thermal Monitor (TM1) */
87#define CPUID_FEATURE_PBE bit(31) /* Pend Break Enable */
88
89#define CPUID_FEATURE_SSE3 hbit(0) /* Streaming SIMD extensions 3 */
90#define CPUID_FEATURE_PCLMULQDQ hbit(1) /* PCLMULQDQ instruction */
91#define CPUID_FEATURE_DTES64 hbit(2) /* 64-bit DS layout */
92#define CPUID_FEATURE_MONITOR hbit(3) /* Monitor/mwait */
93#define CPUID_FEATURE_DSCPL hbit(4) /* Debug Store CPL */
94#define CPUID_FEATURE_VMX hbit(5) /* VMX */
95#define CPUID_FEATURE_SMX hbit(6) /* SMX */
96#define CPUID_FEATURE_EST hbit(7) /* Enhanced SpeedsTep (GV3) */
97#define CPUID_FEATURE_TM2 hbit(8) /* Thermal Monitor 2 */
98#define CPUID_FEATURE_SSSE3 hbit(9) /* Supplemental SSE3 instructions */
99#define CPUID_FEATURE_CID hbit(10) /* L1 Context ID */
100#define CPUID_FEATURE_SEGLIM64 hbit(11) /* 64-bit segment limit checking */
101#define CPUID_FEATURE_FMA hbit(12) /* Fused-Multiply-Add support */
102#define CPUID_FEATURE_CX16 hbit(13) /* CmpXchg16b instruction */
103#define CPUID_FEATURE_xTPR hbit(14) /* Send Task PRiority msgs */
104#define CPUID_FEATURE_PDCM hbit(15) /* Perf/Debug Capability MSR */
105
106#define CPUID_FEATURE_PCID hbit(17) /* ASID-PCID support */
107#define CPUID_FEATURE_DCA hbit(18) /* Direct Cache Access */
108#define CPUID_FEATURE_SSE4_1 hbit(19) /* Streaming SIMD extensions 4.1 */
109#define CPUID_FEATURE_SSE4_2 hbit(20) /* Streaming SIMD extensions 4.2 */
110#define CPUID_FEATURE_x2APIC hbit(21) /* Extended APIC Mode */
111#define CPUID_FEATURE_MOVBE hbit(22) /* MOVBE instruction */
112#define CPUID_FEATURE_POPCNT hbit(23) /* POPCNT instruction */
113#define CPUID_FEATURE_TSCTMR hbit(24) /* TSC deadline timer */
114#define CPUID_FEATURE_AES hbit(25) /* AES instructions */
115#define CPUID_FEATURE_XSAVE hbit(26) /* XSAVE instructions */
116#define CPUID_FEATURE_OSXSAVE hbit(27) /* XGETBV/XSETBV instructions */
117#define CPUID_FEATURE_AVX1_0hbit(28) /* AVX 1.0 instructions */
118#define CPUID_FEATURE_F16C hbit(29) /* Float16 convert instructions */
119#define CPUID_FEATURE_RDRANDhbit(30) /* RDRAND instruction */
120#define CPUID_FEATURE_VMM hbit(31) /* VMM (Hypervisor) present */
121
122/*
123 * Leaf 7, subleaf 0 additional features.
124 * Bits returned in %ebx to a CPUID request with {%eax,%ecx} of (0x7,0x0}:
125 */
126#define CPUID_LEAF7_FEATURE_RDWRFSGS bit(0)/* FS/GS base read/write */
127#define CPUID_LEAF7_FEATURE_TSCOFF bit(1)/* TSC thread offset */
128#define CPUID_LEAF7_FEATURE_BMI1 bit(3)/* Bit Manipulation Instrs, set 1 */
129#define CPUID_LEAF7_FEATURE_HLE bit(4)/* Hardware Lock Elision*/
130#define CPUID_LEAF7_FEATURE_AVX2 bit(5)/* AVX2 Instructions */
131#define CPUID_LEAF7_FEATURE_SMEP bit(7)/* Supervisor Mode Execute Protect */
132#define CPUID_LEAF7_FEATURE_BMI2 bit(8)/* Bit Manipulation Instrs, set 2 */
133#define CPUID_LEAF7_FEATURE_ENFSTRG bit(9)/* ENhanced Fast STRinG copy */
134#define CPUID_LEAF7_FEATURE_INVPCID bit(10)/* INVPCID intruction, TDB */
135#define CPUID_LEAF7_FEATURE_RTM bit(11)/* TBD */
136
137/*
138 * The CPUID_EXTFEATURE_XXX values define 64-bit values
139 * returned in %ecx:%edx to a CPUID request with %eax of 0x80000001:
140 */
141#define CPUID_EXTFEATURE_SYSCALL bit(11)/* SYSCALL/sysret */
142#define CPUID_EXTFEATURE_XD bit(20)/* eXecute Disable */
143
144#define CPUID_EXTFEATURE_1GBPAGE bit(26)/* 1GB pages */
145#define CPUID_EXTFEATURE_RDTSCP bit(27)/* RDTSCP */
146#define CPUID_EXTFEATURE_EM64T bit(29)/* Extended Mem 64 Technology */
147
148#define CPUID_EXTFEATURE_LAHF hbit(0)/* LAFH/SAHF instructions */
149
150/*
151 * The CPUID_EXTFEATURE_XXX values define 64-bit values
152 * returned in %ecx:%edx to a CPUID request with %eax of 0x80000007:
153 */
154#define CPUID_EXTFEATURE_TSCI bit(8)/* TSC Invariant */
155
156#defineCPUID_CACHE_SIZE16/* Number of descriptor values */
157
158#define CPUID_MWAIT_EXTENSIONbit(0)/* enumeration of WMAIT extensions */
159#define CPUID_MWAIT_BREAK bit(1)/* interrupts are break events */
160
161//-- processor type -> p_type:
162#define PT_OEM0x00// Intel Original OEM Processor;
163#define PT_OD0x01 // Intel Over Drive Processor;
164#define PT_DUAL0x02// Intel Dual Processor;
165#define PT_RES0x03// Intel Reserved;
166
167/* Known MSR registers */
168#define MSR_IA32_PLATFORM_ID 0x0017
169#define MSR_CORE_THREAD_COUNT 0x0035/* limited use - not for Penryn or older */
170#define IA32_TSC_ADJUST 0x003B
171#define MSR_IA32_BIOS_SIGN_ID 0x008B/* microcode version */
172#define MSR_FSB_FREQ 0x00CD/* limited use - not for i7 */
173#defineMSR_PLATFORM_INFO 0x00CE/* limited use - MinRatio for i7 but Max for Yonah*/
174/* turbo for penryn */
175#define MSR_PKG_CST_CONFIG_CONTROL 0x00E2/* sandy and ivy */
176#define MSR_PMG_IO_CAPTURE_BASE 0x00E4
177#define IA32_MPERF 0x00E7/* TSC in C0 only */
178#define IA32_APERF 0x00E8/* actual clocks in C0 */
179#define MSR_IA32_EXT_CONFIG 0x00EE/* limited use - not for i7 */
180#define MSR_FLEX_RATIO 0x0194/* limited use - not for Penryn or older */
181//see no value on most CPUs
182#defineMSR_IA32_PERF_STATUS 0x0198
183#define MSR_IA32_PERF_CONTROL 0x0199
184#define MSR_IA32_CLOCK_MODULATION 0x019A
185#define MSR_THERMAL_STATUS 0x019C
186#define MSR_IA32_MISC_ENABLE 0x01A0
187#define MSR_THERMAL_TARGET 0x01A2 /* TjMax limited use - not for Penryn or older*/
188#define MSR_MISC_PWR_MGMT 0x01AA
189#define MSR_TURBO_RATIO_LIMIT 0x01AD /* limited use - not for Penryn or older */
190
191#define IA32_ENERGY_PERF_BIAS0x01B0
192#define MSR_PACKAGE_THERM_STATUS0x01B1
193#define IA32_PLATFORM_DCA_CAP0x01F8
194#define MSR_POWER_CTL0x01FC // MSR 000001FC 0000-0000-0004-005F
195
196// Sandy Bridge & JakeTown specific 'Running Average Power Limit' MSR's.
197#define MSR_RAPL_POWER_UNIT0x606 /* R/O */
198//MSR 00000606 0000-0000-000A-1003
199#define MSR_PKGC3_IRTL 0x60A /* RW time limit to go C3 */
200// bit 15 = 1 -- the value valid for C-state PM
201#define MSR_PKGC6_IRTL 0x60B /* RW time limit to go C6 */
202//MSR 0000060B 0000-0000-0000-8854
203//Valid + 010=1024ns + 0x54=84mks
204#define MSR_PKGC7_IRTL 0x60C /* RW time limit to go C7 */
205//MSR 0000060C 0000-0000-0000-8854
206#define MSR_PKG_C2_RESIDENCY 0x60D /* same as TSC but in C2 only */
207
208#define MSR_PKG_RAPL_POWER_LIMIT0x610 //MSR 00000610 0000-A580-0000-8960
209#define MSR_PKG_ENERGY_STATUS0x611 //MSR 00000611 0000-0000-3212-A857
210#define MSR_PKG_POWER_INFO0x614 //MSR 00000614 0000-0000-01E0-02F8
211
212//AMD
213#define K8_FIDVID_STATUS 0xC0010042
214#define K10_COFVID_LIMIT 0xC0010061
215#define K10_PSTATE_STATUS 0xC0010064
216#define K10_COFVID_STATUS 0xC0010071
217
218#define MSR_AMD_MPERF 0x000000E7
219#define MSR_AMD_APERF 0x000000E8
220
221#define DEFAULT_FSB100000 /* for now, hardcoding 100MHz for old CPUs */
222
223// DFE: This constant comes from older xnu:
224#define CLKNUM1193182/* formerly 1193167 */
225
226// DFE: These two constants come from Linux except CLOCK_TICK_RATE replaced with CLKNUM
227#define CALIBRATE_TIME_MSEC30/* 30 msecs */
228#define CALIBRATE_LATCH((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000)
229
230static inline uint64_t rdtsc64(void)
231{
232uint64_t ret;
233__asm__ volatile("rdtsc" : "=A" (ret));
234return ret;
235}
236
237static inline uint64_t rdmsr64(uint32_t msr)
238{
239 uint64_t ret;
240 __asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr));
241 return ret;
242}
243
244static inline void wrmsr64(uint32_t msr, uint64_t val)
245{
246__asm__ volatile("wrmsr" : : "c" (msr), "A" (val));
247}
248
249static inline void intel_waitforsts(void) {
250uint32_t inline_timeout = 100000;
251while (rdmsr64(MSR_IA32_PERF_STATUS) & (1 << 21)) { if (!inline_timeout--) break; }
252}
253/*
254static inline void do_cpuid(uint32_t selector, uint32_t *data)
255{
256asm volatile ("cpuid"
257 : "=a" (data[0]),
258 "=b" (data[1]),
259 "=c" (data[2]),
260 "=d" (data[3])
261 : "a" (selector));
262}
263*/
264/* From Apple's cpuid.h */
265typedef enum { eax, ebx, ecx, edx } cpuid_register_t;
266
267static inline void cpuid(uint32_t *data)
268{
269asm("cpuid"
270: "=a" (data[eax]),
271 "=b" (data[ebx]),
272 "=c" (data[ecx]),
273 "=d" (data[edx])
274: "a" (data[eax]),
275 "b" (data[ebx]),
276 "c" (data[ecx]),
277 "d" (data[edx]));
278}
279
280static inline void do_cpuid(uint32_t selector, uint32_t *data)
281{
282asm("cpuid"
283: "=a" (data[eax]),
284 "=b" (data[ebx]),
285 "=c" (data[ecx]),
286 "=d" (data[edx])
287: "a"(selector),
288 "b" (0),
289 "c" (0),
290 "d" (0));
291}
292/***/
293static inline void do_cpuid2(uint32_t selector, uint32_t selector2, uint32_t *data)
294{
295asm volatile ("cpuid"
296 : "=a" (data[eax]),
297 "=b" (data[ebx]),
298 "=c" (data[ecx]),
299 "=d" (data[edx])
300 : "a" (selector),
301 "b" (0),
302 "c" (selector2),
303 "d" (0));
304}
305
306// DFE: enable_PIT2 and disable_PIT2 come from older xnu
307
308/*
309 * Enable or disable timer 2.
310 * Port 0x61 controls timer 2:
311 * bit 0 gates the clock,
312 * bit 1 gates output to speaker.
313 */
314static inline void enable_PIT2(void)
315{
316 /* Enable gate, disable speaker */
317 __asm__ volatile(
318 " inb $0x61,%%al \n\t"
319 " and $0xFC,%%al \n\t" /* & ~0x03 */
320 " or $1,%%al \n\t"
321 " outb %%al,$0x61 \n\t"
322 : : : "%al" );
323}
324
325static inline void disable_PIT2(void)
326{
327 /* Disable gate and output to speaker */
328 __asm__ volatile(
329 " inb $0x61,%%al \n\t"
330 " and $0xFC,%%al \n\t"/* & ~0x03 */
331 " outb %%al,$0x61 \n\t"
332 : : : "%al" );
333}
334
335// DFE: set_PIT2_mode0, poll_PIT2_gate, and measure_tsc_frequency are
336// roughly based on Linux code
337
338/* Set the 8254 channel 2 to mode 0 with the specified value.
339 In mode 0, the counter will initially set its gate low when the
340 timer expires. For this to be useful, you ought to set it high
341 before calling this function. The enable_PIT2 function does this.
342 */
343static inline void set_PIT2_mode0(uint16_t value)
344{
345 __asm__ volatile(
346 " movb $0xB0,%%al \n\t"
347 " outb%%al,$0x43\n\t"
348 " movb%%dl,%%al\n\t"
349 " outb%%al,$0x42\n\t"
350 " movb%%dh,%%al\n\t"
351 " outb%%al,$0x42"
352 : : "d"(value) /*: no clobber */ );
353}
354
355/* Returns the number of times the loop ran before the PIT2 signaled */
356static inline unsigned long poll_PIT2_gate(void)
357{
358 unsigned long count = 0;
359 unsigned char nmi_sc_val;
360 do {
361 ++count;
362 __asm__ volatile(
363 "inb$0x61,%0"
364 : "=a"(nmi_sc_val) /*:*/ /* no input */ /*:*/ /* no clobber */);
365 } while( (nmi_sc_val & 0x20) == 0);
366 return count;
367}
368
369inline static void
370set_PIT2(int value)
371{
372/*
373 * First, tell the clock we are going to write 16 bits to the counter
374 * and enable one-shot mode (command 0xB8 to port 0x43)
375 * Then write the two bytes into the PIT2 clock register (port 0x42).
376 * Loop until the value is "realized" in the clock,
377 * this happens on the next tick.
378 */
379 asm volatile(
380 " movb $0xB8,%%al \n\t"
381 " outb %%al,$0x43 \n\t"
382 " movb %%dl,%%al \n\t"
383 " outb %%al,$0x42 \n\t"
384 " movb %%dh,%%al \n\t"
385 " outb %%al,$0x42 \n"
386"1: inb $0x42,%%al \n\t"
387 " inb $0x42,%%al \n\t"
388 " cmp %%al,%%dh \n\t"
389 " jne 1b"
390 : : "d"(value) : "%al");
391}
392
393
394inline static uint64_t
395get_PIT2(unsigned int *value)
396{
397 register uint64_t result;
398/*
399 * This routine first latches the time (command 0x80 to port 0x43),
400 * then gets the time stamp so we know how long the read will take later.
401 * Read (from port 0x42) and return the current value of the timer.
402 */
403#ifdef __i386__
404 asm volatile(
405 " xorl %%ecx,%%ecx \n\t"
406 " movb $0x80,%%al \n\t"
407 " outb %%al,$0x43 \n\t"
408 " rdtsc \n\t"
409 " pushl %%eax \n\t"
410 " inb $0x42,%%al \n\t"
411 " movb %%al,%%cl \n\t"
412 " inb $0x42,%%al \n\t"
413 " movb %%al,%%ch \n\t"
414 " popl %%eax "
415 : "=A"(result), "=c"(*value));
416#else /* __x86_64__ */
417 asm volatile(
418" xorq %%rcx,%%rcx \n\t"
419" movb $0x80,%%al \n\t"
420" outb %%al,$0x43 \n\t"
421" rdtsc \n\t"
422" pushq %%rax \n\t"
423" inb $0x42,%%al \n\t"
424" movb %%al,%%cl \n\t"
425" inb $0x42,%%al \n\t"
426" movb %%al,%%ch \n\t"
427" popq %%rax "
428: "=A"(result), "=c"(*value));
429#endif
430
431 return result;
432}
433
434#endif /* !__LIBSAIO_CPU_H */
435

Archive Download this file

Revision: 2839