Reply by April 3, 20202020-04-03
Today I have added support for simulated buttons/switches/LEDs in U-Boot, so my students may also experiment with systems equipped with the button-selectable "rescue mode" (or "administrative mode"). The design is in the branch "gpio_uboot" of the https://github.com/wzab/BR_Internet_Radio repository.
Reply by March 25, 20202020-03-25
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
Reply by March 23, 20202020-03-23
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
Reply by March 22, 20202020-03-22
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();
        }
    }
}
Reply by March 22, 20202020-03-22
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.
Reply by March 21, 20202020-03-21
I have managed to modify the model of the MPC8XXX GPIO in QEMU so that it works together with the GUI written in Python. The communication is established via POSIX message queues. The code is available at alt.sources group https://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 repository
in branch "gpio".
The code is just a "proof of the concept" so it lacks error checking, and probably 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 Xilinx in their version of QEMU (see 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.)
Reply by March 20, 20202020-03-20
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.
Reply by March 20, 20202020-03-20
According to https://www.xilinx.com/support/documentation/sw_manuals/xilinx2017_4/ug1169-xilinx-qemu.pdf (chapter Remote-Port, page 37), the remote-port is intended for cosimulation with System-C. It is not clear if it can be easily interfaced with user designed GUI...
Reply by March 20, 20202020-03-20
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.
Reply by March 20, 20202020-03-20
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?