This source file includes following definitions.
- opti82c700_init
- opti82c700_addr
- opti82c700_getclink
- opti82c700_get_intr
- opti82c700_set_intr
- opti82c700_get_trigger
- opti82c700_set_trigger
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 #include <sys/param.h>
71 #include <sys/systm.h>
72 #include <sys/device.h>
73 #include <sys/malloc.h>
74
75 #include <machine/intr.h>
76 #include <machine/bus.h>
77
78 #include <dev/pci/pcivar.h>
79 #include <dev/pci/pcireg.h>
80 #include <dev/pci/pcidevs.h>
81
82 #include <i386/pci/pcibiosvar.h>
83 #include <i386/pci/opti82c700reg.h>
84
85 #ifdef FIRESTARDEBUG
86 #define DPRINTF(arg) printf arg
87 #else
88 #define DPRINTF(arg)
89 #endif
90
91 int opti82c700_getclink(pciintr_icu_handle_t, int, int *);
92 int opti82c700_get_intr(pciintr_icu_handle_t, int, int *);
93 int opti82c700_set_intr(pciintr_icu_handle_t, int, int);
94 int opti82c700_get_trigger(pciintr_icu_handle_t, int, int *);
95 int opti82c700_set_trigger(pciintr_icu_handle_t, int, int);
96
97 const struct pciintr_icu opti82c700_pci_icu = {
98 opti82c700_getclink,
99 opti82c700_get_intr,
100 opti82c700_set_intr,
101 opti82c700_get_trigger,
102 opti82c700_set_trigger,
103 };
104
105 struct opti82c700_handle {
106 pci_chipset_tag_t ph_pc;
107 pcitag_t ph_tag;
108 };
109
110 int opti82c700_addr(int, int *, int *);
111 #ifdef FIRESTARDEBUG
112 void opti82c700_pir_dump(struct opti82c700_handle *);
113 #endif
114
115 int
116 opti82c700_init(pci_chipset_tag_t pc, bus_space_tag_t iot, pcitag_t tag,
117 pciintr_icu_tag_t *ptagp, pciintr_icu_handle_t *phandp)
118 {
119 struct opti82c700_handle *ph;
120
121 ph = malloc(sizeof(*ph), M_DEVBUF, M_NOWAIT);
122 if (ph == NULL)
123 return (1);
124
125 ph->ph_pc = pc;
126 ph->ph_tag = tag;
127 #ifdef FIRESTARDEBUG
128 opti82c700_pir_dump(ph);
129 #endif
130 *ptagp = &opti82c700_pci_icu;
131 *phandp = ph;
132 return (0);
133 }
134
135 int
136 opti82c700_addr(int link, int *addrofs, int *ofs)
137 {
138 int regofs, src;
139
140 regofs = FIRESTAR_PIR_REGOFS(link);
141 src = FIRESTAR_PIR_SELECTSRC(link);
142
143 switch (src) {
144 case FIRESTAR_PIR_SELECT_NONE:
145 return (1);
146
147 case FIRESTAR_PIR_SELECT_IRQ:
148 if (regofs < 0 || regofs > 7)
149 return (1);
150 *addrofs = FIRESTAR_CFG_INTR_IRQ + (regofs >> 2);
151 *ofs = (regofs & 3) << 3;
152 break;
153
154 case FIRESTAR_PIR_SELECT_PIRQ:
155
156 case FIRESTAR_PIR_SELECT_BRIDGE:
157 if (regofs < 0 || regofs > 3)
158 return (1);
159 *addrofs = FIRESTAR_CFG_INTR_PIRQ;
160 *ofs = regofs << 2;
161 break;
162
163 default:
164 return (1);
165 }
166
167 return (0);
168 }
169
170 int
171 opti82c700_getclink(pciintr_icu_handle_t v, int link, int *clinkp)
172 {
173 DPRINTF(("FireStar link value 0x%x: ", link));
174
175 switch (FIRESTAR_PIR_SELECTSRC(link)) {
176 default:
177 DPRINTF(("bogus IRQ selection source\n"));
178 return (1);
179 case FIRESTAR_PIR_SELECT_NONE:
180 DPRINTF(("No interrupt connection\n"));
181 return (1);
182 case FIRESTAR_PIR_SELECT_IRQ:
183 DPRINTF(("FireStar IRQ pin"));
184 break;
185 case FIRESTAR_PIR_SELECT_PIRQ:
186 DPRINTF(("FireStar PIO pin or Serial IRQ PIRQ#"));
187 break;
188 case FIRESTAR_PIR_SELECT_BRIDGE:
189 DPRINTF(("FireBridge 1 INTx# pin"));
190 break;
191 }
192
193 DPRINTF((" REGOFST:%#x\n", FIRESTAR_PIR_REGOFS(link)));
194 *clinkp = link;
195
196 return (0);
197 }
198
199 int
200 opti82c700_get_intr(pciintr_icu_handle_t v, int clink, int *irqp)
201 {
202 struct opti82c700_handle *ph = v;
203 pcireg_t reg;
204 int val, addrofs, ofs;
205
206 if (opti82c700_addr(clink, &addrofs, &ofs))
207 return (1);
208
209 reg = pci_conf_read(ph->ph_pc, ph->ph_tag, addrofs);
210 val = (reg >> ofs) & FIRESTAR_CFG_PIRQ_MASK;
211
212 *irqp = (val == FIRESTAR_PIRQ_NONE) ?
213 I386_PCI_INTERRUPT_LINE_NO_CONNECTION : val;
214
215 return (0);
216 }
217
218 int
219 opti82c700_set_intr(pciintr_icu_handle_t v, int clink, int irq)
220 {
221 struct opti82c700_handle *ph = v;
222 int addrofs, ofs;
223 pcireg_t reg;
224
225 if (FIRESTAR_LEGAL_IRQ(irq) == 0)
226 return (1);
227
228 if (opti82c700_addr(clink, &addrofs, &ofs))
229 return (1);
230
231 reg = pci_conf_read(ph->ph_pc, ph->ph_tag, addrofs);
232 reg &= ~(FIRESTAR_CFG_PIRQ_MASK << ofs);
233 reg |= (irq << ofs);
234 pci_conf_write(ph->ph_pc, ph->ph_tag, addrofs, reg);
235
236 return (0);
237 }
238
239 int
240 opti82c700_get_trigger(pciintr_icu_handle_t v, int irq, int *triggerp)
241 {
242 struct opti82c700_handle *ph = v;
243 int i, val, addrofs, ofs;
244 pcireg_t reg;
245
246 if (FIRESTAR_LEGAL_IRQ(irq) == 0) {
247
248 *triggerp = IST_EDGE;
249 return (0);
250 }
251
252
253
254
255 for (i = 0; i < 8; i++) {
256 opti82c700_addr(FIRESTAR_PIR_MAKELINK(FIRESTAR_PIR_SELECT_IRQ,
257 i), &addrofs, &ofs);
258 reg = pci_conf_read(ph->ph_pc, ph->ph_tag, addrofs);
259 val = (reg >> ofs) & FIRESTAR_CFG_PIRQ_MASK;
260 if (val != irq)
261 continue;
262 val = ((reg >> ofs) >> FIRESTAR_TRIGGER_SHIFT) &
263 FIRESTAR_TRIGGER_MASK;
264 *triggerp = val ? IST_LEVEL : IST_EDGE;
265 return (0);
266 }
267
268
269
270
271 for (i = 0; i < 4; i++) {
272 opti82c700_addr(FIRESTAR_PIR_MAKELINK(FIRESTAR_PIR_SELECT_PIRQ,
273 i), &addrofs, &ofs);
274 reg = pci_conf_read(ph->ph_pc, ph->ph_tag, addrofs);
275 val = (reg >> ofs) & FIRESTAR_CFG_PIRQ_MASK;
276 if (val != irq)
277 continue;
278 *triggerp = IST_LEVEL;
279 return (0);
280 }
281
282 return (1);
283 }
284
285 int
286 opti82c700_set_trigger(pciintr_icu_handle_t v, int irq, int trigger)
287 {
288 struct opti82c700_handle *ph = v;
289 int i, val, addrofs, ofs;
290 pcireg_t reg;
291
292 if (FIRESTAR_LEGAL_IRQ(irq) == 0) {
293
294 return ((trigger != IST_LEVEL) ? 0 : 1);
295 }
296
297
298
299
300 for (i = 0; i < 8; i++) {
301 opti82c700_addr(FIRESTAR_PIR_MAKELINK(FIRESTAR_PIR_SELECT_IRQ,
302 i), &addrofs, &ofs);
303 reg = pci_conf_read(ph->ph_pc, ph->ph_tag, addrofs);
304 val = (reg >> ofs) & FIRESTAR_CFG_PIRQ_MASK;
305 if (val != irq)
306 continue;
307 if (trigger == IST_LEVEL)
308 reg |= (FIRESTAR_TRIGGER_MASK <<
309 (FIRESTAR_TRIGGER_SHIFT + ofs));
310 else
311 reg &= ~(FIRESTAR_TRIGGER_MASK <<
312 (FIRESTAR_TRIGGER_SHIFT + ofs));
313 pci_conf_write(ph->ph_pc, ph->ph_tag, addrofs, reg);
314 return (0);
315 }
316
317
318
319
320 for (i = 0; i < 4; i++) {
321 opti82c700_addr(FIRESTAR_PIR_MAKELINK(FIRESTAR_PIR_SELECT_PIRQ,
322 i), &addrofs, &ofs);
323 reg = pci_conf_read(ph->ph_pc, ph->ph_tag, addrofs);
324 val = (reg >> ofs) & FIRESTAR_CFG_PIRQ_MASK;
325 if (val != irq)
326 continue;
327 return (trigger == IST_LEVEL ? 0 : 1);
328 }
329
330 return (1);
331 }