Chameleon

Chameleon Svn Source Tree

Root/branches/slice/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 bit(n)(1UL << (n))
21#define bitmask(h,l)((bit(h)|(bit(h)-1)) & ~(bit(l)-1))
22#define bitfield(x,h,l)(((x) & bitmask(h,l)) >> l)
23
24#define CPU_STRING_UNKNOWN"Unknown CPU Typ"
25
26#define MSR_IA32_PLATFORM_ID0x0017
27#define MSR_P4_EBC_FREQUENCY_ID0x002C
28#defineMSR_IA32_PERF_STATUS0x0198
29#define MSR_IA32_PERF_CONTROL0x0199
30#define MSR_IA32_EXT_CONFIG0x00EE
31#define MSR_FLEX_RATIO0x0194 //Slice - not used
32#define MSR_FSB_FREQ0x00CD //Slice - not used
33#defineMSR_PLATFORM_INFO0x00CE// for i7 it gives min and max
34#define MSR_TURBO_RATIO0x01AD //Slice - for i7
35#define MSR_IA32_EBL_CR_POWERON0x002A //Meklort - for VIA
36#define K8_FIDVID_STATUS0xC0010042
37#define K10_COFVID_STATUS0xC0010071
38
39/* Centaur-Hauls/IDT defined MSRs. */
40#define MSR_IDT_FCR10x00000107
41#define MSR_IDT_FCR20x00000108
42#define MSR_IDT_FCR30x00000109
43#define MSR_IDT_FCR40x0000010a
44
45#define MSR_IDT_MCR00x00000110
46#define MSR_IDT_MCR10x00000111
47#define MSR_IDT_MCR20x00000112
48#define MSR_IDT_MCR30x00000113
49#define MSR_IDT_MCR40x00000114
50#define MSR_IDT_MCR50x00000115
51#define MSR_IDT_MCR60x00000116
52#define MSR_IDT_MCR70x00000117
53#define MSR_IDT_MCR_CTRL0x00000120
54
55/* VIA Nano defined MSTs */
56#define MSR_NANO_FCR1 0x1204 // This MSR contains control bits and family, model, etc.
57#define MSR_NANO_FCR2 0x1206 // This MSR contains part of the vendor string
58#define MSR_NANO_FCR3 0x1207 // This MSR contains part of the vendor string
59#define VIA_ALTERNATIVE_VENDOR_BIT (1 << 8) // This bit in MSR_IDT_FCR1 enables alternative vendor string
60
61/* VIA Cyrix defined MSRs */
62#define MSR_VIA_FCR0x00001107
63#define MSR_VIA_LONGHAUL0x0000110a
64#define MSR_VIA_RNG0x0000110b
65#define MSR_VIA_BCR20x00001147
66
67
68
69#define DEFAULT_FSB100000 /* for now, hardcoding 100MHz for old CPUs */
70
71// DFE: This constant comes from older xnu:
72#define CLKNUM1193182/* formerly 1193167 */
73
74// DFE: These two constants come from Linux except CLOCK_TICK_RATE replaced with CLKNUM
75#define CALIBRATE_TIME_MSEC30/* 30 msecs */
76#define CALIBRATE_LATCH((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000)
77
78static inline uint64_t rdtsc64(void)
79{
80uint64_t ret;
81__asm__ volatile("rdtsc" : "=A" (ret));
82return ret;
83}
84
85static inline uint64_t rdmsr64(uint32_t msr)
86{
87 uint64_t ret;
88 __asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr));
89 return ret;
90}
91
92static inline void wrmsr64(uint32_t msr, uint64_t val)
93{
94__asm__ volatile("wrmsr" : : "c" (msr), "A" (val));
95}
96
97static inline void intel_waitforsts(void) {
98uint32_t inline_timeout = 100000;
99while (rdmsr64(MSR_IA32_PERF_STATUS) & (1 << 21)) { if (!inline_timeout--) break; }
100}
101
102static inline void do_cpuid(uint32_t selector, uint32_t *data)
103{
104asm volatile ("cpuid"
105 : "=a" (data[0]),
106 "=b" (data[1]),
107 "=c" (data[2]),
108 "=d" (data[3])
109 : "a" (selector));
110}
111
112static inline void do_cpuid2(uint32_t selector, uint32_t selector2, uint32_t *data)
113{
114asm volatile ("cpuid"
115 : "=a" (data[0]),
116 "=b" (data[1]),
117 "=c" (data[2]),
118 "=d" (data[3])
119 : "a" (selector), "c" (selector2));
120}
121
122// DFE: enable_PIT2 and disable_PIT2 come from older xnu
123
124/*
125 * Enable or disable timer 2.
126 * Port 0x61 controls timer 2:
127 * bit 0 gates the clock,
128 * bit 1 gates output to speaker.
129 */
130static inline void enable_PIT2(void)
131{
132 /* Enable gate, disable speaker */
133 __asm__ volatile(
134 " inb $0x61,%%al \n\t"
135 " and $0xFC,%%al \n\t" /* & ~0x03 */
136 " or $1,%%al \n\t"
137 " outb %%al,$0x61 \n\t"
138 : : : "%al" );
139}
140
141static inline void disable_PIT2(void)
142{
143 /* Disable gate and output to speaker */
144 __asm__ volatile(
145 " inb $0x61,%%al \n\t"
146 " and $0xFC,%%al \n\t"/* & ~0x03 */
147 " outb %%al,$0x61 \n\t"
148 : : : "%al" );
149}
150
151// DFE: set_PIT2_mode0, poll_PIT2_gate, and measure_tsc_frequency are
152// roughly based on Linux code
153
154/* Set the 8254 channel 2 to mode 0 with the specified value.
155 In mode 0, the counter will initially set its gate low when the
156 timer expires. For this to be useful, you ought to set it high
157 before calling this function. The enable_PIT2 function does this.
158 */
159static inline void set_PIT2_mode0(uint16_t value)
160{
161 __asm__ volatile(
162 " movb $0xB0,%%al \n\t"
163 " outb%%al,$0x43\n\t"
164 " movb%%dl,%%al\n\t"
165 " outb%%al,$0x42\n\t"
166 " movb%%dh,%%al\n\t"
167 " outb%%al,$0x42"
168 : : "d"(value) /*: no clobber */ );
169}
170
171/* Returns the number of times the loop ran before the PIT2 signaled */
172static inline unsigned long poll_PIT2_gate(void)
173{
174 unsigned long count = 0;
175 unsigned char nmi_sc_val;
176 do {
177 ++count;
178 __asm__ volatile(
179 "inb$0x61,%0"
180 : "=q"(nmi_sc_val) /*:*/ /* no input */ /*:*/ /* no clobber */);
181 } while( (nmi_sc_val & 0x20) == 0);
182 return count;
183}
184
185#endif /* !__LIBSAIO_CPU_H */
186

Archive Download this file

Revision: 676