How to connect GPIO in QEMU-emulated nachine to an object in host?

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
I need to connect the GPIO pins in the ARM machine emulated in QEMU to the  
GUI objects in application working on the host machine.

For example, the level on the output GPIO should be reflected by a color of
 a rectangle. The input GPIO should be connected to a button. When the butt
on in GUI is pressed, the input GPIO should be read as zero (otherwise as o
ne) etc. Of course the input GPIOs should be also capable of generating the
 interrupts.

In fact it would be perfect to connect the emulated pin to a pipe or socket
 so that a change of the state caused by QEMU would produce a message sent  
to the host, and the appropriate message sent by the host should trigger th
e appropriate change of the state of GPIO in QEMU (and possibly generate an
 interrupt).

I have created a few own peripherials for QEMU (e.g, https://github.com/wza
b/qemu/blob/ster3/hw/misc/wzab_sysbus_enc1.c ) but implementation of such G
PIO seems to be not trivial.

Up to now I have found that material: https://sudonull.com/post/80905-Virtu
al-GPIO-driver-with-QEMU-ivshmem-interrupt-controller-for-Linux but it uses
 relatively old QEMU. Additionally, the proposed solution is compatible onl
y with the old sysfs-based method of handling GPIOs.

Are there any existing solutions of that problem?
I'll appreciate any hints or suggestions.

TIA & Regards,
Wojtek

Re: How to connect GPIO in QEMU-emulated nachine to an object in host?
I think that the application implementing the GUI could use msgpack ( https://msgpack.org/ ) protocol to communicate the QEMU.
So whenever the QEMU changes the state of the pin, it sends a message contining two fields:
Direction: (In, Out)
State: (High, Low, High Impedance)

Whenever somebody changes the state of the pin in the GUI, similar message is sent to QEMU, but it should contain only one field:
State: (High, Low)

I assume that the logic that resolves collisions and generates the random state when somebody tries to read the not connected input should be implemented in the GUI application.

What do you think about it?

Re: How to connect GPIO in QEMU-emulated nachine to an object in host?
In a version of QEMU modified by Xilinx I have found something that either maybe a solution, or at least provides means to find the solution.

These are the files with names starting with "remote-port" in the https://github.com/Xilinx/qemu/tree/master/include/hw and https://github.com/Xilinx/qemu/tree/master/hw/core directories.

Re: How to connect GPIO in QEMU-emulated nachine to an object in host?
According to https://www.xilinx.com/support/documentation/sw_manuals/xilinx
2017_4/ug1169-xilinx-qemu.pdf (chapter Remote-Port, page 37), the remote-po
rt is intended for cosimulation with System-C. It is not clear if it can be
 easily interfaced with user designed GUI...

Re: How to connect GPIO in QEMU-emulated nachine to an object in host?
I have found a newer solution based on  https://sudonull.com/post/80905-Virtual-GPIO-driver-with-QEMU-ivshmem-interrupt-controller-for-Linux
It is available in the https://github.com/maquefel/virtual_gpio_basic repository. However, it is not clear if it is libgpiod compatible.

Re: How to connect GPIO in QEMU-emulated nachine to an object in host?
I have managed to modify the model of the MPC8XXX GPIO in QEMU so that it w
orks together with the GUI written in Python. The communication is establis
hed via POSIX message queues. The code is available at alt.sources group ht
tps://groups.google.com/forum/#!topic/alt.sources/_EbOdnQKZ18  
The full project that uses the modified MPC8XXX in an emulated Vexpress A9  
board is available in  in https://github.com/wzab/BR_Internet_Radio reposit
ory
in branch "gpio".
The code is just a "proof of the concept" so it lacks error checking, and p
robably is buggy, but it works for me.
I hope that somebody may find it useful and develop the concept further.

With best regards,
Wojtek

PS. The concept is inspired by the "remote port" solution introduced by Xil
inx in their version of QEMU (see the files with names starting with "remot
e-port" in the https://github.com/Xilinx/qemu/tree/master/include/hw and ht
tps://github.com/Xilinx/qemu/tree/master/hw/core directories.)

Re: How to connect GPIO in QEMU-emulated nachine to an object in host?
My code handles input and output, but still has a problem with interrupts. When I enable interrupt for a pin, then I get error in QEMU:

buildroot-2020.02/output/build/host-qemu-4.2.0/accel/tcg/tcg-all.c:40:tcg_handle_interrupt: assertion failed: (qemu_mutex_iothread_locked())  

Obviously I must modify handling of input so that interrupts are not triggered when mutex is locked.

Re: How to connect GPIO in QEMU-emulated nachine to an object in host?
OK. It appeared that the problem was trivial. I have learned the solution from https://lxr.missinglinkelectronics.com/qemu/hw/misc/edu.c#L350

I simply had to call qemu_mutex_lock_iothread(); before calling qemu_set_irq() and qemu_mutex_unlock_iothread() after, when generating IRQs in my thread:

static void * remote_gpio_thread(void * arg)
{
    //Here we receive the data from the queue  
    const int MSG_MAX = 8192;
    char buf[MSG_MAX];
    gpio_msg * mg = (gpio_msg *)&buf;
    mqd_t mq = mq_open("/to_qemu",O_CREAT | O_RDONLY,0x660,NULL);
    if(mq<0) {
        perror("I can't open mq");
        exit(1);
    }
    while(1) {
        int res = mq_receive(mq,buf,8192,NULL);
        if(res<0) {
            perror("I can't receive");
            exit(1);
        }
        if(res != sizeof(gpio_msg)) continue;
        if((int) mg->magick[0]*256+mg->magick[1] != REMOTE_GPIO_MAGICK) {
            printf("Wrong message received");
        }
        if(mg->pin < 32) {
            qemu_mutex_lock_iothread();
            mpc8xxx_gpio_set_irq(arg,mg->pin,mg->state);
            qemu_mutex_unlock_iothread();
        }
    }
}

Re: How to connect GPIO in QEMU-emulated nachine to an object in host?
The version of my emulated GPIO connected to the GUI is quite mature. It even simulates the bouncing effect in buttons and switches. You may find it in https://github.com/wzab/BR_Internet_Radio/tree/gpio

Regards,
Wojtek

Re: How to connect GPIO in QEMU-emulated nachine to an object in host?
I have found a similar interesting solution: https://github.com/evplatt/mse_report described in:
https://repositories.lib.utexas.edu/bitstream/handle/2152/46169/PLATT-MASTERSREPORT-2016.pdf

Regards,
Wojtek

Re: How to connect GPIO in QEMU-emulated nachine to an object in host?
Today I have added support for simulated buttons/switches/LEDs in U-Boot, s
o my students may also experiment with systems equipped with the button-sel
ectable "rescue mode" (or "administrative mode"). The design is in the bran
ch "gpio_uboot" of the https://github.com/wzab/BR_Internet_Radio repository
.

Site Timeline