/[gxemul]/trunk/src/devices/bus_pci.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/devices/bus_pci.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 33 by dpavlin, Mon Oct 8 16:20:58 2007 UTC revision 34 by dpavlin, Mon Oct 8 16:21:17 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2004-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2004-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: bus_pci.c,v 1.72 2006/10/08 02:28:58 debug Exp $   *  $Id: bus_pci.c,v 1.80 2007/02/11 10:03:55 debug Exp $
29   *     *  
30   *  Generic PCI bus framework. This is not a normal "device", but is used by   *  Generic PCI bus framework. This is not a normal "device", but is used by
31   *  individual PCI controllers and devices.   *  individual PCI controllers and devices.
# Line 48  Line 48 
48    
49  #define BUS_PCI_C  #define BUS_PCI_C
50    
51    #include "bus_isa.h"
52  #include "bus_pci.h"  #include "bus_pci.h"
53  #include "cpu.h"  #include "cpu.h"
54  #include "device.h"  #include "device.h"
# Line 221  void bus_pci_add(struct machine *machine Line 222  void bus_pci_add(struct machine *machine
222    
223          if (pci_data == NULL) {          if (pci_data == NULL) {
224                  fatal("bus_pci_add(): pci_data == NULL!\n");                  fatal("bus_pci_add(): pci_data == NULL!\n");
225                  exit(1);                  abort();
226          }          }
227    
228          /*  Find the PCI device:  */          /*  Find the PCI device:  */
# Line 338  static void allocate_device_space(struct Line 339  static void allocate_device_space(struct
339  }  }
340    
341    
 static void bus_pci_debug_dump__2(struct pci_device *pd)  
 {  
         if (pd == NULL)  
                 return;  
         bus_pci_debug_dump__2(pd->next);  
         debug("bus %3i, dev %2i, func %i: %s\n",  
             pd->bus, pd->device, pd->function, pd->name);  
 }  
   
   
 /*  
  *  bus_pci_debug_dump():  
  *  
  *  Lists the attached PCI devices (in reverse).  
  */  
 void bus_pci_debug_dump(void *extra)  
 {  
         struct pci_data *d = (struct pci_data *) extra;  
         int iadd = DEBUG_INDENTATION;  
   
         debug("pci:\n");  
         debug_indentation(iadd);  
   
         if (d->first_device == NULL)  
                 debug("no devices!\n");  
         else  
                 bus_pci_debug_dump__2(d->first_device);  
   
         debug_indentation(-iadd);  
 }  
   
   
342  /*  /*
343   *  bus_pci_init():   *  bus_pci_init():
344   *   *
345   *  This doesn't register a device, but instead returns a pointer to a struct   *  This doesn't register a device, but instead returns a pointer to a struct
346   *  which should be passed to other bus_pci functions when accessing the bus.   *  which should be passed to other bus_pci functions when accessing the bus.
347   *   *
348   *  irq_nr is the (optional) IRQ nr that this PCI bus interrupts at.   *  irq_path is the interrupt path to the PCI controller.
349   *   *
350   *  pci_portbase, pci_membase, and pci_irqbase are the port, memory, and   *  pci_portbase, pci_membase, and pci_irqbase are the port, memory, and
351   *  interrupt bases for PCI devices (as found in the configuration registers).   *  interrupt bases for PCI devices (as found in the configuration registers).
# Line 387  void bus_pci_debug_dump(void *extra) Line 356  void bus_pci_debug_dump(void *extra)
356   *  isa_portbase, isa_membase, and isa_irqbase are the port, memory, and   *  isa_portbase, isa_membase, and isa_irqbase are the port, memory, and
357   *  interrupt bases for legacy ISA devices.   *  interrupt bases for legacy ISA devices.
358   */   */
359  struct pci_data *bus_pci_init(struct machine *machine, int irq_nr,  struct pci_data *bus_pci_init(struct machine *machine, char *irq_path,
360          uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset,          uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset,
361          uint64_t pci_portbase, uint64_t pci_membase, int pci_irqbase,          uint64_t pci_portbase, uint64_t pci_membase, char *pci_irqbase,
362          uint64_t isa_portbase, uint64_t isa_membase, int isa_irqbase)          uint64_t isa_portbase, uint64_t isa_membase, char *isa_irqbase)
363  {  {
364          struct pci_data *d;          struct pci_data *d;
365    
# Line 400  struct pci_data *bus_pci_init(struct mac Line 369  struct pci_data *bus_pci_init(struct mac
369                  exit(1);                  exit(1);
370          }          }
371          memset(d, 0, sizeof(struct pci_data));          memset(d, 0, sizeof(struct pci_data));
372          d->irq_nr                = irq_nr;  
373            d->irq_path              = strdup(irq_path);
374            d->irq_path_isa          = strdup(isa_irqbase);
375            d->irq_path_pci          = strdup(pci_irqbase);
376    
377          d->pci_actual_io_offset  = pci_actual_io_offset;          d->pci_actual_io_offset  = pci_actual_io_offset;
378          d->pci_actual_mem_offset = pci_actual_mem_offset;          d->pci_actual_mem_offset = pci_actual_mem_offset;
379          d->pci_portbase          = pci_portbase;          d->pci_portbase          = pci_portbase;
380          d->pci_membase           = pci_membase;          d->pci_membase           = pci_membase;
         d->pci_irqbase           = pci_irqbase;  
381          d->isa_portbase          = isa_portbase;          d->isa_portbase          = isa_portbase;
382          d->isa_membase           = isa_membase;          d->isa_membase           = isa_membase;
         d->isa_irqbase           = isa_irqbase;  
   
         /*  Register the bus:  */  
         machine_bus_register(machine, "pci", bus_pci_debug_dump, d);  
383    
384          /*  Assume that the first 64KB could be used by legacy ISA devices:  */          /*  Assume that the first 64KB could be used by legacy ISA devices:  */
385          d->cur_pci_portbase = d->pci_portbase + 0x10000;          d->cur_pci_portbase = d->pci_portbase + 0x10000;
# Line 509  PCIINIT(ali_m1543) Line 477  PCIINIT(ali_m1543)
477          /*  Linux uses these to detect which IRQ the IDE controller uses:  */          /*  Linux uses these to detect which IRQ the IDE controller uses:  */
478          PCI_SET_DATA(0x44, 0x0000000e);          PCI_SET_DATA(0x44, 0x0000000e);
479          PCI_SET_DATA(0x58, 0x00000003);          PCI_SET_DATA(0x58, 0x00000003);
480    
481            switch (machine->machine_type) {
482            case MACHINE_CATS:
483                    bus_isa_init(machine, pd->pcibus->irq_path_isa,
484                        BUS_ISA_PCKBC_FORCE_USE | BUS_ISA_PCKBC_NONPCSTYLE,
485                        0x7c000000, 0x80000000);
486                    break;
487            default:fatal("ali_m1543 init: unimplemented machine type\n");
488                    exit(1);
489            }
490  }  }
491    
492  PCIINIT(ali_m5229)  PCIINIT(ali_m5229)
493  {  {
494          char tmpstr[300];          char tmpstr[300], irqstr[300];
495    
496          PCI_SET_DATA(PCI_ID_REG,          PCI_SET_DATA(PCI_ID_REG,
497              PCI_ID_CODE(PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M5229));              PCI_ID_CODE(PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M5229));
# Line 521  PCIINIT(ali_m5229) Line 499  PCIINIT(ali_m5229)
499          PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,          PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
500              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x60) + 0xc1);              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x60) + 0xc1);
501    
502            switch (machine->machine_type) {
503            case MACHINE_CATS:
504                    /*  CATS ISA interrupts are at footbridge irq 10:  */
505                    snprintf(irqstr, sizeof(irqstr), "%s.10.isa",
506                        pd->pcibus->irq_path);
507                    break;
508            default:fatal("ali_m5229 init: unimplemented machine type\n");
509                    exit(1);
510            }
511    
512          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
513              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
514                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s.%i",
515                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      (long long)(pd->pcibus->isa_portbase + 0x1f0),
516                      pd->pcibus->isa_irqbase + 14);                      irqstr, 14);
517                  device_add(machine, tmpstr);                  device_add(machine, tmpstr);
518          }          }
519    
# Line 730  PCIINIT(i31244) Line 718  PCIINIT(i31244)
718          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
719              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
720                  char tmpstr[150];                  char tmpstr[150];
721                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s.%i",
722                      (long long)(pd->pcibus->pci_actual_io_offset + 0),                      (long long)(pd->pcibus->pci_actual_io_offset + 0),
723                      pd->pcibus->pci_irqbase + 0);                      pd->pcibus->irq_path_pci, irq & 255);
724                  device_add(machine, tmpstr);                  device_add(machine, tmpstr);
725          }          }
726  }  }
# Line 828  PCIINIT(piix3_ide) Line 816  PCIINIT(piix3_ide)
816    
817          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
818              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
819                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx "
820                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "irq=%s.isa.%i", (long long)(pd->pcibus->isa_portbase +
821                      pd->pcibus->isa_irqbase + 14);                      0x1f0), pd->pcibus->irq_path_isa, 14);
822                  ((struct piix_ide_extra *)pd->extra)->wdc0 =                  ((struct piix_ide_extra *)pd->extra)->wdc0 =
823                      device_add(machine, tmpstr);                      device_add(machine, tmpstr);
824          }          }
825    
826          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
827              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
828                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx "
829                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "irq=%s.isa.%i", (long long)(pd->pcibus->isa_portbase +
830                      pd->pcibus->isa_irqbase + 15);                      0x170), pd->pcibus->irq_path_isa, 15);
831                  ((struct piix_ide_extra *)pd->extra)->wdc1 =                  ((struct piix_ide_extra *)pd->extra)->wdc1 =
832                      device_add(machine, tmpstr);                      device_add(machine, tmpstr);
833          }          }
# Line 872  PCIINIT(piix4_ide) Line 860  PCIINIT(piix4_ide)
860    
861          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
862              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
863                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
864                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
865                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
866                  ((struct piix_ide_extra *)pd->extra)->wdc0 =                  ((struct piix_ide_extra *)pd->extra)->wdc0 =
867                      device_add(machine, tmpstr);                      device_add(machine, tmpstr);
868          }          }
869    
870          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
871              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
872                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
873                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
874                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
875                  ((struct piix_ide_extra *)pd->extra)->wdc1 =                  ((struct piix_ide_extra *)pd->extra)->wdc1 =
876                      device_add(machine, tmpstr);                      device_add(machine, tmpstr);
877          }          }
# Line 1012  PCIINIT(vt82c586_ide) Line 1000  PCIINIT(vt82c586_ide)
1000    
1001          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
1002              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
1003                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1004                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
1005                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
1006                  ((struct vt82c586_ide_extra *)pd->extra)->wdc0 =                  ((struct vt82c586_ide_extra *)pd->extra)->wdc0 =
1007                      device_add(machine, tmpstr);                      device_add(machine, tmpstr);
1008          }          }
1009    
1010          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
1011              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
1012                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1013                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
1014                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
1015                  ((struct vt82c586_ide_extra *)pd->extra)->wdc1 =                  ((struct vt82c586_ide_extra *)pd->extra)->wdc1 =
1016                      device_add(machine, tmpstr);                      device_add(machine, tmpstr);
1017          }          }
# Line 1052  PCIINIT(symphony_83c553) Line 1040  PCIINIT(symphony_83c553)
1040    
1041          PCI_SET_DATA(PCI_BHLC_REG,          PCI_SET_DATA(PCI_BHLC_REG,
1042              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1043    
1044            switch (machine->machine_type) {
1045            case MACHINE_NETWINDER:
1046                    bus_isa_init(machine, pd->pcibus->irq_path_isa,
1047                        0, 0x7c000000, 0x80000000);
1048                    break;
1049            default:fatal("symphony_83c553 init: unimplemented machine type\n");
1050                    exit(1);
1051            }
1052  }  }
1053    
1054  struct symphony_82c105_extra {  struct symphony_82c105_extra {
# Line 1120  PCIINIT(symphony_82c105) Line 1117  PCIINIT(symphony_82c105)
1117    
1118          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
1119              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
1120                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1121                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
1122                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
1123                  ((struct symphony_82c105_extra *)pd->extra)->wdc0 =                  ((struct symphony_82c105_extra *)pd->extra)->wdc0 =
1124                      device_add(machine, tmpstr);                      device_add(machine, tmpstr);
1125          }          }
1126    
1127          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
1128              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
1129                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1130                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
1131                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
1132                  ((struct symphony_82c105_extra *)pd->extra)->wdc1 =                  ((struct symphony_82c105_extra *)pd->extra)->wdc1 =
1133                      device_add(machine, tmpstr);                      device_add(machine, tmpstr);
1134          }          }
# Line 1151  PCIINIT(symphony_82c105) Line 1148  PCIINIT(symphony_82c105)
1148  PCIINIT(dec21143)  PCIINIT(dec21143)
1149  {  {
1150          uint64_t port, memaddr;          uint64_t port, memaddr;
1151          int irq = 0;            /*  TODO  */          int pci_int_line = 0x101, irq = 0, isa = 0;
1152          int pci_int_line = 0x101;          char irqstr[200];
1153          char tmpstr[200];          char tmpstr[200];
1154    
1155          PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_DEC,          PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_DEC,
# Line 1176  PCIINIT(dec21143) Line 1173  PCIINIT(dec21143)
1173                  irq = 8 + 7;                  irq = 8 + 7;
1174                  pci_int_line = 0x407;                  pci_int_line = 0x407;
1175                  break;                  break;
         case MACHINE_ALGOR:  
                 /*  TODO  */  
                 irq = 8 + 7;  
                 pci_int_line = 0x407;  
                 break;  
1176          case MACHINE_PREP:          case MACHINE_PREP:
1177                  irq = 32 + 10;                  irq = 10;
1178                    isa = 1;
1179                  pci_int_line = 0x20a;                  pci_int_line = 0x20a;
1180                  break;                  break;
1181          case MACHINE_MVMEPPC:          case MACHINE_MVMEPPC:
1182                  /*  TODO  */                  /*  TODO  */
1183                  irq = 32 + 10;                  irq = 10;
1184                  pci_int_line = 0x40a;                  pci_int_line = 0x40a;
1185                  break;                  break;
1186          case MACHINE_PMPPC:          case MACHINE_PMPPC:
# Line 1206  PCIINIT(dec21143) Line 1199  PCIINIT(dec21143)
1199    
1200          allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);          allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);
1201    
1202            if (isa)
1203                    snprintf(irqstr, sizeof(irqstr), "%s.isa.%i",
1204                        pd->pcibus->irq_path_isa, irq);
1205            else
1206                    snprintf(irqstr, sizeof(irqstr), "%s.%i",
1207                        pd->pcibus->irq_path_pci, irq);
1208    
1209          snprintf(tmpstr, sizeof(tmpstr), "dec21143 addr=0x%llx addr2=0x%llx "          snprintf(tmpstr, sizeof(tmpstr), "dec21143 addr=0x%llx addr2=0x%llx "
1210              "irq=%i pci_little_endian=1", (long long)port, (long long)memaddr,              "irq=%s pci_little_endian=1", (long long)port,
1211              irq);              (long long)memaddr, irqstr);
1212    
1213          device_add(machine, tmpstr);          device_add(machine, tmpstr);
1214  }  }
1215    

Legend:
Removed from v.33  
changed lines
  Added in v.34

  ViewVC Help
Powered by ViewVC 1.1.26