1 | /* |
---|
2 | * pci.c -- Crude pci handling for early boot. |
---|
3 | * |
---|
4 | * Copyright (C) 1998, 1999 Gabriel Paubert, paubert@iram.es |
---|
5 | * |
---|
6 | * Modified to compile in RTEMS development environment |
---|
7 | * by Eric Valette |
---|
8 | * |
---|
9 | * Copyright (C) 1999 Eric Valette. valette@crf.canon.fr |
---|
10 | * |
---|
11 | * The license and distribution terms for this file may be |
---|
12 | * found in found in the file LICENSE in this distribution or at |
---|
13 | * http://www.rtems.com/license/LICENSE. |
---|
14 | * |
---|
15 | * pci.c,v 1.3 2003/06/13 17:39:44 joel Exp |
---|
16 | */ |
---|
17 | |
---|
18 | |
---|
19 | #include <sys/types.h> |
---|
20 | #include <rtems/bspIo.h> |
---|
21 | #include <libcpu/spr.h> |
---|
22 | #include "bootldr.h" |
---|
23 | #include "pci.h" |
---|
24 | #include <libcpu/io.h> |
---|
25 | #include <libcpu/page.h> |
---|
26 | #include <bsp/consoleIo.h> |
---|
27 | #include <string.h> |
---|
28 | |
---|
29 | typedef unsigned int u32; |
---|
30 | |
---|
31 | /* |
---|
32 | #define DEBUG |
---|
33 | #define PCI_DEBUG |
---|
34 | */ |
---|
35 | |
---|
36 | /* Used to reorganize PCI space on stupid machines which spread resources |
---|
37 | * across a wide address space. This is bad when P2P bridges are present |
---|
38 | * or when it limits the mappings that a resource hog like a PCI<->VME |
---|
39 | * bridge can use. |
---|
40 | */ |
---|
41 | |
---|
42 | typedef struct _pci_resource { |
---|
43 | struct _pci_resource *next; |
---|
44 | struct pci_dev *dev; |
---|
45 | u_long base; /* will be 64 bits on 64 bits machines */ |
---|
46 | u_long size; |
---|
47 | u_char type; /* 1 is I/O else low order 4 bits of the memory type */ |
---|
48 | u_char reg; /* Register # in conf space header */ |
---|
49 | u_short cmd; /* Original cmd byte */ |
---|
50 | } pci_resource; |
---|
51 | |
---|
52 | typedef struct _pci_area { |
---|
53 | struct _pci_area *next; |
---|
54 | u_long start; |
---|
55 | u_long end; |
---|
56 | struct pci_bus *bus; |
---|
57 | u_int flags; |
---|
58 | } pci_area; |
---|
59 | |
---|
60 | typedef struct _pci_area_head { |
---|
61 | pci_area *head; |
---|
62 | u_long mask; |
---|
63 | int high; /* To allocate from top */ |
---|
64 | } pci_area_head; |
---|
65 | |
---|
66 | #define PCI_AREA_PREFETCHABLE 0 |
---|
67 | #define PCI_AREA_MEMORY 1 |
---|
68 | #define PCI_AREA_IO 2 |
---|
69 | |
---|
70 | struct _pci_private { |
---|
71 | volatile u_int * config_addr; |
---|
72 | volatile u_char * config_data; |
---|
73 | struct pci_dev **last_dev_p; |
---|
74 | struct pci_bus pci_root; |
---|
75 | pci_resource *resources; |
---|
76 | pci_area_head io, mem; |
---|
77 | |
---|
78 | } pci_private = { |
---|
79 | config_addr: NULL, |
---|
80 | config_data: (volatile u_char *) 0x80800000, |
---|
81 | last_dev_p: NULL, |
---|
82 | resources: NULL, |
---|
83 | io: {NULL, 0xfff, 0}, |
---|
84 | mem: {NULL, 0xfffff, 0} |
---|
85 | }; |
---|
86 | |
---|
87 | #define pci ((struct _pci_private *)(bd->pci_private)) |
---|
88 | #define pci_root pci->pci_root |
---|
89 | |
---|
90 | #if !defined(DEBUG) |
---|
91 | #undef PCI_DEBUG |
---|
92 | /* |
---|
93 | #else |
---|
94 | #define PCI_DEBUG |
---|
95 | */ |
---|
96 | #endif |
---|
97 | |
---|
98 | #if defined(PCI_DEBUG) |
---|
99 | static void |
---|
100 | print_pci_resources(const char *s) { |
---|
101 | pci_resource *p; |
---|
102 | printk("%s", s); |
---|
103 | for (p=pci->resources; p; p=p->next) { |
---|
104 | /* |
---|
105 | printk(" %p:%p %06x %08lx %08lx %d\n", |
---|
106 | p, p->next, |
---|
107 | (p->dev->devfn<<8)+(p->dev->bus->number<<16) |
---|
108 | +0x10+p->reg*4, |
---|
109 | p->base, |
---|
110 | p->size, |
---|
111 | p->type); |
---|
112 | */ |
---|
113 | |
---|
114 | printk(" %p:%p %d:%02x (%04x:%04x) %08lx %08lx %d\n", |
---|
115 | p, p->next, |
---|
116 | p->dev->bus->number, PCI_SLOT(p->dev->devfn), |
---|
117 | p->dev->vendor, p->dev->device, |
---|
118 | p->base, |
---|
119 | p->size, |
---|
120 | p->type); |
---|
121 | |
---|
122 | } |
---|
123 | } |
---|
124 | |
---|
125 | static void |
---|
126 | print_pci_area(pci_area *p) { |
---|
127 | for (; p; p=p->next) { |
---|
128 | printk(" %p:%p %p %08lx %08lx\n", |
---|
129 | p, p->next, p->bus, p->start, p->end); |
---|
130 | } |
---|
131 | } |
---|
132 | |
---|
133 | static void |
---|
134 | print_pci_areas(const char *s) { |
---|
135 | printk("%s PCI I/O areas:\n",s); |
---|
136 | print_pci_area(pci->io.head); |
---|
137 | printk(" PCI memory areas:\n"); |
---|
138 | print_pci_area(pci->mem.head); |
---|
139 | } |
---|
140 | #else |
---|
141 | #define print_pci_areas(x) |
---|
142 | #define print_pci_resources(x) |
---|
143 | #endif |
---|
144 | |
---|
145 | /* Maybe there are some devices who use a size different |
---|
146 | * from the alignment. For now we assume both are the same. |
---|
147 | * The blacklist might be used for other weird things in the future too, |
---|
148 | * since weird non PCI complying devices seem to proliferate these days. |
---|
149 | */ |
---|
150 | |
---|
151 | struct blacklist_entry { |
---|
152 | u_short vendor, device; |
---|
153 | u_char reg; |
---|
154 | u_long actual_size; |
---|
155 | }; |
---|
156 | |
---|
157 | #define BLACKLIST(vid, did, breg, actual_size) \ |
---|
158 | {PCI_VENDOR_ID_##vid, PCI_DEVICE_ID_##vid##_##did, breg, actual_size} |
---|
159 | |
---|
160 | static struct blacklist_entry blacklist[] = { |
---|
161 | BLACKLIST(S3, TRIO, 0, 0x04000000), |
---|
162 | {0xffff, 0, 0, 0} |
---|
163 | }; |
---|
164 | |
---|
165 | |
---|
166 | /* This function filters resources and then inserts them into a list of |
---|
167 | * configurable pci resources. |
---|
168 | */ |
---|
169 | |
---|
170 | |
---|
171 | #define AREA(r) \ |
---|
172 | (((r->type&PCI_BASE_ADDRESS_SPACE)==PCI_BASE_ADDRESS_SPACE_IO) ? PCI_AREA_IO :\ |
---|
173 | ((r->type&PCI_BASE_ADDRESS_MEM_PREFETCH) ? PCI_AREA_PREFETCHABLE :\ |
---|
174 | PCI_AREA_MEMORY)) |
---|
175 | |
---|
176 | |
---|
177 | |
---|
178 | static int insert_before(pci_resource *e, pci_resource *t) { |
---|
179 | if (e->dev->bus->number != t->dev->bus->number) |
---|
180 | return e->dev->bus->number > t->dev->bus->number; |
---|
181 | if (AREA(e) != AREA(t)) return AREA(e)<AREA(t); |
---|
182 | return (e->size > t->size); |
---|
183 | } |
---|
184 | |
---|
185 | |
---|
186 | |
---|
187 | |
---|
188 | |
---|
189 | static void insert_resource(pci_resource *r) { |
---|
190 | struct blacklist_entry *b; |
---|
191 | pci_resource *p; |
---|
192 | if (!r) return; |
---|
193 | |
---|
194 | /* First fixup in case we have a blacklist entry. Note that this |
---|
195 | * may temporarily leave a resource in an inconsistent state: with |
---|
196 | * (base & (size-1)) !=0. This is harmless. |
---|
197 | */ |
---|
198 | for (b=blacklist; b->vendor!=0xffff; b++) { |
---|
199 | if ((r->dev->vendor==b->vendor) && |
---|
200 | (r->dev->device==b->device) && |
---|
201 | (r->reg==b->reg)) { |
---|
202 | r->size=b->actual_size; |
---|
203 | break; |
---|
204 | } |
---|
205 | } |
---|
206 | |
---|
207 | /* Motorola NT firmware does not configure pci devices which are not |
---|
208 | * required for booting, others do. For now: |
---|
209 | * - allocated devices in the ISA range (64kB I/O, 16Mb memory) |
---|
210 | * but non zero base registers are left as is. |
---|
211 | * - all other registers, whether already allocated or not, are |
---|
212 | * reallocated unless they require an inordinate amount of |
---|
213 | * resources (>256 Mb for memory >64kB for I/O). These |
---|
214 | * devices with too large mapping requirements are simply ignored |
---|
215 | * and their bases are set to 0. This should disable the |
---|
216 | * corresponding decoders according to the PCI specification. |
---|
217 | * Many devices are buggy in this respect, however, but the |
---|
218 | * limits have hopefully been set high enough to avoid problems. |
---|
219 | */ |
---|
220 | |
---|
221 | /* |
---|
222 | ** This is little ugly below. It seems that at least on the MCP750, |
---|
223 | ** the PBC has some default IO space mappings that the bsp #defines |
---|
224 | ** that read/write to PCI I/O space assume, particuarly the i8259 |
---|
225 | ** manipulation code. So, if we allow the small IO spaces on PCI bus |
---|
226 | ** 0 and 1 to be remapped, the registers can shift out from under the |
---|
227 | ** #defines. This is particuarly awful, but short of redefining the |
---|
228 | ** PCI I/O primitives to be functions with base addresses read from |
---|
229 | ** the hardware, we are stuck with the kludge below. Note that |
---|
230 | ** everything is remapped on the CPCI backplane and any downstream |
---|
231 | ** hardware, its just the builtin stuff we're tiptoeing around. |
---|
232 | ** |
---|
233 | ** Gregm, 7/16/2003 |
---|
234 | ** |
---|
235 | ** Gregm, changed 11/2003 so IO devices only on bus 0 zero are not |
---|
236 | ** remapped. This covers the builtin pc-like io devices- but |
---|
237 | ** properly maps IO devices on higher busses. |
---|
238 | */ |
---|
239 | if( r->dev->bus->number == 0 ) |
---|
240 | { |
---|
241 | if ((r->type==PCI_BASE_ADDRESS_SPACE_IO) |
---|
242 | ? (r->base && r->base <0x10000) |
---|
243 | : (r->base && r->base <0x1000000)) { |
---|
244 | |
---|
245 | #ifdef PCI_DEBUG |
---|
246 | printk("freeing region; %p:%p %d:%02x (%04x:%04x) %08lx %08lx %d\n", |
---|
247 | r, r->next, |
---|
248 | r->dev->bus->number, PCI_SLOT(r->dev->devfn), |
---|
249 | r->dev->vendor, r->dev->device, |
---|
250 | r->base, |
---|
251 | r->size, |
---|
252 | r->type); |
---|
253 | #endif |
---|
254 | sfree(r); |
---|
255 | return; |
---|
256 | } |
---|
257 | } |
---|
258 | |
---|
259 | if ((r->type==PCI_BASE_ADDRESS_SPACE_IO) |
---|
260 | ? (r->size >= 0x10000) |
---|
261 | : (r->size >= 0x10000000)) { |
---|
262 | r->size = 0; |
---|
263 | r->base = 0; |
---|
264 | } |
---|
265 | |
---|
266 | /* Now insert into the list sorting by |
---|
267 | * 1) decreasing bus number |
---|
268 | * 2) space: prefetchable memory, non-prefetchable and finally I/O |
---|
269 | * 3) decreasing size |
---|
270 | */ |
---|
271 | if (!pci->resources || insert_before(r, pci->resources)) { |
---|
272 | r->next = pci->resources; |
---|
273 | pci->resources=r; |
---|
274 | } else { |
---|
275 | for (p=pci->resources; p->next; p=p->next) { |
---|
276 | if (insert_before(r, p->next)) break; |
---|
277 | } |
---|
278 | r->next=p->next; |
---|
279 | p->next=r; |
---|
280 | } |
---|
281 | } |
---|
282 | |
---|
283 | |
---|
284 | |
---|
285 | |
---|
286 | |
---|
287 | /* This version only works for bus 0. I don't have any P2P bridges to test |
---|
288 | * a more sophisticated version which has therefore not been implemented. |
---|
289 | * Prefetchable memory is not yet handled correctly either. |
---|
290 | * And several levels of PCI bridges much less even since there must be |
---|
291 | * allocated together to be able to setup correctly the top bridge. |
---|
292 | */ |
---|
293 | |
---|
294 | static u_long find_range(u_char bus, u_char type, |
---|
295 | pci_resource **first, |
---|
296 | pci_resource **past, u_int *flags) { |
---|
297 | pci_resource *p; |
---|
298 | u_long total=0; |
---|
299 | u_int fl=0; |
---|
300 | |
---|
301 | for (p=pci->resources; p; p=p->next) |
---|
302 | { |
---|
303 | if ((p->dev->bus->number == bus) && |
---|
304 | AREA(p)==type) break; |
---|
305 | } |
---|
306 | |
---|
307 | *first = p; |
---|
308 | |
---|
309 | for (; p; p=p->next) |
---|
310 | { |
---|
311 | if ((p->dev->bus->number != bus) || |
---|
312 | AREA(p)!=type || p->size == 0) break; |
---|
313 | total = total+p->size; |
---|
314 | fl |= 1<<p->type; |
---|
315 | } |
---|
316 | |
---|
317 | *past = p; |
---|
318 | /* This will be used later to tell whether there are any 32 bit |
---|
319 | * devices in an area which could be mapped higher than 4Gb |
---|
320 | * on 64 bits architectures |
---|
321 | */ |
---|
322 | *flags = fl; |
---|
323 | return total; |
---|
324 | } |
---|
325 | |
---|
326 | |
---|
327 | |
---|
328 | |
---|
329 | |
---|
330 | |
---|
331 | static inline void init_free_area(pci_area_head *h, u_long start, |
---|
332 | u_long end, u_int mask, int high) { |
---|
333 | pci_area *p; |
---|
334 | p = salloc(sizeof(pci_area)); |
---|
335 | if (!p) return; |
---|
336 | h->head = p; |
---|
337 | p->next = NULL; |
---|
338 | p->start = (start+mask)&~mask; |
---|
339 | p->end = (end-mask)|mask; |
---|
340 | p->bus = NULL; |
---|
341 | h->mask = mask; |
---|
342 | h->high = high; |
---|
343 | } |
---|
344 | |
---|
345 | |
---|
346 | |
---|
347 | |
---|
348 | |
---|
349 | |
---|
350 | static void insert_area(pci_area_head *h, pci_area *p) { |
---|
351 | pci_area *q = h->head; |
---|
352 | if (!p) return; |
---|
353 | if (q && (q->start< p->start)) { |
---|
354 | for(;q->next && q->next->start<p->start; q = q->next); |
---|
355 | if ((q->end >= p->start) || |
---|
356 | (q->next && p->end>=q->next->start)) { |
---|
357 | sfree(p); |
---|
358 | printk("Overlapping pci areas!\n"); |
---|
359 | return; |
---|
360 | } |
---|
361 | p->next = q->next; |
---|
362 | q->next = p; |
---|
363 | } else { /* Insert at head */ |
---|
364 | if (q && (p->end >= q->start)) { |
---|
365 | sfree(p); |
---|
366 | printk("Overlapping pci areas!\n"); |
---|
367 | return; |
---|
368 | } |
---|
369 | p->next = q; |
---|
370 | h->head = p; |
---|
371 | } |
---|
372 | } |
---|
373 | |
---|
374 | |
---|
375 | |
---|
376 | |
---|
377 | |
---|
378 | static |
---|
379 | void remove_area(pci_area_head *h, pci_area *p) |
---|
380 | { |
---|
381 | pci_area *q = h->head; |
---|
382 | |
---|
383 | if (!p || !q) return; |
---|
384 | if (q==p) |
---|
385 | { |
---|
386 | h->head = q->next; |
---|
387 | return; |
---|
388 | } |
---|
389 | for(;q && q->next!=p; q=q->next); |
---|
390 | if (q) q->next=p->next; |
---|
391 | } |
---|
392 | |
---|
393 | |
---|
394 | |
---|
395 | |
---|
396 | |
---|
397 | |
---|
398 | static pci_area * alloc_area(pci_area_head *h, struct pci_bus *bus, |
---|
399 | u_long required, u_long mask, u_int flags) { |
---|
400 | pci_area *p; |
---|
401 | pci_area *from, *split, *new; |
---|
402 | |
---|
403 | required = (required+h->mask) & ~h->mask; |
---|
404 | for (p=h->head, from=NULL; p; p=p->next) |
---|
405 | { |
---|
406 | u_long l1 = ((p->start+required+mask)&~mask)-1; |
---|
407 | u_long l2 = ((p->start+mask)&~mask)+required-1; |
---|
408 | /* Allocated areas point to the bus to which they pertain */ |
---|
409 | if (p->bus) continue; |
---|
410 | if ((p->end)>=l1 || (p->end)>=l2) from=p; |
---|
411 | if (from && !h->high) break; |
---|
412 | } |
---|
413 | if (!from) return NULL; |
---|
414 | |
---|
415 | split = salloc(sizeof(pci_area)); |
---|
416 | new = salloc(sizeof(pci_area)); |
---|
417 | /* If allocation of new succeeds then allocation of split has |
---|
418 | * also been successful (given the current mm algorithms) ! |
---|
419 | */ |
---|
420 | if (!new) { |
---|
421 | sfree(split); |
---|
422 | return NULL; |
---|
423 | } |
---|
424 | new->bus = bus; |
---|
425 | new->flags = flags; |
---|
426 | /* Now allocate pci_space taking alignment into account ! */ |
---|
427 | if (h->high) |
---|
428 | { |
---|
429 | u_long l1 = ((from->end+1)&~mask)-required; |
---|
430 | u_long l2 = (from->end+1-required)&~mask; |
---|
431 | new->start = (l1>l2) ? l1 : l2; |
---|
432 | split->end = from->end; |
---|
433 | from->end = new->start-1; |
---|
434 | split->start = new->start+required; |
---|
435 | new->end = new->start+required-1; |
---|
436 | } |
---|
437 | else |
---|
438 | { |
---|
439 | u_long l1 = ((from->start+mask)&~mask)+required-1; |
---|
440 | u_long l2 = ((from->start+required+mask)&~mask)-1; |
---|
441 | new->end = (l1<l2) ? l1 : l2; |
---|
442 | split->start = from->start; |
---|
443 | from->start = new->end+1; |
---|
444 | new->start = new->end+1-required; |
---|
445 | split->end = new->start-1; |
---|
446 | } |
---|
447 | |
---|
448 | if (from->end+1 == from->start) remove_area(h, from); |
---|
449 | if (split->end+1 != split->start) |
---|
450 | { |
---|
451 | split->bus = NULL; |
---|
452 | insert_area(h, split); |
---|
453 | } |
---|
454 | else |
---|
455 | { |
---|
456 | sfree(split); |
---|
457 | } |
---|
458 | insert_area(h, new); |
---|
459 | print_pci_areas("alloc_area called:\n"); |
---|
460 | return new; |
---|
461 | } |
---|
462 | |
---|
463 | |
---|
464 | |
---|
465 | |
---|
466 | |
---|
467 | static inline |
---|
468 | void alloc_space(pci_area *p, pci_resource *r) |
---|
469 | { |
---|
470 | if (p->start & (r->size-1)) { |
---|
471 | r->base = p->end+1-r->size; |
---|
472 | p->end -= r->size; |
---|
473 | } else { |
---|
474 | r->base = p->start; |
---|
475 | p->start += r->size; |
---|
476 | } |
---|
477 | } |
---|
478 | |
---|
479 | |
---|
480 | |
---|
481 | |
---|
482 | |
---|
483 | static void reconfigure_bus_space(u_char bus, u_char type, pci_area_head *h) |
---|
484 | { |
---|
485 | pci_resource *first, *past, *r; |
---|
486 | pci_area *area, tmp; |
---|
487 | u_int flags; |
---|
488 | u_int required = find_range(bus, type, &first, &past, &flags); |
---|
489 | |
---|
490 | if (required==0) return; |
---|
491 | |
---|
492 | area = alloc_area(h, first->dev->bus, required, first->size-1, flags); |
---|
493 | |
---|
494 | if (!area) return; |
---|
495 | |
---|
496 | tmp = *area; |
---|
497 | for (r=first; r!=past; r=r->next) |
---|
498 | { |
---|
499 | alloc_space(&tmp, r); |
---|
500 | } |
---|
501 | } |
---|
502 | |
---|
503 | |
---|
504 | |
---|
505 | |
---|
506 | |
---|
507 | |
---|
508 | |
---|
509 | #define BUS0_IO_START 0x10000 |
---|
510 | #define BUS0_IO_END 0x1ffff |
---|
511 | #define BUS0_MEM_START 0x1000000 |
---|
512 | #define BUS0_MEM_END 0x3f00000 |
---|
513 | |
---|
514 | #define BUSREST_IO_START 0x20000 |
---|
515 | #define BUSREST_IO_END 0x7ffff |
---|
516 | #define BUSREST_MEM_START 0x4000000 |
---|
517 | #define BUSREST_MEM_END 0x10000000 |
---|
518 | |
---|
519 | |
---|
520 | |
---|
521 | |
---|
522 | |
---|
523 | static void reconfigure_pci(void) { |
---|
524 | pci_resource *r; |
---|
525 | struct pci_dev *dev; |
---|
526 | |
---|
527 | /* FIXME: for now memory is relocated from low, it's better |
---|
528 | * to start from higher addresses. |
---|
529 | */ |
---|
530 | /* |
---|
531 | init_free_area(&pci->io, 0x10000, 0x7fffff, 0xfff, 0); |
---|
532 | init_free_area(&pci->mem, 0x1000000, 0x3cffffff, 0xfffff, 0); |
---|
533 | */ |
---|
534 | |
---|
535 | init_free_area(&pci->io, BUS0_IO_START, BUS0_IO_END, 0xfff, 0); |
---|
536 | init_free_area(&pci->mem, BUS0_MEM_START, BUS0_MEM_END, 0xfffff, 0); |
---|
537 | |
---|
538 | |
---|
539 | /* First reconfigure the I/O space, this will be more |
---|
540 | * complex when there is more than 1 bus. And 64 bits |
---|
541 | * devices are another kind of problems. |
---|
542 | */ |
---|
543 | reconfigure_bus_space(0, PCI_AREA_IO, &pci->io); |
---|
544 | reconfigure_bus_space(0, PCI_AREA_MEMORY, &pci->mem); |
---|
545 | reconfigure_bus_space(0, PCI_AREA_PREFETCHABLE, &pci->mem); |
---|
546 | |
---|
547 | /* Now we have to touch the configuration space of all |
---|
548 | * the devices to remap them better than they are right now. |
---|
549 | * This is done in 3 steps: |
---|
550 | * 1) first disable I/O and memory response of all devices |
---|
551 | * 2) modify the base registers |
---|
552 | * 3) restore the original PCI_COMMAND register. |
---|
553 | */ |
---|
554 | for (r=pci->resources; r; r= r->next) { |
---|
555 | if (!r->dev->sysdata) { |
---|
556 | r->dev->sysdata=r; |
---|
557 | pci_read_config_word(r->dev, PCI_COMMAND, &r->cmd); |
---|
558 | pci_write_config_word(r->dev, PCI_COMMAND, |
---|
559 | r->cmd & ~(PCI_COMMAND_IO| |
---|
560 | PCI_COMMAND_MEMORY)); |
---|
561 | } |
---|
562 | } |
---|
563 | |
---|
564 | for (r=pci->resources; r; r= r->next) { |
---|
565 | pci_write_config_dword(r->dev, |
---|
566 | PCI_BASE_ADDRESS_0+(r->reg<<2), |
---|
567 | r->base); |
---|
568 | if ((r->type& |
---|
569 | (PCI_BASE_ADDRESS_SPACE| |
---|
570 | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == |
---|
571 | (PCI_BASE_ADDRESS_SPACE_MEMORY| |
---|
572 | PCI_BASE_ADDRESS_MEM_TYPE_64)) { |
---|
573 | pci_write_config_dword(r->dev, |
---|
574 | PCI_BASE_ADDRESS_1+(r->reg<<2), |
---|
575 | 0); |
---|
576 | } |
---|
577 | } |
---|
578 | for (dev=bd->pci_devices; dev; dev= dev->next) { |
---|
579 | if (dev->sysdata) { |
---|
580 | pci_write_config_word(dev, PCI_COMMAND, |
---|
581 | ((pci_resource *)dev->sysdata) |
---|
582 | ->cmd); |
---|
583 | dev->sysdata=NULL; |
---|
584 | } |
---|
585 | } |
---|
586 | } |
---|
587 | |
---|
588 | |
---|
589 | |
---|
590 | |
---|
591 | |
---|
592 | |
---|
593 | static int |
---|
594 | indirect_pci_read_config_byte(unsigned char bus, unsigned char dev_fn, |
---|
595 | unsigned char offset, unsigned char *val) { |
---|
596 | out_be32(pci->config_addr, |
---|
597 | 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24)); |
---|
598 | *val=in_8(pci->config_data + (offset&3)); |
---|
599 | return PCIBIOS_SUCCESSFUL; |
---|
600 | } |
---|
601 | |
---|
602 | static int |
---|
603 | indirect_pci_read_config_word(unsigned char bus, unsigned char dev_fn, |
---|
604 | unsigned char offset, unsigned short *val) { |
---|
605 | *val = 0xffff; |
---|
606 | if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER; |
---|
607 | out_be32(pci->config_addr, |
---|
608 | 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24)); |
---|
609 | *val=in_le16((volatile u_short *)(pci->config_data + (offset&3))); |
---|
610 | return PCIBIOS_SUCCESSFUL; |
---|
611 | } |
---|
612 | |
---|
613 | static int |
---|
614 | indirect_pci_read_config_dword(unsigned char bus, unsigned char dev_fn, |
---|
615 | unsigned char offset, unsigned int *val) { |
---|
616 | *val = 0xffffffff; |
---|
617 | if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER; |
---|
618 | out_be32(pci->config_addr, |
---|
619 | 0x80|(bus<<8)|(dev_fn<<16)|(offset<<24)); |
---|
620 | *val=in_le32((volatile u_int *)pci->config_data); |
---|
621 | return PCIBIOS_SUCCESSFUL; |
---|
622 | } |
---|
623 | |
---|
624 | static int |
---|
625 | indirect_pci_write_config_byte(unsigned char bus, unsigned char dev_fn, |
---|
626 | unsigned char offset, unsigned char val) { |
---|
627 | out_be32(pci->config_addr, |
---|
628 | 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24)); |
---|
629 | out_8(pci->config_data + (offset&3), val); |
---|
630 | return PCIBIOS_SUCCESSFUL; |
---|
631 | } |
---|
632 | |
---|
633 | static int |
---|
634 | indirect_pci_write_config_word(unsigned char bus, unsigned char dev_fn, |
---|
635 | unsigned char offset, unsigned short val) { |
---|
636 | if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER; |
---|
637 | out_be32(pci->config_addr, |
---|
638 | 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24)); |
---|
639 | out_le16((volatile u_short *)(pci->config_data + (offset&3)), val); |
---|
640 | return PCIBIOS_SUCCESSFUL; |
---|
641 | } |
---|
642 | |
---|
643 | static int |
---|
644 | indirect_pci_write_config_dword(unsigned char bus, unsigned char dev_fn, |
---|
645 | unsigned char offset, unsigned int val) { |
---|
646 | if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER; |
---|
647 | out_be32(pci->config_addr, |
---|
648 | 0x80|(bus<<8)|(dev_fn<<16)|(offset<<24)); |
---|
649 | out_le32((volatile u_int *)pci->config_data, val); |
---|
650 | return PCIBIOS_SUCCESSFUL; |
---|
651 | } |
---|
652 | |
---|
653 | static const struct pci_config_access_functions indirect_functions = { |
---|
654 | indirect_pci_read_config_byte, |
---|
655 | indirect_pci_read_config_word, |
---|
656 | indirect_pci_read_config_dword, |
---|
657 | indirect_pci_write_config_byte, |
---|
658 | indirect_pci_write_config_word, |
---|
659 | indirect_pci_write_config_dword |
---|
660 | }; |
---|
661 | |
---|
662 | |
---|
663 | static int |
---|
664 | direct_pci_read_config_byte(unsigned char bus, unsigned char dev_fn, |
---|
665 | unsigned char offset, unsigned char *val) { |
---|
666 | if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) { |
---|
667 | *val=0xff; |
---|
668 | return PCIBIOS_DEVICE_NOT_FOUND; |
---|
669 | } |
---|
670 | *val=in_8(pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1) |
---|
671 | + (PCI_FUNC(dev_fn)<<8) + offset); |
---|
672 | return PCIBIOS_SUCCESSFUL; |
---|
673 | } |
---|
674 | |
---|
675 | static int |
---|
676 | direct_pci_read_config_word(unsigned char bus, unsigned char dev_fn, |
---|
677 | unsigned char offset, unsigned short *val) { |
---|
678 | *val = 0xffff; |
---|
679 | if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER; |
---|
680 | if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) { |
---|
681 | return PCIBIOS_DEVICE_NOT_FOUND; |
---|
682 | } |
---|
683 | *val=in_le16((volatile u_short *) |
---|
684 | (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1) |
---|
685 | + (PCI_FUNC(dev_fn)<<8) + offset)); |
---|
686 | return PCIBIOS_SUCCESSFUL; |
---|
687 | } |
---|
688 | |
---|
689 | static int |
---|
690 | direct_pci_read_config_dword(unsigned char bus, unsigned char dev_fn, |
---|
691 | unsigned char offset, unsigned int *val) { |
---|
692 | *val = 0xffffffff; |
---|
693 | if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER; |
---|
694 | if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) { |
---|
695 | return PCIBIOS_DEVICE_NOT_FOUND; |
---|
696 | } |
---|
697 | *val=in_le32((volatile u_int *) |
---|
698 | (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1) |
---|
699 | + (PCI_FUNC(dev_fn)<<8) + offset)); |
---|
700 | return PCIBIOS_SUCCESSFUL; |
---|
701 | } |
---|
702 | |
---|
703 | static int |
---|
704 | direct_pci_write_config_byte(unsigned char bus, unsigned char dev_fn, |
---|
705 | unsigned char offset, unsigned char val) { |
---|
706 | if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) { |
---|
707 | return PCIBIOS_DEVICE_NOT_FOUND; |
---|
708 | } |
---|
709 | out_8(pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1) |
---|
710 | + (PCI_FUNC(dev_fn)<<8) + offset, |
---|
711 | val); |
---|
712 | return PCIBIOS_SUCCESSFUL; |
---|
713 | } |
---|
714 | |
---|
715 | static int |
---|
716 | direct_pci_write_config_word(unsigned char bus, unsigned char dev_fn, |
---|
717 | unsigned char offset, unsigned short val) { |
---|
718 | if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER; |
---|
719 | if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) { |
---|
720 | return PCIBIOS_DEVICE_NOT_FOUND; |
---|
721 | } |
---|
722 | out_le16((volatile u_short *) |
---|
723 | (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1) |
---|
724 | + (PCI_FUNC(dev_fn)<<8) + offset), |
---|
725 | val); |
---|
726 | return PCIBIOS_SUCCESSFUL; |
---|
727 | } |
---|
728 | |
---|
729 | static int |
---|
730 | direct_pci_write_config_dword(unsigned char bus, unsigned char dev_fn, |
---|
731 | unsigned char offset, unsigned int val) { |
---|
732 | if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER; |
---|
733 | if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) { |
---|
734 | return PCIBIOS_DEVICE_NOT_FOUND; |
---|
735 | } |
---|
736 | out_le32((volatile u_int *) |
---|
737 | (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1) |
---|
738 | + (PCI_FUNC(dev_fn)<<8) + offset), |
---|
739 | val); |
---|
740 | return PCIBIOS_SUCCESSFUL; |
---|
741 | } |
---|
742 | |
---|
743 | static const struct pci_config_access_functions direct_functions = { |
---|
744 | direct_pci_read_config_byte, |
---|
745 | direct_pci_read_config_word, |
---|
746 | direct_pci_read_config_dword, |
---|
747 | direct_pci_write_config_byte, |
---|
748 | direct_pci_write_config_word, |
---|
749 | direct_pci_write_config_dword |
---|
750 | }; |
---|
751 | |
---|
752 | |
---|
753 | |
---|
754 | |
---|
755 | |
---|
756 | |
---|
757 | void pci_read_bases(struct pci_dev *dev, unsigned int howmany) |
---|
758 | { |
---|
759 | unsigned int reg, nextreg; |
---|
760 | |
---|
761 | #define REG (PCI_BASE_ADDRESS_0 + (reg<<2)) |
---|
762 | |
---|
763 | u_short cmd; |
---|
764 | u32 l, ml; |
---|
765 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
---|
766 | |
---|
767 | for(reg=0; reg<howmany; reg=nextreg) |
---|
768 | { |
---|
769 | pci_resource *r; |
---|
770 | |
---|
771 | nextreg=reg+1; |
---|
772 | pci_read_config_dword(dev, REG, &l); |
---|
773 | #if 0 |
---|
774 | if (l == 0xffffffff /*AJF || !l*/) continue; |
---|
775 | #endif |
---|
776 | /* Note that disabling the memory response of a host bridge |
---|
777 | * would lose data if a DMA transfer were in progress. In a |
---|
778 | * bootloader we don't care however. Also we can't print any |
---|
779 | * message for a while since we might just disable the console. |
---|
780 | */ |
---|
781 | pci_write_config_word(dev, PCI_COMMAND, cmd & |
---|
782 | ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)); |
---|
783 | pci_write_config_dword(dev, REG, ~0); |
---|
784 | pci_read_config_dword(dev, REG, &ml); |
---|
785 | pci_write_config_dword(dev, REG, l); |
---|
786 | |
---|
787 | /* Reenable the device now that we've played with |
---|
788 | * base registers. |
---|
789 | */ |
---|
790 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
---|
791 | |
---|
792 | /* seems to be an unused entry skip it */ |
---|
793 | if ( ml == 0 || ml == 0xffffffff ) continue; |
---|
794 | |
---|
795 | if ((l & |
---|
796 | (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) |
---|
797 | == (PCI_BASE_ADDRESS_MEM_TYPE_64 |
---|
798 | |PCI_BASE_ADDRESS_SPACE_MEMORY)) { |
---|
799 | nextreg=reg+2; |
---|
800 | } |
---|
801 | dev->base_address[reg] = l; |
---|
802 | r = salloc(sizeof(pci_resource)); |
---|
803 | if (!r) { |
---|
804 | printk("Error allocating pci_resource struct.\n"); |
---|
805 | continue; |
---|
806 | } |
---|
807 | r->dev = dev; |
---|
808 | r->reg = reg; |
---|
809 | if ((l&PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { |
---|
810 | r->type = l&~PCI_BASE_ADDRESS_IO_MASK; |
---|
811 | r->base = l&PCI_BASE_ADDRESS_IO_MASK; |
---|
812 | /* r->size = ~(ml&PCI_BASE_ADDRESS_IO_MASK)+1; */ |
---|
813 | } else { |
---|
814 | r->type = l&~PCI_BASE_ADDRESS_MEM_MASK; |
---|
815 | r->base = l&PCI_BASE_ADDRESS_MEM_MASK; |
---|
816 | /* r->size = ~(ml&PCI_BASE_ADDRESS_MEM_MASK)+1; */ |
---|
817 | } |
---|
818 | |
---|
819 | /* find the first bit set to one after the base |
---|
820 | address type bits to find length of region */ |
---|
821 | { |
---|
822 | unsigned int c= 16 , val= 0; |
---|
823 | while( !(val= ml & c) ) c <<= 1; |
---|
824 | r->size = val; |
---|
825 | } |
---|
826 | |
---|
827 | #ifdef PCI_DEBUG |
---|
828 | printk(" readbase bus %d, (%04x:%04x), base %08x, size %08x, type %d\n", |
---|
829 | r->dev->bus->number, |
---|
830 | r->dev->vendor, |
---|
831 | r->dev->device, |
---|
832 | r->base, |
---|
833 | r->size, |
---|
834 | r->type ); |
---|
835 | #endif |
---|
836 | |
---|
837 | /* Check for the blacklisted entries */ |
---|
838 | insert_resource(r); |
---|
839 | } |
---|
840 | } |
---|
841 | |
---|
842 | |
---|
843 | |
---|
844 | |
---|
845 | |
---|
846 | |
---|
847 | |
---|
848 | |
---|
849 | u_int pci_scan_bus(struct pci_bus *bus) |
---|
850 | { |
---|
851 | unsigned int devfn, l, max, class; |
---|
852 | unsigned char irq, hdr_type, is_multi = 0; |
---|
853 | struct pci_dev *dev, **bus_last; |
---|
854 | struct pci_bus *child; |
---|
855 | |
---|
856 | #if 0 |
---|
857 | printk("scanning pci bus %d\n", bus->number ); |
---|
858 | #endif |
---|
859 | |
---|
860 | bus_last = &bus->devices; |
---|
861 | max = bus->secondary; |
---|
862 | for (devfn = 0; devfn < 0xff; ++devfn) { |
---|
863 | if (PCI_FUNC(devfn) && !is_multi) { |
---|
864 | /* not a multi-function device */ |
---|
865 | continue; |
---|
866 | } |
---|
867 | if (pcibios_read_config_byte(bus->number, devfn, PCI_HEADER_TYPE, &hdr_type)) |
---|
868 | continue; |
---|
869 | if (!PCI_FUNC(devfn)) |
---|
870 | is_multi = hdr_type & 0x80; |
---|
871 | |
---|
872 | if (pcibios_read_config_dword(bus->number, devfn, PCI_VENDOR_ID, &l) || |
---|
873 | /* some broken boards return 0 if a slot is empty: */ |
---|
874 | l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000) { |
---|
875 | is_multi = 0; |
---|
876 | continue; |
---|
877 | } |
---|
878 | |
---|
879 | dev = salloc(sizeof(*dev)); |
---|
880 | dev->bus = bus; |
---|
881 | dev->devfn = devfn; |
---|
882 | dev->vendor = l & 0xffff; |
---|
883 | dev->device = (l >> 16) & 0xffff; |
---|
884 | |
---|
885 | pcibios_read_config_dword(bus->number, devfn, |
---|
886 | PCI_CLASS_REVISION, &class); |
---|
887 | class >>= 8; /* upper 3 bytes */ |
---|
888 | dev->class = class; |
---|
889 | class >>= 8; |
---|
890 | dev->hdr_type = hdr_type; |
---|
891 | |
---|
892 | switch (hdr_type & 0x7f) { /* header type */ |
---|
893 | case PCI_HEADER_TYPE_NORMAL: /* standard header */ |
---|
894 | if (class == PCI_CLASS_BRIDGE_PCI) |
---|
895 | goto bad; |
---|
896 | /* |
---|
897 | * If the card generates interrupts, read IRQ number |
---|
898 | * (some architectures change it during pcibios_fixup()) |
---|
899 | */ |
---|
900 | pcibios_read_config_byte(bus->number, dev->devfn, PCI_INTERRUPT_PIN, &irq); |
---|
901 | if (irq) |
---|
902 | pcibios_read_config_byte(bus->number, dev->devfn, PCI_INTERRUPT_LINE, &irq); |
---|
903 | dev->irq = irq; |
---|
904 | /* |
---|
905 | * read base address registers, again pcibios_fixup() can |
---|
906 | * tweak these |
---|
907 | */ |
---|
908 | pci_read_bases(dev, 6); |
---|
909 | pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS, &l); |
---|
910 | dev->rom_address = (l == 0xffffffff) ? 0 : l; |
---|
911 | break; |
---|
912 | case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ |
---|
913 | if (class != PCI_CLASS_BRIDGE_PCI) |
---|
914 | goto bad; |
---|
915 | pci_read_bases(dev, 2); |
---|
916 | pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS1, &l); |
---|
917 | dev->rom_address = (l == 0xffffffff) ? 0 : l; |
---|
918 | break; |
---|
919 | case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ |
---|
920 | if (class != PCI_CLASS_BRIDGE_CARDBUS) |
---|
921 | goto bad; |
---|
922 | pci_read_bases(dev, 1); |
---|
923 | break; |
---|
924 | |
---|
925 | default: /* unknown header */ |
---|
926 | bad: |
---|
927 | printk("PCI device with unknown header type %d ignored.\n", |
---|
928 | hdr_type&0x7f); |
---|
929 | continue; |
---|
930 | } |
---|
931 | |
---|
932 | /* |
---|
933 | * Put it into the global PCI device chain. It's used to |
---|
934 | * find devices once everything is set up. |
---|
935 | */ |
---|
936 | *pci->last_dev_p = dev; |
---|
937 | pci->last_dev_p = &dev->next; |
---|
938 | |
---|
939 | /* |
---|
940 | * Now insert it into the list of devices held |
---|
941 | * by the parent bus. |
---|
942 | */ |
---|
943 | *bus_last = dev; |
---|
944 | bus_last = &dev->sibling; |
---|
945 | |
---|
946 | } |
---|
947 | |
---|
948 | /* |
---|
949 | * After performing arch-dependent fixup of the bus, look behind |
---|
950 | * all PCI-to-PCI bridges on this bus. |
---|
951 | */ |
---|
952 | for(dev=bus->devices; dev; dev=dev->sibling) |
---|
953 | /* |
---|
954 | * If it's a bridge, scan the bus behind it. |
---|
955 | */ |
---|
956 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { |
---|
957 | unsigned int buses; |
---|
958 | unsigned int devfn = dev->devfn; |
---|
959 | unsigned short cr; |
---|
960 | |
---|
961 | /* |
---|
962 | * Insert it into the tree of buses. |
---|
963 | */ |
---|
964 | child = salloc(sizeof(*child)); |
---|
965 | child->next = bus->children; |
---|
966 | bus->children = child; |
---|
967 | child->self = dev; |
---|
968 | child->parent = bus; |
---|
969 | |
---|
970 | /* |
---|
971 | * Set up the primary, secondary and subordinate |
---|
972 | * bus numbers. |
---|
973 | */ |
---|
974 | child->number = child->secondary = ++max; |
---|
975 | child->primary = bus->secondary; |
---|
976 | child->subordinate = 0xff; |
---|
977 | /* |
---|
978 | * Clear all status bits and turn off memory, |
---|
979 | * I/O and master enables. |
---|
980 | */ |
---|
981 | pcibios_read_config_word(bus->number, devfn, PCI_COMMAND, &cr); |
---|
982 | pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, 0x0000); |
---|
983 | pcibios_write_config_word(bus->number, devfn, PCI_STATUS, 0xffff); |
---|
984 | /* |
---|
985 | * Read the existing primary/secondary/subordinate bus |
---|
986 | * number configuration to determine if the PCI bridge |
---|
987 | * has already been configured by the system. If so, |
---|
988 | * do not modify the configuration, merely note it. |
---|
989 | */ |
---|
990 | pcibios_read_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, &buses); |
---|
991 | if ((buses & 0xFFFFFF) != 0) |
---|
992 | { |
---|
993 | unsigned int cmax; |
---|
994 | |
---|
995 | child->primary = buses & 0xFF; |
---|
996 | child->secondary = (buses >> 8) & 0xFF; |
---|
997 | child->subordinate = (buses >> 16) & 0xFF; |
---|
998 | child->number = child->secondary; |
---|
999 | cmax = pci_scan_bus(child); |
---|
1000 | if (cmax > max) max = cmax; |
---|
1001 | } |
---|
1002 | else |
---|
1003 | { |
---|
1004 | /* |
---|
1005 | * Configure the bus numbers for this bridge: |
---|
1006 | */ |
---|
1007 | buses &= 0xff000000; |
---|
1008 | buses |= |
---|
1009 | (((unsigned int)(child->primary) << 0) | |
---|
1010 | ((unsigned int)(child->secondary) << 8) | |
---|
1011 | ((unsigned int)(child->subordinate) << 16)); |
---|
1012 | pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses); |
---|
1013 | /* |
---|
1014 | * Now we can scan all subordinate buses: |
---|
1015 | */ |
---|
1016 | max = pci_scan_bus(child); |
---|
1017 | /* |
---|
1018 | * Set the subordinate bus number to its real |
---|
1019 | * value: |
---|
1020 | */ |
---|
1021 | child->subordinate = max; |
---|
1022 | buses = (buses & 0xff00ffff) |
---|
1023 | | ((unsigned int)(child->subordinate) << 16); |
---|
1024 | pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses); |
---|
1025 | } |
---|
1026 | pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, cr ); |
---|
1027 | } |
---|
1028 | |
---|
1029 | /* |
---|
1030 | * We've scanned the bus and so we know all about what's on |
---|
1031 | * the other side of any bridges that may be on this bus plus |
---|
1032 | * any devices. |
---|
1033 | * |
---|
1034 | * Return how far we've got finding sub-buses. |
---|
1035 | */ |
---|
1036 | return max; |
---|
1037 | } |
---|
1038 | |
---|
1039 | |
---|
1040 | |
---|
1041 | |
---|
1042 | |
---|
1043 | |
---|
1044 | |
---|
1045 | |
---|
1046 | |
---|
1047 | |
---|
1048 | #if 0 |
---|
1049 | |
---|
1050 | void |
---|
1051 | pci_fixup(void) |
---|
1052 | { |
---|
1053 | struct pci_dev *p; |
---|
1054 | struct pci_bus *bus; |
---|
1055 | |
---|
1056 | for (bus = &pci_root; bus; bus=bus->next) |
---|
1057 | { |
---|
1058 | for (p=bus->devices; p; p=p->sibling) |
---|
1059 | { |
---|
1060 | } |
---|
1061 | } |
---|
1062 | } |
---|
1063 | |
---|
1064 | |
---|
1065 | |
---|
1066 | |
---|
1067 | |
---|
1068 | |
---|
1069 | static void print_pci_info() |
---|
1070 | { |
---|
1071 | pci_resource *r; |
---|
1072 | struct pci_bus *pb = &pci_root; |
---|
1073 | |
---|
1074 | printk("\n"); |
---|
1075 | printk("PCI busses:\n"); |
---|
1076 | |
---|
1077 | for(pb= &pci_root; pb; pb=pb->children ) |
---|
1078 | { |
---|
1079 | printk(" number %d, primary %d, secondary %d, subordinate %d\n", |
---|
1080 | pb->number, |
---|
1081 | pb->primary, |
---|
1082 | pb->secondary, |
---|
1083 | pb->subordinate ); |
---|
1084 | printk(" bridge; vendor %04x, device %04x\n", |
---|
1085 | pb->self->vendor, |
---|
1086 | pb->self->device ); |
---|
1087 | |
---|
1088 | { |
---|
1089 | struct pci_dev *pd; |
---|
1090 | |
---|
1091 | for(pd= pb->devices; pd; pd=pd->sibling ) |
---|
1092 | { |
---|
1093 | printk(" vendor %04x, device %04x, irq %d\n", |
---|
1094 | pd->vendor, |
---|
1095 | pd->device, |
---|
1096 | pd->irq ); |
---|
1097 | |
---|
1098 | } |
---|
1099 | printk("\n"); |
---|
1100 | } |
---|
1101 | |
---|
1102 | } |
---|
1103 | printk("\n"); |
---|
1104 | |
---|
1105 | printk("PCI resources:\n"); |
---|
1106 | for (r=pci->resources; r; r= r->next) |
---|
1107 | { |
---|
1108 | printk(" bus %d, vendor %04x, device %04x, base %08x, size %08x, type %d\n", |
---|
1109 | r->dev->bus->number, |
---|
1110 | r->dev->vendor, |
---|
1111 | r->dev->device, |
---|
1112 | r->base, |
---|
1113 | r->size, |
---|
1114 | r->type ); |
---|
1115 | } |
---|
1116 | printk("\n"); |
---|
1117 | |
---|
1118 | return; |
---|
1119 | } |
---|
1120 | |
---|
1121 | #endif |
---|
1122 | |
---|
1123 | |
---|
1124 | |
---|
1125 | |
---|
1126 | |
---|
1127 | |
---|
1128 | |
---|
1129 | |
---|
1130 | |
---|
1131 | |
---|
1132 | |
---|
1133 | |
---|
1134 | static struct _addr_start |
---|
1135 | { |
---|
1136 | unsigned32 start_pcimem; |
---|
1137 | unsigned32 start_pciio; |
---|
1138 | unsigned32 start_prefetch; |
---|
1139 | } astart; |
---|
1140 | |
---|
1141 | |
---|
1142 | |
---|
1143 | |
---|
1144 | |
---|
1145 | static pci_resource *enum_device_resources( struct pci_dev *pdev, int i ) |
---|
1146 | { |
---|
1147 | pci_resource *r; |
---|
1148 | |
---|
1149 | for(r= pci->resources; r; r= r->next ) |
---|
1150 | { |
---|
1151 | if( r->dev == pdev ) |
---|
1152 | { |
---|
1153 | if( i-- == 0 ) break; |
---|
1154 | } |
---|
1155 | } |
---|
1156 | return r; |
---|
1157 | } |
---|
1158 | |
---|
1159 | |
---|
1160 | |
---|
1161 | |
---|
1162 | |
---|
1163 | |
---|
1164 | |
---|
1165 | |
---|
1166 | |
---|
1167 | static void recursive_bus_reconfigure( struct pci_bus *pbus ) |
---|
1168 | { |
---|
1169 | struct pci_dev *pdev; |
---|
1170 | struct pci_bus *childbus; |
---|
1171 | int isroot = 0; |
---|
1172 | |
---|
1173 | |
---|
1174 | if( !pbus ) |
---|
1175 | { |
---|
1176 | /* start with the root bus */ |
---|
1177 | astart.start_pcimem = BUSREST_MEM_START; |
---|
1178 | astart.start_pciio = BUSREST_IO_START; |
---|
1179 | astart.start_prefetch = ((BUSREST_MEM_END >> 16) << 16); |
---|
1180 | |
---|
1181 | pbus = &pci_root; |
---|
1182 | isroot = -1; |
---|
1183 | } |
---|
1184 | |
---|
1185 | |
---|
1186 | #define WRITE_BRIDGE_IO |
---|
1187 | #define WRITE_BRIDGE_MEM |
---|
1188 | #define WRITE_BRIDGE_PF |
---|
1189 | #define WRITE_BRIDGE_ENABLE |
---|
1190 | |
---|
1191 | |
---|
1192 | /* |
---|
1193 | ** Run thru the p2p bridges on this bus and recurse into subordinate busses |
---|
1194 | */ |
---|
1195 | for( childbus= pbus->children; childbus; childbus= childbus->next ) |
---|
1196 | { |
---|
1197 | pdev= childbus->self; |
---|
1198 | |
---|
1199 | pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_LATENCY_TIMER, 0x80 ); |
---|
1200 | pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_SEC_LATENCY_TIMER, 0x80 ); |
---|
1201 | |
---|
1202 | { |
---|
1203 | struct _addr_start addrhold; |
---|
1204 | unsigned8 base8, limit8; |
---|
1205 | unsigned16 base16, limit16, ubase16, ulimit16; |
---|
1206 | |
---|
1207 | /* save the base address values */ |
---|
1208 | memcpy( &addrhold, &astart, sizeof(struct _addr_start)); |
---|
1209 | |
---|
1210 | recursive_bus_reconfigure( childbus ); |
---|
1211 | |
---|
1212 | #ifdef PCI_DEBUG |
---|
1213 | printk("pci: configuring bus %d bridge (%04x:%04x), bus %d : (%d-%d)\n", |
---|
1214 | pdev->bus->number, |
---|
1215 | pdev->vendor, |
---|
1216 | pdev->device, |
---|
1217 | childbus->primary, |
---|
1218 | childbus->secondary, |
---|
1219 | childbus->subordinate ); |
---|
1220 | #endif |
---|
1221 | |
---|
1222 | |
---|
1223 | |
---|
1224 | /* |
---|
1225 | ** use the current values & the saved ones to figure out |
---|
1226 | ** the address spaces for the bridge |
---|
1227 | */ |
---|
1228 | |
---|
1229 | if( addrhold.start_pciio == astart.start_pciio ) |
---|
1230 | { |
---|
1231 | base8 = limit8 = 0xff; |
---|
1232 | ubase16 = ulimit16 = 0xffff; |
---|
1233 | } |
---|
1234 | else |
---|
1235 | { |
---|
1236 | base8 = (unsigned8) ((addrhold.start_pciio >> 8) & 0xf0); |
---|
1237 | ubase16 = (unsigned16)(addrhold.start_pciio >> 16); |
---|
1238 | limit8 = (unsigned8) ((astart.start_pciio >> 8 ) & 0xf0); |
---|
1239 | ulimit16 = (unsigned16)(astart.start_pciio >> 16); |
---|
1240 | astart.start_pciio += 0x1000; |
---|
1241 | } |
---|
1242 | |
---|
1243 | #ifdef PCI_DEBUG |
---|
1244 | printk("pci: io base %08x limit %08x\n", (base8<<8)+(ubase16<<16), (limit8<<8)+(ulimit16<<16)); |
---|
1245 | #endif |
---|
1246 | #ifdef WRITE_BRIDGE_IO |
---|
1247 | pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_IO_BASE_UPPER16, ubase16 ); |
---|
1248 | pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_IO_BASE, base8 ); |
---|
1249 | |
---|
1250 | pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_IO_LIMIT_UPPER16, ulimit16 ); |
---|
1251 | pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_IO_LIMIT, limit8 ); |
---|
1252 | #endif |
---|
1253 | |
---|
1254 | |
---|
1255 | |
---|
1256 | |
---|
1257 | if( addrhold.start_pcimem == astart.start_pcimem ) |
---|
1258 | { |
---|
1259 | limit16 = 0; |
---|
1260 | base16 = 0xffff; |
---|
1261 | } |
---|
1262 | else |
---|
1263 | { |
---|
1264 | limit16= (unsigned16)((astart.start_pcimem >> 16) & 0xfff0); |
---|
1265 | base16 = (unsigned16)((addrhold.start_pcimem >> 16) & 0xfff0); |
---|
1266 | astart.start_pcimem += 0x100000; |
---|
1267 | } |
---|
1268 | #ifdef PCI_DEBUG |
---|
1269 | printk("pci: memory %04x, limit %04x\n", base16, limit16); |
---|
1270 | #endif |
---|
1271 | #ifdef WRITE_BRIDGE_MEM |
---|
1272 | pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_MEMORY_BASE, base16 ); |
---|
1273 | pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_MEMORY_LIMIT, limit16 ); |
---|
1274 | #endif |
---|
1275 | |
---|
1276 | |
---|
1277 | |
---|
1278 | |
---|
1279 | if( astart.start_prefetch == addrhold.start_prefetch ) |
---|
1280 | { |
---|
1281 | limit16 = 0; |
---|
1282 | base16 = 0xffff; |
---|
1283 | } |
---|
1284 | else |
---|
1285 | { |
---|
1286 | limit16= (unsigned16)((addrhold.start_prefetch >> 16) & 0xfff0); |
---|
1287 | base16 = (unsigned16)((astart.start_prefetch >> 16) & 0xfff0); |
---|
1288 | astart.start_prefetch -= 0x100000; |
---|
1289 | } |
---|
1290 | #ifdef PCI_DEBUG |
---|
1291 | printk("pci: pf memory %04x, limit %04x\n", base16, limit16); |
---|
1292 | #endif |
---|
1293 | #ifdef WRITE_BRIDGE_PF |
---|
1294 | pcibios_write_config_dword(pdev->bus->number, pdev->devfn, PCI_PREF_BASE_UPPER32, 0); |
---|
1295 | pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_PREF_MEMORY_BASE, base16 ); |
---|
1296 | pcibios_write_config_dword(pdev->bus->number, pdev->devfn, PCI_PREF_LIMIT_UPPER32, 0); |
---|
1297 | pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_PREF_MEMORY_LIMIT, limit16 ); |
---|
1298 | #endif |
---|
1299 | |
---|
1300 | #ifdef WRITE_BRIDGE_ENABLE |
---|
1301 | pcibios_write_config_word(pdev->bus->number, |
---|
1302 | pdev->devfn, |
---|
1303 | PCI_BRIDGE_CONTROL, |
---|
1304 | (unsigned16)( 0 )); |
---|
1305 | |
---|
1306 | pcibios_write_config_word(pdev->bus->number, |
---|
1307 | pdev->devfn, |
---|
1308 | PCI_COMMAND, |
---|
1309 | (unsigned16)( PCI_COMMAND_IO | |
---|
1310 | PCI_COMMAND_MEMORY | |
---|
1311 | PCI_COMMAND_MASTER )); |
---|
1312 | #endif |
---|
1313 | } |
---|
1314 | } |
---|
1315 | |
---|
1316 | |
---|
1317 | |
---|
1318 | |
---|
1319 | |
---|
1320 | |
---|
1321 | if( !isroot ) |
---|
1322 | { |
---|
1323 | #ifdef PCI_DEBUG |
---|
1324 | printk("pci: Configuring devices on bus %d\n", pbus->number); |
---|
1325 | #endif |
---|
1326 | /* |
---|
1327 | ** Run thru this bus and set up addresses for all the non-bridge devices |
---|
1328 | */ |
---|
1329 | for( pdev = pbus->devices; pdev; pdev= pdev->sibling ) |
---|
1330 | { |
---|
1331 | if( (pdev->class >> 8) != PCI_CLASS_BRIDGE_PCI ) |
---|
1332 | { |
---|
1333 | pci_resource *r; |
---|
1334 | int i = 0; |
---|
1335 | unsigned alloc; |
---|
1336 | |
---|
1337 | /* enumerate all the resources defined by this device & reserve space |
---|
1338 | ** for each of their defined regions. |
---|
1339 | */ |
---|
1340 | |
---|
1341 | #ifdef PCI_DEBUG |
---|
1342 | printk("pci: configuring; vendor %04x, device %04x\n", pdev->vendor, pdev->device ); |
---|
1343 | #endif |
---|
1344 | |
---|
1345 | while( (r= enum_device_resources( pdev, i++ )) ) |
---|
1346 | { |
---|
1347 | /* |
---|
1348 | ** Force all memory spaces to be non-prefetchable because |
---|
1349 | ** on the pci bus, byte-wise reads against prefetchable |
---|
1350 | ** memory are applied as 32 bit reads, which is a pain |
---|
1351 | ** when you're trying to talk to hardware. This is a |
---|
1352 | ** little sub-optimal because the algorithm doesn't sort |
---|
1353 | ** the address regions to pack them in, OTOH, perhaps its |
---|
1354 | ** not so bad because the inefficient packing will help |
---|
1355 | ** avoid buffer overflow/underflow problems. |
---|
1356 | */ |
---|
1357 | #if 0 |
---|
1358 | if( (r->type & PCI_BASE_ADDRESS_MEM_PREFETCH) ) |
---|
1359 | { |
---|
1360 | /* prefetchable space */ |
---|
1361 | |
---|
1362 | /* shift base pointer down to an integer multiple of the size of the desired region */ |
---|
1363 | astart.start_prefetch -= (alloc= ((r->size / PAGE_SIZE) + 1) * PAGE_SIZE); |
---|
1364 | /* shift base pointer down to an integer multiple of the size of the desired region */ |
---|
1365 | astart.start_prefetch = (astart.start_prefetch / r->size) * r->size; |
---|
1366 | |
---|
1367 | r->base = astart.start_prefetch; |
---|
1368 | #ifdef PCI_DEBUG |
---|
1369 | printk("pci: pf %08X, size %08X, alloc %08X\n", r->base, r->size, alloc ); |
---|
1370 | #endif |
---|
1371 | } |
---|
1372 | #endif |
---|
1373 | if( r->type & PCI_BASE_ADDRESS_SPACE_IO ) |
---|
1374 | { |
---|
1375 | /* io space */ |
---|
1376 | |
---|
1377 | /* shift base pointer up to an integer multiple of the size of the desired region */ |
---|
1378 | if( astart.start_pciio % r->size ) |
---|
1379 | astart.start_pciio = (((astart.start_pciio / r->size) + 1) * r->size); |
---|
1380 | |
---|
1381 | r->base = astart.start_pciio; |
---|
1382 | astart.start_pciio += (alloc= ((r->size / PAGE_SIZE) + 1) * PAGE_SIZE); |
---|
1383 | #ifdef PCI_DEBUG |
---|
1384 | printk("pci: io %08X, size %08X, alloc %08X\n", r->base, r->size, alloc ); |
---|
1385 | #endif |
---|
1386 | } |
---|
1387 | else |
---|
1388 | { |
---|
1389 | /* memory space */ |
---|
1390 | |
---|
1391 | /* shift base pointer up to an integer multiple of the size of the desired region */ |
---|
1392 | if( astart.start_pcimem % r->size ) |
---|
1393 | astart.start_pcimem = (((astart.start_pcimem / r->size) + 1) * r->size); |
---|
1394 | |
---|
1395 | r->base = astart.start_pcimem; |
---|
1396 | astart.start_pcimem += (alloc= ((r->size / PAGE_SIZE) + 1) * PAGE_SIZE); |
---|
1397 | #ifdef PCI_DEBUG |
---|
1398 | printk("pci: mem %08X, size %08X, alloc %08X\n", r->base, r->size, alloc ); |
---|
1399 | #endif |
---|
1400 | } |
---|
1401 | } |
---|
1402 | |
---|
1403 | } |
---|
1404 | } |
---|
1405 | } |
---|
1406 | |
---|
1407 | } |
---|
1408 | |
---|
1409 | |
---|
1410 | |
---|
1411 | |
---|
1412 | |
---|
1413 | |
---|
1414 | |
---|
1415 | |
---|
1416 | |
---|
1417 | |
---|
1418 | void pci_init(void) |
---|
1419 | { |
---|
1420 | PPC_DEVICE *hostbridge; |
---|
1421 | |
---|
1422 | if (pci->last_dev_p) { |
---|
1423 | printk("Two or more calls to pci_init!\n"); |
---|
1424 | return; |
---|
1425 | } |
---|
1426 | pci->last_dev_p = &(bd->pci_devices); |
---|
1427 | hostbridge=residual_find_device(PROCESSORDEVICE, NULL, |
---|
1428 | BridgeController, |
---|
1429 | PCIBridge, -1, 0); |
---|
1430 | if (hostbridge) { |
---|
1431 | if (hostbridge->DeviceId.Interface==PCIBridgeIndirect) { |
---|
1432 | bd->pci_functions=&indirect_functions; |
---|
1433 | /* Should be extracted from residual data, |
---|
1434 | * indeed MPC106 in CHRP mode is different, |
---|
1435 | * but we should not use residual data in |
---|
1436 | * this case anyway. |
---|
1437 | */ |
---|
1438 | pci->config_addr = ((volatile u_int *) |
---|
1439 | (ptr_mem_map->io_base+0xcf8)); |
---|
1440 | pci->config_data = ptr_mem_map->io_base+0xcfc; |
---|
1441 | } else if(hostbridge->DeviceId.Interface==PCIBridgeDirect) { |
---|
1442 | bd->pci_functions=&direct_functions; |
---|
1443 | pci->config_data=(u_char *) 0x80800000; |
---|
1444 | } else { |
---|
1445 | } |
---|
1446 | } else { |
---|
1447 | /* Let us try by experimentation at our own risk! */ |
---|
1448 | u_int id0; |
---|
1449 | bd->pci_functions = &direct_functions; |
---|
1450 | /* On all direct bridges I know the host bridge itself |
---|
1451 | * appears as device 0 function 0. |
---|
1452 | */ |
---|
1453 | pcibios_read_config_dword(0, 0, PCI_VENDOR_ID, &id0); |
---|
1454 | if (id0==~0U) { |
---|
1455 | bd->pci_functions = &indirect_functions; |
---|
1456 | pci->config_addr = ((volatile u_int *) |
---|
1457 | (ptr_mem_map->io_base+0xcf8)); |
---|
1458 | pci->config_data = ptr_mem_map->io_base+0xcfc; |
---|
1459 | } |
---|
1460 | /* Here we should check that the host bridge is actually |
---|
1461 | * present, but if it not, we are in such a desperate |
---|
1462 | * situation, that we probably can't even tell it. |
---|
1463 | */ |
---|
1464 | } |
---|
1465 | /* Now build a small database of all found PCI devices */ |
---|
1466 | printk("\nPCI: Probing PCI hardware\n"); |
---|
1467 | pci_root.subordinate=pci_scan_bus(&pci_root); |
---|
1468 | |
---|
1469 | print_pci_resources("Installed PCI resources:\n"); |
---|
1470 | |
---|
1471 | recursive_bus_reconfigure(NULL); |
---|
1472 | |
---|
1473 | reconfigure_pci(); |
---|
1474 | |
---|
1475 | print_pci_resources("Allocated PCI resources:\n"); |
---|
1476 | |
---|
1477 | #if 0 |
---|
1478 | print_pci_info(); |
---|
1479 | #endif |
---|
1480 | } |
---|
1481 | |
---|
1482 | |
---|
1483 | /* eof */ |
---|