summaryrefslogtreecommitdiff
path: root/src/soc/intel/common/block/smbus/tco.c
diff options
context:
space:
mode:
authorMarek Maslanka <mmaslanka@google.com>2024-01-12 07:24:21 +0000
committerJakub Czapiga <czapiga@google.com>2024-03-12 13:01:13 +0000
commit531c45e075c3d2f1bb0ba81df3d53acb92499229 (patch)
treeb42c840d3b8770c0c91368909977921601aec6af /src/soc/intel/common/block/smbus/tco.c
parenta0b7c06d07813af1484f3a90e9dc37cc4d041fa4 (diff)
soc/intel/common/block: Add support for watchdog
Implement watchdog for intel based platform by filling ACPI Watchdog Action Table (WDAT) table. The WDAT ACPI table encompasses essential watchdog functions, including: - Setting and retrieving countdown/timeout values - Starting and stopping the watchdog - Pinging the watchdog - Retrieving the cause of the last reboot, whether it was triggered by the watchdog or another reason The general purpose register TCO_MESSAGE1 stores the reason for the most recent reboot rather than the original register TCO2_STS. This is because the firmware must clear TCO2_STS, and it can't be reused for storing this information for the operating system. The watchdog is designed for use by the OS through certain defined actions in the WDAT table. It relies on the ACPI Power Management Timer, which may result in an increase in power consumption. BUG=b:314260167 TEST=Enable CONFIG_ACPI_WDAT_WDT and CONFIG_USE_PM_ACPI_TIMER in the config. Enable CONFIG_WDAT_WDT in the kernel config. Build and deploy both firmware and kernel to the device. Trigger the watchdog by performing the command: “cat > /dev/watchdog”. Wait approximately 30 seconds for the watchdog to reset the device. Change-Id: Iaf7971f8407920a553fd91d2ed04193c882e08f1 Signed-off-by: Marek Maslanka <mmaslanka@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/79909 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Subrata Banik <subratabanik@google.com>
Diffstat (limited to 'src/soc/intel/common/block/smbus/tco.c')
-rw-r--r--src/soc/intel/common/block/smbus/tco.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/soc/intel/common/block/smbus/tco.c b/src/soc/intel/common/block/smbus/tco.c
index 904534393d..ef7ef07d3f 100644
--- a/src/soc/intel/common/block/smbus/tco.c
+++ b/src/soc/intel/common/block/smbus/tco.c
@@ -22,8 +22,11 @@
#define TCO_BASE_EN (1 << 8)
#define TCO_BASE_LOCK (1 << 0)
-/* Get base address of TCO I/O registers. */
-static uint16_t tco_get_bar(void)
+#define TCO_TMR_MIN_VALUE 2
+#define TCO_TMR_MAX_VALUE 1023
+#define TCO_TMR_PERIOD_MS 600
+
+uint16_t tco_get_bar(void)
{
return TCO_BASE_ADDRESS;
}
@@ -73,6 +76,9 @@ uint32_t tco_reset_status(void)
tco2_sts = tco_read_reg(TCO2_STS);
tco_write_reg(TCO2_STS, tco2_sts | TCO2_STS_SECOND_TO);
+ if (CONFIG(ACPI_WDAT_WDT))
+ tco_write_reg(TCO_MESSAGE1, tco2_sts & TCO2_STS_SECOND_TO);
+
return (tco2_sts << 16) | tco1_sts;
}
@@ -137,3 +143,18 @@ void tco_configure(void)
if (CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE))
tco_intruder_smi_enable();
}
+
+uint32_t tco_get_timer_period(void)
+{
+ return TCO_TMR_PERIOD_MS;
+}
+
+uint32_t tco_get_timer_min_value(void)
+{
+ return TCO_TMR_MIN_VALUE;
+}
+
+uint32_t tco_get_timer_max_value(void)
+{
+ return TCO_TMR_MAX_VALUE;
+}