xref: /kvmtool/framebuffer.c (revision 49a8afd1b9a4e503bdafb2bbc04549e03d514836)
108e89f1eSPekka Enberg #include "kvm/framebuffer.h"
2*49a8afd1SSasha Levin #include "kvm/kvm.h"
308e89f1eSPekka Enberg 
408e89f1eSPekka Enberg #include <linux/kernel.h>
508e89f1eSPekka Enberg #include <linux/list.h>
608e89f1eSPekka Enberg #include <stdlib.h>
77fca1897SSasha Levin #include <sys/mman.h>
848d9e01aSSasha Levin #include <errno.h>
908e89f1eSPekka Enberg 
1008e89f1eSPekka Enberg static LIST_HEAD(framebuffers);
1108e89f1eSPekka Enberg 
fb__register(struct framebuffer * fb)1208e89f1eSPekka Enberg struct framebuffer *fb__register(struct framebuffer *fb)
1308e89f1eSPekka Enberg {
1408e89f1eSPekka Enberg 	INIT_LIST_HEAD(&fb->node);
1508e89f1eSPekka Enberg 	list_add(&fb->node, &framebuffers);
1608e89f1eSPekka Enberg 
1708e89f1eSPekka Enberg 	return fb;
1808e89f1eSPekka Enberg }
1908e89f1eSPekka Enberg 
fb__attach(struct framebuffer * fb,struct fb_target_operations * ops)2008e89f1eSPekka Enberg int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops)
2108e89f1eSPekka Enberg {
2208e89f1eSPekka Enberg 	if (fb->nr_targets >= FB_MAX_TARGETS)
2348d9e01aSSasha Levin 		return -ENOSPC;
2408e89f1eSPekka Enberg 
2508e89f1eSPekka Enberg 	fb->targets[fb->nr_targets++] = ops;
2608e89f1eSPekka Enberg 
2708e89f1eSPekka Enberg 	return 0;
2808e89f1eSPekka Enberg }
2908e89f1eSPekka Enberg 
start_targets(struct framebuffer * fb)3008e89f1eSPekka Enberg static int start_targets(struct framebuffer *fb)
3108e89f1eSPekka Enberg {
3208e89f1eSPekka Enberg 	unsigned long i;
3308e89f1eSPekka Enberg 
3408e89f1eSPekka Enberg 	for (i = 0; i < fb->nr_targets; i++) {
3508e89f1eSPekka Enberg 		struct fb_target_operations *ops = fb->targets[i];
3608e89f1eSPekka Enberg 		int err = 0;
3708e89f1eSPekka Enberg 
3808e89f1eSPekka Enberg 		if (ops->start)
3908e89f1eSPekka Enberg 			err = ops->start(fb);
4008e89f1eSPekka Enberg 
4108e89f1eSPekka Enberg 		if (err)
4208e89f1eSPekka Enberg 			return err;
4308e89f1eSPekka Enberg 	}
4408e89f1eSPekka Enberg 
4508e89f1eSPekka Enberg 	return 0;
4608e89f1eSPekka Enberg }
4708e89f1eSPekka Enberg 
fb__init(struct kvm * kvm)48ba46fe53SSasha Levin int fb__init(struct kvm *kvm)
4908e89f1eSPekka Enberg {
5008e89f1eSPekka Enberg 	struct framebuffer *fb;
5108e89f1eSPekka Enberg 
5208e89f1eSPekka Enberg 	list_for_each_entry(fb, &framebuffers, node) {
5308e89f1eSPekka Enberg 		int err;
5408e89f1eSPekka Enberg 
5508e89f1eSPekka Enberg 		err = start_targets(fb);
5608e89f1eSPekka Enberg 		if (err)
5708e89f1eSPekka Enberg 			return err;
5808e89f1eSPekka Enberg 	}
5908e89f1eSPekka Enberg 
6008e89f1eSPekka Enberg 	return 0;
6108e89f1eSPekka Enberg }
62*49a8afd1SSasha Levin firmware_init(fb__init);
6308e89f1eSPekka Enberg 
fb__exit(struct kvm * kvm)64ba46fe53SSasha Levin int fb__exit(struct kvm *kvm)
6508e89f1eSPekka Enberg {
6608e89f1eSPekka Enberg 	struct framebuffer *fb;
6708e89f1eSPekka Enberg 
6808e89f1eSPekka Enberg 	list_for_each_entry(fb, &framebuffers, node) {
6948d9e01aSSasha Levin 		u32 i;
7048d9e01aSSasha Levin 
7148d9e01aSSasha Levin 		for (i = 0; i < fb->nr_targets; i++)
7248d9e01aSSasha Levin 			if (fb->targets[i]->stop)
7348d9e01aSSasha Levin 				fb->targets[i]->stop(fb);
7448d9e01aSSasha Levin 
757fca1897SSasha Levin 		munmap(fb->mem, fb->mem_size);
7608e89f1eSPekka Enberg 	}
77ba46fe53SSasha Levin 
78ba46fe53SSasha Levin 	return 0;
7908e89f1eSPekka Enberg }
80*49a8afd1SSasha Levin firmware_exit(fb__exit);
81