static void pl110_invalidate_display(void * opaque) { pl110_state *s = (pl110_state *)opaque; s->invalidate = 1; if (pl110_enabled(s)) { qemu_console_resize(s->ds, s->cols, s->rows); } }
static void pl110_display_invalidate(struct vmm_vdisplay *vdis) { struct pl110_state *s = vmm_vdisplay_priv(vdis); if (pl110_enabled(s)) { vmm_vdisplay_surface_gfx_clear(vdis); } }
static void pl110_resize(pl110_state *s, int width, int height) { if (width != s->cols || height != s->rows) { if (pl110_enabled(s)) { qemu_console_resize(s->ds, width, height); } } s->cols = width; s->rows = height; }
static int pl110_display_pixeldata(struct vmm_vdisplay *vdis, struct vmm_pixelformat *pf, u32 *rows, u32 *cols, physical_addr_t *pa) { u32 flags; physical_addr_t gpa, hpa; physical_size_t gsz, hsz; int rc, bits_per_pixel, bytes_per_pixel; struct pl110_state *s = vmm_vdisplay_priv(vdis); if (!pl110_enabled(s)) { return VMM_ENOTAVAIL; } switch (s->bpp) { case BPP_16: case BPP_16_565: bits_per_pixel = 16; bytes_per_pixel = 2; break; case BPP_32: bits_per_pixel = 32; bytes_per_pixel = 4; break; default: return VMM_EINVALID; }; gpa = s->upbase; gsz = (s->cols * s->rows) * bytes_per_pixel; rc = vmm_guest_physical_map(s->guest, gpa, gsz, &hpa, &hsz, &flags); if (rc) { return rc; } if (!(flags & VMM_REGION_REAL) || !(flags & VMM_REGION_MEMORY) || !(flags & VMM_REGION_ISRAM)) { return VMM_EINVALID; } vmm_pixelformat_init_default(pf, bits_per_pixel); *rows = s->rows; *cols = s->cols; *pa = hpa; return VMM_OK; }
static void pl110_update_display(void *opaque) { pl110_state *s = (pl110_state *)opaque; drawfn* fntable; drawfn fn; int dest_width; int src_width; int bpp_offset; int first; int last; if (!pl110_enabled(s)) return; switch (ds_get_bits_per_pixel(s->ds)) { case 0: return; case 8: fntable = pl110_draw_fn_8; dest_width = 1; break; case 15: fntable = pl110_draw_fn_15; dest_width = 2; break; case 16: fntable = pl110_draw_fn_16; dest_width = 2; break; case 24: fntable = pl110_draw_fn_24; dest_width = 3; break; case 32: fntable = pl110_draw_fn_32; dest_width = 4; break; default: fprintf(stderr, "pl110: Bad color depth\n"); exit(1); } if (s->cr & PL110_CR_BGR) bpp_offset = 0; else bpp_offset = 18; if (s->cr & PL110_CR_BEBO) fn = fntable[s->bpp + 6 + bpp_offset]; else if (s->cr & PL110_CR_BEPO) fn = fntable[s->bpp + 12 + bpp_offset]; else fn = fntable[s->bpp + bpp_offset]; src_width = s->cols; switch (s->bpp) { case BPP_1: src_width >>= 3; break; case BPP_2: src_width >>= 2; break; case BPP_4: src_width >>= 1; break; case BPP_8: break; case BPP_16: src_width <<= 1; break; case BPP_32: src_width <<= 2; break; } dest_width *= s->cols; first = 0; framebuffer_update_display(s->ds, s->upbase, s->cols, s->rows, src_width, dest_width, 0, s->invalidate, fn, s->pallette, &first, &last); if (first >= 0) { dpy_update(s->ds, 0, first, s->cols, last - first + 1); } s->invalidate = 0; }
static void pl110_display_update(struct vmm_vdisplay *vdis, struct vmm_surface *sf) { drawfn fn; drawfn *fntable; u32 *palette; physical_addr_t gphys; int cols, rows, first, last; int dest_width, src_width, bpp_offset; struct pl110_state *s = vmm_vdisplay_priv(vdis); if (!pl110_enabled(s)) { return; } switch (vmm_surface_bits_per_pixel(sf)) { case 0: return; case 8: fntable = pl110_draw_fn_8; dest_width = 1; palette = s->palette8; break; case 15: fntable = pl110_draw_fn_15; dest_width = 2; palette = s->palette15; break; case 16: fntable = pl110_draw_fn_16; dest_width = 2; palette = s->palette16; break; case 24: fntable = pl110_draw_fn_24; dest_width = 3; palette = s->palette32; break; case 32: fntable = pl110_draw_fn_32; dest_width = 4; palette = s->palette32; break; default: vmm_printf("%s: Bad color depth\n", __func__); return; }; vmm_spin_lock(&s->lock); if (s->cr & PL110_CR_BGR) { bpp_offset = 0; } else { bpp_offset = 24; } if ((s->version != PL111) && (s->bpp == BPP_16)) { /* The PL110's native 16 bit mode is 5551; however * most boards with a PL110 implement an external * mux which allows bits to be reshuffled to give * 565 format. The mux is typically controlled by * an external system register. * This is controlled by a GPIO input pin * so boards can wire it up to their register. * * The PL111 straightforwardly implements both * 5551 and 565 under control of the bpp field * in the LCDControl register. */ switch (s->mux_ctrl) { case 3: /* 565 BGR */ bpp_offset = (BPP_16_565 - BPP_16); break; case 1: /* 5551 */ break; case 0: /* 888; also if we have loaded vmstate from an old version */ case 2: /* 565 RGB */ default: /* treat as 565 but honour BGR bit */ bpp_offset += (BPP_16_565 - BPP_16); break; }; } if (s->cr & PL110_CR_BEBO) { fn = fntable[s->bpp + 8 + bpp_offset]; } else if (s->cr & PL110_CR_BEPO) { fn = fntable[s->bpp + 16 + bpp_offset]; } else { fn = fntable[s->bpp + bpp_offset]; } src_width = s->cols; switch (s->bpp) { case BPP_1: src_width >>= 3; break; case BPP_2: src_width >>= 2; break; case BPP_4: src_width >>= 1; break; case BPP_8: break; case BPP_16: case BPP_16_565: case BPP_12: src_width <<= 1; break; case BPP_32: src_width <<= 2; break; }; dest_width *= s->cols; gphys = s->upbase; cols = s->cols; rows = s->rows; vmm_spin_unlock(&s->lock); first = 0; vmm_surface_update(sf, s->guest, gphys, cols, rows, src_width, dest_width, 0, fn, palette, &first, &last); if (first >= 0) { vmm_vdisplay_surface_gfx_update(vdis, 0, first, cols, last - first + 1); } }