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

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

  ViewVC Help
Powered by ViewVC 1.1.26