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

Archive Download this file

Revision: 789