File indexing completed on 2025-05-11 08:23:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <sys/param.h>
0017 #include <sys/types.h>
0018 #include <rtems/bspIo.h>
0019 #include <libcpu/spr.h>
0020 #include "bootldr.h"
0021 #include "pci.h"
0022 #include <libcpu/io.h>
0023 #include <bsp/consoleIo.h>
0024 #include <string.h>
0025 #include <bsp.h>
0026
0027 #include <string.h>
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 typedef struct _pci_resource {
0042 struct _pci_resource *next;
0043 struct pci_dev *dev;
0044 u_long base;
0045 u_long size;
0046 u_char type;
0047 u_char reg;
0048 u_short cmd;
0049 } pci_resource;
0050
0051 typedef struct _pci_area {
0052 struct _pci_area *next;
0053 u_long start;
0054 u_long end;
0055 struct pci_bus *bus;
0056 u_int flags;
0057 } pci_area;
0058
0059 typedef struct _pci_area_head {
0060 pci_area *head;
0061 u_long mask;
0062 int high;
0063 } pci_area_head;
0064
0065 #define PCI_AREA_PREFETCHABLE 0
0066 #define PCI_AREA_MEMORY 1
0067 #define PCI_AREA_IO 2
0068
0069 struct _pci_private {
0070 volatile void * config_addr;
0071 volatile u_char * config_data;
0072 struct pci_dev **last_dev_p;
0073 struct pci_bus pci_root;
0074 pci_resource *resources;
0075 pci_area_head io, mem;
0076
0077 } pci_private = {
0078 config_addr: NULL,
0079 config_data: (volatile u_char *) 0x80800000,
0080 last_dev_p: NULL,
0081 resources: NULL,
0082 io: {NULL, 0xfff, 0},
0083 mem: {NULL, 0xfffff, 0}
0084 };
0085
0086 #define pci ((struct _pci_private *)(bd->pci_private))
0087 #define pci_root pci->pci_root
0088
0089 #if !defined(DEBUG)
0090 #undef PCI_DEBUG
0091
0092
0093
0094
0095 #endif
0096
0097 #if defined(PCI_DEBUG)
0098 static void
0099 print_pci_resources(const char *s) {
0100 pci_resource *p;
0101 printk("%s", s);
0102 for (p=pci->resources; p; p=p->next) {
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 printk(" %p:%p %d:%02x (%04x:%04x) %08lx %08lx %d\n",
0114 p, p->next,
0115 p->dev->bus->number, PCI_SLOT(p->dev->devfn),
0116 p->dev->vendor, p->dev->device,
0117 p->base,
0118 p->size,
0119 p->type);
0120
0121 }
0122 }
0123
0124 static void
0125 print_pci_area(pci_area *p) {
0126 for (; p; p=p->next) {
0127 printk(" %p:%p %p %08lx %08lx\n",
0128 p, p->next, p->bus, p->start, p->end);
0129 }
0130 }
0131
0132 static void
0133 print_pci_areas(const char *s) {
0134 printk("%s PCI I/O areas:\n",s);
0135 print_pci_area(pci->io.head);
0136 printk(" PCI memory areas:\n");
0137 print_pci_area(pci->mem.head);
0138 }
0139 #else
0140 #define print_pci_areas(x)
0141 #define print_pci_resources(x)
0142 #endif
0143
0144
0145
0146
0147
0148
0149
0150 struct blacklist_entry {
0151 u_short vendor, device;
0152 u_char reg;
0153 u_long actual_size;
0154 };
0155
0156 #define BLACKLIST(vid, did, breg, actual_size) \
0157 {PCI_VENDOR_ID_##vid, PCI_DEVICE_ID_##vid##_##did, breg, actual_size}
0158
0159 static struct blacklist_entry blacklist[] = {
0160 BLACKLIST(S3, TRIO, 0, 0x04000000),
0161 {0xffff, 0, 0, 0}
0162 };
0163
0164
0165
0166
0167
0168 #define AREA(r) \
0169 (((r->type&PCI_BASE_ADDRESS_SPACE)==PCI_BASE_ADDRESS_SPACE_IO) ? PCI_AREA_IO :\
0170 ((r->type&PCI_BASE_ADDRESS_MEM_PREFETCH) ? PCI_AREA_PREFETCHABLE :\
0171 PCI_AREA_MEMORY))
0172
0173 static int insert_before(pci_resource *e, pci_resource *t) {
0174 if (e->dev->bus->number != t->dev->bus->number)
0175 return e->dev->bus->number > t->dev->bus->number;
0176 if (AREA(e) != AREA(t)) return AREA(e)<AREA(t);
0177 return (e->size > t->size);
0178 }
0179
0180 static void insert_resource(pci_resource *r) {
0181 struct blacklist_entry *b;
0182 pci_resource *p;
0183 if (!r) return;
0184
0185
0186
0187
0188
0189 for (b=blacklist; b->vendor!=0xffff; b++) {
0190 if ((r->dev->vendor==b->vendor) &&
0191 (r->dev->device==b->device) &&
0192 (r->reg==b->reg)) {
0193 r->size=b->actual_size;
0194 break;
0195 }
0196 }
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 if( r->dev->bus->number == 0 )
0231 {
0232 if ((r->type==PCI_BASE_ADDRESS_SPACE_IO)
0233 ? (r->base && r->base <0x10000)
0234 : (r->base && r->base <0x1000000)) {
0235
0236 #ifdef PCI_DEBUG
0237 printk("freeing region; %p:%p %d:%02x (%04x:%04x) %08lx %08lx %d\n",
0238 r, r->next,
0239 r->dev->bus->number, PCI_SLOT(r->dev->devfn),
0240 r->dev->vendor, r->dev->device,
0241 r->base,
0242 r->size,
0243 r->type);
0244 #endif
0245 sfree(r);
0246 return;
0247 }
0248 }
0249
0250
0251
0252
0253
0254
0255 if ((r->type==PCI_BASE_ADDRESS_SPACE_IO)
0256 ? (r->size > 0x10000)
0257 : (r->size > 0x18000000)) {
0258 sfree(r);
0259 return;
0260 }
0261
0262
0263
0264
0265
0266
0267 if (!pci->resources || insert_before(r, pci->resources)) {
0268 r->next = pci->resources;
0269 pci->resources=r;
0270 } else {
0271 for (p=pci->resources; p->next; p=p->next) {
0272 if (insert_before(r, p->next)) break;
0273 }
0274 r->next=p->next;
0275 p->next=r;
0276 }
0277 }
0278
0279
0280
0281
0282
0283
0284
0285
0286 static u_long find_range(u_char bus, u_char type,
0287 pci_resource **first,
0288 pci_resource **past, u_int *flags) {
0289 pci_resource *p;
0290 u_long total=0;
0291 u_int fl=0;
0292
0293 for (p=pci->resources; p; p=p->next)
0294 {
0295 if ((p->dev->bus->number == bus) &&
0296 AREA(p)==type) break;
0297 }
0298
0299 *first = p;
0300
0301 for (; p; p=p->next)
0302 {
0303 if ((p->dev->bus->number != bus) ||
0304 AREA(p)!=type || p->size == 0) break;
0305 total = total+p->size;
0306 fl |= 1<<p->type;
0307 }
0308
0309 *past = p;
0310
0311
0312
0313
0314 *flags = fl;
0315 return total;
0316 }
0317
0318 static inline void init_free_area(pci_area_head *h, u_long start,
0319 u_long end, u_int mask, int high) {
0320 pci_area *p;
0321 p = salloc(sizeof(pci_area));
0322 if (!p) return;
0323 h->head = p;
0324 p->next = NULL;
0325 p->start = (start+mask)&~mask;
0326 p->end = (end-mask)|mask;
0327 p->bus = NULL;
0328 h->mask = mask;
0329 h->high = high;
0330 }
0331
0332 static void insert_area(pci_area_head *h, pci_area *p) {
0333 pci_area *q = h->head;
0334 if (!p) return;
0335 if (q && (q->start< p->start)) {
0336 for(;q->next && q->next->start<p->start; q = q->next);
0337 if ((q->end >= p->start) ||
0338 (q->next && p->end>=q->next->start)) {
0339 sfree(p);
0340 printk("Overlapping pci areas!\n");
0341 return;
0342 }
0343 p->next = q->next;
0344 q->next = p;
0345 } else {
0346 if (q && (p->end >= q->start)) {
0347 sfree(p);
0348 printk("Overlapping pci areas!\n");
0349 return;
0350 }
0351 p->next = q;
0352 h->head = p;
0353 }
0354 }
0355
0356 static
0357 void remove_area(pci_area_head *h, pci_area *p)
0358 {
0359 pci_area *q = h->head;
0360
0361 if (!p || !q) return;
0362 if (q==p)
0363 {
0364 h->head = q->next;
0365 return;
0366 }
0367 for(;q && q->next!=p; q=q->next);
0368 if (q) q->next=p->next;
0369 }
0370
0371 static pci_area * alloc_area(pci_area_head *h, struct pci_bus *bus,
0372 u_long required, u_long mask, u_int flags) {
0373 pci_area *p;
0374 pci_area *from, *split, *new;
0375
0376 required = (required+h->mask) & ~h->mask;
0377 for (p=h->head, from=NULL; p; p=p->next)
0378 {
0379 u_long l1 = ((p->start+required+mask)&~mask)-1;
0380 u_long l2 = ((p->start+mask)&~mask)+required-1;
0381
0382 if (p->bus) continue;
0383 if ((p->end)>=l1 || (p->end)>=l2) from=p;
0384 if (from && !h->high) break;
0385 }
0386 if (!from) return NULL;
0387
0388 split = salloc(sizeof(pci_area));
0389 new = salloc(sizeof(pci_area));
0390
0391
0392
0393 if (!new) {
0394 sfree(split);
0395 return NULL;
0396 }
0397 new->bus = bus;
0398 new->flags = flags;
0399
0400 if (h->high)
0401 {
0402 u_long l1 = ((from->end+1)&~mask)-required;
0403 u_long l2 = (from->end+1-required)&~mask;
0404 new->start = (l1>l2) ? l1 : l2;
0405 split->end = from->end;
0406 from->end = new->start-1;
0407 split->start = new->start+required;
0408 new->end = new->start+required-1;
0409 }
0410 else
0411 {
0412 u_long l1 = ((from->start+mask)&~mask)+required-1;
0413 u_long l2 = ((from->start+required+mask)&~mask)-1;
0414 new->end = (l1<l2) ? l1 : l2;
0415 split->start = from->start;
0416 from->start = new->end+1;
0417 new->start = new->end+1-required;
0418 split->end = new->start-1;
0419 }
0420
0421 if (from->end+1 == from->start) remove_area(h, from);
0422 if (split->end+1 != split->start)
0423 {
0424 split->bus = NULL;
0425 insert_area(h, split);
0426 }
0427 else
0428 {
0429 sfree(split);
0430 }
0431 insert_area(h, new);
0432 print_pci_areas("alloc_area called:\n");
0433 return new;
0434 }
0435
0436 static inline
0437 void alloc_space(pci_area *p, pci_resource *r)
0438 {
0439 if (p->start & (r->size-1)) {
0440 r->base = p->end+1-r->size;
0441 p->end -= r->size;
0442 } else {
0443 r->base = p->start;
0444 p->start += r->size;
0445 }
0446 }
0447
0448 static void reconfigure_bus_space(u_char bus, u_char type, pci_area_head *h)
0449 {
0450 pci_resource *first, *past, *r;
0451 pci_area *area, tmp;
0452 u_int flags;
0453 u_int required = find_range(bus, type, &first, &past, &flags);
0454
0455 if (required==0) return;
0456
0457 area = alloc_area(h, first->dev->bus, required, first->size-1, flags);
0458
0459 if (!area) return;
0460
0461 tmp = *area;
0462 for (r=first; r!=past; r=r->next)
0463 {
0464 alloc_space(&tmp, r);
0465 }
0466 }
0467
0468 #define BUS0_IO_START 0x10000
0469 #define BUS0_IO_END 0x1ffff
0470 #define BUS0_MEM_START 0x1000000
0471 #define BUS0_MEM_END 0x3f00000
0472
0473 #define BUSREST_IO_START 0x20000
0474 #define BUSREST_IO_END 0x7ffff
0475 #define BUSREST_MEM_START 0x4000000
0476 #define BUSREST_MEM_END 0x10000000
0477
0478 static void reconfigure_pci(void) {
0479 pci_resource *r;
0480 struct pci_dev *dev;
0481
0482 u_long bus0_mem_start = BUS0_MEM_START;
0483 u_long bus0_mem_end = BUS0_MEM_END;
0484
0485 if ( residual_fw_is_qemu( bd->residual ) ) {
0486 bus0_mem_start += PREP_ISA_MEM_BASE;
0487 bus0_mem_end += PREP_ISA_MEM_BASE;
0488 }
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498 init_free_area(&pci->io, BUS0_IO_START, BUS0_IO_END, 0xfff, 0);
0499 init_free_area(&pci->mem, bus0_mem_start, bus0_mem_end, 0xfffff, 0);
0500
0501
0502
0503
0504
0505 reconfigure_bus_space(0, PCI_AREA_IO, &pci->io);
0506 reconfigure_bus_space(0, PCI_AREA_MEMORY, &pci->mem);
0507 reconfigure_bus_space(0, PCI_AREA_PREFETCHABLE, &pci->mem);
0508
0509
0510
0511
0512
0513
0514
0515
0516 for (r=pci->resources; r; r= r->next) {
0517 if (!r->dev->sysdata) {
0518 r->dev->sysdata=r;
0519 pci_bootloader_read_config_word(r->dev, PCI_COMMAND, &r->cmd);
0520 pci_bootloader_write_config_word(r->dev, PCI_COMMAND,
0521 r->cmd & ~(PCI_COMMAND_IO|
0522 PCI_COMMAND_MEMORY));
0523 }
0524 }
0525
0526 for (r=pci->resources; r; r= r->next) {
0527 pci_bootloader_write_config_dword(r->dev,
0528 PCI_BASE_ADDRESS_0+(r->reg<<2),
0529 r->base);
0530
0531 if ( residual_fw_is_qemu( bd->residual ) && r->dev->sysdata ) {
0532 if ( PCI_BASE_ADDRESS_SPACE_IO == (r->type & PCI_BASE_ADDRESS_SPACE) )
0533 ((pci_resource*)r->dev->sysdata)->cmd |= PCI_COMMAND_IO;
0534 else
0535 ((pci_resource*)r->dev->sysdata)->cmd |= PCI_COMMAND_MEMORY;
0536 }
0537
0538 if ((r->type&
0539 (PCI_BASE_ADDRESS_SPACE|
0540 PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
0541 (PCI_BASE_ADDRESS_SPACE_MEMORY|
0542 PCI_BASE_ADDRESS_MEM_TYPE_64)) {
0543 pci_bootloader_write_config_dword(r->dev,
0544 PCI_BASE_ADDRESS_1+(r->reg<<2),
0545 0);
0546 }
0547 }
0548 for (dev=bd->pci_devices; dev; dev= dev->next) {
0549 if (dev->sysdata) {
0550 pci_bootloader_write_config_word(dev, PCI_COMMAND,
0551 ((pci_resource *)dev->sysdata)
0552 ->cmd);
0553 dev->sysdata=NULL;
0554 }
0555 }
0556 }
0557
0558 static int
0559 indirect_pci_read_config_byte(unsigned char bus, unsigned char dev_fn,
0560 unsigned char offset, uint8_t *val) {
0561 out_be32(pci->config_addr,
0562 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
0563 *val=in_8(pci->config_data + (offset&3));
0564 return PCIBIOS_SUCCESSFUL;
0565 }
0566
0567 static int
0568 indirect_pci_read_config_word(unsigned char bus, unsigned char dev_fn,
0569 unsigned char offset, uint16_t *val) {
0570 *val = 0xffff;
0571 if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
0572 out_be32(pci->config_addr,
0573 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
0574 *val=in_le16((volatile uint16_t *)(pci->config_data + (offset&3)));
0575 return PCIBIOS_SUCCESSFUL;
0576 }
0577
0578 static int
0579 indirect_pci_read_config_dword(unsigned char bus, unsigned char dev_fn,
0580 unsigned char offset, uint32_t *val) {
0581 *val = 0xffffffff;
0582 if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
0583 out_be32(pci->config_addr,
0584 0x80|(bus<<8)|(dev_fn<<16)|(offset<<24));
0585 *val=in_le32((volatile uint32_t *)pci->config_data);
0586 return PCIBIOS_SUCCESSFUL;
0587 }
0588
0589 static int
0590 indirect_pci_write_config_byte(unsigned char bus, unsigned char dev_fn,
0591 unsigned char offset, uint8_t val) {
0592 out_be32(pci->config_addr,
0593 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
0594 out_8(pci->config_data + (offset&3), val);
0595 return PCIBIOS_SUCCESSFUL;
0596 }
0597
0598 static int
0599 indirect_pci_write_config_word(unsigned char bus, unsigned char dev_fn,
0600 unsigned char offset, uint16_t val) {
0601 if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
0602 out_be32(pci->config_addr,
0603 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
0604 out_le16((volatile uint16_t *)(pci->config_data + (offset&3)), val);
0605 return PCIBIOS_SUCCESSFUL;
0606 }
0607
0608 static int
0609 indirect_pci_write_config_dword(unsigned char bus, unsigned char dev_fn,
0610 unsigned char offset, uint32_t val) {
0611 if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
0612 out_be32(pci->config_addr,
0613 0x80|(bus<<8)|(dev_fn<<16)|(offset<<24));
0614 out_le32((volatile uint32_t *)pci->config_data, val);
0615 return PCIBIOS_SUCCESSFUL;
0616 }
0617
0618 static const struct pci_bootloader_config_access_functions indirect_functions = {
0619 indirect_pci_read_config_byte,
0620 indirect_pci_read_config_word,
0621 indirect_pci_read_config_dword,
0622 indirect_pci_write_config_byte,
0623 indirect_pci_write_config_word,
0624 indirect_pci_write_config_dword
0625 };
0626
0627 static int
0628 direct_pci_read_config_byte(unsigned char bus, unsigned char dev_fn,
0629 unsigned char offset, uint8_t *val) {
0630 if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
0631 *val=0xff;
0632 return PCIBIOS_DEVICE_NOT_FOUND;
0633 }
0634 *val=in_8(pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1)
0635 + (PCI_FUNC(dev_fn)<<8) + offset);
0636 return PCIBIOS_SUCCESSFUL;
0637 }
0638
0639 static int
0640 direct_pci_read_config_word(unsigned char bus, unsigned char dev_fn,
0641 unsigned char offset, uint16_t *val) {
0642 *val = 0xffff;
0643 if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
0644 if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
0645 return PCIBIOS_DEVICE_NOT_FOUND;
0646 }
0647 *val=in_le16((volatile uint16_t *)
0648 (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1)
0649 + (PCI_FUNC(dev_fn)<<8) + offset));
0650 return PCIBIOS_SUCCESSFUL;
0651 }
0652
0653 static int
0654 direct_pci_read_config_dword(unsigned char bus, unsigned char dev_fn,
0655 unsigned char offset, uint32_t *val) {
0656 *val = 0xffffffff;
0657 if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
0658 if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
0659 return PCIBIOS_DEVICE_NOT_FOUND;
0660 }
0661 *val=in_le32((volatile uint32_t *)
0662 (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1)
0663 + (PCI_FUNC(dev_fn)<<8) + offset));
0664 return PCIBIOS_SUCCESSFUL;
0665 }
0666
0667 static int
0668 direct_pci_write_config_byte(unsigned char bus, unsigned char dev_fn,
0669 unsigned char offset, uint8_t val) {
0670 if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
0671 return PCIBIOS_DEVICE_NOT_FOUND;
0672 }
0673 out_8(pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1)
0674 + (PCI_FUNC(dev_fn)<<8) + offset,
0675 val);
0676 return PCIBIOS_SUCCESSFUL;
0677 }
0678
0679 static int
0680 direct_pci_write_config_word(unsigned char bus, unsigned char dev_fn,
0681 unsigned char offset, uint16_t val) {
0682 if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
0683 if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
0684 return PCIBIOS_DEVICE_NOT_FOUND;
0685 }
0686 out_le16((volatile uint16_t *)
0687 (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1)
0688 + (PCI_FUNC(dev_fn)<<8) + offset),
0689 val);
0690 return PCIBIOS_SUCCESSFUL;
0691 }
0692
0693 static int
0694 direct_pci_write_config_dword(unsigned char bus, unsigned char dev_fn,
0695 unsigned char offset, uint32_t val) {
0696 if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
0697 if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
0698 return PCIBIOS_DEVICE_NOT_FOUND;
0699 }
0700 out_le32((volatile uint32_t *)
0701 (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1)
0702 + (PCI_FUNC(dev_fn)<<8) + offset),
0703 val);
0704 return PCIBIOS_SUCCESSFUL;
0705 }
0706
0707 static const struct pci_bootloader_config_access_functions direct_functions = {
0708 direct_pci_read_config_byte,
0709 direct_pci_read_config_word,
0710 direct_pci_read_config_dword,
0711 direct_pci_write_config_byte,
0712 direct_pci_write_config_word,
0713 direct_pci_write_config_dword
0714 };
0715
0716 static void pci_read_bases(struct pci_dev *dev, unsigned int howmany)
0717 {
0718 unsigned int reg, nextreg;
0719
0720 #define REG (PCI_BASE_ADDRESS_0 + (reg<<2))
0721
0722 u_short cmd;
0723 uint32_t l, ml;
0724 pci_bootloader_read_config_word(dev, PCI_COMMAND, &cmd);
0725
0726 for(reg=0; reg<howmany; reg=nextreg)
0727 {
0728 pci_resource *r;
0729
0730 nextreg=reg+1;
0731 pci_bootloader_read_config_dword(dev, REG, &l);
0732 #if 0
0733 if (l == 0xffffffff ) continue;
0734 #endif
0735
0736
0737
0738
0739
0740 pci_bootloader_write_config_word(dev, PCI_COMMAND, cmd &
0741 ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY));
0742 pci_bootloader_write_config_dword(dev, REG, ~0);
0743 pci_bootloader_read_config_dword(dev, REG, &ml);
0744 pci_bootloader_write_config_dword(dev, REG, l);
0745
0746
0747
0748
0749 pci_bootloader_write_config_word(dev, PCI_COMMAND, cmd);
0750
0751
0752 if ( ml == 0 || ml == 0xffffffff ) continue;
0753
0754 if ((l &
0755 (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK))
0756 == (PCI_BASE_ADDRESS_MEM_TYPE_64
0757 |PCI_BASE_ADDRESS_SPACE_MEMORY)) {
0758 nextreg=reg+2;
0759 }
0760 dev->base_address[reg] = l;
0761 r = salloc(sizeof(pci_resource));
0762 if (!r) {
0763 printk("Error allocating pci_resource struct.\n");
0764 continue;
0765 }
0766 r->dev = dev;
0767 r->reg = reg;
0768 if ((l&PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
0769 r->type = l&~PCI_BASE_ADDRESS_IO_MASK;
0770 r->base = l&PCI_BASE_ADDRESS_IO_MASK;
0771
0772 } else {
0773 r->type = l&~PCI_BASE_ADDRESS_MEM_MASK;
0774 r->base = l&PCI_BASE_ADDRESS_MEM_MASK;
0775
0776 }
0777
0778
0779
0780 {
0781 unsigned int c= 16 , val= 0;
0782 while( !(val= ml & c) ) c <<= 1;
0783 r->size = val;
0784 }
0785
0786 #ifdef PCI_DEBUG
0787 printk(" readbase bus %d, (%04x:%04x), base %08x, size %08x, type %d\n",
0788 r->dev->bus->number,
0789 r->dev->vendor,
0790 r->dev->device,
0791 r->base,
0792 r->size,
0793 r->type );
0794 #endif
0795
0796
0797 insert_resource(r);
0798 }
0799 }
0800
0801 static u_int pci_scan_bus(struct pci_bus *bus)
0802 {
0803 unsigned int devfn, max;
0804 uint32_t class;
0805 uint32_t l;
0806 unsigned char irq, hdr_type, is_multi = 0;
0807 struct pci_dev *dev, **bus_last;
0808 struct pci_bus *child;
0809
0810 #if 0
0811 printk("scanning pci bus %d\n", bus->number );
0812 #endif
0813
0814 bus_last = &bus->devices;
0815 max = bus->secondary;
0816 for (devfn = 0; devfn < 0xff; ++devfn) {
0817 if (PCI_FUNC(devfn) && !is_multi) {
0818
0819 continue;
0820 }
0821 if (pcibios_read_config_byte(bus->number, devfn, PCI_HEADER_TYPE, &hdr_type))
0822 continue;
0823 if (!PCI_FUNC(devfn))
0824 is_multi = hdr_type & 0x80;
0825
0826 if (pcibios_read_config_dword(bus->number, devfn, PCI_VENDOR_ID, &l) ||
0827
0828 l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000) {
0829 is_multi = 0;
0830 continue;
0831 }
0832
0833 dev = salloc(sizeof(*dev));
0834 dev->bus = bus;
0835 dev->devfn = devfn;
0836 dev->vendor = l & 0xffff;
0837 dev->device = (l >> 16) & 0xffff;
0838
0839 pcibios_read_config_dword(bus->number, devfn,
0840 PCI_CLASS_REVISION, &class);
0841 class >>= 8;
0842 dev->class = class;
0843 class >>= 8;
0844 dev->hdr_type = hdr_type;
0845
0846 switch (hdr_type & 0x7f) {
0847 case PCI_HEADER_TYPE_NORMAL:
0848 if (class == PCI_CLASS_BRIDGE_PCI)
0849 goto bad;
0850
0851
0852
0853
0854 pcibios_read_config_byte(bus->number, dev->devfn, PCI_INTERRUPT_PIN, &irq);
0855 if (irq)
0856 pcibios_read_config_byte(bus->number, dev->devfn, PCI_INTERRUPT_LINE, &irq);
0857 dev->irq = irq;
0858
0859
0860
0861
0862 pci_read_bases(dev, 6);
0863 pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS, &l);
0864 dev->rom_address = (l == 0xffffffff) ? 0 : l;
0865 break;
0866 case PCI_HEADER_TYPE_BRIDGE:
0867 if (class != PCI_CLASS_BRIDGE_PCI)
0868 goto bad;
0869 pci_read_bases(dev, 2);
0870 pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS1, &l);
0871 dev->rom_address = (l == 0xffffffff) ? 0 : l;
0872 break;
0873 case PCI_HEADER_TYPE_CARDBUS:
0874 if (class != PCI_CLASS_BRIDGE_CARDBUS)
0875 goto bad;
0876 pci_read_bases(dev, 1);
0877 break;
0878
0879 default:
0880 bad:
0881 printk("PCI device with unknown header type %d ignored.\n",
0882 hdr_type&0x7f);
0883 continue;
0884 }
0885
0886
0887
0888
0889
0890 *pci->last_dev_p = dev;
0891 pci->last_dev_p = &dev->next;
0892
0893
0894
0895
0896
0897 *bus_last = dev;
0898 bus_last = &dev->sibling;
0899
0900 }
0901
0902
0903
0904
0905
0906 for(dev=bus->devices; dev; dev=dev->sibling)
0907
0908
0909
0910 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
0911 uint32_t buses;
0912 unsigned int devfn = dev->devfn;
0913 unsigned short cr;
0914
0915
0916
0917
0918 child = salloc(sizeof(*child));
0919 child->next = bus->children;
0920 bus->children = child;
0921 child->self = dev;
0922 child->parent = bus;
0923
0924
0925
0926
0927
0928 child->number = child->secondary = ++max;
0929 child->primary = bus->secondary;
0930 child->subordinate = 0xff;
0931
0932
0933
0934
0935 pcibios_read_config_word(bus->number, devfn, PCI_COMMAND, &cr);
0936 pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, 0x0000);
0937 pcibios_write_config_word(bus->number, devfn, PCI_STATUS, 0xffff);
0938
0939
0940
0941
0942
0943
0944 pcibios_read_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, &buses);
0945 if ((buses & 0xFFFFFF) != 0)
0946 {
0947 unsigned int cmax;
0948
0949 child->primary = buses & 0xFF;
0950 child->secondary = (buses >> 8) & 0xFF;
0951 child->subordinate = (buses >> 16) & 0xFF;
0952 child->number = child->secondary;
0953 cmax = pci_scan_bus(child);
0954 if (cmax > max) max = cmax;
0955 }
0956 else
0957 {
0958
0959
0960
0961 buses &= 0xff000000;
0962 buses |=
0963 (((unsigned int)(child->primary) << 0) |
0964 ((unsigned int)(child->secondary) << 8) |
0965 ((unsigned int)(child->subordinate) << 16));
0966 pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses);
0967
0968
0969
0970 max = pci_scan_bus(child);
0971
0972
0973
0974
0975 child->subordinate = max;
0976 buses = (buses & 0xff00ffff)
0977 | ((unsigned int)(child->subordinate) << 16);
0978 pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses);
0979 }
0980 pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, cr );
0981 }
0982
0983
0984
0985
0986
0987
0988
0989
0990 return max;
0991 }
0992
0993 #if 0
0994
0995 void
0996 pci_fixup(void)
0997 {
0998 struct pci_dev *p;
0999 struct pci_bus *bus;
1000
1001 for (bus = &pci_root; bus; bus=bus->next)
1002 {
1003 for (p=bus->devices; p; p=p->sibling)
1004 {
1005 }
1006 }
1007 }
1008
1009 static void print_pci_info()
1010 {
1011 pci_resource *r;
1012 struct pci_bus *pb = &pci_root;
1013
1014 printk("\n");
1015 printk("PCI busses:\n");
1016
1017 for(pb= &pci_root; pb; pb=pb->children )
1018 {
1019 printk(" number %d, primary %d, secondary %d, subordinate %d\n",
1020 pb->number,
1021 pb->primary,
1022 pb->secondary,
1023 pb->subordinate );
1024 printk(" bridge; vendor %04x, device %04x\n",
1025 pb->self->vendor,
1026 pb->self->device );
1027
1028 {
1029 struct pci_dev *pd;
1030
1031 for(pd= pb->devices; pd; pd=pd->sibling )
1032 {
1033 printk(" vendor %04x, device %04x, irq %d\n",
1034 pd->vendor,
1035 pd->device,
1036 pd->irq );
1037
1038 }
1039 printk("\n");
1040 }
1041
1042 }
1043 printk("\n");
1044
1045 printk("PCI resources:\n");
1046 for (r=pci->resources; r; r= r->next)
1047 {
1048 printk(" bus %d, vendor %04x, device %04x, base %08x, size %08x, type %d\n",
1049 r->dev->bus->number,
1050 r->dev->vendor,
1051 r->dev->device,
1052 r->base,
1053 r->size,
1054 r->type );
1055 }
1056 printk("\n");
1057
1058 return;
1059 }
1060
1061 #endif
1062
1063 static struct _addr_start
1064 {
1065 uint32_t start_pcimem;
1066 uint32_t start_pciio;
1067 uint32_t start_prefetch;
1068 } astart;
1069
1070 static pci_resource *enum_device_resources( struct pci_dev *pdev, int i )
1071 {
1072 pci_resource *r;
1073
1074 for(r= pci->resources; r; r= r->next )
1075 {
1076 if( r->dev == pdev )
1077 {
1078 if( i-- == 0 ) break;
1079 }
1080 }
1081 return r;
1082 }
1083
1084 static void recursive_bus_reconfigure( struct pci_bus *pbus )
1085 {
1086 struct pci_dev *pdev;
1087 struct pci_bus *childbus;
1088 int isroot = 0;
1089
1090 if( !pbus )
1091 {
1092
1093 astart.start_pcimem = BUSREST_MEM_START;
1094 astart.start_pciio = BUSREST_IO_START;
1095 astart.start_prefetch = ((BUSREST_MEM_END >> 16) << 16);
1096
1097 pbus = &pci_root;
1098 isroot = -1;
1099 }
1100
1101 #define WRITE_BRIDGE_IO
1102 #define WRITE_BRIDGE_MEM
1103 #define WRITE_BRIDGE_PF
1104 #define WRITE_BRIDGE_ENABLE
1105
1106
1107
1108
1109 for( childbus= pbus->children; childbus; childbus= childbus->next )
1110 {
1111 pdev= childbus->self;
1112
1113 pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_LATENCY_TIMER, 0x80 );
1114 pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_SEC_LATENCY_TIMER, 0x80 );
1115
1116 {
1117 struct _addr_start addrhold;
1118 uint8_t base8, limit8;
1119 uint16_t base16, limit16, ubase16, ulimit16;
1120
1121
1122 memcpy( &addrhold, &astart, sizeof(struct _addr_start));
1123
1124 recursive_bus_reconfigure( childbus );
1125
1126 #ifdef PCI_DEBUG
1127 printk("pci: configuring bus %d bridge (%04x:%04x), bus %d : (%d-%d)\n",
1128 pdev->bus->number,
1129 pdev->vendor,
1130 pdev->device,
1131 childbus->primary,
1132 childbus->secondary,
1133 childbus->subordinate );
1134 #endif
1135
1136
1137
1138
1139
1140
1141 if( addrhold.start_pciio == astart.start_pciio )
1142 {
1143 base8 = limit8 = 0xff;
1144 ubase16 = ulimit16 = 0xffff;
1145 }
1146 else
1147 {
1148 base8 = (uint8_t) ((addrhold.start_pciio >> 8) & 0xf0);
1149 ubase16 = (uint16_t)(addrhold.start_pciio >> 16);
1150 limit8 = (uint8_t) ((astart.start_pciio >> 8 ) & 0xf0);
1151 ulimit16 = (uint16_t)(astart.start_pciio >> 16);
1152 astart.start_pciio += 0x1000;
1153 }
1154
1155 #ifdef PCI_DEBUG
1156 printk("pci: io base %08x limit %08x\n", (base8<<8)+(ubase16<<16), (limit8<<8)+(ulimit16<<16));
1157 #endif
1158 #ifdef WRITE_BRIDGE_IO
1159 pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_IO_BASE_UPPER16, ubase16 );
1160 pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_IO_BASE, base8 );
1161
1162 pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_IO_LIMIT_UPPER16, ulimit16 );
1163 pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_IO_LIMIT, limit8 );
1164 #endif
1165
1166 if( addrhold.start_pcimem == astart.start_pcimem )
1167 {
1168 limit16 = 0;
1169 base16 = 0xffff;
1170 }
1171 else
1172 {
1173 limit16= (uint16_t)((astart.start_pcimem >> 16) & 0xfff0);
1174 base16 = (uint16_t)((addrhold.start_pcimem >> 16) & 0xfff0);
1175 astart.start_pcimem += 0x100000;
1176 }
1177 #ifdef PCI_DEBUG
1178 printk("pci: memory %04x, limit %04x\n", base16, limit16);
1179 #endif
1180 #ifdef WRITE_BRIDGE_MEM
1181 pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_MEMORY_BASE, base16 );
1182 pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_MEMORY_LIMIT, limit16 );
1183 #endif
1184
1185
1186 if( astart.start_prefetch == addrhold.start_prefetch )
1187 {
1188 limit16 = 0;
1189 base16 = 0xffff;
1190 }
1191 else
1192 {
1193 limit16= (uint16_t)((addrhold.start_prefetch >> 16) & 0xfff0);
1194 base16 = (uint16_t)((astart.start_prefetch >> 16) & 0xfff0);
1195 astart.start_prefetch -= 0x100000;
1196 }
1197 #ifdef PCI_DEBUG
1198 printk("pci: pf memory %04x, limit %04x\n", base16, limit16);
1199 #endif
1200 #ifdef WRITE_BRIDGE_PF
1201 pcibios_write_config_dword(pdev->bus->number, pdev->devfn, PCI_PREF_BASE_UPPER32, 0);
1202 pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_PREF_MEMORY_BASE, base16 );
1203 pcibios_write_config_dword(pdev->bus->number, pdev->devfn, PCI_PREF_LIMIT_UPPER32, 0);
1204 pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_PREF_MEMORY_LIMIT, limit16 );
1205 #endif
1206
1207 #ifdef WRITE_BRIDGE_ENABLE
1208 pcibios_write_config_word(pdev->bus->number,
1209 pdev->devfn,
1210 PCI_BRIDGE_CONTROL,
1211 (uint16_t)( 0 ));
1212
1213 pcibios_write_config_word(pdev->bus->number,
1214 pdev->devfn,
1215 PCI_COMMAND,
1216 (uint16_t)( PCI_COMMAND_IO |
1217 PCI_COMMAND_MEMORY |
1218 PCI_COMMAND_MASTER ));
1219 #endif
1220 }
1221 }
1222
1223 if( !isroot )
1224 {
1225 #ifdef PCI_DEBUG
1226 printk("pci: Configuring devices on bus %d\n", pbus->number);
1227 #endif
1228
1229
1230
1231 for( pdev = pbus->devices; pdev; pdev= pdev->sibling )
1232 {
1233 if( (pdev->class >> 8) != PCI_CLASS_BRIDGE_PCI )
1234 {
1235 pci_resource *r;
1236 int i = 0;
1237 unsigned alloc;
1238
1239
1240
1241
1242
1243 #ifdef PCI_DEBUG
1244 printk("pci: configuring; vendor %04x, device %04x\n", pdev->vendor, pdev->device );
1245 #endif
1246
1247 while( (r= enum_device_resources( pdev, i++ )) )
1248 {
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259 #if 0
1260 if( (r->type & PCI_BASE_ADDRESS_MEM_PREFETCH) )
1261 {
1262
1263
1264
1265 astart.start_prefetch -= (alloc= ((r->size / PAGE_SIZE) + 1) * PAGE_SIZE);
1266
1267 astart.start_prefetch = (astart.start_prefetch / r->size) * r->size;
1268
1269 r->base = astart.start_prefetch;
1270 #ifdef PCI_DEBUG
1271 printk("pci: pf %08X, size %08X, alloc %08X\n", r->base, r->size, alloc );
1272 #endif
1273 }
1274 #endif
1275 if( r->type & PCI_BASE_ADDRESS_SPACE_IO )
1276 {
1277
1278
1279
1280 if( astart.start_pciio % r->size )
1281 astart.start_pciio = (((astart.start_pciio / r->size) + 1) * r->size);
1282
1283 r->base = astart.start_pciio;
1284 astart.start_pciio += (alloc= ((r->size / PAGE_SIZE) + 1) * PAGE_SIZE);
1285 #ifdef PCI_DEBUG
1286 printk("pci: io %08X, size %08X, alloc %08X\n", r->base, r->size, alloc );
1287 #endif
1288 }
1289 else
1290 {
1291
1292
1293
1294 if( astart.start_pcimem % r->size )
1295 astart.start_pcimem = (((astart.start_pcimem / r->size) + 1) * r->size);
1296
1297 r->base = astart.start_pcimem;
1298 astart.start_pcimem += (alloc= ((r->size / PAGE_SIZE) + 1) * PAGE_SIZE);
1299 #ifdef PCI_DEBUG
1300 printk("pci: mem %08X, size %08X, alloc %08X\n", r->base, r->size, alloc );
1301 #endif
1302 }
1303 }
1304
1305 }
1306 }
1307 }
1308
1309 }
1310
1311 void pci_init(void)
1312 {
1313 PPC_DEVICE *hostbridge;
1314
1315 if (pci->last_dev_p) {
1316 printk("Two or more calls to pci_init!\n");
1317 return;
1318 }
1319 pci->last_dev_p = &(bd->pci_devices);
1320 hostbridge=residual_find_device(PROCESSORDEVICE, NULL,
1321 BridgeController,
1322 PCIBridge, -1, 0);
1323 if (hostbridge) {
1324 if (hostbridge->DeviceId.Interface==PCIBridgeIndirect) {
1325 bd->pci_functions=&indirect_functions;
1326
1327
1328
1329
1330
1331 pci->config_addr = ((volatile void *)
1332 (ptr_mem_map->io_base+0xcf8));
1333 pci->config_data = ptr_mem_map->io_base+0xcfc;
1334 } else if(hostbridge->DeviceId.Interface==PCIBridgeDirect) {
1335 bd->pci_functions=&direct_functions;
1336 pci->config_data=(u_char *) 0x80800000;
1337 } else {
1338 }
1339 } else {
1340
1341 uint32_t id0;
1342 bd->pci_functions = &direct_functions;
1343
1344
1345
1346 pcibios_read_config_dword(0, 0, PCI_VENDOR_ID, &id0);
1347 if (id0==~0U) {
1348 bd->pci_functions = &indirect_functions;
1349 pci->config_addr = ((volatile u_int *)
1350 (ptr_mem_map->io_base+0xcf8));
1351 pci->config_data = ptr_mem_map->io_base+0xcfc;
1352 }
1353
1354
1355
1356
1357 }
1358
1359 printk("\nPCI: Probing PCI hardware\n");
1360 pci_root.subordinate=pci_scan_bus(&pci_root);
1361
1362 print_pci_resources("Installed PCI resources:\n");
1363
1364 recursive_bus_reconfigure(NULL);
1365
1366 reconfigure_pci();
1367
1368 print_pci_resources("Allocated PCI resources:\n");
1369
1370 #if 0
1371 print_pci_info();
1372 #endif
1373 }
1374
1375