/[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 14 by dpavlin, Mon Oct 8 16:18:51 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.12 2005/09/27 23:18:32 debug Exp $   *  $Id: bus_pci.c,v 1.65 2006/05/10 03:32:32 debug Exp $
29   *     *  
30   *  This is a generic PCI bus device, used by even lower level devices.   *  Generic PCI bus framework. This is not a normal "device", but is used by
31   *  For example, the "gt" device used in Cobalt machines contains a PCI   *  individual PCI controllers and devices.
  *  device.  
32   *   *
33   *  TODO:  This more or less just a dummy bus device, so far.   *  See NetBSD's pcidevs.h for more PCI vendor and device identifiers.
34     *
35     *  TODO:
36     *
37     *      x) Allow guest OSes to do runtime address fixups (i.e. actually
38     *         move a device from one address to another).
39     *
40     *      x) Generalize the PCI and legacy ISA interrupt routing stuff.
41     *
42     *      x) Make sure that pci_little_endian is used correctly everywhere.
43   */   */
44    
45  #include <stdio.h>  #include <stdio.h>
46  #include <stdlib.h>  #include <stdlib.h>
47  #include <string.h>  #include <string.h>
48    
49    #define BUS_PCI_C
50    
51    #include "bus_pci.h"
52    #include "cpu.h"
53    #include "device.h"
54    #include "devices.h"
55    #include "diskimage.h"
56    #include "machine.h"
57  #include "memory.h"  #include "memory.h"
58  #include "misc.h"  #include "misc.h"
59    
60  #include "bus_pci.h"  extern int verbose;
61    
62    
63  /*  #define debug fatal  */  #ifdef UNSTABLE_DEVEL
64    #define debug fatal
65    #endif
66    
67    
68  /*  /*
69   *  bus_pci_access():   *  bus_pci_decompose_1():
  *  
  *  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.  
70   *   *
71   *  Returns 1 if ok, 0 on error.   *  Helper function for decomposing Mechanism 1 tags.
72   */   */
73  int bus_pci_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr,  void bus_pci_decompose_1(uint32_t t, int *bus, int *dev, int *func, int *reg)
         uint64_t *data, int writeflag, struct pci_data *pci_data)  
74  {  {
75          struct pci_device *dev, *found;          *bus  = (t >> 16) & 0xff;
76          int bus, device, function, registernr;          *dev  = (t >> 11) & 0x1f;
77            *func = (t >>  8) &  0x7;
78            *reg  =  t        & 0xff;
79    
80            /*  Warn about unaligned register access:  */
81            if (t & 3)
82                    fatal("[ bus_pci_decompose_1: WARNING: reg = 0x%02x ]\n",
83                        t & 0xff);
84    }
85    
         if (writeflag == MEM_READ)  
                 *data = 0;  
86    
87          switch (relative_addr) {  /*
88          case BUS_PCI_ADDR:   *  bus_pci_data_access():
89                  if (writeflag == MEM_WRITE) {   *
90                          debug("[ bus_pci: write to  PCI ADDR: data = 0x%016llx"   *  Reads from or writes to the PCI configuration registers of a device.
91                              " ]\n", (long long)*data);   */
92                          pci_data->pci_addr = *data;  void bus_pci_data_access(struct cpu *cpu, struct pci_data *pci_data,
93                  } else {          uint64_t *data, int len, int writeflag)
94                          debug("[ bus_pci: read from PCI ADDR (data = "  {
95                              "0x%016llx) ]\n", (long long)pci_data->pci_addr);          struct pci_device *dev;
96                          *data = pci_data->pci_addr;          unsigned char *cfg_base;
97                  }          uint64_t x, idata = *data;
98                  break;          int i;
99          case BUS_PCI_DATA:  
100                  if (writeflag == MEM_WRITE) {          /*  Scan through the list of pci_device entries.  */
101                          debug("[ bus_pci: write to PCI DATA: data = "          dev = pci_data->first_device;
102                              "0x%016llx ]\n", (long long)*data);          while (dev != NULL) {
103                          if (*data == 0xffffffffULL)                  if (dev->bus      == pci_data->cur_bus &&
104                                  pci_data->last_was_write_ffffffff = 1;                      dev->function == pci_data->cur_func &&
105                        dev->device   == pci_data->cur_device)
106                            break;
107                    dev = dev->next;
108            }
109    
110            /*  No device? Then return emptiness.  */
111            if (dev == NULL) {
112                    if (writeflag == MEM_READ) {
113                            if (pci_data->cur_reg == 0)
114                                    *data = -1;
115                            else
116                                    *data = 0;
117                  } else {                  } else {
118                          /*  Get the bus, device, and function numbers from                          fatal("[ bus_pci_data_access(): write to non-existant"
119                              the address:  */                              " device? ]\n");
                         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;  
   
                         /*  Scan through the list of pci_device entries.  */  
                         dev = pci_data->first_device;  
                         found = NULL;  
   
                         while (dev != NULL && found == NULL) {  
                                 if (dev->bus == bus &&  
                                     dev->function == function &&  
                                     dev->device == device)  
                                         found = dev;  
                                 dev = dev->next;  
                         }  
   
                         if (found == NULL) {  
                                 if ((pci_data->pci_addr & 0xff) == 0)  
                                         *data = 0xffffffff;  
                                 else  
                                         *data = 0;  
                                 return 1;  
                         }  
   
                         *data = 0;  
   
                         if (pci_data->last_was_write_ffffffff &&  
                             registernr >= 0x10 && registernr <= 0x24) {  
                                 /*  TODO:  real length!!!  */  
                                 *data = 0x00400000 - 1;  
                         } else if (found->read_register != NULL)  
                                 *data = found->read_register(registernr);  
   
                         pci_data->last_was_write_ffffffff = 0;  
   
                         debug("[ bus_pci: read from PCI DATA, addr = 0x%08lx "  
                             "(bus %i, device %i, function %i, register "  
                             "0x%02x): 0x%08lx ]\n", (long)pci_data->pci_addr,  
                             bus, device, function, registernr, (long)*data);  
120                  }                  }
121                    return;
122            }
123    
124                  break;          /*  Return normal config data, or length data?  */
125          default:          if (pci_data->last_was_write_ffffffff &&
126                  if (writeflag==MEM_READ) {              pci_data->cur_reg >= PCI_MAPREG_START &&
127                          debug("[ bus_pci: read from unimplemented addr "              pci_data->cur_reg <= PCI_MAPREG_END - 4)
128                              "0x%x ]\n", (int)relative_addr);                  cfg_base = dev->cfg_mem_size;
129                          *data = 0;          else
130                  } else {                  cfg_base = dev->cfg_mem;
131                          debug("[ bus_pci: write to unimplemented addr "  
132                              "0x%x:", (int)relative_addr);          /*  Read data as little-endian:  */
133            x = 0;
134            for (i=len-1; i>=0; i--) {
135                    int ofs = pci_data->cur_reg + i;
136                    x <<= 8;
137                    x |= cfg_base[ofs & (PCI_CFG_MEM_SIZE - 1)];
138            }
139    
140            /*  Register write:  */
141            if (writeflag == MEM_WRITE) {
142                    debug("[ bus_pci: write to PCI DATA: data = 0x%08llx ]\n",
143                        (long long)idata);
144                    if (idata == 0xffffffffULL &&
145                        pci_data->cur_reg >= PCI_MAPREG_START &&
146                        pci_data->cur_reg <= PCI_MAPREG_END - 4) {
147                            pci_data->last_was_write_ffffffff = 1;
148                            return;
149                    }
150                    /*  Writes are not really supported yet:  */
151                    if (idata != x) {
152                            debug("[ bus_pci: write to PCI DATA: data = 0x%08llx"
153                                " differs from current value 0x%08llx; NOT YET"
154                                " SUPPORTED. bus %i, device %i, function %i (%s)"
155                                " register 0x%02x ]\n", (long long)idata,
156                                (long long)x, pci_data->cur_bus,
157                                pci_data->cur_device, pci_data->cur_func,
158                                dev->name, pci_data->cur_reg);
159                  }                  }
160                    return;
161          }          }
162    
163          return 1;          /*  Register read:  */
164            *data = x;
165    
166            pci_data->last_was_write_ffffffff = 0;
167    
168            debug("[ bus_pci: read from PCI DATA, bus %i, device "
169                "%i, function %i (%s) register 0x%02x: (len=%i) 0x%08lx ]\n",
170                pci_data->cur_bus, pci_data->cur_device, pci_data->cur_func,
171                dev->name, pci_data->cur_reg, len, (long)*data);
172    }
173    
174    
175    /*
176     *  bus_pci_setaddr():
177     *
178     *  Sets the address in preparation for a PCI register transfer.
179     */
180    void bus_pci_setaddr(struct cpu *cpu, struct pci_data *pci_data,
181            int bus, int device, int function, int reg)
182    {
183            if (cpu == NULL || pci_data == NULL) {
184                    fatal("bus_pci_setaddr(): NULL ptr\n");
185                    exit(1);
186            }
187    
188            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 150  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          void (*init)(struct machine *, struct memory *),          const char *name)
         uint32_t (*read_register)(int reg))  
203  {  {
204          struct pci_device *new_device;          struct pci_device *pd;
205            int ofs;
206            void (*init)(struct machine *, struct memory *, struct pci_device *);
207    
208          if (pci_data == NULL) {          if (pci_data == NULL) {
209                  fatal("bus_pci_add(): pci_data == NULL!\n");                  fatal("bus_pci_add(): pci_data == NULL!\n");
210                  exit(1);                  exit(1);
211          }          }
212    
213            /*  Find the PCI device:  */
214            init = pci_lookup_initf(name);
215    
216          /*  Make sure this bus/device/function number isn't already in use:  */          /*  Make sure this bus/device/function number isn't already in use:  */
217          new_device = pci_data->first_device;          pd = pci_data->first_device;
218          while (new_device != NULL) {          while (pd != NULL) {
219                  if (new_device->bus == bus &&                  if (pd->bus == bus && pd->device == device &&
220                      new_device->device == device &&                      pd->function == function) {
                     new_device->function == function) {  
221                          fatal("bus_pci_add(): (bus %i, device %i, function"                          fatal("bus_pci_add(): (bus %i, device %i, function"
222                              " %i) already in use\n", bus, device, function);                              " %i) already in use\n", bus, device, function);
223                          return;                          exit(1);
224                  }                  }
225                  new_device = new_device->next;                  pd = pd->next;
226          }          }
227    
228          new_device = malloc(sizeof(struct pci_device));          pd = malloc(sizeof(struct pci_device));
229          if (new_device == NULL) {          if (pd == NULL) {
230                  fprintf(stderr, "out of memory\n");                  fprintf(stderr, "out of memory\n");
231                  exit(1);                  exit(1);
232          }          }
233    
234          memset(new_device, 0, sizeof(struct pci_device));          memset(pd, 0, sizeof(struct pci_device));
         new_device->bus           = bus;  
         new_device->device        = device;  
         new_device->function      = function;  
         new_device->init          = init;  
         new_device->read_register = read_register;  
235    
236          /*  Add the new device first in the PCI bus' chain:  */          /*  Add the new device first in the PCI bus' chain:  */
237          new_device->next = pci_data->first_device;          pd->next = pci_data->first_device;
238          pci_data->first_device = new_device;          pci_data->first_device = pd;
239    
240            pd->pcibus   = pci_data;
241            pd->name     = strdup(name);
242            pd->bus      = bus;
243            pd->device   = device;
244            pd->function = function;
245    
246            /*
247             *  Initialize with some default values:
248             *
249             *  TODO:  The command status register is best to set up per device.
250             *  The size registers should also be set up on a per-device basis.
251             */
252            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)
255                    PCI_SET_DATA_SIZE(ofs, 0x00100000 - 1);
256    
257            if (init == NULL) {
258                    fatal("No init function for PCI device \"%s\"?\n", name);
259                    exit(1);
260            }
261    
262          /*  Call the PCI device' init function:  */          /*  Call the PCI device' init function:  */
263          if (init != NULL)          init(machine, mem, pd);
264                  init(machine, mem);  }
265    
266    
267    /*
268     *  allocate_device_space():
269     *
270     *  Used by glue code (see below) to allocate space for a PCI device.
271     *
272     *  The returned values in portp and memp are the actual (emulated) addresses
273     *  that the device should use. (Normally only one of these is actually used.)
274     *
275     *  TODO: PCI irqs?
276     */
277    static void allocate_device_space(struct pci_device *pd,
278            uint64_t portsize, uint64_t memsize,
279            uint64_t *portp, uint64_t *memp)
280    {
281            uint64_t port, mem;
282    
283            /*  Calculate an aligned starting port:  */
284            port = pd->pcibus->cur_pci_portbase;
285            if (portsize != 0) {
286                    port = ((port - 1) | (portsize - 1)) + 1;
287                    pd->pcibus->cur_pci_portbase = port;
288                    PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset,
289                        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:  */
296            mem = pd->pcibus->cur_pci_membase;
297            if (memsize != 0) {
298                    mem = ((mem - 1) | (memsize - 1)) + 1;
299                    pd->pcibus->cur_pci_membase = mem;
300                    PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset, mem);
301                    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;
307            *memp  = mem  + pd->pcibus->pci_actual_mem_offset;
308    
309            if (verbose >= 2) {
310                    debug("pci device '%s' at", pd->name);
311                    if (portsize != 0)
312                            debug(" port 0x%llx-0x%llx", (long long)pd->pcibus->
313                                cur_pci_portbase, (long long)(pd->pcibus->
314                                cur_pci_portbase + portsize - 1));
315                    if (memsize != 0)
316                            debug(" mem 0x%llx-0x%llx", (long long)pd->pcibus->
317                                cur_pci_membase, (long long)(pd->pcibus->
318                                cur_pci_membase + memsize - 1));
319                    debug("\n");
320            }
321    
322            pd->pcibus->cur_pci_portbase += portsize;
323            pd->pcibus->cur_pci_membase += memsize;
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    
# Line 200  void bus_pci_add(struct machine *machine Line 360  void bus_pci_add(struct machine *machine
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.
366     *
367     *  pci_portbase, pci_membase, and pci_irqbase are the port, memory, and
368     *  interrupt bases for PCI devices (as found in the configuration registers).
369     *
370     *  pci_actual_io_offset and pci_actual_mem_offset are the offset from
371     *  the values in the configuration registers to the actual (emulated) device.
372     *
373     *  isa_portbase, isa_membase, and isa_irqbase are the port, memory, and
374     *  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,
378            uint64_t pci_portbase, uint64_t pci_membase, int pci_irqbase,
379            uint64_t isa_portbase, uint64_t isa_membase, int isa_irqbase)
380  {  {
381          struct pci_data *d;          struct pci_data *d;
382    
# Line 212  struct pci_data *bus_pci_init(int irq_nr Line 386  struct pci_data *bus_pci_init(int irq_nr
386                  exit(1);                  exit(1);
387          }          }
388          memset(d, 0, sizeof(struct pci_data));          memset(d, 0, sizeof(struct pci_data));
389          d->irq_nr = irq_nr;          d->irq_nr                = irq_nr;
390            d->pci_actual_io_offset  = pci_actual_io_offset;
391            d->pci_actual_mem_offset = pci_actual_mem_offset;
392            d->pci_portbase          = pci_portbase;
393            d->pci_membase           = pci_membase;
394            d->pci_irqbase           = pci_irqbase;
395            d->isa_portbase          = isa_portbase;
396            d->isa_membase           = isa_membase;
397            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:  */
403            d->cur_pci_portbase = d->pci_portbase + 0x10000;
404            d->cur_pci_membase  = d->pci_membase + 0x10000;
405    
406          return d;          return d;
407  }  }
408    
409    
410    
411    /******************************************************************************
412     *                                                                            *
413     *  The following is glue code for PCI controllers and devices. The glue      *
414     *  code does the minimal stuff necessary to get an emulated OS to detect     *
415     *  the device (i.e. set up PCI configuration registers), and then if         *
416     *  necessary adds a "normal" device.                                         *
417     *                                                                            *
418     ******************************************************************************/
419    
420    
421    
422    /*
423     *  Integraphics Systems "igsfb" Framebuffer (graphics) card.
424     *
425     *  TODO
426     */
427    
428    #define PCI_VENDOR_INTEGRAPHICS         0x10ea
429    
430    PCIINIT(igsfb)
431    {
432            PCI_SET_DATA(PCI_ID_REG,
433                PCI_ID_CODE(PCI_VENDOR_INTEGRAPHICS, 0x2010));
434    
435            PCI_SET_DATA(PCI_CLASS_REG,
436                PCI_CLASS_CODE(PCI_CLASS_DISPLAY,
437                PCI_SUBCLASS_DISPLAY_VGA, 0) + 0x01);
438    
439            /*  TODO  */
440            PCI_SET_DATA(0x10, 0x08000000);
441    
442            dev_vga_init(machine, mem, pd->pcibus->isa_membase + 0xa0000,
443                0x88800000 + 0x3c0, machine->machine_name);
444    }
445    
446    
447    
448    /*
449     *  S3 ViRGE graphics.
450     *
451     *  TODO: Only emulates a standard VGA card, so far.
452     */
453    
454    #define PCI_VENDOR_S3                   0x5333
455    #define PCI_PRODUCT_S3_VIRGE            0x5631
456    #define PCI_PRODUCT_S3_VIRGE_DX         0x8a01
457    
458    PCIINIT(s3_virge)
459    {
460            PCI_SET_DATA(PCI_ID_REG,
461                PCI_ID_CODE(PCI_VENDOR_S3, PCI_PRODUCT_S3_VIRGE_DX));
462    
463            PCI_SET_DATA(PCI_CLASS_REG,
464                PCI_CLASS_CODE(PCI_CLASS_DISPLAY,
465                PCI_SUBCLASS_DISPLAY_VGA, 0) + 0x01);
466    
467            dev_vga_init(machine, mem, pd->pcibus->isa_membase + 0xa0000,
468                pd->pcibus->isa_portbase + 0x3c0, machine->machine_name);
469    }
470    
471    
472    
473    /*
474     *  Acer Labs M5229 PCI-IDE (UDMA) controller.
475     *  Acer Labs M1543 PCI->ISA bridge.
476     */
477    
478    #define PCI_VENDOR_ALI                  0x10b9
479    #define PCI_PRODUCT_ALI_M1543           0x1533  /*  NOTE: not 1543  */
480    #define PCI_PRODUCT_ALI_M5229           0x5229
481    
482    PCIINIT(ali_m1543)
483    {
484            PCI_SET_DATA(PCI_ID_REG,
485                PCI_ID_CODE(PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M1543));
486    
487            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
488                PCI_SUBCLASS_BRIDGE_ISA, 0) + 0xc3);
489    
490            PCI_SET_DATA(PCI_BHLC_REG,
491                PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
492    
493            /*  Linux uses these to detect which IRQ the IDE controller uses:  */
494            PCI_SET_DATA(0x44, 0x0000000e);
495            PCI_SET_DATA(0x58, 0x00000003);
496    }
497    
498    PCIINIT(ali_m5229)
499    {
500            char tmpstr[300];
501    
502            PCI_SET_DATA(PCI_ID_REG,
503                PCI_ID_CODE(PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M5229));
504    
505            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
506                PCI_SUBCLASS_MASS_STORAGE_IDE, 0x60) + 0xc1);
507    
508            if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
509                diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
510                    snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
511                        (long long)(pd->pcibus->isa_portbase + 0x1f0),
512                        pd->pcibus->isa_irqbase + 14);
513                    device_add(machine, tmpstr);
514            }
515    
516            /*  The secondary channel is disabled. TODO: fix this.  */
517    }
518    
519    
520    
521    /*
522     *  Adaptec AHC SCSI controller.
523     */
524    
525    #define PCI_VENDOR_ADP  0x9004          /* Adaptec */
526    #define PCI_VENDOR_ADP2 0x9005          /* Adaptec (2nd PCI Vendor ID) */
527    #define PCI_PRODUCT_ADP_2940U   0x8178          /* AHA-2940 Ultra */
528    #define PCI_PRODUCT_ADP_2940UP  0x8778          /* AHA-2940 Ultra Pro */
529    
530    PCIINIT(ahc)
531    {
532            /*  Numbers taken from a Adaptec 2940U:  */
533            /*  http://mail-index.netbsd.org/netbsd-bugs/2000/04/29/0000.html  */
534    
535            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_ADP,
536                PCI_PRODUCT_ADP_2940U));
537    
538            PCI_SET_DATA(PCI_COMMAND_STATUS_REG, 0x02900007);
539    
540            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
541                PCI_SUBCLASS_MASS_STORAGE_SCSI, 0) + 0x01);
542    
543            PCI_SET_DATA(PCI_BHLC_REG, 0x00004008);
544    
545            /*  1 = type i/o. 0x0000e801;  address?  */
546            /*  second address reg = 0xf1002000?  */
547            PCI_SET_DATA(PCI_MAPREG_START + 0x00, 0x00000001);
548            PCI_SET_DATA(PCI_MAPREG_START + 0x04, 0x00000000);
549    
550            PCI_SET_DATA(PCI_MAPREG_START + 0x08, 0x00000000);
551            PCI_SET_DATA(PCI_MAPREG_START + 0x0c, 0x00000000);
552            PCI_SET_DATA(PCI_MAPREG_START + 0x10, 0x00000000);
553            PCI_SET_DATA(PCI_MAPREG_START + 0x14, 0x00000000);
554            PCI_SET_DATA(PCI_MAPREG_START + 0x18, 0x00000000);
555    
556            /*  Subsystem vendor ID? 0x78819004?  */
557            PCI_SET_DATA(PCI_MAPREG_START + 0x1c, 0x00000000);
558    
559            PCI_SET_DATA(0x30, 0xef000000);
560            PCI_SET_DATA(PCI_CAPLISTPTR_REG, 0x000000dc);
561            PCI_SET_DATA(0x38, 0x00000000);
562            PCI_SET_DATA(PCI_INTERRUPT_REG, 0x08080109);    /*  interrupt pin A  */
563    
564            /*
565             *  TODO:  this address is based on what NetBSD/sgimips uses
566             *  on SGI IP32 (O2). Fix this!
567             */
568    
569            device_add(machine, "ahc addr=0x18000000");
570    
571            /*  OpenBSD/sgi snapshots sometime between 2005-03-11 and
572                2005-04-04 changed to using 0x1a000000:  */
573            dev_ram_init(machine, 0x1a000000, 0x2000000, DEV_RAM_MIRROR,
574                0x18000000);
575    }
576    
577    
578    
579    /*
580     *  Galileo Technology GT-64xxx PCI controller.
581     *
582     *      GT-64011        Used in Cobalt machines.
583     *      GT-64120        Used in evbmips machines (Malta).
584     *
585     *  NOTE: This works in the opposite way compared to other devices; the PCI
586     *  device is added from the normal device instead of the other way around.
587     */
588    
589    #define PCI_VENDOR_GALILEO           0x11ab    /* Galileo Technology */
590    #define PCI_PRODUCT_GALILEO_GT64011  0x4146    /* GT-64011 System Controller */
591    #define PCI_PRODUCT_GALILEO_GT64120  0x4620    /* GT-64120 */
592    #define PCI_PRODUCT_GALILEO_GT64260  0x6430    /* GT-64260 */
593    
594    PCIINIT(gt64011)
595    {
596            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_GALILEO,
597                PCI_PRODUCT_GALILEO_GT64011));
598    
599            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
600                PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x01);       /*  Revision 1  */
601    }
602    
603    PCIINIT(gt64120)
604    {
605            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_GALILEO,
606                PCI_PRODUCT_GALILEO_GT64120));
607    
608            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
609                PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x02);       /*  Revision 2?  */
610    
611            switch (machine->machine_type) {
612            case MACHINE_EVBMIPS:
613                    PCI_SET_DATA(PCI_MAPREG_START + 0x10, 0x1be00000);
614                    break;
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 31244   Serial ATA Controller
631     *  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
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
643    #define PCI_PRODUCT_INTEL_82371AB_IDE   0x7111
644    #define PCI_PRODUCT_INTEL_SIO           0x0484
645    
646    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,
698                PCI_PRODUCT_INTEL_82371AB_ISA));
699    
700            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
701                PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x01);        /*  Rev 1  */
702    
703            PCI_SET_DATA(PCI_BHLC_REG,
704                PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
705    }
706    
707    PCIINIT(i82378zb)
708    {
709            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
710                PCI_PRODUCT_INTEL_SIO));
711    
712            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
713                PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x43);
714    
715            PCI_SET_DATA(PCI_BHLC_REG,
716                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(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];
759    
760            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
761                PCI_PRODUCT_INTEL_82371AB_IDE));
762    
763            /*  Possibly not correct:  */
764            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
765                PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x01);
766    
767            /*  PIIX_IDETIM (see NetBSD's pciide_piix_reg.h)  */
768            /*  channel 0 and 1 enabled as IDE  */
769            PCI_SET_DATA(0x40, 0x80008000);
770    
771            if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
772                diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
773                    snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
774                        (long long)(pd->pcibus->isa_portbase + 0x1f0),
775                        pd->pcibus->isa_irqbase + 14);
776                    device_add(machine, tmpstr);
777            }
778    
779            if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
780                diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
781                    snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
782                        (long long)(pd->pcibus->isa_portbase + 0x170),
783                        pd->pcibus->isa_irqbase + 15);
784                    device_add(machine, tmpstr);
785            }
786    }
787    
788    
789    
790    /*
791     *  IBM ISA bridge (used by at least one PReP machine).
792     */
793    
794    #define PCI_VENDOR_IBM                  0x1014
795    #define PCI_PRODUCT_IBM_ISABRIDGE       0x000a
796    
797    PCIINIT(ibm_isa)
798    {
799            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_IBM,
800                PCI_PRODUCT_IBM_ISABRIDGE));
801    
802            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
803                PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x02);
804    
805            PCI_SET_DATA(PCI_BHLC_REG,
806                PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
807    }
808    
809    
810    
811    /*
812     *  Heuricon PCI host bridge for PM/PPC.
813     */
814    
815    #define PCI_VENDOR_HEURICON             0x1223
816    #define PCI_PRODUCT_HEURICON_PMPPC      0x000e
817    
818    PCIINIT(heuricon_pmppc)
819    {
820            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_HEURICON,
821                PCI_PRODUCT_HEURICON_PMPPC));
822    
823            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
824                PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x00);   /*  Revision?  */
825    
826            PCI_SET_DATA(PCI_BHLC_REG,
827                PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
828    }
829    
830    
831    
832    /*
833     *  VIATECH VT82C586 devices:
834     *
835     *      vt82c586_isa    PCI->ISA bridge
836     *      vt82c586_ide    IDE controller
837     *
838     *  TODO:  This more or less just a dummy device, so far.
839     */
840    
841    #define PCI_VENDOR_VIATECH                0x1106  /* VIA Technologies */
842    #define PCI_PRODUCT_VIATECH_VT82C586_IDE  0x1571  /* VT82C586 (Apollo VP)
843                                                         IDE Controller */
844    #define PCI_PRODUCT_VIATECH_VT82C586_ISA  0x0586  /* VT82C586 (Apollo VP)
845                                                         PCI-ISA Bridge */
846    
847    PCIINIT(vt82c586_isa)
848    {
849            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_VIATECH,
850                PCI_PRODUCT_VIATECH_VT82C586_ISA));
851    
852            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
853                PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x39);   /*  Revision 37 or 39  */
854    
855            PCI_SET_DATA(PCI_BHLC_REG,
856                PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
857    }
858    
859    PCIINIT(vt82c586_ide)
860    {
861            char tmpstr[100];
862    
863            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_VIATECH,
864                PCI_PRODUCT_VIATECH_VT82C586_IDE));
865    
866            /*  Possibly not correct:  */
867            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
868                PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x01);
869    
870            /*  APO_IDECONF  */
871            /*  channel 0 and 1 enabled  */
872            PCI_SET_DATA(0x40, 0x00000003);
873    
874            if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
875                diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
876                    snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
877                        (long long)(pd->pcibus->isa_portbase + 0x1f0),
878                        pd->pcibus->isa_irqbase + 14);
879                    device_add(machine, tmpstr);
880            }
881    
882            if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
883                diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
884                    snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
885                        (long long)(pd->pcibus->isa_portbase + 0x170),
886                        pd->pcibus->isa_irqbase + 15);
887                    device_add(machine, tmpstr);
888            }
889    }
890    
891    
892    
893    /*
894     *  Symphony Labs 83C553 PCI->ISA bridge.
895     *  Symphony Labs 82C105 PCIIDE controller.
896     */
897    
898    #define PCI_VENDOR_SYMPHONY             0x10ad
899    #define PCI_PRODUCT_SYMPHONY_83C553     0x0565
900    #define PCI_PRODUCT_SYMPHONY_82C105     0x0105
901    
902    PCIINIT(symphony_83c553)
903    {
904            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_SYMPHONY,
905                PCI_PRODUCT_SYMPHONY_83C553));
906    
907            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
908                PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x10);
909    
910            PCI_SET_DATA(PCI_BHLC_REG,
911                PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
912    }
913    
914    PCIINIT(symphony_82c105)
915    {
916            char tmpstr[100];
917    
918            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_SYMPHONY,
919                PCI_PRODUCT_SYMPHONY_82C105));
920    
921            /*  Possibly not correct:  */
922            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
923                PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x05);
924    
925            /*  APO_IDECONF  */
926            /*  channel 0 and 1 enabled  */
927            PCI_SET_DATA(0x40, 0x00000003);
928    
929            if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
930                diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
931                    snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
932                        (long long)(pd->pcibus->isa_portbase + 0x1f0),
933                        pd->pcibus->isa_irqbase + 14);
934                    device_add(machine, tmpstr);
935            }
936    
937            if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
938                diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
939                    snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
940                        (long long)(pd->pcibus->isa_portbase + 0x170),
941                        pd->pcibus->isa_irqbase + 15);
942                    device_add(machine, tmpstr);
943            }
944    }
945    
946    
947    
948    /*
949     *  DEC 21143 ("Tulip") PCI ethernet.
950     */
951    
952    #define PCI_VENDOR_DEC          0x1011 /* Digital Equipment */
953    #define PCI_PRODUCT_DEC_21142   0x0019 /* DECchip 21142/21143 10/100 Ethernet */
954    
955    PCIINIT(dec21143)
956    {
957            uint64_t port, memaddr;
958            int irq = 0;            /*  TODO  */
959            int pci_int_line = 0x101;
960            char tmpstr[200];
961    
962            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_DEC,
963                PCI_PRODUCT_DEC_21142));
964    
965            PCI_SET_DATA(PCI_COMMAND_STATUS_REG, 0x02000017);
966    
967            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_NETWORK,
968                PCI_SUBCLASS_NETWORK_ETHERNET, 0x00) + 0x41);
969    
970            PCI_SET_DATA(PCI_BHLC_REG, PCI_BHLC_CODE(0,0,0, 0x40,0));
971    
972            switch (machine->machine_type) {
973            case MACHINE_CATS:
974                    /*  CATS int 18 = PCI.  */
975                    irq = 18;
976                    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;
988            case MACHINE_PREP:
989                    irq = 32 + 10;
990                    pci_int_line = 0x20a;
991                    break;
992            case MACHINE_MVMEPPC:
993                    /*  TODO  */
994                    irq = 32 + 10;
995                    pci_int_line = 0x40a;
996                    break;
997            case MACHINE_PMPPC:
998                    /*  TODO, not working yet  */
999                    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;
1007            }
1008    
1009            PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000 | pci_int_line);
1010    
1011            allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);
1012    
1013            snprintf(tmpstr, sizeof(tmpstr), "dec21143 addr=0x%llx addr2=0x%llx "
1014                "irq=%i pci_little_endian=1", (long long)port, (long long)memaddr,
1015                irq);
1016            device_add(machine, tmpstr);
1017    }
1018    
1019    
1020    
1021    /*
1022     *  DEC 21030 "tga" graphics.
1023     */
1024    
1025    #define PCI_PRODUCT_DEC_21030  0x0004          /*  DECchip 21030 ("TGA")  */
1026    
1027    PCIINIT(dec21030)
1028    {
1029            uint64_t base = 0;
1030            char tmpstr[200];
1031    
1032            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_DEC,
1033                PCI_PRODUCT_DEC_21030));
1034    
1035            PCI_SET_DATA(PCI_COMMAND_STATUS_REG, 0x02800087);  /*  TODO  */
1036    
1037            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_DISPLAY,
1038                PCI_SUBCLASS_DISPLAY_VGA, 0x00) + 0x03);
1039    
1040            /*
1041             *  See http://mail-index.netbsd.org/port-arc/2001/08/13/0000.html
1042             *  for more info.
1043             */
1044    
1045            PCI_SET_DATA(PCI_BHLC_REG, 0x0000ff00);
1046    
1047            /*  8 = prefetchable  */
1048            PCI_SET_DATA(0x10, 0x00000008);
1049            PCI_SET_DATA(0x30, 0x08000001);
1050            PCI_SET_DATA(PCI_INTERRUPT_REG, 0x00000100);    /*  interrupt pin A?  */
1051    
1052            /*
1053             *  Experimental:
1054             *
1055             *  TODO: Base address, pci_little_endian, ...
1056             */
1057    
1058            switch (machine->machine_type) {
1059            case MACHINE_ARC:
1060                    base = 0x100000000ULL;
1061                    break;
1062            default:fatal("dec21030 in non-implemented machine type %i\n",
1063                        machine->machine_type);
1064                    exit(1);
1065            }
1066    
1067            snprintf(tmpstr, sizeof(tmpstr), "dec21030 addr=0x%llx",
1068                (long long)(base));
1069            device_add(machine, tmpstr);
1070    }
1071    
1072    
1073    
1074    /*
1075     *  Motorola MPC105 "Eagle" Host Bridge
1076     *
1077     *  Used in at least PReP and BeBox.
1078     */
1079    
1080    #define PCI_VENDOR_MOT                  0x1057
1081    #define PCI_PRODUCT_MOT_MPC105          0x0001
1082    
1083    PCIINIT(eagle)
1084    {
1085            PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_MOT,
1086                PCI_PRODUCT_MOT_MPC105));
1087    
1088            PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
1089                PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x24);
1090    
1091            PCI_SET_DATA(PCI_BHLC_REG,
1092                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.14  
changed lines
  Added in v.24

  ViewVC Help
Powered by ViewVC 1.1.26