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