From: DaiYoung Kim Date: Sat, 6 Apr 2013 11:52:58 +0000 (+0900) Subject: evdi : emulator virtual device interface is added X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~1023 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2612c7ba90c881df7d216261b1d569ebee7164c8;p=sdk%2Femulator%2Fqemu.git evdi : emulator virtual device interface is added evdi is added. incharge of communicating between guest and host. virt-io pci is supported. Signed-off-by : DaiYoung, Kim --- diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c old mode 100644 new mode 100755 index eb6e23603a..f8ad8347c0 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -35,6 +35,7 @@ #include "range.h" #ifdef CONFIG_MARU #include "../tizen/src/hw/maru_device_ids.h" +#include "../tizen/src/hw/maru_virtio_evdi.h" #include "../tizen/src/mloop_event.h" #endif @@ -993,6 +994,28 @@ static void virtio_hwkey_exit_pci(PCIDevice *pci_dev) virtio_exit_pci(pci_dev); } +static int virtio_evdi_init_pci(PCIDevice *pci_dev) +{ + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIODevice *vdev; + + vdev = virtio_evdi_init(&pci_dev->qdev); + if (!vdev) { + return -1; + } + virtio_init_pci(proxy, vdev); + return 0; +} + +static void virtio_evdi_exit_pci(PCIDevice *pci_dev) +{ + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + + virtio_pci_stop_ioeventfd(proxy); + virtio_evdi_exit(proxy->vdev); + virtio_exit_pci(pci_dev); +} + #endif static Property virtio_blk_properties[] = { @@ -1290,6 +1313,27 @@ static TypeInfo virtio_hwkey_info = { .class_init = virtio_hwkey_class_init, }; +static void virtio_evdi_class_init(ObjectClass *klass, void *data) { + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->init = virtio_evdi_init_pci; + k->exit = virtio_evdi_exit_pci; + k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; + k->device_id = PCI_DEVICE_ID_VIRTIO_EVDI; + k->revision = VIRTIO_PCI_ABI_VERSION; + k->class_id = PCI_CLASS_OTHERS; + dc->reset = virtio_pci_reset; +} + +static TypeInfo virtio_evdi_info = { + .name = "virtio-evdi-pci", + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(VirtIOPCIProxy), + .class_init = virtio_evdi_class_init, +}; + + #endif /* CONFIG_MARU */ static void virtio_pci_register_types(void) @@ -1307,6 +1351,7 @@ static void virtio_pci_register_types(void) type_register_static(&virtio_keyboard_info); type_register_static(&virtio_esm_info); type_register_static(&virtio_hwkey_info); + type_register_static(&virtio_evdi_info); #endif } diff --git a/tizen/src/Makefile.tizen b/tizen/src/Makefile.tizen index 292f4621a1..5b90201622 100755 --- a/tizen/src/Makefile.tizen +++ b/tizen/src/Makefile.tizen @@ -113,6 +113,7 @@ obj-y += maru_virtio_keyboard.o obj-y += maru_codec.o obj-y += maru_virtio_esm.o obj-y += maru_virtio_hwkey.o +obj-y += maru_virtio_evdi.o obj-$(CONFIG_PCI) += maru_camera_common_pci.o obj-$(CONFIG_LINUX) += maru_camera_linux_pci.o diff --git a/tizen/src/hw/maru_device_ids.h b/tizen/src/hw/maru_device_ids.h old mode 100644 new mode 100755 index 8a2a0bd8e9..47a2fda274 --- a/tizen/src/hw/maru_device_ids.h +++ b/tizen/src/hw/maru_device_ids.h @@ -12,6 +12,7 @@ * SungMin Ha * JiHye Kim * GiWoong Kim + * DaiYoung Kim * YeongKyoon Lee * DongKyun Yun * DoHyung Hong @@ -52,6 +53,7 @@ #define PCI_DEVICE_ID_VIRTIO_KEYBOARD 0x1020 #define PCI_DEVICE_ID_VIRTIO_ESM 0x1024 #define PCI_DEVICE_ID_VIRTIO_HWKEY 0x1028 +#define PCI_DEVICE_ID_VIRTIO_EVDI 0x1028 /* Virtio */ /* @@ -84,5 +86,6 @@ #define VIRTIO_ID_KEYBOARD 12 #define VIRTIO_ID_ESM 13 #define VIRTIO_ID_HWKEY 14 +#define VIRTIO_ID_EVDI 15 #endif /* MARU_DEVICE_IDS_H_ */ diff --git a/tizen/src/hw/maru_virtio_evdi.c b/tizen/src/hw/maru_virtio_evdi.c new file mode 100755 index 0000000000..01d54ebf51 --- /dev/null +++ b/tizen/src/hw/maru_virtio_evdi.c @@ -0,0 +1,196 @@ +/* + * Virtio EmulatorVirtualDeviceInterface Device + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: + * DaiYoung Kim + * YeongKyoon Lee + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + +#include "maru_device_ids.h" +#include "maru_virtio_evdi.h" +#include "debug_ch.h" + +MULTI_DEBUG_CHANNEL(qemu, virtio-evdi); + +#define VIRTIO_EVDI_DEVICE_NAME "virtio-evdi" + +#define __MAX_BUF_SIZE 1024 + +enum { + IOTYPE_INPUT = 0, + IOTYPE_OUTPUT = 1 +}; + +struct msg_info { + char buf[__MAX_BUF_SIZE]; + uint32_t use; +}; + +typedef struct VirtIO_EVDI{ + VirtIODevice vdev; + VirtQueue *rvq; + VirtQueue *svq; + DeviceState *qdev; + + QEMUBH *bh; +} VirtIO_EVDI; + + +VirtIO_EVDI* vio_evdi; + +static int g_cnt = 0; + +static void virtio_evdi_recv(VirtIODevice *vdev, VirtQueue *vq) +{ + int index = 0; + + struct msg_info _msg; + + INFO(">> evdirecv : virtio_evdi_recv\n"); + + if (unlikely(virtio_queue_empty(vio_evdi->rvq))) { + INFO(">> evdirecv : virtqueue is empty\n"); + return; + } + + VirtQueueElement elem; + + while ((index = virtqueue_pop(vq, &elem))) { + + INFO(">> evdirecv : virtqueue_pop. index: %d\n", index); + INFO(">> evdirecv : element out_num : %d, in_num : %d\n", elem.out_num, elem.in_num); + + if (index == 0) { + INFO("evdirecv : virtqueue break\n"); + break; + } + + INFO(">> evdirecv : received use = %d, iov_len = %d\n", _msg.use, elem.in_sg[0].iov_len); + + memcpy(&_msg, elem.in_sg[0].iov_base, elem.in_sg[0].iov_len); + + + if (g_cnt < 10) + { + memset(&_msg, 0x00, sizeof(_msg)); + sprintf(_msg.buf, "test_%d\n", g_cnt++); + memcpy(elem.in_sg[0].iov_base, &_msg, sizeof(struct msg_info)); + + INFO(">> evdirecv : send to guest msg use = %d, msg = %s, iov_len = %d \n", + _msg.use, _msg.buf, elem.in_sg[0].iov_len); + + + virtqueue_push(vq, &elem, sizeof(VirtIO_EVDI)); + virtio_notify(&vio_evdi->vdev, vq); + } + } + + INFO("enf of virtio_evdi_recv\n"); +} + + +static void virtio_evdi_send(VirtIODevice *vdev, VirtQueue *vq) +{ + VirtIO_EVDI *vevdi = (VirtIO_EVDI *)vdev; + int index = 0; + struct msg_info _msg; + + INFO("<< evdisend : virtio_evdi_send \n"); + if (virtio_queue_empty(vevdi->svq)) { + INFO("<< evdisend : virtqueue is empty.\n"); + return; + } + + VirtQueueElement elem; + + while ((index = virtqueue_pop(vq, &elem))) { + + INFO("<< evdisend : virtqueue pop. index: %d\n", index); + INFO("<< evdisend : element out_num : %d, in_num : %d\n", elem.out_num, elem.in_num); + + if (index == 0) { + INFO("<< evdisend : virtqueue break\n"); + break; + } + + INFO("<< evdisend : use=%d, iov_len = %d\n", _msg.use, elem.out_sg[0].iov_len); + + memset(&_msg, 0x00, sizeof(_msg)); + memcpy(&_msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len); + + INFO("<< evdisend : recv from guest len = %d, msg = %s \n", _msg.use, _msg.buf); + } + + virtqueue_push(vq, &elem, sizeof(VirtIO_EVDI)); + virtio_notify(&vio_evdi->vdev, vq); +} + +static void maru_virtio_evdi_notify(void) +{ + TRACE("nothing to do.\n"); +} + +static uint32_t virtio_evdi_get_features(VirtIODevice *vdev, + uint32_t request_feature) +{ + TRACE("virtio_evdi_get_features.\n"); + return 0; +} + +static void maru_evdi_bh(void *opaque) +{ + maru_virtio_evdi_notify(); +} + +VirtIODevice *virtio_evdi_init(DeviceState *dev) +{ + INFO("initialize evdi device\n"); + + vio_evdi = (VirtIO_EVDI *)virtio_common_init(VIRTIO_EVDI_DEVICE_NAME, + VIRTIO_ID_EVDI, 0, sizeof(VirtIO_EVDI)); + if (vio_evdi == NULL) { + ERR("failed to initialize evdi device\n"); + return NULL; + } + + vio_evdi->vdev.get_features = virtio_evdi_get_features; + vio_evdi->rvq = virtio_add_queue(&vio_evdi->vdev, 256, virtio_evdi_recv); + vio_evdi->svq = virtio_add_queue(&vio_evdi->vdev, 256, virtio_evdi_send); + vio_evdi->qdev = dev; + + vio_evdi->bh = qemu_bh_new(maru_evdi_bh, vio_evdi); + + return &vio_evdi->vdev; +} + +void virtio_evdi_exit(VirtIODevice *vdev) +{ + INFO("destroy evdi device\n"); + + if (vio_evdi->bh) { + qemu_bh_delete(vio_evdi->bh); + } + + virtio_cleanup(vdev); +} + diff --git a/tizen/src/hw/maru_virtio_evdi.h b/tizen/src/hw/maru_virtio_evdi.h new file mode 100755 index 0000000000..ad88b682d4 --- /dev/null +++ b/tizen/src/hw/maru_virtio_evdi.h @@ -0,0 +1,26 @@ +/* + * maru_virtio_evdi.h + * + * Created on: 2013. 3. 30. + * Author: dykim + */ + +#ifndef MARU_VIRTIO_EVDI_H_ +#define MARU_VIRTIO_EVDI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hw/virtio.h" + +VirtIODevice *virtio_evdi_init(DeviceState *dev); + +void virtio_evdi_exit(VirtIODevice *vdev); + +#ifdef __cplusplus +} +#endif + + +#endif /* MARU_VIRTIO_EVDI_H_ */