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

Archive Download this file

Revision: 1468