Re: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-27 Thread Avi Kivity

 On 10/26/2010 08:33 PM, Blue Swirl wrote:


  Why two types?  I think some devices use PIO on a PC and MMIO on other
  architectures.  Sharing the type would allow sharing code.

Then there are the functions provided by rwhandler.c. I think that
interface makes even more sense compared to 8/16/32 (and 64?) bit
handlers in many cases.


On the other hand, that makes the transition harder.

Perhaps we can have a type with {read,write}(addr, width), and another 
built on top that provides the traditional {read,write}[bwl](addr) to 
ease the transition.


--
error compiling committee.c: too many arguments to function




Re: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-27 Thread Blue Swirl
On Wed, Oct 27, 2010 at 9:26 AM, Avi Kivity a...@redhat.com wrote:
  On 10/26/2010 08:33 PM, Blue Swirl wrote:

 
   Why two types?  I think some devices use PIO on a PC and MMIO on other
   architectures.  Sharing the type would allow sharing code.

 Then there are the functions provided by rwhandler.c. I think that
 interface makes even more sense compared to 8/16/32 (and 64?) bit
 handlers in many cases.

 On the other hand, that makes the transition harder.

 Perhaps we can have a type with {read,write}(addr, width), and another built
 on top that provides the traditional {read,write}[bwl](addr) to ease the
 transition.

That should work.



Re: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-26 Thread Avi Kivity

 On 10/25/2010 08:38 PM, Blue Swirl wrote:


  I don't really see why we need registration; cpu_register_io() takes
  function pointers, a size, and an opaque, and gives an integer handle in
  return.  With the IOPort object approach, you set up the IOPort with
  function pointers, size is implied, and the opaque is derived using
  container_of(); the handle is simply the address of the object.

With the handle, we can separate setting up the structures at device
level, and mapping the object using only the handle at bus or other
higher level. Can this be done with the object approach?


I believe so.  The handle is simply an indirect pointer, no?


The purpose of that patch series was to perform the separation for PCI
BARs. I wasn't so happy with the series, so I never pushed.


In fact I think an IOPort is even more suitable; if we need additional 
attributes we can use a derived object:


struct PCIIOPort {
IOPort ioport;
/* additional fields */
};



--
error compiling committee.c: too many arguments to function




Re: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-26 Thread Blue Swirl
On Tue, Oct 26, 2010 at 8:05 AM, Avi Kivity a...@redhat.com wrote:
  On 10/25/2010 08:38 PM, Blue Swirl wrote:

 
   I don't really see why we need registration; cpu_register_io() takes
   function pointers, a size, and an opaque, and gives an integer handle
  in
   return.  With the IOPort object approach, you set up the IOPort with
   function pointers, size is implied, and the opaque is derived using
   container_of(); the handle is simply the address of the object.

 With the handle, we can separate setting up the structures at device
 level, and mapping the object using only the handle at bus or other
 higher level. Can this be done with the object approach?

 I believe so.  The handle is simply an indirect pointer, no?

Yes, but then the object should also contain size information. That
should not be needed for mapping at higher level.

 The purpose of that patch series was to perform the separation for PCI
 BARs. I wasn't so happy with the series, so I never pushed.

 In fact I think an IOPort is even more suitable; if we need additional
 attributes we can use a derived object:

 struct PCIIOPort {
    IOPort ioport;
    /* additional fields */
 };

One issue with my series was that it would be great if the devices
just had some BAR structures (used by PCI layer to map the devices)
inside PCI/qdev structures, but I invented that too late. Maybe this
can be addressed in your design?



Re: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-26 Thread Avi Kivity

 On 10/26/2010 05:09 PM, Blue Swirl wrote:

On Tue, Oct 26, 2010 at 8:05 AM, Avi Kivitya...@redhat.com  wrote:
On 10/25/2010 08:38 PM, Blue Swirl wrote:

  
  I don't really see why we need registration; cpu_register_io() takes
  function pointers, a size, and an opaque, and gives an integer handle
in
  return.  With the IOPort object approach, you set up the IOPort with
  function pointers, size is implied, and the opaque is derived using
  container_of(); the handle is simply the address of the object.

  With the handle, we can separate setting up the structures at device
  level, and mapping the object using only the handle at bus or other
  higher level. Can this be done with the object approach?

  I believe so.  The handle is simply an indirect pointer, no?

Yes, but then the object should also contain size information. That
should not be needed for mapping at higher level.


Sorry, I don't follow your meaning.

When I said size is implied I meant that the IOPort object has a 
separate function pointer for sizes 1, 2, and 4, so it ioport_register() 
doesn't need a size parameter.  But I don't see how that relates to your 
comment.



  The purpose of that patch series was to perform the separation for PCI
  BARs. I wasn't so happy with the series, so I never pushed.

  In fact I think an IOPort is even more suitable; if we need additional
  attributes we can use a derived object:

  struct PCIIOPort {
  IOPort ioport;
  /* additional fields */
  };

One issue with my series was that it would be great if the devices
just had some BAR structures (used by PCI layer to map the devices)
inside PCI/qdev structures, but I invented that too late. Maybe this
can be addressed in your design?


It looks to be orthogonal.  It would be great to have a BAR object; that 
object can then use your API, my API, or the existing API.


--
error compiling committee.c: too many arguments to function




Re: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-26 Thread Anthony Liguori

On 10/26/2010 12:18 PM, Avi Kivity wrote:

 On 10/26/2010 05:09 PM, Blue Swirl wrote:

On Tue, Oct 26, 2010 at 8:05 AM, Avi Kivitya...@redhat.com  wrote:
On 10/25/2010 08:38 PM, Blue Swirl wrote:

 
 I don't really see why we need registration; 
cpu_register_io() takes
 function pointers, a size, and an opaque, and gives an 
integer handle

   in
 return.  With the IOPort object approach, you set up the 
IOPort with
 function pointers, size is implied, and the opaque is derived 
using

 container_of(); the handle is simply the address of the object.

  With the handle, we can separate setting up the structures at device
  level, and mapping the object using only the handle at bus or other
  higher level. Can this be done with the object approach?

  I believe so.  The handle is simply an indirect pointer, no?

Yes, but then the object should also contain size information. That
should not be needed for mapping at higher level.


Sorry, I don't follow your meaning.

When I said size is implied I meant that the IOPort object has a 
separate function pointer for sizes 1, 2, and 4, so it 
ioport_register() doesn't need a size parameter.  But I don't see how 
that relates to your comment.


Yeah, I don't think it makes sense to combine this is how to dispatch 
I/O with this is a region of I/O address space.


I think an IORegion should contain an IOPort structure though.  I think 
the name needs rethinking.


Maybe:

struct PortIOHandler;
struct MemoryIOHandler;

And it would be good to add a memory callback to this series too.

Regards,

Anthony Liguori

  The purpose of that patch series was to perform the separation 
for PCI

  BARs. I wasn't so happy with the series, so I never pushed.

  In fact I think an IOPort is even more suitable; if we need 
additional

  attributes we can use a derived object:

  struct PCIIOPort {
  IOPort ioport;
  /* additional fields */
  };

One issue with my series was that it would be great if the devices
just had some BAR structures (used by PCI layer to map the devices)
inside PCI/qdev structures, but I invented that too late. Maybe this
can be addressed in your design?


It looks to be orthogonal.  It would be great to have a BAR object; 
that object can then use your API, my API, or the existing API.







Re: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-26 Thread Avi Kivity

 On 10/26/2010 07:27 PM, Anthony Liguori wrote:

Sorry, I don't follow your meaning.

When I said size is implied I meant that the IOPort object has a 
separate function pointer for sizes 1, 2, and 4, so it 
ioport_register() doesn't need a size parameter.  But I don't see how 
that relates to your comment.



Yeah, I don't think it makes sense to combine this is how to dispatch 
I/O with this is a region of I/O address space.


Oh, so Blue meant the size of the region in ports, not the size of the 
individual ports.  I think that putting the range length (but not base 
address) in the IOPort structure may make sense.




I think an IORegion should contain an IOPort structure though.  I 
think the name needs rethinking.


Maybe:

struct PortIOHandler;
struct MemoryIOHandler;


Why two types?  I think some devices use PIO on a PC and MMIO on other 
architectures.  Sharing the type would allow sharing code.


--
error compiling committee.c: too many arguments to function




Re: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-26 Thread Blue Swirl
On Tue, Oct 26, 2010 at 5:35 PM, Avi Kivity a...@redhat.com wrote:
  On 10/26/2010 07:27 PM, Anthony Liguori wrote:

 Sorry, I don't follow your meaning.

 When I said size is implied I meant that the IOPort object has a
 separate function pointer for sizes 1, 2, and 4, so it ioport_register()
 doesn't need a size parameter.  But I don't see how that relates to your
 comment.


 Yeah, I don't think it makes sense to combine this is how to dispatch
 I/O with this is a region of I/O address space.

 Oh, so Blue meant the size of the region in ports, not the size of the
 individual ports.  I think that putting the range length (but not base
 address) in the IOPort structure may make sense.

Yes, that's what I meant. Consider for example the handlers: they
expect that the port is within some range.


 I think an IORegion should contain an IOPort structure though.  I think
 the name needs rethinking.

 Maybe:

 struct PortIOHandler;
 struct MemoryIOHandler;

 Why two types?  I think some devices use PIO on a PC and MMIO on other
 architectures.  Sharing the type would allow sharing code.

Then there are the functions provided by rwhandler.c. I think that
interface makes even more sense compared to 8/16/32 (and 64?) bit
handlers in many cases.



Re: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-25 Thread Avi Kivity

 On 10/24/2010 08:14 PM, Blue Swirl wrote:

On Sun, Oct 24, 2010 at 3:34 PM, Avi Kivitya...@redhat.com  wrote:
  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 Kivitya...@redhat.com

If we are going to change the interface, let's do it so that it's
useful for other uses too:
http://article.gmane.org/gmane.comp.emulators.qemu/76984


I don't really see why we need registration; cpu_register_io() takes 
function pointers, a size, and an opaque, and gives an integer handle in 
return.  With the IOPort object approach, you set up the IOPort with 
function pointers, size is implied, and the opaque is derived using 
container_of(); the handle is simply the address of the object.



  +typedef struct IOPort {
  +IOPortOps *ops;

const


Yup, will fix.  Will repost once we agree on the approach.

--
error compiling committee.c: too many arguments to function




Re: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-25 Thread Blue Swirl
On Mon, Oct 25, 2010 at 10:00 AM, Avi Kivity a...@redhat.com wrote:
  On 10/24/2010 08:14 PM, Blue Swirl wrote:

 On Sun, Oct 24, 2010 at 3:34 PM, Avi Kivitya...@redhat.com  wrote:
   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 Kivitya...@redhat.com

 If we are going to change the interface, let's do it so that it's
 useful for other uses too:
 http://article.gmane.org/gmane.comp.emulators.qemu/76984

 I don't really see why we need registration; cpu_register_io() takes
 function pointers, a size, and an opaque, and gives an integer handle in
 return.  With the IOPort object approach, you set up the IOPort with
 function pointers, size is implied, and the opaque is derived using
 container_of(); the handle is simply the address of the object.

With the handle, we can separate setting up the structures at device
level, and mapping the object using only the handle at bus or other
higher level. Can this be done with the object approach?

The purpose of that patch series was to perform the separation for PCI
BARs. I wasn't so happy with the series, so I never pushed.



[Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-24 Thread Avi Kivity
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 a...@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




Re: [Qemu-devel] [PATCH 1/2] Type-safe ioport callbacks

2010-10-24 Thread Blue Swirl
On Sun, Oct 24, 2010 at 3:34 PM, Avi Kivity a...@redhat.com wrote:
 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 a...@redhat.com

If we are going to change the interface, let's do it so that it's
useful for other uses too:
http://article.gmane.org/gmane.comp.emulators.qemu/76984

 ---
  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;

const