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
470if (drop_ssdt && tableSign(table, "SSDT"))
471{
472DBG("\tOEM SSDT tables was dropped\n");
473dropoffset++;
474continue;
475}
476
477if (tableSign(table, "DSDT"))
478{
479DBG("\tDSDT found\n");
480DBG("\tCustom DSDT table was found\n");
481if(new_dsdt)
482{
483rsdt_entries[i-dropoffset] = (uint32_t)new_dsdt;
484}
485
486continue;
487}
488
489if (tableSign(table, "FACP"))
490{
491struct acpi_2_fadt *fadt, *fadt_mod;
492fadt=(struct acpi_2_fadt *)rsdt_entries[i];
493
494DBG("\tFADT found @%x, Length %d\n",fadt, fadt->Length);
495
496if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000)
497{
498DBG("\tFADT incorrect. Not modified\n");
499continue;
500}
501
502fadt_mod = patch_fadt(fadt, new_dsdt);
503rsdt_entries[i-dropoffset] = (uint32_t)fadt_mod;
504
505// Generate _CST SSDT
506if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod)))
507{
508DBG("\tC-States generated.\n");
509generate_cstates = false; // Generate SSDT only once!
510ssdt_count++;
511}
512
513// Generating _PSS SSDT
514if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT)))
515{
516DBG("\tP-States generated.\n");
517generate_pstates = false; // Generate SSDT only once!
518ssdt_count++;
519}
520continue;
521}
522}
523DBG("\n");
524
525// Allocate rsdt in Kernel memory area
526rsdt_mod->Length += 4*ssdt_count - 4*dropoffset;
527struct acpi_2_rsdt *rsdt_copy = (struct acpi_2_rsdt *)AllocateKernelMemory(rsdt_mod->Length);
528memcpy(rsdt_copy, rsdt_mod, rsdt_mod->Length);
529free(rsdt_mod);
530rsdt_mod = rsdt_copy;
531rsdp_mod->RsdtAddress = (uint32_t)rsdt_mod;
532rsdt_entries_num = (rsdt_mod->Length-sizeof(struct acpi_2_rsdt)) / 4;
533rsdt_entries = (uint32_t *)(rsdt_mod + 1);
534
535// Mozodojo: Insert additional SSDTs into RSDT
536if(ssdt_count > 0)
537{
538int j;
539
540for (j=0; j<ssdt_count; j++)
541{
542rsdt_entries[i-dropoffset+j] = (uint32_t)new_ssdt[j];
543}
544
545DBG("\tRSDT: Added %d SSDT table(s)\n", ssdt_count);
546
547}
548
549// Correct the checksum of RSDT
550DBG("\tRSDT: Original checksum %d, ", rsdt_mod->Checksum);
551
552rsdt_mod->Checksum=0;
553rsdt_mod->Checksum=256-checksum8(rsdt_mod,rsdt_mod->Length);
554
555DBG("\tNew checksum %d at %x\n", rsdt_mod->Checksum,rsdt_mod);
556}
557else
558{
559rsdp_mod->RsdtAddress=0;
560DBG("\tRSDT not found or RSDT incorrect\n");
561}
562DBG("\n");
563
564if (version)
565{
566struct acpi_2_xsdt *xsdt, *xsdt_mod;
567
568// FIXME: handle 64-bit address correctly
569
570xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress);
571DBG("\tXSDT @%x;%x, Length=%d\n", (uint32_t)(rsdp->XsdtAddress>>32),(uint32_t)rsdp->XsdtAddress, xsdt->Length);
572
573if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000)
574{
575uint64_t *xsdt_entries;
576int xsdt_entries_num, i;
577int dropoffset = 0;
578
579// mozo: using malloc cos I didn't found how to free already allocated kernel memory
580xsdt_mod = (struct acpi_2_xsdt *)malloc(xsdt->Length);
581memcpy(xsdt_mod, xsdt, xsdt->Length);
582
583rsdp_mod->XsdtAddress = (uint32_t)xsdt_mod;
584xsdt_entries_num = (xsdt_mod->Length - sizeof(struct acpi_2_xsdt)) / 8;
585xsdt_entries = (uint64_t *)(xsdt_mod + 1);
586for (i = 0;i < xsdt_entries_num; i++)
587{
588char *table = (char *)((uint32_t)(xsdt_entries[i]));
589if (!table)
590{
591continue;
592}
593xsdt_entries[i - dropoffset] = xsdt_entries[i];
594
595if (drop_ssdt && tableSign(table, "SSDT"))
596{
597DBG("\tOEM SSDT tables was dropped\n");
598dropoffset++;
599continue;
600}
601if (tableSign(table, "DSDT"))
602{
603DBG("\tDSDT found\n");
604
605if (new_dsdt)
606{
607xsdt_entries[i-dropoffset] = (uint32_t)new_dsdt;
608DBG("\tcustom table added.\n");
609}
610
611DBG("\tTABLE %c%c%c%c@%x \n", table[0],table[1],table[2],table[3],xsdt_entries[i]);
612
613continue;
614}
615if (tableSign(table, "FACP"))
616{
617struct acpi_2_fadt *fadt, *fadt_mod;
618fadt=(struct acpi_2_fadt *)(uint32_t)xsdt_entries[i];
619
620DBG("\tFADT found @%x%x, Length %d\n",(uint32_t)(xsdt_entries[i]>>32),fadt,
621fadt->Length);
622
623if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000)
624{
625DBG("\tFADT incorrect or after 4GB. Dropping XSDT\n");
626goto drop_xsdt;
627}
628
629fadt_mod = patch_fadt(fadt, new_dsdt);
630xsdt_entries[i - dropoffset] = (uint32_t)fadt_mod;
631
632// DBG("\tTABLE %c%c%c%c@%x \n", table[0],table[1],table[2],table[3],xsdt_entries[i]);
633
634// Generate _CST SSDT
635if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod)))
636{
637DBG("\tC-States generated.\n");
638generate_cstates = false; // Generate SSDT only once!
639ssdt_count++;
640}
641
642// Generating _PSS SSDT
643if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT)))
644{
645DBG("\tP-States generated.\n");
646generate_pstates = false; // Generate SSDT only once!
647ssdt_count++;
648}
649
650// Generating _TSS SSDT
651/*if (generate_tstates && (new_ssdt[ssdt_count] = generate_tss_ssdt((void*)fadt_mod->DSDT)))
652{
653generate_tstates = false; // Generate SSDT only once!
654ssdt_count++;
655}*/
656continue;
657}
658DBG("\tcopied (OEM)\n");
659// DBG("\tTABLE %c%c%c%c@%x \n", table[0],table[1],table[2],table[3],xsdt_entries[i]);
660}
661
662// Allocate xsdt in Kernel memory area
663xsdt_mod->Length += 8*ssdt_count - 8*dropoffset;
664struct acpi_2_xsdt *xsdt_copy = (struct acpi_2_xsdt *)AllocateKernelMemory(xsdt_mod->Length);
665memcpy(xsdt_copy, xsdt_mod, xsdt_mod->Length);
666free(xsdt_mod);
667xsdt_mod = xsdt_copy;
668rsdp_mod->XsdtAddress = (uint32_t)xsdt_mod;
669xsdt_entries_num = (xsdt_mod->Length - sizeof(struct acpi_2_xsdt)) / 8;
670xsdt_entries = (uint64_t *)(xsdt_mod + 1);
671
672// Mozodojo: Insert additional SSDTs into XSDT
673if(ssdt_count > 0)
674{
675int j;
676
677for (j=0; j<ssdt_count; j++)
678{
679xsdt_entries[i - dropoffset + j] = (uint32_t)new_ssdt[j];
680}
681
682verbose("\tAdded %d SSDT table(s) into XSDT\n", ssdt_count);
683
684}
685
686// Correct the checksum of XSDT
687xsdt_mod->Checksum=0;
688xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length);
689}
690else
691{
692drop_xsdt:
693
694DBG("\tAbout to drop XSDT\n");
695
696/*FIXME: Now we just hope that if MacOS doesn't find XSDT it reverts to RSDT.
697 * A Better strategy would be to generate
698 */
699
700rsdp_mod->XsdtAddress=0xffffffffffffffffLL;
701verbose("\tXSDT not found or XSDT incorrect\n");
702}
703}
704DBG("\n");
705
706// Correct the checksum of RSDP
707
708DBG("\tRSDP: Original checksum %d, ", rsdp_mod->Checksum);
709
710rsdp_mod->Checksum=0;
711rsdp_mod->Checksum=256-checksum8(rsdp_mod,20);
712
713DBG("\tNew checksum %d\n", rsdp_mod->Checksum);
714
715if (version)
716{
717DBG("\tRSDP: Original extended checksum %d, ", rsdp_mod->ExtendedChecksum);
718
719rsdp_mod->ExtendedChecksum=0;
720rsdp_mod->ExtendedChecksum=256-checksum8(rsdp_mod,rsdp_mod->Length);
721
722DBG("\tNew extended checksum %d\n", rsdp_mod->ExtendedChecksum);
723
724}
725
726if (version)
727{
728/* XXX aserebln why uint32 cast if pointer is uint64 ? */
729acpi20_p = (uint64_t)(uint32_t)rsdp_mod;
730addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");
731}
732else
733{
734/* XXX aserebln why uint32 cast if pointer is uint64 ? */
735acpi10_p = (uint64_t)(uint32_t)rsdp_mod;
736addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");
737}
738DBG("\tACPI version %d patching finished\n\n", version + 1);
739}
740#if DEBUG_ACPI
741printf("Press a key to continue... (DEBUG_ACPI)\n");
742getchar();
743#endif
744return 1;
745}
746

Archive Download this file

Revision: HEAD