1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved. 7 */ 8 9#include <linux/slab.h> 10#include <asm/sn/types.h> 11#include <asm/sn/addrs.h> 12#include <asm/sn/io.h> 13#include <asm/sn/module.h> 14#include <asm/sn/intr.h> 15#include <asm/sn/pcibus_provider_defs.h> 16#include <asm/sn/pcidev.h> 17#include <asm/sn/sn_sal.h> 18#include "xtalk/hubdev.h" 19 20/* 21 * The code in this file will only be executed when running with 22 * a PROM that does _not_ have base ACPI IO support. 23 * (i.e., SN_ACPI_BASE_SUPPORT() == 0) 24 */ 25 26static int max_segment_number; /* Default highest segment number */ 27static int max_pcibus_number = 255; /* Default highest pci bus number */ 28 29 30/* 31 * Retrieve the hub device info structure for the given nasid. 32 */ 33static inline u64 sal_get_hubdev_info(u64 handle, u64 address) 34{ 35 struct ia64_sal_retval ret_stuff; 36 ret_stuff.status = 0; 37 ret_stuff.v0 = 0; 38 39 SAL_CALL_NOLOCK(ret_stuff, 40 (u64) SN_SAL_IOIF_GET_HUBDEV_INFO, 41 (u64) handle, (u64) address, 0, 0, 0, 0, 0); 42 return ret_stuff.v0; 43} 44 45/* 46 * Retrieve the pci bus information given the bus number. 47 */ 48static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) 49{ 50 struct ia64_sal_retval ret_stuff; 51 ret_stuff.status = 0; 52 ret_stuff.v0 = 0; 53 54 SAL_CALL_NOLOCK(ret_stuff, 55 (u64) SN_SAL_IOIF_GET_PCIBUS_INFO, 56 (u64) segment, (u64) busnum, (u64) address, 0, 0, 0, 0); 57 return ret_stuff.v0; 58} 59 60/* 61 * Retrieve the pci device information given the bus and device|function number. 62 */ 63static inline u64 64sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, 65 u64 sn_irq_info) 66{ 67 struct ia64_sal_retval ret_stuff; 68 ret_stuff.status = 0; 69 ret_stuff.v0 = 0; 70 71 SAL_CALL_NOLOCK(ret_stuff, 72 (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, 73 (u64) segment, (u64) bus_number, (u64) devfn, 74 (u64) pci_dev, 75 sn_irq_info, 0, 0); 76 return ret_stuff.v0; 77} 78 79 80/* 81 * sn_fixup_ionodes() - This routine initializes the HUB data structure for 82 * each node in the system. This function is only 83 * executed when running with a non-ACPI capable PROM. 84 */ 85static void __init sn_fixup_ionodes(void) 86{ 87 88 struct hubdev_info *hubdev; 89 u64 status; 90 u64 nasid; 91 int i; 92 extern void sn_common_hubdev_init(struct hubdev_info *); 93 94 /* 95 * Get SGI Specific HUB chipset information. 96 * Inform Prom that this kernel can support domain bus numbering. 97 */ 98 for (i = 0; i < num_cnodes; i++) { 99 hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo); 100 nasid = cnodeid_to_nasid(i); 101 hubdev->max_segment_number = 0xffffffff; 102 hubdev->max_pcibus_number = 0xff; 103 status = sal_get_hubdev_info(nasid, (u64) __pa(hubdev)); 104 if (status) 105 continue; 106 107 /* Save the largest Domain and pcibus numbers found. */ 108 if (hubdev->max_segment_number) { 109 /* 110 * Dealing with a Prom that supports segments. 111 */ 112 max_segment_number = hubdev->max_segment_number; 113 max_pcibus_number = hubdev->max_pcibus_number; 114 } 115 sn_common_hubdev_init(hubdev); 116 } 117} 118 119/* 120 * sn_pci_legacy_window_fixup - Create PCI controller windows for 121 * legacy IO and MEM space. This needs to 122 * be done here, as the PROM does not have 123 * ACPI support defining the root buses 124 * and their resources (_CRS), 125 */ 126static void 127sn_legacy_pci_window_fixup(struct pci_controller *controller, 128 u64 legacy_io, u64 legacy_mem) 129{ 130 controller->window = kcalloc(2, sizeof(struct pci_window), 131 GFP_KERNEL); 132 BUG_ON(controller->window == NULL); 133 controller->window[0].offset = legacy_io; 134 controller->window[0].resource.name = "legacy_io"; 135 controller->window[0].resource.flags = IORESOURCE_IO; 136 controller->window[0].resource.start = legacy_io; 137 controller->window[0].resource.end = 138 controller->window[0].resource.start + 0xffff; 139 controller->window[0].resource.parent = &ioport_resource; 140 controller->window[1].offset = legacy_mem; 141 controller->window[1].resource.name = "legacy_mem"; 142 controller->window[1].resource.flags = IORESOURCE_MEM; 143 controller->window[1].resource.start = legacy_mem; 144 controller->window[1].resource.end = 145 controller->window[1].resource.start + (1024 * 1024) - 1; 146 controller->window[1].resource.parent = &iomem_resource; 147 controller->windows = 2; 148} 149 150/* 151 * sn_pci_window_fixup() - Create a pci_window for each device resource. 152 * It will setup pci_windows for use by 153 * pcibios_bus_to_resource(), pcibios_resource_to_bus(), 154 * etc. 155 */ 156static void 157sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, 158 s64 * pci_addrs) 159{ 160 struct pci_controller *controller = PCI_CONTROLLER(dev->bus); 161 unsigned int i; 162 unsigned int idx; 163 unsigned int new_count; 164 struct pci_window *new_window; 165 166 if (count == 0) 167 return; 168 idx = controller->windows; 169 new_count = controller->windows + count; 170 new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL); 171 BUG_ON(new_window == NULL); 172 if (controller->window) { 173 memcpy(new_window, controller->window, 174 sizeof(struct pci_window) * controller->windows); 175 kfree(controller->window); 176 } 177 178 /* Setup a pci_window for each device resource. */ 179 for (i = 0; i <= PCI_ROM_RESOURCE; i++) { 180 if (pci_addrs[i] == -1) 181 continue; 182 183 new_window[idx].offset = dev->resource[i].start - pci_addrs[i]; 184 new_window[idx].resource = dev->resource[i]; 185 idx++; 186 } 187 188 controller->windows = new_count; 189 controller->window = new_window; 190} 191 192/* 193 * sn_io_slot_fixup() - We are not running with an ACPI capable PROM, 194 * and need to convert the pci_dev->resource 195 * 'start' and 'end' addresses to mapped addresses, 196 * and setup the pci_controller->window array entries. 197 */ 198void 199sn_io_slot_fixup(struct pci_dev *dev) 200{ 201 unsigned int count = 0; 202 int idx; 203 s64 pci_addrs[PCI_ROM_RESOURCE + 1]; 204 unsigned long addr, end, size, start; 205 struct pcidev_info *pcidev_info; 206 struct sn_irq_info *sn_irq_info; 207 int status; 208 209 pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); 210 if (!pcidev_info) 211 panic("%s: Unable to alloc memory for pcidev_info", __func__); 212 213 sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); 214 if (!sn_irq_info) 215 panic("%s: Unable to alloc memory for sn_irq_info", __func__); 216 217 /* Call to retrieve pci device information needed by kernel. */ 218 status = sal_get_pcidev_info((u64) pci_domain_nr(dev), 219 (u64) dev->bus->number, 220 dev->devfn, 221 (u64) __pa(pcidev_info), 222 (u64) __pa(sn_irq_info)); 223 224 BUG_ON(status); /* Cannot get platform pci device information */ 225 226 227 /* Copy over PIO Mapped Addresses */ 228 for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { 229 230 if (!pcidev_info->pdi_pio_mapped_addr[idx]) { 231 pci_addrs[idx] = -1; 232 continue; 233 } 234 235 start = dev->resource[idx].start; 236 end = dev->resource[idx].end; 237 size = end - start; 238 if (size == 0) { 239 pci_addrs[idx] = -1; 240 continue; 241 } 242 pci_addrs[idx] = start; 243 count++; 244 addr = pcidev_info->pdi_pio_mapped_addr[idx]; 245 addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET; 246 dev->resource[idx].start = addr; 247 dev->resource[idx].end = addr + size; 248 249 /* 250 * if it's already in the device structure, remove it before 251 * inserting 252 */ 253 if (dev->resource[idx].parent && dev->resource[idx].parent->child) 254 release_resource(&dev->resource[idx]); 255 256 if (dev->resource[idx].flags & IORESOURCE_IO) 257 insert_resource(&ioport_resource, &dev->resource[idx]); 258 else 259 insert_resource(&iomem_resource, &dev->resource[idx]); 260 /* 261 * If ROM, set the actual ROM image size, and mark as 262 * shadowed in PROM. 263 */ 264 if (idx == PCI_ROM_RESOURCE) { 265 size_t image_size; 266 void __iomem *rom; 267 268 rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE), 269 size + 1); 270 image_size = pci_get_rom_size(dev, rom, size + 1); 271 dev->resource[PCI_ROM_RESOURCE].end = 272 dev->resource[PCI_ROM_RESOURCE].start + 273 image_size - 1; 274 dev->resource[PCI_ROM_RESOURCE].flags |= 275 IORESOURCE_ROM_BIOS_COPY; 276 } 277 } 278 /* Create a pci_window in the pci_controller struct for 279 * each device resource. 280 */ 281 if (count > 0) 282 sn_pci_window_fixup(dev, count, pci_addrs); 283 284 sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); 285} 286 287EXPORT_SYMBOL(sn_io_slot_fixup); 288 289/* 290 * sn_pci_controller_fixup() - This routine sets up a bus's resources 291 * consistent with the Linux PCI abstraction layer. 292 */ 293static void __init 294sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) 295{ 296 s64 status = 0; 297 struct pci_controller *controller; 298 struct pcibus_bussoft *prom_bussoft_ptr; 299 300 301 status = sal_get_pcibus_info((u64) segment, (u64) busnum, 302 (u64) ia64_tpa(&prom_bussoft_ptr)); 303 if (status > 0) 304 return; /*bus # does not exist */ 305 prom_bussoft_ptr = __va(prom_bussoft_ptr); 306 307 controller = kzalloc(sizeof(*controller), GFP_KERNEL); 308 BUG_ON(!controller); 309 controller->segment = segment; 310 311 /* 312 * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup(). 313 * (platform_data will be overwritten later in sn_common_bus_fixup()) 314 */ 315 controller->platform_data = prom_bussoft_ptr; 316 317 bus = pci_scan_bus(busnum, &pci_root_ops, controller); 318 if (bus == NULL) 319 goto error_return; /* error, or bus already scanned */ 320 321 bus->sysdata = controller; 322 323 return; 324 325error_return: 326 327 kfree(controller); 328 return; 329} 330 331/* 332 * sn_bus_fixup 333 */ 334void 335sn_bus_fixup(struct pci_bus *bus) 336{ 337 struct pci_dev *pci_dev = NULL; 338 struct pcibus_bussoft *prom_bussoft_ptr; 339 340 if (!bus->parent) { /* If root bus */ 341 prom_bussoft_ptr = PCI_CONTROLLER(bus)->platform_data; 342 if (prom_bussoft_ptr == NULL) { 343 printk(KERN_ERR 344 "sn_bus_fixup: 0x%04x:0x%02x Unable to " 345 "obtain prom_bussoft_ptr\n", 346 pci_domain_nr(bus), bus->number); 347 return; 348 } 349 sn_common_bus_fixup(bus, prom_bussoft_ptr); 350 sn_legacy_pci_window_fixup(PCI_CONTROLLER(bus), 351 prom_bussoft_ptr->bs_legacy_io, 352 prom_bussoft_ptr->bs_legacy_mem); 353 } 354 list_for_each_entry(pci_dev, &bus->devices, bus_list) { 355 sn_io_slot_fixup(pci_dev); 356 } 357 358} 359 360/* 361 * sn_io_init - PROM does not have ACPI support to define nodes or root buses, 362 * so we need to do things the hard way, including initiating the 363 * bus scanning ourselves. 364 */ 365 366void __init sn_io_init(void) 367{ 368 int i, j; 369 370 sn_fixup_ionodes(); 371 372 /* busses are not known yet ... */ 373 for (i = 0; i <= max_segment_number; i++) 374 for (j = 0; j <= max_pcibus_number; j++) 375 sn_pci_controller_fixup(i, j, NULL); 376} 377