Deleted Added
full compact
ebus.c (91967) ebus.c (93067)
1/*
2 * Copyright (c) 1999, 2000 Matthew R. Green
3 * Copyright (c) 2001 Thomas Moestl <tmm@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 14 unchanged lines hidden (view full) ---

23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * from: NetBSD: ebus.c,v 1.26 2001/09/10 16:27:53 eeh Exp
30 *
1/*
2 * Copyright (c) 1999, 2000 Matthew R. Green
3 * Copyright (c) 2001 Thomas Moestl <tmm@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 14 unchanged lines hidden (view full) ---

23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * from: NetBSD: ebus.c,v 1.26 2001/09/10 16:27:53 eeh Exp
30 *
31 * $FreeBSD: head/sys/sparc64/ebus/ebus.c 91967 2002-03-09 22:02:02Z tmm $
31 * $FreeBSD: head/sys/sparc64/ebus/ebus.c 93067 2002-03-24 02:11:06Z tmm $
32 */
33
34#include "opt_ebus.h"
35
36/*
37 * UltraSPARC 5 and beyond ebus support.
38 *
39 * note that this driver is not complete:

--- 9 unchanged lines hidden (view full) ---

49 */
50
51#include <sys/param.h>
52#include <sys/systm.h>
53#include <sys/bus.h>
54#include <sys/kernel.h>
55#include <sys/malloc.h>
56
32 */
33
34#include "opt_ebus.h"
35
36/*
37 * UltraSPARC 5 and beyond ebus support.
38 *
39 * note that this driver is not complete:

--- 9 unchanged lines hidden (view full) ---

49 */
50
51#include <sys/param.h>
52#include <sys/systm.h>
53#include <sys/bus.h>
54#include <sys/kernel.h>
55#include <sys/malloc.h>
56
57#include <ofw/openfirm.h>
58#include <ofw/ofw_pci.h>
59
57#include <machine/bus.h>
58#include <machine/ofw_bus.h>
59#include <machine/resource.h>
60
60#include <machine/bus.h>
61#include <machine/ofw_bus.h>
62#include <machine/resource.h>
63
61#include <ofw/openfirm.h>
62#include <ofw/ofw_pci.h>
63
64#include <pci/pcireg.h>
65#include <pci/pcivar.h>
66
67#include <sparc64/pci/ofw_pci.h>
68
69/*
70 * The register, ranges and interrupt map properties are identical to the ISA
71 * ones.

--- 22 unchanged lines hidden (view full) ---

94 struct resource_list edi_rl;
95};
96
97struct ebus_softc {
98 phandle_t sc_node;
99
100 struct isa_ranges *sc_range;
101
64#include <pci/pcireg.h>
65#include <pci/pcivar.h>
66
67#include <sparc64/pci/ofw_pci.h>
68
69/*
70 * The register, ranges and interrupt map properties are identical to the ISA
71 * ones.

--- 22 unchanged lines hidden (view full) ---

94 struct resource_list edi_rl;
95};
96
97struct ebus_softc {
98 phandle_t sc_node;
99
100 struct isa_ranges *sc_range;
101
102 struct ofw_pci_register *sc_reg;
103
104 int sc_imap_type;
105
106 struct isa_imap *sc_ebus_imap;
107 struct isa_imap_msk sc_ebus_imapmsk;
108
109 struct ofw_pci_imap *sc_pci_imap;
110 struct ofw_pci_imap_msk sc_pci_imapmsk;
111
112 int sc_nrange;
102 int sc_nrange;
113 int sc_nreg;
114 int sc_nimap;
115};
116
117static int ebus_probe(device_t);
118static int ebus_print_child(device_t, device_t);
119static void ebus_probe_nomatch(device_t, device_t);
120static int ebus_read_ivar(device_t, device_t, int, uintptr_t *);
121static int ebus_write_ivar(device_t, device_t, int, uintptr_t);
122static struct resource *ebus_alloc_resource(device_t, device_t, int, int *,
123 u_long, u_long, u_long, u_int);
124static struct resource_list *ebus_get_resource_list(device_t, device_t);
125
126static struct ebus_devinfo *ebus_setup_dinfo(struct ebus_softc *,
127 phandle_t, char *);
128static void ebus_destroy_dinfo(struct ebus_devinfo *);
129static int ebus_print_res(struct ebus_devinfo *);
103 int sc_nimap;
104};
105
106static int ebus_probe(device_t);
107static int ebus_print_child(device_t, device_t);
108static void ebus_probe_nomatch(device_t, device_t);
109static int ebus_read_ivar(device_t, device_t, int, uintptr_t *);
110static int ebus_write_ivar(device_t, device_t, int, uintptr_t);
111static struct resource *ebus_alloc_resource(device_t, device_t, int, int *,
112 u_long, u_long, u_long, u_int);
113static struct resource_list *ebus_get_resource_list(device_t, device_t);
114
115static struct ebus_devinfo *ebus_setup_dinfo(struct ebus_softc *,
116 phandle_t, char *);
117static void ebus_destroy_dinfo(struct ebus_devinfo *);
118static int ebus_print_res(struct ebus_devinfo *);
130static int ebus_map_intr(struct ebus_softc *, int, struct isa_regs *, int);
131
132static device_method_t ebus_methods[] = {
133 /* Device interface */
134 DEVMETHOD(device_probe, ebus_probe),
135 DEVMETHOD(device_attach, bus_generic_attach),
136
137 /* Bus interface */
138 DEVMETHOD(bus_print_child, ebus_print_child),

--- 55 unchanged lines hidden (view full) ---

194 else
195 return (ENXIO);
196
197 device_printf(dev, "revision 0x%02x\n", pci_get_revid(dev));
198
199 sc = device_get_softc(dev);
200 sc->sc_node = node;
201
119
120static device_method_t ebus_methods[] = {
121 /* Device interface */
122 DEVMETHOD(device_probe, ebus_probe),
123 DEVMETHOD(device_attach, bus_generic_attach),
124
125 /* Bus interface */
126 DEVMETHOD(bus_print_child, ebus_print_child),

--- 55 unchanged lines hidden (view full) ---

182 else
183 return (ENXIO);
184
185 device_printf(dev, "revision 0x%02x\n", pci_get_revid(dev));
186
187 sc = device_get_softc(dev);
188 sc->sc_node = node;
189
202 /*
203 * Fill in our softc with information from the prom.
204 * There are two possible cases how interrupt mapping needs to be
205 * handled:
206 * - if the ebus node has an interrupt-map properties, the interrut
207 * numbers in child nodes can be mapped using lookups in this map,
208 * using the registers of the child node in question to find the
209 * map entry
210 * - if it does not have such a properties, the interrupts are mapped
211 * in the next higher interrupt map (PCI in our case), using the
212 * interrupt number of the child, but the registers of the ebus
213 * node, to find the mapping.
214 */
215 sc->sc_imap_type = EBUS_IT_EBUS;
216 sc->sc_nimap = OF_getprop_alloc(node, "interrupt-map",
217 sizeof(*sc->sc_ebus_imap), (void **)&sc->sc_ebus_imap);
218 if (sc->sc_nimap == -1) {
219 sc->sc_nimap = ofw_pci_find_imap(node, &sc->sc_pci_imap,
220 &sc->sc_pci_imapmsk);
221 if (sc->sc_nimap == -1)
222 panic("ebus_probe: no interrupt map found");
223 sc->sc_imap_type = EBUS_IT_PCI;
224 } else {
225 if (OF_getprop(node, "interrupt-map-mask",
226 &sc->sc_ebus_imapmsk, sizeof(sc->sc_ebus_imapmsk)) == -1) {
227 panic("ebus_probe: could not get ebus "
228 "interrupt-map-mask");
229 }
230 }
231
232 sc->sc_nrange = OF_getprop_alloc(node, "ranges",
233 sizeof(*sc->sc_range), (void **)&sc->sc_range);
190 sc->sc_nrange = OF_getprop_alloc(node, "ranges",
191 sizeof(*sc->sc_range), (void **)&sc->sc_range);
234 sc->sc_nreg = OF_getprop_alloc(node, "reg",
235 sizeof(*sc->sc_reg), (void **)&sc->sc_reg);
236 if (sc->sc_nrange == -1 || sc->sc_nreg == -1)
237 panic("ebus_attach: could not get ranges/reg property");
192 if (sc->sc_nrange == -1)
193 panic("ebus_attach: could not get ranges property");
238
239 /*
240 * now attach all our children
241 */
242 DPRINTF(EDB_CHILD, ("ebus node %08x, searching children...\n", node));
243 for (node = OF_child(node); node > 0; node = OF_peer(node)) {
244 if ((OF_getprop_alloc(node, "name", 1, (void **)&cname)) == -1)
245 continue;

--- 160 unchanged lines hidden (view full) ---

406 return (&edi->edi_rl);
407}
408
409static struct ebus_devinfo *
410ebus_setup_dinfo(struct ebus_softc *sc, phandle_t node, char *name)
411{
412 struct ebus_devinfo *edi;
413 struct isa_regs *reg;
194
195 /*
196 * now attach all our children
197 */
198 DPRINTF(EDB_CHILD, ("ebus node %08x, searching children...\n", node));
199 for (node = OF_child(node); node > 0; node = OF_peer(node)) {
200 if ((OF_getprop_alloc(node, "name", 1, (void **)&cname)) == -1)
201 continue;

--- 160 unchanged lines hidden (view full) ---

362 return (&edi->edi_rl);
363}
364
365static struct ebus_devinfo *
366ebus_setup_dinfo(struct ebus_softc *sc, phandle_t node, char *name)
367{
368 struct ebus_devinfo *edi;
369 struct isa_regs *reg;
414 u_int32_t *intrs;
370 u_int32_t *intrs, intr;
415 u_int64_t start;
371 u_int64_t start;
416 int nreg, nintr, i, intr;
372 int nreg, nintr, i;
417
418 edi = malloc(sizeof(*edi), M_DEVBUF, M_ZERO | M_WAITOK);
419 if (edi == NULL)
420 return (NULL);
421 resource_list_init(&edi->edi_rl);
422 edi->edi_name = name;
423 edi->edi_node = node;
424

--- 12 unchanged lines hidden (view full) ---

437 */
438 resource_list_add(&edi->edi_rl, SYS_RES_IOPORT, i,
439 start, start + reg[i].size - 1, reg[i].size);
440 }
441
442 nintr = OF_getprop_alloc(node, "interrupts", sizeof(*intrs),
443 (void **)&intrs);
444 for (i = 0; i < nintr; i++) {
373
374 edi = malloc(sizeof(*edi), M_DEVBUF, M_ZERO | M_WAITOK);
375 if (edi == NULL)
376 return (NULL);
377 resource_list_init(&edi->edi_rl);
378 edi->edi_name = name;
379 edi->edi_node = node;
380

--- 12 unchanged lines hidden (view full) ---

393 */
394 resource_list_add(&edi->edi_rl, SYS_RES_IOPORT, i,
395 start, start + reg[i].size - 1, reg[i].size);
396 }
397
398 nintr = OF_getprop_alloc(node, "interrupts", sizeof(*intrs),
399 (void **)&intrs);
400 for (i = 0; i < nintr; i++) {
445 intr = ebus_map_intr(sc, intrs[i], reg, nreg);
446 if (intr == -1)
401 intr = ofw_bus_route_intr(node, intrs[i]);
402 if (intr == ORIR_NOTFOUND) {
447 panic("ebus_setup_dinfo: could not map ebus "
448 "interrupt %d", intrs[i]);
403 panic("ebus_setup_dinfo: could not map ebus "
404 "interrupt %d", intrs[i]);
405 }
449 resource_list_add(&edi->edi_rl, SYS_RES_IRQ, i,
450 intr, intr, 1);
451 }
452 free(reg, M_OFWPROP);
453
454 return (edi);
455}
456

--- 17 unchanged lines hidden (view full) ---

474
475 retval = 0;
476 retval += resource_list_print_type(&edi->edi_rl, "addr", SYS_RES_IOPORT,
477 "%#lx");
478 retval += resource_list_print_type(&edi->edi_rl, "irq", SYS_RES_IRQ,
479 "%ld");
480 return (retval);
481}
406 resource_list_add(&edi->edi_rl, SYS_RES_IRQ, i,
407 intr, intr, 1);
408 }
409 free(reg, M_OFWPROP);
410
411 return (edi);
412}
413

--- 17 unchanged lines hidden (view full) ---

431
432 retval = 0;
433 retval += resource_list_print_type(&edi->edi_rl, "addr", SYS_RES_IOPORT,
434 "%#lx");
435 retval += resource_list_print_type(&edi->edi_rl, "irq", SYS_RES_IRQ,
436 "%ld");
437 return (retval);
438}
482
483static int
484ebus_map_intr(struct ebus_softc *sc, int intr, struct isa_regs *regs,
485 int nregs)
486{
487 int rv;
488
489 if (sc->sc_imap_type == EBUS_IT_PCI) {
490 rv = ofw_pci_route_intr2(intr, sc->sc_reg, sc->sc_pci_imap,
491 sc->sc_nimap, &sc->sc_pci_imapmsk);
492 if (rv == 255)
493 return (-1);
494 return (rv);
495 }
496 return (ofw_isa_map_intr(sc->sc_ebus_imap, sc->sc_nimap,
497 &sc->sc_ebus_imapmsk, intr, regs, nregs));
498}