Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci ichsmb(4), tco(4): Add support for TCO on newer ...



details:   https://anonhg.NetBSD.org/src/rev/b8f986321675
branches:  trunk
changeset: 374239:b8f986321675
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Wed Apr 12 06:39:15 2023 +0000

description:
ichsmb(4), tco(4): Add support for TCO on newer Intel chipsets.

TCO (`Total Cost of Ownership', Intel's bizarre name for a watchdog
timer) used to hang off the Intel I/O platform controller hub's (ICH)
low-pin-count interface bridge (LPC IB), or ichlpcib(4).  On newer
devices, it hangs off the ICH SMBus instead.

Tested on INTEL 100SERIES_SMB (works) and INTEL 100SERIES_LP_SMB
(doesn't work, still not sure why).

XXX kernel revbump: This breaks the module ABI -- tco(4) modules
older than the change to make ta_has_rcba into ta_version will
incorrectly attach at buses they do not understand.  (However, the
tco(4) driver is statically built into GENERIC, so maybe it's safe
for pullup since the module wouldn't have worked anyway.)

diffstat:

 sys/arch/amd64/conf/GENERIC |    6 +-
 sys/arch/x86/pci/files.pci  |    3 +-
 sys/arch/x86/pci/ichlpcib.c |   18 +++-
 sys/arch/x86/pci/tco.c      |   48 ++++++--
 sys/arch/x86/pci/tco.h      |    6 +-
 sys/dev/ic/i82801lpcreg.h   |   45 ++++++++-
 sys/dev/pci/files.pci       |    8 +-
 sys/dev/pci/ichsmb.c        |  234 +++++++++++++++++++++++++++++++++++++++++++-
 8 files changed, 343 insertions(+), 25 deletions(-)

diffs (truncated from 654 to 300 lines):

diff -r b2c1727c87e9 -r b8f986321675 sys/arch/amd64/conf/GENERIC
--- a/sys/arch/amd64/conf/GENERIC       Wed Apr 12 06:35:40 2023 +0000
+++ b/sys/arch/amd64/conf/GENERIC       Wed Apr 12 06:39:15 2023 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.601 2023/02/09 14:09:48 abs Exp $
+# $NetBSD: GENERIC,v 1.602 2023/04/12 06:39:15 riastradh Exp $
 #
 # GENERIC machine description file
 #
@@ -22,7 +22,7 @@ include       "arch/amd64/conf/std.amd64"
 
 options        INCLUDE_CONFIG_FILE     # embed config file in kernel binary
 
-#ident         "GENERIC-$Revision: 1.601 $"
+#ident         "GENERIC-$Revision: 1.602 $"
 
 maxusers       64              # estimated number of users
 
@@ -401,7 +401,7 @@ ichlpcib* at pci? dev ? function ?  # Int
                                        # watchdog, gpio, Speedstep and HPET
 fwhrng* at ichlpcib?           # Intel 82802 FWH Random Number Generator
 #hpet* at ichlpcib?
-tco*   at ichlpcib?            # TCO watch dog timer
+tco*   at tcoichbus?           # TCO watch dog timer
 
 aapic* at pci? dev ? function ?        # AMD 8131 IO apic
 
diff -r b2c1727c87e9 -r b8f986321675 sys/arch/x86/pci/files.pci
--- a/sys/arch/x86/pci/files.pci        Wed Apr 12 06:35:40 2023 +0000
+++ b/sys/arch/x86/pci/files.pci        Wed Apr 12 06:39:15 2023 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.pci,v 1.26 2021/04/24 23:36:51 thorpej Exp $
+#      $NetBSD: files.pci,v 1.27 2023/04/12 06:39:15 riastradh Exp $
 
 device         aapic
 attach         aapic at pci
@@ -59,7 +59,6 @@ file  arch/x86/pci/rdcpcib.c          rdcpcib
 
 define fwhichbus {}
 define hpetichbus {}
-define tcoichbus {}
 device ichlpcib: acpipmtimer, isabus, fwhichbus, hpetichbus, gpiobus, tcoichbus
 attach ichlpcib at pci
 file   arch/x86/pci/ichlpcib.c         ichlpcib
diff -r b2c1727c87e9 -r b8f986321675 sys/arch/x86/pci/ichlpcib.c
--- a/sys/arch/x86/pci/ichlpcib.c       Wed Apr 12 06:35:40 2023 +0000
+++ b/sys/arch/x86/pci/ichlpcib.c       Wed Apr 12 06:39:15 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ichlpcib.c,v 1.58 2022/09/22 14:42:29 riastradh Exp $  */
+/*     $NetBSD: ichlpcib.c,v 1.59 2023/04/12 06:39:15 riastradh Exp $  */
 
 /*-
  * Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ichlpcib.c,v 1.58 2022/09/22 14:42:29 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ichlpcib.c,v 1.59 2023/04/12 06:39:15 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -89,6 +89,11 @@ struct lpcib_softc {
        bus_space_handle_t      sc_pmh;
        bus_size_t              sc_iosize;
 
+       /* TCO variables. */
+       bus_space_tag_t         sc_tcot;
+       bus_space_handle_t      sc_tcoh;
+       bus_size_t              sc_tcosz;
+
        /* HPET variables. */
        uint32_t                sc_hpet_reg;
 
@@ -348,6 +353,13 @@ lpcibattach(device_t parent, device_t se
                return;
        }
 
+       if (bus_space_subregion(sc->sc_pmt, sc->sc_pmh, PMC_TCO_BASE,
+               TCO_REGSIZE, &sc->sc_tcoh)) {
+               aprint_error_dev(self, "can't map TCO space\n");
+       } else {
+               sc->sc_tcot = sc->sc_pmt;
+       }
+
        sc->sc_pmcon_orig = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
            LPCIB_PCI_GEN_PMCON_1);
 
@@ -644,6 +656,8 @@ tcotimer_configure(device_t self)
        arg.ta_rcbat = sc->sc_rcbat;
        arg.ta_rcbah = sc->sc_rcbah;
        arg.ta_pcib = &sc->sc_pcib;
+       arg.ta_tcot = sc->sc_tcot;
+       arg.ta_tcoh = sc->sc_tcoh;
 
        sc->sc_tco = config_found(self, &arg, NULL,
            CFARGS(.iattr = "tcoichbus"));
diff -r b2c1727c87e9 -r b8f986321675 sys/arch/x86/pci/tco.c
--- a/sys/arch/x86/pci/tco.c    Wed Apr 12 06:35:40 2023 +0000
+++ b/sys/arch/x86/pci/tco.c    Wed Apr 12 06:39:15 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tco.c,v 1.9 2022/09/22 14:43:04 riastradh Exp $        */
+/*     $NetBSD: tco.c,v 1.10 2023/04/12 06:39:15 riastradh Exp $       */
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tco.c,v 1.9 2022/09/22 14:43:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tco.c,v 1.10 2023/04/12 06:39:15 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -60,8 +60,10 @@ struct tco_softc {
        bus_space_tag_t         sc_rcbat;
        bus_space_handle_t      sc_rcbah;
        struct pcib_softc *     sc_pcib;
+       pci_chipset_tag_t       sc_pc;
        bus_space_tag_t         sc_tcot;
        bus_space_handle_t      sc_tcoh;
+       int                     (*sc_set_noreboot)(device_t, bool);
        int                     sc_armed;
        unsigned int            sc_min_t;
        unsigned int            sc_max_t;
@@ -93,12 +95,13 @@ tco_match(device_t parent, cfdata_t matc
 {
        struct tco_attach_args *ta = aux;
 
-       if (ta->ta_pmt == 0)
-               return 0;
-
        switch (ta->ta_version) {
+       case TCO_VERSION_SMBUS:
+               break;
        case TCO_VERSION_RCBA:
        case TCO_VERSION_PCIB:
+               if (ta->ta_pmt == 0)
+                       return 0;
                break;
        default:
                return 0;
@@ -125,11 +128,21 @@ tco_attach(device_t parent, device_t sel
        aprint_normal(": TCO (watchdog) timer configured.\n");
        aprint_naive("\n");
 
-       sc->sc_tcot = sc->sc_pmt;
-       if (bus_space_subregion(sc->sc_pmt, sc->sc_pmh, PMC_TCO_BASE,
-               TCO_REGSIZE, &sc->sc_tcoh)) {
-               aprint_error_dev(self, "failed to map TCO registers\n");
-               return;
+       switch (sc->sc_version) {
+       case TCO_VERSION_SMBUS:
+               sc->sc_tcot = ta->ta_tcot;
+               sc->sc_tcoh = ta->ta_tcoh;
+               sc->sc_set_noreboot = ta->ta_set_noreboot;
+               break;
+       case TCO_VERSION_RCBA:
+       case TCO_VERSION_PCIB:
+               sc->sc_tcot = sc->sc_pmt;
+               if (bus_space_subregion(sc->sc_pmt, sc->sc_pmh, PMC_TCO_BASE,
+                       TCO_REGSIZE, &sc->sc_tcoh)) {
+                       aprint_error_dev(self, "failed to map TCO\n");
+                       return;
+               }
+               break;
        }
 
        /* Explicitly stop the TCO timer. */
@@ -140,6 +153,7 @@ tco_attach(device_t parent, device_t sel
         * work. We don't know what the SMBIOS does.
         */
        ioreg = bus_space_read_4(sc->sc_pmt, sc->sc_pmh, PMC_SMI_EN);
+       aprint_debug_dev(self, "SMI_EN=0x%08x\n", ioreg);
        ioreg &= ~PMC_SMI_EN_TCO_EN;
 
        /*
@@ -150,7 +164,10 @@ tco_attach(device_t parent, device_t sel
                ioreg |= PMC_SMI_EN_TCO_EN;
        }
        if ((ioreg & PMC_SMI_EN_GBL_SMI_EN) != 0) {
+               aprint_debug_dev(self, "SMI_EN:=0x%08x\n", ioreg);
                bus_space_write_4(sc->sc_pmt, sc->sc_pmh, PMC_SMI_EN, ioreg);
+               aprint_debug_dev(self, "SMI_EN=0x%08x\n",
+                   bus_space_read_4(sc->sc_pmt, sc->sc_pmh, PMC_SMI_EN));
        }
 
        /* Reset the watchdog status registers. */
@@ -172,6 +189,7 @@ tco_attach(device_t parent, device_t sel
         *                              2secs          23secs
         */
        switch (sc->sc_version) {
+       case TCO_VERSION_SMBUS:
        case TCO_VERSION_RCBA:
                sc->sc_max_t = TCOTIMER2_MAX_TICK;
                sc->sc_min_t = TCOTIMER2_MIN_TICK;
@@ -256,6 +274,7 @@ tcotimer_setmode(struct sysmon_wdog *smw
 
                /* set the timeout, */
                switch (sc->sc_version) {
+               case TCO_VERSION_SMBUS:
                case TCO_VERSION_RCBA:
                        /* ICH6 or newer */
                        ich6period = bus_space_read_2(sc->sc_tcot, sc->sc_tcoh,
@@ -289,6 +308,7 @@ tcotimer_tickle(struct sysmon_wdog *smw)
 
        /* any value is allowed */
        switch (sc->sc_version) {
+       case TCO_VERSION_SMBUS:
        case TCO_VERSION_RCBA:
                bus_space_write_2(sc->sc_tcot, sc->sc_tcoh, TCO_RLD, 1);
                break;
@@ -339,8 +359,14 @@ static int
 tcotimer_disable_noreboot(device_t self)
 {
        struct tco_softc *sc = device_private(self);
+       int error = EINVAL;
 
        switch (sc->sc_version) {
+       case TCO_VERSION_SMBUS:
+               error = (*sc->sc_set_noreboot)(self, false);
+               if (error)
+                       goto error;
+               break;
        case TCO_VERSION_RCBA: {
                uint32_t status;
 
@@ -376,7 +402,7 @@ tcotimer_disable_noreboot(device_t self)
 error:
        aprint_error_dev(self, "TCO timer reboot disabled by hardware; "
            "hope SMBIOS properly handles it.\n");
-       return EINVAL;
+       return error;
 }
 
 MODULE(MODULE_CLASS_DRIVER, tco, "sysmon_wdog");
diff -r b2c1727c87e9 -r b8f986321675 sys/arch/x86/pci/tco.h
--- a/sys/arch/x86/pci/tco.h    Wed Apr 12 06:35:40 2023 +0000
+++ b/sys/arch/x86/pci/tco.h    Wed Apr 12 06:39:15 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tco.h,v 1.4 2022/09/22 14:42:29 riastradh Exp $        */
+/*     $NetBSD: tco.h,v 1.5 2023/04/12 06:39:15 riastradh Exp $        */
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -40,12 +40,16 @@ struct tco_attach_args {
        enum {
                TCO_VERSION_PCIB = 0,
                TCO_VERSION_RCBA = 1,
+               TCO_VERSION_SMBUS = 2,
        }                       ta_version;
        bus_space_tag_t         ta_pmt;
        bus_space_handle_t      ta_pmh;
        bus_space_tag_t         ta_rcbat;
        bus_space_handle_t      ta_rcbah;
        struct pcib_softc *     ta_pcib;
+       bus_space_tag_t         ta_tcot;
+       bus_space_handle_t      ta_tcoh;
+       int                     (*ta_set_noreboot)(device_t, bool);
 };
 
 #endif
diff -r b2c1727c87e9 -r b8f986321675 sys/dev/ic/i82801lpcreg.h
--- a/sys/dev/ic/i82801lpcreg.h Wed Apr 12 06:35:40 2023 +0000
+++ b/sys/dev/ic/i82801lpcreg.h Wed Apr 12 06:39:15 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i82801lpcreg.h,v 1.16 2022/09/22 14:45:33 riastradh Exp $      */
+/*     $NetBSD: i82801lpcreg.h,v 1.17 2023/04/12 06:39:15 riastradh Exp $      */
 
 /*-
  * Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -171,6 +171,11 @@
 #define SMB_HOSTC_HSTEN                (1 << 0)        /* enable host controller */
 #define SMB_HOSTC_SMIEN                (1 << 1)        /* generate SMI */
 #define SMB_HOSTC_I2CEN                (1 << 2)        /* enable I2C commands */
+#define SMB_TCOBASE    0x50            /* TCO Base Address */
+#define  SMB_TCOBASE_TCOBA     __BITS(15,5)    /* TCO Base Address */
+#define  SMB_TCOBASE_IOS       __BIT(0)        /* I/O Space */
+#define SMB_TCOCTL     0x54            /* TCO Control */
+#define  SMB_TCOCTL_TCO_BASE_EN        __BIT(8)        /* TCO Base Enable */
 
 /* SMBus I/O registers */
 #define SMB_HS         0x00            /* host status */
@@ -301,4 +306,42 @@ tcotimer_second_to_tick(int ltick)
 #define TCOTIMER_MAX_TICK      0x3f    /* 39 seconds max */
 #define TCOTIMER2_MAX_TICK     0x265   /* 613 seconds max */
 
+/*
+ * P2SB: Primary to Sideband Bridge, PCI configuration registers
+ */
+#define        P2SB_SBREG_BAR          0x10    /* Sideband Register Access BAR */
+#define        P2SB_SBREG_BARH         0x14    /* Sideband BAR High DWORD */
+#define        P2SB_P2SBC              0xe0    /* P2SB Control */
+#define         P2SB_P2SBC_HIDE        __BIT(8)        /* Hide Device */
+
+/*
+ * PCH Private Configuration Space -- Sideband
+ */
+#define        SB_PORTID               __BITS(23,16)



Home | Main Index | Thread Index | Old Index