|
@@ -32,33 +32,58 @@ struct RAMFBState {
|
|
|
struct RAMFBCfg cfg;
|
|
|
};
|
|
|
|
|
|
+static void ramfb_unmap_display_surface(pixman_image_t *image, void *unused)
|
|
|
+{
|
|
|
+ void *data = pixman_image_get_data(image);
|
|
|
+ uint32_t size = pixman_image_get_stride(image) *
|
|
|
+ pixman_image_get_height(image);
|
|
|
+ cpu_physical_memory_unmap(data, size, 0, 0);
|
|
|
+}
|
|
|
+
|
|
|
+static DisplaySurface *ramfb_create_display_surface(int width, int height,
|
|
|
+ pixman_format_code_t format,
|
|
|
+ int linesize, uint64_t addr)
|
|
|
+{
|
|
|
+ DisplaySurface *surface;
|
|
|
+ hwaddr size;
|
|
|
+ void *data;
|
|
|
+
|
|
|
+ if (linesize == 0) {
|
|
|
+ linesize = width * PIXMAN_FORMAT_BPP(format) / 8;
|
|
|
+ }
|
|
|
+
|
|
|
+ size = (hwaddr)linesize * height;
|
|
|
+ data = cpu_physical_memory_map(addr, &size, 0);
|
|
|
+ if (size != (hwaddr)linesize * height) {
|
|
|
+ cpu_physical_memory_unmap(data, size, 0, 0);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ surface = qemu_create_displaysurface_from(width, height,
|
|
|
+ format, linesize, data);
|
|
|
+ pixman_image_set_destroy_function(surface->image,
|
|
|
+ ramfb_unmap_display_surface, NULL);
|
|
|
+
|
|
|
+ return surface;
|
|
|
+}
|
|
|
+
|
|
|
static void ramfb_fw_cfg_write(void *dev, off_t offset, size_t len)
|
|
|
{
|
|
|
RAMFBState *s = dev;
|
|
|
- void *framebuffer;
|
|
|
uint32_t fourcc, format;
|
|
|
- hwaddr stride, addr, length;
|
|
|
+ hwaddr stride, addr;
|
|
|
|
|
|
s->width = be32_to_cpu(s->cfg.width);
|
|
|
s->height = be32_to_cpu(s->cfg.height);
|
|
|
stride = be32_to_cpu(s->cfg.stride);
|
|
|
fourcc = be32_to_cpu(s->cfg.fourcc);
|
|
|
addr = be64_to_cpu(s->cfg.addr);
|
|
|
- length = stride * s->height;
|
|
|
format = qemu_drm_format_to_pixman(fourcc);
|
|
|
|
|
|
fprintf(stderr, "%s: %dx%d @ 0x%" PRIx64 "\n", __func__,
|
|
|
s->width, s->height, addr);
|
|
|
- framebuffer = address_space_map(&address_space_memory,
|
|
|
- addr, &length, false,
|
|
|
- MEMTXATTRS_UNSPECIFIED);
|
|
|
- if (!framebuffer || length < stride * s->height) {
|
|
|
- s->width = 0;
|
|
|
- s->height = 0;
|
|
|
- return;
|
|
|
- }
|
|
|
- s->ds = qemu_create_displaysurface_from(s->width, s->height,
|
|
|
- format, stride, framebuffer);
|
|
|
+ s->ds = ramfb_create_display_surface(s->width, s->height,
|
|
|
+ format, stride, addr);
|
|
|
}
|
|
|
|
|
|
void ramfb_display_update(QemuConsole *con, RAMFBState *s)
|