From: Avi Kivity <avi@redhat.com>
To: Anthony Liguori <anthony@codemonkey.ws>, qemu-devel@nongnu.org
Cc: kvm@vger.kernel.org
Subject: [PATCH 1/2] Type-safe ioport callbacks
Date: Sun, 24 Oct 2010 17:34:28 +0200 [thread overview]
Message-ID: <1287934469-16624-2-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1287934469-16624-1-git-send-email-avi@redhat.com>
The current ioport callbacks are not type-safe, in that they accept an "opaque"
pointer as an argument whose type must match the argument to the registration
function; this is not checked by the compiler.
This patch adds an alternative that is type-safe. Instead of an opaque
argument, both registation and the callback use a new IOPort type. The
callback then uses container_of() to access its main structures.
Currently the old and new methods exist side by side; once the old way is gone,
we can also save a bunch of memory since the new method requires one pointer
per ioport instead of 6.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
ioport.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ioport.h | 16 +++++++++++++++
2 files changed, 80 insertions(+), 0 deletions(-)
diff --git a/ioport.c b/ioport.c
index ec3dc65..47eafc3 100644
--- a/ioport.c
+++ b/ioport.c
@@ -174,6 +174,70 @@ int register_ioport_write(pio_addr_t start, int length, int size,
return 0;
}
+static uint32_t ioport_readb_thunk(void *opaque, uint32_t addr)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->readb(ioport, addr);
+}
+
+static uint32_t ioport_readw_thunk(void *opaque, uint32_t addr)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->readw(ioport, addr);
+}
+
+static uint32_t ioport_readl_thunk(void *opaque, uint32_t addr)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->readl(ioport, addr);
+}
+
+static void ioport_writeb_thunk(void *opaque, uint32_t addr, uint32_t data)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->writeb(ioport, addr, data);
+}
+
+static void ioport_writew_thunk(void *opaque, uint32_t addr, uint32_t data)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->writew(ioport, addr, data);
+}
+
+static void ioport_writel_thunk(void *opaque, uint32_t addr, uint32_t data)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->writel(ioport, addr, data);
+}
+
+void ioport_register(IOPort *ioport, pio_addr_t start, pio_addr_t length)
+{
+ if (ioport->ops->readb) {
+ register_ioport_read(start, length, 1, ioport_readb_thunk, ioport);
+ }
+ if (ioport->ops->readw) {
+ register_ioport_read(start, length, 2, ioport_readw_thunk, ioport);
+ }
+ if (ioport->ops->readl) {
+ register_ioport_read(start, length, 4, ioport_readl_thunk, ioport);
+ }
+ if (ioport->ops->writeb) {
+ register_ioport_write(start, length, 1, ioport_writeb_thunk, ioport);
+ }
+ if (ioport->ops->writew) {
+ register_ioport_write(start, length, 2, ioport_writew_thunk, ioport);
+ }
+ if (ioport->ops->writel) {
+ register_ioport_write(start, length, 4, ioport_writel_thunk, ioport);
+ }
+}
+
void isa_unassign_ioport(pio_addr_t start, int length)
{
int i;
diff --git a/ioport.h b/ioport.h
index 3d3c8a3..8036e59 100644
--- a/ioport.h
+++ b/ioport.h
@@ -36,6 +36,22 @@ typedef uint32_t pio_addr_t;
typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
+struct IOPort;
+
+typedef struct IOPortOps {
+ uint32_t (*readb)(struct IOPort *ioport, pio_addr_t addr);
+ uint32_t (*readw)(struct IOPort *ioport, pio_addr_t addr);
+ uint32_t (*readl)(struct IOPort *ioport, pio_addr_t addr);
+ void (*writeb)(struct IOPort *ioport, pio_addr_t addr, uint32_t data);
+ void (*writew)(struct IOPort *ioport, pio_addr_t addr, uint32_t data);
+ void (*writel)(struct IOPort *ioport, pio_addr_t addr, uint32_t data);
+} IOPortOps;
+
+typedef struct IOPort {
+ IOPortOps *ops;
+} IOPort;
+
+void ioport_register(IOPort *ioport, pio_addr_t start, pio_addr_t length);
int register_ioport_read(pio_addr_t start, int length, int size,
IOPortReadFunc *func, void *opaque);
int register_ioport_write(pio_addr_t start, int length, int size,
--
1.7.3.1
WARNING: multiple messages have this Message-ID (diff)
From: Avi Kivity <avi@redhat.com>
To: Anthony Liguori <anthony@codemonkey.ws>, qemu-devel@nongnu.org
Cc: kvm@vger.kernel.org
Subject: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks
Date: Sun, 24 Oct 2010 17:34:28 +0200 [thread overview]
Message-ID: <1287934469-16624-2-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1287934469-16624-1-git-send-email-avi@redhat.com>
The current ioport callbacks are not type-safe, in that they accept an "opaque"
pointer as an argument whose type must match the argument to the registration
function; this is not checked by the compiler.
This patch adds an alternative that is type-safe. Instead of an opaque
argument, both registation and the callback use a new IOPort type. The
callback then uses container_of() to access its main structures.
Currently the old and new methods exist side by side; once the old way is gone,
we can also save a bunch of memory since the new method requires one pointer
per ioport instead of 6.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
ioport.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ioport.h | 16 +++++++++++++++
2 files changed, 80 insertions(+), 0 deletions(-)
diff --git a/ioport.c b/ioport.c
index ec3dc65..47eafc3 100644
--- a/ioport.c
+++ b/ioport.c
@@ -174,6 +174,70 @@ int register_ioport_write(pio_addr_t start, int length, int size,
return 0;
}
+static uint32_t ioport_readb_thunk(void *opaque, uint32_t addr)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->readb(ioport, addr);
+}
+
+static uint32_t ioport_readw_thunk(void *opaque, uint32_t addr)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->readw(ioport, addr);
+}
+
+static uint32_t ioport_readl_thunk(void *opaque, uint32_t addr)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->readl(ioport, addr);
+}
+
+static void ioport_writeb_thunk(void *opaque, uint32_t addr, uint32_t data)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->writeb(ioport, addr, data);
+}
+
+static void ioport_writew_thunk(void *opaque, uint32_t addr, uint32_t data)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->writew(ioport, addr, data);
+}
+
+static void ioport_writel_thunk(void *opaque, uint32_t addr, uint32_t data)
+{
+ IOPort *ioport = opaque;
+
+ return ioport->ops->writel(ioport, addr, data);
+}
+
+void ioport_register(IOPort *ioport, pio_addr_t start, pio_addr_t length)
+{
+ if (ioport->ops->readb) {
+ register_ioport_read(start, length, 1, ioport_readb_thunk, ioport);
+ }
+ if (ioport->ops->readw) {
+ register_ioport_read(start, length, 2, ioport_readw_thunk, ioport);
+ }
+ if (ioport->ops->readl) {
+ register_ioport_read(start, length, 4, ioport_readl_thunk, ioport);
+ }
+ if (ioport->ops->writeb) {
+ register_ioport_write(start, length, 1, ioport_writeb_thunk, ioport);
+ }
+ if (ioport->ops->writew) {
+ register_ioport_write(start, length, 2, ioport_writew_thunk, ioport);
+ }
+ if (ioport->ops->writel) {
+ register_ioport_write(start, length, 4, ioport_writel_thunk, ioport);
+ }
+}
+
void isa_unassign_ioport(pio_addr_t start, int length)
{
int i;
diff --git a/ioport.h b/ioport.h
index 3d3c8a3..8036e59 100644
--- a/ioport.h
+++ b/ioport.h
@@ -36,6 +36,22 @@ typedef uint32_t pio_addr_t;
typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
+struct IOPort;
+
+typedef struct IOPortOps {
+ uint32_t (*readb)(struct IOPort *ioport, pio_addr_t addr);
+ uint32_t (*readw)(struct IOPort *ioport, pio_addr_t addr);
+ uint32_t (*readl)(struct IOPort *ioport, pio_addr_t addr);
+ void (*writeb)(struct IOPort *ioport, pio_addr_t addr, uint32_t data);
+ void (*writew)(struct IOPort *ioport, pio_addr_t addr, uint32_t data);
+ void (*writel)(struct IOPort *ioport, pio_addr_t addr, uint32_t data);
+} IOPortOps;
+
+typedef struct IOPort {
+ IOPortOps *ops;
+} IOPort;
+
+void ioport_register(IOPort *ioport, pio_addr_t start, pio_addr_t length);
int register_ioport_read(pio_addr_t start, int length, int size,
IOPortReadFunc *func, void *opaque);
int register_ioport_write(pio_addr_t start, int length, int size,
--
1.7.3.1
next prev parent reply other threads:[~2010-10-24 15:34 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-24 15:34 [PATCH 0/2] Type-safe ioport callbacks Avi Kivity
2010-10-24 15:34 ` [Qemu-devel] " Avi Kivity
2010-10-24 15:34 ` Avi Kivity [this message]
2010-10-24 15:34 ` [Qemu-devel] [PATCH 1/2] " Avi Kivity
2010-10-24 16:41 ` Avi Kivity
2010-10-24 16:41 ` [Qemu-devel] " Avi Kivity
2010-10-24 18:14 ` [Qemu-devel] " Blue Swirl
2010-10-24 18:14 ` Blue Swirl
2010-10-25 10:00 ` Avi Kivity
2010-10-25 10:00 ` Avi Kivity
2010-10-25 18:38 ` Blue Swirl
2010-10-25 18:38 ` Blue Swirl
2010-10-26 8:05 ` Avi Kivity
2010-10-26 8:05 ` Avi Kivity
2010-10-26 15:09 ` Blue Swirl
2010-10-26 15:09 ` Blue Swirl
2010-10-26 17:18 ` Avi Kivity
2010-10-26 17:18 ` Avi Kivity
2010-10-26 17:27 ` Anthony Liguori
2010-10-26 17:35 ` Avi Kivity
2010-10-26 18:33 ` Blue Swirl
2010-10-26 18:33 ` Blue Swirl
2010-10-27 9:26 ` Avi Kivity
2010-10-27 9:26 ` Avi Kivity
2010-10-27 20:23 ` Blue Swirl
2010-10-27 20:23 ` Blue Swirl
2010-10-25 12:54 ` Juan Quintela
2010-10-25 12:54 ` [Qemu-devel] " Juan Quintela
2010-10-25 12:56 ` Avi Kivity
2010-10-25 12:56 ` [Qemu-devel] " Avi Kivity
2010-10-24 15:34 ` [PATCH 2/2] piix4 acpi: convert io BAR to type-safe " Avi Kivity
2010-10-24 15:34 ` [Qemu-devel] " Avi Kivity
2010-10-24 17:35 ` [PATCH 0/2] Type-safe " Paolo Bonzini
2010-10-24 17:35 ` [Qemu-devel] " Paolo Bonzini
2010-10-24 17:38 ` Avi Kivity
2010-10-24 17:38 ` [Qemu-devel] " Avi Kivity
2010-10-25 13:46 ` Anthony Liguori
2010-10-25 13:52 ` Paolo Bonzini
2010-10-25 13:52 ` Paolo Bonzini
2010-10-25 14:04 ` Anthony Liguori
2010-10-25 14:04 ` Anthony Liguori
2010-10-25 13:45 ` [Qemu-devel] " Anthony Liguori
2010-10-25 13:45 ` Anthony Liguori
2010-10-25 15:40 ` Markus Armbruster
2010-10-25 15:40 ` Markus Armbruster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1287934469-16624-2-git-send-email-avi@redhat.com \
--to=avi@redhat.com \
--cc=anthony@codemonkey.ws \
--cc=kvm@vger.kernel.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.