Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside
Hi Corey, Have you got a chance to look at the I2C code? I imagine that the I2C code has to stop the emulation and keep the main thread running so that it can receive events. Is there something like that? Karol From: Corey Minyard on behalf of Corey Minyard Sent: Wednesday, April 19, 2023 4:35 PM To: Karol Nowak Cc: qemu-devel@nongnu.org ; phi...@linaro.org ; c...@kaod.org Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside ⚠ This email originates from outside the organization or the sender could not be verified. On Wed, Apr 19, 2023 at 12:40:36PM +, Karol Nowak wrote: > Hi Corey, > > I looked at hw/ipmi/ipmi_bmc_extern.c and I conclude that it is a bit > different case than in my one. The function ipmi_bmc_extern_handle_command() > does not wait for a response; the response comes in a chardev-handler. If I > am not mistaken, in my case I have to arm a timer to avoid hanging of QEMU, > somehow stop execution of i2c-handler(recv/send/event), wait for a response > in a chardev handler and then resume an execution of i2c-handler when data > arrive. Yes, something like that. Hopefully a timer isn't necessary (well, it's necessary to make sure you don't sit there forever, but it shouldn't be the main way to do it), you can use the response from the other end to resume execution. You don't stop execution of the i2c handler, either. You aren't blocked waiting for a response, that's the big thing you cannot do. You send the message and return. When the response comes in, you do what the hardware would do in that case. I need to spend a little time looking at the I2C code. I assume it would need some adjustment to accommodate this. -corey > > Best regards, > Karol > > > > > From: Corey Minyard on behalf of Corey Minyard > > Sent: Monday, April 17, 2023 4:34 PM > To: Karol Nowak > Cc: qemu-devel@nongnu.org ; phi...@linaro.org > ; c...@kaod.org > Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops > outside > > [You don't often get email from miny...@acm.org. Learn why this is important > at https://aka.ms/LearnAboutSenderIdentification ] > > ⚠ This email originates from outside the organization or the sender could not > be verified. > > On Mon, Apr 17, 2023 at 10:18:08AM +, Karol Nowak wrote: > > Hi Corey, > > > > > > thank you for your response. > > > > > > Could you give me some hints how to make IO operations non-blocking in > > QEMU? Is there a code reference in the source code of QEMU I could use? > > > > You can look at hw/ipmi/ipmi_bmc_extern.c for an example. > > -corey > > > > > Karol > > > > > > > > From: Corey Minyard on behalf of Corey Minyard > > > > Sent: Thursday, March 23, 2023 5:03 PM > > To: Karol Nowak > > Cc: qemu-devel@nongnu.org ; phi...@linaro.org > > ; c...@kaod.org > > Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c > > ops outside > > > > [You don't often get email from miny...@acm.org. Learn why this is > > important at https://aka.ms/LearnAboutSenderIdentification ] > > > > ⚠ This email originates from outside the organization or the sender could > > not be verified. > > > > On Thu, Mar 23, 2023 at 10:09:02AM +, Karol Nowak wrote: > > > Hi, > > > > > > There is a feature I prepared which may be practical for some QEMU users. > > > > > > The feature provides a new I2C slave device > > > that prepares a message depending what i2c-slave callback was called > > > and sends it outside of QEMU through the character device to a client > > > that receives that message, processes it and send back a response. > > > Thanks to that feature, > > > a user can emulate a logic of I2C device outside of QEMU. > > > The message contains 3 bytes ended with CRLF: BBB\r\l > > > Basically, the I2C slave does 4 steps in each i2c-slave callback: > > > * encode > > > * send > > > * receive > > > * decode > > > > > > I put more details in esp32_i2c_tcp_slave.c > > > and also provided a demo client in python that uses TCP. > > > > > > The feature still needs some improvements, but the question is: > > > * Do you find the feature useful? > > > > Someone else has proposed this before with a patch, and it was actually > > pretty complete and mostly ok, but I pointed out an issue and never > > heard back from them. Th
Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside
Hi Corey, I looked at hw/ipmi/ipmi_bmc_extern.c and I conclude that it is a bit different case than in my one. The function ipmi_bmc_extern_handle_command() does not wait for a response; the response comes in a chardev-handler. If I am not mistaken, in my case I have to arm a timer to avoid hanging of QEMU, somehow stop execution of i2c-handler(recv/send/event), wait for a response in a chardev handler and then resume an execution of i2c-handler when data arrive. Best regards, Karol From: Corey Minyard on behalf of Corey Minyard Sent: Monday, April 17, 2023 4:34 PM To: Karol Nowak Cc: qemu-devel@nongnu.org ; phi...@linaro.org ; c...@kaod.org Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside [You don't often get email from miny...@acm.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ] ⚠ This email originates from outside the organization or the sender could not be verified. On Mon, Apr 17, 2023 at 10:18:08AM +0000, Karol Nowak wrote: > Hi Corey, > > > thank you for your response. > > > Could you give me some hints how to make IO operations non-blocking in QEMU? > Is there a code reference in the source code of QEMU I could use? > You can look at hw/ipmi/ipmi_bmc_extern.c for an example. -corey > > Karol > > > > From: Corey Minyard on behalf of Corey Minyard > > Sent: Thursday, March 23, 2023 5:03 PM > To: Karol Nowak > Cc: qemu-devel@nongnu.org ; phi...@linaro.org > ; c...@kaod.org > Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops > outside > > [You don't often get email from miny...@acm.org. Learn why this is important > at https://aka.ms/LearnAboutSenderIdentification ] > > ⚠ This email originates from outside the organization or the sender could not > be verified. > > On Thu, Mar 23, 2023 at 10:09:02AM +, Karol Nowak wrote: > > Hi, > > > > There is a feature I prepared which may be practical for some QEMU users. > > > > The feature provides a new I2C slave device > > that prepares a message depending what i2c-slave callback was called > > and sends it outside of QEMU through the character device to a client > > that receives that message, processes it and send back a response. > > Thanks to that feature, > > a user can emulate a logic of I2C device outside of QEMU. > > The message contains 3 bytes ended with CRLF: BBB\r\l > > Basically, the I2C slave does 4 steps in each i2c-slave callback: > > * encode > > * send > > * receive > > * decode > > > > I put more details in esp32_i2c_tcp_slave.c > > and also provided a demo client in python that uses TCP. > > > > The feature still needs some improvements, but the question is: > > * Do you find the feature useful? > > Someone else has proposed this before with a patch, and it was actually > pretty complete and mostly ok, but I pointed out an issue and never > heard back from them. This feature is something that might be nice. As > you say, this needs some improvements. Some I would point out: > > Obviously this can't be named esp32, it needs to be general. > > All the I/O (reading and writing) has to be non-blocking. I/O handling > in qemu is single-threaded, if you block anywhere you basically stop > qemu. You need to implement something where whatever you do (like > handling a NAK, for instance) it doesn't block qemu. > > The protocol you have implemented is basically an extension of the QEMU > protocol. That's probably not ideal, it would be best to think about a > general protocol for extending I2C over a TCP connection. A lot of the > details of the QEMU implementation is probably not necessary over a TCP > connection. > > -corey > > > > > > > NOTE: > > The feature originally was prepared for espressif/qemu > > that's why there are references to esp32 > > > > > > Signed-off-by: Karol Nowak > > --- > > hw/misc/esp32_i2c_tcp_slave.c | 288 ++ > > include/hw/misc/esp32_i2c_tcp_slave.h | 19 ++ > > tests/i2c-tcp-demo/i2c-tcp-demo.py| 133 > > 3 files changed, 440 insertions(+) > > create mode 100644 hw/misc/esp32_i2c_tcp_slave.c > > create mode 100644 include/hw/misc/esp32_i2c_tcp_slave.h > > create mode 100644 tests/i2c-tcp-demo/i2c-tcp-demo.py > > > > diff --git a/hw/misc/esp32_i2c_tcp_slave.c b/hw/misc/esp32_i2c_tcp_slave.c > > new file mode 100644 > > index 00..db3b6d366a > > --- /dev/null > > +++ b/hw/misc/esp32_i2c_tcp_slave.c > > @
Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside
Hi Corey, thank you for your response. Could you give me some hints how to make IO operations non-blocking in QEMU? Is there a code reference in the source code of QEMU I could use? Karol From: Corey Minyard on behalf of Corey Minyard Sent: Thursday, March 23, 2023 5:03 PM To: Karol Nowak Cc: qemu-devel@nongnu.org ; phi...@linaro.org ; c...@kaod.org Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside [You don't often get email from miny...@acm.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ] ⚠ This email originates from outside the organization or the sender could not be verified. On Thu, Mar 23, 2023 at 10:09:02AM +0000, Karol Nowak wrote: > Hi, > > There is a feature I prepared which may be practical for some QEMU users. > > The feature provides a new I2C slave device > that prepares a message depending what i2c-slave callback was called > and sends it outside of QEMU through the character device to a client > that receives that message, processes it and send back a response. > Thanks to that feature, > a user can emulate a logic of I2C device outside of QEMU. > The message contains 3 bytes ended with CRLF: BBB\r\l > Basically, the I2C slave does 4 steps in each i2c-slave callback: > * encode > * send > * receive > * decode > > I put more details in esp32_i2c_tcp_slave.c > and also provided a demo client in python that uses TCP. > > The feature still needs some improvements, but the question is: > * Do you find the feature useful? Someone else has proposed this before with a patch, and it was actually pretty complete and mostly ok, but I pointed out an issue and never heard back from them. This feature is something that might be nice. As you say, this needs some improvements. Some I would point out: Obviously this can't be named esp32, it needs to be general. All the I/O (reading and writing) has to be non-blocking. I/O handling in qemu is single-threaded, if you block anywhere you basically stop qemu. You need to implement something where whatever you do (like handling a NAK, for instance) it doesn't block qemu. The protocol you have implemented is basically an extension of the QEMU protocol. That's probably not ideal, it would be best to think about a general protocol for extending I2C over a TCP connection. A lot of the details of the QEMU implementation is probably not necessary over a TCP connection. -corey > > > NOTE: > The feature originally was prepared for espressif/qemu > that's why there are references to esp32 > > > Signed-off-by: Karol Nowak > --- > hw/misc/esp32_i2c_tcp_slave.c | 288 ++ > include/hw/misc/esp32_i2c_tcp_slave.h | 19 ++ > tests/i2c-tcp-demo/i2c-tcp-demo.py| 133 > 3 files changed, 440 insertions(+) > create mode 100644 hw/misc/esp32_i2c_tcp_slave.c > create mode 100644 include/hw/misc/esp32_i2c_tcp_slave.h > create mode 100644 tests/i2c-tcp-demo/i2c-tcp-demo.py > > diff --git a/hw/misc/esp32_i2c_tcp_slave.c b/hw/misc/esp32_i2c_tcp_slave.c > new file mode 100644 > index 00..db3b6d366a > --- /dev/null > +++ b/hw/misc/esp32_i2c_tcp_slave.c > @@ -0,0 +1,288 @@ > +#include "qemu/osdep.h" > +#include "qemu/error-report.h" > +#include "qemu/log.h" > +#include "hw/i2c/i2c.h" > +#include "hw/irq.h" > +#include "hw/misc/esp32_i2c_tcp_slave.h" > +#include "qemu/module.h" > + > +#include "qapi/qmp/json-writer.h" > +#include "chardev/char-fe.h" > +#include "io/channel-socket.h" > +#include "chardev/char-io.h" > +#include "chardev/char-socket.h" > +#include "qapi/error.h" > + > +/* > + * Description: > + * To allow to emulate a I2C slave device which is not supported by QEMU, > + * a new I2C slave device was created that encapsulates I2C operations > + * and passes them through a selected chardev to the host > + * where a client resides that implements a logic of emulated device. > + * > + * > + * Architecture: > + *--- > + *| QEMU| > + *| | --- > + *| ESP32 Firmware writes | | | > + *| to I2C Slave | | I2C Slave Emulation | > + *| | | | > + *| ---&-& | > + *| | I2C Slave at 0x7F& tcp & recv msg| > + *| ---&-& process msg | > + *|
[RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside
Hi, There is a feature I prepared which may be practical for some QEMU users. The feature provides a new I2C slave device that prepares a message depending what i2c-slave callback was called and sends it outside of QEMU through the character device to a client that receives that message, processes it and send back a response. Thanks to that feature, a user can emulate a logic of I2C device outside of QEMU. The message contains 3 bytes ended with CRLF: BBB\r\l Basically, the I2C slave does 4 steps in each i2c-slave callback: * encode * send * receive * decode I put more details in esp32_i2c_tcp_slave.c and also provided a demo client in python that uses TCP. The feature still needs some improvements, but the question is: * Do you find the feature useful? NOTE: The feature originally was prepared for espressif/qemu that's why there are references to esp32 Signed-off-by: Karol Nowak --- hw/misc/esp32_i2c_tcp_slave.c | 288 ++ include/hw/misc/esp32_i2c_tcp_slave.h | 19 ++ tests/i2c-tcp-demo/i2c-tcp-demo.py| 133 3 files changed, 440 insertions(+) create mode 100644 hw/misc/esp32_i2c_tcp_slave.c create mode 100644 include/hw/misc/esp32_i2c_tcp_slave.h create mode 100644 tests/i2c-tcp-demo/i2c-tcp-demo.py diff --git a/hw/misc/esp32_i2c_tcp_slave.c b/hw/misc/esp32_i2c_tcp_slave.c new file mode 100644 index 00..db3b6d366a --- /dev/null +++ b/hw/misc/esp32_i2c_tcp_slave.c @@ -0,0 +1,288 @@ +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qemu/log.h" +#include "hw/i2c/i2c.h" +#include "hw/irq.h" +#include "hw/misc/esp32_i2c_tcp_slave.h" +#include "qemu/module.h" + +#include "qapi/qmp/json-writer.h" +#include "chardev/char-fe.h" +#include "io/channel-socket.h" +#include "chardev/char-io.h" +#include "chardev/char-socket.h" +#include "qapi/error.h" + +/* + * Description: + * To allow to emulate a I2C slave device which is not supported by QEMU, + * a new I2C slave device was created that encapsulates I2C operations + * and passes them through a selected chardev to the host + * where a client resides that implements a logic of emulated device. + * + * + * Architecture: + *--- + *| QEMU| + *| | --- + *| ESP32 Firmware writes | | | + *| to I2C Slave | | I2C Slave Emulation | + *| | | | + *| ---&-& | + *| | I2C Slave at 0x7F& tcp & recv msg| + *| ---&-& process msg | + *| | | send respone| + *| | | | + *| | | | + *--- |-- + * + * + * Syntax & protocol: + * QEMU I2C Slave sends a msg in following format: BBB\r\n + * where each 'B' represents a single byte 0-255 + * QEMU I2C Slave expects a respone message in the same format as fast as possible + * Example: + * req: 0x45 0x01 0x00 \r\n + *resp: 0x45 0x01 0x00 \r\n + * + * The format BBB\r\n + *first 'B' is a message type + *second 'B' is a data value + *third 'B' is an error value (not used at the moment) + * + * There are three types of message + *'E' or 0x45 - Event: + *'S' or 0x53 - Send: byte sent to emulated I2C Slave + *'R' or 0x52 - Recv: byte to be received by I2C Master + * + * + * 'E' message + *second byte is an event type: + * 0x0: I2C_START_RECV + * 0x1: I2C_START_SEND + * 0x2: I2C_START_SEND_ASYNC + * 0x3: I2C_FINISH + * 0x4: I2C_NACK + * + *Example: + *0x45 0x01 0x00 - start send + *0x45 0x03 0x00 - finish + * + *In case of 'E' message, a response is the same as a request message + * + * 'S' message + *second byte is a byte transmitted from I2C Master to I2C slave device + *the byte to by processed by I2C Slave Device + * + *Example: + *0x53 0x20 0x00 + * + *In case of 'S' message, a response is the same as a request message + * + * 'R' message + *the I2C Master expect a byte from the emulated i2c slave device + *A client has to modify the second byte of the request message + * and send it back as a response. + * + *Example: + * req: 0x52 0x00 0x00 + *r