␉int i;␊ |
␉for (i = 0; i < 4; i++)␊ |
␉{␊ |
␉␉if ((table[i] &~0x20) != (sgn[i] &~0x20))␊ |
␉␉if ((table[i] & ~0x20) != (sgn[i] & ~0x20))␊ |
␉␉{␊ |
␉␉␉return false;␊ |
␉␉}␊ |
|
␉␉if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE)␊ |
␉␉{␊ |
␉␉␉uint8_t csum = checksum8(acpi_addr, 20);␊ |
␉␉␉if(csum == 0)␊ |
␉␉␉if (csum == 0)␊ |
␉␉␉{␊ |
␉␉␉// Only return the table if it is a true version 1.0 table (Revision 0)␊ |
␉␉␉␉if(((struct acpi_2_rsdp*)acpi_addr)->Revision == 0)␊ |
|
␊ |
␉if (fd >= 0)␊ |
␉{␊ |
␉␉void *tableAddr = (void*)AllocateKernelMemory(file_size(fd));␊ |
␉␉void *tableAddr = (void *)AllocateKernelMemory(file_size(fd));␊ |
␉␉if (tableAddr)␊ |
␉␉{␊ |
␉␉␉if (read(fd, tableAddr, file_size(fd)) != file_size(fd))␊ |
␉␉␉{␊ |
␉␉␉␉DBG("Couldn't read table %s\n",dirspec);␊ |
␉␉␉␉DBG("Couldn't read table %s\n", dirspec);␊ |
␉␉␉␉free(tableAddr);␊ |
␉␉␉␉close(fd);␊ |
␉␉␉␉return NULL;␊ |
|
␉␉␉return tableAddr;␊ |
␉␉}␊ |
␉␉close(fd);␊ |
␉␉DBG("Couldn't allocate memory for table \n", dirspec);␊ |
␉} ␊ |
␉␉DBG("Couldn't allocate memory for table: %s.\n", dirspec);␊ |
␉}␊ |
␉//printf("Couldn't find table %s\n", filename);␊ |
␉return NULL;␊ |
}␊ |
␊ |
uint8_t acpi_cpu_count␉= 0;␊ |
uint32_t acpi_cpu_p_blk␉= 0;␊ |
char *acpi_cpu_name[32];␊ |
␊ |
void get_acpi_cpu_names(unsigned char *dsdt, uint32_t length)␊ |
{␊ |
␉uint32_t i;␊ |
␊ |
␉DBG("ACPIpatcher: start finding cpu names. Length %d\n", length);␊ |
␊ |
␉for (i=0; i<length-7; i++)␊ |
␉{␊ |
␉␉if (dsdt[i] == 0x5B && dsdt[i+1] == 0x83) // ProcessorOP␊ |
␉␉{␊ |
␉␉␉DBG("ACPIpatcher: DSDT[%X%X]\n", dsdt[i], dsdt[i+1]);␊ |
␊ |
␉␉␉uint32_t offset = i + 3 + (dsdt[i+2] >> 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;␊ |
␉␉␉␉␉DBG("ACPIpatcher: 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;␊ |
␊ |
␉␉␉␉if (acpi_cpu_count == 0)␊ |
␉␉␉␉{␊ |
␉␉␉␉␉acpi_cpu_p_blk = dsdt[i] | (dsdt[i+1] << 8);␊ |
␉␉␉␉}␊ |
␊ |
␉␉␉␉DBG("ACPIpatcher: 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;␊ |
␉␉␉␉}␊ |
␉␉␉}␊ |
␉␉}␊ |
␉}␊ |
␊ |
␉DBG("ACPIpatcher: finished finding cpu names. Found: %d.\n", acpi_cpu_count);␊ |
}␊ |
␊ |
struct acpi_2_fadt *patch_fadt(struct acpi_2_fadt *fadt, struct acpi_2_dsdt *new_dsdt)␊ |
{␊ |
␉extern void setupSystemType();␊ |
|
␉}␊ |
␉else␊ |
␉{␊ |
␉␉DBG("Not an Intel platform: Restart Fix not applied !!!\n");␊ |
␉␉DBG("\tNot an Intel platform, FACP Restart Fix will not be applied!\n");␊ |
␉␉fix_restart = false;␊ |
␉}␊ |
␊ |
|
␉}␊ |
␊ |
␉// Allocate new fadt table␊ |
␉if (fadt->Length < 0x84 && fadt_rev2_needed)␊ |
␉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)␊ |
␉␉fadt_mod->Revision = 0x02; // FACP rev 2 (ACPI 1.0B MS extensions)␊ |
␉}␊ |
␉else␊ |
␉{␊ |
|
␉// because we need to take care of FACP original content, if it is correct.␊ |
␉setupSystemType();␊ |
␊ |
␉// Patch FADT to fix restart␊ |
␉// Patch FACP to fix restart␊ |
␉if (fix_restart)␊ |
␉{␊ |
␉␉if (fix_restart_ps2)␊ |
|
␉␉␉fadt_mod->Reset_AccessWidth␉= 0x01; // Byte access␊ |
␉␉␉fadt_mod->Reset_Address␉␉= 0x64; // Address of the register␊ |
␉␉␉fadt_mod->Reset_Value␉␉= 0xfe; // Value to write to reset the system␊ |
␉␉␉DBG("FADT: PS2 Restart Fix applied!\n");␊ |
␉␉␉DBG("\tFACP PS2 Restart Fix applied!\n");␊ |
␉␉}␊ |
␉␉else␊ |
␉␉{␊ |
|
␉␉␉fadt_mod->Reset_AccessWidth␉= 0x01; // Byte access␊ |
␉␉␉fadt_mod->Reset_Address␉␉= 0x0cf9; // Address of the register␊ |
␉␉␉fadt_mod->Reset_Value␉␉= 0x06; // Value to write to reset the system␊ |
␉␉␉DBG("FADT: ACPI Restart Fix applied!\n");␊ |
␉␉␉DBG("\tFACP Restart Fix applied!\n");␊ |
␉␉}␊ |
␊ |
␉}␊ |
␊ |
␉// Bungo: Save Hardware Signature (machine-signature)␊ |
␉if ((fadt_mod->FIRMWARE_CTRL > 0) && (fadt_mod->FIRMWARE_CTRL < 0xFFFFFFFF) && (((struct acpi_2_facs *)fadt_mod->FIRMWARE_CTRL)->Length >= 64))␊ |
␉if ((fadt_mod->FACS > 0) && (fadt_mod->FACS < 0xFFFFFFFF) && (((struct acpi_2_facs *)fadt_mod->FACS)->Length >= 64))␊ |
␉{␊ |
␉␉Platform.HWSignature = ((struct acpi_2_facs *)fadt_mod->FIRMWARE_CTRL)->HWSignature;␊ |
␉␉Platform.HWSignature = ((struct acpi_2_facs *)fadt_mod->FACS)->HWSignature;␊ |
␉␉DBG("\tHardware Signature=0x%08X: using.\n", Platform.HWSignature);␊ |
␉}␊ |
␉else␊ |
|
␉␉{␊ |
␉␉␉uint32_t *rsdt_entries;␊ |
␉␉␉int rsdt_entries_num;␊ |
␉␉␉int dropoffset=0, i;␊ |
␉␉␉int dropoffset = 0, i;␊ |
␊ |
␉␉␉// mozo: using malloc cos I didn't found how to free already allocated kernel memory␊ |
␉␉␉rsdt_mod = (struct acpi_2_rsdt *)malloc(rsdt->Length);␊ |
|
␉␉␉rsdp_mod->RsdtAddress = (uint32_t)rsdt_mod;␊ |
␉␉␉rsdt_entries_num = (rsdt_mod->Length - sizeof(struct acpi_2_rsdt)) / 4;␊ |
␉␉␉rsdt_entries = (uint32_t *)(rsdt_mod + 1);␊ |
␉␉␉for (i = 0;i < rsdt_entries_num;i++)␊ |
␉␉␉for (i = 0; i < rsdt_entries_num; i++)␊ |
␉␉␉{␊ |
␉␉␉␉char *table=(char *)(rsdt_entries[i]);␊ |
␉␉␉␉if (!table)␊ |
|
␉␉␉␉␉DBG("Custom DSDT table was found\n");␊ |
␉␉␉␉␉if(new_dsdt)␊ |
␉␉␉␉␉{␊ |
␉␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;␊ |
␉␉␉␉␉␉rsdt_entries[i-dropoffset] = (uint32_t)new_dsdt;␊ |
␉␉␉␉␉}␊ |
␊ |
␉␉␉␉␉continue;␊ |
|
␉␉␉␉␉// Generate _CST SSDT␊ |
␉␉␉␉␉if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod)))␊ |
␉␉␉␉␉{␊ |
␉␉␉␉␉␉DBG("C-States generated\n");␊ |
␉␉␉␉␉␉DBG("\tC-States generated.\n");␊ |
␉␉␉␉␉␉generate_cstates = false; // Generate SSDT only once!␊ |
␉␉␉␉␉␉ssdt_count++;␊ |
␉␉␉␉␉}␊ |
|
␉␉␉␉␉// Generating _PSS SSDT␊ |
␉␉␉␉␉if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT)))␊ |
␉␉␉␉␉{␊ |
␉␉␉␉␉␉DBG("P-States generated\n");␊ |
␉␉␉␉␉␉DBG("\tP-States generated.\n");␊ |
␉␉␉␉␉␉generate_pstates = false; // Generate SSDT only once!␊ |
␉␉␉␉␉␉ssdt_count++;␊ |
␉␉␉␉␉}␊ |
|
␊ |
␉␉␉␉for (j=0; j<ssdt_count; j++)␊ |
␉␉␉␉{␊ |
␉␉␉␉␉rsdt_entries[i-dropoffset+j]=(uint32_t)new_ssdt[j];␊ |
␉␉␉␉␉rsdt_entries[i-dropoffset+j] = (uint32_t)new_ssdt[j];␊ |
␉␉␉␉}␊ |
␊ |
␉␉␉␉DBG("RSDT: Added %d SSDT table(s)\n", ssdt_count);␊ |
|
␉␉␉{␊ |
␉␉␉␉uint64_t *xsdt_entries;␊ |
␉␉␉␉int xsdt_entries_num, i;␊ |
␉␉␉␉int dropoffset=0;␊ |
␉␉␉␉int dropoffset = 0;␊ |
␊ |
␉␉␉␉// mozo: using malloc cos I didn't found how to free already allocated kernel memory␊ |
␉␉␉␉xsdt_mod=(struct acpi_2_xsdt*)malloc(xsdt->Length);␊ |
␉␉␉␉xsdt_mod = (struct acpi_2_xsdt *)malloc(xsdt->Length);␊ |
␉␉␉␉memcpy(xsdt_mod, xsdt, xsdt->Length);␊ |
␊ |
␉␉␉␉rsdp_mod->XsdtAddress = (uint32_t)xsdt_mod;␊ |
␉␉␉␉xsdt_entries_num = (xsdt_mod->Length - sizeof(struct acpi_2_xsdt)) / 8;␊ |
␉␉␉␉xsdt_entries = (uint64_t *)(xsdt_mod + 1);␊ |
␉␉␉␉for (i = 0;i < xsdt_entries_num;i++)␊ |
␉␉␉␉for (i = 0;i < xsdt_entries_num; i++)␊ |
␉␉␉␉{␊ |
␉␉␉␉␉char *table = (char *)((uint32_t)(xsdt_entries[i]));␊ |
␉␉␉␉␉if (!table)␊ |
|
␉␉␉␉␉␉if (new_dsdt)␊ |
␉␉␉␉␉␉{␊ |
␉␉␉␉␉␉␉xsdt_entries[i-dropoffset] = (uint32_t)new_dsdt;␊ |
␉␉␉␉␉␉␉DBG("custom table added\n");␊ |
␉␉␉␉␉␉␉DBG("custom table added.\n");␊ |
␉␉␉␉␉␉}␊ |
␊ |
␉␉␉␉␉␉DBG("TABLE %c%c%c%c@%x \n", table[0],table[1],table[2],table[3],xsdt_entries[i]);␊ |
|
␉␉␉␉␉␉}␊ |
␊ |
␉␉␉␉␉␉fadt_mod = patch_fadt(fadt, new_dsdt);␊ |
␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;␊ |
␉␉␉␉␉␉xsdt_entries[i - dropoffset] = (uint32_t)fadt_mod;␊ |
␊ |
␉␉␉␉␉␉// DBG("TABLE %c%c%c%c@%x \n", table[0],table[1],table[2],table[3],xsdt_entries[i]);␊ |
␊ |
␉␉␉␉␉␉// Generate _CST SSDT␊ |
␉␉␉␉␉␉if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod)))␊ |
␉␉␉␉␉␉{␊ |
␉␉␉␉␉␉␉DBG("C-States generated\n");␊ |
␉␉␉␉␉␉␉DBG("\tC-States generated.\n");␊ |
␉␉␉␉␉␉␉generate_cstates = false; // Generate SSDT only once!␊ |
␉␉␉␉␉␉␉ssdt_count++;␊ |
␉␉␉␉␉␉}␊ |
|
␉␉␉␉␉␉// Generating _PSS SSDT␊ |
␉␉␉␉␉␉if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT)))␊ |
␉␉␉␉␉␉{␊ |
␉␉␉␉␉␉␉DBG("P-States generated\n");␊ |
␉␉␉␉␉␉␉DBG("\tP-States generated.\n");␊ |
␉␉␉␉␉␉␉generate_pstates = false; // Generate SSDT only once!␊ |
␉␉␉␉␉␉␉ssdt_count++;␊ |
␉␉␉␉␉␉}␊ |
|
␊ |
␉␉␉␉␉for (j=0; j<ssdt_count; j++)␊ |
␉␉␉␉␉{␊ |
␉␉␉␉␉␉xsdt_entries[i-dropoffset+j]=(uint32_t)new_ssdt[j];␊ |
␉␉␉␉␉␉xsdt_entries[i - dropoffset + j] = (uint32_t)new_ssdt[j];␊ |
␉␉␉␉␉}␊ |
␊ |
␉␉␉␉␉verbose("Added %d SSDT table(s) into XSDT\n", ssdt_count);␊ |
|
␉␉␉acpi10_p = (uint64_t)(uint32_t)rsdp_mod;␊ |
␉␉␉addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");␊ |
␉␉}␊ |
␉␉DBG("ACPI version %d patching finished\n\n", version+1);␊ |
␉␉DBG("ACPI version %d patching finished\n\n", version + 1);␊ |
␉}␊ |
#if DEBUG_ACPI␊ |
␉printf("Press a key to continue... (DEBUG_ACPI)\n");␊ |