Skip to content

Commit 7ed292e

Browse files
fyin1lijinxia
authored andcommitted
DM: extend i6300esb device to support watchdog timeout query
6300esb has bit in its register to show whether the watchdog timeout is hit. This patch adds this bit support. So the guest could query whether last reset is triggered by watchdog reset. Signed-off-by: Yin Fengwei <fengwei.yin@intel.com> Reviewed-by: Cao Minggui <minggui.cao@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com> Tested-by: Binbin Wu <binbin.wu@intel.com>
1 parent 1f54b92 commit 7ed292e

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

devicemodel/core/sw_load_vsbl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ struct vsbl_para {
9999
uint64_t bootargs_address;
100100
uint32_t trusty_enabled;
101101
uint32_t key_info_lock;
102-
uint32_t watchdog_reset;
102+
uint32_t reserved;
103103
uint32_t boot_device_address;
104104
};
105105

devicemodel/hw/pci/wdt_i6300esb.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040

4141
#define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */
4242
#define ESB_WDT_RELOAD (0x01 << 8) /* Ping/kick dog */
43+
#define ESB_WDT_TIMEOUT (0x01 << 9) /* WDT timeout happened? */
4344
#define TIMER_TO_SECONDS(val) (val >> 9)
4445

4546
/* Magic constants */
@@ -75,6 +76,11 @@ struct info_wdt {
7576
int unlock_state; /* unlock states 0 -> 1 -> 2 */
7677
};
7778

79+
/* Whether watchdog is timeout. This info should cross reset. So
80+
* we didn't add to struct info_wdt.
81+
*/
82+
static int wdt_timeout = 0;
83+
7884
static struct info_wdt wdt_state;
7985

8086
static void start_wdt_timer(void);
@@ -95,6 +101,9 @@ wdt_expired_thread(union sigval v)
95101
start_wdt_timer();
96102
} else {
97103
if (wdt_state.reboot_enabled) {
104+
wdt_state.stage = 1;
105+
wdt_timeout = 1;
106+
98107
/* watchdog timer out, set the uos to reboot */
99108
vm_set_suspend_mode(VM_SUSPEND_RESET);
100109
mevent_notify();
@@ -264,10 +273,18 @@ pci_wdt_bar_write(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
264273
else if ((value == ESB_UNLOCK2)
265274
&& (wdt_state.unlock_state == 1))
266275
wdt_state.unlock_state = 2;
267-
else if ((wdt_state.unlock_state == 2)
268-
&& (value & ESB_WDT_RELOAD)) {
269-
wdt_state.stage = 1;
270-
start_wdt_timer();
276+
else if (wdt_state.unlock_state == 2) {
277+
if (value & ESB_WDT_RELOAD) {
278+
wdt_state.stage = 1;
279+
start_wdt_timer();
280+
}
281+
282+
/* write ES_WDT_TIMEOUT bit clear wdt timeout */
283+
if (value & ESB_WDT_TIMEOUT) {
284+
DPRINTF("%s: timeout cleaned\n\r", __func__);
285+
wdt_timeout = 0;
286+
}
287+
271288
wdt_state.unlock_state = 0;
272289
}
273290
} else if (wdt_state.unlock_state == 2) {
@@ -284,10 +301,23 @@ uint64_t
284301
pci_wdt_bar_read(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
285302
int baridx, uint64_t offset, int size)
286303
{
304+
uint64_t ret = 0;
305+
287306
assert(baridx == 0);
288-
DPRINTF("%s: addr = 0x%x, size=%d\n", __func__, (int) offset, size);
307+
DPRINTF("%s: addr = 0x%x, size=%d\n\r", __func__, (int) offset, size);
289308

290-
return 0;
309+
if (offset == ESB_RELOAD_REG) {
310+
assert(size == 2);
311+
312+
DPRINTF("%s: timeout: %d\n\r", __func__, wdt_timeout);
313+
if (wdt_timeout != 0)
314+
ret |= ESB_WDT_TIMEOUT;
315+
316+
if (wdt_state.stage == 1)
317+
ret |= ESB_WDT_RELOAD;
318+
}
319+
320+
return ret;
291321
}
292322

293323
static int

0 commit comments

Comments
 (0)