|
// 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; |
|
} |
|
} |
Yeah, because then your service will just fail. The problem is the other way around, you having PawnIO loaded will make it fail loading when installing the proper one, so after closing your app it won’t be running anymore until a reboot. It is less of a real problem for instant things like this, but something more persistent like LHM would cause issues.
Yeah, the modules are LGPL 2.1 as stated in their header. That lets them link against proprietary things (PawnIO official builds) as well as GPL 2 (PawnIO OSS). LGPL 2.1 grants you the permission to redistribute as long as source is made accessible or provided on request and license stuff is included (read the full license for accurate description)