diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-07-07 22:43:30 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-07-07 22:43:30 +0000 |
commit | 8a5f3c0b3e76e88fa546119d56f9cd5930d5dd93 (patch) | |
tree | f2298f45135db8808c1c5266fb8e450ee87ed00f | |
parent | b278a44990ed89c4d28df42012fe81707d93be90 (diff) |
Add opalsens(4), a driver for sensors provided by the OPAL firmware.
-rw-r--r-- | sys/arch/powerpc64/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/arch/powerpc64/conf/files.powerpc64 | 6 | ||||
-rw-r--r-- | sys/arch/powerpc64/dev/opal.c | 8 | ||||
-rw-r--r-- | sys/arch/powerpc64/dev/opalsens.c | 141 | ||||
-rw-r--r-- | sys/arch/powerpc64/include/opal.h | 12 | ||||
-rw-r--r-- | sys/arch/powerpc64/powerpc64/locore.S | 5 |
6 files changed, 170 insertions, 5 deletions
diff --git a/sys/arch/powerpc64/conf/GENERIC b/sys/arch/powerpc64/conf/GENERIC index 75b96eb1e8b..72a1fe60f4f 100644 --- a/sys/arch/powerpc64/conf/GENERIC +++ b/sys/arch/powerpc64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.12 2020/07/05 17:31:11 kettenis Exp $ +# $OpenBSD: GENERIC,v 1.13 2020/07/07 22:43:29 kettenis Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -23,6 +23,7 @@ mainbus0 at root cpu0 at mainbus? opal0 at fdt? opalcons* at fdt? +opalsens* at fdt? phb* at fdt? pci* at phb? xive* at fdt? diff --git a/sys/arch/powerpc64/conf/files.powerpc64 b/sys/arch/powerpc64/conf/files.powerpc64 index 1ad3f7505a3..c092b5f1794 100644 --- a/sys/arch/powerpc64/conf/files.powerpc64 +++ b/sys/arch/powerpc64/conf/files.powerpc64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.powerpc64,v 1.19 2020/07/04 21:07:23 kettenis Exp $ +# $OpenBSD: files.powerpc64,v 1.20 2020/07/07 22:43:29 kettenis Exp $ maxpartitions 16 maxusers 2 8 128 @@ -78,6 +78,10 @@ device opalcons attach opalcons at fdt file arch/powerpc64/dev/opalcons.c opalcons needs-flag +device opalsens +attach opalsens at fdt +file arch/powerpc64/dev/opalsens.c opalsens + device phb: pcibus attach phb at fdt file arch/powerpc64/dev/phb.c phb diff --git a/sys/arch/powerpc64/dev/opal.c b/sys/arch/powerpc64/dev/opal.c index 5246f2af027..13ab766f29e 100644 --- a/sys/arch/powerpc64/dev/opal.c +++ b/sys/arch/powerpc64/dev/opal.c @@ -1,4 +1,4 @@ -/* $OpenBSD: opal.c,v 1.6 2020/07/02 17:40:34 kettenis Exp $ */ +/* $OpenBSD: opal.c,v 1.7 2020/07/07 22:43:29 kettenis Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> * @@ -138,6 +138,12 @@ opal_attach(struct device *parent, struct device *self, void *aux) for (node = OF_child(node); node; node = OF_peer(node)) opal_attach_node(sc, node); } + + node = OF_getnodebyname(faa->fa_node, "sensors"); + if (node) { + for (node = OF_child(node); node; node = OF_peer(node)) + opal_attach_node(sc, node); + } } int diff --git a/sys/arch/powerpc64/dev/opalsens.c b/sys/arch/powerpc64/dev/opalsens.c new file mode 100644 index 00000000000..840911affc0 --- /dev/null +++ b/sys/arch/powerpc64/dev/opalsens.c @@ -0,0 +1,141 @@ +/* $OpenBSD: opalsens.c,v 1.1 2020/07/07 22:43:29 kettenis Exp $ */ +/* + * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> + * + * 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/device.h> +#include <sys/sensors.h> +#include <sys/systm.h> + +#include <machine/fdt.h> +#include <machine/opal.h> + +#include <dev/ofw/openfirm.h> +#include <dev/ofw/fdt.h> + +struct opalsens_softc { + struct device sc_dev; + uint32_t sc_data; + + struct ksensor sc_sensor; + struct ksensordev sc_sensordev; +}; + +int opalsens_match(struct device *, void *, void *); +void opalsens_attach(struct device *, struct device *, void *); + +struct cfattach opalsens_ca = { + sizeof (struct opalsens_softc), opalsens_match, opalsens_attach +}; + +struct cfdriver opalsens_cd = { + NULL, "opalsens", DV_DULL +}; + +void opalsens_refresh(void *); + +int +opalsens_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return OF_is_compatible(faa->fa_node, "ibm,opal-sensor"); +} + +void +opalsens_attach(struct device *parent, struct device *self, void *aux) +{ + struct opalsens_softc *sc = (struct opalsens_softc *)self; + struct fdt_attach_args *faa = aux; + char name[32], type[32], label[32]; + + sc->sc_data = OF_getpropint(faa->fa_node, "sensor-data", 0); + + name[0] = 0; + OF_getprop(faa->fa_node, "name", name, sizeof(name)); + name[sizeof(name) - 1] = 0; + + printf(": \"%s\"", name); + + type[0] = 0; + OF_getprop(faa->fa_node, "sensor-type", type, sizeof(type)); + type[sizeof(type) - 1] = 0; + + if (strcmp(type, "curr") == 0) + sc->sc_sensor.type = SENSOR_AMPS; + else if (strcmp(type, "energy") == 0) + sc->sc_sensor.type = SENSOR_INTEGER; /* SENSOR_JOULES */ + else if (strcmp(type, "in") == 0) + sc->sc_sensor.type = SENSOR_VOLTS_DC; + else if (strcmp(type, "power") == 0) + sc->sc_sensor.type = SENSOR_WATTS; + else if (strcmp(type, "temp") == 0) + sc->sc_sensor.type = SENSOR_TEMP; + else { + printf(", unsupported sensor type \"%s\"\n", type); + return; + } + + label[0] = 0; + OF_getprop(faa->fa_node, "label", label, sizeof(label)); + label[sizeof(label) - 1] = 0; + + strlcpy(sc->sc_sensor.desc, label, sizeof(sc->sc_sensor.desc)); + + printf("\n"); + + /* Register sensor. */ + strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, + sizeof(sc->sc_sensordev.xname)); + sc->sc_sensor.flags = SENSOR_FINVALID; + sensor_attach(&sc->sc_sensordev, &sc->sc_sensor); + sensordev_install(&sc->sc_sensordev); + sensor_task_register(sc, opalsens_refresh, 5); +} + +void +opalsens_refresh(void *arg) +{ + struct opalsens_softc *sc = arg; + uint64_t value; + int64_t error; + + error = opal_sensor_read_u64(sc->sc_data, 0, opal_phys(&value)); + if (error == OPAL_SUCCESS) + sc->sc_sensor.flags &= ~SENSOR_FINVALID; + else + sc->sc_sensor.flags |= SENSOR_FINVALID; + + switch (sc->sc_sensor.type) { + case SENSOR_AMPS: + case SENSOR_VOLTS_DC: + sc->sc_sensor.value = value * 1000; + break; + case SENSOR_WATTS: + sc->sc_sensor.value = value * 1000000; + break; + case SENSOR_TEMP: + /* Firmware reports 0 for unpopulated DIMM slots. */ + if (value == 0) + sc->sc_sensor.flags |= SENSOR_FINVALID; + else + sc->sc_sensor.value = 273150000 + value * 1000000; + break; + default: + sc->sc_sensor.value = value; + break; + } +} diff --git a/sys/arch/powerpc64/include/opal.h b/sys/arch/powerpc64/include/opal.h index 67fcc35bd46..ceadc0e6094 100644 --- a/sys/arch/powerpc64/include/opal.h +++ b/sys/arch/powerpc64/include/opal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: opal.h,v 1.12 2020/06/30 20:09:37 kettenis Exp $ */ +/* $OpenBSD: opal.h,v 1.13 2020/07/07 22:43:29 kettenis Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -42,6 +42,8 @@ #define OPAL_GET_MSI_64 40 #define OPAL_PCI_MAP_PE_DMA_WINDOW_REAL 45 #define OPAL_PCI_RESET 49 +#define OPAL_CHECK_TOKEN 80 +#define OPAL_SENSOR_READ 88 #define OPAL_CONSOLE_FLUSH 117 #define OPAL_XIVE_RESET 128 #define OPAL_XIVE_GET_IRQ_INFO 129 @@ -52,6 +54,7 @@ #define OPAL_XIVE_GET_VP_INFO 137 #define OPAL_XIVE_SET_VP_INFO 138 #define OPAL_XIVE_DUMP 142 +#define OPAL_SENSOR_READ_U64 162 /* Return codes. */ #define OPAL_SUCCESS 0 @@ -106,6 +109,10 @@ #define OPAL_DEASSERT_RESET 0 #define OPAL_ASSERT_RESET 1 +/* OPAL_CHECK_TOKEN */ +#define OPAL_TOKEN_ABSENT 0 +#define OPAL_TOKEN_PRESENT 1 + /* OPAL_XIVE_RESET */ #define OPAL_XIVE_MODE_EMU 0 #define OPAL_XIVE_MODE_EXPL 1 @@ -168,6 +175,8 @@ int64_t opal_get_msi_64(uint64_t, uint32_t, uint32_t, uint8_t, int64_t opal_pci_map_pe_dma_window_real(uint64_t, uint64_t, uint16_t, uint64_t, uint64_t); int64_t opal_pci_reset(uint64_t, uint8_t, uint8_t); +int64_t opal_check_token(uint64_t); +int64_t opal_sensor_read(uint32_t, int, uint32_t *); int64_t opal_console_flush(uint64_t); int64_t opal_xive_reset(uint64_t); int64_t opal_xive_get_irq_info(uint32_t, uint64_t *, uint64_t *, @@ -182,6 +191,7 @@ int64_t opal_xive_get_vp_info(uint64_t, uint64_t *, uint64_t *, uint64_t *, uint32_t *); int64_t opal_xive_set_vp_info(uint64_t, uint64_t, uint64_t); int64_t opal_xive_dump(uint32_t, uint32_t); +int64_t opal_sensor_read_u64(uint32_t, int, uint64_t *); void opal_printf(const char *fmt, ...); diff --git a/sys/arch/powerpc64/powerpc64/locore.S b/sys/arch/powerpc64/powerpc64/locore.S index a5c4c77cd30..e7c7e73e526 100644 --- a/sys/arch/powerpc64/powerpc64/locore.S +++ b/sys/arch/powerpc64/powerpc64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.29 2020/07/05 10:34:08 kettenis Exp $ */ +/* $OpenBSD: locore.S,v 1.30 2020/07/07 22:43:29 kettenis Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -280,6 +280,8 @@ OPAL_CALL(OPAL_GET_MSI_32, opal_get_msi_32) OPAL_CALL(OPAL_GET_MSI_64, opal_get_msi_64) OPAL_CALL(OPAL_PCI_MAP_PE_DMA_WINDOW_REAL, opal_pci_map_pe_dma_window_real) OPAL_CALL(OPAL_PCI_RESET, opal_pci_reset) +OPAL_CALL(OPAL_CHECK_TOKEN, opal_check_token) +OPAL_CALL(OPAL_SENSOR_READ, opal_sensor_read) OPAL_CALL(OPAL_CONSOLE_FLUSH, opal_console_flush) OPAL_CALL(OPAL_XIVE_RESET, opal_xive_reset) OPAL_CALL(OPAL_XIVE_GET_IRQ_INFO, opal_xive_get_irq_info) @@ -290,6 +292,7 @@ OPAL_CALL(OPAL_XIVE_SET_QUEUE_INFO, opal_xive_set_queue_info) OPAL_CALL(OPAL_XIVE_GET_VP_INFO, opal_xive_get_vp_info) OPAL_CALL(OPAL_XIVE_SET_VP_INFO, opal_xive_set_vp_info) OPAL_CALL(OPAL_XIVE_DUMP, opal_xive_dump) +OPAL_CALL(OPAL_SENSOR_READ_U64, opal_sensor_read_u64) opal_call: mflr %r11 |