Add common BusState
[qemu] / hw / grackle_pci.c
index c6aee94..581d1c5 100644 (file)
 #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"
 
@@ -36,6 +46,9 @@ static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,
                                        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
@@ -51,6 +64,8 @@ static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr)
 #ifdef TARGET_WORDS_BIGENDIAN
     val = bswap32(val);
 #endif
+    GRACKLE_DPRINTF("config_readl addr " TARGET_FMT_plx " val %x\n", addr,
+                    val);
     return val;
 }
 
@@ -86,9 +101,31 @@ static int pci_grackle_map_irq(PCIDevice *pci_dev, int irq_num)
 
 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;
@@ -96,7 +133,8 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
     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,
@@ -107,26 +145,20 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
     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
@@ -144,5 +176,9 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
     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;
 }