Index: branches/cparm/i386/libsaio/Makefile =================================================================== --- branches/cparm/i386/libsaio/Makefile (revision 1121) +++ branches/cparm/i386/libsaio/Makefile (revision 1122) @@ -97,8 +97,9 @@ @echo "#define I386BOOT_VERSION \"5.0.132\"" > $(SYMROOT)/vers.h @echo "#define I386BOOT_BUILDDATE \"`date \"+%Y-%m-%d %H:%M:%S\"`\"" >> $(SYMROOT)/vers.h @echo "#define I386BOOT_CHAMELEONVERSION \"`cat ../../version`\"" >> $(SYMROOT)/vers.h - @echo "#define I386BOOT_CHAMELEONREVISION \"`svnversion -n | tr -d [:alpha:]`\"" >> $(SYMROOT)/vers.h - + @echo "#define I386BOOT_CHAMELEONREVISION \"`svnversion -n | tr -d [:alpha:]`\"" >> $(SYMROOT)/vers.h + @echo "#define FIRMWARE_PUBLISHER \"`whoami`\"" >> $(SYMROOT)/vers.h + libsaio.a: $(SAIO_EXTERN_OBJS) $(SAIO_OBJS) rm -f $(SYMROOT)/$(@F) ar q $(SYMROOT)/$(@F) $^ Index: branches/cparm/i386/libsaio/stringTable.c =================================================================== --- branches/cparm/i386/libsaio/stringTable.c (revision 1121) +++ branches/cparm/i386/libsaio/stringTable.c (revision 1122) @@ -605,6 +605,8 @@ char *dirspec[] = { "/Extra/com.apple.Boot.plist", "bt(0,0)/Extra/com.apple.Boot.plist", + "rd(0,0)/Extra/org.chameleon.Boot.plist", // Add compatibility with the trunk + "/Extra/org.chameleon.Boot.plist", // Add compatibility with the trunk "/Library/Preferences/SystemConfiguration/com.apple.Boot.plist", }; int i,fd, count, ret=-1; Index: branches/cparm/i386/libsaio/fake_efi.c =================================================================== --- branches/cparm/i386/libsaio/fake_efi.c (revision 1121) +++ branches/cparm/i386/libsaio/fake_efi.c (revision 1122) @@ -83,11 +83,11 @@ * Fake EFI implementation */ -/* Identify ourselves as the EFI firmware vendor */ static EFI_CHAR16 const FIRMWARE_VENDOR[] = {'A','p','p','l','e', 0}; +/* Info About the current Firmware */ +#define FIRMWARE_MAINTENER "cparm, armelcadetpetit@gmail.com" static EFI_CHAR16 const FIRMWARE_NAME[] = {'M','t','.','H','o','o','d', 0}; //a.k.a Galak. - static EFI_UINT32 const FIRMWARE_REVISION = 0x00010400; //1.4 static EFI_UINT32 const DEVICE_SUPPORTED = 0x00000001; @@ -480,6 +480,9 @@ static const char const FIRMWARE_VENDOR_PROP[] = "firmware-vendor"; static const char const FIRMWARE_NAME_PROP[] = "firmware-name"; static const char const FIRMWARE_DATE_PROP[] = "firmware-date"; +static const char const FIRMWARE_DEV_PROP[] = "firmware-maintener"; +static const char const FIRMWARE_PUBLISH_PROP[] = "firmware-publisher"; + static const char const FIRMWARE_ABI_32_PROP_VALUE[] = "EFI32"; static const char const FIRMWARE_ABI_64_PROP_VALUE[] = "EFI64"; static const char const SYSTEM_ID_PROP[] = "system-id"; @@ -725,7 +728,9 @@ DT__AddProperty(efiNode, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION); DT__AddProperty(efiNode, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR); DT__AddProperty(efiNode, FIRMWARE_NAME_PROP, sizeof(FIRMWARE_NAME), (EFI_CHAR16*)FIRMWARE_NAME); - DT__AddProperty(efiNode, FIRMWARE_DATE_PROP, strlen(I386BOOT_BUILDDATE)+1, I386BOOT_BUILDDATE); + DT__AddProperty(efiNode, FIRMWARE_DATE_PROP, strlen(I386BOOT_BUILDDATE)+1, I386BOOT_BUILDDATE); + DT__AddProperty(efiNode, FIRMWARE_DEV_PROP, strlen(FIRMWARE_MAINTENER)+1, FIRMWARE_MAINTENER); + DT__AddProperty(efiNode, FIRMWARE_PUBLISH_PROP, strlen(FIRMWARE_PUBLISHER)+1, FIRMWARE_PUBLISHER); // Set up the /efi/configuration-table node which will eventually have several child nodes for // all of the configuration tables needed by various kernel extensions. Index: branches/cparm/i386/modules/ACPIMini/aml_generator.c =================================================================== --- branches/cparm/i386/modules/ACPIMini/aml_generator.c (revision 0) +++ branches/cparm/i386/modules/ACPIMini/aml_generator.c (revision 1122) @@ -0,0 +1,562 @@ +/* + * aml_generator.c + * Chameleon + * + * Created by Mozodojo on 20/07/10. + * Copyright 2010 mozo. All rights reserved. + * + */ + +#include "aml_generator.h" + +bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node) +{ + if (parent && node) + { + switch (parent->Type) + { + case AML_CHUNK_NONE: + case AML_CHUNK_BYTE: + case AML_CHUNK_WORD: + case AML_CHUNK_DWORD: + case AML_CHUNK_QWORD: + case AML_CHUNK_ALIAS: + verbose("aml_add_to_parent: Node isn't supports child nodes!\n"); + return false; + case AML_CHUNK_NAME: + if (parent->First) + { + verbose("aml_add_to_parent: Name node could have only one child node!\n"); + return false; + } + break; + + default: + break; + } + + if (!parent->First) + parent->First = node; + + if (parent->Last) + parent->Last->Next = node; + + parent->Last = node; + + return true; + } + + return false; +} + +struct aml_chunk* aml_create_node(struct aml_chunk* parent) +{ + struct aml_chunk* node = (struct aml_chunk*)malloc(sizeof(struct aml_chunk)); + + aml_add_to_parent(parent, node); + + return node; +} + +void aml_destroy_node(struct aml_chunk* node) +{ + // Delete child nodes + struct aml_chunk* child = node->First; + + while (child) + { + struct aml_chunk* next = child->Next; + + if (child->Buffer) + free(child->Buffer); + + free(child); + + child = next; + } + + // Free node + if (node->Buffer) + free(node->Buffer); + + free(node); +} + +struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_NONE; + node->Length = size; + node->Buffer = malloc(node->Length); + memcpy(node->Buffer, buffer, node->Length); + } + + return node; +} + +struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_BYTE; + + node->Length = 1; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value; + } + + return node; +} + +struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_WORD; + node->Length = 2; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value & 0xff; + node->Buffer[1] = value >> 8; + } + + return node; +} + +struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_DWORD; + node->Length = 4; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value & 0xff; + node->Buffer[1] = (value >> 8) & 0xff; + node->Buffer[2] = (value >> 16) & 0xff; + node->Buffer[3] = (value >> 24) & 0xff; + } + + return node; +} + +struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_QWORD; + node->Length = 8; + node->Buffer = malloc(node->Length); + node->Buffer[0] = value & 0xff; + node->Buffer[1] = (value >> 8) & 0xff; + node->Buffer[2] = (value >> 16) & 0xff; + node->Buffer[3] = (value >> 24) & 0xff; + node->Buffer[4] = (value >> 32) & 0xff; + node->Buffer[5] = (value >> 40) & 0xff; + node->Buffer[6] = (value >> 48) & 0xff; + node->Buffer[7] = (value >> 56) & 0xff; + } + + return node; +} + +unsigned int aml_fill_simple_name(char* buffer, const char* name) +{ + if (strlen(name) < 4) + { + verbose("aml_fill_simple_name: simple name %s has incorrect lengh! Must be 4\n", name); + return 0; + } + + memcpy(buffer, name, 4); + return 4; +} + +unsigned int aml_fill_name(struct aml_chunk* node, const char* name) +{ + if (!node) + return 0; + + int len = strlen(name), offset = 0, count = len / 4; + + if ((len % 4) > 1 || count == 0) + { + verbose("aml_fill_name: pathname %s has incorrect length! Must be 4, 8, 12, 16 etc.\n", name); + return 0; + } + + unsigned int root = 0; + + if ((len % 4) == 1 && name[0] == '\\') + root++; + + if (count == 1) + { + node->Length = 4 + root; + node->Buffer = malloc(node->Length); + memcpy(node->Buffer, name, 4 + root); + return node->Length; + } + + if (count == 2) + { + node->Length = 2 + 8; + node->Buffer = malloc(node->Length); + node->Buffer[offset++] = 0x5c; // Root Char + node->Buffer[offset++] = 0x2e; // Double name + memcpy(node->Buffer+offset, name + root, 8); + return node->Length; + } + + node->Length = 3 + count*4; + node->Buffer = malloc(node->Length); + node->Buffer[offset++] = 0x5c; // Root Char + node->Buffer[offset++] = 0x2f; // Multi name + node->Buffer[offset++] = count; // Names count + memcpy(node->Buffer+offset, name + root, count*4); + + return node->Length; +} + +struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_SCOPE; + + aml_fill_name(node, name); + } + + return node; +} + +struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_NAME; + + aml_fill_name(node, name); + } + + return node; +} + +struct aml_chunk* aml_add_package(struct aml_chunk* parent) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_PACKAGE; + + node->Length = 1; + node->Buffer = malloc(node->Length); + } + + return node; +} + +struct aml_chunk* aml_add_package_with_value(struct aml_chunk* parent, uint64_t *lst, int num) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_PACKAGE; + node->Length = 1; + node->Buffer = malloc(node->Length); + aml_add_multiple_value(node,lst,num); + + } + + return node; +} + +void aml_add_value(struct aml_chunk* parent, uint64_t val) +{ + if (parent) + { + if (val > 0xffffffff) + aml_add_qword(parent,val); + else if (val > 0xffff) + aml_add_dword(parent,val); + else if (val > 0xff) + aml_add_word(parent,val); + else + aml_add_byte(parent, val); + } + +} + +void aml_add_multiple_value(struct aml_chunk* parent, uint64_t *lst, int num) +{ + if (parent) + { + int i; + for (i=0; i<(num / 8); i++) { + + aml_add_value(parent, lst[i]); + } + } + +} + +struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2) +{ + struct aml_chunk* node = aml_create_node(parent); + + if (node) + { + node->Type = AML_CHUNK_ALIAS; + + node->Length = 8; + node->Buffer = malloc(node->Length); + aml_fill_simple_name(node->Buffer, name1); + aml_fill_simple_name(node->Buffer+4, name2); + } + + return node; +} + +unsigned char aml_get_size_length(unsigned int size) +{ + if (size + 1 <= 0x3f) + return 1; + else if (size + 2 <= 0x3fff) + return 2; + else if (size + 3 <= 0x3fffff) + return 3; + + return 4; +} + +unsigned int aml_calculate_size(struct aml_chunk* node) +{ + if (node) + { + node->Size = 0; + + // Calculate child nodes size + struct aml_chunk* child = node->First; + unsigned char child_count = 0; + + while (child) + { + child_count++; + + node->Size += aml_calculate_size(child); + + child = child->Next; + } + + switch (node->Type) + { + case AML_CHUNK_NONE: + node->Size += node->Length; + break; + case AML_CHUNK_SCOPE: + node->Size += 1 + node->Length; + node->Size += aml_get_size_length(node->Size); + break; + case AML_CHUNK_PACKAGE: + node->Buffer[0] = child_count; + node->Size += 1 + node->Length; + node->Size += aml_get_size_length(node->Size); + break; + + case AML_CHUNK_BYTE: + if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1) + { + node->Size += node->Length; + } + else + { + node->Size += 1 + node->Length; + } + + break; + + case AML_CHUNK_WORD: + case AML_CHUNK_DWORD: + case AML_CHUNK_QWORD: + case AML_CHUNK_ALIAS: + case AML_CHUNK_NAME: + node->Size += 1 + node->Length; + break; + } + + return node->Size; + } + + return 0; +} + +unsigned int aml_write_byte(unsigned char value, char* buffer, unsigned int offset) +{ + buffer[offset++] = value; + + return offset; +} + +unsigned int aml_write_word(unsigned int value, char* buffer, unsigned int offset) +{ + buffer[offset++] = value & 0xff; + buffer[offset++] = value >> 8; + + return offset; +} + +unsigned int aml_write_dword(unsigned long value, char* buffer, unsigned int offset) +{ + buffer[offset++] = value & 0xff; + buffer[offset++] = (value >> 8) & 0xff; + buffer[offset++] = (value >> 16) & 0xff; + buffer[offset++] = (value >> 24) & 0xff; + + return offset; +} + +unsigned int aml_write_qword(unsigned long long value, char* buffer, unsigned int offset) +{ + buffer[offset++] = value & 0xff; + buffer[offset++] = (value >> 8) & 0xff; + buffer[offset++] = (value >> 16) & 0xff; + buffer[offset++] = (value >> 24) & 0xff; + buffer[offset++] = (value >> 32) & 0xff; + buffer[offset++] = (value >> 40) & 0xff; + buffer[offset++] = (value >> 48) & 0xff; + buffer[offset++] = (value >> 56) & 0xff; + + return offset; +} + +unsigned int aml_write_buffer(const char* value, unsigned int size, char* buffer, unsigned int offset) +{ + if (size > 0) + { + memcpy(buffer + offset, value, size); + } + + return offset + size; +} + +void aml_add_ressource_t_fxhw(struct aml_chunk* parent, uint64_t *lst) +{ + if (parent) { + char resource_template[] = + { + 0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F, + 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x79, 0x00 + }; + + char *buffer = resource_template; + unsigned int offset = aml_write_byte(lst[0], buffer, 8); + offset = aml_write_byte(lst[1], buffer, offset); + offset = aml_write_byte(lst[2], buffer, offset); + aml_write_qword(lst[3], buffer, offset); + aml_add_buffer(parent, buffer, sizeof(resource_template)); + } +} + +unsigned int aml_write_size(unsigned int size, char* buffer, unsigned int offset) +{ + if (size <= 0x3f) + { + buffer[offset++] = size; + } + else if (size <= 0x3fff) + { + buffer[offset++] = 0x40 | (size & 0xf); + buffer[offset++] = (size >> 4) & 0xff; + } + else if (size <= 0x3fffff) + { + buffer[offset++] = 0x80 | (size & 0xf); + buffer[offset++] = (size >> 4) & 0xff; + buffer[offset++] = (size >> 12) & 0xff; + } + else + { + buffer[offset++] = 0xc0 | (size & 0xf); + buffer[offset++] = (size >> 4) & 0xff; + buffer[offset++] = (size >> 12) & 0xff; + buffer[offset++] = (size >> 20) & 0xff; + } + + return offset; +} + +unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset) +{ + if (node && buffer) + { + unsigned int old = offset; + + switch (node->Type) + { + case AML_CHUNK_NONE: + offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset); + break; + + case AML_CHUNK_SCOPE: + case AML_CHUNK_PACKAGE: + offset = aml_write_byte(node->Type, buffer, offset); + offset = aml_write_size(node->Size-1, buffer, offset); + offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset); + break; + + case AML_CHUNK_BYTE: + if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1) + { + offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset); + } + else + { + offset = aml_write_byte(node->Type, buffer, offset); + offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset); + } + break; + + case AML_CHUNK_WORD: + case AML_CHUNK_DWORD: + case AML_CHUNK_QWORD: + case AML_CHUNK_ALIAS: + case AML_CHUNK_NAME: + offset = aml_write_byte(node->Type, buffer, offset); + offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset); + break; + + default: + break; + } + + struct aml_chunk* child = node->First; + + while (child) + { + offset = aml_write_node(child, buffer, offset); + + child = child->Next; + } + + if (offset - old != node->Size) + verbose("Node size incorrect: 0x%x\n", node->Type); + } + + return offset; +} \ No newline at end of file Index: branches/cparm/i386/modules/ACPIMini/acpi_patcher.c =================================================================== --- branches/cparm/i386/modules/ACPIMini/acpi_patcher.c (revision 0) +++ branches/cparm/i386/modules/ACPIMini/acpi_patcher.c (revision 1122) @@ -0,0 +1,2018 @@ +/* + * Copyright 2008 mackerintel + */ + +/* + * Copyright (c) 2010 cparm . All rights reserved. + * + */ + +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "acpi.h" +#include "efi_tables.h" +#include "fake_efi.h" +#include "acpi_patcher.h" +#include "platform.h" +#include "cpu.h" +#include "aml_generator.h" +#include "xml.h" +#include "smp.h" + +uint64_t acpi10_p; +uint64_t acpi20_p; + +#ifndef DEBUG_ACPI +#define DEBUG_ACPI 0 +#endif + +#if DEBUG_ACPI==2 +#define DBG(x...) {printf(x); sleep(1);} +#elif DEBUG_ACPI==1 +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif + +extern EFI_STATUS addConfigurationTable(); + +extern EFI_GUID gEfiAcpiTableGuid; +extern EFI_GUID gEfiAcpi20TableGuid; + +#define tableSign(table, sgn) (table[0]==sgn[0] && table[1]==sgn[1] && table[2]==sgn[2] && table[3]==sgn[3]) + +#define CMOS_WRITE_BYTE(x, y) cmos_write_byte(x, y) +#define CMOS_READ_BYTE(x) cmos_read_byte(x) + +#define RSDP_CHECKSUM_LENGTH 20 + +/*- + * FOR biosacpi_search_rsdp AND biosacpi_find_rsdp + * + * Copyright (c) 2001 Michael Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/boot/i386/libi386/biosacpi.c,v 1.7 2003/08/25 23:28:31 obrien Exp $ + * $DragonFly: src/sys/boot/pc32/libi386/biosacpi.c,v 1.5 2007/01/17 17:31:19 y0netan1 Exp $ + */ + +static struct acpi_2_rsdp * +biosacpi_search_rsdp(char *base, int length, int rev) +{ + struct acpi_2_rsdp *rsdp; + int ofs; + + /* search on 16-byte boundaries */ + for (ofs = 0; ofs < length; ofs += 16) { + rsdp = (struct acpi_2_rsdp*)ptov(base + ofs); + + /* compare signature, validate checksum */ + if (!strncmp(rsdp->Signature, ACPI_SIG_RSDP, strlen(ACPI_SIG_RSDP))) { + + uint8_t csum = checksum8(rsdp, RSDP_CHECKSUM_LENGTH); + if(csum == 0) + { + /* Only assume this is a 2.0 or better table if the revision is greater than 0 + * NOTE: ACPI 3.0 spec only seems to say that 1.0 tables have revision 1 + * and that the current revision is 2.. I am going to assume that rev > 0 is 2.0. + */ + + if((rsdp->Revision > 0) && rev > 0) + { + uint8_t csum2 = checksum8(rsdp, sizeof(struct acpi_2_rsdp)); + if(csum2 == 0) + return(rsdp); + } + + // Only return the table if it is a true version 1.0 table (Revision 0) + if((rsdp->Revision == 0) && rev == 0) + return(rsdp); + } + + } + } + return(NULL); +} + +/* + * Find the RSDP in low memory. See section 5.2.2 of the ACPI spec. + */ +static struct acpi_2_rsdp * +biosacpi_find_rsdp(int rev) +{ + struct acpi_2_rsdp *rsdp; + uint16_t *addr; + + /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */ + addr = (uint16_t *)ptov(EBDA_SEG_ADDR); + if ((rsdp = biosacpi_search_rsdp((char *)(*addr << 4), EBDA_SEG_LEN, rev)) != NULL) + return (rsdp); + + unsigned mem_lower = ((CMOS_READ_BYTE(CMOS_BASE_MEMORY+1) << 8) + | CMOS_READ_BYTE(CMOS_BASE_MEMORY)) << 10; + + if ((rsdp = biosacpi_search_rsdp((char *)mem_lower, EBDA_SEG_LEN, rev)) != NULL) + return (rsdp); + + + /* Check the upper memory BIOS space, 0xe0000 - 0xfffff. */ + if ((rsdp = biosacpi_search_rsdp((char *)0xe0000, 0x20000, rev)) != NULL) + return (rsdp); + + return (NULL); +} + + + +#define __RES(s, u) \ +inline unsigned u \ +resolve_##s(unsigned u defaultentry, char *str, int base) \ +{ \ +unsigned u entry = defaultentry; \ +if (str && (strcmp(str,"Default") != 0)) { \ +entry = strtoul((const char *)str, NULL,base); \ +} \ +return entry; \ +} + +__RES(pss, long) +__RES(cst, int) + + +static void setchecksum(struct acpi_common_header *header) +{ + header->Checksum = 0; + header->Checksum = 256-checksum8(header, header->Length); +} + +static void setRsdpchecksum(struct acpi_2_rsdp *rsdp) +{ + rsdp->Checksum = 0; + rsdp->Checksum = 256-checksum8(rsdp, 20); +} + +static void setRsdpXchecksum(struct acpi_2_rsdp *rsdp) +{ + rsdp->ExtendedChecksum = 0; + rsdp->ExtendedChecksum = 256-checksum8(rsdp, rsdp->Length); +} + +static struct acpi_2_rsdp * gen_rsdp_v2_from_v1(struct acpi_2_rsdp *rsdp) +{ + struct acpi_2_rsdp * rsdp_conv = (struct acpi_2_rsdp *)AllocateKernelMemory(sizeof(struct acpi_2_rsdp)); + memcpy(rsdp_conv, rsdp, 20); + + /* Add/change fields */ + rsdp_conv->Revision = 2; /* ACPI version 3 */ + rsdp_conv->Length = sizeof(struct acpi_2_rsdp); + + /* Correct checksums */ + setRsdpchecksum(rsdp_conv); + setRsdpXchecksum(rsdp_conv); + + rsdp = rsdp_conv; + + return rsdp_conv; +} + +static struct acpi_2_xsdt * gen_xsdt_from_rsdt(struct acpi_2_rsdt *rsdt) +{ + int i,rsdt_entries_num=(rsdt->Length-sizeof(struct acpi_2_rsdt))/4; + + uint32_t *rsdt_entries=(uint32_t *)(rsdt+1); + + struct acpi_2_xsdt * xsdt_conv=(struct acpi_2_xsdt *)AllocateKernelMemory(sizeof(struct acpi_2_xsdt)+(rsdt_entries_num * 8)); + memcpy(xsdt_conv, rsdt, sizeof(struct acpi_2_rsdt)); + + xsdt_conv->Signature[0] = 'X'; + xsdt_conv->Signature[1] = 'S'; + xsdt_conv->Signature[2] = 'D'; + xsdt_conv->Signature[3] = 'T'; + xsdt_conv->Length = sizeof(struct acpi_2_xsdt)+(rsdt_entries_num * 8); + + uint64_t *xsdt_conv_entries=(uint64_t *)(xsdt_conv+1); + + for (i=0;iXsdtAddress = (uint32_t)xsdt; + + setRsdpXchecksum(rsdp); +} + +static void update_rsdp_with_rsdt(struct acpi_2_rsdp *rsdp, struct acpi_2_rsdt *rsdt) +{ + rsdp->RsdtAddress = (uint32_t)rsdt; + + setRsdpchecksum(rsdp); + +} + + +void *loadSSDTTable(int ssdt_number) +{ + int fd = -1; + char dirspec[512]; + char filename[512]; + const char * overriden_pathname=NULL; + int len=0; + + // Check booting partition + + // Rek: if user specified a full path name then take it in consideration + if (getValueForKey(kSSDT, &overriden_pathname, &len, + &bootInfo->bootConfig)) + { + sprintf(filename, "%s-%d.aml", overriden_pathname, ssdt_number); // start searching root + } + else + sprintf(filename, "SSDT-%d.aml", ssdt_number); + + sprintf(dirspec, "/%s", filename); // start searching root + + fd=open (dirspec); + + if (fd<0) + { // Check Extra on booting partition + sprintf(dirspec,"/Extra/%s",filename); + fd=open (dirspec); + if (fd<0) + { // Fall back to booter partition + sprintf(dirspec,"bt(0,0)/Extra/%s",filename); + fd=open (dirspec); + if (fd<0) + { + DBG("SSDT Table not found: %s\n", filename); + return NULL; + } + } + } + + void *tableAddr=(void*)AllocateKernelMemory(file_size (fd)); + if (tableAddr) + { + if (read (fd, tableAddr, file_size (fd))!=file_size (fd)) + { + printf("Couldn't read table %s\n",dirspec); + free (tableAddr); + close (fd); + return NULL; + } + + printf("Valid SSDT Table found: %s\n", filename); + DBG("Table %s read and stored at: %x\n", dirspec, tableAddr); + close (fd); + return tableAddr; + } + + printf("Couldn't allocate memory for table %s\n", dirspec); + close (fd); + + return NULL; +} + +void *loadACPITable(char *key) +{ + int fd = -1; + char dirspec[512]; + char filename[512]; + const char * overriden_pathname=NULL; + int len=0; + + DBG("Searching for %s.aml file ...\n", key); + // Check booting partition + + // Rek: if user specified a full path name then take it in consideration + if (getValueForKey(key, &overriden_pathname, &len, + &bootInfo->bootConfig)) + { + sprintf(filename, "%s", overriden_pathname); + } + else + sprintf(filename, "%s.aml", key); + + + sprintf(dirspec, "/%s", filename); // start searching root + + fd=open (dirspec); + + if (fd<0) + { + // Check Extra on booting partition + sprintf(dirspec,"/Extra/%s",filename); + fd=open (dirspec); + if (fd<0) + { // Fall back to booter partition + sprintf(dirspec,"bt(0,0)/Extra/%s",filename); + fd=open (dirspec); + if (fd<0) + { + DBG("ACPI Table not found: %s\n", key); + return NULL; + } + + } + + } + + void *tableAddr=(void*)AllocateKernelMemory(file_size (fd)); + if (tableAddr) + { + if (read (fd, tableAddr, file_size (fd))!=file_size (fd)) + { + printf("Couldn't read table %s\n",key); + free (tableAddr); + close (fd); + return NULL; + } + verbose("Valid ACPI Table found: %s\n", key); + //DBG("Table %s read and stored at: %x\n", key, tableAddr); + close (fd); + return tableAddr; + } + + printf("Couldn't allocate memory for table %s\n", key); + close (fd); + + return NULL; +} + +uint8_t acpi_cpu_count = 0; +char* acpi_cpu_name[32]; + +void get_acpi_cpu_names(unsigned char* dsdt, uint32_t length) +{ + uint32_t i; + + for (i=0; i> 6); + + bool add_name = true; + + uint8_t j; + + for (j=0; j<4; j++) + { + char c = dsdt[offset+j]; + + if (!aml_isvalidchar(c)) + { + add_name = false; + verbose("Invalid character found in ProcessorOP 0x%x!\n", c); + break; + } + } + + if (add_name) + { + acpi_cpu_name[acpi_cpu_count] = malloc(4); + memcpy(acpi_cpu_name[acpi_cpu_count], dsdt+offset, 4); + i = offset + 5; + + verbose("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]); + + if (++acpi_cpu_count == 32) return; + } + } + } +} + + +struct acpi_2_ssdt *generate_cst_ssdt(struct acpi_2_fadt* fadt) +{ + char ssdt_header[] = + { + 0x53, 0x53, 0x44, 0x54, 0xE7, 0x00, 0x00, 0x00, /* SSDT.... */ + 0x01, 0x17, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x41, /* ..PmRefA */ + 0x43, 0x70, 0x75, 0x43, 0x73, 0x74, 0x00, 0x00, /* CpuCst.. */ + 0x00, 0x10, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* ....INTL */ + 0x31, 0x03, 0x10, 0x20 /* 1.._ */ + }; + + char cstate_resource_template[] = + { + 0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F, + 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x79, 0x00 + }; + + if (Platform->CPU.Vendor != 0x756E6547) { + verbose ("Not an Intel platform: C-States will not be generated !!!\n"); + return NULL; + } + + if (fadt == NULL) { + verbose ("FACP not exists: C-States will not be generated !!!\n"); + return NULL; + } + + struct acpi_2_dsdt* dsdt = (void*)fadt->DSDT; + + if (dsdt == NULL) { + verbose ("DSDT not found: C-States will not be generated !!!\n"); + return NULL; + } + + if (acpi_cpu_count == 0) + get_acpi_cpu_names((void*)dsdt, dsdt->Length); + + if (acpi_cpu_count > 0) + { + bool c2_enabled = fadt->C2_Latency < 100; + bool c3_enabled = fadt->C3_Latency < 1000; + bool c4_enabled = false; + + getBoolForKey(kEnableC4State, &c4_enabled, &bootInfo->bootConfig); + + unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + ((c3_enabled || c4_enabled) ? 1 : 0); + char *Lat = NULL, *Pw = NULL, *tmpstr =NULL; + int base = 16; + TagPtr personality = XMLCastDict(XMLGetProperty(bootInfo->bootConfig.dictionary, (const char*)"C-States")); + + if ((tmpstr = XMLCastString(XMLGetProperty(personality, (const char*)"Base")))) { + + int mybase = strtol(tmpstr, NULL, 10); + + if (mybase == 8 || mybase == 10 || mybase == 16 ) + base = mybase; + } + + struct aml_chunk* root = aml_create_node(NULL); + aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header + struct aml_chunk* scop = aml_add_scope(root, "\\_PR_"); + struct aml_chunk* name = aml_add_name(scop, "CST_"); + struct aml_chunk* pack = aml_add_package(name); + aml_add_byte(pack, cstates_count); + + struct aml_chunk* tmpl = aml_add_package(pack); + TagPtr match_Status = XMLGetProperty(personality, (const char*)"C1"); + if (match_Status) { + Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power")); + Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency")); + } + cstate_resource_template[11] = 0x00; // C1 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x01); // C1 + aml_add_byte(tmpl, (unsigned char)resolve_cst(0x01, Lat, base)); // Latency + aml_add_word(tmpl, resolve_cst(0x03e8, Pw, base)); // Power + // C2 + if (c2_enabled) + { + tmpl = aml_add_package(pack); + Lat = NULL; + Pw = NULL; + match_Status = XMLGetProperty(personality, (const char*)"C2"); + if (match_Status) { + Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power")); + Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency")); + } + + cstate_resource_template[11] = 0x10; // C2 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x02); // C2 + aml_add_word(tmpl, resolve_cst(fadt->C2_Latency, Lat, base)); // Latency + aml_add_word(tmpl, resolve_cst(0x01f4, Pw, base)); // Power + } + + // C4 + if (c4_enabled) + { + tmpl = aml_add_package(pack); + Lat = NULL; + Pw = NULL; + match_Status = XMLGetProperty(personality, (const char*)"C4"); + if (match_Status) { + Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power")); + Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency")); + } + cstate_resource_template[11] = 0x30; // C4 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x04); // C4 + aml_add_word(tmpl, resolve_cst(fadt->C3_Latency / 2, Lat, base)); // TODO: right latency for C4 + aml_add_word(tmpl, resolve_cst(0xfa, Pw, base)); // Power + + } + // C3 + else if (c3_enabled) + { + tmpl = aml_add_package(pack); + Lat = NULL; + Pw = NULL; + match_Status = XMLGetProperty(personality, (const char*)"C3"); + if (match_Status) { + Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power")); + Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency")); + } + cstate_resource_template[11] = 0x20; // C3 + aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template)); + aml_add_byte(tmpl, 0x03); // C3 + aml_add_word(tmpl, resolve_cst(fadt->C3_Latency , Lat, base)); + aml_add_word(tmpl, resolve_cst(0x015e, Pw, base)); // Power + + } + + + // Aliaces + int i; + for (i = 0; i < acpi_cpu_count; i++) + { + char name[9]; + 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]); + + scop = aml_add_scope(root, name); + aml_add_alias(scop, "CST_", "_CST"); + } + + aml_calculate_size(root); + + struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size); + + aml_write_node(root, (void*)ssdt, 0); + + ssdt->Length = root->Size; + + setchecksum((struct acpi_common_header *)ssdt); + + aml_destroy_node(root); + + verbose ("SSDT with CPU C-States generated successfully\n"); + + return ssdt; + } + else + { + verbose ("ACPI CPUs not found: C-States not generated !!!\n"); + } + + return NULL; +} + +struct acpi_2_ssdt *generate_pss_ssdt(struct acpi_2_dsdt* dsdt) +{ + + char ssdt_header[] = + { + 0x53, 0x53, 0x44, 0x54, 0x7E, 0x00, 0x00, 0x00, /* SSDT.... */ + 0x01, 0x6A, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x00, /* ..PmRef. */ + 0x43, 0x70, 0x75, 0x50, 0x6D, 0x00, 0x00, 0x00, /* CpuPm... */ + 0x00, 0x30, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* .0..INTL */ + 0x31, 0x03, 0x10, 0x20, /* 1.._ */ + }; + + if (Platform->CPU.Vendor != 0x756E6547) { + verbose ("Not an Intel platform: P-States will not be generated !!!\n"); + return NULL; + } + + if (!(Platform->CPU.Features & CPUID_FEATURE_MSR)) { + verbose ("Unsupported CPU: P-States will not be generated !!!\n"); + return NULL; + } + + if (acpi_cpu_count == 0) + get_acpi_cpu_names((void*)dsdt, dsdt->Length); + + if (acpi_cpu_count > 0) + { + struct p_state initial, maximum, minimum, p_states[32]; + uint8_t p_states_count = 0; + + // Retrieving P-States, ported from code by superhai (c) + switch (Platform->CPU.Family) { + case 0x06: + { + switch (Platform->CPU.Model) + { + case CPUID_MODEL_DOTHAN: // ? + case CPUID_MODEL_YONAH: // Yonah + case CPUID_MODEL_MEROM: // Merom + case CPUID_MODEL_PENRYN: // Penryn + case CPUID_MODEL_ATOM: // Intel Atom (45nm) + { + bool cpu_dynamic_fsb = false; + + if (rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 27)) + { + wrmsr64(MSR_IA32_EXT_CONFIG, (rdmsr64(MSR_IA32_EXT_CONFIG) | (1 << 28))); + delay(1); + cpu_dynamic_fsb = rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 28); + } + + bool cpu_noninteger_bus_ratio = (rdmsr64(MSR_IA32_PERF_STATUS) & (1ULL << 46)); + + initial.Control = rdmsr64(MSR_IA32_PERF_STATUS); + + maximum.Control = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 32) & 0x1F3F) | (0x4000 * cpu_noninteger_bus_ratio); + maximum.CID = ((maximum.FID & 0x1F) << 1) | cpu_noninteger_bus_ratio; + + minimum.FID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 24) & 0x1F) | (0x80 * cpu_dynamic_fsb); + minimum.VID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 48) & 0x3F); + + if (minimum.FID == 0) + { + uint64_t msr; + uint8_t i; + // Probe for lowest fid + for (i = maximum.FID; i >= 0x6; i--) + { + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (i << 8) | minimum.VID); + intel_waitforsts(); + minimum.FID = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0x1F; + delay(1); + } + + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID); + intel_waitforsts(); + } + + if (minimum.VID == maximum.VID) + { + uint64_t msr; + uint8_t i; + // Probe for lowest vid + for (i = maximum.VID; i > 0xA; i--) + { + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (minimum.FID << 8) | i); + intel_waitforsts(); + minimum.VID = rdmsr64(MSR_IA32_PERF_STATUS) & 0x3F; + delay(1); + } + + msr = rdmsr64(MSR_IA32_PERF_CONTROL); + wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID); + intel_waitforsts(); + } + + minimum.CID = ((minimum.FID & 0x1F) << 1) >> cpu_dynamic_fsb; + + // Sanity check + if (maximum.CID < minimum.CID) + { + DBG("Insane FID values!"); + p_states_count = 0; + } + else + { + // Finalize P-States + // Find how many P-States machine supports + p_states_count = maximum.CID - minimum.CID + 1; + + if (p_states_count > 32) + p_states_count = 32; + + uint8_t vidstep; + uint8_t i = 0, u, invalid = 0; + + vidstep = ((maximum.VID << 2) - (minimum.VID << 2)) / (p_states_count - 1); + + for (u = 0; u < p_states_count; u++) + { + i = u - invalid; + + p_states[i].CID = maximum.CID - u; + p_states[i].FID = (p_states[i].CID >> 1); + + if (p_states[i].FID < 0x6) + { + if (cpu_dynamic_fsb) + p_states[i].FID = (p_states[i].FID << 1) | 0x80; + } + else if (cpu_noninteger_bus_ratio) + { + p_states[i].FID = p_states[i].FID | (0x40 * (p_states[i].CID & 0x1)); + } + + if (i && p_states[i].FID == p_states[i-1].FID) + invalid++; + + p_states[i].VID = ((maximum.VID << 2) - (vidstep * u)) >> 2; + + uint32_t multiplier = p_states[i].FID & 0x1f; // = 0x08 + bool half = p_states[i].FID & 0x40; // = 0x01 + bool dfsb = p_states[i].FID & 0x80; // = 0x00 + uint32_t fsb = Platform->CPU.FSBFrequency / 1000000; // = 400 + uint32_t halffsb = (fsb + 1) >> 1; // = 200 + uint32_t frequency = (multiplier * fsb); // = 3200 + + p_states[i].Frequency = (frequency + (half * halffsb)) >> dfsb; // = 3200 + 200 = 3400 + } + + p_states_count -= invalid; + } + break; + } + case CPUID_MODEL_FIELDS: + case CPUID_MODEL_DALES: + case CPUID_MODEL_DALES_32NM: + case CPUID_MODEL_NEHALEM: + case CPUID_MODEL_NEHALEM_EX: + case CPUID_MODEL_WESTMERE: + case CPUID_MODEL_WESTMERE_EX: + case CPUID_MODEL_SANDYBRIDGE: + case CPUID_MODEL_JAKETOWN: + { + maximum.Control = rdmsr64(MSR_IA32_PERF_STATUS) & 0xff; // Seems it always contains maximum multiplier value (with turbo, that's we need)... + minimum.Control = (rdmsr64(MSR_PLATFORM_INFO) >> 40) & 0xff; + + verbose("P-States: min 0x%x, max 0x%x\n", minimum.Control, maximum.Control); + + // Sanity check + if (maximum.Control < minimum.Control) + { + DBG("Insane control values!"); + p_states_count = 0; + } + else + { + uint8_t i; + p_states_count = 0; + + for (i = maximum.Control; i >= minimum.Control; i--) + { + p_states[p_states_count].Control = i; + p_states[p_states_count].CID = p_states[p_states_count].Control << 1; + p_states[p_states_count].Frequency = (Platform->CPU.FSBFrequency / 1000000) * i; + p_states_count++; + } + } + + break; + } + default: + verbose ("Unsupported CPU: P-States not generated !!!\n"); + break; + } + } + default: + break; + } + + // Generating SSDT + if (p_states_count) + { + int i; + + struct aml_chunk* root = aml_create_node(NULL); + aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header + struct aml_chunk* scop = aml_add_scope(root, "\\_PR_"); + struct aml_chunk* name = aml_add_name(scop, "PSS_"); + struct aml_chunk* pack = aml_add_package(name); + + uint8_t minPSratio = (p_states[p_states_count-1].Frequency / (Platform->CPU.FSBFrequency / 10000000 )); + uint8_t maxPSratio = (p_states[0].Frequency / (Platform->CPU.FSBFrequency / 10000000 )); + + uint8_t cpu_div = Platform->CPU.CurrDiv; + uint8_t cpu_ratio = 0; + + if (cpu_div) + cpu_ratio = (Platform->CPU.CurrCoef * 10) + 5; + else + cpu_ratio = Platform->CPU.CurrCoef * 10; + + + int user_max_ratio = 0; + getIntForKey(kMaxRatio, &user_max_ratio, &bootInfo->bootConfig); + if (user_max_ratio >= minPSratio && maxPSratio >= user_max_ratio) { + + uint8_t maxcurrdiv = 0, maxcurrcoef = (int)(user_max_ratio / 10); + + uint8_t maxdiv = user_max_ratio - (maxcurrcoef * 10); + if (maxdiv > 0) + maxcurrdiv = 1; + + if (maxcurrdiv) + cpu_ratio = (maxcurrcoef * 10) + 5; + else + cpu_ratio = maxcurrcoef * 10; + } + + int user_min_ratio = 0; + getIntForKey(kMinRatio, &user_min_ratio, &bootInfo->bootConfig); + if (user_min_ratio >= minPSratio && cpu_ratio >= user_min_ratio) { + + uint8_t mincurrdiv = 0, mincurrcoef = (int)(user_min_ratio / 10); + + uint8_t mindiv = user_min_ratio - (mincurrcoef * 10); + + if (mindiv > 0) + mincurrdiv = 1; + + if (mincurrdiv) + minPSratio = (mincurrcoef * 10) + 5; + else + minPSratio = mincurrcoef * 10; + + } + + if (maxPSratio >= cpu_ratio && cpu_ratio >= minPSratio) maxPSratio = cpu_ratio; + + TagPtr personality = XMLCastDict(XMLGetProperty(bootInfo->bootConfig.dictionary, (const char*)"P-States")); + char* MatchStat = 0; + int dropPSS = 0, Pstatus = 0, base = 16; + int expert = 0;/* Default: 0 , mean mixed mode | expert mode : 1 , mean add only p-states found in boot.plist*/ + char *tmpstr = XMLCastString(XMLGetProperty(personality, (const char*)"Mode")); + + if (strcmp(tmpstr,"Expert") == 0) { + p_states_count = (XMLTagCount(personality)) - 1 ; // - 1 = - ("Mode" tag) + expert = 1; + } + + + if ((tmpstr = XMLCastString(XMLGetProperty(personality, (const char*)"Base")))) { + + if (expert) p_states_count--; // -= ("Base" tag) + + int mybase = strtol(tmpstr, NULL, 10); + + if (mybase == 8 || mybase == 10 || mybase == 16 ) + base = mybase; + } + + for (i = 0; i < p_states_count; i++) + { + sprintf(MatchStat, "%d",i); + TagPtr match_Status = XMLGetProperty(personality, (const char*)MatchStat); + + char *Lat1 = NULL, *clk = NULL, *Pw = NULL, *Lat2 = NULL, *Ctrl = NULL ; + + if (match_Status) { + + clk = XMLCastString(XMLGetProperty(match_Status, (const char*)"CoreFreq")); + Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power")); + Lat1 = XMLCastString(XMLGetProperty(match_Status, (const char*)"Transition Latency")); + Lat2 = XMLCastString(XMLGetProperty(match_Status, (const char*)"Bus Master Latency")); + Ctrl = XMLCastString(XMLGetProperty(match_Status, (const char*)"Control")); + + + } else if (expert) + continue; + + + unsigned long Frequency = 0x00000000; + + if (!expert) Frequency = p_states[i].Frequency; + + if (clk) + Frequency = strtoul((const char *)clk, NULL,base); + + if (!Frequency || Frequency > p_states[0].Frequency ) continue; + + uint8_t curr_ratio = (Frequency / (Platform->CPU.FSBFrequency / 10000000 )); + + if (curr_ratio > maxPSratio || minPSratio > curr_ratio) + goto dropPstate; + + struct aml_chunk* pstt = aml_add_package(pack); + aml_add_dword(pstt, Frequency); // CoreFreq (in MHz). + aml_add_dword(pstt, resolve_pss(0x00000000, Pw, base)); // Power (in milliWatts) + aml_add_dword(pstt, resolve_pss(0x0000000A, Lat1, base)); // Transition Latency (in microseconds). + aml_add_dword(pstt, resolve_pss(0x0000000A, Lat2, base)); // Bus Master Latency (in microseconds). + unsigned long Control = 0x00000000; + if (!expert) Control = p_states[i].Control; + aml_add_dword(pstt, resolve_pss(Control, Ctrl, base)); // Control + Pstatus++; + aml_add_dword(pstt, Pstatus); // Status + continue; + dropPstate: +#if DEBUG_ACPI + verbose("state with cpu frequency :%d and ratio :%d will be dropped\n",p_states[i].Frequency,curr_ratio); +#endif + dropPSS++; + + + } + + // Add aliaces + for (i = 0; i < acpi_cpu_count; i++) + { + char name[9]; + 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]); + + scop = aml_add_scope(root, name); + aml_add_alias(scop, "PSS_", "_PSS"); + } + + aml_calculate_size(root); + + struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size); + + aml_write_node(root, (void*)ssdt, 0); + + ssdt->Length = root->Size; + + setchecksum((struct acpi_common_header *)ssdt); + + aml_destroy_node(root); + + verbose ("SSDT with CPU P-States generated successfully"); + + if (dropPSS) + verbose(", %d P-state(s) dropped",dropPSS); + + verbose("\n"); + + return ssdt; + } + } + else + { + verbose("ACPI CPUs not found: P-States not generated !!!\n"); + } + + return NULL; +} + + +struct acpi_2_gas FillGASStruct(uint32_t Address, uint8_t Length) +{ + struct acpi_2_gas TmpGAS; + + TmpGAS.Address_Space_ID = 1; /* I/O Address */ + + if (Address == 0) + { + TmpGAS.Register_Bit_Width = 0; + } else { + TmpGAS.Register_Bit_Width = Length * 8; + } + + TmpGAS.Register_Bit_Offset = 0; + TmpGAS.Access_Size = 0; /* Not set for Legacy reasons... */ + TmpGAS.Address = (uint64_t)Address; + + return(TmpGAS); +} + +struct acpi_2_fadt * +patch_fadt(struct acpi_2_fadt *fadt, struct acpi_2_dsdt *new_dsdt, bool UpdateFADT) +{ + + struct acpi_2_fadt *fadt_mod; + struct acpi_2_fadt *fadt_file = (struct acpi_2_fadt *)loadACPITable(kFADT); + bool fadt_rev2_needed = false; + bool fix_restart = false; + const char * value; + bool aspmOff = true; + bool msiOff = true; + + // Restart Fix + if (Platform->CPU.Vendor == 0x756E6547) { /* Intel */ + fix_restart = true; + getBoolForKey(kRestartFix, &fix_restart, &bootInfo->bootConfig); + + } else { + verbose ("Not an Intel platform: Restart Fix not applied !!!\n"); + } + + if (fix_restart) + fadt_rev2_needed = true; + + // Allocate new fadt table + if ((UpdateFADT) && (((fadt_file) && (fadt_file->Length < sizeof(struct acpi_2_fadt))) || + ((!fadt_file) && (fadt->Length < sizeof(struct acpi_2_fadt))))) + { + getBoolForKey(kDisableMSI, &msiOff, &bootInfo->bootConfig) ; + getBoolForKey(kDisableASPM, &aspmOff, &bootInfo->bootConfig); + + if (fadt_file) + { + if (fadt_file->Length < 0xF4) + { + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0xF4); + memcpy(fadt_mod, fadt_file, fadt_file->Length); + fadt_mod->Length = 0xF4; + } + else + { + + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt_file->Length); + memcpy(fadt_mod, fadt_file, fadt_file->Length); + } + } + else + { + if (fadt->Length < 0xF4) + { + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0xF4); + memcpy(fadt_mod, fadt, fadt->Length); + fadt_mod->Length = 0xF4; + } + else + { + + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length); + memcpy(fadt_mod, fadt, fadt->Length); + } + } + + fadt_mod->Revision = 0x04; // FADT rev 4 + fadt_mod->RESET_REG = FillGASStruct(0, 0); + fadt_mod->Reset_Value = 0; + fadt_mod->Reserved[0] = 0; + fadt_mod->Reserved[1] = 0; + fadt_mod->Reserved[2] = 0; + + fadt_mod->X_PM1a_EVT_BLK = FillGASStruct(fadt_mod->PM1A_Event_Block_Address, fadt_mod->PM1_Event_Block_Length); + fadt_mod->X_PM1b_EVT_BLK = FillGASStruct(fadt_mod->PM1B_Event_Block_Address, fadt_mod->PM1_Event_Block_Length); + fadt_mod->X_PM1a_CNT_BLK = FillGASStruct(fadt_mod->PM1A_Control_Block_Address, fadt_mod->PM1_Control_Block_Length); + fadt_mod->X_PM1b_CNT_BLK = FillGASStruct(fadt_mod->PM1B_Control_Block_Address, fadt_mod->PM1_Control_Block_Length); + fadt_mod->X_PM2_CNT_BLK = FillGASStruct(fadt_mod->PM2_Control_Block_Address, fadt_mod->PM2_Control_Block_Length); + fadt_mod->X_PM_TMR_BLK = FillGASStruct(fadt_mod->PM_Timer_Block_Address, fadt_mod->PM_Timer_Block_Length); + fadt_mod->X_GPE0_BLK = FillGASStruct(fadt_mod->GPE0_Block_Address, fadt_mod->GPE0_Block_Length); + fadt_mod->X_GPE1_BLK = FillGASStruct(fadt_mod->GPE1_Block_Address, fadt_mod->GPE1_Block_Length); + + verbose("Converted ACPI V%d FADT to ACPI V4 FADT\n", (fadt) ? fadt->Revision : fadt->Revision); + } else { + + if (fadt_file) { + if (fadt_file->Length < 0x84 && fadt_rev2_needed) + { + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84); + memcpy(fadt_mod, fadt_file, fadt_file->Length); + fadt_mod->Length = 0x84; + fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions) + } else { + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt_file->Length); + memcpy(fadt_mod, fadt_file, fadt_file->Length); + } + + } else { + if (fadt->Length < 0x84 && fadt_rev2_needed) + { + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84); + memcpy(fadt_mod, fadt, fadt->Length); + fadt_mod->Length = 0x84; + fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions) + } else { + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length); + memcpy(fadt_mod, fadt, fadt->Length); + } + + } + + } + + uint8_t Type = PMProfileError; + // Determine system type / PM_Model + + // Fix System-type if needed (should never happen) + if (Platform->Type > MaxSupportedPMProfile) + { + if(fadt_mod->PM_Profile <= MaxSupportedPMProfile) + Platform->Type = fadt_mod->PM_Profile; // get the fadt if correct + else + Platform->Type = 1; /* Set a fixed value (Desktop) */ + } + + // If needed, set System-type from PM_Profile (if valid) else set PM_Profile with a fixed the System-type + // Give prior to the FADT pm profile, allow to also control this value with a patched FADT table + if (fadt_mod->PM_Profile != Platform->Type) + { + bool val = false; + getBoolForKey("PreferInternalProfileDetect", &val, &bootInfo->bootConfig); // if true Give prior to the profile resolved trought the CPU model + + val = Platform->CPU.isServer ; + + if (fadt_mod->PM_Profile <= MaxSupportedPMProfile && !val) { + Platform->Type = fadt_mod->PM_Profile; + } else { + fadt_mod->PM_Profile = Platform->Type; + } + + } + + // Set PM_Profile and System-type if user wanted this value to be forced + if ( (value=getStringForKey("SystemType", &bootInfo->bootConfig))!=NULL) { + if ((Type = (unsigned char) strtoul(value, NULL, 10) ) <= MaxSupportedPMProfile) + { + verbose("FADT: changing Preferred_PM_Profile from 0x%02x to 0x%02x\n", fadt->PM_Profile, Type); + fadt_mod->PM_Profile = Platform->Type = Type; + } else verbose("Error: system-type must be 0..6. Defaulting to %d !\n", Platform->Type); + } + + // Patch FADT to fix restart + if (fix_restart) + { + fadt_mod->Flags|= 0x400; + + fadt_mod->RESET_REG = FillGASStruct(0x0cf9, 1); + fadt_mod->Reset_Value = 0x06; + verbose("FADT: Restart Fix applied !\n"); + } + + + if (aspmOff) { + fadt_mod->Boot_Flags |= 1 << 4; + } else { + fadt_mod->Boot_Flags &= 0xFFEF; + + } + + if (msiOff) { + fadt_mod->Boot_Flags |= 1 << 3; + } else { + fadt_mod->Boot_Flags &= 0xFFF7; + } + + fadt_mod->FIRMWARE_CTRL=(uint32_t)fadt->FIRMWARE_CTRL; + if ((uint32_t)(&(fadt_mod->X_FIRMWARE_CTRL))-(uint32_t)fadt_mod+8<=fadt_mod->Length) + fadt_mod->X_FIRMWARE_CTRL=(uint32_t)fadt->FIRMWARE_CTRL; + + Platform->hardware_signature = ((struct acpi_2_facs *)fadt->FIRMWARE_CTRL)->hardware_signature; + + DBG("setting hardware_signature to %x \n",Platform->hardware_signature); + + + + // Patch DSDT Address if we have loaded a DSDT table + if(new_dsdt) + { + + fadt_mod->DSDT=(uint32_t)new_dsdt; + if ((uint32_t)(&(fadt_mod->X_DSDT))-(uint32_t)fadt_mod+8<=fadt_mod->Length) + fadt_mod->X_DSDT=(uint32_t)new_dsdt; + + } + + // Correct the checksum + setchecksum((struct acpi_common_header *)fadt_mod); + + return fadt_mod; +} + + +/* Setup ACPI */ +EFI_STATUS setupAcpi(void) +{ + int version; + EFI_STATUS Status = EFI_ABORTED; + void *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]; + + struct acpi_2_ssdt *new_ssdt[17]; // 15 + 2 additional tables for pss & cst + struct acpi_2_fadt *fadt; // will be used in CST generator + struct acpi_2_fadt *fadt_mod=NULL; + bool 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; + bool update_acpi=false, gen_xsdt=false; + bool hpet_replaced=false, sbst_replaced=false, ecdt_replaced=false, asft_replaced=false, dmar_replaced=false, apic_replaced=false, mcfg_replaced=false; + bool hpet_added=false, sbst_added=false, ecdt_added=false, asft_added=false, dmar_added=false, apic_added=false, mcfg_added=false; + bool gen_csta=false, gen_psta=false, speed_step=false; + + bool quick_ssdt= false; + // Quick ssdt search, + // first try to find ssdt-0.aml, if the file do not exist we + // stop searching here, else ssdt-0.aml is loaded and we try + // to find ssdt-1.aml, etc ......... + + int curssdt=0, loadtotssdt=0, totssdt=0, newtotssdt=0; + + { + bool tmpval; + + oem_dsdt=getBoolForKey(kOEMDSDT, &tmpval, &bootInfo->bootConfig)&&tmpval; + oem_ssdt=getBoolForKey(kOEMSSDT, &tmpval, &bootInfo->bootConfig)&&tmpval; + oem_hpet=getBoolForKey(kOEMHPET, &tmpval, &bootInfo->bootConfig)&&tmpval; + oem_sbst=getBoolForKey(kOEMSBST, &tmpval, &bootInfo->bootConfig)&&tmpval; + oem_ecdt=getBoolForKey(kOEMECDT, &tmpval, &bootInfo->bootConfig)&&tmpval; + oem_asft=getBoolForKey(kOEMASFT, &tmpval, &bootInfo->bootConfig)&&tmpval; + oem_dmar=getBoolForKey(kOEMDMAR, &tmpval, &bootInfo->bootConfig)&&tmpval; + oem_apic=getBoolForKey(kOEMAPIC, &tmpval, &bootInfo->bootConfig)&&tmpval; + oem_mcfg=getBoolForKey(kOEMMCFG, &tmpval, &bootInfo->bootConfig)&&tmpval; + + gen_csta=getBoolForKey(kGenerateCStates, &tmpval, &bootInfo->bootConfig)&&tmpval; + gen_psta=getBoolForKey(kGeneratePStates, &tmpval, &bootInfo->bootConfig)&&tmpval; + + update_acpi=getBoolForKey(kUpdateACPI, &tmpval, &bootInfo->bootConfig)&&tmpval; + + quick_ssdt=getBoolForKey(kQSSDT, &tmpval, &bootInfo->bootConfig)&&tmpval; + + speed_step=getBoolForKey(kSpeedstep, &tmpval, &bootInfo->bootConfig)&&tmpval; + + } + + if (speed_step) { + gen_psta= true; + gen_csta= true; + } + + + // Load replacement ACPI tables + if (!oem_dsdt) + new_dsdt=loadACPITable(kDSDT); + + + if (!oem_hpet) + new_hpet=loadACPITable(kHPET); + + + if (!oem_sbst) + new_sbst=loadACPITable(kSBST); + + + if (!oem_ecdt) + new_ecdt=loadACPITable(kECDT); + + + if (!oem_asft) + new_asft=loadACPITable(kASFT); + + + if (!oem_dmar) + new_dmar=loadACPITable(kDMAR); + + + if (!oem_apic) + new_apic=loadACPITable(kAPIC); + + + if (!oem_mcfg) + new_mcfg=loadACPITable(kMCFG); + + if (!oem_ssdt) + { + + for (curssdt=0;curssdt<15;curssdt++) + { + new_ssdt[curssdt]=loadSSDTTable(curssdt); + + if (new_ssdt[curssdt]) + loadtotssdt++; + else if (quick_ssdt) + break; + + } + + curssdt=0; + + } + + DBG("New ACPI tables Loaded in memory\n"); + TagPtr DropTables_p = XMLCastDict(XMLGetProperty(bootInfo->bootConfig.dictionary, (const char*)"ACPIDropTables")); + // Do the same procedure for both versions of ACPI + for (version=0; version<2; version++) { + struct acpi_2_rsdp *rsdp_mod, *rsdp_conv=(struct acpi_2_rsdp *)0; + struct acpi_2_rsdt *rsdt, *rsdt_mod; + struct acpi_2_xsdt *xsdt_conv = (struct acpi_2_xsdt *)0; + int rsdplength; + + // Find original rsdp + struct acpi_2_rsdp *rsdp=(struct acpi_2_rsdp *)(version?biosacpi_find_rsdp(2):biosacpi_find_rsdp(0)); + + if ((update_acpi) && (rsdp->Revision == 0)) + { + + rsdp_conv = gen_rsdp_v2_from_v1(rsdp); + gen_xsdt = true; + version = 1; + + addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI"); + + verbose("Converted ACPI RSD PTR version 1 to version 3\n"); + } + + if (!rsdp) + { + DBG("No ACPI version %d found. Ignoring\n", version+1); + if (version) + addConfigurationTable(&gEfiAcpi20TableGuid, NULL, "ACPI_20"); + else + addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI"); + continue; + } + rsdplength=version?rsdp->Length:20; + + DBG("RSDP version %d found @%x. Length=%d\n",version+1,rsdp,rsdplength); + + /* FIXME: no check that memory allocation succeeded + * Copy and patch RSDP,RSDT, XSDT and FADT + * For more info see ACPI Specification pages 110 and following + */ + + if (gen_xsdt) + { + rsdp_mod=rsdp_conv; + } else { + rsdp_mod=(struct acpi_2_rsdp *) AllocateKernelMemory(rsdplength); + memcpy(rsdp_mod, rsdp, rsdplength); + } + + rsdt=(struct acpi_2_rsdt *)(rsdp->RsdtAddress); + + DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length); + + if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000) + { + int dropoffset=0, i; + + rsdt_mod=(struct acpi_2_rsdt *)AllocateKernelMemory(rsdt->Length); + memcpy (rsdt_mod, rsdt, rsdt->Length); + + update_rsdp_with_rsdt(rsdp_mod, rsdt_mod); + + int rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4; + uint32_t *rsdt_entries=(uint32_t *)(rsdt_mod+1); + + if (gen_xsdt) + { + + xsdt_conv=gen_xsdt_from_rsdt(rsdt_mod); + update_rsdp_with_xsdt(rsdp, xsdt_conv); + + + verbose("Converted RSDT table to XSDT table\n"); + } + + for (i=0;iLength); + + if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000) + { + printf("FADT incorrect. Not modified\n"); + continue; + } + verbose("Attempting to patch FADT entry of RSDT\n"); + fadt_mod = patch_fadt(fadt, new_dsdt, update_acpi); + + rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod; + + if (!oem_ssdt) + { + // Generate _CST SSDT + if ( gen_csta && (new_ssdt[loadtotssdt] = generate_cst_ssdt(fadt_mod))) + { + gen_csta= false; + loadtotssdt++; + } + + // Generating _PSS SSDT + if (gen_psta && (new_ssdt[loadtotssdt] = generate_pss_ssdt((void*)fadt_mod->DSDT))) + { + gen_psta= false; + loadtotssdt++; + } + + } + + continue; + } + } + DBG("\n"); + + if ((!oem_hpet) && (!hpet_replaced)) + { + if (new_hpet) + { + rsdt_entries[i-dropoffset]=(uint32_t)new_hpet; + hpet_added=true; + i++; + } + } + + if ((!oem_sbst) && (!sbst_replaced)) + { + if (new_sbst) + { + rsdt_entries[i-dropoffset]=(uint32_t)new_sbst; + sbst_added=true; + i++; + } + } + + if ((!oem_ecdt) && (!ecdt_replaced)) + { + if (new_ecdt) + { + rsdt_entries[i-dropoffset]=(uint32_t)new_ecdt; + ecdt_added=true; + i++; + } + } + + if ((!oem_asft) && (!asft_replaced)) + { + if (new_asft) + { + rsdt_entries[i-dropoffset]=(uint32_t)new_asft; + asft_added=true; + i++; + } + } + + if ((!oem_dmar) && (!dmar_replaced)) + { + if (new_dmar) + { + rsdt_entries[i-dropoffset]=(uint32_t)new_dmar; + dmar_added=true; + i++; + } + } + + if ((!oem_apic) && (!apic_replaced)) + { + if (new_apic) + { + rsdt_entries[i-dropoffset]=(uint32_t)new_apic; + apic_added=true; + i++; + } + } + + if ((!oem_mcfg) && (!mcfg_replaced)) + { + if (new_mcfg) + { + rsdt_entries[i-dropoffset]=(uint32_t)new_mcfg; + mcfg_added=true; + i++; + } + } + + if (!oem_ssdt) + { + while ((totssdt < loadtotssdt) && (curssdt < 17)) + { + if (new_ssdt[curssdt]) + { + DBG("adding SSDT %d\n", curssdt); + rsdt_entries[i-dropoffset]=(uint32_t)new_ssdt[curssdt]; + totssdt++; + newtotssdt++; + i++; + } else if (quick_ssdt) { + break; + } + + curssdt++; + } + } + + // Correct the checksum of RSDT + rsdt_mod->Length-=4*dropoffset; + rsdt_mod->Length+=4*newtotssdt; + if (hpet_added) + rsdt_mod->Length+=4; + if (sbst_added) + rsdt_mod->Length+=4; + if (ecdt_added) + rsdt_mod->Length+=4; + if (asft_added) + rsdt_mod->Length+=4; + if (dmar_added) + rsdt_mod->Length+=4; + if (apic_added) + rsdt_mod->Length+=4; + if (mcfg_added) + rsdt_mod->Length+=4; + + DBG("RSDT: Original checksum %d, ", rsdt_mod->Checksum); + + setchecksum((struct acpi_common_header *)rsdt_mod); + + DBG("New checksum %d at %x\n", rsdt_mod->Checksum,rsdt_mod); + + } + else + { + rsdp_mod->RsdtAddress=0; + printf("RSDT not found or RSDT incorrect\n"); + } + + if (version) + { + struct acpi_2_xsdt *xsdt, *xsdt_mod; + + // FIXME: handle 64-bit address correctly + + if (gen_xsdt) + xsdt=xsdt_conv; + else + xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress); + + DBG("XSDT @%x;%x, Length=%d\n", (uint32_t)(rsdp->XsdtAddress>>32),(uint32_t)rsdp->XsdtAddress, + xsdt->Length); + if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000) + { + int dropoffset=0, i; + curssdt=0, totssdt=0, newtotssdt=0; + hpet_replaced=false, hpet_added=false; + sbst_replaced=false, sbst_added=false; + ecdt_replaced=false, ecdt_added=false; + asft_replaced=false, asft_added=false; + dmar_replaced=false, dmar_added=false; + apic_replaced=false, apic_added=false; + mcfg_replaced=false, mcfg_added=false; + + if (gen_xsdt) + xsdt_mod=xsdt; + else + { + xsdt_mod=(struct acpi_2_xsdt*)AllocateKernelMemory(xsdt->Length); + memcpy(xsdt_mod, xsdt, xsdt->Length); + } + + update_rsdp_with_xsdt(rsdp_mod, xsdt_mod); + + int xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8; + uint64_t *xsdt_entries=(uint64_t *)(xsdt_mod+1); + for (i=0;i>32),fadt, + fadt->Length); + + if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000) + { + verbose("FADT incorrect or after 4GB. Dropping XSDT\n"); + goto drop_xsdt; + } + verbose("Attempting to patch FADT entry of XSDT\n"); + fadt_mod = patch_fadt(fadt, new_dsdt, update_acpi); + + + xsdt_entries[i-dropoffset]=(uint32_t)fadt_mod; + + //DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]); + + if (!oem_ssdt) + { + // Generate _CST SSDT + if ( gen_csta && (new_ssdt[loadtotssdt] = generate_cst_ssdt(fadt_mod))) + { + gen_csta= false; + loadtotssdt++; + } + + // Generating _PSS SSDT + if (gen_psta && (new_ssdt[loadtotssdt] = generate_pss_ssdt((void*)fadt_mod->DSDT))) + { + gen_psta= false; + loadtotssdt++; + } + } + + + continue; + } + + //DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]); + + } + + if ((!oem_hpet) && (!hpet_replaced)) + { + if (new_hpet) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_hpet; + hpet_added=true; + i++; + } + } + + if ((!oem_sbst) && (!sbst_replaced)) + { + if (new_sbst) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_sbst; + sbst_added=true; + i++; + } + } + + if ((!oem_ecdt) && (!ecdt_replaced)) + { + if (new_ecdt) + { + + xsdt_entries[i-dropoffset]=(uint32_t)new_ecdt; + ecdt_added=true; + i++; + } + } + + if ((!oem_asft) && (!asft_replaced)) + { + if (new_asft) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_asft; + asft_added=true; + i++; + } + } + + if ((!oem_dmar) && (!dmar_replaced)) + { + if (new_dmar) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_dmar; + dmar_added=true; + i++; + } + } + + if ((!oem_apic) && (!apic_replaced)) + { + if (new_apic) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_apic; + apic_added=true; + i++; + } + } + + if ((!oem_mcfg) && (!mcfg_replaced)) + { + if (new_mcfg) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_mcfg; + mcfg_added=true; + i++; + } + } + + if (!oem_ssdt) + { + while ((totssdt < loadtotssdt) && (curssdt < 17)) + { + if (new_ssdt[curssdt]) + { + DBG("adding SSDT %d\n", curssdt); + xsdt_entries[i-dropoffset]=(uint32_t)new_ssdt[curssdt]; + totssdt++; + newtotssdt++; + i++; + } else if (quick_ssdt){ + break; + } + + curssdt++; + } + } + + // Correct the checksum of XSDT + xsdt_mod->Length-=8*dropoffset; + xsdt_mod->Length+=8*newtotssdt; + if (hpet_added) + xsdt_mod->Length+=8; + if (sbst_added) + xsdt_mod->Length+=8; + if (ecdt_added) + xsdt_mod->Length+=8; + if (asft_added) + xsdt_mod->Length+=8; + if (dmar_added) + xsdt_mod->Length+=8; + if (apic_added) + xsdt_mod->Length+=8; + if (mcfg_added) + xsdt_mod->Length+=8; + + setchecksum((struct acpi_common_header *)xsdt_mod); + } + else + { + drop_xsdt: + + DBG("About to drop XSDT\n"); + + /*FIXME: Now we just hope that if MacOS doesn't find XSDT it reverts to RSDT. + * A Better strategy would be to generate + */ + + rsdp_mod->XsdtAddress=0xffffffffffffffffLL; + verbose("XSDT not found or XSDT incorrect\n"); + } + } + + // Correct the checksum of RSDP + + DBG("RSDP: Original checksum %d, ", rsdp_mod->Checksum); + + setRsdpchecksum(rsdp_mod); + + DBG("New checksum %d\n", rsdp_mod->Checksum); + + if (version) + { + DBG("RSDP: Original extended checksum %d", rsdp_mod->ExtendedChecksum); + + setRsdpXchecksum(rsdp_mod); + + DBG("New extended checksum %d\n", rsdp_mod->ExtendedChecksum); + + } + + verbose("Patched ACPI version %d\n", version+1); + + if (version) + { + /* XXX aserebln why uint32 cast if pointer is uint64 ? */ + acpi20_p = (uint32_t)rsdp_mod; + if (acpi20_p) + Status = addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20"); + } + else + { + /* XXX aserebln why uint32 cast if pointer is uint64 ? */ + acpi10_p = (uint32_t)rsdp_mod; + if (acpi10_p) + Status = addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI"); + } + } + +#if DEBUG_DSDT + printf("Press a key to continue... (DEBUG_DSDT)\n"); + getc(); +#endif + //return (Status == EFI_SUCCESS) ? 1 : 0; + return Status ; +} Index: branches/cparm/i386/modules/ACPIMini/AcpiPatcher.c =================================================================== --- branches/cparm/i386/modules/ACPIMini/AcpiPatcher.c (revision 0) +++ branches/cparm/i386/modules/ACPIMini/AcpiPatcher.c (revision 1122) @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2009 Evan Lojewski. All rights reserved. + * + */ + +/* + * Copyright (c) 2010 cparm . All rights reserved. + * + */ + +#include "libsaio.h" +#include "modules.h" +#include "boot.h" +#include "bootstruct.h" +#include "pci_root.h" +#include "acpi_patcher.h" + +#define kEnableAcpi "EnableAcpiModule" + +void AcpiPatcher_setupEfiConfigurationTable_hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6) +{ + EFI_STATUS *ret = (EFI_STATUS *)arg1; + + // Setup ACPI (mackerintel's patch) + *ret = setupAcpi(); + +} + +void is_ACPI_Patcher_Registred_Hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6){} + +void AcpiPatcher_start() +{ + bool enable = true; + + getBoolForKey(kEnableAcpi, &enable, &bootInfo->bootConfig); + + enable = (execute_hook("isACPIRegistred", NULL, NULL, NULL, NULL, NULL, NULL) != EFI_SUCCESS); + + if (enable) { + register_hook_callback("setupEfiConfigurationTable", &AcpiPatcher_setupEfiConfigurationTable_hook); + register_hook_callback("isACPIRegistred", &is_ACPI_Patcher_Registred_Hook); + + } +} \ No newline at end of file Property changes on: branches/cparm/i386/modules/ACPIMini/AcpiPatcher.c ___________________________________________________________________ Added: svn:executable + * Index: branches/cparm/i386/modules/ACPIMini/aml_generator.h =================================================================== --- branches/cparm/i386/modules/ACPIMini/aml_generator.h (revision 0) +++ branches/cparm/i386/modules/ACPIMini/aml_generator.h (revision 1122) @@ -0,0 +1,65 @@ +/* + * aml_generator.h + * Chameleon + * + * Created by Mozodojo on 20/07/10. + * Copyright 2010 mozo. All rights reserved. + * + */ + +#ifndef __LIBSAIO_AML_GENERATOR_H +#define __LIBSAIO_AML_GENERATOR_H + +#include "libsaio.h" + +#define AML_CHUNK_NONE 0xff +#define AML_CHUNK_ZERO 0x00 +#define AML_CHUNK_ONE 0x01 +#define AML_CHUNK_ALIAS 0x06 +#define AML_CHUNK_NAME 0x08 +#define AML_CHUNK_BYTE 0x0A +#define AML_CHUNK_WORD 0x0B +#define AML_CHUNK_DWORD 0x0C +#define AML_CHUNK_STRING 0x0D +#define AML_CHUNK_QWORD 0x0E +#define AML_CHUNK_SCOPE 0x10 +#define AML_CHUNK_PACKAGE 0x12 + +struct aml_chunk +{ + unsigned char Type; + unsigned int Length; + char* Buffer; + + unsigned int Size; + + struct aml_chunk* Next; + struct aml_chunk* First; + struct aml_chunk* Last; +}; + +static inline bool aml_isvalidchar(char c) +{ + return isupper(c) || isdigit(c) || c == '_'; +}; + +bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node); +struct aml_chunk* aml_create_node(struct aml_chunk* parent); +void aml_destroy_node(struct aml_chunk* node); +struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size); +struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value); +struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value); +struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value); +struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value); +struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name); +struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name); +struct aml_chunk* aml_add_package(struct aml_chunk* parent); +struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2); +unsigned int aml_calculate_size(struct aml_chunk* node); +unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset); +struct aml_chunk* aml_add_package_with_value(struct aml_chunk* parent, uint64_t *lst, int num); +void aml_add_multiple_value(struct aml_chunk* parent, uint64_t *lst, int num); +void aml_add_ressource_t_fxhw(struct aml_chunk* parent, uint64_t *lst); +void aml_add_value(struct aml_chunk* parent, uint64_t val); + +#endif /* !__LIBSAIO_AML_GENERATOR_H */ \ No newline at end of file Index: branches/cparm/i386/modules/ACPIMini/acpi_patcher.h =================================================================== --- branches/cparm/i386/modules/ACPIMini/acpi_patcher.h (revision 0) +++ branches/cparm/i386/modules/ACPIMini/acpi_patcher.h (revision 1122) @@ -0,0 +1,235 @@ +/* + * Copyright 2008 mackerintel + */ + +/* + * Copyright (c) 2010 cparm . All rights reserved. + * + */ + +#ifndef __LIBSAIO_ACPI_PATCHER_H +#define __LIBSAIO_ACPI_PATCHER_H + +#include "libsaio.h" +#include "efi.h" + +#define kDSDT "DSDT" /* acpi_patcher.c */ +#define kRestartFix "RestartFix" /* acpi_patcher.c */ +#define kGeneratePStates "GeneratePStates" /* acpi_patcher.c */ +#define kGenerateCStates "GenerateCStates" /* acpi_patcher.c */ +#define kMaxRatio "MaxBusRatio" /* acpi_patcher.c */ +#define kMinRatio "MinBusRatio" /* acpi_patcher.c */ +#define kQSSDT "quickSSDTsearch" /* acpi_patcher.c */ +#define kSpeedstep "EnableSpeedStep" /* acpi_patcher.c */ +#define kEnableC4State "EnableC4State" /* acpi_patcher.c */ + +#define kFACS "FACS" /* acpi_patcher.c */ +#define kSSDT "SSDT" /* acpi_patcher.c */ +#define kHPET "HPET" /* acpi_patcher.c */ +#define kSBST "SBST" /* acpi_patcher.c */ +#define kECDT "ECDT" /* acpi_patcher.c */ +#define kASFT "ASFT" /* acpi_patcher.c */ +#define kDMAR "DMAR" /* acpi_patcher.c */ +#define kFADT "FADT" /* acpi_patcher.c */ +#define kAPIC "APIC" /* acpi_patcher.c */ +#define kMCFG "MCFG" /* acpi_patcher.c */ +#define kOEMDSDT "oemDSDT" /* acpi_patcher.c */ +#define kOEMSSDT "oemSSDT" /* acpi_patcher.c */ +#define kOEMHPET "oemHPET" /* acpi_patcher.c */ +#define kOEMSBST "oemSBST" /* acpi_patcher.c */ +#define kOEMECDT "oemECDT" /* acpi_patcher.c */ +#define kOEMASFT "oemASFT" /* acpi_patcher.c */ +#define kOEMDMAR "oemDMAR" /* acpi_patcher.c */ +#define kOEMFADT "oemFADT" /* acpi_patcher.c */ +#define kOEMAPIC "oemAPIC" /* acpi_patcher.c */ +#define kOEMMCFG "oemMCFG" /* acpi_patcher.c */ + +#define kUpdateACPI "UpdateACPI" /* acpi_patcher.c */ + +#define kDisableASPM "DisableASPM" /* acpi_patcher.c */ +#define kDisableMSI "DisableMSI" /* acpi_patcher.c */ + +#if UNUSED +#define kGenerateFACS "GenerateFACS" /* acpi_patcher.c */ +#define kOEMFACS "oemFACS" /* acpi_patcher.c */ +#endif + +extern EFI_STATUS setupAcpi(); + +struct p_state +{ + union + { + uint16_t Control; + struct + { + uint8_t VID; // Voltage ID + uint8_t FID; // Frequency ID + }; + }; + + uint8_t CID; // Compare ID + uint32_t Frequency; +}; + +/* + * SIGNATURE_16, SIGNATURE_32, SIGNATURE_64 are extracted from the edk2 project (Base.h), and are under the following license: + * + * Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. + * Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved. + * This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php. + * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + */ + +#define SIGNATURE_16(A, B) ((A) | (B << 8)) + +#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16)) + +#define SIGNATURE_64(A, B, C, D, E, F, G, H) \ +(SIGNATURE_32 (A, B, C, D) | ((uint64_t) (SIGNATURE_32 (E, F, G, H)) << 32)) + +#define ACPI_SIGNATURE_UINT64_LE SIGNATURE_64('R','S','D',' ','P','T','R',' ') + + +/* Per ACPI 3.0a spec */ + +// TODO Migrate +struct acpi_2_rsdp { + char Signature[8]; + uint8_t Checksum; + char OEMID[6]; + uint8_t Revision; + uint32_t RsdtAddress; + uint32_t Length; + uint64_t XsdtAddress; + uint8_t ExtendedChecksum; + char Reserved[3]; +} __attribute__((packed)); + + +#define ACPI_HEADER_CORE \ +char Signature[4]; \ +uint32_t Length; \ +uint8_t Revision; \ +uint8_t Checksum; \ +char OEMID[6]; \ +char OEMTableId[8]; \ +uint32_t OEMRevision; \ +uint32_t CreatorId; \ +uint32_t CreatorRevision; + +struct acpi_common_header { + ACPI_HEADER_CORE +} __attribute__((packed)); + +// TODO Migrate +struct acpi_2_rsdt { + ACPI_HEADER_CORE +} __attribute__((packed)); + +// TODO Migrate +struct acpi_2_xsdt { + ACPI_HEADER_CORE +} __attribute__((packed)); + +// TODO Migrate +struct acpi_2_gas { + uint8_t Address_Space_ID; + uint8_t Register_Bit_Width; + uint8_t Register_Bit_Offset; + uint8_t Access_Size; + uint64_t Address; +} __attribute__((packed)); + +// TODO Migrate +struct acpi_2_ssdt { + ACPI_HEADER_CORE +} __attribute__((packed)); + +// TODO Migrate +struct acpi_2_dsdt { + ACPI_HEADER_CORE +} __attribute__((packed)); + +// TODO Migrate +struct acpi_2_fadt { + ACPI_HEADER_CORE + uint32_t FIRMWARE_CTRL; + uint32_t DSDT; + uint8_t Model; // JrCs + uint8_t PM_Profile; // JrCs + uint16_t SCI_Interrupt; + uint32_t SMI_Command_Port; + uint8_t ACPI_Enable; + uint8_t ACPI_Disable; + uint8_t S4BIOS_Command; + uint8_t PState_Control; + uint32_t PM1A_Event_Block_Address; + uint32_t PM1B_Event_Block_Address; + uint32_t PM1A_Control_Block_Address; + uint32_t PM1B_Control_Block_Address; + uint32_t PM2_Control_Block_Address; + uint32_t PM_Timer_Block_Address; + uint32_t GPE0_Block_Address; + uint32_t GPE1_Block_Address; + uint8_t PM1_Event_Block_Length; + uint8_t PM1_Control_Block_Length; + uint8_t PM2_Control_Block_Length; + uint8_t PM_Timer_Block_Length; + uint8_t GPE0_Block_Length; + uint8_t GPE1_Block_Length; + uint8_t GPE1_Base_Offset; + uint8_t CST_Support; + uint16_t C2_Latency; + uint16_t C3_Latency; + uint16_t CPU_Cache_Size; + uint16_t Cache_Flush_Stride; + uint8_t Duty_Cycle_Offset; + uint8_t Duty_Cycle_Width; + uint8_t RTC_Day_Alarm_Index; + uint8_t RTC_Month_Alarm_Index; + uint8_t RTC_Century_Index; + uint16_t Boot_Flags; + uint8_t Reserved0; + /* Begin Asere */ + //Reset Fix + uint32_t Flags; + struct acpi_2_gas RESET_REG; + uint8_t Reset_Value; + uint8_t Reserved[3]; + + uint64_t X_FIRMWARE_CTRL; + uint64_t X_DSDT; + +#if UNUSED + /* End Asere */ + /*We absolutely don't care about theese fields*/ + uint8_t notimp2[96]; +#else + struct acpi_2_gas X_PM1a_EVT_BLK; + struct acpi_2_gas X_PM1b_EVT_BLK; + struct acpi_2_gas X_PM1a_CNT_BLK; + struct acpi_2_gas X_PM1b_CNT_BLK; + struct acpi_2_gas X_PM2_CNT_BLK; + struct acpi_2_gas X_PM_TMR_BLK; + struct acpi_2_gas X_GPE0_BLK; + struct acpi_2_gas X_GPE1_BLK; +#endif + +} __attribute__((packed)); + +struct acpi_2_facs { + char Signature[4]; + uint32_t Length; + uint32_t hardware_signature; + uint32_t firmware_waking_vector; + uint32_t global_lock; + uint32_t flags; + uint64_t x_firmware_waking_vector; + uint8_t version; + uint8_t Reserved[3]; + uint32_t ospm_flags; + uint8_t Reserved1[24]; +} __attribute__ ((packed)); + +#endif /* !__LIBSAIO_ACPI_PATCHER_H */ Index: branches/cparm/i386/modules/ACPIMini/Makefile =================================================================== --- branches/cparm/i386/modules/ACPIMini/Makefile (revision 0) +++ branches/cparm/i386/modules/ACPIMini/Makefile (revision 1122) @@ -0,0 +1,91 @@ + +MODULE_NAME = AcpiPatcher +MODULE_VERSION = "1.0.0" +MODULE_COMPAT_VERSION = "1.0.0" +MODULE_START = _$(MODULE_NAME)_start +MODULE_DEPENDENCIES = + +DIR = AcpiPatcher + +include ../../MakePaths.dir + +OBJROOT=../../../obj/i386/modules/$(DIR) +SYMROOT=../../../sym/i386/modules/ +DSTROOT=../../../dst/i386/modules/ + + +UTILDIR = ../../util +LIBSADIR = ../../libsa +LIBSAIODIR = ../../libsaio +BOOT2DIR = ../../boot2 + +INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone + +OPTIM = -Os -Oz +DEBUG = -DNOTHING +CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost \ + -D__ARCHITECTURE__=\"i386\" -DSAIO_INTERNAL_USER \ + -DRCZ_COMPRESSED_FILE_SUPPORT $(DEBUG) \ + -fno-builtin $(OMIT_FRAME_POINTER_CFLAG) \ + -mpreferred-stack-boundary=2 -fno-align-functions -fno-stack-protector \ + -march=pentium4 -msse2 -mfpmath=sse -msoft-float -fno-common #-mdynamic-no-pic -Wextra -Wpacked -Wpadded -Wunreachable-code -Winline -Wunsafe-loop-optimizations -funsafe-loop-optimizations -Wconversion + +DEFINES= +CONFIG = hd +INC = -I. -I.. -I$(SYMROOT) -I$(UTILDIR) -I$(LIBSADIR) -I$(LIBSAIODIR) -I$(BOOT2DIR) +ifneq "" "$(wildcard /bin/mkdirs)" + MKDIRS = /bin/mkdirs +else + MKDIRS = /bin/mkdir -p +endif +AS = as +LD = ld +# LIBS= -lc_static +LIBS= + +VPATH = $(OBJROOT):$(SYMROOT) + +ACPI_PATCHER_OBJS = AcpiPatcher.o aml_generator.o acpi_patcher.o + + +SFILES = +CFILES = +HFILES = +EXPORTED_HFILES = +INSTALLED_HFILES = +OTHERFILES = Makefile +ALLSRC = $(SFILES) $(CFILES) \ + $(HFILES) $(OTHERFILES) +DIRS_NEEDED = $(OBJROOT) $(SYMROOT) + +all embedtheme: ${ACPI_PATCHER_OBJS} dylib + + +dylib: + ld -arch i386 \ + -undefined dynamic_lookup \ + -alias $(MODULE_START) start \ + -dylib -read_only_relocs suppress \ + -S -x -Z -dead_strip_dylibs \ + -no_uuid \ + -current_version $(MODULE_VERSION) -compatibility_version $(MODULE_COMPAT_VERSION) \ + -final_output $(MODULE_NAME) \ + $(OBJROOT)/AcpiPatcher.o \ + $(OBJROOT)/aml_generator.o \ + $(OBJROOT)/acpi_patcher.o \ + -o $(SYMROOT)/$(MODULE_NAME).dylib + +AcpiPatcher.o: + $(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c "AcpiPatcher.c" $(INC) -o "$(OBJROOT)/AcpiPatcher.o" + +aml_generator.o: + $(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c "aml_generator.c" $(INC) -o "$(OBJROOT)/aml_generator.o" + +acpi_patcher.o: + $(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c "acpi_patcher.c" $(INC) -o "$(OBJROOT)/acpi_patcher.o" + + +include ../../MakeInc.dir + +# dependencies +-include $(OBJROOT)/Makedep Index: branches/cparm/i386/modules/ACPICodec/ACPICodec.c =================================================================== --- branches/cparm/i386/modules/ACPICodec/ACPICodec.c (revision 1121) +++ branches/cparm/i386/modules/ACPICodec/ACPICodec.c (revision 1122) @@ -28,23 +28,7 @@ bool enable = true; getBoolForKey(kEnableAcpi, &enable, &bootInfo->bootConfig) ; - /* - * This method is not perfect (symbols collisions between two modules with that provide the same service is still possible, - * (as well as two module with a different service but there is more chance of collisions if dthey do the same thing) - * even if one of them have been disabled by this method and have no hook registred), will be deprecated soon. - * - * Possible solutions: - * - * 1 - check the symbols list each time a symbols is loaded to avoid double symbol (slow, may be buggy) - * - * 2 - categorize all symbols by callers (hard to implement) - * - * 3 - ????, will work great at least for modules with the same service - * - * - * - */ - enable = (execute_hook("isACPIRegistred", NULL, NULL, NULL, NULL, NULL, NULL) != EFI_SUCCESS); + enable = (execute_hook("isACPIRegistred", NULL, NULL, NULL, NULL, NULL, NULL) != EFI_SUCCESS); if (enable) { register_hook_callback("setupEfiConfigurationTable", &ACPICodec_setupEfiConfigurationTable_hook);