summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-07-07 22:43:30 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-07-07 22:43:30 +0000
commit8a5f3c0b3e76e88fa546119d56f9cd5930d5dd93 (patch)
treef2298f45135db8808c1c5266fb8e450ee87ed00f
parentb278a44990ed89c4d28df42012fe81707d93be90 (diff)
Add opalsens(4), a driver for sensors provided by the OPAL firmware.
-rw-r--r--sys/arch/powerpc64/conf/GENERIC3
-rw-r--r--sys/arch/powerpc64/conf/files.powerpc646
-rw-r--r--sys/arch/powerpc64/dev/opal.c8
-rw-r--r--sys/arch/powerpc64/dev/opalsens.c141
-rw-r--r--sys/arch/powerpc64/include/opal.h12
-rw-r--r--sys/arch/powerpc64/powerpc64/locore.S5
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