From nobody Sun Sep 13 20:36:36 2026 X-Original-To: dev-commits-src-all@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 4hjg6s39lnz6sWF3 for ; Sun, 13 Sep 2026 20:36:37 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hjg6s0VLhz4JfQ for ; Sun, 13 Sep 2026 20:36:37 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789331797; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=rrB/Dhe4gZr6rRLXfZKFtmTe58RRCCOYFLfekf3KhQ8=; b=kq7c18Adg8oWcUoc+zUQXle5Nw2YtyqT0DA6hu/s7iPqtXr2kwiyoA48aX5Z5y9e8yCdhT nbptShxj1GWaUWPzK4tFsjvQ+OgJ6noRpB2+b8J+dAVpSNVZPJuQt8cMrkU5w1SAHM8jSf G5ZHKZCh09rI78K8yZUBOJT1ptucvG1oSLL/kHeTdnlyOSs5G3wlo/2Apl0ANVK/OF9t3V NDilILKpRIgJIA06UohqVCEM3qc/KLcQFsc4as+qLM6g8gF5Wz5HlYOZYKq4YY2i8BCb6q BprzPz7IfBulgOucqa2d44RPLxABuWKjqquVhWcVM8d7QVBOPUIrHXbOYiihFA== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1789331797; b=b4hqAO39SVhzozEf1VngecnpZ0YvMjl1V4+Gxl14jSel5mDGfNDRYmEoF2dOJS05Dssjai rarm5ea0dwBq3hKugohjV3lIinQ6gzzK4Ff7c/rfrCKO8V+mtSx18aVvsMAfqa1RLgcLl3 RYU350Ik7zXPnB4Hc9qPWFm102YLu7Oi5CvFlhbUzjuR3aq4pTFtSZT3iMJtgZsdXRne/E b5ZKVA+YD4k8+JbYJ3e/vEqyBbg2xdv13OeIUfsezvk0WAVP4+32xEEGxzIvnaITk1AyCx iuGDWXyZeFs3pp424vqQBNM4W4cROQhggA9e3u97FlU9BR9wTYHM6649W7inUw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789331797; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=rrB/Dhe4gZr6rRLXfZKFtmTe58RRCCOYFLfekf3KhQ8=; b=MGjjoDO3ZErLfzMnI3IAVo9UJp4ronNFlD78sO3D/tBBHaxp82i9dRNYSt4jmJXdlO2Y/i aIZZZSRIGEKLp3m9EvU0AdB0xd1F8KjXIqoMVPNDTLju0gVX4j0zlSzyrN9xDQ4uwZHmmS vRW8qkJLGEnQKevUwHtXMBplcm7iBI/wU+BL6WbaBLzDQU5hD7nbdpRmgBqXLZIBJT5GHO ZBDl0HMp+md3ctzruHaY3nBogAO1OgY34e/bz9zod63hlNxA7rQH/Nre1QiSo1mvc+/nun 0DQ6HV+IMhvqw32sDaRSRcVDfKz83owiDI+446SIxRKZF3vxcy4ULZRGEbWJDg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hjg6r6gv9zybK for ; Sun, 13 Sep 2026 20:36:36 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 304b1 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 13 Sep 2026 20:36:36 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Abdelkader Boudih Subject: git: dd9e49a10bc1 - main - intel/intelpmc: Add Intel PMC Core driver List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@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: seuros X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: dd9e49a10bc14f7d876426d7d85fed0d1fe9699d Auto-Submitted: auto-generated Date: Sun, 13 Sep 2026 20:36:36 +0000 Message-Id: <6aa70954.304b1.7946c04b@gitrepo.freebsd.org> The branch main has been updated by seuros: URL: https://cgit.FreeBSD.org/src/commit/?id=dd9e49a10bc14f7d876426d7d85fed0d1fe9699d commit dd9e49a10bc14f7d876426d7d85fed0d1fe9699d Author: Abdelkader Boudih AuthorDate: 2026-09-13 20:36:16 +0000 Commit: Abdelkader Boudih CommitDate: 2026-09-13 20:36:16 +0000 intel/intelpmc: Add Intel PMC Core driver Add driver for Intel Power Management Controller (PMC) found on Sunrise Point PCH chipsets. This device exposes S0ix sleep state residency counters and power management status. Sysctls provided: dev.intelpmc.0.slp_s0_residency_us - Time in deepest sleep (us) dev.intelpmc.0.ltr_ignore - LTR ignore mask dev.intelpmc.0.pm_cfg - PM configuration register dev.intelpmc.0.pm_sts - PM status register dev.intelpmc.0.access_denied - Firmware lock status Supported devices for now: - Sunrise Point-LP (0x9D21) - Sunrise Point-H (0xA121) Note: Later PCH generations (Cannon Lake, Tiger Lake, ect.) have different PMC register layouts according to the datasheet and would need per-generation tables. I avoided adding untested hardware in case they have a quirk. Reviewed by: olce, adrian Differential Revision: https://reviews.freebsd.org/D54881 --- share/man/man4/Makefile | 1 + share/man/man4/intel_pmc.4 | 83 ++++++++++++++++ sys/conf/files.x86 | 1 + sys/dev/intel/intel_pmc.c | 219 +++++++++++++++++++++++++++++++++++++++++ sys/modules/Makefile | 2 + sys/modules/intel_pmc/Makefile | 6 ++ 6 files changed, 312 insertions(+) diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 07307c59308c..7a5ef9f397eb 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -262,6 +262,7 @@ MAN= aac.4 \ ${_imcsmb.4} \ inet.4 \ inet6.4 \ + intel_pmc.4 \ intpm.4 \ intro.4 \ ${_io.4} \ diff --git a/share/man/man4/intel_pmc.4 b/share/man/man4/intel_pmc.4 new file mode 100644 index 000000000000..1f12e8532675 --- /dev/null +++ b/share/man/man4/intel_pmc.4 @@ -0,0 +1,83 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright (c) 2026 Abdelkader Boudih +.\" +.Dd September 7, 2026 +.Dt INTEL_PMC 4 +.Os +.Sh NAME +.Nm intel_pmc +.Nd Intel Performance Management Controller driver +.Sh SYNOPSIS +.Cd "device intel_pmc" +.Sh DESCRIPTION +The +.Nm +driver exposes information and controls from the Performance +Management Controller (PMC) of Intel platforms. +Presently, it supports the Intel Sunrise Point platform (Skylake CPU +generation), providing access to debug information and controls +related to S0ix (Modern Standby). +.Pp +The cumulative time spent in low power mode while in S0 is reported, +and the administrator can force the platform to ignore IP blocks +whose Latency Tolerance Reporting (LTR) prevents the platform from +entering S0ix. +.Sh HARDWARE +The +.Nm +driver supports the PMC block found in the following Intel Platform +Controller Hubs: +.Pp +.Bl -bullet -compact +.It +Intel Sunrise Point-LP PMC (6th/7th Gen Core mobile, PCI ID 0x8086:0x9d21) +.It +Intel Sunrise Point-H PMC (6th/7th Gen Core desktop/server, +PCI ID 0x8086:0xa121) +.El +.Sh SYSCTLS +The following +.Xr sysctl 8 +variables are available: +.Bl -tag -width indent +.It Va dev.intel_pmc.%d.ltr_ignore Pq read-write +Latency Tolerance Reporting (LTR) ignore mask. +Each bit corresponds to one IP block (bits 0-16). +Setting a bit tells the PMC to ignore that IP's LTR requirements, +allowing S0ix entry even if the IP would otherwise block it. +A clear bit means the IP's requirements are considered and can +prevent S0ix. +.Pp +Sunrise Point bit assignments: +SOUTHPORT_A, SOUTHPORT_B, SATA, GIGABIT_ETHERNET, XHCI, reserved, +ME, EVA, SOUTHPORT_C, HD_AUDIO, LPSS, SOUTHPORT_D, SOUTHPORT_E, +CAMERA, ESPI, SCC, ISH. +.It Va dev.intel_pmc.%d.slp_s0_residency Pq read-only +Cumulative time in microseconds that the SLP_S0 signal has been +asserted (100\ us per counter step). +Per the datasheet, SLP_S0 asserts when the PCH is idle and the +processor is in C10 state. +A value that never advances indicates S0ix transitions are not occurring. +.Pp +The counter is 32-bit and wraps after approximately 5 days of +cumulative S0ix residency. +.El +.Sh SEE ALSO +.Xr acpi 4 , +.Xr pci 4 , +.Xr sysctl 8 +.Pp +Intel 100 Series Chipset Family PCH Datasheet, Volume 2, Section 4.3. +.Sh HISTORY +The +.Nm +driver first appeared in +.Fx 16.0 . +.Sh AUTHORS +.An Abdelkader Boudih Aq Mt seuros@FreeBSD.org +.Sh CAVEATS +Only Sunrise Point PCH is supported. +Other PCH generations (Cannon Point, Tiger Lake, etc.) have different +register layouts and are not handled by this driver. diff --git a/sys/conf/files.x86 b/sys/conf/files.x86 index bb52975598ab..d0c131bf0730 100644 --- a/sys/conf/files.x86 +++ b/sys/conf/files.x86 @@ -159,6 +159,7 @@ dev/ichwd/i6300esbwd.c optional ichwd dev/ichwd/ichwd.c optional ichwd dev/imcsmb/imcsmb.c optional imcsmb dev/imcsmb/imcsmb_pci.c optional imcsmb pci +dev/intel/intel_pmc.c optional intel_pmc pci dev/intel/pchtherm.c optional pchtherm dev/intel/spi.c optional intelspi dev/intel/spi_pci.c optional intelspi pci diff --git a/sys/dev/intel/intel_pmc.c b/sys/dev/intel/intel_pmc.c new file mode 100644 index 000000000000..ee437cc08b5d --- /dev/null +++ b/sys/dev/intel/intel_pmc.c @@ -0,0 +1,219 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 Abdelkader Boudih + */ + +/* + * intel_pmc -- Intel Performance Management Controller (PMC) driver + * + * Exposes information and controls from the PMC of Intel platforms. + * Only the Sunrise Point (SPT) platform, paired with Skylake + * generation processors, is currently supported; everything below + * describes that hardware only. + * + * The driver reports the cumulative time spent in low power mode + * (S0ix, Modern Standby) while in S0, and lets the administrator + * force the PMC to ignore IP blocks whose Latency Tolerance + * Reporting (LTR) prevents the platform from entering S0ix. + * + * The PMC register space (PWRM) is mapped via the PWRM_BASE register + * at PCI config offset 0x48, not through BAR0. See Intel 100 Series + * Chipset Family PCH Datasheet Vol 2, section 4.3.53. + * + * The SLP_S0_RESIDENCY counter increments (100 us per step) while the + * PCH SLP_S0 signal is asserted. Per the datasheet, SLP_S0 asserts + * when the PCH is idle and the processor is in C10 state; in general + * this also requires ModPhy lanes power-gated and PLLs idle (Linux + * commit b740d2e9233cb). A counter that never advances indicates + * S0ix transitions are not occurring. The counter is 32-bit and + * wraps after approximately 5 days of cumulative S0ix residency. + * + * LTR_IGNORE (PWRM+0x30C) has one bit per IP block. Setting a bit + * tells the PMC to ignore that IP's LTR requirements, allowing S0ix + * entry even if the IP would otherwise block it. A clear bit means + * the IP's LTR requirements are considered and can prevent S0ix. + * + * SPT bit assignments (0-16): + * 0=SOUTHPORT_A 1=SOUTHPORT_B 2=SATA + * 3=GIGABIT_ETHERNET 4=XHCI 5=reserved + * 6=ME 7=EVA 8=SOUTHPORT_C + * 9=HD_AUDIO 10=LPSS 11=SOUTHPORT_D + * 12=SOUTHPORT_E 13=CAMERA 14=ESPI + * 15=SCC 16=ISH + * + * Ref: Intel 100 Series Chipset Family PCH Datasheet Vol 2, section 4.3 + * Ref: Linux commit 9c2ee19987ef (initial SPT PMC support) + * Ref: Linux commit 2eb150558bb7 (LTR IP block documentation) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +/* + * Sunrise Point (SPT) PMC Register Definitions + * Reference: Intel 100 Series Chipset Family PCH Datasheet Vol 2. + * LTR_IGNORE is not documented there; the offset comes from Linux + * commit 9c2ee19987ef (initial SPT PMC support). + */ +#define SPT_PMC_ACTL_OFFSET 0x44 /* ACPI Control */ +#define SPT_PMC_ACTL_PWRM_EN (1u << 8) /* PWRM decode enabled */ +#define SPT_PMC_PWRM_BASE_OFFSET 0x48 /* PCI config offset for PWRM */ +#define SPT_PMC_PWRM_BASE_MASK 0xfffff000 +#define SPT_PMC_MMIO_SIZE 0x1000 + +#define SPT_PMC_SLP_S0_RES_OFFSET 0x13C +#define SPT_PMC_SLP_S0_RES_STEP 100 /* 100us per datasheet */ +#define SPT_PMC_LTR_IGNORE_OFFSET 0x30C +#define SPT_PMC_LTR_IGNORE_BITS 17 /* bits 0-16 are valid IP blocks */ + +struct intel_pmc_softc { + bus_space_tag_t bst; + bus_space_handle_t bsh; +}; + +/* + * Only Sunrise Point - other generations have different layouts. + * 0xa121 is documented in the Intel 100 Series Chipset Family PCH + * Datasheet Vol 2. Sunrise Point-LP has no public datasheet; 0x9d21 + * comes from the pci_vendors database, where Linux also sourced it. + */ +static const struct pci_device_table intel_pmc_devices[] = { + { PCI_DEV(0x8086, 0x9d21), PCI_DESCR("Sunrise Point-LP PMC")}, + { PCI_DEV(0x8086, 0xa121), PCI_DESCR("Sunrise Point-H PMC")}, +}; + +static inline uint32_t +intel_pmc_read(struct intel_pmc_softc *sc, uint32_t offset) +{ + + return (bus_space_read_4(sc->bst, sc->bsh, offset)); +} + +static inline void +intel_pmc_write(struct intel_pmc_softc *sc, uint32_t offset, uint32_t val) +{ + + bus_space_write_4(sc->bst, sc->bsh, offset, val); +} + +static int +intel_pmc_slp_s0_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct intel_pmc_softc *sc = oidp->oid_arg1; + uint64_t val, usec; + + val = intel_pmc_read(sc, SPT_PMC_SLP_S0_RES_OFFSET); + usec = val * SPT_PMC_SLP_S0_RES_STEP; + return (sysctl_handle_64(oidp, &usec, 0, req)); +} + +static int +intel_pmc_ltr_ignore_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct intel_pmc_softc *sc = oidp->oid_arg1; + uint32_t val; + int error; + + val = intel_pmc_read(sc, SPT_PMC_LTR_IGNORE_OFFSET); + error = sysctl_handle_32(oidp, &val, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + /* Only bits 0-16 are valid IP blocks */ + val &= (1u << SPT_PMC_LTR_IGNORE_BITS) - 1; + intel_pmc_write(sc, SPT_PMC_LTR_IGNORE_OFFSET, val); + return (0); +} + +static int +intel_pmc_probe(device_t dev) +{ + const struct pci_device_table *tbl; + + tbl = PCI_MATCH(dev, intel_pmc_devices); + if (tbl == NULL) + return (ENXIO); + device_set_desc(dev, tbl->descr); + return (BUS_PROBE_DEFAULT); +} + +static int +intel_pmc_attach(device_t dev) +{ + struct intel_pmc_softc *sc = device_get_softc(dev); + struct sysctl_ctx_list *ctx; + struct sysctl_oid *tree; + vm_paddr_t pwrm_base; + + if ((pci_read_config(dev, SPT_PMC_ACTL_OFFSET, 4) & + SPT_PMC_ACTL_PWRM_EN) == 0) { + device_printf(dev, "PWRM decode not enabled by firmware\n"); + return (ENXIO); + } + pwrm_base = pci_read_config(dev, SPT_PMC_PWRM_BASE_OFFSET, 4) & + SPT_PMC_PWRM_BASE_MASK; + + sc->bst = X86_BUS_SPACE_MEM; + sc->bsh = (bus_space_handle_t)pmap_mapdev(pwrm_base, + SPT_PMC_MMIO_SIZE); + + ctx = device_get_sysctl_ctx(dev); + tree = device_get_sysctl_tree(dev); + + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "ltr_ignore", + CTLTYPE_U32 | CTLFLAG_RW | CTLFLAG_MPSAFE, + sc, 0, intel_pmc_ltr_ignore_sysctl, "IU", + "LTR ignore mask: set bit = ignore IP, allowing S0ix"); + + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "slp_s0_residency", + CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_MPSAFE, + sc, 0, intel_pmc_slp_s0_sysctl, "QU", + "SLP_S0 residency time in microseconds"); + + return (0); +} + +static int +intel_pmc_detach(device_t dev) +{ + struct intel_pmc_softc *sc = device_get_softc(dev); + + pmap_unmapdev((void *)sc->bsh, SPT_PMC_MMIO_SIZE); + return (0); +} + +static device_method_t intel_pmc_methods[] = { + DEVMETHOD(device_probe, intel_pmc_probe), + DEVMETHOD(device_attach, intel_pmc_attach), + DEVMETHOD(device_detach, intel_pmc_detach), + DEVMETHOD_END +}; + +static driver_t intel_pmc_driver = { + "intel_pmc", + intel_pmc_methods, + sizeof(struct intel_pmc_softc) +}; + +DRIVER_MODULE(intel_pmc, pci, intel_pmc_driver, 0, 0); +PCI_PNP_INFO(intel_pmc_devices); +MODULE_VERSION(intel_pmc, 1); +MODULE_DEPEND(intel_pmc, pci, 1, 1, 1); diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 2c3553aea2f3..0b196b72c079 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -178,6 +178,7 @@ SUBDIR= \ ${_igc} \ imgact_binmisc \ ${_imx} \ + ${_intel_pmc} \ ${_intelspi} \ ${_io} \ ${_ioat} \ @@ -831,6 +832,7 @@ _hptrr= hptrr _hyperv= hyperv _ichwd= ichwd _ida= ida +_intel_pmc= intel_pmc _intelspi= intelspi _ips= ips _isci= isci diff --git a/sys/modules/intel_pmc/Makefile b/sys/modules/intel_pmc/Makefile new file mode 100644 index 000000000000..5f68a19f4b3e --- /dev/null +++ b/sys/modules/intel_pmc/Makefile @@ -0,0 +1,6 @@ +.PATH: ${SRCTOP}/sys/dev/intel +KMOD= intel_pmc +SRCS= intel_pmc.c +SRCS+= device_if.h bus_if.h pci_if.h + +.include