Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/modules/ACPIPatcher/acpi_patcher.c

  • Property svn:executable set to *
1/*
2 * Copyright 2008 mackerintel
3 */
4
5/*
6 * Copyright (c) 2010 cparm <armelcadetpetit@gmail.com>. All rights reserved.
7 *
8 */
9
10#include "libsaio.h"
11#include "bootstruct.h"
12#include "acpi.h"
13#include "efi_tables.h"
14#include "fake_efi.h"
15#include "acpi_patcher.h"
16#include "platform.h"
17#include "cpu.h"
18#include "aml_generator.h"
19#include "xml.h"
20
21uint64_t acpi10_p;
22uint64_t acpi20_p;
23
24#ifndef DEBUG_ACPI
25#define DEBUG_ACPI 0
26#endif
27
28#if DEBUG_ACPI==2
29#define DBG(x...) {printf(x); sleep(1);}
30#elif DEBUG_ACPI==1
31#define DBG(x...) printf(x)
32#else
33#define DBG(x...)
34#endif
35
36#define EBDA_SEG_ADDR0x40E
37#define EBDA_SEG_LEN0x400
38#define CMOS_BASE_MEMORY0x15
39
40extern EFI_STATUS addConfigurationTable();
41
42extern EFI_GUID gEfiAcpiTableGuid;
43extern EFI_GUID gEfiAcpi20TableGuid;
44struct acpi_2_fadt *
45patch_fadt(struct acpi_2_fadt *fadt, struct acpi_2_dsdt *new_dsdt, bool UpdateFADT);
46struct acpi_2_gas FillGASStruct(uint32_t Address, uint8_t Length);
47struct acpi_2_ssdt *generate_pss_ssdt(struct acpi_2_dsdt* dsdt);
48struct acpi_2_ssdt *generate_cst_ssdt(struct acpi_2_fadt* fadt);
49void get_acpi_cpu_names(unsigned char* dsdt, uint32_t length);
50void *loadACPITable(char *key);
51void *loadSSDTTable(int ssdt_number);
52
53#define tableSign(table, sgn) (table[0]==sgn[0] && table[1]==sgn[1] && table[2]==sgn[2] && table[3]==sgn[3])
54
55#define CMOS_WRITE_BYTE(x, y)cmos_write_byte(x, y)
56#define CMOS_READ_BYTE(x)cmos_read_byte(x)
57
58#define RSDP_CHECKSUM_LENGTH 20
59
60/* COPYRIGHT NOTICE: checksum8 from AppleSMBIOS */
61static uint8_t checksum8( void * start, unsigned int length )
62{
63 uint8_t csum = 0;
64 uint8_t * cp = (uint8_t *) start;
65 unsigned int i;
66
67 for ( i = 0; i < length; i++)
68 csum += *cp++;
69
70 return csum;
71}
72
73/*-
74 *FOR biosacpi_search_rsdp AND biosacpi_find_rsdp
75 *
76 * Copyright (c) 2001 Michael Smith <msmith@freebsd.org>
77 * All rights reserved.
78 *
79 * Redistribution and use in source and binary forms, with or without
80 * modification, are permitted provided that the following conditions
81 * are met:
82 * 1. Redistributions of source code must retain the above copyright
83 * notice, this list of conditions and the following disclaimer.
84 * 2. Redistributions in binary form must reproduce the above copyright
85 * notice, this list of conditions and the following disclaimer in the
86 * documentation and/or other materials provided with the distribution.
87 *
88 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
89 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
90 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
91 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
92 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
93 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
94 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
95 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
96 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
97 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
98 * SUCH DAMAGE.
99 *
100 * $FreeBSD: src/sys/boot/i386/libi386/biosacpi.c,v 1.7 2003/08/25 23:28:31 obrien Exp $
101 * $DragonFly: src/sys/boot/pc32/libi386/biosacpi.c,v 1.5 2007/01/17 17:31:19 y0netan1 Exp $
102 */
103
104static struct acpi_2_rsdp *
105biosacpi_search_rsdp(char *base, int length, int rev)
106{
107 struct acpi_2_rsdp *rsdp;
108 intofs;
109
110 /* search on 16-byte boundaries */
111 for (ofs = 0; ofs < length; ofs += 16) {
112rsdp = (struct acpi_2_rsdp*)ptov(base + ofs);
113
114/* compare signature, validate checksum */
115if (!strncmp(rsdp->Signature, ACPI_SIG_RSDP, strlen(ACPI_SIG_RSDP))) {
116
117uint8_t csum = checksum8(rsdp, RSDP_CHECKSUM_LENGTH);
118 if(csum == 0)
119 {
120/* Only assume this is a 2.0 or better table if the revision is greater than 0
121 * NOTE: ACPI 3.0 spec only seems to say that 1.0 tables have revision 1
122 * and that the current revision is 2.. I am going to assume that rev > 0 is 2.0.
123 */
124
125if((rsdp->Revision > 0) && rev > 0)
126{
127uint8_t csum2 = checksum8(rsdp, sizeof(struct acpi_2_rsdp));
128if(csum2 == 0)
129return(rsdp);
130}
131
132 // Only return the table if it is a true version 1.0 table (Revision 0)
133 if((rsdp->Revision == 0) && rev == 0)
134 return(rsdp);
135 }
136
137}
138 }
139 return(NULL);
140}
141
142/*
143 * Find the RSDP in low memory. See section 5.2.2 of the ACPI spec.
144 */
145static struct acpi_2_rsdp *
146biosacpi_find_rsdp(int rev)
147{
148 struct acpi_2_rsdp *rsdp;
149 uint16_t*addr;
150
151 /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
152 addr = (uint16_t *)ptov(EBDA_SEG_ADDR);
153 if ((rsdp = biosacpi_search_rsdp((char *)(*addr << 4), EBDA_SEG_LEN, rev)) != NULL)
154return (rsdp);
155
156unsigned mem_lower = ((CMOS_READ_BYTE(CMOS_BASE_MEMORY+1) << 8)
157 | CMOS_READ_BYTE(CMOS_BASE_MEMORY)) << 10;
158
159if ((rsdp = biosacpi_search_rsdp((char *)mem_lower, EBDA_SEG_LEN, rev)) != NULL)
160return (rsdp);
161
162
163 /* Check the upper memory BIOS space, 0xe0000 - 0xfffff. */
164 if ((rsdp = biosacpi_search_rsdp((char *)0xe0000, 0x20000, rev)) != NULL)
165return (rsdp);
166
167 return (NULL);
168}
169
170
171
172#define __RES(s, u)\
173static inline unsigned u\
174resolve_##s(unsigned u defaultentry, char *str, int base) \
175{\
176unsigned u entry = defaultentry;\
177if (str && (strcmp(str,"Default") != 0)) {\
178entry = strtoul((const char *)str, NULL,base);\
179}\
180return entry;\
181}
182
183__RES(pss, long)
184__RES(cst, int)
185
186
187static void setchecksum(struct acpi_common_header *header)
188{
189 header->Checksum = 0;
190 header->Checksum = 256-checksum8(header, header->Length);
191}
192
193static void setRsdpchecksum(struct acpi_2_rsdp *rsdp)
194{
195 rsdp->Checksum = 0;
196 rsdp->Checksum = 256-checksum8(rsdp, 20);
197}
198
199static void setRsdpXchecksum(struct acpi_2_rsdp *rsdp)
200{
201 rsdp->ExtendedChecksum = 0;
202 rsdp->ExtendedChecksum = 256-checksum8(rsdp, rsdp->Length);
203}
204
205static struct acpi_2_rsdp * gen_rsdp_v2_from_v1(struct acpi_2_rsdp *rsdp)
206{
207 struct acpi_2_rsdp * rsdp_conv = (struct acpi_2_rsdp *)AllocateKernelMemory(sizeof(struct acpi_2_rsdp));
208 memcpy(rsdp_conv, rsdp, 20);
209
210 /* Add/change fields */
211 rsdp_conv->Revision = 2; /* ACPI version 3 */
212 rsdp_conv->Length = sizeof(struct acpi_2_rsdp);
213
214 /* Correct checksums */
215 setRsdpchecksum(rsdp_conv);
216 setRsdpXchecksum(rsdp_conv);
217
218 rsdp = rsdp_conv;
219
220 return rsdp_conv;
221}
222
223static struct acpi_2_xsdt * gen_xsdt_from_rsdt(struct acpi_2_rsdt *rsdt)
224{
225 int i,rsdt_entries_num=(rsdt->Length-sizeof(struct acpi_2_rsdt))/4;
226
227 uint32_t *rsdt_entries=(uint32_t *)(rsdt+1);
228
229 struct acpi_2_xsdt * xsdt_conv=(struct acpi_2_xsdt *)AllocateKernelMemory(sizeof(struct acpi_2_xsdt)+(rsdt_entries_num * 8));
230 memcpy(xsdt_conv, rsdt, sizeof(struct acpi_2_rsdt));
231
232 xsdt_conv->Signature[0] = 'X';
233 xsdt_conv->Signature[1] = 'S';
234 xsdt_conv->Signature[2] = 'D';
235 xsdt_conv->Signature[3] = 'T';
236 xsdt_conv->Length = sizeof(struct acpi_2_xsdt)+(rsdt_entries_num * 8);
237
238 uint64_t *xsdt_conv_entries=(uint64_t *)(xsdt_conv+1);
239
240 for (i=0;i<rsdt_entries_num;i++)
241 {
242 xsdt_conv_entries[i] = (uint64_t)rsdt_entries[i];
243 }
244
245 setchecksum((struct acpi_common_header *)xsdt_conv);
246
247 return xsdt_conv;
248}
249
250static void update_rsdp_with_xsdt(struct acpi_2_rsdp *rsdp, struct acpi_2_xsdt *xsdt)
251{
252 rsdp->XsdtAddress = (uint32_t)xsdt;
253
254 setRsdpXchecksum(rsdp);
255}
256
257static void update_rsdp_with_rsdt(struct acpi_2_rsdp *rsdp, struct acpi_2_rsdt *rsdt)
258{
259 rsdp->RsdtAddress = (uint32_t)rsdt;
260
261 setRsdpchecksum(rsdp);
262
263}
264
265
266void *loadSSDTTable(int ssdt_number)
267{
268int fd = -1;
269char dirspec[512];
270char filename[512];
271const char * overriden_pathname=NULL;
272int len=0;
273
274// Check booting partition
275
276// Rek: if user specified a full path name then take it in consideration
277if (getValueForKey(kSSDT, &overriden_pathname, &len,
278 DEFAULT_BOOT_CONFIG))
279{
280sprintf(filename, "%s-%d.aml", overriden_pathname, ssdt_number); // start searching root
281}
282else
283sprintf(filename, "SSDT-%d.aml", ssdt_number);
284
285sprintf(dirspec, "/%s", filename); // start searching root
286
287fd=open (dirspec);
288
289if (fd<0)
290{// Check Extra on booting partition
291sprintf(dirspec,"/Extra/%s",filename);
292fd=open (dirspec);
293if (fd<0)
294{// Fall back to booter partition
295sprintf(dirspec,"bt(0,0)/Extra/%s",filename);
296fd=open (dirspec);
297if (fd<0)
298{
299DBG("SSDT Table not found: %s\n", filename);
300return NULL;
301}
302}
303}
304
305void *tableAddr=(void*)AllocateKernelMemory(file_size (fd));
306if (tableAddr)
307{
308if (read (fd, tableAddr, file_size (fd))!=file_size (fd))
309{
310printf("Couldn't read table %s\n",dirspec);
311free (tableAddr);
312close (fd);
313return NULL;
314}
315
316printf("Valid SSDT Table found: %s\n", filename);
317DBG("Table %s read and stored at: %x\n", dirspec, tableAddr);
318close (fd);
319return tableAddr;
320}
321
322printf("Couldn't allocate memory for table %s\n", dirspec);
323close (fd);
324
325return NULL;
326}
327
328void *loadACPITable(char *key)
329{
330int fd = -1;
331char dirspec[512];
332char filename[512];
333const char * overriden_pathname=NULL;
334int len=0;
335
336DBG("Searching for %s.aml file ...\n", key);
337// Check booting partition
338
339// Rek: if user specified a full path name then take it in consideration
340if (getValueForKey(key, &overriden_pathname, &len,
341 DEFAULT_BOOT_CONFIG))
342{
343sprintf(filename, "%s", overriden_pathname);
344}
345else
346sprintf(filename, "%s.aml", key);
347
348
349sprintf(dirspec, "/%s", filename); // start searching root
350
351fd=open (dirspec);
352
353if (fd<0)
354{
355// Check Extra on booting partition
356sprintf(dirspec,"/Extra/%s",filename);
357fd=open (dirspec);
358if (fd<0)
359{// Fall back to booter partition
360sprintf(dirspec,"bt(0,0)/Extra/%s",filename);
361fd=open (dirspec);
362if (fd<0)
363{
364DBG("ACPI Table not found: %s\n", key);
365return NULL;
366}
367
368}
369
370}
371
372void *tableAddr=(void*)AllocateKernelMemory(file_size (fd));
373if (tableAddr)
374{
375if (read (fd, tableAddr, file_size (fd))!=file_size (fd))
376{
377printf("Couldn't read table %s\n",key);
378free (tableAddr);
379close (fd);
380return NULL;
381}
382verbose("Valid ACPI Table found: %s\n", key);
383//DBG("Table %s read and stored at: %x\n", key, tableAddr);
384close (fd);
385return tableAddr;
386}
387
388printf("Couldn't allocate memory for table %s\n", key);
389close (fd);
390
391return NULL;
392}
393
394uint8_tacpi_cpu_count = 0;
395char* acpi_cpu_name[32];
396
397void get_acpi_cpu_names(unsigned char* dsdt, uint32_t length)
398{
399uint32_t i;
400
401for (i=0; i<length-7; i++)
402{
403if (dsdt[i] == 0x5B && dsdt[i+1] == 0x83) // ProcessorOP
404{
405uint32_t offset = i + 3 + (dsdt[i+2] >> 6);
406
407bool add_name = true;
408
409uint8_t j;
410
411for (j=0; j<4; j++)
412{
413char c = dsdt[offset+j];
414
415if (!aml_isvalidchar(c))
416{
417add_name = false;
418verbose("Invalid character found in ProcessorOP 0x%x!\n", c);
419break;
420}
421}
422
423if (add_name)
424{
425acpi_cpu_name[acpi_cpu_count] = malloc(4);
426memcpy(acpi_cpu_name[acpi_cpu_count], dsdt+offset, 4);
427i = offset + 5;
428
429verbose("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]);
430
431if (++acpi_cpu_count == 32) return;
432}
433}
434}
435}
436
437
438struct acpi_2_ssdt *generate_cst_ssdt(struct acpi_2_fadt* fadt)
439{
440char ssdt_header[] =
441{
4420x53, 0x53, 0x44, 0x54, 0xE7, 0x00, 0x00, 0x00, /* SSDT.... */
4430x01, 0x17, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x41, /* ..PmRefA */
4440x43, 0x70, 0x75, 0x43, 0x73, 0x74, 0x00, 0x00, /* CpuCst.. */
4450x00, 0x10, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* ....INTL */
4460x31, 0x03, 0x10, 0x20 /* 1.._*/
447};
448
449char cstate_resource_template[] =
450{
4510x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F,
4520x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
4530x00, 0x00, 0x00, 0x79, 0x00
454};
455
456if (get_env(envVendor) != CPUID_VENDOR_INTEL) {
457verbose ("Not an Intel platform: C-States will not be generated !!!\n");
458return NULL;
459}
460
461if (fadt == NULL) {
462verbose ("FACP not exists: C-States will not be generated !!!\n");
463return NULL;
464}
465
466struct acpi_2_dsdt* dsdt = (void*)fadt->DSDT;
467
468if (dsdt == NULL) {
469verbose ("DSDT not found: C-States will not be generated !!!\n");
470return NULL;
471}
472
473if (acpi_cpu_count == 0)
474get_acpi_cpu_names((void*)dsdt, dsdt->Length);
475
476if (acpi_cpu_count > 0)
477{
478bool c2_enabled = fadt->C2_Latency < 100;
479bool c3_enabled = fadt->C3_Latency < 1000;
480bool c4_enabled = false;
481
482getBoolForKey(kEnableC4State, &c4_enabled, DEFAULT_BOOT_CONFIG);
483
484unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + ((c3_enabled || c4_enabled) ? 1 : 0);
485char *Lat = NULL, *Pw = NULL, *tmpstr =NULL;
486int base = 16;
487TagPtr personality = XMLCastDict(XMLGetProperty(DEFAULT_BOOT_CONFIG_DICT, (const char*)"C-States"));
488
489if ((tmpstr = XMLCastString(XMLGetProperty(personality, (const char*)"Base")))) {
490
491int mybase = strtol(tmpstr, NULL, 10);
492
493if (mybase == 8 || mybase == 10 || mybase == 16 )
494base = mybase;
495}
496
497struct aml_chunk* root = aml_create_node(NULL);
498 aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header
499 struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");
500 struct aml_chunk* name = aml_add_name(scop, "CST_");
501 struct aml_chunk* pack = aml_add_package(name);
502 aml_add_byte(pack, cstates_count);
503
504 struct aml_chunk* tmpl = aml_add_package(pack);
505 TagPtr match_Status = XMLGetProperty(personality, (const char*)"C1");
506 if (match_Status) {
507 Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power"));
508 Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency"));
509 }
510 cstate_resource_template[11] = 0x00; // C1
511 aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
512 aml_add_byte(tmpl, 0x01); // C1
513 aml_add_byte(tmpl, (unsigned char)resolve_cst(0x01, Lat, base)); // Latency
514 aml_add_word(tmpl, resolve_cst(0x03e8, Pw, base)); // Power
515// C2
516if (c2_enabled)
517{
518tmpl = aml_add_package(pack);
519Lat = NULL;
520Pw = NULL;
521match_Status = XMLGetProperty(personality, (const char*)"C2");
522if (match_Status) {
523Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power"));
524Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency"));
525}
526
527cstate_resource_template[11] = 0x10; // C2
528aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
529aml_add_byte(tmpl, 0x02); // C2
530aml_add_word(tmpl, resolve_cst(fadt->C2_Latency, Lat, base)); // Latency
531aml_add_word(tmpl, resolve_cst(0x01f4, Pw, base)); // Power
532}
533
534// C4
535if (c4_enabled)
536{
537tmpl = aml_add_package(pack);
538Lat = NULL;
539Pw = NULL;
540match_Status = XMLGetProperty(personality, (const char*)"C4");
541if (match_Status) {
542Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power"));
543Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency"));
544}
545cstate_resource_template[11] = 0x30; // C4
546aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
547aml_add_byte(tmpl, 0x04); // C4
548aml_add_word(tmpl, resolve_cst(fadt->C3_Latency / 2, Lat, base)); // TODO: right latency for C4
549aml_add_word(tmpl, resolve_cst(0xfa, Pw, base)); // Power
550
551}
552// C3
553else if (c3_enabled)
554{
555tmpl = aml_add_package(pack);
556Lat = NULL;
557Pw = NULL;
558match_Status = XMLGetProperty(personality, (const char*)"C3");
559if (match_Status) {
560Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power"));
561Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency"));
562}
563cstate_resource_template[11] = 0x20; // C3
564aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
565aml_add_byte(tmpl, 0x03); // C3
566aml_add_word(tmpl, resolve_cst(fadt->C3_Latency , Lat, base));
567aml_add_word(tmpl, resolve_cst(0x015e, Pw, base)); // Power
568
569}
570
571
572 // Aliaces
573 int i;
574 for (i = 0; i < acpi_cpu_count; i++)
575 {
576 char name[9];
577 sprintf(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]);
578
579 scop = aml_add_scope(root, name);
580 aml_add_alias(scop, "CST_", "_CST");
581 }
582
583aml_calculate_size(root);
584
585struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);
586
587aml_write_node(root, (void*)ssdt, 0);
588
589ssdt->Length = root->Size;
590
591setchecksum((struct acpi_common_header *)ssdt);
592
593aml_destroy_node(root);
594
595verbose ("SSDT with CPU C-States generated successfully\n");
596
597return ssdt;
598}
599else
600{
601verbose ("ACPI CPUs not found: C-States not generated !!!\n");
602}
603
604return NULL;
605}
606
607struct acpi_2_ssdt *generate_pss_ssdt(struct acpi_2_dsdt* dsdt)
608{
609
610char ssdt_header[] =
611{
6120x53, 0x53, 0x44, 0x54, 0x7E, 0x00, 0x00, 0x00, /* SSDT.... */
6130x01, 0x6A, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x00, /* ..PmRef. */
6140x43, 0x70, 0x75, 0x50, 0x6D, 0x00, 0x00, 0x00, /* CpuPm... */
6150x00, 0x30, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* .0..INTL */
6160x31, 0x03, 0x10, 0x20,/* 1.._*/
617};
618
619if (get_env(envVendor) != CPUID_VENDOR_INTEL) {
620verbose ("Not an Intel platform: P-States will not be generated !!!\n");
621return NULL;
622}
623
624if (!(get_env(envFeatures) & CPUID_FEATURE_MSR)) {
625verbose ("Unsupported CPU: P-States will not be generated !!!\n");
626return NULL;
627}
628
629if (acpi_cpu_count == 0)
630get_acpi_cpu_names((void*)dsdt, dsdt->Length);
631
632if (acpi_cpu_count > 0)
633{
634struct p_state initial, maximum, minimum, p_states[32];
635uint8_t p_states_count = 0;
636
637// Retrieving P-States, ported from code by superhai (c)
638switch (get_env(envFamily)) {
639case 0x06:
640{
641switch (get_env(envModel))
642{
643case CPUID_MODEL_DOTHAN: // ?
644case CPUID_MODEL_YONAH: // Yonah
645case CPUID_MODEL_MEROM: // Merom
646case CPUID_MODEL_PENRYN: // Penryn
647case CPUID_MODEL_ATOM: // Intel Atom (45nm)
648{
649bool cpu_dynamic_fsb = false;
650
651if (rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 27))
652{
653wrmsr64(MSR_IA32_EXT_CONFIG, (rdmsr64(MSR_IA32_EXT_CONFIG) | (1 << 28)));
654delay(1);
655cpu_dynamic_fsb = rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 28);
656}
657
658bool cpu_noninteger_bus_ratio = (rdmsr64(MSR_IA32_PERF_STATUS) & (1ULL << 46));
659
660initial.Control = rdmsr64(MSR_IA32_PERF_STATUS);
661
662maximum.Control = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 32) & 0x1F3F) | (0x4000 * cpu_noninteger_bus_ratio);
663maximum.CID = ((maximum.FID & 0x1F) << 1) | cpu_noninteger_bus_ratio;
664
665minimum.FID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 24) & 0x1F) | (0x80 * cpu_dynamic_fsb);
666minimum.VID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 48) & 0x3F);
667
668if (minimum.FID == 0)
669{
670uint64_t msr;
671uint8_t i;
672// Probe for lowest fid
673for (i = maximum.FID; i >= 0x6; i--)
674{
675msr = rdmsr64(MSR_IA32_PERF_CONTROL);
676wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (i << 8) | minimum.VID);
677intel_waitforsts();
678minimum.FID = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0x1F;
679delay(1);
680}
681
682msr = rdmsr64(MSR_IA32_PERF_CONTROL);
683wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);
684intel_waitforsts();
685}
686
687if (minimum.VID == maximum.VID)
688{
689uint64_t msr;
690uint8_t i;
691// Probe for lowest vid
692for (i = maximum.VID; i > 0xA; i--)
693{
694msr = rdmsr64(MSR_IA32_PERF_CONTROL);
695wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (minimum.FID << 8) | i);
696intel_waitforsts();
697minimum.VID = rdmsr64(MSR_IA32_PERF_STATUS) & 0x3F;
698delay(1);
699}
700
701msr = rdmsr64(MSR_IA32_PERF_CONTROL);
702wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);
703intel_waitforsts();
704}
705
706minimum.CID = ((minimum.FID & 0x1F) << 1) >> cpu_dynamic_fsb;
707
708// Sanity check
709if (maximum.CID < minimum.CID)
710{
711DBG("Insane FID values!");
712p_states_count = 0;
713}
714else
715{
716// Finalize P-States
717// Find how many P-States machine supports
718p_states_count = maximum.CID - minimum.CID + 1;
719
720if (p_states_count > 32)
721p_states_count = 32;
722
723uint8_t vidstep;
724uint8_t i = 0, u, invalid = 0;
725
726vidstep = ((maximum.VID << 2) - (minimum.VID << 2)) / (p_states_count - 1);
727
728 uint32_t fsb = (uint32_t)get_env(envFSBFreq) / 1000000;
729
730for (u = 0; u < p_states_count; u++)
731{
732i = u - invalid;
733
734p_states[i].CID = maximum.CID - u;
735p_states[i].FID = (p_states[i].CID >> 1);
736
737if (p_states[i].FID < 0x6)
738{
739if (cpu_dynamic_fsb)
740p_states[i].FID = (p_states[i].FID << 1) | 0x80;
741}
742else if (cpu_noninteger_bus_ratio)
743{
744p_states[i].FID = p_states[i].FID | (0x40 * (p_states[i].CID & 0x1));
745}
746
747if (i && p_states[i].FID == p_states[i-1].FID)
748invalid++;
749
750p_states[i].VID = ((maximum.VID << 2) - (vidstep * u)) >> 2;
751
752uint32_t multiplier = p_states[i].FID & 0x1f;// = 0x08
753bool half = p_states[i].FID & 0x40;// = 0x01
754bool dfsb = p_states[i].FID & 0x80;// = 0x00
755//uint32_t fsb = Platform->CPU.FSBFrequency / 1000000; // = 400
756uint32_t halffsb = (fsb + 1) >> 1;// = 200
757uint32_t frequency = (multiplier * fsb);// = 3200
758
759p_states[i].Frequency = (frequency + (half * halffsb)) >> dfsb;// = 3200 + 200 = 3400
760}
761
762p_states_count -= invalid;
763}
764break;
765}
766case CPUID_MODEL_FIELDS:
767case CPUID_MODEL_DALES:
768case CPUID_MODEL_DALES_32NM:
769case CPUID_MODEL_NEHALEM:
770case CPUID_MODEL_NEHALEM_EX:
771case CPUID_MODEL_WESTMERE:
772case CPUID_MODEL_WESTMERE_EX:
773case CPUID_MODEL_SANDYBRIDGE:
774 case CPUID_MODEL_JAKETOWN:
775{
776maximum.Control = rdmsr64(MSR_IA32_PERF_STATUS) & 0xff; // Seems it always contains maximum multiplier value (with turbo, that's we need)...
777minimum.Control = (rdmsr64(MSR_PLATFORM_INFO) >> 40) & 0xff;
778
779verbose("P-States: min 0x%x, max 0x%x\n", minimum.Control, maximum.Control);
780
781// Sanity check
782if (maximum.Control < minimum.Control)
783{
784DBG("Insane control values!");
785p_states_count = 0;
786}
787else
788{
789uint8_t i;
790p_states_count = 0;
791uint64_t fsb = (get_env(envFSBFreq) / 1000000);
792for (i = maximum.Control; i >= minimum.Control; i--)
793{
794p_states[p_states_count].Control = i;
795p_states[p_states_count].CID = p_states[p_states_count].Control << 1;
796p_states[p_states_count].Frequency = (uint32_t) fsb * i;
797p_states_count++;
798}
799}
800
801break;
802}
803default:
804verbose ("Unsupported CPU: P-States not generated !!!\n");
805break;
806}
807}
808default:
809break;
810}
811
812// Generating SSDT
813if (p_states_count)
814{
815int i;
816
817struct aml_chunk* root = aml_create_node(NULL);
818 aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header
819 struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");
820 struct aml_chunk* name = aml_add_name(scop, "PSS_");
821 struct aml_chunk* pack = aml_add_package(name);
822
823 uint64_t FSBFreq = get_env(envFSBFreq);
824
825 uint8_t minPSratio = (p_states[p_states_count-1].Frequency / (FSBFreq / 10000000 ));
826 uint8_t maxPSratio = (p_states[0].Frequency / (FSBFreq / 10000000 ));
827
828 uint8_t cpu_div = (uint8_t)get_env(envCurrDiv);
829 uint8_t cpu_coef = (uint8_t)get_env(envCurrCoef);
830
831 uint8_t cpu_ratio = 0;
832
833 if (cpu_div)
834 cpu_ratio = (cpu_coef * 10) + 5;
835 else
836 cpu_ratio = cpu_coef * 10;
837
838
839 int user_max_ratio = 0;
840 getIntForKey(kMaxRatio, &user_max_ratio, DEFAULT_BOOT_CONFIG);
841 if (user_max_ratio >= minPSratio && maxPSratio >= user_max_ratio) {
842
843 uint8_t maxcurrdiv = 0, maxcurrcoef = (int)(user_max_ratio / 10);
844
845 uint8_t maxdiv = user_max_ratio - (maxcurrcoef * 10);
846 if (maxdiv > 0)
847 maxcurrdiv = 1;
848
849 if (maxcurrdiv)
850 cpu_ratio = (maxcurrcoef * 10) + 5;
851 else
852 cpu_ratio = maxcurrcoef * 10;
853 }
854
855 int user_min_ratio = 0;
856 getIntForKey(kMinRatio, &user_min_ratio, DEFAULT_BOOT_CONFIG);
857 if (user_min_ratio >= minPSratio && cpu_ratio >= user_min_ratio) {
858
859 uint8_t mincurrdiv = 0, mincurrcoef = (int)(user_min_ratio / 10);
860
861 uint8_t mindiv = user_min_ratio - (mincurrcoef * 10);
862
863 if (mindiv > 0)
864 mincurrdiv = 1;
865
866 if (mincurrdiv)
867 minPSratio = (mincurrcoef * 10) + 5;
868 else
869 minPSratio = mincurrcoef * 10;
870
871 }
872
873 if (maxPSratio >= cpu_ratio && cpu_ratio >= minPSratio)maxPSratio = cpu_ratio;
874
875 TagPtr personality = XMLCastDict(XMLGetProperty(DEFAULT_BOOT_CONFIG_DICT, (const char*)"P-States"));
876 char* MatchStat = 0;
877 int dropPSS = 0, Pstatus = 0, base = 16;
878 int expert = 0;/* Default: 0 , mean mixed mode | expert mode : 1 , mean add only p-states found in boot.plist*/
879 char *tmpstr = XMLCastString(XMLGetProperty(personality, (const char*)"Mode"));
880
881 if (strcmp(tmpstr,"Expert") == 0) {
882 p_states_count = (XMLTagCount(personality)) - 1 ; // - 1 = - ("Mode" tag)
883 expert = 1;
884 }
885
886
887 if ((tmpstr = XMLCastString(XMLGetProperty(personality, (const char*)"Base")))) {
888
889 if (expert) p_states_count--; // -= ("Base" tag)
890
891 int mybase = strtol(tmpstr, NULL, 10);
892
893 if (mybase == 8 || mybase == 10 || mybase == 16 )
894 base = mybase;
895 }
896
897 uint64_t fsb = (get_env(envFSBFreq) / 10000000 );
898
899 for (i = 0; i < p_states_count; i++)
900 {
901 sprintf(MatchStat, "%d",i);
902 TagPtr match_Status = XMLGetProperty(personality, (const char*)MatchStat);
903
904 char *Lat1 = NULL, *clk = NULL, *Pw = NULL, *Lat2 = NULL, *Ctrl = NULL ;
905
906 if (match_Status) {
907
908 clk = XMLCastString(XMLGetProperty(match_Status, (const char*)"CoreFreq"));
909 Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power"));
910 Lat1 = XMLCastString(XMLGetProperty(match_Status, (const char*)"Transition Latency"));
911 Lat2 = XMLCastString(XMLGetProperty(match_Status, (const char*)"Bus Master Latency"));
912 Ctrl = XMLCastString(XMLGetProperty(match_Status, (const char*)"Control"));
913
914
915 } else if (expert)
916 continue;
917
918
919 unsigned long Frequency = 0x00000000;
920
921 if (!expert) Frequency = p_states[i].Frequency;
922
923 if (clk)
924 Frequency = strtoul((const char *)clk, NULL,base);
925
926 if (!Frequency || Frequency > p_states[0].Frequency ) continue;
927
928 uint8_t curr_ratio = (uint8_t)(Frequency / fsb);
929
930 if (curr_ratio > maxPSratio || minPSratio > curr_ratio)
931 goto dropPstate;
932
933 struct aml_chunk* pstt = aml_add_package(pack);
934 aml_add_dword(pstt, Frequency); // CoreFreq (in MHz).
935 aml_add_dword(pstt, resolve_pss(0x00000000, Pw, base)); // Power (in milliWatts)
936 aml_add_dword(pstt, resolve_pss(0x0000000A, Lat1, base)); // Transition Latency (in microseconds).
937 aml_add_dword(pstt, resolve_pss(0x0000000A, Lat2, base)); // Bus Master Latency (in microseconds).
938 unsigned long Control = 0x00000000;
939 if (!expert) Control = p_states[i].Control;
940 aml_add_dword(pstt, resolve_pss(Control, Ctrl, base)); // Control
941 Pstatus++;
942 aml_add_dword(pstt, Pstatus); // Status
943 continue;
944 dropPstate:
945#if DEBUG_ACPI
946 verbose("state with cpu frequency :%d and ratio :%d will be dropped\n",p_states[i].Frequency,curr_ratio);
947#endif
948 dropPSS++;
949
950
951 }
952
953// Add aliaces
954for (i = 0; i < acpi_cpu_count; i++)
955{
956char name[9];
957sprintf(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]);
958
959scop = aml_add_scope(root, name);
960aml_add_alias(scop, "PSS_", "_PSS");
961}
962
963aml_calculate_size(root);
964
965struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);
966
967aml_write_node(root, (void*)ssdt, 0);
968
969ssdt->Length = root->Size;
970
971 setchecksum((struct acpi_common_header *)ssdt);
972
973aml_destroy_node(root);
974
975verbose ("SSDT with CPU P-States generated successfully");
976
977if (dropPSS)
978 verbose(", %d P-state(s) dropped",dropPSS);
979
980verbose("\n");
981
982return ssdt;
983}
984}
985else
986{
987verbose("ACPI CPUs not found: P-States not generated !!!\n");
988}
989
990return NULL;
991}
992
993
994struct acpi_2_gas FillGASStruct(uint32_t Address, uint8_t Length)
995{
996struct acpi_2_gas TmpGAS;
997
998TmpGAS.Address_Space_ID = 1; /* I/O Address */
999
1000if (Address == 0)
1001{
1002TmpGAS.Register_Bit_Width = 0;
1003} else {
1004TmpGAS.Register_Bit_Width = Length * 8;
1005}
1006
1007TmpGAS.Register_Bit_Offset = 0;
1008TmpGAS.Access_Size = 0; /* Not set for Legacy reasons... */
1009TmpGAS.Address = (uint64_t)Address;
1010
1011return(TmpGAS);
1012}
1013
1014struct acpi_2_fadt *
1015patch_fadt(struct acpi_2_fadt *fadt, struct acpi_2_dsdt *new_dsdt, bool UpdateFADT)
1016{
1017
1018struct acpi_2_fadt *fadt_mod;
1019struct acpi_2_fadt *fadt_file = (struct acpi_2_fadt *)loadACPITable(kFADT);
1020bool fadt_rev2_needed = false;
1021bool fix_restart = false;
1022const char * value;
1023bool aspmOff = true;
1024bool msiOff = true;
1025
1026// Restart Fix
1027if (get_env(envVendor) == CPUID_VENDOR_INTEL) {/* Intel */
1028fix_restart = true;
1029getBoolForKey(kRestartFix, &fix_restart, DEFAULT_BOOT_CONFIG);
1030
1031} else {
1032verbose ("Not an Intel platform: Restart Fix not applied !!!\n");
1033}
1034
1035if (fix_restart)
1036fadt_rev2_needed = true;
1037
1038// Allocate new fadt table
1039if ((UpdateFADT) && (((fadt_file) && (fadt_file->Length < sizeof(struct acpi_2_fadt))) ||
1040 ((!fadt_file) && (fadt->Length < sizeof(struct acpi_2_fadt)))))
1041{
1042 getBoolForKey(kDisableMSI, &msiOff, DEFAULT_BOOT_CONFIG) ;
1043 getBoolForKey(kDisableASPM, &aspmOff, DEFAULT_BOOT_CONFIG);
1044
1045if (fadt_file)
1046{
1047if (fadt_file->Length < 0xF4)
1048{
1049fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0xF4);
1050memcpy(fadt_mod, fadt_file, fadt_file->Length);
1051fadt_mod->Length = 0xF4;
1052}
1053else
1054{
1055
1056fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt_file->Length);
1057memcpy(fadt_mod, fadt_file, fadt_file->Length);
1058}
1059}
1060else
1061{
1062if (fadt->Length < 0xF4)
1063{
1064fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0xF4);
1065memcpy(fadt_mod, fadt, fadt->Length);
1066fadt_mod->Length = 0xF4;
1067}
1068else
1069{
1070
1071fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length);
1072memcpy(fadt_mod, fadt, fadt->Length);
1073}
1074}
1075
1076fadt_mod->Revision = 0x04; // FADT rev 4
1077fadt_mod->RESET_REG = FillGASStruct(0, 0);
1078fadt_mod->Reset_Value = 0;
1079fadt_mod->Reserved[0] = 0;
1080fadt_mod->Reserved[1] = 0;
1081fadt_mod->Reserved[2] = 0;
1082
1083fadt_mod->X_PM1a_EVT_BLK = FillGASStruct(fadt_mod->PM1A_Event_Block_Address, fadt_mod->PM1_Event_Block_Length);
1084fadt_mod->X_PM1b_EVT_BLK = FillGASStruct(fadt_mod->PM1B_Event_Block_Address, fadt_mod->PM1_Event_Block_Length);
1085fadt_mod->X_PM1a_CNT_BLK = FillGASStruct(fadt_mod->PM1A_Control_Block_Address, fadt_mod->PM1_Control_Block_Length);
1086fadt_mod->X_PM1b_CNT_BLK = FillGASStruct(fadt_mod->PM1B_Control_Block_Address, fadt_mod->PM1_Control_Block_Length);
1087fadt_mod->X_PM2_CNT_BLK = FillGASStruct(fadt_mod->PM2_Control_Block_Address, fadt_mod->PM2_Control_Block_Length);
1088fadt_mod->X_PM_TMR_BLK = FillGASStruct(fadt_mod->PM_Timer_Block_Address, fadt_mod->PM_Timer_Block_Length);
1089fadt_mod->X_GPE0_BLK = FillGASStruct(fadt_mod->GPE0_Block_Address, fadt_mod->GPE0_Block_Length);
1090fadt_mod->X_GPE1_BLK = FillGASStruct(fadt_mod->GPE1_Block_Address, fadt_mod->GPE1_Block_Length);
1091
1092verbose("Converted ACPI V%d FADT to ACPI V4 FADT\n", (fadt) ? fadt->Revision : fadt->Revision);
1093} else {
1094
1095if (fadt_file) {
1096if (fadt_file->Length < 0x84 && fadt_rev2_needed)
1097{
1098fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84);
1099memcpy(fadt_mod, fadt_file, fadt_file->Length);
1100fadt_mod->Length = 0x84;
1101fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions)
1102} else {
1103fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt_file->Length);
1104memcpy(fadt_mod, fadt_file, fadt_file->Length);
1105}
1106
1107} else {
1108if (fadt->Length < 0x84 && fadt_rev2_needed)
1109{
1110fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84);
1111memcpy(fadt_mod, fadt, fadt->Length);
1112fadt_mod->Length = 0x84;
1113fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions)
1114} else {
1115fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length);
1116memcpy(fadt_mod, fadt, fadt->Length);
1117}
1118
1119}
1120
1121}
1122
1123uint8_t Type = PMProfileError;
1124// Determine system type / PM_Model
1125
1126// Fix System-type if needed (should never happen)
1127if (get_env(envType) > MaxSupportedPMProfile)
1128{
1129if(fadt_mod->PM_Profile <= MaxSupportedPMProfile)
1130safe_set_env(envType,fadt_mod->PM_Profile); // get the fadt if correct
1131else
1132safe_set_env(envType, 1);/* Set a fixed value (Desktop) */
1133}
1134
1135// If needed, set System-type from PM_Profile (if valid) else set PM_Profile with a fixed the System-type
1136// Give prior to the FADT pm profile, allow to also control this value with a patched FADT table
1137if (fadt_mod->PM_Profile != get_env(envType))
1138{
1139bool val = false;
1140getBoolForKey("PreferInternalProfileDetect", &val, DEFAULT_BOOT_CONFIG); // if true Give prior to the profile resolved trought the CPU model
1141
1142val = get_env(envIsServer) ;
1143
1144if (fadt_mod->PM_Profile <= MaxSupportedPMProfile && !val) {
1145safe_set_env(envType, fadt_mod->PM_Profile);
1146} else {
1147fadt_mod->PM_Profile = (uint8_t)get_env(envType);
1148}
1149
1150}
1151
1152// Set PM_Profile and System-type if user wanted this value to be forced
1153if ( (value=getStringForKey("SystemType", DEFAULT_BOOT_CONFIG))!=NULL) {
1154if ((Type = (unsigned char) strtoul(value, NULL, 10) ) <= MaxSupportedPMProfile)
1155{
1156verbose("FADT: changing Preferred_PM_Profile from 0x%02x to 0x%02x\n", fadt->PM_Profile, Type);
1157 safe_set_env(envType,(fadt_mod->PM_Profile = Type));
1158} else verbose("Error: system-type must be 0..6. Defaulting to %d !\n", (uint8_t)get_env(envType));
1159}
1160
1161// Patch FADT to fix restart
1162if (fix_restart)
1163{
1164 fadt_mod->Flags|= 0x400;
1165
1166fadt_mod->RESET_REG = FillGASStruct(0x0cf9, 1);
1167fadt_mod->Reset_Value = 0x06;
1168verbose("FADT: Restart Fix applied !\n");
1169}
1170
1171
1172if (aspmOff) {
1173fadt_mod->Boot_Flags |= 1 << 4;
1174} else {
1175fadt_mod->Boot_Flags &= 0xFFEF;
1176
1177}
1178
1179if (msiOff) {
1180fadt_mod->Boot_Flags |= 1 << 3;
1181} else {
1182fadt_mod->Boot_Flags &= 0xFFF7;
1183}
1184
1185fadt_mod->FIRMWARE_CTRL=(uint32_t)fadt->FIRMWARE_CTRL;
1186if ((uint32_t)(&(fadt_mod->X_FIRMWARE_CTRL))-(uint32_t)fadt_mod+8<=fadt_mod->Length)
1187fadt_mod->X_FIRMWARE_CTRL=(uint32_t)fadt->FIRMWARE_CTRL;
1188
1189
1190 safe_set_env(envHardwareSignature,((struct acpi_2_facs *)fadt->FIRMWARE_CTRL)->hardware_signature);
1191
1192DBG("setting hardware_signature to %x \n",(uint32_t)get_env(envHardwareSignature));
1193
1194// Patch DSDT Address if we have loaded a DSDT table
1195if(new_dsdt)
1196{
1197
1198fadt_mod->DSDT=(uint32_t)new_dsdt;
1199if ((uint32_t)(&(fadt_mod->X_DSDT))-(uint32_t)fadt_mod+8<=fadt_mod->Length)
1200fadt_mod->X_DSDT=(uint32_t)new_dsdt;
1201
1202}
1203
1204// Correct the checksum
1205 setchecksum((struct acpi_common_header *)fadt_mod);
1206
1207return fadt_mod;
1208}
1209
1210
1211/* Setup ACPI */
1212EFI_STATUS setupAcpi(void)
1213{
1214int version;
1215 EFI_STATUS Status = EFI_ABORTED;
1216void *new_dsdt=NULL, *new_hpet=NULL, *new_sbst=NULL, *new_ecdt=NULL, *new_asft=NULL, *new_dmar=NULL, *new_apic=NULL, *new_mcfg=NULL, *new_ssdts[14];
1217
1218struct acpi_2_ssdt *new_ssdt[17]; // 15 + 2 additional tables for pss & cst
1219struct acpi_2_fadt *fadt; // will be used in CST generator
1220struct acpi_2_fadt *fadt_mod=NULL;
1221bool oem_dsdt=false, oem_ssdt=false, oem_hpet=false, oem_sbst=false, oem_ecdt=false, oem_asft=false, oem_dmar=false, oem_apic=false, oem_mcfg=false;
1222bool update_acpi=false, gen_xsdt=false;
1223bool hpet_replaced=false, sbst_replaced=false, ecdt_replaced=false, asft_replaced=false, dmar_replaced=false, apic_replaced=false, mcfg_replaced=false;
1224bool hpet_added=false, sbst_added=false, ecdt_added=false, asft_added=false, dmar_added=false, apic_added=false, mcfg_added=false;
1225bool gen_csta=false, gen_psta=false, speed_step=false;
1226
1227bool quick_ssdt= false;
1228// Quick ssdt search,
1229// first try to find ssdt-0.aml, if the file do not exist we
1230// stop searching here, else ssdt-0.aml is loaded and we try
1231// to find ssdt-1.aml, etc .........
1232
1233int curssdt=0, loadtotssdt=0, totssdt=0, newtotssdt=0;
1234
1235{
1236bool tmpval;
1237
1238oem_dsdt=getBoolForKey(kOEMDSDT, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1239oem_ssdt=getBoolForKey(kOEMSSDT, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1240oem_hpet=getBoolForKey(kOEMHPET, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1241oem_sbst=getBoolForKey(kOEMSBST, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1242oem_ecdt=getBoolForKey(kOEMECDT, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1243oem_asft=getBoolForKey(kOEMASFT, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1244oem_dmar=getBoolForKey(kOEMDMAR, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1245oem_apic=getBoolForKey(kOEMAPIC, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1246oem_mcfg=getBoolForKey(kOEMMCFG, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1247
1248gen_csta=getBoolForKey(kGenerateCStates, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1249gen_psta=getBoolForKey(kGeneratePStates, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1250
1251update_acpi=getBoolForKey(kUpdateACPI, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1252
1253quick_ssdt=getBoolForKey(kQSSDT, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1254
1255speed_step=getBoolForKey(kSpeedstep, &tmpval, DEFAULT_BOOT_CONFIG)&&tmpval;
1256
1257}
1258
1259if (speed_step) {
1260gen_psta= true;
1261gen_csta= true;
1262}
1263
1264
1265// Load replacement ACPI tables
1266if (!oem_dsdt)
1267new_dsdt=loadACPITable(kDSDT);
1268
1269
1270if (!oem_hpet)
1271new_hpet=loadACPITable(kHPET);
1272
1273
1274if (!oem_sbst)
1275new_sbst=loadACPITable(kSBST);
1276
1277
1278if (!oem_ecdt)
1279new_ecdt=loadACPITable(kECDT);
1280
1281
1282if (!oem_asft)
1283new_asft=loadACPITable(kASFT);
1284
1285
1286if (!oem_dmar)
1287new_dmar=loadACPITable(kDMAR);
1288
1289
1290if (!oem_apic)
1291new_apic=loadACPITable(kAPIC);
1292
1293
1294if (!oem_mcfg)
1295new_mcfg=loadACPITable(kMCFG);
1296
1297if (!oem_ssdt)
1298{
1299
1300for (curssdt=0;curssdt<15;curssdt++)
1301{
1302new_ssdt[curssdt]=loadSSDTTable(curssdt);
1303
1304if (new_ssdt[curssdt])
1305loadtotssdt++;
1306else if (quick_ssdt)
1307break;
1308
1309}
1310
1311curssdt=0;
1312
1313}
1314
1315DBG("New ACPI tables Loaded in memory\n");
1316TagPtr DropTables_p = XMLCastDict(XMLGetProperty(DEFAULT_BOOT_CONFIG_DICT, (const char*)"ACPIDropTables"));
1317// Do the same procedure for both versions of ACPI
1318for (version=0; version<2; version++) {
1319struct acpi_2_rsdp *rsdp_mod, *rsdp_conv=(struct acpi_2_rsdp *)0;
1320struct acpi_2_rsdt *rsdt, *rsdt_mod;
1321struct acpi_2_xsdt *xsdt_conv = (struct acpi_2_xsdt *)0;
1322int rsdplength;
1323
1324// Find original rsdp
1325 struct acpi_2_rsdp *rsdp=(struct acpi_2_rsdp *)(version?biosacpi_find_rsdp(2):biosacpi_find_rsdp(0));
1326
1327if ((update_acpi) && (rsdp->Revision == 0))
1328{
1329
1330rsdp_conv = gen_rsdp_v2_from_v1(rsdp);
1331gen_xsdt = true;
1332version = 1;
1333
1334addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI");
1335
1336verbose("Converted ACPI RSD PTR version 1 to version 3\n");
1337}
1338
1339if (!rsdp)
1340{
1341DBG("No ACPI version %d found. Ignoring\n", version+1);
1342if (version)
1343addConfigurationTable(&gEfiAcpi20TableGuid, NULL, "ACPI_20");
1344else
1345addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI");
1346continue;
1347}
1348rsdplength=version?rsdp->Length:20;
1349
1350DBG("RSDP version %d found @%x. Length=%d\n",version+1,rsdp,rsdplength);
1351
1352/* FIXME: no check that memory allocation succeeded
1353 * Copy and patch RSDP,RSDT, XSDT and FADT
1354 * For more info see ACPI Specification pages 110 and following
1355 */
1356
1357if (gen_xsdt)
1358{
1359rsdp_mod=rsdp_conv;
1360} else {
1361rsdp_mod=(struct acpi_2_rsdp *) AllocateKernelMemory(rsdplength);
1362memcpy(rsdp_mod, rsdp, rsdplength);
1363}
1364
1365rsdt=(struct acpi_2_rsdt *)(rsdp->RsdtAddress);
1366
1367DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length);
1368
1369if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000)
1370{
1371int dropoffset=0, i;
1372
1373rsdt_mod=(struct acpi_2_rsdt *)AllocateKernelMemory(rsdt->Length);
1374memcpy (rsdt_mod, rsdt, rsdt->Length);
1375
1376 update_rsdp_with_rsdt(rsdp_mod, rsdt_mod);
1377
1378int rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4;
1379uint32_t *rsdt_entries=(uint32_t *)(rsdt_mod+1);
1380
1381if (gen_xsdt)
1382{
1383
1384 xsdt_conv=gen_xsdt_from_rsdt(rsdt_mod);
1385 update_rsdp_with_xsdt(rsdp, xsdt_conv);
1386
1387
1388verbose("Converted RSDT table to XSDT table\n");
1389}
1390
1391for (i=0;i<rsdt_entries_num;i++)
1392{
1393char *table=(char *)(rsdt_entries[i]);
1394if (!table)
1395continue;
1396
1397DBG("TABLE %c%c%c%c,",table[0],table[1],table[2],table[3]);
1398
1399rsdt_entries[i-dropoffset]=rsdt_entries[i];
1400
1401char table4[5];
1402strlcpy(table4, table, sizeof(table4));
1403TagPtr match_drop = XMLGetProperty(DropTables_p, (const char*)table4);
1404if ( match_drop ) {
1405char *tmpstr = XMLCastString(match_drop);
1406if (strcmp(tmpstr,"No") != 0) {
1407dropoffset++;
1408DBG("%s table dropped\n",table4);
1409continue;
1410}
1411}
1412
1413if ((!(oem_hpet)) && tableSign(table, "HPET"))
1414{
1415DBG("HPET found\n");
1416if (new_hpet)
1417{
1418rsdt_entries[i-dropoffset]=(uint32_t)new_hpet;
1419hpet_replaced=true;
1420}
1421continue;
1422}
1423
1424if ((!(oem_sbst)) && tableSign(table, "SBST"))
1425{
1426DBG("SBST found\n");
1427if (new_sbst)
1428{
1429rsdt_entries[i-dropoffset]=(uint32_t)new_sbst;
1430sbst_replaced=true;
1431}
1432continue;
1433}
1434
1435if ((!(oem_ecdt)) && tableSign(table, "ECDT"))
1436{
1437DBG("ECDT found\n");
1438
1439if (new_ecdt)
1440{
1441rsdt_entries[i-dropoffset]=(uint32_t)new_ecdt;
1442ecdt_replaced=true;
1443}
1444
1445continue;
1446}
1447
1448if ((!(oem_asft)) && tableSign(table, "ASF!"))
1449{
1450DBG("ASF! found\n");
1451if (new_asft)
1452{
1453rsdt_entries[i-dropoffset]=(uint32_t)new_asft;
1454asft_replaced=true;
1455}
1456continue;
1457}
1458
1459if ((!(oem_dmar)) && tableSign(table, "DMAR"))
1460{
1461DBG("DMAR found\n");
1462if (new_dmar)
1463{
1464rsdt_entries[i-dropoffset]=(uint32_t)new_dmar;
1465dmar_replaced=true;
1466}
1467continue;
1468}
1469
1470if ((!(oem_apic)) && tableSign(table, "APIC"))
1471{
1472DBG("APIC found\n");
1473if (new_apic)
1474{
1475rsdt_entries[i-dropoffset]=(uint32_t)new_apic;
1476apic_replaced=true;
1477}
1478continue;
1479}
1480
1481if ((!(oem_mcfg)) && tableSign(table, "MCFG"))
1482{
1483DBG("MCFG found\n");
1484if (new_mcfg)
1485{
1486rsdt_entries[i-dropoffset]=(uint32_t)new_mcfg;
1487mcfg_replaced=true;
1488}
1489continue;
1490}
1491
1492if ((!(oem_ssdt)) && tableSign(table, "SSDT"))
1493{
1494DBG("SSDT %d found", curssdt);
1495if (new_ssdts[curssdt])
1496{
1497DBG(" and replaced");
1498rsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt];
1499totssdt++;
1500}
1501DBG("\n");
1502curssdt++;
1503continue;
1504}
1505
1506if ((!(oem_dsdt)) && tableSign(table, "DSDT"))
1507{
1508DBG("DSDT found\n");
1509rsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;
1510continue;
1511}
1512
1513if (tableSign(table, "FACP"))
1514{
1515fadt=(struct acpi_2_fadt *)rsdt_entries[i];
1516
1517DBG("FADT found @%x, Length %d\n",fadt, fadt->Length);
1518
1519if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000)
1520{
1521printf("FADT incorrect. Not modified\n");
1522continue;
1523}
1524verbose("Attempting to patch FADT entry of RSDT\n");
1525fadt_mod = patch_fadt(fadt, new_dsdt, update_acpi);
1526
1527rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;
1528
1529if (!oem_ssdt)
1530{
1531// Generate _CST SSDT
1532if ( gen_csta && (new_ssdt[loadtotssdt] = generate_cst_ssdt(fadt_mod)))
1533{
1534gen_csta= false;
1535loadtotssdt++;
1536}
1537
1538// Generating _PSS SSDT
1539 if (gen_psta && (new_ssdt[loadtotssdt] = generate_pss_ssdt((void*)fadt_mod->DSDT)))
1540 {
1541 gen_psta= false;
1542 loadtotssdt++;
1543 }
1544
1545}
1546
1547continue;
1548}
1549}
1550DBG("\n");
1551
1552if ((!oem_hpet) && (!hpet_replaced))
1553{
1554if (new_hpet)
1555{
1556rsdt_entries[i-dropoffset]=(uint32_t)new_hpet;
1557hpet_added=true;
1558i++;
1559}
1560}
1561
1562if ((!oem_sbst) && (!sbst_replaced))
1563{
1564if (new_sbst)
1565{
1566rsdt_entries[i-dropoffset]=(uint32_t)new_sbst;
1567sbst_added=true;
1568i++;
1569}
1570}
1571
1572if ((!oem_ecdt) && (!ecdt_replaced))
1573{
1574if (new_ecdt)
1575{
1576rsdt_entries[i-dropoffset]=(uint32_t)new_ecdt;
1577ecdt_added=true;
1578i++;
1579}
1580}
1581
1582if ((!oem_asft) && (!asft_replaced))
1583{
1584if (new_asft)
1585{
1586rsdt_entries[i-dropoffset]=(uint32_t)new_asft;
1587asft_added=true;
1588i++;
1589}
1590}
1591
1592if ((!oem_dmar) && (!dmar_replaced))
1593{
1594if (new_dmar)
1595{
1596rsdt_entries[i-dropoffset]=(uint32_t)new_dmar;
1597dmar_added=true;
1598i++;
1599}
1600}
1601
1602if ((!oem_apic) && (!apic_replaced))
1603{
1604if (new_apic)
1605{
1606rsdt_entries[i-dropoffset]=(uint32_t)new_apic;
1607apic_added=true;
1608i++;
1609}
1610}
1611
1612if ((!oem_mcfg) && (!mcfg_replaced))
1613{
1614if (new_mcfg)
1615{
1616rsdt_entries[i-dropoffset]=(uint32_t)new_mcfg;
1617mcfg_added=true;
1618i++;
1619}
1620}
1621
1622if (!oem_ssdt)
1623{
1624while ((totssdt < loadtotssdt) && (curssdt < 17))
1625{
1626if (new_ssdt[curssdt])
1627{
1628DBG("adding SSDT %d\n", curssdt);
1629rsdt_entries[i-dropoffset]=(uint32_t)new_ssdt[curssdt];
1630totssdt++;
1631newtotssdt++;
1632i++;
1633} else if (quick_ssdt) {
1634break;
1635}
1636
1637curssdt++;
1638}
1639}
1640
1641// Correct the checksum of RSDT
1642rsdt_mod->Length-=4*dropoffset;
1643rsdt_mod->Length+=4*newtotssdt;
1644if (hpet_added)
1645rsdt_mod->Length+=4;
1646if (sbst_added)
1647rsdt_mod->Length+=4;
1648if (ecdt_added)
1649rsdt_mod->Length+=4;
1650if (asft_added)
1651rsdt_mod->Length+=4;
1652if (dmar_added)
1653rsdt_mod->Length+=4;
1654if (apic_added)
1655rsdt_mod->Length+=4;
1656if (mcfg_added)
1657rsdt_mod->Length+=4;
1658
1659DBG("RSDT: Original checksum %d, ", rsdt_mod->Checksum);
1660
1661 setchecksum((struct acpi_common_header *)rsdt_mod);
1662
1663DBG("New checksum %d at %x\n", rsdt_mod->Checksum,rsdt_mod);
1664
1665}
1666else
1667{
1668rsdp_mod->RsdtAddress=0;
1669printf("RSDT not found or RSDT incorrect\n");
1670}
1671
1672if (version)
1673{
1674struct acpi_2_xsdt *xsdt, *xsdt_mod;
1675
1676// FIXME: handle 64-bit address correctly
1677
1678if (gen_xsdt)
1679xsdt=xsdt_conv;
1680else
1681xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress);
1682
1683DBG("XSDT @%x;%x, Length=%d\n", (uint32_t)(rsdp->XsdtAddress>>32),(uint32_t)rsdp->XsdtAddress,
1684xsdt->Length);
1685if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000)
1686{
1687int dropoffset=0, i;
1688curssdt=0, totssdt=0, newtotssdt=0;
1689hpet_replaced=false, hpet_added=false;
1690sbst_replaced=false, sbst_added=false;
1691ecdt_replaced=false, ecdt_added=false;
1692asft_replaced=false, asft_added=false;
1693dmar_replaced=false, dmar_added=false;
1694apic_replaced=false, apic_added=false;
1695mcfg_replaced=false, mcfg_added=false;
1696
1697if (gen_xsdt)
1698xsdt_mod=xsdt;
1699else
1700{
1701xsdt_mod=(struct acpi_2_xsdt*)AllocateKernelMemory(xsdt->Length);
1702memcpy(xsdt_mod, xsdt, xsdt->Length);
1703}
1704
1705 update_rsdp_with_xsdt(rsdp_mod, xsdt_mod);
1706
1707int xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8;
1708uint64_t *xsdt_entries=(uint64_t *)(xsdt_mod+1);
1709for (i=0;i<xsdt_entries_num;i++)
1710{
1711
1712char *table=(char *)((uint32_t)(xsdt_entries[i]));
1713if (!table)
1714continue;
1715
1716xsdt_entries[i-dropoffset]=xsdt_entries[i];
1717
1718char table4[5];
1719strlcpy(table4, table, sizeof(table4));
1720TagPtr match_drop = XMLGetProperty(DropTables_p, (const char*)table4);
1721if ( match_drop ) {
1722char *tmpstr = XMLCastString(match_drop);
1723if (strcmp(tmpstr,"No") != 0) {
1724dropoffset++;
1725DBG("%s table dropped\n",table4);
1726continue;
1727}
1728}
1729
1730 if ((!(oem_hpet)) && tableSign(table, "HPET"))
1731{
1732DBG("HPET found\n");
1733if (new_hpet)
1734{
1735xsdt_entries[i-dropoffset]=(uint32_t)new_hpet;
1736hpet_replaced=true;
1737}
1738continue;
1739}
1740
1741 if ((!(oem_sbst)) && tableSign(table, "SBST"))
1742{
1743DBG("SBST found\n");
1744if (new_sbst)
1745{
1746xsdt_entries[i-dropoffset]=(uint32_t)new_sbst;
1747sbst_replaced=true;
1748}
1749continue;
1750}
1751
1752 if ((!(oem_ecdt)) && tableSign(table, "ECDT"))
1753{
1754DBG("ECDT found\n");
1755
1756if (new_ecdt)
1757{
1758xsdt_entries[i-dropoffset]=(uint32_t)new_ecdt;
1759ecdt_replaced=true;
1760}
1761
1762continue;
1763}
1764
1765 if ((!(oem_asft)) && tableSign(table, "ASF!"))
1766{
1767DBG("ASF! found\n");
1768if (new_asft)
1769{
1770xsdt_entries[i-dropoffset]=(uint32_t)new_asft;
1771asft_replaced=true;
1772}
1773continue;
1774}
1775
1776
1777 if ((!(oem_dmar)) && tableSign(table, "DMAR"))
1778{
1779DBG("DMAR found\n");
1780if (new_dmar)
1781{
1782xsdt_entries[i-dropoffset]=(uint32_t)new_dmar;
1783dmar_replaced=true;
1784}
1785continue;
1786}
1787
1788 if ((!(oem_apic)) && tableSign(table, "APIC"))
1789{
1790DBG("APIC found\n");
1791if (new_apic)
1792{
1793xsdt_entries[i-dropoffset]=(uint32_t)new_apic;
1794apic_replaced=true;
1795}
1796continue;
1797}
1798
1799 if ((!(oem_mcfg)) && tableSign(table, "MCFG"))
1800{
1801DBG("MCFG found\n");
1802if (new_mcfg)
1803{
1804xsdt_entries[i-dropoffset]=(uint32_t)new_mcfg;
1805mcfg_replaced=true;
1806}
1807continue;
1808}
1809
1810 if ((!(oem_ssdt)) && tableSign(table, "SSDT"))
1811{
1812DBG("SSDT %d found", curssdt);
1813if (new_ssdts[curssdt])
1814{
1815DBG(" and replaced");
1816xsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt];
1817totssdt++;
1818}
1819DBG("\n");
1820curssdt++;
1821continue;
1822}
1823
1824 if ((!(oem_dsdt)) && tableSign(table, "DSDT"))
1825{
1826DBG("DSDT found\n");
1827
1828xsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;
1829
1830DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
1831
1832continue;
1833
1834}
1835
1836 if (tableSign(table, "FACP"))
1837{
1838fadt=(struct acpi_2_fadt *)(uint32_t)xsdt_entries[i];
1839
1840DBG("FADT found @%x,%x, Length %d\n",(uint32_t)(xsdt_entries[i]>>32),fadt,
1841fadt->Length);
1842
1843if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000)
1844{
1845verbose("FADT incorrect or after 4GB. Dropping XSDT\n");
1846goto drop_xsdt;
1847}
1848verbose("Attempting to patch FADT entry of XSDT\n");
1849fadt_mod = patch_fadt(fadt, new_dsdt, update_acpi);
1850
1851
1852xsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;
1853
1854//DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
1855
1856if (!oem_ssdt)
1857 {
1858 // Generate _CST SSDT
1859 if ( gen_csta && (new_ssdt[loadtotssdt] = generate_cst_ssdt(fadt_mod)))
1860 {
1861 gen_csta= false;
1862 loadtotssdt++;
1863 }
1864
1865 // Generating _PSS SSDT
1866 if (gen_psta && (new_ssdt[loadtotssdt] = generate_pss_ssdt((void*)fadt_mod->DSDT)))
1867 {
1868 gen_psta= false;
1869 loadtotssdt++;
1870 }
1871 }
1872
1873
1874continue;
1875}
1876
1877//DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
1878
1879}
1880
1881if ((!oem_hpet) && (!hpet_replaced))
1882{
1883if (new_hpet)
1884{
1885xsdt_entries[i-dropoffset]=(uint32_t)new_hpet;
1886hpet_added=true;
1887i++;
1888}
1889}
1890
1891if ((!oem_sbst) && (!sbst_replaced))
1892{
1893if (new_sbst)
1894{
1895xsdt_entries[i-dropoffset]=(uint32_t)new_sbst;
1896sbst_added=true;
1897i++;
1898}
1899}
1900
1901if ((!oem_ecdt) && (!ecdt_replaced))
1902{
1903if (new_ecdt)
1904{
1905
1906xsdt_entries[i-dropoffset]=(uint32_t)new_ecdt;
1907ecdt_added=true;
1908i++;
1909}
1910}
1911
1912if ((!oem_asft) && (!asft_replaced))
1913{
1914if (new_asft)
1915{
1916xsdt_entries[i-dropoffset]=(uint32_t)new_asft;
1917asft_added=true;
1918i++;
1919}
1920}
1921
1922if ((!oem_dmar) && (!dmar_replaced))
1923{
1924if (new_dmar)
1925{
1926xsdt_entries[i-dropoffset]=(uint32_t)new_dmar;
1927dmar_added=true;
1928i++;
1929}
1930}
1931
1932if ((!oem_apic) && (!apic_replaced))
1933{
1934if (new_apic)
1935{
1936xsdt_entries[i-dropoffset]=(uint32_t)new_apic;
1937apic_added=true;
1938i++;
1939}
1940}
1941
1942if ((!oem_mcfg) && (!mcfg_replaced))
1943{
1944if (new_mcfg)
1945{
1946xsdt_entries[i-dropoffset]=(uint32_t)new_mcfg;
1947mcfg_added=true;
1948i++;
1949}
1950}
1951
1952if (!oem_ssdt)
1953{
1954while ((totssdt < loadtotssdt) && (curssdt < 17))
1955{
1956if (new_ssdt[curssdt])
1957{
1958DBG("adding SSDT %d\n", curssdt);
1959xsdt_entries[i-dropoffset]=(uint32_t)new_ssdt[curssdt];
1960totssdt++;
1961newtotssdt++;
1962i++;
1963} else if (quick_ssdt){
1964break;
1965}
1966
1967curssdt++;
1968}
1969}
1970
1971// Correct the checksum of XSDT
1972xsdt_mod->Length-=8*dropoffset;
1973xsdt_mod->Length+=8*newtotssdt;
1974if (hpet_added)
1975xsdt_mod->Length+=8;
1976if (sbst_added)
1977xsdt_mod->Length+=8;
1978if (ecdt_added)
1979xsdt_mod->Length+=8;
1980if (asft_added)
1981xsdt_mod->Length+=8;
1982if (dmar_added)
1983xsdt_mod->Length+=8;
1984if (apic_added)
1985xsdt_mod->Length+=8;
1986if (mcfg_added)
1987xsdt_mod->Length+=8;
1988
1989 setchecksum((struct acpi_common_header *)xsdt_mod);
1990}
1991else
1992{
1993drop_xsdt:
1994
1995DBG("About to drop XSDT\n");
1996
1997/*FIXME: Now we just hope that if MacOS doesn't find XSDT it reverts to RSDT.
1998 * A Better strategy would be to generate
1999 */
2000
2001rsdp_mod->XsdtAddress=0xffffffffffffffffLL;
2002verbose("XSDT not found or XSDT incorrect\n");
2003}
2004}
2005
2006// Correct the checksum of RSDP
2007
2008DBG("RSDP: Original checksum %d, ", rsdp_mod->Checksum);
2009
2010 setRsdpchecksum(rsdp_mod);
2011
2012DBG("New checksum %d\n", rsdp_mod->Checksum);
2013
2014if (version)
2015{
2016DBG("RSDP: Original extended checksum %d", rsdp_mod->ExtendedChecksum);
2017
2018 setRsdpXchecksum(rsdp_mod);
2019
2020DBG("New extended checksum %d\n", rsdp_mod->ExtendedChecksum);
2021
2022}
2023
2024verbose("Patched ACPI version %d\n", version+1);
2025
2026
2027 Status = Register_Acpi_Efi(rsdp_mod, version+1);
2028
2029}
2030
2031#if DEBUG_DSDT
2032printf("Press a key to continue... (DEBUG_DSDT)\n");
2033getc();
2034#endif
2035return Status ;
2036}
2037

Archive Download this file

Revision: 2010