aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbdelkader Boudih <freebsd@seuros.com>2026-07-01 00:13:42 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2026-07-01 00:18:40 +0000
commitbb1e071be47fa03accadace587784c85654de91e (patch)
tree9ec38c169f2078ee08b0df9be5be97e503da08fa
parent9ea13242985dc145b2471cc8f651be87c6a74bfe (diff)
asmc: try PIO before MMIO to avoid false T2 detection
Add hw.asmc.system-state and hw.asmc.board-id read-only sysctls to expose the T2 system state register and Mac board identifier via SMC. Try PIO access before MMIO during probe to prevent false T2 detection on Macs that happen to have something mapped at the T2 BAR address. Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D57844
-rw-r--r--sys/dev/asmc/asmc.c55
-rw-r--r--sys/dev/asmc/asmcmmio.c2
-rw-r--r--sys/dev/asmc/asmcvar.h2
3 files changed, 33 insertions, 26 deletions
diff --git a/sys/dev/asmc/asmc.c b/sys/dev/asmc/asmc.c
index 055f98e06892..1796867786e5 100644
--- a/sys/dev/asmc/asmc.c
+++ b/sys/dev/asmc/asmc.c
@@ -418,43 +418,50 @@ asmc_probe(device_t dev)
return (rv);
}
+/*
+ * Try PIO first; fall back to MMIO for T2 Macs.
+ */
static int
-asmc_attach(device_t dev)
+asmc_try_probe(device_t dev)
{
- int i, j;
- int ret;
- char name[2];
struct asmc_softc *sc = device_get_softc(dev);
- struct sysctl_ctx_list *sysctlctx;
- struct sysctl_oid *sysctlnode;
- /*
- * Try MMIO first (T2 Macs expose SMC via memory-mapped I/O).
- * Fall back to standard I/O port if MMIO is not available.
- */
+ sc->sc_ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
+ &sc->sc_rid_port, RF_ACTIVE);
+ if (sc->sc_ioport != NULL)
+ return (0);
+
sc->sc_rid_mem = 0;
sc->sc_iomem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->sc_rid_mem, RF_ACTIVE);
if (sc->sc_iomem != NULL) {
if (asmc_mmio_probe(dev) == 0) {
- sc->sc_is_mmio = 1;
+ sc->sc_is_mmio = true;
device_printf(dev, "using MMIO backend (T2)\n");
- } else {
- bus_release_resource(dev, SYS_RES_MEMORY,
- sc->sc_rid_mem, sc->sc_iomem);
- sc->sc_iomem = NULL;
+ return (0);
}
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ sc->sc_rid_mem, sc->sc_iomem);
+ sc->sc_iomem = NULL;
}
- if (!sc->sc_is_mmio) {
- sc->sc_ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
- &sc->sc_rid_port, RF_ACTIVE);
- if (sc->sc_ioport == NULL) {
- device_printf(dev, "unable to allocate IO port\n");
- ret = ENOMEM;
- goto err;
- }
- }
+ device_printf(dev, "unable to allocate IO port\n");
+ return (ENOMEM);
+}
+
+static int
+asmc_attach(device_t dev)
+{
+ int i, j;
+ int ret;
+ char name[2];
+ struct asmc_softc *sc = device_get_softc(dev);
+ struct sysctl_ctx_list *sysctlctx;
+ struct sysctl_oid *sysctlnode;
+
+ ret = asmc_try_probe(dev);
+ if (ret != 0)
+ goto err;
sysctlctx = device_get_sysctl_ctx(dev);
sysctlnode = device_get_sysctl_tree(dev);
diff --git a/sys/dev/asmc/asmcmmio.c b/sys/dev/asmc/asmcmmio.c
index 016c50f6170f..237e8ec4ed52 100644
--- a/sys/dev/asmc/asmcmmio.c
+++ b/sys/dev/asmc/asmcmmio.c
@@ -307,7 +307,7 @@ asmc_mmio_detach(device_t dev, struct asmc_softc *sc)
sc->sc_iomem);
sc->sc_iomem = NULL;
}
- sc->sc_is_mmio = 0;
+ sc->sc_is_mmio = false;
sc->sc_is_t2 = 0;
}
diff --git a/sys/dev/asmc/asmcvar.h b/sys/dev/asmc/asmcvar.h
index bc0c624eb7a2..70485c32ea88 100644
--- a/sys/dev/asmc/asmcvar.h
+++ b/sys/dev/asmc/asmcvar.h
@@ -56,7 +56,7 @@ struct asmc_softc {
/* MMIO backend (T2 Macs) */
int sc_rid_mem;
struct resource *sc_iomem;
- int sc_is_mmio;
+ bool sc_is_mmio;
int sc_is_t2; /* T2 fan float + per-fan manual */
int sc_sms_intrtype;
struct taskqueue *sc_sms_tq;