ACPI_TABLE_HEADER * dsdt_load_file(char *infile) { ACPI_TABLE_HEADER *sdt; uint8_t *dp; struct stat sb; if ((acpi_mem_fd = open(infile, O_RDONLY)) == -1) errx(1, "opening %s", infile); LIST_INIT(&maplist); if (fstat(acpi_mem_fd, &sb) == -1) errx(1, "fstat %s", infile); dp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, acpi_mem_fd, 0); if (dp == NULL) errx(1, "mmap %s", infile); sdt = (ACPI_TABLE_HEADER *)dp; if (strncmp(dp, ACPI_SIG_DSDT, 4) != 0 || acpi_checksum(sdt, sdt->Length) != 0) return (NULL); return (sdt); }
/* http://www.intel.com/hardwaredesign/hpetspec_1.pdf */ void acpi_create_hpet(acpi_hpet_t *hpet) { acpi_header_t *header = &(hpet->header); acpi_addr_t *addr = &(hpet->addr); memset((void *)hpet, 0, sizeof(acpi_hpet_t)); /* Fill out header fields. */ memcpy(header->signature, "HPET", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->length = sizeof(acpi_hpet_t); header->revision = 1; /* Currently 1. Table added in ACPI 2.0. */ /* Fill out HPET address. */ addr->space_id = 0; /* Memory */ addr->bit_width = 64; addr->bit_offset = 0; addr->addrl = CONFIG_HPET_ADDRESS & 0xffffffff; addr->addrh = ((unsigned long long)CONFIG_HPET_ADDRESS) >> 32; hpet->id = *(unsigned int*)CONFIG_HPET_ADDRESS; hpet->number = 0; hpet->min_tick = CONFIG_HPET_MIN_TICKS; header->checksum = acpi_checksum((void *)hpet, sizeof(acpi_hpet_t)); }
void acpi_create_dmar(acpi_dmar_t *dmar) { acpi_header_t *header = &(dmar->header); unsigned long current = (unsigned long)dmar + sizeof(acpi_dmar_t); memset((void *)dmar, 0, sizeof(acpi_dmar_t)); /* Fill out header fields. */ memcpy(header->signature, "DMAR", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->length = sizeof(acpi_dmar_t); header->revision = 1; dmar->host_address_width = 40 - 1; /* FIXME: == MTRR size? */ dmar->flags = 0; current = acpi_fill_dmar(current); /* (Re)calculate length and checksum. */ header->length = current - (unsigned long)dmar; header->checksum = acpi_checksum((void *)dmar, header->length); }
void acpi_create_madt(acpi_madt_t *madt) { acpi_header_t *header = &(madt->header); unsigned long current = (unsigned long)madt + sizeof(acpi_madt_t); memset((void *)madt, 0, sizeof(acpi_madt_t)); /* Fill out header fields. */ memcpy(header->signature, "APIC", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->length = sizeof(acpi_madt_t); header->revision = 1; /* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */ madt->lapic_addr = LOCAL_APIC_ADDR; madt->flags = 0x1; /* PCAT_COMPAT */ current = acpi_fill_madt(current); /* (Re)calculate length and checksum. */ header->length = current - (unsigned long)madt; header->checksum = acpi_checksum((void *)madt, header->length); }
unsigned long mainboard_write_acpi_tables(device_t device, unsigned long current, acpi_rsdp_t *rsdp) { acpi_header_t *ssdtx; const void *p; size_t p_size; int i; get_bus_conf(); /* it will get sblk, pci1234, hcdn, and sbdn */ /* same htio, but different possition? 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 */ const char *file_name; if((sysconf.pci1234[i] & 1) != 1 ) continue; u8 c; if(i < 7) { c = (u8) ('4' + i - 1); } else { c = (u8) ('A' + i - 1 - 6); } current = ALIGN(current, 8); printk(BIOS_DEBUG, "ACPI: * SSDT for PCI%c at %lx\n", c, current); /* pci0 and pci1 are in dsdt */ ssdtx = (acpi_header_t *)current; switch(sysconf.hcid[i]) { case 1: file_name = CONFIG_CBFS_PREFIX "/ssdt2.aml"; break; case 2: file_name = CONFIG_CBFS_PREFIX "/ssdt3.aml"; break; case 3: /* 8131 */ file_name = CONFIG_CBFS_PREFIX "/ssdt4.aml"; break; default: /* HTX no io apic */ file_name = CONFIG_CBFS_PREFIX "/ssdt5.aml"; } p = cbfs_boot_map_with_leak( file_name, CBFS_TYPE_RAW, &p_size); if (!p || p_size < sizeof(acpi_header_t)) continue; 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((u8 *)ssdtx, ssdtx->length); acpi_add_table(rsdp, ssdtx); } return current; }
static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp) { if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) return NULL; printk(BIOS_DEBUG, "Looking on %p for valid checksum\n", rsdp); if (acpi_checksum((void *)rsdp, 20) != 0) return NULL; printk(BIOS_DEBUG, "Checksum 1 passed\n"); if ((rsdp->revision > 1) && (acpi_checksum((void *)rsdp, rsdp->length) != 0)) return NULL; printk(BIOS_DEBUG, "Checksum 2 passed all OK\n"); return rsdp; }
int acpi_detect(void) { struct ACPIrsdp *rp; struct ACPIsdt *rsdp; u_long addr; size_t len; if (!acpi0_present()) { warnx("no acpi0 device located"); return -1; } acpi_user_init(); /* Attempt to use sysctl to find RSD PTR record. */ len = sizeof(addr); if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) != 0) { warnx("cannot find ACPI information"); return -1; } rp = acpi_get_rsdp(addr); if (rp == NULL) { warnx("cannot find ACPI information: sysctl %s does not point to RSDP", machdep_acpi_root); return -1; } if (rp->revision < 2) { rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->rsdt_addr); if (memcmp(rsdp->signature, "RSDT", 4) != 0 || acpi_checksum(rsdp, rsdp->len) != 0) errx(1, "RSDT is corrupted"); addr_size = sizeof(uint32_t); } else { rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->xsdt_addr); if (memcmp(rsdp->signature, "XSDT", 4) != 0 || acpi_checksum(rsdp, rsdp->len) != 0) errx(1, "XSDT is corrupted"); addr_size = sizeof(uint64_t); } ncpu = 0; acpi_handle_rsdt(rsdp); return (ncpu == 0 ? 1 : ncpu); }
void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt) { acpi_header_t *header = &(fadt->header); acpi_fill_in_fadt(fadt,facs,dsdt); /* Platform specific customizations go here */ header->checksum = 0; header->checksum = acpi_checksum((void *) fadt, sizeof(acpi_fadt_t)); }
unsigned long write_acpi_tables(unsigned long start) { unsigned long current; acpi_rsdp_t *rsdp; acpi_rsdt_t *rsdt; acpi_fadt_t *fadt; acpi_facs_t *facs; acpi_header_t *dsdt; /* Align ACPI tables to 16byte */ start = ALIGN(start, 16); 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); /* clear all table memory */ memset((void *)start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, NULL); acpi_write_rsdt(rsdt); /* * We explicitly add these tables later on: */ printk(BIOS_DEBUG, "ACPI: * FACS\n"); facs = (acpi_facs_t *) current; current += sizeof(acpi_facs_t); acpi_create_facs(facs); dsdt = (acpi_header_t *)current; memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); current += dsdt->length; memcpy(dsdt, &AmlCode, dsdt->length); dsdt->checksum = 0; // don't trust intel iasl compiler to get this right dsdt->checksum = acpi_checksum((u8*)dsdt, dsdt->length); printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n",dsdt,dsdt->length); printk(BIOS_DEBUG, "ACPI: * FADT\n"); 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; }
static void test_acpi_fadt_table(test_data *data) { AcpiFadtDescriptorRev1 *fadt_table = &data->fadt_table; uint32_t addr; /* FADT table comes first */ addr = data->rsdt_tables_addr[0]; ACPI_READ_TABLE_HEADER(fadt_table, addr); ACPI_READ_FIELD(fadt_table->firmware_ctrl, addr); ACPI_READ_FIELD(fadt_table->dsdt, addr); ACPI_READ_FIELD(fadt_table->model, addr); ACPI_READ_FIELD(fadt_table->reserved1, addr); ACPI_READ_FIELD(fadt_table->sci_int, addr); ACPI_READ_FIELD(fadt_table->smi_cmd, addr); ACPI_READ_FIELD(fadt_table->acpi_enable, addr); ACPI_READ_FIELD(fadt_table->acpi_disable, addr); ACPI_READ_FIELD(fadt_table->S4bios_req, addr); ACPI_READ_FIELD(fadt_table->reserved2, addr); ACPI_READ_FIELD(fadt_table->pm1a_evt_blk, addr); ACPI_READ_FIELD(fadt_table->pm1b_evt_blk, addr); ACPI_READ_FIELD(fadt_table->pm1a_cnt_blk, addr); ACPI_READ_FIELD(fadt_table->pm1b_cnt_blk, addr); ACPI_READ_FIELD(fadt_table->pm2_cnt_blk, addr); ACPI_READ_FIELD(fadt_table->pm_tmr_blk, addr); ACPI_READ_FIELD(fadt_table->gpe0_blk, addr); ACPI_READ_FIELD(fadt_table->gpe1_blk, addr); ACPI_READ_FIELD(fadt_table->pm1_evt_len, addr); ACPI_READ_FIELD(fadt_table->pm1_cnt_len, addr); ACPI_READ_FIELD(fadt_table->pm2_cnt_len, addr); ACPI_READ_FIELD(fadt_table->pm_tmr_len, addr); ACPI_READ_FIELD(fadt_table->gpe0_blk_len, addr); ACPI_READ_FIELD(fadt_table->gpe1_blk_len, addr); ACPI_READ_FIELD(fadt_table->gpe1_base, addr); ACPI_READ_FIELD(fadt_table->reserved3, addr); ACPI_READ_FIELD(fadt_table->plvl2_lat, addr); ACPI_READ_FIELD(fadt_table->plvl3_lat, addr); ACPI_READ_FIELD(fadt_table->flush_size, addr); ACPI_READ_FIELD(fadt_table->flush_stride, addr); ACPI_READ_FIELD(fadt_table->duty_offset, addr); ACPI_READ_FIELD(fadt_table->duty_width, addr); ACPI_READ_FIELD(fadt_table->day_alrm, addr); ACPI_READ_FIELD(fadt_table->mon_alrm, addr); ACPI_READ_FIELD(fadt_table->century, addr); ACPI_READ_FIELD(fadt_table->reserved4, addr); ACPI_READ_FIELD(fadt_table->reserved4a, addr); ACPI_READ_FIELD(fadt_table->reserved4b, addr); ACPI_READ_FIELD(fadt_table->flags, addr); ACPI_ASSERT_CMP(fadt_table->signature, "FACP"); g_assert(!acpi_checksum((uint8_t *)fadt_table, fadt_table->length)); }
static u64 find_rsdp_iapc_sub (u64 start, u64 end) { struct rsdp *p; u64 i; for (i = start; i < end; i += 16) { p = acpi_mapmem (i, sizeof *p); if (!memcmp (p->signature, RSDP_SIGNATURE, RSDP_SIGNATURE_LEN) && !acpi_checksum (p, sizeof *p)) return i; } return FIND_RSDP_NOT_FOUND; }
static bool smbios_ep_table_ok(test_data *data) { struct smbios_21_entry_point *ep_table = &data->smbios_ep_table; uint32_t addr = data->smbios_ep_addr; ACPI_READ_ARRAY(ep_table->anchor_string, addr); if (memcmp(ep_table->anchor_string, "_SM_", 4)) { return false; } ACPI_READ_FIELD(ep_table->checksum, addr); ACPI_READ_FIELD(ep_table->length, addr); ACPI_READ_FIELD(ep_table->smbios_major_version, addr); ACPI_READ_FIELD(ep_table->smbios_minor_version, addr); ACPI_READ_FIELD(ep_table->max_structure_size, addr); ACPI_READ_FIELD(ep_table->entry_point_revision, addr); ACPI_READ_ARRAY(ep_table->formatted_area, addr); ACPI_READ_ARRAY(ep_table->intermediate_anchor_string, addr); if (memcmp(ep_table->intermediate_anchor_string, "_DMI_", 5)) { return false; } ACPI_READ_FIELD(ep_table->intermediate_checksum, addr); ACPI_READ_FIELD(ep_table->structure_table_length, addr); if (ep_table->structure_table_length == 0) { return false; } ACPI_READ_FIELD(ep_table->structure_table_address, addr); ACPI_READ_FIELD(ep_table->number_of_structures, addr); if (ep_table->number_of_structures == 0) { return false; } ACPI_READ_FIELD(ep_table->smbios_bcd_revision, addr); if (acpi_checksum((uint8_t *)ep_table, sizeof *ep_table) || acpi_checksum((uint8_t *)ep_table + 0x10, sizeof *ep_table - 0x10)) { return false; } return true; }
/* * Reference Serial Port Console Redirection Table * Version 1.00 - January 11, 2002 * * http://msdn.microsoft.com/en-us/windows/hardware/gg487465 */ void acpi_create_spcr(acpi_spcr_t *spcr) { acpi_header_t *header = &(spcr->header); /* Prepare the header */ memset((void *)spcr, 0, sizeof(acpi_spcr_t)); memcpy(header->signature, SPCR_SIG, 4); header->length = sizeof(acpi_spcr_t); header->revision = ACPI_SPCR_REV; memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->asl_compiler_revision = 0; /* TODO: defaulting to 16550 type for now */ spcr->interface_type = SPCR_16550_INTERFACE; spcr->reserved_1 = SPCR_RESERVED_MUST_BE_ZERO; spcr->reserved_2 = SPCR_RESERVED_MUST_BE_ZERO; spcr->reserved_3 = SPCR_RESERVED_MUST_BE_ZERO; spcr->base_address.space_id = SPCR_BAR_TYPE; spcr->base_address.bit_width = 8; spcr->base_address.bit_offset = 0; spcr->base_address.access_size = ACPI_ACCESS_SIZE_UNDEFINED; spcr->base_address.addrl = SPCR_BAR_ADDRESS_LOW; spcr->base_address.addrh = 0x0; spcr->interrupt_type = SPCR_INTERRUPT_TYPE; spcr->irq = SPCR_IRQ; spcr->global_system_interrupt = SPCR_NO_GSI; spcr->baud_rate = SPCR_BAUD; spcr->parity = SPCR_NO_PARITY; spcr->stop_bits = SPCR_1_STOP_BIT; spcr->flow_control = SPCR_NO_FLOW_CONTROL; spcr->terminal_type = SPCR_TERM_VT100; //TODO - what do we want? spcr->reserved_4 = SPCR_RESERVED_MUST_BE_ZERO; spcr->pci_device_id = SPCR_PCI_DID; spcr->pci_vendor_id = SPCR_PCI_VID; spcr->pci_bus_number = SPCR_PCI_BUS; spcr->pci_device_number = SPCR_PCI_DEV; spcr->pci_function_number = SPCR_PCI_FUNC; spcr->pci_flags = SPCR_PCI_FLAGS; spcr->pci_segment = SPCR_PCI_SEGMENT_0; spcr->reserved_5 = SPCR_RESERVED_MUST_BE_ZERO; header->checksum = acpi_checksum((void *)spcr, sizeof(acpi_spcr_t)); }
static void test_acpi_rsdp_table(test_data *data) { AcpiRsdpDescriptor *rsdp_table = &data->rsdp_table; uint32_t addr = data->rsdp_addr; ACPI_READ_FIELD(rsdp_table->signature, addr); ACPI_ASSERT_CMP64(rsdp_table->signature, "RSD PTR "); ACPI_READ_FIELD(rsdp_table->checksum, addr); ACPI_READ_ARRAY(rsdp_table->oem_id, addr); ACPI_READ_FIELD(rsdp_table->revision, addr); ACPI_READ_FIELD(rsdp_table->rsdt_physical_address, addr); ACPI_READ_FIELD(rsdp_table->length, addr); /* rsdp checksum is not for the whole table, but for the first 20 bytes */ g_assert(!acpi_checksum((uint8_t *)rsdp_table, 20)); }
static long acpi_create_ecdt(acpi_ecdt_t * ecdt) { /* Attention: Make sure these match the values from * the DSDT's ec.asl */ static const char ec_id[] = "\\_SB.PCI0.LPCB.EC0"; int ecdt_len = sizeof(acpi_ecdt_t) + strlen(ec_id) + 1; acpi_header_t *header = &(ecdt->header); memset((void *) ecdt, 0, ecdt_len); /* fill out header fields */ memcpy(header->signature, "ECDT", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->length = ecdt_len; header->revision = 1; /* Location of the two EC registers */ ecdt->ec_control.space_id = ACPI_ADDRESS_SPACE_IO; ecdt->ec_control.bit_width = 8; ecdt->ec_control.bit_offset = 0; ecdt->ec_control.addrl = 0x66; ecdt->ec_control.addrh = 0; ecdt->ec_data.space_id = ACPI_ADDRESS_SPACE_IO; /* Memory */ ecdt->ec_data.bit_width = 8; ecdt->ec_data.bit_offset = 0; ecdt->ec_data.addrl = 0x62; ecdt->ec_data.addrh = 0; ecdt->uid = 1; // Must match _UID of the EC0 node. ecdt->gpe_bit = 23; // SCI interrupt within GPEx_STS strncpy((char *)ecdt->ec_id, ec_id, strlen(ec_id)); header->checksum = acpi_checksum((void *) ecdt, ecdt_len); return header->length; }
/* ACPI 4.0 */ void acpi_write_hest(acpi_hest_t *hest) { acpi_header_t *header = &(hest->header); memset(hest, 0, sizeof(acpi_hest_t)); memcpy(header->signature, "HEST", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->length += sizeof(acpi_hest_t); header->revision = 1; acpi_fill_hest(hest); /* Calculate checksums. */ header->checksum = acpi_checksum((void *)hest, header->length); }
void acpi_write_xsdt(acpi_xsdt_t *xsdt) { acpi_header_t *header = &(xsdt->header); /* Fill out header fields. */ memcpy(header->signature, "XSDT", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->length = sizeof(acpi_xsdt_t); header->revision = 1; /* ACPI 1.0: N/A, 2.0/3.0/4.0: 1 */ /* Entries are filled in later, we come with an empty set. */ /* Fix checksum. */ header->checksum = acpi_checksum((void *)xsdt, sizeof(acpi_xsdt_t)); }
static void acpi_write_rsdt(acpi_rsdt_t *rsdt, char *oem_id, char *oem_table_id) { acpi_header_t *header = &(rsdt->header); /* Fill out header fields. */ memcpy(header->signature, "RSDT", 4); memcpy(header->oem_id, oem_id, 6); memcpy(header->oem_table_id, oem_table_id, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->length = sizeof(acpi_rsdt_t); header->revision = 1; /* ACPI 1.0/2.0/3.0/4.0: 1 */ /* Entries are filled in later, we come with an empty set. */ /* Fix checksum. */ header->checksum = acpi_checksum((void *)rsdt, sizeof(acpi_rsdt_t)); }
void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id) { unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t); memset((void *)ssdt, 0, sizeof(acpi_header_t)); memcpy(&ssdt->signature, "SSDT", 4); ssdt->revision = 2; /* ACPI 1.0/2.0: ?, ACPI 3.0/4.0: 2 */ memcpy(&ssdt->oem_id, OEM_ID, 6); memcpy(&ssdt->oem_table_id, oem_table_id, 8); ssdt->oem_revision = 42; memcpy(&ssdt->asl_compiler_id, ASLC, 4); ssdt->asl_compiler_revision = 42; ssdt->length = sizeof(acpi_header_t); acpigen_set_current((char *) current); current = acpi_fill_ssdt_generator(current, oem_table_id); /* (Re)calculate length and checksum. */ ssdt->length = current - (unsigned long)ssdt; ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length); }
/* MCFG is defined in the PCI Firmware Specification 3.0. */ void acpi_create_mcfg(acpi_mcfg_t *mcfg) { acpi_header_t *header = &(mcfg->header); unsigned long current = (unsigned long)mcfg + sizeof(acpi_mcfg_t); memset((void *)mcfg, 0, sizeof(acpi_mcfg_t)); /* Fill out header fields. */ memcpy(header->signature, "MCFG", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->length = sizeof(acpi_mcfg_t); header->revision = 1; current = acpi_fill_mcfg(current); /* (Re)calculate length and checksum. */ header->length = current - (unsigned long)mcfg; header->checksum = acpi_checksum((void *)mcfg, header->length); }
/* * Public interfaces */ ACPI_TABLE_RSDP * acpi_find_rsd_ptr(void) { int i; uint8_t buf[sizeof(ACPI_TABLE_RSDP)]; acpi_user_init(); for (i = 0; i < 1024 * 1024; i += 16) { read(acpi_mem_fd, buf, 16); if (!memcmp(buf, "RSD PTR ", 8)) { /* Read the rest of the structure */ read(acpi_mem_fd, buf + 16, sizeof(ACPI_TABLE_RSDP) - 16); /* Verify checksum before accepting it. */ if (acpi_checksum(buf, sizeof(ACPI_TABLE_RSDP))) continue; return (acpi_map_physical(i, sizeof(ACPI_TABLE_RSDP))); } } return acpi_scan_rsd_ptr(); }
/* http://h21007.www2.hp.com/portal/download/files/unprot/Itanium/slit.pdf */ void acpi_create_slit(acpi_slit_t *slit) { acpi_header_t *header = &(slit->header); unsigned long current = (unsigned long)slit + sizeof(acpi_slit_t); memset((void *)slit, 0, sizeof(acpi_slit_t)); /* Fill out header fields. */ memcpy(header->signature, "SLIT", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->length = sizeof(acpi_slit_t); header->revision = 1; /* ACPI 1.0: N/A, ACPI 2.0/3.0/4.0: 1 */ current = acpi_fill_slit(current); /* (Re)calculate length and checksum. */ header->length = current - (unsigned long)slit; header->checksum = acpi_checksum((void *)slit, header->length); }
void acpi_create_ivrs(acpi_ivrs_t *ivrs, unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t* ivrs_struct, unsigned long current)) { acpi_header_t *header = &(ivrs->header); unsigned long current = (unsigned long)ivrs + sizeof(acpi_ivrs_t); memset((void *)ivrs, 0, sizeof(acpi_ivrs_t)); /* Fill out header fields. */ memcpy(header->signature, "IVRS", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->length = sizeof(acpi_ivrs_t); header->revision = 1; /* ACPI 1.0: N/A, ACPI 2.0/3.0/4.0: 1 */ current = acpi_fill_ivrs(ivrs, current); /* (Re)calculate length and checksum. */ header->length = current - (unsigned long)ivrs; header->checksum = acpi_checksum((void *)ivrs, header->length); }
/* http://www.microsoft.com/whdc/system/sysinternals/sratdwn.mspx */ void acpi_create_srat(acpi_srat_t *srat) { acpi_header_t *header = &(srat->header); unsigned long current = (unsigned long)srat + sizeof(acpi_srat_t); memset((void *)srat, 0, sizeof(acpi_srat_t)); /* Fill out header fields. */ memcpy(header->signature, "SRAT", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->length = sizeof(acpi_srat_t); header->revision = 1; /* ACPI 1.0: N/A, 2.0: 1, 3.0: 2, 4.0: 3 */ srat->resv = 1; /* Spec: Reserved to 1 for backwards compatibility. */ current = acpi_fill_srat(current); /* (Re)calculate length and checksum. */ header->length = current - (unsigned long)srat; header->checksum = acpi_checksum((void *)srat, header->length); }
static int __init acpi_tables_init(void) { int result = -ENODEV; acpi_table_header *header = NULL; struct acpi_table_rsdp *rsdp = NULL; struct acpi_table_rsdt *rsdt = NULL; struct acpi_table_rsdt saved_rsdt; int tables = 0; int type = 0; int i = 0; rsdp = (struct acpi_table_rsdp *) acpi_find_root_pointer(); if (!rsdp) return -ENODEV; printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision, rsdp->oem_id); if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) { printk(KERN_WARNING "RSDP table signature incorrect\n"); return -EINVAL; } rsdt = (struct acpi_table_rsdt *) __va_range(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt)); if (!rsdt) { printk(KERN_WARNING "ACPI: Invalid root system description tables (RSDT)\n"); return -ENODEV; } header = & rsdt->header; acpi_print_table_header(header); if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) { printk(KERN_WARNING "ACPI: RSDT signature incorrect\n"); return -ENODEV; } /* * The number of tables is computed by taking the * size of all entries (header size minus total * size of RSDT) divided by the size of each entry * (4-byte table pointers). */ tables = (header->length - sizeof(acpi_table_header)) / 4; memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt)); if (saved_rsdt.header.length > sizeof(saved_rsdt)) { printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", saved_rsdt.header.length); return -ENODEV; } for (i = 0; i < tables; i++) { /* Map in header, then map in full table length. */ header = (acpi_table_header *) __va_range(saved_rsdt.entry[i], sizeof(acpi_table_header)); if (!header) break; header = (acpi_table_header *) __va_range(saved_rsdt.entry[i], header->length); if (!header) break; acpi_print_table_header(header); if (acpi_checksum(header,header->length)) { printk(KERN_WARNING "ACPI %s has invalid checksum\n", acpi_table_signatures[i]); continue; } for (type = 0; type < ACPI_TABLE_COUNT; type++) if (!strncmp((char *) &header->signature, acpi_table_signatures[type],strlen(acpi_table_signatures[type]))) break; if (type >= ACPI_TABLE_COUNT) { printk(KERN_WARNING "ACPI: Unsupported table %.4s\n", header->signature); continue; } if (!acpi_boot_ops[type]) continue; result = acpi_boot_ops[type] (header, (unsigned long) saved_rsdt. entry[i]); } return result; }
void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt) { acpi_header_t *header = &(fadt->header); u16 pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f,0)), 0x40) & 0xfffe; memset((void *) fadt, 0, sizeof(acpi_fadt_t)); memcpy(header->signature, "FACP", 4); header->length = 244; header->revision = 3; memcpy(header->oem_id, "CORE ", 6); memcpy(header->oem_table_id, "COREBOOT", 8); memcpy(header->asl_compiler_id, "CORE", 4); header->asl_compiler_revision = 0; fadt->firmware_ctrl = (unsigned long) facs; fadt->dsdt = (unsigned long) dsdt; fadt->preferred_pm_profile = 7; /* Performance Server */ fadt->sci_int = 0x9; #if CONFIG_HAVE_SMI_HANDLER == 1 fadt->smi_cmd = 0xb2; #else fadt->smi_cmd = 0x00; #endif fadt->acpi_enable = 0xe1; fadt->acpi_disable = 0x1e; fadt->s4bios_req = 0x0; fadt->pstate_cnt = 0xe2; fadt->pm1a_evt_blk = pmbase; fadt->pm1b_evt_blk = 0x0; fadt->pm1a_cnt_blk = pmbase + 0x4; fadt->pm1b_cnt_blk = 0x0; fadt->pm2_cnt_blk = 0x0; fadt->pm_tmr_blk = pmbase + 0x8; fadt->gpe0_blk = pmbase + 0x28; fadt->gpe1_blk = 0x0; fadt->pm1_evt_len = 0x4; fadt->pm1_cnt_len = 0x2; fadt->pm2_cnt_len = 0x0; fadt->pm_tmr_len = 0x4; fadt->gpe0_blk_len = 0x8; fadt->gpe1_blk_len = 0x0; fadt->gpe1_base = 0x0; fadt->cst_cnt = 0xe3; fadt->p_lvl2_lat = 0x65; fadt->p_lvl3_lat = 0x3e9; fadt->flush_size = 0x400; fadt->flush_stride = 0x10; fadt->duty_offset = 0x1; fadt->duty_width = 0x3; fadt->day_alrm = 0xd; fadt->mon_alrm = 0x00; fadt->century = 0x00; fadt->iapc_boot_arch = 0x03; fadt->flags = 0xa5; fadt->reset_reg.space_id = 1; fadt->reset_reg.bit_width = 8; fadt->reset_reg.bit_offset = 0; fadt->reset_reg.resv = 0; fadt->reset_reg.addrl = 0xcf9; fadt->reset_reg.addrh = 0; fadt->reset_value = 6; fadt->res3 = 0; fadt->res4 = 0; fadt->res5 = 0; fadt->x_firmware_ctl_l = (u32)facs; fadt->x_firmware_ctl_h = 0; fadt->x_dsdt_l = (u32)dsdt; fadt->x_dsdt_h = 0; fadt->x_pm1a_evt_blk.space_id = 1; fadt->x_pm1a_evt_blk.bit_width = 32; fadt->x_pm1a_evt_blk.bit_offset = 0; fadt->x_pm1a_evt_blk.resv = 0; fadt->x_pm1a_evt_blk.addrl = pmbase; fadt->x_pm1a_evt_blk.addrh = 0x0; fadt->x_pm1b_evt_blk.space_id = 1; fadt->x_pm1b_evt_blk.bit_width = 32; fadt->x_pm1b_evt_blk.bit_offset = 0; fadt->x_pm1b_evt_blk.resv = 0; fadt->x_pm1b_evt_blk.addrl = 0x0; fadt->x_pm1b_evt_blk.addrh = 0x0; fadt->x_pm1a_cnt_blk.space_id = 1; fadt->x_pm1a_cnt_blk.bit_width = 16; fadt->x_pm1a_cnt_blk.bit_offset = 0; fadt->x_pm1a_cnt_blk.resv = 0; fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4; fadt->x_pm1a_cnt_blk.addrh = 0x0; fadt->x_pm1b_cnt_blk.space_id = 1; fadt->x_pm1b_cnt_blk.bit_width = 0; fadt->x_pm1b_cnt_blk.bit_offset = 0; fadt->x_pm1b_cnt_blk.resv = 0; fadt->x_pm1b_cnt_blk.addrl = 0x0; fadt->x_pm1b_cnt_blk.addrh = 0x0; fadt->x_pm2_cnt_blk.space_id = 1; fadt->x_pm2_cnt_blk.bit_width = 0; fadt->x_pm2_cnt_blk.bit_offset = 0; fadt->x_pm2_cnt_blk.resv = 0; fadt->x_pm2_cnt_blk.addrl = 0x0; fadt->x_pm2_cnt_blk.addrh = 0x0; fadt->x_pm_tmr_blk.space_id = 1; fadt->x_pm_tmr_blk.bit_width = 32; fadt->x_pm_tmr_blk.bit_offset = 0; fadt->x_pm_tmr_blk.resv = 0; fadt->x_pm_tmr_blk.addrl = pmbase + 0x8; fadt->x_pm_tmr_blk.addrh = 0x0; fadt->x_gpe0_blk.space_id = 1; fadt->x_gpe0_blk.bit_width = 64; fadt->x_gpe0_blk.bit_offset = 0; fadt->x_gpe0_blk.resv = 0; fadt->x_gpe0_blk.addrl = pmbase + 0x28; fadt->x_gpe0_blk.addrh = 0x0; fadt->x_gpe1_blk.space_id = 1; fadt->x_gpe1_blk.bit_width = 32; fadt->x_gpe1_blk.bit_offset = 0; fadt->x_gpe1_blk.resv = 0; fadt->x_gpe1_blk.addrl = 0x0; fadt->x_gpe1_blk.addrh = 0x0; header->checksum = acpi_checksum((void *) fadt, header->length); }
unsigned long write_acpi_tables(unsigned long start) { unsigned long current; acpi_rsdp_t *rsdp; acpi_rsdt_t *rsdt; acpi_hpet_t *hpet; acpi_madt_t *madt; acpi_srat_t *srat; acpi_slit_t *slit; acpi_fadt_t *fadt; acpi_facs_t *facs; acpi_header_t *dsdt; acpi_header_t *ssdt; acpi_header_t *ssdtx; void *p; int i; get_bus_conf(); //it will get sblk, pci1234, hcdn, and sbdn /* Align ACPI tables to 16 bytes */ 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); /* clear all table memory */ memset((void *)start, 0, current - start); acpi_write_rsdp(rsdp, rsdt, NULL); acpi_write_rsdt(rsdt); /* 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 at %lx\n", current); 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 at %lx\n", current); fadt = (acpi_fadt_t *) current; current += sizeof(acpi_fadt_t); acpi_create_fadt(fadt, facs, dsdt); acpi_add_table(rsdp, fadt); /* * We explicitly add these tables later on: */ printk(BIOS_DEBUG, "ACPI: * HPET at %lx\n", current); 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 at %lx\n", current); madt = (acpi_madt_t *) current; acpi_create_madt(madt); current+=madt->header.length; acpi_add_table(rsdp, madt); /* SRAT */ printk(BIOS_DEBUG, "ACPI: * SRAT at %lx\n", current); srat = (acpi_srat_t *) current; acpi_create_srat(srat); current+=srat->header.length; acpi_add_table(rsdp, srat); /* SLIT */ printk(BIOS_DEBUG, "ACPI: * SLIT at %lx\n", current); slit = (acpi_slit_t *) current; acpi_create_slit(slit); current+=slit->header.length; acpi_add_table(rsdp, slit); /* SSDT */ printk(BIOS_DEBUG, "ACPI: * SSDT at %lx\n", current); 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 //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; u8 c; if(i<7) { c = (u8) ('4' + i - 1); } else { c = (u8) ('A' + i - 1 - 6); } current = ( current + 0x07) & -0x08; printk(BIOS_DEBUG, "ACPI: * SSDT for PCI%c Aka hcid = %d\n", c, sysconf.hcid[i]); //pci0 and pci1 are in dsdt 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: continue; } 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((u8 *)ssdtx, ssdtx->length); acpi_add_table(rsdp, ssdtx); } #endif #if DUMP_ACPI_TABLES == 1 printk(BIOS_DEBUG, "rsdp\n"); dump_mem(rsdp, ((void *)rsdp) + sizeof(acpi_rsdp_t)); printk(BIOS_DEBUG, "rsdt\n"); dump_mem(rsdt, ((void *)rsdt) + sizeof(acpi_rsdt_t)); printk(BIOS_DEBUG, "madt\n"); dump_mem(madt, ((void *)madt) + madt->header.length); printk(BIOS_DEBUG, "srat\n"); dump_mem(srat, ((void *)srat) + srat->header.length); printk(BIOS_DEBUG, "slit\n"); dump_mem(slit, ((void *)slit) + slit->header.length); printk(BIOS_DEBUG, "ssdt\n"); dump_mem(ssdt, ((void *)ssdt) + ssdt->length); printk(BIOS_DEBUG, "fadt\n"); dump_mem(fadt, ((void *)fadt) + fadt->header.length); #endif printk(BIOS_INFO, "ACPI: done.\n"); return current; }
void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt) { acpi_header_t *header = &(fadt->header); printk(BIOS_DEBUG, "pm_base: 0x%04x\n", SB800_ACPI_IO_BASE); /* Prepare the header */ memset((void *)fadt, 0, sizeof(acpi_fadt_t)); memcpy(header->signature, "FACP", 4); header->length = 244; header->revision = 3; memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->asl_compiler_revision = 0; fadt->firmware_ctrl = (u32) facs; fadt->dsdt = (u32) dsdt; /* 3=Workstation,4=Enterprise Server, 7=Performance Server */ fadt->preferred_pm_profile = 0x03; fadt->sci_int = 9; /* disable system management mode by setting to 0: */ fadt->smi_cmd = 0; fadt->acpi_enable = 0xf0; fadt->acpi_disable = 0xf1; fadt->s4bios_req = 0x0; fadt->pstate_cnt = 0xe2; fadt->pm1a_evt_blk = ACPI_PM_EVT_BLK; fadt->pm1b_evt_blk = 0x0000; fadt->pm1a_cnt_blk = ACPI_PM1_CNT_BLK; fadt->pm1b_cnt_blk = 0x0000; fadt->pm2_cnt_blk = ACPI_PMA_CNT_BLK; fadt->pm_tmr_blk = ACPI_PM_TMR_BLK; fadt->gpe0_blk = ACPI_GPE0_BLK; fadt->gpe1_blk = 0x0000; /* we dont have gpe1 block, do we? */ fadt->pm1_evt_len = 4; fadt->pm1_cnt_len = 2; fadt->pm2_cnt_len = 1; fadt->pm_tmr_len = 4; fadt->gpe0_blk_len = 8; fadt->gpe1_blk_len = 0; fadt->gpe1_base = 0; fadt->cst_cnt = 0xe3; fadt->p_lvl2_lat = 101; fadt->p_lvl3_lat = 1001; fadt->flush_size = 0; fadt->flush_stride = 0; fadt->duty_offset = 1; fadt->duty_width = 3; fadt->day_alrm = 0; /* 0x7d these have to be */ fadt->mon_alrm = 0; /* 0x7e added to cmos.layout */ fadt->century = 0; /* 0x7f to make rtc alrm work */ fadt->iapc_boot_arch = 0x3; /* See table 5-11 */ fadt->flags = 0x0001c1a5;/* 0x25; */ fadt->res2 = 0; fadt->reset_reg.space_id = 1; fadt->reset_reg.bit_width = 8; fadt->reset_reg.bit_offset = 0; fadt->reset_reg.resv = 0; fadt->reset_reg.addrl = 0xcf9; fadt->reset_reg.addrh = 0x0; fadt->reset_value = 6; fadt->x_firmware_ctl_l = (u32) facs; fadt->x_firmware_ctl_h = 0; fadt->x_dsdt_l = (u32) dsdt; fadt->x_dsdt_h = 0; fadt->x_pm1a_evt_blk.space_id = 1; fadt->x_pm1a_evt_blk.bit_width = 32; fadt->x_pm1a_evt_blk.bit_offset = 0; fadt->x_pm1a_evt_blk.resv = 0; fadt->x_pm1a_evt_blk.addrl = ACPI_PM_EVT_BLK; fadt->x_pm1a_evt_blk.addrh = 0x0; fadt->x_pm1b_evt_blk.space_id = 1; fadt->x_pm1b_evt_blk.bit_width = 4; fadt->x_pm1b_evt_blk.bit_offset = 0; fadt->x_pm1b_evt_blk.resv = 0; fadt->x_pm1b_evt_blk.addrl = 0x0; fadt->x_pm1b_evt_blk.addrh = 0x0; fadt->x_pm1a_cnt_blk.space_id = 1; fadt->x_pm1a_cnt_blk.bit_width = 16; fadt->x_pm1a_cnt_blk.bit_offset = 0; fadt->x_pm1a_cnt_blk.resv = 0; fadt->x_pm1a_cnt_blk.addrl = ACPI_PM1_CNT_BLK; fadt->x_pm1a_cnt_blk.addrh = 0x0; fadt->x_pm1b_cnt_blk.space_id = 1; fadt->x_pm1b_cnt_blk.bit_width = 2; fadt->x_pm1b_cnt_blk.bit_offset = 0; fadt->x_pm1b_cnt_blk.resv = 0; fadt->x_pm1b_cnt_blk.addrl = 0x0; fadt->x_pm1b_cnt_blk.addrh = 0x0; fadt->x_pm2_cnt_blk.space_id = 1; fadt->x_pm2_cnt_blk.bit_width = 0; fadt->x_pm2_cnt_blk.bit_offset = 0; fadt->x_pm2_cnt_blk.resv = 0; fadt->x_pm2_cnt_blk.addrl = ACPI_PMA_CNT_BLK; fadt->x_pm2_cnt_blk.addrh = 0x0; fadt->x_pm_tmr_blk.space_id = 1; fadt->x_pm_tmr_blk.bit_width = 32; fadt->x_pm_tmr_blk.bit_offset = 0; fadt->x_pm_tmr_blk.resv = 0; fadt->x_pm_tmr_blk.addrl = ACPI_PM_TMR_BLK; fadt->x_pm_tmr_blk.addrh = 0x0; fadt->x_gpe0_blk.space_id = 1; fadt->x_gpe0_blk.bit_width = 32; fadt->x_gpe0_blk.bit_offset = 0; fadt->x_gpe0_blk.resv = 0; fadt->x_gpe0_blk.addrl = ACPI_GPE0_BLK; fadt->x_gpe0_blk.addrh = 0x0; fadt->x_gpe1_blk.space_id = 1; fadt->x_gpe1_blk.bit_width = 0; fadt->x_gpe1_blk.bit_offset = 0; fadt->x_gpe1_blk.resv = 0; fadt->x_gpe1_blk.addrl = 0; fadt->x_gpe1_blk.addrh = 0x0; header->checksum = acpi_checksum((void *)fadt, sizeof(acpi_fadt_t)); }
/* * Reference section 5.2.9 Fixed ACPI Description Table (FADT) * in the ACPI 3.0b specification. */ void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt) { acpi_header_t *header = &(fadt->header); printk(BIOS_DEBUG, "pm_base: 0x%04x\n", HUDSON_ACPI_IO_BASE); /* Prepare the header */ memset((void *)fadt, 0, sizeof(acpi_fadt_t)); memcpy(header->signature, "FACP", 4); header->length = sizeof(acpi_fadt_t); header->revision = ACPI_FADT_REV_ACPI_3_0; memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->asl_compiler_revision = 0; fadt->firmware_ctrl = (u32) facs; fadt->dsdt = (u32) dsdt; fadt->model = 0; /* reserved, should be 0 ACPI 3.0 */ fadt->preferred_pm_profile = FADT_PM_PROFILE; fadt->sci_int = 9; /* HUDSON - IRQ 09 – ACPI SCI */ if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) { fadt->smi_cmd = ACPI_SMI_CTL_PORT; fadt->acpi_enable = ACPI_SMI_CMD_ENABLE; fadt->acpi_disable = ACPI_SMI_CMD_DISABLE; fadt->s4bios_req = 0; /* Not supported */ fadt->pstate_cnt = 0; /* Not supported */ fadt->cst_cnt = 0; /* Not supported */ outl(0x0, ACPI_PM1_CNT_BLK); /* clear SCI_EN */ } else { fadt->smi_cmd = 0; /* disable system management mode */ fadt->acpi_enable = 0; /* unused if SMI_CMD = 0 */ fadt->acpi_disable = 0; /* unused if SMI_CMD = 0 */ fadt->s4bios_req = 0; /* unused if SMI_CMD = 0 */ fadt->pstate_cnt = 0; /* unused if SMI_CMD = 0 */ fadt->cst_cnt = 0x00; /* unused if SMI_CMD = 0 */ outl(0x1, ACPI_PM1_CNT_BLK); /* set SCI_EN */ } fadt->pm1a_evt_blk = ACPI_PM_EVT_BLK; fadt->pm1b_evt_blk = 0x0000; fadt->pm1a_cnt_blk = ACPI_PM1_CNT_BLK; fadt->pm1b_cnt_blk = 0x0000; fadt->pm2_cnt_blk = 0x0000; fadt->pm_tmr_blk = ACPI_PM_TMR_BLK; fadt->gpe0_blk = ACPI_GPE0_BLK; fadt->gpe1_blk = 0x0000; /* No gpe1 block in hudson */ fadt->pm1_evt_len = 4; /* 32 bits */ fadt->pm1_cnt_len = 2; /* 16 bits */ fadt->pm2_cnt_len = 0; fadt->pm_tmr_len = 4; /* 32 bits */ fadt->gpe0_blk_len = 8; /* 64 bits */ fadt->gpe1_blk_len = 0; fadt->gpe1_base = 0; fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED; fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED; fadt->flush_size = 0; /* set to 0 if WBINVD is 1 in flags */ fadt->flush_stride = 0; /* set to 0 if WBINVD is 1 in flags */ fadt->duty_offset = 1; /* CLK_VAL bits 3:1 */ fadt->duty_width = 3; /* CLK_VAL bits 3:1 */ fadt->day_alrm = 0; /* 0x7d these have to be */ fadt->mon_alrm = 0; /* 0x7e added to cmos.layout */ fadt->century = 0; /* 0x7f to make rtc alarm work */ fadt->iapc_boot_arch = FADT_BOOT_ARCH; /* See table 5-10 */ fadt->res2 = 0; /* reserved, MUST be 0 ACPI 3.0 */ fadt->flags = ACPI_FADT_WBINVD | /* See table 5-10 ACPI 3.0a spec */ ACPI_FADT_C1_SUPPORTED | ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_32BIT_TIMER | ACPI_FADT_RESET_REGISTER | ACPI_FADT_PCI_EXPRESS_WAKE | ACPI_FADT_PLATFORM_CLOCK | ACPI_FADT_S4_RTC_VALID | ACPI_FADT_REMOTE_POWER_ON; /* Format is from 5.2.3.1: Generic Address Structure */ /* reset_reg: see section 4.7.3.6 ACPI 3.0a spec */ /* 8 bit write of value 0x06 to 0xCF9 in IO space */ fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO; fadt->reset_reg.bit_width = 8; fadt->reset_reg.bit_offset = 0; fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; fadt->reset_reg.addrl = 0xcf9; fadt->reset_reg.addrh = 0x0; fadt->reset_value = 6; fadt->res3 = 0; /* reserved, MUST be 0 ACPI 3.0 */ fadt->res4 = 0; /* reserved, MUST be 0 ACPI 3.0 */ fadt->res5 = 0; /* reserved, MUST be 0 ACPI 3.0 */ fadt->x_firmware_ctl_l = 0; /* set to 0 if firmware_ctrl is used */ fadt->x_firmware_ctl_h = 0; fadt->x_dsdt_l = (u32) dsdt; fadt->x_dsdt_h = 0; fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1a_evt_blk.bit_width = 32; fadt->x_pm1a_evt_blk.bit_offset = 0; fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS; fadt->x_pm1a_evt_blk.addrl = ACPI_PM_EVT_BLK; fadt->x_pm1a_evt_blk.addrh = 0x0; fadt->x_pm1b_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1b_evt_blk.bit_width = 0; fadt->x_pm1b_evt_blk.bit_offset = 0; fadt->x_pm1b_evt_blk.access_size = 0; fadt->x_pm1b_evt_blk.addrl = 0x0; fadt->x_pm1b_evt_blk.addrh = 0x0; fadt->x_pm1a_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1a_cnt_blk.bit_width = 16; fadt->x_pm1a_cnt_blk.bit_offset = 0; fadt->x_pm1a_cnt_blk.access_size = 0; fadt->x_pm1a_cnt_blk.addrl = ACPI_PM1_CNT_BLK; fadt->x_pm1a_cnt_blk.addrh = 0x0; fadt->x_pm1b_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1b_cnt_blk.bit_width = 0; fadt->x_pm1b_cnt_blk.bit_offset = 0; fadt->x_pm1b_cnt_blk.access_size = 0; fadt->x_pm1b_cnt_blk.addrl = 0x0; fadt->x_pm1b_cnt_blk.addrh = 0x0; /* * Note: Under this current AMD C state implementation, this is no longer * used and should not be reported to OS. */ fadt->x_pm2_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm2_cnt_blk.bit_width = 0; fadt->x_pm2_cnt_blk.bit_offset = 0; fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; fadt->x_pm2_cnt_blk.addrl = 0; fadt->x_pm2_cnt_blk.addrh = 0x0; fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm_tmr_blk.bit_width = 32; fadt->x_pm_tmr_blk.bit_offset = 0; fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; fadt->x_pm_tmr_blk.addrl = ACPI_PM_TMR_BLK; fadt->x_pm_tmr_blk.addrh = 0x0; fadt->x_gpe0_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_gpe0_blk.bit_width = 64; /* EventStatus + Event Enable */ fadt->x_gpe0_blk.bit_offset = 0; fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; fadt->x_gpe0_blk.addrl = ACPI_GPE0_BLK; fadt->x_gpe0_blk.addrh = 0x0; fadt->x_gpe1_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_gpe1_blk.bit_width = 0; fadt->x_gpe1_blk.bit_offset = 0; fadt->x_gpe1_blk.access_size = 0; fadt->x_gpe1_blk.addrl = 0; fadt->x_gpe1_blk.addrh = 0x0; header->checksum = acpi_checksum((void *)fadt, sizeof(acpi_fadt_t)); }
void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt) { acpi_header_t *header = &(fadt->header); u16 pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f,0)), 0x40) & 0xfffe; memset((void *) fadt, 0, sizeof(acpi_fadt_t)); memcpy(header->signature, "FACP", 4); header->length = sizeof(acpi_fadt_t); header->revision = 4; memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->asl_compiler_revision = 1; fadt->firmware_ctrl = (unsigned long) facs; fadt->dsdt = (unsigned long) dsdt; fadt->model = 1; fadt->preferred_pm_profile = 0; /* PM_MOBILE; */ fadt->sci_int = 0x9; fadt->smi_cmd = APM_CNT; fadt->acpi_enable = ACPI_ENABLE; fadt->acpi_disable = ACPI_DISABLE; fadt->s4bios_req = S4_BIOS; fadt->pstate_cnt = PST_CONTROL; fadt->pm1a_evt_blk = pmbase; fadt->pm1b_evt_blk = 0x0; fadt->pm1a_cnt_blk = pmbase + 0x4; fadt->pm1b_cnt_blk = 0x0; fadt->pm2_cnt_blk = 0x0; fadt->pm_tmr_blk = pmbase + 0x8; fadt->gpe0_blk = pmbase + 0x28; fadt->gpe1_blk = 0; fadt->pm1_evt_len = 4; fadt->pm1_cnt_len = 2; // XXX: pm2_cnt_len is probably wrong. find out right value (hint: it's != 0) fadt->pm2_cnt_len = 0; fadt->pm_tmr_len = 4; fadt->gpe0_blk_len = 8; fadt->gpe1_blk_len = 0; fadt->gpe1_base = 0; fadt->cst_cnt = 0; /* CST_CONTROL; */ fadt->p_lvl2_lat = 1; fadt->p_lvl3_lat = 85; fadt->flush_size = 1024; fadt->flush_stride = 16; fadt->duty_offset = 1; fadt->duty_width = 0; fadt->day_alrm = 0xd; fadt->mon_alrm = 0x00; fadt->century = 0x00; fadt->iapc_boot_arch = 0x03; fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED | ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK; fadt->reset_reg.space_id = 0; fadt->reset_reg.bit_width = 0; fadt->reset_reg.bit_offset = 0; fadt->reset_reg.resv = 0; fadt->reset_reg.addrl = 0x0; fadt->reset_reg.addrh = 0x0; fadt->reset_value = 0; fadt->x_firmware_ctl_l = (unsigned long)facs; fadt->x_firmware_ctl_h = 0; fadt->x_dsdt_l = (unsigned long)dsdt; fadt->x_dsdt_h = 0; fadt->x_pm1a_evt_blk.space_id = 1; fadt->x_pm1a_evt_blk.bit_width = 32; fadt->x_pm1a_evt_blk.bit_offset = 0; fadt->x_pm1a_evt_blk.resv = 0; fadt->x_pm1a_evt_blk.addrl = pmbase; fadt->x_pm1a_evt_blk.addrh = 0x0; fadt->x_pm1b_evt_blk.space_id = 1; fadt->x_pm1b_evt_blk.bit_width = 0; fadt->x_pm1b_evt_blk.bit_offset = 0; fadt->x_pm1b_evt_blk.resv = 0; fadt->x_pm1b_evt_blk.addrl = 0x0; fadt->x_pm1b_evt_blk.addrh = 0x0; fadt->x_pm1a_cnt_blk.space_id = 1; fadt->x_pm1a_cnt_blk.bit_width = 16; fadt->x_pm1a_cnt_blk.bit_offset = 0; fadt->x_pm1a_cnt_blk.resv = 0; fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4; fadt->x_pm1a_cnt_blk.addrh = 0x0; fadt->x_pm1b_cnt_blk.space_id = 1; fadt->x_pm1b_cnt_blk.bit_width = 0; fadt->x_pm1b_cnt_blk.bit_offset = 0; fadt->x_pm1b_cnt_blk.resv = 0; fadt->x_pm1b_cnt_blk.addrl = 0x0; fadt->x_pm1b_cnt_blk.addrh = 0x0; fadt->x_pm2_cnt_blk.space_id = 1; fadt->x_pm2_cnt_blk.bit_width = 0; fadt->x_pm2_cnt_blk.bit_offset = 0; fadt->x_pm2_cnt_blk.resv = 0; fadt->x_pm2_cnt_blk.addrl = 0x0; fadt->x_pm2_cnt_blk.addrh = 0x0; fadt->x_pm_tmr_blk.space_id = 1; fadt->x_pm_tmr_blk.bit_width = 32; fadt->x_pm_tmr_blk.bit_offset = 0; fadt->x_pm_tmr_blk.resv = 0; fadt->x_pm_tmr_blk.addrl = pmbase + 0x8; fadt->x_pm_tmr_blk.addrh = 0x0; fadt->x_gpe0_blk.space_id = 1; fadt->x_gpe0_blk.bit_width = 64; fadt->x_gpe0_blk.bit_offset = 0; fadt->x_gpe0_blk.resv = 0; fadt->x_gpe0_blk.addrl = pmbase + 0x28; fadt->x_gpe0_blk.addrh = 0x0; fadt->x_gpe1_blk.space_id = 1; fadt->x_gpe1_blk.bit_width = 0; fadt->x_gpe1_blk.bit_offset = 0; fadt->x_gpe1_blk.resv = 0; fadt->x_gpe1_blk.addrl = 0x0; fadt->x_gpe1_blk.addrh = 0x0; header->checksum = acpi_checksum((void *) fadt, header->length); }