root / hw / wdt_ib700.c @ 96cc1810
History | View | Annotate | Download (2.9 kB)
1 | 9dd986cc | Richard W.M. Jones | /*
|
---|---|---|---|
2 | 9dd986cc | Richard W.M. Jones | * Virtual hardware watchdog.
|
3 | 9dd986cc | Richard W.M. Jones | *
|
4 | 9dd986cc | Richard W.M. Jones | * Copyright (C) 2009 Red Hat Inc.
|
5 | 9dd986cc | Richard W.M. Jones | *
|
6 | 9dd986cc | Richard W.M. Jones | * This program is free software; you can redistribute it and/or
|
7 | 9dd986cc | Richard W.M. Jones | * modify it under the terms of the GNU General Public License
|
8 | 9dd986cc | Richard W.M. Jones | * as published by the Free Software Foundation; either version 2
|
9 | 9dd986cc | Richard W.M. Jones | * of the License, or (at your option) any later version.
|
10 | 9dd986cc | Richard W.M. Jones | *
|
11 | 9dd986cc | Richard W.M. Jones | * This program is distributed in the hope that it will be useful,
|
12 | 9dd986cc | Richard W.M. Jones | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 9dd986cc | Richard W.M. Jones | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 | 9dd986cc | Richard W.M. Jones | * GNU General Public License for more details.
|
15 | 9dd986cc | Richard W.M. Jones | *
|
16 | 9dd986cc | Richard W.M. Jones | * You should have received a copy of the GNU General Public License
|
17 | 8167ee88 | Blue Swirl | * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
18 | 9dd986cc | Richard W.M. Jones | *
|
19 | 9dd986cc | Richard W.M. Jones | * By Richard W.M. Jones (rjones@redhat.com).
|
20 | 9dd986cc | Richard W.M. Jones | */
|
21 | 9dd986cc | Richard W.M. Jones | |
22 | 9dd986cc | Richard W.M. Jones | #include "qemu-common.h" |
23 | 9dd986cc | Richard W.M. Jones | #include "qemu-timer.h" |
24 | 9dd986cc | Richard W.M. Jones | #include "watchdog.h" |
25 | 9dd986cc | Richard W.M. Jones | #include "hw.h" |
26 | 9dd986cc | Richard W.M. Jones | #include "isa.h" |
27 | 9dd986cc | Richard W.M. Jones | #include "pc.h" |
28 | 9dd986cc | Richard W.M. Jones | |
29 | 9dd986cc | Richard W.M. Jones | /*#define IB700_DEBUG 1*/
|
30 | 9dd986cc | Richard W.M. Jones | |
31 | 9dd986cc | Richard W.M. Jones | #ifdef IB700_DEBUG
|
32 | 9dd986cc | Richard W.M. Jones | #define ib700_debug(fs,...) \
|
33 | 9dd986cc | Richard W.M. Jones | fprintf(stderr,"ib700: %s: "fs,__func__,##__VA_ARGS__) |
34 | 9dd986cc | Richard W.M. Jones | #else
|
35 | 9dd986cc | Richard W.M. Jones | #define ib700_debug(fs,...)
|
36 | 9dd986cc | Richard W.M. Jones | #endif
|
37 | 9dd986cc | Richard W.M. Jones | |
38 | 9dd986cc | Richard W.M. Jones | /* This is the timer. We use a global here because the watchdog
|
39 | 9dd986cc | Richard W.M. Jones | * code ensures there is only one watchdog (it is located at a fixed,
|
40 | 9dd986cc | Richard W.M. Jones | * unchangable IO port, so there could only ever be one anyway).
|
41 | 9dd986cc | Richard W.M. Jones | */
|
42 | 9dd986cc | Richard W.M. Jones | static QEMUTimer *timer = NULL; |
43 | 9dd986cc | Richard W.M. Jones | |
44 | 9dd986cc | Richard W.M. Jones | /* A write to this register enables the timer. */
|
45 | 9dd986cc | Richard W.M. Jones | static void ib700_write_enable_reg(void *vp, uint32_t addr, uint32_t data) |
46 | 9dd986cc | Richard W.M. Jones | { |
47 | 9dd986cc | Richard W.M. Jones | static int time_map[] = { |
48 | 9dd986cc | Richard W.M. Jones | 30, 28, 26, 24, 22, 20, 18, 16, |
49 | 9dd986cc | Richard W.M. Jones | 14, 12, 10, 8, 6, 4, 2, 0 |
50 | 9dd986cc | Richard W.M. Jones | }; |
51 | 9dd986cc | Richard W.M. Jones | int64 timeout; |
52 | 9dd986cc | Richard W.M. Jones | |
53 | 9dd986cc | Richard W.M. Jones | ib700_debug("addr = %x, data = %x\n", addr, data);
|
54 | 9dd986cc | Richard W.M. Jones | |
55 | 9dd986cc | Richard W.M. Jones | timeout = (int64_t) time_map[data & 0xF] * ticks_per_sec;
|
56 | 9dd986cc | Richard W.M. Jones | qemu_mod_timer(timer, qemu_get_clock (vm_clock) + timeout); |
57 | 9dd986cc | Richard W.M. Jones | } |
58 | 9dd986cc | Richard W.M. Jones | |
59 | 9dd986cc | Richard W.M. Jones | /* A write (of any value) to this register disables the timer. */
|
60 | 9dd986cc | Richard W.M. Jones | static void ib700_write_disable_reg(void *vp, uint32_t addr, uint32_t data) |
61 | 9dd986cc | Richard W.M. Jones | { |
62 | 9dd986cc | Richard W.M. Jones | ib700_debug("addr = %x, data = %x\n", addr, data);
|
63 | 9dd986cc | Richard W.M. Jones | |
64 | 9dd986cc | Richard W.M. Jones | qemu_del_timer(timer); |
65 | 9dd986cc | Richard W.M. Jones | } |
66 | 9dd986cc | Richard W.M. Jones | |
67 | 9dd986cc | Richard W.M. Jones | /* This is called when the watchdog expires. */
|
68 | 9dd986cc | Richard W.M. Jones | static void ib700_timer_expired(void *vp) |
69 | 9dd986cc | Richard W.M. Jones | { |
70 | 9dd986cc | Richard W.M. Jones | ib700_debug("watchdog expired\n");
|
71 | 9dd986cc | Richard W.M. Jones | |
72 | 9dd986cc | Richard W.M. Jones | watchdog_perform_action(); |
73 | 9dd986cc | Richard W.M. Jones | qemu_del_timer(timer); |
74 | 9dd986cc | Richard W.M. Jones | } |
75 | 9dd986cc | Richard W.M. Jones | |
76 | 9dd986cc | Richard W.M. Jones | static void ib700_save(QEMUFile *f, void *vp) |
77 | 9dd986cc | Richard W.M. Jones | { |
78 | 9dd986cc | Richard W.M. Jones | qemu_put_timer(f, timer); |
79 | 9dd986cc | Richard W.M. Jones | } |
80 | 9dd986cc | Richard W.M. Jones | |
81 | 9dd986cc | Richard W.M. Jones | static int ib700_load(QEMUFile *f, void *vp, int version) |
82 | 9dd986cc | Richard W.M. Jones | { |
83 | 9dd986cc | Richard W.M. Jones | if (version != 0) |
84 | 9dd986cc | Richard W.M. Jones | return -EINVAL;
|
85 | 9dd986cc | Richard W.M. Jones | |
86 | 9dd986cc | Richard W.M. Jones | qemu_get_timer(f, timer); |
87 | 9dd986cc | Richard W.M. Jones | |
88 | 9dd986cc | Richard W.M. Jones | return 0; |
89 | 9dd986cc | Richard W.M. Jones | } |
90 | 9dd986cc | Richard W.M. Jones | |
91 | 9dd986cc | Richard W.M. Jones | /* Create and initialize a virtual IB700 during PC creation. */
|
92 | 9dd986cc | Richard W.M. Jones | static void ib700_pc_init(PCIBus *unused) |
93 | 9dd986cc | Richard W.M. Jones | { |
94 | 9dd986cc | Richard W.M. Jones | register_savevm("ib700_wdt", -1, 0, ib700_save, ib700_load, NULL); |
95 | 9dd986cc | Richard W.M. Jones | |
96 | 9dd986cc | Richard W.M. Jones | register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, NULL); |
97 | 9dd986cc | Richard W.M. Jones | register_ioport_write(0x443, 2, 1, ib700_write_enable_reg, NULL); |
98 | 9dd986cc | Richard W.M. Jones | } |
99 | 9dd986cc | Richard W.M. Jones | |
100 | 9dd986cc | Richard W.M. Jones | static WatchdogTimerModel model = {
|
101 | 9dd986cc | Richard W.M. Jones | .wdt_name = "ib700",
|
102 | 9dd986cc | Richard W.M. Jones | .wdt_description = "iBASE 700",
|
103 | 9dd986cc | Richard W.M. Jones | .wdt_pc_init = ib700_pc_init, |
104 | 9dd986cc | Richard W.M. Jones | }; |
105 | 9dd986cc | Richard W.M. Jones | |
106 | 9dd986cc | Richard W.M. Jones | void wdt_ib700_init(void) |
107 | 9dd986cc | Richard W.M. Jones | { |
108 | 9dd986cc | Richard W.M. Jones | watchdog_add_model(&model); |
109 | 9dd986cc | Richard W.M. Jones | timer = qemu_new_timer(vm_clock, ib700_timer_expired, NULL);
|
110 | 9dd986cc | Richard W.M. Jones | } |