mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-08-22 05:28:30 +00:00
4123ca555b
The recent introduction of bi-endianness on arm/arm64 had the odd effect of breaking virtio-pci support on these platforms, as the device endian field defaults to being VIRTIO_ENDIAN_HOST, which is the wrong thing to have on a bi-endian capable architecture. The fix is to check for the endianness on the ioport path the same way we do it for mmio, which implies passing the vcpu all the way down. Patch is a bit ugly, but aligns MMIO and ioport nicely. Tested on arm64 and x86. Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
89 lines
2.2 KiB
C
89 lines
2.2 KiB
C
#include "kvm/vesa.h"
|
|
|
|
#include "kvm/devices.h"
|
|
#include "kvm/virtio-pci-dev.h"
|
|
#include "kvm/framebuffer.h"
|
|
#include "kvm/kvm-cpu.h"
|
|
#include "kvm/ioport.h"
|
|
#include "kvm/util.h"
|
|
#include "kvm/irq.h"
|
|
#include "kvm/kvm.h"
|
|
#include "kvm/pci.h"
|
|
|
|
#include <linux/byteorder.h>
|
|
#include <sys/mman.h>
|
|
#include <linux/err.h>
|
|
#include <sys/types.h>
|
|
#include <sys/ioctl.h>
|
|
#include <inttypes.h>
|
|
#include <unistd.h>
|
|
|
|
static bool vesa_pci_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
static bool vesa_pci_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
static struct ioport_operations vesa_io_ops = {
|
|
.io_in = vesa_pci_io_in,
|
|
.io_out = vesa_pci_io_out,
|
|
};
|
|
|
|
static struct pci_device_header vesa_pci_device = {
|
|
.vendor_id = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
|
|
.device_id = cpu_to_le16(PCI_DEVICE_ID_VESA),
|
|
.header_type = PCI_HEADER_TYPE_NORMAL,
|
|
.revision_id = 0,
|
|
.class[2] = 0x03,
|
|
.subsys_vendor_id = cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
|
|
.subsys_id = cpu_to_le16(PCI_SUBSYSTEM_ID_VESA),
|
|
.bar[1] = cpu_to_le32(VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY),
|
|
.bar_size[1] = VESA_MEM_SIZE,
|
|
};
|
|
|
|
static struct device_header vesa_device = {
|
|
.bus_type = DEVICE_BUS_PCI,
|
|
.data = &vesa_pci_device,
|
|
};
|
|
|
|
static struct framebuffer vesafb;
|
|
|
|
struct framebuffer *vesa__init(struct kvm *kvm)
|
|
{
|
|
u16 vesa_base_addr;
|
|
char *mem;
|
|
int r;
|
|
|
|
if (!kvm->cfg.vnc && !kvm->cfg.sdl && !kvm->cfg.gtk)
|
|
return NULL;
|
|
|
|
r = ioport__register(kvm, IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE, NULL);
|
|
if (r < 0)
|
|
return ERR_PTR(r);
|
|
|
|
vesa_base_addr = (u16)r;
|
|
vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO);
|
|
device__register(&vesa_device);
|
|
|
|
mem = mmap(NULL, VESA_MEM_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
|
|
if (mem == MAP_FAILED)
|
|
ERR_PTR(-errno);
|
|
|
|
kvm__register_mem(kvm, VESA_MEM_ADDR, VESA_MEM_SIZE, mem);
|
|
|
|
vesafb = (struct framebuffer) {
|
|
.width = VESA_WIDTH,
|
|
.height = VESA_HEIGHT,
|
|
.depth = VESA_BPP,
|
|
.mem = mem,
|
|
.mem_addr = VESA_MEM_ADDR,
|
|
.mem_size = VESA_MEM_SIZE,
|
|
.kvm = kvm,
|
|
};
|
|
return fb__register(&vesafb);
|
|
}
|