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

Archive Download this file

Revision: 2006