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