/[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

Annotation of /trunk/src/devices/bus_pci.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Mon Oct 8 16:19:37 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 31232 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1121 2006/02/18 21:03:08 debug Exp $
20051126	Cobalt and PReP now work with the 21143 NIC.
		Continuing on Alpha dyntrans things.
		Fixing some more left-shift-by-24 to unsigned.
20051127	Working on OpenFirmware emulation; major cleanup/redesign.
		Progress on MacPPC emulation: NetBSD detects two CPUs (when
		running with -n 2), framebuffer output (for text) works.
		Adding quick-hack Bandit PCI controller and "gc" interrupt
		controller for MacPPC.
20051128	Changing from a Bandit to a Uni-North controller for macppc.
		Continuing on OpenFirmware and MacPPC emulation in general
		(obio controller, and wdc attached to the obio seems to work).
20051129	More work on MacPPC emulation (adding a dummy ADB controller).
		Continuing the PCI bus cleanup (endianness and tag composition)
		and rewriting all PCI controllers' access functions.
20051130	Various minor PPC dyntrans optimizations.
		Manually inlining some parts of the framebuffer redraw routine.
		Slowly beginning the conversion of the old MIPS emulation into
		dyntrans (but this will take quite some time to get right).
		Generalizing quick_pc_to_pointers.
20051201	Documentation update (David Muse has made available a kernel
		which simplifies Debian/DECstation installation).
		Continuing on the ADB bus controller.
20051202	Beginning a rewrite of the Zilog serial controller (dev_zs).
20051203	Continuing on the zs rewrite (now called dev_z8530); conversion
		to devinit style.
		Reworking some of the input-only vs output-only vs input-output
		details of src/console.c, better warning messages, and adding
		a debug dump.
		Removing the concept of "device state"; it wasn't really used.
		Changing some debug output (-vv should now be used to show all
		details about devices and busses; not shown during normal
		startup anymore).
		Beginning on some SPARC instruction disassembly support.
20051204	Minor PPC updates (WALNUT skeleton stuff).
		Continuing on the MIPS dyntrans rewrite.
		More progress on the ADB controller (a keyboard is "detected"
		by NetBSD and OpenBSD).
		Downgrading OpenBSD/arc as a guest OS from "working" to
		"almost working" in the documentation.
		Progress on Algor emulation ("v3" PCI controller).
20051205	Minor updates.
20051207	Sorting devices according to address; this reduces complexity
		of device lookups from O(n) to O(log n) in memory_rw (but no
		real performance increase (yet) in experiments).
20051210	Beginning the work on native dyntrans backends (by making a
		simple skeleton; so far only for Alpha hosts).
20051211	Some very minor SPARC updates.
20051215	Fixing a bug in the MIPS mul (note: not mult) instruction,
		so it also works with non-64-bit emulation. (Thanks to Alec
		Voropay for noticing the problem.)
20051216	More work on the fake/empty/simple/skeleton/whatever backend;
		performance doesn't increase, so this isn't really worth it,
		but it was probably worth it to prepare for a real backend
		later.
20051219	More instr call statistics gathering and analysis stuff.
20051220	Another fix for MIPS 'mul'. Also converting mul and {d,}cl{o,z}
		to dyntrans.
		memory_ppc.c syntax error fix (noticed by Peter Valchev).
		Beginning to move out machines from src/machine.c into
		individual files in src/machines (in a way similar to the
		autodev system for devices).
20051222	Updating the documentation regarding NetBSD/pmax 3.0.
20051223	- " - NetBSD/cats 3.0.
20051225	- " - NetBSD/hpcmips 3.0.
20051226	Continuing on the machine registry redesign.
		Adding support for ARM rrx (33-bit rotate).
		Fixing some signed/unsigned issues (exposed by gcc -W).
20051227	Fixing the bug which prevented a NetBSD/prep 3.0 install kernel
		from starting (triggered when an mtmsr was the last instruction
		on a page). Unfortunately not enough to get the kernel to run
		as well as the 2.1 kernels did.
20051230	Some dyntrans refactoring.
20051231	Continuing on the machine registry redesign.
20060101-10	Continuing... moving more machines. Moving MD interrupt stuff
		from machine.c into a new src/machines/interrupts.c.
20060114	Adding various mvmeppc machine skeletons.
20060115	Continuing on mvme* stuff. NetBSD/mvmeppc prints boot messages
		(for MVME1600) and reaches the root device prompt, but no
		specific hardware devices are emulated yet.
20060116	Minor updates to the mvme1600 emulation mode; the Eagle PCI bus
		seems to work without much modification, and a 21143 can be
		detected, interrupts might work (but untested so far).
		Adding a fake MK48Txx (mkclock) device, for NetBSD/mvmeppc.
20060121	Adding an aux control register for ARM. (A BIG thank you to
		Olivier Houchard for tracking down this bug.)
20060122	Adding more ARM instructions (smulXY), and dev_iq80321_7seg.
20060124	Adding disassembly of more ARM instructions (mia*, mra/mar),
		and some semi-bogus XScale and i80321 registers.
20060201-02	Various minor updates. Moving the last machines out of
		machine.c.
20060204	Adding a -c command line option, for running debugger commands
		before the simulation starts, but after all files have been
		loaded.
		Minor iq80321-related updates.
20060209	Minor hacks (DEVINIT macro, etc).
		Preparing for the generalization of the 64-bit dyntrans address
		translation subsystem.
20060216	Adding ARM ldrd (double-register load).
20060217	Continuing on various ARM-related stuff.
20060218	More progress on the ATA/wdc emulation for NetBSD/iq80321.
		NetBSD/evbarm can now be installed :-)  Updating the docs, etc.
		Continuing on Algor emulation.

==============  RELEASE 0.3.8  ==============


1 dpavlin 4 /*
2 dpavlin 22 * Copyright (C) 2004-2006 Anders Gavare. All rights reserved.
3 dpavlin 4 *
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 dpavlin 22 * $Id: bus_pci.c,v 1.62 2006/02/18 21:03:12 debug Exp $
29 dpavlin 4 *
30 dpavlin 20 * Generic PCI bus framework. This is not a normal "device", but is used by
31     * individual PCI controllers and devices.
32 dpavlin 4 *
33 dpavlin 20 * 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 dpavlin 4 */
44    
45     #include <stdio.h>
46     #include <stdlib.h>
47     #include <string.h>
48    
49 dpavlin 20 #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 dpavlin 4 #include "memory.h"
58     #include "misc.h"
59    
60 dpavlin 20 extern int verbose;
61 dpavlin 4
62 dpavlin 20
63 dpavlin 22 /* #define debug fatal */
64 dpavlin 4
65 dpavlin 14
66 dpavlin 22 /*
67     * bus_pci_decompose_1():
68     *
69     * Helper function for decomposing Mechanism 1 tags.
70     */
71     void bus_pci_decompose_1(uint32_t t, int *bus, int *dev, int *func, int *reg)
72 dpavlin 20 {
73 dpavlin 22 *bus = (t >> 16) & 0xff;
74     *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 dpavlin 20 }
83    
84    
85 dpavlin 4 /*
86 dpavlin 20 * bus_pci_data_access():
87     *
88 dpavlin 22 * Reads from or writes to the PCI configuration registers of a device.
89 dpavlin 20 */
90 dpavlin 22 void bus_pci_data_access(struct cpu *cpu, struct pci_data *pci_data,
91     uint64_t *data, int len, int writeflag)
92 dpavlin 20 {
93     struct pci_device *dev;
94     unsigned char *cfg_base;
95     uint64_t x, idata = *data;
96 dpavlin 22 int i;
97 dpavlin 20
98     /* Scan through the list of pci_device entries. */
99     dev = pci_data->first_device;
100     while (dev != NULL) {
101 dpavlin 22 if (dev->bus == pci_data->cur_bus &&
102     dev->function == pci_data->cur_func &&
103     dev->device == pci_data->cur_device)
104 dpavlin 20 break;
105     dev = dev->next;
106     }
107    
108     /* No device? Then return emptiness. */
109     if (dev == NULL) {
110 dpavlin 22 if (writeflag == MEM_READ) {
111     if (pci_data->cur_reg == 0)
112     *data = -1;
113     else
114     *data = 0;
115     } else {
116     fatal("[ bus_pci_data_access(): write to non-existant"
117     " device? ]\n");
118     }
119 dpavlin 20 return;
120     }
121    
122     /* Return normal config data, or length data? */
123     if (pci_data->last_was_write_ffffffff &&
124 dpavlin 22 pci_data->cur_reg >= PCI_MAPREG_START &&
125     pci_data->cur_reg <= PCI_MAPREG_END - 4)
126 dpavlin 20 cfg_base = dev->cfg_mem_size;
127     else
128     cfg_base = dev->cfg_mem;
129    
130     /* Read data as little-endian: */
131     x = 0;
132 dpavlin 22 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 dpavlin 20 }
137    
138     /* Register write: */
139     if (writeflag == MEM_WRITE) {
140 dpavlin 22 debug("[ bus_pci: write to PCI DATA: data = 0x%08llx ]\n",
141 dpavlin 20 (long long)idata);
142 dpavlin 22 if (idata == 0xffffffffULL &&
143     pci_data->cur_reg >= PCI_MAPREG_START &&
144     pci_data->cur_reg <= PCI_MAPREG_END - 4) {
145 dpavlin 20 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 dpavlin 22 (long long)x, pci_data->cur_bus,
155     pci_data->cur_device, pci_data->cur_func,
156     dev->name, pci_data->cur_reg);
157 dpavlin 20 }
158     return;
159     }
160    
161     /* Register read: */
162     *data = x;
163    
164     pci_data->last_was_write_ffffffff = 0;
165    
166 dpavlin 22 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 dpavlin 20 }
171    
172    
173     /*
174 dpavlin 22 * bus_pci_setaddr():
175 dpavlin 4 *
176 dpavlin 22 * Sets the address in preparation for a PCI register transfer.
177 dpavlin 4 */
178 dpavlin 22 void bus_pci_setaddr(struct cpu *cpu, struct pci_data *pci_data,
179     int bus, int device, int function, int reg)
180 dpavlin 4 {
181 dpavlin 22 if (cpu == NULL || pci_data == NULL) {
182     fatal("bus_pci_setaddr(): NULL ptr\n");
183     exit(1);
184 dpavlin 4 }
185    
186 dpavlin 22 pci_data->cur_bus = bus;
187     pci_data->cur_device = device;
188     pci_data->cur_func = function;
189     pci_data->cur_reg = reg;
190 dpavlin 4 }
191    
192    
193     /*
194     * bus_pci_add():
195     *
196     * Add a PCI device to a bus_pci device.
197     */
198     void bus_pci_add(struct machine *machine, struct pci_data *pci_data,
199     struct memory *mem, int bus, int device, int function,
200 dpavlin 22 const char *name)
201 dpavlin 4 {
202 dpavlin 20 struct pci_device *pd;
203     int ofs;
204     void (*init)(struct machine *, struct memory *, struct pci_device *);
205 dpavlin 4
206 dpavlin 14 if (pci_data == NULL) {
207     fatal("bus_pci_add(): pci_data == NULL!\n");
208     exit(1);
209     }
210    
211 dpavlin 20 /* Find the PCI device: */
212     init = pci_lookup_initf(name);
213    
214 dpavlin 4 /* Make sure this bus/device/function number isn't already in use: */
215 dpavlin 20 pd = pci_data->first_device;
216     while (pd != NULL) {
217     if (pd->bus == bus && pd->device == device &&
218     pd->function == function) {
219 dpavlin 4 fatal("bus_pci_add(): (bus %i, device %i, function"
220     " %i) already in use\n", bus, device, function);
221 dpavlin 20 exit(1);
222 dpavlin 4 }
223 dpavlin 20 pd = pd->next;
224 dpavlin 4 }
225    
226 dpavlin 20 pd = malloc(sizeof(struct pci_device));
227     if (pd == NULL) {
228 dpavlin 4 fprintf(stderr, "out of memory\n");
229     exit(1);
230     }
231    
232 dpavlin 20 memset(pd, 0, sizeof(struct pci_device));
233 dpavlin 4
234     /* Add the new device first in the PCI bus' chain: */
235 dpavlin 20 pd->next = pci_data->first_device;
236     pci_data->first_device = pd;
237 dpavlin 4
238 dpavlin 20 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 dpavlin 22 * 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 dpavlin 20 */
250 dpavlin 22 PCI_SET_DATA(PCI_COMMAND_STATUS_REG,
251     PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE);
252 dpavlin 20 for (ofs = PCI_MAPREG_START; ofs < PCI_MAPREG_END; ofs += 4)
253 dpavlin 22 PCI_SET_DATA_SIZE(ofs, 0x00100000 - 1);
254 dpavlin 20
255     if (init == NULL) {
256     fatal("No init function for PCI device \"%s\"?\n", name);
257     exit(1);
258     }
259    
260 dpavlin 4 /* Call the PCI device' init function: */
261 dpavlin 20 init(machine, mem, pd);
262 dpavlin 4 }
263    
264    
265     /*
266 dpavlin 20 * 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 dpavlin 22 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 dpavlin 20 }
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 dpavlin 22 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 dpavlin 20 }
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 dpavlin 22 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 dpavlin 20 /*
336 dpavlin 22 * bus_pci_debug_dump():
337     *
338     * Lists the attached PCI devices (in reverse).
339     */
340     void bus_pci_debug_dump(void *extra)
341     {
342     struct pci_data *d = (struct pci_data *) extra;
343     int iadd = DEBUG_INDENTATION;
344    
345     debug("pci:\n");
346     debug_indentation(iadd);
347    
348     if (d->first_device == NULL)
349     debug("no devices!\n");
350     else
351     bus_pci_debug_dump__2(d->first_device);
352    
353     debug_indentation(-iadd);
354     }
355    
356    
357     /*
358 dpavlin 4 * bus_pci_init():
359     *
360     * This doesn't register a device, but instead returns a pointer to a struct
361 dpavlin 22 * which should be passed to other bus_pci functions when accessing the bus.
362 dpavlin 20 *
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 dpavlin 4 */
374 dpavlin 22 struct pci_data *bus_pci_init(struct machine *machine, int irq_nr,
375 dpavlin 20 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 dpavlin 4 {
379     struct pci_data *d;
380    
381     d = malloc(sizeof(struct pci_data));
382     if (d == NULL) {
383     fprintf(stderr, "out of memory\n");
384     exit(1);
385     }
386     memset(d, 0, sizeof(struct pci_data));
387 dpavlin 20 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 dpavlin 4
397 dpavlin 22 /* Register the bus: */
398     machine_bus_register(machine, "pci", bus_pci_debug_dump, d);
399    
400 dpavlin 20 /* 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 dpavlin 4 return d;
405     }
406    
407 dpavlin 20
408    
409     /******************************************************************************
410 dpavlin 22 * *
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 dpavlin 20 ******************************************************************************/
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 dpavlin 22 PCI_SET_DATA(0x10, 0x08000000);
439 dpavlin 20
440 dpavlin 22 dev_vga_init(machine, mem, pd->pcibus->isa_membase + 0xa0000,
441     0x88800000 + 0x3c0, machine->machine_name);
442 dpavlin 20 }
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 dpavlin 22 #define PCI_PRODUCT_GALILEO_GT64260 0x6430 /* GT-64260 */
591 dpavlin 20
592     PCIINIT(gt64011)
593     {
594     PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_GALILEO,
595     PCI_PRODUCT_GALILEO_GT64011));
596    
597 dpavlin 22 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
598 dpavlin 20 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 dpavlin 22 PCIINIT(gt64260)
617     {
618     PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_GALILEO,
619     PCI_PRODUCT_GALILEO_GT64260));
620 dpavlin 20
621 dpavlin 22 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
622     PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x01); /* Revision 1? */
623     }
624 dpavlin 20
625 dpavlin 22
626    
627 dpavlin 20 /*
628 dpavlin 22 * 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 dpavlin 20 */
635    
636     #define PCI_VENDOR_INTEL 0x8086
637 dpavlin 22 #define PCI_PRODUCT_INTEL_31244 0x3200
638     #define PCI_PRODUCT_INTEL_82371SB_ISA 0x7000
639     #define PCI_PRODUCT_INTEL_82371SB_IDE 0x7010
640 dpavlin 20 #define PCI_PRODUCT_INTEL_82371AB_ISA 0x7110
641     #define PCI_PRODUCT_INTEL_82371AB_IDE 0x7111
642     #define PCI_PRODUCT_INTEL_SIO 0x0484
643    
644 dpavlin 22 PCIINIT(i31244)
645 dpavlin 20 {
646 dpavlin 22 uint64_t port, memaddr;
647    
648 dpavlin 20 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
649 dpavlin 22 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 dpavlin 20 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 dpavlin 22
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 dpavlin 20 }
719    
720 dpavlin 22 PCIINIT(piix3_ide)
721 dpavlin 20 {
722     char tmpstr[100];
723    
724     PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
725 dpavlin 22 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 dpavlin 20 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 dpavlin 22 int pci_int_line = 0x101;
956 dpavlin 20 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 dpavlin 22 /* CATS int 18 = PCI. */
971 dpavlin 20 irq = 18;
972 dpavlin 22 pci_int_line = 0x101;
973 dpavlin 20 break;
974 dpavlin 22 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 dpavlin 20 case MACHINE_PREP:
985 dpavlin 22 irq = 32 + 10;
986     pci_int_line = 0x20a;
987 dpavlin 20 break;
988 dpavlin 22 case MACHINE_MVMEPPC:
989     /* TODO */
990     irq = 32 + 10;
991     pci_int_line = 0x40a;
992     break;
993 dpavlin 20 case MACHINE_PMPPC:
994 dpavlin 22 /* TODO, not working yet */
995 dpavlin 20 irq = 31 - 21;
996 dpavlin 22 pci_int_line = 0x201;
997 dpavlin 20 break;
998 dpavlin 22 case MACHINE_MACPPC:
999     /* TODO, not working yet */
1000     irq = 25;
1001     pci_int_line = 0x101;
1002     break;
1003 dpavlin 20 }
1004    
1005 dpavlin 22 PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000 | pci_int_line);
1006 dpavlin 20
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 dpavlin 22
1070 dpavlin 20 /*
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 dpavlin 22
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    

  ViewVC Help
Powered by ViewVC 1.1.26