/[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 21 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2004-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2004-2006  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.40 2005/11/25 03:59:58 debug Exp $   *  $Id: bus_pci.c,v 1.62 2006/02/18 21:03:12 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 60  Line 60 
60  extern int verbose;  extern int verbose;
61    
62    
63  /*  #define debug fatal  */  /* #define debug fatal */
64    
65    
66  static void reverse(uint64_t *p, int len)  /*
67     *  bus_pci_decompose_1():
68     *
69     *  Helper function for decomposing Mechanism 1 tags.
70     */
71    void bus_pci_decompose_1(uint32_t t, int *bus, int *dev, int *func, int *reg)
72  {  {
73          uint64_t x = *p, y = 0;          *bus  = (t >> 16) & 0xff;
74          int i;          *dev  = (t >> 11) & 0x1f;
75          for (i=0; i<len; i++) {          *func = (t >>  8) &  0x7;
76                  y <<= 8;          *reg  =  t        & 0xff;
77                  y |= ((x >> (8*i)) & 0xff);  
78          }          /*  Warn about unaligned register access:  */
79          *p = y;          if (t & 3)
80                    fatal("[ bus_pci_decompose_1: WARNING: reg = 0x%02x ]\n",
81                        t & 0xff);
82  }  }
83    
84    
85  /*  /*
86   *  bus_pci_data_access():   *  bus_pci_data_access():
87   *   *
88   *  Reads from and writes to the PCI configuration registers of a device.   *  Reads from or writes to the PCI configuration registers of a device.
89   */   */
90  void bus_pci_data_access(struct cpu *cpu, struct memory *mem,  void bus_pci_data_access(struct cpu *cpu, struct pci_data *pci_data,
91          uint64_t *data, int len, int writeflag, struct pci_data *pci_data)          uint64_t *data, int len, int writeflag)
92  {  {
93          struct pci_device *dev;          struct pci_device *dev;
         int bus, device, function, registernr;  
94          unsigned char *cfg_base;          unsigned char *cfg_base;
95          uint64_t x, idata = *data;          uint64_t x, idata = *data;
96            int i;
         if (cpu->byte_order == EMUL_BIG_ENDIAN)  
                 reverse(&idata, len);  
   
         /*  Get the bus, device, and function numbers from the address:  */  
         bus        = (pci_data->pci_addr >> 16) & 0xff;  
         device     = (pci_data->pci_addr >> 11) & 0x1f;  
         function   = (pci_data->pci_addr >> 8)  & 0x7;  
         registernr = (pci_data->pci_addr)       & 0xff;  
97    
98          /*  Scan through the list of pci_device entries.  */          /*  Scan through the list of pci_device entries.  */
99          dev = pci_data->first_device;          dev = pci_data->first_device;
100          while (dev != NULL) {          while (dev != NULL) {
101                  if (dev->bus == bus && dev->function == function &&                  if (dev->bus      == pci_data->cur_bus &&
102                      dev->device == device)                      dev->function == pci_data->cur_func &&
103                        dev->device   == pci_data->cur_device)
104                          break;                          break;
105                  dev = dev->next;                  dev = dev->next;
106          }          }
107    
108          /*  No device? Then return emptiness.  */          /*  No device? Then return emptiness.  */
109          if (dev == NULL) {          if (dev == NULL) {
110                  if ((pci_data->pci_addr & 0xff) == 0)                  if (writeflag == MEM_READ) {
111                          *data = 0xffffffff;                          if (pci_data->cur_reg == 0)
112                  else                                  *data = -1;
113                          *data = 0;                          else
114                                    *data = 0;
115                    } else {
116                            fatal("[ bus_pci_data_access(): write to non-existant"
117                                " device? ]\n");
118                    }
119                  return;                  return;
120          }          }
121    
122          /*  Return normal config data, or length data?  */          /*  Return normal config data, or length data?  */
123          if (pci_data->last_was_write_ffffffff &&          if (pci_data->last_was_write_ffffffff &&
124              registernr >= PCI_MAPREG_START && registernr <= PCI_MAPREG_END - 4)              pci_data->cur_reg >= PCI_MAPREG_START &&
125                pci_data->cur_reg <= PCI_MAPREG_END - 4)
126                  cfg_base = dev->cfg_mem_size;                  cfg_base = dev->cfg_mem_size;
127          else          else
128                  cfg_base = dev->cfg_mem;                  cfg_base = dev->cfg_mem;
129    
130          /*  Read data as little-endian:  */          /*  Read data as little-endian:  */
131          x = 0;          x = 0;
132          if (registernr + len - 1 < PCI_CFG_MEM_SIZE) {          for (i=len-1; i>=0; i--) {
133                  x = cfg_base[registernr];                  int ofs = pci_data->cur_reg + i;
134                  if (len > 1)                  x <<= 8;
135                          x |= (cfg_base[registernr+1] << 8);                  x |= cfg_base[ofs & (PCI_CFG_MEM_SIZE - 1)];
                 if (len > 2)  
                         x |= (cfg_base[registernr+2] << 16);  
                 if (len > 3)  
                         x |= ((uint64_t)cfg_base[registernr+3] << 24);  
                 if (len > 4)  
                         fatal("TODO: more than 32-bit PCI access?\n");  
136          }          }
137    
138          /*  Register write:  */          /*  Register write:  */
139          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
140                  debug("[ bus_pci: write to PCI DATA: data = 0x%016llx ]\n",                  debug("[ bus_pci: write to PCI DATA: data = 0x%08llx ]\n",
141                      (long long)idata);                      (long long)idata);
142                  if (idata == 0xffffffffULL && registernr >= PCI_MAPREG_START                  if (idata == 0xffffffffULL &&
143                      && registernr <= PCI_MAPREG_END - 4) {                      pci_data->cur_reg >= PCI_MAPREG_START &&
144                        pci_data->cur_reg <= PCI_MAPREG_END - 4) {
145                          pci_data->last_was_write_ffffffff = 1;                          pci_data->last_was_write_ffffffff = 1;
146                          return;                          return;
147                  }                  }
# Line 151  void bus_pci_data_access(struct cpu *cpu Line 151  void bus_pci_data_access(struct cpu *cpu
151                              " differs from current value 0x%08llx; NOT YET"                              " differs from current value 0x%08llx; NOT YET"
152                              " SUPPORTED. bus %i, device %i, function %i (%s)"                              " SUPPORTED. bus %i, device %i, function %i (%s)"
153                              " register 0x%02x ]\n", (long long)idata,                              " register 0x%02x ]\n", (long long)idata,
154                              (long long)x, bus, device, function, dev->name,                              (long long)x, pci_data->cur_bus,
155                              registernr);                              pci_data->cur_device, pci_data->cur_func,
156                                dev->name, pci_data->cur_reg);
157                  }                  }
158                  return;                  return;
159          }          }
160    
161          /*  Register read:  */          /*  Register read:  */
         if (cpu->byte_order == EMUL_BIG_ENDIAN)  
                 reverse(&x, len);  
162          *data = x;          *data = x;
163    
164          pci_data->last_was_write_ffffffff = 0;          pci_data->last_was_write_ffffffff = 0;
165    
166          debug("[ bus_pci: read from PCI DATA, addr = 0x%08lx (bus %i, device "          debug("[ bus_pci: read from PCI DATA, bus %i, device "
167              "%i, function %i (%s) register 0x%02x): 0x%08lx ]\n", (long)              "%i, function %i (%s) register 0x%02x: 0x%08lx ]\n", (long)
168              pci_data->pci_addr, bus, device, function, dev->name,              pci_data->cur_bus, pci_data->cur_device,
169              registernr, (long)*data);              pci_data->cur_func, dev->name, pci_data->cur_reg, (long)*data);
170  }  }
171    
172    
173  /*  /*
174   *  bus_pci_access():   *  bus_pci_setaddr():
  *  
  *  relative_addr should be either BUS_PCI_ADDR or BUS_PCI_DATA. The uint64_t  
  *  pointed to by data should contain the word to be written to the pci bus,  
  *  or a placeholder for information read from the bus.  
175   *   *
176   *  Returns 1 if ok, 0 on error.   *  Sets the address in preparation for a PCI register transfer.
177   */   */
178  int bus_pci_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr,  void bus_pci_setaddr(struct cpu *cpu, struct pci_data *pci_data,
179          uint64_t *data, int len, int writeflag, struct pci_data *pci_data)          int bus, int device, int function, int reg)
180  {  {
181          if (writeflag == MEM_READ)          if (cpu == NULL || pci_data == NULL) {
182                  *data = 0;                  fatal("bus_pci_setaddr(): NULL ptr\n");
183                    exit(1);
         switch (relative_addr) {  
   
         case BUS_PCI_ADDR:  
                 if (writeflag == MEM_WRITE) {  
                         debug("[ bus_pci: write to PCI ADDR: data = 0x%016llx"  
                             " ]\n", (long long)*data);  
                         pci_data->pci_addr = *data;  
   
                         /*  
                          *  Big-endian systems (e.g. PowerPC) seem to access  
                          *  PCI config data using little-endian accesses.  
                          */  
                         if (cpu->byte_order == EMUL_BIG_ENDIAN) {  
                                 uint32_t t = pci_data->pci_addr;  
                                 pci_data->pci_addr = ((t >> 24) & 255)  
                                     | ((t >> 8) & 0xff00)  
                                     | ((t << 8) & 0xff0000)  
                                     | ((t << 24) & 0xff000000);  
                         }  
   
                         /*  Linux seems to use type 0 even when it does  
                             type 1 detection. Hm. This is commented for now.  */  
                         /*  if (pci_data->pci_addr & 1)  
                                 fatal("[ bus_pci: WARNING! pci type 0 not"  
                                     " yet implemented! ]\n");  */  
                 } else {  
                         debug("[ bus_pci: read from PCI ADDR (data = "  
                             "0x%016llx) ]\n", (long long)pci_data->pci_addr);  
                         *data = pci_data->pci_addr;  
                 }  
                 break;  
   
         case BUS_PCI_DATA:  
                 bus_pci_data_access(cpu, mem, data, len, writeflag, pci_data);  
                 break;  
   
         default:if (writeflag == MEM_READ) {  
                         debug("[ bus_pci: read from unimplemented addr "  
                             "0x%x ]\n", (int)relative_addr);  
                         *data = 0;  
                 } else {  
                         debug("[ bus_pci: write to unimplemented addr "  
                             "0x%x: 0x%llx ]\n", (int)relative_addr,  
                             (long long)*data);  
                 }  
184          }          }
185    
186          return 1;          pci_data->cur_bus = bus;
187            pci_data->cur_device = device;
188            pci_data->cur_func = function;
189            pci_data->cur_reg = reg;
190  }  }
191    
192    
# Line 244  int bus_pci_access(struct cpu *cpu, stru Line 197  int bus_pci_access(struct cpu *cpu, stru
197   */   */
198  void bus_pci_add(struct machine *machine, struct pci_data *pci_data,  void bus_pci_add(struct machine *machine, struct pci_data *pci_data,
199          struct memory *mem, int bus, int device, int function,          struct memory *mem, int bus, int device, int function,
200          char *name)          const char *name)
201  {  {
202          struct pci_device *pd;          struct pci_device *pd;
203          int ofs;          int ofs;
# Line 291  void bus_pci_add(struct machine *machine Line 244  void bus_pci_add(struct machine *machine
244          /*          /*
245           *  Initialize with some default values:           *  Initialize with some default values:
246           *           *
247           *  TODO:  The command status register is best to set up per device,           *  TODO:  The command status register is best to set up per device.
248           *         just enabling all bits like this is not really good.           *  The size registers should also be set up on a per-device basis.
          *         The size registers should also be set up on a per-device  
          *         basis.  
249           */           */
250          PCI_SET_DATA(PCI_COMMAND_STATUS_REG, 0x00ffffffULL);          PCI_SET_DATA(PCI_COMMAND_STATUS_REG,
251                PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE);
252          for (ofs = PCI_MAPREG_START; ofs < PCI_MAPREG_END; ofs += 4)          for (ofs = PCI_MAPREG_START; ofs < PCI_MAPREG_END; ofs += 4)
253                  PCI_SET_DATA_SIZE(ofs, 0x00400000 - 1);                  PCI_SET_DATA_SIZE(ofs, 0x00100000 - 1);
254    
255          if (init == NULL) {          if (init == NULL) {
256                  fatal("No init function for PCI device \"%s\"?\n", name);                  fatal("No init function for PCI device \"%s\"?\n", name);
# Line 331  static void allocate_device_space(struct Line 283  static void allocate_device_space(struct
283          if (portsize != 0) {          if (portsize != 0) {
284                  port = ((port - 1) | (portsize - 1)) + 1;                  port = ((port - 1) | (portsize - 1)) + 1;
285                  pd->pcibus->cur_pci_portbase = port;                  pd->pcibus->cur_pci_portbase = port;
286                  PCI_SET_DATA(PCI_MAPREG_START, port | PCI_MAPREG_TYPE_IO);                  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset,
287                  PCI_SET_DATA_SIZE(PCI_MAPREG_START, portsize - 1);                      port | PCI_MAPREG_TYPE_IO);
288                    PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,
289                        portsize - 1);
290                    pd->cur_mapreg_offset += sizeof(uint32_t);
291          }          }
292    
293          /*  Calculate an aligned starting memory location:  */          /*  Calculate an aligned starting memory location:  */
# Line 340  static void allocate_device_space(struct Line 295  static void allocate_device_space(struct
295          if (memsize != 0) {          if (memsize != 0) {
296                  mem = ((mem - 1) | (memsize - 1)) + 1;                  mem = ((mem - 1) | (memsize - 1)) + 1;
297                  pd->pcibus->cur_pci_membase = mem;                  pd->pcibus->cur_pci_membase = mem;
298                  PCI_SET_DATA(PCI_MAPREG_START + 0x04, mem);                  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset, mem);
299                  PCI_SET_DATA_SIZE(PCI_MAPREG_START + 0x04, memsize - 1);                  PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,
300                        memsize - 1);
301                    pd->cur_mapreg_offset += sizeof(uint32_t);
302          }          }
303    
304          *portp = port + pd->pcibus->pci_actual_io_offset;          *portp = port + pd->pcibus->pci_actual_io_offset;
# Line 365  static void allocate_device_space(struct Line 322  static void allocate_device_space(struct
322  }  }
323    
324    
325    static void bus_pci_debug_dump__2(struct pci_device *pd)
326    {
327            if (pd == NULL)
328                    return;
329            bus_pci_debug_dump__2(pd->next);
330            debug("bus %3i, dev %2i, func %i: %s\n",
331                pd->bus, pd->device, pd->function, pd->name);
332    }
333    
334    
335    /*
336     *  bus_pci_debug_dump():
337     *
338     *  Lists the attached PCI devices (in reverse).
339     */
340    void bus_pci_debug_dump(void *extra)
341    {
342            struct pci_data *d = (struct pci_data *) extra;
343            int iadd = DEBUG_INDENTATION;
344    
345            debug("pci:\n");
346            debug_indentation(iadd);
347    
348            if (d->first_device == NULL)
349                    debug("no devices!\n");
350            else
351                    bus_pci_debug_dump__2(d->first_device);
352    
353            debug_indentation(-iadd);
354    }
355    
356    
357  /*  /*
358   *  bus_pci_init():   *  bus_pci_init():
359   *   *
360   *  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
361   *  which should be passed to bus_pci_access() when accessing the PCI bus.   *  which should be passed to other bus_pci functions when accessing the bus.
362   *   *
363   *  irq_nr is the (optional) IRQ nr that this PCI bus interrupts at.   *  irq_nr is the (optional) IRQ nr that this PCI bus interrupts at.
364   *   *
# Line 382  static void allocate_device_space(struct Line 371  static void allocate_device_space(struct
371   *  isa_portbase, isa_membase, and isa_irqbase are the port, memory, and   *  isa_portbase, isa_membase, and isa_irqbase are the port, memory, and
372   *  interrupt bases for legacy ISA devices.   *  interrupt bases for legacy ISA devices.
373   */   */
374  struct pci_data *bus_pci_init(int irq_nr,  struct pci_data *bus_pci_init(struct machine *machine, int irq_nr,
375          uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset,          uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset,
376          uint64_t pci_portbase, uint64_t pci_membase, int pci_irqbase,          uint64_t pci_portbase, uint64_t pci_membase, int pci_irqbase,
377          uint64_t isa_portbase, uint64_t isa_membase, int isa_irqbase)          uint64_t isa_portbase, uint64_t isa_membase, int isa_irqbase)
# Line 405  struct pci_data *bus_pci_init(int irq_nr Line 394  struct pci_data *bus_pci_init(int irq_nr
394          d->isa_membase           = isa_membase;          d->isa_membase           = isa_membase;
395          d->isa_irqbase           = isa_irqbase;          d->isa_irqbase           = isa_irqbase;
396    
397            /*  Register the bus:  */
398            machine_bus_register(machine, "pci", bus_pci_debug_dump, d);
399    
400          /*  Assume that the first 64KB could be used by legacy ISA devices:  */          /*  Assume that the first 64KB could be used by legacy ISA devices:  */
401          d->cur_pci_portbase = d->pci_portbase + 0x10000;          d->cur_pci_portbase = d->pci_portbase + 0x10000;
402          d->cur_pci_membase  = d->pci_membase + 0x10000;          d->cur_pci_membase  = d->pci_membase + 0x10000;
# Line 415  struct pci_data *bus_pci_init(int irq_nr Line 407  struct pci_data *bus_pci_init(int irq_nr
407    
408    
409  /******************************************************************************  /******************************************************************************
410   *   *                                                                            *
411   *  The following is glue code for PCI controllers and devices. The glue code   *  The following is glue code for PCI controllers and devices. The glue      *
412   *  does the minimal stuff necessary to get an emulated OS to detect the   *  code does the minimal stuff necessary to get an emulated OS to detect     *
413   *  device (i.e. set up PCI configuration registers), and then if necessary   *  the device (i.e. set up PCI configuration registers), and then if         *
414   *  add a "normal" device.   *  necessary adds a "normal" device.                                         *
415   *   *                                                                            *
416   ******************************************************************************/   ******************************************************************************/
417    
418    
# Line 443  PCIINIT(igsfb) Line 435  PCIINIT(igsfb)
435              PCI_SUBCLASS_DISPLAY_VGA, 0) + 0x01);              PCI_SUBCLASS_DISPLAY_VGA, 0) + 0x01);
436    
437          /*  TODO  */          /*  TODO  */
438          PCI_SET_DATA(0x10, 0xb0000000);          PCI_SET_DATA(0x10, 0x08000000);
439    
440          /*  TODO: This is just a dummy so far.  */          dev_vga_init(machine, mem, pd->pcibus->isa_membase + 0xa0000,
441                0x88800000 + 0x3c0, machine->machine_name);
442  }  }
443    
444    
# Line 594  PCIINIT(ahc) Line 587  PCIINIT(ahc)
587  #define PCI_VENDOR_GALILEO           0x11ab    /* Galileo Technology */  #define PCI_VENDOR_GALILEO           0x11ab    /* Galileo Technology */
588  #define PCI_PRODUCT_GALILEO_GT64011  0x4146    /* GT-64011 System Controller */  #define PCI_PRODUCT_GALILEO_GT64011  0x4146    /* GT-64011 System Controller */
589  #define PCI_PRODUCT_GALILEO_GT64120  0x4620    /* GT-64120 */  #define PCI_PRODUCT_GALILEO_GT64120  0x4620    /* GT-64120 */
590    #define PCI_PRODUCT_GALILEO_GT64260  0x6430    /* GT-64260 */
591    
592  PCIINIT(gt64011)  PCIINIT(gt64011)
593  {  {
594          PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_GALILEO,          PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_GALILEO,
595              PCI_PRODUCT_GALILEO_GT64011));              PCI_PRODUCT_GALILEO_GT64011));
596    
597          PCI_SET_DATA(PCI_CLASS_REG,          PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
             PCI_CLASS_CODE(PCI_CLASS_BRIDGE,  
598              PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x01);       /*  Revision 1  */              PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x01);       /*  Revision 1  */
599  }  }
600    
# Line 620  PCIINIT(gt64120) Line 613  PCIINIT(gt64120)
613          }          }
614  }  }
615    
616    PCIINIT(gt64260)
617    {
618            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_GALILEO,
619                PCI_PRODUCT_GALILEO_GT64260));
620    
621            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
622                PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x01);       /*  Revision 1?  */
623    }
624    
625    
626    
627  /*  /*
628   *  Intel 82371AB PIIX4 PCI-ISA bridge and IDE controller   *  Intel 31244   Serial ATA Controller
629   *  and 82378ZB System I/O controller.   *  Intel 82371SB PIIX3 PCI-ISA bridge
630     *  Intel 82371AB PIIX4 PCI-ISA bridge
631     *  Intel 82371SB IDE controller
632     *  Intel 82371AB IDE controller
633     *  Intel 82378ZB System I/O controller.
634   */   */
635    
636  #define PCI_VENDOR_INTEL                0x8086  #define PCI_VENDOR_INTEL                0x8086
637    #define PCI_PRODUCT_INTEL_31244         0x3200
638    #define PCI_PRODUCT_INTEL_82371SB_ISA   0x7000
639    #define PCI_PRODUCT_INTEL_82371SB_IDE   0x7010
640  #define PCI_PRODUCT_INTEL_82371AB_ISA   0x7110  #define PCI_PRODUCT_INTEL_82371AB_ISA   0x7110
641  #define PCI_PRODUCT_INTEL_82371AB_IDE   0x7111  #define PCI_PRODUCT_INTEL_82371AB_IDE   0x7111
642  #define PCI_PRODUCT_INTEL_SIO           0x0484  #define PCI_PRODUCT_INTEL_SIO           0x0484
643    
644  PCIINIT(i82371ab_isa)  PCIINIT(i31244)
645    {
646            uint64_t port, memaddr;
647    
648            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
649                PCI_PRODUCT_INTEL_31244));
650    
651            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
652                PCI_SUBCLASS_MASS_STORAGE_IDE, 0x33) + 0x00);
653    
654            switch (machine->machine_type) {
655            case MACHINE_IQ80321:
656                    /*  S-PCI-X slot uses PCI IRQ A  */
657                    break;
658            default:fatal("i31244 in non-implemented machine type %i\n",
659                        machine->machine_type);
660                    exit(1);
661            }
662    
663            PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140100);
664    
665            allocate_device_space(pd, 0x400, 0, &port, &memaddr);
666            allocate_device_space(pd, 0x400, 0, &port, &memaddr);
667    
668            /*  PCI IDE using dev_wdc:  */
669            if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
670                diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
671                    char tmpstr[150];
672                    snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
673                        (long long)(pd->pcibus->pci_actual_io_offset + 0),
674                        pd->pcibus->pci_irqbase + 0);
675                    device_add(machine, tmpstr);
676            }
677    }
678    
679    PCIINIT(piix3_isa)
680    {
681            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
682                PCI_PRODUCT_INTEL_82371SB_ISA));
683    
684            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
685                PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x01);        /*  Rev 1  */
686    
687            PCI_SET_DATA(PCI_BHLC_REG,
688                PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
689    }
690    
691    PCIINIT(piix4_isa)
692  {  {
693          PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,          PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
694              PCI_PRODUCT_INTEL_82371AB_ISA));              PCI_PRODUCT_INTEL_82371AB_ISA));
# Line 654  PCIINIT(i82378zb) Line 710  PCIINIT(i82378zb)
710    
711          PCI_SET_DATA(PCI_BHLC_REG,          PCI_SET_DATA(PCI_BHLC_REG,
712              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
713    
714            PCI_SET_DATA(0x40, 0x20);
715    
716            /*  PIRQ[0]=10 PIRQ[1]=11 PIRQ[2]=14 PIRQ[3]=15  */
717            PCI_SET_DATA(0x60, 0x0f0e0b0a);
718  }  }
719    
720  PCIINIT(i82371ab_ide)  PCIINIT(piix3_ide)
721    {
722            char tmpstr[100];
723    
724            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
725                PCI_PRODUCT_INTEL_82371SB_IDE));
726    
727            /*  Possibly not correct:  */
728            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
729                PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x00);
730    
731            /*  PIIX_IDETIM (see NetBSD's pciide_piix_reg.h)  */
732            /*  channel 0 and 1 enabled as IDE  */
733            PCI_SET_DATA(0x40, 0x80008000);
734    
735            if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
736                diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
737                    snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
738                        (long long)(pd->pcibus->isa_portbase + 0x1f0),
739                        pd->pcibus->isa_irqbase + 14);
740                    device_add(machine, tmpstr);
741            }
742    
743            if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
744                diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
745                    snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
746                        (long long)(pd->pcibus->isa_portbase + 0x170),
747                        pd->pcibus->isa_irqbase + 15);
748                    device_add(machine, tmpstr);
749            }
750    }
751    
752    PCIINIT(piix4_ide)
753  {  {
754          char tmpstr[100];          char tmpstr[100];
755    
# Line 859  PCIINIT(dec21143) Line 952  PCIINIT(dec21143)
952  {  {
953          uint64_t port, memaddr;          uint64_t port, memaddr;
954          int irq = 0;            /*  TODO  */          int irq = 0;            /*  TODO  */
955          int int_line = 1;       /*  TODO  */          int pci_int_line = 0x101;
956          char tmpstr[200];          char tmpstr[200];
957    
958          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 874  PCIINIT(dec21143) Line 967  PCIINIT(dec21143)
967    
968          switch (machine->machine_type) {          switch (machine->machine_type) {
969          case MACHINE_CATS:          case MACHINE_CATS:
970                    /*  CATS int 18 = PCI.  */
971                  irq = 18;                  irq = 18;
972                  int_line = 1;                  pci_int_line = 0x101;
973                    break;
974            case MACHINE_COBALT:
975                    /*  On Cobalt, IRQ 7 = PCI.  */
976                    irq = 8 + 7;
977                    pci_int_line = 0x407;
978                    break;
979            case MACHINE_ALGOR:
980                    /*  TODO  */
981                    irq = 8 + 7;
982                    pci_int_line = 0x407;
983                  break;                  break;
984          case MACHINE_PREP:          case MACHINE_PREP:
985                  int_line = 0xa;                  irq = 32 + 10;
986                  irq = 31 - int_line;                  pci_int_line = 0x20a;
987                    break;
988            case MACHINE_MVMEPPC:
989                    /*  TODO  */
990                    irq = 32 + 10;
991                    pci_int_line = 0x40a;
992                  break;                  break;
993          case MACHINE_PMPPC:          case MACHINE_PMPPC:
994                    /*  TODO, not working yet  */
995                  irq = 31 - 21;                  irq = 31 - 21;
996                    pci_int_line = 0x201;
997                    break;
998            case MACHINE_MACPPC:
999                    /*  TODO, not working yet  */
1000                    irq = 25;
1001                    pci_int_line = 0x101;
1002                  break;                  break;
1003          }          }
1004    
1005          PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140100 | int_line);          PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000 | pci_int_line);
1006    
1007          allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);          allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);
1008    
# Line 950  PCIINIT(dec21030) Line 1066  PCIINIT(dec21030)
1066  }  }
1067    
1068    
1069    
1070  /*  /*
1071   *  Motorola MPC105 "Eagle" Host Bridge   *  Motorola MPC105 "Eagle" Host Bridge
1072   *   *
# Line 971  PCIINIT(eagle) Line 1088  PCIINIT(eagle)
1088              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));              PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1089  }  }
1090    
1091    
1092    
1093    /*
1094     *  Apple (MacPPC) stuff:
1095     *
1096     *  Grand Central (I/O controller)
1097     *  Uni-North (PCI controller)
1098     */
1099    
1100    #define PCI_VENDOR_APPLE                0x106b
1101    #define PCI_PRODUCT_APPLE_GC            0x0002
1102    #define PCI_PRODUCT_APPLE_UNINORTH1     0x001e
1103    
1104    PCIINIT(gc_obio)
1105    {
1106            uint64_t port, memaddr;
1107    
1108            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_APPLE,
1109                PCI_PRODUCT_APPLE_GC));
1110    
1111            /*  TODO:  */
1112            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_SYSTEM,
1113                PCI_SUBCLASS_SYSTEM_PIC, 0) + 0x00);
1114    
1115            PCI_SET_DATA(PCI_BHLC_REG,
1116                PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1117    
1118            /*  TODO  */
1119            allocate_device_space(pd, 0x10000, 0x10000, &port, &memaddr);
1120    }
1121    
1122    PCIINIT(uninorth)
1123    {
1124            uint64_t port, memaddr;
1125    
1126            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_APPLE,
1127                PCI_PRODUCT_APPLE_UNINORTH1));
1128    
1129            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
1130                PCI_SUBCLASS_BRIDGE_HOST, 0) + 0xff);
1131    
1132            PCI_SET_DATA(PCI_BHLC_REG,
1133                PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1134    
1135            /*  TODO  */
1136            allocate_device_space(pd, 0x10000, 0x10000, &port, &memaddr);
1137    }
1138    
1139    
1140    
1141    /*
1142     *  ATI graphics cards
1143     */
1144    
1145    #define PCI_VENDOR_ATI                  0x1002
1146    #define PCI_PRODUCT_ATI_RADEON_9200_2   0x5962
1147    
1148    PCIINIT(ati_radeon_9200_2)
1149    {
1150            uint64_t port, memaddr;
1151    
1152            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_ATI,
1153                PCI_PRODUCT_ATI_RADEON_9200_2));
1154    
1155            /*  TODO: other subclass?  */
1156            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_DISPLAY,
1157                PCI_SUBCLASS_DISPLAY_VGA, 0) + 0x03);
1158    
1159            /*  TODO  */
1160            allocate_device_space(pd, 0x1000, 0x400000, &port, &memaddr);
1161    }
1162    

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

  ViewVC Help
Powered by ViewVC 1.1.26