Chameleon

Chameleon Svn Source Tree

Root/trunk/i386/libsaio/state_generator.c

1/*
2 * Copyright 2008 mackerintel
3 *
4 * state_generator.h
5 * Chameleon
6 *
7 * Created by Mozodojo on 20/07/10.
8 * Copyright 2010 mozodojo. All rights reserved.
9 *
10 */
11
12#include "libsaio.h"
13#include "boot.h"
14#include "bootstruct.h"
15#include "acpi.h"
16#include "efi_tables.h"
17#include "fake_efi.h"
18#include "acpi_patcher.h"
19#include "platform.h"
20#include "cpu.h"
21#include "aml_generator.h"
22#include "state_generator.h"
23
24#ifndef DEBUG_STATE
25#define DEBUG_STATE 0
26#endif
27
28#if DEBUG_STATE==2
29#define DBG(x...) {printf(x); sleep(1);}
30#elif DEBUG_STATE==1
31#define DBG(x...) printf(x)
32#else
33#define DBG(x...) msglog(x)
34#endif
35
36uint8_t acpi_cpu_count= 0;
37uint32_t acpi_cpu_p_blk= 0;
38char *acpi_cpu_name[32];
39
40void get_acpi_cpu_names(unsigned char *dsdt, uint32_t length)
41{
42uint32_t i;
43
44DBG("\tACPI patcher: start finding cpu names. Length %d\n", length);
45
46for (i=0; i<length-7; i++)
47{
48if (dsdt[i] == 0x5B && dsdt[i+1] == 0x83) // ProcessorOP
49{
50DBG("\tACPIpatcher: DSDT[%X%X]\n", dsdt[i], dsdt[i+1]);
51
52uint32_t offset = i + 3 + (dsdt[i+2] >> 6);
53
54bool add_name = true;
55
56uint8_t j;
57
58for (j=0; j<4; j++)
59{
60char c = dsdt[offset+j];
61
62if (!aml_isvalidchar(c))
63{
64add_name = false;
65DBG("\tACPI patcher: invalid character found in ProcessorOP '0x%X'!\n", c);
66break;
67}
68}
69
70if (add_name)
71{
72acpi_cpu_name[acpi_cpu_count] = malloc(4);
73memcpy(acpi_cpu_name[acpi_cpu_count], dsdt+offset, 4);
74i = offset + 5;
75
76if (acpi_cpu_count == 0)
77{
78acpi_cpu_p_blk = dsdt[i] | (dsdt[i+1] << 8);
79}
80
81DBG("\tACPI patcher: found ACPI CPU [%c%c%c%c]\n", acpi_cpu_name[acpi_cpu_count][0], acpi_cpu_name[acpi_cpu_count][1], acpi_cpu_name[acpi_cpu_count][2], acpi_cpu_name[acpi_cpu_count][3]);
82
83if (++acpi_cpu_count == 32)
84{
85return;
86}
87}
88}
89}
90
91DBG("\tACPIpatcher: finished finding cpu names. Found: %d.\n", acpi_cpu_count);
92}
93
94static char const pss_ssdt_header[] =
95{
960x53, 0x53, 0x44, 0x54, 0x7E, 0x00, 0x00, 0x00, /* SSDT.... */
970x01, 0x6A, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x00, /* ..PmRef. */
980x43, 0x70, 0x75, 0x50, 0x6D, 0x00, 0x00, 0x00, /* CpuPm... */
990x00, 0x30, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* .0..INTL */
1000x31, 0x03, 0x10, 0x20,/* 1.._*/
101};
102
103static char const cst_ssdt_header[] =
104{
1050x53, 0x53, 0x44, 0x54, 0xE7, 0x00, 0x00, 0x00, /* SSDT.... */
1060x01, 0x17, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x41, /* ..PmRefA */
1070x43, 0x70, 0x75, 0x43, 0x73, 0x74, 0x00, 0x00, /* CpuCst.. */
1080x00, 0x10, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* ....INTL */
1090x31, 0x03, 0x10, 0x20/* 1.._*/
110};
111
112char resource_template_register_fixedhw[] =
113{
1140x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F,
1150x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1160x00, 0x00, 0x01, 0x79, 0x00
117};
118
119char resource_template_register_systemio[] =
120{
1210x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x01,
1220x08, 0x00, 0x00, 0x15, 0x04, 0x00, 0x00, 0x00,
1230x00, 0x00, 0x00, 0x79, 0x00,
124};
125
126struct acpi_2_ssdt *generate_pss_ssdt(struct acpi_2_dsdt *dsdt)
127{
128verbose("[ GENERATE P-STATES ]\n");
129
130if (Platform.CPU.Vendor != CPUID_VENDOR_INTEL) // 0x756E6547
131{
132DBG("\tNot an Intel platform: P-States will not be generated !!!\n");
133return NULL;
134}
135
136if (!(Platform.CPU.Features & CPU_FEATURE_MSR))
137{
138DBG("\tUnsupported CPU: P-States will not be generated !!! No MSR support\n");
139return NULL;
140}
141
142if (acpi_cpu_count == 0)
143{
144get_acpi_cpu_names((void*)dsdt, dsdt->Length);
145}
146
147if (acpi_cpu_count > 0)
148{
149struct p_state initial, maximum, minimum, p_states[32];
150uint8_t p_states_count = 0;
151
152// Retrieving P-States, ported from code by superhai (c)
153switch (Platform.CPU.Family)
154{
155case 0x06:
156{
157switch (Platform.CPU.Model)
158{
159case CPUID_MODEL_DOTHAN:// Intel Pentium M
160case CPUID_MODEL_YONAH:// Intel Mobile Core Solo, Duo
161case CPUID_MODEL_MEROM:// Intel Mobile Core 2 Solo, Duo, Xeon 30xx, Xeon 51xx, Xeon X53xx, Xeon E53xx, Xeon X32xx
162case CPUID_MODEL_PENRYN:// Intel Core 2 Solo, Duo, Quad, Extreme, Xeon X54xx, Xeon X33xx
163case CPUID_MODEL_ATOM:// Intel Atom (45nm)
164{
165bool cpu_dynamic_fsb = false;
166
167if (rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 27))
168{
169wrmsr64(MSR_IA32_EXT_CONFIG, (rdmsr64(MSR_IA32_EXT_CONFIG) | (1 << 28)));
170delay(1);
171cpu_dynamic_fsb = rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 28);
172}
173
174bool cpu_noninteger_bus_ratio = (rdmsr64(MSR_IA32_PERF_STATUS) & (1ULL << 46));
175
176initial.Control = rdmsr64(MSR_IA32_PERF_STATUS);
177
178maximum.Control = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 32) & 0x1F3F) | (0x4000 * cpu_noninteger_bus_ratio);
179maximum.CID = ((maximum.FID & 0x1F) << 1) | cpu_noninteger_bus_ratio;
180
181minimum.FID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 24) & 0x1F) | (0x80 * cpu_dynamic_fsb);
182minimum.VID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 48) & 0x3F);
183
184if (minimum.FID == 0)
185{
186uint64_t msr;
187uint8_t i;
188// Probe for lowest fid
189for (i = maximum.FID; i >= 0x6; i--)
190{
191msr = rdmsr64(MSR_IA32_PERF_CONTROL);
192wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (i << 8) | minimum.VID);
193intel_waitforsts();
194minimum.FID = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0x1F;
195delay(1);
196}
197
198msr = rdmsr64(MSR_IA32_PERF_CONTROL);
199wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);
200intel_waitforsts();
201}
202
203if (minimum.VID == maximum.VID)
204{
205uint64_t msr;
206uint8_t i;
207// Probe for lowest vid
208for (i = maximum.VID; i > 0xA; i--)
209{
210msr = rdmsr64(MSR_IA32_PERF_CONTROL);
211wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (minimum.FID << 8) | i);
212intel_waitforsts();
213minimum.VID = rdmsr64(MSR_IA32_PERF_STATUS) & 0x3F;
214delay(1);
215}
216
217msr = rdmsr64(MSR_IA32_PERF_CONTROL);
218wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);
219intel_waitforsts();
220}
221
222minimum.CID = ((minimum.FID & 0x1F) << 1) >> cpu_dynamic_fsb;
223
224// Sanity check
225if (maximum.CID < minimum.CID)
226{
227DBG("\tP-States: Insane FID values!");
228p_states_count = 0;
229}
230else
231{
232uint8_t vidstep;
233uint8_t u, invalid = 0;
234// Finalize P-States
235// Find how many P-States machine supports
236p_states_count = (uint8_t)(maximum.CID - minimum.CID + 1);
237
238if (p_states_count > 32)
239{
240p_states_count = 32;
241}
242DBG("\tPStates count=%d\n", p_states_count);
243
244vidstep = ((maximum.VID << 2) - (minimum.VID << 2)) / (p_states_count - 1);
245
246for (u = 0; u < p_states_count; u++)
247{
248uint8_t i = u - invalid;
249
250p_states[i].CID = maximum.CID - u;
251p_states[i].FID = (uint8_t)(p_states[i].CID >> 1);
252
253if (p_states[i].FID < 0x6)
254{
255if (cpu_dynamic_fsb)
256{
257p_states[i].FID = (p_states[i].FID << 1) | 0x80;
258}
259}
260else if (cpu_noninteger_bus_ratio)
261{
262p_states[i].FID = p_states[i].FID | (0x40 * (p_states[i].CID & 0x1));
263}
264
265if (i && p_states[i].FID == p_states[i-1].FID)
266{
267invalid++;
268}
269p_states[i].VID = ((maximum.VID << 2) - (vidstep * u)) >> 2;
270uint32_t multiplier = p_states[i].FID & 0x1f;// = 0x08
271bool half = p_states[i].FID & 0x40;// = 0x01
272bool dfsb = p_states[i].FID & 0x80;// = 0x00
273uint32_t fsb = (uint32_t)(Platform.CPU.FSBFrequency / 1000000); // = 400
274uint32_t halffsb = (fsb + 1) >> 1;// = 200
275uint32_t frequency = (multiplier * fsb);// = 3200
276
277p_states[i].Frequency = (uint32_t)(frequency + (half * halffsb)) >> dfsb;// = 3200 + 200 = 3400
278}
279
280p_states_count -= invalid;
281}
282
283break;
284}
285case CPUID_MODEL_FIELDS:// Intel Core i5, i7, Xeon X34xx LGA1156 (45nm)
286case CPUID_MODEL_CLARKDALE://
287case CPUID_MODEL_DALES:// Intel Core i3, i5 LGA1156 (32nm)
288case CPUID_MODEL_NEHALEM:// Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm)
289case CPUID_MODEL_NEHALEM_EX:// Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65xx
290case CPUID_MODEL_WESTMERE:// Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core
291case CPUID_MODEL_WESTMERE_EX:// Intel Xeon E7
292case CPUID_MODEL_SANDYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (32nm)
293case CPUID_MODEL_JAKETOWN:// Intel Core i7, Xeon E5 LGA2011 (32nm)
294case CPUID_MODEL_IVYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (22nm)
295case CPUID_MODEL_HASWELL://
296case CPUID_MODEL_IVYBRIDGE_XEON://
297//case CPUID_MODEL_HASWELL_H://
298case CPUID_MODEL_HASWELL_SVR://
299case CPUID_MODEL_HASWELL_ULT://
300case CPUID_MODEL_HASWELL_ULX://
301case CPUID_MODEL_ATOM_3700:
302
303{
304if ( (Platform.CPU.Model == CPUID_MODEL_SANDYBRIDGE) ||
305(Platform.CPU.Model == CPUID_MODEL_JAKETOWN) ||
306(Platform.CPU.Model == CPUID_MODEL_IVYBRIDGE) ||
307(Platform.CPU.Model == CPUID_MODEL_HASWELL) ||
308(Platform.CPU.Model == CPUID_MODEL_IVYBRIDGE_XEON) ||
309(Platform.CPU.Model == CPUID_MODEL_HASWELL_SVR) ||
310(Platform.CPU.Model == CPUID_MODEL_HASWELL_ULT) ||
311(Platform.CPU.Model == CPUID_MODEL_HASWELL_ULX) ||
312(Platform.CPU.Model == CPUID_MODEL_ATOM_3700) )
313{
314maximum.Control = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0xff;
315}
316else
317{
318maximum.Control = rdmsr64(MSR_IA32_PERF_STATUS) & 0xff;
319}
320
321minimum.Control = (rdmsr64(MSR_PLATFORM_INFO) >> 40) & 0xff;
322
323DBG("\tP-States: min 0x%x, max 0x%x\n", minimum.Control, maximum.Control);
324
325// Sanity check
326if (maximum.Control < minimum.Control)
327{
328DBG("\tInsane control values!");
329p_states_count = 0;
330}
331else
332{
333uint8_t i;
334p_states_count = 0;
335
336for (i = maximum.Control; i >= minimum.Control; i--)
337{
338p_states[p_states_count].Control = i;
339p_states[p_states_count].CID = p_states[p_states_count].Control << 1;
340p_states[p_states_count].Frequency = (Platform.CPU.FSBFrequency / 1000000) * i;
341p_states_count++;
342}
343}
344
345break;
346}
347default:
348DBG("\tUnsupported CPU (0x%X): P-States not generated !!!\n", Platform.CPU.Family);
349break;
350}
351}
352}
353
354// Generating SSDT
355if (p_states_count > 0)
356{
357
358int i;
359
360AML_CHUNK *root = aml_create_node(NULL);
361aml_add_buffer(root, pss_ssdt_header, sizeof(pss_ssdt_header)); // SSDT header
362
363AML_CHUNK *scop = aml_add_scope(root, "\\_PR_");
364AML_CHUNK *name = aml_add_name(scop, "PSS_");
365AML_CHUNK *pack = aml_add_package(name);
366
367for (i = 0; i < p_states_count; i++)
368{
369AML_CHUNK *pstt = aml_add_package(pack);
370
371aml_add_dword(pstt, p_states[i].Frequency);
372aml_add_dword(pstt, 0x00000000); // Power
373aml_add_dword(pstt, 0x0000000A); // Latency
374aml_add_dword(pstt, 0x0000000A); // Latency
375aml_add_dword(pstt, p_states[i].Control);
376aml_add_dword(pstt, i+1); // Status
377}
378
379// Add aliaces CPUs
380for (i = 0; i < acpi_cpu_count; i++)
381{
382char name[9];
383sprintf(name, "_PR_%c%c%c%c", acpi_cpu_name[i][0], acpi_cpu_name[i][1], acpi_cpu_name[i][2], acpi_cpu_name[i][3]);
384
385scop = aml_add_scope(root, name);
386aml_add_alias(scop, "PSS_", "_PSS");
387}
388
389aml_calculate_size(root);
390
391struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);
392
393aml_write_node(root, (void*)ssdt, 0);
394
395ssdt->Length = root->Size;
396ssdt->Checksum = 0;
397ssdt->Checksum = (uint8_t)(256 - checksum8(ssdt, ssdt->Length));
398
399aml_destroy_node(root);
400
401//dumpPhysAddr("P-States SSDT content: ", ssdt, ssdt->Length);
402
403DBG("\tSSDT with CPU P-States generated successfully\n");
404
405return ssdt;
406}
407}
408else
409{
410DBG("\tACPI CPUs not found: P-States not generated !!!\n");
411}
412
413verbose("\n");
414
415return NULL;
416}
417
418struct acpi_2_ssdt *generate_cst_ssdt(struct acpi_2_fadt *fadt)
419{
420verbose("[ GENERATE C-STATES ]\n");
421
422if (Platform.CPU.Vendor != CPUID_VENDOR_INTEL) // 0x756E6547
423{
424DBG("\tNot an Intel platform: C-States will not be generated !!!\n");
425return NULL;
426}
427
428if (fadt == NULL)
429{
430DBG("\tFACP not exists: C-States will not be generated !!!\n");
431return NULL;
432}
433
434struct acpi_2_dsdt *dsdt = (void *)fadt->DSDT;
435
436if (dsdt == NULL)
437{
438DBG("\tDSDT not found: C-States will not be generated !!!\n");
439return NULL;
440}
441
442if (acpi_cpu_count == 0)
443get_acpi_cpu_names((void*)dsdt, dsdt->Length);
444
445if (acpi_cpu_count > 0)
446{
447bool c2_enabled = false;
448bool c3_enabled = false;
449bool c4_enabled = false;
450bool c6_enabled = false;
451bool c7_enabled = false;
452bool cst_using_systemio = false;
453
454getBoolForKey(kEnableC2State, &c2_enabled, &bootInfo->chameleonConfig);
455getBoolForKey(kEnableC3State, &c3_enabled, &bootInfo->chameleonConfig);
456getBoolForKey(kEnableC4State, &c4_enabled, &bootInfo->chameleonConfig);
457getBoolForKey(kEnableC6State, &c6_enabled, &bootInfo->chameleonConfig);
458getBoolForKey(kEnableC7State, &c7_enabled, &bootInfo->chameleonConfig);
459getBoolForKey(kCSTUsingSystemIO, &cst_using_systemio, &bootInfo->chameleonConfig);
460
461c2_enabled = c2_enabled | (fadt->C2_Latency < 100);
462c3_enabled = c3_enabled | (fadt->C3_Latency < 1000);
463
464unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + ((c3_enabled || c4_enabled)? 1 : 0) + (c6_enabled ? 1 : 0) + (c7_enabled ? 1 : 0);
465
466AML_CHUNK* root = aml_create_node(NULL);
467aml_add_buffer(root, cst_ssdt_header, sizeof(cst_ssdt_header)); // SSDT header
468AML_CHUNK* scop = aml_add_scope(root, "\\_PR_");
469AML_CHUNK* name = aml_add_name(scop, "CST_");
470AML_CHUNK* pack = aml_add_package(name);
471aml_add_byte(pack, cstates_count);
472
473AML_CHUNK* tmpl = aml_add_package(pack);
474if (cst_using_systemio)
475{
476// C1
477resource_template_register_fixedhw[8] = 0x00;
478resource_template_register_fixedhw[9] = 0x00;
479resource_template_register_fixedhw[18] = 0x00;
480aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
481aml_add_byte(tmpl, 0x01);// C1
482aml_add_word(tmpl, 0x0001);// Latency
483aml_add_dword(tmpl, 0x000003e8);// Power
484
485uint8_t p_blk_lo, p_blk_hi;
486
487if (c2_enabled) // C2
488{
489p_blk_lo = acpi_cpu_p_blk + 4;
490p_blk_hi = (acpi_cpu_p_blk + 4) >> 8;
491
492tmpl = aml_add_package(pack);
493resource_template_register_systemio[11] = p_blk_lo; // C2
494resource_template_register_systemio[12] = p_blk_hi; // C2
495aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
496aml_add_byte(tmpl, 0x02);// C2
497aml_add_word(tmpl, 0x0040);// Latency
498aml_add_dword(tmpl, 0x000001f4);// Power
499}
500
501if (c4_enabled) // C4
502{
503p_blk_lo = acpi_cpu_p_blk + 5;
504p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;
505
506tmpl = aml_add_package(pack);
507resource_template_register_systemio[11] = p_blk_lo; // C4
508resource_template_register_systemio[12] = p_blk_hi; // C4
509aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
510aml_add_byte(tmpl, 0x04);// C4
511aml_add_word(tmpl, 0x0080);// Latency
512aml_add_dword(tmpl, 0x000000C8);// Power
513}
514else if (c3_enabled) // C3
515{
516p_blk_lo = acpi_cpu_p_blk + 5;
517p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;
518
519tmpl = aml_add_package(pack);
520resource_template_register_systemio[11] = p_blk_lo; // C3
521resource_template_register_systemio[12] = p_blk_hi; // C3
522aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
523aml_add_byte(tmpl, 0x03);// C3
524aml_add_word(tmpl, 0x0043);// Latency
525aml_add_dword(tmpl, 0x000001F4);// Power
526}
527if (c6_enabled) // C6
528{
529p_blk_lo = acpi_cpu_p_blk + 5;
530p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;
531
532tmpl = aml_add_package(pack);
533resource_template_register_systemio[11] = p_blk_lo; // C6
534resource_template_register_systemio[12] = p_blk_hi; // C6
535aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
536aml_add_byte(tmpl, 0x06);// C6
537aml_add_word(tmpl, 0x0046);// Latency
538aml_add_dword(tmpl, 0x0000015E);// Power
539}
540if (c7_enabled) //C7
541{
542p_blk_lo = (acpi_cpu_p_blk + 6) & 0xff;
543p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;
544
545tmpl = aml_add_package(pack);
546resource_template_register_systemio[11] = p_blk_lo; // C4 or C7
547resource_template_register_systemio[12] = p_blk_hi;
548aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
549aml_add_byte(tmpl, 0x07);// C7
550aml_add_word(tmpl, 0xF5);// Latency as in iMac14,1
551aml_add_dword(tmpl, 0xC8);// Power
552}
553}
554else
555{
556// C1
557resource_template_register_fixedhw[8] = 0x01;
558resource_template_register_fixedhw[9] = 0x02;
559resource_template_register_fixedhw[18] = 0x01;
560
561resource_template_register_fixedhw[11] = 0x00; // C1
562aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
563aml_add_byte(tmpl, 0x01);// C1
564aml_add_word(tmpl, 0x0001);// Latency
565aml_add_dword(tmpl, 0x000003e8);// Power
566
567resource_template_register_fixedhw[18] = 0x03;
568
569if (c2_enabled) // C2
570{
571tmpl = aml_add_package(pack);
572resource_template_register_fixedhw[11] = 0x10; // C2
573aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
574aml_add_byte(tmpl, 0x02);// C2
575aml_add_word(tmpl, 0x0040);// Latency
576aml_add_dword(tmpl, 0x000001f4);// Power
577}
578
579if (c4_enabled) // C4
580{
581tmpl = aml_add_package(pack);
582resource_template_register_fixedhw[11] = 0x30; // C4
583aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
584aml_add_byte(tmpl, 0x04);// C4
585aml_add_word(tmpl, 0x0080);// Latency
586aml_add_dword(tmpl, 0x000000C8);// Power
587}
588else if (c3_enabled)
589{
590tmpl = aml_add_package(pack);
591resource_template_register_fixedhw[11] = 0x20; // C3
592aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
593aml_add_byte(tmpl, 0x03);// C3
594aml_add_word(tmpl, 0x0043);// Latency
595aml_add_dword(tmpl, 0x000001F4);// Power
596}
597if (c6_enabled) // C6
598{
599tmpl = aml_add_package(pack);
600resource_template_register_fixedhw[11] = 0x20; // C6
601aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
602aml_add_byte(tmpl, 0x06);// C6
603aml_add_word(tmpl, 0x0046);// Latency as in MacPro6,1
604aml_add_dword(tmpl, 0x0000015E);// Power
605}
606if (c7_enabled) // C7
607{
608tmpl = aml_add_package(pack);
609resource_template_register_fixedhw[11] = 0x30; // C4 or C7
610aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
611aml_add_byte(tmpl, 0x07);// C7
612aml_add_word(tmpl, 0xF5);// Latency as in iMac14,1
613aml_add_dword(tmpl, 0xC8);// Power
614}
615}
616
617// Aliaces
618int i;
619for (i = 0; i < acpi_cpu_count; i++)
620{
621char name[9];
622sprintf(name, "_PR_%c%c%c%c", acpi_cpu_name[i][0], acpi_cpu_name[i][1], acpi_cpu_name[i][2], acpi_cpu_name[i][3]);
623
624scop = aml_add_scope(root, name);
625aml_add_alias(scop, "CST_", "_CST");
626}
627
628aml_calculate_size(root);
629
630struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);
631
632aml_write_node(root, (void*)ssdt, 0);
633
634ssdt->Length = root->Size;
635ssdt->Checksum = 0;
636ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length);
637
638aml_destroy_node(root);
639
640// dumpPhysAddr("C-States SSDT content: ", ssdt, ssdt->Length);
641
642DBG("\tSSDT with CPU C-States generated successfully\n");
643
644return ssdt;
645}
646else
647{
648DBG("\tACPI CPUs not found: C-States not generated !!!\n");
649}
650
651verbose("\n");
652
653return NULL;
654}
655

Archive Download this file

Revision: 2687