/[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 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 40 by dpavlin, Mon Oct 8 16:22:11 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.62 2006/02/18 21:03:12 debug Exp $   *  $Id: bus_pci.c,v 1.82 2007/04/21 02:36:23 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 57  Line 58 
58  #include "memory.h"  #include "memory.h"
59  #include "misc.h"  #include "misc.h"
60    
61    #include "wdc.h"
62    
63  extern int verbose;  extern int verbose;
64    
65    
66  /* #define debug fatal */  #ifdef UNSTABLE_DEVEL
67    #define debug fatal
68    #endif
69    
70    
71  /*  /*
# Line 145  void bus_pci_data_access(struct cpu *cpu Line 150  void bus_pci_data_access(struct cpu *cpu
150                          pci_data->last_was_write_ffffffff = 1;                          pci_data->last_was_write_ffffffff = 1;
151                          return;                          return;
152                  }                  }
153                  /*  Writes are not really supported yet:  */  
154                  if (idata != x) {                  if (dev->cfg_reg_write != NULL) {
155                            dev->cfg_reg_write(dev, pci_data->cur_reg, *data);
156                    } else {
157                            /*  Print a warning for unhandled writes:  */
158                          debug("[ bus_pci: write to PCI DATA: data = 0x%08llx"                          debug("[ bus_pci: write to PCI DATA: data = 0x%08llx"
159                              " differs from current value 0x%08llx; NOT YET"                              " (current value = 0x%08llx); NOT YET"
160                              " SUPPORTED. bus %i, device %i, function %i (%s)"                              " SUPPORTED. bus %i, device %i, function %i (%s)"
161                              " register 0x%02x ]\n", (long long)idata,                              " register 0x%02x ]\n", (long long)idata,
162                              (long long)x, pci_data->cur_bus,                              (long long)x, pci_data->cur_bus,
163                              pci_data->cur_device, pci_data->cur_func,                              pci_data->cur_device, pci_data->cur_func,
164                              dev->name, pci_data->cur_reg);                              dev->name, pci_data->cur_reg);
165    
166                            /*  Special warning, to detect if NetBSD's special
167                                detection of PCI devices fails:  */
168                            if (pci_data->cur_reg == PCI_COMMAND_STATUS_REG
169                                && !((*data) & PCI_COMMAND_IO_ENABLE)) {
170                                    fatal("\n[ NetBSD PCI detection stuff not"
171                                        " yet implemented for device '%s' ]\n",
172                                        dev->name);
173                            }
174                  }                  }
175                  return;                  return;
176          }          }
# Line 164  void bus_pci_data_access(struct cpu *cpu Line 181  void bus_pci_data_access(struct cpu *cpu
181          pci_data->last_was_write_ffffffff = 0;          pci_data->last_was_write_ffffffff = 0;
182    
183          debug("[ bus_pci: read from PCI DATA, bus %i, device "          debug("[ bus_pci: read from PCI DATA, bus %i, device "
184              "%i, function %i (%s) register 0x%02x: 0x%08lx ]\n", (long)              "%i, function %i (%s) register 0x%02x: (len=%i) 0x%08lx ]\n",
185              pci_data->cur_bus, pci_data->cur_device,              pci_data->cur_bus, pci_data->cur_device, pci_data->cur_func,
186              pci_data->cur_func, dev->name, pci_data->cur_reg, (long)*data);              dev->name, pci_data->cur_reg, len, (long)*data);
187  }  }
188    
189    
# Line 205  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 286  static void allocate_device_space(struct Line 303  static void allocate_device_space(struct
303                  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset,                  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset,
304                      port | PCI_MAPREG_TYPE_IO);                      port | PCI_MAPREG_TYPE_IO);
305                  PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,                  PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,
306                      portsize - 1);                      ((portsize - 1) & ~0xf) | 0xd);
307                  pd->cur_mapreg_offset += sizeof(uint32_t);                  pd->cur_mapreg_offset += sizeof(uint32_t);
308          }          }
309    
# Line 297  static void allocate_device_space(struct Line 314  static void allocate_device_space(struct
314                  pd->pcibus->cur_pci_membase = mem;                  pd->pcibus->cur_pci_membase = mem;
315                  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset, mem);                  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset, mem);
316                  PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,                  PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,
317                      memsize - 1);                      ((memsize - 1) & ~0xf) | 0x0);
318                  pd->cur_mapreg_offset += sizeof(uint32_t);                  pd->cur_mapreg_offset += sizeof(uint32_t);
319          }          }
320    
# Line 322  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 371  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 384  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;  
383    
384          /*  Register the bus:  */          d->cur_pci_portbase = d->pci_portbase;
385          machine_bus_register(machine, "pci", bus_pci_debug_dump, d);          d->cur_pci_membase  = d->pci_membase;
386    
387          /*  Assume that the first 64KB could be used by legacy ISA devices:  */          /*  Assume that the first 64KB could be used by legacy ISA devices:  */
388          d->cur_pci_portbase = d->pci_portbase + 0x10000;          if (d->isa_portbase != 0 || d->isa_membase != 0) {
389          d->cur_pci_membase  = d->pci_membase + 0x10000;                  d->cur_pci_portbase += 0x10000;
390                    d->cur_pci_membase  += 0x10000;
391            }
392    
393          return d;          return d;
394  }  }
# Line 418  struct pci_data *bus_pci_init(struct mac Line 407  struct pci_data *bus_pci_init(struct mac
407    
408    
409  /*  /*
410   *  Integraphics Systems "igsfb" Framebuffer (graphics) card.   *  Integraphics Systems "igsfb" Framebuffer (graphics) card, used in at
411   *   *  least the NetWinder.
  *  TODO  
412   */   */
413    
414  #define PCI_VENDOR_INTEGRAPHICS         0x10ea  #define PCI_VENDOR_INTEGRAPHICS         0x10ea
415    
416  PCIINIT(igsfb)  PCIINIT(igsfb)
417  {  {
418            char tmpstr[200];
419    
420          PCI_SET_DATA(PCI_ID_REG,          PCI_SET_DATA(PCI_ID_REG,
421              PCI_ID_CODE(PCI_VENDOR_INTEGRAPHICS, 0x2010));              PCI_ID_CODE(PCI_VENDOR_INTEGRAPHICS, 0x2010));
422    
# Line 437  PCIINIT(igsfb) Line 427  PCIINIT(igsfb)
427          /*  TODO  */          /*  TODO  */
428          PCI_SET_DATA(0x10, 0x08000000);          PCI_SET_DATA(0x10, 0x08000000);
429    
430          dev_vga_init(machine, mem, pd->pcibus->isa_membase + 0xa0000,          snprintf(tmpstr, sizeof(tmpstr), "igsfb addr=0x%llx",
431              0x88800000 + 0x3c0, machine->machine_name);              (long long)(pd->pcibus->isa_membase + 0x08000000));
432            device_add(machine, tmpstr);
433  }  }
434    
435    
# Line 491  PCIINIT(ali_m1543) Line 482  PCIINIT(ali_m1543)
482          /*  Linux uses these to detect which IRQ the IDE controller uses:  */          /*  Linux uses these to detect which IRQ the IDE controller uses:  */
483          PCI_SET_DATA(0x44, 0x0000000e);          PCI_SET_DATA(0x44, 0x0000000e);
484          PCI_SET_DATA(0x58, 0x00000003);          PCI_SET_DATA(0x58, 0x00000003);
485    
486            switch (machine->machine_type) {
487            case MACHINE_CATS:
488                    bus_isa_init(machine, pd->pcibus->irq_path_isa,
489                        BUS_ISA_PCKBC_FORCE_USE | BUS_ISA_PCKBC_NONPCSTYLE,
490                        0x7c000000, 0x80000000);
491                    break;
492            default:fatal("ali_m1543 init: unimplemented machine type\n");
493                    exit(1);
494            }
495  }  }
496    
497  PCIINIT(ali_m5229)  PCIINIT(ali_m5229)
498  {  {
499          char tmpstr[300];          char tmpstr[300], irqstr[300];
500    
501          PCI_SET_DATA(PCI_ID_REG,          PCI_SET_DATA(PCI_ID_REG,
502              PCI_ID_CODE(PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M5229));              PCI_ID_CODE(PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M5229));
# Line 503  PCIINIT(ali_m5229) Line 504  PCIINIT(ali_m5229)
504          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,
505              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x60) + 0xc1);              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x60) + 0xc1);
506    
507            switch (machine->machine_type) {
508            case MACHINE_CATS:
509                    /*  CATS ISA interrupts are at footbridge irq 10:  */
510                    snprintf(irqstr, sizeof(irqstr), "%s.10.isa",
511                        pd->pcibus->irq_path);
512                    break;
513            default:fatal("ali_m5229 init: unimplemented machine type\n");
514                    exit(1);
515            }
516    
517          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
518              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
519                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s.%i",
520                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      (long long)(pd->pcibus->isa_portbase + 0x1f0),
521                      pd->pcibus->isa_irqbase + 14);                      irqstr, 14);
522                  device_add(machine, tmpstr);                  device_add(machine, tmpstr);
523          }          }
524    
# Line 625  PCIINIT(gt64260) Line 636  PCIINIT(gt64260)
636    
637    
638  /*  /*
639     *  AMD PCnet Ethernet card.
640     *
641     *  "Am79c970A PCnet-PCI II rev 0" or similar.
642     */
643    
644    #define PCI_VENDOR_AMD                  0x1022  /* Advanced Micro Devices */
645    #define PCI_PRODUCT_AMD_PCNET_PCI       0x2000  /* PCnet-PCI Ethernet */
646    
647    PCIINIT(pcn)
648    {
649            int irq;
650    
651            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_AMD,
652                PCI_PRODUCT_AMD_PCNET_PCI));
653    
654            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_NETWORK,
655                PCI_SUBCLASS_NETWORK_ETHERNET, 0) + 0x00);  /*  Revision 0  */
656    
657            switch (machine->machine_type) {
658    
659            case MACHINE_EVBMIPS:
660                    irq = (1 << 8) + 10;    /*  TODO  */
661                    break;
662    
663            default:fatal("pcn in non-implemented machine type %i\n",
664                        machine->machine_type);
665                    exit(1);
666            }
667    
668            PCI_SET_DATA(PCI_INTERRUPT_REG, 0x01100000 | irq);
669    
670            /*
671             *  TODO: Add the pcn device here. The pcn device will need to work as
672             *  a wrapper for dev_le + all the DMA magic and whatever is required.
673             *  It's too much to implement right now.
674             */
675    }
676    
677    
678    
679    /*
680   *  Intel 31244   Serial ATA Controller   *  Intel 31244   Serial ATA Controller
681   *  Intel 82371SB PIIX3 PCI-ISA bridge   *  Intel 82371SB PIIX3 PCI-ISA bridge
682   *  Intel 82371AB PIIX4 PCI-ISA bridge   *  Intel 82371AB PIIX4 PCI-ISA bridge
# Line 644  PCIINIT(gt64260) Line 696  PCIINIT(gt64260)
696  PCIINIT(i31244)  PCIINIT(i31244)
697  {  {
698          uint64_t port, memaddr;          uint64_t port, memaddr;
699            int irq = 0;
700    
701          PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,          PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
702              PCI_PRODUCT_INTEL_31244));              PCI_PRODUCT_INTEL_31244));
# Line 653  PCIINIT(i31244) Line 706  PCIINIT(i31244)
706    
707          switch (machine->machine_type) {          switch (machine->machine_type) {
708          case MACHINE_IQ80321:          case MACHINE_IQ80321:
709                  /*  S-PCI-X slot uses PCI IRQ A  */                  /*  S-PCI-X slot uses PCI IRQ A, int 29  */
710                    irq = (1 << 8) + 29;
711                  break;                  break;
712          default:fatal("i31244 in non-implemented machine type %i\n",          default:fatal("i31244 in non-implemented machine type %i\n",
713                      machine->machine_type);                      machine->machine_type);
714                  exit(1);                  exit(1);
715          }          }
716    
717          PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140100);          PCI_SET_DATA(PCI_INTERRUPT_REG, 0x01100000 | irq);
718    
719          allocate_device_space(pd, 0x400, 0, &port, &memaddr);          allocate_device_space(pd, 0x1000, 0, &port, &memaddr);
720          allocate_device_space(pd, 0x400, 0, &port, &memaddr);          allocate_device_space(pd, 0x1000, 0, &port, &memaddr);
721    
722          /*  PCI IDE using dev_wdc:  */          /*  PCI IDE using dev_wdc:  */
723          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
724              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
725                  char tmpstr[150];                  char tmpstr[150];
726                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s.%i",
727                      (long long)(pd->pcibus->pci_actual_io_offset + 0),                      (long long)(pd->pcibus->pci_actual_io_offset + 0),
728                      pd->pcibus->pci_irqbase + 0);                      pd->pcibus->irq_path_pci, irq & 255);
729                  device_add(machine, tmpstr);                  device_add(machine, tmpstr);
730          }          }
731  }  }
# Line 717  PCIINIT(i82378zb) Line 771  PCIINIT(i82378zb)
771          PCI_SET_DATA(0x60, 0x0f0e0b0a);          PCI_SET_DATA(0x60, 0x0f0e0b0a);
772  }  }
773    
774    struct piix_ide_extra {
775            void    *wdc0;
776            void    *wdc1;
777    };
778    
779    int piix_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
780    {
781            void *wdc0 = ((struct piix_ide_extra *)pd->extra)->wdc0;
782            void *wdc1 = ((struct piix_ide_extra *)pd->extra)->wdc1;
783            int enabled = 0;
784    
785            switch (reg) {
786            case PCI_COMMAND_STATUS_REG:
787                    if (value & PCI_COMMAND_IO_ENABLE)
788                            enabled = 1;
789                    if (wdc0 != NULL)
790                            wdc_set_io_enabled(wdc0, enabled);
791                    if (wdc1 != NULL)
792                            wdc_set_io_enabled(wdc1, enabled);
793                    return 1;
794            }
795    
796            return 0;
797    }
798    
799  PCIINIT(piix3_ide)  PCIINIT(piix3_ide)
800  {  {
801          char tmpstr[100];          char tmpstr[100];
# Line 732  PCIINIT(piix3_ide) Line 811  PCIINIT(piix3_ide)
811          /*  channel 0 and 1 enabled as IDE  */          /*  channel 0 and 1 enabled as IDE  */
812          PCI_SET_DATA(0x40, 0x80008000);          PCI_SET_DATA(0x40, 0x80008000);
813    
814            pd->extra = malloc(sizeof(struct piix_ide_extra));
815            if (pd->extra == NULL) {
816                    fatal("Out of memory.\n");
817                    exit(1);
818            }
819            ((struct piix_ide_extra *)pd->extra)->wdc0 = NULL;
820            ((struct piix_ide_extra *)pd->extra)->wdc1 = NULL;
821    
822          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
823              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
824                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx "
825                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "irq=%s.isa.%i", (long long)(pd->pcibus->isa_portbase +
826                      pd->pcibus->isa_irqbase + 14);                      0x1f0), pd->pcibus->irq_path_isa, 14);
827                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc0 =
828                        device_add(machine, tmpstr);
829          }          }
830    
831          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
832              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
833                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx "
834                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "irq=%s.isa.%i", (long long)(pd->pcibus->isa_portbase +
835                      pd->pcibus->isa_irqbase + 15);                      0x170), pd->pcibus->irq_path_isa, 15);
836                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc1 =
837                        device_add(machine, tmpstr);
838          }          }
839    
840            pd->cfg_reg_write = piix_ide_cfg_reg_write;
841  }  }
842    
843  PCIINIT(piix4_ide)  PCIINIT(piix4_ide)
# Line 764  PCIINIT(piix4_ide) Line 855  PCIINIT(piix4_ide)
855          /*  channel 0 and 1 enabled as IDE  */          /*  channel 0 and 1 enabled as IDE  */
856          PCI_SET_DATA(0x40, 0x80008000);          PCI_SET_DATA(0x40, 0x80008000);
857    
858            pd->extra = malloc(sizeof(struct piix_ide_extra));
859            if (pd->extra == NULL) {
860                    fatal("Out of memory.\n");
861                    exit(1);
862            }
863            ((struct piix_ide_extra *)pd->extra)->wdc0 = NULL;
864            ((struct piix_ide_extra *)pd->extra)->wdc1 = NULL;
865    
866          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
867              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
868                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
869                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
870                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
871                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc0 =
872                        device_add(machine, tmpstr);
873          }          }
874    
875          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
876              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
877                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
878                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
879                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
880                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc1 =
881                        device_add(machine, tmpstr);
882          }          }
883    
884            pd->cfg_reg_write = piix_ide_cfg_reg_write;
885  }  }
886    
887    
# Line 852  PCIINIT(vt82c586_isa) Line 955  PCIINIT(vt82c586_isa)
955              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
956  }  }
957    
958    struct vt82c586_ide_extra {
959            void    *wdc0;
960            void    *wdc1;
961    };
962    
963    int vt82c586_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
964    {
965            void *wdc0 = ((struct vt82c586_ide_extra *)pd->extra)->wdc0;
966            void *wdc1 = ((struct vt82c586_ide_extra *)pd->extra)->wdc1;
967            int enabled = 0;
968    
969            switch (reg) {
970            case PCI_COMMAND_STATUS_REG:
971                    if (value & PCI_COMMAND_IO_ENABLE)
972                            enabled = 1;
973                    if (wdc0 != NULL)
974                            wdc_set_io_enabled(wdc0, enabled);
975                    if (wdc1 != NULL)
976                            wdc_set_io_enabled(wdc1, enabled);
977                    return 1;
978            }
979    
980            return 0;
981    }
982    
983  PCIINIT(vt82c586_ide)  PCIINIT(vt82c586_ide)
984  {  {
985          char tmpstr[100];          char tmpstr[100];
# Line 867  PCIINIT(vt82c586_ide) Line 995  PCIINIT(vt82c586_ide)
995          /*  channel 0 and 1 enabled  */          /*  channel 0 and 1 enabled  */
996          PCI_SET_DATA(0x40, 0x00000003);          PCI_SET_DATA(0x40, 0x00000003);
997    
998            pd->extra = malloc(sizeof(struct vt82c586_ide_extra));
999            if (pd->extra == NULL) {
1000                    fatal("Out of memory.\n");
1001                    exit(1);
1002            }
1003            ((struct vt82c586_ide_extra *)pd->extra)->wdc0 = NULL;
1004            ((struct vt82c586_ide_extra *)pd->extra)->wdc1 = NULL;
1005    
1006          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
1007              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
1008                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1009                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
1010                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
1011                  device_add(machine, tmpstr);                  ((struct vt82c586_ide_extra *)pd->extra)->wdc0 =
1012                        device_add(machine, tmpstr);
1013          }          }
1014    
1015          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
1016              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
1017                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1018                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
1019                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
1020                  device_add(machine, tmpstr);                  ((struct vt82c586_ide_extra *)pd->extra)->wdc1 =
1021                        device_add(machine, tmpstr);
1022          }          }
1023    
1024            pd->cfg_reg_write = vt82c586_ide_cfg_reg_write;
1025  }  }
1026    
1027    
# Line 905  PCIINIT(symphony_83c553) Line 1045  PCIINIT(symphony_83c553)
1045    
1046          PCI_SET_DATA(PCI_BHLC_REG,          PCI_SET_DATA(PCI_BHLC_REG,
1047              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1048    
1049            switch (machine->machine_type) {
1050            case MACHINE_NETWINDER:
1051                    bus_isa_init(machine, pd->pcibus->irq_path_isa,
1052                        0, 0x7c000000, 0x80000000);
1053                    break;
1054            default:fatal("symphony_83c553 init: unimplemented machine type\n");
1055                    exit(1);
1056            }
1057    }
1058    
1059    struct symphony_82c105_extra {
1060            void    *wdc0;
1061            void    *wdc1;
1062    };
1063    
1064    int symphony_82c105_cfg_reg_write(struct pci_device *pd, int reg,
1065            uint32_t value)
1066    {
1067            void *wdc0 = ((struct symphony_82c105_extra *)pd->extra)->wdc0;
1068            void *wdc1 = ((struct symphony_82c105_extra *)pd->extra)->wdc1;
1069            int enabled = 0;
1070    
1071    printf("reg = 0x%x\n", reg);
1072            switch (reg) {
1073            case PCI_COMMAND_STATUS_REG:
1074                    if (value & PCI_COMMAND_IO_ENABLE)
1075                            enabled = 1;
1076    printf("  value = 0x%"PRIx32"\n", value);
1077                    if (wdc0 != NULL)
1078                            wdc_set_io_enabled(wdc0, enabled);
1079                    if (wdc1 != NULL)
1080                            wdc_set_io_enabled(wdc1, enabled);
1081                    /*  Set all bits:  */
1082                    PCI_SET_DATA(reg, value);
1083                    return 1;
1084            case PCI_MAPREG_START:
1085            case PCI_MAPREG_START + 4:
1086            case PCI_MAPREG_START + 8:
1087            case PCI_MAPREG_START + 12:
1088            case PCI_MAPREG_START + 16:
1089            case PCI_MAPREG_START + 20:
1090                    PCI_SET_DATA(reg, value);
1091                    return 1;
1092            }
1093    
1094            return 0;
1095  }  }
1096    
1097  PCIINIT(symphony_82c105)  PCIINIT(symphony_82c105)
# Line 918  PCIINIT(symphony_82c105) Line 1105  PCIINIT(symphony_82c105)
1105          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,
1106              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x05);              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x05);
1107    
1108            /*  TODO: Interrupt line:  */
1109            /*  PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000);  */
1110    
1111          /*  APO_IDECONF  */          /*  APO_IDECONF  */
1112          /*  channel 0 and 1 enabled  */          /*  channel 0 and 1 enabled  */
1113          PCI_SET_DATA(0x40, 0x00000003);          PCI_SET_DATA(0x40, 0x00000003);
1114    
1115            pd->extra = malloc(sizeof(struct symphony_82c105_extra));
1116            if (pd->extra == NULL) {
1117                    fatal("Out of memory.\n");
1118                    exit(1);
1119            }
1120            ((struct symphony_82c105_extra *)pd->extra)->wdc0 = NULL;
1121            ((struct symphony_82c105_extra *)pd->extra)->wdc1 = NULL;
1122    
1123          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
1124              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
1125                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1126                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
1127                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
1128                  device_add(machine, tmpstr);                  ((struct symphony_82c105_extra *)pd->extra)->wdc0 =
1129                        device_add(machine, tmpstr);
1130          }          }
1131    
1132          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
1133              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
1134                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1135                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
1136                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
1137                  device_add(machine, tmpstr);                  ((struct symphony_82c105_extra *)pd->extra)->wdc1 =
1138                        device_add(machine, tmpstr);
1139            }
1140    
1141            pd->cfg_reg_write = symphony_82c105_cfg_reg_write;
1142    }
1143    
1144    
1145    
1146    /*
1147     *  Realtek 8139C+ PCI ethernet.
1148     */
1149    
1150    #define PCI_VENDOR_REALTEK              0x10ec
1151    #define PCI_PRODUCT_REALTEK_RT8139      0x8139
1152    
1153    PCIINIT(rtl8139c)
1154    {
1155            uint64_t port, memaddr;
1156            int pci_int_line = 0x101, irq = 0;
1157            char irqstr[200];
1158            char tmpstr[200];
1159    
1160            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_REALTEK,
1161                PCI_PRODUCT_REALTEK_RT8139));
1162    
1163            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_NETWORK,
1164                PCI_SUBCLASS_NETWORK_ETHERNET, 0x00) + 0x20);
1165    
1166            switch (machine->machine_type) {
1167            case MACHINE_LANDISK:
1168                    irq = 5;
1169                    pci_int_line = 0x105;
1170                    break;
1171            default:fatal("rtl8139c for this machine has not been "
1172                        "implemented yet\n");
1173                    exit(1);
1174          }          }
1175    
1176            PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000 | pci_int_line);
1177    
1178            allocate_device_space(pd, 0x100, 0, &port, &memaddr);
1179    
1180            snprintf(irqstr, sizeof(irqstr), "%s.%i",
1181                pd->pcibus->irq_path_pci, irq);
1182    
1183            snprintf(tmpstr, sizeof(tmpstr), "rtl8139c addr=0x%llx "
1184                "irq=%s pci_little_endian=1", (long long)port, irqstr);
1185    
1186            device_add(machine, tmpstr);
1187  }  }
1188    
1189    
# Line 951  PCIINIT(symphony_82c105) Line 1198  PCIINIT(symphony_82c105)
1198  PCIINIT(dec21143)  PCIINIT(dec21143)
1199  {  {
1200          uint64_t port, memaddr;          uint64_t port, memaddr;
1201          int irq = 0;            /*  TODO  */          int pci_int_line = 0x101, irq = 0, isa = 0;
1202          int pci_int_line = 0x101;          char irqstr[200];
1203          char tmpstr[200];          char tmpstr[200];
1204    
1205          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 976  PCIINIT(dec21143) Line 1223  PCIINIT(dec21143)
1223                  irq = 8 + 7;                  irq = 8 + 7;
1224                  pci_int_line = 0x407;                  pci_int_line = 0x407;
1225                  break;                  break;
         case MACHINE_ALGOR:  
                 /*  TODO  */  
                 irq = 8 + 7;  
                 pci_int_line = 0x407;  
                 break;  
1226          case MACHINE_PREP:          case MACHINE_PREP:
1227                  irq = 32 + 10;                  irq = 10;
1228                    isa = 1;
1229                  pci_int_line = 0x20a;                  pci_int_line = 0x20a;
1230                  break;                  break;
1231          case MACHINE_MVMEPPC:          case MACHINE_MVMEPPC:
1232                  /*  TODO  */                  /*  TODO  */
1233                  irq = 32 + 10;                  irq = 10;
1234                  pci_int_line = 0x40a;                  pci_int_line = 0x40a;
1235                  break;                  break;
1236          case MACHINE_PMPPC:          case MACHINE_PMPPC:
# Line 1006  PCIINIT(dec21143) Line 1249  PCIINIT(dec21143)
1249    
1250          allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);          allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);
1251    
1252            if (isa)
1253                    snprintf(irqstr, sizeof(irqstr), "%s.isa.%i",
1254                        pd->pcibus->irq_path_isa, irq);
1255            else
1256                    snprintf(irqstr, sizeof(irqstr), "%s.%i",
1257                        pd->pcibus->irq_path_pci, irq);
1258    
1259          snprintf(tmpstr, sizeof(tmpstr), "dec21143 addr=0x%llx addr2=0x%llx "          snprintf(tmpstr, sizeof(tmpstr), "dec21143 addr=0x%llx addr2=0x%llx "
1260              "irq=%i pci_little_endian=1", (long long)port, (long long)memaddr,              "irq=%s pci_little_endian=1", (long long)port,
1261              irq);              (long long)memaddr, irqstr);
1262    
1263          device_add(machine, tmpstr);          device_add(machine, tmpstr);
1264  }  }
1265    

Legend:
Removed from v.22  
changed lines
  Added in v.40

  ViewVC Help
Powered by ViewVC 1.1.26