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

  ViewVC Help
Powered by ViewVC 1.1.26