From patchwork Mon May 23 11:19:11 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sasha Levin X-Patchwork-Id: 808332 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 p4NBJg1L001859 for ; Mon, 23 May 2011 11:19:43 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753499Ab1EWLTg (ORCPT ); Mon, 23 May 2011 07:19:36 -0400 Received: from mail-wy0-f174.google.com ([74.125.82.174]:45557 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750982Ab1EWLTf (ORCPT ); Mon, 23 May 2011 07:19:35 -0400 Received: by mail-wy0-f174.google.com with SMTP id 21so4109441wya.19 for ; Mon, 23 May 2011 04:19:34 -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=Ze0cCfbWYE4tQjm1xahTbxdv3B6e5p8R0jICVPzc/VI=; b=MhULgqnG5r/nOVE5GxKje37A8iA6eRx0YvEvkru2/EFmYTBI/cv9rCkSCifN64cVYB I6GgtklQhQuH8jPijcEf5BijhHKfso3Si3Lh1fcgjxey9JQrCWLRVgN0bUHhBaCzZmBn w5W0v/EmVOzlBJU3aJPZZZi3S+I8NzFH0Vxl8= 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=g1W8d0K/CFmqQ3bXWx/RP665xMQCbzUgMnitPTxJLPw5G7GgO6XodjBinoERfe/hUm r1hGNX99A0q1qHH5gF/npSXcwFgp7FHkDyVjTd5x8X/VxNSOnPn24teeUbca01SvPtJI JYHy8ypB/ToBWTESd6zrHyPWxXkMr47C1CRXg= Received: by 10.216.159.141 with SMTP id s13mr2101912wek.17.1306149574406; Mon, 23 May 2011 04:19:34 -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 r29sm3208804weq.21.2011.05.23.04.19.32 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 23 May 2011 04:19:34 -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 V2] kvm tools: Add VESA device Date: Mon, 23 May 2011 14:19:11 +0300 Message-Id: <1306149553-26793-3-git-send-email-levinsasha928@gmail.com> X-Mailer: git-send-email 1.7.5.rc3 In-Reply-To: <1306149553-26793-1-git-send-email-levinsasha928@gmail.com> References: <1306149553-26793-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 11:19:43 +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 [ turning code into patches and cleanup ] Signed-off-by: Sasha Levin --- tools/kvm/hw/vesa.c | 108 ++++++++++++++++++++++++++++++++ tools/kvm/include/kvm/ioport.h | 2 + tools/kvm/include/kvm/vesa.h | 27 ++++++++ tools/kvm/include/kvm/virtio-pci-dev.h | 3 + 4 files changed, 140 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..3003aa5 --- /dev/null +++ b/tools/kvm/hw/vesa.c @@ -0,0 +1,108 @@ +#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; + pthread_t thread; + + 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); + pthread_create(&thread, NULL, vesa__dovnc, kvm); +} + +/* + * 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..3e58587 --- /dev/null +++ b/tools/kvm/include/kvm/vesa.h @@ -0,0 +1,27 @@ +#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; + +void vesa_mmio_callback(u64, u8*, u32, u8); +void vesa__init(struct kvm *self); +void *vesa__dovnc(void *); +void int10handler(struct int10args *args); + +#ifndef CONFIG_HAS_VNCSERVER +void vesa__init(struct kvm *self) { } +#endif + +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_ */