Index: branches/rekursor/i386/libsaio/Makefile =================================================================== --- branches/rekursor/i386/libsaio/Makefile (revision 62) +++ branches/rekursor/i386/libsaio/Makefile (revision 63) @@ -39,7 +39,7 @@ ufs.o ufs_byteorder.o \ vbe.o nbp.o hfs.o hfs_compare.o \ xml.o ntfs.o msdos.o md5c.o device_tree.o \ - cpu.o platform.o dsdt_patcher.o \ + cpu.o platform.o acpi.o dsdt_patcher.o \ smbios_patcher.o fake_efi.o ext2fs.o \ hpet.o spd.o usb.o pci_setup.o \ device_inject.o nvidia.o ati.o pci_root.o \ Index: branches/rekursor/i386/libsaio/dsdt_patcher.c =================================================================== --- branches/rekursor/i386/libsaio/dsdt_patcher.c (revision 62) +++ branches/rekursor/i386/libsaio/dsdt_patcher.c (revision 63) @@ -23,1195 +23,750 @@ #define DBG(x...) #endif -/* Gets the ACPI 1.0 RSDP address */ -static struct acpi_2_rsdp* getAddressOfAcpiTable() +struct acpi_2_fadt * +patch_fadt(struct acpi_2_fadt *fadt, void *new_dsdt, bool UpdateFADT) { - /* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */ + extern void setupSystemType(); - void *acpi_addr = (void*)ACPI_RANGE_START; - for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16) - { - if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE) - { - uint8_t csum = checksum8(acpi_addr, 20); - 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) - return acpi_addr; - } - } + struct acpi_2_fadt *fadt_mod; + struct acpi_2_fadt *fadt_file = (struct acpi_2_fadt *)acpiLoadTable(kFADT); + bool fadt_rev2_needed = false; + bool fix_restart; + const char * value; + + // 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"); + fix_restart = false; } - return NULL; -} -/* Gets the ACPI 2.0 RSDP address */ -static struct acpi_2_rsdp* getAddressOfAcpi20Table() -{ - /* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */ - - void *acpi_addr = (void*)ACPI_RANGE_START; - for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16) + 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))))) { - if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE) + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(sizeof(struct acpi_2_fadt)); + + if (fadt_file) + memcpy(fadt_mod, fadt_file, fadt_file->Length); + else + memcpy(fadt_mod, fadt, fadt->Length); + + fadt_mod->Length = sizeof(struct acpi_2_fadt); + fadt_mod->Revision = 0x04; // FADT rev 4 + fadt_mod->RESET_REG = acpiFillGASStruct(0, 0); + fadt_mod->RESET_VALUE = 0; + fadt_mod->Reserved2[0] = 0; + fadt_mod->Reserved2[1] = 0; + fadt_mod->Reserved2[2] = 0; + fadt_mod->X_PM1a_EVT_BLK = acpiFillGASStruct(fadt_mod->PM1a_EVT_BLK, fadt_mod->PM1_EVT_LEN); + fadt_mod->X_PM1b_EVT_BLK = acpiFillGASStruct(fadt_mod->PM1b_EVT_BLK, fadt_mod->PM1_EVT_LEN); + fadt_mod->X_PM1a_CNT_BLK = acpiFillGASStruct(fadt_mod->PM1a_CNT_BLK, fadt_mod->PM1_CNT_LEN); + fadt_mod->X_PM1b_CNT_BLK = acpiFillGASStruct(fadt_mod->PM1b_CNT_BLK, fadt_mod->PM1_CNT_LEN); + fadt_mod->X_PM2_CNT_BLK = acpiFillGASStruct(fadt_mod->PM2_CNT_BLK, fadt_mod->PM2_CNT_LEN); + fadt_mod->X_PM_TMR_BLK = acpiFillGASStruct(fadt_mod->PM_TMR_BLK, fadt_mod->PM_TMR_LEN); + fadt_mod->X_GPE0_BLK = acpiFillGASStruct(fadt_mod->GPE0_BLK, fadt_mod->GPE0_BLK_LEN); + fadt_mod->X_GPE1_BLK = acpiFillGASStruct(fadt_mod->GPE1_BLK, fadt_mod->GPE1_BLK_LEN); + verbose("Converted ACPI V%d FADT to ACPI V4 FADT\n", (fadt_file) ? fadt_file->Revision : fadt->Revision); + } else { + if (((!fadt_file) && ((fadt->Length < 0x84) && (fadt_rev2_needed))) || + ((fadt_file) && ((fadt_file->Length < 0x84) && (fadt_rev2_needed)))) { - uint8_t csum = checksum8(acpi_addr, 20); + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84); - /* 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 (fadt_file) + memcpy(fadt_mod, fadt_file, fadt_file->Length); + else + memcpy(fadt_mod, fadt, fadt->Length); - if(csum == 0 && (((struct acpi_2_rsdp*)acpi_addr)->Revision > 0)) + fadt_mod->Length = 0x84; + fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions) + } + else + { + if (fadt_file) { - uint8_t csum2 = checksum8(acpi_addr, sizeof(struct acpi_2_rsdp)); - if(csum2 == 0) - return acpi_addr; + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt_file->Length); + memcpy(fadt_mod, fadt_file, fadt_file->Length); + } else { + fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length); + memcpy(fadt_mod, fadt, fadt->Length); } } } - return NULL; -} + // Determine system type / PM_Model + if ( (value=getStringForKey(kSystemType, &bootInfo->bootConfig))!=NULL) + { + if (Platform.Type > 6) + { + if(fadt_mod->Preferred_PM_Profile<=6) + Platform.Type = fadt_mod->Preferred_PM_Profile; // get the fadt if correct + else + Platform.Type = 1; /* Set a fixed value (Desktop) */ + verbose("Error: system-type must be 0..6. Defaulting to %d !\n", Platform.Type); + } + else + Platform.Type = (unsigned char) strtoul(value, NULL, 10); + } + // Set Preferred_PM_Profile from System-type if only if user wanted this value to be forced + if (fadt_mod->Preferred_PM_Profile != Platform.Type) + { + if (value) + { // user has overriden the SystemType so take care of it in FACP + verbose("FADT: changing Preferred_PM_Profile from 0x%02x to 0x%02x\n", fadt_mod->Preferred_PM_Profile, Platform.Type); + fadt_mod->Preferred_PM_Profile = Platform.Type; + } + else + { // Preferred_PM_Profile has a different value and no override has been set, so reflect the user value to ioregs + Platform.Type = fadt_mod->Preferred_PM_Profile <= 6 ? fadt_mod->Preferred_PM_Profile : 1; + } + } + // We now have to write the systemm-type in ioregs: we cannot do it before in setupDeviceTree() + // because we need to take care of facp original content, if it is correct. + setupSystemType(); -/** The folowing ACPI Table search algo. should be reused anywhere needed:*/ -int search_and_get_acpi_fd(const char * key, const char ** outDirspec) -{ - int fd=0; - const char * overriden_pathname=NULL; - char filename[64]; - static char dirspec[512]=""; - int len=0,i=0; - - sprintf(filename, "%s.aml", key); - - /// Take in account user overriding for 'DSDT'.aml table - // and try to find .aml at the same place - if (getValueForKey("DSDT", &overriden_pathname, &len, - &bootInfo->bootConfig) && len>0) + // Patch FADT to fix restart + if (fix_restart) { - strcpy(dirspec, overriden_pathname); - for (i=len-1; i>=0; i--) - { - if (dirspec[i]=='/') - { - dirspec[i+1]='\0'; - strcat(dirspec, filename); - break; - } - else if (i==0) // no '/' found copy filename and seek in current directory - { - strcpy(dirspec, filename); - break; - } - } - fd=open (dirspec,0); - if (fd>=0) goto success_fd; + fadt_mod->Flags|= 0x400; + fadt_mod->RESET_REG = acpiFillGASStruct(0x0cf9, 1); + fadt_mod->RESET_VALUE = 0x06; + verbose("FADT: Restart Fix applied !\n"); } - // Start searching any potential location for ACPI Table - sprintf(dirspec, "/%s", filename); // start searching root - fd=open (dirspec,0); - if (fd>=0) goto success_fd; + // Patch FACS Address + 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 - sprintf(dirspec, "%s", filename); // start current dir - fd=open (dirspec,0); - if (fd>=0) goto success_fd; + // Patch DSDT Address + DBG("DSDT: Old @%x,%x, ",fadt_mod->DSDT,fadt_mod->X_DSDT); - sprintf(dirspec,"/Extra/%s",filename); - fd=open (dirspec,0); - if (fd>=0) goto success_fd; + 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; - sprintf(dirspec,"bt(0,0)/Extra/%s",filename); - fd=open (dirspec,0); - if (fd>=0) goto success_fd; + DBG("New @%x,%x\n",fadt_mod->DSDT,fadt_mod->X_DSDT); - // NOT FOUND: - verbose("ACPI Table not found: %s\n", filename); - if (outDirspec) *outDirspec = ""; - return -1; - // FOUND -success_fd: - if (outDirspec) *outDirspec = dirspec; - return fd; -} + // Correct the checksum + fadt_mod->Checksum=0; + fadt_mod->Checksum=256-checksum8(fadt_mod,fadt_mod->Length); -void *loadACPITable (const char * key) -{ - void *tableAddr; - const char * dirspec=NULL; - - int fd = search_and_get_acpi_fd(key, &dirspec); - - if (fd>=0) - { - 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; - } - - DBG("Table %s read and stored at: %x\n", dirspec, tableAddr); - close (fd); - return tableAddr; - } - close (fd); - } - printf("Couldn't allocate memory for table %s\n", dirspec); - return NULL; + return fadt_mod; } -void *loadSSDTTable(int ssdt_number) -{ - void *tableAddr; - int fd = -1; - char dirspec[512]; - char filename[512]; - const char * overriden_pathname=NULL; - int len=0; - - sprintf(filename, "SSDT-%d.aml", ssdt_number); - - // 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(dirspec, "%s-%d.aml", overriden_pathname, ssdt_number); // start searching root - //printf("Using custom %s path %s\n", key, dirspec); - //getc(); - } - else - sprintf(dirspec, "/%s", filename); // start searching root - - fd=open (dirspec,0); - - if (fd<0) - { // Check Extra on booting partition - //verbose("Searching for %s.aml file ...\n", key); - sprintf(dirspec,"/Extra/%s",filename); - fd=open (dirspec,0); - if (fd<0) - { // Fall back to booter partition - sprintf(dirspec,"bt(0,0)/Extra/%s",filename); - fd=open (dirspec,0); - if (fd<0) - { - verbose("SSDT Table not found: %s\n", filename); - return NULL; - } - } - } - - 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; - } - - 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; -} - -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, void *new_dsdt, bool UpdateFADT) -{ - extern void setupSystemType(); - - 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; - const char * value; - - // 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"); - fix_restart = false; - } - - 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))))) - { - fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(sizeof(struct acpi_2_fadt)); - - if (fadt_file) - memcpy(fadt_mod, fadt_file, fadt_file->Length); - else - memcpy(fadt_mod, fadt, fadt->Length); - - fadt_mod->Length = sizeof(struct acpi_2_fadt); - fadt_mod->Revision = 0x04; // FADT rev 4 - fadt_mod->RESET_REG = FillGASStruct(0, 0); - fadt_mod->RESET_VALUE = 0; - fadt_mod->Reserved2[0] = 0; - fadt_mod->Reserved2[1] = 0; - fadt_mod->Reserved2[2] = 0; - fadt_mod->X_PM1a_EVT_BLK = FillGASStruct(fadt_mod->PM1a_EVT_BLK, fadt_mod->PM1_EVT_LEN); - fadt_mod->X_PM1b_EVT_BLK = FillGASStruct(fadt_mod->PM1b_EVT_BLK, fadt_mod->PM1_EVT_LEN); - fadt_mod->X_PM1a_CNT_BLK = FillGASStruct(fadt_mod->PM1a_CNT_BLK, fadt_mod->PM1_CNT_LEN); - fadt_mod->X_PM1b_CNT_BLK = FillGASStruct(fadt_mod->PM1b_CNT_BLK, fadt_mod->PM1_CNT_LEN); - fadt_mod->X_PM2_CNT_BLK = FillGASStruct(fadt_mod->PM2_CNT_BLK, fadt_mod->PM2_CNT_LEN); - fadt_mod->X_PM_TMR_BLK = FillGASStruct(fadt_mod->PM_TMR_BLK, fadt_mod->PM_TMR_LEN); - fadt_mod->X_GPE0_BLK = FillGASStruct(fadt_mod->GPE0_BLK, fadt_mod->GPE0_BLK_LEN); - fadt_mod->X_GPE1_BLK = FillGASStruct(fadt_mod->GPE1_BLK, fadt_mod->GPE1_BLK_LEN); - verbose("Converted ACPI V%d FADT to ACPI V4 FADT\n", (fadt_file) ? fadt_file->Revision : fadt->Revision); - } else { - if (((!fadt_file) && ((fadt->Length < 0x84) && (fadt_rev2_needed))) || - ((fadt_file) && ((fadt_file->Length < 0x84) && (fadt_rev2_needed)))) - { - fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84); - - if (fadt_file) - memcpy(fadt_mod, fadt_file, fadt_file->Length); - else - memcpy(fadt_mod, fadt, fadt->Length); - - fadt_mod->Length = 0x84; - fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions) - } - else - { - if (fadt_file) - { - fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt_file->Length); - memcpy(fadt_mod, fadt_file, fadt_file->Length); - } else { - fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length); - memcpy(fadt_mod, fadt, fadt->Length); - } - } - } - // Determine system type / PM_Model - if ( (value=getStringForKey(kSystemType, &bootInfo->bootConfig))!=NULL) - { - if (Platform.Type > 6) - { - if(fadt_mod->Preferred_PM_Profile<=6) - Platform.Type = fadt_mod->Preferred_PM_Profile; // get the fadt if correct - else - Platform.Type = 1; /* Set a fixed value (Desktop) */ - verbose("Error: system-type must be 0..6. Defaulting to %d !\n", Platform.Type); - } - else - Platform.Type = (unsigned char) strtoul(value, NULL, 10); - } - // Set Preferred_PM_Profile from System-type if only if user wanted this value to be forced - if (fadt_mod->Preferred_PM_Profile != Platform.Type) - { - if (value) - { // user has overriden the SystemType so take care of it in FACP - verbose("FADT: changing Preferred_PM_Profile from 0x%02x to 0x%02x\n", fadt_mod->Preferred_PM_Profile, Platform.Type); - fadt_mod->Preferred_PM_Profile = Platform.Type; - } - else - { // Preferred_PM_Profile has a different value and no override has been set, so reflect the user value to ioregs - Platform.Type = fadt_mod->Preferred_PM_Profile <= 6 ? fadt_mod->Preferred_PM_Profile : 1; - } - } - // We now have to write the systemm-type in ioregs: we cannot do it before in setupDeviceTree() - // because we need to take care of facp original content, if it is correct. - setupSystemType(); - - // 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"); - } - - // Patch FACS Address - 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 - - // Patch DSDT Address - DBG("DSDT: Old @%x,%x, ",fadt_mod->DSDT,fadt_mod->X_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; - - DBG("New @%x,%x\n",fadt_mod->DSDT,fadt_mod->X_DSDT); - - // Correct the checksum - fadt_mod->Checksum=0; - fadt_mod->Checksum=256-checksum8(fadt_mod,fadt_mod->Length); - - return fadt_mod; -} - /* Setup ACPI without replacing DSDT. */ int setupAcpiNoMod() { -// addConfigurationTable(&gEfiAcpiTableGuid, getAddressOfAcpiTable(), "ACPI"); -// addConfigurationTable(&gEfiAcpi20TableGuid, getAddressOfAcpi20Table(), "ACPI_20"); - /* XXX aserebln why uint32 cast if pointer is uint64 ? */ - acpi10_p = (uint32_t)getAddressOfAcpiTable(); - acpi20_p = (uint32_t)getAddressOfAcpi20Table(); - addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI"); - if(acpi20_p) addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20"); - return 1; + // addConfigurationTable(&gEfiAcpiTableGuid, acpiGetAddressOfTable10(), "ACPI"); + // addConfigurationTable(&gEfiAcpi20TableGuid, acpiGetAddressOfTable20(), "ACPI_20"); + /* XXX aserebln why uint32 cast if pointer is uint64 ? */ + acpi10_p = (uint32_t) acpiGetAddressOfTable10(); + acpi20_p = (uint32_t) acpiGetAddressOfTable20(); + addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI"); + if(acpi20_p) addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20"); + return 1; } + /* Setup ACPI. Replace DSDT if DSDT.aml is found */ int setupAcpi(void) { - int version; - 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[30]; + int version; + void *new_dsdt=NULL, *new_content=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 drop_ssdt=false, drop_hpet=false, drop_slic=false, drop_sbst=false, drop_ecdt=false, drop_asft=false, drop_dmar=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 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; - int curssdt=0, loadtotssdt=0, totssdt=0, newtotssdt=0; + int curssdt=0, loadtotssdt=0, totssdt=0, newtotssdt=0; - { - bool tmpval; + { + bool tmpval; - drop_ssdt=getBoolForKey(kDropSSDT, &tmpval, &bootInfo->bootConfig)&&tmpval; - drop_hpet=getBoolForKey(kDropHPET, &tmpval, &bootInfo->bootConfig)&&tmpval; - drop_slic=getBoolForKey(kDropSLIC, &tmpval, &bootInfo->bootConfig)&&tmpval; - drop_sbst=getBoolForKey(kDropSBST, &tmpval, &bootInfo->bootConfig)&&tmpval; - drop_ecdt=getBoolForKey(kDropECDT, &tmpval, &bootInfo->bootConfig)&&tmpval; - drop_asft=getBoolForKey(kDropASFT, &tmpval, &bootInfo->bootConfig)&&tmpval; - drop_dmar=getBoolForKey(kDropDMAR, &tmpval, &bootInfo->bootConfig)&&tmpval; + update_acpi=getBoolForKey(kUpdateACPI, &tmpval, &bootInfo->bootConfig)&&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; + // Load replacement ACPI tables if they provided by user according to the drop table list + acpiLoadUserTables(); - update_acpi=getBoolForKey(kUpdateACPI, &tmpval, &bootInfo->bootConfig)&&tmpval; - } + if (!(new_dsdt=acpiLoadTable("DSDT"))) + return setupAcpiNoMod(); - // 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<30;curssdt++) - { - new_ssdts[curssdt]=loadSSDTTable(curssdt); - if (new_ssdts[curssdt]) - loadtotssdt++; - } - curssdt=0; - } - - if (!new_dsdt) - return setupAcpiNoMod(); - - DBG("New ACPI tables Loaded in memory\n"); + DBG("New ACPI tables Loaded in memory\n"); - // Do the same procedure for both versions of ACPI - for (version=0; version<2; version++) { - struct acpi_2_rsdp *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; + // Do the same procedure for both versions of ACPI + for (version=0; version<2; version++) { + struct acpi_2_rsdp *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 - rsdp=(struct acpi_2_rsdp *)(version?getAddressOfAcpi20Table():getAddressOfAcpiTable()); - if ((update_acpi) && (rsdp->Revision == 0)) - { - rsdp_conv = (struct acpi_2_rsdp *)AllocateKernelMemory(sizeof(struct acpi_2_rsdp)); - memcpy(rsdp_conv, rsdp, 20); + // Find original rsdp + rsdp=(struct acpi_2_rsdp *) (version? + acpiGetAddressOfTable20() : + acpiGetAddressOfTable10()); + if ((update_acpi) && (rsdp->Revision == 0)) + { + 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); + /* Add/change fields */ + rsdp_conv->Revision = 2; /* ACPI version 3 */ + rsdp_conv->Length = sizeof(struct acpi_2_rsdp); - /* Correct checksums */ - rsdp_conv->Checksum = 0; - rsdp_conv->Checksum = 256-checksum8(rsdp_conv, 20); - rsdp_conv->ExtendedChecksum = 0; - rsdp_conv->ExtendedChecksum = 256-checksum8(rsdp_conv, rsdp_conv->Length); + /* Correct checksums */ + rsdp_conv->Checksum = 0; + rsdp_conv->Checksum = 256-checksum8(rsdp_conv, 20); + rsdp_conv->ExtendedChecksum = 0; + rsdp_conv->ExtendedChecksum = 256-checksum8(rsdp_conv, rsdp_conv->Length); - rsdp = rsdp_conv; + rsdp = rsdp_conv; - gen_xsdt = true; - version = 1; + gen_xsdt = true; + version = 1; - addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI"); + 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; + 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); + 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 - */ + /* 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); - } + 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); + rsdt=(struct acpi_2_rsdt *)(rsdp->RsdtAddress); - DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length); + DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length); - if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000) - { - uint32_t *rsdt_entries; - int rsdt_entries_num; - int dropoffset=0, i; + if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000) + { + uint32_t *rsdt_entries; + int rsdt_entries_num; + int dropoffset=0, i; - rsdt_mod=(struct acpi_2_rsdt *)AllocateKernelMemory(rsdt->Length); - memcpy (rsdt_mod, rsdt, 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); + rsdt_mod=(struct acpi_2_rsdt *)AllocateKernelMemory(rsdt->Length); + memcpy (rsdt_mod, rsdt, 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); - if (gen_xsdt) - { - uint64_t *xsdt_conv_entries; + if (gen_xsdt) + { + uint64_t *xsdt_conv_entries; - 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=(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); + 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); - xsdt_conv_entries=(uint64_t *)(xsdt_conv+1); + xsdt_conv_entries=(uint64_t *)(xsdt_conv+1); - for (i=0;iChecksum = 0; - xsdt_conv->Checksum = 256-checksum8(xsdt_conv, xsdt_conv->Length); + xsdt_conv->Checksum = 0; + xsdt_conv->Checksum = 256-checksum8(xsdt_conv, xsdt_conv->Length); - rsdp->XsdtAddress = (uint32_t)xsdt_conv; + rsdp->XsdtAddress = (uint32_t)xsdt_conv; - rsdp->ExtendedChecksum = 0; - rsdp->ExtendedChecksum = 256-checksum8(rsdp, rsdp->Length); + rsdp->ExtendedChecksum = 0; + rsdp->ExtendedChecksum = 256-checksum8(rsdp, rsdp->Length); - verbose("Converted RSDT table to XSDT table\n"); - } + verbose("Converted RSDT table to XSDT table\n"); + } - for (i=0;iLength); + /* either we add a user table*/ + if ((new_content=acpiTableUserContent(table))) + { + DBG("..Installing user acpi table %c%c%c%c\n", table[0],table[1],table[2],table[3]); + if (new_content) + { + rsdt_entries[i-dropoffset]=(uint32_t)new_content; + rsdt_mod->Length+=4; + } + continue; + } + else if (acpiIsTableDropped(table)) + { // or it is in the drop list and we don't add it at all + dropoffset++; + continue; + } + else // or we keep the default table + rsdt_entries[i-dropoffset]=rsdt_entries[i]; - if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000) - { - printf("FADT incorrect. Not modified\n"); - continue; - } - - fadt_mod = patch_fadt(fadt, new_dsdt, update_acpi); - rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod; - continue; - } - } - DBG("\n"); + /* CHECK ME HERE: for special cases */ +/* + if ((!(oem_ssdt)) && table[0]=='S' && table[1]=='S' && table[2]=='D' && table[3]=='T') + { + DBG("SSDT %d found", curssdt); + if (new_ssdts[curssdt]) + { + DBG(" and replaced"); + rsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt]; + totssdt++; + } + DBG("\n"); + curssdt++; + continue; + } + if (table[0]=='F' && table[1]=='A' && table[2]=='C' && table[3]=='P') + { + struct acpi_2_fadt *fadt, *fadt_mod; + fadt=(struct acpi_2_fadt *)rsdt_entries[i]; - if ((!oem_hpet) && (!hpet_replaced)) - { - if (new_hpet) - { - rsdt_entries[i-dropoffset]=(uint32_t)new_hpet; - hpet_added=true; - i++; - } - } + DBG("FADT found @%x, Length %d\n",fadt, fadt->Length); - if ((!oem_sbst) && (!sbst_replaced)) - { - if (new_sbst) - { - rsdt_entries[i-dropoffset]=(uint32_t)new_sbst; - sbst_added=true; - i++; - } - } + if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000) + { + printf("FADT incorrect. Not modified\n"); + continue; + } + + fadt_mod = patch_fadt(fadt, new_dsdt, update_acpi); + rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod; + continue; + } +*/ + } + DBG("\n"); - if ((!oem_ecdt) && (!ecdt_replaced)) - { - if (new_ecdt) - { - rsdt_entries[i-dropoffset]=(uint32_t)new_ecdt; - ecdt_added=true; - i++; - } - } + /* CHECK ME here */ +/* if (!oem_ssdt) + { + while ((totssdt < loadtotssdt) && (curssdt < 30)) + { + if (new_ssdts[curssdt]) + { + DBG("adding SSDT %d\n", curssdt); + rsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt]; + totssdt++; + newtotssdt++; + i++; + } + curssdt++; + } + } +*/ - if ((!oem_asft) && (!asft_replaced)) - { - if (new_asft) - { - rsdt_entries[i-dropoffset]=(uint32_t)new_asft; - asft_added=true; - i++; - } - } + // Correct the checksum of RSDT + rsdt_mod->Length-=4*dropoffset; + rsdt_mod->Length+=4*newtotssdt; - if ((!oem_dmar) && (!dmar_replaced)) - { - if (new_dmar) - { - rsdt_entries[i-dropoffset]=(uint32_t)new_dmar; - dmar_added=true; - i++; - } - } + DBG("RSDT: Original checksum %d, ", rsdt_mod->Checksum); - if ((!oem_apic) && (!apic_replaced)) - { - if (new_apic) - { - rsdt_entries[i-dropoffset]=(uint32_t)new_apic; - apic_added=true; - i++; - } - } + rsdt_mod->Checksum=0; + rsdt_mod->Checksum=256-checksum8(rsdt_mod,rsdt_mod->Length); - 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 < 30)) - { - if (new_ssdts[curssdt]) - { - DBG("adding SSDT %d\n", curssdt); - rsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt]; - totssdt++; - newtotssdt++; - i++; - } - curssdt++; - } - } + 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"); + } - // 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; + if (version) + { + struct acpi_2_xsdt *xsdt, *xsdt_mod; - DBG("RSDT: Original checksum %d, ", rsdt_mod->Checksum); + // FIXME: handle 64-bit address correctly - rsdt_mod->Checksum=0; - rsdt_mod->Checksum=256-checksum8(rsdt_mod,rsdt_mod->Length); + if (gen_xsdt) + xsdt=xsdt_conv; + else + xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress); - 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"); - } + 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) + { + uint64_t *xsdt_entries; + int xsdt_entries_num, i; + int dropoffset=0; + 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 (version) - { - struct acpi_2_xsdt *xsdt, *xsdt_mod; + if (gen_xsdt) + xsdt_mod=xsdt; + else + { + xsdt_mod=(struct acpi_2_xsdt*)AllocateKernelMemory(xsdt->Length); + memcpy(xsdt_mod, xsdt, xsdt->Length); + } - // FIXME: handle 64-bit address correctly + 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;iXsdtAddress); + xsdt_entries[i-dropoffset]=(uint32_t)new_dsdt; - 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) - { - uint64_t *xsdt_entries; - int xsdt_entries_num, i; - int dropoffset=0; - 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); - } - - 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>32),fadt, - fadt->Length); + DBG("FADT found @%x,%x, Length %d\n",(uint32_t)(xsdt_entries[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; - } + if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000) + { + verbose("FADT incorrect or after 4GB. Dropping XSDT\n"); + goto drop_xsdt; + } - fadt_mod = patch_fadt(fadt, new_dsdt,update_acpi); - xsdt_entries[i-dropoffset]=(uint32_t)fadt_mod; + 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]); + DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]); - continue; - } + continue; + } - DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]); + 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_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_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_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_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_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_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_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 < 30)) - { - if (new_ssdts[curssdt]) - { - DBG("adding SSDT %d\n", curssdt); - xsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt]; - totssdt++; - newtotssdt++; - i++; - } - curssdt++; - } - } + if (!oem_ssdt) + { + while ((totssdt < loadtotssdt) && (curssdt < 30)) + { + if (new_ssdts[curssdt]) + { + DBG("adding SSDT %d\n", curssdt); + xsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt]; + totssdt++; + newtotssdt++; + i++; + } + 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; + // 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; - xsdt_mod->Checksum=0; - xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length); - } - else - { - drop_xsdt: + xsdt_mod->Checksum=0; + xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length); + } + else + { + drop_xsdt: - DBG("About to drop XSDT\n"); + 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 - */ + /*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"); - } - } + rsdp_mod->XsdtAddress=0xffffffffffffffffLL; + verbose("XSDT not found or XSDT incorrect\n"); + } + } - // Correct the checksum of RSDP + // Correct the checksum of RSDP - DBG("RSDP: Original checksum %d, ", rsdp_mod->Checksum); + DBG("RSDP: Original checksum %d, ", rsdp_mod->Checksum); - rsdp_mod->Checksum=0; - rsdp_mod->Checksum=256-checksum8(rsdp_mod,20); + rsdp_mod->Checksum=0; + rsdp_mod->Checksum=256-checksum8(rsdp_mod,20); - DBG("New checksum %d\n", rsdp_mod->Checksum); + DBG("New checksum %d\n", rsdp_mod->Checksum); - if (version) - { - DBG("RSDP: Original extended checksum %d", rsdp_mod->ExtendedChecksum); + if (version) + { + DBG("RSDP: Original extended checksum %d", rsdp_mod->ExtendedChecksum); - rsdp_mod->ExtendedChecksum=0; - rsdp_mod->ExtendedChecksum=256-checksum8(rsdp_mod,rsdp_mod->Length); + rsdp_mod->ExtendedChecksum=0; + rsdp_mod->ExtendedChecksum=256-checksum8(rsdp_mod,rsdp_mod->Length); - DBG("New extended checksum %d\n", rsdp_mod->ExtendedChecksum); + DBG("New extended checksum %d\n", rsdp_mod->ExtendedChecksum); - } + } - verbose("Patched ACPI version %d DSDT\n", version+1); - if (version) - { - /* XXX aserebln why uint32 cast if pointer is uint64 ? */ - acpi20_p = (uint32_t)rsdp_mod; - addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20"); - } - else - { - /* XXX aserebln why uint32 cast if pointer is uint64 ? */ - acpi10_p = (uint32_t)rsdp_mod; - addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI"); - } - } + verbose("Patched ACPI version %d DSDT\n", version+1); + if (version) + { + /* XXX aserebln why uint32 cast if pointer is uint64 ? */ + acpi20_p = (uint32_t)rsdp_mod; + addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20"); + } + else + { + /* XXX aserebln why uint32 cast if pointer is uint64 ? */ + acpi10_p = (uint32_t)rsdp_mod; + addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI"); + } + } #if DEBUG_DSDT - printf("Press a key to continue... (DEBUG_DSDT)\n"); - getc(); + printf("Press a key to continue... (DEBUG_DSDT)\n"); + getc(); #endif - return 1; + return 1; } Index: branches/rekursor/i386/libsaio/acpi.c =================================================================== --- branches/rekursor/i386/libsaio/acpi.c (revision 0) +++ branches/rekursor/i386/libsaio/acpi.c (revision 63) @@ -0,0 +1,292 @@ +#include "libsaio.h" +#include "boot.h" +#include "bootstruct.h" +#include "acpi.h" + +#ifndef DEBUG_ACPI +#define DEBUG_ACPI 1 +#endif + +#if DEBUG_ACPI!=0 +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif + +/** Search and try opening an acpi table matching a spec defined by key, should be reused anywhere needed:*/ +int acpiSearchAndGetFd(const char * key, const char ** outDirspec) +{ + int fd=0; + const char * overriden_pathname=NULL; + char filename[64]; + static char dirspec[512]=""; + int len=0,i=0; + + sprintf(filename, "%s.aml", key); + + /// Take in account user overriding for 'DSDT'.aml table + // and try to find .aml at the same place + if (getValueForKey("DSDT", &overriden_pathname, &len, + &bootInfo->bootConfig) && len>0) + { + strcpy(dirspec, overriden_pathname); + for (i=len-1; i>=0; i--) + { + if (dirspec[i]=='/') + { + dirspec[i+1]='\0'; + strcat(dirspec, filename); + break; + } + else if (i==0) // no '/' found copy filename and seek in current directory + { + strcpy(dirspec, filename); + break; + } + } + fd=open (dirspec,0); + if (fd>=0) goto success_fd; + } + + // Start searching any potential location for ACPI Table + sprintf(dirspec, "/%s", filename); // start searching root + fd=open (dirspec,0); + if (fd>=0) goto success_fd; + + sprintf(dirspec, "%s", filename); // start current dir + fd=open (dirspec,0); + if (fd>=0) goto success_fd; + + sprintf(dirspec,"/Extra/%s",filename); + fd=open (dirspec,0); + if (fd>=0) goto success_fd; + + sprintf(dirspec,"bt(0,0)/Extra/%s",filename); + fd=open (dirspec,0); + if (fd>=0) goto success_fd; + + // NOT FOUND: + verbose("ACPI Table not found: %s\n", filename); + if (outDirspec) *outDirspec = ""; + return -1; + // FOUND + success_fd: + if (outDirspec) *outDirspec = dirspec; + return fd; +} + +/** Load a table in kernel memory and return a pointer to it if found, NULL otherwise */ +void *acpiLoadTable (const char * key) +{ + void *tableAddr; + const char * dirspec=NULL; + + int fd = acpiSearchAndGetFd(key, &dirspec); + + if (fd>=0) + { + 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; + } + + DBG("Table %s read and stored at: %x\n", dirspec, tableAddr); + close (fd); + return tableAddr; + } + close (fd); + } + printf("Couldn't allocate memory for table %s\n", dirspec); + return NULL; +} + +/** Load an SSDTx into memory, code could be factorized here using acpiSearchAndGetFd() */ +void * acpiLoadSSDTTable(int ssdt_number) +{ + char filename[64]; + + sprintf(filename, "SSDT-%d", ssdt_number); + return acpiLoadTable(filename); +} + +/** Gets the ACPI 1.0 RSDP address */ +struct acpi_2_rsdp* acpiGetAddressOfTable10() +{ + /* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */ + + void *acpi_addr = (void*)ACPI_RANGE_START; + for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16) + { + if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE) + { + uint8_t csum = checksum8(acpi_addr, 20); + 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) + return acpi_addr; + } + } + } + return NULL; +} + +/** Gets the ACPI 2.0 RSDP address */ +struct acpi_2_rsdp* acpiGetAddressOfTable20() +{ + /* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */ + + void *acpi_addr = (void*)ACPI_RANGE_START; + for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16) + { + if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE) + { + uint8_t csum = checksum8(acpi_addr, 20); + + /* 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(csum == 0 && (((struct acpi_2_rsdp*)acpi_addr)->Revision > 0)) + { + uint8_t csum2 = checksum8(acpi_addr, sizeof(struct acpi_2_rsdp)); + if(csum2 == 0) + return acpi_addr; + } + } + } + return NULL; +} + +/** Fills an ACPI 2.0 GAS structure */ +struct acpi_2_gas acpiFillGASStruct(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); +} + +/* Handling acpi dropped tables enumeration */ + +static struct ACPIDropTableEntry sACPIKeyDropTable[16]; +const int sACPIKeyDropTableSize = sizeof(sACPIKeyDropTableSize) / sizeof(char); +static int sACPIKeyCount = 0; +static bool bACPIDropTableInitialized=false; + +/* initialize the the dropped table array from user specification, if not done already*/ +static void acpiInitializeDropTables() +{ + if (bACPIDropTableInitialized) return; + const char * dropTablesEnum = NULL; + int len = 0; + bool bOverride = getValueForKey(kDrop, &dropTablesEnum, &len, &bootInfo->bootConfig); + bACPIDropTableInitialized = true; + bzero(sACPIKeyDropTable, sACPIKeyDropTableSize); + + if (!bOverride || !dropTablesEnum || len==0) return; + + // Now transform the whitespace delimited enum into an array of keys: + char buffer[sACPIKeyDropTableSize*8]; + int i,j; + // skip beginning whitespaces + for (i=0; i < len; i++) + if (dropTablesEnum[i]!=' ' && dropTablesEnum[i]!='\t') + break; + for (;i < len; i++) + { + j=0; + *buffer = '\0'; + while(i0) + { + DBG("ACPI: Adding Key[%d]: %s\n", sACPIKeyCount, buffer); + strncpy(sACPIKeyDropTable[sACPIKeyCount++].key,buffer, ACPI_KEY_MAX_SIZE); + } + } +} + +static int _current = 0; +/** Get first acpi drop key*/ +struct ACPIDropTableEntry* acpiGetFirstDropTable() +{ + acpiInitializeDropTables(); + _current = 0; + return sACPIKeyCount>0 ? &sACPIKeyDropTable[0] : NULL; +} + +/** Get Next acpi drop key*/ +struct ACPIDropTableEntry* acpiGetNextDropTable() +{ + acpiInitializeDropTables(); + return (_currentkey[0]==key[0] && p->key[1]==key[1] && + p->key[2]==key[2] && p->key[3]==key[3]) + { + DBG("ACPI: Key: %s found in the drop list\n", p); + return true; + } + } + DBG("ACPI: Key: %c%c%c%c NOT found in the drop list\n", p); + return false; +} +/* Return the content of user acpi table if it has been loaded sucessfully, NULL otherwise*/ +void * acpiTableUserContent(const char * key) +{ +// Note: input key can be non zero terminated + struct ACPIDropTableEntry* p; + for (p = acpiGetFirstDropTable(); p; p = acpiGetNextDropTable()) + { + if (p->key[0]==key[0] && p->key[1]==key[1] && + p->key[2]==key[2] && p->key[3]==key[3]) + { + return p->content; + } + } + return NULL; +} + +/** For each table in the drop list, try to load an equivalent user table */ +void acpiLoadUserTables() +{ + struct ACPIDropTableEntry* p; + for (p = acpiGetFirstDropTable(); p; p = acpiGetNextDropTable()) + { + p->content = acpiLoadTable(p->key); + + if (p->content) + { + DBG("ACPI: User Table %s loaded in Memory\n", p->key); + } + } +} Index: branches/rekursor/i386/libsaio/acpi.h =================================================================== --- branches/rekursor/i386/libsaio/acpi.h (revision 62) +++ branches/rekursor/i386/libsaio/acpi.h (revision 63) @@ -131,4 +131,26 @@ struct acpi_2_gas X_GPE1_BLK; } __attribute__((packed)); +/* ACPI utilities declarations, structures & functions */ +#define ACPI_KEY_MAX_SIZE 8 + +struct ACPIDropTableEntry +{ + char key[ACPI_KEY_MAX_SIZE+1]; + void * content; +}; + +int acpiSearchAndGetFd(const char * key, const char ** outDirspec); +void *acpiLoadTable(const char * key); +void * acpiLoadSSDTTable(int ssdt_number); +void acpiLoadUserTables(); +struct acpi_2_gas acpiFillGASStruct(uint32_t Address, uint8_t Length); +struct acpi_2_rsdp* acpiGetAddressOfTable10(); +struct acpi_2_rsdp* acpiGetAddressOfTable20(); + +struct ACPIDropTableEntry* acpiGetFirstDropTable(); +struct ACPIDropTableEntry* acpiGetNextDropTable(); +bool acpiIsTableDropped(const char * key); + + #endif /* !__LIBSAIO_ACPI_H */ Index: branches/rekursor/i386/boot2/boot.h =================================================================== --- branches/rekursor/i386/boot2/boot.h (revision 62) +++ branches/rekursor/i386/boot2/boot.h (revision 63) @@ -85,13 +85,7 @@ #define kOEMFADT "oemFADT" /* dsdt_patcher.c */ #define kOEMAPIC "oemAPIC" /* dsdt_patcher.c */ #define kOEMMCFG "oemMCFG" /* dsdt_patcher.c */ -#define kDropSSDT "DropSSDT" /* dsdt_patcher.c */ -#define kDropHPET "DropHPET" /* dsdt_patcher.c */ -#define kDropSLIC "DropSLIC" /* dsdt_patcher.c */ -#define kDropSBST "DropSBST" /* dsdt_patcher.c */ -#define kDropECDT "DropECDT" /* dsdt_patcher.c */ -#define kDropASFT "DropASFT" /* dsdt_patcher.c */ -#define kDropDMAR "DropDMAR" /* dsdt_patcher.c */ +#define kDrop "Drop" /* dsdt_patcher.c */ #define kUpdateACPI "UpdateACPI" /* dsdt_patcher.c */ #define kRestartFix "RestartFix" /* dsdt_patcher.c */ #define kSMBIOS "SMBIOS" /* fake_efi.c */ Index: branches/rekursor/CREDITS =================================================================== --- branches/rekursor/CREDITS (revision 62) +++ branches/rekursor/CREDITS (revision 63) @@ -3,6 +3,7 @@ Developers: ---------- + Andy Crazor Dense fassl