Root/
Source at commit 1146 created 12 years 10 months ago. By azimutz, Sync with trunk (r1145). Add nVidia dev id's, 0DF4 for "GeForce GT 450M" (issue 99) and 1251 for "GeForce GTX 560M" (thanks to oSxFr33k for testing). | |
---|---|
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_C3␉␉␉0x07␊ |
12 | #define CPU_VIA_C3_Ezra_T␉0x08␊ |
13 | ␊ |
14 | #define CPU_VIA_NANO␉␉0x0F␊ |
15 | ␊ |
16 | ␊ |
17 | ␊ |
18 | extern 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_PERF_STATUS␉0x198␊ |
27 | #define MSR_IA32_PERF_CONTROL␉0x199␊ |
28 | #define MSR_IA32_EXT_CONFIG␉␉0x00EE␊ |
29 | #define MSR_IA32_EBL_CR_POWERON␉0x2A␊ |
30 | ␊ |
31 | #define MSR_FLEX_RATIO␉␉␉0x194␊ |
32 | #define␉MSR_PLATFORM_INFO␉␉0xCE␊ |
33 | ␊ |
34 | #define K8_FIDVID_STATUS␉␉0xC0010042␊ |
35 | #define K10_COFVID_STATUS␉␉0xC0010071␊ |
36 | ␊ |
37 | /* Centaur-Hauls/IDT defined MSRs. */␊ |
38 | #define MSR_IDT_FCR1␉␉␉0x00000107␊ |
39 | #define MSR_IDT_FCR2␉␉␉0x00000108␊ |
40 | #define MSR_IDT_FCR3␉␉␉0x00000109␊ |
41 | #define MSR_IDT_FCR4␉␉␉0x0000010a␊ |
42 | ␊ |
43 | #define MSR_IDT_MCR0␉␉␉0x00000110␊ |
44 | #define MSR_IDT_MCR1␉␉␉0x00000111␊ |
45 | #define MSR_IDT_MCR2␉␉␉0x00000112␊ |
46 | #define MSR_IDT_MCR3␉␉␉0x00000113␊ |
47 | #define MSR_IDT_MCR4␉␉␉0x00000114␊ |
48 | #define MSR_IDT_MCR5␉␉␉0x00000115␊ |
49 | #define MSR_IDT_MCR6␉␉␉0x00000116␊ |
50 | #define MSR_IDT_MCR7␉␉␉0x00000117␊ |
51 | #define MSR_IDT_MCR_CTRL␉␉0x00000120␊ |
52 | ␊ |
53 | /* VIA Nano defined MSTs */␊ |
54 | #define MSR_NANO_FCR1 0x1204 // This MSR contains control bits and family, model, etc.␊ |
55 | #define MSR_NANO_FCR2 0x1206 // This MSR contains part of the vendor string␊ |
56 | #define MSR_NANO_FCR3 0x1207 // This MSR contains part of the vendor string␊ |
57 | #define VIA_ALTERNATIVE_VENDOR_BIT (1 << 8) // This bit in MSR_IDT_FCR1 enables alternative vendor string␊ |
58 | ␊ |
59 | /* VIA Cyrix defined MSRs */␊ |
60 | #define MSR_VIA_FCR␉␉␉␉0x00001107␊ |
61 | #define MSR_VIA_LONGHAUL␉␉0x0000110a␊ |
62 | #define MSR_VIA_RNG␉␉␉␉0x0000110b␊ |
63 | #define MSR_VIA_BCR2␉␉␉0x00001147␊ |
64 | ␊ |
65 | ␊ |
66 | ␊ |
67 | #define DEFAULT_FSB␉␉100000 /* for now, hardcoding 100MHz for old CPUs */␊ |
68 | ␊ |
69 | // DFE: This constant comes from older xnu:␊ |
70 | #define CLKNUM␉␉␉1193182␉␉/* formerly 1193167 */␊ |
71 | ␊ |
72 | // DFE: These two constants come from Linux except CLOCK_TICK_RATE replaced with CLKNUM␊ |
73 | #define CALIBRATE_TIME_MSEC␉30␉␉/* 30 msecs */␊ |
74 | #define CALIBRATE_LATCH␉␉((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000)␊ |
75 | ␊ |
76 | static inline uint64_t rdtsc64(void)␊ |
77 | {␊ |
78 | ␉uint64_t ret;␊ |
79 | ␉__asm__ volatile("rdtsc" : "=A" (ret));␊ |
80 | ␉return ret;␊ |
81 | }␊ |
82 | ␊ |
83 | static inline uint64_t rdmsr64(uint32_t msr)␊ |
84 | {␊ |
85 | uint64_t ret;␊ |
86 | __asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr));␊ |
87 | return ret;␊ |
88 | }␊ |
89 | ␊ |
90 | static inline void wrmsr64(uint32_t msr, uint64_t val)␊ |
91 | {␊ |
92 | ␉__asm__ volatile("wrmsr" : : "c" (msr), "A" (val));␊ |
93 | }␊ |
94 | ␊ |
95 | ␊ |
96 | static inline void intel_waitforsts(void) {␊ |
97 | ␉uint32_t inline_timeout = 100000;␊ |
98 | ␉while (rdmsr64(MSR_IA32_PERF_STATUS) & (1 << 21)) { if (!inline_timeout--) break; }␊ |
99 | }␊ |
100 | ␊ |
101 | ␊ |
102 | ␊ |
103 | ␊ |
104 | ␊ |
105 | static inline void do_cpuid(uint32_t selector, uint32_t *data)␊ |
106 | {␊ |
107 | ␉asm volatile ("cpuid"␊ |
108 | ␉␉␉␉ : "=a" (data[0]),␊ |
109 | ␉␉␉␉ "=b" (data[1]),␊ |
110 | ␉␉␉␉ "=c" (data[2]),␊ |
111 | ␉␉␉␉ "=d" (data[3])␊ |
112 | ␉␉␉␉ : "a" (selector));␊ |
113 | }␊ |
114 | ␊ |
115 | static inline void do_cpuid2(uint32_t selector, uint32_t selector2, uint32_t *data)␊ |
116 | {␊ |
117 | ␉asm volatile ("cpuid"␊ |
118 | ␉␉␉␉ : "=a" (data[0]),␊ |
119 | ␉␉␉␉ "=b" (data[1]),␊ |
120 | ␉␉␉␉ "=c" (data[2]),␊ |
121 | ␉␉␉␉ "=d" (data[3])␊ |
122 | ␉␉␉␉ : "a" (selector), "c" (selector2));␊ |
123 | }␊ |
124 | ␊ |
125 | // DFE: enable_PIT2 and disable_PIT2 come from older xnu␊ |
126 | ␊ |
127 | /*␊ |
128 | * Enable or disable timer 2.␊ |
129 | * Port 0x61 controls timer 2:␊ |
130 | * bit 0 gates the clock,␊ |
131 | * bit 1 gates output to speaker.␊ |
132 | */␊ |
133 | static inline void enable_PIT2(void)␊ |
134 | {␊ |
135 | /* Enable gate, disable speaker */␊ |
136 | __asm__ volatile(␊ |
137 | ␉␉␉␉␉ " inb $0x61,%%al \n\t"␊ |
138 | ␉␉␉␉␉ " and $0xFC,%%al \n\t" /* & ~0x03 */␊ |
139 | ␉␉␉␉␉ " or $1,%%al \n\t"␊ |
140 | ␉␉␉␉␉ " outb %%al,$0x61 \n\t"␊ |
141 | ␉␉␉␉␉ : : : "%al" );␊ |
142 | }␊ |
143 | ␊ |
144 | static inline void disable_PIT2(void)␊ |
145 | {␊ |
146 | /* Disable gate and output to speaker */␊ |
147 | __asm__ volatile(␊ |
148 | ␉␉␉␉␉ " inb $0x61,%%al \n\t"␊ |
149 | ␉␉␉␉␉ " and $0xFC,%%al \n\t"␉/* & ~0x03 */␊ |
150 | ␉␉␉␉␉ " outb %%al,$0x61 \n\t"␊ |
151 | ␉␉␉␉␉ : : : "%al" );␊ |
152 | }␊ |
153 | ␊ |
154 | // DFE: set_PIT2_mode0, poll_PIT2_gate, and measure_tsc_frequency are␊ |
155 | // roughly based on Linux code␊ |
156 | ␊ |
157 | /* Set the 8254 channel 2 to mode 0 with the specified value.␊ |
158 | In mode 0, the counter will initially set its gate low when the␊ |
159 | timer expires. For this to be useful, you ought to set it high␊ |
160 | before calling this function. The enable_PIT2 function does this.␊ |
161 | */␊ |
162 | static inline void set_PIT2_mode0(uint16_t value)␊ |
163 | {␊ |
164 | __asm__ volatile(␊ |
165 | ␉␉␉␉␉ " movb $0xB0,%%al \n\t"␊ |
166 | ␉␉␉␉␉ " outb␉%%al,$0x43␉\n\t"␊ |
167 | ␉␉␉␉␉ " movb␉%%dl,%%al␉\n\t"␊ |
168 | ␉␉␉␉␉ " outb␉%%al,$0x42␉\n\t"␊ |
169 | ␉␉␉␉␉ " movb␉%%dh,%%al␉\n\t"␊ |
170 | ␉␉␉␉␉ " outb␉%%al,$0x42"␊ |
171 | ␉␉␉␉␉ : : "d"(value) /*: no clobber */ );␊ |
172 | }␊ |
173 | ␊ |
174 | /* Returns the number of times the loop ran before the PIT2 signaled */␊ |
175 | static inline unsigned long poll_PIT2_gate(void)␊ |
176 | {␊ |
177 | unsigned long count = 0;␊ |
178 | unsigned char nmi_sc_val;␊ |
179 | do {␊ |
180 | ++count;␊ |
181 | __asm__ volatile(␊ |
182 | ␉␉␉␉␉␉ "inb␉$0x61,%0"␊ |
183 | ␉␉␉␉␉␉ : "=q"(nmi_sc_val) /*:*/ /* no input */ /*:*/ /* no clobber */);␊ |
184 | } while( (nmi_sc_val & 0x20) == 0);␊ |
185 | return count;␊ |
186 | }␊ |
187 | ␊ |
188 | #endif /* !__LIBSAIO_CPU_H */␊ |
189 |