]> git.karo-electronics.de Git - karo-tx-linux.git/blob - tools/kvm/hw/vesa.c
Merge remote-tracking branch 'signal/for-next'
[karo-tx-linux.git] / tools / kvm / hw / vesa.c
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 <linux/byteorder.h>
13 #include <sys/mman.h>
14 #include <linux/err.h>
15 #include <sys/types.h>
16 #include <sys/ioctl.h>
17 #include <inttypes.h>
18 #include <unistd.h>
19
20 static bool vesa_pci_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
21 {
22         return true;
23 }
24
25 static bool vesa_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
26 {
27         return true;
28 }
29
30 static struct ioport_operations vesa_io_ops = {
31         .io_in                  = vesa_pci_io_in,
32         .io_out                 = vesa_pci_io_out,
33 };
34
35 static struct pci_device_header vesa_pci_device = {
36         .vendor_id              = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
37         .device_id              = cpu_to_le16(PCI_DEVICE_ID_VESA),
38         .header_type            = PCI_HEADER_TYPE_NORMAL,
39         .revision_id            = 0,
40         .class[2]               = 0x03,
41         .subsys_vendor_id       = cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
42         .subsys_id              = cpu_to_le16(PCI_SUBSYSTEM_ID_VESA),
43         .bar[1]                 = cpu_to_le32(VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY),
44         .bar_size[1]            = VESA_MEM_SIZE,
45 };
46
47 static struct framebuffer vesafb;
48
49 struct framebuffer *vesa__init(struct kvm *kvm)
50 {
51         u16 vesa_base_addr;
52         u8 dev, line, pin;
53         char *mem;
54         int r;
55
56         if (!kvm->cfg.vnc && !kvm->cfg.sdl)
57                 return NULL;
58
59         r = irq__register_device(PCI_DEVICE_ID_VESA, &dev, &pin, &line);
60         if (r < 0)
61                 return ERR_PTR(r);
62
63         r = ioport__register(kvm, IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE, NULL);
64         if (r < 0)
65                 return ERR_PTR(r);
66
67         vesa_pci_device.irq_pin         = pin;
68         vesa_pci_device.irq_line        = line;
69         vesa_base_addr                  = (u16)r;
70         vesa_pci_device.bar[0]          = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO);
71         pci__register(&vesa_pci_device, dev);
72
73         mem = mmap(NULL, VESA_MEM_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
74         if (mem == MAP_FAILED)
75                 ERR_PTR(-errno);
76
77         kvm__register_mem(kvm, VESA_MEM_ADDR, VESA_MEM_SIZE, mem);
78
79         vesafb = (struct framebuffer) {
80                 .width                  = VESA_WIDTH,
81                 .height                 = VESA_HEIGHT,
82                 .depth                  = VESA_BPP,
83                 .mem                    = mem,
84                 .mem_addr               = VESA_MEM_ADDR,
85                 .mem_size               = VESA_MEM_SIZE,
86                 .kvm                    = kvm,
87         };
88         return fb__register(&vesafb);
89 }