diff options
-rw-r--r-- | include/ui/console.h | 4 | ||||
-rw-r--r-- | ui/console.c | 37 |
2 files changed, 41 insertions, 0 deletions
diff --git a/include/ui/console.h b/include/ui/console.h index 68ac362f06..61901f7212 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -189,6 +189,10 @@ DisplayState *init_displaystate(void); DisplaySurface *qemu_create_displaysurface_from(int width, int height, pixman_format_code_t format, int linesize, uint8_t *data); +DisplaySurface *qemu_create_displaysurface_guestmem(int width, int height, + pixman_format_code_t format, + int linesize, + uint64_t addr); PixelFormat qemu_different_endianness_pixelformat(int bpp); PixelFormat qemu_default_pixelformat(int bpp); diff --git a/ui/console.c b/ui/console.c index 968aaaffef..654c0d31b1 100644 --- a/ui/console.c +++ b/ui/console.c @@ -28,6 +28,7 @@ #include "qmp-commands.h" #include "sysemu/char.h" #include "trace.h" +#include "exec/memory.h" #define DEFAULT_BACKSCROLL 512 #define CONSOLE_CURSOR_PERIOD 500 @@ -1270,6 +1271,42 @@ DisplaySurface *qemu_create_displaysurface_from(int width, int height, return surface; } +static void qemu_unmap_displaysurface_guestmem(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); +} + +DisplaySurface *qemu_create_displaysurface_guestmem(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 = linesize * height; + data = cpu_physical_memory_map(addr, &size, 0); + if (size != 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, qemu_unmap_displaysurface_guestmem, NULL); + + return surface; +} + static DisplaySurface *qemu_create_message_surface(int w, int h, const char *msg) { |