5

I've gotten QEMU emulation working with: Emulation on a Linux PC

On that Linux based example, I can see the HDMI output on a window, and hear sounds from the speaker.

Now I started playing with bare metal, and the hello world is to blink the OK LED.

Is it possible to get the value of the OK LED from QEMU somehow, without modifying my bare metal code at all?

Same goes for the on / off state of the GPIO pins.

1 Answers1

1

GPIO

I think it is not possible, but I've found the QEMU 2.7.0 callback that gets called when you do GPIO:

hw/gpio/pl061.c:pl061_write

where PL061 is the GPIO controller of -M versatilepb (edit: -M raspi2 was added in QEMU 2.6, see that instead) which is documented here.

This is the setup I'm using to test it out.

You could then monitor GPIO changes by printing to a file:

s->parent_obj->mmio[0].addr

which contains the MMIO base addresses, e.g. 0x101e7000 as in:

/sys/devices/platform/amba/101e7000.gpio/gpio/gpiochip480

and the offsets within each controller can be obtained with offset.

You could also compile with:

./configure --extra-cflags=-DDEBUG_PL061=1

which prints some interesting PL061 debug information.

The hw/arm/versatilepb.c QEMU file sets up 4 such controllers, each one capable of dealing with 8 pins

The MMIO address of those controllers is given by the .dts device tree file, which is generated with the Linux kernel build from versatile-pb.dts.

I'm not sure how the exported IDs (e.g. 480) are chosen for the pins by the Linux kernel.

Linux has in-tree support for the PL061 under drivers/gpio/gpio-pl061.c, which my test script accesses througg /sys/class/gpio.

LEDs

Add a printf at hw/misc/arm_sysctl.c:

static void arm_sysctl_write(void *opaque, hwaddr offset,
                            uint64_t val, unsigned size)
{
    arm_sysctl_state *s = (arm_sysctl_state *)opaque;

    switch (offset) {
    case 0x08: /* LED */
        printf("LED val = %llx\n", (unsigned long long)val);

The kernel driver is drivers/leds/leds-syscon.c.