@@ -17,6 +17,7 @@ TAGS = ctags
OBJS += cpuid.o
OBJS += disk/core.o
+OBJS += framebuffer.o
OBJS += hw/rtc.o
OBJS += hw/serial.o
OBJS += interrupt.o
new file mode 100644
@@ -0,0 +1,87 @@
+#include "kvm/framebuffer.h"
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <stdlib.h>
+
+static LIST_HEAD(framebuffers);
+
+struct framebuffer *fb__register(struct framebuffer *fb)
+{
+ INIT_LIST_HEAD(&fb->node);
+ list_add(&fb->node, &framebuffers);
+
+ return fb;
+}
+
+int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops)
+{
+ if (fb->nr_targets >= FB_MAX_TARGETS)
+ return -1;
+
+ fb->targets[fb->nr_targets++] = ops;
+
+ return 0;
+}
+
+static int start_targets(struct framebuffer *fb)
+{
+ unsigned long i;
+
+ for (i = 0; i < fb->nr_targets; i++) {
+ struct fb_target_operations *ops = fb->targets[i];
+ int err = 0;
+
+ if (ops->start)
+ err = ops->start(fb);
+
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+int fb__start(void)
+{
+ struct framebuffer *fb;
+
+ list_for_each_entry(fb, &framebuffers, node) {
+ int err;
+
+ err = start_targets(fb);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+void fb__stop(void)
+{
+ struct framebuffer *fb;
+
+ list_for_each_entry(fb, &framebuffers, node) {
+ free(fb->mem);
+ }
+}
+
+static void write_to_targets(struct framebuffer *fb, u64 addr, u8 *data, u32 len)
+{
+ unsigned long i;
+
+ for (i = 0; i < fb->nr_targets; i++) {
+ struct fb_target_operations *ops = fb->targets[i];
+
+ ops->write(fb, addr, data, len);
+ }
+}
+
+void fb__write(u64 addr, u8 *data, u32 len)
+{
+ struct framebuffer *fb;
+
+ list_for_each_entry(fb, &framebuffers, node) {
+ write_to_targets(fb, addr, data, len);
+ }
+}
new file mode 100644
@@ -0,0 +1,35 @@
+#ifndef KVM__FRAMEBUFFER_H
+#define KVM__FRAMEBUFFER_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+struct framebuffer;
+
+struct fb_target_operations {
+ int (*start)(struct framebuffer *fb);
+ void (*write)(struct framebuffer *fb, u64 addr, u8 *data, u32 len);
+};
+
+#define FB_MAX_TARGETS 2
+
+struct framebuffer {
+ u32 width;
+ u32 height;
+ u8 depth;
+ char *mem;
+ u64 mem_addr;
+
+ unsigned long nr_targets;
+ struct fb_target_operations *targets[FB_MAX_TARGETS];
+
+ struct list_head node;
+};
+
+struct framebuffer *fb__register(struct framebuffer *fb);
+int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops);
+int fb__start(void);
+void fb__stop(void);
+void fb__write(u64 addr, u8 *data, u32 len);
+
+#endif /* KVM__FRAMEBUFFER_H */
This patch introduces 'struct framebuffer' and related API as a preparational step to killing libvnc dependency from hw/vesa.c. Cc: Cyrill Gorcunov <gorcunov@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: John Floren <john@jfloren.net> Cc: Sasha Levin <levinsasha928@gmail.com> Signed-off-by: Pekka Enberg <penberg@kernel.org> --- tools/kvm/Makefile | 1 + tools/kvm/framebuffer.c | 87 +++++++++++++++++++++++++++++++++++ tools/kvm/include/kvm/framebuffer.h | 35 ++++++++++++++ 3 files changed, 123 insertions(+), 0 deletions(-) create mode 100644 tools/kvm/framebuffer.c create mode 100644 tools/kvm/include/kvm/framebuffer.h