Message ID | 20180630083357.23489-2-huth@tuxfamily.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 06/30/2018 01:33 AM, Thomas Huth wrote: > + uint32_t pal[4] = { 0xFFFFFFFF, 0xFFAAAAAA, 0xFF555555, 0xFF000000 }; static const. Otherwise, Reviewed-by: Richard Henderson <richard.henderson@linaro.org> r~
On 30 June 2018 at 09:33, Thomas Huth <huth@tuxfamily.org> wrote: > The NeXTcube uses a linear framebuffer with 4 greyscale colors and > a fixed resolution of 1120 * 832. > This code has been taken from Bryce Lanham's GSoC 2011 NeXT branch at > > https://github.com/blanham/qemu-NeXT/blob/next-cube/hw/next-fb.c > > and altered to fit the latest interface of the current QEMU (e.g. > the device has been "qdev"-ified etc.). > > Signed-off-by: Thomas Huth <huth@tuxfamily.org> > +static void nextfb_realize(DeviceState *dev, Error **errp) > +{ > + NeXTFbState *s = NEXTFB(dev); > + > + memory_region_allocate_system_memory(&s->fb_mr, NULL, "next.video", > + 0x1CB100); memory_region_allocate_system_memory() is for allocating a machine model's main memory, not for things like video framebuffer RAM. (See the doc comment in memory.h.) > + memory_region_add_subregion(get_system_memory(), 0xB000000, &s->fb_mr); Devices shouldn't directly add memory regions into system memory. Instead they should expose sysbus memory regions which the board model then maps into the right place. > + > + s->invalidate = 1; > + s->cols = 1120; > + s->rows = 832; > + > + s->con = graphic_console_init(dev, 0, &nextfb_ops, s); > + qemu_console_resize(s->con, s->cols, s->rows); > +} > + > +static void nextfb_class_init(ObjectClass *oc, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(oc); > + > + set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); > + dc->realize = nextfb_realize; Worth having at least a comment to say this device has no mutable state and so needs no reset function or vmstate. > +} > + > +static const TypeInfo nextfb_info = { > + .name = TYPE_NEXTFB, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_size = sizeof(NeXTFbState), > + .class_init = nextfb_class_init, > +}; > + > +static void nextfb_register_types(void) > +{ > + type_register_static(&nextfb_info); > +} > + > +type_init(nextfb_register_types) > + > +void nextfb_init(void) > +{ > + DeviceState *dev; > + > + dev = qdev_create(NULL, TYPE_NEXTFB); > + qdev_init_nofail(dev); > +} This is so simple it's not really worth having, I think. Just have the board model code create the device... > diff --git a/include/hw/m68k/next-cube.h b/include/hw/m68k/next-cube.h > new file mode 100644 > index 0000000000..cf07243bda > --- /dev/null > +++ b/include/hw/m68k/next-cube.h > @@ -0,0 +1,8 @@ > + > +#ifndef NEXT_CUBE_H > +#define NEXT_CUBE_H > + > +/* next-fb.c */ > +void nextfb_init(void); > + > +#endif /* NEXT_CUBE_H */ New header files should have copyright and license comment headers too, though in this case if you drop the nextfb_init() function then the header isn't needed any more. thanks -- PMM
Am Sat, 30 Jun 2018 17:12:01 +0100 schrieb Peter Maydell <peter.maydell@linaro.org>: > On 30 June 2018 at 09:33, Thomas Huth <huth@tuxfamily.org> wrote: > > The NeXTcube uses a linear framebuffer with 4 greyscale colors and > > a fixed resolution of 1120 * 832. > > This code has been taken from Bryce Lanham's GSoC 2011 NeXT branch > > at > > > > https://github.com/blanham/qemu-NeXT/blob/next-cube/hw/next-fb.c > > > > and altered to fit the latest interface of the current QEMU (e.g. > > the device has been "qdev"-ified etc.). > > > > Signed-off-by: Thomas Huth <huth@tuxfamily.org> > > > +static void nextfb_realize(DeviceState *dev, Error **errp) > > +{ > > + NeXTFbState *s = NEXTFB(dev); > > + > > + memory_region_allocate_system_memory(&s->fb_mr, NULL, > > "next.video", > > + 0x1CB100); > > memory_region_allocate_system_memory() is for allocating > a machine model's main memory, not for things like video > framebuffer RAM. (See the doc comment in memory.h.) That comment recommends memory_region_allocate_aux_memory(), but that function does not exist (anymore)? > > + memory_region_add_subregion(get_system_memory(), 0xB000000, > > &s->fb_mr); > > Devices shouldn't directly add memory regions into > system memory. Instead they should expose sysbus > memory regions which the board model then maps into > the right place. Ok, ... so just to make sure that I've got you right: The device should call memory_region_init_ram() in it's realize function and the board code should then call sysbus_mmio_map() with that region, right? Thomas
On 30 June 2018 at 20:47, Thomas Huth <huth@tuxfamily.org> wrote: > Am Sat, 30 Jun 2018 17:12:01 +0100 > schrieb Peter Maydell <peter.maydell@linaro.org>: > >> On 30 June 2018 at 09:33, Thomas Huth <huth@tuxfamily.org> wrote: >> > The NeXTcube uses a linear framebuffer with 4 greyscale colors and >> > a fixed resolution of 1120 * 832. >> > This code has been taken from Bryce Lanham's GSoC 2011 NeXT branch >> > at >> > >> > https://github.com/blanham/qemu-NeXT/blob/next-cube/hw/next-fb.c >> > >> > and altered to fit the latest interface of the current QEMU (e.g. >> > the device has been "qdev"-ified etc.). >> > >> > Signed-off-by: Thomas Huth <huth@tuxfamily.org> >> >> > +static void nextfb_realize(DeviceState *dev, Error **errp) >> > +{ >> > + NeXTFbState *s = NEXTFB(dev); >> > + >> > + memory_region_allocate_system_memory(&s->fb_mr, NULL, >> > "next.video", >> > + 0x1CB100); >> >> memory_region_allocate_system_memory() is for allocating >> a machine model's main memory, not for things like video >> framebuffer RAM. (See the doc comment in memory.h.) > > That comment recommends memory_region_allocate_aux_memory(), but > that function does not exist (anymore)? Oops, good catch. That's a leftover comment that should have been updated -- we changed the function name during discussion of the patchset, I think, but I forgot to fix the comment. I'll send a patch to fix that next week. You want memory_region_init_ram() (which does both the MR init and the mark-this-ram-for-migration). >> > + memory_region_add_subregion(get_system_memory(), 0xB000000, >> > &s->fb_mr); >> >> Devices shouldn't directly add memory regions into >> system memory. Instead they should expose sysbus >> memory regions which the board model then maps into >> the right place. > > Ok, ... so just to make sure that I've got you right: The device > should call memory_region_init_ram() in it's realize function and the > board code should then call sysbus_mmio_map() with that region, right? The device should call memory_region_init_ram() and then sysbus_init_mmio(); then the board code can call sysbus_mmio_map(). I have a feeling that for framebuffer devices you should also do something involving DIRTY_MEMORY_VGA, but I'm not really familiar enough with the display code to say for sure. thanks -- PMM
diff --git a/default-configs/m68k-softmmu.mak b/default-configs/m68k-softmmu.mak index 60f7cdfbf2..d3248a6506 100644 --- a/default-configs/m68k-softmmu.mak +++ b/default-configs/m68k-softmmu.mak @@ -2,3 +2,5 @@ CONFIG_COLDFIRE=y CONFIG_PTIMER=y +CONFIG_NEXTCUBE=y +CONFIG_FRAMEBUFFER=y diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs index fb8408c6d0..c91a660ad2 100644 --- a/hw/display/Makefile.objs +++ b/hw/display/Makefile.objs @@ -34,6 +34,7 @@ obj-$(CONFIG_RASPI) += bcm2835_fb.o obj-$(CONFIG_SM501) += sm501.o obj-$(CONFIG_TCX) += tcx.o obj-$(CONFIG_CG3) += cg3.o +obj-$(CONFIG_NEXTCUBE) += next-fb.o obj-$(CONFIG_VGA) += vga.o diff --git a/hw/display/next-fb.c b/hw/display/next-fb.c new file mode 100644 index 0000000000..f4248405df --- /dev/null +++ b/hw/display/next-fb.c @@ -0,0 +1,152 @@ +/* + * NeXT Cube/Station Framebuffer Emulation + * + * Copyright (c) 2011 Bryce Lanham + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "hw/hw.h" +#include "hw/boards.h" +#include "hw/loader.h" +#include "hw/display/framebuffer.h" +#include "ui/console.h" +#define BITS 8 +#include "ui/pixel_ops.h" +#include "hw/m68k/next-cube.h" + +#define TYPE_NEXTFB "next-fb" +#define NEXTFB(obj) OBJECT_CHECK(NeXTFbState, (obj), TYPE_NEXTFB) + +struct NeXTFbState { + SysBusDevice parent_obj; + + MemoryRegion fb_mr; + MemoryRegionSection fbsection; + QemuConsole *con; + + uint32_t pitch; + uint32_t cols; + uint32_t rows; + int invalidate; +}; +typedef struct NeXTFbState NeXTFbState; + +static void nextfb_draw_line(void *opaque, uint8_t *d, const uint8_t *s, + int width, int pitch) +{ + NeXTFbState *nfbstate = NEXTFB(opaque); + uint32_t pal[4] = { 0xFFFFFFFF, 0xFFAAAAAA, 0xFF555555, 0xFF000000 }; + uint32_t *buf = (uint32_t *)d; + int i = 0; + + for (i = 0; i < nfbstate->cols / 4; i++) { + int j = i * 4; + uint8_t src = s[i]; + buf[j + 3] = pal[src & 0x3]; + src >>= 2; + buf[j + 2] = pal[src & 0x3]; + src >>= 2; + buf[j + 1] = pal[src & 0x3]; + src >>= 2; + buf[j + 0] = pal[src & 0x3]; + } +} + +static void nextfb_update(void *opaque) +{ + NeXTFbState *s = NEXTFB(opaque); + int dest_width = 4; + int src_width; + int first = 0; + int last = 0; + DisplaySurface *surface = qemu_console_surface(s->con); + + src_width = s->cols / 4 + 8; + dest_width = s->cols * 4; + + if (s->invalidate) { + framebuffer_update_memory_section(&s->fbsection, &s->fb_mr, 0, + s->cols, src_width); + s->invalidate = 0; + } + + framebuffer_update_display(surface, &s->fbsection, 1120, 832, + src_width, dest_width, 0, 1, nextfb_draw_line, + s, &first, &last); + + dpy_gfx_update(s->con, 0, 0, 1120, 832); +} + +static void nextfb_invalidate(void *opaque) +{ + NeXTFbState *s = NEXTFB(opaque); + s->invalidate = 1; +} + +static const GraphicHwOps nextfb_ops = { + .invalidate = nextfb_invalidate, + .gfx_update = nextfb_update, +}; + +static void nextfb_realize(DeviceState *dev, Error **errp) +{ + NeXTFbState *s = NEXTFB(dev); + + memory_region_allocate_system_memory(&s->fb_mr, NULL, "next.video", + 0x1CB100); + memory_region_add_subregion(get_system_memory(), 0xB000000, &s->fb_mr); + + s->invalidate = 1; + s->cols = 1120; + s->rows = 832; + + s->con = graphic_console_init(dev, 0, &nextfb_ops, s); + qemu_console_resize(s->con, s->cols, s->rows); +} + +static void nextfb_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); + dc->realize = nextfb_realize; +} + +static const TypeInfo nextfb_info = { + .name = TYPE_NEXTFB, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(NeXTFbState), + .class_init = nextfb_class_init, +}; + +static void nextfb_register_types(void) +{ + type_register_static(&nextfb_info); +} + +type_init(nextfb_register_types) + +void nextfb_init(void) +{ + DeviceState *dev; + + dev = qdev_create(NULL, TYPE_NEXTFB); + qdev_init_nofail(dev); +} diff --git a/include/hw/m68k/next-cube.h b/include/hw/m68k/next-cube.h new file mode 100644 index 0000000000..cf07243bda --- /dev/null +++ b/include/hw/m68k/next-cube.h @@ -0,0 +1,8 @@ + +#ifndef NEXT_CUBE_H +#define NEXT_CUBE_H + +/* next-fb.c */ +void nextfb_init(void); + +#endif /* NEXT_CUBE_H */
The NeXTcube uses a linear framebuffer with 4 greyscale colors and a fixed resolution of 1120 * 832. This code has been taken from Bryce Lanham's GSoC 2011 NeXT branch at https://github.com/blanham/qemu-NeXT/blob/next-cube/hw/next-fb.c and altered to fit the latest interface of the current QEMU (e.g. the device has been "qdev"-ified etc.). Signed-off-by: Thomas Huth <huth@tuxfamily.org> --- default-configs/m68k-softmmu.mak | 2 + hw/display/Makefile.objs | 1 + hw/display/next-fb.c | 152 +++++++++++++++++++++++++++++++ include/hw/m68k/next-cube.h | 8 ++ 4 files changed, 163 insertions(+) create mode 100644 hw/display/next-fb.c create mode 100644 include/hw/m68k/next-cube.h