ofw_pcibus.c (178728) | ofw_pcibus.c (182020) |
---|---|
1/*- 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3 * Copyright (c) 2000, Michael Smith <msmith@freebsd.org> 4 * Copyright (c) 2000, BSDi 5 * Copyright (c) 2003, Thomas Moestl <tmm@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3 * Copyright (c) 2000, Michael Smith <msmith@freebsd.org> 4 * Copyright (c) 2000, BSDi 5 * Copyright (c) 2003, Thomas Moestl <tmm@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/sparc64/pci/ofw_pcibus.c 178728 2008-05-02 17:44:18Z marius $"); | 31__FBSDID("$FreeBSD: head/sys/sparc64/pci/ofw_pcibus.c 182020 2008-08-22 20:28:19Z marius $"); |
32 33#include "opt_ofw_pci.h" 34 35#include <sys/param.h> 36#include <sys/bus.h> 37#include <sys/kernel.h> 38#include <sys/libkern.h> 39#include <sys/module.h> --- 15 unchanged lines hidden (view full) --- 55#include <dev/pci/pcivar.h> 56#include <dev/pci/pci_private.h> 57 58#include <sparc64/pci/ofw_pci.h> 59 60#include "pcib_if.h" 61#include "pci_if.h" 62 | 32 33#include "opt_ofw_pci.h" 34 35#include <sys/param.h> 36#include <sys/bus.h> 37#include <sys/kernel.h> 38#include <sys/libkern.h> 39#include <sys/module.h> --- 15 unchanged lines hidden (view full) --- 55#include <dev/pci/pcivar.h> 56#include <dev/pci/pci_private.h> 57 58#include <sparc64/pci/ofw_pci.h> 59 60#include "pcib_if.h" 61#include "pci_if.h" 62 |
63/* Helper functions. */ | 63/* Helper functions */ |
64static void ofw_pcibus_setup_device(device_t, u_int, u_int, u_int); 65 | 64static void ofw_pcibus_setup_device(device_t, u_int, u_int, u_int); 65 |
66/* Methods. */ | 66/* Methods */ |
67static device_probe_t ofw_pcibus_probe; 68static device_attach_t ofw_pcibus_attach; 69static pci_assign_interrupt_t ofw_pcibus_assign_interrupt; 70static ofw_bus_get_devinfo_t ofw_pcibus_get_devinfo; 71 72static device_method_t ofw_pcibus_methods[] = { 73 /* Device interface */ 74 DEVMETHOD(device_probe, ofw_pcibus_probe), --- 43 unchanged lines hidden (view full) --- 118 * Perform miscellaneous setups the firmware usually does not do for us. 119 */ 120static void 121ofw_pcibus_setup_device(device_t bridge, u_int busno, u_int slot, u_int func) 122{ 123 uint32_t reg; 124 125 /* | 67static device_probe_t ofw_pcibus_probe; 68static device_attach_t ofw_pcibus_attach; 69static pci_assign_interrupt_t ofw_pcibus_assign_interrupt; 70static ofw_bus_get_devinfo_t ofw_pcibus_get_devinfo; 71 72static device_method_t ofw_pcibus_methods[] = { 73 /* Device interface */ 74 DEVMETHOD(device_probe, ofw_pcibus_probe), --- 43 unchanged lines hidden (view full) --- 118 * Perform miscellaneous setups the firmware usually does not do for us. 119 */ 120static void 121ofw_pcibus_setup_device(device_t bridge, u_int busno, u_int slot, u_int func) 122{ 123 uint32_t reg; 124 125 /* |
126 * Initialize the latency timer register for busmaster devices to work 127 * properly. This is another task which the firmware does not always 128 * perform. The Min_Gnt register can be used to compute it's recommended 129 * value: it contains the desired latency in units of 1/4 us. To 130 * calculate the correct latency timer value, the clock frequency of 131 * the bus (defaulting to 33Mhz) should be used and no wait states | 126 * Initialize the latency timer register for busmaster devices to 127 * work properly. This is another task which the firmware doesn't 128 * always perform. The Min_Gnt register can be used to compute its 129 * recommended value: it contains the desired latency in units of 130 * 1/4 us. To calculate the correct latency timer value, the clock 131 * frequency of the bus (defaulting to 33MHz) and no wait states |
132 * should be assumed. 133 */ 134 if (OF_getprop(ofw_bus_get_node(bridge), "clock-frequency", ®, 135 sizeof(reg)) == -1) 136 reg = 33000000; 137 reg = PCIB_READ_CONFIG(bridge, busno, slot, func, PCIR_MINGNT, 1) * 138 reg / 1000000 / 4; 139 if (reg != 0) { --- 6 unchanged lines hidden (view full) --- 146 PCIB_WRITE_CONFIG(bridge, busno, slot, func, 147 PCIR_LATTIMER, min(reg, 255), 1); 148 } 149 150#ifndef SUN4V 151 /* 152 * Compute a value to write into the cache line size register. 153 * The role of the streaming cache is unclear in write invalidate | 132 * should be assumed. 133 */ 134 if (OF_getprop(ofw_bus_get_node(bridge), "clock-frequency", ®, 135 sizeof(reg)) == -1) 136 reg = 33000000; 137 reg = PCIB_READ_CONFIG(bridge, busno, slot, func, PCIR_MINGNT, 1) * 138 reg / 1000000 / 4; 139 if (reg != 0) { --- 6 unchanged lines hidden (view full) --- 146 PCIB_WRITE_CONFIG(bridge, busno, slot, func, 147 PCIR_LATTIMER, min(reg, 255), 1); 148 } 149 150#ifndef SUN4V 151 /* 152 * Compute a value to write into the cache line size register. 153 * The role of the streaming cache is unclear in write invalidate |
154 * transfers, so it is made sure that it's line size is always reached. 155 * Generally, the cache line size is fixed at 64 bytes by Fireplane/ 156 * Safari, JBus and UPA. | 154 * transfers, so it is made sure that it's line size is always 155 * reached. Generally, the cache line size is fixed at 64 bytes 156 * by Fireplane/Safari, JBus and UPA. |
157 */ 158 PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_CACHELNSZ, 159 STRBUF_LINESZ / sizeof(uint32_t), 1); 160#endif 161 162 /* | 157 */ 158 PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_CACHELNSZ, 159 STRBUF_LINESZ / sizeof(uint32_t), 1); 160#endif 161 162 /* |
163 * The preset in the intline register is usually wrong. Reset it to 255, 164 * so that the PCI code will reroute the interrupt if needed. | 163 * The preset in the intline register is usually wrong. Reset 164 * it to 255, so that the PCI code will reroute the interrupt if 165 * needed. |
165 */ 166 PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_INTLINE, 167 PCI_INVALID_IRQ, 1); 168} 169 170static int 171ofw_pcibus_attach(device_t dev) 172{ --- 5 unchanged lines hidden (view full) --- 178 179 pcib = device_get_parent(dev); 180 181 domain = pcib_get_domain(dev); 182 busno = pcib_get_bus(dev); 183 if (bootverbose) 184 device_printf(dev, "domain=%d, physical bus=%d\n", 185 domain, busno); | 166 */ 167 PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_INTLINE, 168 PCI_INVALID_IRQ, 1); 169} 170 171static int 172ofw_pcibus_attach(device_t dev) 173{ --- 5 unchanged lines hidden (view full) --- 179 180 pcib = device_get_parent(dev); 181 182 domain = pcib_get_domain(dev); 183 busno = pcib_get_bus(dev); 184 if (bootverbose) 185 device_printf(dev, "domain=%d, physical bus=%d\n", 186 domain, busno); |
186 | |
187 node = ofw_bus_get_node(dev); 188 189#ifndef SUN4V 190 /* Add the PCI side of the HOST-PCI bridge itself to the bus. */ 191 if (strcmp(device_get_name(device_get_parent(pcib)), "nexus") == 0 && 192 (dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib, 193 domain, busno, 0, 0, sizeof(*dinfo))) != NULL) { 194 if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, node) != 0) --- 37 unchanged lines hidden (view full) --- 232 sizeof(intr)); 233 if (isz != sizeof(intr)) { 234 /* No property; our best guess is the intpin. */ 235 intr = pci_get_intpin(child); 236#ifndef SUN4V 237 } else if (intr >= 255) { 238 /* 239 * A fully specified interrupt (including IGN), as present on | 187 node = ofw_bus_get_node(dev); 188 189#ifndef SUN4V 190 /* Add the PCI side of the HOST-PCI bridge itself to the bus. */ 191 if (strcmp(device_get_name(device_get_parent(pcib)), "nexus") == 0 && 192 (dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib, 193 domain, busno, 0, 0, sizeof(*dinfo))) != NULL) { 194 if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, node) != 0) --- 37 unchanged lines hidden (view full) --- 232 sizeof(intr)); 233 if (isz != sizeof(intr)) { 234 /* No property; our best guess is the intpin. */ 235 intr = pci_get_intpin(child); 236#ifndef SUN4V 237 } else if (intr >= 255) { 238 /* 239 * A fully specified interrupt (including IGN), as present on |
240 * SPARCengine Ultra AX and e450. Extract the INO and return it. | 240 * SPARCengine Ultra AX and E450. Extract the INO and return 241 * it. |
241 */ 242 return (INTINO(intr)); 243#endif 244 } 245 /* 246 * If we got intr from a property, it may or may not be an intpin. 247 * For on-board devices, it frequently is not, and is completely out | 242 */ 243 return (INTINO(intr)); 244#endif 245 } 246 /* 247 * If we got intr from a property, it may or may not be an intpin. 248 * For on-board devices, it frequently is not, and is completely out |
248 * of the valid intpin range. For PCI slots, it hopefully is, otherwise 249 * we will have trouble interfacing with non-OFW buses such as cardbus. | 249 * of the valid intpin range. For PCI slots, it hopefully is, 250 * otherwise we will have trouble interfacing with non-OFW buses 251 * such as cardbus. |
250 * Since we cannot tell which it is without violating layering, we | 252 * Since we cannot tell which it is without violating layering, we |
251 * will always use the route_interrupt method, and treat exceptions on 252 * the level they become apparent. | 253 * will always use the route_interrupt method, and treat exceptions 254 * on the level they become apparent. |
253 */ 254 return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, intr)); 255} 256 257static const struct ofw_bus_devinfo * 258ofw_pcibus_get_devinfo(device_t bus, device_t dev) 259{ 260 struct ofw_pcibus_devinfo *dinfo; 261 262 dinfo = device_get_ivars(dev); 263 return (&dinfo->opd_obdinfo); 264} | 255 */ 256 return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, intr)); 257} 258 259static const struct ofw_bus_devinfo * 260ofw_pcibus_get_devinfo(device_t bus, device_t dev) 261{ 262 struct ofw_pcibus_devinfo *dinfo; 263 264 dinfo = device_get_ivars(dev); 265 return (&dinfo->opd_obdinfo); 266} |