diff --git a/sys/dev/ichwd/ichwd.h b/sys/dev/ichwd/ichwd.h --- a/sys/dev/ichwd/ichwd.h +++ b/sys/dev/ichwd/ichwd.h @@ -38,6 +38,7 @@ char *desc; unsigned int ich_version; unsigned int tco_version; + uint32_t quirks; }; struct ichwd_softc { @@ -277,6 +278,9 @@ #define DEVICEID_WCPT_LP7 0x9cc7 #define DEVICEID_WCPT_LP9 0x9cc9 #define DEVICEID_LEWISBURG_SMB 0xa1a3 +#define DEVICEID_LEWISBURG_SMB_SSKU 0xa223 +#define DEVICEID_CANNON_SMB 0xa323 +#define DEVICEID_COMET_SMB 0x06a3 #define DEVICEID_SRPTLP_SMB 0x9d23 /* ICH LPC Interface Bridge Registers (ICH5 and older) */ @@ -386,6 +390,9 @@ #define TCO_INTRD_SEL_INTR 0x0001 #define TCO_INTRD_SEL_SMI 0x0002 +/* default ACPI Base values */ +#define ACPI_DEFAULT_CANNON 0x1800 + /* * Masks for the TCO timer value field in TCO_RLD. * If the datasheets are to be believed, the minimum value actually varies @@ -408,4 +415,11 @@ */ #define ICHWD_TCO_V3_TICK 1000000000 +/* + * Quirks + */ + +/* On Cannon Lake and Commet Lake PHCs, the PMC is hidden */ +#define PMC_HIDDEN (1 << 0) + #endif diff --git a/sys/dev/ichwd/ichwd.c b/sys/dev/ichwd/ichwd.c --- a/sys/dev/ichwd/ichwd.c +++ b/sys/dev/ichwd/ichwd.c @@ -296,6 +296,9 @@ static struct ichwd_device ichwd_smb_devices[] = { { DEVICEID_LEWISBURG_SMB, "Lewisburg watchdog timer", 10, 4 }, + { DEVICEID_LEWISBURG_SMB_SSKU, "Lewisburg watchdog timer", 10, 4 }, + { DEVICEID_CANNON_SMB, "Cannon Lake watchdog timer", 10, 4, PMC_HIDDEN}, + { DEVICEID_COMET_SMB, "Comet Lake watchdog timer", 10, 4, PMC_HIDDEN}, { DEVICEID_SRPTLP_SMB, "Sunrise Point-LP watchdog timer", 10, 4 }, { DEVICEID_C3000, "Intel Atom C3000 watchdog timer", 10, 4 }, { 0, NULL, 0, 0 }, @@ -788,13 +791,23 @@ isab = device_get_parent(device_get_parent(dev)); pmdev = pci_find_dbsf(pci_get_domain(isab), pci_get_bus(isab), 31, 2); if (pmdev == NULL) { - device_printf(dev, "unable to find Power Management device\n"); - return (ENXIO); - } - acpi_base = pci_read_config(pmdev, ICH_PMBASE, 4) & 0xffffff00; - if (acpi_base == 0) { - device_printf(dev, "ACPI base address is not set\n"); - return (ENXIO); + if (id_p->quirks & PMC_HIDDEN) { + /* + * Since the PMC is hidden, we take the default value for the + * given device, which happens to be the same for the ones we + * support. + */ + acpi_base = ACPI_DEFAULT_CANNON; + } else { + device_printf(dev, "unable to find Power Management device\n"); + return (ENXIO); + } + } else { + acpi_base = pci_read_config(pmdev, ICH_PMBASE, 4) & 0xffffff00; + if (acpi_base == 0) { + device_printf(dev, "ACPI base address is not set\n"); + return (ENXIO); + } } /* Allocate SMI control I/O register space. */