ofw_pci.c (90613) | ofw_pci.c (93067) |
---|---|
1/* 2 * Copyright (c) 1999, 2000 Matthew R. Green 3 * All rights reserved. 4 * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. 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: psycho.c,v 1.35 2001/09/10 16:17:06 eeh Exp 30 * | 1/* 2 * Copyright (c) 1999, 2000 Matthew R. Green 3 * All rights reserved. 4 * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. 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: psycho.c,v 1.35 2001/09/10 16:17:06 eeh Exp 30 * |
31 * $FreeBSD: head/sys/sparc64/pci/ofw_pci.c 90613 2002-02-13 15:44:58Z tmm $ | 31 * $FreeBSD: head/sys/sparc64/pci/ofw_pci.c 93067 2002-03-24 02:11:06Z tmm $ |
32 */ 33 34#include "opt_ofw_pci.h" 35 36#include <sys/param.h> 37#include <sys/kernel.h> 38#include <sys/systm.h> 39#include <sys/bus.h> --- 5 unchanged lines hidden (view full) --- 45#include <dev/ofw/openfirm.h> 46 47#include <sparc64/pci/ofw_pci.h> 48 49#include <machine/ofw_bus.h> 50 51#include "pcib_if.h" 52 | 32 */ 33 34#include "opt_ofw_pci.h" 35 36#include <sys/param.h> 37#include <sys/kernel.h> 38#include <sys/systm.h> 39#include <sys/bus.h> --- 5 unchanged lines hidden (view full) --- 45#include <dev/ofw/openfirm.h> 46 47#include <sparc64/pci/ofw_pci.h> 48 49#include <machine/ofw_bus.h> 50 51#include "pcib_if.h" 52 |
53/* 54 * Find the interrupt-map properties for a node. This might not be a property 55 * of the parent, because there may be bridges in between, so go up through the 56 * tree to find it. 57 * This seems to be only needed for PCI systems, so it has not been moved to 58 * ofw_bus.c 59 */ 60int 61ofw_pci_find_imap(phandle_t node, struct ofw_pci_imap **imap, 62 struct ofw_pci_imap_msk *imapmsk) | 53u_int32_t 54ofw_pci_route_intr(phandle_t node) |
63{ | 55{ |
64 int nimap; | 56 u_int32_t rv; |
65 | 57 |
66 nimap = -1; 67 while ((node = OF_parent(node)) != 0) { 68 if ((nimap = OF_getprop_alloc(node, "interrupt-map", 69 sizeof(**imap), (void **)imap)) == -1 || 70 OF_getprop(node, "interrupt-map-mask", 71 imapmsk, sizeof(*imapmsk)) == -1) { 72 if (*imap != NULL) { 73 free(*imap, M_OFWPROP); 74 *imap = NULL; 75 } 76 nimap = -1; 77 } else 78 break; 79 } 80 return (nimap); 81} 82 83/* 84 * Route an interrupt using the firmware nodes. Returns 255 for interrupts 85 * that cannot be routed (suitable for the PCI code). 86 */ 87int 88ofw_pci_route_intr2(int intr, struct ofw_pci_register *pcir, 89 struct ofw_pci_imap *imap, int nimap, struct ofw_pci_imap_msk *imapmsk) 90{ 91 char regm[12]; 92 int cintr; 93 94 cintr = ofw_bus_route_intr(intr, pcir, sizeof(*pcir), 12, 1, imap, 95 nimap, imapmsk, regm); 96 if (cintr == -1) | 58 rv = ofw_bus_route_intr(node, ORIP_NOINT); 59 if (rv == ORIR_NOTFOUND) |
97 return (255); | 60 return (255); |
98 else 99 return (cintr); | 61 return (rv); |
100} 101 | 62} 63 |
102int 103ofw_pci_route_intr(phandle_t node, struct ofw_pci_register *pcir, 104 struct ofw_pci_imap *intrmap, int nintrmap, 105 struct ofw_pci_imap_msk *intrmapmsk) 106{ 107 int intr; 108 109 if (OF_getprop(node, "interrupts", &intr, sizeof(intr)) == -1) 110 return (255); 111 112 return (ofw_pci_route_intr2(intr, pcir, intrmap, nintrmap, intrmapmsk)); 113} 114 | |
115#define OFW_PCI_PCIBUS "pci" 116/* 117 * Walk the PCI bus hierarchy, starting with the root PCI bus and descending 118 * through bridges, and initialize the interrupt line configuration registers 119 * of attached devices using firmware information. 120 */ 121void | 64#define OFW_PCI_PCIBUS "pci" 65/* 66 * Walk the PCI bus hierarchy, starting with the root PCI bus and descending 67 * through bridges, and initialize the interrupt line configuration registers 68 * of attached devices using firmware information. 69 */ 70void |
122ofw_pci_init_intr(device_t dev, phandle_t bus, struct ofw_pci_imap *intrmap, 123 int nintrmap, struct ofw_pci_imap_msk *intrmapmsk) | 71ofw_pci_init_intr(device_t dev, phandle_t bus) |
124{ | 72{ |
125 struct ofw_pci_imap_msk lintrmapmsk; | |
126 struct ofw_pci_register pcir; 127 phandle_t node; 128 char type[32]; 129 int intr; 130 int freemap; 131 132 if ((node = OF_child(bus)) == 0) 133 return; --- 7 unchanged lines hidden (view full) --- 141 type[sizeof(type) - 1] = '\0'; 142 if (strcmp(type, OFW_PCI_PCIBUS) == 0) { 143 /* 144 * This is a pci-pci bridge, recurse to initialize the 145 * child bus. The hierarchy is usually at most 2 levels 146 * deep, so recursion is feasible. 147 */ 148#ifdef OFW_PCI_DEBUG | 73 struct ofw_pci_register pcir; 74 phandle_t node; 75 char type[32]; 76 int intr; 77 int freemap; 78 79 if ((node = OF_child(bus)) == 0) 80 return; --- 7 unchanged lines hidden (view full) --- 88 type[sizeof(type) - 1] = '\0'; 89 if (strcmp(type, OFW_PCI_PCIBUS) == 0) { 90 /* 91 * This is a pci-pci bridge, recurse to initialize the 92 * child bus. The hierarchy is usually at most 2 levels 93 * deep, so recursion is feasible. 94 */ 95#ifdef OFW_PCI_DEBUG |
149 device_printf(dev, __func__": descending to " 150 "subordinate PCI bus\n"); | 96 device_printf(dev, "%s: descending to " 97 "subordinate PCI bus\n", __func__); |
151#endif | 98#endif |
152 ofw_pci_init_intr(dev, node, NULL, 0, NULL); | 99 ofw_pci_init_intr(dev, node); |
153 } else { 154 if (OF_getprop(node, "reg", &pcir, sizeof(pcir)) == -1) 155 panic("ofw_pci_route_intr: OF_getprop failed"); | 100 } else { 101 if (OF_getprop(node, "reg", &pcir, sizeof(pcir)) == -1) 102 panic("ofw_pci_route_intr: OF_getprop failed"); |
156 /* 157 * If we didn't get interrupt map properties passed, 158 * try to find them now. On some systems, buses that 159 * have no non-bridge children have no such properties, 160 * so only try to find them at need. 161 */ 162 if (intrmap == NULL) { 163 nintrmap = OF_getprop_alloc(bus, 164 "interrupt-map", sizeof(*intrmap), 165 (void **)&intrmap); 166 if (nintrmap == -1 || 167 OF_getprop(bus, "interrupt-map-mask", 168 &lintrmapmsk, sizeof(lintrmapmsk)) == -1) { 169 printf("ofw_pci_init_intr: could not get " 170 "interrupt map properties\n"); 171 if (nintrmap != -1) 172 free(intrmap, M_OFWPROP); 173 return; 174 } 175 intrmapmsk = &lintrmapmsk; 176 freemap = 1; 177 } 178 if ((intr = ofw_pci_route_intr(node, &pcir, intrmap, 179 nintrmap, intrmapmsk)) != 255) { | 103 104 if ((intr = ofw_pci_route_intr(node)) != 255) { |
180#ifdef OFW_PCI_DEBUG | 105#ifdef OFW_PCI_DEBUG |
181 device_printf(dev, __func__": mapping intr for " | 106 device_printf(dev, "%s: mapping intr for " |
182 "%d/%d/%d to %d (preset was %d)\n", | 107 "%d/%d/%d to %d (preset was %d)\n", |
108 __func__, |
|
183 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 184 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 185 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 186 intr, 187 (int)PCIB_READ_CONFIG(dev, 188 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 189 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 190 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 191 PCIR_INTLINE, 1)); | 109 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 110 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 111 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 112 intr, 113 (int)PCIB_READ_CONFIG(dev, 114 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 115 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 116 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 117 PCIR_INTLINE, 1)); |
192 | |
193#endif /* OFW_PCI_DEBUG */ 194 PCIB_WRITE_CONFIG(dev, 195 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 196 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 197 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 198 PCIR_INTLINE, intr, 1); 199 } else { 200#ifdef OFW_PCI_DEBUG | 118#endif /* OFW_PCI_DEBUG */ 119 PCIB_WRITE_CONFIG(dev, 120 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 121 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 122 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 123 PCIR_INTLINE, intr, 1); 124 } else { 125#ifdef OFW_PCI_DEBUG |
201 device_printf(dev, __func__": no interrupt " | 126 device_printf(dev, "%s: no interrupt " |
202 "mapping found for %d/%d/%d (preset %d)\n", | 127 "mapping found for %d/%d/%d (preset %d)\n", |
128 __func__, |
|
203 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 204 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 205 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 206 (int)PCIB_READ_CONFIG(dev, 207 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 208 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 209 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 210 PCIR_INTLINE, 1)); 211#endif /* OFW_PCI_DEBUG */ 212 /* The firmware initializes to 0 instead 255 */ 213 PCIB_WRITE_CONFIG(dev, 214 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 215 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 216 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 217 PCIR_INTLINE, 255, 1); 218 } 219 } 220 } while ((node = OF_peer(node)) != 0); | 129 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 130 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 131 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 132 (int)PCIB_READ_CONFIG(dev, 133 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 134 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 135 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 136 PCIR_INTLINE, 1)); 137#endif /* OFW_PCI_DEBUG */ 138 /* The firmware initializes to 0 instead 255 */ 139 PCIB_WRITE_CONFIG(dev, 140 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi), 141 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi), 142 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi), 143 PCIR_INTLINE, 255, 1); 144 } 145 } 146 } while ((node = OF_peer(node)) != 0); |
221 if (freemap) 222 free(intrmap, M_OFWPROP); | |
223} 224 225phandle_t 226ofw_pci_find_node(int bus, int slot, int func) 227{ 228 phandle_t node, bnode, parent; 229 struct ofw_pci_register pcir; 230 int br[2]; --- 32 unchanged lines hidden (view full) --- 263 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi) == func) { 264 if (OFW_PCI_PHYS_HI_BUS(pcir.phys_hi) != bus) 265 panic("ofw_pci_find_node: bus number mismatch"); 266 return (node); 267 } 268 } 269 return (0); 270} | 147} 148 149phandle_t 150ofw_pci_find_node(int bus, int slot, int func) 151{ 152 phandle_t node, bnode, parent; 153 struct ofw_pci_register pcir; 154 int br[2]; --- 32 unchanged lines hidden (view full) --- 187 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi) == func) { 188 if (OFW_PCI_PHYS_HI_BUS(pcir.phys_hi) != bus) 189 panic("ofw_pci_find_node: bus number mismatch"); 190 return (node); 191 } 192 } 193 return (0); 194} |
195 196phandle_t 197ofw_pci_node(device_t dev) 198{ 199 200 return (ofw_pci_find_node(pci_get_bus(dev), pci_get_slot(dev), 201 pci_get_function(dev))); 202} |
|