Page MenuHomeFreeBSD

D57853.id180650.diff
No OneTemporary

D57853.id180650.diff

diff --git a/sys/dev/asmc/asmc.c b/sys/dev/asmc/asmc.c
--- a/sys/dev/asmc/asmc.c
+++ b/sys/dev/asmc/asmc.c
@@ -129,6 +129,15 @@
static int asmc_key_getinfo(device_t, const char *, uint8_t *, char *);
+/* System state / board identity sysctls */
+static int asmc_mssd_sysctl(SYSCTL_HANDLER_ARGS);
+static int asmc_mssp_sysctl(SYSCTL_HANDLER_ARGS);
+static int asmc_msal_sysctl(SYSCTL_HANDLER_ARGS);
+static int asmc_clkt_sysctl(SYSCTL_HANDLER_ARGS);
+static int asmc_msps_sysctl(SYSCTL_HANDLER_ARGS);
+static int asmc_rplt_sysctl(SYSCTL_HANDLER_ARGS);
+static int asmc_rgen_sysctl(SYSCTL_HANDLER_ARGS);
+
#ifdef ASMC_DEBUG
/* Raw key access */
static int asmc_raw_key_sysctl(SYSCTL_HANDLER_ARGS);
@@ -650,6 +659,67 @@
"Battery charge limit (0-100)");
}
+ /* System state / board identity subtree. */
+ {
+ struct sysctl_oid *sys_tree;
+ uint8_t msps_len;
+
+ sys_tree = SYSCTL_ADD_NODE(sysctlctx,
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+ "system", CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
+ "System state and board identity");
+
+ if (asmc_key_getinfo(dev, ASMC_KEY_MSSD, NULL, NULL) == 0)
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sys_tree), OID_AUTO, "shutdown_cause",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ dev, 0, asmc_mssd_sysctl, "A",
+ "Last shutdown cause (MSSD)");
+
+ if (asmc_key_getinfo(dev, ASMC_KEY_MSSP, NULL, NULL) == 0)
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sys_tree), OID_AUTO, "sleep_cause",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ dev, 0, asmc_mssp_sysctl, "A",
+ "Last sleep cause (MSSP)");
+
+ if (asmc_key_getinfo(dev, ASMC_KEY_MSAL, NULL, NULL) == 0)
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sys_tree), OID_AUTO, "thermal_status",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ dev, 0, asmc_msal_sysctl, "A",
+ "Thermal subsystem status flags (MSAL)");
+
+ if (asmc_key_getinfo(dev, ASMC_KEY_CLKT, NULL, NULL) == 0)
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sys_tree), OID_AUTO, "time_of_day",
+ CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ dev, 0, asmc_clkt_sysctl, "IU",
+ "Seconds since midnight per SMC clock (CLKT)");
+
+ if (asmc_key_getinfo(dev, ASMC_KEY_MSPS, &msps_len, NULL) == 0 &&
+ (msps_len == 1 || msps_len == 2))
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sys_tree), OID_AUTO, "power_state",
+ CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ dev, 0, asmc_msps_sysctl, "IU",
+ "SMC power state index (MSPS)");
+
+ if (asmc_key_getinfo(dev, ASMC_KEY_RPLT, NULL, NULL) == 0)
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sys_tree), OID_AUTO, "board_id",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ dev, 0, asmc_rplt_sysctl, "A",
+ "Apple internal board codename (RPlt)");
+
+ if (asmc_key_getinfo(dev, ASMC_KEY_RGEN, NULL, NULL) == 0)
+ SYSCTL_ADD_PROC(sysctlctx,
+ SYSCTL_CHILDREN(sys_tree), OID_AUTO, "chip_gen",
+ CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ dev, 0, asmc_rgen_sysctl, "IU",
+ "Apple security chip generation (RGEN; 3=T2)");
+ }
+
if (!sc->sc_has_sms)
goto nosms;
@@ -2531,3 +2601,172 @@
return (0);
}
+
+static const char *
+asmc_cause_str(int8_t cause, bool is_sleep)
+{
+ switch (cause) {
+ case 5: return (is_sleep ? "good-sleep" : "good-shutdown");
+ case 3: return "power-button";
+ case 2: return "low-battery-sleep";
+ case 1: return "overtemp-sleep";
+ case 0: return "initial";
+ case -1: return "health-check";
+ case -2: return "power-supply";
+ case -3: return "temperature-multisleep";
+ case -4: return "sensor-fan";
+ case -30: return "temperature-overlimit-timeout";
+ case -40: return "pswr-smrst";
+ case -50: return "unmapped";
+ case -60: return "low-battery";
+ case -61: return "ninja-shutdown";
+ case -62: return "ninja-restart";
+ case -70: return "palm-rest-temperature";
+ case -71: return "sodimm-temperature";
+ case -72: return "heatpipe-temperature";
+ case -74: return "battery-temperature";
+ case -75: return "adapter-timeout";
+ case -77: return "manual-temperature";
+ case -78: return "adapter-current";
+ case -79: return "battery-current";
+ case -82: return "skin-temperature";
+ case -83: return "skin-temperature-sensors";
+ case -84: return "backup-temperature";
+ case -86: return "cpu-proximity-temperature";
+ case -95: return "cpu-temperature";
+ case -100: return "power-supply-temperature";
+ case -101: return "lcd-temperature";
+ case -102: return "rsm-power-fail";
+ case -103: return "battery-cuv";
+ case -127: return "pmu-forced-shutdown";
+ case -128: return "unknown";
+ default: return NULL;
+ }
+}
+
+static int
+asmc_mssd_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t)arg1;
+ int8_t cause;
+ const char *desc;
+ char buf[48];
+
+ if (asmc_key_read(dev, ASMC_KEY_MSSD, (uint8_t *)&cause, 1) != 0)
+ return (EIO);
+
+ desc = asmc_cause_str(cause, false);
+ if (desc != NULL)
+ snprintf(buf, sizeof(buf), "%d (%s)", (int)cause, desc);
+ else
+ snprintf(buf, sizeof(buf), "%d", (int)cause);
+
+ return (sysctl_handle_string(oidp, buf, sizeof(buf), req));
+}
+
+static int
+asmc_mssp_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t)arg1;
+ int8_t cause;
+ const char *desc;
+ char buf[48];
+
+ if (asmc_key_read(dev, ASMC_KEY_MSSP, (uint8_t *)&cause, 1) != 0)
+ return (EIO);
+
+ desc = asmc_cause_str(cause, true);
+ if (desc != NULL)
+ snprintf(buf, sizeof(buf), "%d (%s)", (int)cause, desc);
+ else
+ snprintf(buf, sizeof(buf), "%d", (int)cause);
+
+ return (sysctl_handle_string(oidp, buf, sizeof(buf), req));
+}
+
+static int
+asmc_msal_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t)arg1;
+ uint8_t msal;
+ char buf[80];
+
+ if (asmc_key_read(dev, ASMC_KEY_MSAL, &msal, 1) != 0)
+ return (EIO);
+
+ snprintf(buf, sizeof(buf),
+ "0x%02x (tss=%d therm_valid=%d calib_valid=%d prochot=%d plimits=%d)",
+ msal,
+ (msal & ASMC_MSAL_TSS) != 0,
+ (msal & ASMC_MSAL_THERM_VALID) != 0,
+ (msal & ASMC_MSAL_CALIB_VALID) != 0,
+ (msal & ASMC_MSAL_PROCHOT) != 0,
+ (msal & ASMC_MSAL_PLIMITS) != 0);
+
+ return (sysctl_handle_string(oidp, buf, sizeof(buf), req));
+}
+
+static int
+asmc_clkt_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t)arg1;
+ uint8_t buf[4];
+ uint32_t secs;
+
+ if (asmc_key_read(dev, ASMC_KEY_CLKT, buf, 4) != 0)
+ return (EIO);
+
+ secs = be32dec(buf);
+ return (sysctl_handle_32(oidp, &secs, 0, req));
+}
+
+static int
+asmc_msps_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t)arg1;
+ uint8_t buf[2], len;
+ uint32_t state;
+
+ if (asmc_key_getinfo(dev, ASMC_KEY_MSPS, &len, NULL) != 0)
+ return (EIO);
+ if (len != 1 && len != 2)
+ return (EIO);
+
+ memset(buf, 0, sizeof(buf));
+ if (asmc_key_read(dev, ASMC_KEY_MSPS, buf, len) != 0)
+ return (EIO);
+
+ state = (len == 1) ? buf[0] : be16dec(buf);
+ return (sysctl_handle_32(oidp, &state, 0, req));
+}
+
+static int
+asmc_rplt_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t)arg1;
+ uint8_t buf[9];
+ char name[9];
+
+ memset(buf, 0, sizeof(buf));
+ if (asmc_key_read(dev, ASMC_KEY_RPLT, buf, 8) != 0)
+ return (EIO);
+
+ memcpy(name, buf, 8);
+ name[8] = '\0';
+
+ return (sysctl_handle_string(oidp, name, sizeof(name), req));
+}
+
+static int
+asmc_rgen_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t)arg1;
+ uint8_t gen;
+ uint32_t val;
+
+ if (asmc_key_read(dev, ASMC_KEY_RGEN, &gen, 1) != 0)
+ return (EIO);
+
+ val = gen;
+ return (sysctl_handle_32(oidp, &val, 0, req));
+}
diff --git a/sys/dev/asmc/asmcvar.h b/sys/dev/asmc/asmcvar.h
--- a/sys/dev/asmc/asmcvar.h
+++ b/sys/dev/asmc/asmcvar.h
@@ -190,3 +190,25 @@
* Interrupt keys.
*/
#define ASMC_KEY_INTOK "NTOK" /* WO; 1 byte */
+
+/*
+ * System State Machine / diagnostics keys.
+ */
+#define ASMC_KEY_CLKT "CLKT" /* RO; 4 bytes ui32 BE, seconds since midnight */
+#define ASMC_KEY_MSSD "MSSD" /* RO; 1 byte si8, last shutdown cause code */
+#define ASMC_KEY_MSSP "MSSP" /* RO; 1 byte si8, last sleep cause code */
+#define ASMC_KEY_MSAL "MSAL" /* RO; 1 byte hex_, thermal subsystem status */
+#define ASMC_KEY_MSPS "MSPS" /* RO; 1 or 2 bytes hex_, power state index */
+#define ASMC_KEY_MSTS "MSTS" /* RO; 1 byte ui8, SSM state (0=S0 awake) */
+
+#define ASMC_MSAL_TSS 0x01 /* TSS running */
+#define ASMC_MSAL_THERM_VALID 0x02 /* thermal calibration valid */
+#define ASMC_MSAL_CALIB_VALID 0x08 /* I/P calibration valid */
+#define ASMC_MSAL_PROCHOT 0x40 /* Prochot enabled */
+#define ASMC_MSAL_PLIMITS 0x80 /* plimits enabled */
+
+/*
+ * Board identity keys.
+ */
+#define ASMC_KEY_RPLT "RPlt" /* RO; 8 bytes ch8*, board codename */
+#define ASMC_KEY_RGEN "RGEN" /* RO; 1 byte ui8, chip generation (3 = T2) */

File Metadata

Mime Type
text/plain
Expires
Mon, Aug 24, 4:54 AM (5 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37174034
Default Alt Text
D57853.id180650.diff (8 KB)

Event Timeline