Skip to contentSkip to conversation

bwap: add qemu_bswap helper

PATCH New Michael S. Tsirkin 1 participant 3 messages Jan 18, 2010 1 message not in the archive Kbuild

lore
Share & tools
lore
#1 lore raw

PATCH v2 1/3 bwap: add qemu_bswap helper

In reply to a message not in the archive

add helper that can swap values of 4, 2, 1 bytes

---
 bswap.h |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
bswap.h +6 -0
index 4558704..aace9b7 100644
@@ -214,4 +214,10 @@ static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
 #undef le_bswaps
 #undef be_bswaps
 
+/* len must be one of 1, 2, 4 */
+static inline uint32_t qemu_bswap_len(uint32_t value, int len)
+{
+    return bswap32(value) >> (32 - 8 * len);
+}
+
 #endif /* BSWAP_H */
Signature · 1 line
1.6.6.144.g5c3af
#2 lore raw

PATCH v2 2/3 rwhandler: simplified way to register for mem/io

In reply to a message not in the archive

Some users prefer a single callback with length passed as parameter to using b/w/l callbacks. It would maybe be cleaner to just pass length to existing callbacks but that's a lot of churn. So for now add a wrapper. For convenience use uint64_t for address so a single callback can be used for ioport/memory.

I did have to resort to preprocessor to reduce code duplication. It is however slightly more straightforward, and better contained than what we had with pci_host_template.h. Again, it would go away if we just passed len to existing callbacks.

---
 Makefile.target |    1 +
 rwhandler.c     |   91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 rwhandler.h     |   27 ++++++++++++++++
 3 files changed, 119 insertions(+), 0 deletions(-)
 create mode 100644 rwhandler.c
 create mode 100644 rwhandler.h
Makefile.target +1 -0
index e661478..f9f4a2e 100644
@@ -46,6 +46,7 @@ all: $(PROGS)
 # cpu emulator library
 libobj-y = exec.o translate-all.o cpu-exec.o translate.o
 libobj-y += tcg/tcg.o
+libobj-y += rwhandler.o
 libobj-$(CONFIG_SOFTFLOAT) += fpu/softfloat.o
 libobj-$(CONFIG_NOSOFTFLOAT) += fpu/softfloat-native.o
 libobj-y += op_helper.o helper.o
rwhandler.c new file +91 -0

91 lines not on this page · raw message

rwhandler.h new file +27 -0
new file mode 100644
index 0000000..aa44b28
@@ -0,0 +1,27 @@
+#ifndef READ_WRITE_HANDLER_H
+#define READ_WRITE_HANDLER_H
+
+#include "qemu-common.h"
+#include "ioport.h"
+
+typedef struct ReadWriteHandler ReadWriteHandler;
+
+/* len is guaranteed to be one of 1, 2 or 4, addr is guaranteed to fit in an
+ * appropriate type (io/memory/etc). They do not need to be range checked. */
+typedef void WriteHandlerFunc(ReadWriteHandler *, uint64_t addr,
+			      uint32_t value, int len);
+typedef uint32_t ReadHandlerFunc(ReadWriteHandler *, uint64_t addr, int len);
+
+struct ReadWriteHandler {
+    WriteHandlerFunc *write;
+    ReadHandlerFunc *read;
+};
+
+/* Helpers for when we want to use a single routine with length. */
+/* CPU memory handler: both read and write must be present. */
+int cpu_register_io_memory_simple(ReadWriteHandler *);
+/* io port handler: can supply only read or write handlers. */
+int register_ioport_simple(ReadWriteHandler *,
+			   pio_addr_t start, int length, int size);
+
+#endif
Signature · 1 line
1.6.6.144.g5c3af
#3 lore raw

PATCH v2 3/3 pci_host: rewrite using rwhandler

In reply to a message not in the archive

Save a ton of code by switching pcihost to use rwhandler.

---
 hw/pci_host.c          |  172 +++++++++++++++++++----------------------------
 hw/pci_host.h          |    4 +
 hw/pci_host_template.h |  109 ------------------------------
 3 files changed, 74 insertions(+), 211 deletions(-)
 delete mode 100644 hw/pci_host_template.h
hw/pci_host.c +70 -102
index 6289ead..e96f617 100644
@@ -79,152 +79,120 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
     return val;
 }
 
-static void pci_host_config_writel(void *opaque, target_phys_addr_t addr,
-                                   uint32_t val)
+static void pci_host_config_write(ReadWriteHandler *handler,
+				  uint64_t addr, uint32_t val, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
 
+    PCI_DPRINTF("%s addr %" PRIx64 " %d val %"PRIx32"\n",
+                __func__, addr, len, val);
 #ifdef TARGET_WORDS_BIGENDIAN
-    val = bswap32(val);
+    val = qemu_bswap_len(val, len);
 #endif
-    PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n",
-                __func__, addr, val);
     s->config_reg = val;
 }
 
-static uint32_t pci_host_config_readl(void *opaque, target_phys_addr_t addr)
+static uint32_t pci_host_config_read(ReadWriteHandler *handler,
+                                            uint64_t addr, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
     uint32_t val = s->config_reg;
-
 #ifdef TARGET_WORDS_BIGENDIAN
-    val = bswap32(val);
+    val = qemu_bswap_len(val, len);
 #endif
-    PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n",
-                __func__, addr, val);
+    PCI_DPRINTF("%s addr %" PRIx64 " len %d val %"PRIx32"\n",
+                __func__, addr, len, val);
     return val;
 }
 
-static CPUWriteMemoryFunc * const pci_host_config_write[] = {
-    &pci_host_config_writel,
-    &pci_host_config_writel,
-    &pci_host_config_writel,
-};
-
-static CPUReadMemoryFunc * const pci_host_config_read[] = {
-    &pci_host_config_readl,
-    &pci_host_config_readl,
-    &pci_host_config_readl,
-};
-
-int pci_host_conf_register_mmio(PCIHostState *s)
-{
-    return cpu_register_io_memory(pci_host_config_read,
-                                  pci_host_config_write, s);
-}
-
-static void pci_host_config_writel_noswap(void *opaque,
-                                          target_phys_addr_t addr,
-                                          uint32_t val)
+static void pci_host_config_write_noswap(ReadWriteHandler *handler,
+					 uint64_t addr, uint32_t val, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, conf_noswap_handler);
 
-    PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n",
-                __func__, addr, val);
+    PCI_DPRINTF("%s addr %" PRIx64 " %d val %"PRIx32"\n",
+                __func__, addr, len, val);
     s->config_reg = val;
 }
 
-static uint32_t pci_host_config_readl_noswap(void *opaque,
-                                             target_phys_addr_t addr)
+static uint32_t pci_host_config_read_noswap(ReadWriteHandler *handler,
+                                            uint64_t addr, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, conf_noswap_handler);
     uint32_t val = s->config_reg;
 
-    PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n",
-                __func__, addr, val);
+    PCI_DPRINTF("%s addr %" PRIx64 " len %d val %"PRIx32"\n",
+                __func__, addr, len, val);
     return val;
 }
 
-static CPUWriteMemoryFunc * const pci_host_config_write_noswap[] = {
-    &pci_host_config_writel_noswap,
-    &pci_host_config_writel_noswap,
-    &pci_host_config_writel_noswap,
-};
-
-static CPUReadMemoryFunc * const pci_host_config_read_noswap[] = {
-    &pci_host_config_readl_noswap,
-    &pci_host_config_readl_noswap,
-    &pci_host_config_readl_noswap,
-};
-
-int pci_host_conf_register_mmio_noswap(PCIHostState *s)
+static void pci_host_data_write(ReadWriteHandler *handler,
+				uint64_t addr, uint32_t val, int len)
 {
-    return cpu_register_io_memory(pci_host_config_read_noswap,
-                                  pci_host_config_write_noswap, s);
+    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = qemu_bswap_len(val, len);
+#endif
+    PCI_DPRINTF("write addr %" PRIx64 " len %d val %x\n",
+                addr, len, val);
+    if (s->config_reg & (1u << 31))
+        pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
 }
 
-static void pci_host_config_writel_ioport(void *opaque,
-                                          uint32_t addr, uint32_t val)
+static uint32_t pci_host_data_read(ReadWriteHandler *handler,
+				   uint64_t addr, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
+    uint32_t val;
+    if (!(s->config_reg & (1 << 31)))
+        return 0xffffffff;
+    val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
+    PCI_DPRINTF("read addr %" PRIx64 " len %d val %x\n",
+                addr, len, val);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = qemu_bswap_len(val, len);
+#endif
+    return val;
+}
 
-    PCI_DPRINTF("%s addr %"PRIx32 " val %"PRIx32"\n", __func__, addr, val);
-    s->config_reg = val;
+static void pci_host_init(PCIHostState *s)
+{
+    s->conf_handler.write = pci_host_config_write;
+    s->conf_handler.read = pci_host_config_read;
+    s->conf_noswap_handler.write = pci_host_config_write_noswap;
+    s->conf_noswap_handler.read = pci_host_config_read_noswap;
+    s->data_handler.write = pci_host_data_write;
+    s->data_handler.read = pci_host_data_read;
 }
 
-static uint32_t pci_host_config_readl_ioport(void *opaque, uint32_t addr)
+int pci_host_conf_register_mmio(PCIHostState *s)
 {
-    PCIHostState *s = opaque;
-    uint32_t val = s->config_reg;
+    pci_host_init(s);
+    return cpu_register_io_memory_simple(&s->conf_handler);
+}
 
-    PCI_DPRINTF("%s addr %"PRIx32" val %"PRIx32"\n", __func__, addr, val);
-    return val;
+int pci_host_conf_register_mmio_noswap(PCIHostState *s)
+{
+    pci_host_init(s);
+    return cpu_register_io_memory_simple(&s->conf_noswap_handler);
 }
 
 void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s)
 {
-    register_ioport_write(ioport, 4, 4, pci_host_config_writel_ioport, s);
-    register_ioport_read(ioport, 4, 4, pci_host_config_readl_ioport, s);
+    pci_host_init(s);
+    register_ioport_simple(&s->conf_noswap_handler, ioport, 4, 4);
 }
 
-#define PCI_ADDR_T      target_phys_addr_t
-#define PCI_HOST_SUFFIX _mmio
-
-#include "pci_host_template.h"
-
-static CPUWriteMemoryFunc * const pci_host_data_write_mmio[] = {
-    pci_host_data_writeb_mmio,
-    pci_host_data_writew_mmio,
-    pci_host_data_writel_mmio,
-};
-
-static CPUReadMemoryFunc * const pci_host_data_read_mmio[] = {
-    pci_host_data_readb_mmio,
-    pci_host_data_readw_mmio,
-    pci_host_data_readl_mmio,
-};
-
 int pci_host_data_register_mmio(PCIHostState *s)
 {
-    return cpu_register_io_memory(pci_host_data_read_mmio,
-                                  pci_host_data_write_mmio,
-                                  s);
+    pci_host_init(s);
+    return cpu_register_io_memory_simple(&s->data_handler);
 }
 
-#undef PCI_ADDR_T
-#undef PCI_HOST_SUFFIX
-
-#define PCI_ADDR_T      uint32_t
-#define PCI_HOST_SUFFIX _ioport
-
-#include "pci_host_template.h"
-
 void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s)
 {
-    register_ioport_write(ioport, 4, 1, pci_host_data_writeb_ioport, s);
-    register_ioport_write(ioport, 4, 2, pci_host_data_writew_ioport, s);
-    register_ioport_write(ioport, 4, 4, pci_host_data_writel_ioport, s);
-    register_ioport_read(ioport, 4, 1, pci_host_data_readb_ioport, s);
-    register_ioport_read(ioport, 4, 2, pci_host_data_readw_ioport, s);
-    register_ioport_read(ioport, 4, 4, pci_host_data_readl_ioport, s);
+    pci_host_init(s);
+    register_ioport_simple(&s->data_handler, ioport, 4, 1);
+    register_ioport_simple(&s->data_handler, ioport, 4, 2);
+    register_ioport_simple(&s->data_handler, ioport, 4, 4);
 }
hw/pci_host.h +4 -0
index a006687..5ff6443 100644
@@ -29,9 +29,13 @@
 #define PCI_HOST_H
 
 #include "sysbus.h"
+#include "rwhandler.h"
 
 struct PCIHostState {
     SysBusDevice busdev;
+    ReadWriteHandler conf_noswap_handler;
+    ReadWriteHandler conf_handler;
+    ReadWriteHandler data_handler;
     uint32_t config_reg;
     PCIBus *bus;
 };
hw/pci_host_template.h deleted +0 -109

109 lines not on this page · raw message

Signature · 1 line
1.6.6.144.g5c3af