1 |
/* |
/* |
2 |
* Copyright (C) 2003-2006 Anders Gavare. All rights reserved. |
* Copyright (C) 2003-2007 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_eagle.c,v 1.10 2006/02/27 05:32:26 debug Exp $ |
* $Id: dev_eagle.c,v 1.18 2007/02/16 19:57:56 debug Exp $ |
29 |
* |
* |
30 |
* Motorola MPC105 "Eagle" host bridge. |
* Motorola MPC105 "Eagle" host bridge. |
31 |
*/ |
*/ |
34 |
#include <stdlib.h> |
#include <stdlib.h> |
35 |
#include <string.h> |
#include <string.h> |
36 |
|
|
37 |
|
#include "bus_isa.h" |
38 |
#include "bus_pci.h" |
#include "bus_pci.h" |
39 |
#include "cpu.h" |
#include "cpu.h" |
40 |
#include "devices.h" |
#include "device.h" |
41 |
|
#include "interrupt.h" |
42 |
#include "machine.h" |
#include "machine.h" |
43 |
#include "memory.h" |
#include "memory.h" |
44 |
#include "misc.h" |
#include "misc.h" |
45 |
|
|
46 |
|
|
47 |
struct eagle_data { |
struct eagle_data { |
48 |
int pciirq; |
struct interrupt irq; |
49 |
|
|
50 |
struct pci_data *pci_data; |
struct pci_data *pci_data; |
51 |
}; |
}; |
52 |
|
|
53 |
|
|
|
/* |
|
|
* dev_eagle_access(): |
|
|
* |
|
|
* Passes accesses to ISA ports 0xcf8 and 0xcfc onto bus_pci. |
|
|
*/ |
|
54 |
DEVICE_ACCESS(eagle) |
DEVICE_ACCESS(eagle) |
55 |
{ |
{ |
56 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
60 |
if (writeflag == MEM_WRITE) |
if (writeflag == MEM_WRITE) |
61 |
idata = memory_readmax64(cpu, data, len|MEM_PCI_LITTLE_ENDIAN); |
idata = memory_readmax64(cpu, data, len|MEM_PCI_LITTLE_ENDIAN); |
62 |
|
|
63 |
|
/* |
64 |
|
* Pass accesses to ISA ports 0xcf8 and 0xcfc onto bus_pci_*: |
65 |
|
*/ |
66 |
|
|
67 |
switch (relative_addr) { |
switch (relative_addr) { |
68 |
case 0: /* Address: */ |
case 0: /* Address: */ |
69 |
bus_pci_decompose_1(idata, &bus, &dev, &func, ®); |
bus_pci_decompose_1(idata, &bus, &dev, &func, ®); |
83 |
} |
} |
84 |
|
|
85 |
|
|
86 |
/* |
DEVINIT(eagle) |
|
* dev_eagle_init(): |
|
|
*/ |
|
|
struct pci_data *dev_eagle_init(struct machine *machine, struct memory *mem, |
|
|
int isa_irqbase, int pciirq) |
|
87 |
{ |
{ |
88 |
struct eagle_data *d; |
struct eagle_data *d; |
|
int pci_irqbase = 0; /* TODO */ |
|
89 |
uint64_t pci_io_offset, pci_mem_offset; |
uint64_t pci_io_offset, pci_mem_offset; |
90 |
uint64_t isa_portbase = 0, isa_membase = 0; |
uint64_t isa_portbase = 0, isa_membase = 0; |
91 |
uint64_t pci_portbase = 0, pci_membase = 0; |
uint64_t pci_portbase = 0, pci_membase = 0; |
92 |
|
char pci_irq_base[300]; |
93 |
|
char isa_irq_base[300]; |
94 |
|
|
95 |
d = malloc(sizeof(struct eagle_data)); |
d = malloc(sizeof(struct eagle_data)); |
96 |
if (d == NULL) { |
if (d == NULL) { |
98 |
exit(1); |
exit(1); |
99 |
} |
} |
100 |
memset(d, 0, sizeof(struct eagle_data)); |
memset(d, 0, sizeof(struct eagle_data)); |
101 |
d->pciirq = pciirq; |
|
102 |
|
/* The interrupt path to the CPU at which we are connected: */ |
103 |
|
INTERRUPT_CONNECT(devinit->interrupt_path, d->irq); |
104 |
|
|
105 |
/* |
/* |
106 |
* According to http://www.beatjapan.org/mirror/www.be.com/ |
* According to http://www.beatjapan.org/mirror/www.be.com/ |
130 |
isa_portbase = 0x80000000ULL; |
isa_portbase = 0x80000000ULL; |
131 |
isa_membase = 0xc0000000ULL; |
isa_membase = 0xc0000000ULL; |
132 |
|
|
133 |
|
switch (devinit->machine->machine_type) { |
134 |
|
case MACHINE_BEBOX: |
135 |
|
snprintf(pci_irq_base, sizeof(pci_irq_base), "%s.bebox", |
136 |
|
devinit->interrupt_path); |
137 |
|
snprintf(isa_irq_base, sizeof(isa_irq_base), "%s.bebox.5", |
138 |
|
devinit->interrupt_path); |
139 |
|
break; |
140 |
|
default: |
141 |
|
snprintf(pci_irq_base, sizeof(pci_irq_base), "%s", |
142 |
|
devinit->interrupt_path); |
143 |
|
snprintf(isa_irq_base, sizeof(isa_irq_base), "%s", |
144 |
|
devinit->interrupt_path); |
145 |
|
} |
146 |
|
|
147 |
/* Create a PCI bus: */ |
/* Create a PCI bus: */ |
148 |
d->pci_data = bus_pci_init(machine, pciirq, |
d->pci_data = bus_pci_init(devinit->machine, devinit->interrupt_path, |
149 |
pci_io_offset, pci_mem_offset, |
pci_io_offset, pci_mem_offset, |
150 |
pci_portbase, pci_membase, pci_irqbase, |
pci_portbase, pci_membase, pci_irq_base, |
151 |
isa_portbase, isa_membase, isa_irqbase); |
isa_portbase, isa_membase, isa_irq_base); |
152 |
|
|
153 |
/* Add the PCI glue for the controller itself: */ |
/* Add the PCI glue for the controller itself: */ |
154 |
bus_pci_add(machine, d->pci_data, mem, 0, 0, 0, "eagle"); |
bus_pci_add(devinit->machine, d->pci_data, |
155 |
|
devinit->machine->memory, 0, 0, 0, "eagle"); |
156 |
|
|
157 |
/* ADDR and DATA configuration ports in ISA space: */ |
/* ADDR and DATA configuration ports in ISA space: */ |
158 |
memory_device_register(mem, "eagle", isa_portbase + BUS_PCI_ADDR, |
memory_device_register(devinit->machine->memory, "eagle", |
159 |
8, dev_eagle_access, d, DM_DEFAULT, NULL); |
isa_portbase + BUS_PCI_ADDR, 8, dev_eagle_access, d, |
160 |
|
DM_DEFAULT, NULL); |
161 |
|
|
162 |
switch (machine->machine_type) { |
switch (devinit->machine->machine_type) { |
163 |
case MACHINE_BEBOX: |
case MACHINE_BEBOX: |
164 |
bus_pci_add(machine, d->pci_data, mem, 0, 11, 0, "i82378zb"); |
bus_isa_init(devinit->machine, isa_irq_base, |
165 |
|
BUS_ISA_IDE0 | BUS_ISA_VGA, isa_portbase, isa_membase); |
166 |
|
bus_pci_add(devinit->machine, d->pci_data, |
167 |
|
devinit->machine->memory, 0, 11, 0, "i82378zb"); |
168 |
break; |
break; |
169 |
case MACHINE_PREP: |
case MACHINE_PREP: |
170 |
bus_pci_add(machine, d->pci_data, mem, 0, 11, 0, "ibm_isa"); |
bus_pci_add(devinit->machine, d->pci_data, |
171 |
|
devinit->machine->memory, 0, 11, 0, "ibm_isa"); |
172 |
break; |
break; |
173 |
case MACHINE_MVMEPPC: |
case MACHINE_MVMEPPC: |
174 |
switch (machine->machine_subtype) { |
bus_isa_init(devinit->machine, isa_irq_base, |
175 |
|
BUS_ISA_LPTBASE_3BC, isa_portbase, isa_membase); |
176 |
|
switch (devinit->machine->machine_subtype) { |
177 |
case MACHINE_MVMEPPC_1600: |
case MACHINE_MVMEPPC_1600: |
178 |
bus_pci_add(machine, d->pci_data, mem, 0, 11, 0, |
bus_pci_add(devinit->machine, d->pci_data, |
179 |
"i82378zb"); |
devinit->machine->memory, 0, 11, 0, "i82378zb"); |
180 |
break; |
break; |
181 |
default:fatal("unimplemented machine subtype for " |
default:fatal("unimplemented machine subtype for " |
182 |
"eagle/mvmeppc\n"); |
"eagle/mvmeppc\n"); |
187 |
exit(1); |
exit(1); |
188 |
} |
} |
189 |
|
|
190 |
return d->pci_data; |
devinit->return_ptr = d->pci_data; |
191 |
|
|
192 |
|
return 1; |
193 |
} |
} |
194 |
|
|