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) 1999, 2000, 04, 06 Ralf Baechle (ralf@linux-mips.org) 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 */ 9#include <linux/pci.h> 10#include <asm/paccess.h> 11#include <asm/pci/bridge.h> 12#include <asm/sn/arch.h> 13#include <asm/sn/intr.h> 14#include <asm/sn/sn0/hub.h> 15 16/* 17 * Most of the IOC3 PCI config register aren't present 18 * we emulate what is needed for a normal PCI enumeration 19 */ 20static u32 emulate_ioc3_cfg(int where, int size) 21{ 22 if (size == 1 && where == 0x3d) 23 return 0x01; 24 else if (size == 2 && where == 0x3c) 25 return 0x0100; 26 else if (size == 4 && where == 0x3c) 27 return 0x00000100; 28 29 return 0; 30} 31 32/* 33 * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is 34 * not really documented, so right now I can't write code which uses it. 35 * Therefore we use type 0 accesses for now even though they won't work 36 * correcly for PCI-to-PCI bridges. 37 * 38 * The function is complicated by the ultimate brokeness of the IOC3 chip 39 * which is used in SGI systems. The IOC3 can only handle 32-bit PCI 40 * accesses and does only decode parts of it's address space. 41 */ 42 43static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, 44 int where, int size, u32 * value) 45{ 46 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); 47 bridge_t *bridge = bc->base; 48 int slot = PCI_SLOT(devfn); 49 int fn = PCI_FUNC(devfn); 50 volatile void *addr; 51 u32 cf, shift, mask; 52 int res; 53 54 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID]; 55 if (get_dbe(cf, (u32 *) addr)) 56 return PCIBIOS_DEVICE_NOT_FOUND; 57 58 /* 59 * IOC3 is fucking fucked beyond belief ... Don't even give the 60 * generic PCI code a chance to look at it for real ... 61 */ 62 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 63 goto oh_my_gawd; 64 65 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; 66 67 if (size == 1) 68 res = get_dbe(*value, (u8 *) addr); 69 else if (size == 2) 70 res = get_dbe(*value, (u16 *) addr); 71 else 72 res = get_dbe(*value, (u32 *) addr); 73 74 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 75 76oh_my_gawd: 77 78 /* 79 * IOC3 is fucking fucked beyond belief ... Don't even give the 80 * generic PCI code a chance to look at the wrong register. 81 */ 82 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { 83 *value = emulate_ioc3_cfg(where, size); 84 return PCIBIOS_SUCCESSFUL; 85 } 86 87 /* 88 * IOC3 is fucking fucked beyond belief ... Don't try to access 89 * anything but 32-bit words ... 90 */ 91 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 92 93 if (get_dbe(cf, (u32 *) addr)) 94 return PCIBIOS_DEVICE_NOT_FOUND; 95 96 shift = ((where & 3) << 3); 97 mask = (0xffffffffU >> ((4 - size) << 3)); 98 *value = (cf >> shift) & mask; 99 100 return PCIBIOS_SUCCESSFUL; 101} 102 103static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, 104 int where, int size, u32 * value) 105{ 106 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); 107 bridge_t *bridge = bc->base; 108 int busno = bus->number; 109 int slot = PCI_SLOT(devfn); 110 int fn = PCI_FUNC(devfn); 111 volatile void *addr; 112 u32 cf, shift, mask; 113 int res; 114 115 bridge->b_pci_cfg = (busno << 16) | (slot << 11); 116 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; 117 if (get_dbe(cf, (u32 *) addr)) 118 return PCIBIOS_DEVICE_NOT_FOUND; 119 120 /* 121 * IOC3 is fucking fucked beyond belief ... Don't even give the 122 * generic PCI code a chance to look at it for real ... 123 */ 124 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 125 goto oh_my_gawd; 126 127 bridge->b_pci_cfg = (busno << 16) | (slot << 11); 128 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; 129 130 if (size == 1) 131 res = get_dbe(*value, (u8 *) addr); 132 else if (size == 2) 133 res = get_dbe(*value, (u16 *) addr); 134 else 135 res = get_dbe(*value, (u32 *) addr); 136 137 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 138 139oh_my_gawd: 140 141 /* 142 * IOC3 is fucking fucked beyond belief ... Don't even give the 143 * generic PCI code a chance to look at the wrong register. 144 */ 145 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { 146 *value = emulate_ioc3_cfg(where, size); 147 return PCIBIOS_SUCCESSFUL; 148 } 149 150 /* 151 * IOC3 is fucking fucked beyond belief ... Don't try to access 152 * anything but 32-bit words ... 153 */ 154 bridge->b_pci_cfg = (busno << 16) | (slot << 11); 155 addr = &bridge->b_type1_cfg.c[(fn << 8) | where]; 156 157 if (get_dbe(cf, (u32 *) addr)) 158 return PCIBIOS_DEVICE_NOT_FOUND; 159 160 shift = ((where & 3) << 3); 161 mask = (0xffffffffU >> ((4 - size) << 3)); 162 *value = (cf >> shift) & mask; 163 164 return PCIBIOS_SUCCESSFUL; 165} 166 167static int pci_read_config(struct pci_bus *bus, unsigned int devfn, 168 int where, int size, u32 * value) 169{ 170 if (bus->number > 0) 171 return pci_conf1_read_config(bus, devfn, where, size, value); 172 173 return pci_conf0_read_config(bus, devfn, where, size, value); 174} 175 176static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, 177 int where, int size, u32 value) 178{ 179 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); 180 bridge_t *bridge = bc->base; 181 int slot = PCI_SLOT(devfn); 182 int fn = PCI_FUNC(devfn); 183 volatile void *addr; 184 u32 cf, shift, mask, smask; 185 int res; 186 187 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID]; 188 if (get_dbe(cf, (u32 *) addr)) 189 return PCIBIOS_DEVICE_NOT_FOUND; 190 191 /* 192 * IOC3 is fucking fucked beyond belief ... Don't even give the 193 * generic PCI code a chance to look at it for real ... 194 */ 195 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 196 goto oh_my_gawd; 197 198 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; 199 200 if (size == 1) { 201 res = put_dbe(value, (u8 *) addr); 202 } else if (size == 2) { 203 res = put_dbe(value, (u16 *) addr); 204 } else { 205 res = put_dbe(value, (u32 *) addr); 206 } 207 208 if (res) 209 return PCIBIOS_DEVICE_NOT_FOUND; 210 211 return PCIBIOS_SUCCESSFUL; 212 213oh_my_gawd: 214 215 /* 216 * IOC3 is fucking fucked beyond belief ... Don't even give the 217 * generic PCI code a chance to touch the wrong register. 218 */ 219 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) 220 return PCIBIOS_SUCCESSFUL; 221 222 /* 223 * IOC3 is fucking fucked beyond belief ... Don't try to access 224 * anything but 32-bit words ... 225 */ 226 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 227 228 if (get_dbe(cf, (u32 *) addr)) 229 return PCIBIOS_DEVICE_NOT_FOUND; 230 231 shift = ((where & 3) << 3); 232 mask = (0xffffffffU >> ((4 - size) << 3)); 233 smask = mask << shift; 234 235 cf = (cf & ~smask) | ((value & mask) << shift); 236 if (put_dbe(cf, (u32 *) addr)) 237 return PCIBIOS_DEVICE_NOT_FOUND; 238 239 return PCIBIOS_SUCCESSFUL; 240} 241 242static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, 243 int where, int size, u32 value) 244{ 245 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); 246 bridge_t *bridge = bc->base; 247 int slot = PCI_SLOT(devfn); 248 int fn = PCI_FUNC(devfn); 249 int busno = bus->number; 250 volatile void *addr; 251 u32 cf, shift, mask, smask; 252 int res; 253 254 bridge->b_pci_cfg = (busno << 16) | (slot << 11); 255 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; 256 if (get_dbe(cf, (u32 *) addr)) 257 return PCIBIOS_DEVICE_NOT_FOUND; 258 259 /* 260 * IOC3 is fucking fucked beyond belief ... Don't even give the 261 * generic PCI code a chance to look at it for real ... 262 */ 263 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 264 goto oh_my_gawd; 265 266 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; 267 268 if (size == 1) { 269 res = put_dbe(value, (u8 *) addr); 270 } else if (size == 2) { 271 res = put_dbe(value, (u16 *) addr); 272 } else { 273 res = put_dbe(value, (u32 *) addr); 274 } 275 276 if (res) 277 return PCIBIOS_DEVICE_NOT_FOUND; 278 279 return PCIBIOS_SUCCESSFUL; 280 281oh_my_gawd: 282 283 /* 284 * IOC3 is fucking fucked beyond belief ... Don't even give the 285 * generic PCI code a chance to touch the wrong register. 286 */ 287 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) 288 return PCIBIOS_SUCCESSFUL; 289 290 /* 291 * IOC3 is fucking fucked beyond belief ... Don't try to access 292 * anything but 32-bit words ... 293 */ 294 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 295 296 if (get_dbe(cf, (u32 *) addr)) 297 return PCIBIOS_DEVICE_NOT_FOUND; 298 299 shift = ((where & 3) << 3); 300 mask = (0xffffffffU >> ((4 - size) << 3)); 301 smask = mask << shift; 302 303 cf = (cf & ~smask) | ((value & mask) << shift); 304 if (put_dbe(cf, (u32 *) addr)) 305 return PCIBIOS_DEVICE_NOT_FOUND; 306 307 return PCIBIOS_SUCCESSFUL; 308} 309 310static int pci_write_config(struct pci_bus *bus, unsigned int devfn, 311 int where, int size, u32 value) 312{ 313 if (bus->number > 0) 314 return pci_conf1_write_config(bus, devfn, where, size, value); 315 316 return pci_conf0_write_config(bus, devfn, where, size, value); 317} 318 319struct pci_ops bridge_pci_ops = { 320 .read = pci_read_config, 321 .write = pci_write_config, 322}; 323