int __init acpi_init(void) { int i, nr_sys_hdr, ret = VMM_EFAIL; struct acpi_rsdp *root_desc = NULL; struct acpi_rsdt rsdt, *prsdt; vmm_printf("Starting to parse ACPI tables...\n"); root_desc = (struct acpi_rsdp *)find_root_system_descriptor(); if (root_desc == NULL) { vmm_printf("ACPI ERROR: No root system descriptor" " table found!\n"); goto rdesc_fail; } if (root_desc->rsdt_addr == 0) { vmm_printf("ACPI ERROR: No root descriptor found" " in RSD Pointer!\n"); goto rsdt_fail; } prsdt = (struct acpi_rsdt *)vmm_host_iomap(root_desc->rsdt_addr, PAGE_SIZE); if (unlikely(!prsdt)) { vmm_printf("ACPI ERROR: Failed to map physical address 0x%x.\n", __func__, root_desc->rsdt_addr); goto rsdt_fail; } if (acpi_read_sdt_at(prsdt, (struct acpi_sdt_hdr *)&rsdt, sizeof(struct acpi_rsdt), RSDT_SIGNATURE) < 0) { goto sdt_fail; } nr_sys_hdr = (rsdt.hdr.len - sizeof(struct acpi_sdt_hdr))/sizeof(u32); for (i = 0; i < nr_sys_hdr; i++) { struct acpi_sdt_hdr *hdr; char sign[32]; memset(sign, 0, sizeof(sign)); hdr = (struct acpi_sdt_hdr *) vmm_host_iomap(rsdt.data[i], PAGE_SIZE); if (hdr == NULL) { vmm_printf("ACPI ERROR: Cannot read header at 0x%x\n", rsdt.data[i]); goto sdt_fail; } memcpy(sign, hdr->signature, SDT_SIGN_LEN); sign[SDT_SIGN_LEN] = 0; if (process_acpi_sdt_table((char *)sign, (u32 *)hdr) != VMM_OK) { vmm_host_iounmap((virtual_addr_t)hdr); goto sdt_fail; } vmm_host_iounmap((virtual_addr_t)hdr); } ret = VMM_OK; sdt_fail: vmm_host_iounmap((virtual_addr_t)prsdt); rsdt_fail: vmm_host_iounmap((virtual_addr_t)root_desc); rdesc_fail: return ret; }
int acpi_init(void) { int i; if (!acpi_ctxt) { acpi_ctxt = vmm_malloc(sizeof(struct acpi_context)); if (!acpi_ctxt) { vmm_printf("ACPI ERROR: Failed to allocate memory for" " ACPI context.\n"); return VMM_EFAIL; } acpi_ctxt->root_desc = (struct acpi_rsdp *)find_root_system_descriptor(); acpi_ctxt->rsdt = NULL; if (acpi_ctxt->root_desc == NULL) { vmm_printf("ACPI ERROR: No root system descriptor" " table found!\n"); goto rdesc_fail; } if (acpi_ctxt->root_desc->rsdt_addr == 0) { vmm_printf("ACPI ERROR: No root descriptor found" " in RSD Pointer!\n"); goto rsdt_fail; } acpi_ctxt->rsdt = (struct acpi_rsdt *)vmm_malloc(sizeof(struct acpi_rsdt)); if (!acpi_ctxt->rsdt) goto rsdt_fail; if (acpi_read_sdt_at(acpi_ctxt->root_desc->rsdt_addr, (struct acpi_sdt_hdr *)acpi_ctxt->rsdt, sizeof(struct acpi_rsdt), RSDT_SIGNATURE) < 0) { goto sdt_fail; } acpi_ctxt->nr_sys_hdr = (acpi_ctxt->rsdt->hdr.len - sizeof(struct acpi_sdt_hdr))/sizeof(u32); for (i = 0; i < acpi_ctxt->nr_sys_hdr; i++) { struct acpi_sdt_hdr *hdr; hdr = (struct acpi_sdt_hdr *) vmm_host_iomap(acpi_ctxt->rsdt->data[i], PAGE_SIZE); if (hdr == NULL) { vmm_printf("ACPI ERROR: Cannot read header at 0x%x\n", acpi_ctxt->rsdt->data[i]); goto sdt_fail; } vmm_memcpy(&acpi_ctxt->sdt_trans[i].signature, &hdr->signature, SDT_SIGN_LEN); acpi_ctxt->sdt_trans[i].signature[SDT_SIGN_LEN] = '\0'; acpi_ctxt->sdt_trans[i].length = hdr->len; //vmm_host_iounmap((virtual_addr_t)hdr, PAGE_SIZE); } acpi_ctxt->madt_hdr = (struct acpi_madt_hdr *) vmm_host_iomap(acpi_get_table_base("APIC"), PAGE_SIZE); if (acpi_ctxt->madt_hdr == NULL) goto sdt_fail; } return VMM_OK; sdt_fail: vmm_free(acpi_ctxt->rsdt); rsdt_fail: vmm_host_iounmap((virtual_addr_t)acpi_ctxt->root_desc, PAGE_SIZE); rdesc_fail: vmm_free(acpi_ctxt); acpi_ctxt = NULL; return VMM_EFAIL; }