194692dcdSGerd Hoffmann #include "qemu/osdep.h" 2a1e88d2dSMarc-André Lureau #include "migration/vmstate.h" 394692dcdSGerd Hoffmann #include "qapi/error.h" 40b8fa32fSMarkus Armbruster #include "qemu/module.h" 594692dcdSGerd Hoffmann #include "hw/loader.h" 6a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h" 794692dcdSGerd Hoffmann #include "hw/display/ramfb.h" 894692dcdSGerd Hoffmann #include "ui/console.h" 9db1015e9SEduardo Habkost #include "qom/object.h" 1094692dcdSGerd Hoffmann 11db1015e9SEduardo Habkost typedef struct RAMFBStandaloneState RAMFBStandaloneState; 128110fa1dSEduardo Habkost DECLARE_INSTANCE_CHECKER(RAMFBStandaloneState, RAMFB, 138110fa1dSEduardo Habkost TYPE_RAMFB_DEVICE) 1494692dcdSGerd Hoffmann 15db1015e9SEduardo Habkost struct RAMFBStandaloneState { 1694692dcdSGerd Hoffmann SysBusDevice parent_obj; 1794692dcdSGerd Hoffmann QemuConsole *con; 1894692dcdSGerd Hoffmann RAMFBState *state; 19a1e88d2dSMarc-André Lureau bool migrate; 20db1015e9SEduardo Habkost }; 2194692dcdSGerd Hoffmann 2294692dcdSGerd Hoffmann static void display_update_wrapper(void *dev) 2394692dcdSGerd Hoffmann { 2494692dcdSGerd Hoffmann RAMFBStandaloneState *ramfb = RAMFB(dev); 2594692dcdSGerd Hoffmann 2694692dcdSGerd Hoffmann if (0 /* native driver active */) { 2794692dcdSGerd Hoffmann /* non-standalone device would run native display update here */; 2894692dcdSGerd Hoffmann } else { 2994692dcdSGerd Hoffmann ramfb_display_update(ramfb->con, ramfb->state); 3094692dcdSGerd Hoffmann } 3194692dcdSGerd Hoffmann } 3294692dcdSGerd Hoffmann 3394692dcdSGerd Hoffmann static const GraphicHwOps wrapper_ops = { 3494692dcdSGerd Hoffmann .gfx_update = display_update_wrapper, 3594692dcdSGerd Hoffmann }; 3694692dcdSGerd Hoffmann 3794692dcdSGerd Hoffmann static void ramfb_realizefn(DeviceState *dev, Error **errp) 3894692dcdSGerd Hoffmann { 3994692dcdSGerd Hoffmann RAMFBStandaloneState *ramfb = RAMFB(dev); 4094692dcdSGerd Hoffmann 4194692dcdSGerd Hoffmann ramfb->con = graphic_console_init(dev, 0, &wrapper_ops, dev); 422fc979cbSGerd Hoffmann ramfb->state = ramfb_setup(errp); 4394692dcdSGerd Hoffmann } 4494692dcdSGerd Hoffmann 45a1e88d2dSMarc-André Lureau static bool migrate_needed(void *opaque) 46a1e88d2dSMarc-André Lureau { 47a1e88d2dSMarc-André Lureau RAMFBStandaloneState *ramfb = RAMFB(opaque); 48a1e88d2dSMarc-André Lureau 49a1e88d2dSMarc-André Lureau return ramfb->migrate; 50a1e88d2dSMarc-André Lureau } 51a1e88d2dSMarc-André Lureau 52a1e88d2dSMarc-André Lureau static const VMStateDescription ramfb_dev_vmstate = { 53a1e88d2dSMarc-André Lureau .name = "ramfb-dev", 54a1e88d2dSMarc-André Lureau .version_id = 1, 55a1e88d2dSMarc-André Lureau .minimum_version_id = 1, 56a1e88d2dSMarc-André Lureau .needed = migrate_needed, 57*f0613160SRichard Henderson .fields = (const VMStateField[]) { 58a1e88d2dSMarc-André Lureau VMSTATE_STRUCT_POINTER(state, RAMFBStandaloneState, ramfb_vmstate, RAMFBState), 59a1e88d2dSMarc-André Lureau VMSTATE_END_OF_LIST() 60a1e88d2dSMarc-André Lureau } 61a1e88d2dSMarc-André Lureau }; 62a1e88d2dSMarc-André Lureau 63a1e88d2dSMarc-André Lureau static Property ramfb_properties[] = { 64a1e88d2dSMarc-André Lureau DEFINE_PROP_BOOL("x-migrate", RAMFBStandaloneState, migrate, true), 65a1e88d2dSMarc-André Lureau DEFINE_PROP_END_OF_LIST(), 66a1e88d2dSMarc-André Lureau }; 67a1e88d2dSMarc-André Lureau 6894692dcdSGerd Hoffmann static void ramfb_class_initfn(ObjectClass *klass, void *data) 6994692dcdSGerd Hoffmann { 7094692dcdSGerd Hoffmann DeviceClass *dc = DEVICE_CLASS(klass); 7194692dcdSGerd Hoffmann 7294692dcdSGerd Hoffmann set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); 73a1e88d2dSMarc-André Lureau dc->vmsd = &ramfb_dev_vmstate; 7494692dcdSGerd Hoffmann dc->realize = ramfb_realizefn; 7594692dcdSGerd Hoffmann dc->desc = "ram framebuffer standalone device"; 7694692dcdSGerd Hoffmann dc->user_creatable = true; 77a1e88d2dSMarc-André Lureau device_class_set_props(dc, ramfb_properties); 7894692dcdSGerd Hoffmann } 7994692dcdSGerd Hoffmann 8094692dcdSGerd Hoffmann static const TypeInfo ramfb_info = { 8194692dcdSGerd Hoffmann .name = TYPE_RAMFB_DEVICE, 8294692dcdSGerd Hoffmann .parent = TYPE_SYS_BUS_DEVICE, 8394692dcdSGerd Hoffmann .instance_size = sizeof(RAMFBStandaloneState), 8494692dcdSGerd Hoffmann .class_init = ramfb_class_initfn, 8594692dcdSGerd Hoffmann }; 8694692dcdSGerd Hoffmann 8794692dcdSGerd Hoffmann static void ramfb_register_types(void) 8894692dcdSGerd Hoffmann { 8994692dcdSGerd Hoffmann type_register_static(&ramfb_info); 9094692dcdSGerd Hoffmann } 9194692dcdSGerd Hoffmann 9294692dcdSGerd Hoffmann type_init(ramfb_register_types) 93