1 #include "kvm/vesa.h" 2 3 #include "kvm/virtio-pci-dev.h" 4 #include "kvm/framebuffer.h" 5 #include "kvm/kvm-cpu.h" 6 #include "kvm/ioport.h" 7 #include "kvm/util.h" 8 #include "kvm/irq.h" 9 #include "kvm/kvm.h" 10 #include "kvm/pci.h" 11 12 #include <sys/types.h> 13 #include <sys/ioctl.h> 14 #include <inttypes.h> 15 #include <unistd.h> 16 17 static bool vesa_pci_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count) 18 { 19 return true; 20 } 21 22 static bool vesa_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size, u32 count) 23 { 24 return true; 25 } 26 27 static struct ioport_operations vesa_io_ops = { 28 .io_in = vesa_pci_io_in, 29 .io_out = vesa_pci_io_out, 30 }; 31 32 static struct pci_device_header vesa_pci_device = { 33 .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET, 34 .device_id = PCI_DEVICE_ID_VESA, 35 .header_type = PCI_HEADER_TYPE_NORMAL, 36 .revision_id = 0, 37 .class = 0x030000, 38 .subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET, 39 .subsys_id = PCI_SUBSYSTEM_ID_VESA, 40 .bar[1] = VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY, 41 }; 42 43 static void vesa_mmio_callback(u64 addr, u8 *data, u32 len, u8 is_write) 44 { 45 if (!is_write) 46 return; 47 48 fb__write(addr, data, len); 49 } 50 51 static struct framebuffer vesafb; 52 53 struct framebuffer *vesa__init(struct kvm *kvm) 54 { 55 u16 vesa_base_addr; 56 u8 dev, line, pin; 57 char *mem; 58 59 if (irq__register_device(PCI_DEVICE_ID_VESA, &dev, &pin, &line) < 0) 60 return NULL; 61 62 vesa_pci_device.irq_pin = pin; 63 vesa_pci_device.irq_line = line; 64 vesa_base_addr = ioport__register(IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE, NULL); 65 vesa_pci_device.bar[0] = vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO; 66 pci__register(&vesa_pci_device, dev); 67 68 kvm__register_mmio(kvm, VESA_MEM_ADDR, VESA_MEM_SIZE, &vesa_mmio_callback); 69 70 mem = calloc(1, VESA_MEM_SIZE); 71 if (!mem) 72 return NULL; 73 74 vesafb = (struct framebuffer) { 75 .width = VESA_WIDTH, 76 .height = VESA_HEIGHT, 77 .depth = VESA_BPP, 78 .mem = mem, 79 .mem_addr = VESA_MEM_ADDR, 80 }; 81 return fb__register(&vesafb); 82 } 83