<div dir="ltr">hw/pci/pci.c<div><br></div><div>this patch adds:</div><div>* read / write host PCI config space</div><div><br></div><div><div>patch</div><div>---------------------</div></div><div><br></div><div><div>diff --git a/hw/pci/pci.c b/hw/pci/pci.c</div><div>index 42995e6..041f6f1 100644</div><div>--- a/hw/pci/pci.c</div><div>+++ b/hw/pci/pci.c</div><div>@@ -2,6 +2,8 @@</div><div>  * QEMU PCI bus manager</div><div>  *</div><div>  * Copyright (c) 2004 Fabrice Bellard</div><div>+ *    2014 Andrew Barnes <<a href="mailto:andy@outsideglobe.com">andy@outsideglobe.com</a>> IGD Support</div><div>+ *        Temporarily extended to provide host config read/write.</div><div>  *</div><div>  * Permission is hereby granted, free of charge, to any person obtaining a copy</div><div>  * of this software and associated documentation files (the "Software"), to deal</div><div>@@ -37,9 +39,9 @@</div><div> #include "exec/address-spaces.h"</div><div> #include "hw/hotplug.h"</div><div> </div><div>-//#define DEBUG_PCI</div><div>+/* #define DEBUG_PCI */</div><div> #ifdef DEBUG_PCI</div><div>-# define PCI_DPRINTF(format, ...)       printf(format, ## __VA_ARGS__)</div><div>+# define PCI_DPRINTF(format, ...)       printf("pci:" format, ## __VA_ARGS__)</div><div> #else</div><div> # define PCI_DPRINTF(format, ...)       do { } while (0)</div><div> #endif</div><div>@@ -60,6 +62,81 @@ static Property pci_props[] = {</div><div>     DEFINE_PROP_END_OF_LIST()</div><div> };</div><div> </div><div>+/* Provides config reads from the host */</div><div>+uint32_t host_pci_read_config(int bus, int slot, int fn, uint32_t address, int len)</div><div>+{</div><div>+    uint32_t val = 0;</div><div>+    int fd;</div><div>+    int domain = 0;</div><div>+    ssize_t ret;</div><div>+    char dir[128], name[128];</div><div>+</div><div>+    snprintf(dir, sizeof(dir), "/sys/bus/pci/devices/%04x:%02x:%02x.%x/",</div><div>+             domain, bus, slot, fn);</div><div>+    snprintf(name, sizeof(name), "%sconfig", dir);</div><div>+</div><div>+    fd = open(name, O_RDONLY);</div><div>+</div><div>+    if (fd >= 0)</div><div>+    {</div><div>+        do</div><div>+        {</div><div>+            ret = pread(fd,&val,len,address);</div><div>+        } while ((ret < 0) && (errno == EINTR || errno == EAGAIN));</div><div>+</div><div>+        if (ret != len)</div><div>+        {</div><div>+            PCI_DPRINTF("%s(%04x:%02x:%02x.%x, @0x%x, len=0x%x) %s ret=%zd error=%d\n",</div><div>+                 __func__, 0000, bus, slot, fn, address, len, "pread Failed",ret,errno);</div><div>+            val = (1UL << (len * 8)) - 1;</div><div>+        }</div><div>+    }</div><div>+    else</div><div>+    {</div><div>+        PCI_DPRINTF("%s(%04x:%02x:%02x.%x, @0x%x, len=0x%x) %s\n",</div><div>+                 __func__, 0000, bus, slot, fn, address, len, "Open Failed");</div><div>+    }</div><div>+</div><div>+    PCI_DPRINTF("%s(%04x:%02x:%02x.%x, @0x%x, len=0x%x) %x\n",</div><div>+                 __func__, 0000, bus, slot, fn, address, len, val);</div><div>+    return val;</div><div>+}</div><div>+</div><div>+/* Provides config writes to the host*/</div><div>+void host_pci_write_config(int bus, int slot, int fn, uint32_t address, int len, uint32_t val)</div><div>+{</div><div>+    int fd;</div><div>+    int domain = 0;</div><div>+    ssize_t ret;</div><div>+    char dir[128], name[128];</div><div>+</div><div>+    snprintf(dir, sizeof(dir), "/sys/bus/pci/devices/%04x:%02x:%02x.%x/",</div><div>+             domain, bus, slot, fn);</div><div>+    snprintf(name, sizeof(name), "%sconfig", dir);</div><div>+</div><div>+    fd = open(name, O_RDWR);</div><div>+</div><div>+    if (fd >= 0)</div><div>+    {</div><div>+        do</div><div>+        {</div><div>+            ret = pwrite(fd,&val,len,address);</div><div>+        } while ((ret < 0) && (errno == EINTR || errno == EAGAIN));</div><div>+</div><div>+</div><div>+        if (ret != len)</div><div>+        {</div><div>+            PCI_DPRINTF("%s(%04x:%02x:%02x.%x, @0x%x, len=0x%x) %x %s ret=%zd error=%d\n",</div><div>+                 __func__, 0000, bus, slot, fn, address, len, val, "pread Failed",ret,errno);</div><div>+        }</div><div>+    }</div><div>+    else</div><div>+    {</div><div>+        PCI_DPRINTF("%s(%04x:%02x:%02x.%x, @0x%x, len=0x%x) %s\n",</div><div>+                 __func__, 0000, bus, slot, fn, address, len, "Open Failed");</div><div>+    }</div><div>+}</div><div>+</div><div> static const VMStateDescription vmstate_pcibus = {</div><div>     .name = "PCIBUS",</div><div>     .version_id = 1,</div></div></div>