#include "ppc_mac.h"
#include "pci.h"
+/* debug Grackle */
+//#define DEBUG_GRACKLE
+
+#ifdef DEBUG_GRACKLE
+#define GRACKLE_DPRINTF(fmt, ...) \
+ do { printf("GRACKLE: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define GRACKLE_DPRINTF(fmt, ...)
+#endif
+
typedef target_phys_addr_t pci_addr_t;
#include "pci_host.h"
uint32_t val)
{
GrackleState *s = opaque;
+
+ GRACKLE_DPRINTF("config_writel addr " TARGET_FMT_plx " val %x\n", addr,
+ val);
#ifdef TARGET_WORDS_BIGENDIAN
val = bswap32(val);
#endif
#ifdef TARGET_WORDS_BIGENDIAN
val = bswap32(val);
#endif
+ GRACKLE_DPRINTF("config_readl addr " TARGET_FMT_plx " val %x\n", addr,
+ val);
return val;
}
static void pci_grackle_set_irq(qemu_irq *pic, int irq_num, int level)
{
+ GRACKLE_DPRINTF("set_irq num %d level %d\n", irq_num, level);
qemu_set_irq(pic[irq_num + 0x15], level);
}
+static void pci_grackle_save(QEMUFile* f, void *opaque)
+{
+ PCIDevice *d = opaque;
+
+ pci_device_save(d, f);
+}
+
+static int pci_grackle_load(QEMUFile* f, void *opaque, int version_id)
+{
+ PCIDevice *d = opaque;
+
+ if (version_id != 1)
+ return -EINVAL;
+
+ return pci_device_load(d, f);
+}
+
+static void pci_grackle_reset(void *opaque)
+{
+}
+
PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
{
GrackleState *s;
int pci_mem_config, pci_mem_data;
s = qemu_mallocz(sizeof(GrackleState));
- s->bus = pci_register_bus(pci_grackle_set_irq, pci_grackle_map_irq,
+ s->bus = pci_register_bus(NULL, "pci",
+ pci_grackle_set_irq, pci_grackle_map_irq,
pic, 0, 4);
pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read,
cpu_register_physical_memory(base + 0x00200000, 0x1000, pci_mem_data);
d = pci_register_device(s->bus, "Grackle host bridge", sizeof(PCIDevice),
0, NULL, NULL);
- d->config[0x00] = 0x57; // vendor_id
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x02; // device_id
- d->config[0x03] = 0x00;
+ pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MOTOROLA);
+ pci_config_set_device_id(d->config, PCI_DEVICE_ID_MOTOROLA_MPC106);
d->config[0x08] = 0x00; // revision
d->config[0x09] = 0x01;
- d->config[0x0a] = 0x00; // class_sub = host
- d->config[0x0b] = 0x06; // class_base = PCI_bridge
- d->config[0x0e] = 0x00; // header_type
+ pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
+ d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
#if 0
/* PCI2PCI bridge same values as PearPC - check this */
- d->config[0x00] = 0x11; // vendor_id
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x26; // device_id
- d->config[0x03] = 0x00;
+ pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_DEC);
+ pci_config_set_device_id(d->config, PCI_DEVICE_ID_DEC_21154);
d->config[0x08] = 0x02; // revision
- d->config[0x0a] = 0x04; // class_sub = pci2pci
- d->config[0x0b] = 0x06; // class_base = PCI_bridge
- d->config[0x0e] = 0x01; // header_type
+ pci_config_set_class(d->config, PCI_CLASS_BRIDGE_PCI);
+ d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_BRIDGE; // header_type
d->config[0x18] = 0x0; // primary_bus
d->config[0x19] = 0x1; // secondary_bus
d->config[0x26] = 0x00; // prefetchable_memory_limit
d->config[0x27] = 0x85;
#endif
+ register_savevm("grackle", 0, 1, pci_grackle_save, pci_grackle_load, d);
+ qemu_register_reset(pci_grackle_reset, 0, d);
+ pci_grackle_reset(d);
+
return s->bus;
}