Beispiel #1
0
void
sdhc_acpi_attach(struct device *parent, struct device *self, void *aux)
{
	struct acpi_attach_args *aaa = aux;
	struct sdhc_acpi_softc *sc = (struct sdhc_acpi_softc *)self;
	struct aml_value res;

	sc->sc_acpi = (struct acpi_softc *)parent;
	sc->sc_node = aaa->aaa_node;
	printf(": %s", sc->sc_node->name);

	if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
		printf(", can't find registers\n");
		return;
	}

	aml_parse_resource(&res, sdhc_acpi_parse_resources, sc);
	printf(" addr 0x%lx/0x%lx", sc->sc_addr, sc->sc_size);
	if (sc->sc_addr == 0 || sc->sc_size == 0) {
		printf("\n");
		return;
	}

	printf(" irq %d", sc->sc_irq);

	sc->sc_memt = aaa->aaa_memt;
	if (bus_space_map(sc->sc_memt, sc->sc_addr, sc->sc_size, 0,
	    &sc->sc_memh)) {
		printf(", can't map registers\n");
		return;
	}

	sc->sc_ih = acpi_intr_establish(sc->sc_irq, sc->sc_irq_flags, IPL_BIO,
	    sdhc_intr, sc, sc->sc.sc_dev.dv_xname);
	if (sc->sc_ih == NULL) {
		printf(", can't establish interrupt\n");
		return;
	}

	printf("\n");

	sc->sc.sc_host = &sc->sc_host;
	sdhc_host_found(&sc->sc, sc->sc_memt, sc->sc_memh, sc->sc_size, 0, 0);
}
Beispiel #2
0
void
acpiprt_prt_add(struct acpiprt_softc *sc, struct aml_value *v)
{
	struct aml_node	*node;
	struct aml_value res, *pp;
	u_int64_t addr;
	int pin, irq, sta;
#if NIOAPIC > 0
	struct mp_intr_map *map;
	struct ioapic_softc *apic;
#endif
	pci_chipset_tag_t pc = NULL;
	pcitag_t tag;
	pcireg_t reg;
	int bus, dev, func, nfuncs;

	if (v->type != AML_OBJTYPE_PACKAGE || v->length != 4) {
		printf("invalid mapping object\n");
		return;
	}

	addr = aml_val2int(v->v_package[0]);
	pin = aml_val2int(v->v_package[1]);
	if (pin > 3) {
		return;
	}

	pp = v->v_package[2];
	if (pp->type == AML_OBJTYPE_NAMEREF) {
		node = aml_searchname(sc->sc_devnode, pp->v_nameref);
		if (node == NULL) {
			printf("Invalid device!\n");
			return;
		}
		pp = node->value;
	}
	if (pp->type == AML_OBJTYPE_OBJREF) {
		pp = pp->v_objref.ref;
	}
	if (pp->type == AML_OBJTYPE_DEVICE) {
		node = pp->node;
		if (aml_evalname(sc->sc_acpi, node, "_STA", 0, NULL, &res))
			printf("no _STA method\n");

		sta = aml_val2int(&res) & STA_ENABLED;
		aml_freevalue(&res);
		if (sta == 0)
			return;

		if (aml_evalname(sc->sc_acpi, node, "_CRS", 0, NULL, &res))
			printf("no _CRS method\n");

		if (res.type != AML_OBJTYPE_BUFFER || res.length < 6) {
			printf("invalid _CRS object\n");
			aml_freevalue(&res);
			return;
		}
		aml_parse_resource(res.length, res.v_buffer,
		    acpiprt_getirq, &irq);
		aml_freevalue(&res);
	} else {
		irq = aml_val2int(v->v_package[3]);
	}

#ifdef ACPI_DEBUG
	printf("%s: %s addr 0x%llx pin %d irq %d\n",
	    DEVNAME(sc), aml_nodename(pp->node), addr, pin, irq);
#endif

#if NIOAPIC > 0
	if (nioapics > 0) {
		apic = ioapic_find_bybase(irq);
		if (apic == NULL) {
			printf("%s: no apic found for irq %d\n", DEVNAME(sc), irq);
			return;
		}

		map = malloc(sizeof (struct mp_intr_map), M_DEVBUF, M_NOWAIT);
		if (map == NULL)
			return;

		memset(map, 0, sizeof *map);
		map->ioapic = apic;
		map->ioapic_pin = irq - apic->sc_apic_vecbase;
		map->bus_pin = ((addr >> 14) & 0x7c) | (pin & 0x3);
		map->redir = IOAPIC_REDLO_ACTLO | IOAPIC_REDLO_LEVEL;
		map->redir |= (IOAPIC_REDLO_DEL_LOPRI << IOAPIC_REDLO_DEL_SHIFT);

		map->ioapic_ih = APIC_INT_VIA_APIC |
		    ((apic->sc_apicid << APIC_INT_APIC_SHIFT) |
		    (map->ioapic_pin << APIC_INT_PIN_SHIFT));

		apic->sc_pins[map->ioapic_pin].ip_map = map;

		map->next = mp_busses[sc->sc_bus].mb_intrs;
		mp_busses[sc->sc_bus].mb_intrs = map;

		return;
	}