Chameleon

Chameleon Svn Source Tree

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

Source at commit 655 created 13 years 4 months ago.
By meklort, Modules update. removed hardcoding for dyld_stub_bunder in modules.c Added a subset of klibc for a more complete c library implimentation. Added a subset of uclibc++ for an initial c++ implimentation. Note: cout / cin / file io has been disabled. Also note that exceptions and rtti is disabled. Modified the helow world code foa small c++ test.
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#defineMSR_IA32_PERF_STATUS0x198
27#define MSR_IA32_PERF_CONTROL0x199
28#define MSR_IA32_EXT_CONFIG0x00EE
29#define MSR_IA32_EBL_CR_POWERON0x2A
30
31#define MSR_FLEX_RATIO0x194
32#defineMSR_PLATFORM_INFO0xCE
33
34#define K8_FIDVID_STATUS0xC0010042
35#define K10_COFVID_STATUS0xC0010071
36
37/* Centaur-Hauls/IDT defined MSRs. */
38#define MSR_IDT_FCR10x00000107
39#define MSR_IDT_FCR20x00000108
40#define MSR_IDT_FCR30x00000109
41#define MSR_IDT_FCR40x0000010a
42
43#define MSR_IDT_MCR00x00000110
44#define MSR_IDT_MCR10x00000111
45#define MSR_IDT_MCR20x00000112
46#define MSR_IDT_MCR30x00000113
47#define MSR_IDT_MCR40x00000114
48#define MSR_IDT_MCR50x00000115
49#define MSR_IDT_MCR60x00000116
50#define MSR_IDT_MCR70x00000117
51#define MSR_IDT_MCR_CTRL0x00000120
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_FCR0x00001107
61#define MSR_VIA_LONGHAUL0x0000110a
62#define MSR_VIA_RNG0x0000110b
63#define MSR_VIA_BCR20x00001147
64
65
66
67#define DEFAULT_FSB100000 /* for now, hardcoding 100MHz for old CPUs */
68
69// DFE: This constant comes from older xnu:
70#define CLKNUM1193182/* formerly 1193167 */
71
72// DFE: These two constants come from Linux except CLOCK_TICK_RATE replaced with CLKNUM
73#define CALIBRATE_TIME_MSEC30/* 30 msecs */
74#define CALIBRATE_LATCH((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000)
75
76static inline uint64_t rdtsc64(void)
77{
78uint64_t ret;
79__asm__ volatile("rdtsc" : "=A" (ret));
80return ret;
81}
82
83static 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
90static inline void wrmsr64(uint32_t msr, uint64_t val)
91{
92__asm__ volatile("wrmsr" : : "c" (msr), "A" (val));
93}
94
95
96static inline void intel_waitforsts(void) {
97uint32_t inline_timeout = 100000;
98while (rdmsr64(MSR_IA32_PERF_STATUS) & (1 << 21)) { if (!inline_timeout--) break; }
99}
100
101
102
103
104
105static inline void do_cpuid(uint32_t selector, uint32_t *data)
106{
107asm volatile ("cpuid"
108 : "=a" (data[0]),
109 "=b" (data[1]),
110 "=c" (data[2]),
111 "=d" (data[3])
112 : "a" (selector));
113}
114
115static inline void do_cpuid2(uint32_t selector, uint32_t selector2, uint32_t *data)
116{
117asm 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 */
133static 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
144static 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 */
162static 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 */
175static 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

Archive Download this file

Revision: 655