admin管理员组

文章数量:1287523

I am trying to write some minimal display emulation for sabrelite machine in QEMU. So I thought the right move would be to create an IPU QOM device and do it there. So basically I am calling framebuffer_update_memory_section in realize function, which successfully allocates fbsection for me:

MachineState *machine = MACHINE(qdev_get_machine());
s->ram_mem_ptr = machine->ram;

address_space_init(&s->ram_as, s->ram_mem_ptr, "ipu-memory");
    
framebuffer_update_memory_section(&s->fbsection, s->ram_mem_ptr, s->fb_base,
                                  s->fb.width, s->fb.height);

s->con = graphic_console_init(dev, 0, &vgafb_ops, s);
qemu_console_resize(s->con, s->config.xres, s->config.yres);

and here is how initialize the start of framebuffer in the realize function in fsl-imx6.c before the code above is called:

uint32_t fbram_size = object_property_get_uint(OBJECT(&s->ipu), "fbram-size", &err);
if (err) {
    error_propagate(errp, err);
    return;
}

MachineState *machine = MACHINE(qdev_get_machine());
uint32_t ram_size = machine->ram_size;
uint32_t fbram_base = ram_size - fbram_size;

if (!object_property_set_uint(OBJECT(&s->ipu), "fb-base", 
                              fbram_base, errp)) {
    return;
}

if (!sysbus_realize(SYS_BUS_DEVICE(&s->ipu), errp)) {
    return;
}
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ipu), 0, FSL_IMX6_IPU_1_ADDR);

sysbus_connect_irq(SYS_BUS_DEVICE(&s->ipu), 0,
                   qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_IPU1_ERROR_IRQ));

sysbus_connect_irq(SYS_BUS_DEVICE(&s->ipu), 1,
                   qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_IPU1_SYNC_IRQ));  

and then I also have an update display function where I call framebuffer_update_display function, but the display does not work and I can see that the values coming in are only 0, even though I am executing a script on linux which should output gradient on display (checked on other platform and it works as expected).

  framebuffer_update_display(surface, &s->fbsection,
                               s->config.xres, s->config.yres,
                               src_width, dest_width, 0, s->invalidate,
                               draw_line_src16, s, &first, &last);

    if (first >= 0) {
        dpy_gfx_update(s->con, 0, first, s->config.xres,
                       last - first + 1);
    }

I guess my first question is, if framebuffer_update_memory_section lets the os running on QEMU know the memory to use for framebuffer and writes there, because after investigating other solutions in QEMU sources I don't see any other way to create this kind of communication? If so, then what am I missing?

The other question is if it matters in which QOM device I am trying to implement the display? Because I can see that in fsl-imx6.h there are defines for HDMI:

#define FSL_IMX6_HDMI_ADDR 0x00120000
#define FSL_IMX6_HDMI_SIZE 0x9000
#define FSL_IMX6_HDMI_MASTER_IRQ 115
#define FSL_IMX6_HDMI_CEC_IRQ 116

meaning that possible I can also create QOM object for HDMI and do this stuff there.

本文标签: Display emulation in QEMUStack Overflow