From patchwork Mon Sep 10 23:41:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 968305 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="oNZafPmN"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 428Pk93QJSz9rxp for ; Tue, 11 Sep 2018 09:43:12 +1000 (AEST) Received: from localhost ([::1]:54629 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fzVpk-0001GC-LD for incoming@patchwork.ozlabs.org; Mon, 10 Sep 2018 19:43:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42620) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fzVoz-00018m-GS for qemu-devel@nongnu.org; Mon, 10 Sep 2018 19:42:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fzVoy-0003lQ-Ma for qemu-devel@nongnu.org; Mon, 10 Sep 2018 19:42:21 -0400 Received: from mail-lf1-x141.google.com ([2a00:1450:4864:20::141]:39665) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fzVou-0003ak-OT for qemu-devel@nongnu.org; Mon, 10 Sep 2018 19:42:17 -0400 Received: by mail-lf1-x141.google.com with SMTP id v77-v6so18865680lfa.6 for ; Mon, 10 Sep 2018 16:42:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=n40sYLIVBVuT1iOLAwH5XQiQ7W2pRGReltGy9zvsaKI=; b=oNZafPmNq3Vh84ErE5zzXD7aDnD8RiANEnwLqQRBWnKj3irYXhEDm84OxX7imxm+y+ doyyGfMwknWjRyZLrn0chYwStQPBudYqu8V1DpQNCvcYomBta8RUmH1vbiajHQYFSLqs cEJ7GZjy8USwoCP5Akb4LOsK2ADUq50Ekjw8O3WeCAu/8tN0GmyzFA9khKBcuCWrntH6 t5NBCxWgkYKwLiDKkKenj4xGeJY7MTT1BVh3NcSYk8iv05aM+lz5ciAoeAbq3B0wrZZl 2quUf873RHD2DjJddaUw8z5gzc6XZ23/qURQPH8U54HYGRlJ1zvGkk9K5Qv86K/zj+U9 a1Mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=n40sYLIVBVuT1iOLAwH5XQiQ7W2pRGReltGy9zvsaKI=; b=HChp+riopzkJ5aTesXhd1j9dzYNAnSJXexnQ6eABKOyLpAWl3YFpTFRCHtGXe7MJwK FOzcEWqP6GVghR+tq4J4U3fEwy3JPN8bGikep2kbQiD5ISq0xiAtIj6N0VprKLfHyxAW bAhXLu8UKVFkFW3I47WpI399d3Y9Jbk3L+THS/FAVG/UtR2Bf8GQG62Yl8nKzFUrmJeX o1DqWFsrS94YJa1zPwNjsAJ5OdBnQXjYQ+fBmrId/W89MiPzB8lK2luBiHTn1sXJVMpj KVbrumaVo7lNGLFhKQrjBMOwnvrp5TvBdLkJGPs33k2rr0pIp8u0FU7njf0JnZDZNQah VMxw== X-Gm-Message-State: APzg51BeQpxs+fiXIw/Fc/a/HILgsD0LuxC8LlnNtNgpHDRBj5ehbGMF 4oL58E5NKD5V4UUP2pOjIh8kR3P3 X-Google-Smtp-Source: ANB0VdY/ueP0Y7dwNiQInhNoVz2PgY+RnOP6G0qpbPAxSQ2PF8D1dlG3os5RxE4jTrOsCSXtPGEQiQ== X-Received: by 2002:a19:a401:: with SMTP id q1-v6mr14516381lfc.111.1536622930837; Mon, 10 Sep 2018 16:42:10 -0700 (PDT) Received: from octofox.cadence.com (jcmvbkbc-1-pt.tunnel.tserv24.sto1.ipv6.he.net. [2001:470:27:1fa::2]) by smtp.gmail.com with ESMTPSA id q128-v6sm3039716ljq.72.2018.09.10.16.42.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 10 Sep 2018 16:42:10 -0700 (PDT) From: Max Filippov To: qemu-devel@nongnu.org Date: Mon, 10 Sep 2018 16:41:54 -0700 Message-Id: <20180910234154.24393-1-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.11.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::141 Subject: [Qemu-devel] [PATCH v2] target/xtensa: support input from chardev console X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Max Filippov Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Complete xtensa-semi chardev console implementation: allow reading input characters from file descriptor 0 and call sys_select_one simcall on it. Signed-off-by: Max Filippov --- Changes v1->v2: - put CharBackend and input buffer into the XtensaSimConsole structure target/xtensa/xtensa-semi.c | 71 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/target/xtensa/xtensa-semi.c b/target/xtensa/xtensa-semi.c index 7aa1d1357bda..2f762162768c 100644 --- a/target/xtensa/xtensa-semi.c +++ b/target/xtensa/xtensa-semi.c @@ -34,8 +34,6 @@ #include "qemu/log.h" #include "sysemu/sysemu.h" -static CharBackend *xtensa_sim_console; - enum { TARGET_SYS_exit = 1, TARGET_SYS_read = 3, @@ -153,13 +151,48 @@ static uint32_t errno_h2g(int host_errno) } } -void xtensa_sim_open_console(Chardev *chr) +typedef struct XtensaSimConsole { + CharBackend be; + struct { + char buffer[16]; + size_t offset; + } input; +} XtensaSimConsole; + +static XtensaSimConsole *sim_console; + +static IOCanReadHandler sim_console_can_read; +static int sim_console_can_read(void *opaque) { - static CharBackend console; + XtensaSimConsole *p = opaque; - qemu_chr_fe_init(&console, chr, &error_abort); - qemu_chr_fe_set_handlers(&console, NULL, NULL, NULL, NULL, NULL, NULL, true); - xtensa_sim_console = &console; + return sizeof(p->input.buffer) - p->input.offset; +} + +static IOReadHandler sim_console_read; +static void sim_console_read(void *opaque, const uint8_t *buf, int size) +{ + XtensaSimConsole *p = opaque; + size_t copy = sizeof(p->input.buffer) - p->input.offset; + + if (size < copy) { + copy = size; + } + memcpy(p->input.buffer + p->input.offset, buf, copy); + p->input.offset += copy; +} + +void xtensa_sim_open_console(Chardev *chr) +{ + static XtensaSimConsole console; + + qemu_chr_fe_init(&console.be, chr, &error_abort); + qemu_chr_fe_set_handlers(&console.be, + sim_console_can_read, + sim_console_read, + NULL, NULL, &console, + NULL, true); + sim_console = &console; } void HELPER(simcall)(CPUXtensaState *env) @@ -195,11 +228,27 @@ void HELPER(simcall)(CPUXtensaState *env) if (buf) { vaddr += io_sz; len -= io_sz; - if (fd < 3 && xtensa_sim_console) { + if (fd < 3 && sim_console) { if (is_write && (fd == 1 || fd == 2)) { - io_done = qemu_chr_fe_write_all(xtensa_sim_console, + io_done = qemu_chr_fe_write_all(&sim_console->be, buf, io_sz); regs[3] = errno_h2g(errno); + } else if (!is_write && fd == 0) { + if (sim_console->input.offset) { + io_done = sim_console->input.offset; + if (io_sz < io_done) { + io_done = io_sz; + } + memcpy(buf, sim_console->input.buffer, io_done); + memmove(sim_console->input.buffer, + sim_console->input.buffer + io_done, + sim_console->input.offset - io_done); + sim_console->input.offset -= io_done; + qemu_chr_fe_accept_input(&sim_console->be); + } else { + io_done = -1; + regs[3] = TARGET_EAGAIN; + } } else { qemu_log_mask(LOG_GUEST_ERROR, "%s fd %d is not supported with chardev console\n", @@ -292,9 +341,11 @@ void HELPER(simcall)(CPUXtensaState *env) tv.tv_sec = (int32_t)tswap32(target_tvv[0]); tv.tv_usec = (int32_t)tswap32(target_tvv[1]); } - if (fd < 3 && xtensa_sim_console) { + if (fd < 3 && sim_console) { if ((fd == 1 || fd == 2) && rq == SELECT_ONE_WRITE) { regs[2] = 1; + } else if (fd == 0 && rq == SELECT_ONE_READ) { + regs[2] = sim_console->input.offset > 0; } else { regs[2] = 0; }