Пример #1
0
int
acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa)
{
	struct aml_value	res;
	bus_size_t		ec_sc, ec_data;
	int			type1, type2;
	char			*buf;
	int			size, ret;

	if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_GPE", 0, NULL, &res)) {
		dnprintf(10, "%s: no _GPE\n", DEVNAME(sc));
		return (1);
	}

	sc->sc_gpe = aml_val2int(&res);
	aml_freevalue(&res);

	if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRS", 0, NULL, &res)) {
		dnprintf(10, "%s: no _CRS\n", DEVNAME(sc));
		return (1);
	}

	/* Parse CRS to get control and data registers */

	if (res.type != AML_OBJTYPE_BUFFER) {
		dnprintf(10, "%s: unknown _CRS type %d\n",
		    DEVNAME(sc), res.type);
		aml_freevalue(&res);
		return (1);
	}

	size = res.length;
	buf = res.v_buffer;

	ret = acpiec_getregister(buf, size, &type1, &ec_data);
	if (ret <= 0) {
		dnprintf(10, "%s: failed to read DATA from _CRS\n",
		    DEVNAME(sc));
		aml_freevalue(&res);
		return (1);
	}

	buf += ret;
	size -= ret;

	ret = acpiec_getregister(buf, size, &type2,  &ec_sc);
	if (ret <= 0) {
		dnprintf(10, "%s: failed to read S/C from _CRS\n",
		    DEVNAME(sc));
		aml_freevalue(&res);
		return (1);
	}

	buf += ret;
	size -= ret;

	if (size != 2 || *buf != RES_TYPE_ENDTAG) {
		dnprintf(10, "%s: no _CRS end tag\n", DEVNAME(sc));
		aml_freevalue(&res);
		return (1);
	}
	aml_freevalue(&res);

	/* XXX: todo - validate _CRS checksum? */

	dnprintf(10, "%s: Data: 0x%x, S/C: 0x%x\n",
	    DEVNAME(sc), ec_data, ec_sc);

	if (type1 == GAS_SYSTEM_IOSPACE)
		sc->sc_cmd_bt = aa->aaa_iot;
	else
		sc->sc_cmd_bt = aa->aaa_memt;

	if (bus_space_map(sc->sc_cmd_bt, ec_sc, 1, 0, &sc->sc_cmd_bh)) {
		dnprintf(10, "%s: failed to map S/C reg.\n", DEVNAME(sc));
		return (1);
	}

	if (type2 == GAS_SYSTEM_IOSPACE)
		sc->sc_data_bt = aa->aaa_iot;
	else
		sc->sc_data_bt = aa->aaa_memt;

	if (bus_space_map(sc->sc_data_bt, ec_data, 1, 0, &sc->sc_data_bh)) {
		dnprintf(10, "%s: failed to map DATA reg.\n", DEVNAME(sc));
		bus_space_unmap(sc->sc_cmd_bt, sc->sc_cmd_bh, 1);
		return (1);
	}

	return (0);
}
Пример #2
0
int
acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa)
{
	struct aml_value	res;
	bus_size_t		ec_sc, ec_data;
	int			dtype, ctype;
	char			*buf;
	int			size, ret;
	int64_t			gpe;
	struct acpi_ecdt	*ecdt = aa->aaa_table;
	extern struct aml_node	aml_root;

	/* Check if this is ECDT initialization */
	if (ecdt) {
		/* Get GPE, Data and Control segments */
		sc->sc_gpe = ecdt->gpe_bit;

		ctype = ecdt->ec_control.address_space_id;
		ec_sc = ecdt->ec_control.address;

		dtype = ecdt->ec_data.address_space_id;
		ec_data = ecdt->ec_data.address;

		/* Get devnode from header */
		sc->sc_devnode = aml_searchname(&aml_root, ecdt->ec_id);

		goto ecdtdone;
	}

	if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_GPE", 0, NULL, &gpe)) {
		dnprintf(10, "%s: no _GPE\n", DEVNAME(sc));
		return (1);
	}

	sc->sc_gpe = gpe;

	if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRS", 0, NULL, &res)) {
		dnprintf(10, "%s: no _CRS\n", DEVNAME(sc));
		return (1);
	}

	/* Parse CRS to get control and data registers */

	if (res.type != AML_OBJTYPE_BUFFER) {
		dnprintf(10, "%s: unknown _CRS type %d\n",
		    DEVNAME(sc), res.type);
		aml_freevalue(&res);
		return (1);
	}

	size = res.length;
	buf = res.v_buffer;

	ret = acpiec_getregister(buf, size, &dtype, &ec_data);
	if (ret <= 0) {
		dnprintf(10, "%s: failed to read DATA from _CRS\n",
		    DEVNAME(sc));
		aml_freevalue(&res);
		return (1);
	}

	buf += ret;
	size -= ret;

	ret = acpiec_getregister(buf, size, &ctype, &ec_sc);
	if (ret <= 0) {
		dnprintf(10, "%s: failed to read S/C from _CRS\n",
		    DEVNAME(sc));
		aml_freevalue(&res);
		return (1);
	}

	buf += ret;
	size -= ret;

	if (size != 2 || *buf != RES_TYPE_ENDTAG) {
		dnprintf(10, "%s: no _CRS end tag\n", DEVNAME(sc));
		aml_freevalue(&res);
		return (1);
	}
	aml_freevalue(&res);

	/* XXX: todo - validate _CRS checksum? */
ecdtdone:

	dnprintf(10, "%s: Data: 0x%lx, S/C: 0x%lx\n",
	    DEVNAME(sc), ec_data, ec_sc);

	if (ctype == GAS_SYSTEM_IOSPACE)
		sc->sc_cmd_bt = aa->aaa_iot;
	else
		sc->sc_cmd_bt = aa->aaa_memt;

	if (bus_space_map(sc->sc_cmd_bt, ec_sc, 1, 0, &sc->sc_cmd_bh)) {
		dnprintf(10, "%s: failed to map S/C reg.\n", DEVNAME(sc));
		return (1);
	}

	if (dtype == GAS_SYSTEM_IOSPACE)
		sc->sc_data_bt = aa->aaa_iot;
	else
		sc->sc_data_bt = aa->aaa_memt;

	if (bus_space_map(sc->sc_data_bt, ec_data, 1, 0, &sc->sc_data_bh)) {
		dnprintf(10, "%s: failed to map DATA reg.\n", DEVNAME(sc));
		bus_space_unmap(sc->sc_cmd_bt, sc->sc_cmd_bh, 1);
		return (1);
	}

	return (0);
}