xref: /kvmtool/framebuffer.c (revision 08e89f1ecd3c1c8210140d0e7307fd5dd97306ae)
1*08e89f1eSPekka Enberg #include "kvm/framebuffer.h"
2*08e89f1eSPekka Enberg 
3*08e89f1eSPekka Enberg #include <linux/kernel.h>
4*08e89f1eSPekka Enberg #include <linux/list.h>
5*08e89f1eSPekka Enberg #include <stdlib.h>
6*08e89f1eSPekka Enberg 
7*08e89f1eSPekka Enberg static LIST_HEAD(framebuffers);
8*08e89f1eSPekka Enberg 
9*08e89f1eSPekka Enberg struct framebuffer *fb__register(struct framebuffer *fb)
10*08e89f1eSPekka Enberg {
11*08e89f1eSPekka Enberg 	INIT_LIST_HEAD(&fb->node);
12*08e89f1eSPekka Enberg 	list_add(&fb->node, &framebuffers);
13*08e89f1eSPekka Enberg 
14*08e89f1eSPekka Enberg 	return fb;
15*08e89f1eSPekka Enberg }
16*08e89f1eSPekka Enberg 
17*08e89f1eSPekka Enberg int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops)
18*08e89f1eSPekka Enberg {
19*08e89f1eSPekka Enberg 	if (fb->nr_targets >= FB_MAX_TARGETS)
20*08e89f1eSPekka Enberg 		return -1;
21*08e89f1eSPekka Enberg 
22*08e89f1eSPekka Enberg 	fb->targets[fb->nr_targets++] = ops;
23*08e89f1eSPekka Enberg 
24*08e89f1eSPekka Enberg 	return 0;
25*08e89f1eSPekka Enberg }
26*08e89f1eSPekka Enberg 
27*08e89f1eSPekka Enberg static int start_targets(struct framebuffer *fb)
28*08e89f1eSPekka Enberg {
29*08e89f1eSPekka Enberg 	unsigned long i;
30*08e89f1eSPekka Enberg 
31*08e89f1eSPekka Enberg 	for (i = 0; i < fb->nr_targets; i++) {
32*08e89f1eSPekka Enberg 		struct fb_target_operations *ops = fb->targets[i];
33*08e89f1eSPekka Enberg 		int err = 0;
34*08e89f1eSPekka Enberg 
35*08e89f1eSPekka Enberg 		if (ops->start)
36*08e89f1eSPekka Enberg 			err = ops->start(fb);
37*08e89f1eSPekka Enberg 
38*08e89f1eSPekka Enberg 		if (err)
39*08e89f1eSPekka Enberg 			return err;
40*08e89f1eSPekka Enberg 	}
41*08e89f1eSPekka Enberg 
42*08e89f1eSPekka Enberg 	return 0;
43*08e89f1eSPekka Enberg }
44*08e89f1eSPekka Enberg 
45*08e89f1eSPekka Enberg int fb__start(void)
46*08e89f1eSPekka Enberg {
47*08e89f1eSPekka Enberg 	struct framebuffer *fb;
48*08e89f1eSPekka Enberg 
49*08e89f1eSPekka Enberg 	list_for_each_entry(fb, &framebuffers, node) {
50*08e89f1eSPekka Enberg 		int err;
51*08e89f1eSPekka Enberg 
52*08e89f1eSPekka Enberg 		err = start_targets(fb);
53*08e89f1eSPekka Enberg 		if (err)
54*08e89f1eSPekka Enberg 			return err;
55*08e89f1eSPekka Enberg 	}
56*08e89f1eSPekka Enberg 
57*08e89f1eSPekka Enberg 	return 0;
58*08e89f1eSPekka Enberg }
59*08e89f1eSPekka Enberg 
60*08e89f1eSPekka Enberg void fb__stop(void)
61*08e89f1eSPekka Enberg {
62*08e89f1eSPekka Enberg 	struct framebuffer *fb;
63*08e89f1eSPekka Enberg 
64*08e89f1eSPekka Enberg 	list_for_each_entry(fb, &framebuffers, node) {
65*08e89f1eSPekka Enberg 		free(fb->mem);
66*08e89f1eSPekka Enberg 	}
67*08e89f1eSPekka Enberg }
68*08e89f1eSPekka Enberg 
69*08e89f1eSPekka Enberg static void write_to_targets(struct framebuffer *fb, u64 addr, u8 *data, u32 len)
70*08e89f1eSPekka Enberg {
71*08e89f1eSPekka Enberg 	unsigned long i;
72*08e89f1eSPekka Enberg 
73*08e89f1eSPekka Enberg 	for (i = 0; i < fb->nr_targets; i++) {
74*08e89f1eSPekka Enberg 		struct fb_target_operations *ops = fb->targets[i];
75*08e89f1eSPekka Enberg 
76*08e89f1eSPekka Enberg 		ops->write(fb, addr, data, len);
77*08e89f1eSPekka Enberg 	}
78*08e89f1eSPekka Enberg }
79*08e89f1eSPekka Enberg 
80*08e89f1eSPekka Enberg void fb__write(u64 addr, u8 *data, u32 len)
81*08e89f1eSPekka Enberg {
82*08e89f1eSPekka Enberg 	struct framebuffer *fb;
83*08e89f1eSPekka Enberg 
84*08e89f1eSPekka Enberg 	list_for_each_entry(fb, &framebuffers, node) {
85*08e89f1eSPekka Enberg 		write_to_targets(fb, addr, data, len);
86*08e89f1eSPekka Enberg 	}
87*08e89f1eSPekka Enberg }
88