From e10546a7e3ce018d660ec40f7652daa921e29381 Mon Sep 17 00:00:00 2001 From: James Hughes Date: Tue, 28 Jul 2026 16:31:35 +0100 Subject: [PATCH 1/2] Add rpipmic --- README.md | 1 + rpipmic/README.md | 8 +++++++ rpipmic/rpipmic | 61 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 rpipmic/README.md create mode 100644 rpipmic/rpipmic diff --git a/README.md b/README.md index 46c9ea4..802a775 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ A collection of scripts and simple applications * [rpifwcrypto](rpifwcrypto/) - A command line application and shared library for the firmware cryptography service. Intended for use with Raspberry Pi Connect and secure-boot provisioner. +* [rpipmic](rpipmic/) - A command line utility to report any stored PMIC events. * [rpi-gpu-usage](rpi-gpu-usage/) - A tool for showing the per-process usage of the V3D GPU on Raspberry Pi 4 and 5. * [vcgencmd](vcgencmd/) - A tool to send commands to the VideoCore firmware and diff --git a/rpipmic/README.md b/rpipmic/README.md new file mode 100644 index 0000000..fb6c373 --- /dev/null +++ b/rpipmic/README.md @@ -0,0 +1,8 @@ + +# rpipmic + +Tool to fetch PMIC stored events. + +Uses vcgencmd to recover PMIC register 0x3018 and makes the results human +readable + diff --git a/rpipmic/rpipmic b/rpipmic/rpipmic new file mode 100644 index 0000000..77fd307 --- /dev/null +++ b/rpipmic/rpipmic @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# +# Reads the PMIC EVT status register via vcgencmd and reports any +# error events that are currently latched (RW1C bits). +# +# Usage: ./rpipmic + +set -euo pipefail + +REG_ADDR="0x3018" + +# bit -> "NAME:description" for the EVT register at REG_ADDR +EVENTS=( + "0:EVT_PB_SHORT_PRESS: short press on the power button was detected" + "1:EVT_OVERTEMP_WARN: over-temperature warning" + "2:EVT_OVERTEMP_RESET: over-temperature reset occurred" + "3:EVT_WDT_RESET: watchdog timer timed out" + "4:EVT_ENABLE_LOW: chip reset/halt caused by a low on the ENABLE pin" + "5:EVT_UVLO_WARN: supply voltage fell below the warning threshold" + "6:EVT_UVLO_SHUT: last shutdown was caused by supply voltage falling below the critical threshold" + "7:EVT_VDD_SNS_OV: over-voltage detected on the VDD_SNS pin" +) + +if ! command -v vcgencmd >/dev/null 2>&1; then + echo "error: vcgencmd not found (this script must run on a Raspberry Pi)" >&2 + exit 1 +fi + +raw_output=$(vcgencmd pmicrd "$REG_ADDR") + +# expected form: "[3018] = 00" +hex_value=$(echo "$raw_output" | awk -F'=' '{print $2}' | tr -d '[:space:]') +hex_value=${hex_value#0x} + +if [[ -z "$hex_value" || ! "$hex_value" =~ ^[0-9a-fA-F]+$ ]]; then + echo "error: could not parse vcgencmd output: '$raw_output'" >&2 + exit 1 +fi + +reg_value=$((16#$hex_value)) + +echo "PMIC EVT register ($REG_ADDR) = 0x$(printf '%02x' "$reg_value")" + +error_found=0 +for entry in "${EVENTS[@]}"; do + bit="${entry%%:*}" + rest="${entry#*:}" + name="${rest%%:*}" + desc="${rest#*:}" + + if (( (reg_value >> bit) & 1 )); then + echo " [ERROR] $name -$desc" + error_found=1 + fi +done + +if (( error_found == 0 )); then + echo " No error events detected." +fi + +exit "$error_found" From b08016244bd99624c7371208be7966fdb6aef38b Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Fri, 13 Nov 2026 15:43:15 +0000 Subject: [PATCH 2/2] rpipmic: Report power_reset from device tree and check for Pi 5 The bootloader clears fatal PMIC events at power on, so read the reset reason from /proc/device-tree/chosen/power/power_reset. Refuse to run on anything other than BCM2712 as the PMIC is Pi 5 specific, and treat the vcgencmd pmicrd read as optional since it may be removed. --- rpipmic/README.md | 11 +++--- rpipmic/rpipmic | 90 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 71 insertions(+), 30 deletions(-) diff --git a/rpipmic/README.md b/rpipmic/README.md index fb6c373..952632e 100644 --- a/rpipmic/README.md +++ b/rpipmic/README.md @@ -1,8 +1,9 @@ - # rpipmic -Tool to fetch PMIC stored events. - -Uses vcgencmd to recover PMIC register 0x3018 and makes the results human -readable +Tool to report PMIC events on Raspberry Pi 5 family devices (Pi 5, Pi 500, +CM5). +The bootloader clears fatal PMIC events at power on, so the reason for the +last PMIC reset is read from /proc/device-tree/chosen/power/power_reset. +Events latched since boot are read from PMIC register 0x3018 using vcgencmd, +if available. diff --git a/rpipmic/rpipmic b/rpipmic/rpipmic index 77fd307..231d4f6 100644 --- a/rpipmic/rpipmic +++ b/rpipmic/rpipmic @@ -1,14 +1,28 @@ #!/usr/bin/env bash # -# Reads the PMIC EVT status register via vcgencmd and reports any -# error events that are currently latched (RW1C bits). +# Reports PMIC events on Raspberry Pi 5 (BCM2712) family devices. +# +# The bootloader clears fatal PMIC events at power on and passes them on in +# /proc/device-tree/chosen/power/power_reset. Events latched since boot are +# read from the PMIC EVT status register via vcgencmd, if available. # # Usage: ./rpipmic set -euo pipefail +DT=/proc/device-tree +POWER_RESET="$DT/chosen/power/power_reset" REG_ADDR="0x3018" +# bit -> "NAME:description" for power_reset +RESET_REASONS=( + "0:OVER_VOLTAGE: over voltage" + "1:UNDER_VOLTAGE: under voltage" + "2:OVER_TEMPERATURE: over temperature" + "3:ENABLE: chip reset/halt caused by a low on the ENABLE pin" + "4:WATCHDOG: watchdog timer timed out" +) + # bit -> "NAME:description" for the EVT register at REG_ADDR EVENTS=( "0:EVT_PB_SHORT_PRESS: short press on the power button was detected" @@ -21,41 +35,67 @@ EVENTS=( "7:EVT_VDD_SNS_OV: over-voltage detected on the VDD_SNS pin" ) -if ! command -v vcgencmd >/dev/null 2>&1; then - echo "error: vcgencmd not found (this script must run on a Raspberry Pi)" >&2 +error_found=0 + +report_bits() { + local value=$1 + shift + local entry bit rest name desc found=0 + + for entry in "$@"; do + bit="${entry%%:*}" + rest="${entry#*:}" + name="${rest%%:*}" + desc="${rest#*:}" + + if (( (value >> bit) & 1 )); then + echo " [ERROR] $name -$desc" + found=1 + fi + done + + if (( found )); then + error_found=1 + else + echo " No error events detected." + fi +} + +if ! tr '\0' '\n' < "$DT/compatible" 2>/dev/null | grep -qx 'brcm,bcm2712'; then + echo "error: this tool only supports the Raspberry Pi 5 family PMIC" >&2 exit 1 fi -raw_output=$(vcgencmd pmicrd "$REG_ADDR") +if [[ -r "$POWER_RESET" ]]; then + reset_value=0 + for byte in $(od -An -v -tu1 "$POWER_RESET"); do + reset_value=$(( (reset_value << 8) | byte )) + done + echo "PMIC reset reason at power on ($POWER_RESET) = 0x$(printf '%08x' "$reset_value")" + report_bits "$reset_value" "${RESET_REASONS[@]}" +else + echo "warning: $POWER_RESET not found (bootloader too old?)" >&2 +fi + +if ! command -v vcgencmd >/dev/null 2>&1; then + echo "warning: vcgencmd not found, skipping PMIC EVT register" >&2 + exit "$error_found" +fi + +raw_output=$(vcgencmd pmicrd "$REG_ADDR" 2>&1 || true) # expected form: "[3018] = 00" hex_value=$(echo "$raw_output" | awk -F'=' '{print $2}' | tr -d '[:space:]') hex_value=${hex_value#0x} if [[ -z "$hex_value" || ! "$hex_value" =~ ^[0-9a-fA-F]+$ ]]; then - echo "error: could not parse vcgencmd output: '$raw_output'" >&2 - exit 1 + echo "warning: could not read PMIC EVT register: '$raw_output'" >&2 + exit "$error_found" fi reg_value=$((16#$hex_value)) -echo "PMIC EVT register ($REG_ADDR) = 0x$(printf '%02x' "$reg_value")" - -error_found=0 -for entry in "${EVENTS[@]}"; do - bit="${entry%%:*}" - rest="${entry#*:}" - name="${rest%%:*}" - desc="${rest#*:}" - - if (( (reg_value >> bit) & 1 )); then - echo " [ERROR] $name -$desc" - error_found=1 - fi -done - -if (( error_found == 0 )); then - echo " No error events detected." -fi +echo "PMIC EVT register since boot ($REG_ADDR) = 0x$(printf '%02x' "$reg_value")" +report_bits "$reg_value" "${EVENTS[@]}" exit "$error_found"