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("ACPIpatcher: 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("ACPIpatcher: 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("ACPIpatcher: 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("ACPIpatcher: 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("ACPIpatcher: 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{
128
129if (Platform.CPU.Vendor != CPUID_VENDOR_INTEL) // 0x756E6547
130{
131DBG("Not an Intel platform: P-States will not be generated !!!\n");
132return NULL;
133}
134
135if (!(Platform.CPU.Features & CPU_FEATURE_MSR))
136{
137DBG("Unsupported CPU: P-States will not be generated !!! No MSR support\n");
138return NULL;
139}
140
141if (acpi_cpu_count == 0)
142{
143get_acpi_cpu_names((void*)dsdt, dsdt->Length);
144}
145
146if (acpi_cpu_count > 0)
147{
148struct p_state initial, maximum, minimum, p_states[32];
149uint8_t p_states_count = 0;
150
151// Retrieving P-States, ported from code by superhai (c)
152switch (Platform.CPU.Family)
153{
154case 0x06:
155{
156switch (Platform.CPU.Model)
157{
158case CPUID_MODEL_DOTHAN:// Intel Pentium M
159case CPUID_MODEL_YONAH:// Intel Mobile Core Solo, Duo
160case CPUID_MODEL_MEROM:// Intel Mobile Core 2 Solo, Duo, Xeon 30xx, Xeon 51xx, Xeon X53xx, Xeon E53xx, Xeon X32xx
161case CPUID_MODEL_PENRYN:// Intel Core 2 Solo, Duo, Quad, Extreme, Xeon X54xx, Xeon X33xx
162case CPUID_MODEL_ATOM:// Intel Atom (45nm)
163{
164bool cpu_dynamic_fsb = false;
165
166if (rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 27))
167{
168wrmsr64(MSR_IA32_EXT_CONFIG, (rdmsr64(MSR_IA32_EXT_CONFIG) | (1 << 28)));
169delay(1);
170cpu_dynamic_fsb = rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 28);
171}
172
173bool cpu_noninteger_bus_ratio = (rdmsr64(MSR_IA32_PERF_STATUS) & (1ULL << 46));
174
175initial.Control = rdmsr64(MSR_IA32_PERF_STATUS);
176
177maximum.Control = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 32) & 0x1F3F) | (0x4000 * cpu_noninteger_bus_ratio);
178maximum.CID = ((maximum.FID & 0x1F) << 1) | cpu_noninteger_bus_ratio;
179
180minimum.FID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 24) & 0x1F) | (0x80 * cpu_dynamic_fsb);
181minimum.VID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 48) & 0x3F);
182
183if (minimum.FID == 0)
184{
185uint64_t msr;
186uint8_t i;
187// Probe for lowest fid
188for (i = maximum.FID; i >= 0x6; i--)
189{
190msr = rdmsr64(MSR_IA32_PERF_CONTROL);
191wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (i << 8) | minimum.VID);
192intel_waitforsts();
193minimum.FID = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0x1F;
194delay(1);
195}
196
197msr = rdmsr64(MSR_IA32_PERF_CONTROL);
198wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);
199intel_waitforsts();
200}
201
202if (minimum.VID == maximum.VID)
203{
204uint64_t msr;
205uint8_t i;
206// Probe for lowest vid
207for (i = maximum.VID; i > 0xA; i--)
208{
209msr = rdmsr64(MSR_IA32_PERF_CONTROL);
210wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (minimum.FID << 8) | i);
211intel_waitforsts();
212minimum.VID = rdmsr64(MSR_IA32_PERF_STATUS) & 0x3F;
213delay(1);
214}
215
216msr = rdmsr64(MSR_IA32_PERF_CONTROL);
217wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);
218intel_waitforsts();
219}
220
221minimum.CID = ((minimum.FID & 0x1F) << 1) >> cpu_dynamic_fsb;
222
223// Sanity check
224if (maximum.CID < minimum.CID)
225{
226DBG("P-States: Insane FID values!");
227p_states_count = 0;
228}
229else
230{
231uint8_t vidstep;
232uint8_t u, invalid = 0;
233// Finalize P-States
234// Find how many P-States machine supports
235p_states_count = (uint8_t)(maximum.CID - minimum.CID + 1);
236
237if (p_states_count > 32)
238{
239p_states_count = 32;
240}
241
242vidstep = ((maximum.VID << 2) - (minimum.VID << 2)) / (p_states_count - 1);
243
244for (u = 0; u < p_states_count; u++)
245{
246uint8_t i = u - invalid;
247
248p_states[i].CID = maximum.CID - u;
249p_states[i].FID = (uint8_t)(p_states[i].CID >> 1);
250
251if (p_states[i].FID < 0x6)
252{
253if (cpu_dynamic_fsb)
254{
255p_states[i].FID = (p_states[i].FID << 1) | 0x80;
256}
257}
258else if (cpu_noninteger_bus_ratio)
259{
260p_states[i].FID = p_states[i].FID | (0x40 * (p_states[i].CID & 0x1));
261}
262
263if (i && p_states[i].FID == p_states[i-1].FID)
264{
265invalid++;
266}
267p_states[i].VID = ((maximum.VID << 2) - (vidstep * u)) >> 2;
268uint32_t multiplier = p_states[i].FID & 0x1f;// = 0x08
269bool half = p_states[i].FID & 0x40;// = 0x01
270bool dfsb = p_states[i].FID & 0x80;// = 0x00
271uint32_t fsb = (uint32_t)(Platform.CPU.FSBFrequency / 1000000); // = 400
272uint32_t halffsb = (fsb + 1) >> 1;// = 200
273uint32_t frequency = (multiplier * fsb);// = 3200
274
275p_states[i].Frequency = (uint32_t)(frequency + (half * halffsb)) >> dfsb;// = 3200 + 200 = 3400
276}
277
278p_states_count -= invalid;
279}
280
281break;
282}
283case CPUID_MODEL_FIELDS:// Intel Core i5, i7, Xeon X34xx LGA1156 (45nm)
284case CPUID_MODEL_DALES://
285case CPUID_MODEL_DALES_32NM:// Intel Core i3, i5 LGA1156 (32nm)
286case CPUID_MODEL_NEHALEM:// Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm)
287case CPUID_MODEL_NEHALEM_EX:// Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65xx
288case CPUID_MODEL_WESTMERE:// Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core
289case CPUID_MODEL_WESTMERE_EX:// Intel Xeon E7
290case CPUID_MODEL_SANDYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (32nm)
291case CPUID_MODEL_JAKETOWN:// Intel Core i7, Xeon E5 LGA2011 (32nm)
292case CPUID_MODEL_IVYBRIDGE:// Intel Core i3, i5, i7 LGA1155 (22nm)
293case CPUID_MODEL_HASWELL://
294case CPUID_MODEL_IVYBRIDGE_XEON://
295//case CPUID_MODEL_HASWELL_H://
296case CPUID_MODEL_HASWELL_SVR://
297case CPUID_MODEL_HASWELL_ULT://
298case CPUID_MODEL_CRYSTALWELL://
299
300{
301if ( (Platform.CPU.Model == CPUID_MODEL_SANDYBRIDGE) ||
302(Platform.CPU.Model == CPUID_MODEL_JAKETOWN) ||
303(Platform.CPU.Model == CPUID_MODEL_IVYBRIDGE) ||
304(Platform.CPU.Model == CPUID_MODEL_HASWELL) ||
305(Platform.CPU.Model == CPUID_MODEL_IVYBRIDGE_XEON) ||
306(Platform.CPU.Model == CPUID_MODEL_HASWELL_SVR) ||
307(Platform.CPU.Model == CPUID_MODEL_HASWELL_ULT) ||
308(Platform.CPU.Model == CPUID_MODEL_CRYSTALWELL) )
309{
310maximum.Control = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0xff;
311}
312else
313{
314maximum.Control = rdmsr64(MSR_IA32_PERF_STATUS) & 0xff;
315}
316
317minimum.Control = (rdmsr64(MSR_PLATFORM_INFO) >> 40) & 0xff;
318
319DBG("P-States: min 0x%x, max 0x%x\n", minimum.Control, maximum.Control);
320
321// Sanity check
322if (maximum.Control < minimum.Control)
323{
324DBG("Insane control values!");
325p_states_count = 0;
326}
327else
328{
329uint8_t i;
330p_states_count = 0;
331
332for (i = maximum.Control; i >= minimum.Control; i--)
333{
334p_states[p_states_count].Control = i;
335p_states[p_states_count].CID = p_states[p_states_count].Control << 1;
336p_states[p_states_count].Frequency = (Platform.CPU.FSBFrequency / 1000000) * i;
337p_states_count++;
338}
339}
340
341break;
342}
343default:
344DBG("Unsupported CPU (0x%X): P-States not generated !!!\n", Platform.CPU.Family);
345break;
346}
347}
348}
349
350// Generating SSDT
351if (p_states_count > 0)
352{
353
354int i;
355
356AML_CHUNK* root = aml_create_node(NULL);
357aml_add_buffer(root, pss_ssdt_header, sizeof(pss_ssdt_header)); // SSDT header
358
359AML_CHUNK* scop = aml_add_scope(root, "\\_PR_");
360AML_CHUNK* name = aml_add_name(scop, "PSS_");
361AML_CHUNK* pack = aml_add_package(name);
362
363for (i = 0; i < p_states_count; i++)
364{
365AML_CHUNK* pstt = aml_add_package(pack);
366
367aml_add_dword(pstt, p_states[i].Frequency);
368aml_add_dword(pstt, 0x00000000); // Power
369aml_add_dword(pstt, 0x0000000A); // Latency
370aml_add_dword(pstt, 0x0000000A); // Latency
371aml_add_dword(pstt, p_states[i].Control);
372aml_add_dword(pstt, i+1); // Status
373}
374
375// Add aliaces
376for (i = 0; i < acpi_cpu_count; i++)
377{
378char name[9];
379sprintf(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]);
380
381scop = aml_add_scope(root, name);
382aml_add_alias(scop, "PSS_", "_PSS");
383}
384
385aml_calculate_size(root);
386
387struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);
388
389aml_write_node(root, (void*)ssdt, 0);
390
391ssdt->Length = root->Size;
392ssdt->Checksum = 0;
393ssdt->Checksum = (uint8_t)(256 - checksum8(ssdt, ssdt->Length));
394
395aml_destroy_node(root);
396
397//dumpPhysAddr("P-States SSDT content: ", ssdt, ssdt->Length);
398
399DBG("SSDT with CPU P-States generated successfully\n");
400
401return ssdt;
402}
403}
404else
405{
406DBG("ACPI CPUs not found: P-States not generated !!!\n");
407}
408
409return NULL;
410}
411
412struct acpi_2_ssdt *generate_cst_ssdt(struct acpi_2_fadt *fadt)
413{
414
415if (Platform.CPU.Vendor != CPUID_VENDOR_INTEL) // 0x756E6547
416{
417DBG("Not an Intel platform: C-States will not be generated !!!\n");
418return NULL;
419}
420
421if (fadt == NULL)
422{
423DBG("FACP not exists: C-States will not be generated !!!\n");
424return NULL;
425}
426
427struct acpi_2_dsdt *dsdt = (void *)fadt->DSDT;
428
429if (dsdt == NULL)
430{
431DBG("DSDT not found: C-States will not be generated !!!\n");
432return NULL;
433}
434
435if (acpi_cpu_count == 0)
436get_acpi_cpu_names((void*)dsdt, dsdt->Length);
437
438if (acpi_cpu_count > 0)
439{
440bool c2_enabled = false;
441bool c3_enabled = false;
442bool c4_enabled = false;
443bool c6_enabled = false;
444bool c7_enabled = false;
445bool cst_using_systemio = false;
446
447getBoolForKey(kEnableC2State, &c2_enabled, &bootInfo->chameleonConfig);
448getBoolForKey(kEnableC3State, &c3_enabled, &bootInfo->chameleonConfig);
449getBoolForKey(kEnableC4State, &c4_enabled, &bootInfo->chameleonConfig);
450getBoolForKey(kEnableC6State, &c6_enabled, &bootInfo->chameleonConfig);
451getBoolForKey(kEnableC7State, &c7_enabled, &bootInfo->chameleonConfig);
452getBoolForKey(kCSTUsingSystemIO, &cst_using_systemio, &bootInfo->chameleonConfig);
453
454c2_enabled = c2_enabled | (fadt->C2_Latency < 100);
455c3_enabled = c3_enabled | (fadt->C3_Latency < 1000);
456
457unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + ((c3_enabled || c4_enabled)? 1 : 0) + (c6_enabled ? 1 : 0) + (c7_enabled ? 1 : 0);
458
459AML_CHUNK* root = aml_create_node(NULL);
460aml_add_buffer(root, cst_ssdt_header, sizeof(cst_ssdt_header)); // SSDT header
461AML_CHUNK* scop = aml_add_scope(root, "\\_PR_");
462AML_CHUNK* name = aml_add_name(scop, "CST_");
463AML_CHUNK* pack = aml_add_package(name);
464aml_add_byte(pack, cstates_count);
465
466AML_CHUNK* tmpl = aml_add_package(pack);
467if (cst_using_systemio)
468{
469// C1
470resource_template_register_fixedhw[8] = 0x00;
471resource_template_register_fixedhw[9] = 0x00;
472resource_template_register_fixedhw[18] = 0x00;
473aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
474aml_add_byte(tmpl, 0x01);// C1
475aml_add_word(tmpl, 0x0001);// Latency
476aml_add_dword(tmpl, 0x000003e8);// Power
477
478uint8_t p_blk_lo, p_blk_hi;
479
480if (c2_enabled) // C2
481{
482p_blk_lo = acpi_cpu_p_blk + 4;
483p_blk_hi = (acpi_cpu_p_blk + 4) >> 8;
484
485tmpl = aml_add_package(pack);
486resource_template_register_systemio[11] = p_blk_lo; // C2
487resource_template_register_systemio[12] = p_blk_hi; // C2
488aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
489aml_add_byte(tmpl, 0x02);// C2
490aml_add_word(tmpl, 0x0040);// Latency
491aml_add_dword(tmpl, 0x000001f4);// Power
492}
493
494if (c4_enabled) // C4
495{
496p_blk_lo = acpi_cpu_p_blk + 5;
497p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;
498
499tmpl = aml_add_package(pack);
500resource_template_register_systemio[11] = p_blk_lo; // C4
501resource_template_register_systemio[12] = p_blk_hi; // C4
502aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
503aml_add_byte(tmpl, 0x04);// C4
504aml_add_word(tmpl, 0x0080);// Latency
505aml_add_dword(tmpl, 0x000000C8);// Power
506}
507else if (c3_enabled) // C3
508{
509p_blk_lo = acpi_cpu_p_blk + 5;
510p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;
511
512tmpl = aml_add_package(pack);
513resource_template_register_systemio[11] = p_blk_lo; // C3
514resource_template_register_systemio[12] = p_blk_hi; // C3
515aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
516aml_add_byte(tmpl, 0x03);// C3
517aml_add_word(tmpl, 0x0043);// Latency
518aml_add_dword(tmpl, 0x000001F4);// Power
519}
520if (c6_enabled) // C6
521{
522p_blk_lo = acpi_cpu_p_blk + 5;
523p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;
524
525tmpl = aml_add_package(pack);
526resource_template_register_systemio[11] = p_blk_lo; // C6
527resource_template_register_systemio[12] = p_blk_hi; // C6
528aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
529aml_add_byte(tmpl, 0x06);// C6
530aml_add_word(tmpl, 0x0046);// Latency
531aml_add_dword(tmpl, 0x0000015E);// Power
532}
533if (c7_enabled) //C7
534{
535p_blk_lo = (acpi_cpu_p_blk + 6) & 0xff;
536p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;
537
538tmpl = aml_add_package(pack);
539resource_template_register_systemio[11] = p_blk_lo; // C4 or C7
540resource_template_register_systemio[12] = p_blk_hi;
541aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
542aml_add_byte(tmpl, 0x07);// C7
543aml_add_word(tmpl, 0xF5);// Latency as in iMac14,1
544aml_add_dword(tmpl, 0xC8);// Power
545}
546}
547else
548{
549// C1
550resource_template_register_fixedhw[8] = 0x01;
551resource_template_register_fixedhw[9] = 0x02;
552resource_template_register_fixedhw[18] = 0x01;
553
554resource_template_register_fixedhw[11] = 0x00; // C1
555aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
556aml_add_byte(tmpl, 0x01);// C1
557aml_add_word(tmpl, 0x0001);// Latency
558aml_add_dword(tmpl, 0x000003e8);// Power
559
560resource_template_register_fixedhw[18] = 0x03;
561
562if (c2_enabled) // C2
563{
564tmpl = aml_add_package(pack);
565resource_template_register_fixedhw[11] = 0x10; // C2
566aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
567aml_add_byte(tmpl, 0x02);// C2
568aml_add_word(tmpl, 0x0040);// Latency
569aml_add_dword(tmpl, 0x000001f4);// Power
570}
571
572if (c4_enabled) // C4
573{
574tmpl = aml_add_package(pack);
575resource_template_register_fixedhw[11] = 0x30; // C4
576aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
577aml_add_byte(tmpl, 0x04);// C4
578aml_add_word(tmpl, 0x0080);// Latency
579aml_add_dword(tmpl, 0x000000C8);// Power
580}
581else if (c3_enabled)
582{
583tmpl = aml_add_package(pack);
584resource_template_register_fixedhw[11] = 0x20; // C3
585aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
586aml_add_byte(tmpl, 0x03);// C3
587aml_add_word(tmpl, 0x0043);// Latency
588aml_add_dword(tmpl, 0x000001F4);// Power
589}
590if (c6_enabled) // C6
591{
592tmpl = aml_add_package(pack);
593resource_template_register_fixedhw[11] = 0x20; // C6
594aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
595aml_add_byte(tmpl, 0x06);// C6
596aml_add_word(tmpl, 0x0046);// Latency as in MacPro6,1
597aml_add_dword(tmpl, 0x0000015E);// Power
598}
599if (c7_enabled) // C7
600{
601tmpl = aml_add_package(pack);
602resource_template_register_fixedhw[11] = 0x30; // C4 or C7
603aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
604aml_add_byte(tmpl, 0x07);// C7
605aml_add_word(tmpl, 0xF5);// Latency as in iMac14,1
606aml_add_dword(tmpl, 0xC8);// Power
607}
608}
609
610// Aliaces
611int i;
612for (i = 0; i < acpi_cpu_count; i++)
613{
614char name[9];
615sprintf(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]);
616
617scop = aml_add_scope(root, name);
618aml_add_alias(scop, "CST_", "_CST");
619}
620
621aml_calculate_size(root);
622
623struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);
624
625aml_write_node(root, (void*)ssdt, 0);
626
627ssdt->Length = root->Size;
628ssdt->Checksum = 0;
629ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length);
630
631aml_destroy_node(root);
632
633// dumpPhysAddr("C-States SSDT content: ", ssdt, ssdt->Length);
634
635DBG("SSDT with CPU C-States generated successfully\n");
636
637return ssdt;
638}
639else
640{
641DBG("ACPI CPUs not found: C-States not generated !!!\n");
642}
643
644return NULL;
645}
646

Archive Download this file

Revision: 2656