From nobody Wed Jul 1 00:18:46 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gqgbq0Ft7z6kCFB for ; Wed, 01 Jul 2026 00:18:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gqgbp3Tykz3RrL for ; Wed, 01 Jul 2026 00:18:46 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1782865126; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7nWim8C7RqnPp6KVWe/MkPbYGktlc+kkfGwSPqn1Bas=; b=ETqCTd4Le6GOHJVQyg7nl7NCzWECGwJHPG+ZD8ex/ahKbjtSxl8Ubq9LfZ6rkNm3hf1K4v gsPQOfwYou1gy4WSajzivk7Xjt4QpD1IcHTT9wencEA12ahzXwkCBeKeuQfubNQM3S15Of c3fE0qDIc0oApRHfNPktVPizEFZc/ZngqxVstzPgUgJ4U0yvuK5iEXlCGxBnozGU34iTqo 3C23lLj3Q9R1G6iqYFFCVD12aqtxt+1DLGc6mlGCPCINoGX8cVOyvYB0NO9l2qQhB5tuzJ Ft0uuVLAWQSDbO9/NlsQb47CqVUBumk/zU0kHkQcS09meCP34X4sOjScnfqJ/Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1782865126; a=rsa-sha256; cv=none; b=oOvZKO/57kgvZ8NBNoRrP+ca1G2MYaoeKy1UW7tjs2WrsX+V5JiazM8QshtjnuCR4I5W0E JF8TbLMUB22eoHsxtKpk2agKtrEGAEP85yqDfpFT7drGvosv9dQBpLZ3JEVJ8Yc8WPMejs hAQn8T6qXIyaMlRwIycrrQVmQ3NCvi1XPV+KK9TAQnNiFykAC0cyNzy7Az8BCqA9bgOogF fucxdSkhXVO0NmfQw/dOpxlyrb//Vt5KthmGmqoFRHCwwjzQK5p7pCO0JIfaf5FYQ9ifJ1 vLLLhnkbR7SRAfwxUtkviXt48PGvYnj328Vk7Nl4Q56uVfSTBO9Z81g/pgIVEA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1782865126; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7nWim8C7RqnPp6KVWe/MkPbYGktlc+kkfGwSPqn1Bas=; b=ha6Lx1Pdb+7EBfItAuDMxV0V+Z00uTdxnKTbZlc3QGN4kY+kZ30M/JBY24no0IDfMMxP+W Wx0v6+UQ7HDtF4qMbUv4fPlG3qHVuJ5Zhb1+83siDmN7DITCv+EpymZ6oXI4GaQeTp7HhI Qfwsw1j2f4D3A9vxkLpKJdvbgljF/PfDehwxGaR1ryMbBIS7ulAfZ/4KrweegY06X8UbZN Etq44L2wFh6m9qjfG8bKwuqJqRc1htzNybEnSfjHUMKthDKkJLgwwTQ/wetofc2tLHWA0S 9+eM+mFZoFhvMZ0qUEWpf8sPVWUjwN6C7Am5OvdXvvtWmpVbsaxpeb6G+IoyQA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gqgbp2KnTz15rV for ; Wed, 01 Jul 2026 00:18:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 22e46 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 01 Jul 2026 00:18:46 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Abdelkader Boudih From: Adrian Chadd Subject: git: 6a1bd5212f29 - main - asmc: add system state and board identity sysctls List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: adrian X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 6a1bd5212f290933d1429a6d4787394ee53e3181 Auto-Submitted: auto-generated Date: Wed, 01 Jul 2026 00:18:46 +0000 Message-Id: <6a445ce6.22e46.16a85379@gitrepo.freebsd.org> The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=6a1bd5212f290933d1429a6d4787394ee53e3181 commit 6a1bd5212f290933d1429a6d4787394ee53e3181 Author: Abdelkader Boudih AuthorDate: 2026-07-01 00:15:24 +0000 Commit: Adrian Chadd CommitDate: 2026-07-01 00:18:40 +0000 asmc: add system state and board identity sysctls Add dev.asmc.0.system subtree with read-only sysctls for SMC diagnostic and identity keys: shutdown_cause (MSSD), sleep_cause (MSSP), thermal_status (MSAL), time_of_day (CLKT), power_state (MSPS), board_id (RPlt), and chip_gen (RGEN). Each sysctl is registered only if the key exists on the hardware. Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D57853 --- sys/dev/asmc/asmc.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++ sys/dev/asmc/asmcvar.h | 86 +++++++++++++++++++ 2 files changed, 306 insertions(+) diff --git a/sys/dev/asmc/asmc.c b/sys/dev/asmc/asmc.c index 1796867786e5..6513cfed7b4f 100644 --- a/sys/dev/asmc/asmc.c +++ b/sys/dev/asmc/asmc.c @@ -129,6 +129,15 @@ static int asmc_aupo_sysctl(SYSCTL_HANDLER_ARGS); 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); @@ -659,6 +668,72 @@ asmc_attach(device_t dev) "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 (sys_tree == NULL) { + device_printf(dev, + "failed to create system sysctl node\n"); + goto nosms; + } + + 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; @@ -2540,3 +2615,148 @@ asmc_backlight_get_info(device_t dev, struct backlight_info *info) return (0); } + +static const char * +asmc_cause_str(int8_t cause, bool is_sleep) +{ + size_t i; + + for (i = 0; i < nitems(asmc_cause_table); i++) { + if (asmc_cause_table[i].code != cause) + continue; + if (is_sleep && asmc_cause_table[i].sleep_desc != NULL) + return (asmc_cause_table[i].sleep_desc); + return (asmc_cause_table[i].desc); + } + return (NULL); +} + +static int +asmc_mssd_sysctl(SYSCTL_HANDLER_ARGS) +{ + device_t dev = (device_t)arg1; + int8_t cause; + const char *desc; + char buf[ASMC_CAUSE_BUFLEN]; + + /* EIO: SMC I/O bus did not respond to key read. */ + 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[ASMC_CAUSE_BUFLEN]; + + /* EIO: SMC I/O bus did not respond to key read. */ + 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]; + + /* EIO: SMC I/O bus did not respond to key read. */ + 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[ASMC_RPLT_MAXLEN + 1]; + char name[ASMC_RPLT_MAXLEN + 1]; + + memset(buf, 0, sizeof(buf)); + if (asmc_key_read(dev, ASMC_KEY_RPLT, buf, ASMC_RPLT_MAXLEN) != 0) + return (EIO); + + memcpy(name, buf, ASMC_RPLT_MAXLEN); + name[ASMC_RPLT_MAXLEN] = '\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 index 70485c32ea88..940119e59774 100644 --- a/sys/dev/asmc/asmcvar.h +++ b/sys/dev/asmc/asmcvar.h @@ -190,3 +190,89 @@ struct asmc_softc { * Interrupt keys. */ #define ASMC_KEY_INTOK "NTOK" /* WO; 1 byte */ + +/* + * System State Machine / diagnostics keys. + * + * MSSD - Mac System Shutdown cause (last shutdown reason code) + * MSSP - Mac System SleeP cause (last sleep reason code) + * MSAL - Mac System ALarm (thermal subsystem status bitmap) + * MSPS - Mac System Power State (current power state index) + * CLKT - CLocK Time (seconds since midnight, SMC RTC) + * MSTS - Mac System sTate/Status (SSM state; 0 = S0 awake) + */ +#define ASMC_KEY_CLKT "CLKT" /* RO; 4 bytes ui32 BE */ +#define ASMC_KEY_MSSD "MSSD" /* RO; 1 byte si8 */ +#define ASMC_KEY_MSSP "MSSP" /* RO; 1 byte si8 */ +#define ASMC_KEY_MSAL "MSAL" /* RO; 1 byte hex_ */ +#define ASMC_KEY_MSPS "MSPS" /* RO; 1 or 2 bytes hex_ */ +#define ASMC_KEY_MSTS "MSTS" /* RO; 1 byte ui8 */ + +#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. + * + * RPlt - board platform identifier (e.g. "Mac-XXXX") + * RGEN - security chip generation (3 = T2) + */ +#define ASMC_KEY_RPLT "RPlt" /* RO; 8 bytes ch8* */ +#define ASMC_KEY_RGEN "RGEN" /* RO; 1 byte ui8 */ +#define ASMC_RPLT_MAXLEN 8 /* RPlt key data length */ + +/* + * Shutdown/sleep cause codes (MSSD/MSSP values). + * + * Positive values indicate normal operation; negative values indicate + * fault conditions. + * Sources: Apple SMC firmware, VirtualSMC docs, macOS + * pmset/powermetrics output. + */ +struct asmc_cause { + int8_t code; + const char *desc; /* shutdown description */ + const char *sleep_desc; /* sleep description, or NULL if same */ +}; + +#define ASMC_CAUSE_BUFLEN 48 /* "-128 (temperature-overlimit-timeout)\0" */ + +static const struct asmc_cause asmc_cause_table[] = { + { 5, "good-shutdown", "good-sleep" }, + { 3, "power-button", NULL }, + { 2, "low-battery-sleep", NULL }, + { 1, "overtemp-sleep", NULL }, + { 0, "initial", NULL }, + { -1, "health-check", NULL }, + { -2, "power-supply", NULL }, + { -3, "temperature-multisleep", NULL }, + { -4, "sensor-fan", NULL }, + { -30, "temperature-overlimit-timeout",NULL }, + { -40, "pswr-smrst", NULL }, /* power supply watchdog reset */ + { -50, "unmapped", NULL }, + { -60, "low-battery", NULL }, + { -61, "ninja-shutdown", NULL }, /* sudden unexpected power loss */ + { -62, "ninja-restart", NULL }, + { -70, "palm-rest-temperature", NULL }, + { -71, "sodimm-temperature", NULL }, + { -72, "heatpipe-temperature", NULL }, + { -74, "battery-temperature", NULL }, + { -75, "adapter-timeout", NULL }, + { -77, "manual-temperature", NULL }, + { -78, "adapter-current", NULL }, + { -79, "battery-current", NULL }, + { -82, "skin-temperature", NULL }, + { -83, "skin-temperature-sensors", NULL }, + { -84, "backup-temperature", NULL }, + { -86, "cpu-proximity-temperature", NULL }, + { -95, "cpu-temperature", NULL }, + { -100, "power-supply-temperature", NULL }, + { -101, "lcd-temperature", NULL }, + { -102, "rsm-power-fail", NULL }, + { -103, "battery-cuv", NULL }, /* cell under-voltage */ + { -127, "pmu-forced-shutdown", NULL }, + { -128, "unknown", NULL }, +};