X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/dc11549ec213f85f6a024c7df68d349464cd1688..947231ad3b479de82d8f5ec185e2d00f3c96edcd:/hw/display/milkymist-vgafb.c diff --git a/hw/display/milkymist-vgafb.c b/hw/display/milkymist-vgafb.c index 870b339581..177fdac7d8 100644 --- a/hw/display/milkymist-vgafb.c +++ b/hw/display/milkymist-vgafb.c @@ -19,9 +19,10 @@ * * * Specification available at: - * http://www.milkymist.org/socdoc/vgafb.pdf + * http://milkymist.walle.cc/socdoc/vgafb.pdf */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/sysbus.h" #include "trace.h" @@ -63,9 +64,15 @@ enum { CTRL_RESET = (1<<0), }; +#define TYPE_MILKYMIST_VGAFB "milkymist-vgafb" +#define MILKYMIST_VGAFB(obj) \ + OBJECT_CHECK(MilkymistVgafbState, (obj), TYPE_MILKYMIST_VGAFB) + struct MilkymistVgafbState { - SysBusDevice busdev; + SysBusDevice parent_obj; + MemoryRegion regs_region; + MemoryRegionSection fbsection; QemuConsole *con; int invalidate; @@ -84,7 +91,9 @@ static int vgafb_enabled(MilkymistVgafbState *s) static void vgafb_update_display(void *opaque) { MilkymistVgafbState *s = opaque; + SysBusDevice *sbd; DisplaySurface *surface = qemu_console_surface(s->con); + int src_width; int first = 0; int last = 0; drawfn fn; @@ -93,6 +102,7 @@ static void vgafb_update_display(void *opaque) return; } + sbd = SYS_BUS_DEVICE(s); int dest_width = s->regs[R_HRES]; switch (surface_bits_per_pixel(surface)) { @@ -122,11 +132,18 @@ static void vgafb_update_display(void *opaque) break; } - framebuffer_update_display(surface, sysbus_address_space(&s->busdev), - s->regs[R_BASEADDRESS] + s->fb_offset, + src_width = s->regs[R_HRES] * 2; + if (s->invalidate) { + framebuffer_update_memory_section(&s->fbsection, + sysbus_address_space(sbd), + s->regs[R_BASEADDRESS] + s->fb_offset, + s->regs[R_VRES], src_width); + } + + framebuffer_update_display(surface, &s->fbsection, s->regs[R_HRES], s->regs[R_VRES], - s->regs[R_HRES] * 2, + src_width, dest_width, 0, s->invalidate, @@ -256,7 +273,7 @@ static const MemoryRegionOps vgafb_mmio_ops = { static void milkymist_vgafb_reset(DeviceState *d) { - MilkymistVgafbState *s = container_of(d, MilkymistVgafbState, busdev.qdev); + MilkymistVgafbState *s = MILKYMIST_VGAFB(d); int i; for (i = 0; i < R_MAX; i++) { @@ -275,17 +292,21 @@ static const GraphicHwOps vgafb_ops = { .gfx_update = vgafb_update_display, }; -static int milkymist_vgafb_init(SysBusDevice *dev) +static void milkymist_vgafb_init(Object *obj) { - MilkymistVgafbState *s = FROM_SYSBUS(typeof(*s), dev); + MilkymistVgafbState *s = MILKYMIST_VGAFB(obj); + SysBusDevice *dev = SYS_BUS_DEVICE(obj); memory_region_init_io(&s->regs_region, OBJECT(s), &vgafb_mmio_ops, s, "milkymist-vgafb", R_MAX * 4); sysbus_init_mmio(dev, &s->regs_region); +} - s->con = graphic_console_init(DEVICE(dev), &vgafb_ops, s); +static void milkymist_vgafb_realize(DeviceState *dev, Error **errp) +{ + MilkymistVgafbState *s = MILKYMIST_VGAFB(dev); - return 0; + s->con = graphic_console_init(dev, 0, &vgafb_ops, s); } static int vgafb_post_load(void *opaque, int version_id) @@ -298,9 +319,8 @@ static const VMStateDescription vmstate_milkymist_vgafb = { .name = "milkymist-vgafb", .version_id = 1, .minimum_version_id = 1, - .minimum_version_id_old = 1, .post_load = vgafb_post_load, - .fields = (VMStateField[]) { + .fields = (VMStateField[]) { VMSTATE_UINT32_ARRAY(regs, MilkymistVgafbState, R_MAX), VMSTATE_END_OF_LIST() } @@ -315,18 +335,18 @@ static Property milkymist_vgafb_properties[] = { static void milkymist_vgafb_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = milkymist_vgafb_init; dc->reset = milkymist_vgafb_reset; dc->vmsd = &vmstate_milkymist_vgafb; dc->props = milkymist_vgafb_properties; + dc->realize = milkymist_vgafb_realize; } static const TypeInfo milkymist_vgafb_info = { - .name = "milkymist-vgafb", + .name = TYPE_MILKYMIST_VGAFB, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(MilkymistVgafbState), + .instance_init = milkymist_vgafb_init, .class_init = milkymist_vgafb_class_init, };