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

  ViewVC Help
Powered by ViewVC 1.1.26