/[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 24 by dpavlin, Mon Oct 8 16:19:56 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 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.65 2006/05/10 03:32:32 debug Exp $   *  $Id: bus_pci.c,v 1.84 2007/06/15 18:13:04 debug Exp $
29   *     *  
30   *  Generic PCI bus framework. This is not a normal "device", but is used by   *  COMMENT: Generic PCI bus framework
31   *  individual PCI controllers and devices.   *
32     *  This is not a normal "device", but is used by individual PCI controllers
33     *  and devices.
34   *   *
35   *  See NetBSD's pcidevs.h for more PCI vendor and device identifiers.   *  See NetBSD's pcidevs.h for more PCI vendor and device identifiers.
36   *   *
# Line 48  Line 50 
50    
51  #define BUS_PCI_C  #define BUS_PCI_C
52    
53    #include "bus_isa.h"
54  #include "bus_pci.h"  #include "bus_pci.h"
55  #include "cpu.h"  #include "cpu.h"
56  #include "device.h"  #include "device.h"
# Line 57  Line 60 
60  #include "memory.h"  #include "memory.h"
61  #include "misc.h"  #include "misc.h"
62    
63    #include "cpc700reg.h"
64    #include "wdc.h"
65    
66  extern int verbose;  extern int verbose;
67    
68    
# Line 147  void bus_pci_data_access(struct cpu *cpu Line 153  void bus_pci_data_access(struct cpu *cpu
153                          pci_data->last_was_write_ffffffff = 1;                          pci_data->last_was_write_ffffffff = 1;
154                          return;                          return;
155                  }                  }
156                  /*  Writes are not really supported yet:  */  
157                  if (idata != x) {                  if (dev->cfg_reg_write != NULL) {
158                            dev->cfg_reg_write(dev, pci_data->cur_reg, *data);
159                    } else {
160                            /*  Print a warning for unhandled writes:  */
161                          debug("[ bus_pci: write to PCI DATA: data = 0x%08llx"                          debug("[ bus_pci: write to PCI DATA: data = 0x%08llx"
162                              " differs from current value 0x%08llx; NOT YET"                              " (current value = 0x%08llx); NOT YET"
163                              " SUPPORTED. bus %i, device %i, function %i (%s)"                              " SUPPORTED. bus %i, device %i, function %i (%s)"
164                              " register 0x%02x ]\n", (long long)idata,                              " register 0x%02x ]\n", (long long)idata,
165                              (long long)x, pci_data->cur_bus,                              (long long)x, pci_data->cur_bus,
166                              pci_data->cur_device, pci_data->cur_func,                              pci_data->cur_device, pci_data->cur_func,
167                              dev->name, pci_data->cur_reg);                              dev->name, pci_data->cur_reg);
168    
169                            /*  Special warning, to detect if NetBSD's special
170                                detection of PCI devices fails:  */
171                            if (pci_data->cur_reg == PCI_COMMAND_STATUS_REG
172                                && !((*data) & PCI_COMMAND_IO_ENABLE)) {
173                                    fatal("\n[ NetBSD PCI detection stuff not"
174                                        " yet implemented for device '%s' ]\n",
175                                        dev->name);
176                            }
177                  }                  }
178                  return;                  return;
179          }          }
# Line 207  void bus_pci_add(struct machine *machine Line 225  void bus_pci_add(struct machine *machine
225    
226          if (pci_data == NULL) {          if (pci_data == NULL) {
227                  fatal("bus_pci_add(): pci_data == NULL!\n");                  fatal("bus_pci_add(): pci_data == NULL!\n");
228                  exit(1);                  abort();
229          }          }
230    
231          /*  Find the PCI device:  */          /*  Find the PCI device:  */
# Line 225  void bus_pci_add(struct machine *machine Line 243  void bus_pci_add(struct machine *machine
243                  pd = pd->next;                  pd = pd->next;
244          }          }
245    
246          pd = malloc(sizeof(struct pci_device));          CHECK_ALLOCATION(pd = malloc(sizeof(struct pci_device)));
         if (pd == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
   
247          memset(pd, 0, sizeof(struct pci_device));          memset(pd, 0, sizeof(struct pci_device));
248    
249          /*  Add the new device first in the PCI bus' chain:  */          /*  Add the new device first in the PCI bus' chain:  */
250          pd->next = pci_data->first_device;          pd->next = pci_data->first_device;
251          pci_data->first_device = pd;          pci_data->first_device = pd;
252    
253            CHECK_ALLOCATION(pd->name = strdup(name));
254          pd->pcibus   = pci_data;          pd->pcibus   = pci_data;
         pd->name     = strdup(name);  
255          pd->bus      = bus;          pd->bus      = bus;
256          pd->device   = device;          pd->device   = device;
257          pd->function = function;          pd->function = function;
# Line 324  static void allocate_device_space(struct Line 337  static void allocate_device_space(struct
337  }  }
338    
339    
 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);  
 }  
   
   
340  /*  /*
341   *  bus_pci_init():   *  bus_pci_init():
342   *   *
343   *  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
344   *  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.
345   *   *
346   *  irq_nr is the (optional) IRQ nr that this PCI bus interrupts at.   *  irq_path is the interrupt path to the PCI controller.
347   *   *
348   *  pci_portbase, pci_membase, and pci_irqbase are the port, memory, and   *  pci_portbase, pci_membase, and pci_irqbase are the port, memory, and
349   *  interrupt bases for PCI devices (as found in the configuration registers).   *  interrupt bases for PCI devices (as found in the configuration registers).
# Line 373  void bus_pci_debug_dump(void *extra) Line 354  void bus_pci_debug_dump(void *extra)
354   *  isa_portbase, isa_membase, and isa_irqbase are the port, memory, and   *  isa_portbase, isa_membase, and isa_irqbase are the port, memory, and
355   *  interrupt bases for legacy ISA devices.   *  interrupt bases for legacy ISA devices.
356   */   */
357  struct pci_data *bus_pci_init(struct machine *machine, int irq_nr,  struct pci_data *bus_pci_init(struct machine *machine, char *irq_path,
358          uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset,          uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset,
359          uint64_t pci_portbase, uint64_t pci_membase, int pci_irqbase,          uint64_t pci_portbase, uint64_t pci_membase, char *pci_irqbase,
360          uint64_t isa_portbase, uint64_t isa_membase, int isa_irqbase)          uint64_t isa_portbase, uint64_t isa_membase, char *isa_irqbase)
361  {  {
362          struct pci_data *d;          struct pci_data *d;
363    
364          d = malloc(sizeof(struct pci_data));          CHECK_ALLOCATION(d = malloc(sizeof(struct pci_data)));
         if (d == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
365          memset(d, 0, sizeof(struct pci_data));          memset(d, 0, sizeof(struct pci_data));
366          d->irq_nr                = irq_nr;  
367            CHECK_ALLOCATION(d->irq_path     = strdup(irq_path));
368            CHECK_ALLOCATION(d->irq_path_isa = strdup(isa_irqbase));
369            CHECK_ALLOCATION(d->irq_path_pci = strdup(pci_irqbase));
370    
371          d->pci_actual_io_offset  = pci_actual_io_offset;          d->pci_actual_io_offset  = pci_actual_io_offset;
372          d->pci_actual_mem_offset = pci_actual_mem_offset;          d->pci_actual_mem_offset = pci_actual_mem_offset;
373          d->pci_portbase          = pci_portbase;          d->pci_portbase          = pci_portbase;
374          d->pci_membase           = pci_membase;          d->pci_membase           = pci_membase;
         d->pci_irqbase           = pci_irqbase;  
375          d->isa_portbase          = isa_portbase;          d->isa_portbase          = isa_portbase;
376          d->isa_membase           = isa_membase;          d->isa_membase           = isa_membase;
         d->isa_irqbase           = isa_irqbase;  
377    
378          /*  Register the bus:  */          d->cur_pci_portbase = d->pci_portbase;
379          machine_bus_register(machine, "pci", bus_pci_debug_dump, d);          d->cur_pci_membase  = d->pci_membase;
380    
381          /*  Assume that the first 64KB could be used by legacy ISA devices:  */          /*  Assume that the first 64KB could be used by legacy ISA devices:  */
382          d->cur_pci_portbase = d->pci_portbase + 0x10000;          if (d->isa_portbase != 0 || d->isa_membase != 0) {
383          d->cur_pci_membase  = d->pci_membase + 0x10000;                  d->cur_pci_portbase += 0x10000;
384                    d->cur_pci_membase  += 0x10000;
385            }
386    
387          return d;          return d;
388  }  }
# Line 420  struct pci_data *bus_pci_init(struct mac Line 401  struct pci_data *bus_pci_init(struct mac
401    
402    
403  /*  /*
404   *  Integraphics Systems "igsfb" Framebuffer (graphics) card.   *  Integraphics Systems "igsfb" Framebuffer (graphics) card, used in at
405   *   *  least the NetWinder.
  *  TODO  
406   */   */
407    
408  #define PCI_VENDOR_INTEGRAPHICS         0x10ea  #define PCI_VENDOR_INTEGRAPHICS         0x10ea
409    
410  PCIINIT(igsfb)  PCIINIT(igsfb)
411  {  {
412            char tmpstr[200];
413    
414          PCI_SET_DATA(PCI_ID_REG,          PCI_SET_DATA(PCI_ID_REG,
415              PCI_ID_CODE(PCI_VENDOR_INTEGRAPHICS, 0x2010));              PCI_ID_CODE(PCI_VENDOR_INTEGRAPHICS, 0x2010));
416    
# Line 439  PCIINIT(igsfb) Line 421  PCIINIT(igsfb)
421          /*  TODO  */          /*  TODO  */
422          PCI_SET_DATA(0x10, 0x08000000);          PCI_SET_DATA(0x10, 0x08000000);
423    
424          dev_vga_init(machine, mem, pd->pcibus->isa_membase + 0xa0000,          snprintf(tmpstr, sizeof(tmpstr), "igsfb addr=0x%llx",
425              0x88800000 + 0x3c0, machine->machine_name);              (long long)(pd->pcibus->isa_membase + 0x08000000));
426            device_add(machine, tmpstr);
427  }  }
428    
429    
# Line 493  PCIINIT(ali_m1543) Line 476  PCIINIT(ali_m1543)
476          /*  Linux uses these to detect which IRQ the IDE controller uses:  */          /*  Linux uses these to detect which IRQ the IDE controller uses:  */
477          PCI_SET_DATA(0x44, 0x0000000e);          PCI_SET_DATA(0x44, 0x0000000e);
478          PCI_SET_DATA(0x58, 0x00000003);          PCI_SET_DATA(0x58, 0x00000003);
479    
480            switch (machine->machine_type) {
481            case MACHINE_CATS:
482                    bus_isa_init(machine, pd->pcibus->irq_path_isa,
483                        BUS_ISA_PCKBC_FORCE_USE | BUS_ISA_PCKBC_NONPCSTYLE,
484                        0x7c000000, 0x80000000);
485                    break;
486            default:fatal("ali_m1543 init: unimplemented machine type\n");
487                    exit(1);
488            }
489  }  }
490    
491  PCIINIT(ali_m5229)  PCIINIT(ali_m5229)
492  {  {
493          char tmpstr[300];          char tmpstr[300], irqstr[300];
494    
495          PCI_SET_DATA(PCI_ID_REG,          PCI_SET_DATA(PCI_ID_REG,
496              PCI_ID_CODE(PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M5229));              PCI_ID_CODE(PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M5229));
# Line 505  PCIINIT(ali_m5229) Line 498  PCIINIT(ali_m5229)
498          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,
499              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x60) + 0xc1);              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x60) + 0xc1);
500    
501            switch (machine->machine_type) {
502            case MACHINE_CATS:
503                    /*  CATS ISA interrupts are at footbridge irq 10:  */
504                    snprintf(irqstr, sizeof(irqstr), "%s.10.isa",
505                        pd->pcibus->irq_path);
506                    break;
507            default:fatal("ali_m5229 init: unimplemented machine type\n");
508                    exit(1);
509            }
510    
511          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
512              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
513                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s.%i",
514                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      (long long)(pd->pcibus->isa_portbase + 0x1f0),
515                      pd->pcibus->isa_irqbase + 14);                      irqstr, 14);
516                  device_add(machine, tmpstr);                  device_add(machine, tmpstr);
517          }          }
518    
# Line 627  PCIINIT(gt64260) Line 630  PCIINIT(gt64260)
630    
631    
632  /*  /*
633     *  AMD PCnet Ethernet card.
634     *
635     *  "Am79c970A PCnet-PCI II rev 0" or similar.
636     */
637    
638    #define PCI_VENDOR_AMD                  0x1022  /* Advanced Micro Devices */
639    #define PCI_PRODUCT_AMD_PCNET_PCI       0x2000  /* PCnet-PCI Ethernet */
640    
641    PCIINIT(pcn)
642    {
643            int irq;
644    
645            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_AMD,
646                PCI_PRODUCT_AMD_PCNET_PCI));
647    
648            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_NETWORK,
649                PCI_SUBCLASS_NETWORK_ETHERNET, 0) + 0x00);  /*  Revision 0  */
650    
651            switch (machine->machine_type) {
652    
653            case MACHINE_EVBMIPS:
654                    irq = (1 << 8) + 10;    /*  TODO  */
655                    break;
656    
657            default:fatal("pcn in non-implemented machine type %i\n",
658                        machine->machine_type);
659                    exit(1);
660            }
661    
662            PCI_SET_DATA(PCI_INTERRUPT_REG, 0x01100000 | irq);
663    
664            /*
665             *  TODO: Add the pcn device here. The pcn device will need to work as
666             *  a wrapper for dev_le + all the DMA magic and whatever is required.
667             *  It's too much to implement right now.
668             */
669    }
670    
671    
672    
673    /*
674   *  Intel 31244   Serial ATA Controller   *  Intel 31244   Serial ATA Controller
675   *  Intel 82371SB PIIX3 PCI-ISA bridge   *  Intel 82371SB PIIX3 PCI-ISA bridge
676   *  Intel 82371AB PIIX4 PCI-ISA bridge   *  Intel 82371AB PIIX4 PCI-ISA bridge
# Line 673  PCIINIT(i31244) Line 717  PCIINIT(i31244)
717          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
718              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
719                  char tmpstr[150];                  char tmpstr[150];
720                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s.%i",
721                      (long long)(pd->pcibus->pci_actual_io_offset + 0),                      (long long)(pd->pcibus->pci_actual_io_offset + 0),
722                      pd->pcibus->pci_irqbase + 0);                      pd->pcibus->irq_path_pci, irq & 255);
723                  device_add(machine, tmpstr);                  device_add(machine, tmpstr);
724          }          }
725  }  }
# Line 721  PCIINIT(i82378zb) Line 765  PCIINIT(i82378zb)
765          PCI_SET_DATA(0x60, 0x0f0e0b0a);          PCI_SET_DATA(0x60, 0x0f0e0b0a);
766  }  }
767    
768    struct piix_ide_extra {
769            void    *wdc0;
770            void    *wdc1;
771    };
772    
773    int piix_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
774    {
775            void *wdc0 = ((struct piix_ide_extra *)pd->extra)->wdc0;
776            void *wdc1 = ((struct piix_ide_extra *)pd->extra)->wdc1;
777            int enabled = 0;
778    
779            switch (reg) {
780            case PCI_COMMAND_STATUS_REG:
781                    if (value & PCI_COMMAND_IO_ENABLE)
782                            enabled = 1;
783                    if (wdc0 != NULL)
784                            wdc_set_io_enabled(wdc0, enabled);
785                    if (wdc1 != NULL)
786                            wdc_set_io_enabled(wdc1, enabled);
787                    return 1;
788            }
789    
790            return 0;
791    }
792    
793  PCIINIT(piix3_ide)  PCIINIT(piix3_ide)
794  {  {
795          char tmpstr[100];          char tmpstr[100];
# Line 736  PCIINIT(piix3_ide) Line 805  PCIINIT(piix3_ide)
805          /*  channel 0 and 1 enabled as IDE  */          /*  channel 0 and 1 enabled as IDE  */
806          PCI_SET_DATA(0x40, 0x80008000);          PCI_SET_DATA(0x40, 0x80008000);
807    
808            CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct piix_ide_extra)));
809            ((struct piix_ide_extra *)pd->extra)->wdc0 = NULL;
810            ((struct piix_ide_extra *)pd->extra)->wdc1 = NULL;
811    
812          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
813              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
814                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx "
815                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "irq=%s.isa.%i", (long long)(pd->pcibus->isa_portbase +
816                      pd->pcibus->isa_irqbase + 14);                      0x1f0), pd->pcibus->irq_path_isa, 14);
817                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc0 =
818                        device_add(machine, tmpstr);
819          }          }
820    
821          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
822              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
823                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx "
824                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "irq=%s.isa.%i", (long long)(pd->pcibus->isa_portbase +
825                      pd->pcibus->isa_irqbase + 15);                      0x170), pd->pcibus->irq_path_isa, 15);
826                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc1 =
827                        device_add(machine, tmpstr);
828          }          }
829    
830            pd->cfg_reg_write = piix_ide_cfg_reg_write;
831  }  }
832    
833  PCIINIT(piix4_ide)  PCIINIT(piix4_ide)
# Line 768  PCIINIT(piix4_ide) Line 845  PCIINIT(piix4_ide)
845          /*  channel 0 and 1 enabled as IDE  */          /*  channel 0 and 1 enabled as IDE  */
846          PCI_SET_DATA(0x40, 0x80008000);          PCI_SET_DATA(0x40, 0x80008000);
847    
848            CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct piix_ide_extra)));
849            ((struct piix_ide_extra *)pd->extra)->wdc0 = NULL;
850            ((struct piix_ide_extra *)pd->extra)->wdc1 = NULL;
851    
852          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
853              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
854                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
855                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
856                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
857                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc0 =
858                        device_add(machine, tmpstr);
859          }          }
860    
861          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
862              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, 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 + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
865                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
866                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc1 =
867                        device_add(machine, tmpstr);
868          }          }
869    
870            pd->cfg_reg_write = piix_ide_cfg_reg_write;
871  }  }
872    
873    
# Line 856  PCIINIT(vt82c586_isa) Line 941  PCIINIT(vt82c586_isa)
941              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
942  }  }
943    
944    struct vt82c586_ide_extra {
945            void    *wdc0;
946            void    *wdc1;
947    };
948    
949    int vt82c586_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
950    {
951            void *wdc0 = ((struct vt82c586_ide_extra *)pd->extra)->wdc0;
952            void *wdc1 = ((struct vt82c586_ide_extra *)pd->extra)->wdc1;
953            int enabled = 0;
954    
955            switch (reg) {
956            case PCI_COMMAND_STATUS_REG:
957                    if (value & PCI_COMMAND_IO_ENABLE)
958                            enabled = 1;
959                    if (wdc0 != NULL)
960                            wdc_set_io_enabled(wdc0, enabled);
961                    if (wdc1 != NULL)
962                            wdc_set_io_enabled(wdc1, enabled);
963                    return 1;
964            }
965    
966            return 0;
967    }
968    
969  PCIINIT(vt82c586_ide)  PCIINIT(vt82c586_ide)
970  {  {
971          char tmpstr[100];          char tmpstr[100];
# Line 871  PCIINIT(vt82c586_ide) Line 981  PCIINIT(vt82c586_ide)
981          /*  channel 0 and 1 enabled  */          /*  channel 0 and 1 enabled  */
982          PCI_SET_DATA(0x40, 0x00000003);          PCI_SET_DATA(0x40, 0x00000003);
983    
984            CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct vt82c586_ide_extra)));
985            ((struct vt82c586_ide_extra *)pd->extra)->wdc0 = NULL;
986            ((struct vt82c586_ide_extra *)pd->extra)->wdc1 = NULL;
987    
988          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
989              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
990                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
991                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
992                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
993                  device_add(machine, tmpstr);                  ((struct vt82c586_ide_extra *)pd->extra)->wdc0 =
994                        device_add(machine, tmpstr);
995          }          }
996    
997          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
998              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
999                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1000                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
1001                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
1002                  device_add(machine, tmpstr);                  ((struct vt82c586_ide_extra *)pd->extra)->wdc1 =
1003                        device_add(machine, tmpstr);
1004          }          }
1005    
1006            pd->cfg_reg_write = vt82c586_ide_cfg_reg_write;
1007  }  }
1008    
1009    
# Line 909  PCIINIT(symphony_83c553) Line 1027  PCIINIT(symphony_83c553)
1027    
1028          PCI_SET_DATA(PCI_BHLC_REG,          PCI_SET_DATA(PCI_BHLC_REG,
1029              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1030    
1031            switch (machine->machine_type) {
1032            case MACHINE_NETWINDER:
1033                    bus_isa_init(machine, pd->pcibus->irq_path_isa,
1034                        0, 0x7c000000, 0x80000000);
1035                    break;
1036            default:fatal("symphony_83c553 init: unimplemented machine type\n");
1037                    exit(1);
1038            }
1039    }
1040    
1041    struct symphony_82c105_extra {
1042            void    *wdc0;
1043            void    *wdc1;
1044    };
1045    
1046    int symphony_82c105_cfg_reg_write(struct pci_device *pd, int reg,
1047            uint32_t value)
1048    {
1049            void *wdc0 = ((struct symphony_82c105_extra *)pd->extra)->wdc0;
1050            void *wdc1 = ((struct symphony_82c105_extra *)pd->extra)->wdc1;
1051            int enabled = 0;
1052    
1053    printf("reg = 0x%x\n", reg);
1054            switch (reg) {
1055            case PCI_COMMAND_STATUS_REG:
1056                    if (value & PCI_COMMAND_IO_ENABLE)
1057                            enabled = 1;
1058    printf("  value = 0x%"PRIx32"\n", value);
1059                    if (wdc0 != NULL)
1060                            wdc_set_io_enabled(wdc0, enabled);
1061                    if (wdc1 != NULL)
1062                            wdc_set_io_enabled(wdc1, enabled);
1063                    /*  Set all bits:  */
1064                    PCI_SET_DATA(reg, value);
1065                    return 1;
1066            case PCI_MAPREG_START:
1067            case PCI_MAPREG_START + 4:
1068            case PCI_MAPREG_START + 8:
1069            case PCI_MAPREG_START + 12:
1070            case PCI_MAPREG_START + 16:
1071            case PCI_MAPREG_START + 20:
1072                    PCI_SET_DATA(reg, value);
1073                    return 1;
1074            }
1075    
1076            return 0;
1077  }  }
1078    
1079  PCIINIT(symphony_82c105)  PCIINIT(symphony_82c105)
# Line 922  PCIINIT(symphony_82c105) Line 1087  PCIINIT(symphony_82c105)
1087          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,
1088              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x05);              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x05);
1089    
1090            /*  TODO: Interrupt line:  */
1091            /*  PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000);  */
1092    
1093          /*  APO_IDECONF  */          /*  APO_IDECONF  */
1094          /*  channel 0 and 1 enabled  */          /*  channel 0 and 1 enabled  */
1095          PCI_SET_DATA(0x40, 0x00000003);          PCI_SET_DATA(0x40, 0x00000003);
1096    
1097            CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct symphony_82c105_extra)));
1098            ((struct symphony_82c105_extra *)pd->extra)->wdc0 = NULL;
1099            ((struct symphony_82c105_extra *)pd->extra)->wdc1 = NULL;
1100    
1101          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
1102              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
1103                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1104                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
1105                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
1106                  device_add(machine, tmpstr);                  ((struct symphony_82c105_extra *)pd->extra)->wdc0 =
1107                        device_add(machine, tmpstr);
1108          }          }
1109    
1110          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
1111              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
1112                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1113                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
1114                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
1115                  device_add(machine, tmpstr);                  ((struct symphony_82c105_extra *)pd->extra)->wdc1 =
1116                        device_add(machine, tmpstr);
1117            }
1118    
1119            pd->cfg_reg_write = symphony_82c105_cfg_reg_write;
1120    }
1121    
1122    
1123    
1124    /*
1125     *  Realtek 8139C+ PCI ethernet.
1126     */
1127    
1128    #define PCI_VENDOR_REALTEK              0x10ec
1129    #define PCI_PRODUCT_REALTEK_RT8139      0x8139
1130    
1131    PCIINIT(rtl8139c)
1132    {
1133            uint64_t port, memaddr;
1134            int pci_int_line = 0x101, irq = 0;
1135            char irqstr[200];
1136            char tmpstr[200];
1137    
1138            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_REALTEK,
1139                PCI_PRODUCT_REALTEK_RT8139));
1140    
1141            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_NETWORK,
1142                PCI_SUBCLASS_NETWORK_ETHERNET, 0x00) + 0x20);
1143    
1144            switch (machine->machine_type) {
1145            case MACHINE_LANDISK:
1146                    irq = 5;
1147                    pci_int_line = 0x105;
1148                    break;
1149            default:fatal("rtl8139c for this machine has not been "
1150                        "implemented yet\n");
1151                    exit(1);
1152          }          }
1153    
1154            PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000 | pci_int_line);
1155    
1156            allocate_device_space(pd, 0x100, 0, &port, &memaddr);
1157    
1158            snprintf(irqstr, sizeof(irqstr), "%s.%i",
1159                pd->pcibus->irq_path_pci, irq);
1160    
1161            snprintf(tmpstr, sizeof(tmpstr), "rtl8139c addr=0x%llx "
1162                "irq=%s pci_little_endian=1", (long long)port, irqstr);
1163    
1164            device_add(machine, tmpstr);
1165  }  }
1166    
1167    
# Line 955  PCIINIT(symphony_82c105) Line 1176  PCIINIT(symphony_82c105)
1176  PCIINIT(dec21143)  PCIINIT(dec21143)
1177  {  {
1178          uint64_t port, memaddr;          uint64_t port, memaddr;
1179          int irq = 0;            /*  TODO  */          int pci_int_line = 0x101, irq = 0, isa = 0;
1180          int pci_int_line = 0x101;          char irqstr[200];
1181          char tmpstr[200];          char tmpstr[200];
1182    
1183          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 980  PCIINIT(dec21143) Line 1201  PCIINIT(dec21143)
1201                  irq = 8 + 7;                  irq = 8 + 7;
1202                  pci_int_line = 0x407;                  pci_int_line = 0x407;
1203                  break;                  break;
         case MACHINE_ALGOR:  
                 /*  TODO  */  
                 irq = 8 + 7;  
                 pci_int_line = 0x407;  
                 break;  
1204          case MACHINE_PREP:          case MACHINE_PREP:
1205                  irq = 32 + 10;                  irq = 10;
1206                    isa = 1;
1207                  pci_int_line = 0x20a;                  pci_int_line = 0x20a;
1208                  break;                  break;
1209          case MACHINE_MVMEPPC:          case MACHINE_MVMEPPC:
1210                  /*  TODO  */                  /*  TODO  */
1211                  irq = 32 + 10;                  irq = 10;
1212                  pci_int_line = 0x40a;                  pci_int_line = 0x40a;
1213                  break;                  break;
1214          case MACHINE_PMPPC:          case MACHINE_PMPPC:
1215                  /*  TODO, not working yet  */                  /*  TODO, not working yet  */
1216                  irq = 31 - 21;                  irq = 31 - CPC_IB_EXT1;
1217                  pci_int_line = 0x201;                  pci_int_line = 0x101;
1218                  break;                  break;
1219          case MACHINE_MACPPC:          case MACHINE_MACPPC:
1220                  /*  TODO, not working yet  */                  /*  TODO, not working yet  */
# Line 1010  PCIINIT(dec21143) Line 1227  PCIINIT(dec21143)
1227    
1228          allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);          allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);
1229    
1230            if (isa)
1231                    snprintf(irqstr, sizeof(irqstr), "%s.isa.%i",
1232                        pd->pcibus->irq_path_isa, irq);
1233            else
1234                    snprintf(irqstr, sizeof(irqstr), "%s.%i",
1235                        pd->pcibus->irq_path_pci, irq);
1236    
1237          snprintf(tmpstr, sizeof(tmpstr), "dec21143 addr=0x%llx addr2=0x%llx "          snprintf(tmpstr, sizeof(tmpstr), "dec21143 addr=0x%llx addr2=0x%llx "
1238              "irq=%i pci_little_endian=1", (long long)port, (long long)memaddr,              "irq=%s pci_little_endian=1", (long long)port,
1239              irq);              (long long)memaddr, irqstr);
1240    
1241          device_add(machine, tmpstr);          device_add(machine, tmpstr);
1242  }  }
1243    

Legend:
Removed from v.24  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26