Skip to content

Instantly share code, notes, and snippets.

@Steve-Tech
Last active May 13, 2025 08:13
Show Gist options
  • Save Steve-Tech/100bf6958156fb7c4c5df122202c2d48 to your computer and use it in GitHub Desktop.
Save Steve-Tech/100bf6958156fb7c4c5df122202c2d48 to your computer and use it in GitHub Desktop.
Gets the reset reason on AMD systems

AMDResetStatus

This is a simple Windows exe to get the reset reason register on AMD systems.

The PawnIO driver is required to be installed, and you will need the AMDReset PawnIO module too.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
// AMDResetStatus.cpp : Gets the reset reason on AMD systems
//
// Parts copied from https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?id=b343579de7b250101e4ed6c354b4c1fa986973a7
#include <iostream>
#include <filesystem>
#include <fstream>
#include "Windows.h"
#include "PawnIOLib.h"
#define BIT(nr) (1UL << (nr))
constexpr const char* filename = "AMDReset.bin";
const char* const s5_reset_reason_txt[] = {
"thermal pin BP_THERMTRIP_L was tripped", // index 0
"power button was pressed for 4 seconds", // index 1
"shutdown pin was shorted", // index 2
nullptr, // index 3 (reserved)
"remote ASF power off command was received", // index 4
nullptr, // index 5 (reserved)
nullptr, // index 6 (reserved)
nullptr, // index 7 (reserved)
nullptr, // index 8 (reserved)
"internal CPU thermal limit was tripped", // index 9
nullptr, // index 10 (reserved)
nullptr, // index 11 (reserved)
nullptr, // index 12 (reserved)
nullptr, // index 13 (reserved)
nullptr, // index 14 (pmeturnofftime)
nullptr, // index 15 (pmeturnofftime)
"system reset pin BP_SYS_RST_L was tripped", // index 16
"software issued PCI reset", // index 17
"software wrote 0x4 (init) to reset control register 0xCF9", // index 18
"software wrote 0x6 (warm reset) to reset control register 0xCF9", // index 19
"software wrote 0xE (cold reset) to reset control register 0xCF9", // index 20
"ACPI power state transition occurred", // index 21
"keyboard reset pin KB_RST_L was asserted", // index 22
"internal CPU shutdown event occurred", // index 23
"system failed to boot before failed boot timer expired", // index 24
"hardware watchdog timer expired", // index 25
"remote ASF reset command was received", // index 26
"an uncorrected error caused a data fabric sync flood event", // index 27
nullptr, // index 28 (reserved)
"FCH and MP1 failed warm reset handshake", // index 29
"a parity error occurred", // index 30
"a software sync flood event occurred" // index 31
};
int main()
{
HRESULT status;
HANDLE handle;
status = pawnio_open(&handle);
if (status != S_OK) {
if (status == E_ACCESSDENIED) {
fprintf(stderr, "Error Opening PawnIO: Permission Denied (%x)\n", status);
} else {
fprintf(stderr, "Error Opening PawnIO: (%x)\n", status);
}
return status;
}
if (!std::filesystem::exists(filename)) {
fprintf(stderr, "Error Loading PawnIO Driver: Failed to find %s\n", filename);
return status;
}
std::ifstream file(filename, std::ios::binary);
if (!file.is_open()) {
fprintf(stderr, "Error Loading PawnIO Driver: Failed to open %s\n", filename);
return ERROR_OPEN_FAILED;
}
std::vector<char> blob((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
file.close();
status = pawnio_load(handle, reinterpret_cast<const UCHAR*>(blob.data()), blob.size());
if (status != S_OK)
{
fprintf(stderr, "Error Loading PawnIO Driver: Failed to load %s (%x)\n", filename, status);
return status;
}
ULONG64 out;
SIZE_T return_size;
status = pawnio_execute(handle, "ioctl_amd_reset_status", NULL, 0, &out, 1, &return_size);
if (status != S_OK)
{
fprintf(stderr, "Error Executing PawnIO Driver: (%x)\n", status);
return status;
}
ULONG32 value = (ULONG32)out;
printf("Previous system reset reason [0x%08lx]\n", value);
for (size_t i = 0; i < 32; i++) {
if (!(value & BIT(i)))
continue;
if (s5_reset_reason_txt[i])
printf("%s\n", s5_reset_reason_txt[i]);
}
status = pawnio_close(handle);
if (status != S_OK)
{
fprintf(stderr, "Error Closing PawnIO: (%x)\n", status);
return status;
}
}
@Steve-Tech
Copy link
Author

I'm not sure if it'd be legal to redistribute the official PawnIO build with it

Yeah that's fine, I have no intention of redistributing PawnIO with it, a download link to pawnio.eu is what I've doing. It was just 'AMDResetStatus.zip' I made without thinking things though.

That is unless 'official PawnIO build' includes the signed modules by themselves.

you can say you used the LGPL 2.1 converted to GPL 2 for implementing the YAFI-side, but it happens to work with the proprietary one as well

Oh cool, I guess the "System Library" loophole also works, since PawnIO isn't being included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment