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

Archive Download this file

Revision: 2858