qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] hw/arm: add Lego NXT board


From: Paolo Bonzini
Subject: Re: [Qemu-devel] hw/arm: add Lego NXT board
Date: Tue, 15 Jul 2014 22:09:25 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0

Il 15/07/2014 20:55, Alexander Graf ha scritto:
3. I do not circumvent the GPL!   The whole software in the loop simulator
is itself GPL Software. The reason I emulate the sensor values outside
of qemu is simple. This is exactly what happens in the real world. The
MCU or even the sensors do not know what values they read. This is
decided by the environment. In the simulator this is archived by a
complex environment simulation that has nothing to do with qemu and will
never be part of it, no matter what license is involved.

Understood. I didn't mean you were going to circumvent the GPL, just that a lot of justification is required for interfaces that allow doing that.

BTW, sorry for the confusion. There is another frequent contributor to QEMU with the same name as yours. I only noticed now that the email address is different.

4. Now, thanks to the help on this list I know there is a the "-chardev"
functionality in qemu that basically archives what I did by hand using
pipes. Now my idea is to port my own "proprietary" implementation to
"the qemu way" - chardevs. You said you think it is a bad idea to build
a device that directly translates I/O memory access to a chardev. I
still don't understand why. Is this all about legal issues or is there a
technical reason?

Could you point me to the code where the chardev devices are defined in
qemu?
I found examples in hw/char.

I think that there are two other ways to do it.

1) You can look at hw/misc/tmp105.c and tests/tmp105-test.c for examples. This is an I2C device, but the suggestion has nothing to do with I2C.

QEMU has an object model and an interface for outside devices to interact with the object model. The command you need is qom-set.

Your MMIO device can expose properties like tmp105.c does with its "temperature" property. The relevant code is:

static void tmp105_get_temperature(Object *obj, Visitor *v, void *opaque,
                                   const char *name, Error **errp)
{
    TMP105State *s = TMP105(obj);
    int64_t value = s->temperature * 1000 / 256;

    visit_type_int(v, &value, name, errp);
}

static void tmp105_set_temperature(Object *obj, Visitor *v,
                                   void *opaque,
                                   const char *name, Error **errp)
{
    TMP105State *s = TMP105(obj);
    Error *local_err = NULL;
    int64_t temp;

    visit_type_int(v, &temp, name, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
    if (temp >= 128000 || temp < -128000) {
        error_setg(errp, "value %" PRId64 ".%03" PRIu64
                   " °C is out of range",
                   temp / 1000, temp % 1000);
        return;
    }

    s->temperature = (int16_t) (temp * 256 / 1000);


    tmp105_alarm_update(s);
}

static void tmp105_initfn(Object *obj)
{
    object_property_add(obj, "temperature", "int",
                        tmp105_get_temperature,
                        tmp105_set_temperature, NULL, NULL, NULL);
}


Here, the temperature is passed in 1/1000th of a °C (e.g. 20000 = 20 °C) and the device reads it in 1/256th of a °C (e.g. 20 °C reads as 0x1400).

You can give the device a QOM name like this:

    object_property_add_child(qdev_get_machine(), "mmio-interface",
                              OBJECT(mmio_interface), NULL);

between the call to qdev_create and the one to qdev_init_nofail. If you are using sysbus_create_simple or sysbus_create_varargs, you will have to use the lower-level functions instead.

Then, in the QEMU invocation you can create a socket like this:

   ... -qmp unix:/tmp/unix.sock,server,nowait

on the command line and a single process will be able to connect to /tmp/unix.sock and send commands. The first command must be

  { 'execute': 'qmp_capabilities' }

Then the actual accesses will look like this:

    { 'execute': 'qom-get', 'arguments': {
      'path': 'mmio-interface', 'property': 'temperature' } }
    { 'execute': 'qom-set', 'arguments': {
      'path': 'mmio-interface', 'property': 'temperature',
      'value': 20000 } }



2) Another possibility is to just place the sensor and actuator data in normal RAM. You can use the test probe functionality ("qtest") to access it and read/write it while the guest is running. It looks like this:

    ... -qtest unix:/tmp/unix.sock,server,nowait -machine accel=tcg

and it requires no glue code like the above object_property_*. The protocol is very simple and documented in qtest.c.

Getting the next simulation tick is a bit more complicated, but possible. If the above works out for you, and you can point us to some code, it will be easier to explain it.

Paolo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]