aboutsummaryrefslogtreecommitdiffstats
path: root/tools/ioemu/hw/pci_emulation.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ioemu/hw/pci_emulation.c')
-rw-r--r--tools/ioemu/hw/pci_emulation.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/tools/ioemu/hw/pci_emulation.c b/tools/ioemu/hw/pci_emulation.c
new file mode 100644
index 0000000000..0a4a7b452b
--- /dev/null
+++ b/tools/ioemu/hw/pci_emulation.c
@@ -0,0 +1,118 @@
+/*
+ * Changes to PCI emulation made by Marathon Technologies, June 2008
+ */
+
+#include "vl.h"
+
+typedef struct {
+ PCIDevice dev;
+} PCI_EMULATION_State;
+
+void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO *pci_emulation_info)
+{
+ char *p;
+ int i;
+ int ret;
+ for (p = config_text, i = 0; *p != '\0'; p++) {
+ if (*p == ':') {
+ break;
+ }
+ if (i < sizeof(pci_emulation_info->name) - 1) {
+ pci_emulation_info->name[i] = *p;
+ i++;
+ }
+ }
+ pci_emulation_info->name[i] = '\0';
+ if (*p == '\0') return;
+ p++;
+ ret = sscanf(p, "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x",
+ &(pci_emulation_info->vendorid),
+ &(pci_emulation_info->deviceid),
+ &(pci_emulation_info->command),
+ &(pci_emulation_info->status),
+ &(pci_emulation_info->revision),
+ &(pci_emulation_info->classcode),
+ &(pci_emulation_info->headertype),
+ &(pci_emulation_info->subvendorid),
+ &(pci_emulation_info->subsystemid),
+ &(pci_emulation_info->interruputline),
+ &(pci_emulation_info->interruputpin));
+#ifdef DEBUG
+ fprintf(logfile, "qemu: pciemulation %s:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x\n",
+ pci_emulation_info->name,
+ pci_emulation_info->vendorid,
+ pci_emulation_info->deviceid,
+ pci_emulation_info->command,
+ pci_emulation_info->status,
+ pci_emulation_info->revision,
+ pci_emulation_info->classcode,
+ pci_emulation_info->headertype,
+ pci_emulation_info->subvendorid,
+ pci_emulation_info->subsystemid,
+ pci_emulation_info->interruputline,
+ pci_emulation_info->interruputpin);
+#endif
+ return;
+}
+
+static void pci_emulation_save(QEMUFile *f, void *opaque)
+{
+ PCIDevice *d = opaque;
+
+ pci_device_save(d, f);
+}
+
+static int pci_emulation_load(QEMUFile *f, void *opaque, int version_id)
+{
+ PCIDevice *d = opaque;
+
+ if (version_id != 1)
+ return -EINVAL;
+
+ return pci_device_load(d, f);
+}
+
+
+void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info)
+{
+ int instance_id;
+ PCI_EMULATION_State *d;
+ uint8_t *pci_conf;
+
+#ifdef DEBUG
+ fprintf(logfile, "qemu: pciinit\n");
+#endif
+
+ d = (PCI_EMULATION_State *)pci_register_device(bus,
+ pci_emulation_info->name,
+ sizeof(PCI_EMULATION_State),
+ -1,
+ NULL, NULL);
+ pci_conf = d->dev.config;
+ pci_conf[0x00] = pci_emulation_info->vendorid & 0xff;
+ pci_conf[0x01] = (pci_emulation_info->vendorid & 0xff00) >> 8;
+ pci_conf[0x02] = pci_emulation_info->deviceid & 0xff;
+ pci_conf[0x03] = (pci_emulation_info->deviceid & 0xff00) >> 8;
+ pci_conf[0x04] = pci_emulation_info->command & 0xff;
+ pci_conf[0x05] = (pci_emulation_info->command & 0xff00) >> 8;
+ pci_conf[0x06] = pci_emulation_info->status & 0xff;
+ pci_conf[0x07] = (pci_emulation_info->status & 0xff00) >> 8;
+ pci_conf[0x08] = pci_emulation_info->revision & 0xff;
+ pci_conf[0x09] = pci_emulation_info->classcode & 0xff;
+ pci_conf[0x0a] = (pci_emulation_info->classcode & 0xff00) >> 8;
+ pci_conf[0x0b] = (pci_emulation_info->classcode & 0xff0000) >> 16;
+ pci_conf[0x0e] = pci_emulation_info->headertype & 0xff;
+ pci_conf[0x2c] = pci_emulation_info->subvendorid & 0xff;
+ pci_conf[0x2d] = (pci_emulation_info->subvendorid & 0xff00) >> 8;
+ pci_conf[0x2e] = pci_emulation_info->subsystemid & 0xff;
+ pci_conf[0x2f] = (pci_emulation_info->subsystemid & 0xff00) >> 8;
+ pci_conf[0x3c] = pci_emulation_info->interruputline & 0xff;
+ pci_conf[0x3d] = pci_emulation_info->interruputpin & 0xff;
+
+ instance_id = pci_bus_num(bus) << 8 | d->dev.devfn;
+ register_savevm(pci_emulation_info->name, instance_id,
+ 1, pci_emulation_save, pci_emulation_load, d);
+
+
+ return;
+}