source: rtems/c/src/lib/libbsp/mips/malta/pci/pci.c @ e026dbc5

5
Last change on this file since e026dbc5 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 27.6 KB
Line 
1/**
2 *  @file
3 *
4 *  This file was based on the powerpc.
5 */
6
7/*
8 *  COPYRIGHT (c) 1989-2012.
9 *  On-Line Applications Research Corporation (OAR).
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.org/license/LICENSE.
14 */
15
16#include <rtems.h>
17#include <bsp.h>
18
19#include <bsp/pci.h>
20#include <bsp/irq.h>
21#include <rtems/bspIo.h>
22#include <rtems/endian.h>
23
24/*
25 * DEFINES
26 */
27
28#undef SHOW_PCI_SETTING
29
30// #define DEBUG_PCI 1
31
32/* allow for overriding these definitions */
33#ifndef PCI_CONFIG_ADDR
34#define PCI_CONFIG_ADDR      0xcf8
35#endif
36#ifndef PCI_CONFIG_DATA
37#define PCI_CONFIG_DATA      0xcfc
38#endif
39
40/* define a shortcut */
41#define pci  BSP_pci_configuration
42
43#ifndef  PCI_CONFIG_ADDR_VAL
44#define  PCI_CONFIG_ADDR_VAL(bus, slot, funcion, offset) \
45     (0x80000000|((bus)<<16)|(PCI_DEVFN((slot),(function))<<8)|(((offset)&~3)))
46#endif
47
48#ifdef DEBUG_PCI
49  #define JPRINTK(fmt, ...) printk("%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
50#else
51  #define JPRINTK(fmt, ...)
52#endif
53
54#ifndef  PCI_CONFIG_WR_ADDR
55#define  PCI_CONFIG_WR_ADDR( addr, val ) out_le32((uint32_t)(addr), (val))
56#endif
57
58/* Bit encode for PCI_CONFIG_HEADER_TYPE register */
59#define PCI_CONFIG_SET_ADDR(addr, bus, slot,function,offset) \
60  PCI_CONFIG_WR_ADDR( \
61    (addr), \
62    PCI_CONFIG_ADDR_VAL((bus), (slot), (function), (offset))\
63  )
64
65#define PRINT_MSG() \
66  printk("pci : Device %d:0x%02x:%d routed to interrupt_line %d\n", \
67    pbus, pslot, pfun, int_name )
68
69/*
70 * STRUCTURES
71 */
72
73/*
74 * PROTOTYPES
75 */
76void print_bars(
77  unsigned char slot,
78  unsigned char func
79);
80int direct_pci_read_config_byte(
81  unsigned char bus,
82  unsigned char slot,
83  unsigned char function,
84  unsigned char offset,
85  uint8_t      *val
86);
87int direct_pci_read_config_word(
88  unsigned char bus,
89  unsigned char slot,
90  unsigned char function,
91  unsigned char offset,
92  uint16_t     *val
93);
94int direct_pci_read_config_dword(
95  unsigned char bus,
96  unsigned char slot,
97  unsigned char function,
98  unsigned char offset,
99  uint32_t     *val
100);
101int direct_pci_write_config_byte(
102  unsigned char bus,
103  unsigned char slot,
104  unsigned char function,
105  unsigned char offset,
106  uint8_t       val
107);
108int direct_pci_write_config_word(
109  unsigned char bus,
110  unsigned char slot,
111  unsigned char function,
112  unsigned char offset,
113  uint16_t      val
114);
115int direct_pci_write_config_dword(
116  unsigned char bus,
117  unsigned char slot,
118  unsigned char function,
119  unsigned char offset,
120  uint32_t      val
121);
122int test_intname(
123  const struct _int_map *row,
124  int pbus,
125  int pslot,
126  int pfun,
127  int int_pin,
128  int int_name
129);
130void pci_memory_enable(
131  unsigned char bus,
132  unsigned char slot,
133  unsigned char function
134);
135void pci_io_enable(
136  unsigned char bus,
137  unsigned char slot,
138  unsigned char function
139);
140void pci_busmaster_enable(
141  unsigned char bus,
142  unsigned char slot,
143  unsigned char function
144);
145
146/*
147 * GLOBALS
148 */
149unsigned char ucMaxPCIBus;
150const pci_config_access_functions pci_indirect_functions = {
151  indirect_pci_read_config_byte,
152  indirect_pci_read_config_word,
153  indirect_pci_read_config_dword,
154  indirect_pci_write_config_byte,
155  indirect_pci_write_config_word,
156  indirect_pci_write_config_dword
157};
158
159rtems_pci_config_t BSP_pci_configuration = {
160  (volatile unsigned char*)PCI_CONFIG_ADDR,
161  (volatile unsigned char*)PCI_CONFIG_DATA,
162  &pci_indirect_functions
163};
164
165const pci_config_access_functions pci_direct_functions = {
166  direct_pci_read_config_byte,
167  direct_pci_read_config_word,
168  direct_pci_read_config_dword,
169  direct_pci_write_config_byte,
170  direct_pci_write_config_word,
171  direct_pci_write_config_dword
172};
173
174/*
175 * PCI specific accesses.  Note these are made on 32 bit
176 * boundries.
177 */
178void pci_out_32(uint32_t base, uint32_t addr, uint32_t val)
179{
180  volatile uint32_t *ptr;
181
182  ptr = (volatile uint32_t *) (base + addr);
183  *ptr = val;
184
185  JPRINTK( "%p data: 0x%x\n", ptr, val);
186}
187
188void pci_out_le32(uint32_t base, uint32_t addr, uint32_t val)
189{
190  volatile uint32_t *ptr;
191  uint32_t           data = 0;
192
193  ptr = (volatile uint32_t *) (base + addr);
194  rtems_uint32_to_little_endian( val, (uint8_t *) &data);
195  *ptr = data;
196
197  JPRINTK( "%p data: 0x%x\n", ptr, data);
198}
199
200uint8_t pci_in_8( uint32_t base, uint32_t addr ) {
201  volatile uint32_t *ptr;
202  uint8_t            val;
203  uint32_t           data;
204
205  data = addr/4;
206  ptr = (volatile uint32_t *) (base + (data*4));
207  data = *ptr;
208
209  switch ( addr%4 ) {
210    case 0: val = (data & 0x000000ff) >>  0; break;
211    case 1: val = (data & 0x0000ff00) >>  8; break;
212    case 2: val = (data & 0x00ff0000) >> 16; break;
213    case 3: val = (data & 0xff000000) >> 24; break;
214   }
215
216   JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, data);
217
218  return val;
219}
220
221int16_t pci_in_le16( uint32_t base, uint32_t addr ) {
222  volatile uint32_t *ptr;
223  uint16_t           val;
224  uint16_t           rval;
225  uint32_t           data;
226
227  data = addr/4;
228  ptr = (volatile uint32_t *) (base + (data*4));
229  data = *ptr;
230  if ( addr%4 == 0 )
231    val = data & 0xffff;
232  else
233    val = (data>>16) & 0xffff;
234
235  rval = rtems_uint16_from_little_endian( (uint8_t *) &val);
236  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, rval, data);
237  return rval;
238}
239
240int16_t pci_in_16( uint32_t base, uint32_t addr ) {
241  volatile uint32_t *ptr;
242  uint16_t           val;
243  uint32_t           data;
244
245  data = addr/4;
246  ptr = (volatile uint32_t *) (base + (data*4));
247  data = *ptr;
248  if ( addr%4 == 0 )
249    val = data & 0xffff;
250  else
251    val = (data>>16) & 0xffff;
252
253  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, data);
254  return val;
255}
256
257uint32_t pci_in_32( uint32_t base, uint32_t addr ) {
258  volatile uint32_t *ptr;
259  uint32_t           val;
260
261  ptr = (volatile uint32_t *) (base + addr);
262  val = *ptr;
263
264  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, val);
265  return val;
266}
267uint32_t pci_in_le32( uint32_t base, uint32_t addr ) {
268  volatile uint32_t *ptr;
269  uint32_t           val;
270  uint32_t           rval;
271
272  ptr = (volatile uint32_t *) (base + addr);
273  val = *ptr;
274  rval = rtems_uint32_from_little_endian( (uint8_t *) &val);
275
276  JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, rval, val);
277  return rval;
278}
279
280void pci_out_8( uint32_t base, uint32_t addr, uint8_t val ) {
281  volatile uint32_t *ptr;
282
283  ptr = (volatile uint32_t *) (base + addr);
284  JPRINTK("Address: %p\n", ptr);
285  *ptr = val;
286  JPRINTK( "%p data: 0x%x\n", ptr, val);
287}
288
289void pci_out_le16( uint32_t base, uint32_t addr, uint16_t val ) {
290  volatile uint32_t *ptr;
291  uint32_t           out_data;
292  uint32_t           data;
293
294  ptr = (volatile uint32_t *) (base + (addr & ~0x3));
295  data = *ptr;
296  if ( addr%4 == 0 )
297    out_data = (data & 0xffff0000) | val;
298  else
299    out_data = ((val << 16)&0xffff0000) | (data & 0xffff);
300  rtems_uint32_to_little_endian( out_data, (uint8_t *) &data);
301  *ptr = data;
302
303  JPRINTK( "0x%x data: 0x%x\n", ptr, data);
304}
305
306void pci_out_16( uint32_t base, uint32_t addr, uint16_t val ) {
307  volatile uint32_t *ptr;
308  uint32_t           out_data;
309  uint32_t           data;
310
311  ptr = (volatile uint32_t *) (base + (addr & ~0x3));
312  data = *ptr;
313  if ( addr%4 == 0 )
314    out_data = (data & 0xffff0000) | val;
315  else
316    out_data = ((val << 16)&0xffff0000) | (data & 0xffff);
317  *ptr = out_data;
318
319  JPRINTK( "0x%x data: 0x%x\n", ptr, out_data);
320}
321
322/*
323 * INDIRECT PCI CONFIGURATION ACCESSES
324 */
325int indirect_pci_read_config_byte(
326  unsigned char bus,
327  unsigned char slot,
328  unsigned char function,
329  unsigned char offset,
330  uint8_t       *val
331) {
332
333  JPRINTK("==>\n");
334  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
335  *val = in_8((uint32_t) (pci.pci_config_data +  (offset&3)) );
336  JPRINTK("\n\n");
337
338  return PCIBIOS_SUCCESSFUL;
339}
340
341int indirect_pci_read_config_word(
342  unsigned char bus,
343  unsigned char slot,
344  unsigned char function,
345  unsigned char offset,
346  uint16_t      *val
347) {
348
349  JPRINTK("==>\n");
350
351  *val = 0xffff;
352  if (offset&1)
353    return PCIBIOS_BAD_REGISTER_NUMBER;
354
355  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
356  *val = in_16((uint32_t)(pci.pci_config_data + (offset&3)));
357
358  JPRINTK("\n\n");
359
360  return PCIBIOS_SUCCESSFUL;
361}
362
363int indirect_pci_read_config_dword(
364  unsigned char bus,
365  unsigned char slot,
366  unsigned char function,
367  unsigned char offset,
368  uint32_t *val
369) {
370  uint32_t v;
371  JPRINTK("==>\n");
372
373  *val = 0xffffffff;
374  if (offset&3)
375    return PCIBIOS_BAD_REGISTER_NUMBER;
376  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
377  v = in_32( (uint32_t) pci.pci_config_data );
378  *val = v;
379   if ( offset == 0x0b )
380     JPRINTK( "%x:%x %x ==> 0x%08x, 0x%08x\n", bus, slot, function, v, *val );
381
382  JPRINTK("\n\n");
383
384  return PCIBIOS_SUCCESSFUL;
385}
386
387int indirect_pci_write_config_byte(
388  unsigned char bus,
389  unsigned char slot,
390  unsigned char function,
391  unsigned char offset,
392  uint8_t       val
393) {
394
395  JPRINTK("==>\n");
396
397  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
398  out_8( (uint32_t) (pci.pci_config_data + (offset&3)), val);
399
400  JPRINTK("\n\n");
401
402  return PCIBIOS_SUCCESSFUL;
403}
404
405int indirect_pci_write_config_word(
406  unsigned char bus,
407  unsigned char slot,
408  unsigned char function,
409  unsigned char offset,
410  uint16_t      val
411) {
412
413  JPRINTK("==>\n");
414
415  if (offset&1)
416    return PCIBIOS_BAD_REGISTER_NUMBER;
417
418  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
419  out_16((uint32_t)(pci.pci_config_data + (offset&3)), val);
420
421  JPRINTK("\n\n");
422
423  return PCIBIOS_SUCCESSFUL;
424}
425
426int indirect_pci_write_config_dword(
427  unsigned char bus,
428  unsigned char slot,
429  unsigned char function,
430  unsigned char offset,
431  uint32_t      val
432) {
433
434  if (offset&3)
435    return PCIBIOS_BAD_REGISTER_NUMBER;
436
437  JPRINTK("==>\n");
438
439  /*
440   * The Base Address Registers get accessed big endian while the
441   * other registers are little endian.
442   */
443  PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
444  if ( bus == 0 && slot == 0x0b &&
445       (offset >= PCI_BASE_ADDRESS_0 && offset <= PCI_BASE_ADDRESS_5) ) {
446    out_32((uint32_t)pci.pci_config_data, val);
447  } else {
448    out_le32((uint32_t)pci.pci_config_data, val);
449  }
450
451  JPRINTK("\n\n");
452
453  return PCIBIOS_SUCCESSFUL;
454}
455
456/*
457 * DIRECT CONFIGUREATION ACCESSES.
458 */
459int direct_pci_read_config_byte(
460  unsigned char bus,
461  unsigned char slot,
462  unsigned char function,
463  unsigned char offset,
464  uint8_t      *val
465) {
466  if (bus != 0 || (1<<slot & 0xff8007fe)) {
467    *val=0xff;
468     return PCIBIOS_DEVICE_NOT_FOUND;
469  }
470
471  JPRINTK("==>\n");
472
473  *val=in_8((uint32_t) (pci.pci_config_data + ((1<<slot)&~1)
474   + (function<<8) + offset));
475
476  JPRINTK("\n\n");
477
478  return PCIBIOS_SUCCESSFUL;
479}
480
481int direct_pci_read_config_word(
482  unsigned char bus,
483  unsigned char slot,
484  unsigned char function,
485  unsigned char offset,
486  uint16_t     *val
487) {
488  *val = 0xffff;
489  if (offset&1)
490    return PCIBIOS_BAD_REGISTER_NUMBER;
491  if (bus != 0 || (1<<slot & 0xff8007fe))
492     return PCIBIOS_DEVICE_NOT_FOUND;
493
494  JPRINTK("==>\n");
495
496  *val=in_le16((uint32_t)
497      (pci.pci_config_data + ((1<<slot)&~1)
498       + (function<<8) + offset));
499
500  JPRINTK("\n\n");
501
502  return PCIBIOS_SUCCESSFUL;
503}
504
505int direct_pci_read_config_dword(
506  unsigned char bus,
507  unsigned char slot,
508  unsigned char function,
509  unsigned char offset,
510  uint32_t     *val
511) {
512  *val = 0xffffffff;
513  if (offset&3)
514    return PCIBIOS_BAD_REGISTER_NUMBER;
515  if (bus != 0 || (1<<slot & 0xff8007fe))
516     return PCIBIOS_DEVICE_NOT_FOUND;
517
518  JPRINTK("==>\n");
519
520  *val=in_le32((uint32_t)(pci.pci_config_data +
521    ((1<<slot)&~1)+(function<<8) + offset));
522
523  JPRINTK("\n\n");
524
525  return PCIBIOS_SUCCESSFUL;
526}
527
528int direct_pci_write_config_byte(
529  unsigned char bus,
530  unsigned char slot,
531  unsigned char function,
532  unsigned char offset,
533  uint8_t       val
534) {
535  if (bus != 0 || (1<<slot & 0xff8007fe))
536     return PCIBIOS_DEVICE_NOT_FOUND;
537
538  JPRINTK("==>\n");
539
540  out_8((uint32_t) (pci.pci_config_data + ((1<<slot)&~1) +
541    (function<<8) + offset),
542     val);
543
544  JPRINTK("\n\n");
545
546  return PCIBIOS_SUCCESSFUL;
547}
548
549int direct_pci_write_config_word(
550  unsigned char bus,
551  unsigned char slot,
552  unsigned char function,
553  unsigned char offset,
554  uint16_t      val
555) {
556  if (offset&1)
557    return PCIBIOS_BAD_REGISTER_NUMBER;
558  if (bus != 0 || (1<<slot & 0xff8007fe))
559     return PCIBIOS_DEVICE_NOT_FOUND;
560
561  JPRINTK("==>\n");
562
563  out_le16((uint32_t)(pci.pci_config_data + ((1<<slot)&~1) +
564    (function<<8) + offset),
565    val);
566
567  JPRINTK("\n\n");
568
569  return PCIBIOS_SUCCESSFUL;
570}
571
572int direct_pci_write_config_dword(
573  unsigned char bus,
574  unsigned char slot,
575  unsigned char function,
576  unsigned char offset,
577  uint32_t      val
578) {
579  if (offset&3)
580    return PCIBIOS_BAD_REGISTER_NUMBER;
581  if (bus != 0 || (1<<slot & 0xff8007fe))
582     return PCIBIOS_DEVICE_NOT_FOUND;
583
584  JPRINTK("direct_pci_write_config_dword==>\n");
585
586  out_le32((uint32_t)
587     (pci.pci_config_data + ((1<<slot)&~1)
588   + (function<<8) + offset),
589     val);
590
591  JPRINTK("\n\n");
592
593  return PCIBIOS_SUCCESSFUL;
594}
595
596/*
597 * Validate a test interrupt name and print a warning if its not one of
598 * the names defined in the routing record.
599 */
600int test_intname(
601  const struct _int_map *row,
602  int pbus,
603  int pslot,
604  int pfun,
605  int int_pin,
606  int int_name
607) {
608  int j, k;
609  int _nopin= -1, _noname= -1;
610
611  for (j=0; row->pin_route[j].pin > -1; j++) {
612    if ( row->pin_route[j].pin == int_pin ) {
613   _nopin = 0;
614
615   for (k=0; k<4 && row->pin_route[j].int_name[k] > -1; k++ ) {
616     if ( row->pin_route[j].int_name[k] == int_name ) {
617       _noname=0; break;
618     }
619   }
620   break;
621    }
622  }
623
624   if( _nopin  )
625   {
626      printk(
627        "pci : Device %d:0x%02x:%d supplied a bogus interrupt_pin %d\n",
628        pbus,
629        pslot,
630        pfun,
631        int_pin
632      );
633      return -1;
634   }
635   else
636   {
637     if( _noname ) {
638       unsigned char v = row->pin_route[j].int_name[0];
639       printk(
640         "pci : Device %d:0x%02x:%d supplied a suspicious interrupt_line %d, ",
641         pbus,
642         pslot,
643         pfun,
644         int_name
645       );
646       if ((row->opts & PCI_FIXUP_OPT_OVERRIDE_NAME) && 255 !=
647           (v = row->pin_route[j].int_name[0])
648          ) {
649         printk("OVERRIDING with %d from fixup table\n", v);
650         pci_write_config_byte(pbus,pslot,pfun,PCI_INTERRUPT_LINE,v);
651       } else {
652        printk("using it anyway\n");
653       }
654     }
655   }
656   return 0;
657}
658
659int FindPCIbridge( int mybus, struct pcibridge *pb )
660{
661  int          pbus, pslot;
662  uint8_t      bussec, buspri;
663  uint16_t     devid, vendorid, dclass;
664
665  for(pbus=0; pbus< pci_bus_count(); pbus++) {
666    for(pslot=0; pslot< PCI_MAX_DEVICES; pslot++) {
667      pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
668      if ( devid == 0xffff ) continue;
669
670      pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &vendorid);
671      if ( vendorid == 0xffff ) continue;
672
673      pci_read_config_word(pbus, pslot, 0, PCI_CLASS_DEVICE, &dclass);
674
675      if ( dclass == PCI_CLASS_BRIDGE_PCI ) {
676        pci_read_config_byte(pbus, pslot, 0, PCI_PRIMARY_BUS,    &buspri);
677        pci_read_config_byte(pbus, pslot, 0, PCI_SECONDARY_BUS,  &bussec);
678
679        #ifdef SHOW_PCI_SETTING
680          JPRINTK(
681            "pci : Found bridge at %d:0x%02x, mybus %d, pribus %d, secbus %d ",
682            pbus,
683            pslot,
684            mybus,
685            buspri,
686            bussec
687          );
688        #endif
689        if ( bussec == mybus ) {
690          #ifdef SHOW_PCI_SETTING
691            JPRINTK("match\n");
692          #endif
693          /* found our nearest bridge going towards the root */
694          pb->bus = pbus;
695          pb->slot = pslot;
696          return 0;
697        }
698        #ifdef SHOW_PCI_SETTING
699          JPRINTK("no match\n");
700        #endif
701      }
702
703     }
704   }
705   return -1;
706}
707
708void FixupPCI( const struct _int_map *bspmap, int (*swizzler)(int,int) )
709{
710  unsigned char cvalue;
711  uint16_t      devid;
712  int           ismatch, i, j, pbus, pslot, pfun, int_pin, int_name, nfuns;
713
714  /*
715   * If the device has a non-zero INTERRUPT_PIN, assign a bsp-specific
716   * INTERRUPT_NAME if one isn't already in place.  Then, drivers can
717   * trivially use INTERRUPT_NAME to hook up with devices.
718   */
719
720  for (pbus=0; pbus< pci_bus_count(); pbus++) {
721    for (pslot=0; pslot< PCI_MAX_DEVICES; pslot++) {
722      pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
723      if ( devid == 0xffff ) continue;
724
725      /* got a device */
726      pci_read_config_byte(pbus, pslot, 0, PCI_HEADER_TYPE, &cvalue);
727      nfuns = cvalue & PCI_HEADER_TYPE_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1;
728      for (pfun=0; pfun< nfuns; pfun++) {
729
730        pci_read_config_word(pbus, pslot, pfun, PCI_DEVICE_ID, &devid);
731        if( devid == 0xffff ) continue;
732
733        pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_PIN, &cvalue);
734        int_pin = cvalue;
735
736        pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_LINE, &cvalue);
737        int_name = cvalue;
738
739        #ifdef SHOW_PCI_SETTING
740        {
741          unsigned short cmd,stat;
742          unsigned char  lat, seclat, csize;
743
744          pci_read_config_word(pbus,pslot,pfun,PCI_COMMAND, &cmd );
745          pci_read_config_word(pbus,pslot,pfun,PCI_STATUS, &stat );
746          pci_read_config_byte(pbus,pslot,pfun,PCI_LATENCY_TIMER, &lat );
747          pci_read_config_byte(pbus,pslot,pfun,PCI_SEC_LATENCY_TIMER, &seclat);
748          pci_read_config_byte(pbus,pslot,pfun,PCI_CACHE_LINE_SIZE, &csize );
749
750          JPRINTK(
751            "pci : device %d:0x%02x:%d  cmd %04X, stat %04X, latency %d, "
752            " sec_latency %d, clsize %d\n",
753            pbus,
754            pslot,
755            pfun,
756            cmd,
757            stat,
758            lat,
759            seclat,
760            csize
761          );
762        }
763        #endif
764
765        if ( int_pin > 0 ) {
766          ismatch = 0;
767
768          /*
769           * first run thru the bspmap table and see if we have an
770           * explicit configuration
771           */
772          for (i=0; bspmap[i].bus > -1; i++) {
773            if ( bspmap[i].bus == pbus && bspmap[i].slot == pslot ) {
774              ismatch = -1;
775
776              /* we have a record in the table that gives specific
777               * pins and interrupts for devices in this slot
778               */
779              if ( int_name == 255 ) {
780
781                /* find the vector associated with whatever pin the
782                 * device gives us
783                 */
784                for ( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ ){
785                  if ( bspmap[i].pin_route[j].pin == int_pin ) {
786                    int_name = bspmap[i].pin_route[j].int_name[0];
787                    break;
788                  }
789                }
790
791                if ( int_name == -1 ) {
792                  printk(
793                    "pci : Unable to resolve device %d:0x%02x:%d w/ "
794                    "swizzled int pin %i to an interrupt_line.\n",
795                    pbus,
796                    pslot,
797                    pfun,
798                    int_pin
799                  );
800                } else {
801                  PRINT_MSG();
802                  pci_write_config_byte(
803                    pbus,
804                    pslot,
805                    pfun,
806                    PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue)
807                  );
808                }
809              } else {
810                test_intname( &bspmap[i],pbus,pslot,pfun,int_pin,int_name);
811              }
812              break;
813            }
814          }
815
816          if ( !ismatch ) {
817            /*
818             * no match, which means we're on a bus someplace.  Work
819             * backwards from it to one of our defined busses,
820             * swizzling thru each bridge on the way.
821             */
822
823            /* keep pbus, pslot pointed to the device being
824             * configured while we track down the bridges using
825             * tbus,tslot.  We keep searching the routing table because
826             * we may end up finding our bridge in it
827             */
828
829            int tbus= pbus, tslot= pslot;
830            for (;;) {
831              for (i=0; bspmap[i].bus > -1; i++) {
832                if ( bspmap[i].bus == tbus &&
833                    (bspmap[i].slot == tslot || bspmap[i].slot == -1))
834                {
835                  ismatch = -1;
836
837                  /* found a record for this bus, so swizzle the
838                   * int_pin which we then use to find the
839                   * interrupt_name.
840                   */
841                  if ( int_name == 255 ) {
842                    /*
843                     * FIXME.  I can't believe this little hack
844                     * is right.  It does not yield an error in
845                     * convienently simple situations.
846                     */
847                    if ( tbus ) int_pin = (*swizzler)(tslot,int_pin);
848
849                    /*
850                     * int_pin points to the interrupt channel
851                     * this card ends up delivering interrupts
852                     * on.  Find the int_name servicing it.
853                     */
854                    for (int_name=-1, j=0;
855                         bspmap[i].pin_route[j].pin > -1;
856                         j++)
857                    {
858                      if ( bspmap[i].pin_route[j].pin == int_pin ) {
859                        int_name = bspmap[i].pin_route[j].int_name[0];
860                        break;
861                      }
862                    }
863
864                    if ( int_name == -1 ) {
865                      printk(
866                        "pci : Unable to resolve device %d:0x%02x:%d w/ "
867                        "swizzled int pin %i to an interrupt_line.\n",
868                        pbus,
869                        pslot,
870                        pfun,
871                        int_pin
872                      );
873                    } else {
874                      PRINT_MSG();
875                      pci_write_config_byte(pbus,pslot,pfun,
876                      PCI_INTERRUPT_LINE,(cvalue=int_name, cvalue));
877                    }
878                  } else {
879                    test_intname(
880                      &bspmap[i],
881                      pbus,
882                      pslot,
883                      pfun,
884                      int_pin,
885                      int_name
886                    );
887                  }
888                  goto donesearch;
889                }
890              }
891              if ( !ismatch ) {
892                struct pcibridge   pb;
893
894                /*
895                 * Haven't found our bus in the int map, so work
896                 * upwards thru the bridges till we find it.
897                 */
898                if ( FindPCIbridge( tbus, &pb )== 0 ) {
899                  int_pin = (*swizzler)(tslot,int_pin);
900
901                  /* our next bridge up is on pb.bus, pb.slot- now
902                   * instead of pointing to the device we're
903                   * trying to configure, we move from bridge to
904                   * bridge.
905                   */
906                  tbus = pb.bus;
907                  tslot = pb.slot;
908                } else {
909                  printk(
910                    "pci : No bridge from bus %i towards root found\n",
911                    tbus
912                  );
913                  goto donesearch;
914                }
915              }
916            }
917          }
918
919          donesearch:
920          if ( !ismatch && int_pin != 0 && int_name == 255 ) {
921            printk(
922              "pci : Unable to match device %d:0x%02x:%d with an int "
923              "routing table entry\n",
924              pbus,
925              pslot,
926              pfun
927            );
928          }
929        }
930      }
931    }
932  }
933}
934
935void print_bars(
936  unsigned char slot,
937  unsigned char func
938)
939{
940  uint32_t addr;
941
942  printk( "*** BARs for slot=%d func=%d\n", slot, func );
943  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_0, &addr);
944  printk("***    PCI DEVICE BAR0: 0x%x\n", addr);
945  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_1, &addr);
946  printk("***    PCI DEVICE BAR1: 0x%x\n", addr);
947  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_2, &addr);
948  printk("***    PCI DEVICE BAR2: 0x%x\n", addr);
949  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_3, &addr);
950  printk("***    PCI DEVICE BAR3: 0x%x\n", addr);
951  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_4, &addr);
952  printk("***    PCI DEVICE BAR4: 0x%x\n", addr);
953  pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_5, &addr);
954  printk("***    PCI DEVICE BAR5: 0x%x\n", addr);
955}
956
957void pci_memory_enable(
958  unsigned char bus,
959  unsigned char slot,
960  unsigned char function
961)
962{
963  uint16_t data;
964
965  pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
966  data |= PCI_COMMAND_MEMORY;
967  pci_write_config_word(0, slot, function, PCI_COMMAND, data );
968  pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
969}
970
971void pci_io_enable(
972  unsigned char bus,
973  unsigned char slot,
974  unsigned char function
975)
976{
977  uint16_t data;
978
979  pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
980  data |= PCI_COMMAND_IO;
981  pci_write_config_word(0, slot, function, PCI_COMMAND, data );
982}
983
984void pci_busmaster_enable(
985  unsigned char bus,
986  unsigned char slot,
987  unsigned char function
988)
989{
990  uint16_t data;
991
992  pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
993  data |= PCI_COMMAND_MASTER;
994  pci_write_config_word(0, slot, function, PCI_COMMAND, data );
995}
996
997/*
998 * This routine determines the maximum bus number in the system
999 */
1000int pci_initialize(void)
1001{
1002  unsigned char slot, func, ucNumFuncs;
1003  unsigned char ucHeader;
1004  uint32_t class;
1005  uint32_t device;
1006  uint32_t vendor;
1007
1008  /*
1009   * Initialize GT_PCI0IOREMAP
1010   */
1011  pci_out_32( BSP_PCI_BASE_ADDRESS, 0xf0, 0 );
1012
1013  /*
1014   *  According to Linux and BSD sources, this is needed to cover up a bug
1015   *  in some versions of the hardware.
1016   */
1017  out_le32( PCI_CONFIG_ADDR, 0x80000020 );
1018  out_le32( PCI_CONFIG_DATA, 0x1be00000 );
1019
1020  /*
1021   * Scan PCI bus 0 looking for the known Network devices and
1022   * initializing the PCI for them.
1023   */
1024  for (slot=0;slot<PCI_MAX_DEVICES;slot++) {
1025    pci_read_config_dword(0, slot, 0, PCI_VENDOR_ID, &device);
1026    if (device == PCI_INVALID_VENDORDEVICEID) {
1027      /* This slot is empty */
1028      continue;
1029    }
1030
1031    pci_read_config_byte(0, slot, 0, PCI_HEADER_TYPE, &ucHeader);
1032    if (ucHeader & PCI_HEADER_TYPE_MULTI_FUNCTION)  {
1033      ucNumFuncs = PCI_MAX_FUNCTIONS;
1034    } else {
1035      ucNumFuncs=1;
1036    }
1037    for (func=0;func<ucNumFuncs;func++) {
1038      pci_read_config_dword(0, slot, func, PCI_VENDOR_ID, &device);
1039       if (device==PCI_INVALID_VENDORDEVICEID) {
1040        /* This slot/function is empty */
1041        continue;
1042      }
1043      vendor = device & 0xffff;
1044      device = device >> 16;
1045
1046      /* This slot/function has a device fitted. */
1047      pci_read_config_dword(0, slot, func, PCI_CLASS_REVISION, &class);
1048      class >>= 16;
1049
1050      // printk( "FOUND DEVICE 0x%04x/0x%04x class 0x%x\n",
1051      //          vendor, device, class );
1052      if (class == PCI_CLASS_NETWORK_ETHERNET) {
1053        JPRINTK("FOUND ETHERNET\n");
1054
1055        pci_write_config_byte(
1056            0, slot, func, PCI_INTERRUPT_LINE, MALTA_IRQ_ETHERNET );
1057
1058        /*
1059         * Rewrite BAR1 for RTL8139
1060         */
1061        if ( vendor == PCI_VENDOR_ID_REALTEK &&
1062             device == PCI_DEVICE_ID_REALTEK_8139 ) {
1063
1064          pci_memory_enable(0, slot, func);
1065          pci_io_enable(0, slot, func);
1066          pci_busmaster_enable(0, slot, func);
1067
1068          // BAR0: IO at 0x0000_1001
1069          pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_0, 0x00001001);
1070
1071          // BAR1: Memory at 0x1203_1000
1072          pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_1, 0x12031000);
1073
1074          // print_bars( slot, func );
1075       } else if ( vendor == PCI_VENDOR_ID_AMD &&
1076                   device == PCI_DEVICE_ID_AMD_LANCE ) {
1077         print_bars( slot, func );
1078         pci_memory_enable(0, slot, func);
1079         pci_io_enable(0, slot, func);
1080         pci_busmaster_enable(0, slot, func);
1081
1082         // BAR0: IO at 0x0000_1041
1083         pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_0, 0x00001041);
1084
1085         // BAR1: Memory at 0x1201_1020
1086         pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_1, 0x12011020);
1087         print_bars( slot, func );
1088       }
1089
1090      }
1091    }
1092  }
1093  return PCIB_ERR_SUCCESS;
1094}
1095
1096/*
1097 * Return the number of PCI busses in the system
1098 */
1099unsigned char pci_bus_count(void)
1100{
1101  return (ucMaxPCIBus+1);
1102}
Note: See TracBrowser for help on using the repository browser.