Chameleon

Chameleon Svn Source Tree

Root/trunk/i386/libsaio/acpi_patcher.c

1/*
2 * Copyright 2008 mackerintel
3 * 2010 mojodojo, 2012 slice
4 */
5
6#include "libsaio.h"
7#include "boot.h"
8#include "bootstruct.h"
9#include "acpi.h"
10#include "efi_tables.h"
11#include "fake_efi.h"
12#include "acpi_patcher.h"
13#include "platform.h"
14#include "cpu.h"
15#include "aml_generator.h"
16#include "state_generator.h"
17
18#ifndef DEBUG_ACPI
19#define DEBUG_ACPI 0
20#endif
21
22#if DEBUG_ACPI==2
23#define DBG(x...) {printf(x); sleep(1);}
24#elif DEBUG_ACPI==1
25#define DBG(x...) printf(x)
26#else
27#define DBG(x...) msglog(x)
28#endif
29
30// Slice: New signature compare function
31boolean_t tableSign(char *table, const char *sgn)
32{
33int i;
34for (i = 0; i < 4; i++)
35{
36if ((table[i] & ~0x20) != (sgn[i] & ~0x20))
37{
38return false;
39}
40}
41return true;
42}
43
44/* Gets the ACPI 1.0 RSDP address */
45static struct acpi_2_rsdp *getAddressOfAcpiTable()
46{
47/* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */
48
49void *acpi_addr = (void*)ACPI_RANGE_START;
50
51for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16)
52{
53if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE)
54{
55uint8_t csum = checksum8(acpi_addr, 20);
56if (csum == 0)
57{
58// Only return the table if it is a true version 1.0 table (Revision 0)
59if(((struct acpi_2_rsdp*)acpi_addr)->Revision == 0)
60return acpi_addr;
61}
62}
63}
64return NULL;
65}
66
67/* Gets the ACPI 2.0 RSDP address */
68static struct acpi_2_rsdp *getAddressOfAcpi20Table()
69{
70/* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */
71
72void *acpi_addr = (void *)ACPI_RANGE_START;
73
74for(; acpi_addr <= (void *)ACPI_RANGE_END; acpi_addr += 16)
75{
76if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE)
77{
78uint8_t csum = checksum8(acpi_addr, 20);
79
80/* Only assume this is a 2.0 or better table if the revision is greater than 0
81 * NOTE: ACPI 3.0 spec only seems to say that 1.0 tables have revision 1
82 * and that the current revision is 2.. I am going to assume that rev > 0 is 2.0.
83 */
84
85if(csum == 0 && (((struct acpi_2_rsdp*)acpi_addr)->Revision > 0))
86{
87uint8_t csum2 = checksum8(acpi_addr, sizeof(struct acpi_2_rsdp));
88if(csum2 == 0)
89{
90return acpi_addr;
91}
92}
93}
94}
95return NULL;
96}
97
98/* The folowing ACPI Table search algo. should be reused anywhere needed:*/
99/* WARNING: outDirspec string will be overwritten by subsequent calls! */
100int search_and_get_acpi_fd(const char *filename, const char **outDirspec)
101{
102int fd = 0;
103static char dirSpec[512];
104
105// Try finding 'filename' in the usual places
106// Start searching any potential location for ACPI Table
107strncpy(dirSpec, filename, sizeof(dirSpec) );
108fd = open(dirSpec, 0);
109if (fd < 0)
110{
111snprintf(dirSpec, sizeof(dirSpec), "/Extra/%s", filename);
112fd = open(dirSpec, 0);
113if (fd < 0)
114{
115snprintf(dirSpec, sizeof(dirSpec), "bt(0,0)/Extra/%s", filename);
116fd = open(dirSpec, 0);
117if (fd < 0)
118{
119// NOT FOUND:
120DBG("\tACPI Table not found: %s\n", filename);
121*dirSpec = '\0';
122}
123}
124}
125
126if (outDirspec) *outDirspec = dirSpec;
127return fd;
128}
129
130void *loadACPITable (const char *filename)
131{
132const char *dirspec = NULL;
133
134int fd = search_and_get_acpi_fd(filename, &dirspec);
135
136if (fd >= 0)
137{
138void *tableAddr = (void *)AllocateKernelMemory(file_size(fd));
139if (tableAddr)
140{
141if (read(fd, tableAddr, file_size(fd)) != file_size(fd))
142{
143DBG("\tCouldn't read table %s\n", dirspec);
144free(tableAddr);
145close(fd);
146return NULL;
147}
148
149DBG("\tTable %s read and stored at: %x\n", dirspec, tableAddr);
150close(fd);
151return tableAddr;
152}
153close(fd);
154DBG("\tCouldn't allocate memory for table: %s.\n", dirspec);
155}
156//printf("Couldn't find table %s\n", filename);
157return NULL;
158}
159
160struct acpi_2_fadt *patch_fadt(struct acpi_2_fadt *fadt, struct acpi_2_dsdt *new_dsdt)
161{
162extern void setupSystemType();
163
164struct acpi_2_fadt *fadt_mod = NULL;
165bool fadt_rev2_needed = false;
166bool fix_restart;
167bool fix_restart_ps2;
168const char * value;
169
170// Restart Fix
171if (Platform.CPU.Vendor == 0x756E6547)
172{/* Intel */
173fix_restart = true;
174fix_restart_ps2 = false;
175if ( getBoolForKey(kPS2RestartFix, &fix_restart_ps2, &bootInfo->chameleonConfig) && fix_restart_ps2)
176{
177fix_restart = true;
178}
179else
180{
181getBoolForKey(kRestartFix, &fix_restart, &bootInfo->chameleonConfig);
182}
183}
184else
185{
186DBG("\tNot an Intel platform, FACP Restart Fix will not be applied!\n");
187fix_restart = false;
188}
189
190if (fix_restart)
191{
192fadt_rev2_needed = true;
193}
194
195// Allocate new fadt table
196if ((fadt->Length < 0x84) && fadt_rev2_needed)
197{
198fadt_mod = (struct acpi_2_fadt *)AllocateKernelMemory(0x84);
199memcpy(fadt_mod, fadt, fadt->Length);
200fadt_mod->Length = 0x84;
201fadt_mod->Revision = 0x02; // FACP rev 2 (ACPI 1.0B MS extensions)
202}
203else
204{
205fadt_mod = (struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length);
206memcpy(fadt_mod, fadt, fadt->Length);
207}
208// Determine system type / PM_Model
209if ( (value=getStringForKey(kSystemType, &bootInfo->chameleonConfig))!=NULL)
210{
211if (Platform.Type > 6)
212{
213if(fadt_mod->PM_Profile<=6)
214{
215Platform.Type = fadt_mod->PM_Profile; // get the fadt if correct
216}
217else
218{
219Platform.Type = 1;/* Set a fixed value (Desktop) */
220}
221DBG("\tError: system-type must be 0..6. Defaulting to %d !\n", Platform.Type);
222}
223else
224{
225Platform.Type = (unsigned char) strtoul(value, NULL, 10);
226}
227}
228// Set PM_Profile from System-type if only user wanted this value to be forced
229if (fadt_mod->PM_Profile != Platform.Type)
230{
231if (value)
232{
233// user has overriden the SystemType so take care of it in FACP
234DBG("\tFADT: changing PM_Profile from 0x%02x to 0x%02x\n", fadt_mod->PM_Profile, Platform.Type);
235fadt_mod->PM_Profile = Platform.Type;
236}
237else
238{
239// PM_Profile has a different value and no override has been set, so reflect the user value to ioregs
240Platform.Type = fadt_mod->PM_Profile <= 6 ? fadt_mod->PM_Profile : 1;
241}
242}
243// We now have to write the systemm-type in ioregs: we cannot do it before in setupDeviceTree()
244// because we need to take care of FACP original content, if it is correct.
245setupSystemType();
246
247// Patch FACP to fix restart
248if (fix_restart)
249{
250if (fix_restart_ps2)
251{
252fadt_mod->Flags|= 0x400;
253fadt_mod->Reset_SpaceID= 0x01; // System I/O
254fadt_mod->Reset_BitWidth= 0x08; // 1 byte
255fadt_mod->Reset_BitOffset= 0x00; // Offset 0
256fadt_mod->Reset_AccessWidth= 0x01; // Byte access
257fadt_mod->Reset_Address= 0x64; // Address of the register
258fadt_mod->Reset_Value= 0xfe; // Value to write to reset the system
259DBG("\tFACP PS2 Restart Fix applied!\n");
260}
261else
262{
263fadt_mod->Flags|= 0x400;
264fadt_mod->Reset_SpaceID= 0x01; // System I/O
265fadt_mod->Reset_BitWidth= 0x08; // 1 byte
266fadt_mod->Reset_BitOffset= 0x00; // Offset 0
267fadt_mod->Reset_AccessWidth= 0x01; // Byte access
268fadt_mod->Reset_Address= 0x0cf9; // Address of the register
269fadt_mod->Reset_Value= 0x06; // Value to write to reset the system
270DBG("\tFACP Restart Fix applied!\n");
271}
272
273}
274
275// Bungo: Save Hardware Signature (machine-signature)
276if ((fadt_mod->FACS > 0) && (fadt_mod->FACS < 0xFFFFFFFF) && (((struct acpi_2_facs *)fadt_mod->FACS)->Length >= 64))
277{
278Platform.HWSignature = ((struct acpi_2_facs *)fadt_mod->FACS)->HWSignature;
279DBG("\tHardware Signature=0x%08X: using.\n", Platform.HWSignature);
280}
281else
282{
283Platform.HWSignature = 0;
284DBG("\tFixing Hardware Signature=0x%08X.\n", Platform.HWSignature);
285}
286
287// Patch DSDT address if we have loaded DSDT.aml
288if (new_dsdt)
289{
290DBG("\tDSDT: Old @%x,%x, ",fadt_mod->DSDT,fadt_mod->X_DSDT);
291
292fadt_mod->DSDT = (uint32_t)new_dsdt;
293if ((uint32_t)(&(fadt_mod->X_DSDT)) - (uint32_t)fadt_mod + 8<=fadt_mod->Length)
294{
295fadt_mod->X_DSDT = (uint32_t)new_dsdt;
296}
297
298DBG("\tNew @%x,%x\n",fadt_mod->DSDT,fadt_mod->X_DSDT);
299
300DBG("\tFADT: Using custom DSDT!\n");
301}
302
303// Correct the checksum
304fadt_mod->Checksum=0;
305fadt_mod->Checksum=256-checksum8(fadt_mod,fadt_mod->Length);
306
307return fadt_mod;
308}
309
310/* Setup ACPI without replacing DSDT. */
311int setupAcpiNoMod()
312{
313//addConfigurationTable(&gEfiAcpiTableGuid, getAddressOfAcpiTable(), "ACPI");
314//addConfigurationTable(&gEfiAcpi20TableGuid, getAddressOfAcpi20Table(), "ACPI_20");
315/* XXX aserebln why uint32 cast if pointer is uint64 ? */
316acpi10_p = (uint64_t)(uint32_t)getAddressOfAcpiTable();
317acpi20_p = (uint64_t)(uint32_t)getAddressOfAcpi20Table();
318addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");
319if(acpi20_p)
320{
321addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");
322}
323else
324{
325DBG("\tNo ACPI 2.\n");
326}
327return 1;
328}
329
330/* Setup ACPI. Replace DSDT if DSDT.aml is found */
331int setupAcpi(void)
332{
333verbose("[ ACPI PATCHER ]\n");
334int version;
335void *new_dsdt = NULL;
336
337
338const char *filename;
339char dirSpec[128];
340int len = 0;
341
342// always reset cpu count to 0 when injecting new acpi
343acpi_cpu_count = 0;
344
345/* Try using the file specified with the DSDT option */
346if (getValueForKey(kDSDT, &filename, &len, &bootInfo->chameleonConfig))
347{
348strncpy(dirSpec, filename, sizeof(dirSpec) );
349}
350else
351{
352strcpy(dirSpec, "DSDT.aml");
353//verbose("dirSpec, DSDT.aml");
354}
355
356// Load replacement DSDT
357new_dsdt = loadACPITable(dirSpec);
358
359// Mozodojo: going to patch FACP and load SSDT's even if DSDT.aml is not present
360/*if (!new_dsdt)
361 {
362 return setupAcpiNoMod();
363 }*/
364
365// Mozodojo: Load additional SSDTs
366struct acpi_2_ssdt *new_ssdt[32]; // 30 + 2 additional tables for pss & cst
367int ssdt_count=0;
368
369// SSDT Options
370bool drop_ssdt = false, generate_pstates = false, generate_cstates = false;
371
372getBoolForKey(kDropSSDT, &drop_ssdt, &bootInfo->chameleonConfig);
373getBoolForKey(kGeneratePStates, &generate_pstates, &bootInfo->chameleonConfig);
374getBoolForKey(kGenerateCStates, &generate_cstates, &bootInfo->chameleonConfig);
375//getBoolForKey(kGenerateTStates, &generate_tstates, &bootInfo->chameleonConfig);
376
377DBG("\tGenerating P-States config: %s\n", generate_pstates ? "Yes" : "No");
378DBG("\tGenerating C-States config: %s\n", generate_cstates ? "Yes" : "No");
379//DBG("Generating T-States config: %s\n", generate_tstates ? "Yes" : "No");
380
381{
382int i;
383
384for (i = 0; i < 30; i++)
385{
386char filename[512];
387
388if (i > 0)
389{
390sprintf(filename, "SSDT-%d.aml", i);
391}
392else
393{
394strcpy(filename, "SSDT.aml");
395}
396
397if ( (new_ssdt[ssdt_count] = loadACPITable(filename)) )
398{
399ssdt_count++;
400}
401else
402{
403break;
404}
405}
406}
407
408// Do the same procedure for both versions of ACPI
409for (version = 0; version < 2; version++)
410{
411struct acpi_2_rsdp *rsdp, *rsdp_mod;
412struct acpi_2_rsdt *rsdt, *rsdt_mod;
413int rsdplength;
414
415// Find original rsdp
416rsdp = (struct acpi_2_rsdp *)(version ? getAddressOfAcpi20Table() : getAddressOfAcpiTable());
417if (!rsdp)
418{
419DBG("\tNo ACPI version %d found. Ignoring\n", version+1);
420if (version)
421{
422addConfigurationTable(&gEfiAcpi20TableGuid, NULL, "ACPI_20");
423}
424else
425{
426addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI");
427}
428continue;
429}
430rsdplength = version ? rsdp->Length : 20;
431
432DBG("\tRSDP version %d found @%x. Length=%d\n",version+1,rsdp,rsdplength);
433
434/* FIXME: no check that memory allocation succeeded
435 * Copy and patch RSDP,RSDT, XSDT and FADT
436 * For more info see ACPI Specification pages 110 and following
437 */
438
439rsdp_mod = (struct acpi_2_rsdp *) AllocateKernelMemory(rsdplength);
440memcpy(rsdp_mod, rsdp, rsdplength);
441
442rsdt = (struct acpi_2_rsdt *)rsdp->RsdtAddress;
443
444DBG("\tRSDT @%x, Length %d\n",rsdt, rsdt ? rsdt->Length : 0);
445
446if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length < 0x10000)
447{
448uint32_t *rsdt_entries;
449int rsdt_entries_num;
450int dropoffset = 0, i;
451
452// mozo: using malloc cos I didn't found how to free already allocated kernel memory
453rsdt_mod = (struct acpi_2_rsdt *)malloc(rsdt->Length);
454memcpy(rsdt_mod, rsdt, rsdt->Length);
455rsdp_mod->RsdtAddress = (uint32_t)rsdt_mod;
456rsdt_entries_num = (rsdt_mod->Length - sizeof(struct acpi_2_rsdt)) / 4;
457rsdt_entries = (uint32_t *)(rsdt_mod + 1);
458for (i = 0; i < rsdt_entries_num; i++)
459{
460char *table=(char *)(rsdt_entries[i]);
461if (!table)
462{
463continue;
464}
465
466DBG("\tTABLE %c%c%c%c,",table[0],table[1],table[2],table[3]);
467
468rsdt_entries[i-dropoffset]=rsdt_entries[i];
469
470// Dropping DMAR (DMA Remapping table) table can fix stuck on "waitForSystemMapper" or "PCI configuration begin" if nothing wokrks except rolling old AppleACPIplatform.kext back. Needs testing with current OEM AppleACPIplatform.kext not with old rolled back one
471if (tableSign(table, "DMAR"))
472{
473DBG("\tOEM DMAR table was dropped\n");
474dropoffset++;
475continue;
476}
477
478if (drop_ssdt && tableSign(table, "SSDT"))
479{
480DBG("\tOEM SSDT tables was dropped\n");
481dropoffset++;
482continue;
483}
484
485if (tableSign(table, "DSDT"))
486{
487DBG("\tDSDT found\n");
488DBG("\tCustom DSDT table was found\n");
489if(new_dsdt)
490{
491rsdt_entries[i-dropoffset] = (uint32_t)new_dsdt;
492}
493
494continue;
495}
496
497if (tableSign(table, "FACP"))
498{
499struct acpi_2_fadt *fadt, *fadt_mod;
500fadt=(struct acpi_2_fadt *)rsdt_entries[i];
501
502DBG("\tFADT found @%x, Length %d\n",fadt, fadt->Length);
503
504if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000)
505{
506DBG("\tFADT incorrect. Not modified\n");
507continue;
508}
509
510fadt_mod = patch_fadt(fadt, new_dsdt);
511rsdt_entries[i-dropoffset] = (uint32_t)fadt_mod;
512
513// Generate _CST SSDT
514if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod)))
515{
516DBG("\tC-States generated.\n");
517generate_cstates = false; // Generate SSDT only once!
518ssdt_count++;
519}
520
521// Generating _PSS SSDT
522if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT)))
523{
524DBG("\tP-States generated.\n");
525generate_pstates = false; // Generate SSDT only once!
526ssdt_count++;
527}
528continue;
529}
530}
531DBG("\n");
532
533// Allocate rsdt in Kernel memory area
534rsdt_mod->Length += 4*ssdt_count - 4*dropoffset;
535struct acpi_2_rsdt *rsdt_copy = (struct acpi_2_rsdt *)AllocateKernelMemory(rsdt_mod->Length);
536memcpy(rsdt_copy, rsdt_mod, rsdt_mod->Length);
537free(rsdt_mod);
538rsdt_mod = rsdt_copy;
539rsdp_mod->RsdtAddress = (uint32_t)rsdt_mod;
540rsdt_entries_num = (rsdt_mod->Length-sizeof(struct acpi_2_rsdt)) / 4;
541rsdt_entries = (uint32_t *)(rsdt_mod + 1);
542
543// Mozodojo: Insert additional SSDTs into RSDT
544if(ssdt_count > 0)
545{
546int j;
547
548for (j=0; j<ssdt_count; j++)
549{
550rsdt_entries[i-dropoffset+j] = (uint32_t)new_ssdt[j];
551}
552
553DBG("\tRSDT: Added %d SSDT table(s)\n", ssdt_count);
554
555}
556
557// Correct the checksum of RSDT
558DBG("\tRSDT: Original checksum %d, ", rsdt_mod->Checksum);
559
560rsdt_mod->Checksum=0;
561rsdt_mod->Checksum=256-checksum8(rsdt_mod,rsdt_mod->Length);
562
563DBG("\tNew checksum %d at %x\n", rsdt_mod->Checksum,rsdt_mod);
564}
565else
566{
567rsdp_mod->RsdtAddress=0;
568DBG("\tRSDT not found or RSDT incorrect\n");
569}
570DBG("\n");
571
572if (version)
573{
574struct acpi_2_xsdt *xsdt, *xsdt_mod;
575
576// FIXME: handle 64-bit address correctly
577
578xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress);
579DBG("\tXSDT @%x;%x, Length=%d\n", (uint32_t)(rsdp->XsdtAddress>>32),(uint32_t)rsdp->XsdtAddress, xsdt->Length);
580
581if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000)
582{
583uint64_t *xsdt_entries;
584int xsdt_entries_num, i;
585int dropoffset = 0;
586
587// mozo: using malloc cos I didn't found how to free already allocated kernel memory
588xsdt_mod = (struct acpi_2_xsdt *)malloc(xsdt->Length);
589memcpy(xsdt_mod, xsdt, xsdt->Length);
590
591rsdp_mod->XsdtAddress = (uint32_t)xsdt_mod;
592xsdt_entries_num = (xsdt_mod->Length - sizeof(struct acpi_2_xsdt)) / 8;
593xsdt_entries = (uint64_t *)(xsdt_mod + 1);
594for (i = 0;i < xsdt_entries_num; i++)
595{
596char *table = (char *)((uint32_t)(xsdt_entries[i]));
597if (!table)
598{
599continue;
600}
601xsdt_entries[i - dropoffset] = xsdt_entries[i];
602
603// Dropping DMAR (DMA Remapping table) table can fix stuck on "waitForSystemMapper" or "PCI configuration begin" if nothing wokrks except rolling old AppleACPIplatform.kext back. Needs testing with current OEM AppleACPIplatform.kext not with old rolled back one
604if (tableSign(table, "DMAR"))
605{
606DBG("\tOEM DMAR table was dropped\n");
607dropoffset++;
608continue;
609}
610
611if (drop_ssdt && tableSign(table, "SSDT"))
612{
613DBG("\tOEM SSDT tables was dropped\n");
614dropoffset++;
615continue;
616}
617if (tableSign(table, "DSDT"))
618{
619DBG("\tDSDT found\n");
620
621if (new_dsdt)
622{
623xsdt_entries[i-dropoffset] = (uint32_t)new_dsdt;
624DBG("\tcustom table added.\n");
625}
626
627DBG("\tTABLE %c%c%c%c@%x \n", table[0],table[1],table[2],table[3],xsdt_entries[i]);
628
629continue;
630}
631if (tableSign(table, "FACP"))
632{
633struct acpi_2_fadt *fadt, *fadt_mod;
634fadt=(struct acpi_2_fadt *)(uint32_t)xsdt_entries[i];
635
636DBG("\tFADT found @%x%x, Length %d\n",(uint32_t)(xsdt_entries[i]>>32),fadt,
637fadt->Length);
638
639if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000)
640{
641DBG("\tFADT incorrect or after 4GB. Dropping XSDT\n");
642goto drop_xsdt;
643}
644
645fadt_mod = patch_fadt(fadt, new_dsdt);
646xsdt_entries[i - dropoffset] = (uint32_t)fadt_mod;
647
648// DBG("\tTABLE %c%c%c%c@%x \n", table[0],table[1],table[2],table[3],xsdt_entries[i]);
649
650// Generate _CST SSDT
651if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod)))
652{
653DBG("\tC-States generated.\n");
654generate_cstates = false; // Generate SSDT only once!
655ssdt_count++;
656}
657
658// Generating _PSS SSDT
659if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT)))
660{
661DBG("\tP-States generated.\n");
662generate_pstates = false; // Generate SSDT only once!
663ssdt_count++;
664}
665
666// Generating _TSS SSDT
667/*if (generate_tstates && (new_ssdt[ssdt_count] = generate_tss_ssdt((void*)fadt_mod->DSDT)))
668{
669generate_tstates = false; // Generate SSDT only once!
670ssdt_count++;
671}*/
672continue;
673}
674DBG("\tcopied (OEM)\n");
675// DBG("\tTABLE %c%c%c%c@%x \n", table[0],table[1],table[2],table[3],xsdt_entries[i]);
676}
677
678// Allocate xsdt in Kernel memory area
679xsdt_mod->Length += 8*ssdt_count - 8*dropoffset;
680struct acpi_2_xsdt *xsdt_copy = (struct acpi_2_xsdt *)AllocateKernelMemory(xsdt_mod->Length);
681memcpy(xsdt_copy, xsdt_mod, xsdt_mod->Length);
682free(xsdt_mod);
683xsdt_mod = xsdt_copy;
684rsdp_mod->XsdtAddress = (uint32_t)xsdt_mod;
685xsdt_entries_num = (xsdt_mod->Length - sizeof(struct acpi_2_xsdt)) / 8;
686xsdt_entries = (uint64_t *)(xsdt_mod + 1);
687
688// Mozodojo: Insert additional SSDTs into XSDT
689if(ssdt_count > 0)
690{
691int j;
692
693for (j=0; j<ssdt_count; j++)
694{
695xsdt_entries[i - dropoffset + j] = (uint32_t)new_ssdt[j];
696}
697
698verbose("\tAdded %d SSDT table(s) into XSDT\n", ssdt_count);
699
700}
701
702// Correct the checksum of XSDT
703xsdt_mod->Checksum=0;
704xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length);
705}
706else
707{
708drop_xsdt:
709
710DBG("\tAbout to drop XSDT\n");
711
712/*FIXME: Now we just hope that if MacOS doesn't find XSDT it reverts to RSDT.
713 * A Better strategy would be to generate
714 */
715
716rsdp_mod->XsdtAddress=0xffffffffffffffffLL;
717verbose("\tXSDT not found or XSDT incorrect\n");
718}
719}
720DBG("\n");
721
722// Correct the checksum of RSDP
723
724DBG("\tRSDP: Original checksum %d, ", rsdp_mod->Checksum);
725
726rsdp_mod->Checksum=0;
727rsdp_mod->Checksum=256-checksum8(rsdp_mod,20);
728
729DBG("\tNew checksum %d\n", rsdp_mod->Checksum);
730
731if (version)
732{
733DBG("\tRSDP: Original extended checksum %d, ", rsdp_mod->ExtendedChecksum);
734
735rsdp_mod->ExtendedChecksum=0;
736rsdp_mod->ExtendedChecksum=256-checksum8(rsdp_mod,rsdp_mod->Length);
737
738DBG("\tNew extended checksum %d\n", rsdp_mod->ExtendedChecksum);
739
740}
741
742if (version)
743{
744/* XXX aserebln why uint32 cast if pointer is uint64 ? */
745acpi20_p = (uint64_t)(uint32_t)rsdp_mod;
746addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");
747}
748else
749{
750/* XXX aserebln why uint32 cast if pointer is uint64 ? */
751acpi10_p = (uint64_t)(uint32_t)rsdp_mod;
752addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");
753}
754DBG("\tACPI version %d patching finished\n\n", version + 1);
755}
756#if DEBUG_ACPI
757printf("Press a key to continue... (DEBUG_ACPI)\n");
758getchar();
759#endif
760return 1;
761}
762

Archive Download this file

Revision: 2847