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 struct pci_device_header vesa_pci_device = { 22 .vendor_id = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET), 23 .device_id = cpu_to_le16(PCI_DEVICE_ID_VESA), 24 .header_type = PCI_HEADER_TYPE_NORMAL, 25 .revision_id = 0, 26 .class[2] = 0x03, 27 .subsys_vendor_id = cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET), 28 .subsys_id = cpu_to_le16(PCI_SUBSYSTEM_ID_VESA), 29 .bar[1] = cpu_to_le32(VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY), 30 .bar_size[1] = VESA_MEM_SIZE, 31 }; 32 33 static struct device_header vesa_device = { 34 .bus_type = DEVICE_BUS_PCI, 35 .data = &vesa_pci_device, 36 }; 37 38 static struct framebuffer vesafb = { 39 .width = VESA_WIDTH, 40 .height = VESA_HEIGHT, 41 .depth = VESA_BPP, 42 .mem_addr = VESA_MEM_ADDR, 43 .mem_size = VESA_MEM_SIZE, 44 }; 45 46 static bool vesa_pci_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) 47 { 48 return true; 49 } 50 51 static bool vesa_pci_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) 52 { 53 return true; 54 } 55 56 static struct ioport_operations vesa_io_ops = { 57 .io_in = vesa_pci_io_in, 58 .io_out = vesa_pci_io_out, 59 }; 60 61 static int vesa__bar_activate(struct kvm *kvm, struct pci_device_header *pci_hdr, 62 int bar_num, void *data) 63 { 64 /* We don't support remapping of the framebuffer. */ 65 return 0; 66 } 67 68 static int vesa__bar_deactivate(struct kvm *kvm, struct pci_device_header *pci_hdr, 69 int bar_num, void *data) 70 { 71 /* We don't support remapping of the framebuffer. */ 72 return -EINVAL; 73 } 74 75 struct framebuffer *vesa__init(struct kvm *kvm) 76 { 77 u16 vesa_base_addr; 78 char *mem; 79 int r; 80 81 BUILD_BUG_ON(!is_power_of_two(VESA_MEM_SIZE)); 82 BUILD_BUG_ON(VESA_MEM_SIZE < VESA_BPP/8 * VESA_WIDTH * VESA_HEIGHT); 83 84 vesa_base_addr = pci_get_io_port_block(PCI_IO_SIZE); 85 r = ioport__register(kvm, vesa_base_addr, &vesa_io_ops, PCI_IO_SIZE, NULL); 86 if (r < 0) 87 goto out_error; 88 89 vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); 90 vesa_pci_device.bar_size[0] = PCI_IO_SIZE; 91 r = pci__register_bar_regions(kvm, &vesa_pci_device, vesa__bar_activate, 92 vesa__bar_deactivate, NULL); 93 if (r < 0) 94 goto unregister_ioport; 95 96 r = device__register(&vesa_device); 97 if (r < 0) 98 goto unregister_ioport; 99 100 mem = mmap(NULL, VESA_MEM_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0); 101 if (mem == MAP_FAILED) { 102 r = -errno; 103 goto unregister_device; 104 } 105 106 r = kvm__register_dev_mem(kvm, VESA_MEM_ADDR, VESA_MEM_SIZE, mem); 107 if (r < 0) 108 goto unmap_dev; 109 110 vesafb.mem = mem; 111 vesafb.kvm = kvm; 112 return fb__register(&vesafb); 113 114 unmap_dev: 115 munmap(mem, VESA_MEM_SIZE); 116 unregister_device: 117 device__unregister(&vesa_device); 118 unregister_ioport: 119 ioport__unregister(kvm, vesa_base_addr); 120 out_error: 121 return ERR_PTR(r); 122 } 123