amdsbwd: fix reboot status reporting

Originally, I overlooked that PMIO register 0xc0 has a dual personality.
It can either be S5/Reset Status register or Misc. Fix register (aka
debug status register).  The mode is controlled by bit 2 in PMIO
register 0xc4.  Apparently there are register programming requirements
for the second personality, so many BIOSes leave the register, after
programming it, in that mode.  So, we need to switch the register to the
correct mode.

Additionally, AMDSB8_WD_RST_STS was defined incorrectly as bit 13 while
it is actually bit 25 (and the register's width is 32 bits, not 16).

With this change I see the following in dmesg after a reset by the
watchdog:
amdsbwd0: ResetStatus = 0x42000000
amdsbwd0: Previous Reset was caused by Watchdog

MFC after:	2 weeks
This commit is contained in:
avg 2018-05-05 05:22:11 +00:00
parent 8fe6ebebfd
commit 79db40ce37
2 changed files with 18 additions and 10 deletions

View File

@ -95,9 +95,10 @@
#define AMDSB8_WDT_32KHZ 0x00
#define AMDSB8_WDT_1HZ 0x03
#define AMDSB8_WDT_RES_MASK 0x03
#define AMDSB8_PM_RESET_STATUS0 0xc0
#define AMDSB8_PM_RESET_STATUS1 0xc1
#define AMDSB8_WD_RST_STS 0x20
#define AMDSB8_PM_RESET_STATUS 0xc0 /* 32 bit wide */
#define AMDSB8_WD_RST_STS 0x2000000
#define AMDSB8_PM_RESET_CTRL 0xc4
#define AMDSB8_RST_STS_DIS 0x04
/*
* Newer FCH registers in the PMIO space.

View File

@ -321,16 +321,23 @@ amdsbwd_probe_sb7xx(device_t dev, struct resource *pmres, uint32_t *addr)
static void
amdsbwd_probe_sb8xx(device_t dev, struct resource *pmres, uint32_t *addr)
{
uint8_t val;
int i;
uint32_t val;
int i;
/* Report cause of previous reset for user's convenience. */
val = pmio_read(pmres, AMDSB8_PM_RESET_STATUS0);
val = pmio_read(pmres, AMDSB8_PM_RESET_CTRL);
if ((val & AMDSB8_RST_STS_DIS) != 0) {
val &= ~AMDSB8_RST_STS_DIS;
pmio_write(pmres, AMDSB8_PM_RESET_CTRL, val);
}
val = 0;
for (i = 3; i >= 0; i--) {
val <<= 8;
val |= pmio_read(pmres, AMDSB8_PM_RESET_STATUS + i);
}
if (val != 0)
amdsbwd_verbose_printf(dev, "ResetStatus0 = %#04x\n", val);
val = pmio_read(pmres, AMDSB8_PM_RESET_STATUS1);
if (val != 0)
amdsbwd_verbose_printf(dev, "ResetStatus1 = %#04x\n", val);
amdsbwd_verbose_printf(dev, "ResetStatus = 0x%08x\n", val);
if ((val & AMDSB8_WD_RST_STS) != 0)
device_printf(dev, "Previous Reset was caused by Watchdog\n");