This source file includes following definitions.
- ichwdt_unlock_write
- ichwdt_match
- ichwdt_attach
- ichwdt_cb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/device.h>
26
27 #include <machine/bus.h>
28
29 #include <dev/pci/pcireg.h>
30 #include <dev/pci/pcivar.h>
31 #include <dev/pci/pcidevs.h>
32
33 #include <dev/pci/ichreg.h>
34
35 #ifdef ICHWDT_DEBUG
36 #define DPRINTF(x) printf x
37 #else
38 #define DPRINTF(x)
39 #endif
40
41 struct ichwdt_softc {
42 struct device sc_dev;
43
44 pci_chipset_tag_t sc_pc;
45 pcitag_t sc_tag;
46
47 bus_space_tag_t sc_iot;
48 bus_space_handle_t sc_ioh;
49
50 int sc_divisor;
51 int sc_period;
52 };
53
54 int ichwdt_match(struct device *, void *, void *);
55 void ichwdt_attach(struct device *, struct device *, void *);
56
57 int ichwdt_cb(void *, int);
58
59 struct cfattach ichwdt_ca = {
60 sizeof(struct ichwdt_softc),
61 ichwdt_match,
62 ichwdt_attach
63 };
64
65 struct cfdriver ichwdt_cd = {
66 NULL, "ichwdt", DV_DULL
67 };
68
69 const struct pci_matchid ichwdt_devices[] = {
70 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_6300ESB_WDT }
71 };
72
73 static __inline void
74 ichwdt_unlock_write(struct ichwdt_softc *sc, int reg, u_int32_t val)
75 {
76
77 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ICH_WDT_RELOAD, 0x80);
78 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ICH_WDT_RELOAD, 0x86);
79
80
81 bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, val);
82 }
83
84 int
85 ichwdt_match(struct device *parent, void *match, void *aux)
86 {
87 return (pci_matchbyid((struct pci_attach_args *)aux, ichwdt_devices,
88 sizeof(ichwdt_devices) / sizeof(ichwdt_devices[0])));
89 }
90
91 void
92 ichwdt_attach(struct device *parent, struct device *self, void *aux)
93 {
94 struct ichwdt_softc *sc = (struct ichwdt_softc *)self;
95 struct pci_attach_args *pa = aux;
96 u_int32_t reg;
97
98 sc->sc_pc = pa->pa_pc;
99 sc->sc_tag = pa->pa_tag;
100
101
102 sc->sc_iot = pa->pa_iot;
103 if (pci_mapreg_map(pa, ICH_WDT_BASE, PCI_MAPREG_TYPE_MEM, 0,
104 &sc->sc_iot, &sc->sc_ioh, NULL, NULL, 0)) {
105 printf(": failed to map memory space\n");
106 return;
107 }
108
109
110 reg = pci_conf_read(sc->sc_pc, sc->sc_tag, ICH_WDT_CONF);
111 DPRINTF((": conf 0x%x", reg));
112
113
114 sc->sc_divisor = (reg & ICH_WDT_CONF_PRE ? 32 : 32768);
115 printf(": %s clock", (reg & ICH_WDT_CONF_PRE ? "1MHz" : "1kHz"));
116
117
118 reg &= ~ICH_WDT_CONF_INT_MASK;
119 reg |= ICH_WDT_CONF_INT_DIS;
120 pci_conf_write(sc->sc_pc, sc->sc_tag, ICH_WDT_CONF, reg);
121
122
123 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, ICH_WDT_RELOAD);
124 if (reg & ICH_WDT_RELOAD_TIMEOUT) {
125 printf(": reboot on timeout");
126
127
128 ichwdt_unlock_write(sc, ICH_WDT_RELOAD,
129 ICH_WDT_RELOAD_TIMEOUT);
130 }
131
132
133 pci_conf_write(sc->sc_pc, sc->sc_tag, ICH_WDT_LOCK, 0);
134 sc->sc_period = 0;
135
136 printf("\n");
137
138
139 wdog_register(sc, ichwdt_cb);
140 }
141
142 int
143 ichwdt_cb(void *arg, int period)
144 {
145 struct ichwdt_softc *sc = arg;
146 int ticks;
147
148 if (period == 0) {
149 if (sc->sc_period != 0) {
150
151 ichwdt_unlock_write(sc, ICH_WDT_RELOAD,
152 ICH_WDT_RELOAD_RLD);
153 pci_conf_write(sc->sc_pc, sc->sc_tag, ICH_WDT_LOCK, 0);
154 DPRINTF(("%s: disabled, conf 0x%x\n",
155 sc->sc_dev.dv_xname,
156 pci_conf_read(sc->sc_pc, sc->sc_tag,
157 ICH_WDT_LOCK)));
158 }
159 } else {
160
161 if (period > 1000)
162 period = 1000;
163
164 if (sc->sc_period != period) {
165
166 ticks = (period * 33000000) / sc->sc_divisor;
167 ichwdt_unlock_write(sc, ICH_WDT_PRE1, ticks);
168 ichwdt_unlock_write(sc, ICH_WDT_PRE2, 2);
169 DPRINTF(("%s: timeout %ds (%d ticks)\n",
170 sc->sc_dev.dv_xname, period, ticks));
171 }
172 if (sc->sc_period == 0) {
173
174 pci_conf_write(sc->sc_pc, sc->sc_tag, ICH_WDT_LOCK,
175 ICH_WDT_LOCK_ENABLED);
176 DPRINTF(("%s: enabled, conf 0x%x\n",
177 sc->sc_dev.dv_xname,
178 pci_conf_read(sc->sc_pc, sc->sc_tag,
179 ICH_WDT_LOCK)));
180 } else {
181
182 ichwdt_unlock_write(sc, ICH_WDT_RELOAD,
183 ICH_WDT_RELOAD_RLD);
184 DPRINTF(("%s: reloaded\n", sc->sc_dev.dv_xname));
185 }
186 }
187 sc->sc_period = period;
188
189 return (period);
190 }