Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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));
	}
}