/[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 29 by dpavlin, Mon Oct 8 16:19:56 2007 UTC revision 30 by dpavlin, Mon Oct 8 16:20:40 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: bus_pci.c,v 1.65 2006/05/10 03:32:32 debug Exp $   *  $Id: bus_pci.c,v 1.70 2006/08/12 19:38:24 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 57  Line 57 
57  #include "memory.h"  #include "memory.h"
58  #include "misc.h"  #include "misc.h"
59    
60    #include "wdc.h"
61    
62  extern int verbose;  extern int verbose;
63    
64    
# Line 147  void bus_pci_data_access(struct cpu *cpu Line 149  void bus_pci_data_access(struct cpu *cpu
149                          pci_data->last_was_write_ffffffff = 1;                          pci_data->last_was_write_ffffffff = 1;
150                          return;                          return;
151                  }                  }
152                  /*  Writes are not really supported yet:  */  
153                  if (idata != x) {                  if (dev->cfg_reg_write != NULL) {
154                            dev->cfg_reg_write(dev, pci_data->cur_reg, *data);
155                    } else {
156                            /*  Print a warning for unhandled writes:  */
157                          debug("[ bus_pci: write to PCI DATA: data = 0x%08llx"                          debug("[ bus_pci: write to PCI DATA: data = 0x%08llx"
158                              " differs from current value 0x%08llx; NOT YET"                              " (current value = 0x%08llx); NOT YET"
159                              " SUPPORTED. bus %i, device %i, function %i (%s)"                              " SUPPORTED. bus %i, device %i, function %i (%s)"
160                              " register 0x%02x ]\n", (long long)idata,                              " register 0x%02x ]\n", (long long)idata,
161                              (long long)x, pci_data->cur_bus,                              (long long)x, pci_data->cur_bus,
162                              pci_data->cur_device, pci_data->cur_func,                              pci_data->cur_device, pci_data->cur_func,
163                              dev->name, pci_data->cur_reg);                              dev->name, pci_data->cur_reg);
164    
165                            /*  Special warning, to detect if NetBSD's special
166                                detection of PCI devices fails:  */
167                            if (pci_data->cur_reg == PCI_COMMAND_STATUS_REG
168                                && !((*data) & PCI_COMMAND_IO_ENABLE)) {
169                                    fatal("\n[ NetBSD PCI detection stuff not"
170                                        " yet implemented for device '%s' ]\n",
171                                        dev->name);
172                            }
173                  }                  }
174                  return;                  return;
175          }          }
# Line 420  struct pci_data *bus_pci_init(struct mac Line 434  struct pci_data *bus_pci_init(struct mac
434    
435    
436  /*  /*
437   *  Integraphics Systems "igsfb" Framebuffer (graphics) card.   *  Integraphics Systems "igsfb" Framebuffer (graphics) card, used in at
438   *   *  least the NetWinder.
  *  TODO  
439   */   */
440    
441  #define PCI_VENDOR_INTEGRAPHICS         0x10ea  #define PCI_VENDOR_INTEGRAPHICS         0x10ea
442    
443  PCIINIT(igsfb)  PCIINIT(igsfb)
444  {  {
445            char tmpstr[200];
446    
447          PCI_SET_DATA(PCI_ID_REG,          PCI_SET_DATA(PCI_ID_REG,
448              PCI_ID_CODE(PCI_VENDOR_INTEGRAPHICS, 0x2010));              PCI_ID_CODE(PCI_VENDOR_INTEGRAPHICS, 0x2010));
449    
# Line 439  PCIINIT(igsfb) Line 454  PCIINIT(igsfb)
454          /*  TODO  */          /*  TODO  */
455          PCI_SET_DATA(0x10, 0x08000000);          PCI_SET_DATA(0x10, 0x08000000);
456    
457          dev_vga_init(machine, mem, pd->pcibus->isa_membase + 0xa0000,          snprintf(tmpstr, sizeof(tmpstr), "igsfb addr=0x%llx",
458              0x88800000 + 0x3c0, machine->machine_name);              (long long)(pd->pcibus->isa_membase + 0x08000000));
459            device_add(machine, tmpstr);
460  }  }
461    
462    
# Line 627  PCIINIT(gt64260) Line 643  PCIINIT(gt64260)
643    
644    
645  /*  /*
646     *  AMD PCnet Ethernet card.
647     *
648     *  "Am79c970A PCnet-PCI II rev 0" or similar.
649     */
650    
651    #define PCI_VENDOR_AMD                  0x1022  /* Advanced Micro Devices */
652    #define PCI_PRODUCT_AMD_PCNET_PCI       0x2000  /* PCnet-PCI Ethernet */
653    
654    PCIINIT(pcn)
655    {
656            int irq;
657    
658            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_AMD,
659                PCI_PRODUCT_AMD_PCNET_PCI));
660    
661            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_NETWORK,
662                PCI_SUBCLASS_NETWORK_ETHERNET, 0) + 0x00);  /*  Revision 0  */
663    
664            switch (machine->machine_type) {
665    
666            case MACHINE_EVBMIPS:
667                    irq = (1 << 8) + 10;    /*  TODO  */
668                    break;
669    
670            default:fatal("pcn in non-implemented machine type %i\n",
671                        machine->machine_type);
672                    exit(1);
673            }
674    
675            PCI_SET_DATA(PCI_INTERRUPT_REG, 0x01100000 | irq);
676    
677            /*
678             *  TODO: Add the pcn device here. The pcn device will need to work as
679             *  a wrapper for dev_le + all the DMA magic and whatever is required.
680             *  It's too much to implement right now.
681             */
682    }
683    
684    
685    
686    /*
687   *  Intel 31244   Serial ATA Controller   *  Intel 31244   Serial ATA Controller
688   *  Intel 82371SB PIIX3 PCI-ISA bridge   *  Intel 82371SB PIIX3 PCI-ISA bridge
689   *  Intel 82371AB PIIX4 PCI-ISA bridge   *  Intel 82371AB PIIX4 PCI-ISA bridge
# Line 721  PCIINIT(i82378zb) Line 778  PCIINIT(i82378zb)
778          PCI_SET_DATA(0x60, 0x0f0e0b0a);          PCI_SET_DATA(0x60, 0x0f0e0b0a);
779  }  }
780    
781    struct piix_ide_extra {
782            void    *wdc0;
783            void    *wdc1;
784    };
785    
786    int piix_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
787    {
788            void *wdc0 = ((struct piix_ide_extra *)pd->extra)->wdc0;
789            void *wdc1 = ((struct piix_ide_extra *)pd->extra)->wdc1;
790            int enabled = 0;
791    
792            switch (reg) {
793            case PCI_COMMAND_STATUS_REG:
794                    if (value & PCI_COMMAND_IO_ENABLE)
795                            enabled = 1;
796                    if (wdc0 != NULL)
797                            wdc_set_io_enabled(wdc0, enabled);
798                    if (wdc1 != NULL)
799                            wdc_set_io_enabled(wdc1, enabled);
800                    return 1;
801            }
802    
803            return 0;
804    }
805    
806  PCIINIT(piix3_ide)  PCIINIT(piix3_ide)
807  {  {
808          char tmpstr[100];          char tmpstr[100];
# Line 736  PCIINIT(piix3_ide) Line 818  PCIINIT(piix3_ide)
818          /*  channel 0 and 1 enabled as IDE  */          /*  channel 0 and 1 enabled as IDE  */
819          PCI_SET_DATA(0x40, 0x80008000);          PCI_SET_DATA(0x40, 0x80008000);
820    
821            pd->extra = malloc(sizeof(struct piix_ide_extra));
822            if (pd->extra == NULL) {
823                    fatal("Out of memory.\n");
824                    exit(1);
825            }
826            ((struct piix_ide_extra *)pd->extra)->wdc0 = NULL;
827            ((struct piix_ide_extra *)pd->extra)->wdc1 = NULL;
828    
829          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
830              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
831                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
832                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      (long long)(pd->pcibus->isa_portbase + 0x1f0),
833                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->isa_irqbase + 14);
834                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc0 =
835                        device_add(machine, tmpstr);
836          }          }
837    
838          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
# Line 749  PCIINIT(piix3_ide) Line 840  PCIINIT(piix3_ide)
840                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
841                      (long long)(pd->pcibus->isa_portbase + 0x170),                      (long long)(pd->pcibus->isa_portbase + 0x170),
842                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->isa_irqbase + 15);
843                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc1 =
844                        device_add(machine, tmpstr);
845          }          }
846    
847            pd->cfg_reg_write = piix_ide_cfg_reg_write;
848  }  }
849    
850  PCIINIT(piix4_ide)  PCIINIT(piix4_ide)
# Line 768  PCIINIT(piix4_ide) Line 862  PCIINIT(piix4_ide)
862          /*  channel 0 and 1 enabled as IDE  */          /*  channel 0 and 1 enabled as IDE  */
863          PCI_SET_DATA(0x40, 0x80008000);          PCI_SET_DATA(0x40, 0x80008000);
864    
865            pd->extra = malloc(sizeof(struct piix_ide_extra));
866            if (pd->extra == NULL) {
867                    fatal("Out of memory.\n");
868                    exit(1);
869            }
870            ((struct piix_ide_extra *)pd->extra)->wdc0 = NULL;
871            ((struct piix_ide_extra *)pd->extra)->wdc1 = NULL;
872    
873          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
874              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
875                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
876                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      (long long)(pd->pcibus->isa_portbase + 0x1f0),
877                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->isa_irqbase + 14);
878                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc0 =
879                        device_add(machine, tmpstr);
880          }          }
881    
882          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
# Line 781  PCIINIT(piix4_ide) Line 884  PCIINIT(piix4_ide)
884                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
885                      (long long)(pd->pcibus->isa_portbase + 0x170),                      (long long)(pd->pcibus->isa_portbase + 0x170),
886                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->isa_irqbase + 15);
887                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc1 =
888                        device_add(machine, tmpstr);
889          }          }
890    
891            pd->cfg_reg_write = piix_ide_cfg_reg_write;
892  }  }
893    
894    
# Line 856  PCIINIT(vt82c586_isa) Line 962  PCIINIT(vt82c586_isa)
962              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
963  }  }
964    
965    struct vt82c586_ide_extra {
966            void    *wdc0;
967            void    *wdc1;
968    };
969    
970    int vt82c586_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
971    {
972            void *wdc0 = ((struct vt82c586_ide_extra *)pd->extra)->wdc0;
973            void *wdc1 = ((struct vt82c586_ide_extra *)pd->extra)->wdc1;
974            int enabled = 0;
975    
976            switch (reg) {
977            case PCI_COMMAND_STATUS_REG:
978                    if (value & PCI_COMMAND_IO_ENABLE)
979                            enabled = 1;
980                    if (wdc0 != NULL)
981                            wdc_set_io_enabled(wdc0, enabled);
982                    if (wdc1 != NULL)
983                            wdc_set_io_enabled(wdc1, enabled);
984                    return 1;
985            }
986    
987            return 0;
988    }
989    
990  PCIINIT(vt82c586_ide)  PCIINIT(vt82c586_ide)
991  {  {
992          char tmpstr[100];          char tmpstr[100];
# Line 871  PCIINIT(vt82c586_ide) Line 1002  PCIINIT(vt82c586_ide)
1002          /*  channel 0 and 1 enabled  */          /*  channel 0 and 1 enabled  */
1003          PCI_SET_DATA(0x40, 0x00000003);          PCI_SET_DATA(0x40, 0x00000003);
1004    
1005            pd->extra = malloc(sizeof(struct vt82c586_ide_extra));
1006            if (pd->extra == NULL) {
1007                    fatal("Out of memory.\n");
1008                    exit(1);
1009            }
1010            ((struct vt82c586_ide_extra *)pd->extra)->wdc0 = NULL;
1011            ((struct vt82c586_ide_extra *)pd->extra)->wdc1 = NULL;
1012    
1013          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
1014              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
1015                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
1016                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      (long long)(pd->pcibus->isa_portbase + 0x1f0),
1017                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->isa_irqbase + 14);
1018                  device_add(machine, tmpstr);                  ((struct vt82c586_ide_extra *)pd->extra)->wdc0 =
1019                        device_add(machine, tmpstr);
1020          }          }
1021    
1022          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
# Line 884  PCIINIT(vt82c586_ide) Line 1024  PCIINIT(vt82c586_ide)
1024                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
1025                      (long long)(pd->pcibus->isa_portbase + 0x170),                      (long long)(pd->pcibus->isa_portbase + 0x170),
1026                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->isa_irqbase + 15);
1027                  device_add(machine, tmpstr);                  ((struct vt82c586_ide_extra *)pd->extra)->wdc1 =
1028                        device_add(machine, tmpstr);
1029          }          }
1030    
1031            pd->cfg_reg_write = vt82c586_ide_cfg_reg_write;
1032  }  }
1033    
1034    

Legend:
Removed from v.29  
changed lines
  Added in v.30

  ViewVC Help
Powered by ViewVC 1.1.26