Chameleon

Chameleon Svn Source Tree

Root/branches/rekursor/i386/libsaio/dsdt_patcher.c

1/*
2 * Copyright 2008 mackerintel
3 */
4
5#include "libsaio.h"
6#include "boot.h"
7#include "bootstruct.h"
8#include "acpi.h"
9#include "efi_tables.h"
10#include "fake_efi.h"
11#include "dsdt_patcher.h"
12#include "platform.h"
13
14#ifndef DEBUG_DSDT
15#define DEBUG_DSDT 0
16#endif
17
18#if DEBUG_DSDT==2
19#define DBG(x...) {printf(x); sleep(1);}
20#elif DEBUG_DSDT==1
21#define DBG(x...) printf(x)
22#else
23#define DBG(x...)
24#endif
25
26struct acpi_2_fadt *
27patch_fadt(struct acpi_2_fadt *fadt, void *new_dsdt, bool UpdateFADT)
28{
29 extern void setupSystemType();
30
31 struct acpi_2_fadt *fadt_mod;
32 struct acpi_2_fadt *fadt_file = (struct acpi_2_fadt *)acpiLoadTable(kFADT);
33 bool fadt_rev2_needed = false;
34 bool fix_restart;
35 const char * value;
36
37 // Restart Fix
38 if (Platform.CPU.Vendor == 0x756E6547) {/* Intel */
39 fix_restart = true;
40 getBoolForKey(kRestartFix, &fix_restart, &bootInfo->bootConfig);
41 } else {
42 verbose ("Not an Intel platform: Restart Fix not applied !!!\n");
43 fix_restart = false;
44 }
45
46 if (fix_restart)
47 fadt_rev2_needed = true;
48
49 // Allocate new fadt table
50 if ((UpdateFADT) && (((fadt_file) && (fadt_file->Length < sizeof(struct acpi_2_fadt))) ||
51 ((!fadt_file) && (fadt->Length < sizeof(struct acpi_2_fadt)))))
52 {
53 fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(sizeof(struct acpi_2_fadt));
54
55 if (fadt_file)
56 memcpy(fadt_mod, fadt_file, fadt_file->Length);
57 else
58 memcpy(fadt_mod, fadt, fadt->Length);
59
60 fadt_mod->Length = sizeof(struct acpi_2_fadt);
61 fadt_mod->Revision = 0x04; // FADT rev 4
62 fadt_mod->RESET_REG = acpiFillGASStruct(0, 0);
63 fadt_mod->RESET_VALUE = 0;
64 fadt_mod->Reserved2[0] = 0;
65 fadt_mod->Reserved2[1] = 0;
66 fadt_mod->Reserved2[2] = 0;
67 fadt_mod->X_PM1a_EVT_BLK = acpiFillGASStruct(fadt_mod->PM1a_EVT_BLK, fadt_mod->PM1_EVT_LEN);
68 fadt_mod->X_PM1b_EVT_BLK = acpiFillGASStruct(fadt_mod->PM1b_EVT_BLK, fadt_mod->PM1_EVT_LEN);
69 fadt_mod->X_PM1a_CNT_BLK = acpiFillGASStruct(fadt_mod->PM1a_CNT_BLK, fadt_mod->PM1_CNT_LEN);
70 fadt_mod->X_PM1b_CNT_BLK = acpiFillGASStruct(fadt_mod->PM1b_CNT_BLK, fadt_mod->PM1_CNT_LEN);
71 fadt_mod->X_PM2_CNT_BLK = acpiFillGASStruct(fadt_mod->PM2_CNT_BLK, fadt_mod->PM2_CNT_LEN);
72 fadt_mod->X_PM_TMR_BLK = acpiFillGASStruct(fadt_mod->PM_TMR_BLK, fadt_mod->PM_TMR_LEN);
73 fadt_mod->X_GPE0_BLK = acpiFillGASStruct(fadt_mod->GPE0_BLK, fadt_mod->GPE0_BLK_LEN);
74 fadt_mod->X_GPE1_BLK = acpiFillGASStruct(fadt_mod->GPE1_BLK, fadt_mod->GPE1_BLK_LEN);
75 verbose("Converted ACPI V%d FADT to ACPI V4 FADT\n", (fadt_file) ? fadt_file->Revision : fadt->Revision);
76 } else {
77 if (((!fadt_file) && ((fadt->Length < 0x84) && (fadt_rev2_needed))) ||
78 ((fadt_file) && ((fadt_file->Length < 0x84) && (fadt_rev2_needed))))
79 {
80 fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84);
81
82 if (fadt_file)
83 memcpy(fadt_mod, fadt_file, fadt_file->Length);
84 else
85 memcpy(fadt_mod, fadt, fadt->Length);
86
87 fadt_mod->Length = 0x84;
88 fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions)
89 }
90 else
91 {
92 if (fadt_file)
93 {
94 fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt_file->Length);
95 memcpy(fadt_mod, fadt_file, fadt_file->Length);
96 } else {
97 fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length);
98 memcpy(fadt_mod, fadt, fadt->Length);
99 }
100 }
101 }
102 // Determine system type / PM_Model
103 if ( (value=getStringForKey(kSystemType, &bootInfo->bootConfig))!=NULL)
104 {
105 if (Platform.Type > 6)
106 {
107 if(fadt_mod->Preferred_PM_Profile<=6)
108 Platform.Type = fadt_mod->Preferred_PM_Profile; // get the fadt if correct
109 else
110 Platform.Type = 1;/* Set a fixed value (Desktop) */
111 verbose("Error: system-type must be 0..6. Defaulting to %d !\n", Platform.Type);
112 }
113 else
114 Platform.Type = (unsigned char) strtoul(value, NULL, 10);
115 }
116 // Set Preferred_PM_Profile from System-type if only if user wanted this value to be forced
117 if (fadt_mod->Preferred_PM_Profile != Platform.Type)
118 {
119 if (value)
120 { // user has overriden the SystemType so take care of it in FACP
121 verbose("FADT: changing Preferred_PM_Profile from 0x%02x to 0x%02x\n", fadt_mod->Preferred_PM_Profile, Platform.Type);
122 fadt_mod->Preferred_PM_Profile = Platform.Type;
123 }
124 else
125 { // Preferred_PM_Profile has a different value and no override has been set, so reflect the user value to ioregs
126 Platform.Type = fadt_mod->Preferred_PM_Profile <= 6 ? fadt_mod->Preferred_PM_Profile : 1;
127 }
128 }
129 // We now have to write the systemm-type in ioregs: we cannot do it before in setupDeviceTree()
130 // because we need to take care of facp original content, if it is correct.
131 setupSystemType();
132
133 // Patch FADT to fix restart
134 if (fix_restart)
135 {
136 fadt_mod->Flags|= 0x400;
137 fadt_mod->RESET_REG = acpiFillGASStruct(0x0cf9, 1);
138 fadt_mod->RESET_VALUE = 0x06;
139 verbose("FADT: Restart Fix applied !\n");
140 }
141
142 // Patch FACS Address
143 fadt_mod->FIRMWARE_CTRL=(uint32_t)fadt->FIRMWARE_CTRL;
144 if ((uint32_t)(&(fadt_mod->X_FIRMWARE_CTRL))-(uint32_t)fadt_mod+8<=fadt_mod->Length)
145 fadt_mod->X_FIRMWARE_CTRL=(uint32_t)fadt->FIRMWARE_CTRL
146
147 // Patch DSDT Address
148 DBG("DSDT: Old @%x,%x, ",fadt_mod->DSDT,fadt_mod->X_DSDT);
149
150 fadt_mod->DSDT=(uint32_t)new_dsdt;
151 if ((uint32_t)(&(fadt_mod->X_DSDT))-(uint32_t)fadt_mod+8<=fadt_mod->Length)
152 fadt_mod->X_DSDT=(uint32_t)new_dsdt;
153
154 DBG("New @%x,%x\n",fadt_mod->DSDT,fadt_mod->X_DSDT);
155
156 // Correct the checksum
157 fadt_mod->Checksum=0;
158 fadt_mod->Checksum=256-checksum8(fadt_mod,fadt_mod->Length);
159
160 return fadt_mod;
161}
162
163/* Setup ACPI without replacing DSDT. */
164int setupAcpiNoMod()
165{
166 //addConfigurationTable(&gEfiAcpiTableGuid, acpiGetAddressOfTable10(), "ACPI");
167 //addConfigurationTable(&gEfiAcpi20TableGuid, acpiGetAddressOfTable20(), "ACPI_20");
168 /* XXX aserebln why uint32 cast if pointer is uint64 ? */
169 acpi10_p = (uint32_t) acpiGetAddressOfTable10();
170 acpi20_p = (uint32_t) acpiGetAddressOfTable20();
171 addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");
172 if(acpi20_p) addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");
173 return 1;
174}
175
176
177/* Setup ACPI. Replace DSDT if DSDT.aml is found */
178int setupAcpi(void)
179{
180 int version;
181 void *new_dsdt=NULL, *new_content=NULL;
182
183 bool update_acpi=false, gen_xsdt=false;
184 bool hpet_replaced=false, sbst_replaced=false, ecdt_replaced=false, asft_replaced=false, dmar_replaced=false, apic_replaced=false, mcfg_replaced=false;
185 bool hpet_added=false, sbst_added=false, ecdt_added=false, asft_added=false, dmar_added=false, apic_added=false, mcfg_added=false;
186
187 int curssdt=0, loadtotssdt=0, totssdt=0, newtotssdt=0;
188
189 {
190 bool tmpval;
191
192 update_acpi=getBoolForKey(kUpdateACPI, &tmpval, &bootInfo->bootConfig)&&tmpval;
193 }
194
195 // Load replacement ACPI tables if they provided by user according to the drop table list
196 acpiLoadUserTables();
197
198 if (!(new_dsdt=acpiLoadTable("DSDT")))
199 return setupAcpiNoMod();
200
201 DBG("New ACPI tables Loaded in memory\n");
202
203 // Do the same procedure for both versions of ACPI
204 for (version=0; version<2; version++) {
205 struct acpi_2_rsdp *rsdp, *rsdp_mod, *rsdp_conv=(struct acpi_2_rsdp *)0;
206 struct acpi_2_rsdt *rsdt, *rsdt_mod;
207 struct acpi_2_xsdt *xsdt_conv = (struct acpi_2_xsdt *)0;
208 int rsdplength;
209
210 // Find original rsdp
211 rsdp=(struct acpi_2_rsdp *) (version?
212 acpiGetAddressOfTable20() :
213 acpiGetAddressOfTable10());
214 if ((update_acpi) && (rsdp->Revision == 0))
215 {
216 rsdp_conv = (struct acpi_2_rsdp *)AllocateKernelMemory(sizeof(struct acpi_2_rsdp));
217 memcpy(rsdp_conv, rsdp, 20);
218
219 /* Add/change fields */
220 rsdp_conv->Revision = 2; /* ACPI version 3 */
221 rsdp_conv->Length = sizeof(struct acpi_2_rsdp);
222
223 /* Correct checksums */
224 rsdp_conv->Checksum = 0;
225 rsdp_conv->Checksum = 256-checksum8(rsdp_conv, 20);
226 rsdp_conv->ExtendedChecksum = 0;
227 rsdp_conv->ExtendedChecksum = 256-checksum8(rsdp_conv, rsdp_conv->Length);
228
229 rsdp = rsdp_conv;
230
231 gen_xsdt = true;
232 version = 1;
233
234 addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI");
235
236 verbose("Converted ACPI RSD PTR version 1 to version 3\n");
237 }
238 if (!rsdp)
239 {
240 DBG("No ACPI version %d found. Ignoring\n", version+1);
241 if (version)
242 addConfigurationTable(&gEfiAcpi20TableGuid, NULL, "ACPI_20");
243 else
244 addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI");
245 continue;
246 }
247 rsdplength=version?rsdp->Length:20;
248
249 DBG("RSDP version %d found @%x. Length=%d\n",version+1,rsdp,rsdplength);
250
251 /* FIXME: no check that memory allocation succeeded
252 * Copy and patch RSDP,RSDT, XSDT and FADT
253 * For more info see ACPI Specification pages 110 and following
254 */
255
256 if (gen_xsdt)
257 {
258 rsdp_mod=rsdp_conv;
259 } else {
260 rsdp_mod=(struct acpi_2_rsdp *) AllocateKernelMemory(rsdplength);
261 memcpy(rsdp_mod, rsdp, rsdplength);
262 }
263
264 rsdt=(struct acpi_2_rsdt *)(rsdp->RsdtAddress);
265
266 DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length);
267
268 if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000)
269 {
270 uint32_t *rsdt_entries;
271 int rsdt_entries_num;
272 int dropoffset=0, i;
273
274 rsdt_mod=(struct acpi_2_rsdt *)AllocateKernelMemory(rsdt->Length);
275 memcpy (rsdt_mod, rsdt, rsdt->Length);
276 rsdp_mod->RsdtAddress=(uint32_t)rsdt_mod;
277 rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4;
278 rsdt_entries=(uint32_t *)(rsdt_mod+1);
279
280 if (gen_xsdt)
281 {
282 uint64_t *xsdt_conv_entries;
283
284 xsdt_conv=(struct acpi_2_xsdt *)AllocateKernelMemory(sizeof(struct acpi_2_xsdt)+(rsdt_entries_num * 8));
285 memcpy(xsdt_conv, rsdt, sizeof(struct acpi_2_rsdt));
286
287 xsdt_conv->Signature[0] = 'X';
288 xsdt_conv->Signature[1] = 'S';
289 xsdt_conv->Signature[2] = 'D';
290 xsdt_conv->Signature[3] = 'T';
291 xsdt_conv->Length = sizeof(struct acpi_2_xsdt)+(rsdt_entries_num * 8);
292
293 xsdt_conv_entries=(uint64_t *)(xsdt_conv+1);
294
295 for (i=0;i<rsdt_entries_num;i++)
296 {
297 xsdt_conv_entries[i] = (uint64_t)rsdt_entries[i];
298 }
299
300 xsdt_conv->Checksum = 0;
301 xsdt_conv->Checksum = 256-checksum8(xsdt_conv, xsdt_conv->Length);
302
303 rsdp->XsdtAddress = (uint32_t)xsdt_conv;
304
305 rsdp->ExtendedChecksum = 0;
306 rsdp->ExtendedChecksum = 256-checksum8(rsdp, rsdp->Length);
307
308 verbose("Converted RSDT table to XSDT table\n");
309 }
310
311 for (i=0;i<rsdt_entries_num;i++)
312 {
313 char *table=(char *)(rsdt_entries[i]);
314 if (!table)
315 continue;
316
317 DBG("TABLE %c%c%c%c,",table[0],table[1],table[2],table[3]);
318
319 /*****************/
320 /* CHECK ME here:*/
321 /****************/
322
323 /* either we add a user table*/
324 if ((new_content=acpiTableUserContent(table)))
325 {
326 DBG("..Installing user acpi table %c%c%c%c\n", table[0],table[1],table[2],table[3]);
327 if (new_content)
328 {
329 rsdt_entries[i-dropoffset]=(uint32_t)new_content;
330 rsdt_mod->Length+=4;
331 }
332 continue;
333 }
334 else if (acpiIsTableDropped(table))
335 { // or it is in the drop list and we don't add it at all
336 dropoffset++;
337 continue;
338 }
339 else // or we keep the default table
340 rsdt_entries[i-dropoffset]=rsdt_entries[i];
341
342 /* CHECK ME HERE: for special cases */
343/*
344 if ((!(oem_ssdt)) && table[0]=='S' && table[1]=='S' && table[2]=='D' && table[3]=='T')
345 {
346 DBG("SSDT %d found", curssdt);
347 if (new_ssdts[curssdt])
348 {
349 DBG(" and replaced");
350 rsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt];
351 totssdt++;
352 }
353 DBG("\n");
354 curssdt++;
355 continue;
356 }
357 if (table[0]=='F' && table[1]=='A' && table[2]=='C' && table[3]=='P')
358 {
359 struct acpi_2_fadt *fadt, *fadt_mod;
360 fadt=(struct acpi_2_fadt *)rsdt_entries[i];
361
362 DBG("FADT found @%x, Length %d\n",fadt, fadt->Length);
363
364 if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000)
365 {
366 printf("FADT incorrect. Not modified\n");
367 continue;
368 }
369
370 fadt_mod = patch_fadt(fadt, new_dsdt, update_acpi);
371 rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;
372 continue;
373 }
374*/
375 }
376 DBG("\n");
377
378 /* CHECK ME here */
379/* if (!oem_ssdt)
380 {
381 while ((totssdt < loadtotssdt) && (curssdt < 30))
382 {
383 if (new_ssdts[curssdt])
384 {
385 DBG("adding SSDT %d\n", curssdt);
386 rsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt];
387 totssdt++;
388 newtotssdt++;
389 i++;
390 }
391 curssdt++;
392 }
393 }
394*/
395
396 // Correct the checksum of RSDT
397 rsdt_mod->Length-=4*dropoffset;
398 rsdt_mod->Length+=4*newtotssdt;
399
400 DBG("RSDT: Original checksum %d, ", rsdt_mod->Checksum);
401
402 rsdt_mod->Checksum=0;
403 rsdt_mod->Checksum=256-checksum8(rsdt_mod,rsdt_mod->Length);
404
405 DBG("New checksum %d at %x\n", rsdt_mod->Checksum,rsdt_mod);
406 }
407 else
408 {
409 rsdp_mod->RsdtAddress=0;
410 printf("RSDT not found or RSDT incorrect\n");
411 }
412
413 if (version)
414 {
415 struct acpi_2_xsdt *xsdt, *xsdt_mod;
416
417 // FIXME: handle 64-bit address correctly
418
419 if (gen_xsdt)
420 xsdt=xsdt_conv;
421 else
422 xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress);
423
424 DBG("XSDT @%x;%x, Length=%d\n", (uint32_t)(rsdp->XsdtAddress>>32),(uint32_t)rsdp->XsdtAddress,
425 xsdt->Length);
426 if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000)
427 {
428 uint64_t *xsdt_entries;
429 int xsdt_entries_num, i;
430 int dropoffset=0;
431 curssdt=0, totssdt=0, newtotssdt=0;
432 hpet_replaced=false, hpet_added=false;
433 sbst_replaced=false, sbst_added=false;
434 ecdt_replaced=false, ecdt_added=false;
435 asft_replaced=false, asft_added=false;
436 dmar_replaced=false, dmar_added=false;
437 apic_replaced=false, apic_added=false;
438 mcfg_replaced=false, mcfg_added=false;
439
440 if (gen_xsdt)
441 xsdt_mod=xsdt;
442 else
443 {
444 xsdt_mod=(struct acpi_2_xsdt*)AllocateKernelMemory(xsdt->Length);
445 memcpy(xsdt_mod, xsdt, xsdt->Length);
446 }
447
448 rsdp_mod->XsdtAddress=(uint32_t)xsdt_mod;
449 xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8;
450 xsdt_entries=(uint64_t *)(xsdt_mod+1);
451 for (i=0;i<xsdt_entries_num;i++)
452 {
453 char *table=(char *)((uint32_t)(xsdt_entries[i]));
454 if (!table)
455 continue;
456 xsdt_entries[i-dropoffset]=xsdt_entries[i];
457 if (drop_ssdt && table[0]=='S' && table[1]=='S' && table[2]=='D' && table[3]=='T')
458 {
459 dropoffset++;
460 continue;
461 }
462 if (drop_hpet && table[0]=='H' && table[1]=='P' && table[2]=='E' && table[3]=='T')
463 {
464 dropoffset++;
465 continue;
466 }
467 if (drop_slic && table[0]=='S' && table[1]=='L' && table[2]=='I' && table[3]=='C')
468 {
469 dropoffset++;
470 continue;
471 }
472 if (drop_sbst && table[0]=='S' && table[1]=='B' && table[2]=='S' && table[3]=='T')
473 {
474 dropoffset++;
475 continue;
476 }
477 if (drop_ecdt && table[0]=='E' && table[1]=='C' && table[2]=='D' && table[3]=='T')
478 {
479 dropoffset++;
480 continue;
481 }
482 if (drop_asft && table[0]=='A' && table[1]=='S' && table[2]=='F' && table[3]=='!')
483 {
484 dropoffset++;
485 continue;
486 }
487 if (drop_dmar && table[0]=='D' && table[1]=='M' && table[2]=='A' && table[3]=='R')
488 {
489 dropoffset++;
490 continue;
491 }
492 if ((!(oem_hpet)) && table[0]=='H' && table[1]=='P' && table[2]=='E' && table[3]=='T')
493 {
494 DBG("HPET found\n");
495 if (new_hpet)
496 {
497 xsdt_entries[i-dropoffset]=(uint32_t)new_hpet;
498 hpet_replaced=true;
499 }
500 continue;
501 }
502 if ((!(oem_sbst)) && table[0]=='S' && table[1]=='B' && table[2]=='S' && table[3]=='T')
503 {
504 DBG("SBST found\n");
505 if (new_sbst)
506 {
507 xsdt_entries[i-dropoffset]=(uint32_t)new_sbst;
508 sbst_replaced=true;
509 }
510 continue;
511 }
512 if ((!(oem_ecdt)) && table[0]=='E' && table[1]=='C' && table[2]=='D' && table[3]=='T')
513 {
514 DBG("ECDT found\n");
515 if (new_ecdt)
516 {
517 xsdt_entries[i-dropoffset]=(uint32_t)new_ecdt;
518 ecdt_replaced=true;
519 }
520 continue;
521 }
522 if ((!(oem_asft)) && table[0]=='A' && table[1]=='S' && table[2]=='F' && table[3]=='!')
523 {
524 DBG("ASF! found\n");
525 if (new_asft)
526 {
527 xsdt_entries[i-dropoffset]=(uint32_t)new_asft;
528 asft_replaced=true;
529 }
530 continue;
531 }
532 if ((!(oem_dmar)) && table[0]=='D' && table[1]=='M' && table[2]=='A' && table[3]=='R')
533 {
534 DBG("DMAR found\n");
535 if (new_dmar)
536 {
537 xsdt_entries[i-dropoffset]=(uint32_t)new_dmar;
538 dmar_replaced=true;
539 }
540 continue;
541 }
542 if ((!(oem_apic)) && table[0]=='A' && table[1]=='P' && table[2]=='I' && table[3]=='C')
543 {
544 DBG("APIC found\n");
545 if (new_apic)
546 {
547 xsdt_entries[i-dropoffset]=(uint32_t)new_apic;
548 apic_replaced=true;
549 }
550 continue;
551 }
552 if ((!(oem_mcfg)) && table[0]=='M' && table[1]=='C' && table[2]=='F' && table[3]=='G')
553 {
554 DBG("MCFG found\n");
555 if (new_mcfg)
556 {
557 xsdt_entries[i-dropoffset]=(uint32_t)new_mcfg;
558 mcfg_replaced=true;
559 }
560 continue;
561 }
562 if ((!(oem_ssdt)) && table[0]=='S' && table[1]=='S' && table[2]=='D' && table[3]=='T')
563 {
564 DBG("SSDT %d found", curssdt);
565 if (new_ssdts[curssdt])
566 {
567 DBG(" and replaced");
568 xsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt];
569 totssdt++;
570 }
571 DBG("\n");
572 curssdt++;
573 continue;
574 }
575 if (table[0]=='D' && table[1]=='S' && table[2]=='D' && table[3]=='T')
576 {
577 DBG("DSDT found\n");
578
579 xsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;
580
581 DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
582
583 continue;
584 }
585 if (table[0]=='F' && table[1]=='A' && table[2]=='C' && table[3]=='P')
586 {
587 struct acpi_2_fadt *fadt, *fadt_mod;
588 fadt=(struct acpi_2_fadt *)(uint32_t)xsdt_entries[i];
589
590 DBG("FADT found @%x,%x, Length %d\n",(uint32_t)(xsdt_entries[i]>>32),fadt,
591 fadt->Length);
592
593 if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000)
594 {
595 verbose("FADT incorrect or after 4GB. Dropping XSDT\n");
596 goto drop_xsdt;
597 }
598
599 fadt_mod = patch_fadt(fadt, new_dsdt,update_acpi);
600 xsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;
601
602 DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
603
604 continue;
605 }
606
607 DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
608
609 }
610
611 if ((!oem_hpet) && (!hpet_replaced))
612 {
613 if (new_hpet)
614 {
615 xsdt_entries[i-dropoffset]=(uint32_t)new_hpet;
616 hpet_added=true;
617 i++;
618 }
619 }
620
621 if ((!oem_sbst) && (!sbst_replaced))
622 {
623 if (new_sbst)
624 {
625 xsdt_entries[i-dropoffset]=(uint32_t)new_sbst;
626 sbst_added=true;
627 i++;
628 }
629 }
630
631 if ((!oem_ecdt) && (!ecdt_replaced))
632 {
633 if (new_ecdt)
634 {
635 xsdt_entries[i-dropoffset]=(uint32_t)new_ecdt;
636 ecdt_added=true;
637 i++;
638 }
639 }
640
641 if ((!oem_asft) && (!asft_replaced))
642 {
643 if (new_asft)
644 {
645 xsdt_entries[i-dropoffset]=(uint32_t)new_asft;
646 asft_added=true;
647 i++;
648 }
649 }
650
651 if ((!oem_dmar) && (!dmar_replaced))
652 {
653 if (new_dmar)
654 {
655 xsdt_entries[i-dropoffset]=(uint32_t)new_dmar;
656 dmar_added=true;
657 i++;
658 }
659 }
660
661 if ((!oem_apic) && (!apic_replaced))
662 {
663 if (new_apic)
664 {
665 xsdt_entries[i-dropoffset]=(uint32_t)new_apic;
666 apic_added=true;
667 i++;
668 }
669 }
670
671 if ((!oem_mcfg) && (!mcfg_replaced))
672 {
673 if (new_mcfg)
674 {
675 xsdt_entries[i-dropoffset]=(uint32_t)new_mcfg;
676 mcfg_added=true;
677 i++;
678 }
679 }
680
681 if (!oem_ssdt)
682 {
683 while ((totssdt < loadtotssdt) && (curssdt < 30))
684 {
685 if (new_ssdts[curssdt])
686 {
687 DBG("adding SSDT %d\n", curssdt);
688 xsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt];
689 totssdt++;
690 newtotssdt++;
691 i++;
692 }
693 curssdt++;
694 }
695 }
696
697 // Correct the checksum of XSDT
698 xsdt_mod->Length-=8*dropoffset;
699 xsdt_mod->Length+=8*newtotssdt;
700 if (hpet_added)
701 xsdt_mod->Length+=8;
702 if (sbst_added)
703 xsdt_mod->Length+=8;
704 if (ecdt_added)
705 xsdt_mod->Length+=8;
706 if (asft_added)
707 xsdt_mod->Length+=8;
708 if (dmar_added)
709 xsdt_mod->Length+=8;
710 if (apic_added)
711 xsdt_mod->Length+=8;
712 if (mcfg_added)
713 xsdt_mod->Length+=8;
714
715 xsdt_mod->Checksum=0;
716 xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length);
717 }
718 else
719 {
720 drop_xsdt:
721
722 DBG("About to drop XSDT\n");
723
724 /*FIXME: Now we just hope that if MacOS doesn't find XSDT it reverts to RSDT.
725 * A Better strategy would be to generate
726 */
727
728 rsdp_mod->XsdtAddress=0xffffffffffffffffLL;
729 verbose("XSDT not found or XSDT incorrect\n");
730 }
731 }
732
733 // Correct the checksum of RSDP
734
735 DBG("RSDP: Original checksum %d, ", rsdp_mod->Checksum);
736
737 rsdp_mod->Checksum=0;
738 rsdp_mod->Checksum=256-checksum8(rsdp_mod,20);
739
740 DBG("New checksum %d\n", rsdp_mod->Checksum);
741
742 if (version)
743 {
744 DBG("RSDP: Original extended checksum %d", rsdp_mod->ExtendedChecksum);
745
746 rsdp_mod->ExtendedChecksum=0;
747 rsdp_mod->ExtendedChecksum=256-checksum8(rsdp_mod,rsdp_mod->Length);
748
749 DBG("New extended checksum %d\n", rsdp_mod->ExtendedChecksum);
750
751 }
752
753 verbose("Patched ACPI version %d DSDT\n", version+1);
754 if (version)
755 {
756 /* XXX aserebln why uint32 cast if pointer is uint64 ? */
757 acpi20_p = (uint32_t)rsdp_mod;
758 addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");
759 }
760 else
761 {
762 /* XXX aserebln why uint32 cast if pointer is uint64 ? */
763 acpi10_p = (uint32_t)rsdp_mod;
764 addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");
765 }
766 }
767#if DEBUG_DSDT
768 printf("Press a key to continue... (DEBUG_DSDT)\n");
769 getc();
770#endif
771 return 1;
772}
773

Archive Download this file

Revision: 63