From: SeokYeon Hwang Date: Wed, 6 Jul 2016 06:04:32 +0000 (+0900) Subject: Merge branch 'develop' into develop_qemu_2.6 X-Git-Tag: TizenStudio_2.0_p2.4~27^2~6^2~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4875fd78bfeab06790761c3cea222d7b6820a4dd;p=sdk%2Femulator%2Fqemu.git Merge branch 'develop' into develop_qemu_2.6 Change-Id: Id31ceffdbfe8938ea70a11f904fb38e2c4732dd0 Signed-off-by: SeokYeon Hwang --- 4875fd78bfeab06790761c3cea222d7b6820a4dd diff --cc tizen/src/hw/virtio/maru_virtio_esm.c index 6737bfd,099c5be..069be2c --- a/tizen/src/hw/virtio/maru_virtio_esm.c +++ b/tizen/src/hw/virtio/maru_virtio_esm.c @@@ -26,13 -25,16 +25,16 @@@ * */ -#include "maru_virtio_esm.h" - +#include "qemu/osdep.h" - #include "hw/maru_device_ids.h" + #include "qemu/iov.h" + +#include "maru_virtio_esm.h" + #include "hw/maru_device_ids.h" #include "emul_state.h" - #include "debug_ch.h" - MULTI_DEBUG_CHANNEL(qemu, esm); + #include "util/new_debug_ch.h" + + DECLARE_DEBUG_CHANNEL(esm); #define SYSTEM_MODE_LAYER 1 #define USER_MODE_LAYER 0 @@@ -56,40 -59,35 +59,38 @@@ static void virtio_esm_handle(VirtIODev return; } - if (!virtqueue_pop(vq, &elem) || elem.out_num != 1) { + // Get a queue buffer. + elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); + - TRACE("virtio element out number : %d\n", elem->out_num); - if (elem->out_num != 1) { - ERR("virtio element out number is wierd.\n"); - } - else { - TRACE("caramis elem.out_sg[0].iov_len : %x\n", elem->out_sg[0].iov_len); - TRACE("caramis elem.out_sg[0].iov_base : %x\n", elem->out_sg[0].iov_base); - if (elem->out_sg[0].iov_len != 4) { - ERR("out lenth is wierd.\n"); ++ if (!elem || elem->out_num != 1) { + LOG_SEVERE("virtqueue is broken or virtio element out number " + "is wierd.\n"); + } else { - size_t len = iov_to_buf(elem.out_sg, elem.out_num, ++ size_t len = iov_to_buf(elem->out_sg, elem->out_num, + 0, &progress, sizeof(struct progress_info)); + if (len != 4) { + LOG_SEVERE("out lenth is wierd.\n"); } - else { - progress = *((struct progress_info*)elem->out_sg[0].iov_base); - TRACE("Boot up progress is [%u] percent done at %s.\n", - ++ progress = *((struct progress_info*)elem->out_sg[0].iov_base); + LOG_TRACE("Boot up progress is [%u] percent done at %s.\n", progress.percentage, - progress.mode == 's' || progress.mode == 'S' ? "system mode" : "user mode"); - - if (progress.mode == 's' || progress.mode == 'S') { - if (progress.percentage >= 100) { - boot_complete |= (1 << SYSTEM_MODE_LAYER); - } - } else { - if (progress.percentage >= 100) { - boot_complete |= (1 << USER_MODE_LAYER); - } + progress.mode == 's' || progress.mode == 'S' ? + "system mode" : "user mode"); + + if (progress.mode == 's' || progress.mode == 'S') { + if (progress.percentage >= 100) { + boot_complete |= (1 << SYSTEM_MODE_LAYER); + } + } else { + if (progress.percentage >= 100) { + boot_complete |= (1 << USER_MODE_LAYER); } + } - /* booting complete check */ - if ((boot_complete & (1 << SYSTEM_MODE_LAYER)) && + /* booting complete check */ + if ((boot_complete & (1 << SYSTEM_MODE_LAYER)) && (boot_complete & (1 << USER_MODE_LAYER))) { - set_emulator_condition(BOOT_COMPLETED); - } + set_emulator_condition(BOOT_COMPLETED); } } diff --cc tizen/src/hw/virtio/maru_virtio_input.c index 0000000,d84c5cf..419f970 mode 000000,100644..100644 --- a/tizen/src/hw/virtio/maru_virtio_input.c +++ b/tizen/src/hw/virtio/maru_virtio_input.c @@@ -1,0 -1,627 +1,624 @@@ + /* + * Maru Virtio Input Device + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: + * SeokYeon Hwang + * Jinhyung Jo + * + * 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 "qemu/osdep.h" + #include "qemu/iov.h" + #include "hw/maru_device_ids.h" + #include "maru_virtio_input.h" + + #include "util/new_debug_ch.h" + DECLARE_DEBUG_CHANNEL(input); + + + // + // INPUT COMMON + // + + #define MAX_EVENT_CNT 128 + + #define TYPE_VIRTIO_MARU_INPUT "virtio-maru-input-device" + + #if 0 + // TODO + #define VIRTIO_MARU_INPUT(obj) \ + OBJECT_CHECK(VirtIOMaruInput, (obj), TYPE_VIRTIO_MARU_INPUT) + #else + #define VIRTIO_MARU_INPUT(obj) ((VirtIOMaruInput *)(obj)) + #endif + + static void default_get_config( + VirtIODevice *vdev, uint8_t *config_data) + { + // do nothing + } + + static void default_set_config( + VirtIODevice *vdev, const uint8_t *config_data) + { + // do nothing + } + + static uint64_t default_get_features( + VirtIODevice *vdev, uint64_t request_features, Error **errp) + { + // do nothing + return request_features; + } + + + static void default_handle_output(VirtIODevice *vdev, VirtQueue *vq) + { + // do nothing + } + + static void send_event(void *opaque) + { + VirtIOMaruInput *input = VIRTIO_MARU_INPUT(opaque); + int i = 0; + int len = 0; + + LOG_TRACE("%s\n", __func__); + + qemu_mutex_lock(&input->event_mutex); + + for (i = 0; i < input->buf_index; ++i) { - VirtQueueElement elem; - VirtQueueElement *element = &elem; -// preparing to merge qemu 2.6 -// element = virtqueue_pop(input->vq, sizeof(VirtQueueElement)); -// if (element) { - if (virtqueue_pop(input->vq, element)) { ++ VirtQueueElement *element = ++ virtqueue_pop(input->vq, sizeof(VirtQueueElement)); ++ if (element) { + len = iov_from_buf(element->in_sg, element->in_num, + 0, input->events + (input->event_size * i), + input->event_size); + virtqueue_push(input->vq, element, len); + } else { + LOG_SEVERE("virtqueue is not available, dropping event.\n"); + break; + } + } + input->buf_index = 0; + + qemu_mutex_unlock(&input->event_mutex); + + virtio_notify(VIRTIO_DEVICE(input), input->vq); + } + + static void input_common_realize(DeviceState *dev, const char* name, + uint16_t device_id, void *handle_output, void *bh, + void *events, size_t event_size) + { + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOMaruInput *input = VIRTIO_MARU_INPUT(dev); + + if (!handle_output) { + handle_output = default_handle_output; + } + + if (!bh) { + bh = send_event; + } + + virtio_init(vdev, name, device_id, 4); + + input->vq = virtio_add_queue(&input->vdev, MAX_EVENT_CNT, handle_output); + input->qdev = dev; + + /* bottom halves */ + input->bh = qemu_bh_new(bh, vdev); + + input->events = (uint8_t *)events; + input->event_size = event_size; + + qemu_mutex_init(&input->event_mutex); + } + + static void input_common_unrealize(DeviceState *dev) + { + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOMaruInput *input = VIRTIO_MARU_INPUT(dev); + + if (input->bh) { + qemu_bh_delete(input->bh); + } + + qemu_mutex_destroy(&input->event_mutex); + + virtio_cleanup(vdev); + } + + static void input_common_reset(VirtIODevice *vdev) + { + VirtIOMaruInput *input = VIRTIO_MARU_INPUT(vdev); + + qemu_mutex_lock(&input->event_mutex); + /* reset the counters */ + input->event_cnt = 0; + input->buf_index = 0; + qemu_mutex_unlock(&input->event_mutex); + } + + static bool check_ready(VirtIOMaruInput *input) + { + if (unlikely(!virtio_queue_ready(input->vq))) { + LOG_INFO("virtqueue is not ready, dropping event.\n"); + return false; + } + + ++(input->event_cnt); + + if (input->buf_index >= MAX_EVENT_CNT ) { + LOG_SEVERE("event queue is not available, dropping event.\n"); + return false; + } + + return true; + } + + static void push_event(VirtIOMaruInput *input) + { + /* send */ + qemu_bh_schedule(input->bh); + } + + + // + // TOUCHSCREEN + // + + #define VIRTIO_MARU_TOUCHSCREEN(obj) \ + OBJECT_CHECK(VirtIOTouchscreen, (obj), TYPE_VIRTIO_MARU_TOUCHSCREEN) + + #define TOUCHSCREEN_OPTION_NAME "max_point" + + static VirtIOTouchscreen *ts; + static touch_event touch_events[MAX_EVENT_CNT]; + + bool virtio_touchscreen_ready(void) + { + if (ts == NULL) { + return false; + } + + return virtio_queue_ready(ts->input.vq) != 0; + } + + int virtio_touchscreen_get_max_touch_point(void) + { + if (ts) { + return ts->max_finger; + } else { + return 1; + } + } + + void virtio_touchscreen_event(int x, int y, int z, int buttons_state) + { + VirtIOMaruInput *input = &ts->input; + touch_event *event; + + qemu_mutex_lock(&input->event_mutex); + + if (!check_ready(input)) { + return; + } + + event = &touch_events[input->buf_index++]; + + /* mouse event is copied into the queue */ + event->x = x; + event->y = y; + event->z = z; + event->state = buttons_state; + + qemu_mutex_unlock(&input->event_mutex); + + push_event(input); + + + LOG_TRACE("touch event: x=%d, y=%d, z=%d, state=%d\n", + event->x, event->y, + event->z, event->state); + } + + static void virtio_touchscreen_get_config( + VirtIODevice *vdev, uint8_t *config_data) + { + VirtIOTouchscreen *ts = VIRTIO_MARU_TOUCHSCREEN(vdev); + int max_trkid = 10; + + LOG_TRACE("%s\n", __func__); + + max_trkid = ts->max_finger; + memcpy(config_data, &max_trkid, 4); + } + + static void virtio_touchscreen_device_realize(DeviceState *dev, Error **errp) + { + ts = VIRTIO_MARU_TOUCHSCREEN(dev); + + LOG_INFO("%s: %d\n", __func__, ts->max_finger); + + input_common_realize(dev, TYPE_VIRTIO_MARU_TOUCHSCREEN, + VIRTIO_ID_MARU_TOUCHSCREEN, NULL, NULL, + touch_events, sizeof(touch_event)); + } + + static void virtio_touchscreen_device_unrealize(DeviceState *dev, Error **errp) + { + LOG_INFO("%s\n", __func__); + + input_common_unrealize(dev); + } + + static void virtio_touchscreen_device_reset(VirtIODevice *vdev) + { + LOG_INFO("%s\n", __func__); + + input_common_reset(vdev); + } + + static Property virtio_touchscreen_properties[] = { + DEFINE_PROP_UINT32(TOUCHSCREEN_OPTION_NAME, + VirtIOTouchscreen, max_finger, DEFAULT_MAX_FINGER), + DEFINE_PROP_END_OF_LIST(), + }; + + static void virtio_touchscreen_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); + + dc->props = virtio_touchscreen_properties; + vdc->realize = virtio_touchscreen_device_realize; + vdc->unrealize = virtio_touchscreen_device_unrealize; + vdc->reset = virtio_touchscreen_device_reset; + vdc->get_config = virtio_touchscreen_get_config; + vdc->set_config = default_set_config; + vdc->get_features = default_get_features; + } + + static const TypeInfo virtio_touchscreen_info = { + .name = TYPE_VIRTIO_MARU_TOUCHSCREEN, + .parent = TYPE_VIRTIO_DEVICE, + .instance_size = sizeof(VirtIOTouchscreen), + .class_init = virtio_touchscreen_class_init, + }; + + + // + // KEYBOARD + // + + #define VIRTIO_MARU_KEYBOARD(obj) \ + OBJECT_CHECK(VirtIOKeyboard, (obj), TYPE_VIRTIO_MARU_KEYBOARD) + + static VirtIOKeyboard *kbd; + static keyboard_event keyboard_events[MAX_EVENT_CNT]; + + void virtio_keyboard_event(int keycode) + { + VirtIOMaruInput *input = &kbd->input; + keyboard_event *event; + + qemu_mutex_lock(&input->event_mutex); + + if (!check_ready(input)) { + return; + } + + event = &keyboard_events[input->buf_index++]; + + if (keycode < 0xe0) { + if (kbd->extension_key) { + switch (keycode & 0x7f) { + case 28: /* KP_Enter */ + event->code = 96; + break; + case 29: /* Right Ctrl */ + event->code = 97; + break; + case 56: /* Right Alt */ + event->code = 100; + break; + case 71: /* Home */ + event->code = 102; + break; + case 72: /* Up */ + event->code = 103; + break; + case 73: /* Page Up */ + event->code = 104; + break; + case 75: /* Left */ + event->code = 105; + break; + case 77: /* Right */ + event->code = 106; + break; + case 79: /* End */ + event->code = 107; + break; + case 80: /* Down */ + event->code = 108; + break; + case 81: /* Page Down */ + event->code = 109; + break; + case 82: /* Insert */ + event->code = 110; + break; + case 83: /* Delete */ + event->code = 111; + break; + default: + LOG_WARNING("There is no keymap for this keycode %d.\n", keycode); + } + kbd->extension_key = 0; + } else { + event->code = keycode & 0x7f; + } + + if (!(keycode & 0x80)) { + event->type = 1; /* KEY_PRESSED */ + } else { + event->type = 0; /* KEY_RELEASED */ + } + } else { + LOG_TRACE("Extension key.\n"); + event->code = keycode; + kbd->extension_key = 1; + } + + qemu_mutex_unlock(&input->event_mutex); + + push_event(input); + + LOG_TRACE("keyboard event: code=%d, type=%d\n", + event->code, event->type); + } + + static void virtio_keyboard_device_realize(DeviceState *dev, Error **errp) + { + kbd = VIRTIO_MARU_KEYBOARD(dev); + + LOG_INFO("%s\n", __func__); + + input_common_realize(dev, TYPE_VIRTIO_MARU_KEYBOARD, + VIRTIO_ID_MARU_KEYBOARD, NULL, NULL, + keyboard_events, sizeof(keyboard_event)); + } + + static void virtio_keyboard_device_unrealize(DeviceState *dev, Error **errp) + { + LOG_INFO("%s\n", __func__); + + input_common_unrealize(dev); + } + + static void virtio_keyboard_device_reset(VirtIODevice *vdev) + { + VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev; + + LOG_INFO("%s\n", __func__); + + vkbd->extension_key = 0; + input_common_reset(vdev); + } + + static void virtio_keyboard_class_init(ObjectClass *klass, void *data) + { + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); + vdc->unrealize = virtio_keyboard_device_unrealize; + vdc->realize = virtio_keyboard_device_realize; + vdc->reset = virtio_keyboard_device_reset; + vdc->get_config = default_get_config; + vdc->set_config = default_set_config; + vdc->get_features = default_get_features; + } + + static const TypeInfo virtio_keyboard_info = { + .name = TYPE_VIRTIO_MARU_KEYBOARD, + .parent = TYPE_VIRTIO_DEVICE, + .instance_size = sizeof(VirtIOKeyboard), + .class_init = virtio_keyboard_class_init, + }; + + + // + // HW KEY + // + + #define VIRTIO_MARU_HWKEY(obj) \ + OBJECT_CHECK(VirtIOHWKey, (obj), TYPE_VIRTIO_MARU_HWKEY) + + static VirtIOHWKey *hwkey; + static hwkey_event hwkey_events[MAX_EVENT_CNT]; + + void maru_hwkey_event(int event_type, int keycode) + { + VirtIOMaruInput *input = &hwkey->input; + hwkey_event *event; + + if (!check_ready(input)) { + return; + } + + qemu_mutex_lock(&input->event_mutex); + + event = &hwkey_events[input->buf_index++]; + + /* hwkey event is copied into the queue */ + event->keycode = keycode; + event->event_type = event_type; + + qemu_mutex_unlock(&input->event_mutex); + + push_event(input); + + LOG_TRACE("hwkey event: keycode=%d, event_type=%d\n", + event->keycode, event->event_type); + } + + static void virtio_hwkey_device_realize(DeviceState *dev, Error **errp) + { + hwkey = VIRTIO_MARU_HWKEY(dev); + + LOG_INFO("%s\n", __func__); + + input_common_realize(dev, TYPE_VIRTIO_MARU_HWKEY, + VIRTIO_ID_MARU_HWKEY, NULL, NULL, + hwkey_events, sizeof(hwkey_event)); + } + + static void virtio_hwkey_device_unrealize(DeviceState *dev, Error **errp) + { + LOG_INFO("%s\n", __func__); + + input_common_unrealize(dev); + } + + static void virtio_hwkey_device_reset(VirtIODevice *vdev) + { + LOG_INFO("%s\n", __func__); + + input_common_reset(vdev); + } + + static void virtio_hwkey_class_init(ObjectClass *klass, void *data) + { + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); + vdc->unrealize = virtio_hwkey_device_unrealize; + vdc->realize = virtio_hwkey_device_realize; + vdc->reset = virtio_hwkey_device_reset; + vdc->get_config = default_get_config; + vdc->set_config = default_set_config; + vdc->get_features = default_get_features; + } + + static const TypeInfo virtio_hwkey_info = { + .name = TYPE_VIRTIO_MARU_HWKEY, + .parent = TYPE_VIRTIO_DEVICE, + .instance_size = sizeof(VirtIOHWKey), + .class_init = virtio_hwkey_class_init, + }; + + + // + // ROTARY + // + + #define VIRTIO_MARU_ROTARY(obj) \ + OBJECT_CHECK(VirtIORotary, (obj), TYPE_VIRTIO_MARU_ROTARY) + + static VirtIORotary *rotary; + static rotary_event rotary_events[MAX_EVENT_CNT]; + + void maru_rotary_event(int32_t delta, int32_t type) + { + VirtIOMaruInput *input = &rotary->input; + rotary_event *event; + + /* skip useless data */ + if (!delta && !type) { + return; + } + + if (!check_ready(input)) { + return; + } + + qemu_mutex_lock(&input->event_mutex); + + event = &rotary_events[input->buf_index++]; + + event->delta = delta; + event->type = type; + + qemu_mutex_unlock(&input->event_mutex); + + push_event(input); + + LOG_TRACE("[%s] delta(%d), type(%d)\n", __func__, delta, type); + } + + static void virtio_rotary_device_realize(DeviceState *dev, Error **errp) + { + rotary = VIRTIO_MARU_ROTARY(dev); + + LOG_INFO("%s\n", __func__); + + input_common_realize(dev, TYPE_VIRTIO_MARU_ROTARY, + VIRTIO_ID_MARU_ROTARY, NULL, NULL, + rotary_events, sizeof(rotary_event)); + } + + static void virtio_rotary_device_unrealize(DeviceState *dev, Error **errp) + { + LOG_INFO("%s\n", __func__); + + input_common_unrealize(dev); + } + + static void virtio_rotary_device_reset(VirtIODevice *vdev) + { + LOG_INFO("%s\n", __func__); + + input_common_reset(vdev); + } + + static void virtio_rotary_class_init(ObjectClass *klass, void *data) + { + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); + vdc->unrealize = virtio_rotary_device_unrealize; + vdc->realize = virtio_rotary_device_realize; + vdc->reset = virtio_rotary_device_reset; + vdc->get_config = default_get_config; + vdc->set_config = default_set_config; + vdc->get_features = default_get_features; + } + + static const TypeInfo virtio_rotary_info = { + .name = TYPE_VIRTIO_MARU_ROTARY, + .parent = TYPE_VIRTIO_DEVICE, + .instance_size = sizeof(VirtIORotary), + .class_init = virtio_rotary_class_init, + }; + + + + // + // Register devices + // + + static void virtio_register_types(void) + { + type_register_static(&virtio_touchscreen_info); + type_register_static(&virtio_keyboard_info); + type_register_static(&virtio_hwkey_info); + type_register_static(&virtio_rotary_info); + } + + type_init(virtio_register_types)