/[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 62 by dpavlin, Sat Oct 13 12:51:47 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.85 2007/06/16 14:39:18 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    
69  /* #define debug fatal */  #ifdef UNSTABLE_DEVEL
70    #define debug fatal
71    #endif
72    
73    
74  /*  /*
# Line 145  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 164  void bus_pci_data_access(struct cpu *cpu Line 184  void bus_pci_data_access(struct cpu *cpu
184          pci_data->last_was_write_ffffffff = 0;          pci_data->last_was_write_ffffffff = 0;
185    
186          debug("[ bus_pci: read from PCI DATA, bus %i, device "          debug("[ bus_pci: read from PCI DATA, bus %i, device "
187              "%i, function %i (%s) register 0x%02x: 0x%08lx ]\n", (long)              "%i, function %i (%s) register 0x%02x: (len=%i) 0x%08lx ]\n",
188              pci_data->cur_bus, pci_data->cur_device,              pci_data->cur_bus, pci_data->cur_device, pci_data->cur_func,
189              pci_data->cur_func, dev->name, pci_data->cur_reg, (long)*data);              dev->name, pci_data->cur_reg, len, (long)*data);
190  }  }
191    
192    
# Line 187  void bus_pci_setaddr(struct cpu *cpu, st Line 207  void bus_pci_setaddr(struct cpu *cpu, st
207          pci_data->cur_device = device;          pci_data->cur_device = device;
208          pci_data->cur_func = function;          pci_data->cur_func = function;
209          pci_data->cur_reg = reg;          pci_data->cur_reg = reg;
210            debug("bus_pci_setaddr( bus %d device 0x%x func 0x%x reg 0x%x )\n", bus, device, function, reg );
211  }  }
212    
213    
# Line 205  void bus_pci_add(struct machine *machine Line 226  void bus_pci_add(struct machine *machine
226    
227          if (pci_data == NULL) {          if (pci_data == NULL) {
228                  fatal("bus_pci_add(): pci_data == NULL!\n");                  fatal("bus_pci_add(): pci_data == NULL!\n");
229                  exit(1);                  abort();
230          }          }
231    
232          /*  Find the PCI device:  */          /*  Find the PCI device:  */
# Line 223  void bus_pci_add(struct machine *machine Line 244  void bus_pci_add(struct machine *machine
244                  pd = pd->next;                  pd = pd->next;
245          }          }
246    
247          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);  
         }  
   
248          memset(pd, 0, sizeof(struct pci_device));          memset(pd, 0, sizeof(struct pci_device));
249    
250          /*  Add the new device first in the PCI bus' chain:  */          /*  Add the new device first in the PCI bus' chain:  */
251          pd->next = pci_data->first_device;          pd->next = pci_data->first_device;
252          pci_data->first_device = pd;          pci_data->first_device = pd;
253    
254            CHECK_ALLOCATION(pd->name = strdup(name));
255          pd->pcibus   = pci_data;          pd->pcibus   = pci_data;
         pd->name     = strdup(name);  
256          pd->bus      = bus;          pd->bus      = bus;
257          pd->device   = device;          pd->device   = device;
258          pd->function = function;          pd->function = function;
# Line 286  static void allocate_device_space(struct Line 302  static void allocate_device_space(struct
302                  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset,                  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset,
303                      port | PCI_MAPREG_TYPE_IO);                      port | PCI_MAPREG_TYPE_IO);
304                  PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,                  PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,
305                      portsize - 1);                      ((portsize - 1) & ~0xf) | 0xd);
306                  pd->cur_mapreg_offset += sizeof(uint32_t);                  pd->cur_mapreg_offset += sizeof(uint32_t);
307          }          }
308    
# Line 297  static void allocate_device_space(struct Line 313  static void allocate_device_space(struct
313                  pd->pcibus->cur_pci_membase = mem;                  pd->pcibus->cur_pci_membase = mem;
314                  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset, mem);                  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset, mem);
315                  PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,                  PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,
316                      memsize - 1);                      ((memsize - 1) & ~0xf) | 0x0);
317                  pd->cur_mapreg_offset += sizeof(uint32_t);                  pd->cur_mapreg_offset += sizeof(uint32_t);
318          }          }
319    
# Line 322  static void allocate_device_space(struct Line 338  static void allocate_device_space(struct
338  }  }
339    
340    
 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);  
 }  
   
   
341  /*  /*
342   *  bus_pci_init():   *  bus_pci_init():
343   *   *
344   *  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
345   *  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.
346   *   *
347   *  irq_nr is the (optional) IRQ nr that this PCI bus interrupts at.   *  irq_path is the interrupt path to the PCI controller.
348   *   *
349   *  pci_portbase, pci_membase, and pci_irqbase are the port, memory, and   *  pci_portbase, pci_membase, and pci_irqbase are the port, memory, and
350   *  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 355  void bus_pci_debug_dump(void *extra)
355   *  isa_portbase, isa_membase, and isa_irqbase are the port, memory, and   *  isa_portbase, isa_membase, and isa_irqbase are the port, memory, and
356   *  interrupt bases for legacy ISA devices.   *  interrupt bases for legacy ISA devices.
357   */   */
358  struct pci_data *bus_pci_init(struct machine *machine, int irq_nr,  struct pci_data *bus_pci_init(struct machine *machine, char *irq_path,
359          uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset,          uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset,
360          uint64_t pci_portbase, uint64_t pci_membase, int pci_irqbase,          uint64_t pci_portbase, uint64_t pci_membase, char *pci_irqbase,
361          uint64_t isa_portbase, uint64_t isa_membase, int isa_irqbase)          uint64_t isa_portbase, uint64_t isa_membase, char *isa_irqbase)
362  {  {
363          struct pci_data *d;          struct pci_data *d;
364    
365          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);  
         }  
366          memset(d, 0, sizeof(struct pci_data));          memset(d, 0, sizeof(struct pci_data));
367          d->irq_nr                = irq_nr;  
368            CHECK_ALLOCATION(d->irq_path     = strdup(irq_path));
369            CHECK_ALLOCATION(d->irq_path_isa = strdup(isa_irqbase));
370            CHECK_ALLOCATION(d->irq_path_pci = strdup(pci_irqbase));
371    
372          d->pci_actual_io_offset  = pci_actual_io_offset;          d->pci_actual_io_offset  = pci_actual_io_offset;
373          d->pci_actual_mem_offset = pci_actual_mem_offset;          d->pci_actual_mem_offset = pci_actual_mem_offset;
374          d->pci_portbase          = pci_portbase;          d->pci_portbase          = pci_portbase;
375          d->pci_membase           = pci_membase;          d->pci_membase           = pci_membase;
         d->pci_irqbase           = pci_irqbase;  
376          d->isa_portbase          = isa_portbase;          d->isa_portbase          = isa_portbase;
377          d->isa_membase           = isa_membase;          d->isa_membase           = isa_membase;
         d->isa_irqbase           = isa_irqbase;  
378    
379          /*  Register the bus:  */          d->cur_pci_portbase = d->pci_portbase;
380          machine_bus_register(machine, "pci", bus_pci_debug_dump, d);          d->cur_pci_membase  = d->pci_membase;
381    
382          /*  Assume that the first 64KB could be used by legacy ISA devices:  */          /*  Assume that the first 64KB could be used by legacy ISA devices:  */
383          d->cur_pci_portbase = d->pci_portbase + 0x10000;          if (d->isa_portbase != 0 || d->isa_membase != 0) {
384          d->cur_pci_membase  = d->pci_membase + 0x10000;                  d->cur_pci_portbase += 0x10000;
385                    d->cur_pci_membase  += 0x10000;
386            }
387    
388            debug("bus_pci_init( pci_actual_io_offset %x pci_actual_mem_offset 0x%x pci_portbase 0x%x pci_membase 0x%x isa_portbase %x isa_membase %x )\n", pci_actual_io_offset, pci_actual_mem_offset, pci_portbase, pci_membase, isa_portbase, isa_membase );
389    
390          return d;          return d;
391  }  }
# Line 418  struct pci_data *bus_pci_init(struct mac Line 404  struct pci_data *bus_pci_init(struct mac
404    
405    
406  /*  /*
407   *  Integraphics Systems "igsfb" Framebuffer (graphics) card.   *  Integraphics Systems "igsfb" Framebuffer (graphics) card, used in at
408   *   *  least the NetWinder.
  *  TODO  
409   */   */
410    
411  #define PCI_VENDOR_INTEGRAPHICS         0x10ea  #define PCI_VENDOR_INTEGRAPHICS         0x10ea
412    
413  PCIINIT(igsfb)  PCIINIT(igsfb)
414  {  {
415            char tmpstr[200];
416    
417          PCI_SET_DATA(PCI_ID_REG,          PCI_SET_DATA(PCI_ID_REG,
418              PCI_ID_CODE(PCI_VENDOR_INTEGRAPHICS, 0x2010));              PCI_ID_CODE(PCI_VENDOR_INTEGRAPHICS, 0x2010));
419    
# Line 437  PCIINIT(igsfb) Line 424  PCIINIT(igsfb)
424          /*  TODO  */          /*  TODO  */
425          PCI_SET_DATA(0x10, 0x08000000);          PCI_SET_DATA(0x10, 0x08000000);
426    
427          dev_vga_init(machine, mem, pd->pcibus->isa_membase + 0xa0000,          snprintf(tmpstr, sizeof(tmpstr), "igsfb addr=0x%llx",
428              0x88800000 + 0x3c0, machine->machine_name);              (long long)(pd->pcibus->isa_membase + 0x08000000));
429            device_add(machine, tmpstr);
430  }  }
431    
432    
# Line 491  PCIINIT(ali_m1543) Line 479  PCIINIT(ali_m1543)
479          /*  Linux uses these to detect which IRQ the IDE controller uses:  */          /*  Linux uses these to detect which IRQ the IDE controller uses:  */
480          PCI_SET_DATA(0x44, 0x0000000e);          PCI_SET_DATA(0x44, 0x0000000e);
481          PCI_SET_DATA(0x58, 0x00000003);          PCI_SET_DATA(0x58, 0x00000003);
482    
483            switch (machine->machine_type) {
484            case MACHINE_CATS:
485                    bus_isa_init(machine, pd->pcibus->irq_path_isa,
486                        BUS_ISA_PCKBC_FORCE_USE | BUS_ISA_PCKBC_NONPCSTYLE,
487                        0x7c000000, 0x80000000);
488                    break;
489            default:fatal("ali_m1543 init: unimplemented machine type\n");
490                    exit(1);
491            }
492  }  }
493    
494  PCIINIT(ali_m5229)  PCIINIT(ali_m5229)
495  {  {
496          char tmpstr[300];          char tmpstr[300], irqstr[300];
497    
498          PCI_SET_DATA(PCI_ID_REG,          PCI_SET_DATA(PCI_ID_REG,
499              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 501  PCIINIT(ali_m5229)
501          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,
502              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x60) + 0xc1);              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x60) + 0xc1);
503    
504            switch (machine->machine_type) {
505            case MACHINE_CATS:
506                    /*  CATS ISA interrupts are at footbridge irq 10:  */
507                    snprintf(irqstr, sizeof(irqstr), "%s.10.isa",
508                        pd->pcibus->irq_path);
509                    break;
510            default:fatal("ali_m5229 init: unimplemented machine type\n");
511                    exit(1);
512            }
513    
514          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
515              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
516                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s.%i",
517                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      (long long)(pd->pcibus->isa_portbase + 0x1f0),
518                      pd->pcibus->isa_irqbase + 14);                      irqstr, 14);
519                  device_add(machine, tmpstr);                  device_add(machine, tmpstr);
520          }          }
521    
# Line 625  PCIINIT(gt64260) Line 633  PCIINIT(gt64260)
633    
634    
635  /*  /*
636     *  AMD PCnet Ethernet card.
637     *
638     *  "Am79c970A PCnet-PCI II rev 0" or similar.
639     */
640    
641    #define PCI_VENDOR_AMD                  0x1022  /* Advanced Micro Devices */
642    #define PCI_PRODUCT_AMD_PCNET_PCI       0x2000  /* PCnet-PCI Ethernet */
643    
644    PCIINIT(pcn)
645    {
646            int irq;
647    
648            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_AMD,
649                PCI_PRODUCT_AMD_PCNET_PCI));
650    
651            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_NETWORK,
652                PCI_SUBCLASS_NETWORK_ETHERNET, 0) + 0x00);  /*  Revision 0  */
653    
654            switch (machine->machine_type) {
655    
656            case MACHINE_EVBMIPS:
657                    irq = (1 << 8) + 10;    /*  TODO  */
658                    break;
659    
660            default:fatal("pcn in non-implemented machine type %i\n",
661                        machine->machine_type);
662                    exit(1);
663            }
664    
665            PCI_SET_DATA(PCI_INTERRUPT_REG, 0x01100000 | irq);
666    
667            /*
668             *  TODO: Add the pcn device here. The pcn device will need to work as
669             *  a wrapper for dev_le + all the DMA magic and whatever is required.
670             *  It's too much to implement right now.
671             */
672    }
673    
674    
675    
676    /*
677   *  Intel 31244   Serial ATA Controller   *  Intel 31244   Serial ATA Controller
678   *  Intel 82371SB PIIX3 PCI-ISA bridge   *  Intel 82371SB PIIX3 PCI-ISA bridge
679   *  Intel 82371AB PIIX4 PCI-ISA bridge   *  Intel 82371AB PIIX4 PCI-ISA bridge
# Line 644  PCIINIT(gt64260) Line 693  PCIINIT(gt64260)
693  PCIINIT(i31244)  PCIINIT(i31244)
694  {  {
695          uint64_t port, memaddr;          uint64_t port, memaddr;
696            int irq = 0;
697    
698          PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,          PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
699              PCI_PRODUCT_INTEL_31244));              PCI_PRODUCT_INTEL_31244));
# Line 653  PCIINIT(i31244) Line 703  PCIINIT(i31244)
703    
704          switch (machine->machine_type) {          switch (machine->machine_type) {
705          case MACHINE_IQ80321:          case MACHINE_IQ80321:
706                  /*  S-PCI-X slot uses PCI IRQ A  */                  /*  S-PCI-X slot uses PCI IRQ A, int 29  */
707                    irq = (1 << 8) + 29;
708                  break;                  break;
709          default:fatal("i31244 in non-implemented machine type %i\n",          default:fatal("i31244 in non-implemented machine type %i\n",
710                      machine->machine_type);                      machine->machine_type);
711                  exit(1);                  exit(1);
712          }          }
713    
714          PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140100);          PCI_SET_DATA(PCI_INTERRUPT_REG, 0x01100000 | irq);
715    
716          allocate_device_space(pd, 0x400, 0, &port, &memaddr);          allocate_device_space(pd, 0x1000, 0, &port, &memaddr);
717          allocate_device_space(pd, 0x400, 0, &port, &memaddr);          allocate_device_space(pd, 0x1000, 0, &port, &memaddr);
718    
719          /*  PCI IDE using dev_wdc:  */          /*  PCI IDE using dev_wdc:  */
720          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
721              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
722                  char tmpstr[150];                  char tmpstr[150];
723                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s.%i",
724                      (long long)(pd->pcibus->pci_actual_io_offset + 0),                      (long long)(pd->pcibus->pci_actual_io_offset + 0),
725                      pd->pcibus->pci_irqbase + 0);                      pd->pcibus->irq_path_pci, irq & 255);
726                  device_add(machine, tmpstr);                  device_add(machine, tmpstr);
727          }          }
728  }  }
# Line 717  PCIINIT(i82378zb) Line 768  PCIINIT(i82378zb)
768          PCI_SET_DATA(0x60, 0x0f0e0b0a);          PCI_SET_DATA(0x60, 0x0f0e0b0a);
769  }  }
770    
771    struct piix_ide_extra {
772            void    *wdc0;
773            void    *wdc1;
774    };
775    
776    int piix_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
777    {
778            void *wdc0 = ((struct piix_ide_extra *)pd->extra)->wdc0;
779            void *wdc1 = ((struct piix_ide_extra *)pd->extra)->wdc1;
780            int enabled = 0;
781    
782            switch (reg) {
783            case PCI_COMMAND_STATUS_REG:
784                    if (value & PCI_COMMAND_IO_ENABLE)
785                            enabled = 1;
786                    if (wdc0 != NULL)
787                            wdc_set_io_enabled(wdc0, enabled);
788                    if (wdc1 != NULL)
789                            wdc_set_io_enabled(wdc1, enabled);
790                    return 1;
791            }
792    
793            return 0;
794    }
795    
796  PCIINIT(piix3_ide)  PCIINIT(piix3_ide)
797  {  {
798          char tmpstr[100];          char tmpstr[100];
# Line 732  PCIINIT(piix3_ide) Line 808  PCIINIT(piix3_ide)
808          /*  channel 0 and 1 enabled as IDE  */          /*  channel 0 and 1 enabled as IDE  */
809          PCI_SET_DATA(0x40, 0x80008000);          PCI_SET_DATA(0x40, 0x80008000);
810    
811            CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct piix_ide_extra)));
812            ((struct piix_ide_extra *)pd->extra)->wdc0 = NULL;
813            ((struct piix_ide_extra *)pd->extra)->wdc1 = NULL;
814    
815          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
816              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
817                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx "
818                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "irq=%s.isa.%i", (long long)(pd->pcibus->isa_portbase +
819                      pd->pcibus->isa_irqbase + 14);                      0x1f0), pd->pcibus->irq_path_isa, 14);
820                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc0 =
821                        device_add(machine, tmpstr);
822          }          }
823    
824          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
825              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
826                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx "
827                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "irq=%s.isa.%i", (long long)(pd->pcibus->isa_portbase +
828                      pd->pcibus->isa_irqbase + 15);                      0x170), pd->pcibus->irq_path_isa, 15);
829                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc1 =
830                        device_add(machine, tmpstr);
831          }          }
832    
833            pd->cfg_reg_write = piix_ide_cfg_reg_write;
834  }  }
835    
836  PCIINIT(piix4_ide)  PCIINIT(piix4_ide)
# Line 764  PCIINIT(piix4_ide) Line 848  PCIINIT(piix4_ide)
848          /*  channel 0 and 1 enabled as IDE  */          /*  channel 0 and 1 enabled as IDE  */
849          PCI_SET_DATA(0x40, 0x80008000);          PCI_SET_DATA(0x40, 0x80008000);
850    
851            CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct piix_ide_extra)));
852            ((struct piix_ide_extra *)pd->extra)->wdc0 = NULL;
853            ((struct piix_ide_extra *)pd->extra)->wdc1 = NULL;
854    
855          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
856              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
857                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
858                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
859                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
860                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc0 =
861                        device_add(machine, tmpstr);
862          }          }
863    
864          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
865              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
866                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
867                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
868                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
869                  device_add(machine, tmpstr);                  ((struct piix_ide_extra *)pd->extra)->wdc1 =
870                        device_add(machine, tmpstr);
871          }          }
872    
873            pd->cfg_reg_write = piix_ide_cfg_reg_write;
874  }  }
875    
876    
# Line 823  PCIINIT(heuricon_pmppc) Line 915  PCIINIT(heuricon_pmppc)
915              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
916  }  }
917    
918    /*
919     * Sandpoint host bridge based on uninorth
920     */
921    
922    #define PCI_VENDOR_MOT                  0x1057
923    #define PCI_DEVICE_ID_MOTOROLA_MPC106   0x0002
924    #define PCI_DEVICE_ID_MOTOROLA_MPC107   0x0004
925    
926    PCIINIT(mpc10x)
927    {
928            uint64_t port, memaddr;
929    
930            debug("sandpoint mpx10x host bridge\n");
931    
932            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_MOT,
933                PCI_DEVICE_ID_MOTOROLA_MPC107));    /* FIXME MPC106 ?? */
934    
935            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
936                PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x00);   /*  Revision?  */
937    
938            PCI_SET_DATA(PCI_BHLC_REG,
939                PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
940    
941            allocate_device_space(pd, 0x1000, 0, &port, &memaddr);
942            allocate_device_space(pd, 0x1000, 0, &port, &memaddr);
943            allocate_device_space(pd, 0x1000, 0, &port, &memaddr);
944            allocate_device_space(pd, 0x1000, 0, &port, &memaddr);
945    
946    }
947    
948    
949    
950  /*  /*
# Line 852  PCIINIT(vt82c586_isa) Line 974  PCIINIT(vt82c586_isa)
974              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
975  }  }
976    
977    struct vt82c586_ide_extra {
978            void    *wdc0;
979            void    *wdc1;
980    };
981    
982    int vt82c586_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
983    {
984            void *wdc0 = ((struct vt82c586_ide_extra *)pd->extra)->wdc0;
985            void *wdc1 = ((struct vt82c586_ide_extra *)pd->extra)->wdc1;
986            int enabled = 0;
987    
988            switch (reg) {
989            case PCI_COMMAND_STATUS_REG:
990                    if (value & PCI_COMMAND_IO_ENABLE)
991                            enabled = 1;
992                    if (wdc0 != NULL)
993                            wdc_set_io_enabled(wdc0, enabled);
994                    if (wdc1 != NULL)
995                            wdc_set_io_enabled(wdc1, enabled);
996                    return 1;
997            }
998    
999            return 0;
1000    }
1001    
1002  PCIINIT(vt82c586_ide)  PCIINIT(vt82c586_ide)
1003  {  {
1004          char tmpstr[100];          char tmpstr[100];
# Line 867  PCIINIT(vt82c586_ide) Line 1014  PCIINIT(vt82c586_ide)
1014          /*  channel 0 and 1 enabled  */          /*  channel 0 and 1 enabled  */
1015          PCI_SET_DATA(0x40, 0x00000003);          PCI_SET_DATA(0x40, 0x00000003);
1016    
1017            CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct vt82c586_ide_extra)));
1018            ((struct vt82c586_ide_extra *)pd->extra)->wdc0 = NULL;
1019            ((struct vt82c586_ide_extra *)pd->extra)->wdc1 = NULL;
1020    
1021          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
1022              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
1023                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1024                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
1025                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
1026                  device_add(machine, tmpstr);                  ((struct vt82c586_ide_extra *)pd->extra)->wdc0 =
1027                        device_add(machine, tmpstr);
1028          }          }
1029    
1030          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
1031              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
1032                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1033                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
1034                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
1035                  device_add(machine, tmpstr);                  ((struct vt82c586_ide_extra *)pd->extra)->wdc1 =
1036                        device_add(machine, tmpstr);
1037          }          }
1038    
1039            pd->cfg_reg_write = vt82c586_ide_cfg_reg_write;
1040  }  }
1041    
1042    
# Line 905  PCIINIT(symphony_83c553) Line 1060  PCIINIT(symphony_83c553)
1060    
1061          PCI_SET_DATA(PCI_BHLC_REG,          PCI_SET_DATA(PCI_BHLC_REG,
1062              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1063    
1064            switch (machine->machine_type) {
1065            case MACHINE_NETWINDER:
1066                    bus_isa_init(machine, pd->pcibus->irq_path_isa,
1067                        0, 0x7c000000, 0x80000000);
1068                    break;
1069            default:fatal("symphony_83c553 init: unimplemented machine type\n");
1070                    exit(1);
1071            }
1072    }
1073    
1074    struct symphony_82c105_extra {
1075            void    *wdc0;
1076            void    *wdc1;
1077    };
1078    
1079    int symphony_82c105_cfg_reg_write(struct pci_device *pd, int reg,
1080            uint32_t value)
1081    {
1082            void *wdc0 = ((struct symphony_82c105_extra *)pd->extra)->wdc0;
1083            void *wdc1 = ((struct symphony_82c105_extra *)pd->extra)->wdc1;
1084            int enabled = 0;
1085    
1086    printf("reg = 0x%x\n", reg);
1087            switch (reg) {
1088            case PCI_COMMAND_STATUS_REG:
1089                    if (value & PCI_COMMAND_IO_ENABLE)
1090                            enabled = 1;
1091    printf("  value = 0x%"PRIx32"\n", value);
1092                    if (wdc0 != NULL)
1093                            wdc_set_io_enabled(wdc0, enabled);
1094                    if (wdc1 != NULL)
1095                            wdc_set_io_enabled(wdc1, enabled);
1096                    /*  Set all bits:  */
1097                    PCI_SET_DATA(reg, value);
1098                    return 1;
1099            case PCI_MAPREG_START:
1100            case PCI_MAPREG_START + 4:
1101            case PCI_MAPREG_START + 8:
1102            case PCI_MAPREG_START + 12:
1103            case PCI_MAPREG_START + 16:
1104            case PCI_MAPREG_START + 20:
1105                    PCI_SET_DATA(reg, value);
1106                    return 1;
1107            }
1108    
1109            return 0;
1110  }  }
1111    
1112  PCIINIT(symphony_82c105)  PCIINIT(symphony_82c105)
# Line 918  PCIINIT(symphony_82c105) Line 1120  PCIINIT(symphony_82c105)
1120          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,
1121              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x05);              PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x05);
1122    
1123            /*  TODO: Interrupt line:  */
1124            /*  PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000);  */
1125    
1126          /*  APO_IDECONF  */          /*  APO_IDECONF  */
1127          /*  channel 0 and 1 enabled  */          /*  channel 0 and 1 enabled  */
1128          PCI_SET_DATA(0x40, 0x00000003);          PCI_SET_DATA(0x40, 0x00000003);
1129    
1130            CHECK_ALLOCATION(pd->extra =
1131                malloc(sizeof(struct symphony_82c105_extra)));
1132            ((struct symphony_82c105_extra *)pd->extra)->wdc0 = NULL;
1133            ((struct symphony_82c105_extra *)pd->extra)->wdc1 = NULL;
1134    
1135          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
1136              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {              diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
1137                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1138                      (long long)(pd->pcibus->isa_portbase + 0x1f0),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
1139                      pd->pcibus->isa_irqbase + 14);                      pd->pcibus->irq_path_isa, 14);
1140                  device_add(machine, tmpstr);                  ((struct symphony_82c105_extra *)pd->extra)->wdc0 =
1141                        device_add(machine, tmpstr);
1142          }          }
1143    
1144          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||          if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
1145              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {              diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
1146                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",                  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1147                      (long long)(pd->pcibus->isa_portbase + 0x170),                      "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
1148                      pd->pcibus->isa_irqbase + 15);                      pd->pcibus->irq_path_isa, 15);
1149                  device_add(machine, tmpstr);                  ((struct symphony_82c105_extra *)pd->extra)->wdc1 =
1150                        device_add(machine, tmpstr);
1151          }          }
1152    
1153            pd->cfg_reg_write = symphony_82c105_cfg_reg_write;
1154    }
1155    
1156    
1157    
1158    /*
1159     *  Realtek 8139C+ PCI ethernet.
1160     */
1161    
1162    #define PCI_VENDOR_REALTEK              0x10ec
1163    #define PCI_PRODUCT_REALTEK_RT8139      0x8139
1164    
1165    PCIINIT(rtl8139c)
1166    {
1167            uint64_t port, memaddr;
1168            int pci_int_line = 0x101, irq = 0;
1169            char irqstr[200];
1170            char tmpstr[200];
1171    
1172            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_REALTEK,
1173                PCI_PRODUCT_REALTEK_RT8139));
1174    
1175            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_NETWORK,
1176                PCI_SUBCLASS_NETWORK_ETHERNET, 0x00) + 0x20);
1177    
1178            switch (machine->machine_type) {
1179            case MACHINE_LANDISK:
1180                    irq = 5;
1181                    pci_int_line = 0x105;
1182                    break;
1183            default:fatal("rtl8139c for this machine has not been "
1184                        "implemented yet\n");
1185                    exit(1);
1186            }
1187    
1188            PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000 | pci_int_line);
1189    
1190            allocate_device_space(pd, 0x100, 0, &port, &memaddr);
1191    
1192            snprintf(irqstr, sizeof(irqstr), "%s.%i",
1193                pd->pcibus->irq_path_pci, irq);
1194    
1195            snprintf(tmpstr, sizeof(tmpstr), "rtl8139c addr=0x%llx "
1196                "irq=%s pci_little_endian=1", (long long)port, irqstr);
1197    
1198            device_add(machine, tmpstr);
1199  }  }
1200    
1201    
# Line 951  PCIINIT(symphony_82c105) Line 1210  PCIINIT(symphony_82c105)
1210  PCIINIT(dec21143)  PCIINIT(dec21143)
1211  {  {
1212          uint64_t port, memaddr;          uint64_t port, memaddr;
1213          int irq = 0;            /*  TODO  */          int pci_int_line = 0x101, irq = 0, isa = 0;
1214          int pci_int_line = 0x101;          char irqstr[200];
1215          char tmpstr[200];          char tmpstr[200];
1216    
1217          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 1235  PCIINIT(dec21143)
1235                  irq = 8 + 7;                  irq = 8 + 7;
1236                  pci_int_line = 0x407;                  pci_int_line = 0x407;
1237                  break;                  break;
         case MACHINE_ALGOR:  
                 /*  TODO  */  
                 irq = 8 + 7;  
                 pci_int_line = 0x407;  
                 break;  
1238          case MACHINE_PREP:          case MACHINE_PREP:
1239                  irq = 32 + 10;                  irq = 10;
1240                    isa = 1;
1241                  pci_int_line = 0x20a;                  pci_int_line = 0x20a;
1242                  break;                  break;
1243          case MACHINE_MVMEPPC:          case MACHINE_MVMEPPC:
1244                  /*  TODO  */                  /*  TODO  */
1245                  irq = 32 + 10;                  irq = 10;
1246                  pci_int_line = 0x40a;                  pci_int_line = 0x40a;
1247                  break;                  break;
1248          case MACHINE_PMPPC:          case MACHINE_PMPPC:
1249                  /*  TODO, not working yet  */                  /*  TODO, not working yet  */
1250                  irq = 31 - 21;                  irq = 31 - CPC_IB_EXT1;
1251                  pci_int_line = 0x201;                  pci_int_line = 0x101;
1252                  break;                  break;
1253          case MACHINE_MACPPC:          case MACHINE_MACPPC:
1254                  /*  TODO, not working yet  */                  /*  TODO, not working yet  */
# Line 1006  PCIINIT(dec21143) Line 1261  PCIINIT(dec21143)
1261    
1262          allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);          allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);
1263    
1264            if (isa)
1265                    snprintf(irqstr, sizeof(irqstr), "%s.isa.%i",
1266                        pd->pcibus->irq_path_isa, irq);
1267            else
1268                    snprintf(irqstr, sizeof(irqstr), "%s.%i",
1269                        pd->pcibus->irq_path_pci, irq);
1270    
1271          snprintf(tmpstr, sizeof(tmpstr), "dec21143 addr=0x%llx addr2=0x%llx "          snprintf(tmpstr, sizeof(tmpstr), "dec21143 addr=0x%llx addr2=0x%llx "
1272              "irq=%i pci_little_endian=1", (long long)port, (long long)memaddr,              "irq=%s pci_little_endian=1", (long long)port,
1273              irq);              (long long)memaddr, irqstr);
1274    
1275          device_add(machine, tmpstr);          device_add(machine, tmpstr);
1276  }  }
1277    

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

  ViewVC Help
Powered by ViewVC 1.1.26