unsigned long write_acpi_tables(unsigned long start) { unsigned long current; acpi_rsdp_t *rsdp; acpi_rsdt_t *rsdt; acpi_xsdt_t *xsdt; acpi_hpet_t *hpet; acpi_madt_t *madt; acpi_mcfg_t *mcfg; acpi_fadt_t *fadt; acpi_facs_t *facs; #if CONFIG_HAVE_ACPI_SLIC acpi_header_t *slic; #endif acpi_header_t *ssdt; acpi_header_t *dsdt; current = fw_cfg_acpi_tables(start); if (current) return current; current = start; /* Align ACPI tables to 16byte */ ALIGN_CURRENT; printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start); /* We need at least an RSDP and an RSDT Table */ rsdp = (acpi_rsdp_t *) current; current += sizeof(acpi_rsdp_t); ALIGN_CURRENT; rsdt = (acpi_rsdt_t *) current; current += sizeof(acpi_rsdt_t); ALIGN_CURRENT; xsdt = (acpi_xsdt_t *) current; current += sizeof(acpi_xsdt_t); ALIGN_CURRENT; /* clear all table memory */ memset((void *) start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, xsdt); acpi_write_rsdt(rsdt); acpi_write_xsdt(xsdt); /* * We explicitly add these tables later on: */ printk(BIOS_DEBUG, "ACPI: * HPET\n"); hpet = (acpi_hpet_t *) current; current += sizeof(acpi_hpet_t); ALIGN_CURRENT; acpi_create_hpet(hpet); acpi_add_table(rsdp, hpet); /* If we want to use HPET Timers Linux wants an MADT */ printk(BIOS_DEBUG, "ACPI: * MADT\n"); madt = (acpi_madt_t *) current; acpi_create_madt(madt); current += madt->header.length; ALIGN_CURRENT; acpi_add_table(rsdp, madt); printk(BIOS_DEBUG, "ACPI: * MCFG\n"); mcfg = (acpi_mcfg_t *) current; acpi_create_mcfg(mcfg); current += mcfg->header.length; ALIGN_CURRENT; acpi_add_table(rsdp, mcfg); printk(BIOS_DEBUG, "ACPI: * FACS\n"); facs = (acpi_facs_t *) current; current += sizeof(acpi_facs_t); ALIGN_CURRENT; acpi_create_facs(facs); dsdt = (acpi_header_t *) current; memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); current += dsdt->length; memcpy(dsdt, &AmlCode, dsdt->length); ALIGN_CURRENT; /* We patched up the DSDT, so we need to recalculate the checksum */ dsdt->checksum = 0; dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length); printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt, dsdt->length); #if CONFIG_HAVE_ACPI_SLIC printk(BIOS_DEBUG, "ACPI: * SLIC\n"); slic = (acpi_header_t *)current; current += acpi_create_slic(current); ALIGN_CURRENT; acpi_add_table(rsdp, slic); #endif printk(BIOS_DEBUG, "ACPI: * FADT\n"); fadt = (acpi_fadt_t *) current; current += sizeof(acpi_fadt_t); ALIGN_CURRENT; acpi_create_fadt(fadt, facs, dsdt); acpi_add_table(rsdp, fadt); printk(BIOS_DEBUG, "ACPI: * SSDT\n"); ssdt = (acpi_header_t *)current; acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR); current += ssdt->length; acpi_add_table(rsdp, ssdt); ALIGN_CURRENT; printk(BIOS_DEBUG, "current = %lx\n", current); printk(BIOS_INFO, "ACPI: done.\n"); return current; }
unsigned long write_acpi_tables(unsigned long start) { unsigned long current; int i; acpi_rsdp_t *rsdp; acpi_rsdt_t *rsdt; acpi_xsdt_t *xsdt; acpi_hpet_t *hpet; acpi_madt_t *madt; acpi_mcfg_t *mcfg; acpi_fadt_t *fadt; acpi_facs_t *facs; #if CONFIG_HAVE_ACPI_SLIC acpi_header_t *slic; #endif acpi_header_t *ssdt; acpi_header_t *dsdt; void *gnvs; current = start; /* Align ACPI tables to 16byte */ ALIGN_CURRENT; printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start); /* We need at least an RSDP and an RSDT Table */ rsdp = (acpi_rsdp_t *) current; current += sizeof(acpi_rsdp_t); ALIGN_CURRENT; rsdt = (acpi_rsdt_t *) current; current += sizeof(acpi_rsdt_t); ALIGN_CURRENT; xsdt = (acpi_xsdt_t *) current; current += sizeof(acpi_xsdt_t); ALIGN_CURRENT; /* clear all table memory */ memset((void *) start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, xsdt); acpi_write_rsdt(rsdt); acpi_write_xsdt(xsdt); /* * We explicitly add these tables later on: */ printk(BIOS_DEBUG, "ACPI: * HPET\n"); hpet = (acpi_hpet_t *) current; current += sizeof(acpi_hpet_t); ALIGN_CURRENT; acpi_create_intel_hpet(hpet); acpi_add_table(rsdp, hpet); /* If we want to use HPET Timers Linux wants an MADT */ printk(BIOS_DEBUG, "ACPI: * MADT\n"); madt = (acpi_madt_t *) current; acpi_create_madt(madt); current += madt->header.length; ALIGN_CURRENT; acpi_add_table(rsdp, madt); printk(BIOS_DEBUG, "ACPI: * MCFG\n"); mcfg = (acpi_mcfg_t *) current; acpi_create_mcfg(mcfg); current += mcfg->header.length; ALIGN_CURRENT; acpi_add_table(rsdp, mcfg); printk(BIOS_DEBUG, "ACPI: * FACS\n"); facs = (acpi_facs_t *) current; current += sizeof(acpi_facs_t); ALIGN_CURRENT; acpi_create_facs(facs); dsdt = (acpi_header_t *) current; memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); current += dsdt->length; memcpy(dsdt, &AmlCode, dsdt->length); /* Fix up global NVS region for SMI handler. The GNVS region lives * in the (high) table area. The low memory map looks like this: * * 0x00000000 - 0x000003ff Real Mode IVT * 0x00000020 - 0x0000019c Low MP Table (XXX conflict?) * 0x00000400 - 0x000004ff BDA (somewhat unused) * 0x00000500 - 0x0000052f Moved GDT * 0x00000530 - 0x00000b64 coreboot table * 0x0007c000 - 0x0007dfff OS boot sector (unused?) * 0x0007e000 - 0x0007ffff free to use (so no good for acpi+smi) * 0x00080000 - 0x0009fbff usable ram * 0x0009fc00 - 0x0009ffff EBDA (unused?) * 0x000a0000 - 0x000bffff VGA memory * 0x000c0000 - 0x000cffff VGA option rom * 0x000d0000 - 0x000dffff free for other option roms? * 0x000e0000 - 0x000fffff SeaBIOS? (conflict with low tables:) * 0x000f0000 - 0x000f03ff PIRQ table * 0x000f0400 - 0x000f66?? ACPI tables * 0x000f66?? - 0x000f???? DMI tables */ ALIGN_CURRENT; /* Pack GNVS into the ACPI table area */ for (i=0; i < dsdt->length; i++) { if (*(u32*)(((u32)dsdt) + i) == 0xC0DEBABE) { printk(BIOS_DEBUG, "ACPI: Patching up global NVS in DSDT at offset 0x%04x -> 0x%08x\n", i, (u32)current); *(u32*)(((u32)dsdt) + i) = current; // 0x92 bytes break; } } /* And fill it */ acpi_create_gnvs((global_nvs_t *)current); /* Keep pointer around */ gnvs = (void *)current; current += 0x100; ALIGN_CURRENT; /* And tell SMI about it */ smm_setup_structures(gnvs, NULL, NULL); /* We patched up the DSDT, so we need to recalculate the checksum */ dsdt->checksum = 0; dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length); printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt, dsdt->length); #if CONFIG_HAVE_ACPI_SLIC printk(BIOS_DEBUG, "ACPI: * SLIC\n"); slic = (acpi_header_t *)current; current += acpi_create_slic(current); ALIGN_CURRENT; acpi_add_table(rsdp, slic); #endif printk(BIOS_DEBUG, "ACPI: * FADT\n"); fadt = (acpi_fadt_t *) current; current += sizeof(acpi_fadt_t); ALIGN_CURRENT; acpi_create_fadt(fadt, facs, dsdt); acpi_add_table(rsdp, fadt); printk(BIOS_DEBUG, "ACPI: * SSDT\n"); ssdt = (acpi_header_t *)current; acpi_create_ssdt_generator(ssdt, "COREBOOT"); current += ssdt->length; acpi_add_table(rsdp, ssdt); ALIGN_CURRENT; printk(BIOS_DEBUG, "current = %lx\n", current); printk(BIOS_DEBUG, "ACPI: * DMI (Linux workaround)\n"); memcpy((void *)0xfff80, dmi_table, DMI_TABLE_SIZE); #if CONFIG_WRITE_HIGH_TABLES == 1 memcpy((void *)current, dmi_table, DMI_TABLE_SIZE); current += DMI_TABLE_SIZE; ALIGN_CURRENT; #endif printk(BIOS_INFO, "ACPI: done.\n"); /* Enable Dummy DCC ON# for DVI */ printk(BIOS_DEBUG, "Laptop handling...\n"); outb(inb(0x60f) & ~(1 << 5), 0x60f); return current; }
unsigned long write_acpi_tables(unsigned long start) { unsigned long current; acpi_rsdp_t *rsdp; acpi_rsdt_t *rsdt; acpi_xsdt_t *xsdt; acpi_fadt_t *fadt; acpi_facs_t *facs; #if CONFIG_HAVE_ACPI_SLIC acpi_header_t *slic; #endif acpi_header_t *ssdt; acpi_header_t *dsdt; acpi_mcfg_t *mcfg; acpi_madt_t *madt; device_t dev; current = start; /* Align ACPI tables to 16byte */ ALIGN_CURRENT; printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start); /* We need at least an RSDP and an RSDT Table */ rsdp = (acpi_rsdp_t *) current; current += sizeof(acpi_rsdp_t); ALIGN_CURRENT; rsdt = (acpi_rsdt_t *) current; current += sizeof(acpi_rsdt_t); ALIGN_CURRENT; xsdt = (acpi_xsdt_t *) current; current += sizeof(acpi_xsdt_t); ALIGN_CURRENT; /* clear all table memory */ memset((void *) start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, xsdt); acpi_write_rsdt(rsdt); acpi_write_xsdt(xsdt); printk(BIOS_DEBUG, "ACPI: * FACS\n"); facs = (acpi_facs_t *) current; current += sizeof(acpi_facs_t); ALIGN_CURRENT; acpi_create_facs(facs); printk(BIOS_DEBUG, "ACPI: * DSDT\n"); dsdt = (acpi_header_t *) current; memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); if (dsdt->length >= sizeof(acpi_header_t)) { current += sizeof(acpi_header_t); acpigen_set_current((char *) current); for (dev = all_devices; dev; dev = dev->next) if (dev->ops && dev->ops->acpi_inject_dsdt_generator) { dev->ops->acpi_inject_dsdt_generator(); } current = (unsigned long) acpigen_get_current(); memcpy((char *)current, (char *)&AmlCode + sizeof(acpi_header_t), dsdt->length - sizeof(acpi_header_t)); current += dsdt->length - sizeof(acpi_header_t); /* (Re)calculate length and checksum. */ dsdt->length = current - (unsigned long)dsdt; dsdt->checksum = 0; dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length); } ALIGN_CURRENT; printk(BIOS_DEBUG, "ACPI: * FADT\n"); fadt = (acpi_fadt_t *) current; current += sizeof(acpi_fadt_t); ALIGN_CURRENT; acpi_create_fadt(fadt, facs, dsdt); acpi_add_table(rsdp, fadt); #if CONFIG_HAVE_ACPI_SLIC printk(BIOS_DEBUG, "ACPI: * SLIC\n"); slic = (acpi_header_t *)current; current += acpi_create_slic(current); ALIGN_CURRENT; acpi_add_table(rsdp, slic); #endif printk(BIOS_DEBUG, "ACPI: * SSDT\n"); ssdt = (acpi_header_t *)current; acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR); if (ssdt->length > sizeof(acpi_header_t)) { current += ssdt->length; acpi_add_table(rsdp, ssdt); ALIGN_CURRENT; } printk(BIOS_DEBUG, "ACPI: * MCFG\n"); mcfg = (acpi_mcfg_t *) current; acpi_create_mcfg(mcfg); if (mcfg->header.length > sizeof(acpi_mcfg_t)) { current += mcfg->header.length; ALIGN_CURRENT; acpi_add_table(rsdp, mcfg); } printk(BIOS_DEBUG, "ACPI: * MADT\n"); madt = (acpi_madt_t *) current; acpi_create_madt(madt); if (madt->header.length > sizeof(acpi_madt_t)) { current+=madt->header.length; acpi_add_table(rsdp,madt); } ALIGN_CURRENT; printk(BIOS_DEBUG, "current = %lx\n", current); for (dev = all_devices; dev; dev = dev->next) { if (dev->ops && dev->ops->write_acpi_tables) { current = dev->ops->write_acpi_tables(current, rsdp); ALIGN_CURRENT; } } printk(BIOS_INFO, "ACPI: done.\n"); return current; }
/* * QEMU's version of write_acpi_tables is defined in * arch/x86/cpu/qemu/acpi_table.c */ u32 write_acpi_tables(u32 start) { u32 current; struct acpi_rsdp *rsdp; struct acpi_rsdt *rsdt; struct acpi_xsdt *xsdt; struct acpi_facs *facs; struct acpi_table_header *dsdt; struct acpi_fadt *fadt; struct acpi_mcfg *mcfg; struct acpi_madt *madt; current = start; /* Align ACPI tables to 16 byte */ current = ALIGN(current, 16); debug("ACPI: Writing ACPI tables at %x\n", start); /* We need at least an RSDP and an RSDT Table */ rsdp = (struct acpi_rsdp *)current; current += sizeof(struct acpi_rsdp); current = ALIGN(current, 16); rsdt = (struct acpi_rsdt *)current; current += sizeof(struct acpi_rsdt); current = ALIGN(current, 16); xsdt = (struct acpi_xsdt *)current; current += sizeof(struct acpi_xsdt); /* * Per ACPI spec, the FACS table address must be aligned to a 64 byte * boundary (Windows checks this, but Linux does not). */ current = ALIGN(current, 64); /* clear all table memory */ memset((void *)start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, xsdt); acpi_write_rsdt(rsdt); acpi_write_xsdt(xsdt); debug("ACPI: * FACS\n"); facs = (struct acpi_facs *)current; current += sizeof(struct acpi_facs); current = ALIGN(current, 16); acpi_create_facs(facs); debug("ACPI: * DSDT\n"); dsdt = (struct acpi_table_header *)current; memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header)); current += sizeof(struct acpi_table_header); memcpy((char *)current, (char *)&AmlCode + sizeof(struct acpi_table_header), dsdt->length - sizeof(struct acpi_table_header)); current += dsdt->length - sizeof(struct acpi_table_header); current = ALIGN(current, 16); debug("ACPI: * FADT\n"); fadt = (struct acpi_fadt *)current; current += sizeof(struct acpi_fadt); current = ALIGN(current, 16); acpi_create_fadt(fadt, facs, dsdt); acpi_add_table(rsdp, fadt); debug("ACPI: * MADT\n"); madt = (struct acpi_madt *)current; acpi_create_madt(madt); current += madt->header.length; acpi_add_table(rsdp, madt); current = ALIGN(current, 16); debug("ACPI: * MCFG\n"); mcfg = (struct acpi_mcfg *)current; acpi_create_mcfg(mcfg); current += mcfg->header.length; acpi_add_table(rsdp, mcfg); current = ALIGN(current, 16); debug("current = %x\n", current); debug("ACPI: done\n"); /* * Other than waiting for OSPM to request us to switch to ACPI mode, * do it by ourselves, since SMI will not be triggered. */ enter_acpi_mode(fadt->pm1a_cnt_blk); return current; }
unsigned long write_acpi_tables(unsigned long start) { unsigned long current; int i; acpi_rsdp_t *rsdp; acpi_rsdt_t *rsdt; acpi_xsdt_t *xsdt; acpi_hpet_t *hpet; acpi_madt_t *madt; acpi_mcfg_t *mcfg; acpi_fadt_t *fadt; acpi_facs_t *facs; #if CONFIG_HAVE_ACPI_SLIC acpi_header_t *slic; #endif acpi_header_t *ssdt; acpi_header_t *dsdt; global_nvs_t *gnvs; current = start; /* Align ACPI tables to 16byte */ ALIGN_CURRENT; printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start); /* We need at least an RSDP and an RSDT Table */ rsdp = (acpi_rsdp_t *) current; current += sizeof(acpi_rsdp_t); ALIGN_CURRENT; rsdt = (acpi_rsdt_t *) current; current += sizeof(acpi_rsdt_t); ALIGN_CURRENT; xsdt = (acpi_xsdt_t *) current; current += sizeof(acpi_xsdt_t); ALIGN_CURRENT; /* clear all table memory */ memset((void *) start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, xsdt); acpi_write_rsdt(rsdt); acpi_write_xsdt(xsdt); printk(BIOS_DEBUG, "ACPI: * FACS\n"); facs = (acpi_facs_t *) current; current += sizeof(acpi_facs_t); ALIGN_CURRENT; acpi_create_facs(facs); printk(BIOS_DEBUG, "ACPI: * DSDT\n"); dsdt = (acpi_header_t *) current; memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); current += dsdt->length; memcpy(dsdt, &AmlCode, dsdt->length); ALIGN_CURRENT; printk(BIOS_DEBUG, "ACPI: * FADT\n"); fadt = (acpi_fadt_t *) current; current += sizeof(acpi_fadt_t); ALIGN_CURRENT; acpi_create_fadt(fadt, facs, dsdt); acpi_add_table(rsdp, fadt); /* * We explicitly add these tables later on: */ printk(BIOS_DEBUG, "ACPI: * HPET\n"); hpet = (acpi_hpet_t *) current; current += sizeof(acpi_hpet_t); ALIGN_CURRENT; acpi_create_intel_hpet(hpet); acpi_add_table(rsdp, hpet); /* If we want to use HPET Timers Linux wants an MADT */ printk(BIOS_DEBUG, "ACPI: * MADT\n"); madt = (acpi_madt_t *) current; acpi_create_madt(madt); current += madt->header.length; ALIGN_CURRENT; acpi_add_table(rsdp, madt); printk(BIOS_DEBUG, "ACPI: * MCFG\n"); mcfg = (acpi_mcfg_t *) current; acpi_create_mcfg(mcfg); current += mcfg->header.length; ALIGN_CURRENT; acpi_add_table(rsdp, mcfg); /* Update GNVS pointer into CBMEM */ gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); if (!gnvs) { printk(BIOS_DEBUG, "ACPI: Could not find CBMEM GNVS\n"); gnvs = (global_nvs_t *)current; } for (i=0; i < dsdt->length; i++) { if (*(u32*)(((u32)dsdt) + i) == 0xC0DEBABE) { printk(BIOS_DEBUG, "ACPI: Patching up global NVS in " "DSDT at offset 0x%04x -> %p\n", i, gnvs); *(u32*)(((u32)dsdt) + i) = (unsigned long)gnvs; acpi_save_gnvs((unsigned long)gnvs); break; } } /* And fill it */ acpi_create_gnvs(gnvs); /* And tell SMI about it */ smm_setup_structures(gnvs, NULL, NULL); current += sizeof(global_nvs_t); ALIGN_CURRENT; /* We patched up the DSDT, so we need to recalculate the checksum */ dsdt->checksum = 0; dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length); printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt, dsdt->length); #if CONFIG_HAVE_ACPI_SLIC printk(BIOS_DEBUG, "ACPI: * SLIC\n"); slic = (acpi_header_t *)current; current += acpi_create_slic(current); ALIGN_CURRENT; acpi_add_table(rsdp, slic); #endif printk(BIOS_DEBUG, "ACPI: * SSDT\n"); ssdt = (acpi_header_t *)current; acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR); current += ssdt->length; acpi_add_table(rsdp, ssdt); ALIGN_CURRENT; printk(BIOS_DEBUG, "ACPI: * SSDT2\n"); ssdt = (acpi_header_t *)current; acpi_create_serialio_ssdt(ssdt); current += ssdt->length; acpi_add_table(rsdp, ssdt); ALIGN_CURRENT; printk(BIOS_DEBUG, "current = %lx\n", current); printk(BIOS_INFO, "ACPI: done.\n"); return current; }
unsigned long write_acpi_tables(unsigned long start) { unsigned long current; acpi_rsdp_t *rsdp; acpi_rsdt_t *rsdt; acpi_xsdt_t *xsdt; acpi_hpet_t *hpet; acpi_madt_t *madt; acpi_srat_t *srat; acpi_slit_t *slit; acpi_facs_t *facs; acpi_header_t *dsdt; acpi_header_t *ssdt; get_bus_conf(); //it will get sblk, pci1234, hcdn, and sbdn /* Align ACPI tables to 16byte */ start = ( start + 0x0f ) & -0x10; current = start; printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx...\n", start); /* We need at least an RSDP and an RSDT Table */ rsdp = (acpi_rsdp_t *) current; current += sizeof(acpi_rsdp_t); rsdt = (acpi_rsdt_t *) current; current += sizeof(acpi_rsdt_t); xsdt = (acpi_xsdt_t *) current; current += sizeof(acpi_xsdt_t); /* clear all table memory */ memset((void *)start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, xsdt); acpi_write_rsdt(rsdt); acpi_write_xsdt(xsdt); /* * We explicitly add these tables later on: */ printk(BIOS_DEBUG, "ACPI: * HPET\n"); hpet = (acpi_hpet_t *) current; current += sizeof(acpi_hpet_t); acpi_create_hpet(hpet); acpi_add_table(rsdp,hpet); /* If we want to use HPET Timers Linux wants an MADT */ printk(BIOS_DEBUG, "ACPI: * MADT\n"); madt = (acpi_madt_t *) current; acpi_create_madt(madt); current+=madt->header.length; acpi_add_table(rsdp,madt); /* SRAT */ printk(BIOS_DEBUG, "ACPI: * SRAT\n"); srat = (acpi_srat_t *) current; acpi_create_srat(srat); current+=srat->header.length; acpi_add_table(rsdp,srat); /* SLIT */ printk(BIOS_DEBUG, "ACPI: * SLIT\n"); slit = (acpi_slit_t *) current; acpi_create_slit(slit); current+=slit->header.length; acpi_add_table(rsdp,slit); /* SSDT */ printk(BIOS_DEBUG, "ACPI: * SSDT\n"); ssdt = (acpi_header_t *)current; acpi_create_ssdt_generator(ssdt, "DYNADATA"); current += ssdt->length; acpi_add_table(rsdp, ssdt); #if CONFIG_ACPI_SSDTX_NUM >= 1 int i; void *p; acpi_header_t *ssdtx; //same htio, but different position? We may have to copy, change HCIN, and recalculate the checknum and add_table for(i=1;i<sysconf.hc_possible_num;i++) { // 0: is hc sblink if((sysconf.pci1234[i] & 1) != 1 ) continue; uint8_t c; if(i<7) { c = (uint8_t) ('4' + i - 1); } else { c = (uint8_t) ('A' + i - 1 - 6); } printk(BIOS_DEBUG, "ACPI: * SSDT for PCI%c Aka hcid = %d\n", c, sysconf.hcid[i]); //pci0 and pci1 are in dsdt current = ( current + 0x07) & -0x08; ssdtx = (acpi_header_t *)current; switch(sysconf.hcid[i]) { case 1: //8132 p = &AmlCode_ssdt2; break; case 2: //8151 p = &AmlCode_ssdt3; break; case 3: //8131 p = &AmlCode_ssdt4; break; default: //HTX no io apic p = &AmlCode_ssdt5; break; } memcpy(ssdtx, p, sizeof(acpi_header_t)); current += ssdtx->length; memcpy(ssdtx, p, ssdtx->length); update_ssdtx((void *)ssdtx, i); ssdtx->checksum = 0; ssdtx->checksum = acpi_checksum((unsigned char *)ssdtx,ssdtx->length); acpi_add_table(rsdp,ssdtx); } #endif /* FACS */ printk(BIOS_DEBUG, "ACPI: * FACS\n"); facs = (acpi_facs_t *) current; current += sizeof(acpi_facs_t); acpi_create_facs(facs); /* DSDT */ printk(BIOS_DEBUG, "ACPI: * DSDT\n"); dsdt = (acpi_header_t *)current; memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); current += dsdt->length; memcpy(dsdt, &AmlCode, dsdt->length); printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n",dsdt,dsdt->length); /* FADT */ printk(BIOS_DEBUG, "ACPI: * FADT\n"); acpi_fadt_t *fadt = (acpi_fadt_t *) current; current += sizeof(acpi_fadt_t); acpi_create_fadt(fadt,facs,dsdt); acpi_add_table(rsdp,fadt); printk(BIOS_INFO, "ACPI: done.\n"); return current; }
unsigned long write_acpi_tables(unsigned long start) { unsigned long current; int i; acpi_rsdp_t *rsdp; acpi_rsdt_t *rsdt; acpi_xsdt_t *xsdt; acpi_hpet_t *hpet; acpi_madt_t *madt; acpi_mcfg_t *mcfg; acpi_fadt_t *fadt; acpi_facs_t *facs; #if CONFIG_HAVE_ACPI_SLIC acpi_header_t *slic; #endif acpi_header_t *ssdt; acpi_header_t *dsdt; current = start; /* Align ACPI tables to 16byte */ ALIGN_CURRENT; printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start); /* We need at least an RSDP and an RSDT Table */ rsdp = (acpi_rsdp_t *) current; current += sizeof(acpi_rsdp_t); ALIGN_CURRENT; rsdt = (acpi_rsdt_t *) current; current += sizeof(acpi_rsdt_t); ALIGN_CURRENT; xsdt = (acpi_xsdt_t *) current; current += sizeof(acpi_xsdt_t); ALIGN_CURRENT; /* clear all table memory */ memset((void *) start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, xsdt); acpi_write_rsdt(rsdt); acpi_write_xsdt(xsdt); /* * We explicitly add these tables later on: */ printk(BIOS_DEBUG, "ACPI: * HPET\n"); hpet = (acpi_hpet_t *) current; current += sizeof(acpi_hpet_t); ALIGN_CURRENT; acpi_create_intel_hpet(hpet); acpi_add_table(rsdp, hpet); /* If we want to use HPET Timers Linux wants an MADT */ printk(BIOS_DEBUG, "ACPI: * MADT\n"); madt = (acpi_madt_t *) current; acpi_create_madt(madt); current += madt->header.length; ALIGN_CURRENT; acpi_add_table(rsdp, madt); printk(BIOS_DEBUG, "ACPI: * MCFG\n"); mcfg = (acpi_mcfg_t *) current; acpi_create_mcfg(mcfg); current += mcfg->header.length; ALIGN_CURRENT; acpi_add_table(rsdp, mcfg); printk(BIOS_DEBUG, "ACPI: * FACS\n"); facs = (acpi_facs_t *) current; current += sizeof(acpi_facs_t); ALIGN_CURRENT; acpi_create_facs(facs); dsdt = (acpi_header_t *) current; memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); current += dsdt->length; memcpy(dsdt, &AmlCode, dsdt->length); ALIGN_CURRENT; /* Pack GNVS into the ACPI table area */ for (i=0; i < dsdt->length; i++) { if (*(u32*)(((u32)dsdt) + i) == 0xC0DEBABE) { printk(BIOS_DEBUG, "ACPI: Patching up global NVS in DSDT at offset 0x%04x -> 0x%08lx\n", i, current); *(u32*)(((u32)dsdt) + i) = current; // 0x92 bytes break; } } /* And fill it */ acpi_create_gnvs((global_nvs_t *)current); current += 0x100; ALIGN_CURRENT; /* And tell SMI about it */ smm_setup_structures((void *)current, NULL, NULL); /* We patched up the DSDT, so we need to recalculate the checksum */ dsdt->checksum = 0; dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length); printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt, dsdt->length); #if CONFIG_HAVE_ACPI_SLIC printk(BIOS_DEBUG, "ACPI: * SLIC\n"); slic = (acpi_header_t *)current; current += acpi_create_slic(current); ALIGN_CURRENT; acpi_add_table(rsdp, slic); #endif printk(BIOS_DEBUG, "ACPI: * FADT\n"); fadt = (acpi_fadt_t *) current; current += sizeof(acpi_fadt_t); ALIGN_CURRENT; acpi_create_fadt(fadt, facs, dsdt); acpi_add_table(rsdp, fadt); printk(BIOS_DEBUG, "ACPI: * SSDT\n"); ssdt = (acpi_header_t *)current; acpi_create_ssdt_generator(ssdt, "COREBOOT"); current += ssdt->length; acpi_add_table(rsdp, ssdt); ALIGN_CURRENT; printk(BIOS_DEBUG, "current = %lx\n", current); printk(BIOS_DEBUG, "ACPI: * DMI (Linux workaround)\n"); memcpy((void *)0xfff80, dmi_table, DMI_TABLE_SIZE); #if CONFIG_WRITE_HIGH_TABLES == 1 memcpy((void *)current, dmi_table, DMI_TABLE_SIZE); current += DMI_TABLE_SIZE; ALIGN_CURRENT; #endif printk(BIOS_INFO, "ACPI: done.\n"); return current; }
unsigned long write_acpi_tables(unsigned long start) { unsigned long current; acpi_rsdp_t *rsdp; acpi_rsdt_t *rsdt; acpi_xsdt_t *xsdt; acpi_fadt_t *fadt; acpi_facs_t *facs; acpi_header_t *slic_file, *slic; acpi_header_t *ssdt; acpi_header_t *dsdt_file, *dsdt; acpi_mcfg_t *mcfg; acpi_tcpa_t *tcpa; acpi_madt_t *madt; struct device *dev; unsigned long fw; size_t slic_size, dsdt_size; char oem_id[6], oem_table_id[8]; current = start; /* Align ACPI tables to 16byte */ current = acpi_align_current(current); fw = fw_cfg_acpi_tables(current); if (fw) return fw; #if CONFIG_COMPILE_IN_DSDT extern char _binary_dsdt_aml_start; extern char _binary_dsdt_aml_end; dsdt_file = (acpi_header_t *)&_binary_dsdt_aml_start; dsdt_size = (size_t)(&_binary_dsdt_aml_end - &_binary_dsdt_aml_start); #else dsdt_file = cbfs_boot_map_with_leak( CONFIG_CBFS_PREFIX "/dsdt.aml", CBFS_TYPE_RAW, &dsdt_size); #endif if (!dsdt_file) { printk(BIOS_ERR, "No DSDT file, skipping ACPI tables\n"); return current; } if (dsdt_file->length > dsdt_size || dsdt_file->length < sizeof (acpi_header_t) || memcmp(dsdt_file->signature, "DSDT", 4) != 0) { printk(BIOS_ERR, "Invalid DSDT file, skipping ACPI tables\n"); return current; } slic_file = cbfs_boot_map_with_leak(CONFIG_CBFS_PREFIX "/slic", CBFS_TYPE_RAW, &slic_size); if (slic_file && (slic_file->length > slic_size || slic_file->length < sizeof (acpi_header_t) || memcmp(slic_file->signature, "SLIC", 4) != 0)) { slic_file = 0; } if (slic_file) { memcpy(oem_id, slic_file->oem_id, 6); memcpy(oem_table_id, slic_file->oem_table_id, 8); } else { memcpy(oem_id, OEM_ID, 6); memcpy(oem_table_id, ACPI_TABLE_CREATOR, 8); } printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start); /* We need at least an RSDP and an RSDT Table */ rsdp = (acpi_rsdp_t *) current; current += sizeof(acpi_rsdp_t); current = acpi_align_current(current); rsdt = (acpi_rsdt_t *) current; current += sizeof(acpi_rsdt_t); current = acpi_align_current(current); xsdt = (acpi_xsdt_t *) current; current += sizeof(acpi_xsdt_t); current = acpi_align_current(current); /* clear all table memory */ memset((void *) start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, xsdt, oem_id); acpi_write_rsdt(rsdt, oem_id, oem_table_id); acpi_write_xsdt(xsdt, oem_id, oem_table_id); printk(BIOS_DEBUG, "ACPI: * FACS\n"); current = (ALIGN(current, 64)); facs = (acpi_facs_t *) current; current += sizeof(acpi_facs_t); current = acpi_align_current(current); acpi_create_facs(facs); printk(BIOS_DEBUG, "ACPI: * DSDT\n"); dsdt = (acpi_header_t *) current; memcpy(dsdt, dsdt_file, sizeof(acpi_header_t)); if (dsdt->length >= sizeof(acpi_header_t)) { current += sizeof(acpi_header_t); acpigen_set_current((char *) current); for (dev = all_devices; dev; dev = dev->next) if (dev->ops && dev->ops->acpi_inject_dsdt_generator) { dev->ops->acpi_inject_dsdt_generator(dev); } current = (unsigned long) acpigen_get_current(); memcpy((char *)current, (char *)dsdt_file + sizeof(acpi_header_t), dsdt->length - sizeof(acpi_header_t)); current += dsdt->length - sizeof(acpi_header_t); /* (Re)calculate length and checksum. */ dsdt->length = current - (unsigned long)dsdt; dsdt->checksum = 0; dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length); } current = acpi_align_current(current); printk(BIOS_DEBUG, "ACPI: * FADT\n"); fadt = (acpi_fadt_t *) current; current += sizeof(acpi_fadt_t); current = acpi_align_current(current); acpi_create_fadt(fadt, facs, dsdt); acpi_add_table(rsdp, fadt); if (slic_file) { printk(BIOS_DEBUG, "ACPI: * SLIC\n"); slic = (acpi_header_t *)current; memcpy(slic, slic_file, slic_file->length); current += slic_file->length; current = acpi_align_current(current); acpi_add_table(rsdp, slic); } printk(BIOS_DEBUG, "ACPI: * SSDT\n"); ssdt = (acpi_header_t *)current; acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR); if (ssdt->length > sizeof(acpi_header_t)) { current += ssdt->length; acpi_add_table(rsdp, ssdt); current = acpi_align_current(current); } printk(BIOS_DEBUG, "ACPI: * MCFG\n"); mcfg = (acpi_mcfg_t *) current; acpi_create_mcfg(mcfg); if (mcfg->header.length > sizeof(acpi_mcfg_t)) { current += mcfg->header.length; current = acpi_align_current(current); acpi_add_table(rsdp, mcfg); } printk(BIOS_DEBUG, "ACPI: * TCPA\n"); tcpa = (acpi_tcpa_t *) current; acpi_create_tcpa(tcpa); if (tcpa->header.length >= sizeof(acpi_tcpa_t)) { current += tcpa->header.length; current = acpi_align_current(current); acpi_add_table(rsdp, tcpa); } printk(BIOS_DEBUG, "ACPI: * MADT\n"); madt = (acpi_madt_t *) current; acpi_create_madt(madt); if (madt->header.length > sizeof(acpi_madt_t)) { current+=madt->header.length; acpi_add_table(rsdp,madt); } current = acpi_align_current(current); printk(BIOS_DEBUG, "current = %lx\n", current); for (dev = all_devices; dev; dev = dev->next) { if (dev->ops && dev->ops->write_acpi_tables) { current = dev->ops->write_acpi_tables(dev, current, rsdp); current = acpi_align_current(current); } } printk(BIOS_INFO, "ACPI: done.\n"); return current; }
/* * QEMU's version of write_acpi_tables is defined in * arch/x86/cpu/qemu/fw_cfg.c */ unsigned long write_acpi_tables(unsigned long start) { unsigned long current; struct acpi_rsdp *rsdp; struct acpi_rsdt *rsdt; struct acpi_xsdt *xsdt; struct acpi_facs *facs; acpi_header_t *dsdt; struct acpi_fadt *fadt; struct acpi_mcfg *mcfg; struct acpi_madt *madt; acpi_header_t *ssdt; current = start; /* Align ACPI tables to 16byte */ current = ALIGN(current, 16); debug("ACPI: Writing ACPI tables at %lx.\n", start); /* We need at least an RSDP and an RSDT Table */ rsdp = (struct acpi_rsdp *)current; current += sizeof(struct acpi_rsdp); current = ALIGN(current, 16); rsdt = (struct acpi_rsdt *)current; current += sizeof(struct acpi_rsdt); current = ALIGN(current, 16); xsdt = (struct acpi_xsdt *)current; current += sizeof(struct acpi_xsdt); current = ALIGN(current, 16); /* clear all table memory */ memset((void *)start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, xsdt); acpi_write_rsdt(rsdt); acpi_write_xsdt(xsdt); debug("ACPI: * FACS\n"); facs = (struct acpi_facs *)current; current += sizeof(struct acpi_facs); current = ALIGN(current, 16); acpi_create_facs(facs); debug("ACPI: * DSDT\n"); dsdt = (acpi_header_t *)current; memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); if (dsdt->length >= sizeof(acpi_header_t)) { current += sizeof(acpi_header_t); memcpy((char *)current, (char *)&AmlCode + sizeof(acpi_header_t), dsdt->length - sizeof(acpi_header_t)); current += dsdt->length - sizeof(acpi_header_t); /* (Re)calculate length and checksum */ dsdt->length = current - (unsigned long)dsdt; dsdt->checksum = 0; dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length); } current = ALIGN(current, 16); debug("ACPI: * FADT\n"); fadt = (struct acpi_fadt *)current; current += sizeof(struct acpi_fadt); current = ALIGN(current, 16); acpi_create_fadt(fadt, facs, dsdt); acpi_add_table(rsdp, fadt); debug("ACPI: * MCFG\n"); mcfg = (struct acpi_mcfg *)current; acpi_create_mcfg(mcfg); if (mcfg->header.length > sizeof(struct acpi_mcfg)) { current += mcfg->header.length; current = ALIGN(current, 16); acpi_add_table(rsdp, mcfg); } debug("ACPI: * MADT\n"); madt = (struct acpi_madt *)current; acpi_create_madt(madt); if (madt->header.length > sizeof(struct acpi_madt)) { current += madt->header.length; acpi_add_table(rsdp, madt); } current = ALIGN(current, 16); debug("ACPI: * SSDT\n"); ssdt = (acpi_header_t *)current; acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR); if (ssdt->length > sizeof(acpi_header_t)) { current += ssdt->length; acpi_add_table(rsdp, ssdt); current = ALIGN(current, 16); } debug("current = %lx\n", current); debug("ACPI: done.\n"); return current; }
/* * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c */ ulong write_acpi_tables(ulong start) { u32 current; struct acpi_rsdp *rsdp; struct acpi_rsdt *rsdt; struct acpi_xsdt *xsdt; struct acpi_facs *facs; struct acpi_table_header *dsdt; struct acpi_fadt *fadt; struct acpi_mcfg *mcfg; struct acpi_madt *madt; struct acpi_spcr *spcr; int i; current = start; /* Align ACPI tables to 16 byte */ current = ALIGN(current, 16); debug("ACPI: Writing ACPI tables at %lx\n", start); /* We need at least an RSDP and an RSDT Table */ rsdp = (struct acpi_rsdp *)current; current += sizeof(struct acpi_rsdp); current = ALIGN(current, 16); rsdt = (struct acpi_rsdt *)current; current += sizeof(struct acpi_rsdt); current = ALIGN(current, 16); xsdt = (struct acpi_xsdt *)current; current += sizeof(struct acpi_xsdt); /* * Per ACPI spec, the FACS table address must be aligned to a 64 byte * boundary (Windows checks this, but Linux does not). */ current = ALIGN(current, 64); /* clear all table memory */ memset((void *)start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, xsdt); acpi_write_rsdt(rsdt); acpi_write_xsdt(xsdt); debug("ACPI: * FACS\n"); facs = (struct acpi_facs *)current; current += sizeof(struct acpi_facs); current = ALIGN(current, 16); acpi_create_facs(facs); debug("ACPI: * DSDT\n"); dsdt = (struct acpi_table_header *)current; memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header)); current += sizeof(struct acpi_table_header); memcpy((char *)current, (char *)&AmlCode + sizeof(struct acpi_table_header), dsdt->length - sizeof(struct acpi_table_header)); current += dsdt->length - sizeof(struct acpi_table_header); current = ALIGN(current, 16); /* Pack GNVS into the ACPI table area */ for (i = 0; i < dsdt->length; i++) { u32 *gnvs = (u32 *)((u32)dsdt + i); if (*gnvs == ACPI_GNVS_ADDR) { debug("Fix up global NVS in DSDT to 0x%08x\n", current); *gnvs = current; break; } } /* Update DSDT checksum since we patched the GNVS address */ dsdt->checksum = 0; dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length); /* Fill in platform-specific global NVS variables */ acpi_create_gnvs((struct acpi_global_nvs *)current); current += sizeof(struct acpi_global_nvs); current = ALIGN(current, 16); debug("ACPI: * FADT\n"); fadt = (struct acpi_fadt *)current; current += sizeof(struct acpi_fadt); current = ALIGN(current, 16); acpi_create_fadt(fadt, facs, dsdt); acpi_add_table(rsdp, fadt); debug("ACPI: * MADT\n"); madt = (struct acpi_madt *)current; acpi_create_madt(madt); current += madt->header.length; acpi_add_table(rsdp, madt); current = ALIGN(current, 16); debug("ACPI: * MCFG\n"); mcfg = (struct acpi_mcfg *)current; acpi_create_mcfg(mcfg); current += mcfg->header.length; acpi_add_table(rsdp, mcfg); current = ALIGN(current, 16); debug("ACPI: * SPCR\n"); spcr = (struct acpi_spcr *)current; acpi_create_spcr(spcr); current += spcr->header.length; acpi_add_table(rsdp, spcr); current = ALIGN(current, 16); debug("current = %x\n", current); acpi_rsdp_addr = (unsigned long)rsdp; debug("ACPI: done\n"); return current; }