[Qemu-devel] Trying to write a new device / virtio-i2c ?

2014-02-13 Thread Alex David
Hello,

I'm new to QEMU and kinda new to driver & QEMU programming in general, so
please excuse my questions...

I want to develop a new QEMU i2c device (qemu x86), that would get/send
data to an application running on the guest. Thing is : I need these data
onto the host, as a daemon will send/get the same kind of data to the guest.

After reading code, documentation and available things, I've been trying to
write something like a "virtio-i2c" : I wrote a virtio-i2c module for my
kernel (I used some examples from virtio-pci and virtio-console), it seems
that it created a "i2c-1" device in /dev,

My device that I launch with QEMU (-chardev
socket,path=/tmp/test0,server,nowait,id=bob -device virtio-i2c,chardev=bob)
doesn't seem to be recognized by the kernel driver : my probe function
doesn't run.

I might have missed something : how does a kernel driver uses the "probe"
function with a QEMU device ?

Hoping that it doesn't look too confused...


Re: [Qemu-devel] Trying to write a new device / virtio-i2c ?

2014-02-17 Thread Alex David
Thanks for all your answers.

I understand that what I want to achieve seemed pretty confused. I will try
to clarify :

On real hardware, I have an I2C device used to get temperatures, pressure
etc... and it works on x86 and there were no QEMU virtualized hardware
corresponding.

I don't really need to simulate the I2C hardware in QEMU. Indeed, there are
few of them just sending regular i2c data. For some tests, I want to be
able to send/receive these ones from my daemon on the host. After some
researches, what I was thinking about was :

1) Use virtio-serial and write an I2C driver (guest kernel) that would
give/take data to/from i2c-1 and read/write to vportp0... Seemed a bit
ugly, so I wanted to try something else.

2) Write virtio-i2c (using i2c-driver and virtio kernel basics) that would
register, for example, i2c-1 and get/send data from my guest app, and use
virtio to send these data to host.

What I have done for now : I used virtio-serial / virtio-console in linux
kernel and inspired from virtio-pci to try to registers these "vport0pX" as
i2c-1, i2c-2 etc... and as i2c devices. I also wrote a virtio-i2c QEMU-side
to register as this hardware using virtio-i2c drivers. I think my
understanding of the architecture is probably not complete, as it seems
that this QEMU device doesn't automatically registers as a "virtio-i2c"
hardware that would launch my guest kernel driver.
My printk's in the "probe" are not printed. My driver is then never used.

My questions were then :
- My solution might be a bit complicated assuming I don't have that much
knowledge in the architecture (however I'm interested into learning...)
- Are there solutions that seems more adapted to my case ? Like using
USB-I2C bridge ?


2014-02-14 17:45 GMT+01:00 Paolo Bonzini :

> Il 14/02/2014 17:31, Andreas Färber ha scritto:
>
>  While that is certainly possible in case host passthrough was desired,
>> maybe virtio was mixed up with VFIO?
>>
>
> I don't think so, VFIO is mostly about IOMMUs and protecting from DMA.
>
> Paolo
>


[Qemu-devel] Fwd: Trying to write a new device / virtio-i2c ?

2014-02-17 Thread Alex David
2014-02-17 10:19 GMT+01:00 Paolo Bonzini :

> Il 17/02/2014 09:35, Alex David ha scritto:
>
>  - Are there solutions that seems more adapted to my case ? Like using
>> USB-I2C bridge ?
>>
>
> From an upstream point of view, a host passthrough device pair (one object
> talking to /dev/i2c-N on the host, and one device per sensor talking to the
> other object) would be the best.
>

i2c-N is on the guest, that's why I want to virtualize an i2c hardware on
QEMU. My idea was getting the data on a socket on the host => read these
data from my daemon. That's why virtio-serial seemed like a good thing to
use / adapt as i2c.

I'll look on the parallel solution, I don't think there's a
virtio-parallel, right ?


Re: [Qemu-devel] Fwd: Trying to write a new device / virtio-i2c ?

2014-02-17 Thread Alex David
2014-02-17 11:38 GMT+01:00 Paolo Bonzini :

> Il 17/02/2014 11:01, Alex David ha scritto:
>
>  I indeed don't use paravirtualization.
>>
>
> Virtio _is_ paravirtualization. :)
>
>
Ok, now that seems much more understandable... I missed that point ha.



>
>  I'm emulating a bunch of sensors/actuators.
>>
>> If I virtualize my sensors and attach them to the i2c-dev with -device,
>> how do I get those data on the host then ?
>>
>
> It depends on your use case.
>
> It could be that you can make them return a constant value.
>
> Otherwise, you may want to use a chardev for that purpose, or finally a
> QOM (QEMU Object Model) property.  For example, add
>
> CONFIG_TMP105=y
>
> to default-configs/x86_64-softmmu.mak before building QEMU, then do the
> following (indented = in the guest):
>
> $ x86_64-softmmu/qemu-system-x86_64 --enable-kvm ~/test2.img  -m 256 \
>-device tmp105,id=sensor,address=0x50 \
>-qmp unix:$HOME/qmp.sock,server,nowait
> $ qmp/qom-list -s ~/qmp.sock /machine/peripheral/sensor
> temperature
> @parent_bus/
> address
> hotpluggable
> realized
> type
> $ scripts/qmp/qmp-shell ~/qmp.sock
> (QEMU) qom-get path=/machine/peripheral/sensor property=temperature
> {u'return': 0}
> (QEMU) qom-get path=sensor property=address
> {u'return': 80}
>
> # modprobe i2c-dev
> # i2cget -y 0 0x50 0 w
> 0x
>
> (QEMU) qom-set path=sensor property=temperature value=2
> {u'return': {}}
>
> # i2cget -y 0 0x50 0 w
> 0x0014
>
> For this particular sensor, you have to swap the two bytes and the result
> is 8.8 fixed-point.
>
> Paolo
>
>
>  Thanks for your help. As you may see, I'm not that experienced in
>> QEMU/Linux kernel.
>>
>
>
Ok, I'm gonna try these things. I might try to use a chardev also. Thanks
for your help !


Re: [Qemu-devel] Fwd: Trying to write a new device / virtio-i2c ?

2014-02-17 Thread Alex David
>
>
>
>>
>>  I'm emulating a bunch of sensors/actuators.
>>>
>>> If I virtualize my sensors and attach them to the i2c-dev with -device,
>>> how do I get those data on the host then ?
>>>
>>
>> It depends on your use case.
>>
>> It could be that you can make them return a constant value.
>>
>> Otherwise, you may want to use a chardev for that purpose, or finally a
>> QOM (QEMU Object Model) property.  For example, add
>>
>> CONFIG_TMP105=y
>>
>> to default-configs/x86_64-softmmu.mak before building QEMU, then do the
>> following (indented = in the guest):
>>
>> $ x86_64-softmmu/qemu-system-x86_64 --enable-kvm ~/test2.img  -m 256 \
>>-device tmp105,id=sensor,address=0x50 \
>>-qmp unix:$HOME/qmp.sock,server,nowait
>> $ qmp/qom-list -s ~/qmp.sock /machine/peripheral/sensor
>> temperature
>> @parent_bus/
>> address
>> hotpluggable
>> realized
>> type
>> $ scripts/qmp/qmp-shell ~/qmp.sock
>> (QEMU) qom-get path=/machine/peripheral/sensor property=temperature
>> {u'return': 0}
>> (QEMU) qom-get path=sensor property=address
>> {u'return': 80}
>>
>> # modprobe i2c-dev
>> # i2cget -y 0 0x50 0 w
>> 0x
>>
>> (QEMU) qom-set path=sensor property=temperature value=2
>> {u'return': {}}
>>
>> # i2cget -y 0 0x50 0 w
>> 0x0014
>>
>> For this particular sensor, you have to swap the two bytes and the result
>> is 8.8 fixed-point.
>>
>> Paolo
>>
>>
>>  Thanks for your help. As you may see, I'm not that experienced in
>>> QEMU/Linux kernel.
>>>
>>
>>
> Ok, I'm gonna try these things. I might try to use a chardev also. Thanks
> for your help !
>


I've tried using tmp105. As my linux isn't 64bits, i'm using
qemu-system-i386... It crashes my computer when I use it with my linux
image (it's a debian .qcow2..., easy to do some tests...).

I will most probably need a chardev anyways, I will need to read/write data
when I want to. I'm gonna be annoying and ask another basic question : I
wrote this in my i2c_device_test.c (QEMU device) :

static const TypeInfo mydevice_i2c_type_info = {
.name= TYPE_MYDEVICE_I2C,
.parent= TYPE_I2C_SLAVE,
.instance_size= sizeof(MYDEVICEI2CState),
.instance_init= MYDEVICE_i2c_init,
.class_init= mydevice_i2c_class_init,
};

I will be able to add a chardev using the properties, right ?

static void mydevice_i2c_class_init(ObjectClass *klass, void *data)
{
printf("Test init2\n");

I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);

sc->init = mydevice_i2c_init;
sc->event = mydevice_i2c_event;
sc->recv = mydevice_i2c_recv;
sc->send = mydevice_i2c_send;

dc->vmsd = &mydevice_i2c_vmstate;
dc->props = mydevice_i2c_properties;
dc->realize = mydevice_i2c_realize;
}

Does this seems ok for you ? So far, I understood the "props" are needed
for when I'm gonna declare the device at QEMU launch.
I am not sure if it's needed (my i2c-0 should be created anyways), but in
that case, how do I "plug" it on my socket on the host ?

Thanks !


Re: [Qemu-devel] Fwd: Trying to write a new device / virtio-i2c ?

2014-02-17 Thread Alex David
2014-02-17 14:19 GMT+01:00 Paolo Bonzini :

> Il 17/02/2014 14:11, Alex David ha scritto:
>
>  I've tried using tmp105. As my linux isn't 64bits, i'm using
>> qemu-system-i386... It crashes my computer when I use it with my linux
>> image (it's a debian .qcow2..., easy to do some tests...).
>>
>
> You mean crashes your host?
>

Yes, my host crashes... I need to hard-reboot my computer.


>
>  I will most probably need a chardev anyways, I will need to read/write
>> data when I want to.
>>
>
> Depends on how much data.  If it's just one or two ints, like tmp105, QOM
> would work too.  qmp-shell talks to QEMU via a simple JSON protocol, and it
> has simple Python bindings too.
>
>
>  static const TypeInfo mydevice_i2c_type_info = {
>> .name= TYPE_MYDEVICE_I2C,
>> .parent= TYPE_I2C_SLAVE,
>> .instance_size= sizeof(MYDEVICEI2CState),
>> .instance_init= MYDEVICE_i2c_init,
>> .class_init= mydevice_i2c_class_init,
>> };
>>
>> I will be able to add a chardev using the properties, right ?
>>
>
> Yes, using dc->props.
>
>
>  Does this seems ok for you ? So far, I understood the "props" are needed
>> for when I'm gonna declare the device at QEMU launch.
>> I am not sure if it's needed (my i2c-0 should be created anyways), but
>> in that case, how do I "plug" it on my socket on the host ?
>>
>
> Your device is not i2c-0.  i2c-0 is provided by the PC board.  Your device
> will get one address, e.g. 0x42, on the i2c bus.  You'll be able to access
> it with i2cget and i2cset using "0" as the bus address (for i2c-0) and 0x42
> as the device address on bus 0.
>
> So you'll indeed have to do something like "-chardev socket,id=foo -device
> myi2c,address=0x42,chr=foo" if you go for sockets, or just "-device
> myi2c,address=0x42" if you go for QOM.  The "chr" property should go into
> dc->props, while "address" is provided by the abstract class TYPE_I2C_SLAVE.
>
> Paolo
>


That seems fairly easy.

But that leaves me with another problem as I now understand how I2C works
on linux... I, in fact, need at least 3 busses (for my at least 3 devices)
- so i2c-0, i2c-1, i2c-2 ... There are applications I can't change on the
guest and opening / writing / reading on i2c-0, i2c-1 etc...

Can I just declare these busses using i2c-dev ?


Re: [Qemu-devel] Fwd: Trying to write a new device / virtio-i2c ?

2014-02-17 Thread Alex David
2014-02-17 15:30 GMT+01:00 Paolo Bonzini :

> So you cannot configure the three devices on the same bus, with three
> different addresses?


Each sensor is different on the original hardware, they are connected on
different busses. As my guest apps are calling i2c-1, i2c-2,  ,i2c-N
(and I can't change them), I will need to create those busses...


> If you need more than one bus, you need a new device exposing the I2C bus,
> besides the new sensor devices.  USB-I2C could be one such device.
>

So let me see if I understood well. USB-I2C (host QEMU device) seems a good
idea, I could normally do : qemu-system-i386 -device usb-I2c,chardev=foo
-device usb-i2c,chardev=bar -chardev
socket,path=/tmp/test0,server,nowait,id=foo -chardev
socket,path=/tmp/test1,server,nowait,id=bar.

I need a "USB-I2C guest kernel driver" that would register a bus (i2c-1 for
chardev foo, i2c-2 for chardev bar etc...), I guess ?


Re: [Qemu-devel] Fwd: Trying to write a new device / virtio-i2c ?

2014-02-18 Thread Alex David
2014-02-17 17:11 GMT+01:00 Paolo Bonzini :

> Il 17/02/2014 16:33, Alex David ha scritto:
>
>  If you need more than one bus, you need a new device exposing the
>> I2C bus, besides the new sensor devices.  USB-I2C could be one such
>> device.
>>
>> So let me see if I understood well. USB-I2C (host QEMU device) seems a
>> good idea, I could normally do : qemu-system-i386 -device
>> usb-I2c,chardev=foo -device usb-i2c,chardev=bar -chardev
>> socket,path=/tmp/test0,server,nowait,id=foo -chardev
>> socket,path=/tmp/test1,server,nowait,id=bar.
>>
>
> Almost. For QOM:
>
> -device usb-i2c,id=usb-i2c-0
> -device i2c-my-sensor,address=0x48,bus=usb-i2c-0.0
>
> For chardev:
>
> -device usb-i2c,id=usb-i2c-0
> -chardev socket,path=/tmp/test0,server,nowait,id=chr-foo-0
> -device i2c-my-sensor,address=0x48,bus=usb-i2c-0.0,chardev=chr-foo-0
>
> Repeat for the other buses, replacing -0 with -1 and -2.
>
>
>  I need a "USB-I2C guest kernel driver" that would register a bus (i2c-1
>> for chardev foo, i2c-2 for chardev bar etc...), I guess ?
>>
>
> It exists already, drivers/i2c/busses/i2c-tiny-usb.c.
>

I'm now trying to write this new USB-I2C device, I look through some of the
code (dev-serial, dev-...), I used dev-serial code and removed the code
that wanted to declare a chardev (I don't need one to create my bus, right
?).

Now I'm wondering, how will be i2c-tiny-usb launched and declare a new
/dev/i2c-N, with my device. I found :

static struct usb_device_id i2c_tiny_usb_table [] = {
{ USB_DEVICE(0x0403, 0xc631) },   /* FTDI */
{ USB_DEVICE(0x1c40, 0x0534) },   /* EZPrototypes */
{ }   /* Terminating entry */
};

So I figured my USB-I2C should register using these numbers ?

static const USBDesc desc_i2c = {
.id = {
.idVendor  = 0x0403,
.idProduct = 0xc631,
.bcdDevice = 0x0400,
.iManufacturer = STR_MANUFACTURER,
.iProduct  = STR_PRODUCT_I2C,
.iSerialNumber = STR_SERIALNUMBER,
},
.full = &desc_device,
.str  = desc_strings,
};

However, this doesn't work, after a $ qemu-system-i386
debian_wheezy_i386_standard.qcow2 -usb -device USB-I2C,id=usb-i2c-0, the
driver doesn't seem to be used (/sys/class/i2c-dev/i2c-0/name isn't for
it...), even if I modprobe i2c-tiny-usb...
The dmesg shows it doesn't go into the "probe" function.

What did I miss ?


Re: [Qemu-devel] Fwd: Trying to write a new device / virtio-i2c ?

2014-02-18 Thread Alex David
Ok, thank you very much for your help then. I'm gonna spend some time on
this.

If qemu-dev / you are interested in what I've done later, I'll send a new
mail.



2014-02-18 14:05 GMT+01:00 Paolo Bonzini :

> Il 18/02/2014 13:48, Alex David ha scritto:
>
>>
>> 2014-02-17 17:11 GMT+01:00 Paolo Bonzini > <mailto:pbonz...@redhat.com>>:
>>
>>
>> Il 17/02/2014 16:33, Alex David ha scritto:
>>
>> If you need more than one bus, you need a new device
>> exposing the
>> I2C bus, besides the new sensor devices.  USB-I2C could be
>> one such
>> device.
>>
>> So let me see if I understood well. USB-I2C (host QEMU device)
>> seems a
>> good idea, I could normally do : qemu-system-i386 -device
>> usb-I2c,chardev=foo -device usb-i2c,chardev=bar -chardev
>> socket,path=/tmp/test0,server,__nowait,id=foo -chardev
>> socket,path=/tmp/test1,server,__nowait,id=bar.
>>
>>
>>
>> Almost. For QOM:
>>
>> -device usb-i2c,id=usb-i2c-0
>> -device i2c-my-sensor,address=0x48,__bus=usb-i2c-0.0
>>
>> For chardev:
>>
>> -device usb-i2c,id=usb-i2c-0
>> -chardev socket,path=/tmp/test0,server,__nowait,id=chr-foo-0
>> -device
>> i2c-my-sensor,address=0x48,__bus=usb-i2c-0.0,chardev=chr-__foo-0
>>
>>
>> Repeat for the other buses, replacing -0 with -1 and -2.
>>
>>
>> I need a "USB-I2C guest kernel driver" that would register a bus
>> (i2c-1
>> for chardev foo, i2c-2 for chardev bar etc...), I guess ?
>>
>>
>> It exists already, drivers/i2c/busses/i2c-tiny-usb.c.
>>
>>
>> I'm now trying to write this new USB-I2C device, I look through some of
>> the code (dev-serial, dev-...), I used dev-serial code and removed the
>> code that wanted to declare a chardev (I don't need one to create my
>> bus, right ?).
>>
>> Now I'm wondering, how will be i2c-tiny-usb launched and declare a new
>> /dev/i2c-N, with my device. I found :
>>
>> static struct usb_device_id i2c_tiny_usb_table [] = {
>> { USB_DEVICE(0x0403, 0xc631) },   /* FTDI */
>> { USB_DEVICE(0x1c40, 0x0534) },   /* EZPrototypes */
>> { }   /* Terminating entry */
>> };
>>
>> So I figured my USB-I2C should register using these numbers ?
>>
>> static const USBDesc desc_i2c = {
>> .id = {
>> .idVendor  = 0x0403,
>> .idProduct = 0xc631,
>> .bcdDevice = 0x0400,
>> .iManufacturer = STR_MANUFACTURER,
>> .iProduct  = STR_PRODUCT_I2C,
>> .iSerialNumber = STR_SERIALNUMBER,
>> },
>> .full = &desc_device,
>> .str  = desc_strings,
>> };
>>
>> However, this doesn't work, after a $ qemu-system-i386
>> debian_wheezy_i386_standard.qcow2 -usb -device USB-I2C,id=usb-i2c-0, the
>> driver doesn't seem to be used (/sys/class/i2c-dev/i2c-0/name isn't for
>> it...), even if I modprobe i2c-tiny-usb...
>> The dmesg shows it doesn't go into the "probe" function.
>>
>> What did I miss ?
>>
>
> I honestly don't know, you'll have to debug it.
>
> Paolo
>