Changeset 12838559 in rtems


Ignore:
Timestamp:
06/13/03 17:40:41 (20 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Children:
641fb28
Parents:
7a848b40
Message:

2003-06-13 Greg Menke <gregory.menke@…>

PR 405/bsps

  • bootloader/pci.c: Added support for configuring devices for pci busses > 0
  • pci/pci.c, pci/pci.h: Added FixupPCI() to store vectors in the INTERRUPT_LINE register of pci devices any # of hops away from the host processor.
  • motorola/motorola.c, motorola/motorola.h: Added interrupt routing tables in support of FixupPCI. This is board-specific, each board will have to supply information for FixupPCI() to do anything for it.
  • startup/bspstart.c: Extended bat2 to cover entire PCI address space.
  • irq/irq.c, irq/irq.h: Added support for shared interrupts. Existing single hander vectors are undisturbed, a new function added to allow adding/removing handlers from a vector.
Location:
c/src/lib/libbsp/powerpc/shared
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/shared/ChangeLog

    r7a848b40 r12838559  
     12003-06-13      Greg Menke <gregory.menke@gsfc.nasa.gov>
     2
     3        PR 405/bsps
     4        * bootloader/pci.c: Added support for configuring devices for pci
     5        busses > 0
     6        * pci/pci.c, pci/pci.h: Added FixupPCI() to store vectors in the
     7        INTERRUPT_LINE register of pci devices any # of hops away
     8        from the host processor.
     9        * motorola/motorola.c, motorola/motorola.h: Added interrupt
     10        routing tables in support of FixupPCI.  This is board-specific,
     11        each board will have to supply information for FixupPCI() to do
     12        anything for it.
     13        * startup/bspstart.c: Extended bat2 to cover entire PCI address space.
     14        * irq/irq.c, irq/irq.h: Added support for shared interrupts.
     15        Existing single hander vectors are undisturbed, a new function
     16        added to allow adding/removing handlers from a vector.
     17
    1182003-06-13  Till Straumann <strauman@slac.stanford.edu>
    219
  • c/src/lib/libbsp/powerpc/shared/bootloader/README

    r7a848b40 r12838559  
    4040
    4141
     42**************************************************
     432003/5/7, Greg Menke, gregory.menke@gsfc.nasa.gov
     44
     45Reworked the pci bus 0 initialization a little and added support for
     46configuring an arbitrary number of other busses & their respective
     47bridges.  Also added support for configuring IO ranges below 0x10000,
     48which I think is reasonable given this is a PowerPC bsp.
     49
  • c/src/lib/libbsp/powerpc/shared/bootloader/pci.c

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

    r7a848b40 r12838559  
    119119}
    120120
     121
     122/*
     123 * ------------------------ RTEMS Shared Irq Handler Mngt Routines ----------------
     124 */
     125int BSP_install_rtems_shared_irq_handler  (const rtems_irq_connect_data* irq)
     126{
     127    unsigned int level;
     128    rtems_irq_connect_data* vchain;
     129 
     130    if (!isValidInterrupt(irq->name)) {
     131      printk("Invalid interrupt vector %i\n",irq->name);
     132      return 0;
     133    }
     134    if ( (int)rtems_hdl_tbl[irq->name].next_handler  == -1 ) {
     135      printk("IRQ vector %i already connected to an unshared handler\n",irq->name);
     136      return 0;
     137    }
     138    _CPU_ISR_Disable(level);
     139
     140
     141     vchain = (rtems_irq_connect_data*)malloc(sizeof(rtems_irq_connect_data));
     142
     143    /* save off topmost handler */
     144    vchain[0]= rtems_hdl_tbl[irq->name];
     145   
     146    /*
     147     * store the data provided by user
     148     */
     149    rtems_hdl_tbl[irq->name] = *irq;
     150
     151    /* link chain to new topmost handler */
     152    rtems_hdl_tbl[irq->name].next_handler = (void *)vchain;
     153
     154   
     155    if (is_isa_irq(irq->name)) {
     156      /*
     157       * Enable interrupt at PIC level
     158       */
     159      BSP_irq_enable_at_i8259s (irq->name);
     160    }
     161   
     162    if (is_pci_irq(irq->name)) {
     163      /*
     164       * Enable interrupt at OPENPIC level
     165       */
     166      openpic_enable_irq ((int) irq->name - BSP_PCI_IRQ_LOWEST_OFFSET);
     167    }
     168
     169    if (is_processor_irq(irq->name)) {
     170      /*
     171       * Enable exception at processor level
     172       */
     173    }
     174    /*
     175     * Enable interrupt on device
     176     */
     177    irq->on(irq);
     178   
     179    _CPU_ISR_Enable(level);
     180
     181    return 1;
     182}
     183
     184
    121185/*
    122186 * ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
     
    148212     */
    149213    rtems_hdl_tbl[irq->name] = *irq;
     214    rtems_hdl_tbl[irq->name].next_handler = (void *)-1;
    150215   
    151216    if (is_isa_irq(irq->name)) {
     
    190255int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
    191256{
     257   rtems_irq_connect_data *pchain= NULL, *vchain = NULL;
    192258    unsigned int level;
    193259 
     
    207273    _CPU_ISR_Disable(level);
    208274
     275    if( (int)rtems_hdl_tbl[irq->name].next_handler != -1 )
     276    {
     277       int found = 0;
     278
     279       for( (pchain= NULL, vchain = &rtems_hdl_tbl[irq->name]);
     280            (vchain->hdl != default_rtems_entry.hdl);
     281            (pchain= vchain, vchain = (rtems_irq_connect_data*)vchain->next_handler) )
     282       {
     283          if( vchain->hdl == irq->hdl )
     284          {
     285             found= -1; break;
     286          }
     287       }
     288
     289       if( !found )
     290       {
     291          _CPU_ISR_Enable(level);
     292          return 0;
     293       }
     294    }
     295    else
     296    {
     297       if (rtems_hdl_tbl[irq->name].hdl != irq->hdl)
     298       {
     299          _CPU_ISR_Enable(level);
     300         return 0;
     301       }
     302    }
     303
    209304    if (is_isa_irq(irq->name)) {
    210305      /*
     
    233328     * restore the default irq value
    234329     */
    235     rtems_hdl_tbl[irq->name] = default_rtems_entry;
     330    if( !vchain )
     331    {
     332       /* single handler vector... */
     333       rtems_hdl_tbl[irq->name] = default_rtems_entry;
     334    }
     335    else
     336    {
     337       if( pchain )
     338       {
     339          /* non-first handler being removed */
     340          pchain->next_handler = vchain->next_handler;
     341       }
     342       else
     343       {
     344          /* first handler isn't malloc'ed, so just overwrite it.  Since
     345          the contents of vchain are being struct copied, vchain itself
     346          goes away */
     347          rtems_hdl_tbl[irq->name]= *vchain;
     348       }
     349       free(vchain);
     350    }
    236351
    237352    _CPU_ISR_Enable(level);
     
    266381    for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
    267382      if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
    268         BSP_irq_enable_at_i8259s (i);
    269         rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
     383         BSP_irq_enable_at_i8259s (i);
     384
     385         /* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */
     386         {
     387            rtems_irq_connect_data* vchain;
     388            for( vchain = &rtems_hdl_tbl[i];
     389                 ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
     390                 vchain = (rtems_irq_connect_data*)vchain->next_handler )
     391            {
     392               vchain->on(vchain);
     393            }
     394         }
    270395      }
    271396      else {
    272         rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
    273         BSP_irq_disable_at_i8259s (i);
     397         /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
     398         {
     399            rtems_irq_connect_data* vchain;
     400            for( vchain = &rtems_hdl_tbl[i];
     401                 ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
     402                 vchain = (rtems_irq_connect_data*)vchain->next_handler )
     403            {
     404               vchain->off(vchain);
     405            }
     406         }
     407         BSP_irq_disable_at_i8259s (i);
    274408      }
    275409    }
     
    288422                                  internal_config->irqPrioTbl[i]);
    289423      if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
    290         openpic_enable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
    291         rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
     424         openpic_enable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
     425         /* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */
     426         {
     427            rtems_irq_connect_data* vchain;
     428            for( vchain = &rtems_hdl_tbl[i];
     429                 ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
     430                 vchain = (rtems_irq_connect_data*)vchain->next_handler )
     431            {
     432               vchain->on(vchain);
     433            }
     434         }
     435
    292436      }
    293437      else {
    294         rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
    295         openpic_disable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
     438         /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
     439         {
     440            rtems_irq_connect_data* vchain;
     441            for( vchain = &rtems_hdl_tbl[i];
     442                 ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
     443                 vchain = (rtems_irq_connect_data*)vchain->next_handler )
     444            {
     445               vchain->off(vchain);
     446            }
     447         }
     448         
     449         openpic_disable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
    296450      }
    297451    }
     
    305459    for (i=BSP_PROCESSOR_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER; i++) {
    306460      if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
    307         rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
     461         /* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */
     462         {
     463            rtems_irq_connect_data* vchain;
     464            for( vchain = &rtems_hdl_tbl[i];
     465                 ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
     466                 vchain = (rtems_irq_connect_data*)vchain->next_handler )
     467            {
     468               vchain->on(vchain);
     469            }
     470         }
     471
    308472      }
    309473      else {
    310         rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
     474         /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
     475         {
     476            rtems_irq_connect_data* vchain;
     477            for( vchain = &rtems_hdl_tbl[i];
     478                 ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
     479                 vchain = (rtems_irq_connect_data*)vchain->next_handler )
     480            {
     481               vchain->off(vchain);
     482            }
     483         }
     484
    311485      }
    312486    }
     
    374548  _CPU_MSR_SET(new_msr);
    375549   
    376   rtems_hdl_tbl[irq].hdl();
     550  /* rtems_hdl_tbl[irq].hdl(); */
     551  {
     552     rtems_irq_connect_data* vchain;
     553     for( vchain = &rtems_hdl_tbl[irq];
     554          ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
     555          vchain = (rtems_irq_connect_data*)vchain->next_handler )
     556     {
     557        vchain->hdl();
     558     }
     559  }
     560
    377561
    378562  _CPU_MSR_SET(msr);
  • c/src/lib/libbsp/powerpc/shared/irq/irq.h

    r7a848b40 r12838559  
    144144
    145145typedef struct __rtems_irq_connect_data__ {
    146   /*
    147    * IRQ line
    148    */
    149   rtems_irq_symbolic_name       name;
    150   /*
    151    * handler. See comment on handler properties below in function prototype.
    152    */
    153   rtems_irq_hdl                 hdl;
    154   /*
    155    * function for enabling interrupts at device level (ONLY!).
    156    * The BSP code will automatically enable it at i8259s level and openpic level.
    157    * RATIONALE : anyway such code has to exist in current driver code.
    158    * It is usually called immediately AFTER connecting the interrupt handler.
    159    * RTEMS may well need such a function when restoring normal interrupt
    160    * processing after a debug session.
    161    *
    162    */
    163     rtems_irq_enable            on;     
    164   /*
    165    * function for disabling interrupts at device level (ONLY!).
    166    * The code will disable it at i8259s level. RATIONALE : anyway
    167    * such code has to exist for clean shutdown. It is usually called
    168    * BEFORE disconnecting the interrupt. RTEMS may well need such
    169    * a function when disabling normal interrupt processing for
    170    * a debug session. May well be a NOP function.
    171    */
    172   rtems_irq_disable             off;
    173   /*
    174    * function enabling to know what interrupt may currently occur
    175    * if someone manipulates the i8259s interrupt mask without care...
    176    */
    177     rtems_irq_is_enabled        isOn;
     146      /*
     147       * IRQ line
     148       */
     149      rtems_irq_symbolic_name   name;
     150      /*
     151       * handler. See comment on handler properties below in function prototype.
     152       */
     153      rtems_irq_hdl                     hdl;
     154      /*
     155       * function for enabling interrupts at device level (ONLY!).
     156       * The BSP code will automatically enable it at i8259s level and openpic level.
     157       * RATIONALE : anyway such code has to exist in current driver code.
     158       * It is usually called immediately AFTER connecting the interrupt handler.
     159       * RTEMS may well need such a function when restoring normal interrupt
     160       * processing after a debug session.
     161       *
     162       */
     163      rtems_irq_enable          on;     
     164      /*
     165       * function for disabling interrupts at device level (ONLY!).
     166       * The code will disable it at i8259s level. RATIONALE : anyway
     167       * such code has to exist for clean shutdown. It is usually called
     168       * BEFORE disconnecting the interrupt. RTEMS may well need such
     169       * a function when disabling normal interrupt processing for
     170       * a debug session. May well be a NOP function.
     171       */
     172      rtems_irq_disable         off;
     173      /*
     174       * function enabling to know what interrupt may currently occur
     175       * if someone manipulates the i8259s interrupt mask without care...
     176       */
     177      rtems_irq_is_enabled      isOn;
     178      /*
     179       *  Set to -1 for vectors forced to have only 1 handler
     180       */
     181      void *next_handler;
     182
    178183}rtems_irq_connect_data;
    179184
     
    277282 */
    278283int BSP_install_rtems_irq_handler       (const rtems_irq_connect_data*);
     284int BSP_install_rtems_shared_irq_handler  (const rtems_irq_connect_data*);
     285
     286#define BSP_SHARED_HANDLER_SUPPORT      1
     287
    279288/*
    280289 * function to get the current RTEMS irq handler for ptr->name. It enables to
  • c/src/lib/libbsp/powerpc/shared/motorola/motorola.c

    r7a848b40 r12838559  
    1818#include <libcpu/io.h>
    1919#include <string.h>
     20
     21
     22/*
     23** Board-specific table that maps interrupt names to onboard pci
     24** peripherals as well as local pci busses.  This table is used at
     25** bspstart() to configure the interrupt name & pin for all devices that
     26** do not have it already specified.  If the device is already
     27** configured, we leave it alone but sanity check & print a warning if
     28** we don't know about the pin/line the card gives us.
     29**
     30** bus = the bus number of the slot/device in question
     31**
     32** slot :
     33**
     34**   If slot != -1, it indicates a device on the given bus in that slot
     35**   is to use one of the listed interrupt names given an interrupt pin.
     36**
     37**   If slot == -1, it means devices on this bus can occupy any slot-
     38**   and for pci, this means the particular interrupt pin that the
     39**   device signals is therefore dependent on the particular slot.  To
     40**   work from the slot to the interrupt pin, the swizzle table is used.
     41**   Once the bus and interrupt pin is known, the correct interrupt name
     42**   can be pulled from the table.  The swizzle table relates the
     43**   interrupt pin from the device to the particular interrupt
     44**   controller interrupt pin- so it is quite reasonable for a device on
     45**   bus 1 signalling interrupt pin 1 to show up at the interrupt
     46**   controller as pin 4- this is why the int pin field varies for
     47**   bridged pci busses.
     48**
     49**
     50** opts = bitmap of options that control the configuration of this
     51** slot/bus.
     52**
     53** pin_routes[] = array of pin & vectors that may serve this slot;
     54**
     55**      pin = the pin # which delivers an interrupt on this route, A=1,
     56**      B=2, C=3, D=4
     57**
     58**      int_name[4] = an array of up to 4 bsp-specific interrupt name
     59**      that can be used by this route.  Unused entries should be -1.
     60**      The array is of primary use for slots that can be vectored thru
     61**      multiple interrupt lines over the interrupt pin supplied by the
     62**      record.  If more than one entry is present, the most preferable
     63**      should supplied first.
     64**
     65*/
     66
     67#define NULL_PINMAP     {-1,{-1,-1,-1,-1}}
     68#define NULL_INTMAP     {-1,-1,-1,{}}
     69
     70
     71
     72static struct _int_map mcp750_intmap[] = {
     73
     74   { 0, 16, 0, {{1,  {5, 19,-1,-1}}, /* pmc slot */
     75                NULL_PINMAP}},
     76
     77   { 0, 14, 0, {{1,  {10,18,-1,-1}}, /* onboard ethernet */
     78                NULL_PINMAP}},
     79
     80   { 1, -1, 0, {{1,  {24,-1,-1,-1}},
     81                {2,  {25,-1,-1,-1}},
     82                {3,  {26,-1,-1,-1}},
     83                {4,  {27,-1,-1,-1}},
     84                NULL_PINMAP}},
     85
     86   NULL_INTMAP };
     87
     88
     89
     90
     91static struct _int_map mtx603_intmap[] = {
     92
     93   {0, 14, 0, {{1, {10,16,-1,-1}},  /* onboard ethernet */
     94               NULL_PINMAP}},
     95
     96   {0, 12, 0, {{1, {14,18,-1,-1}},  /* onboard scsi */
     97               NULL_PINMAP}},
     98
     99   {0, 16, 0, {{1, {25,-1,-1,-1}},  /* pci/pmc slot 1 */
     100               {2, {26,-1,-1,-1}},
     101               {3, {27,-1,-1,-1}},
     102               {4, {28,-1,-1,-1}},
     103               NULL_PINMAP}},
     104
     105   {0, 17, 0, {{1, {26,-1,-1,-1}},  /* pci/pmc slot 2 */
     106               {2, {27,-1,-1,-1}},
     107               {3, {28,-1,-1,-1}},
     108               {4, {25,-1,-1,-1}},
     109               NULL_PINMAP}},
     110
     111   {0, 18, 0, {{1, {27,-1,-1,-1}},  /* pci slot 3 */
     112               {2, {28,-1,-1,-1}},
     113               {3, {25,-1,-1,-1}},
     114               {4, {26,-1,-1,-1}},
     115               NULL_PINMAP}},
     116
     117   NULL_INTMAP };
     118
     119
     120
     121
     122
     123
     124
     125
     126/*
     127 * This table represents the standard PCI swizzle defined in the
     128 * PCI bus specification.  Table taken from Linux 2.4.18, prep_pci.c,
     129 * the values in this table are interrupt_pin values (1 based).
     130 */
     131static unsigned char prep_pci_intpins[4][4] =
     132{
     133        { 1, 2, 3, 4 },  /* Buses 0, 4, 8, ... */
     134        { 2, 3, 4, 1 },  /* Buses 1, 5, 9, ... */
     135        { 3, 4, 1, 2 },  /* Buses 2, 6, 10 ... */
     136        { 4, 1, 2, 3 },  /* Buses 3, 7, 11 ... */
     137};
     138
     139static int prep_pci_swizzle(int slot, int pin)
     140{
     141   return prep_pci_intpins[ slot % 4 ][ pin-1 ];
     142}
     143
     144
     145
     146
     147
     148
     149
     150
    20151
    21152typedef struct {
     
    25156   * 0x200 if this board has a Hawk chip.
    26157   */
    27   int           cpu_type;
    28   int           base_type;
    29   const char    *name;
     158      int               cpu_type;
     159      int               base_type;
     160      const char        *name;
     161
     162      struct _int_map   *intmap;
     163      int               (*swizzler)(int, int);
    30164} mot_info_t;
    31165
    32166
    33167static const mot_info_t mot_boards[] = {
    34   {0x300, 0x00, "MVME 2400"},
    35   {0x010, 0x00, "Genesis"},
    36   {0x020, 0x00, "Powerstack (Series E)"},
    37   {0x040, 0x00, "Blackhawk (Powerstack)"},
    38   {0x050, 0x00, "Omaha (PowerStack II Pro3000)"},
    39   {0x060, 0x00, "Utah (Powerstack II Pro4000)"},
    40   {0x0A0, 0x00, "Powerstack (Series EX)"},
    41   {0x1E0, 0xE0, "Mesquite cPCI (MCP750)"},
    42   {0x1E0, 0xE1, "Sitka cPCI (MCPN750)"},
    43   {0x1E0, 0xE2, "Mesquite cPCI (MCP750) w/ HAC"},
    44   {0x1E0, 0xF6, "MTX Plus"},
    45   {0x1E0, 0xF7, "MTX w/o Parallel Port"},
    46   {0x1E0, 0xF8, "MTX w/ Parallel Port"},
    47   {0x1E0, 0xF9, "MVME 2300"},
    48   {0x1E0, 0xFA, "MVME 2300SC/2600"},
    49   {0x1E0, 0xFB, "MVME 2600 with MVME712M"},
    50   {0x1E0, 0xFC, "MVME 2600/2700 with MVME761"},
    51   {0x1E0, 0xFD, "MVME 3600 with MVME712M"},
    52   {0x1E0, 0xFE, "MVME 3600 with MVME761"},
    53   {0x1E0, 0xFF, "MVME 1600-001 or 1600-011"},
     168  {0x300, 0x00, "MVME 2400", NULL, NULL},
     169  {0x010, 0x00, "Genesis", NULL, NULL},
     170  {0x020, 0x00, "Powerstack (Series E)", NULL, NULL},
     171  {0x040, 0x00, "Blackhawk (Powerstack)", NULL, NULL},
     172  {0x050, 0x00, "Omaha (PowerStack II Pro3000)", NULL, NULL},
     173  {0x060, 0x00, "Utah (Powerstack II Pro4000)", NULL, NULL},
     174  {0x0A0, 0x00, "Powerstack (Series EX)", NULL, NULL},
     175  {0x1E0, 0xE0, "Mesquite cPCI (MCP750)", mcp750_intmap, prep_pci_swizzle},
     176  {0x1E0, 0xE1, "Sitka cPCI (MCPN750)", mcp750_intmap, prep_pci_swizzle},
     177  {0x1E0, 0xE2, "Mesquite cPCI (MCP750) w/ HAC", mcp750_intmap, prep_pci_swizzle},
     178  {0x1E0, 0xF6, "MTX Plus", NULL, NULL},
     179  {0x1E0, 0xF7, "MTX w/o Parallel Port", mtx603_intmap, prep_pci_swizzle},
     180  {0x1E0, 0xF8, "MTX w/ Parallel Port", mtx603_intmap, prep_pci_swizzle},
     181  {0x1E0, 0xF9, "MVME 2300", NULL, NULL},
     182  {0x1E0, 0xFA, "MVME 2300SC/2600", NULL, NULL},
     183  {0x1E0, 0xFB, "MVME 2600 with MVME712M", NULL, NULL},
     184  {0x1E0, 0xFC, "MVME 2600/2700 with MVME761", NULL, NULL},
     185  {0x1E0, 0xFD, "MVME 3600 with MVME712M", NULL, NULL},
     186  {0x1E0, 0xFE, "MVME 3600 with MVME761", NULL, NULL},
     187  {0x1E0, 0xFF, "MVME 1600-001 or 1600-011", NULL, NULL},
    54188  {0x000, 0x00, ""}
    55189};
     190
     191
    56192
    57193prep_t currentPrepType;
     
    115251}
    116252
     253
    117254const char* motorolaBoardToString(motorolaBoard board)
    118255{
     
    121258}
    122259
     260
     261const struct _int_map *motorolaIntMap(motorolaBoard board)
     262{
     263  if (board == MOTOROLA_UNKNOWN) return NULL;
     264  return mot_boards[board].intmap;
     265}
     266
     267
     268const void *motorolaIntSwizzle(motorolaBoard board)
     269{
     270  if (board == MOTOROLA_UNKNOWN) return NULL;
     271  return (void *)mot_boards[board].swizzler;
     272}
     273
  • c/src/lib/libbsp/powerpc/shared/motorola/motorola.h

    r7a848b40 r12838559  
    1717
    1818#include <bsp/residual.h>
     19#include <bsp/pci.h>
     20
     21
     22
     23
     24
     25
     26
    1927
    2028typedef enum {
     
    6270extern motorolaBoard            currentBoard;
    6371extern const char*              motorolaBoardToString(motorolaBoard);
     72extern const struct _int_map    *motorolaIntMap(motorolaBoard board);
     73extern const void               *motorolaIntSwizzle(motorolaBoard board);
    6474
    6575
  • c/src/lib/libbsp/powerpc/shared/pci/pci.c

    r7a848b40 r12838559  
    217217
    218218
     219
     220
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230#define PRINT_MSG() \
     231             printk("pci : Device %d:%02x routed to interrupt_line %d\n", pbus, pslot, int_name )
     232
     233
     234/*
     235** Validate a test interrupt name and print a warning if its not one of
     236** the names defined in the routing record.
     237*/
     238static int test_intname( struct _int_map *row, int pbus, int pslot, int int_pin, int int_name )
     239{
     240   int j,k;
     241   int _nopin= -1, _noname= -1;
     242
     243   for(j=0; row->pin_route[j].pin > -1; j++)
     244   {
     245      if( row->pin_route[j].pin == int_pin )
     246      {
     247         _nopin = 0;
     248         
     249         for(k=0; k<4 && row->pin_route[j].int_name[k] > -1; k++ )
     250         {
     251            if( row->pin_route[j].int_name[k] == int_name ){ _noname=0; break; }
     252         }
     253         break;
     254      }
     255   }
     256
     257   if( _nopin  )
     258   {
     259      printk("pci : Device %d:%02x supplied a bogus interrupt_pin %d\n", pbus, pslot, int_pin );
     260      return -1;
     261   }
     262   else
     263   {
     264      if( _noname )
     265         printk("pci : Device %d:%02x supplied a suspicious interrupt_line %d, using it anyway\n", pbus, pslot, int_name );
     266   }
     267   return 0;
     268}
     269
     270
     271
     272
     273
     274struct pcibridge
     275{
     276      int bus,slot;
     277};
     278
     279
     280static int FindPCIbridge( int mybus, struct pcibridge *pb )
     281{
     282   int          pbus, pslot;
     283   unsigned8    bussec, buspri;
     284   unsigned16   devid, vendorid, dclass;
     285
     286   for(pbus=0; pbus< BusCountPCI(); pbus++)
     287   {
     288      for(pslot=0; pslot< PCI_MAX_DEVICES; pslot++)
     289      {
     290         pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
     291         if( devid == 0xffff ) continue;
     292
     293         pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &vendorid);
     294         if( vendorid == 0xffff ) continue;
     295
     296         pci_read_config_word(pbus, pslot, 0, PCI_CLASS_DEVICE, &dclass);
     297
     298         if( dclass == PCI_CLASS_BRIDGE_PCI )
     299         {
     300            pci_read_config_byte(pbus, pslot, 0, PCI_PRIMARY_BUS,    &buspri);
     301            pci_read_config_byte(pbus, pslot, 0, PCI_SECONDARY_BUS,  &bussec);
     302
     303#if 0
     304            printk("pci : Found bridge at %d:%d, mybus %d, pribus %d, secbus %d  ", pbus, pslot, mybus, buspri, bussec );
     305#endif
     306            if( bussec == mybus )
     307            {
     308#if 0
     309               printk("match\n");
     310#endif
     311               /* found our nearest bridge going towards the root */
     312               pb->bus = pbus;
     313               pb->slot = pslot;
     314
     315               return 0;
     316            }
     317#if 0
     318            printk("no match\n");
     319#endif
     320         }
     321
     322
     323      }
     324   }
     325   return -1;
     326}
     327
     328
     329
     330
     331
     332
     333
     334
     335void FixupPCI( struct _int_map *bspmap, int (*swizzler)(int,int) )
     336{
     337   unsigned char        cvalue;
     338   unsigned16           devid;
     339   int                  ismatch, i, j, pbus, pslot, int_pin, int_name;
     340
     341   /*
     342   ** If the device has a non-zero INTERRUPT_PIN, assign a bsp-specific
     343   ** INTERRUPT_NAME if one isn't already in place.  Then, drivers can
     344   ** trivially use INTERRUPT_NAME to hook up with devices.
     345   */
     346
     347   for(pbus=0; pbus< BusCountPCI(); pbus++)
     348   {
     349      for(pslot=0; pslot< PCI_MAX_DEVICES; pslot++)
     350      {
     351         pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
     352         if( devid == 0xffff ) continue;
     353
     354         /* got a device */
     355
     356         pci_read_config_byte( pbus, pslot, 0, PCI_INTERRUPT_PIN, &cvalue);
     357         int_pin = cvalue;
     358
     359         pci_read_config_byte( pbus, pslot, 0, PCI_INTERRUPT_LINE, &cvalue);
     360         int_name = cvalue;
     361
     362/* printk("pci : device %d:%02x devid %04x, intpin %d, intline  %d\n", pbus, pslot, devid, int_pin, int_name ); */
     363
     364         if( int_pin > 0 )
     365         {
     366            ismatch = 0;
     367
     368            /*
     369            ** first run thru the bspmap table and see if we have an explicit configuration
     370            */
     371            for(i=0; bspmap[i].bus > -1; i++)
     372            {
     373               if( bspmap[i].bus == pbus && bspmap[i].slot == pslot )
     374               {
     375                  ismatch = -1;
     376                  /* we have a record in the table that gives specific
     377                   * pins and interrupts for devices in this slot */
     378                  if( int_name == 255 )
     379                  {
     380                     /* find the vector associated with whatever pin the device gives us */
     381                     for( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ )
     382                     {
     383                        if( bspmap[i].pin_route[j].pin == int_pin )
     384                        {
     385                           int_name = bspmap[i].pin_route[j].int_name[0];
     386                           break;
     387                        }
     388                     }
     389                     if( int_name == -1 )
     390                     {
     391                        printk("pci : Unable to resolve device %d:%d w/ swizzled int pin %i to an interrupt_line.\n", pbus, pslot, int_pin );
     392                     }
     393                     else
     394                     {
     395                        PRINT_MSG();
     396                        pci_write_config_byte(pbus,pslot,0,PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue));
     397                     }
     398                  }
     399                  else
     400                  {
     401                     test_intname( &bspmap[i],pbus,pslot,int_pin,int_name);
     402                  }
     403                  break;
     404               }
     405            }
     406
     407           
     408            if( !ismatch )
     409            {
     410               /*
     411               ** no match, which means we're on a bus someplace.  Work
     412               ** backwards from it to one of our defined busses,
     413               ** swizzling thru each bridge on the way.
     414               */
     415
     416               /* keep pbus, pslot pointed to the device being
     417               configured while we track down the bridges using
     418               tbus,tslot.  We keep searching the routing table because
     419               we may end up finding our bridge in it */
     420
     421               int tbus= pbus, tslot= pslot;
     422
     423               for(;;)
     424               {
     425
     426                  for(i=0; bspmap[i].bus > -1; i++)
     427                  {
     428                     if( bspmap[i].bus == tbus && (bspmap[i].slot == tslot || bspmap[i].slot == -1) )
     429                     {
     430                        ismatch = -1;
     431                        /* found a record for this bus, so swizzle the
     432                         * int_pin which we then use to find the
     433                         * interrupt_name.
     434                         */
     435
     436                        if( int_name == 255 )
     437                        {
     438                           /*
     439                           ** FIXME.  I can't believe this little hack
     440                           ** is right.  It does not yield an error in
     441                           ** convienently simple situations.
     442                           */
     443                           if( tbus ) int_pin = (*swizzler)(tslot,int_pin);
     444
     445
     446                           /*
     447                           ** int_pin points to the interrupt channel
     448                           ** this card ends up delivering interrupts
     449                           ** on.  Find the int_name servicing it.
     450                           */
     451                           for( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ )
     452                           {
     453                              if( bspmap[i].pin_route[j].pin == int_pin )
     454                              {
     455                                 int_name = bspmap[i].pin_route[j].int_name[0];
     456                                 break;
     457                              }
     458                           }
     459                           if( int_name == -1 )
     460                           {
     461                              printk("pci : Unable to resolve device %d:%d w/ swizzled int pin %i to an interrupt_line.\n", pbus, pslot, int_pin );
     462                           }
     463                           else
     464                           {
     465                              PRINT_MSG();
     466                              pci_write_config_byte(pbus,pslot,0,PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue));
     467                           }
     468                        }
     469                        else
     470                        {
     471                           test_intname(&bspmap[i],pbus,pslot,int_pin,int_name);
     472                        }
     473                        goto donesearch;
     474                     }
     475                  }
     476
     477
     478                  if( !ismatch )
     479                  {
     480                     struct pcibridge   pb;
     481
     482                     /*
     483                     ** Haven't found our bus in the int map, so work
     484                     ** upwards thru the bridges till we find it.
     485                     */
     486
     487                     if( FindPCIbridge( tbus, &pb )== 0 )
     488                     {
     489                        int_pin = (*swizzler)(tslot,int_pin);
     490
     491                        /* our next bridge up is on pb.bus, pb.slot- now
     492                        ** instead of pointing to the device we're
     493                        ** trying to configure, we move from bridge to
     494                        ** bridge.
     495                        */
     496
     497                        tbus = pb.bus;
     498                        tslot = pb.slot;
     499                     }
     500                     else
     501                     {
     502                        printk("pci : No bridge from bus %i towards root found\n", tbus );
     503                        goto donesearch;
     504                     }
     505                     
     506                  }
     507
     508               }
     509            }
     510           donesearch:
     511
     512
     513            if( !ismatch && int_pin != 0 && int_name == 255 )
     514            {
     515               printk("pci : Unable to match device %d:%d with an int routing table entry\n", pbus, pslot  );
     516            }
     517
     518
     519         }
     520      }
     521   }
     522}
     523
     524
     525
     526
     527
     528
     529
     530
     531
     532
    219533/*
    220534 * This routine determines the maximum bus number in the system
     
    229543
    230544  detect_host_bridge();
     545
    231546  /*
    232547   * Scan PCI bus 0 looking for PCI-PCI bridges
  • c/src/lib/libbsp/powerpc/shared/pci/pci.h

    r7a848b40 r12838559  
    11541154extern void InitializePCI();
    11551155
     1156
     1157struct _pin_routes
     1158{
     1159      int pin, int_name[4];
     1160};
     1161struct _int_map
     1162{
     1163      int bus, slot, opts;
     1164      struct _pin_routes pin_route[5];
     1165};
     1166
     1167void FixupPCI( struct _int_map *, int (*swizzler)(int,int) );
     1168
     1169
    11561170/* scan for a specific device */
    11571171/* find a particular PCI device
  • c/src/lib/libbsp/powerpc/shared/pci/pcifinddevice.c

    r7a848b40 r12838559  
    3838                                continue;
    3939#ifdef PCI_DEBUG
    40                         printk("BSP_pciFindDevice: found 0x%08x at %i/%i/%i\n",d,bus,dev,fun);
     40                        printk("BSP_pciFindDevice: found 0x%08x at %d/%d/%d\n",d,bus,dev,fun);
    4141#endif
    4242                        (void) pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
  • c/src/lib/libbsp/powerpc/shared/startup/bspstart.c

    r7a848b40 r12838559  
    254254   */
    255255  /* T. Straumann: give more PCI address space */
    256   setdbat(2, PCI_MEM_BASE, PCI_MEM_BASE, 0x10000000, IO_PAGE);
     256  setdbat(2, PCI_MEM_BASE, PCI_MEM_BASE, 0x30000000, IO_PAGE);
    257257  /*
    258258   * Must have acces to open pic PCI ACK registers
     
    301301#endif 
    302302  InitializePCI();
     303
     304 {
     305    struct _int_map     *bspmap   = motorolaIntMap(currentBoard);
     306    if( bspmap )
     307    {
     308       printk("pci : Configuring interrupt routing for '%s'\n", motorolaBoardToString(currentBoard));
     309       FixupPCI(bspmap, motorolaIntSwizzle(currentBoard) );
     310    }
     311    else
     312       printk("pci : Interrupt routing not available for this bsp\n");
     313
     314 }
     315
     316
     317
    303318#ifdef SHOW_MORE_INIT_SETTINGS
    304319  printk("Number of PCI buses found is : %d\n", BusCountPCI());
Note: See TracChangeset for help on using the changeset viewer.