bus_pci.cc Source File

Back to the index.

bus_pci.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2018 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * COMMENT: Generic PCI bus framework
29  *
30  * This is not a normal "device", but is used by individual PCI controllers
31  * and devices.
32  *
33  * 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>
46 #include <stdlib.h>
47 #include <string.h>
48 
49 #define BUS_PCI_C
50 
51 #include "bus_isa.h"
52 #include "bus_pci.h"
53 #include "cpu.h"
54 #include "device.h"
55 #include "devices.h"
56 #include "diskimage.h"
57 #include "machine.h"
58 #include "memory.h"
59 #include "misc.h"
60 #include "wdc.h"
61 
62 #include "thirdparty/cpc700reg.h"
63 
64 extern int verbose;
65 
66 // #ifdef UNSTABLE_DEVEL
67 // #define debug fatal
68 // #endif
69 
70 
71 /*
72  * bus_pci_decompose_1():
73  *
74  * Helper function for decomposing Mechanism 1 tags.
75  */
76 void bus_pci_decompose_1(uint32_t t, int *bus, int *dev, int *func, int *reg)
77 {
78  *bus = (t >> 16) & 0xff;
79  *dev = (t >> 11) & 0x1f;
80  *func = (t >> 8) & 0x7;
81  *reg = t & 0xff;
82 
83  /* Warn about unaligned register access: */
84  if (t & 3)
85  fatal("[ bus_pci_decompose_1: WARNING: reg = 0x%02x ]\n",
86  t & 0xff);
87 }
88 
89 
90 /*
91  * bus_pci_data_access():
92  *
93  * Reads from or writes to the PCI configuration registers of a device.
94  */
95 void bus_pci_data_access(struct cpu *cpu, struct pci_data *pci_data,
96  uint64_t *data, int len, int writeflag)
97 {
98  struct pci_device *dev;
99  unsigned char *cfg_base;
100  uint64_t x, idata = *data;
101  int i;
102 
103  /* Scan through the list of pci_device entries. */
104  dev = pci_data->first_device;
105  while (dev != NULL) {
106  if (dev->bus == pci_data->cur_bus &&
107  dev->function == pci_data->cur_func &&
108  dev->device == pci_data->cur_device)
109  break;
110  dev = dev->next;
111  }
112 
113  /* No device? Then return emptiness. */
114  if (dev == NULL) {
115  if (writeflag == MEM_READ) {
116  if (pci_data->cur_reg == 0)
117  *data = (uint64_t) -1;
118  else
119  *data = 0;
120  } else {
121  fatal("[ bus_pci_data_access(): write to non-existant"
122  " device, bus %i func %i device %i ]\n",
123  pci_data->cur_bus, pci_data->cur_func,
124  pci_data->cur_device);
125  }
126  return;
127  }
128 
129  /* Return normal config data, or length data? */
130  if (pci_data->last_was_write_ffffffff &&
131  pci_data->cur_reg >= PCI_MAPREG_START &&
132  pci_data->cur_reg <= PCI_MAPREG_END - 4)
133  cfg_base = dev->cfg_mem_size;
134  else
135  cfg_base = dev->cfg_mem;
136 
137  /* Read data as little-endian: */
138  x = 0;
139  for (i=len-1; i>=0; i--) {
140  int ofs = pci_data->cur_reg + i;
141  x <<= 8;
142  x |= cfg_base[ofs & (PCI_CFG_MEM_SIZE - 1)];
143  }
144 
145  /* Register write: */
146  if (writeflag == MEM_WRITE) {
147  debug("[ bus_pci: write to PCI DATA: data = 0x%08llx ]\n",
148  (long long)idata);
149  if (idata == 0xffffffffULL &&
150  pci_data->cur_reg >= PCI_MAPREG_START &&
151  pci_data->cur_reg <= PCI_MAPREG_END - 4) {
152  pci_data->last_was_write_ffffffff = 1;
153  return;
154  }
155 
156  if (dev->cfg_reg_write == NULL ||
157  dev->cfg_reg_write(dev, pci_data->cur_reg, *data) == 0) {
158  /* Print a warning for unhandled writes: */
159  debug("[ bus_pci: write to PCI DATA: data = 0x%08llx"
160  " (current value = 0x%08llx); NOT YET"
161  " SUPPORTED. bus %i, device %i, function %i (%s)"
162  " register 0x%02x ]\n", (long long)idata,
163  (long long)x, pci_data->cur_bus,
164  pci_data->cur_device, pci_data->cur_func,
165  dev->name, pci_data->cur_reg);
166 
167  /* Special warning, to detect if NetBSD's special
168  detection of PCI devices fails: */
169  if (pci_data->cur_reg == PCI_COMMAND_STATUS_REG
170  && !((*data) & PCI_COMMAND_IO_ENABLE)) {
171  fatal("\n[ NetBSD PCI detection stuff not"
172  " yet implemented for device '%s' ]\n",
173  dev->name);
174  }
175  }
176  return;
177  }
178 
179  /* Register read: */
180  *data = x;
181 
182  pci_data->last_was_write_ffffffff = 0;
183 
184  debug("[ bus_pci: read from PCI DATA, bus %i, device "
185  "%i, function %i (%s) register 0x%02x: (len=%i) 0x%08lx ]\n",
186  pci_data->cur_bus, pci_data->cur_device, pci_data->cur_func,
187  dev->name, pci_data->cur_reg, len, (long)*data);
188 }
189 
190 
191 /*
192  * bus_pci_setaddr():
193  *
194  * Sets the address in preparation for a PCI register transfer.
195  */
196 void bus_pci_setaddr(struct cpu *cpu, struct pci_data *pci_data,
197  int bus, int device, int function, int reg)
198 {
199  if (cpu == NULL || pci_data == NULL) {
200  fatal("bus_pci_setaddr(): NULL ptr\n");
201  exit(1);
202  }
203 
204  pci_data->cur_bus = bus;
205  pci_data->cur_device = device;
206  pci_data->cur_func = function;
207  pci_data->cur_reg = reg;
208 }
209 
210 
211 /*
212  * bus_pci_add():
213  *
214  * Add a PCI device to a bus_pci device.
215  */
216 void bus_pci_add(struct machine *machine, struct pci_data *pci_data,
217  struct memory *mem, int bus, int device, int function,
218  const char *name)
219 {
220  struct pci_device *pd;
221  int ofs;
222  void (*init)(struct machine *, struct memory *, struct pci_device *);
223 
224  if (pci_data == NULL) {
225  fatal("bus_pci_add(): pci_data == NULL!\n");
226  abort();
227  }
228 
229  /* Find the PCI device: */
230  init = pci_lookup_initf(name);
231 
232  /* Make sure this bus/device/function number isn't already in use: */
233  pd = pci_data->first_device;
234  while (pd != NULL) {
235  if (pd->bus == bus && pd->device == device &&
236  pd->function == function) {
237  fatal("bus_pci_add(): (bus %i, device %i, function"
238  " %i) already in use\n", bus, device, function);
239  exit(1);
240  }
241  pd = pd->next;
242  }
243 
244  CHECK_ALLOCATION(pd = (struct pci_device *) malloc(sizeof(struct pci_device)));
245  memset(pd, 0, sizeof(struct pci_device));
246 
247  /* Add the new device first in the PCI bus' chain: */
248  pd->next = pci_data->first_device;
249  pci_data->first_device = pd;
250 
251  CHECK_ALLOCATION(pd->name = strdup(name));
252  pd->pcibus = pci_data;
253  pd->bus = bus;
254  pd->device = device;
255  pd->function = function;
256 
257  /*
258  * Initialize with some default values:
259  *
260  * TODO: The command status register is best to set up per device.
261  * The size registers should also be set up on a per-device basis.
262  */
263  PCI_SET_DATA(PCI_COMMAND_STATUS_REG,
265  for (ofs = PCI_MAPREG_START; ofs < PCI_MAPREG_END; ofs += 4)
266  PCI_SET_DATA_SIZE(ofs, 0x00100000 - 1);
267 
268  if (init == NULL) {
269  fatal("No init function for PCI device \"%s\"?\n", name);
270  exit(1);
271  }
272 
273  /* Call the PCI device' init function: */
274  init(machine, mem, pd);
275 }
276 
277 
278 /*
279  * allocate_device_space():
280  *
281  * Used by glue code (see below) to allocate space for a PCI device.
282  *
283  * The returned values in portp and memp are the actual (emulated) addresses
284  * that the device should use. (Normally only one of these is actually used.)
285  *
286  * TODO: PCI irqs?
287  */
288 static void allocate_device_space(struct pci_device *pd,
289  uint64_t portsize, uint64_t memsize,
290  uint64_t *portp, uint64_t *memp)
291 {
292  uint64_t port, mem;
293 
294  /* Calculate an aligned starting port: */
295  port = pd->pcibus->cur_pci_portbase;
296  if (portsize != 0) {
297  port = ((port - 1) | (portsize - 1)) + 1;
298  pd->pcibus->cur_pci_portbase = port;
299  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset,
300  port | PCI_MAPREG_TYPE_IO);
301  PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,
302  ((portsize - 1) & ~0xf) | 0xd);
303  pd->cur_mapreg_offset += sizeof(uint32_t);
304  }
305 
306  /* Calculate an aligned starting memory location: */
307  mem = pd->pcibus->cur_pci_membase;
308  if (memsize != 0) {
309  mem = ((mem - 1) | (memsize - 1)) + 1;
310  pd->pcibus->cur_pci_membase = mem;
311  PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset, mem);
312  PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,
313  ((memsize - 1) & ~0xf) | 0x0);
314  pd->cur_mapreg_offset += sizeof(uint32_t);
315  }
316 
317  *portp = port + pd->pcibus->pci_actual_io_offset;
318  *memp = mem + pd->pcibus->pci_actual_mem_offset;
319 
320  if (verbose >= 2) {
321  debug("pci device '%s' at", pd->name);
322  if (portsize != 0)
323  debug(" port 0x%llx-0x%llx", (long long)pd->pcibus->
324  cur_pci_portbase, (long long)(pd->pcibus->
325  cur_pci_portbase + portsize - 1));
326  if (memsize != 0)
327  debug(" mem 0x%llx-0x%llx", (long long)pd->pcibus->
328  cur_pci_membase, (long long)(pd->pcibus->
329  cur_pci_membase + memsize - 1));
330  debug("\n");
331  }
332 
333  pd->pcibus->cur_pci_portbase += portsize;
334  pd->pcibus->cur_pci_membase += memsize;
335 }
336 
337 
338 /*
339  * bus_pci_init():
340  *
341  * This doesn't register a device, but instead returns a pointer to a struct
342  * which should be passed to other bus_pci functions when accessing the bus.
343  *
344  * irq_path is the interrupt path to the PCI controller.
345  *
346  * pci_portbase, pci_membase, and pci_irqbase are the port, memory, and
347  * interrupt bases for PCI devices (as found in the configuration registers).
348  *
349  * pci_actual_io_offset and pci_actual_mem_offset are the offset from
350  * the values in the configuration registers to the actual (emulated) device.
351  *
352  * isa_portbase, isa_membase, and isa_irqbase are the port, memory, and
353  * interrupt bases for legacy ISA devices.
354  */
355 struct pci_data *bus_pci_init(struct machine *machine, const char *irq_path,
356  uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset,
357  uint64_t pci_portbase, uint64_t pci_membase, const char *pci_irqbase,
358  uint64_t isa_portbase, uint64_t isa_membase, const char *isa_irqbase)
359 {
360  struct pci_data *d;
361 
362  CHECK_ALLOCATION(d = (struct pci_data *) malloc(sizeof(struct pci_data)));
363  memset(d, 0, sizeof(struct pci_data));
364 
365  CHECK_ALLOCATION(d->irq_path = strdup(irq_path));
366  CHECK_ALLOCATION(d->irq_path_isa = strdup(isa_irqbase));
367  CHECK_ALLOCATION(d->irq_path_pci = strdup(pci_irqbase));
368 
369  d->pci_actual_io_offset = pci_actual_io_offset;
370  d->pci_actual_mem_offset = pci_actual_mem_offset;
371  d->pci_portbase = pci_portbase;
372  d->pci_membase = pci_membase;
373  d->isa_portbase = isa_portbase;
374  d->isa_membase = isa_membase;
375 
376  d->cur_pci_portbase = d->pci_portbase;
377  d->cur_pci_membase = d->pci_membase;
378 
379  /* Assume that the first 64KB could be used by legacy ISA devices: */
380  if (d->isa_portbase != 0 || d->isa_membase != 0) {
381  d->cur_pci_portbase += 0x10000;
382  d->cur_pci_membase += 0x10000;
383  }
384 
385  return d;
386 }
387 
388 
389 
390 /******************************************************************************
391  * *
392  * The following is glue code for PCI controllers and devices. The glue *
393  * code does the minimal stuff necessary to get an emulated OS to detect *
394  * the device (i.e. set up PCI configuration registers), and then if *
395  * necessary adds a "normal" device. *
396  * *
397  ******************************************************************************/
398 
399 
400 
401 /*
402  * Integraphics Systems "igsfb" Framebuffer (graphics) card, used in at
403  * least the NetWinder.
404  */
405 
406 #define PCI_VENDOR_INTEGRAPHICS 0x10ea
407 
408 PCIINIT(igsfb)
409 {
410  char tmpstr[2000];
411 
412  PCI_SET_DATA(PCI_ID_REG,
414 
415  PCI_SET_DATA(PCI_CLASS_REG,
417  PCI_SUBCLASS_DISPLAY_VGA, 0) + 0x01);
418 
419  /* TODO */
420  PCI_SET_DATA(0x10, 0x08000000);
421 
422  snprintf(tmpstr, sizeof(tmpstr), "igsfb addr=0x%llx",
423  (long long)(pd->pcibus->isa_membase + 0x08000000));
424  device_add(machine, tmpstr);
425 }
426 
427 
428 
429 /*
430  * S3 ViRGE graphics.
431  *
432  * TODO: Only emulates a standard VGA card, so far.
433  */
434 
435 #define PCI_VENDOR_S3 0x5333
436 #define PCI_PRODUCT_S3_VIRGE 0x5631
437 #define PCI_PRODUCT_S3_VIRGE_DX 0x8a01
438 
439 PCIINIT(s3_virge)
440 {
441  PCI_SET_DATA(PCI_ID_REG,
443 
444  PCI_SET_DATA(PCI_CLASS_REG,
446  PCI_SUBCLASS_DISPLAY_VGA, 0) + 0x01);
447 
448  dev_vga_init(machine, mem, pd->pcibus->isa_membase + 0xa0000,
449  pd->pcibus->isa_portbase + 0x3c0, machine->machine_name);
450 }
451 
452 
453 
454 /*
455  * Acer Labs M5229 PCI-IDE (UDMA) controller.
456  * Acer Labs M1543 PCI->ISA bridge.
457  */
458 
459 #define PCI_VENDOR_ALI 0x10b9
460 #define PCI_PRODUCT_ALI_M1543 0x1533 /* NOTE: not 1543 */
461 #define PCI_PRODUCT_ALI_M5229 0x5229
462 
463 PCIINIT(ali_m1543)
464 {
465  PCI_SET_DATA(PCI_ID_REG,
467 
469  PCI_SUBCLASS_BRIDGE_ISA, 0) + 0xc3);
470 
471  PCI_SET_DATA(PCI_BHLC_REG,
472  PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
473 
474  /* Linux uses these to detect which IRQ the IDE controller uses: */
475  PCI_SET_DATA(0x44, 0x0000000e);
476  PCI_SET_DATA(0x58, 0x00000003);
477 
478  switch (machine->machine_type) {
479  case MACHINE_CATS:
480  bus_isa_init(machine, pd->pcibus->irq_path_isa,
482  0x7c000000, 0x80000000);
483  break;
484  default:fatal("ali_m1543 init: unimplemented machine type\n");
485  exit(1);
486  }
487 }
488 
489 PCIINIT(ali_m5229)
490 {
491  char tmpstr[2000], irqstr[1000];
492 
493  PCI_SET_DATA(PCI_ID_REG,
495 
497  PCI_SUBCLASS_MASS_STORAGE_IDE, 0x60) + 0xc1);
498 
499  switch (machine->machine_type) {
500  case MACHINE_CATS:
501  /* CATS ISA interrupts are at footbridge irq 10: */
502  snprintf(irqstr, sizeof(irqstr), "%s.10.isa",
503  pd->pcibus->irq_path);
504  break;
505  default:fatal("ali_m5229 init: unimplemented machine type\n");
506  exit(1);
507  }
508 
511  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s.%i",
512  (long long)(pd->pcibus->isa_portbase + 0x1f0),
513  irqstr, 14);
514  device_add(machine, tmpstr);
515  }
516 
517  /* The secondary channel is disabled. TODO: fix this. */
518 }
519 
520 
521 
522 /*
523  * Adaptec AHC SCSI controller, with values as they are in my SGI O2.
524  */
525 
526 #define PCI_VENDOR_ADP 0x9004 /* Adaptec */
527 #define PCI_PRODUCT_ADP_AIC7880 0x8078 /* AIC7880 */
528 
530 {
531  PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_ADP,
533 
534  PCI_SET_DATA(PCI_COMMAND_STATUS_REG, 0x02800046);
535 
537  PCI_SUBCLASS_MASS_STORAGE_SCSI, 0) + 0x01);
538 
539  PCI_SET_DATA(PCI_BHLC_REG, 0x00001020);
540 
541  PCI_SET_DATA(PCI_MAPREG_START + 0x00, 0xffffff01);
542  PCI_SET_DATA(PCI_MAPREG_START + 0x04, 0x80001000);
543  PCI_SET_DATA(PCI_MAPREG_START + 0x08, 0x00000000);
544  PCI_SET_DATA(PCI_MAPREG_START + 0x0c, 0x00000000);
545  PCI_SET_DATA(PCI_MAPREG_START + 0x10, 0x00000000);
546  PCI_SET_DATA(PCI_MAPREG_START + 0x14, 0x00000000);
547  PCI_SET_DATA(PCI_MAPREG_START + 0x18, 0x00000000);
548 
549  PCI_SET_DATA(PCI_MAPREG_START + 0x1c, 0x00000000);
550 
551  PCI_SET_DATA(0x30, 0x80010000);
552  PCI_SET_DATA(PCI_INTERRUPT_REG, 0x08080100); /* interrupt pin */
553 
554  PCI_SET_DATA(0x40, 0x00000180);
555  PCI_SET_DATA(0x40, 0x00000180);
556 
557 
558  /*
559  * TODO: this address is based on what NetBSD/sgimips uses
560  * on SGI IP32 (O2). Fix this! Allow devices to move? Or
561  * implement PCI space redirection at least!
562  */
563 
564  // device_add(machine, "ahc addr=0x1a001000");
565  device_add(machine, "ahc addr=0x18002000");
566 }
567 
568 
569 
570 /*
571  * Galileo Technology GT-64xxx PCI controller.
572  *
573  * GT-64011 Used in Cobalt machines.
574  * GT-64120 Used in evbmips machines (Malta).
575  *
576  * NOTE: This works in the opposite way compared to other devices; the PCI
577  * device is added from the normal device instead of the other way around.
578  */
579 
580 #define PCI_VENDOR_GALILEO 0x11ab /* Galileo Technology */
581 #define PCI_PRODUCT_GALILEO_GT64011 0x4146 /* GT-64011 System Controller */
582 #define PCI_PRODUCT_GALILEO_GT64120 0x4620 /* GT-64120 */
583 #define PCI_PRODUCT_GALILEO_GT64260 0x6430 /* GT-64260 */
584 
585 PCIINIT(gt64011)
586 {
589 
591  PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x01); /* Revision 1 */
592 }
593 
594 PCIINIT(gt64120)
595 {
598 
600  PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x02); /* Revision 2? */
601 
602  switch (machine->machine_type) {
603  case MACHINE_EVBMIPS:
604  PCI_SET_DATA(PCI_MAPREG_START + 0x10, 0x1be00000);
605  break;
606  }
607 }
608 
609 PCIINIT(gt64260)
610 {
613 
615  PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x01); /* Revision 1? */
616 }
617 
618 
619 
620 /*
621  * AMD PCnet Ethernet card.
622  *
623  * "Am79c970A PCnet-PCI II rev 0" or similar.
624  */
625 
626 #define PCI_VENDOR_AMD 0x1022 /* Advanced Micro Devices */
627 #define PCI_PRODUCT_AMD_PCNET_PCI 0x2000 /* PCnet-PCI Ethernet */
628 
630 {
631  int irq;
632 
633  PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_AMD,
635 
637  PCI_SUBCLASS_NETWORK_ETHERNET, 0) + 0x00); /* Revision 0 */
638 
639  switch (machine->machine_type) {
640 
641  case MACHINE_EVBMIPS:
642  irq = (1 << 8) + 10; /* TODO */
643  break;
644 
645  default:fatal("pcn in non-implemented machine type %i\n",
647  exit(1);
648  }
649 
650  PCI_SET_DATA(PCI_INTERRUPT_REG, 0x01100000 | irq);
651 
652  /*
653  * TODO: Add the pcn device here. The pcn device will need to work as
654  * a wrapper for dev_le + all the DMA magic and whatever is required.
655  * It's too much to implement right now.
656  */
657 }
658 
659 
660 
661 /*
662  * Intel 31244 Serial ATA Controller
663  * Intel 82371SB PIIX3 PCI-ISA bridge
664  * Intel 82371AB PIIX4 PCI-ISA bridge
665  * Intel 82371SB IDE controller
666  * Intel 82371AB IDE controller
667  * Intel 82378ZB System I/O controller.
668  */
669 
670 #define PCI_VENDOR_INTEL 0x8086
671 #define PCI_PRODUCT_INTEL_31244 0x3200
672 #define PCI_PRODUCT_INTEL_82371SB_ISA 0x7000
673 #define PCI_PRODUCT_INTEL_82371SB_IDE 0x7010
674 #define PCI_PRODUCT_INTEL_82371AB_ISA 0x7110
675 #define PCI_PRODUCT_INTEL_82371AB_IDE 0x7111
676 #define PCI_PRODUCT_INTEL_SIO 0x0484
677 
678 PCIINIT(i31244)
679 {
680  uint64_t port, memaddr;
681  int irq = 0;
682 
685 
687  PCI_SUBCLASS_MASS_STORAGE_IDE, 0x33) + 0x00);
688 
689  switch (machine->machine_type) {
690  case MACHINE_IQ80321:
691  /* S-PCI-X slot uses PCI IRQ A, int 29 */
692  irq = (1 << 8) + 29;
693  break;
694  default:fatal("i31244 in non-implemented machine type %i\n",
696  exit(1);
697  }
698 
699  PCI_SET_DATA(PCI_INTERRUPT_REG, 0x01100000 | irq);
700 
701  allocate_device_space(pd, 0x1000, 0, &port, &memaddr);
702  allocate_device_space(pd, 0x1000, 0, &port, &memaddr);
703 
704  /* PCI IDE using dev_wdc: */
707  char tmpstr[2000];
708  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s.%i",
709  (long long)(pd->pcibus->pci_actual_io_offset + 0),
710  pd->pcibus->irq_path_pci, irq & 255);
711  device_add(machine, tmpstr);
712  }
713 }
714 
715 int piix_isa_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
716 {
717  switch (reg) {
718  case PCI_MAPREG_START:
719  case PCI_MAPREG_START + 4:
720  case PCI_MAPREG_START + 8:
721  case PCI_MAPREG_START + 12:
722  case PCI_MAPREG_START + 16:
723  case PCI_MAPREG_START + 20:
724  PCI_SET_DATA(reg, value);
725  return 1;
726  }
727 
728  return 0;
729 }
730 
731 PCIINIT(piix3_isa)
732 {
735 
737  PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x01); /* Rev 1 */
738 
739  PCI_SET_DATA(PCI_BHLC_REG,
740  PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
741 }
742 
743 PCIINIT(piix4_isa)
744 {
747 
749  PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x01); /* Rev 1 */
750 
751  PCI_SET_DATA(PCI_BHLC_REG,
752  PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
753 
754  pd->cfg_reg_write = piix_isa_cfg_reg_write;
755 }
756 
757 PCIINIT(i82378zb)
758 {
761 
763  PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x43);
764 
765  PCI_SET_DATA(PCI_BHLC_REG,
766  PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
767 
768  PCI_SET_DATA(0x40, 0x20);
769 
770  /* PIRQ[0]=10 PIRQ[1]=11 PIRQ[2]=14 PIRQ[3]=15 */
771  PCI_SET_DATA(0x60, 0x0f0e0b0a);
772 }
773 
775  void *wdc0;
776  void *wdc1;
777 };
778 
779 int piix_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
780 {
781  void *wdc0 = ((struct piix_ide_extra *)pd->extra)->wdc0;
782  void *wdc1 = ((struct piix_ide_extra *)pd->extra)->wdc1;
783  int enabled = 0;
784 
785  PCI_SET_DATA(reg, value);
786 
787  switch (reg) {
789  if (value & PCI_COMMAND_IO_ENABLE)
790  enabled = 1;
791  if (wdc0 != NULL)
792  wdc_set_io_enabled((struct wdc_data *) wdc0, enabled);
793  if (wdc1 != NULL)
794  wdc_set_io_enabled((struct wdc_data *) wdc1, enabled);
795  return 1;
796  case PCI_MAPREG_START:
797  case PCI_MAPREG_START + 4:
798  case PCI_MAPREG_START + 8:
799  case PCI_MAPREG_START + 12:
800  case PCI_MAPREG_START + 16:
801  case PCI_MAPREG_START + 20:
802  return 1;
803  }
804 
805  return 0;
806 }
807 
808 PCIINIT(piix3_ide)
809 {
810  char tmpstr[2000];
811 
814 
815  /* Possibly not correct: */
817  PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x00);
818 
819  /* PIIX_IDETIM (see NetBSD's pciide_piix_reg.h) */
820  /* channel 0 and 1 enabled as IDE */
821  PCI_SET_DATA(0x40, 0x80008000);
822 
823  CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct piix_ide_extra)));
824  ((struct piix_ide_extra *)pd->extra)->wdc0 = NULL;
825  ((struct piix_ide_extra *)pd->extra)->wdc1 = NULL;
826 
829  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx "
830  "irq=%s.isa.%i", (long long)(pd->pcibus->isa_portbase +
831  0x1f0), pd->pcibus->irq_path_isa, 14);
832  ((struct piix_ide_extra *)pd->extra)->wdc0 =
833  device_add(machine, tmpstr);
834  }
835 
838  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx "
839  "irq=%s.isa.%i", (long long)(pd->pcibus->isa_portbase +
840  0x170), pd->pcibus->irq_path_isa, 15);
841  ((struct piix_ide_extra *)pd->extra)->wdc1 =
842  device_add(machine, tmpstr);
843  }
844 
845  pd->cfg_reg_write = piix_ide_cfg_reg_write;
846 }
847 
848 PCIINIT(piix4_ide)
849 {
850  char tmpstr[2000];
851 
854 
855  /* Possibly not correct: */
857  PCI_SUBCLASS_MASS_STORAGE_IDE, 0x80) + 0x01);
858 
859  /* PIIX_BMIBA (see NetBSD's pciide_piix_reg.h) */
860  /* 2009-05-18: Needs to have the lowest bit set, or Linux/Malta
861  crashes. */
862  PCI_SET_DATA(0x20, 1);
863 
864  /* PIIX_IDETIM (see NetBSD's pciide_piix_reg.h) */
865  /* channel 0 and 1 enabled as IDE */
866  PCI_SET_DATA(0x40, 0x80008000);
867 
868  CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct piix_ide_extra)));
869  ((struct piix_ide_extra *)pd->extra)->wdc0 = NULL;
870  ((struct piix_ide_extra *)pd->extra)->wdc1 = NULL;
871 
874  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
875  "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
876  pd->pcibus->irq_path_isa, 14);
877  ((struct piix_ide_extra *)pd->extra)->wdc0 =
878  device_add(machine, tmpstr);
879  }
880 
883  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
884  "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
885  pd->pcibus->irq_path_isa, 15);
886  ((struct piix_ide_extra *)pd->extra)->wdc1 =
887  device_add(machine, tmpstr);
888  }
889 
890  pd->cfg_reg_write = piix_ide_cfg_reg_write;
891 }
892 
893 
894 
895 /*
896  * IBM ISA bridge (used by at least one PReP machine).
897  */
898 
899 #define PCI_VENDOR_IBM 0x1014
900 #define PCI_PRODUCT_IBM_ISABRIDGE 0x000a
901 
902 PCIINIT(ibm_isa)
903 {
904  PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_IBM,
906 
908  PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x02);
909 
910  PCI_SET_DATA(PCI_BHLC_REG,
911  PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
912 }
913 
914 
915 
916 /*
917  * Heuricon PCI host bridge for PM/PPC.
918  */
919 
920 #define PCI_VENDOR_HEURICON 0x1223
921 #define PCI_PRODUCT_HEURICON_PMPPC 0x000e
922 
923 PCIINIT(heuricon_pmppc)
924 {
927 
929  PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x00); /* Revision? */
930 
931  PCI_SET_DATA(PCI_BHLC_REG,
932  PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
933 }
934 
935 
936 
937 /*
938  * VIATECH VT82C586 devices:
939  *
940  * vt82c586_isa PCI->ISA bridge
941  * vt82c586_ide IDE controller
942  *
943  * TODO: This more or less just a dummy device, so far.
944  */
945 
946 #define PCI_VENDOR_VIATECH 0x1106 /* VIA Technologies */
947 #define PCI_PRODUCT_VIATECH_VT82C586_IDE 0x1571 /* VT82C586 (Apollo VP)
948  IDE Controller */
949 #define PCI_PRODUCT_VIATECH_VT82C586_ISA 0x0586 /* VT82C586 (Apollo VP)
950  PCI-ISA Bridge */
951 
952 PCIINIT(vt82c586_isa)
953 {
956 
958  PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x39); /* Revision 37 or 39 */
959 
960  PCI_SET_DATA(PCI_BHLC_REG,
961  PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
962 
963  /*
964  * NetBSD/cobalt specific: bits 7..4 are the "model id". See
965  * netbsd/usr/src/sys/arch/cobalt/cobalt/machdep.c read_board_id()
966  * for details.
967  */
969 #define COBALT_PCIB_BOARD_ID_REG 0x94
970 #define COBALT_QUBE2_ID 5
971  PCI_SET_DATA(COBALT_PCIB_BOARD_ID_REG, COBALT_QUBE2_ID << 4);
972  }
973 }
974 
976  void *wdc0;
977  void *wdc1;
978 };
979 
980 int vt82c586_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
981 {
982  void *wdc0 = ((struct vt82c586_ide_extra *)pd->extra)->wdc0;
983  void *wdc1 = ((struct vt82c586_ide_extra *)pd->extra)->wdc1;
984  int enabled = 0;
985 
986  switch (reg) {
988  if (value & PCI_COMMAND_IO_ENABLE)
989  enabled = 1;
990  if (wdc0 != NULL)
991  wdc_set_io_enabled((struct wdc_data *) wdc0, enabled);
992  if (wdc1 != NULL)
993  wdc_set_io_enabled((struct wdc_data *) wdc1, enabled);
994  return 1;
995  }
996 
997  return 0;
998 }
999 
1000 PCIINIT(vt82c586_ide)
1001 {
1002  char tmpstr[2000];
1003 
1006 
1007  /* Possibly not correct: */
1009  PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x01);
1010 
1011  /* APO_IDECONF */
1012  /* channel 0 and 1 enabled */
1013  PCI_SET_DATA(0x40, 0x00000003);
1014 
1015  CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct vt82c586_ide_extra)));
1016  ((struct vt82c586_ide_extra *)pd->extra)->wdc0 = NULL;
1017  ((struct vt82c586_ide_extra *)pd->extra)->wdc1 = NULL;
1018 
1021  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1022  "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
1023  pd->pcibus->irq_path_isa, 14);
1024  ((struct vt82c586_ide_extra *)pd->extra)->wdc0 =
1025  device_add(machine, tmpstr);
1026  }
1027 
1030  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1031  "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
1032  pd->pcibus->irq_path_isa, 15);
1033  ((struct vt82c586_ide_extra *)pd->extra)->wdc1 =
1034  device_add(machine, tmpstr);
1035  }
1036 
1037  pd->cfg_reg_write = vt82c586_ide_cfg_reg_write;
1038 }
1039 
1040 
1041 
1042 /*
1043  * Symphony Labs 83C553 PCI->ISA bridge.
1044  * Symphony Labs 82C105 PCIIDE controller.
1045  */
1047 #define PCI_VENDOR_SYMPHONY 0x10ad
1048 #define PCI_PRODUCT_SYMPHONY_83C553 0x0565
1049 #define PCI_PRODUCT_SYMPHONY_82C105 0x0105
1050 
1051 PCIINIT(symphony_83c553)
1052 {
1055 
1057  PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x10);
1058 
1059  PCI_SET_DATA(PCI_BHLC_REG,
1060  PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1061 
1062  switch (machine->machine_type) {
1063  case MACHINE_NETWINDER:
1064  bus_isa_init(machine, pd->pcibus->irq_path_isa,
1065  0, 0x7c000000, 0x80000000);
1066  break;
1067  default:fatal("symphony_83c553 init: unimplemented machine type\n");
1068  exit(1);
1069  }
1073  void *wdc0;
1074  void *wdc1;
1075 };
1076 
1077 int symphony_82c105_cfg_reg_write(struct pci_device *pd, int reg,
1078  uint32_t value)
1079 {
1080  void *wdc0 = ((struct symphony_82c105_extra *)pd->extra)->wdc0;
1081  void *wdc1 = ((struct symphony_82c105_extra *)pd->extra)->wdc1;
1082  int enabled = 0;
1083 
1084 printf("reg = 0x%x\n", reg);
1085  switch (reg) {
1087  if (value & PCI_COMMAND_IO_ENABLE)
1088  enabled = 1;
1089 printf(" value = 0x%" PRIx32"\n", value);
1090  if (wdc0 != NULL)
1091  wdc_set_io_enabled((struct wdc_data *) wdc0, enabled);
1092  if (wdc1 != NULL)
1093  wdc_set_io_enabled((struct wdc_data *) wdc1, enabled);
1094  /* Set all bits: */
1095  PCI_SET_DATA(reg, value);
1096  return 1;
1097  case PCI_MAPREG_START:
1098  case PCI_MAPREG_START + 4:
1099  case PCI_MAPREG_START + 8:
1100  case PCI_MAPREG_START + 12:
1101  case PCI_MAPREG_START + 16:
1102  case PCI_MAPREG_START + 20:
1103  PCI_SET_DATA(reg, value);
1104  return 1;
1105  }
1106 
1107  return 0;
1109 
1110 PCIINIT(symphony_82c105)
1111 {
1112  char tmpstr[2000];
1113 
1116 
1117  /* Possibly not correct: */
1119  PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x05);
1120 
1121  /* TODO: Interrupt line: */
1122  /* PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000); */
1123 
1124  /* APO_IDECONF */
1125  /* channel 0 and 1 enabled */
1126  PCI_SET_DATA(0x40, 0x00000003);
1127 
1128  CHECK_ALLOCATION(pd->extra =
1129  malloc(sizeof(struct symphony_82c105_extra)));
1130  ((struct symphony_82c105_extra *)pd->extra)->wdc0 = NULL;
1131  ((struct symphony_82c105_extra *)pd->extra)->wdc1 = NULL;
1132 
1135  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1136  "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x1f0),
1137  pd->pcibus->irq_path_isa, 14);
1138  ((struct symphony_82c105_extra *)pd->extra)->wdc0 =
1139  device_add(machine, tmpstr);
1140  }
1141 
1144  snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%s."
1145  "isa.%i", (long long)(pd->pcibus->isa_portbase + 0x170),
1146  pd->pcibus->irq_path_isa, 15);
1147  ((struct symphony_82c105_extra *)pd->extra)->wdc1 =
1148  device_add(machine, tmpstr);
1149  }
1150 
1151  pd->cfg_reg_write = symphony_82c105_cfg_reg_write;
1152 }
1153 
1154 
1155 
1156 /*
1157  * Realtek 8139C+ PCI ethernet.
1158  */
1160 #define PCI_VENDOR_REALTEK 0x10ec
1161 #define PCI_PRODUCT_REALTEK_RT8139 0x8139
1162 
1163 PCIINIT(rtl8139c)
1164 {
1165  uint64_t port, memaddr;
1166  int pci_int_line = 0x101, irq = 0;
1167  char irqstr[1000];
1168  char tmpstr[2000];
1169 
1172 
1174  PCI_SUBCLASS_NETWORK_ETHERNET, 0x00) + 0x20);
1175 
1176  switch (machine->machine_type) {
1177  case MACHINE_LANDISK:
1178  irq = 5;
1179  pci_int_line = 0x105;
1180  break;
1181  default:fatal("rtl8139c for this machine has not been "
1182  "implemented yet\n");
1183  exit(1);
1184  }
1185 
1186  PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000 | pci_int_line);
1187 
1188  allocate_device_space(pd, 0x100, 0, &port, &memaddr);
1189 
1190  snprintf(irqstr, sizeof(irqstr), "%s.%i",
1191  pd->pcibus->irq_path_pci, irq);
1192 
1193  snprintf(tmpstr, sizeof(tmpstr), "rtl8139c addr=0x%llx "
1194  "irq=%s pci_little_endian=1", (long long)port, irqstr);
1195 
1196  device_add(machine, tmpstr);
1197 }
1198 
1199 
1200 
1201 /*
1202  * DEC 21143 ("Tulip") PCI ethernet.
1203  */
1205 #define PCI_VENDOR_DEC 0x1011 /* Digital Equipment */
1206 #define PCI_PRODUCT_DEC_21142 0x0019 /* DECchip 21142/21143 10/100 Ethernet */
1207 
1208 PCIINIT(dec21143)
1209 {
1210  uint64_t port, memaddr;
1211  int pci_int_line = 0x101, irq = 0, isa = 0;
1212  char irqstr[1000];
1213  char tmpstr[2000];
1214 
1215  PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_DEC,
1217 
1218  PCI_SET_DATA(PCI_COMMAND_STATUS_REG, 0x02000017);
1219 
1221  PCI_SUBCLASS_NETWORK_ETHERNET, 0x00) + 0x41);
1222 
1223  PCI_SET_DATA(PCI_BHLC_REG, PCI_BHLC_CODE(0,0,0, 0x40,0));
1224 
1225  switch (machine->machine_type) {
1226  case MACHINE_CATS:
1227  /* CATS int 18 = PCI. */
1228  irq = 18;
1229  pci_int_line = 0x101;
1230  break;
1231  case MACHINE_COBALT:
1232  /* On Cobalt, IRQ 7 = PCI. */
1233  irq = 8 + 7;
1234  pci_int_line = 0x407;
1235  break;
1236  case MACHINE_PREP:
1237  irq = 10;
1238  isa = 1;
1239  pci_int_line = 0x20a;
1240  break;
1241  case MACHINE_MVMEPPC:
1242  /* TODO */
1243  irq = 10;
1244  pci_int_line = 0x40a;
1245  break;
1246  case MACHINE_PMPPC:
1247  /* TODO, not working yet */
1248  irq = 31 - CPC_IB_EXT1;
1249  pci_int_line = 0x101;
1250  break;
1251  case MACHINE_MACPPC:
1252  /* TODO, not working yet */
1253  irq = 25;
1254  pci_int_line = 0x101;
1255  break;
1256  }
1257 
1258  PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000 | pci_int_line);
1259 
1260  allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);
1261 
1262  if (isa)
1263  snprintf(irqstr, sizeof(irqstr), "%s.isa.%i",
1264  pd->pcibus->irq_path_isa, irq);
1265  else
1266  snprintf(irqstr, sizeof(irqstr), "%s.%i",
1267  pd->pcibus->irq_path_pci, irq);
1268 
1269  snprintf(tmpstr, sizeof(tmpstr), "dec21143 addr=0x%llx addr2=0x%llx "
1270  "irq=%s pci_little_endian=1", (long long)port,
1271  (long long)memaddr, irqstr);
1272 
1273  device_add(machine, tmpstr);
1274 }
1275 
1276 
1277 
1278 /*
1279  * DEC 21030 "tga" graphics.
1280  */
1281 
1282 #define PCI_PRODUCT_DEC_21030 0x0004 /* DECchip 21030 ("TGA") */
1283 
1284 PCIINIT(dec21030)
1285 {
1286  uint64_t base = 0;
1287  char tmpstr[2000];
1288 
1289  PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_DEC,
1291 
1292  PCI_SET_DATA(PCI_COMMAND_STATUS_REG, 0x02800087); /* TODO */
1293 
1295  PCI_SUBCLASS_DISPLAY_VGA, 0x00) + 0x03);
1296 
1297  /*
1298  * See http://mail-index.netbsd.org/port-arc/2001/08/13/0000.html
1299  * for more info.
1300  */
1301 
1302  PCI_SET_DATA(PCI_BHLC_REG, 0x0000ff00);
1303 
1304  /* 8 = prefetchable */
1305  PCI_SET_DATA(0x10, 0x00000008);
1306  PCI_SET_DATA(0x30, 0x08000001);
1307  PCI_SET_DATA(PCI_INTERRUPT_REG, 0x00000100); /* interrupt pin A? */
1308 
1309  /*
1310  * Experimental:
1311  *
1312  * TODO: Base address, pci_little_endian, ...
1313  */
1314 
1315  switch (machine->machine_type) {
1316  case MACHINE_ARC:
1317  base = 0x100000000ULL;
1318  break;
1319  default:fatal("dec21030 in non-implemented machine type %i\n",
1321  exit(1);
1322  }
1323 
1324  snprintf(tmpstr, sizeof(tmpstr), "dec21030 addr=0x%llx",
1325  (long long)(base));
1326  device_add(machine, tmpstr);
1327 }
1328 
1329 
1330 
1331 /*
1332  * Motorola MPC105 "Eagle" Host Bridge
1333  *
1334  * Used in at least PReP and BeBox.
1335  */
1337 #define PCI_VENDOR_MOT 0x1057
1338 #define PCI_PRODUCT_MOT_MPC105 0x0001
1339 
1340 PCIINIT(eagle)
1341 {
1342  PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_MOT,
1344 
1346  PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x24);
1347 
1348  PCI_SET_DATA(PCI_BHLC_REG,
1349  PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1350 }
1351 
1352 
1353 
1354 /*
1355  * Apple (MacPPC) stuff:
1356  *
1357  * Grand Central (I/O controller)
1358  * Uni-North (PCI controller)
1359  */
1361 #define PCI_VENDOR_APPLE 0x106b
1362 #define PCI_PRODUCT_APPLE_GC 0x0002
1363 #define PCI_PRODUCT_APPLE_UNINORTH1 0x001e
1364 
1365 PCIINIT(gc_obio)
1366 {
1367  uint64_t port, memaddr;
1368 
1369  PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_APPLE,
1371 
1372  /* TODO: */
1374  PCI_SUBCLASS_SYSTEM_PIC, 0) + 0x00);
1375 
1376  PCI_SET_DATA(PCI_BHLC_REG,
1377  PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1378 
1379  /* TODO */
1380  allocate_device_space(pd, 0x10000, 0x10000, &port, &memaddr);
1382 
1383 PCIINIT(uninorth)
1384 {
1385  uint64_t port, memaddr;
1386 
1387  PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_APPLE,
1389 
1391  PCI_SUBCLASS_BRIDGE_HOST, 0) + 0xff);
1392 
1393  PCI_SET_DATA(PCI_BHLC_REG,
1394  PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1395 
1396  /* TODO */
1397  allocate_device_space(pd, 0x10000, 0x10000, &port, &memaddr);
1398 }
1399 
1400 
1401 
1402 /*
1403  * ATI graphics cards
1404  */
1406 #define PCI_VENDOR_ATI 0x1002
1407 #define PCI_PRODUCT_ATI_RADEON_9200_2 0x5962
1408 
1409 PCIINIT(ati_radeon_9200_2)
1410 {
1411  uint64_t port, memaddr;
1412 
1413  PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_ATI,
1415 
1416  /* TODO: other subclass? */
1418  PCI_SUBCLASS_DISPLAY_VGA, 0) + 0x03);
1419 
1420  /* TODO */
1421  allocate_device_space(pd, 0x1000, 0x400000, &port, &memaddr);
1422 }
1423 
PCI_SUBCLASS_MASS_STORAGE_SCSI
#define PCI_SUBCLASS_MASS_STORAGE_SCSI
Definition: pcireg.h:177
PCI_PRODUCT_VIATECH_VT82C586_IDE
#define PCI_PRODUCT_VIATECH_VT82C586_IDE
Definition: bus_pci.cc:947
MACHINE_COBALT
#define MACHINE_COBALT
Definition: machine.h:214
PCI_SUBCLASS_NETWORK_ETHERNET
#define PCI_SUBCLASS_NETWORK_ETHERNET
Definition: pcireg.h:186
data
u_short data
Definition: siireg.h:79
PCI_MAPREG_END
#define PCI_MAPREG_END
Definition: pcireg.h:347
PCI_PRODUCT_DEC_21030
#define PCI_PRODUCT_DEC_21030
Definition: bus_pci.cc:1280
PCI_PRODUCT_HEURICON_PMPPC
#define PCI_PRODUCT_HEURICON_PMPPC
Definition: bus_pci.cc:921
wdc_data
Definition: dev_wdc.cc:54
PCI_CLASS_REG
#define PCI_CLASS_REG
Definition: pcireg.h:119
BUS_ISA_PCKBC_FORCE_USE
#define BUS_ISA_PCKBC_FORCE_USE
Definition: bus_isa.h:63
diskimage.h
piix_ide_extra
Definition: bus_pci.cc:774
PCI_COMMAND_IO_ENABLE
#define PCI_COMMAND_IO_ENABLE
Definition: pcireg.h:90
memory
Definition: memory.h:75
debug
#define debug
Definition: dev_adb.cc:57
MACHINE_LANDISK
#define MACHINE_LANDISK
Definition: machine.h:253
PCI_PRODUCT_MOT_MPC105
#define PCI_PRODUCT_MOT_MPC105
Definition: bus_pci.cc:1336
bus_pci_setaddr
void bus_pci_setaddr(struct cpu *cpu, struct pci_data *pci_data, int bus, int device, int function, int reg)
Definition: bus_pci.cc:196
MACHINE_CATS
#define MACHINE_CATS
Definition: machine.h:240
PCI_CLASS_MASS_STORAGE
#define PCI_CLASS_MASS_STORAGE
Definition: pcireg.h:153
PCI_ID_REG
#define PCI_ID_REG
Definition: pcireg.h:58
bus_isa.h
PCI_PRODUCT_APPLE_GC
#define PCI_PRODUCT_APPLE_GC
Definition: bus_pci.cc:1360
PCI_VENDOR_AMD
#define PCI_VENDOR_AMD
Definition: bus_pci.cc:626
dev_vga_init
void dev_vga_init(struct machine *machine, struct memory *mem, uint64_t videomem_base, uint64_t control_base, const char *name)
Definition: dev_vga.cc:1187
PCI_PRODUCT_SYMPHONY_83C553
#define PCI_PRODUCT_SYMPHONY_83C553
Definition: bus_pci.cc:1046
PCI_SUBCLASS_DISPLAY_VGA
#define PCI_SUBCLASS_DISPLAY_VGA
Definition: pcireg.h:196
PCI_VENDOR_VIATECH
#define PCI_VENDOR_VIATECH
Definition: bus_pci.cc:946
bus_pci_data_access
void bus_pci_data_access(struct cpu *cpu, struct pci_data *pci_data, uint64_t *data, int len, int writeflag)
Definition: bus_pci.cc:95
wdc_set_io_enabled
int wdc_set_io_enabled(struct wdc_data *d, int io_enabled)
Definition: dev_wdc.cc:119
MEM_READ
#define MEM_READ
Definition: memory.h:116
t
vmrs t
Definition: armreg.h:750
PCI_VENDOR_SYMPHONY
#define PCI_VENDOR_SYMPHONY
Definition: bus_pci.cc:1045
PCI_PRODUCT_AMD_PCNET_PCI
#define PCI_PRODUCT_AMD_PCNET_PCI
Definition: bus_pci.cc:627
PCI_PRODUCT_INTEL_31244
#define PCI_PRODUCT_INTEL_31244
Definition: bus_pci.cc:671
MACHINE_PREP
#define MACHINE_PREP
Definition: machine.h:228
PCI_VENDOR_HEURICON
#define PCI_VENDOR_HEURICON
Definition: bus_pci.cc:920
PCI_VENDOR_APPLE
#define PCI_VENDOR_APPLE
Definition: bus_pci.cc:1359
device.h
bus_pci_decompose_1
void bus_pci_decompose_1(uint32_t t, int *bus, int *dev, int *func, int *reg)
Definition: bus_pci.cc:76
bus_pci_init
struct pci_data * bus_pci_init(struct machine *machine, const char *irq_path, uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset, uint64_t pci_portbase, uint64_t pci_membase, const char *pci_irqbase, uint64_t isa_portbase, uint64_t isa_membase, const char *isa_irqbase)
Definition: bus_pci.cc:355
PCI_VENDOR_INTEGRAPHICS
#define PCI_VENDOR_INTEGRAPHICS
Definition: bus_pci.cc:406
PCI_VENDOR_IBM
#define PCI_VENDOR_IBM
Definition: bus_pci.cc:899
PCI_CLASS_SYSTEM
#define PCI_CLASS_SYSTEM
Definition: pcireg.h:160
PCI_CLASS_CODE
#define PCI_CLASS_CODE(mainclass, subclass, interface)
Definition: pcireg.h:146
MEM_WRITE
#define MEM_WRITE
Definition: memory.h:117
PCI_PRODUCT_INTEL_82371AB_IDE
#define PCI_PRODUCT_INTEL_82371AB_IDE
Definition: bus_pci.cc:675
PCI_VENDOR_ATI
#define PCI_VENDOR_ATI
Definition: bus_pci.cc:1404
vt82c586_ide_extra::wdc0
void * wdc0
Definition: bus_pci.cc:974
PCI_PRODUCT_GALILEO_GT64011
#define PCI_PRODUCT_GALILEO_GT64011
Definition: bus_pci.cc:581
PCI_MAPREG_TYPE_IO
#define PCI_MAPREG_TYPE_IO
Definition: pcireg.h:357
COBALT_PCIB_BOARD_ID_REG
#define COBALT_PCIB_BOARD_ID_REG
PCI_PRODUCT_GALILEO_GT64260
#define PCI_PRODUCT_GALILEO_GT64260
Definition: bus_pci.cc:583
PCI_SUBCLASS_BRIDGE_HOST
#define PCI_SUBCLASS_BRIDGE_HOST
Definition: pcireg.h:213
PCI_PRODUCT_IBM_ISABRIDGE
#define PCI_PRODUCT_IBM_ISABRIDGE
Definition: bus_pci.cc:900
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
PCI_PRODUCT_INTEL_82371SB_ISA
#define PCI_PRODUCT_INTEL_82371SB_ISA
Definition: bus_pci.cc:672
piix_isa_cfg_reg_write
int piix_isa_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
Definition: bus_pci.cc:715
pci_lookup_initf
void(*)(struct machine *machine, struct memory *mem, struct pci_device *pd) pci_lookup_initf(const char *name)
Definition: device.cc:136
MACHINE_NETWINDER
#define MACHINE_NETWINDER
Definition: machine.h:242
misc.h
COBALT_QUBE2_ID
#define COBALT_QUBE2_ID
PCI_PRODUCT_GALILEO_GT64120
#define PCI_PRODUCT_GALILEO_GT64120
Definition: bus_pci.cc:582
device_add
void * device_add(struct machine *machine, const char *name_and_params)
Definition: device.cc:252
machine.h
machine
Definition: machine.h:97
PCI_CLASS_BRIDGE
#define PCI_CLASS_BRIDGE
Definition: pcireg.h:158
symphony_82c105_extra::wdc1
void * wdc1
Definition: bus_pci.cc:1072
PCI_PRODUCT_APPLE_UNINORTH1
#define PCI_PRODUCT_APPLE_UNINORTH1
Definition: bus_pci.cc:1361
MACHINE_IQ80321
#define MACHINE_IQ80321
Definition: machine.h:243
verbose
int verbose
Definition: main.cc:77
MACHINE_PMPPC
#define MACHINE_PMPPC
Definition: machine.h:227
BUS_ISA_PCKBC_NONPCSTYLE
#define BUS_ISA_PCKBC_NONPCSTYLE
Definition: bus_isa.h:64
PCI_ID_CODE
#define PCI_ID_CODE(vid, pid)
Definition: pcireg.h:73
vt82c586_ide_cfg_reg_write
int vt82c586_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
Definition: bus_pci.cc:978
MACHINE_MVMEPPC
#define MACHINE_MVMEPPC
Definition: machine.h:230
PCI_BHLC_REG
#define PCI_BHLC_REG
Definition: pcireg.h:309
vt82c586_ide_extra
Definition: bus_pci.cc:973
PCI_PRODUCT_INTEL_82371AB_ISA
#define PCI_PRODUCT_INTEL_82371AB_ISA
Definition: bus_pci.cc:674
cpu.h
PCI_VENDOR_REALTEK
#define PCI_VENDOR_REALTEK
Definition: bus_pci.cc:1158
PCI_SUBCLASS_BRIDGE_ISA
#define PCI_SUBCLASS_BRIDGE_ISA
Definition: pcireg.h:214
PCI_VENDOR_ALI
#define PCI_VENDOR_ALI
Definition: bus_pci.cc:459
PCI_CLASS_DISPLAY
#define PCI_CLASS_DISPLAY
Definition: pcireg.h:155
symphony_82c105_extra::wdc0
void * wdc0
Definition: bus_pci.cc:1071
bus_pci.h
bus_isa_init
struct bus_isa_data * bus_isa_init(struct machine *machine, char *interrupt_base_path, uint32_t bus_isa_flags, uint64_t isa_portbase, uint64_t isa_membase)
Definition: bus_isa.cc:174
vt82c586_ide_extra::wdc1
void * wdc1
Definition: bus_pci.cc:975
PCI_PRODUCT_INTEL_SIO
#define PCI_PRODUCT_INTEL_SIO
Definition: bus_pci.cc:676
wdc.h
CPC_IB_EXT1
#define CPC_IB_EXT1
Definition: cpc700reg.h:146
reg
#define reg(x)
Definition: tmp_alpha_tail.cc:53
PCI_COMMAND_STATUS_REG
#define PCI_COMMAND_STATUS_REG
Definition: pcireg.h:80
PCI_CLASS_NETWORK
#define PCI_CLASS_NETWORK
Definition: pcireg.h:154
PCI_VENDOR_ADP
#define PCI_VENDOR_ADP
Definition: bus_pci.cc:526
PCIINIT
PCIINIT(igsfb)
Definition: bus_pci.cc:408
symphony_82c105_extra
Definition: bus_pci.cc:1070
PCI_PRODUCT_VIATECH_VT82C586_ISA
#define PCI_PRODUCT_VIATECH_VT82C586_ISA
Definition: bus_pci.cc:948
PCI_PRODUCT_ATI_RADEON_9200_2
#define PCI_PRODUCT_ATI_RADEON_9200_2
Definition: bus_pci.cc:1405
PCI_PRODUCT_SYMPHONY_82C105
#define PCI_PRODUCT_SYMPHONY_82C105
Definition: bus_pci.cc:1047
PCI_INTERRUPT_REG
#define PCI_INTERRUPT_REG
Definition: pcireg.h:445
PCI_SUBCLASS_MASS_STORAGE_IDE
#define PCI_SUBCLASS_MASS_STORAGE_IDE
Definition: pcireg.h:178
symphony_82c105_cfg_reg_write
int symphony_82c105_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
Definition: bus_pci.cc:1075
PCI_VENDOR_INTEL
#define PCI_VENDOR_INTEL
Definition: bus_pci.cc:670
PCI_VENDOR_S3
#define PCI_VENDOR_S3
Definition: bus_pci.cc:435
PCI_VENDOR_DEC
#define PCI_VENDOR_DEC
Definition: bus_pci.cc:1203
cpc700reg.h
piix_ide_extra::wdc0
void * wdc0
Definition: bus_pci.cc:775
PCI_MAPREG_START
#define PCI_MAPREG_START
Definition: pcireg.h:346
machine::machine_type
int machine_type
Definition: machine.h:111
piix_ide_extra::wdc1
void * wdc1
Definition: bus_pci.cc:776
PCI_PRODUCT_S3_VIRGE_DX
#define PCI_PRODUCT_S3_VIRGE_DX
Definition: bus_pci.cc:437
DISKIMAGE_IDE
#define DISKIMAGE_IDE
Definition: diskimage.h:41
piix_ide_cfg_reg_write
int piix_ide_cfg_reg_write(struct pci_device *pd, int reg, uint32_t value)
Definition: bus_pci.cc:779
PCI_PRODUCT_REALTEK_RT8139
#define PCI_PRODUCT_REALTEK_RT8139
Definition: bus_pci.cc:1159
PCI_BHLC_CODE
#define PCI_BHLC_CODE(bist, type, multi, latency, cacheline)
Definition: pcireg.h:336
devices.h
PCI_PRODUCT_DEC_21142
#define PCI_PRODUCT_DEC_21142
Definition: bus_pci.cc:1204
PCI_PRODUCT_ALI_M5229
#define PCI_PRODUCT_ALI_M5229
Definition: bus_pci.cc:461
machine::machine_name
const char * machine_name
Definition: machine.h:115
cpu
Definition: cpu.h:326
MACHINE_ARC
#define MACHINE_ARC
Definition: machine.h:218
PCI_SUBCLASS_SYSTEM_PIC
#define PCI_SUBCLASS_SYSTEM_PIC
Definition: pcireg.h:236
bus_pci_add
void bus_pci_add(struct machine *machine, struct pci_data *pci_data, struct memory *mem, int bus, int device, int function, const char *name)
Definition: bus_pci.cc:216
PCI_PRODUCT_INTEL_82371SB_IDE
#define PCI_PRODUCT_INTEL_82371SB_IDE
Definition: bus_pci.cc:673
PCI_VENDOR_MOT
#define PCI_VENDOR_MOT
Definition: bus_pci.cc:1335
PCI_PRODUCT_ALI_M1543
#define PCI_PRODUCT_ALI_M1543
Definition: bus_pci.cc:460
memory.h
MACHINE_MACPPC
#define MACHINE_MACPPC
Definition: machine.h:229
MACHINE_EVBMIPS
#define MACHINE_EVBMIPS
Definition: machine.h:219
diskimage_exist
int diskimage_exist(struct machine *machine, int id, int type)
Definition: diskimage.cc:106
PCI_COMMAND_MEM_ENABLE
#define PCI_COMMAND_MEM_ENABLE
Definition: pcireg.h:91
PCI_VENDOR_GALILEO
#define PCI_VENDOR_GALILEO
Definition: bus_pci.cc:580
PCI_PRODUCT_ADP_AIC7880
#define PCI_PRODUCT_ADP_AIC7880
Definition: bus_pci.cc:527
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239

Generated on Tue Mar 24 2020 14:04:48 for GXemul by doxygen 1.8.17