25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: bus_pci.c,v 1.80 2007/02/11 10:03:55 debug Exp $ |
* $Id: bus_pci.c,v 1.84 2007/06/15 18:13:04 debug Exp $ |
29 |
* |
* |
30 |
* Generic PCI bus framework. This is not a normal "device", but is used by |
* COMMENT: Generic PCI bus framework |
31 |
* individual PCI controllers and devices. |
* |
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. |
* See NetBSD's pcidevs.h for more PCI vendor and device identifiers. |
36 |
* |
* |
60 |
#include "memory.h" |
#include "memory.h" |
61 |
#include "misc.h" |
#include "misc.h" |
62 |
|
|
63 |
|
#include "cpc700reg.h" |
64 |
#include "wdc.h" |
#include "wdc.h" |
65 |
|
|
66 |
extern int verbose; |
extern int verbose; |
243 |
pd = pd->next; |
pd = pd->next; |
244 |
} |
} |
245 |
|
|
246 |
pd = malloc(sizeof(struct pci_device)); |
CHECK_ALLOCATION(pd = malloc(sizeof(struct pci_device))); |
|
if (pd == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
|
|
|
247 |
memset(pd, 0, sizeof(struct pci_device)); |
memset(pd, 0, sizeof(struct pci_device)); |
248 |
|
|
249 |
/* Add the new device first in the PCI bus' chain: */ |
/* Add the new device first in the PCI bus' chain: */ |
250 |
pd->next = pci_data->first_device; |
pd->next = pci_data->first_device; |
251 |
pci_data->first_device = pd; |
pci_data->first_device = pd; |
252 |
|
|
253 |
|
CHECK_ALLOCATION(pd->name = strdup(name)); |
254 |
pd->pcibus = pci_data; |
pd->pcibus = pci_data; |
|
pd->name = strdup(name); |
|
255 |
pd->bus = bus; |
pd->bus = bus; |
256 |
pd->device = device; |
pd->device = device; |
257 |
pd->function = function; |
pd->function = function; |
361 |
{ |
{ |
362 |
struct pci_data *d; |
struct pci_data *d; |
363 |
|
|
364 |
d = malloc(sizeof(struct pci_data)); |
CHECK_ALLOCATION(d = malloc(sizeof(struct pci_data))); |
|
if (d == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
365 |
memset(d, 0, sizeof(struct pci_data)); |
memset(d, 0, sizeof(struct pci_data)); |
366 |
|
|
367 |
d->irq_path = strdup(irq_path); |
CHECK_ALLOCATION(d->irq_path = strdup(irq_path)); |
368 |
d->irq_path_isa = strdup(isa_irqbase); |
CHECK_ALLOCATION(d->irq_path_isa = strdup(isa_irqbase)); |
369 |
d->irq_path_pci = strdup(pci_irqbase); |
CHECK_ALLOCATION(d->irq_path_pci = strdup(pci_irqbase)); |
370 |
|
|
371 |
d->pci_actual_io_offset = pci_actual_io_offset; |
d->pci_actual_io_offset = pci_actual_io_offset; |
372 |
d->pci_actual_mem_offset = pci_actual_mem_offset; |
d->pci_actual_mem_offset = pci_actual_mem_offset; |
375 |
d->isa_portbase = isa_portbase; |
d->isa_portbase = isa_portbase; |
376 |
d->isa_membase = isa_membase; |
d->isa_membase = isa_membase; |
377 |
|
|
378 |
|
d->cur_pci_portbase = d->pci_portbase; |
379 |
|
d->cur_pci_membase = d->pci_membase; |
380 |
|
|
381 |
/* Assume that the first 64KB could be used by legacy ISA devices: */ |
/* Assume that the first 64KB could be used by legacy ISA devices: */ |
382 |
d->cur_pci_portbase = d->pci_portbase + 0x10000; |
if (d->isa_portbase != 0 || d->isa_membase != 0) { |
383 |
d->cur_pci_membase = d->pci_membase + 0x10000; |
d->cur_pci_portbase += 0x10000; |
384 |
|
d->cur_pci_membase += 0x10000; |
385 |
|
} |
386 |
|
|
387 |
return d; |
return d; |
388 |
} |
} |
805 |
/* channel 0 and 1 enabled as IDE */ |
/* channel 0 and 1 enabled as IDE */ |
806 |
PCI_SET_DATA(0x40, 0x80008000); |
PCI_SET_DATA(0x40, 0x80008000); |
807 |
|
|
808 |
pd->extra = malloc(sizeof(struct piix_ide_extra)); |
CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct piix_ide_extra))); |
|
if (pd->extra == NULL) { |
|
|
fatal("Out of memory.\n"); |
|
|
exit(1); |
|
|
} |
|
809 |
((struct piix_ide_extra *)pd->extra)->wdc0 = NULL; |
((struct piix_ide_extra *)pd->extra)->wdc0 = NULL; |
810 |
((struct piix_ide_extra *)pd->extra)->wdc1 = NULL; |
((struct piix_ide_extra *)pd->extra)->wdc1 = NULL; |
811 |
|
|
845 |
/* channel 0 and 1 enabled as IDE */ |
/* channel 0 and 1 enabled as IDE */ |
846 |
PCI_SET_DATA(0x40, 0x80008000); |
PCI_SET_DATA(0x40, 0x80008000); |
847 |
|
|
848 |
pd->extra = malloc(sizeof(struct piix_ide_extra)); |
CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct piix_ide_extra))); |
|
if (pd->extra == NULL) { |
|
|
fatal("Out of memory.\n"); |
|
|
exit(1); |
|
|
} |
|
849 |
((struct piix_ide_extra *)pd->extra)->wdc0 = NULL; |
((struct piix_ide_extra *)pd->extra)->wdc0 = NULL; |
850 |
((struct piix_ide_extra *)pd->extra)->wdc1 = NULL; |
((struct piix_ide_extra *)pd->extra)->wdc1 = NULL; |
851 |
|
|
981 |
/* channel 0 and 1 enabled */ |
/* channel 0 and 1 enabled */ |
982 |
PCI_SET_DATA(0x40, 0x00000003); |
PCI_SET_DATA(0x40, 0x00000003); |
983 |
|
|
984 |
pd->extra = malloc(sizeof(struct vt82c586_ide_extra)); |
CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct vt82c586_ide_extra))); |
|
if (pd->extra == NULL) { |
|
|
fatal("Out of memory.\n"); |
|
|
exit(1); |
|
|
} |
|
985 |
((struct vt82c586_ide_extra *)pd->extra)->wdc0 = NULL; |
((struct vt82c586_ide_extra *)pd->extra)->wdc0 = NULL; |
986 |
((struct vt82c586_ide_extra *)pd->extra)->wdc1 = NULL; |
((struct vt82c586_ide_extra *)pd->extra)->wdc1 = NULL; |
987 |
|
|
1094 |
/* channel 0 and 1 enabled */ |
/* channel 0 and 1 enabled */ |
1095 |
PCI_SET_DATA(0x40, 0x00000003); |
PCI_SET_DATA(0x40, 0x00000003); |
1096 |
|
|
1097 |
pd->extra = malloc(sizeof(struct symphony_82c105_extra)); |
CHECK_ALLOCATION(pd->extra = malloc(sizeof(struct symphony_82c105_extra))); |
|
if (pd->extra == NULL) { |
|
|
fatal("Out of memory.\n"); |
|
|
exit(1); |
|
|
} |
|
1098 |
((struct symphony_82c105_extra *)pd->extra)->wdc0 = NULL; |
((struct symphony_82c105_extra *)pd->extra)->wdc0 = NULL; |
1099 |
((struct symphony_82c105_extra *)pd->extra)->wdc1 = NULL; |
((struct symphony_82c105_extra *)pd->extra)->wdc1 = NULL; |
1100 |
|
|
1122 |
|
|
1123 |
|
|
1124 |
/* |
/* |
1125 |
|
* Realtek 8139C+ PCI ethernet. |
1126 |
|
*/ |
1127 |
|
|
1128 |
|
#define PCI_VENDOR_REALTEK 0x10ec |
1129 |
|
#define PCI_PRODUCT_REALTEK_RT8139 0x8139 |
1130 |
|
|
1131 |
|
PCIINIT(rtl8139c) |
1132 |
|
{ |
1133 |
|
uint64_t port, memaddr; |
1134 |
|
int pci_int_line = 0x101, irq = 0; |
1135 |
|
char irqstr[200]; |
1136 |
|
char tmpstr[200]; |
1137 |
|
|
1138 |
|
PCI_SET_DATA(PCI_ID_REG, PCI_ID_CODE(PCI_VENDOR_REALTEK, |
1139 |
|
PCI_PRODUCT_REALTEK_RT8139)); |
1140 |
|
|
1141 |
|
PCI_SET_DATA(PCI_CLASS_REG, PCI_CLASS_CODE(PCI_CLASS_NETWORK, |
1142 |
|
PCI_SUBCLASS_NETWORK_ETHERNET, 0x00) + 0x20); |
1143 |
|
|
1144 |
|
switch (machine->machine_type) { |
1145 |
|
case MACHINE_LANDISK: |
1146 |
|
irq = 5; |
1147 |
|
pci_int_line = 0x105; |
1148 |
|
break; |
1149 |
|
default:fatal("rtl8139c for this machine has not been " |
1150 |
|
"implemented yet\n"); |
1151 |
|
exit(1); |
1152 |
|
} |
1153 |
|
|
1154 |
|
PCI_SET_DATA(PCI_INTERRUPT_REG, 0x28140000 | pci_int_line); |
1155 |
|
|
1156 |
|
allocate_device_space(pd, 0x100, 0, &port, &memaddr); |
1157 |
|
|
1158 |
|
snprintf(irqstr, sizeof(irqstr), "%s.%i", |
1159 |
|
pd->pcibus->irq_path_pci, irq); |
1160 |
|
|
1161 |
|
snprintf(tmpstr, sizeof(tmpstr), "rtl8139c addr=0x%llx " |
1162 |
|
"irq=%s pci_little_endian=1", (long long)port, irqstr); |
1163 |
|
|
1164 |
|
device_add(machine, tmpstr); |
1165 |
|
} |
1166 |
|
|
1167 |
|
|
1168 |
|
|
1169 |
|
/* |
1170 |
* DEC 21143 ("Tulip") PCI ethernet. |
* DEC 21143 ("Tulip") PCI ethernet. |
1171 |
*/ |
*/ |
1172 |
|
|
1213 |
break; |
break; |
1214 |
case MACHINE_PMPPC: |
case MACHINE_PMPPC: |
1215 |
/* TODO, not working yet */ |
/* TODO, not working yet */ |
1216 |
irq = 31 - 21; |
irq = 31 - CPC_IB_EXT1; |
1217 |
pci_int_line = 0x201; |
pci_int_line = 0x101; |
1218 |
break; |
break; |
1219 |
case MACHINE_MACPPC: |
case MACHINE_MACPPC: |
1220 |
/* TODO, not working yet */ |
/* TODO, not working yet */ |