Deleted Added
full compact
gt_pci.c (183174) gt_pci.c (187251)
1/* $NetBSD: gt_pci.c,v 1.4 2003/07/15 00:24:54 lukem Exp $ */
2
3/*-
4 * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
5 * All rights reserved.
6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38/*
39 * PCI configuration support for gt I/O Processor chip.
40 */
41
42#include <sys/cdefs.h>
1/* $NetBSD: gt_pci.c,v 1.4 2003/07/15 00:24:54 lukem Exp $ */
2
3/*-
4 * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
5 * All rights reserved.
6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38/*
39 * PCI configuration support for gt I/O Processor chip.
40 */
41
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: head/sys/mips/malta/gt_pci.c 183174 2008-09-19 04:16:13Z imp $");
43__FBSDID("$FreeBSD: head/sys/mips/malta/gt_pci.c 187251 2009-01-14 22:32:43Z gonzo $");
44
45#include <sys/param.h>
46#include <sys/systm.h>
47
48#include <sys/bus.h>
49#include <sys/interrupt.h>
50#include <sys/malloc.h>
51#include <sys/kernel.h>
52#include <sys/module.h>
53#include <sys/rman.h>
54
55#include <vm/vm.h>
56#include <vm/pmap.h>
57#include <vm/vm_extern.h>
58
59#include <machine/bus.h>
60#include <machine/cpu.h>
61#include <machine/pmap.h>
62
63#include <mips/malta/maltareg.h>
64
65#include <mips/malta/gtreg.h>
66#include <mips/malta/gtvar.h>
67
68#include <isa/isareg.h>
69#include <dev/ic/i8259.h>
70
71#include <dev/pci/pcireg.h>
72#include <dev/pci/pcivar.h>
73
74#include <dev/pci/pcib_private.h>
75#include "pcib_if.h"
76
77
78#define ICU_LEN 16 /* number of ISA IRQs */
79
80/*
81 * XXX: These defines are from NetBSD's <dev/ic/i8259reg.h>. Respective file
82 * from FreeBSD src tree <dev/ic/i8259.h> lacks some definitions.
83 */
84#define PIC_OCW1 1
85#define PIC_OCW2 0
86#define PIC_OCW3 0
87
88#define OCW2_SELECT 0
89#define OCW2_ILS(x) ((x) << 0) /* interrupt level select */
90
91#define OCW3_POLL_IRQ(x) ((x) & 0x7f)
92#define OCW3_POLL_PENDING (1U << 7)
93
94struct gt_pci_softc {
95 device_t sc_dev;
96 bus_space_tag_t sc_st;
97 bus_space_tag_t sc_pciio;
98 bus_space_tag_t sc_pcimem;
99 bus_space_handle_t sc_ioh_icu1;
100 bus_space_handle_t sc_ioh_icu2;
101 bus_space_handle_t sc_ioh_elcr;
102
103 int sc_busno;
104 struct rman sc_mem_rman;
105 struct rman sc_io_rman;
106 struct rman sc_irq_rman;
107 uint32_t sc_mem;
108 uint32_t sc_io;
109
110 struct resource *sc_irq;
111 struct intr_event *sc_eventstab[ICU_LEN];
112 uint16_t sc_imask;
113 uint16_t sc_elcr;
114
115 uint16_t sc_reserved;
116
117 void *sc_ih;
118};
119
120static void
121gt_pci_set_icus(struct gt_pci_softc *sc)
122{
123 /* Enable the cascade IRQ (2) if 8-15 is enabled. */
124 if ((sc->sc_imask & 0xff00) != 0xff00)
125 sc->sc_imask &= ~(1U << 2);
126 else
127 sc->sc_imask |= (1U << 2);
128
129 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW1,
130 sc->sc_imask & 0xff);
131 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, PIC_OCW1,
132 (sc->sc_imask >> 8) & 0xff);
133
134 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 0,
135 sc->sc_elcr & 0xff);
136 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 1,
137 (sc->sc_elcr >> 8) & 0xff);
138}
139
140static int
141gt_pci_intr(void *v)
142{
143 struct gt_pci_softc *sc = v;
144 struct intr_event *event;
145 int irq;
146
147 for (;;) {
148 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW3,
149 OCW3_SEL | OCW3_P);
150 irq = bus_space_read_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW3);
151 if ((irq & OCW3_POLL_PENDING) == 0)
152 {
153 return FILTER_HANDLED;
154 }
155
156 irq = OCW3_POLL_IRQ(irq);
157
158 if (irq == 2) {
159 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2,
160 PIC_OCW3, OCW3_SEL | OCW3_P);
161 irq = bus_space_read_1(sc->sc_pciio, sc->sc_ioh_icu2,
162 PIC_OCW3);
163 if (irq & OCW3_POLL_PENDING)
164 irq = OCW3_POLL_IRQ(irq) + 8;
165 else
166 irq = 2;
167 }
168
169 event = sc->sc_eventstab[irq];
170
171 if (!event || TAILQ_EMPTY(&event->ie_handlers))
172 continue;
173
174 /* TODO: frame instead of NULL? */
175 intr_event_handle(event, NULL);
176 /* XXX: Log stray IRQs */
177
178 /* Send a specific EOI to the 8259. */
179 if (irq > 7) {
180 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2,
181 PIC_OCW2, OCW2_SELECT | OCW2_EOI | OCW2_SL |
182 OCW2_ILS(irq & 7));
183 irq = 2;
184 }
185
186 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW2,
187 OCW2_SELECT | OCW2_EOI | OCW2_SL | OCW2_ILS(irq));
188 }
189
190 return FILTER_HANDLED;
191}
192
193static int
194gt_pci_probe(device_t dev)
195{
196 device_set_desc(dev, "GT64120 PCI bridge");
197 return (0);
198}
199
200static int
201gt_pci_attach(device_t dev)
202{
203
204 uint32_t busno;
205 struct gt_pci_softc *sc = device_get_softc(dev);
206 int rid;
207
208 busno = 0;
209 sc->sc_dev = dev;
210 sc->sc_busno = busno;
211 sc->sc_pciio = MIPS_BUS_SPACE_IO;
212 sc->sc_pcimem = MIPS_BUS_SPACE_MEM;
213
214 /* Use KSEG1 to access IO ports for it is uncached */
215 sc->sc_io = MIPS_PHYS_TO_KSEG1(MALTA_PCI0_IO_BASE);
216 sc->sc_io_rman.rm_type = RMAN_ARRAY;
217 sc->sc_io_rman.rm_descr = "GT64120 PCI I/O Ports";
218 if (rman_init(&sc->sc_io_rman) != 0 ||
219 rman_manage_region(&sc->sc_io_rman, 0, 0xffff) != 0) {
220 panic("gt_pci_attach: failed to set up I/O rman");
221 }
222
223 /* Use KSEG1 to access PCI memory for it is uncached */
224 sc->sc_mem = MIPS_PHYS_TO_KSEG1(MALTA_PCIMEM1_BASE);
225 sc->sc_mem_rman.rm_type = RMAN_ARRAY;
226 sc->sc_mem_rman.rm_descr = "GT64120 PCI Memory";
227 if (rman_init(&sc->sc_mem_rman) != 0 ||
228 rman_manage_region(&sc->sc_mem_rman,
229 sc->sc_mem, sc->sc_mem + MALTA_PCIMEM1_SIZE) != 0) {
230 panic("gt_pci_attach: failed to set up memory rman");
231 }
232 sc->sc_irq_rman.rm_type = RMAN_ARRAY;
233 sc->sc_irq_rman.rm_descr = "GT64120 PCI IRQs";
234 if (rman_init(&sc->sc_irq_rman) != 0 ||
235 rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0)
236 panic("gt_pci_attach: failed to set up IRQ rman");
237
238 /*
239 * Map the PIC/ELCR registers.
240 */
241#if 0
242 if (bus_space_map(sc->sc_pciio, 0x4d0, 2, 0, &sc->sc_ioh_elcr) != 0)
243 device_printf(dev, "unable to map ELCR registers\n");
244 if (bus_space_map(sc->sc_pciio, IO_ICU1, 2, 0, &sc->sc_ioh_icu1) != 0)
245 device_printf(dev, "unable to map ICU1 registers\n");
246 if (bus_space_map(sc->sc_pciio, IO_ICU2, 2, 0, &sc->sc_ioh_icu2) != 0)
247 device_printf(dev, "unable to map ICU2 registers\n");
248#else
249 sc->sc_ioh_elcr = sc->sc_io + 0x4d0;
250 sc->sc_ioh_icu1 = sc->sc_io + IO_ICU1;
251 sc->sc_ioh_icu2 = sc->sc_io + IO_ICU2;
252#endif
253
254
255 /* All interrupts default to "masked off". */
256 sc->sc_imask = 0xffff;
257
258 /* All interrupts default to edge-triggered. */
259 sc->sc_elcr = 0;
260
261 /*
262 * Initialize the 8259s.
263 */
264 /* reset, program device, 4 bytes */
265 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 0,
266 ICW1_RESET | ICW1_IC4);
267 /*
268 * XXX: values from NetBSD's <dev/ic/i8259reg.h>
269 */
270 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
271 0/*XXX*/);
272 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
273 1 << 2);
274 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
275 ICW4_8086);
276
277 /* mask all interrupts */
278 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 0,
279 sc->sc_imask & 0xff);
280
281 /* enable special mask mode */
282 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
283 OCW3_SEL | OCW3_ESMM | OCW3_SMM);
284
285 /* read IRR by default */
286 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
287 OCW3_SEL | OCW3_RR);
288
289 /* reset, program device, 4 bytes */
290 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 0,
291 ICW1_RESET | ICW1_IC4);
292 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1,
293 0/*XXX*/);
294 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1,
295 1 << 2);
296 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1,
297 ICW4_8086);
298
299 /* mask all interrupts */
300 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 0,
301 sc->sc_imask & 0xff);
302
303 /* enable special mask mode */
304 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1,
305 OCW3_SEL | OCW3_ESMM | OCW3_SMM);
306
307 /* read IRR by default */
308 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1,
309 OCW3_SEL | OCW3_RR);
310
311 /*
312 * Default all interrupts to edge-triggered.
313 */
314 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 0,
315 sc->sc_elcr & 0xff);
316 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 1,
317 (sc->sc_elcr >> 8) & 0xff);
318
319 /*
320 * Some ISA interrupts are reserved for devices that
321 * we know are hard-wired to certain IRQs.
322 */
323 sc->sc_reserved =
324 (1U << 0) | /* timer */
325 (1U << 1) | /* keyboard controller (keyboard) */
326 (1U << 2) | /* PIC cascade */
327 (1U << 3) | /* COM 2 */
328 (1U << 4) | /* COM 1 */
329 (1U << 6) | /* floppy */
330 (1U << 7) | /* centronics */
331 (1U << 8) | /* RTC */
332 (1U << 9) | /* I2C */
333 (1U << 12) | /* keyboard controller (mouse) */
334 (1U << 14) | /* IDE primary */
335 (1U << 15); /* IDE secondary */
336
337 /* Hook up our interrupt handler. */
338 if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
339 MALTA_SOUTHBRIDGE_INTR, MALTA_SOUTHBRIDGE_INTR, 1,
340 RF_SHAREABLE | RF_ACTIVE)) == NULL) {
341 device_printf(dev, "unable to allocate IRQ resource\n");
342 return ENXIO;
343 }
344
345 if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC,
346 gt_pci_intr, NULL, sc, &sc->sc_ih))) {
347 device_printf(dev,
348 "WARNING: unable to register interrupt handler\n");
349 return ENXIO;
350 }
351
352 /* Initialize memory and i/o rmans. */
353 device_add_child(dev, "pci", busno);
354 return (bus_generic_attach(dev));
355}
356
357static int
358gt_pci_maxslots(device_t dev)
359{
360 return (PCI_SLOTMAX);
361}
362
363static int
364gt_pci_conf_setup(struct gt_pci_softc *sc, int bus, int slot, int func,
365 int reg, uint32_t *addr)
366{
367 *addr = (bus << 16) | (slot << 11) | (func << 8) | reg;
368
369 return (0);
370}
371
372static uint32_t
373gt_pci_read_config(device_t dev, int bus, int slot, int func, int reg,
374 int bytes)
375{
376 struct gt_pci_softc *sc = device_get_softc(dev);
377 uint32_t data;
378 uint32_t addr;
379 uint32_t shift, mask;
380
381 if (gt_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
382 return (uint32_t)(-1);
383
384 /* Clear cause register bits. */
385 GT_REGVAL(GT_INTR_CAUSE) = 0;
386
387 GT_REGVAL(GT_PCI0_CFG_ADDR) = (1 << 31) | addr;
388 data = GT_REGVAL(GT_PCI0_CFG_DATA);
389
390 /* Check for master abort. */
391 if (GT_REGVAL(GT_INTR_CAUSE) & (GTIC_MASABORT0 | GTIC_TARABORT0))
392 data = (uint32_t) -1;
393
394 /*
395 * XXX: We assume that words readed from GT chip are BE.
396 * Should we set the mode explicitly during chip
397 * Initialization?
398 */
399 switch(reg % 4)
400 {
401 case 3:
402 shift = 24;
403 break;
404 case 2:
405 shift = 16;
406 break;
407 case 1:
408 shift = 8;
409 break;
410 default:
411 shift = 0;
412 break;
413 }
414
415 switch(bytes)
416 {
417 case 1:
418 mask = 0xff;
419 data = (data >> shift) & mask;
420 break;
421 case 2:
422 mask = 0xffff;
423 if(reg % 4 == 0)
424 data = data & mask;
425 else
426 data = (data >> 16) & mask;
427 break;
428 case 4:
429 break;
430 default:
431 panic("gt_pci_readconfig: wrong bytes count");
432 break;
433 }
434#if 0
435 printf("PCICONF_READ(%02x:%02x.%02x[%04x] -> %02x(%d)\n",
436 bus, slot, func, reg, data, bytes);
437#endif
438
439 return (data);
440}
441
442static void
443gt_pci_write_config(device_t dev, int bus, int slot, int func, int reg,
444 uint32_t data, int bytes)
445{
446 struct gt_pci_softc *sc = device_get_softc(dev);
447 uint32_t addr;
448 uint32_t reg_data;
449 uint32_t shift, mask;
450
451 if(bytes != 4)
452 {
453 reg_data = gt_pci_read_config(dev, bus, slot, func, reg, 4);
454
455 /*
456 * XXX: We assume that words readed from GT chip are BE.
457 * Should we set the mode explicitly during chip
458 * Initialization?
459 */
44
45#include <sys/param.h>
46#include <sys/systm.h>
47
48#include <sys/bus.h>
49#include <sys/interrupt.h>
50#include <sys/malloc.h>
51#include <sys/kernel.h>
52#include <sys/module.h>
53#include <sys/rman.h>
54
55#include <vm/vm.h>
56#include <vm/pmap.h>
57#include <vm/vm_extern.h>
58
59#include <machine/bus.h>
60#include <machine/cpu.h>
61#include <machine/pmap.h>
62
63#include <mips/malta/maltareg.h>
64
65#include <mips/malta/gtreg.h>
66#include <mips/malta/gtvar.h>
67
68#include <isa/isareg.h>
69#include <dev/ic/i8259.h>
70
71#include <dev/pci/pcireg.h>
72#include <dev/pci/pcivar.h>
73
74#include <dev/pci/pcib_private.h>
75#include "pcib_if.h"
76
77
78#define ICU_LEN 16 /* number of ISA IRQs */
79
80/*
81 * XXX: These defines are from NetBSD's <dev/ic/i8259reg.h>. Respective file
82 * from FreeBSD src tree <dev/ic/i8259.h> lacks some definitions.
83 */
84#define PIC_OCW1 1
85#define PIC_OCW2 0
86#define PIC_OCW3 0
87
88#define OCW2_SELECT 0
89#define OCW2_ILS(x) ((x) << 0) /* interrupt level select */
90
91#define OCW3_POLL_IRQ(x) ((x) & 0x7f)
92#define OCW3_POLL_PENDING (1U << 7)
93
94struct gt_pci_softc {
95 device_t sc_dev;
96 bus_space_tag_t sc_st;
97 bus_space_tag_t sc_pciio;
98 bus_space_tag_t sc_pcimem;
99 bus_space_handle_t sc_ioh_icu1;
100 bus_space_handle_t sc_ioh_icu2;
101 bus_space_handle_t sc_ioh_elcr;
102
103 int sc_busno;
104 struct rman sc_mem_rman;
105 struct rman sc_io_rman;
106 struct rman sc_irq_rman;
107 uint32_t sc_mem;
108 uint32_t sc_io;
109
110 struct resource *sc_irq;
111 struct intr_event *sc_eventstab[ICU_LEN];
112 uint16_t sc_imask;
113 uint16_t sc_elcr;
114
115 uint16_t sc_reserved;
116
117 void *sc_ih;
118};
119
120static void
121gt_pci_set_icus(struct gt_pci_softc *sc)
122{
123 /* Enable the cascade IRQ (2) if 8-15 is enabled. */
124 if ((sc->sc_imask & 0xff00) != 0xff00)
125 sc->sc_imask &= ~(1U << 2);
126 else
127 sc->sc_imask |= (1U << 2);
128
129 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW1,
130 sc->sc_imask & 0xff);
131 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, PIC_OCW1,
132 (sc->sc_imask >> 8) & 0xff);
133
134 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 0,
135 sc->sc_elcr & 0xff);
136 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 1,
137 (sc->sc_elcr >> 8) & 0xff);
138}
139
140static int
141gt_pci_intr(void *v)
142{
143 struct gt_pci_softc *sc = v;
144 struct intr_event *event;
145 int irq;
146
147 for (;;) {
148 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW3,
149 OCW3_SEL | OCW3_P);
150 irq = bus_space_read_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW3);
151 if ((irq & OCW3_POLL_PENDING) == 0)
152 {
153 return FILTER_HANDLED;
154 }
155
156 irq = OCW3_POLL_IRQ(irq);
157
158 if (irq == 2) {
159 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2,
160 PIC_OCW3, OCW3_SEL | OCW3_P);
161 irq = bus_space_read_1(sc->sc_pciio, sc->sc_ioh_icu2,
162 PIC_OCW3);
163 if (irq & OCW3_POLL_PENDING)
164 irq = OCW3_POLL_IRQ(irq) + 8;
165 else
166 irq = 2;
167 }
168
169 event = sc->sc_eventstab[irq];
170
171 if (!event || TAILQ_EMPTY(&event->ie_handlers))
172 continue;
173
174 /* TODO: frame instead of NULL? */
175 intr_event_handle(event, NULL);
176 /* XXX: Log stray IRQs */
177
178 /* Send a specific EOI to the 8259. */
179 if (irq > 7) {
180 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2,
181 PIC_OCW2, OCW2_SELECT | OCW2_EOI | OCW2_SL |
182 OCW2_ILS(irq & 7));
183 irq = 2;
184 }
185
186 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, PIC_OCW2,
187 OCW2_SELECT | OCW2_EOI | OCW2_SL | OCW2_ILS(irq));
188 }
189
190 return FILTER_HANDLED;
191}
192
193static int
194gt_pci_probe(device_t dev)
195{
196 device_set_desc(dev, "GT64120 PCI bridge");
197 return (0);
198}
199
200static int
201gt_pci_attach(device_t dev)
202{
203
204 uint32_t busno;
205 struct gt_pci_softc *sc = device_get_softc(dev);
206 int rid;
207
208 busno = 0;
209 sc->sc_dev = dev;
210 sc->sc_busno = busno;
211 sc->sc_pciio = MIPS_BUS_SPACE_IO;
212 sc->sc_pcimem = MIPS_BUS_SPACE_MEM;
213
214 /* Use KSEG1 to access IO ports for it is uncached */
215 sc->sc_io = MIPS_PHYS_TO_KSEG1(MALTA_PCI0_IO_BASE);
216 sc->sc_io_rman.rm_type = RMAN_ARRAY;
217 sc->sc_io_rman.rm_descr = "GT64120 PCI I/O Ports";
218 if (rman_init(&sc->sc_io_rman) != 0 ||
219 rman_manage_region(&sc->sc_io_rman, 0, 0xffff) != 0) {
220 panic("gt_pci_attach: failed to set up I/O rman");
221 }
222
223 /* Use KSEG1 to access PCI memory for it is uncached */
224 sc->sc_mem = MIPS_PHYS_TO_KSEG1(MALTA_PCIMEM1_BASE);
225 sc->sc_mem_rman.rm_type = RMAN_ARRAY;
226 sc->sc_mem_rman.rm_descr = "GT64120 PCI Memory";
227 if (rman_init(&sc->sc_mem_rman) != 0 ||
228 rman_manage_region(&sc->sc_mem_rman,
229 sc->sc_mem, sc->sc_mem + MALTA_PCIMEM1_SIZE) != 0) {
230 panic("gt_pci_attach: failed to set up memory rman");
231 }
232 sc->sc_irq_rman.rm_type = RMAN_ARRAY;
233 sc->sc_irq_rman.rm_descr = "GT64120 PCI IRQs";
234 if (rman_init(&sc->sc_irq_rman) != 0 ||
235 rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0)
236 panic("gt_pci_attach: failed to set up IRQ rman");
237
238 /*
239 * Map the PIC/ELCR registers.
240 */
241#if 0
242 if (bus_space_map(sc->sc_pciio, 0x4d0, 2, 0, &sc->sc_ioh_elcr) != 0)
243 device_printf(dev, "unable to map ELCR registers\n");
244 if (bus_space_map(sc->sc_pciio, IO_ICU1, 2, 0, &sc->sc_ioh_icu1) != 0)
245 device_printf(dev, "unable to map ICU1 registers\n");
246 if (bus_space_map(sc->sc_pciio, IO_ICU2, 2, 0, &sc->sc_ioh_icu2) != 0)
247 device_printf(dev, "unable to map ICU2 registers\n");
248#else
249 sc->sc_ioh_elcr = sc->sc_io + 0x4d0;
250 sc->sc_ioh_icu1 = sc->sc_io + IO_ICU1;
251 sc->sc_ioh_icu2 = sc->sc_io + IO_ICU2;
252#endif
253
254
255 /* All interrupts default to "masked off". */
256 sc->sc_imask = 0xffff;
257
258 /* All interrupts default to edge-triggered. */
259 sc->sc_elcr = 0;
260
261 /*
262 * Initialize the 8259s.
263 */
264 /* reset, program device, 4 bytes */
265 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 0,
266 ICW1_RESET | ICW1_IC4);
267 /*
268 * XXX: values from NetBSD's <dev/ic/i8259reg.h>
269 */
270 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
271 0/*XXX*/);
272 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
273 1 << 2);
274 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
275 ICW4_8086);
276
277 /* mask all interrupts */
278 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 0,
279 sc->sc_imask & 0xff);
280
281 /* enable special mask mode */
282 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
283 OCW3_SEL | OCW3_ESMM | OCW3_SMM);
284
285 /* read IRR by default */
286 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu1, 1,
287 OCW3_SEL | OCW3_RR);
288
289 /* reset, program device, 4 bytes */
290 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 0,
291 ICW1_RESET | ICW1_IC4);
292 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1,
293 0/*XXX*/);
294 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1,
295 1 << 2);
296 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1,
297 ICW4_8086);
298
299 /* mask all interrupts */
300 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 0,
301 sc->sc_imask & 0xff);
302
303 /* enable special mask mode */
304 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1,
305 OCW3_SEL | OCW3_ESMM | OCW3_SMM);
306
307 /* read IRR by default */
308 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_icu2, 1,
309 OCW3_SEL | OCW3_RR);
310
311 /*
312 * Default all interrupts to edge-triggered.
313 */
314 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 0,
315 sc->sc_elcr & 0xff);
316 bus_space_write_1(sc->sc_pciio, sc->sc_ioh_elcr, 1,
317 (sc->sc_elcr >> 8) & 0xff);
318
319 /*
320 * Some ISA interrupts are reserved for devices that
321 * we know are hard-wired to certain IRQs.
322 */
323 sc->sc_reserved =
324 (1U << 0) | /* timer */
325 (1U << 1) | /* keyboard controller (keyboard) */
326 (1U << 2) | /* PIC cascade */
327 (1U << 3) | /* COM 2 */
328 (1U << 4) | /* COM 1 */
329 (1U << 6) | /* floppy */
330 (1U << 7) | /* centronics */
331 (1U << 8) | /* RTC */
332 (1U << 9) | /* I2C */
333 (1U << 12) | /* keyboard controller (mouse) */
334 (1U << 14) | /* IDE primary */
335 (1U << 15); /* IDE secondary */
336
337 /* Hook up our interrupt handler. */
338 if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
339 MALTA_SOUTHBRIDGE_INTR, MALTA_SOUTHBRIDGE_INTR, 1,
340 RF_SHAREABLE | RF_ACTIVE)) == NULL) {
341 device_printf(dev, "unable to allocate IRQ resource\n");
342 return ENXIO;
343 }
344
345 if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC,
346 gt_pci_intr, NULL, sc, &sc->sc_ih))) {
347 device_printf(dev,
348 "WARNING: unable to register interrupt handler\n");
349 return ENXIO;
350 }
351
352 /* Initialize memory and i/o rmans. */
353 device_add_child(dev, "pci", busno);
354 return (bus_generic_attach(dev));
355}
356
357static int
358gt_pci_maxslots(device_t dev)
359{
360 return (PCI_SLOTMAX);
361}
362
363static int
364gt_pci_conf_setup(struct gt_pci_softc *sc, int bus, int slot, int func,
365 int reg, uint32_t *addr)
366{
367 *addr = (bus << 16) | (slot << 11) | (func << 8) | reg;
368
369 return (0);
370}
371
372static uint32_t
373gt_pci_read_config(device_t dev, int bus, int slot, int func, int reg,
374 int bytes)
375{
376 struct gt_pci_softc *sc = device_get_softc(dev);
377 uint32_t data;
378 uint32_t addr;
379 uint32_t shift, mask;
380
381 if (gt_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
382 return (uint32_t)(-1);
383
384 /* Clear cause register bits. */
385 GT_REGVAL(GT_INTR_CAUSE) = 0;
386
387 GT_REGVAL(GT_PCI0_CFG_ADDR) = (1 << 31) | addr;
388 data = GT_REGVAL(GT_PCI0_CFG_DATA);
389
390 /* Check for master abort. */
391 if (GT_REGVAL(GT_INTR_CAUSE) & (GTIC_MASABORT0 | GTIC_TARABORT0))
392 data = (uint32_t) -1;
393
394 /*
395 * XXX: We assume that words readed from GT chip are BE.
396 * Should we set the mode explicitly during chip
397 * Initialization?
398 */
399 switch(reg % 4)
400 {
401 case 3:
402 shift = 24;
403 break;
404 case 2:
405 shift = 16;
406 break;
407 case 1:
408 shift = 8;
409 break;
410 default:
411 shift = 0;
412 break;
413 }
414
415 switch(bytes)
416 {
417 case 1:
418 mask = 0xff;
419 data = (data >> shift) & mask;
420 break;
421 case 2:
422 mask = 0xffff;
423 if(reg % 4 == 0)
424 data = data & mask;
425 else
426 data = (data >> 16) & mask;
427 break;
428 case 4:
429 break;
430 default:
431 panic("gt_pci_readconfig: wrong bytes count");
432 break;
433 }
434#if 0
435 printf("PCICONF_READ(%02x:%02x.%02x[%04x] -> %02x(%d)\n",
436 bus, slot, func, reg, data, bytes);
437#endif
438
439 return (data);
440}
441
442static void
443gt_pci_write_config(device_t dev, int bus, int slot, int func, int reg,
444 uint32_t data, int bytes)
445{
446 struct gt_pci_softc *sc = device_get_softc(dev);
447 uint32_t addr;
448 uint32_t reg_data;
449 uint32_t shift, mask;
450
451 if(bytes != 4)
452 {
453 reg_data = gt_pci_read_config(dev, bus, slot, func, reg, 4);
454
455 /*
456 * XXX: We assume that words readed from GT chip are BE.
457 * Should we set the mode explicitly during chip
458 * Initialization?
459 */
460 switch(reg % 4)
461 {
462 case 3:
463 shift = 24;
464 break;
465 case 2:
466 shift = 16;
467 break;
468 case 1:
469 shift = 8;
470 break;
471 default:
472 shift = 0;
473 break;
474 }
460 shift = 8 * (reg & 3);
475
476 switch(bytes)
477 {
478 case 1:
479 mask = 0xff;
480 data = (reg_data & ~ (mask << shift)) | (data << shift);
481 break;
482 case 2:
483 mask = 0xffff;
484 if(reg % 4 == 0)
485 data = (reg_data & ~mask) | data;
486 else
487 data = (reg_data & ~ (mask << shift)) |
488 (data << shift);
489 break;
490 case 4:
491 break;
492 default:
493 panic("gt_pci_readconfig: wrong bytes count");
494 break;
495 }
496 }
497
498 if (gt_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
499 return;
500
501 /* The galileo has problems accessing device 31. */
502 if (bus == 0 && slot == 31)
503 return;
504
505 /* XXX: no support for bus > 0 yet */
506 if (bus > 0)
507 return;
508
509 /* Clear cause register bits. */
510 GT_REGVAL(GT_INTR_CAUSE) = 0;
511
512 GT_REGVAL(GT_PCI0_CFG_ADDR) = (1 << 31) | addr;
513 GT_REGVAL(GT_PCI0_CFG_DATA) = data;
514}
515
516static int
517gt_pci_route_interrupt(device_t pcib, device_t dev, int pin)
518{
519 int bus;
520 int device;
521 int func;
522 /* struct gt_pci_softc *sc = device_get_softc(pcib); */
523 bus = pci_get_bus(dev);
524 device = pci_get_slot(dev);
525 func = pci_get_function(dev);
526 /*
527 * XXXMIPS: We need routing logic. This is just a stub .
528 */
529 switch (device) {
530 case 9: /*
531 * PIIX4 IDE adapter. HW IRQ0
532 */
533 return 0;
534 default:
535 printf("No mapping for %d/%d/%d/%d\n", bus, device, func, pin);
536
537 }
538 return (0);
539
540}
541
542static int
543gt_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
544{
545 struct gt_pci_softc *sc = device_get_softc(dev);
546 switch (which) {
547 case PCIB_IVAR_DOMAIN:
548 *result = 0;
549 return (0);
550 case PCIB_IVAR_BUS:
551 *result = sc->sc_busno;
552 return (0);
553
554 }
555 return (ENOENT);
556}
557
558static int
559gt_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
560{
561 struct gt_pci_softc * sc = device_get_softc(dev);
562
563 switch (which) {
564 case PCIB_IVAR_BUS:
565 sc->sc_busno = result;
566 return (0);
567 }
568 return (ENOENT);
569}
570
571static struct resource *
572gt_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
573 u_long start, u_long end, u_long count, u_int flags)
574{
575 struct gt_pci_softc *sc = device_get_softc(bus);
576 struct resource *rv = NULL;
577 struct rman *rm;
578 bus_space_tag_t bt = 0;
579 bus_space_handle_t bh = 0;
580
581 switch (type) {
582 case SYS_RES_IRQ:
583 rm = &sc->sc_irq_rman;
584 break;
585 case SYS_RES_MEMORY:
586 rm = &sc->sc_mem_rman;
587 bt = sc->sc_pcimem;
588 bh = sc->sc_mem;
589 break;
590 case SYS_RES_IOPORT:
591 rm = &sc->sc_io_rman;
592 bt = sc->sc_pciio;
593 bh = sc->sc_io;
594 break;
595 default:
596 return (NULL);
597 }
598
599 rv = rman_reserve_resource(rm, start, end, count, flags, child);
600 if (rv == NULL)
601 return (NULL);
602 rman_set_rid(rv, *rid);
603 if (type != SYS_RES_IRQ) {
604 bh += (rman_get_start(rv));
605
606 rman_set_bustag(rv, bt);
607 rman_set_bushandle(rv, bh);
608 if (flags & RF_ACTIVE) {
609 if (bus_activate_resource(child, type, *rid, rv)) {
610 rman_release_resource(rv);
611 return (NULL);
612 }
613 }
614 }
615 return (rv);
616}
617
618static int
619gt_pci_activate_resource(device_t bus, device_t child, int type, int rid,
620 struct resource *r)
621{
622 bus_space_handle_t p;
623 int error;
624
625 if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) {
626 error = bus_space_map(rman_get_bustag(r),
627 rman_get_bushandle(r), rman_get_size(r), 0, &p);
628 if (error)
629 return (error);
630 rman_set_bushandle(r, p);
631 }
632 return (rman_activate_resource(r));
633}
634
635static int
636gt_pci_setup_intr(device_t dev, device_t child, struct resource *ires,
637 int flags, driver_filter_t *filt, driver_intr_t *handler,
638 void *arg, void **cookiep)
639{
640 struct gt_pci_softc *sc = device_get_softc(dev);
641 struct intr_event *event;
642 int irq, error;
643
644 irq = rman_get_start(ires);
645 if (irq >= ICU_LEN || irq == 2)
646 panic("%s: bad irq or type", __func__);
647
648 event = sc->sc_eventstab[irq];
649 if (event == NULL) {
650 error = intr_event_create(&event, (void *)irq, 0, irq,
651 (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq,
652 (mask_fn)mips_unmask_irq, NULL, "gt_pci intr%d:", irq);
653 if (error)
654 return 0;
655 sc->sc_eventstab[irq] = event;
656 }
657
658 intr_event_add_handler(event, device_get_nameunit(child), filt,
659 handler, arg, intr_priority(flags), flags, cookiep);
660
661 /* Enable it, set trigger mode. */
662 sc->sc_imask &= ~(1 << irq);
663 sc->sc_elcr &= ~(1 << irq);
664
665 gt_pci_set_icus(sc);
666
667 return 0;
668}
669
670static int
671gt_pci_teardown_intr(device_t dev, device_t child, struct resource *res,
672 void *cookie)
673{
674 return (intr_event_remove_handler(cookie));
675}
676
677static device_method_t gt_pci_methods[] = {
678 /* Device interface */
679 DEVMETHOD(device_probe, gt_pci_probe),
680 DEVMETHOD(device_attach, gt_pci_attach),
681 DEVMETHOD(device_shutdown, bus_generic_shutdown),
682 DEVMETHOD(device_suspend, bus_generic_suspend),
683 DEVMETHOD(device_resume, bus_generic_resume),
684
685 /* Bus interface */
686 DEVMETHOD(bus_print_child, bus_generic_print_child),
687 DEVMETHOD(bus_read_ivar, gt_read_ivar),
688 DEVMETHOD(bus_write_ivar, gt_write_ivar),
689 DEVMETHOD(bus_alloc_resource, gt_pci_alloc_resource),
690 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
691 DEVMETHOD(bus_activate_resource, gt_pci_activate_resource),
692 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
693 DEVMETHOD(bus_setup_intr, gt_pci_setup_intr),
694 DEVMETHOD(bus_teardown_intr, gt_pci_teardown_intr),
695
696 /* pcib interface */
697 DEVMETHOD(pcib_maxslots, gt_pci_maxslots),
698 DEVMETHOD(pcib_read_config, gt_pci_read_config),
699 DEVMETHOD(pcib_write_config, gt_pci_write_config),
700 DEVMETHOD(pcib_route_interrupt, gt_pci_route_interrupt),
701
702 {0, 0}
703};
704
705static driver_t gt_pci_driver = {
706 "pcib",
707 gt_pci_methods,
708 sizeof(struct gt_pci_softc),
709};
710
711static devclass_t gt_pci_devclass;
712
713DRIVER_MODULE(gt_pci, gt, gt_pci_driver, gt_pci_devclass, 0, 0);
461
462 switch(bytes)
463 {
464 case 1:
465 mask = 0xff;
466 data = (reg_data & ~ (mask << shift)) | (data << shift);
467 break;
468 case 2:
469 mask = 0xffff;
470 if(reg % 4 == 0)
471 data = (reg_data & ~mask) | data;
472 else
473 data = (reg_data & ~ (mask << shift)) |
474 (data << shift);
475 break;
476 case 4:
477 break;
478 default:
479 panic("gt_pci_readconfig: wrong bytes count");
480 break;
481 }
482 }
483
484 if (gt_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
485 return;
486
487 /* The galileo has problems accessing device 31. */
488 if (bus == 0 && slot == 31)
489 return;
490
491 /* XXX: no support for bus > 0 yet */
492 if (bus > 0)
493 return;
494
495 /* Clear cause register bits. */
496 GT_REGVAL(GT_INTR_CAUSE) = 0;
497
498 GT_REGVAL(GT_PCI0_CFG_ADDR) = (1 << 31) | addr;
499 GT_REGVAL(GT_PCI0_CFG_DATA) = data;
500}
501
502static int
503gt_pci_route_interrupt(device_t pcib, device_t dev, int pin)
504{
505 int bus;
506 int device;
507 int func;
508 /* struct gt_pci_softc *sc = device_get_softc(pcib); */
509 bus = pci_get_bus(dev);
510 device = pci_get_slot(dev);
511 func = pci_get_function(dev);
512 /*
513 * XXXMIPS: We need routing logic. This is just a stub .
514 */
515 switch (device) {
516 case 9: /*
517 * PIIX4 IDE adapter. HW IRQ0
518 */
519 return 0;
520 default:
521 printf("No mapping for %d/%d/%d/%d\n", bus, device, func, pin);
522
523 }
524 return (0);
525
526}
527
528static int
529gt_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
530{
531 struct gt_pci_softc *sc = device_get_softc(dev);
532 switch (which) {
533 case PCIB_IVAR_DOMAIN:
534 *result = 0;
535 return (0);
536 case PCIB_IVAR_BUS:
537 *result = sc->sc_busno;
538 return (0);
539
540 }
541 return (ENOENT);
542}
543
544static int
545gt_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
546{
547 struct gt_pci_softc * sc = device_get_softc(dev);
548
549 switch (which) {
550 case PCIB_IVAR_BUS:
551 sc->sc_busno = result;
552 return (0);
553 }
554 return (ENOENT);
555}
556
557static struct resource *
558gt_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
559 u_long start, u_long end, u_long count, u_int flags)
560{
561 struct gt_pci_softc *sc = device_get_softc(bus);
562 struct resource *rv = NULL;
563 struct rman *rm;
564 bus_space_tag_t bt = 0;
565 bus_space_handle_t bh = 0;
566
567 switch (type) {
568 case SYS_RES_IRQ:
569 rm = &sc->sc_irq_rman;
570 break;
571 case SYS_RES_MEMORY:
572 rm = &sc->sc_mem_rman;
573 bt = sc->sc_pcimem;
574 bh = sc->sc_mem;
575 break;
576 case SYS_RES_IOPORT:
577 rm = &sc->sc_io_rman;
578 bt = sc->sc_pciio;
579 bh = sc->sc_io;
580 break;
581 default:
582 return (NULL);
583 }
584
585 rv = rman_reserve_resource(rm, start, end, count, flags, child);
586 if (rv == NULL)
587 return (NULL);
588 rman_set_rid(rv, *rid);
589 if (type != SYS_RES_IRQ) {
590 bh += (rman_get_start(rv));
591
592 rman_set_bustag(rv, bt);
593 rman_set_bushandle(rv, bh);
594 if (flags & RF_ACTIVE) {
595 if (bus_activate_resource(child, type, *rid, rv)) {
596 rman_release_resource(rv);
597 return (NULL);
598 }
599 }
600 }
601 return (rv);
602}
603
604static int
605gt_pci_activate_resource(device_t bus, device_t child, int type, int rid,
606 struct resource *r)
607{
608 bus_space_handle_t p;
609 int error;
610
611 if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) {
612 error = bus_space_map(rman_get_bustag(r),
613 rman_get_bushandle(r), rman_get_size(r), 0, &p);
614 if (error)
615 return (error);
616 rman_set_bushandle(r, p);
617 }
618 return (rman_activate_resource(r));
619}
620
621static int
622gt_pci_setup_intr(device_t dev, device_t child, struct resource *ires,
623 int flags, driver_filter_t *filt, driver_intr_t *handler,
624 void *arg, void **cookiep)
625{
626 struct gt_pci_softc *sc = device_get_softc(dev);
627 struct intr_event *event;
628 int irq, error;
629
630 irq = rman_get_start(ires);
631 if (irq >= ICU_LEN || irq == 2)
632 panic("%s: bad irq or type", __func__);
633
634 event = sc->sc_eventstab[irq];
635 if (event == NULL) {
636 error = intr_event_create(&event, (void *)irq, 0, irq,
637 (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq,
638 (mask_fn)mips_unmask_irq, NULL, "gt_pci intr%d:", irq);
639 if (error)
640 return 0;
641 sc->sc_eventstab[irq] = event;
642 }
643
644 intr_event_add_handler(event, device_get_nameunit(child), filt,
645 handler, arg, intr_priority(flags), flags, cookiep);
646
647 /* Enable it, set trigger mode. */
648 sc->sc_imask &= ~(1 << irq);
649 sc->sc_elcr &= ~(1 << irq);
650
651 gt_pci_set_icus(sc);
652
653 return 0;
654}
655
656static int
657gt_pci_teardown_intr(device_t dev, device_t child, struct resource *res,
658 void *cookie)
659{
660 return (intr_event_remove_handler(cookie));
661}
662
663static device_method_t gt_pci_methods[] = {
664 /* Device interface */
665 DEVMETHOD(device_probe, gt_pci_probe),
666 DEVMETHOD(device_attach, gt_pci_attach),
667 DEVMETHOD(device_shutdown, bus_generic_shutdown),
668 DEVMETHOD(device_suspend, bus_generic_suspend),
669 DEVMETHOD(device_resume, bus_generic_resume),
670
671 /* Bus interface */
672 DEVMETHOD(bus_print_child, bus_generic_print_child),
673 DEVMETHOD(bus_read_ivar, gt_read_ivar),
674 DEVMETHOD(bus_write_ivar, gt_write_ivar),
675 DEVMETHOD(bus_alloc_resource, gt_pci_alloc_resource),
676 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
677 DEVMETHOD(bus_activate_resource, gt_pci_activate_resource),
678 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
679 DEVMETHOD(bus_setup_intr, gt_pci_setup_intr),
680 DEVMETHOD(bus_teardown_intr, gt_pci_teardown_intr),
681
682 /* pcib interface */
683 DEVMETHOD(pcib_maxslots, gt_pci_maxslots),
684 DEVMETHOD(pcib_read_config, gt_pci_read_config),
685 DEVMETHOD(pcib_write_config, gt_pci_write_config),
686 DEVMETHOD(pcib_route_interrupt, gt_pci_route_interrupt),
687
688 {0, 0}
689};
690
691static driver_t gt_pci_driver = {
692 "pcib",
693 gt_pci_methods,
694 sizeof(struct gt_pci_softc),
695};
696
697static devclass_t gt_pci_devclass;
698
699DRIVER_MODULE(gt_pci, gt, gt_pci_driver, gt_pci_devclass, 0, 0);