Index: branches/rekursor/i386/libsaio/pci_root.c =================================================================== --- branches/rekursor/i386/libsaio/pci_root.c (revision 61) +++ branches/rekursor/i386/libsaio/pci_root.c (revision 62) @@ -7,7 +7,7 @@ #include "bootstruct.h" #ifndef DEBUG_PCIROOT -#define DEBUG_PCIROOT 1 +#define DEBUG_PCIROOT 0 #endif #if DEBUG_PCIROOT Index: branches/rekursor/i386/libsaio/usb.c =================================================================== --- branches/rekursor/i386/libsaio/usb.c (revision 61) +++ branches/rekursor/i386/libsaio/usb.c (revision 62) @@ -146,6 +146,96 @@ return 1; } +int legacy_off (pci_dt_t *pci_dev) +{ + // Set usb legacy off modification by Signal64 + uint32_t capaddr, opaddr; + uint8_t eecp; + uint32_t usbcmd, usbsts, usbintr; + uint32_t usblegsup, usblegctlsts; + + int isOSowned; + int isBIOSowned; + + verbose("Setting Legacy USB Off on controller [%04x:%04x] at %02x:%2x.%x\n", + pci_dev->vendor_id, pci_dev->device_id, + pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func); + + // capaddr = Capability Registers = dev.addr + offset stored in dev.addr + 0x10 (USBBASE) + capaddr = pci_config_read32(pci_dev->dev.addr, 0x10); + + // opaddr = Operational Registers = capaddr + offset (8bit CAPLENGTH in Capability Registers + offset 0) + opaddr = capaddr + *((unsigned char*)(capaddr)); + + // eecp = EHCI Extended Capabilities offset = capaddr HCCPARAMS bits 15:8 + eecp=*((unsigned char*)(capaddr + 9)); + + DBG("capaddr=%x opaddr=%x eecp=%x\n", capaddr, opaddr, eecp); + + usbcmd = *((unsigned int*)(opaddr)); // Command Register + usbsts = *((unsigned int*)(opaddr + 4)); // Status Register + usbintr = *((unsigned int*)(opaddr + 8)); // Interrupt Enable Register + + DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr); + + // read PCI Config 32bit USBLEGSUP (eecp+0) + usblegsup = pci_config_read32(pci_dev->dev.addr, eecp); + + // informational only + isBIOSowned = !!((usblegsup) & (1 << (16))); + isOSowned = !!((usblegsup) & (1 << (24))); + + // read PCI Config 32bit USBLEGCTLSTS (eecp+4) + usblegctlsts = pci_config_read32(pci_dev->dev.addr, eecp + 4); + + DBG("usblegsup=%08x isOSowned=%d isBIOSowned=%d usblegctlsts=%08x\n", usblegsup, isOSowned, isBIOSowned, usblegctlsts); + + // Reset registers to Legacy OFF + DBG("Clearing USBLEGCTLSTS\n"); + pci_config_write32(pci_dev->dev.addr, eecp + 4, 0); //usblegctlsts + + // if delay value is in milliseconds it doesn't appear to work. + // setting value to anything up to 65535 does not add the expected delay here. + delay(100); + + usbcmd = *((unsigned int*)(opaddr)); + usbsts = *((unsigned int*)(opaddr + 4)); + usbintr = *((unsigned int*)(opaddr + 8)); + + DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr); + + DBG("Clearing Registers\n"); + + // clear registers to default + usbcmd = (usbcmd & 0xffffff00); + *((unsigned int*)(opaddr)) = usbcmd; + *((unsigned int*)(opaddr + 8)) = 0; //usbintr - clear interrupt registers + *((unsigned int*)(opaddr + 4)) = 0x1000; //usbsts - clear status registers + pci_config_write32(pci_dev->dev.addr, eecp, 1); //usblegsup + + // get the results + usbcmd = *((unsigned int*)(opaddr)); + usbsts = *((unsigned int*)(opaddr + 4)); + usbintr = *((unsigned int*)(opaddr + 8)); + + DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr); + + // read 32bit USBLEGSUP (eecp+0) + usblegsup = pci_config_read32(pci_dev->dev.addr, eecp); + + // informational only + isBIOSowned = !!((usblegsup) & (1 << (16))); + isOSowned = !!((usblegsup) & (1 << (24))); + + // read 32bit USBLEGCTLSTS (eecp+4) + usblegctlsts = pci_config_read32(pci_dev->dev.addr, eecp + 4); + + DBG("usblegsup=%08x isOSowned=%d isBIOSowned=%d usblegctlsts=%08x\n", usblegsup, isOSowned, isBIOSowned, usblegctlsts); + + verbose("Legacy USB Off Done\n"); + return 1; +} + int uhci_reset (pci_dt_t *pci_dev) { uint32_t base, port_base; Index: branches/rekursor/i386/libsaio/dsdt_patcher.c =================================================================== --- branches/rekursor/i386/libsaio/dsdt_patcher.c (revision 61) +++ branches/rekursor/i386/libsaio/dsdt_patcher.c (revision 62) @@ -72,20 +72,38 @@ } return NULL; } + /** The folowing ACPI Table search algo. should be reused anywhere needed:*/ -int search_and_get_acpi_fd(const char * filename, const char ** outDirspec) +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; + int len=0,i=0; + + sprintf(filename, "%s.aml", key); - /// Take in accound user overriding if it's DSDT only - if (strstr(filename, "DSDT") && - getValueForKey(kDSDT, &overriden_pathname, &len, - &bootInfo->bootConfig)) + /// 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) { - sprintf(dirspec, "%s", overriden_pathname); // start searching root + 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; } @@ -117,12 +135,12 @@ return fd; } -void *loadACPITable (const char * filename) +void *loadACPITable (const char * key) { void *tableAddr; const char * dirspec=NULL; - int fd = search_and_get_acpi_fd(filename, &dirspec); + int fd = search_and_get_acpi_fd(key, &dirspec); if (fd>=0) { @@ -147,18 +165,102 @@ return NULL; } +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) +patch_fadt(struct acpi_2_fadt *fadt, void *new_dsdt, bool UpdateFADT) { - - extern void setupSystemType(); + 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; @@ -168,28 +270,69 @@ fix_restart = false; } - if (fix_restart) fadt_rev2_needed = true; + if (fix_restart) + fadt_rev2_needed = true; // Allocate new fadt table - if (fadt->Length < 0x84 && fadt_rev2_needed) + 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(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=(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); + } + } } - 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->PM_Profile<=6) - Platform.Type = fadt_mod->PM_Profile; // get the fadt if correct + 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); @@ -197,17 +340,17 @@ else Platform.Type = (unsigned char) strtoul(value, NULL, 10); } - // Set PM_Profile from System-type if only if user wanted this value to be forced - if (fadt_mod->PM_Profile != Platform.Type) + // 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 PM_Profile from 0x%02x to 0x%02x\n", fadt_mod->PM_Profile, Platform.Type); - fadt_mod->PM_Profile = Platform.Type; + 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 - { // PM_Profile has a different value and no override has been set, so reflect the user value to ioregs - Platform.Type = fadt_mod->PM_Profile <= 6 ? fadt_mod->PM_Profile : 1; + { // 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() @@ -218,15 +361,16 @@ if (fix_restart) { fadt_mod->Flags|= 0x400; - fadt_mod->Reset_SpaceID = 0x01; // System I/O - fadt_mod->Reset_BitWidth = 0x08; // 1 byte - fadt_mod->Reset_BitOffset = 0x00; // Offset 0 - 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 + 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); @@ -260,32 +404,114 @@ int setupAcpi(void) { int version; - void *new_dsdt; + 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]; - bool drop_ssdt; - - // Load replacement DSDT - new_dsdt=loadACPITable("DSDT.aml"); - if (!new_dsdt) + 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; + + int curssdt=0, loadtotssdt=0, totssdt=0, newtotssdt=0; + { - return setupAcpiNoMod(); + 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; + + 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; + + update_acpi=getBoolForKey(kUpdateACPI, &tmpval, &bootInfo->bootConfig)&&tmpval; } - DBG("New DSDT Loaded in memory\n"); - + // 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) { - bool tmp; - drop_ssdt=getBoolForKey(kDropSSDT, &tmp, &bootInfo->bootConfig)&&tmp; + 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"); + // Do the same procedure for both versions of ACPI for (version=0; version<2; version++) { - struct acpi_2_rsdp *rsdp, *rsdp_mod; + 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); + + /* 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); + + rsdp = rsdp_conv; + + 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); @@ -304,8 +530,14 @@ * For more info see ACPI Specification pages 110 and following */ - 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); DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length); @@ -321,6 +553,38 @@ 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; + + 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_entries=(uint64_t *)(xsdt_conv+1); + + for (i=0;iChecksum = 0; + xsdt_conv->Checksum = 256-checksum8(xsdt_conv, xsdt_conv->Length); + + rsdp->XsdtAddress = (uint32_t)xsdt_conv; + + rsdp->ExtendedChecksum = 0; + rsdp->ExtendedChecksum = 256-checksum8(rsdp, rsdp->Length); + + verbose("Converted RSDT table to XSDT table\n"); + } + for (i=0;iLength-=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); @@ -383,7 +861,11 @@ // FIXME: handle 64-bit address correctly - xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress); + 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) @@ -391,9 +873,23 @@ uint64_t *xsdt_entries; int xsdt_entries_num, i; int dropoffset=0; - - xsdt_mod=(struct acpi_2_xsdt*)AllocateKernelMemory(xsdt->Length); - memcpy(xsdt_mod, xsdt, xsdt->Length); + 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); @@ -407,7 +903,120 @@ { dropoffset++; continue; + } + if (drop_hpet && table[0]=='H' && table[1]=='P' && table[2]=='E' && table[3]=='T') + { + dropoffset++; + continue; + } + if (drop_slic && table[0]=='S' && table[1]=='L' && table[2]=='I' && table[3]=='C') + { + dropoffset++; + continue; + } + if (drop_sbst && table[0]=='S' && table[1]=='B' && table[2]=='S' && table[3]=='T') + { + dropoffset++; + continue; + } + if (drop_ecdt && table[0]=='E' && table[1]=='C' && table[2]=='D' && table[3]=='T') + { + dropoffset++; + continue; } + if (drop_asft && table[0]=='A' && table[1]=='S' && table[2]=='F' && table[3]=='!') + { + dropoffset++; + continue; + } + if (drop_dmar && table[0]=='D' && table[1]=='M' && table[2]=='A' && table[3]=='R') + { + dropoffset++; + continue; + } + if ((!(oem_hpet)) && table[0]=='H' && table[1]=='P' && table[2]=='E' && table[3]=='T') + { + DBG("HPET found\n"); + if (new_hpet) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_hpet; + hpet_replaced=true; + } + continue; + } + if ((!(oem_sbst)) && table[0]=='S' && table[1]=='B' && table[2]=='S' && table[3]=='T') + { + DBG("SBST found\n"); + if (new_sbst) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_sbst; + sbst_replaced=true; + } + continue; + } + if ((!(oem_ecdt)) && table[0]=='E' && table[1]=='C' && table[2]=='D' && table[3]=='T') + { + DBG("ECDT found\n"); + if (new_ecdt) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_ecdt; + ecdt_replaced=true; + } + continue; + } + if ((!(oem_asft)) && table[0]=='A' && table[1]=='S' && table[2]=='F' && table[3]=='!') + { + DBG("ASF! found\n"); + if (new_asft) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_asft; + asft_replaced=true; + } + continue; + } + if ((!(oem_dmar)) && table[0]=='D' && table[1]=='M' && table[2]=='A' && table[3]=='R') + { + DBG("DMAR found\n"); + if (new_dmar) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_dmar; + dmar_replaced=true; + } + continue; + } + if ((!(oem_apic)) && table[0]=='A' && table[1]=='P' && table[2]=='I' && table[3]=='C') + { + DBG("APIC found\n"); + if (new_apic) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_apic; + apic_replaced=true; + } + continue; + } + if ((!(oem_mcfg)) && table[0]=='M' && table[1]=='C' && table[2]=='F' && table[3]=='G') + { + DBG("MCFG found\n"); + if (new_mcfg) + { + xsdt_entries[i-dropoffset]=(uint32_t)new_mcfg; + mcfg_replaced=true; + } + continue; + } + 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"); + xsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt]; + totssdt++; + } + DBG("\n"); + curssdt++; + continue; + } if (table[0]=='D' && table[1]=='S' && table[2]=='D' && table[3]=='T') { DBG("DSDT found\n"); @@ -432,7 +1041,7 @@ goto drop_xsdt; } - fadt_mod = patch_fadt(fadt, new_dsdt); + 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]); @@ -444,8 +1053,110 @@ } + 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 < 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; + xsdt_mod->Checksum=0; xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length); } Index: branches/rekursor/i386/libsaio/acpi.h =================================================================== --- branches/rekursor/i386/libsaio/acpi.h (revision 61) +++ branches/rekursor/i386/libsaio/acpi.h (revision 62) @@ -59,38 +59,76 @@ } __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_fadt { - 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; - uint32_t FIRMWARE_CTRL; - uint32_t DSDT; - uint8_t Model; // JrCs - uint8_t PM_Profile; // JrCs - /*We absolutely don't care about theese fields*/ - uint8_t notimp1[66]; -/* Begin Asere */ - //Reset Fix - uint32_t Flags; - uint8_t Reset_SpaceID; - uint8_t Reset_BitWidth; - uint8_t Reset_BitOffset; - uint8_t Reset_AccessWidth; - uint64_t Reset_Address; - uint8_t Reset_Value; - uint8_t Reserved[3]; - - uint64_t X_FIRMWARE_CTRL; - uint64_t X_DSDT; -/* End Asere */ - /*We absolutely don't care about theese fields*/ - uint8_t notimp2[96]; + 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; + uint32_t FIRMWARE_CTRL; + uint32_t DSDT; + uint8_t INT_MODEL; // JrCs + uint8_t Preferred_PM_Profile; // JrCs + uint16_t SCI_INT; + uint32_t SMI_CMD; + uint8_t ACPI_ENABLE; + uint8_t ACPI_DISABLE; + uint8_t S4BIOS_REQ; + uint8_t PSTATE_CNT; + uint32_t PM1a_EVT_BLK; + uint32_t PM1b_EVT_BLK; + uint32_t PM1a_CNT_BLK; + uint32_t PM1b_CNT_BLK; + uint32_t PM2_CNT_BLK; + uint32_t PM_TMR_BLK; + uint32_t GPE0_BLK; + uint32_t GPE1_BLK; + uint8_t PM1_EVT_LEN; + uint8_t PM1_CNT_LEN; + uint8_t PM2_CNT_LEN; + uint8_t PM_TMR_LEN; + uint8_t GPE0_BLK_LEN; + uint8_t GPE1_BLK_LEN; + uint8_t GPE1_BASE; + uint8_t CST_CNT; + uint16_t P_LVL2_LAT; + uint16_t P_LVL3_LAT; + uint16_t FLUSH_SIZE; + uint16_t FLUSH_STRIDE; + uint8_t DUTY_OFFSET; + uint8_t DUTY_WIDTH; + uint8_t DAY_ALRM; + uint8_t MON_ALRM; + uint8_t CENTURY; + uint16_t IAPC_BOOT_ARCH; + uint8_t Reserved1; + uint32_t Flags; + struct acpi_2_gas RESET_REG; + uint8_t RESET_VALUE; + uint8_t Reserved2[3]; + uint64_t X_FIRMWARE_CTRL; + uint64_t X_DSDT; + 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; } __attribute__((packed)); #endif /* !__LIBSAIO_ACPI_H */ Index: branches/rekursor/i386/libsaio/pci_setup.c =================================================================== --- branches/rekursor/i386/libsaio/pci_setup.c (revision 61) +++ branches/rekursor/i386/libsaio/pci_setup.c (revision 62) @@ -7,16 +7,17 @@ extern void set_eth_builtin(pci_dt_t *eth_dev); extern int ehci_acquire(pci_dt_t *pci_dev); +extern int legacy_off(pci_dt_t *pci_dev); extern int uhci_reset(pci_dt_t *pci_dev); extern void force_enable_hpet(pci_dt_t *lpc_dev); void setup_pci_devs(pci_dt_t *pci_dt) { char *devicepath; - bool do_eth_devprop, do_gfx_devprop, fix_ehci, fix_uhci, fix_usb, do_enable_hpet; + bool do_eth_devprop, do_gfx_devprop, fix_ehci, fix_legoff, fix_uhci, fix_usb, do_enable_hpet; pci_dt_t *current = pci_dt; - do_eth_devprop = do_gfx_devprop = fix_ehci = fix_uhci = fix_usb = do_enable_hpet = false; + do_eth_devprop = do_gfx_devprop = fix_ehci = fix_legoff = fix_uhci = fix_usb = do_enable_hpet = false; getBoolForKey(kEthernetBuiltIn, &do_eth_devprop, &bootInfo->bootConfig); getBoolForKey(kGraphicsEnabler, &do_gfx_devprop, &bootInfo->bootConfig); @@ -26,6 +27,7 @@ getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->bootConfig); getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->bootConfig); } + getBoolForKey(kUSBLegacyOff, &fix_legoff, &bootInfo->bootConfig); getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->bootConfig); while (current) @@ -68,6 +70,8 @@ case 0x20: if (fix_ehci) ehci_acquire(current); + if (fix_legoff) + legacy_off(current); break; /* UHCI */ Index: branches/rekursor/i386/libsaio/pci.c =================================================================== --- branches/rekursor/i386/libsaio/pci.c (revision 61) +++ branches/rekursor/i386/libsaio/pci.c (revision 62) @@ -10,7 +10,7 @@ #include "pci_root.h" #ifndef DEBUG_PCI -#define DEBUG_PCI 1 +#define DEBUG_PCI 0 #endif #if DEBUG_PCI Index: branches/rekursor/i386/boot2/boot.c =================================================================== --- branches/rekursor/i386/boot2/boot.c (revision 61) +++ branches/rekursor/i386/boot2/boot.c (revision 62) @@ -413,6 +413,9 @@ if (getValueForKey(k32BitModeFlag, &val, &len, &bootInfo->bootConfig)) { archCpuType = CPU_TYPE_I386; } + if (getValueForKey(k64BitModeFlag, &val, &len, &bootInfo->bootConfig)) { + archCpuType = CPU_TYPE_X86_64; + } if (!getBoolForKey (kWake, &tryresume, &bootInfo->bootConfig)) { tryresume = true; Index: branches/rekursor/i386/boot2/boot.h =================================================================== --- branches/rekursor/i386/boot2/boot.h (revision 61) +++ branches/rekursor/i386/boot2/boot.h (revision 62) @@ -66,7 +66,33 @@ #define kProductVersion "ProductVersion" /* boot.c */ #define karch "arch" /* boot.c */ #define kDSDT "DSDT" /* dsdt_patcher.c */ +#define kSSDT "SSDT" /* dsdt_patcher.c */ +#define kHPET "HPET" /* dsdt_patcher.c */ +#define kSBST "SBST" /* dsdt_patcher.c */ +#define kECDT "ECDT" /* dsdt_patcher.c */ +#define kASFT "ASFT" /* dsdt_patcher.c */ +#define kDMAR "DMAR" /* dsdt_patcher.c */ +#define kFADT "FADT" /* dsdt_patcher.c */ +#define kAPIC "APIC" /* dsdt_patcher.c */ +#define kMCFG "MCFG" /* dsdt_patcher.c */ +#define kOEMDSDT "oemDSDT" /* dsdt_patcher.c */ +#define kOEMSSDT "oemSSDT" /* dsdt_patcher.c */ +#define kOEMHPET "oemHPET" /* dsdt_patcher.c */ +#define kOEMSBST "oemSBST" /* dsdt_patcher.c */ +#define kOEMECDT "oemECDT" /* dsdt_patcher.c */ +#define kOEMASFT "oemASFT" /* dsdt_patcher.c */ +#define kOEMDMAR "oemDMAR" /* dsdt_patcher.c */ +#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 kUpdateACPI "UpdateACPI" /* dsdt_patcher.c */ #define kRestartFix "RestartFix" /* dsdt_patcher.c */ #define kSMBIOS "SMBIOS" /* fake_efi.c */ #define kSystemID "SystemId" /* fake_efi.c */ @@ -77,6 +103,7 @@ #define kEthernetBuiltIn "EthernetBuiltIn" /* pci_setup.c */ #define kGraphicsEnabler "GraphicsEnabler" /* pci_setup.c */ #define kUSBBusFix "USBBusFix" /* pci_setup.c */ +#define kUSBLegacyOff "USBLegacyOff" /* pci_setup.c */ #define kEHCIacquire "EHCIacquire" /* pci_setup.c */ #define kUHCIreset "UHCIreset" /* pci_setup.c */ #define kForceHPET "ForceHPET" /* pci_setup.c */ @@ -97,6 +124,7 @@ #define kIgnoreBootFileFlag "-F" #define kSingleUserModeFlag "-s" #define k32BitModeFlag "-x32" +#define k64BitModeFlag "-x64" /* * Booter behavior control Index: branches/rekursor/i386/boot2/options.c =================================================================== --- branches/rekursor/i386/boot2/options.c (revision 61) +++ branches/rekursor/i386/boot2/options.c (revision 62) @@ -724,35 +724,86 @@ // If the user is holding down a modifier key, enter safe mode. if ((readKeyboardShiftFlags() & 0x0F) != 0) { - gBootMode |= kBootModeSafe; + gBootMode |= kBootModeSafe; } - // If user typed F8, abort quiet mode, and display the menu. + + /* + Patch from 18seven & modified by me to make it even more mac like and to include couple of commands + + * Bootargs keyboard shortcut + * Keys were obtaiend from ApplePS2ToADBMap.h + * F8 abort quiet mode, and display the menu. + * alt+f old safe mode + * shift+f ignore boot configuration file + * alt+s single user mode + * alt+v verbose (in mac its command +v) + * alt+x safe mode (aka boot args with -x , in macs its command +x) + * alt+l legacy mode (not sure why you need this) + * 6 +4 = 64-bit + * 3 + 2 = 32-bit + */ + clearBootArgs(); { - bool f8press = false, spress = false, vpress = false; + bool f8 = false, altf = false, shiftf = false, alts = false, + altv = false, x32 = false, x64 = false, altx = false; int key; while (readKeyboardStatus()) { key = bgetc (); - if (key == 0x4200) f8press = true; - if ((key & 0xff) == 's' || (key & 0xff) == 'S') spress = true; - if ((key & 0xff) == 'v' || (key & 0xff) == 'V') vpress = true; + if (key == 0x4200) f8 = true; + if (key == 0x2100) altf = true; + if (key == 0x2146) shiftf = true; + if (key == 0x1F00) alts = true; + if (key == 0x2F00) altv = true; + if (key == 0x2D00) altx = true; + if (key == 0x0403) x32 = true; + if (key == 0x0705) x64 = true; } - if (f8press) { + if (f8) { gBootMode &= ~kBootModeQuiet; timeout = 0; } - if ((gBootMode & kBootModeQuiet) && firstRun && vpress && (gBootArgsPtr + 3 < gBootArgsEnd)) { + if ((altf) && (gBootArgsPtr + 3 < gBootArgsEnd)) { *(gBootArgsPtr++) = ' '; *(gBootArgsPtr++) = '-'; - *(gBootArgsPtr++) = 'v'; + *(gBootArgsPtr++) = 'f'; + } + if ((shiftf) && (gBootArgsPtr + 3 < gBootArgsEnd)) { + *(gBootArgsPtr++) = ' '; + *(gBootArgsPtr++) = '-'; + *(gBootArgsPtr++) = 'F'; + } + if ((alts) && (gBootArgsPtr + 3 < gBootArgsEnd)) { + *(gBootArgsPtr++) = ' '; + *(gBootArgsPtr++) = '-'; + *(gBootArgsPtr++) = 's'; + } + if ((altv) && (gBootArgsPtr + 3 < gBootArgsEnd)) { + *(gBootArgsPtr++) = ' '; + *(gBootArgsPtr++) = '-'; + *(gBootArgsPtr++) = 'v'; } - if ((gBootMode & kBootModeQuiet) && firstRun && spress && (gBootArgsPtr + 3 < gBootArgsEnd)) { + if ((altx) && (gBootArgsPtr + 3 < gBootArgsEnd)) { *(gBootArgsPtr++) = ' '; *(gBootArgsPtr++) = '-'; - *(gBootArgsPtr++) = 's'; - } + *(gBootArgsPtr++) = 'x'; + } + if ((x32) && (gBootArgsPtr + 5 < gBootArgsEnd)) { // Boot into 32-bit Kernel + *(gBootArgsPtr++) = ' '; + *(gBootArgsPtr++) = '-'; + *(gBootArgsPtr++) = 'x'; + *(gBootArgsPtr++) = '3'; + *(gBootArgsPtr++) = '2'; + } + + if ((x64) && (gBootArgsPtr + 5 < gBootArgsEnd)) { // Boot into 64-bit Kernel (in case those who are using 32-bit and wanna try 64-bit) + *(gBootArgsPtr++) = ' '; + *(gBootArgsPtr++) = '-'; + *(gBootArgsPtr++) = 'x'; + *(gBootArgsPtr++) = '6'; + *(gBootArgsPtr++) = '4'; + } } - clearBootArgs(); if (bootArgs->Video.v_display == VGA_TEXT_MODE) { setCursorPosition(0, 0, 0);