Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/modules/CPUfreq/CPUfreq.c

1/*
2 * Copyright 2010,2011 valv, cparm <armelcadetpetit@gmail.com>. All rights reserved.
3 */
4#include "boot.h"
5#include "bootstruct.h"
6#include "libsaio.h"
7#include "modules.h"
8#include "Platform.h"
9#include "cpu.h"
10
11#define kFixFSB "FixFSB"
12#define MSR_FSB_FREQ0x000000cd
13#define AMD_10H_11H_CONFIG 0xc0010064
14#define kEnableCPUfreq"EnableCPUfreqModule"
15
16void CPUfreq_hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6)
17{
18int bus_ratio;
19uint64_tmsr , fsbFrequency , cpuFrequency , minfsb , maxfsb ;
20
21if ((Platform->CPU.Vendor == 0x756E6547 /* Intel */) && ((Platform->CPU.Family == 0x06) || (Platform->CPU.Family == 0x0f))) {
22if ((Platform->CPU.Family == 0x06 && Platform->CPU.Model >= 0x0c) || (Platform->CPU.Family == 0x0f && Platform->CPU.Model >= 0x03)) {
23
24if (Platform->CPU.Family == 0x06) {
25
26bus_ratio = 0;
27msr = rdmsr64(MSR_FSB_FREQ);
28fsbFrequency = 0;
29cpuFrequency = 0;
30minfsb = 183000000;
31maxfsb = 185000000;
32
33boolfix_fsb = false;
34uint16_t idlo;
35uint8_t crlo, crhi = 0;
36
37switch (Platform->CPU.Model) {
38case CPUID_MODEL_YONAH:// Core Duo/Solo, Pentium M DC
39case CPUID_MODEL_MEROM:// Core Xeon, Core 2 DC, 65nm
40case 0x16:// Celeron, Core 2 SC, 65nm
41case CPUID_MODEL_PENRYN:// Core 2 Duo/Extreme, Xeon, 45nm
42case CPUID_MODEL_ATOM:// Atom :)
43case 0x27:// Atom Lincroft, 45nm
44
45getBoolForKey(kFixFSB, &fix_fsb, &bootInfo->bootConfig);
46
47if (fix_fsb) {
48
49int bus = (msr >> 0) & 0x7;
50switch (bus) {
51case 0:
52fsbFrequency = 266666667;
53break;
54case 1:
55fsbFrequency = 133333333;
56break;
57case 2:
58fsbFrequency = 200000000;
59break;
60case 3:
61fsbFrequency = 166666667;
62break;
63case 4:
64fsbFrequency = 333333333;
65break;
66case 5:
67fsbFrequency = 100000000;
68break;
69case 6:
70fsbFrequency = 400000000;
71break;
72default:
73fsbFrequency = 200000000;
74break;
75}
76
77
78if (((fsbFrequency) > (minfsb) && (fsbFrequency) < (maxfsb)) || (!fsbFrequency)) {
79fsbFrequency = 200000000;
80}
81Platform->CPU.FSBFrequency = fsbFrequency;
82}
83
84if (getIntForKey("MaxBusRatio", &bus_ratio, &bootInfo->bootConfig))
85{
86msr = rdmsr64(MSR_IA32_PERF_STATUS);
87idlo = (msr >> 48) & 0xffff;
88crlo = (idlo >> 8) & 0xff;
89
90//printf("CPUfreq: MinCoef: 0x%x\n",crlo);
91
92if (Platform->CPU.MaxCoef)
93{
94if (Platform->CPU.MaxDiv)
95{
96crhi = (Platform->CPU.MaxCoef * 10) + 5;
97}
98else
99{
100crhi = Platform->CPU.MaxCoef * 10;
101}
102}
103if (crlo == 0 || crhi == crlo) goto out;
104
105if ((bus_ratio >= (crlo *10)) && (crhi >= bus_ratio) )
106//if (bus_ratio >= 60)
107{
108uint8_t currdiv = 0, currcoef = 0;
109
110currcoef = (int)(bus_ratio / 10);
111
112uint8_t fdiv = bus_ratio - (currcoef * 10);
113if (fdiv > 0)
114currdiv = 1;
115
116Platform->CPU.CurrCoef = currcoef;
117Platform->CPU.CurrDiv = currdiv;
118}
119
120
121}
122
123out:
124if (Platform->CPU.CurrDiv)
125{
126cpuFrequency = (Platform->CPU.FSBFrequency * ((Platform->CPU.CurrCoef * 2) + 1) / 2);
127}
128else
129{
130cpuFrequency = (Platform->CPU.FSBFrequency * Platform->CPU.CurrCoef);
131}
132
133Platform->CPU.CPUFrequency = cpuFrequency;
134verbose("CPU: FSBFreq changed to: %dMHz\n", Platform->CPU.FSBFrequency / 1000000);
135verbose("CPU: CPUFreq changed to: %dMHz\n", Platform->CPU.CPUFrequency / 1000000);
136//verbose("CPUfreq: FSB Fix applied !\n");
137
138break;
139case 0x1d:// Xeon MP MP 7400
140default:
141break;
142}
143}
144}
145}
146else if(Platform->CPU.Vendor == 0x68747541 /* AMD */ && Platform->CPU.Family == 0x0f) // valv: work in progress
147 {
148 verbose("CPU: ");
149 // valv: mobility check
150 if ((strstr(Platform->CPU.BrandString, "obile") == 0) || (strstr(Platform->CPU.BrandString, "Atom") == 0))
151{
152 Platform->CPU.isMobile = true;
153}
154
155 verbose("%s\n", Platform->CPU.BrandString);
156uint8_t bus_ratio_current = 0;
157
158 if(Platform->CPU.ExtFamily == 0x00 /* K8 */)
159 {
160
161 msr = rdmsr64(K8_FIDVID_STATUS);
162bus_ratio_current = (msr & 0x3f) / 2 + 4;
163Platform->CPU.CurrDiv = (msr & 0x01) * 2;
164 if (bus_ratio_current)
165 {
166 if (Platform->CPU.CurrDiv)
167 {
168 Platform->CPU.FSBFrequency = ((Platform->CPU.TSCFrequency * Platform->CPU.CurrDiv) / bus_ratio_current); // ?
169 }
170 else
171 {
172 Platform->CPU.FSBFrequency = (Platform->CPU.TSCFrequency / bus_ratio_current);
173 }
174 //fsbFrequency = (tscFrequency / bus_ratio_max); // ?
175 }
176 }
177 else if(Platform->CPU.ExtFamily >= 0x01 /* K10+ */)
178 {
179
180 msr = rdmsr64(AMD_10H_11H_CONFIG);
181 bus_ratio_current = ((msr) & 0x3F);
182Platform->CPU.CurrDiv = (2 << ((msr >> 6) & 0x07)) / 2;
183 Platform->CPU.FSBFrequency = (Platform->CPU.CPUFrequency / bus_ratio_current);
184
185
186 }
187
188if (!Platform->CPU.FSBFrequency)
189{
190Platform->CPU.FSBFrequency = (DEFAULT_FSB * 1000);
191verbose("0 ! using the default value for FSB !\n");
192}
193Platform->CPU.CurrCoef = bus_ratio_current / 10;
194Platform->CPU.CPUFrequency = Platform->CPU.TSCFrequency;
195
196verbose("CPU (AMD): FSBFreq: %dMHz\n", Platform->CPU.FSBFrequency / 1000000);
197verbose("CPU (AMD): CPUFreq: %dMHz\n", Platform->CPU.CPUFrequency / 1000000);
198verbose("CPU (AMD): CurrCoef: 0x%x\n", Platform->CPU.CurrCoef);
199verbose("CPU (AMD): CurrDiv: 0x%x\n", Platform->CPU.CurrDiv);
200 }
201
202}
203
204void CPUfreq_start()
205{
206bool enable = true;
207getBoolForKey(kEnableCPUfreq, &enable, &bootInfo->bootConfig) ;
208
209if (enable) {
210if (Platform->CPU.Features & CPUID_FEATURE_MSR) {
211register_hook_callback("PreBoot", &CPUfreq_hook);
212} else {
213verbose ("Unsupported CPU: CPUfreq disabled !!!\n");
214}
215}
216}
217

Archive Download this file

Revision: 1119