Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/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
11extern void scan_cpu(PlatformInfo_t *);
12
13#defineMSR_IA32_PERF_STATUS0x198
14#define MSR_IA32_PERF_CONTROL0x199
15#define MSR_IA32_EXT_CONFIG0x00EE
16#define MSR_FLEX_RATIO0x194
17#defineMSR_PLATFORM_INFO0xCE
18#define MSR_TURBO_RATIO_LIMIT0x1AD
19#define MSR_IA32_BIOS_SIGN_ID 0x08B
20#define MSR_CORE_THREAD_COUNT 0x035
21#define K8_FIDVID_STATUS0xC0010042
22#define K10_COFVID_STATUS0xC0010071
23
24#define DEFAULT_FSB100000 /* for now, hardcoding 100MHz for old CPUs */
25
26// DFE: This constant comes from older xnu:
27#define CLKNUM1193182/* formerly 1193167 */
28
29// DFE: These two constants come from Linux except CLOCK_TICK_RATE replaced with CLKNUM
30#define CALIBRATE_TIME_MSEC30/* 30 msecs */
31#define CALIBRATE_LATCH((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000)
32
33static inline uint64_t rdtsc64(void)
34{
35uint64_t ret;
36__asm__ volatile("rdtsc" : "=A" (ret));
37return ret;
38}
39
40static inline uint64_t rdmsr64(uint32_t msr)
41{
42 uint64_t ret;
43 __asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr));
44 return ret;
45}
46
47static inline void wrmsr64(uint32_t msr, uint64_t val)
48{
49__asm__ volatile("wrmsr" : : "c" (msr), "A" (val));
50}
51
52static inline void intel_waitforsts(void) {
53uint32_t inline_timeout = 100000;
54while (rdmsr64(MSR_IA32_PERF_STATUS) & (1 << 21)) { if (!inline_timeout--) break; }
55}
56
57static inline void do_cpuid2(uint32_t selector, uint32_t selector2, uint32_t *data)
58{
59asm volatile ("cpuid"
60 : "=a" (data[0]),
61 "=b" (data[1]),
62 "=c" (data[2]),
63 "=d" (data[3])
64 : "a" (selector), "c" (selector2),
65 "b" (0),
66 "d" (0));
67}
68
69// DFE: enable_PIT2 and disable_PIT2 come from older xnu
70
71/*
72 * Enable or disable timer 2.
73 * Port 0x61 controls timer 2:
74 * bit 0 gates the clock,
75 * bit 1 gates output to speaker.
76 */
77static inline void enable_PIT2(void)
78{
79 /* Enable gate, disable speaker */
80 __asm__ volatile(
81 " inb $0x61,%%al \n\t"
82 " and $0xFC,%%al \n\t" /* & ~0x03 */
83 " or $1,%%al \n\t"
84 " outb %%al,$0x61 \n\t"
85 : : : "%al" );
86}
87
88static inline void disable_PIT2(void)
89{
90 /* Disable gate and output to speaker */
91 __asm__ volatile(
92 " inb $0x61,%%al \n\t"
93 " and $0xFC,%%al \n\t"/* & ~0x03 */
94 " outb %%al,$0x61 \n\t"
95 : : : "%al" );
96}
97
98// DFE: set_PIT2_mode0, poll_PIT2_gate, and measure_tsc_frequency are
99// roughly based on Linux code
100
101/* Set the 8254 channel 2 to mode 0 with the specified value.
102 In mode 0, the counter will initially set its gate low when the
103 timer expires. For this to be useful, you ought to set it high
104 before calling this function. The enable_PIT2 function does this.
105 */
106static inline void set_PIT2_mode0(uint16_t value)
107{
108 __asm__ volatile(
109 " movb $0xB0,%%al \n\t"
110 " outb%%al,$0x43\n\t"
111 " movb%%dl,%%al\n\t"
112 " outb%%al,$0x42\n\t"
113 " movb%%dh,%%al\n\t"
114 " outb%%al,$0x42"
115 : : "d"(value) /*: no clobber */ );
116}
117
118/* Returns the number of times the loop ran before the PIT2 signaled */
119static inline unsigned long poll_PIT2_gate(void)
120{
121 unsigned long count = 0;
122 unsigned char nmi_sc_val;
123 do {
124 ++count;
125 __asm__ volatile(
126 "inb$0x61,%0"
127 : "=q"(nmi_sc_val) /*:*/ /* no input */ /*:*/ /* no clobber */);
128 } while( (nmi_sc_val & 0x20) == 0);
129 return count;
130}
131
132#endif /* !__LIBSAIO_CPU_H */
133

Archive Download this file

Revision: 1119