25
/* XXX This file and most of its contests are somewhat misnamed. The
25
/* XXX This file and most of its contents are somewhat misnamed. The
26
26
Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
27
27
the secondary PCI bridge. */
36
#define APB_DPRINTF(fmt, args...) \
37
do { printf("APB: " fmt , ##args); } while (0)
39
#define APB_DPRINTF(fmt, args...)
31
42
typedef target_phys_addr_t pci_addr_t;
32
43
#include "pci_host.h"
39
50
APBState *s = opaque;
42
for (i = 11; i < 32; i++) {
43
if ((val & (1 << i)) != 0)
46
s->config_reg = (1 << 16) | (val & 0x7FC) | (i << 11);
52
#ifdef TARGET_WORDS_BIGENDIAN
55
APB_DPRINTF("config_writel addr " TARGET_FMT_plx " val %x\n", addr,
49
60
static uint32_t pci_apb_config_readl (void *opaque,
210
224
PCIBus *pci_apb_init(target_phys_addr_t special_base,
211
225
target_phys_addr_t mem_base,
226
qemu_irq *pic, PCIBus **bus2, PCIBus **bus3)
216
230
int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
219
232
s = qemu_mallocz(sizeof(APBState));
220
233
/* Ultrasparc PBM main bus */
230
243
pci_apb_iowrite, s);
232
245
cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
233
cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config);
234
cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);
235
cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom
246
cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10,
248
cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000,
250
cpu_register_physical_memory(mem_base, 0x10000000,
251
pci_mem_data); // XXX size should be 4G-prom
237
253
d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice),
239
d->config[0x00] = 0x8e; // vendor_id : Sun
240
d->config[0x01] = 0x10;
241
d->config[0x02] = 0x00; // device_id
242
d->config[0x03] = 0xa0;
255
pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN);
256
pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE);
243
257
d->config[0x04] = 0x06; // command = bus master, pci mem
244
258
d->config[0x05] = 0x00;
245
259
d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
246
260
d->config[0x07] = 0x03; // status = medium devsel
247
261
d->config[0x08] = 0x00; // revision
248
262
d->config[0x09] = 0x00; // programming i/f
249
d->config[0x0A] = 0x00; // class_sub = pci host
250
d->config[0x0B] = 0x06; // class_base = PCI_bridge
263
pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
251
264
d->config[0x0D] = 0x10; // latency_timer
252
265
d->config[0x0E] = 0x00; // header_type
254
267
/* APB secondary busses */
255
secondary = pci_bridge_init(s->bus, 8, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 1");
256
pci_bridge_init(s->bus, 9, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 2");
268
*bus2 = pci_bridge_init(s->bus, 8, PCI_VENDOR_ID_SUN,
269
PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,
270
"Advanced PCI Bus secondary bridge 1");
271
*bus3 = pci_bridge_init(s->bus, 9, PCI_VENDOR_ID_SUN,
272
PCI_DEVICE_ID_SUN_SIMBA, pci_apb_map_irq,
273
"Advanced PCI Bus secondary bridge 2");