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

Archive Download this file

Revision: 1468