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