Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch/i386/libsaio/acpi_patcher.c

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

Archive Download this file

Revision: 2853