Index: src/sys/arch/sparc64/dev/envmon_ebus.c
===================================================================
RCS file: src/sys/arch/sparc64/dev/envmon_ebus.c
diff -N src/sys/arch/sparc64/dev/envmon_ebus.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/sys/arch/sparc64/dev/envmon_ebus.c	9 Jul 2026 08:35:13 -0000
@@ -0,0 +1,209 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2026 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Julian Coleman.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+#include <sys/types.h>
+
+#include <sys/bus.h>
+#include <machine/autoconf.h>
+
+#include <dev/ebus/ebusreg.h>
+#include <dev/ebus/ebusvar.h>
+
+#include <dev/sysmon/sysmonvar.h>
+
+#include <arch/sparc64/dev/envmon_ebusreg.h>
+
+#define ENVMON_TYPE_PIC16F	0x00
+#define ENVMON_TYPE_EPIC	0x01
+
+#define ENVMON_MAX_SENSORS	1
+
+struct envmon_softc {
+	device_t	sc_dev;
+
+	bus_space_tag_t sc_bst;	
+	bus_space_handle_t sc_bsh;
+
+	struct sysmon_envsys *sc_sme;
+	envsys_data_t sc_sensor[ENVMON_MAX_SENSORS];
+
+	int sc_type;
+};
+
+static int envmon_ebus_match(device_t, cfdata_t, void *);
+static void envmon_ebus_attach(device_t, device_t, void *);
+static void envmon_attach_u45(struct envmon_softc *, int);
+static void envmon_attach_v245(struct envmon_softc *, int);
+void envmon_refresh_u45(struct sysmon_envsys *, envsys_data_t *);
+void envmon_refresh_v245(struct sysmon_envsys *, envsys_data_t *);
+
+CFATTACH_DECL_NEW(envmon_ebus, sizeof(struct envmon_softc),
+    envmon_ebus_match, envmon_ebus_attach, NULL, NULL);
+
+#define	envmon_read(sc, reg) \
+    bus_space_read_1(sc->sc_bst, sc->sc_bsh, reg)
+#define envmon_write(sc, reg, val) \
+    bus_space_write_1(sc->sc_bst, sc->sc_bsh, reg, val)
+
+static int
+envmon_ebus_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct ebus_attach_args *ea = aux;
+	char *compat;
+
+	if (strcmp("env-monitor", ea->ea_name) != 0)
+		return 0;
+
+	compat = prom_getpropstring(ea->ea_node, "compatible");
+	if (compat != NULL && (!strcmp(compat, "SUNW,ebus-pic16f747-env") ||
+	    !strcmp(compat, "epic")))
+		return 1;
+
+	return 0;
+}
+
+static void
+envmon_ebus_attach(device_t parent, device_t self, void *aux)
+{
+	struct envmon_softc *sc = device_private(self);
+	struct ebus_attach_args *ea = aux;
+	char compat[32];
+	int sz;
+
+	sc->sc_dev = self;
+	sc->sc_bst = ea->ea_bustag;
+
+	sz = ea->ea_reg[0].size;
+
+	if (bus_space_map(sc->sc_bst,
+			 EBUS_ADDR_FROM_REG(&ea->ea_reg[0]),
+			 sz, 0,
+			 &sc->sc_bsh) != 0) {
+		aprint_error(": can't map register\n");
+		return;
+	}
+
+	sc->sc_sme = sysmon_envsys_create();
+	sc->sc_sme->sme_name = device_xname(self);
+	sc->sc_sme->sme_cookie = sc;
+
+	OF_getprop(ea->ea_node, "compatible", compat, sizeof(compat));
+
+	if (!strcmp(compat, "SUNW,ebus-pic16f747-env")) {
+		sc->sc_type = ENVMON_TYPE_PIC16F;
+		envmon_attach_u45(sc, ea->ea_node);
+	}
+	if (!strcmp(compat, "epic")) {
+		sc->sc_type = ENVMON_TYPE_EPIC;
+		envmon_attach_v245(sc, ea->ea_node);
+	}
+}
+
+/*
+ * We only add the front panel temperature here.
+ * Other U45 sensors are handled by the ADT7462 driver.
+ */
+static void
+envmon_attach_u45(struct envmon_softc *sc, int node)
+{
+	int32_t vers;
+
+	vers = prom_getpropint(node, "version", 0);
+	aprint_normal(": pic16f747 (ver. %d)\n", vers);
+
+	sc->sc_sme->sme_refresh = envmon_refresh_u45;
+	strlcpy(sc->sc_sensor[0].desc, "Front_panel",
+	    sizeof(sc->sc_sensor[0].desc));
+	sc->sc_sensor[0].units = ENVSYS_STEMP;
+	sc->sc_sensor[0].state = ENVSYS_SINVALID;
+	sc->sc_sensor[0].flags = ENVSYS_FHAS_ENTROPY;
+	if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor[0])) {
+		sysmon_envsys_destroy(sc->sc_sme);
+		sc->sc_sme = NULL;
+		aprint_error_dev(sc->sc_dev,
+		    "unable to attach sensor to sysmon\n");
+		return;
+	}
+	if (sysmon_envsys_register(sc->sc_sme)) {
+		aprint_error_dev(sc->sc_dev,
+		    "unable to register with sysmon\n");
+		sysmon_envsys_destroy(sc->sc_sme);
+		sc->sc_sme = NULL;
+		return;
+	}
+
+	return;
+}
+
+static void
+envmon_attach_v245(struct envmon_softc *sc, int node)
+{
+	const char *vers;
+	uint8_t reg, val;
+
+	vers = prom_getpropstring(node, "version");
+	aprint_normal(": epic (ver. %s)\n", vers);
+
+	sc->sc_sme->sme_refresh = envmon_refresh_v245;
+
+	for (reg = 0; reg < 0x3d; reg++) {
+		envmon_write(sc, ENVMON_ADDR, reg);
+		val = envmon_read(sc, ENVMON_DATA);
+		printf("  reg 0x%02x = 0x%02x\n", reg, val);
+	}
+
+	return;
+}
+
+void
+envmon_refresh_u45(struct sysmon_envsys *sme, envsys_data_t *edata)
+{
+	struct envmon_softc *sc = sme->sme_cookie;
+	uint8_t val;
+	
+	envmon_write(sc, ENVMON_ADDR, ENVMON_PIC_TEMP_FP);
+	val = envmon_read(sc, ENVMON_DATA);
+	edata->value_cur = ENVMON_PIC_TEMP_BASE + val * 1000000;
+	edata->state = ENVSYS_SVALID;
+}
+
+void
+envmon_refresh_v245(struct sysmon_envsys *sme, envsys_data_t *edata)
+{
+	return;
+}
Index: src/sys/arch/sparc64/dev/envmon_ebusreg.h
===================================================================
RCS file: src/sys/arch/sparc64/dev/envmon_ebusreg.h
diff -N src/sys/arch/sparc64/dev/envmon_ebusreg.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/sys/arch/sparc64/dev/envmon_ebusreg.h	9 Jul 2026 08:35:13 -0000
@@ -0,0 +1,77 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2026 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Julian Coleman.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Register definitions for "env-monitor":
+ *   "SUNW,ebus-pic16f747-env" on U45/U25
+ *   "epic" on V245/V215
+ * Registers are indirectly accessed through a address and data register.
+ *
+ * Register contents are mostly copies of registers from other chips on
+ * the i2c bus.  However, some registers contain local sensor data, e.g.
+ * front panel temperature on U45.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#define ENVMON_COMPAT_PIC	"SUNW,ebus-pic16f747-env"
+#define ENVMON_COMPAT_EPIC	"epic"
+
+#define ENVMON_DATA		0x40	/* Read/write register data */
+#define ENVMON_ADDR		0x41	/* Register address */
+
+/* U45/U25 registers */
+#define ENVMON_PIC_FAN0		0x00	/* Fan 0 speed */
+#define ENVMON_PIC_FAN1		0x01	/* Fan 1 speed */
+#define ENVMON_PIC_FAN2		0x02	/* Fan 2 speed */
+#define ENVMON_PIC_FAN3		0x03	/* Fan 3 speed */
+#define ENVMON_PIC_FAN4		0x04	/* Fan 4 speed */
+
+#define ENVMON_PIC_TEMP_ADT	0x06	/* ADT7462 temperature */
+#define ENVMON_PIC_TEMP_CPU0	0x07	/* CPU 0 temperature */
+#define ENVMON_PIC_TEMP_CPU1	0x08	/* CPU 1 temperature */
+#define ENVMON_PIC_TEMP_MB	0x09	/* Motherboard temperature */
+#define ENVMON_PIC_TEMP_LM	0x0a	/* LM95221 temperature */
+#define ENVMON_PIC_TEMP_FIRE	0x0b	/* FireASIC temperature */
+#define ENVMON_PIC_TEMP_LSI	0x0c	/* LSI1064 temperature */
+#define ENVMON_PIC_TEMP_FP	0x0d	/* Front Panel temperature */
+#define ENVMON_PIC_TEMP_BASE	209150000	/* -64'C */
+
+#define ENVMON_PIC_VOLT_15_1	0x0f	/* 1.5v #1 */
+#define ENVMON_PIC_VOLT_15_2	0x10	/* 1.5v #2 */
+#define ENVMON_PIC_SCALE_1_5V	7800	
+
+#define ENVMON_PIC_TEMP_PSU	0x13	/* Power Supply temperature */
+
+/* V245/V215 registers */
+#define ENVMON_EPC_FW		0x05	/* Firmware version */
+#define ENVMON_EPC_LED_F0	0x06	/* Front power and top fault LED's */
Index: src/sys/arch/sparc64/conf/GENERIC
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/conf/GENERIC,v
retrieving revision 1.249
diff -u -r1.249 GENERIC
--- src/sys/arch/sparc64/conf/GENERIC	7 Jul 2026 14:15:03 -0000	1.249
+++ src/sys/arch/sparc64/conf/GENERIC	9 Jul 2026 08:35:17 -0000
@@ -243,6 +243,9 @@
 ## bq4802 compatible clock found on ebus on Ultra 45.
 bq4802rtc* 	at ebus?
 
+## env-monitor found on ebus on Ultra 45 and Fire V245.
+envmon* 	at ebus?
+
 ## Timer chip found on 4/300, sun4c, sun4m and (some) sun4u systems.
 timer*	at mainbus0				# sun4c
 
Index: src/sys/arch/sparc64/conf/files.sparc64
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/conf/files.sparc64,v
retrieving revision 1.171
diff -u -r1.171 files.sparc64
--- src/sys/arch/sparc64/conf/files.sparc64	7 Jul 2026 12:44:48 -0000	1.171
+++ src/sys/arch/sparc64/conf/files.sparc64	9 Jul 2026 08:35:18 -0000
@@ -99,6 +99,10 @@
 attach bq4802rtc at ebus with bq4802rtc_ebus
 file	arch/sparc64/dev/bq4802_ebus.c		bq4802rtc
 
+device envmon: sysmon_envsys
+attach envmon at ebus with envmon_ebus
+file	arch/sparc64/dev/envmon_ebus.c		envmon
+
 device psm: sysmon_power
 attach psm at ebus
 file	arch/sparc64/dev/psm.c			psm
