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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (show 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 /*
2 * Copyright (C) 2004-2006 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 * $Id: bus_pci.c,v 1.62 2006/02/18 21:03:12 debug Exp $
29 *
30 * Generic PCI bus framework. This is not a normal "device", but is used by
31 * individual PCI controllers 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_pci.h"
52 #include "cpu.h"
53 #include "device.h"
54 #include "devices.h"
55 #include "diskimage.h"
56 #include "machine.h"
57 #include "memory.h"
58 #include "misc.h"
59
60 extern int verbose;
61
62
63 /* #define debug fatal */
64
65
66 /*
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 {
73 *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 }
83
84
85 /*
86 * bus_pci_data_access():
87 *
88 * Reads from or writes to the PCI configuration registers of a device.
89 */
90 void bus_pci_data_access(struct cpu *cpu, struct pci_data *pci_data,
91 uint64_t *data, int len, int writeflag)
92 {
93 struct pci_device *dev;
94 unsigned char *cfg_base;
95 uint64_t x, idata = *data;
96 int i;
97
98 /* Scan through the list of pci_device entries. */
99 dev = pci_data->first_device;
100 while (dev != NULL) {
101 if (dev->bus == pci_data->cur_bus &&
102 dev->function == pci_data->cur_func &&
103 dev->device == pci_data->cur_device)
104 break;
105 dev = dev->next;
106 }
107
108 /* No device? Then return emptiness. */
109 if (dev == NULL) {
110 if (writeflag == MEM_READ) {
111 if (pci_data->cur_reg == 0)
112 *data = -1;
113 else
114 *data = 0;
115 } else {
116 fatal("[ bus_pci_data_access(): write to non-existant"
117 " device? ]\n");
118 }
119 return;
120 }
121
122 /* Return normal config data, or length data? */
123 if (pci_data->last_was_write_ffffffff &&
124 pci_data->cur_reg >= PCI_MAPREG_START &&
125 pci_data->cur_reg <= PCI_MAPREG_END - 4)
126 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 for (i=len-1; i>=0; i--) {
133 int ofs = pci_data->cur_reg + i;
134 x <<= 8;
135 x |= cfg_base[ofs & (PCI_CFG_MEM_SIZE - 1)];
136 }
137
138 /* Register write: */
139 if (writeflag == MEM_WRITE) {
140 debug("[ bus_pci: write to PCI DATA: data = 0x%08llx ]\n",
141 (long long)idata);
142 if (idata == 0xffffffffULL &&
143 pci_data->cur_reg >= PCI_MAPREG_START &&
144 pci_data->cur_reg <= PCI_MAPREG_END - 4) {
145 pci_data->last_was_write_ffffffff = 1;
146 return;
147 }
148 /* Writes are not really supported yet: */
149 if (idata != x) {
150 debug("[ bus_pci: write to PCI DATA: data = 0x%08llx"
151 " differs from current value 0x%08llx; NOT YET"
152 " SUPPORTED. bus %i, device %i, function %i (%s)"
153 " register 0x%02x ]\n", (long long)idata,
154 (long long)x, pci_data->cur_bus,
155 pci_data->cur_device, pci_data->cur_func,
156 dev->name, pci_data->cur_reg);
157 }
158 return;
159 }
160
161 /* Register read: */
162 *data = x;
163
164 pci_data->last_was_write_ffffffff = 0;
165
166 debug("[ bus_pci: read from PCI DATA, bus %i, device "
167 "%i, function %i (%s) register 0x%02x: 0x%08lx ]\n", (long)
168 pci_data->cur_bus, pci_data->cur_device,
169 pci_data->cur_func, dev->name, pci_data->cur_reg, (long)*data);
170 }
171
172
173 /*
174 * bus_pci_setaddr():
175 *
176 * Sets the address in preparation for a PCI register transfer.
177 */
178 void bus_pci_setaddr(struct cpu *cpu, struct pci_data *pci_data,
179 int bus, int device, int function, int reg)
180 {
181 if (cpu == NULL || pci_data == NULL) {
182 fatal("bus_pci_setaddr(): NULL ptr\n");
183 exit(1);
184 }
185
186 pci_data->cur_bus = bus;
187 pci_data->cur_device = device;
188 pci_data->cur_func = function;
189 pci_data->cur_reg = reg;
190 }
191
192
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 const char *name)
201 {
202 struct pci_device *pd;
203 int ofs;
204 void (*init)(struct machine *, struct memory *, struct pci_device *);
205
206 if (pci_data == NULL) {
207 fatal("bus_pci_add(): pci_data == NULL!\n");
208 exit(1);
209 }
210
211 /* Find the PCI device: */
212 init = pci_lookup_initf(name);
213
214 /* Make sure this bus/device/function number isn't already in use: */
215 pd = pci_data->first_device;
216 while (pd != NULL) {
217 if (pd->bus == bus && pd->device == device &&
218 pd->function == function) {
219 fatal("bus_pci_add(): (bus %i, device %i, function"
220 " %i) already in use\n", bus, device, function);
221 exit(1);
222 }
223 pd = pd->next;
224 }
225
226 pd = malloc(sizeof(struct pci_device));
227 if (pd == NULL) {
228 fprintf(stderr, "out of memory\n");
229 exit(1);
230 }
231
232 memset(pd, 0, sizeof(struct pci_device));
233
234 /* Add the new device first in the PCI bus' chain: */
235 pd->next = pci_data->first_device;
236 pci_data->first_device = pd;
237
238 pd->pcibus = pci_data;
239 pd->name = strdup(name);
240 pd->bus = bus;
241 pd->device = device;
242 pd->function = function;
243
244 /*
245 * Initialize with some default values:
246 *
247 * TODO: The command status register is best to set up per device.
248 * The size registers should also be set up on a per-device basis.
249 */
250 PCI_SET_DATA(PCI_COMMAND_STATUS_REG,
251 PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE);
252 for (ofs = PCI_MAPREG_START; ofs < PCI_MAPREG_END; ofs += 4)
253 PCI_SET_DATA_SIZE(ofs, 0x00100000 - 1);
254
255 if (init == NULL) {
256 fatal("No init function for PCI device \"%s\"?\n", name);
257 exit(1);
258 }
259
260 /* Call the PCI device' init function: */
261 init(machine, mem, pd);
262 }
263
264
265 /*
266 * allocate_device_space():
267 *
268 * Used by glue code (see below) to allocate space for a PCI device.
269 *
270 * The returned values in portp and memp are the actual (emulated) addresses
271 * that the device should use. (Normally only one of these is actually used.)
272 *
273 * TODO: PCI irqs?
274 */
275 static void allocate_device_space(struct pci_device *pd,
276 uint64_t portsize, uint64_t memsize,
277 uint64_t *portp, uint64_t *memp)
278 {
279 uint64_t port, mem;
280
281 /* Calculate an aligned starting port: */
282 port = pd->pcibus->cur_pci_portbase;
283 if (portsize != 0) {
284 port = ((port - 1) | (portsize - 1)) + 1;
285 pd->pcibus->cur_pci_portbase = port;
286 PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset,
287 port | PCI_MAPREG_TYPE_IO);
288 PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,
289 portsize - 1);
290 pd->cur_mapreg_offset += sizeof(uint32_t);
291 }
292
293 /* Calculate an aligned starting memory location: */
294 mem = pd->pcibus->cur_pci_membase;
295 if (memsize != 0) {
296 mem = ((mem - 1) | (memsize - 1)) + 1;
297 pd->pcibus->cur_pci_membase = mem;
298 PCI_SET_DATA(PCI_MAPREG_START + pd->cur_mapreg_offset, mem);
299 PCI_SET_DATA_SIZE(PCI_MAPREG_START + pd->cur_mapreg_offset,
300 memsize - 1);
301 pd->cur_mapreg_offset += sizeof(uint32_t);
302 }
303
304 *portp = port + pd->pcibus->pci_actual_io_offset;
305 *memp = mem + pd->pcibus->pci_actual_mem_offset;
306
307 if (verbose >= 2) {
308 debug("pci device '%s' at", pd->name);
309 if (portsize != 0)
310 debug(" port 0x%llx-0x%llx", (long long)pd->pcibus->
311 cur_pci_portbase, (long long)(pd->pcibus->
312 cur_pci_portbase + portsize - 1));
313 if (memsize != 0)
314 debug(" mem 0x%llx-0x%llx", (long long)pd->pcibus->
315 cur_pci_membase, (long long)(pd->pcibus->
316 cur_pci_membase + memsize - 1));
317 debug("\n");
318 }
319
320 pd->pcibus->cur_pci_portbase += portsize;
321 pd->pcibus->cur_pci_membase += memsize;
322 }
323
324
325 static void bus_pci_debug_dump__2(struct pci_device *pd)
326 {
327 if (pd == NULL)
328 return;
329 bus_pci_debug_dump__2(pd->next);
330 debug("bus %3i, dev %2i, func %i: %s\n",
331 pd->bus, pd->device, pd->function, pd->name);
332 }
333
334
335 /*
336 * bus_pci_debug_dump():
337 *
338 * Lists the attached PCI devices (in reverse).
339 */
340 void bus_pci_debug_dump(void *extra)
341 {
342 struct pci_data *d = (struct pci_data *) extra;
343 int iadd = DEBUG_INDENTATION;
344
345 debug("pci:\n");
346 debug_indentation(iadd);
347
348 if (d->first_device == NULL)
349 debug("no devices!\n");
350 else
351 bus_pci_debug_dump__2(d->first_device);
352
353 debug_indentation(-iadd);
354 }
355
356
357 /*
358 * bus_pci_init():
359 *
360 * This doesn't register a device, but instead returns a pointer to a struct
361 * which should be passed to other bus_pci functions when accessing the bus.
362 *
363 * irq_nr is the (optional) IRQ nr that this PCI bus interrupts at.
364 *
365 * pci_portbase, pci_membase, and pci_irqbase are the port, memory, and
366 * interrupt bases for PCI devices (as found in the configuration registers).
367 *
368 * pci_actual_io_offset and pci_actual_mem_offset are the offset from
369 * the values in the configuration registers to the actual (emulated) device.
370 *
371 * isa_portbase, isa_membase, and isa_irqbase are the port, memory, and
372 * interrupt bases for legacy ISA devices.
373 */
374 struct pci_data *bus_pci_init(struct machine *machine, int irq_nr,
375 uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset,
376 uint64_t pci_portbase, uint64_t pci_membase, int pci_irqbase,
377 uint64_t isa_portbase, uint64_t isa_membase, int isa_irqbase)
378 {
379 struct pci_data *d;
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 d->irq_nr = irq_nr;
388 d->pci_actual_io_offset = pci_actual_io_offset;
389 d->pci_actual_mem_offset = pci_actual_mem_offset;
390 d->pci_portbase = pci_portbase;
391 d->pci_membase = pci_membase;
392 d->pci_irqbase = pci_irqbase;
393 d->isa_portbase = isa_portbase;
394 d->isa_membase = isa_membase;
395 d->isa_irqbase = isa_irqbase;
396
397 /* Register the bus: */
398 machine_bus_register(machine, "pci", bus_pci_debug_dump, d);
399
400 /* Assume that the first 64KB could be used by legacy ISA devices: */
401 d->cur_pci_portbase = d->pci_portbase + 0x10000;
402 d->cur_pci_membase = d->pci_membase + 0x10000;
403
404 return d;
405 }
406
407
408
409 /******************************************************************************
410 * *
411 * The following is glue code for PCI controllers and devices. The glue *
412 * code does the minimal stuff necessary to get an emulated OS to detect *
413 * the device (i.e. set up PCI configuration registers), and then if *
414 * necessary adds a "normal" device. *
415 * *
416 ******************************************************************************/
417
418
419
420 /*
421 * Integraphics Systems "igsfb" Framebuffer (graphics) card.
422 *
423 * TODO
424 */
425
426 #define PCI_VENDOR_INTEGRAPHICS 0x10ea
427
428 PCIINIT(igsfb)
429 {
430 PCI_SET_DATA(PCI_ID_REG,
431 PCI_ID_CODE(PCI_VENDOR_INTEGRAPHICS, 0x2010));
432
433 PCI_SET_DATA(PCI_CLASS_REG,
434 PCI_CLASS_CODE(PCI_CLASS_DISPLAY,
435 PCI_SUBCLASS_DISPLAY_VGA, 0) + 0x01);
436
437 /* TODO */
438 PCI_SET_DATA(0x10, 0x08000000);
439
440 dev_vga_init(machine, mem, pd->pcibus->isa_membase + 0xa0000,
441 0x88800000 + 0x3c0, machine->machine_name);
442 }
443
444
445
446 /*
447 * S3 ViRGE graphics.
448 *
449 * TODO: Only emulates a standard VGA card, so far.
450 */
451
452 #define PCI_VENDOR_S3 0x5333
453 #define PCI_PRODUCT_S3_VIRGE 0x5631
454 #define PCI_PRODUCT_S3_VIRGE_DX 0x8a01
455
456 PCIINIT(s3_virge)
457 {
458 PCI_SET_DATA(PCI_ID_REG,
459 PCI_ID_CODE(PCI_VENDOR_S3, PCI_PRODUCT_S3_VIRGE_DX));
460
461 PCI_SET_DATA(PCI_CLASS_REG,
462 PCI_CLASS_CODE(PCI_CLASS_DISPLAY,
463 PCI_SUBCLASS_DISPLAY_VGA, 0) + 0x01);
464
465 dev_vga_init(machine, mem, pd->pcibus->isa_membase + 0xa0000,
466 pd->pcibus->isa_portbase + 0x3c0, machine->machine_name);
467 }
468
469
470
471 /*
472 * Acer Labs M5229 PCI-IDE (UDMA) controller.
473 * Acer Labs M1543 PCI->ISA bridge.
474 */
475
476 #define PCI_VENDOR_ALI 0x10b9
477 #define PCI_PRODUCT_ALI_M1543 0x1533 /* NOTE: not 1543 */
478 #define PCI_PRODUCT_ALI_M5229 0x5229
479
480 PCIINIT(ali_m1543)
481 {
482 PCI_SET_DATA(PCI_ID_REG,
483 PCI_ID_CODE(PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M1543));
484
485 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
486 PCI_SUBCLASS_BRIDGE_ISA, 0) + 0xc3);
487
488 PCI_SET_DATA(PCI_BHLC_REG,
489 PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
490
491 /* Linux uses these to detect which IRQ the IDE controller uses: */
492 PCI_SET_DATA(0x44, 0x0000000e);
493 PCI_SET_DATA(0x58, 0x00000003);
494 }
495
496 PCIINIT(ali_m5229)
497 {
498 char tmpstr[300];
499
500 PCI_SET_DATA(PCI_ID_REG,
501 PCI_ID_CODE(PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M5229));
502
503 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
504 PCI_SUBCLASS_MASS_STORAGE_IDE, 0x60) + 0xc1);
505
506 if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
507 diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
508 snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
509 (long long)(pd->pcibus->isa_portbase + 0x1f0),
510 pd->pcibus->isa_irqbase + 14);
511 device_add(machine, tmpstr);
512 }
513
514 /* The secondary channel is disabled. TODO: fix this. */
515 }
516
517
518
519 /*
520 * Adaptec AHC SCSI controller.
521 */
522
523 #define PCI_VENDOR_ADP 0x9004 /* Adaptec */
524 #define PCI_VENDOR_ADP2 0x9005 /* Adaptec (2nd PCI Vendor ID) */
525 #define PCI_PRODUCT_ADP_2940U 0x8178 /* AHA-2940 Ultra */
526 #define PCI_PRODUCT_ADP_2940UP 0x8778 /* AHA-2940 Ultra Pro */
527
528 PCIINIT(ahc)
529 {
530 /* Numbers taken from a Adaptec 2940U: */
531 /* http://mail-index.netbsd.org/netbsd-bugs/2000/04/29/0000.html */
532
533 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_ADP,
534 PCI_PRODUCT_ADP_2940U));
535
536 PCI_SET_DATA(PCI_COMMAND_STATUS_REG, 0x02900007);
537
538 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
539 PCI_SUBCLASS_MASS_STORAGE_SCSI, 0) + 0x01);
540
541 PCI_SET_DATA(PCI_BHLC_REG, 0x00004008);
542
543 /* 1 = type i/o. 0x0000e801; address? */
544 /* second address reg = 0xf1002000? */
545 PCI_SET_DATA(PCI_MAPREG_START + 0x00, 0x00000001);
546 PCI_SET_DATA(PCI_MAPREG_START + 0x04, 0x00000000);
547
548 PCI_SET_DATA(PCI_MAPREG_START + 0x08, 0x00000000);
549 PCI_SET_DATA(PCI_MAPREG_START + 0x0c, 0x00000000);
550 PCI_SET_DATA(PCI_MAPREG_START + 0x10, 0x00000000);
551 PCI_SET_DATA(PCI_MAPREG_START + 0x14, 0x00000000);
552 PCI_SET_DATA(PCI_MAPREG_START + 0x18, 0x00000000);
553
554 /* Subsystem vendor ID? 0x78819004? */
555 PCI_SET_DATA(PCI_MAPREG_START + 0x1c, 0x00000000);
556
557 PCI_SET_DATA(0x30, 0xef000000);
558 PCI_SET_DATA(PCI_CAPLISTPTR_REG, 0x000000dc);
559 PCI_SET_DATA(0x38, 0x00000000);
560 PCI_SET_DATA(PCI_INTERRUPT_REG, 0x08080109); /* interrupt pin A */
561
562 /*
563 * TODO: this address is based on what NetBSD/sgimips uses
564 * on SGI IP32 (O2). Fix this!
565 */
566
567 device_add(machine, "ahc addr=0x18000000");
568
569 /* OpenBSD/sgi snapshots sometime between 2005-03-11 and
570 2005-04-04 changed to using 0x1a000000: */
571 dev_ram_init(machine, 0x1a000000, 0x2000000, DEV_RAM_MIRROR,
572 0x18000000);
573 }
574
575
576
577 /*
578 * Galileo Technology GT-64xxx PCI controller.
579 *
580 * GT-64011 Used in Cobalt machines.
581 * GT-64120 Used in evbmips machines (Malta).
582 *
583 * NOTE: This works in the opposite way compared to other devices; the PCI
584 * device is added from the normal device instead of the other way around.
585 */
586
587 #define PCI_VENDOR_GALILEO 0x11ab /* Galileo Technology */
588 #define PCI_PRODUCT_GALILEO_GT64011 0x4146 /* GT-64011 System Controller */
589 #define PCI_PRODUCT_GALILEO_GT64120 0x4620 /* GT-64120 */
590 #define PCI_PRODUCT_GALILEO_GT64260 0x6430 /* GT-64260 */
591
592 PCIINIT(gt64011)
593 {
594 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_GALILEO,
595 PCI_PRODUCT_GALILEO_GT64011));
596
597 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
598 PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x01); /* Revision 1 */
599 }
600
601 PCIINIT(gt64120)
602 {
603 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_GALILEO,
604 PCI_PRODUCT_GALILEO_GT64120));
605
606 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
607 PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x02); /* Revision 2? */
608
609 switch (machine->machine_type) {
610 case MACHINE_EVBMIPS:
611 PCI_SET_DATA(PCI_MAPREG_START + 0x10, 0x1be00000);
612 break;
613 }
614 }
615
616 PCIINIT(gt64260)
617 {
618 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_GALILEO,
619 PCI_PRODUCT_GALILEO_GT64260));
620
621 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
622 PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x01); /* Revision 1? */
623 }
624
625
626
627 /*
628 * Intel 31244 Serial ATA Controller
629 * Intel 82371SB PIIX3 PCI-ISA bridge
630 * Intel 82371AB PIIX4 PCI-ISA bridge
631 * Intel 82371SB IDE controller
632 * Intel 82371AB IDE controller
633 * Intel 82378ZB System I/O controller.
634 */
635
636 #define PCI_VENDOR_INTEL 0x8086
637 #define PCI_PRODUCT_INTEL_31244 0x3200
638 #define PCI_PRODUCT_INTEL_82371SB_ISA 0x7000
639 #define PCI_PRODUCT_INTEL_82371SB_IDE 0x7010
640 #define PCI_PRODUCT_INTEL_82371AB_ISA 0x7110
641 #define PCI_PRODUCT_INTEL_82371AB_IDE 0x7111
642 #define PCI_PRODUCT_INTEL_SIO 0x0484
643
644 PCIINIT(i31244)
645 {
646 uint64_t port, memaddr;
647
648 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
649 PCI_PRODUCT_INTEL_31244));
650
651 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
652 PCI_SUBCLASS_MASS_STORAGE_IDE, 0x33) + 0x00);
653
654 switch (machine->machine_type) {
655 case MACHINE_IQ80321:
656 /* S-PCI-X slot uses PCI IRQ A */
657 break;
658 default:fatal("i31244 in non-implemented machine type %i\n",
659 machine->machine_type);
660 exit(1);
661 }
662
663 PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140100);
664
665 allocate_device_space(pd, 0x400, 0, &port, &memaddr);
666 allocate_device_space(pd, 0x400, 0, &port, &memaddr);
667
668 /* PCI IDE using dev_wdc: */
669 if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
670 diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
671 char tmpstr[150];
672 snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
673 (long long)(pd->pcibus->pci_actual_io_offset + 0),
674 pd->pcibus->pci_irqbase + 0);
675 device_add(machine, tmpstr);
676 }
677 }
678
679 PCIINIT(piix3_isa)
680 {
681 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
682 PCI_PRODUCT_INTEL_82371SB_ISA));
683
684 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
685 PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x01); /* Rev 1 */
686
687 PCI_SET_DATA(PCI_BHLC_REG,
688 PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
689 }
690
691 PCIINIT(piix4_isa)
692 {
693 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
694 PCI_PRODUCT_INTEL_82371AB_ISA));
695
696 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
697 PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x01); /* Rev 1 */
698
699 PCI_SET_DATA(PCI_BHLC_REG,
700 PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
701 }
702
703 PCIINIT(i82378zb)
704 {
705 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
706 PCI_PRODUCT_INTEL_SIO));
707
708 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
709 PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x43);
710
711 PCI_SET_DATA(PCI_BHLC_REG,
712 PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
713
714 PCI_SET_DATA(0x40, 0x20);
715
716 /* PIRQ[0]=10 PIRQ[1]=11 PIRQ[2]=14 PIRQ[3]=15 */
717 PCI_SET_DATA(0x60, 0x0f0e0b0a);
718 }
719
720 PCIINIT(piix3_ide)
721 {
722 char tmpstr[100];
723
724 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
725 PCI_PRODUCT_INTEL_82371SB_IDE));
726
727 /* Possibly not correct: */
728 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
729 PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x00);
730
731 /* PIIX_IDETIM (see NetBSD's pciide_piix_reg.h) */
732 /* channel 0 and 1 enabled as IDE */
733 PCI_SET_DATA(0x40, 0x80008000);
734
735 if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
736 diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
737 snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
738 (long long)(pd->pcibus->isa_portbase + 0x1f0),
739 pd->pcibus->isa_irqbase + 14);
740 device_add(machine, tmpstr);
741 }
742
743 if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
744 diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
745 snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
746 (long long)(pd->pcibus->isa_portbase + 0x170),
747 pd->pcibus->isa_irqbase + 15);
748 device_add(machine, tmpstr);
749 }
750 }
751
752 PCIINIT(piix4_ide)
753 {
754 char tmpstr[100];
755
756 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_INTEL,
757 PCI_PRODUCT_INTEL_82371AB_IDE));
758
759 /* Possibly not correct: */
760 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
761 PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x01);
762
763 /* PIIX_IDETIM (see NetBSD's pciide_piix_reg.h) */
764 /* channel 0 and 1 enabled as IDE */
765 PCI_SET_DATA(0x40, 0x80008000);
766
767 if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
768 diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
769 snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
770 (long long)(pd->pcibus->isa_portbase + 0x1f0),
771 pd->pcibus->isa_irqbase + 14);
772 device_add(machine, tmpstr);
773 }
774
775 if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
776 diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
777 snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
778 (long long)(pd->pcibus->isa_portbase + 0x170),
779 pd->pcibus->isa_irqbase + 15);
780 device_add(machine, tmpstr);
781 }
782 }
783
784
785
786 /*
787 * IBM ISA bridge (used by at least one PReP machine).
788 */
789
790 #define PCI_VENDOR_IBM 0x1014
791 #define PCI_PRODUCT_IBM_ISABRIDGE 0x000a
792
793 PCIINIT(ibm_isa)
794 {
795 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_IBM,
796 PCI_PRODUCT_IBM_ISABRIDGE));
797
798 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
799 PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x02);
800
801 PCI_SET_DATA(PCI_BHLC_REG,
802 PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
803 }
804
805
806
807 /*
808 * Heuricon PCI host bridge for PM/PPC.
809 */
810
811 #define PCI_VENDOR_HEURICON 0x1223
812 #define PCI_PRODUCT_HEURICON_PMPPC 0x000e
813
814 PCIINIT(heuricon_pmppc)
815 {
816 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_HEURICON,
817 PCI_PRODUCT_HEURICON_PMPPC));
818
819 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
820 PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x00); /* Revision? */
821
822 PCI_SET_DATA(PCI_BHLC_REG,
823 PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
824 }
825
826
827
828 /*
829 * VIATECH VT82C586 devices:
830 *
831 * vt82c586_isa PCI->ISA bridge
832 * vt82c586_ide IDE controller
833 *
834 * TODO: This more or less just a dummy device, so far.
835 */
836
837 #define PCI_VENDOR_VIATECH 0x1106 /* VIA Technologies */
838 #define PCI_PRODUCT_VIATECH_VT82C586_IDE 0x1571 /* VT82C586 (Apollo VP)
839 IDE Controller */
840 #define PCI_PRODUCT_VIATECH_VT82C586_ISA 0x0586 /* VT82C586 (Apollo VP)
841 PCI-ISA Bridge */
842
843 PCIINIT(vt82c586_isa)
844 {
845 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_VIATECH,
846 PCI_PRODUCT_VIATECH_VT82C586_ISA));
847
848 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
849 PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x39); /* Revision 37 or 39 */
850
851 PCI_SET_DATA(PCI_BHLC_REG,
852 PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
853 }
854
855 PCIINIT(vt82c586_ide)
856 {
857 char tmpstr[100];
858
859 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_VIATECH,
860 PCI_PRODUCT_VIATECH_VT82C586_IDE));
861
862 /* Possibly not correct: */
863 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
864 PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x01);
865
866 /* APO_IDECONF */
867 /* channel 0 and 1 enabled */
868 PCI_SET_DATA(0x40, 0x00000003);
869
870 if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
871 diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
872 snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
873 (long long)(pd->pcibus->isa_portbase + 0x1f0),
874 pd->pcibus->isa_irqbase + 14);
875 device_add(machine, tmpstr);
876 }
877
878 if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
879 diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
880 snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
881 (long long)(pd->pcibus->isa_portbase + 0x170),
882 pd->pcibus->isa_irqbase + 15);
883 device_add(machine, tmpstr);
884 }
885 }
886
887
888
889 /*
890 * Symphony Labs 83C553 PCI->ISA bridge.
891 * Symphony Labs 82C105 PCIIDE controller.
892 */
893
894 #define PCI_VENDOR_SYMPHONY 0x10ad
895 #define PCI_PRODUCT_SYMPHONY_83C553 0x0565
896 #define PCI_PRODUCT_SYMPHONY_82C105 0x0105
897
898 PCIINIT(symphony_83c553)
899 {
900 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_SYMPHONY,
901 PCI_PRODUCT_SYMPHONY_83C553));
902
903 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
904 PCI_SUBCLASS_BRIDGE_ISA, 0) + 0x10);
905
906 PCI_SET_DATA(PCI_BHLC_REG,
907 PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
908 }
909
910 PCIINIT(symphony_82c105)
911 {
912 char tmpstr[100];
913
914 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_SYMPHONY,
915 PCI_PRODUCT_SYMPHONY_82C105));
916
917 /* Possibly not correct: */
918 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_MASS_STORAGE,
919 PCI_SUBCLASS_MASS_STORAGE_IDE, 0x00) + 0x05);
920
921 /* APO_IDECONF */
922 /* channel 0 and 1 enabled */
923 PCI_SET_DATA(0x40, 0x00000003);
924
925 if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
926 diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
927 snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
928 (long long)(pd->pcibus->isa_portbase + 0x1f0),
929 pd->pcibus->isa_irqbase + 14);
930 device_add(machine, tmpstr);
931 }
932
933 if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
934 diskimage_exist(machine, 3, DISKIMAGE_IDE)) {
935 snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i",
936 (long long)(pd->pcibus->isa_portbase + 0x170),
937 pd->pcibus->isa_irqbase + 15);
938 device_add(machine, tmpstr);
939 }
940 }
941
942
943
944 /*
945 * DEC 21143 ("Tulip") PCI ethernet.
946 */
947
948 #define PCI_VENDOR_DEC 0x1011 /* Digital Equipment */
949 #define PCI_PRODUCT_DEC_21142 0x0019 /* DECchip 21142/21143 10/100 Ethernet */
950
951 PCIINIT(dec21143)
952 {
953 uint64_t port, memaddr;
954 int irq = 0; /* TODO */
955 int pci_int_line = 0x101;
956 char tmpstr[200];
957
958 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_DEC,
959 PCI_PRODUCT_DEC_21142));
960
961 PCI_SET_DATA(PCI_COMMAND_STATUS_REG, 0x02000017);
962
963 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_NETWORK,
964 PCI_SUBCLASS_NETWORK_ETHERNET, 0x00) + 0x41);
965
966 PCI_SET_DATA(PCI_BHLC_REG, PCI_BHLC_CODE(0,0,0, 0x40,0));
967
968 switch (machine->machine_type) {
969 case MACHINE_CATS:
970 /* CATS int 18 = PCI. */
971 irq = 18;
972 pci_int_line = 0x101;
973 break;
974 case MACHINE_COBALT:
975 /* On Cobalt, IRQ 7 = PCI. */
976 irq = 8 + 7;
977 pci_int_line = 0x407;
978 break;
979 case MACHINE_ALGOR:
980 /* TODO */
981 irq = 8 + 7;
982 pci_int_line = 0x407;
983 break;
984 case MACHINE_PREP:
985 irq = 32 + 10;
986 pci_int_line = 0x20a;
987 break;
988 case MACHINE_MVMEPPC:
989 /* TODO */
990 irq = 32 + 10;
991 pci_int_line = 0x40a;
992 break;
993 case MACHINE_PMPPC:
994 /* TODO, not working yet */
995 irq = 31 - 21;
996 pci_int_line = 0x201;
997 break;
998 case MACHINE_MACPPC:
999 /* TODO, not working yet */
1000 irq = 25;
1001 pci_int_line = 0x101;
1002 break;
1003 }
1004
1005 PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000 | pci_int_line);
1006
1007 allocate_device_space(pd, 0x100, 0x100, &port, &memaddr);
1008
1009 snprintf(tmpstr, sizeof(tmpstr), "dec21143 addr=0x%llx addr2=0x%llx "
1010 "irq=%i pci_little_endian=1", (long long)port, (long long)memaddr,
1011 irq);
1012 device_add(machine, tmpstr);
1013 }
1014
1015
1016
1017 /*
1018 * DEC 21030 "tga" graphics.
1019 */
1020
1021 #define PCI_PRODUCT_DEC_21030 0x0004 /* DECchip 21030 ("TGA") */
1022
1023 PCIINIT(dec21030)
1024 {
1025 uint64_t base = 0;
1026 char tmpstr[200];
1027
1028 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_DEC,
1029 PCI_PRODUCT_DEC_21030));
1030
1031 PCI_SET_DATA(PCI_COMMAND_STATUS_REG, 0x02800087); /* TODO */
1032
1033 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_DISPLAY,
1034 PCI_SUBCLASS_DISPLAY_VGA, 0x00) + 0x03);
1035
1036 /*
1037 * See http://mail-index.netbsd.org/port-arc/2001/08/13/0000.html
1038 * for more info.
1039 */
1040
1041 PCI_SET_DATA(PCI_BHLC_REG, 0x0000ff00);
1042
1043 /* 8 = prefetchable */
1044 PCI_SET_DATA(0x10, 0x00000008);
1045 PCI_SET_DATA(0x30, 0x08000001);
1046 PCI_SET_DATA(PCI_INTERRUPT_REG, 0x00000100); /* interrupt pin A? */
1047
1048 /*
1049 * Experimental:
1050 *
1051 * TODO: Base address, pci_little_endian, ...
1052 */
1053
1054 switch (machine->machine_type) {
1055 case MACHINE_ARC:
1056 base = 0x100000000ULL;
1057 break;
1058 default:fatal("dec21030 in non-implemented machine type %i\n",
1059 machine->machine_type);
1060 exit(1);
1061 }
1062
1063 snprintf(tmpstr, sizeof(tmpstr), "dec21030 addr=0x%llx",
1064 (long long)(base));
1065 device_add(machine, tmpstr);
1066 }
1067
1068
1069
1070 /*
1071 * Motorola MPC105 "Eagle" Host Bridge
1072 *
1073 * Used in at least PReP and BeBox.
1074 */
1075
1076 #define PCI_VENDOR_MOT 0x1057
1077 #define PCI_PRODUCT_MOT_MPC105 0x0001
1078
1079 PCIINIT(eagle)
1080 {
1081 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_MOT,
1082 PCI_PRODUCT_MOT_MPC105));
1083
1084 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
1085 PCI_SUBCLASS_BRIDGE_HOST, 0) + 0x24);
1086
1087 PCI_SET_DATA(PCI_BHLC_REG,
1088 PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1089 }
1090
1091
1092
1093 /*
1094 * Apple (MacPPC) stuff:
1095 *
1096 * Grand Central (I/O controller)
1097 * Uni-North (PCI controller)
1098 */
1099
1100 #define PCI_VENDOR_APPLE 0x106b
1101 #define PCI_PRODUCT_APPLE_GC 0x0002
1102 #define PCI_PRODUCT_APPLE_UNINORTH1 0x001e
1103
1104 PCIINIT(gc_obio)
1105 {
1106 uint64_t port, memaddr;
1107
1108 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_APPLE,
1109 PCI_PRODUCT_APPLE_GC));
1110
1111 /* TODO: */
1112 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_SYSTEM,
1113 PCI_SUBCLASS_SYSTEM_PIC, 0) + 0x00);
1114
1115 PCI_SET_DATA(PCI_BHLC_REG,
1116 PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1117
1118 /* TODO */
1119 allocate_device_space(pd, 0x10000, 0x10000, &port, &memaddr);
1120 }
1121
1122 PCIINIT(uninorth)
1123 {
1124 uint64_t port, memaddr;
1125
1126 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_APPLE,
1127 PCI_PRODUCT_APPLE_UNINORTH1));
1128
1129 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
1130 PCI_SUBCLASS_BRIDGE_HOST, 0) + 0xff);
1131
1132 PCI_SET_DATA(PCI_BHLC_REG,
1133 PCI_BHLC_CODE(0,0, 1 /* multi-function */, 0x40,0));
1134
1135 /* TODO */
1136 allocate_device_space(pd, 0x10000, 0x10000, &port, &memaddr);
1137 }
1138
1139
1140
1141 /*
1142 * ATI graphics cards
1143 */
1144
1145 #define PCI_VENDOR_ATI 0x1002
1146 #define PCI_PRODUCT_ATI_RADEON_9200_2 0x5962
1147
1148 PCIINIT(ati_radeon_9200_2)
1149 {
1150 uint64_t port, memaddr;
1151
1152 PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_ATI,
1153 PCI_PRODUCT_ATI_RADEON_9200_2));
1154
1155 /* TODO: other subclass? */
1156 PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_DISPLAY,
1157 PCI_SUBCLASS_DISPLAY_VGA, 0) + 0x03);
1158
1159 /* TODO */
1160 allocate_device_space(pd, 0x1000, 0x400000, &port, &memaddr);
1161 }
1162

  ViewVC Help
Powered by ViewVC 1.1.26