struct acpi_madt_lapic * acpi_get_lapic_next(void) { static unsigned idx = 0; static struct acpi_madt_hdr * madt_hdr; struct acpi_madt_lapic * ret; if (idx == 0) { madt_hdr = (struct acpi_madt_hdr *) acpi_phys2vir(acpi_get_table_base("APIC")); if (madt_hdr == NULL) return NULL; } for (;;) { ret = (struct acpi_madt_lapic *) acpi_madt_get_typed_item(madt_hdr, ACPI_MADT_TYPE_LAPIC, idx); if (!ret) break; idx++; /* report only usable CPUs */ if (ret->flags & 1) break; } return ret; }
acpi_madt_ioapic * acpi_get_ioapic(unsigned int *idxp){ unsigned int idx; acpi_madt_hdr *madt_hdr; acpi_madt_ioapic *ret; kassert(idxp != NULL); idx = *idxp; madt_hdr = (acpi_madt_hdr *)acpi_get_table_base(ACPI_SDT_TRANS_TYPE_APIC); if (idx == 0) { if (madt_hdr == NULL) goto error_out; } ret = (acpi_madt_ioapic *)madt_get_typed_item(madt_hdr, ACPI_MADT_TYPE_IOAPIC, &idx); if ( ret == NULL ) goto error_out; *idxp = idx + 1; return ret; error_out: return NULL; }
acpi_madt_lapic * acpi_get_lapic(unsigned int *idxp){ unsigned int idx; acpi_madt_hdr *madt_hdr; acpi_madt_lapic *ret; kassert(idxp != NULL); idx = *idxp; madt_hdr = (acpi_madt_hdr *)acpi_get_table_base(ACPI_SDT_TRANS_TYPE_APIC); if (idx == 0) { if (madt_hdr == NULL) goto error_out; } ret = (acpi_madt_lapic *)madt_get_typed_item(madt_hdr, ACPI_MADT_TYPE_LAPIC, &idx); if ( ret == NULL ) goto error_out; /* report only usable CPUs */ if ( ret->flags & ACPI_MADT_LAPIC_FLAGS_PROC_ENABLED ) { *idxp = idx + 1; return ret; } error_out: return NULL; }
struct acpi_madt_ioapic * acpi_get_ioapic_next(void) { static unsigned idx = 0; static struct acpi_madt_hdr * madt_hdr; struct acpi_madt_ioapic * ret; if (idx == 0) { madt_hdr = (struct acpi_madt_hdr *) acpi_phys2vir(acpi_get_table_base("APIC")); if (madt_hdr == NULL) return NULL; } ret = (struct acpi_madt_ioapic *) acpi_madt_get_typed_item(madt_hdr, ACPI_MADT_TYPE_IOAPIC, idx); if (ret) idx++; 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; }
static void acpi_init_poweroff(void) { u8_t *ptr = NULL; u8_t *start = NULL; u8_t *end = NULL; struct acpi_fadt_header *fadt_header = NULL; struct acpi_rsdt * dsdt_header = NULL; char *msg = NULL; /* Everything used here existed since ACPI spec 1.0 */ /* So we can safely use them */ fadt_header = (struct acpi_fadt_header *) acpi_phys2vir(acpi_get_table_base("FACP")); if (fadt_header == NULL) { msg = "Could not load FACP"; goto exit; } dsdt_header = (struct acpi_rsdt *) acpi_phys2vir((phys_bytes) fadt_header->dsdt); if (dsdt_header == NULL) { msg = "Could not load DSDT"; goto exit; } pm1a_cnt_blk = fadt_header->pm1a_cnt_blk; pm1b_cnt_blk = fadt_header->pm1b_cnt_blk; ptr = start = (u8_t *) dsdt_header->data; end = start + dsdt_header->hdr.length - 4; /* See http://forum.osdev.org/viewtopic.php?t=16990 */ /* for layout of \_S5 */ while (ptr < end && memcmp(ptr, "_S5_", 4) != 0) ptr++; msg = "Could not read S5 data. Use default SLP_TYPa and SLP_TYPb"; if (ptr >= end || ptr == start) goto exit; /* validate AML structure */ if (*(ptr + AMI_S5_PACKAGE_OP_OFFSET) != AMI_PACKAGE_OP_CODE) goto exit; if ((ptr < start + (-AMI_S5_NAME_OP_OFFSET_2) || (*(ptr + AMI_S5_NAME_OP_OFFSET_2) != AMI_NAME_OP_CODE || *(ptr + AMI_S5_NAME_OP_OFFSET_2 + 1) != '\\')) && *(ptr + AMI_S5_NAME_OP_OFFSET_1) != AMI_NAME_OP_CODE) goto exit; ptr += AMI_S5_PACKET_LENGTH_OFFSET; if (ptr >= end) goto exit; /* package length */ ptr += ((*ptr & AMI_PACKAGE_LENGTH_ENCODING_BITS_MASK) >> AMI_PACKAGE_LENGTH_ENCODING_BITS_SHIFT) + AMI_MIN_PACKAGE_LENGTH + AMI_NUM_ELEMENTS_LENGTH; if (ptr >= end) goto exit; if (*ptr == AMI_BYTE_PREFIX_CODE) ptr++; /* skip byte prefix */ slp_typa = (*ptr) << AMI_SLP_TYPA_SHIFT; ptr++; /* move to SLP_TYPb */ if (*ptr == AMI_BYTE_PREFIX_CODE) ptr++; /* skip byte prefix */ slp_typb = (*ptr) << AMI_SLP_TYPB_SHIFT; msg = "poweroff initialized"; exit: if (msg) { DEBUGBASIC(("acpi: %s\n", msg)); } }