Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/mips/pci/ops-bridge.c
10817 views
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 ([email protected])
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
*/
20
static 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
43
static 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 fucked fucked beyond believe ... 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
76
oh_my_gawd:
77
78
/*
79
* IOC3 is fucked fucked beyond believe ... 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 fucked fucked beyond believe ... 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
103
static 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 fucked fucked beyond believe ... 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
139
oh_my_gawd:
140
141
/*
142
* IOC3 is fucked fucked beyond believe ... 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 fucked fucked beyond believe ... 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
167
static 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
176
static 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 fucked fucked beyond believe ... 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
213
oh_my_gawd:
214
215
/*
216
* IOC3 is fucked fucked beyond believe ... 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 fucked fucked beyond believe ... 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
242
static 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 fucked fucked beyond believe ... 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
281
oh_my_gawd:
282
283
/*
284
* IOC3 is fucked fucked beyond believe ... 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 fucked fucked beyond believe ... 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
310
static 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
319
struct pci_ops bridge_pci_ops = {
320
.read = pci_read_config,
321
.write = pci_write_config,
322
};
323
324