Exemplo n.º 1
0
static vm_paddr_t
sdt_search_rsdt(vm_paddr_t rsdt_paddr, const uint8_t *sig)
{
	struct acpi_rsdt *rsdt;
	vm_paddr_t sdt_paddr = 0;
	int i, nent;

	if (rsdt_paddr == 0) {
		kprintf("sdt_search_rsdt: RSDT paddr == 0\n");
		return 0;
	}

	rsdt = sdt_sdth_map(rsdt_paddr);
	if (rsdt == NULL) {
		kprintf("sdt_search_rsdt: can't map RSDT\n");
		return 0;
	}

	if (memcmp(rsdt->rsdt_hdr.sdth_sig, ACPI_RSDT_SIG,
		   ACPI_SDTH_SIGLEN) != 0) {
		kprintf("sdt_search_rsdt: not RSDT\n");
		goto back;
	}

	if (rsdt->rsdt_hdr.sdth_rev != 1) {
		kprintf("sdt_search_rsdt: unknown RSDT revision %d\n",
			rsdt->rsdt_hdr.sdth_rev);
	}

	if (rsdt->rsdt_hdr.sdth_len < sizeof(rsdt->rsdt_hdr)) {
		kprintf("sdt_search_rsdt: invalid RSDT length %u\n",
			rsdt->rsdt_hdr.sdth_len);
		goto back;
	}

	nent = (rsdt->rsdt_hdr.sdth_len - sizeof(rsdt->rsdt_hdr)) /
	       sizeof(rsdt->rsdt_ents[0]);
	for (i = 0; i < nent; ++i) {
		struct acpi_sdth *sdth;

		if (rsdt->rsdt_ents[i] == 0)
			continue;

		sdth = sdt_sdth_map(rsdt->rsdt_ents[i]);
		if (sdth != NULL) {
			int ret;

			ret = memcmp(sdth->sdth_sig, sig, ACPI_SDTH_SIGLEN);
			sdt_sdth_unmap(sdth);

			if (ret == 0) {
				sdt_paddr = rsdt->rsdt_ents[i];
				break;
			}
		}
	}
back:
	sdt_sdth_unmap(&rsdt->rsdt_hdr);
	return sdt_paddr;
}
Exemplo n.º 2
0
static vm_paddr_t
sdt_search_rsdt(vm_paddr_t rsdt_paddr, const uint8_t *sig)
{
	ACPI_TABLE_RSDT *rsdt;
	vm_paddr_t sdt_paddr = 0;
	int i, nent;

	if (rsdt_paddr == 0) {
		kprintf("sdt_search_rsdt: RSDT paddr == 0\n");
		return 0;
	}

	rsdt = sdt_sdth_map(rsdt_paddr);
	if (rsdt == NULL) {
		kprintf("sdt_search_rsdt: can't map RSDT\n");
		return 0;
	}

	if (memcmp(rsdt->Header.Signature, ACPI_SIG_RSDT,
		   ACPI_NAME_SIZE) != 0) {
		kprintf("sdt_search_rsdt: not RSDT\n");
		goto back;
	}

	if (rsdt->Header.Revision != 1) {
		kprintf("sdt_search_rsdt: unknown RSDT revision %d\n",
			rsdt->Header.Revision);
	}

	if (rsdt->Header.Length < sizeof(rsdt->Header)) {
		kprintf("sdt_search_rsdt: invalid RSDT length %u\n",
			rsdt->Header.Length);
		goto back;
	}

	nent = (rsdt->Header.Length - sizeof(rsdt->Header)) /
	       sizeof(rsdt->TableOffsetEntry[0]);
	for (i = 0; i < nent; ++i) {
		ACPI_TABLE_HEADER *sdth;

		if (rsdt->TableOffsetEntry[i] == 0)
			continue;

		sdth = sdt_sdth_map(rsdt->TableOffsetEntry[i]);
		if (sdth != NULL) {
			int ret;

			ret = memcmp(sdth->Signature, sig, ACPI_NAME_SIZE);
			sdt_sdth_unmap(sdth);

			if (ret == 0) {
				sdt_paddr = rsdt->TableOffsetEntry[i];
				break;
			}
		}
	}
back:
	sdt_sdth_unmap(&rsdt->Header);
	return sdt_paddr;
}
Exemplo n.º 3
0
static vm_paddr_t
sdt_search_xsdt(vm_paddr_t xsdt_paddr, const uint8_t *sig)
{
	struct acpi_xsdt *xsdt;
	vm_paddr_t sdt_paddr = 0;
	int i, nent;

	if (xsdt_paddr == 0) {
		kprintf("sdt_search_xsdt: XSDT paddr == 0\n");
		return 0;
	}

	xsdt = sdt_sdth_map(xsdt_paddr);
	if (xsdt == NULL) {
		kprintf("sdt_search_xsdt: can't map XSDT\n");
		return 0;
	}

	if (memcmp(xsdt->xsdt_hdr.sdth_sig, ACPI_XSDT_SIG,
		   ACPI_SDTH_SIGLEN) != 0) {
		kprintf("sdt_search_xsdt: not XSDT\n");
		goto back;
	}

	if (xsdt->xsdt_hdr.sdth_rev != 1) {
		kprintf("sdt_search_xsdt: unsupported XSDT revision %d\n",
			xsdt->xsdt_hdr.sdth_rev);
		goto back;
	}

	nent = (xsdt->xsdt_hdr.sdth_len - sizeof(xsdt->xsdt_hdr)) /
	       sizeof(xsdt->xsdt_ents[0]);
	for (i = 0; i < nent; ++i) {
		struct acpi_sdth *sdth;

		if (xsdt->xsdt_ents[i] == 0)
			continue;

		sdth = sdt_sdth_map(xsdt->xsdt_ents[i]);
		if (sdth != NULL) {
			int ret;

			ret = memcmp(sdth->sdth_sig, sig, ACPI_SDTH_SIGLEN);
			sdt_sdth_unmap(sdth);

			if (ret == 0) {
				sdt_paddr = xsdt->xsdt_ents[i];
				break;
			}
		}
	}
back:
	sdt_sdth_unmap(&xsdt->xsdt_hdr);
	return sdt_paddr;
}
Exemplo n.º 4
0
static int
madt_lapic_probe(struct lapic_enumerator *e)
{
	struct madt_lapic_probe_cbarg arg;
	struct acpi_madt *madt;
	int error;

	if (madt_phyaddr == 0)
		return ENXIO;

	madt = sdt_sdth_map(madt_phyaddr);
	KKASSERT(madt != NULL);

	bzero(&arg, sizeof(arg));
	arg.lapic_addr = madt->madt_lapic_addr;

	error = madt_iterate_entries(madt, madt_lapic_probe_callback, &arg);
	if (!error) {
		if (arg.cpu_count == 0) {
			kprintf("madt_lapic_probe: no CPU is found\n");
			error = EOPNOTSUPP;
		}
		if (arg.lapic_addr == 0) {
			kprintf("madt_lapic_probe: zero LAPIC address\n");
			error = EOPNOTSUPP;
		}
	}

	sdt_sdth_unmap(&madt->madt_hdr);
	return error;
}
Exemplo n.º 5
0
static int
madt_lapic_pass2(int bsp_apic_id)
{
	struct acpi_madt *madt;
	struct madt_lapic_pass2_cbarg arg;
	int error;

	MADT_VPRINTF("BSP apic id %d\n", bsp_apic_id);

	KKASSERT(madt_phyaddr != 0);

	madt = sdt_sdth_map(madt_phyaddr);
	KKASSERT(madt != NULL);

	bzero(&arg, sizeof(arg));
	arg.cpu = 1;
	arg.bsp_apic_id = bsp_apic_id;

	error = madt_iterate_entries(madt, madt_lapic_pass2_callback, &arg);
	if (error)
		panic("madt_iterate_entries(pass2) failed");

	KKASSERT(arg.bsp_found);
	naps = arg.cpu - 1; /* exclude BSP */

	sdt_sdth_unmap(&madt->madt_hdr);

	return 0;
}
Exemplo n.º 6
0
static vm_paddr_t
madt_lapic_pass1(void)
{
	struct acpi_madt *madt;
	vm_paddr_t lapic_addr;
	uint64_t lapic_addr64;
	int error;

	KKASSERT(madt_phyaddr != 0);

	madt = sdt_sdth_map(madt_phyaddr);
	KKASSERT(madt != NULL);

	MADT_VPRINTF("LAPIC address 0x%x, flags %#x\n",
		     madt->madt_lapic_addr, madt->madt_flags);
	lapic_addr = madt->madt_lapic_addr;

	lapic_addr64 = 0;
	error = madt_iterate_entries(madt, madt_lapic_pass1_callback,
				     &lapic_addr64);
	if (error)
		panic("madt_iterate_entries(pass1) failed");

	if (lapic_addr64 != 0) {
		kprintf("ACPI MADT: 64bits lapic address 0x%lx\n",
			lapic_addr64);
		lapic_addr = lapic_addr64;
	}

	sdt_sdth_unmap(&madt->madt_hdr);

	return lapic_addr;
}
Exemplo n.º 7
0
static int
madt_check(vm_paddr_t madt_paddr)
{
	struct acpi_madt *madt;
	int error = 0;

	KKASSERT(madt_paddr != 0);

	madt = sdt_sdth_map(madt_paddr);
	KKASSERT(madt != NULL);

	/*
	 * MADT in ACPI specification 1.0 - 4.0
	 */
	if (madt->madt_hdr.sdth_rev < 1 || madt->madt_hdr.sdth_rev > 3) {
		kprintf("madt_check: unknown MADT revision %d\n",
			madt->madt_hdr.sdth_rev);
	}

	if (madt->madt_hdr.sdth_len <
	    sizeof(*madt) - sizeof(madt->madt_ents)) {
		kprintf("madt_check: invalid MADT length %u\n",
			madt->madt_hdr.sdth_len);
		error = EINVAL;
		goto back;
	}
back:
	sdt_sdth_unmap(&madt->madt_hdr);
	return error;
}
Exemplo n.º 8
0
static void
fadt_probe(void)
{
	struct acpi_fadt *fadt;
	vm_paddr_t fadt_paddr;
	enum intr_trigger trig;
	enum intr_polarity pola;
	int enabled = 1;
	char *env;

	fadt_paddr = sdt_search(ACPI_FADT_SIG);
	if (fadt_paddr == 0) {
		kprintf("fadt_probe: can't locate FADT\n");
		return;
	}

	fadt = sdt_sdth_map(fadt_paddr);
	KKASSERT(fadt != NULL);

	/*
	 * FADT in ACPI specification 1.0 - 4.0
	 */
	if (fadt->fadt_hdr.sdth_rev < 1 || fadt->fadt_hdr.sdth_rev > 4) {
		kprintf("fadt_probe: unsupported FADT revision %d\n",
			fadt->fadt_hdr.sdth_rev);
		goto back;
	}

	if (fadt->fadt_hdr.sdth_len < sizeof(*fadt)) {
		kprintf("fadt_probe: invalid FADT length %u\n",
			fadt->fadt_hdr.sdth_len);
		goto back;
	}

	kgetenv_int("hw.acpi.sci.enabled", &enabled);
	if (!enabled)
		goto back;

	acpi_sci_irq = fadt->fadt_sci_int;

	env = kgetenv("hw.acpi.sci.trigger");
	if (env == NULL)
		goto back;

	trig = INTR_TRIGGER_CONFORM;
	if (strcmp(env, "edge") == 0)
		trig = INTR_TRIGGER_EDGE;
	else if (strcmp(env, "level") == 0)
		trig = INTR_TRIGGER_LEVEL;

	kfreeenv(env);

	if (trig == INTR_TRIGGER_CONFORM)
		goto back;

	env = kgetenv("hw.acpi.sci.polarity");
	if (env == NULL)
		goto back;

	pola = INTR_POLARITY_CONFORM;
	if (strcmp(env, "high") == 0)
		pola = INTR_POLARITY_HIGH;
	else if (strcmp(env, "low") == 0)
		pola = INTR_POLARITY_LOW;

	kfreeenv(env);

	if (pola == INTR_POLARITY_CONFORM)
		goto back;

	acpi_sci_trig = trig;
	acpi_sci_pola = pola;
back:
	if (acpi_sci_irq >= 0) {
		FADT_VPRINTF("SCI irq %d, %s/%s\n", acpi_sci_irq,
			     intr_str_trigger(acpi_sci_trig),
			     intr_str_polarity(acpi_sci_pola));
	} else {
		FADT_VPRINTF("SCI is disabled\n");
	}
	sdt_sdth_unmap(&fadt->fadt_hdr);
}
Exemplo n.º 9
0
static void
fadt_probe(void)
{
	ACPI_TABLE_FADT *fadt;
	vm_paddr_t fadt_paddr;
	enum intr_trigger trig;
	enum intr_polarity pola;
	int enabled = 1;
	char *env;

	fadt_paddr = sdt_search(ACPI_SIG_FADT);
	if (fadt_paddr == 0) {
		kprintf("fadt_probe: can't locate FADT\n");
		return;
	}

	fadt = sdt_sdth_map(fadt_paddr);
	KKASSERT(fadt != NULL);

	/*
	 * FADT in ACPI specification 1.0 - 6.0
	 */
	if (fadt->Header.Revision < 1 || fadt->Header.Revision > 6) {
		kprintf("fadt_probe: unknown FADT revision %d\n",
			fadt->Header.Revision);
	}

	if (fadt->Header.Length < ACPI_FADT_V1_SIZE) {
		kprintf("fadt_probe: invalid FADT length %u (< %u)\n",
		    fadt->Header.Length, ACPI_FADT_V1_SIZE);
		goto back;
	}

	kgetenv_int("hw.acpi.sci.enabled", &enabled);
	if (!enabled)
		goto back;

	acpi_sci_irq = fadt->SciInterrupt;

	env = kgetenv("hw.acpi.sci.trigger");
	if (env == NULL)
		goto back;

	trig = INTR_TRIGGER_CONFORM;
	if (strcmp(env, "edge") == 0)
		trig = INTR_TRIGGER_EDGE;
	else if (strcmp(env, "level") == 0)
		trig = INTR_TRIGGER_LEVEL;

	kfreeenv(env);

	if (trig == INTR_TRIGGER_CONFORM)
		goto back;

	env = kgetenv("hw.acpi.sci.polarity");
	if (env == NULL)
		goto back;

	pola = INTR_POLARITY_CONFORM;
	if (strcmp(env, "high") == 0)
		pola = INTR_POLARITY_HIGH;
	else if (strcmp(env, "low") == 0)
		pola = INTR_POLARITY_LOW;

	kfreeenv(env);

	if (pola == INTR_POLARITY_CONFORM)
		goto back;

	acpi_sci_trig = trig;
	acpi_sci_pola = pola;
back:
	if (acpi_sci_irq >= 0) {
		FADT_VPRINTF("SCI irq %d, %s/%s\n", acpi_sci_irq,
			     intr_str_trigger(acpi_sci_trig),
			     intr_str_polarity(acpi_sci_pola));
	} else {
		FADT_VPRINTF("SCI is disabled\n");
	}
	sdt_sdth_unmap(&fadt->Header);
}