wdt_i6300esb.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. /*
  2. * Virtual hardware watchdog.
  3. *
  4. * Copyright (C) 2009 Red Hat Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  18. *
  19. * By Richard W.M. Jones (rjones@redhat.com).
  20. */
  21. #include "qemu/osdep.h"
  22. #include "qemu/module.h"
  23. #include "qemu/timer.h"
  24. #include "system/watchdog.h"
  25. #include "hw/pci/pci_device.h"
  26. #include "migration/vmstate.h"
  27. #include "qom/object.h"
  28. /*#define I6300ESB_DEBUG 1*/
  29. #ifdef I6300ESB_DEBUG
  30. #define i6300esb_debug(fs,...) \
  31. fprintf(stderr,"i6300esb: %s: "fs,__func__,##__VA_ARGS__)
  32. #else
  33. #define i6300esb_debug(fs,...)
  34. #endif
  35. /* PCI configuration registers */
  36. #define ESB_CONFIG_REG 0x60 /* Config register */
  37. #define ESB_LOCK_REG 0x68 /* WDT lock register */
  38. /* Memory mapped registers (offset from base address) */
  39. #define ESB_TIMER1_REG 0x00 /* Timer1 value after each reset */
  40. #define ESB_TIMER2_REG 0x04 /* Timer2 value after each reset */
  41. #define ESB_GINTSR_REG 0x08 /* General Interrupt Status Register */
  42. #define ESB_RELOAD_REG 0x0c /* Reload register */
  43. /* Lock register bits */
  44. #define ESB_WDT_FUNC (0x01 << 2) /* Watchdog functionality */
  45. #define ESB_WDT_ENABLE (0x01 << 1) /* Enable WDT */
  46. #define ESB_WDT_LOCK (0x01 << 0) /* Lock (nowayout) */
  47. /* Config register bits */
  48. #define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */
  49. #define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */
  50. #define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */
  51. /* Reload register bits */
  52. #define ESB_WDT_RELOAD (0x01 << 8) /* prevent timeout */
  53. /* Magic constants */
  54. #define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */
  55. #define ESB_UNLOCK2 0x86 /* Step 2 to unlock reset registers */
  56. /* Device state. */
  57. struct I6300State {
  58. PCIDevice dev;
  59. MemoryRegion io_mem;
  60. int reboot_enabled; /* "Reboot" on timer expiry. The real action
  61. * performed depends on the -watchdog-action
  62. * param passed on QEMU command line.
  63. */
  64. int clock_scale; /* Clock scale. */
  65. #define CLOCK_SCALE_1KHZ 0
  66. #define CLOCK_SCALE_1MHZ 1
  67. int int_type; /* Interrupt type generated. */
  68. #define INT_TYPE_IRQ 0 /* APIC 1, INT 10 */
  69. #define INT_TYPE_SMI 2
  70. #define INT_TYPE_DISABLED 3
  71. int free_run; /* If true, reload timer on expiry. */
  72. int locked; /* If true, enabled field cannot be changed. */
  73. int enabled; /* If true, watchdog is enabled. */
  74. QEMUTimer *timer; /* The actual watchdog timer. */
  75. uint32_t timer1_preload; /* Values preloaded into timer1, timer2. */
  76. uint32_t timer2_preload;
  77. int stage; /* Stage (1 or 2). */
  78. int unlock_state; /* Guest writes 0x80, 0x86 to unlock the
  79. * registers, and we transition through
  80. * states 0 -> 1 -> 2 when this happens.
  81. */
  82. int previous_reboot_flag; /* If the watchdog caused the previous
  83. * reboot, this flag will be set.
  84. */
  85. };
  86. #define TYPE_WATCHDOG_I6300ESB_DEVICE "i6300esb"
  87. OBJECT_DECLARE_SIMPLE_TYPE(I6300State, WATCHDOG_I6300ESB_DEVICE)
  88. /* This function is called when the watchdog has either been enabled
  89. * (hence it starts counting down) or has been keep-alived.
  90. */
  91. static void i6300esb_restart_timer(I6300State *d, int stage)
  92. {
  93. int64_t timeout;
  94. if (!d->enabled)
  95. return;
  96. d->stage = stage;
  97. if (d->stage <= 1)
  98. timeout = d->timer1_preload;
  99. else
  100. timeout = d->timer2_preload;
  101. if (d->clock_scale == CLOCK_SCALE_1KHZ)
  102. timeout <<= 15;
  103. else
  104. timeout <<= 5;
  105. /* Get the timeout in nanoseconds. */
  106. timeout = timeout * 30; /* on a PCI bus, 1 tick is 30 ns*/
  107. i6300esb_debug("stage %d, timeout %" PRIi64 "\n", d->stage, timeout);
  108. timer_mod(d->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
  109. }
  110. /* This is called when the guest disables the watchdog. */
  111. static void i6300esb_disable_timer(I6300State *d)
  112. {
  113. i6300esb_debug("timer disabled\n");
  114. timer_del(d->timer);
  115. }
  116. static void i6300esb_reset(DeviceState *dev)
  117. {
  118. PCIDevice *pdev = PCI_DEVICE(dev);
  119. I6300State *d = WATCHDOG_I6300ESB_DEVICE(pdev);
  120. i6300esb_debug("I6300State = %p\n", d);
  121. i6300esb_disable_timer(d);
  122. /* NB: Don't change d->previous_reboot_flag in this function. */
  123. d->reboot_enabled = 1;
  124. d->clock_scale = CLOCK_SCALE_1KHZ;
  125. d->int_type = INT_TYPE_IRQ;
  126. d->free_run = 0;
  127. d->locked = 0;
  128. d->enabled = 0;
  129. d->timer1_preload = 0xfffff;
  130. d->timer2_preload = 0xfffff;
  131. d->stage = 1;
  132. d->unlock_state = 0;
  133. }
  134. /* This function is called when the watchdog expires. Note that
  135. * the hardware has two timers, and so expiry happens in two stages.
  136. * If d->stage == 1 then we perform the first stage action (usually,
  137. * sending an interrupt) and then restart the timer again for the
  138. * second stage. If the second stage expires then the watchdog
  139. * really has run out.
  140. */
  141. static void i6300esb_timer_expired(void *vp)
  142. {
  143. I6300State *d = vp;
  144. i6300esb_debug("stage %d\n", d->stage);
  145. if (d->stage == 1) {
  146. /* What to do at the end of stage 1? */
  147. switch (d->int_type) {
  148. case INT_TYPE_IRQ:
  149. fprintf(stderr, "i6300esb_timer_expired: I would send APIC 1 INT 10 here if I knew how (XXX)\n");
  150. break;
  151. case INT_TYPE_SMI:
  152. fprintf(stderr, "i6300esb_timer_expired: I would send SMI here if I knew how (XXX)\n");
  153. break;
  154. }
  155. /* Start the second stage. */
  156. i6300esb_restart_timer(d, 2);
  157. } else {
  158. /* Second stage expired, reboot for real. */
  159. if (d->reboot_enabled) {
  160. d->previous_reboot_flag = 1;
  161. watchdog_perform_action(); /* This reboots, exits, etc */
  162. i6300esb_reset(DEVICE(d));
  163. }
  164. /* In "free running mode" we start stage 1 again. */
  165. if (d->free_run)
  166. i6300esb_restart_timer(d, 1);
  167. }
  168. }
  169. static void i6300esb_config_write(PCIDevice *dev, uint32_t addr,
  170. uint32_t data, int len)
  171. {
  172. I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev);
  173. int old;
  174. i6300esb_debug("addr = %x, data = %x, len = %d\n", addr, data, len);
  175. if (addr == ESB_CONFIG_REG && len == 2) {
  176. d->reboot_enabled = (data & ESB_WDT_REBOOT) == 0;
  177. d->clock_scale =
  178. (data & ESB_WDT_FREQ) != 0 ? CLOCK_SCALE_1MHZ : CLOCK_SCALE_1KHZ;
  179. d->int_type = (data & ESB_WDT_INTTYPE);
  180. } else if (addr == ESB_LOCK_REG && len == 1) {
  181. if (!d->locked) {
  182. d->locked = (data & ESB_WDT_LOCK) != 0;
  183. d->free_run = (data & ESB_WDT_FUNC) != 0;
  184. old = d->enabled;
  185. d->enabled = (data & ESB_WDT_ENABLE) != 0;
  186. if (!old && d->enabled) /* Enabled transitioned from 0 -> 1 */
  187. i6300esb_restart_timer(d, 1);
  188. else if (!d->enabled)
  189. i6300esb_disable_timer(d);
  190. }
  191. } else {
  192. pci_default_write_config(dev, addr, data, len);
  193. }
  194. }
  195. static uint32_t i6300esb_config_read(PCIDevice *dev, uint32_t addr, int len)
  196. {
  197. I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev);
  198. uint32_t data;
  199. i6300esb_debug ("addr = %x, len = %d\n", addr, len);
  200. if (addr == ESB_CONFIG_REG && len == 2) {
  201. data =
  202. (d->reboot_enabled ? 0 : ESB_WDT_REBOOT) |
  203. (d->clock_scale == CLOCK_SCALE_1MHZ ? ESB_WDT_FREQ : 0) |
  204. d->int_type;
  205. return data;
  206. } else if (addr == ESB_LOCK_REG && len == 1) {
  207. data =
  208. (d->free_run ? ESB_WDT_FUNC : 0) |
  209. (d->locked ? ESB_WDT_LOCK : 0) |
  210. (d->enabled ? ESB_WDT_ENABLE : 0);
  211. return data;
  212. } else {
  213. return pci_default_read_config(dev, addr, len);
  214. }
  215. }
  216. static uint32_t i6300esb_mem_readb(void *vp, hwaddr addr)
  217. {
  218. i6300esb_debug ("addr = %x\n", (int) addr);
  219. return 0;
  220. }
  221. static uint32_t i6300esb_mem_readw(void *vp, hwaddr addr)
  222. {
  223. uint32_t data = 0;
  224. I6300State *d = vp;
  225. i6300esb_debug("addr = %x\n", (int) addr);
  226. if (addr == 0xc) {
  227. /* The previous reboot flag is really bit 9, but there is
  228. * a bug in the Linux driver where it thinks it's bit 12.
  229. * Set both.
  230. */
  231. data = d->previous_reboot_flag ? 0x1200 : 0;
  232. }
  233. return data;
  234. }
  235. static uint32_t i6300esb_mem_readl(void *vp, hwaddr addr)
  236. {
  237. i6300esb_debug("addr = %x\n", (int) addr);
  238. return 0;
  239. }
  240. static void i6300esb_mem_writeb(void *vp, hwaddr addr, uint32_t val)
  241. {
  242. I6300State *d = vp;
  243. i6300esb_debug("addr = %x, val = %x\n", (int) addr, val);
  244. if (addr == 0xc && val == 0x80)
  245. d->unlock_state = 1;
  246. else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
  247. d->unlock_state = 2;
  248. }
  249. static void i6300esb_mem_writew(void *vp, hwaddr addr, uint32_t val)
  250. {
  251. I6300State *d = vp;
  252. i6300esb_debug("addr = %x, val = %x\n", (int) addr, val);
  253. if (addr == 0xc && val == 0x80)
  254. d->unlock_state = 1;
  255. else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
  256. d->unlock_state = 2;
  257. else {
  258. if (d->unlock_state == 2) {
  259. if (addr == 0xc) {
  260. if ((val & 0x100) != 0)
  261. /* This is the "ping" from the userspace watchdog in
  262. * the guest ...
  263. */
  264. i6300esb_restart_timer(d, 1);
  265. /* Setting bit 9 resets the previous reboot flag.
  266. * There's a bug in the Linux driver where it sets
  267. * bit 12 instead.
  268. */
  269. if ((val & 0x200) != 0 || (val & 0x1000) != 0) {
  270. d->previous_reboot_flag = 0;
  271. }
  272. }
  273. d->unlock_state = 0;
  274. }
  275. }
  276. }
  277. static void i6300esb_mem_writel(void *vp, hwaddr addr, uint32_t val)
  278. {
  279. I6300State *d = vp;
  280. i6300esb_debug ("addr = %x, val = %x\n", (int) addr, val);
  281. if (addr == 0xc && val == 0x80)
  282. d->unlock_state = 1;
  283. else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
  284. d->unlock_state = 2;
  285. else {
  286. if (d->unlock_state == 2) {
  287. if (addr == 0)
  288. d->timer1_preload = val & 0xfffff;
  289. else if (addr == 4)
  290. d->timer2_preload = val & 0xfffff;
  291. d->unlock_state = 0;
  292. }
  293. }
  294. }
  295. static uint64_t i6300esb_mem_readfn(void *opaque, hwaddr addr, unsigned size)
  296. {
  297. switch (size) {
  298. case 1:
  299. return i6300esb_mem_readb(opaque, addr);
  300. case 2:
  301. return i6300esb_mem_readw(opaque, addr);
  302. case 4:
  303. return i6300esb_mem_readl(opaque, addr);
  304. default:
  305. g_assert_not_reached();
  306. }
  307. }
  308. static void i6300esb_mem_writefn(void *opaque, hwaddr addr,
  309. uint64_t value, unsigned size)
  310. {
  311. switch (size) {
  312. case 1:
  313. i6300esb_mem_writeb(opaque, addr, value);
  314. break;
  315. case 2:
  316. i6300esb_mem_writew(opaque, addr, value);
  317. break;
  318. case 4:
  319. i6300esb_mem_writel(opaque, addr, value);
  320. break;
  321. default:
  322. g_assert_not_reached();
  323. }
  324. }
  325. static const MemoryRegionOps i6300esb_ops = {
  326. .read = i6300esb_mem_readfn,
  327. .write = i6300esb_mem_writefn,
  328. .valid.min_access_size = 1,
  329. .valid.max_access_size = 4,
  330. .endianness = DEVICE_LITTLE_ENDIAN,
  331. };
  332. static const VMStateDescription vmstate_i6300esb = {
  333. .name = "i6300esb_wdt",
  334. /* With this VMSD's introduction, version_id/minimum_version_id were
  335. * erroneously set to sizeof(I6300State), causing a somewhat random
  336. * version_id to be set for every build. This eventually broke
  337. * migration.
  338. *
  339. * To correct this without breaking old->new migration for older
  340. * versions of QEMU, we've set version_id to a value high enough
  341. * to exceed all past values of sizeof(I6300State) across various
  342. * build environments, and have reset minimum_version_id to 1,
  343. * since this VMSD has never changed and thus can accept all past
  344. * versions.
  345. *
  346. * For future changes we can treat these values as we normally would.
  347. */
  348. .version_id = 10000,
  349. .minimum_version_id = 1,
  350. .fields = (const VMStateField[]) {
  351. VMSTATE_PCI_DEVICE(dev, I6300State),
  352. VMSTATE_INT32(reboot_enabled, I6300State),
  353. VMSTATE_INT32(clock_scale, I6300State),
  354. VMSTATE_INT32(int_type, I6300State),
  355. VMSTATE_INT32(free_run, I6300State),
  356. VMSTATE_INT32(locked, I6300State),
  357. VMSTATE_INT32(enabled, I6300State),
  358. VMSTATE_TIMER_PTR(timer, I6300State),
  359. VMSTATE_UINT32(timer1_preload, I6300State),
  360. VMSTATE_UINT32(timer2_preload, I6300State),
  361. VMSTATE_INT32(stage, I6300State),
  362. VMSTATE_INT32(unlock_state, I6300State),
  363. VMSTATE_INT32(previous_reboot_flag, I6300State),
  364. VMSTATE_END_OF_LIST()
  365. }
  366. };
  367. static void i6300esb_realize(PCIDevice *dev, Error **errp)
  368. {
  369. I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev);
  370. i6300esb_debug("I6300State = %p\n", d);
  371. d->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, i6300esb_timer_expired, d);
  372. d->previous_reboot_flag = 0;
  373. memory_region_init_io(&d->io_mem, OBJECT(d), &i6300esb_ops, d,
  374. "i6300esb", 0x10);
  375. pci_register_bar(&d->dev, 0, 0, &d->io_mem);
  376. }
  377. static void i6300esb_exit(PCIDevice *dev)
  378. {
  379. I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev);
  380. timer_free(d->timer);
  381. }
  382. static void i6300esb_class_init(ObjectClass *klass, void *data)
  383. {
  384. DeviceClass *dc = DEVICE_CLASS(klass);
  385. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  386. k->config_read = i6300esb_config_read;
  387. k->config_write = i6300esb_config_write;
  388. k->realize = i6300esb_realize;
  389. k->exit = i6300esb_exit;
  390. k->vendor_id = PCI_VENDOR_ID_INTEL;
  391. k->device_id = PCI_DEVICE_ID_INTEL_ESB_9;
  392. k->class_id = PCI_CLASS_SYSTEM_OTHER;
  393. device_class_set_legacy_reset(dc, i6300esb_reset);
  394. dc->vmsd = &vmstate_i6300esb;
  395. set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
  396. dc->desc = "Intel 6300ESB";
  397. }
  398. static const TypeInfo i6300esb_info = {
  399. .name = TYPE_WATCHDOG_I6300ESB_DEVICE,
  400. .parent = TYPE_PCI_DEVICE,
  401. .instance_size = sizeof(I6300State),
  402. .class_init = i6300esb_class_init,
  403. .interfaces = (InterfaceInfo[]) {
  404. { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  405. { },
  406. },
  407. };
  408. static void i6300esb_register_types(void)
  409. {
  410. type_register_static(&i6300esb_info);
  411. }
  412. type_init(i6300esb_register_types)