This source file includes following definitions.
- p4tcc_init
- p4tcc_cpuspeed
- p4tcc_setperf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 #include <sys/param.h>
40 #include <sys/sysctl.h>
41
42 #include <machine/cpu.h>
43 #include <machine/cpufunc.h>
44 #include <machine/specialreg.h>
45
46 static struct {
47 u_short level;
48 u_short reg;
49 } tcc[] = {
50 { 88, 0 },
51 { 75, 7 },
52 { 63, 6 },
53 { 50, 5 },
54 { 38, 4 },
55 { 25, 3 },
56 { 13, 2 },
57 { 0, 1 }
58 };
59
60 #define TCC_LEVELS sizeof(tcc) / sizeof(tcc[0])
61
62 extern int setperf_prio;
63 int p4tcc_level;
64
65 int p4tcc_cpuspeed(int *);
66
67 void
68 p4tcc_init(int family, int step)
69 {
70 if (setperf_prio > 1)
71 return;
72
73 switch (family) {
74 case 0xf:
75 switch (step) {
76 case 0x22:
77 case 0x24:
78 case 0x25:
79 case 0x27:
80 case 0x29:
81
82 tcc[TCC_LEVELS - 1].reg = 2;
83 break;
84 case 0x07:
85 case 0x0a:
86 case 0x12:
87 case 0x13:
88
89 tcc[TCC_LEVELS - 1].reg = 3;
90 tcc[TCC_LEVELS - 2].reg = 3;
91 break;
92 }
93 break;
94 }
95
96 p4tcc_level = tcc[0].level;
97 cpu_setperf = p4tcc_setperf;
98 cpu_cpuspeed = p4tcc_cpuspeed;
99 setperf_prio = 1;
100 }
101
102 int
103 p4tcc_cpuspeed(int *speed)
104 {
105 *speed = cpuspeed * (p4tcc_level + 12) / 100;
106
107 return 0;
108 }
109
110 void
111 p4tcc_setperf(int level)
112 {
113 int i;
114 uint64_t msreg, vet;
115
116 for (i = 0; i < TCC_LEVELS; i++) {
117 if (level >= tcc[i].level)
118 break;
119 }
120
121 msreg = rdmsr(MSR_THERM_CONTROL);
122 msreg &= ~0x1e;
123 if (tcc[i].reg != 0)
124 msreg |= tcc[i].reg << 1 | 1 << 4;
125 wrmsr(MSR_THERM_CONTROL, msreg);
126 vet = rdmsr(MSR_THERM_CONTROL);
127
128 if ((vet & 0x1e) != (msreg & 0x1e))
129 printf("p4_tcc: cpu did not honor request\n");
130 else
131 p4tcc_level = tcc[i].level;
132 }