From patchwork Mon May 23 08:44:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sasha Levin X-Patchwork-Id: 808092 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p4N8jmC9005751 for ; Mon, 23 May 2011 08:45:48 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752707Ab1EWIpn (ORCPT ); Mon, 23 May 2011 04:45:43 -0400 Received: from mail-bw0-f46.google.com ([209.85.214.46]:63394 "EHLO mail-bw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750755Ab1EWIpm (ORCPT ); Mon, 23 May 2011 04:45:42 -0400 Received: by mail-bw0-f46.google.com with SMTP id 15so4514519bwz.19 for ; Mon, 23 May 2011 01:45:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=AJ7ChFumBb6o+gZKUsRMSLc6RmUPB14QrMdPusDxUW0=; b=IBPqDYIPJ9wfIyxIprNdtivFmqCfzek6HUxQAA/7ADvoOQ5xaTlMyzlm1PckMqdz4g s12FkhO/9ebqnDCu6rfbIKcg8bryP2TKIrFlQz7NrD8P31aqnhnVn4l3e58U5e6G6+W+ v7Tr2HTQ/0kHOHJ2zFbT7XaCuYTRRZGYsYn24= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=Xsz4ySJVQwkFfIi8Zerhi2iBha3jFyn8JYJx6dzkpxyK71DMkBV+Izcgtgv69kS8s9 nzndJxL0nz7DxRmKiB6gZWgwwGSbp+Ycfy4dX5cGVNag58mhpKH/aYACLMVevr4Mx8TF isFxNUoSLQZrqoCTsO0+DYGb/6QSON+Ml/FHI= Received: by 10.204.151.205 with SMTP id d13mr1910201bkw.117.1306140341535; Mon, 23 May 2011 01:45:41 -0700 (PDT) Received: from localhost.localdomain (bzq-79-179-199-121.red.bezeqint.net [79.179.199.121]) by mx.google.com with ESMTPS id q18sm3742392bka.15.2011.05.23.01.45.39 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 23 May 2011 01:45:41 -0700 (PDT) From: Sasha Levin To: penberg@kernel.org Cc: john@jfloren.net, kvm@vger.kernel.org, mingo@elte.hu, asias.hejun@gmail.com, gorcunov@gmail.com, prasadjoshi124@gmail.com, Sasha Levin Subject: [PATCH 3/5] kvm tools: Add VESA device Date: Mon, 23 May 2011 11:44:49 +0300 Message-Id: <1306140291-17493-3-git-send-email-levinsasha928@gmail.com> X-Mailer: git-send-email 1.7.5.rc3 In-Reply-To: <1306140291-17493-1-git-send-email-levinsasha928@gmail.com> References: <1306140291-17493-1-git-send-email-levinsasha928@gmail.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 23 May 2011 08:45:48 +0000 (UTC) Add a simple VESA device which simply moves a framebuffer from guest kernel to a VNC server. VESA device PCI code is very similar to virtio-* PCI code. Signed-off-by: John Floren Signed-off-by: Sasha Levin --- tools/kvm/hw/vesa.c | 106 ++++++++++++++++++++++++++++++++ tools/kvm/include/kvm/ioport.h | 2 + tools/kvm/include/kvm/vesa.h | 31 +++++++++ tools/kvm/include/kvm/virtio-pci-dev.h | 3 + 4 files changed, 142 insertions(+), 0 deletions(-) create mode 100644 tools/kvm/hw/vesa.c create mode 100644 tools/kvm/include/kvm/vesa.h diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c new file mode 100644 index 0000000..c1a4c64 --- /dev/null +++ b/tools/kvm/hw/vesa.c @@ -0,0 +1,106 @@ +#include "kvm/vesa.h" +#include "kvm/ioport.h" +#include "kvm/util.h" +#include "kvm/kvm.h" +#include "kvm/pci.h" +#include "kvm/kvm-cpu.h" +#include "kvm/irq.h" +#include "kvm/virtio-pci-dev.h" + +#include + +#include +#include +#include +#include + +#define VESA_QUEUE_SIZE 128 +#define VESA_IRQ 14 + +/* + * This "6000" value is pretty much the result of experimentation + * It seems that around this value, things update pretty smoothly + */ +#define VESA_UPDATE_TIME 6000 + +u8 videomem[VESA_MEM_SIZE]; + +static bool vesa_pci_io_in(struct kvm *kvm, u16 port, void *data, int size, u32 count) +{ + printf("vesa in port=%u\n", port); + return true; +} + +static bool vesa_pci_io_out(struct kvm *kvm, u16 port, void *data, int size, u32 count) +{ + printf("vesa out port=%u\n", port); + 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 = PCI_VENDOR_ID_REDHAT_QUMRANET, + .device_id = PCI_DEVICE_ID_VESA, + .header_type = PCI_HEADER_TYPE_NORMAL, + .revision_id = 0, + .class = 0x030000, + .subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET, + .subsys_id = PCI_SUBSYSTEM_ID_VESA, + .bar[0] = IOPORT_VESA | PCI_BASE_ADDRESS_SPACE_IO, + .bar[1] = VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY, +}; + + +void vesa_mmio_callback(u64 addr, u8 *data, u32 len, u8 is_write) +{ + if (is_write) + memcpy(&videomem[addr - VESA_MEM_ADDR], data, len); + + return; +} + +void vesa__init(struct kvm *kvm) +{ + u8 dev, line, pin; + + if (irq__register_device(PCI_DEVICE_ID_VESA, &dev, &pin, &line) < 0) + return; + + vesa_pci_device.irq_pin = pin; + vesa_pci_device.irq_line = line; + pci__register(&vesa_pci_device, dev); + ioport__register(IOPORT_VESA, &vesa_io_ops, IOPORT_VESA_SIZE); + + kvm__register_mmio(VESA_MEM_ADDR, VESA_MEM_SIZE, &vesa_mmio_callback); +} + +/* + * This starts a VNC server to display the framebuffer. + * It's not altogether clear this belongs here rather than in kvm-run.c + */ +void *vesa__dovnc(void *v) +{ + /* + * Make a fake argc and argv because the getscreen function + * seems to want it. + */ + int ac = 1; + char av[1][1] = {{0} }; + rfbScreenInfoPtr server; + + server = rfbGetScreen(&ac, (char **)av, VESA_WIDTH, VESA_HEIGHT, 8, 3, 4); + server->frameBuffer = (char *)videomem; + server->alwaysShared = TRUE; + rfbInitServer(server); + + while (rfbIsActive(server)) { + rfbMarkRectAsModified(server, 0, 0, VESA_WIDTH, VESA_HEIGHT); + rfbProcessEvents(server, server->deferUpdateTime * VESA_UPDATE_TIME); + } + return NULL; +} + diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h index 218530c..8253938 100644 --- a/tools/kvm/include/kvm/ioport.h +++ b/tools/kvm/include/kvm/ioport.h @@ -7,6 +7,8 @@ /* some ports we reserve for own use */ #define IOPORT_DBG 0xe0 +#define IOPORT_VESA 0xa200 +#define IOPORT_VESA_SIZE 256 #define IOPORT_VIRTIO_P9 0xb200 /* Virtio 9P device */ #define IOPORT_VIRTIO_P9_SIZE 256 #define IOPORT_VIRTIO_BLK 0xc200 /* Virtio block device */ diff --git a/tools/kvm/include/kvm/vesa.h b/tools/kvm/include/kvm/vesa.h new file mode 100644 index 0000000..dfa3d941 --- /dev/null +++ b/tools/kvm/include/kvm/vesa.h @@ -0,0 +1,31 @@ +#ifndef KVM__VESA_H +#define KVM__VESA_H + +#include + +#define VESA_WIDTH 640 +#define VESA_HEIGHT 480 + +#define VESA_MEM_ADDR 0xd0000000 +#define VESA_MEM_SIZE (4*VESA_WIDTH*VESA_HEIGHT) +#define VESA_BPP 32 + +struct kvm; +struct int10args; + +#ifdef CONFIG_HAS_VNCSERVER +void vesa_mmio_callback(u64, u8*, u32, u8); +void vesa__init(struct kvm *self); +void *vesa__dovnc(void *); +#else +void vesa__init(struct kvm *self); +void *vesa__dovnc(void *); +void vesa__init(struct kvm *self) { } +void *vesa__dovnc(void *param) { return NULL; } +#endif + +void int10handler(struct int10args *args); +extern u8 videomem[VESA_MEM_SIZE]; + + +#endif diff --git a/tools/kvm/include/kvm/virtio-pci-dev.h b/tools/kvm/include/kvm/virtio-pci-dev.h index 1b7862e..ca373df 100644 --- a/tools/kvm/include/kvm/virtio-pci-dev.h +++ b/tools/kvm/include/kvm/virtio-pci-dev.h @@ -13,8 +13,11 @@ #define PCI_DEVICE_ID_VIRTIO_CONSOLE 0x1003 #define PCI_DEVICE_ID_VIRTIO_RNG 0x1004 #define PCI_DEVICE_ID_VIRTIO_P9 0x1009 +#define PCI_DEVICE_ID_VESA 0x2000 #define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4 #define PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET 0x1af4 +#define PCI_SUBSYSTEM_ID_VESA 0x0004 + #endif /* VIRTIO_PCI_DEV_H_ */