Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 2920