From: Mario Limonciello <superm1@kernel.org>
To: Borislav Petkov <bp@alien8.de>
Cc: Jonathan Corbet <corbet@lwn.net>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org (maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)),
"H . Peter Anvin" <hpa@zytor.com>,
linux-doc@vger.kernel.org (open list:DOCUMENTATION),
linux-kernel@vger.kernel.org (open list),
Yazen Ghannam <yazen.ghannam@amd.com>,
Mario Limonciello <mario.limonciello@amd.com>
Subject: [PATCH 2/2] x86/CPU/AMD: Print the reason for the last reset
Date: Mon, 7 Apr 2025 11:25:25 -0500 [thread overview]
Message-ID: <20250407162525.1357673-2-superm1@kernel.org> (raw)
In-Reply-To: <20250407162525.1357673-1-superm1@kernel.org>
From: Yazen Ghannam <yazen.ghannam@amd.com>
The following register contains bits that indicate the cause for the
previous reset.
PMx000000C0 (FCH::PM::S5_RESET_STATUS)
This is useful for debug. The reasons for reset are broken into 6 high
level categories. Decode it by category and print during boot.
Specifics within a category are split off into debugging documentation.
The register is accessed indirectly through a "PM" port in the FCH. Use
MMIO access in order to avoid restrictions with legacy port access.
Use a late_initcall() to ensure that MMIO has been set up before trying
to access the register.
This register was introduced with AMD Family 17h, so avoid access on
older families. There is no CPUID feature bit for this register.
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
Co-developed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
.../admin-guide/amd/amd-reboot-reason.csv | 21 ++++++++
Documentation/admin-guide/amd/debugging.rst | 22 ++++++++
arch/x86/kernel/cpu/amd.c | 50 +++++++++++++++++++
3 files changed, 93 insertions(+)
create mode 100644 Documentation/admin-guide/amd/amd-reboot-reason.csv
diff --git a/Documentation/admin-guide/amd/amd-reboot-reason.csv b/Documentation/admin-guide/amd/amd-reboot-reason.csv
new file mode 100644
index 0000000000000..c31c7a0464c38
--- /dev/null
+++ b/Documentation/admin-guide/amd/amd-reboot-reason.csv
@@ -0,0 +1,21 @@
+Bit, Type, Reason
+0, Pin, Thermal trip (BP_THERMTRIP_L)
+1, Pin, Power button
+2, Pin, SHUTDOWN# pin
+4, Remote, Remote ASF power off command
+9, Internal, Thermal trip (internal)
+16, Pin, User reset (BP_SYS_RST_L)
+17, Software, PCI reset (PMIO 0xC4)
+18, Software, CF9 reset (0x04)
+19, Software, CF9 reset (0x06)
+20, Software, CF9 reset (0x0E)
+21, Sleep, Power state or ACPI state transition
+22, Pin, Keyboard reset (KB_RST_L)
+23, Internal, Internal CPU shutdown
+24, Hardware, Failed boot timer
+25, Hardware, Watchdog timer
+26, Remote, Remote ASF reset command
+27, Internal, Data fabric sync flood event due to uncorrected error
+29, Internal, MP1 Watchdog timer timeout
+30, Internal, Parity error
+31, Internal, SW sync flood event
\ No newline at end of file
diff --git a/Documentation/admin-guide/amd/debugging.rst b/Documentation/admin-guide/amd/debugging.rst
index 5a721ab4fe013..2a966f0ead26a 100644
--- a/Documentation/admin-guide/amd/debugging.rst
+++ b/Documentation/admin-guide/amd/debugging.rst
@@ -268,3 +268,25 @@ EPP Policy
The ``energy_performance_preference`` sysfs file can be used to set a bias
of efficiency or performance for a CPU. This has a direct relationship on
the battery life when more heavily biased towards performance.
+
+Random reboot issues
+====================
+When a random reboot occurs, the high-level reason for the reboot is stored
+in a register that will persist onto the next boot.
+
+There are 6 classes of reasons for the reboot:
+ * Software induced
+ * Power state transition
+ * Pin induced
+ * Hardware induced
+ * Remote reset
+ * Internal CPU event
+
+.. csv-table::
+ :header-rows: 1
+ :widths: 1, 1, 1
+ :file: ./amd-reboot-reason.csv
+
+This information is read by the kernel at bootup and is saved into the
+kernel ring buffer. When a random reboot occurs this message can be helpful
+to determine the next component to debug such an issue.
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 79569f72b8ee5..bb187c46a6a71 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -1231,3 +1231,53 @@ void amd_check_microcode(void)
if (cpu_feature_enabled(X86_FEATURE_ZEN2))
on_each_cpu(zenbleed_check_cpu, NULL, 1);
}
+
+#define PIN_RESET (BIT(0) | BIT(1) | BIT(2) | BIT(16) | BIT(22))
+#define REMOTE_RESET (BIT(4) | BIT(26))
+#define INTERNAL_RESET (BIT(9) | BIT(23) | BIT(27) | BIT(29) | BIT(30) | BIT(31))
+#define SW_RESET (BIT(17) | BIT(18) | BIT(19) | BIT(20))
+#define HW_RESET (BIT(24) | BIT(25))
+#define SLEEP_RESET (BIT(21))
+
+static inline char *get_s5_reset_reason(u32 value)
+{
+ if (value & SW_RESET)
+ return "software";
+ if (value & SLEEP_RESET)
+ return "power state transition";
+ if (value & PIN_RESET)
+ return "pin state change";
+ if (value & HW_RESET)
+ return "hardware";
+ if (value & REMOTE_RESET)
+ return "remote power event";
+ if (value & INTERNAL_RESET)
+ return "internal CPU error";
+ return "unknown reason";
+}
+
+static __init int print_s5_reset_status_mmio(void)
+{
+ void __iomem *addr;
+ u32 value;
+
+ if (!cpu_feature_enabled(X86_FEATURE_ZEN))
+ return 0;
+
+ /*
+ * FCH::PM::S5_RESET_STATUS
+ * PM Base = 0xFED80300
+ * S5_RESET_STATUS offset = 0xC0
+ */
+ addr = ioremap(0xFED803C0, sizeof(value));
+ if (!addr)
+ return 0;
+ value = ioread32(addr);
+ iounmap(addr);
+
+ pr_info("System reset was due to %s (0x%08x)\n",
+ get_s5_reset_reason(value), value);
+
+ return 0;
+}
+late_initcall(print_s5_reset_status_mmio);
--
2.43.0
next prev parent reply other threads:[~2025-04-07 16:25 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-07 16:25 [PATCH 1/2] Documentation: Add AMD Zen debugging document Mario Limonciello
2025-04-07 16:25 ` Mario Limonciello [this message]
2025-04-07 18:46 ` [PATCH 2/2] x86/CPU/AMD: Print the reason for the last reset Ingo Molnar
2025-04-07 18:56 ` Mario Limonciello
2025-04-07 19:04 ` Ingo Molnar
2025-04-07 21:46 ` Borislav Petkov
2025-04-08 7:09 ` Ingo Molnar
2025-04-08 7:17 ` Ingo Molnar
2025-04-08 15:45 ` Dave Hansen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250407162525.1357673-2-superm1@kernel.org \
--to=superm1@kernel.org \
--cc=bp@alien8.de \
--cc=corbet@lwn.net \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mario.limonciello@amd.com \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
--cc=yazen.ghannam@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).