1 #include "kvm/vesa.h" 2 3 #include "kvm/devices.h" 4 #include "kvm/virtio-pci-dev.h" 5 #include "kvm/framebuffer.h" 6 #include "kvm/kvm-cpu.h" 7 #include "kvm/ioport.h" 8 #include "kvm/util.h" 9 #include "kvm/irq.h" 10 #include "kvm/kvm.h" 11 #include "kvm/pci.h" 12 13 #include <linux/byteorder.h> 14 #include <sys/mman.h> 15 #include <linux/err.h> 16 #include <sys/types.h> 17 #include <sys/ioctl.h> 18 #include <inttypes.h> 19 #include <unistd.h> 20 21 static bool vesa_pci_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) 22 { 23 return true; 24 } 25 26 static bool vesa_pci_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) 27 { 28 return true; 29 } 30 31 static struct ioport_operations vesa_io_ops = { 32 .io_in = vesa_pci_io_in, 33 .io_out = vesa_pci_io_out, 34 }; 35 36 static struct pci_device_header vesa_pci_device = { 37 .vendor_id = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET), 38 .device_id = cpu_to_le16(PCI_DEVICE_ID_VESA), 39 .header_type = PCI_HEADER_TYPE_NORMAL, 40 .revision_id = 0, 41 .class[2] = 0x03, 42 .subsys_vendor_id = cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET), 43 .subsys_id = cpu_to_le16(PCI_SUBSYSTEM_ID_VESA), 44 .bar[1] = cpu_to_le32(VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY), 45 .bar_size[1] = VESA_MEM_SIZE, 46 }; 47 48 static struct device_header vesa_device = { 49 .bus_type = DEVICE_BUS_PCI, 50 .data = &vesa_pci_device, 51 }; 52 53 static struct framebuffer vesafb; 54 55 struct framebuffer *vesa__init(struct kvm *kvm) 56 { 57 u16 vesa_base_addr; 58 char *mem; 59 int r; 60 61 BUILD_BUG_ON(!is_power_of_two(VESA_MEM_SIZE)); 62 BUILD_BUG_ON(VESA_MEM_SIZE < VESA_BPP/8 * VESA_WIDTH * VESA_HEIGHT); 63 64 if (!kvm->cfg.vnc && !kvm->cfg.sdl && !kvm->cfg.gtk) 65 return NULL; 66 r = pci_get_io_port_block(PCI_IO_SIZE); 67 r = ioport__register(kvm, r, &vesa_io_ops, PCI_IO_SIZE, NULL); 68 if (r < 0) 69 return ERR_PTR(r); 70 71 vesa_base_addr = (u16)r; 72 vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); 73 r = device__register(&vesa_device); 74 if (r < 0) 75 return ERR_PTR(r); 76 77 mem = mmap(NULL, VESA_MEM_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0); 78 if (mem == MAP_FAILED) 79 return ERR_PTR(-errno); 80 81 kvm__register_dev_mem(kvm, VESA_MEM_ADDR, VESA_MEM_SIZE, mem); 82 83 vesafb = (struct framebuffer) { 84 .width = VESA_WIDTH, 85 .height = VESA_HEIGHT, 86 .depth = VESA_BPP, 87 .mem = mem, 88 .mem_addr = VESA_MEM_ADDR, 89 .mem_size = VESA_MEM_SIZE, 90 .kvm = kvm, 91 }; 92 return fb__register(&vesafb); 93 } 94