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