diff options
-rw-r--r-- | sys/arch/amd64/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/dev/acpi/acpireg.h | 3 | ||||
-rw-r--r-- | sys/dev/acpi/files.acpi | 6 | ||||
-rw-r--r-- | sys/dev/acpi/ipmi_acpi.c | 161 |
4 files changed, 170 insertions, 3 deletions
diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index f76f70697c2..6c53c13bac1 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.450 2017/12/24 19:50:56 patrick Exp $ +# $OpenBSD: GENERIC,v 1.451 2018/03/14 18:52:16 patrick Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -66,6 +66,7 @@ acpicbkbd* at acpi? acpials* at acpi? tpm* at acpi? acpihve* at acpi? +ipmi0 at acpi? disable mpbios0 at bios0 diff --git a/sys/dev/acpi/acpireg.h b/sys/dev/acpi/acpireg.h index 130df5c97b2..5b1e145e82c 100644 --- a/sys/dev/acpi/acpireg.h +++ b/sys/dev/acpi/acpireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: acpireg.h,v 1.39 2017/03/12 21:30:44 jcs Exp $ */ +/* $OpenBSD: acpireg.h,v 1.40 2018/03/14 18:52:16 patrick Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org> @@ -760,5 +760,6 @@ struct acpi_ivrs { #define ACPI_DEV_IOSA "ACPI000B" /* IO SAPIC Device */ #define ACPI_DEV_THZ "THERMALZONE" /* Thermal Zone */ #define ACPI_DEV_FFB "FIXEDBUTTON" /* Fixed Feature Button */ +#define ACPI_DEV_IPMI "IPI0001" /* IPMI */ #endif /* !_DEV_ACPI_ACPIREG_H_ */ diff --git a/sys/dev/acpi/files.acpi b/sys/dev/acpi/files.acpi index 44edff19d6f..58cce95eba0 100644 --- a/sys/dev/acpi/files.acpi +++ b/sys/dev/acpi/files.acpi @@ -1,4 +1,4 @@ -# $OpenBSD: files.acpi,v 1.38 2017/11/16 18:12:27 jcs Exp $ +# $OpenBSD: files.acpi,v 1.39 2018/03/14 18:52:16 patrick Exp $ # # Config file and device description for machine-independent ACPI code. # Included by ports that need it. @@ -154,3 +154,7 @@ file dev/acpi/acpihve.c acpihve device acpisbs attach acpisbs at acpi file dev/acpi/acpisbs.c acpisbs + +# IPMI +attach ipmi at acpi with ipmi_acpi +file dev/acpi/ipmi_acpi.c ipmi_acpi diff --git a/sys/dev/acpi/ipmi_acpi.c b/sys/dev/acpi/ipmi_acpi.c new file mode 100644 index 00000000000..ddb20738683 --- /dev/null +++ b/sys/dev/acpi/ipmi_acpi.c @@ -0,0 +1,161 @@ +/* $OpenBSD: ipmi_acpi.c,v 1.1 2018/03/14 18:52:16 patrick Exp $ */ +/* + * Copyright (c) 2018 Patrick Wildt <patrick@blueri.se> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/signalvar.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/malloc.h> + +#include <machine/bus.h> +#include <machine/apmvar.h> + +#include <dev/acpi/acpireg.h> +#include <dev/acpi/acpivar.h> +#include <dev/acpi/acpidev.h> +#include <dev/acpi/amltypes.h> +#include <dev/acpi/dsdt.h> +#undef DEVNAME + +#include <dev/ipmivar.h> + +#define DEVNAME(s) ((s)->sc.sc_dev.dv_xname) + +int ipmi_acpi_match(struct device *, void *, void *); +void ipmi_acpi_attach(struct device *, struct device *, void *); +int ipmi_acpi_parse_crs(int, union acpi_resource *, void *); + +extern void ipmi_attach(struct device *, struct device *, void *); + +struct ipmi_acpi_softc { + struct ipmi_softc sc; + + struct acpi_softc *sc_acpi; + struct aml_node *sc_devnode; + + int sc_ift; + + bus_space_tag_t sc_iot; + bus_size_t sc_iobase; + int sc_iospacing; + char sc_iotype; +}; + +struct cfattach ipmi_acpi_ca = { + sizeof(struct ipmi_acpi_softc), ipmi_acpi_match, ipmi_acpi_attach, +}; + +const char *ipmi_acpi_hids[] = { ACPI_DEV_IPMI, NULL }; + +int +ipmi_acpi_match(struct device *parent, void *match, void *aux) +{ + struct acpi_attach_args *aa = aux; + struct cfdata *cf = match; + + /* sanity */ + return (acpi_matchhids(aa, ipmi_acpi_hids, cf->cf_driver->cd_name)); +} + +void +ipmi_acpi_attach(struct device *parent, struct device *self, void *aux) +{ + struct ipmi_acpi_softc *sc = (struct ipmi_acpi_softc *)self; + struct acpi_attach_args *aa = aux; + struct ipmi_attach_args ia; + struct aml_value res; + int64_t ift; + int rc; + + sc->sc_acpi = (struct acpi_softc *)parent; + sc->sc_devnode = aa->aaa_node; + + rc = aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_IFT", 0, NULL, &ift); + if (rc) { + printf(": no _IFT\n"); + return; + } + sc->sc_ift = ift; + + if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRS", 0, NULL, &res)) { + printf(": no _CRS method\n"); + return; + } + if (res.type != AML_OBJTYPE_BUFFER) { + printf(": invalid _CRS object (type %d len %d)\n", + res.type, res.length); + aml_freevalue(&res); + return; + } + + aml_parse_resource(&res, ipmi_acpi_parse_crs, sc); + aml_freevalue(&res); + + if (sc->sc_iot == NULL) { + printf("%s: incomplete resources (ift %d)\n", + DEVNAME(sc), sc->sc_ift); + return; + } + + ia.iaa_iot = sc->sc_iot; + ia.iaa_memt = sc->sc_iot; + ia.iaa_if_type = sc->sc_ift; + ia.iaa_if_rev = 0; + ia.iaa_if_irq = -1; + ia.iaa_if_irqlvl = 0; + ia.iaa_if_iospacing = sc->sc_iospacing; + ia.iaa_if_iobase = sc->sc_iobase; + ia.iaa_if_iotype = sc->sc_iotype; + + ipmi_attach(parent, self, &ia); +} + +int +ipmi_acpi_parse_crs(int crsidx, union acpi_resource *crs, void *arg) +{ + struct ipmi_acpi_softc *sc = arg; + int type = AML_CRSTYPE(crs); + + switch (crsidx) { + case 0: + if (type != SR_IOPORT) { + printf("%s: Unexpected resource #%d type %d\n", + DEVNAME(sc), crsidx, type); + break; + } + sc->sc_iot = sc->sc_acpi->sc_iot; + sc->sc_iobase = crs->sr_ioport._max; + sc->sc_iospacing = 1; + sc->sc_iotype = 'i'; + break; + case 1: + if (type != SR_IOPORT) { + printf("%s: Unexpected resource #%d type %d\n", + DEVNAME(sc), crsidx, type); + break; + } + if (crs->sr_ioport._max <= sc->sc_iobase) + break; + sc->sc_iospacing = crs->sr_ioport._max - sc->sc_iobase; + break; + default: + printf("%s: invalid resource #%d type %d (ift %d)\n", + DEVNAME(sc), crsidx, type, sc->sc_ift); + } + + return 0; +} |