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

Archive Download this file

Revision: 1126