diff --git a/docs/BRINGUP.md b/docs/BRINGUP.md index c15cde8..c77d5f3 100644 --- a/docs/BRINGUP.md +++ b/docs/BRINGUP.md @@ -1264,8 +1264,12 @@ is committed. 115200, the strings present in the fielded binary); the same adapter on the SoC console pins shows U-Boot at every normal boot and a console in the recovery image after a button-hold recovery from power-off. An oddity of - the watchdog reboot, recorded, not an open item. The kernel config now - carries CONFIG_WATCHDOG_SYSFS so the state is readable without /dev/mem. + the watchdog reboot, recorded, not an open item. The kernel config carries + CONFIG_WATCHDOG_SYSFS (identity, timeout, bootstatus). The sysfs `state` + reads `inactive`: it says whether a process holds the device, which none + does, the kernel's core feeds the hardware. The proof that WDOG1 is armed + is its own WCR (WDE set, a 60 s period), which `image.health` reads through + /dev/mem. ## Next work Open items only. Anything closed is in `CAMPAIGN-LOG.md`. Open items (bugs, diff --git a/forgetest/forgetest/suite/image.py b/forgetest/forgetest/suite/image.py index 66a65de..ced8f1f 100644 --- a/forgetest/forgetest/suite/image.py +++ b/forgetest/forgetest/suite/image.py @@ -1,7 +1,9 @@ """image.* - the post-flash health of the running image (always-required).""" import glob import gzip +import mmap import os +import struct import re import stat @@ -9,6 +11,23 @@ from ..catalog import test from .. import hw +WDOG1_BASE = 0x020BC000 # i.MX6 WDOG1; WCR is the 16-bit word at offset 0 + + +def _wdog1_wcr(): + """WDOG1's control register, read through /dev/mem (MMIO stays readable + under STRICT_DEVMEM), or None.""" + try: + with open("/dev/mem", "r+b") as f: + m = mmap.mmap(f.fileno(), 4096, offset=WDOG1_BASE) + try: + return struct.unpack_from("> 8) + 1) / 2.0 if wcr is not None else None ev["watchdog"] = wd ctx.log("watchdog0: %s", wd) - ctx.check(wd["state"] == "active", "watchdog0 is %r, expected active (armed by the bootloader, " - "fed by the kernel core)", wd["state"] or None) + ctx.check(wd["identity"], "watchdog0 has no sysfs view (CONFIG_WATCHDOG_SYSFS)") ctx.check(wd["timeout"] == "60", "watchdog0 timeout %r, expected 60 s", wd["timeout"] or None) + ctx.check(wcr is not None, "WDOG1 WCR unreadable through /dev/mem") + ctx.check(wd["wde"], "WDOG1 is not enabled (WCR %s): nothing resets a hung kernel", wd["wcr"]) + ctx.check(wd["period_s"] == 60.0, "WDOG1 period %s s (WCR %s), expected 60", wd["period_s"], wd["wcr"]) + ctx.check(wd["state"] == "inactive", "watchdog0 is %r: a process holds the device, which the image " + "does not do", wd["state"] or None) rel = _read("/proc/sys/kernel/osrelease", "").strip() ev["kernel_release"] = rel mods = manifest.platform.get("kernel_modules") or []