From patchwork Sat Jan 18 16:42:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11340151 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 69E0C921 for ; Sat, 18 Jan 2020 16:43:55 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2F5E32469A for ; Sat, 18 Jan 2020 16:43:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bR9vDAPZ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2F5E32469A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=roeck-us.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:42558 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrCT-0005uC-RV for patchwork-qemu-devel@patchwork.kernel.org; Sat, 18 Jan 2020 11:43:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36129) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrBJ-00042r-LE for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1isrBH-0002AI-Ja for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:41 -0500 Received: from mail-yw1-xc36.google.com ([2607:f8b0:4864:20::c36]:33299) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1isrBD-000245-Oe; Sat, 18 Jan 2020 11:42:35 -0500 Received: by mail-yw1-xc36.google.com with SMTP id 192so15878608ywy.0; Sat, 18 Jan 2020 08:42:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=AwPwh2AA501F4MFYWrsZRKLaZSZaHflqS70l8N/9q3s=; b=bR9vDAPZr8KYdxKOjMnxbQUwm+JvIOhICVBGBmCkcrZln0yywbX25nLrb57XxhdN9U ATWSoBeFJk129plcIJ39SrsWKWk3CMjKyw5DFmtZeQe8gO864d9bm970jaLefb4iC2Qb vkHRg2r59xWARsPJjxeRa0D2Jk0FIozlH0bmX+EH4sq2qEPFpWk9OzlPoLbUh/uB+CM5 cPxeZurHMzum9Cfu0j6aSy+mAF55EsqM4x/e/ivcmOtQNkaiq/kjbphAfXdaINEKxUqp W2iRfwcIhWn2Ozlt+e+VZEnks3bJalDhpZn7c/BLigxIePTyHFhFzhKNE14AgUmYYqSI y9jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=AwPwh2AA501F4MFYWrsZRKLaZSZaHflqS70l8N/9q3s=; b=hYY4qYMBSfE/gumZh4qOUULAPfuj3a5tLCIcI9shNd4VdGvc/8ytQOBK1NrWgIUUFu oVZ/7zIYptTiKg/gw8EBXpfP4252jbrAx0KsZqgnKrMNCOa6DhouBx8grz/xkckh2mwf Gi8UexviHfIiv5Xf/ePEEVNH1oOryg+EFXmbQzzYKNriW0x3UVaRy7JnnC66cw5NhJcR Na0kxpjtxAiHSNC7taLxjnsZ2iipwALndOvqomcY60L4guReZlI5DKaJut22OHP7ON1i db8NbslWQkPdiZSNh1SLYrApze4/mzOUWFP4km+8L+PC9iok4WRZ0sV4+T7sXGKhx6m9 TVGw== X-Gm-Message-State: APjAAAXuvRYoRpXaBlsMq3WsJiuhXjnynp197hvUqI5ePwLdy3/D9HRQ RK2pzK++qvsm3e0lgYRChcs= X-Google-Smtp-Source: APXvYqynGferM8C0+0cFzn+80b/MOj5wyBUJYRqpIUy120Avc9o3ryxVQpfQcE/aSOK4WvJRYRFbSQ== X-Received: by 2002:a81:9893:: with SMTP id p141mr32609644ywg.360.1579365755074; Sat, 18 Jan 2020 08:42:35 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id h203sm12623654ywb.98.2020.01.18.08.42.34 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 18 Jan 2020 08:42:34 -0800 (PST) From: Guenter Roeck To: Peter Maydell Subject: [PATCH v2 1/7] dma/pl330: Convert to support tracing Date: Sat, 18 Jan 2020 08:42:23 -0800 Message-Id: <20200118164229.22539-2-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200118164229.22539-1-linux@roeck-us.net> References: <20200118164229.22539-1-linux@roeck-us.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c36 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Igor Mitsyanko , Paolo Bonzini , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Replace debug logging code with tracing. Signed-off-by: Guenter Roeck Reviewed-by: Peter Maydell --- v2: Make call to pl330_hexdump() conditional hw/dma/pl330.c | 88 ++++++++++++++++++++++++--------------------- hw/dma/trace-events | 24 +++++++++++++ 2 files changed, 72 insertions(+), 40 deletions(-) diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c index f2bb2d9ac1..64519971ef 100644 --- a/hw/dma/pl330.c +++ b/hw/dma/pl330.c @@ -25,19 +25,12 @@ #include "sysemu/dma.h" #include "qemu/log.h" #include "qemu/module.h" +#include "trace.h" #ifndef PL330_ERR_DEBUG #define PL330_ERR_DEBUG 0 #endif -#define DB_PRINT_L(lvl, fmt, args...) do {\ - if (PL330_ERR_DEBUG >= lvl) {\ - fprintf(stderr, "PL330: %s:" fmt, __func__, ## args);\ - } \ -} while (0) - -#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args) - #define PL330_PERIPH_NUM 32 #define PL330_MAX_BURST_LEN 128 #define PL330_INSN_MAXSIZE 6 @@ -319,6 +312,26 @@ typedef struct PL330InsnDesc { void (*exec)(PL330Chan *, uint8_t opcode, uint8_t *args, int len); } PL330InsnDesc; +static void pl330_hexdump(uint8_t *buf, size_t size) +{ + unsigned int b, i, len; + char tmpbuf[80]; + + for (b = 0; b < size; b += 16) { + len = size - b; + if (len > 16) { + len = 16; + } + tmpbuf[0] = '\0'; + for (i = 0; i < len; i++) { + if ((i % 4) == 0) { + strcat(tmpbuf, " "); + } + sprintf(tmpbuf + strlen(tmpbuf), " %02x", buf[b + i]); + } + trace_pl330_hexdump(b, tmpbuf); + } +} /* MFIFO Implementation * @@ -582,7 +595,7 @@ static inline void pl330_queue_remove_tagged(PL330Queue *s, uint8_t tag) static inline void pl330_fault(PL330Chan *ch, uint32_t flags) { - DB_PRINT("ch: %p, flags: %" PRIx32 "\n", ch, flags); + trace_pl330_fault(ch, flags); ch->fault_type |= flags; if (ch->state == pl330_chan_fault) { return; @@ -590,7 +603,7 @@ static inline void pl330_fault(PL330Chan *ch, uint32_t flags) ch->state = pl330_chan_fault; ch->parent->num_faulting++; if (ch->parent->num_faulting == 1) { - DB_PRINT("abort interrupt raised\n"); + trace_pl330_fault_abort(); qemu_irq_raise(ch->parent->irq_abort); } } @@ -648,7 +661,7 @@ static void pl330_dmaend(PL330Chan *ch, uint8_t opcode, return; } } - DB_PRINT("DMA ending!\n"); + trace_pl330_dmaend(); pl330_fifo_tagged_remove(&s->fifo, ch->tag); pl330_queue_remove_tagged(&s->read_queue, ch->tag); pl330_queue_remove_tagged(&s->write_queue, ch->tag); @@ -683,7 +696,7 @@ static void pl330_dmago(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len) uint32_t pc; PL330Chan *s; - DB_PRINT("\n"); + trace_pl330_dmago(); if (!ch->is_manager) { pl330_fault(ch, PL330_FAULT_UNDEF_INSTR); @@ -740,9 +753,7 @@ static void pl330_dmald(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len) ch->stall = pl330_queue_put_insn(&ch->parent->read_queue, ch->src, size, num, inc, 0, ch->tag); if (!ch->stall) { - DB_PRINT("channel:%" PRId8 " address:%08" PRIx32 " size:%" PRIx32 - " num:%" PRId32 " %c\n", - ch->tag, ch->src, size, num, inc ? 'Y' : 'N'); + trace_pl330_dmald(ch->tag, ch->src, size, num, inc ? 'Y' : 'N'); ch->src += inc ? size * num - (ch->src & (size - 1)) : 0; } } @@ -782,7 +793,7 @@ static void pl330_dmakill(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len) ch->fault_type = 0; ch->parent->num_faulting--; if (ch->parent->num_faulting == 0) { - DB_PRINT("abort interrupt lowered\n"); + trace_pl330_dmakill(); qemu_irq_lower(ch->parent->irq_abort); } } @@ -800,6 +811,8 @@ static void pl330_dmalpend(PL330Chan *ch, uint8_t opcode, uint8_t bs = opcode & 3; uint8_t lc = (opcode & 4) >> 2; + trace_pl330_dmalpend(nf, bs, lc, ch->lc[lc], ch->request_flag); + if (bs == 2) { pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); return; @@ -813,12 +826,12 @@ static void pl330_dmalpend(PL330Chan *ch, uint8_t opcode, if (nf) { ch->lc[lc]--; } - DB_PRINT("loop reiteration\n"); + trace_pl330_dmalpiter(); ch->pc -= args[0]; ch->pc -= len + 1; /* "ch->pc -= args[0] + len + 1" is incorrect when args[0] == 256 */ } else { - DB_PRINT("loop fallthrough\n"); + trace_pl330_dmalpfallthrough(); } } @@ -886,10 +899,10 @@ static void pl330_dmasev(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len) } if (ch->parent->inten & (1 << ev_id)) { ch->parent->int_status |= (1 << ev_id); - DB_PRINT("event interrupt raised %" PRId8 "\n", ev_id); + trace_pl330_dmasev_evirq(ev_id); qemu_irq_raise(ch->parent->irq[ev_id]); } - DB_PRINT("event raised %" PRId8 "\n", ev_id); + trace_pl330_dmasev_event(ev_id); ch->parent->ev_status |= (1 << ev_id); } @@ -914,9 +927,7 @@ static void pl330_dmast(PL330Chan *ch, uint8_t opcode, uint8_t *args, int len) ch->stall = pl330_queue_put_insn(&ch->parent->write_queue, ch->dst, size, num, inc, 0, ch->tag); if (!ch->stall) { - DB_PRINT("channel:%" PRId8 " address:%08" PRIx32 " size:%" PRIx32 - " num:%" PRId32 " %c\n", - ch->tag, ch->dst, size, num, inc ? 'Y' : 'N'); + trace_pl330_dmast(ch->tag, ch->dst, size, num, inc ? 'Y' : 'N'); ch->dst += inc ? size * num - (ch->dst & (size - 1)) : 0; } } @@ -992,7 +1003,7 @@ static void pl330_dmawfe(PL330Chan *ch, uint8_t opcode, } } ch->parent->ev_status &= ~(1 << ev_id); - DB_PRINT("event lowered %" PRIx8 "\n", ev_id); + trace_pl330_dmawfe(ev_id); } else { ch->stall = 1; } @@ -1135,7 +1146,7 @@ static int pl330_chan_exec(PL330Chan *ch) ch->stall = 0; insn = pl330_fetch_insn(ch); if (!insn) { - DB_PRINT("pl330 undefined instruction\n"); + trace_pl330_chan_exec_undef(); pl330_fault(ch, PL330_FAULT_UNDEF_INSTR); return 0; } @@ -1175,10 +1186,9 @@ static int pl330_exec_cycle(PL330Chan *channel) int len = q->len - (q->addr & (q->len - 1)); dma_memory_read(&address_space_memory, q->addr, buf, len); - if (PL330_ERR_DEBUG > 1) { - DB_PRINT("PL330 read from memory @%08" PRIx32 " (size = %08x):\n", - q->addr, len); - qemu_hexdump((char *)buf, stderr, "", len); + trace_pl330_exec_cycle(q->addr, len); + if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) { + pl330_hexdump(buf, len); } fifo_res = pl330_fifo_push(&s->fifo, buf, len, q->tag); if (fifo_res == PL330_FIFO_OK) { @@ -1207,10 +1217,9 @@ static int pl330_exec_cycle(PL330Chan *channel) } if (fifo_res == PL330_FIFO_OK || q->z) { dma_memory_write(&address_space_memory, q->addr, buf, len); - if (PL330_ERR_DEBUG > 1) { - DB_PRINT("PL330 read from memory @%08" PRIx32 - " (size = %08x):\n", q->addr, len); - qemu_hexdump((char *)buf, stderr, "", len); + trace_pl330_exec_cycle(q->addr, len); + if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) { + pl330_hexdump(buf, len); } if (q->inc) { q->addr += len; @@ -1252,8 +1261,8 @@ static int pl330_exec_channel(PL330Chan *channel) static inline void pl330_exec(PL330State *s) { - DB_PRINT("\n"); int i, insr_exec; + trace_pl330_exec(); do { insr_exec = pl330_exec_channel(&s->manager); @@ -1298,7 +1307,7 @@ static void pl330_debug_exec(PL330State *s) args[2] = (s->dbg[1] >> 8) & 0xff; args[3] = (s->dbg[1] >> 16) & 0xff; args[4] = (s->dbg[1] >> 24) & 0xff; - DB_PRINT("chan id: %" PRIx8 "\n", chan_id); + trace_pl330_debug_exec(chan_id); if (s->dbg[0] & 1) { ch = &s->chan[chan_id]; } else { @@ -1320,6 +1329,7 @@ static void pl330_debug_exec(PL330State *s) ch->fault_type |= PL330_FAULT_DBG_INSTR; } if (ch->stall) { + trace_pl330_debug_exec_stall(); qemu_log_mask(LOG_UNIMP, "pl330: stall of debug instruction not " "implemented\n"); } @@ -1334,7 +1344,7 @@ static void pl330_iomem_write(void *opaque, hwaddr offset, PL330State *s = (PL330State *) opaque; int i; - DB_PRINT("addr: %08x data: %08x\n", (unsigned)offset, (unsigned)value); + trace_pl330_iomem_write((unsigned)offset, (unsigned)value); switch (offset) { case PL330_REG_INTEN: @@ -1343,7 +1353,7 @@ static void pl330_iomem_write(void *opaque, hwaddr offset, case PL330_REG_INTCLR: for (i = 0; i < s->num_events; i++) { if (s->int_status & s->inten & value & (1 << i)) { - DB_PRINT("event interrupt lowered %d\n", i); + trace_pl330_iomem_write_clr(i); qemu_irq_lower(s->irq[i]); } } @@ -1361,11 +1371,9 @@ static void pl330_iomem_write(void *opaque, hwaddr offset, } break; case PL330_REG_DBGINST0: - DB_PRINT("s->dbg[0] = %08x\n", (unsigned)value); s->dbg[0] = value; break; case PL330_REG_DBGINST1: - DB_PRINT("s->dbg[1] = %08x\n", (unsigned)value); s->dbg[1] = value; break; default: @@ -1489,7 +1497,7 @@ static uint64_t pl330_iomem_read(void *opaque, hwaddr offset, unsigned size) { uint32_t ret = pl330_iomem_read_imp(opaque, offset); - DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx32 "\n", offset, ret); + trace_pl330_iomem_read((uint32_t)offset, ret); return ret; } diff --git a/hw/dma/trace-events b/hw/dma/trace-events index e4498428c5..5902ac5969 100644 --- a/hw/dma/trace-events +++ b/hw/dma/trace-events @@ -20,3 +20,27 @@ sparc32_dma_enable_lower(void) "Lower DMA enable" # i8257.c i8257_unregistered_dma(int nchan, int dma_pos, int dma_len) "unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d" + +# pl330.c +pl330_fault(void *ptr, uint32_t flags) "ch: %p, flags: 0x%"PRIx32 +pl330_fault_abort(void) "abort interrupt raised" +pl330_dmaend(void) "DMA ending" +pl330_dmago(void) "DMA run" +pl330_dmald(uint32_t chan, uint32_t addr, uint32_t size, uint32_t num, uint32_t ch) "channel:%"PRId8" address:0x%08"PRIx32" size:0x%"PRIx32" num:%"PRId32"%c" +pl330_dmakill(void) "abort interrupt lowered" +pl330_dmalpend(uint8_t nf, uint8_t bs, uint8_t lc, uint8_t ch, uint8_t flag) "nf=0x%02x bs=0x%02x lc=0x%02x ch=0x%02x flag=0x%02x" +pl330_dmalpiter(void) "loop reiteration" +pl330_dmalpfallthrough(void) "loop fallthrough" +pl330_dmasev_evirq(uint8_t ev_id) "event interrupt raised %"PRId8 +pl330_dmasev_event(uint8_t ev_id) "event raised %"PRId8 +pl330_dmast(uint32_t chn, uint32_t addr, uint32_t sz, uint32_t num, uint32_t c) "channel:%"PRId8" address:0x%08"PRIx32" size:0x%"PRIx32" num:%"PRId32" %c" +pl330_dmawfe(uint8_t ev_id) "event lowered 0x%"PRIx8 +pl330_chan_exec_undef(void) "undefined instruction" +pl330_exec_cycle(uint32_t addr, uint32_t size) "PL330 read from memory @0x%08"PRIx32" (size = 0x%08"PRIx32")" +pl330_hexdump(uint32_t offset, char *str) " 0x%04"PRIx32":%s" +pl330_exec(void) "pl330_exec" +pl330_debug_exec(uint8_t ch) "chan id: 0x%"PRIx8 +pl330_debug_exec_stall(void) "stall of debug instruction not implemented" +pl330_iomem_write(uint32_t offset, uint32_t value) "addr: 0x%08"PRIx32" data: 0x%08"PRIx32 +pl330_iomem_write_clr(int i) "event interrupt lowered %d" +pl330_iomem_read(uint32_t addr, uint32_t data) "addr: 0x%08"PRIx32" data: 0x%08"PRIx32 From patchwork Sat Jan 18 16:42:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11340155 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EAD1517EA for ; Sat, 18 Jan 2020 16:44:34 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C11442469A for ; Sat, 18 Jan 2020 16:44:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qMFW3kHx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C11442469A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=roeck-us.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:42562 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrD7-0006qI-Eo for patchwork-qemu-devel@patchwork.kernel.org; Sat, 18 Jan 2020 11:44:33 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36130) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrBJ-00042t-M8 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1isrBI-0002Au-DB for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:41 -0500 Received: from mail-yb1-xb41.google.com ([2607:f8b0:4864:20::b41]:41572) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1isrBF-00026y-E8; Sat, 18 Jan 2020 11:42:37 -0500 Received: by mail-yb1-xb41.google.com with SMTP id z15so7674679ybm.8; Sat, 18 Jan 2020 08:42:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=ldTrGfmguJmXL3eSQF5uN0jHMmEr5R4Wn7Le7S6JTWM=; b=qMFW3kHxzSZO2JcAflvVutUH/zWG3/zXlSaqe2vtxpjsv2WR9FJN2+5F32EupBUUW6 r5rR4skqXurVzbiB8Jeql3Qf/Lgd2mecHldz9hgAfEqeYk2+m8eM0fM55pU0+wT8sSzu ZCPlYJt2QCFck9zvQeIG54xZBhV5q/Vi/nNSyWfBueKiBOByvXfpjPDmFVSByEWD8UJM tv6RL5GDvfMBUKstlKtCvlQYQ5BDwK3ZCU3MpMfu8+ezRvwMNq/jrVg5Yfj9aSQgrvtS k+HFILg9Me+7N7ePhC3uDeYqiqYytoRJJFXVx7wWLCkhI5MVtFCpkJiB5kKxAMGBX7pq cGZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=ldTrGfmguJmXL3eSQF5uN0jHMmEr5R4Wn7Le7S6JTWM=; b=JMjhgfbTjNOhDjC8eOkLXPhiktQTry18dFF3wSjjlTZgvAqwkQy0asLP+3DRdQ7CIq mAc6kD3k7JD18nJyh7CQhoEWLm/wsruRWmZ7BEbIZBWdED8ykagLR+mOM3st38gUVLpG ydGMSszFr1+/82EOxTHVRv3yMfWPrQNaRMZsCof2Ml9z/22uyJx2D0zJLL9cjuBh3Guf tRMdaTSpgVZe8pWgepkW4n4UTh9o8oogReDa16lDRGrBuHutCmfbBKMK9+rqgVhKMCD7 i1+OtMdjToeE2JxW6mbiZHgbUCktRoJdB5hX5D2djj4uBzUG1w0hbeeveBDM80/R1SQG XhlA== X-Gm-Message-State: APjAAAWw8uD1XtpmjOFO1aJpRccucbc47WHGqZMtW95sLI5NXqQ6dgwq AFKUk2r/prPAfAPv8yoZFqc= X-Google-Smtp-Source: APXvYqzb6pu0LagOQbWIGJ2oYkWpnfK/1EY9jvG2dWQSrAP5UqtSw1iuBvaIbVmz4gGIyH94uMiDFQ== X-Received: by 2002:a25:230d:: with SMTP id j13mr34605263ybj.22.1579365756861; Sat, 18 Jan 2020 08:42:36 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id l74sm13213723ywc.45.2020.01.18.08.42.36 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 18 Jan 2020 08:42:36 -0800 (PST) From: Guenter Roeck To: Peter Maydell Subject: [PATCH v2 2/7] hw/arm/exynos4210: Fix DMA initialization Date: Sat, 18 Jan 2020 08:42:24 -0800 Message-Id: <20200118164229.22539-3-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200118164229.22539-1-linux@roeck-us.net> References: <20200118164229.22539-1-linux@roeck-us.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::b41 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Igor Mitsyanko , Paolo Bonzini , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" First parameter to exynos4210_get_irq() is not the SPI port number, but the interrupt group number. Interrupt groups are 20 for mdma and 21 for pdma. Interrupts are not inverted. Controllers support 32 events (pdma) or 31 events (mdma). Events must all be routed to a single interrupt line. Set other parameters as documented in Exynos4210 datasheet, section 8 (DMA controller). Reduce the number of DMA events to 30 for both pdma and mdma. QEMU's OR interrupt gates are currently limited to less than 32, and we would need 33 gates to support 32 event interrupts plus the abort interrupt. Operationally this should not make a difference since they are all routed to a single interrupt line anyway. Fixes: 59520dc65e ("hw/arm/exynos4210: Add DMA support for the Exynos4210") Signed-off-by: Guenter Roeck Reviewed-by: Peter Maydell --- v2: Use interrupt combiner instead of connecting all events to a single interrupt. Limit number of events per DMA channel to 31 to meet qemu interrupt combiner limitations. [Not sure if "assert(s->num_lines < MAX_OR_LINES);" should be "assert(s->num_lines <= MAX_OR_LINES);"] Introduce exynos4210_init() to handle interrupt combiner initialization. hw/arm/exynos4210.c | 51 +++++++++++++++++++++++++++++++------ include/hw/arm/exynos4210.h | 4 +++ 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 77fbe1baab..91586fe265 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -166,17 +166,36 @@ static uint64_t exynos4210_calc_affinity(int cpu) return (0x9 << ARM_AFF1_SHIFT) | cpu; } -static void pl330_create(uint32_t base, qemu_irq irq, int nreq) +static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq, + int nreq, int nevents, int width) { SysBusDevice *busdev; DeviceState *dev; + int i; dev = qdev_create(NULL, "pl330"); + qdev_prop_set_uint8(dev, "num_events", nevents); + qdev_prop_set_uint8(dev, "num_chnls", 8); qdev_prop_set_uint8(dev, "num_periph_req", nreq); + + qdev_prop_set_uint8(dev, "wr_cap", 4); + qdev_prop_set_uint8(dev, "wr_q_dep", 8); + qdev_prop_set_uint8(dev, "rd_cap", 4); + qdev_prop_set_uint8(dev, "rd_q_dep", 8); + qdev_prop_set_uint8(dev, "data_width", width); + qdev_prop_set_uint16(dev, "data_buffer_dep", width); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, base); - sysbus_connect_irq(busdev, 0, irq); + + object_property_set_int(OBJECT(orgate), nevents + 1, "num-lines", + &error_abort); + object_property_set_bool(OBJECT(orgate), true, "realized", &error_abort); + + for (i = 0; i < nevents + 1; i++) { + sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i)); + } + qdev_connect_gpio_out(DEVICE(orgate), 0, irq); } static void exynos4210_realize(DeviceState *socdev, Error **errp) @@ -431,12 +450,27 @@ static void exynos4210_realize(DeviceState *socdev, Error **errp) s->irq_table[exynos4210_get_irq(28, 3)]); /*** DMA controllers ***/ - pl330_create(EXYNOS4210_PL330_BASE0_ADDR, - qemu_irq_invert(s->irq_table[exynos4210_get_irq(35, 1)]), 32); - pl330_create(EXYNOS4210_PL330_BASE1_ADDR, - qemu_irq_invert(s->irq_table[exynos4210_get_irq(36, 1)]), 32); - pl330_create(EXYNOS4210_PL330_BASE2_ADDR, - qemu_irq_invert(s->irq_table[exynos4210_get_irq(34, 1)]), 1); + pl330_create(EXYNOS4210_PL330_BASE0_ADDR, &s->pl330_irq_orgate[0], + s->irq_table[exynos4210_get_irq(21, 0)], 32, 30, 32); + pl330_create(EXYNOS4210_PL330_BASE1_ADDR, &s->pl330_irq_orgate[1], + s->irq_table[exynos4210_get_irq(21, 1)], 32, 30, 32); + pl330_create(EXYNOS4210_PL330_BASE2_ADDR, &s->pl330_irq_orgate[2], + s->irq_table[exynos4210_get_irq(20, 1)], 1, 30, 64); +} + +static void exynos4210_init(Object *obj) +{ + Exynos4210State *s = EXYNOS4210_SOC(obj); + int i; + + for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) { + char *name = g_strdup_printf("pl330-irq-orgate%d", i); + qemu_or_irq *orgate = &s->pl330_irq_orgate[i]; + + object_initialize_child(obj, name, orgate, sizeof(*orgate), + TYPE_OR_IRQ, &error_abort, NULL); + g_free(name); + } } static void exynos4210_class_init(ObjectClass *klass, void *data) @@ -450,6 +484,7 @@ static const TypeInfo exynos4210_info = { .name = TYPE_EXYNOS4210_SOC, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Exynos4210State), + .instance_init = exynos4210_init, .class_init = exynos4210_class_init, }; diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index f0f23b0e9b..55260394af 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -24,6 +24,7 @@ #ifndef EXYNOS4210_H #define EXYNOS4210_H +#include "hw/or-irq.h" #include "hw/sysbus.h" #include "target/arm/cpu-qom.h" @@ -74,6 +75,8 @@ #define EXYNOS4210_I2C_NUMBER 9 +#define EXYNOS4210_NUM_DMA 3 + typedef struct Exynos4210Irq { qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ]; qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ]; @@ -97,6 +100,7 @@ typedef struct Exynos4210State { MemoryRegion boot_secondary; MemoryRegion bootreg_mem; I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER]; + qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA]; } Exynos4210State; #define TYPE_EXYNOS4210_SOC "exynos4210" From patchwork Sat Jan 18 16:42:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11340159 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 026F117EA for ; Sat, 18 Jan 2020 16:47:27 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B38832469A for ; Sat, 18 Jan 2020 16:47:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="sFW2aYdU" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B38832469A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=roeck-us.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:42630 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrFt-0002aw-4z for patchwork-qemu-devel@patchwork.kernel.org; Sat, 18 Jan 2020 11:47:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36171) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrBM-00047N-C9 for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1isrBK-0002CP-LF for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:44 -0500 Received: from mail-yb1-xb44.google.com ([2607:f8b0:4864:20::b44]:42605) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1isrBH-00029f-5K; Sat, 18 Jan 2020 11:42:39 -0500 Received: by mail-yb1-xb44.google.com with SMTP id c8so7090633ybk.9; Sat, 18 Jan 2020 08:42:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=39fHTiyX/0J89e65TbMGqFwEY3KsN+AI+pGbkAukXfQ=; b=sFW2aYdUhMxuwFY398GTHxnAGKRiloK0WdK7yhT1Ud4dvdX0MkA3K5aQ3zpd4DxBip lXadXpH50VRKPmkXU3W8xCyqtOAfi8j2PzEfYqXBNE8c8igc8OivYIiNQdiV7XKn0yzG c1vbROh662Yncu5w1mGAOS4Ft/X+NrSXTuFdgscNLPyqJVlJIHN1BJXVylaOqcMnhx03 MymKSlcqIB7yV8Bn3q0QMZFDAWnppnJ/I6J7PucZ8QoH0MiKvmV2gUvS5jheflmCmPOw qb1LFGbWNDgIwLVERBly0ITYJjRHh85tSZgF6QsO4NouK3TAhkWQiZwBKQQhe3LhRSdA 2Vzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=39fHTiyX/0J89e65TbMGqFwEY3KsN+AI+pGbkAukXfQ=; b=LUOFcdunGT+xMoLV+V7Lh8oOv7umZb9ggCGkaOB4VPjKNNsAqpOmtW/oQOofrrW7Tx 7VFpf6qb5yfBpMAs8o2TQbtLQpsgVlF4LKoJExic73d8pyvhQ2FNBQlbIEkuuXKrNhJw M8AbN9AkBS9V8gC4BNhncNs9LjrYiQ93NFjHTpOgXOenU+Q7mhpFRblJgQULYn5bMkgj Gg06XIte1E4HcEwb762xFu82NvbWGRXJzCruCQvDNDn06vAs681ZP2fkSblMwWTYxU15 yl0CtXmbVwkoIxZ2LAML/1QSCqNw9yDMSqJiMdGlC8IerqUkFUnyW66OzURAyIUv/MXQ 1kjA== X-Gm-Message-State: APjAAAVdjV2K1sSWopSCji9Bn5XgghKIUqGR1ERYFlGG70sU6Idj7ESK nQTqGKuNHsgkLIg4yEdGLgk= X-Google-Smtp-Source: APXvYqxP038PvuV1FLgf/qJe3xkAHSlpiyuDb5dwsngIMudoi82SBETawDlLBkEq08kSt6lWIW9Rvw== X-Received: by 2002:a25:c5d1:: with SMTP id v200mr32497273ybe.450.1579365758481; Sat, 18 Jan 2020 08:42:38 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id g190sm12790274ywf.41.2020.01.18.08.42.37 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 18 Jan 2020 08:42:38 -0800 (PST) From: Guenter Roeck To: Peter Maydell Subject: [PATCH v2 3/7] hw/char/exynos4210_uart: Convert to support tracing Date: Sat, 18 Jan 2020 08:42:25 -0800 Message-Id: <20200118164229.22539-4-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200118164229.22539-1-linux@roeck-us.net> References: <20200118164229.22539-1-linux@roeck-us.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::b44 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Igor Mitsyanko , Paolo Bonzini , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Replace debug code with tracing to aid debugging. Reviewed-by: Peter Maydell Signed-off-by: Guenter Roeck --- v2: Added Reviewed-by: tag hw/char/exynos4210_uart.c | 96 ++++++++++++--------------------------- hw/char/trace-events | 17 +++++++ 2 files changed, 47 insertions(+), 66 deletions(-) diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index d6b6b62366..fb7a3ebd09 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -31,45 +31,7 @@ #include "hw/irq.h" #include "hw/qdev-properties.h" -#undef DEBUG_UART -#undef DEBUG_UART_EXTEND -#undef DEBUG_IRQ -#undef DEBUG_Rx_DATA -#undef DEBUG_Tx_DATA - -#define DEBUG_UART 0 -#define DEBUG_UART_EXTEND 0 -#define DEBUG_IRQ 0 -#define DEBUG_Rx_DATA 0 -#define DEBUG_Tx_DATA 0 - -#if DEBUG_UART -#define PRINT_DEBUG(fmt, args...) \ - do { \ - fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \ - } while (0) - -#if DEBUG_UART_EXTEND -#define PRINT_DEBUG_EXTEND(fmt, args...) \ - do { \ - fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \ - } while (0) -#else -#define PRINT_DEBUG_EXTEND(fmt, args...) \ - do {} while (0) -#endif /* EXTEND */ - -#else -#define PRINT_DEBUG(fmt, args...) \ - do {} while (0) -#define PRINT_DEBUG_EXTEND(fmt, args...) \ - do {} while (0) -#endif - -#define PRINT_ERROR(fmt, args...) \ - do { \ - fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \ - } while (0) +#include "trace.h" /* * Offsets for UART registers relative to SFR base address @@ -193,8 +155,7 @@ typedef struct Exynos4210UartState { } Exynos4210UartState; -#if DEBUG_UART -/* Used only for debugging inside PRINT_DEBUG_... macros */ +/* Used only for tracing */ static const char *exynos4210_uart_regname(hwaddr offset) { @@ -208,7 +169,6 @@ static const char *exynos4210_uart_regname(hwaddr offset) return NULL; } -#endif static void fifo_store(Exynos4210UartFIFO *q, uint8_t ch) @@ -271,7 +231,7 @@ static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState break; default: level = 0; - PRINT_ERROR("Wrong UART channel number: %d\n", s->channel); + trace_exynos_uart_channel_error(s->channel); } return level; @@ -297,14 +257,10 @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s) if (s->reg[I_(UINTP)]) { qemu_irq_raise(s->irq); - -#if DEBUG_IRQ - fprintf(stderr, "UART%d: IRQ has been raised: %08x\n", - s->channel, s->reg[I_(UINTP)]); -#endif - + trace_exynos_uart_irq_raised(s->channel, s->reg[I_(UINTP)]); } else { qemu_irq_lower(s->irq); + trace_exynos_uart_irq_lowered(s->channel); } } @@ -348,7 +304,7 @@ static void exynos4210_uart_update_parameters(Exynos4210UartState *s) qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); - PRINT_DEBUG("UART%d: speed: %d, parity: %c, data: %d, stop: %d\n", + trace_exynos_uart_update_params( s->channel, speed, parity, data_bits, stop_bits); } @@ -358,8 +314,8 @@ static void exynos4210_uart_write(void *opaque, hwaddr offset, Exynos4210UartState *s = (Exynos4210UartState *)opaque; uint8_t ch; - PRINT_DEBUG_EXTEND("UART%d: <0x%04x> %s <- 0x%08llx\n", s->channel, - offset, exynos4210_uart_regname(offset), (long long unsigned int)val); + trace_exynos_uart_write(s->channel, offset, + exynos4210_uart_regname(offset), val); switch (offset) { case ULCON: @@ -373,12 +329,12 @@ static void exynos4210_uart_write(void *opaque, hwaddr offset, if (val & UFCON_Rx_FIFO_RESET) { fifo_reset(&s->rx); s->reg[I_(UFCON)] &= ~UFCON_Rx_FIFO_RESET; - PRINT_DEBUG("UART%d: Rx FIFO Reset\n", s->channel); + trace_exynos_uart_rx_fifo_reset(s->channel); } if (val & UFCON_Tx_FIFO_RESET) { fifo_reset(&s->tx); s->reg[I_(UFCON)] &= ~UFCON_Tx_FIFO_RESET; - PRINT_DEBUG("UART%d: Tx FIFO Reset\n", s->channel); + trace_exynos_uart_tx_fifo_reset(s->channel); } break; @@ -390,9 +346,7 @@ static void exynos4210_uart_write(void *opaque, hwaddr offset, /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ qemu_chr_fe_write_all(&s->chr, &ch, 1); -#if DEBUG_Tx_DATA - fprintf(stderr, "%c", ch); -#endif + trace_exynos_uart_tx(s->channel, ch); s->reg[I_(UTRSTAT)] |= UTRSTAT_TRANSMITTER_EMPTY | UTRSTAT_Tx_BUFFER_EMPTY; s->reg[I_(UINTSP)] |= UINTSP_TXD; @@ -403,8 +357,7 @@ static void exynos4210_uart_write(void *opaque, hwaddr offset, case UINTP: s->reg[I_(UINTP)] &= ~val; s->reg[I_(UINTSP)] &= ~val; - PRINT_DEBUG("UART%d: UINTP [%04x] have been cleared: %08x\n", - s->channel, offset, s->reg[I_(UINTP)]); + trace_exynos_uart_intclr(s->channel, s->reg[I_(UINTP)]); exynos4210_uart_update_irq(s); break; case UTRSTAT: @@ -412,7 +365,7 @@ static void exynos4210_uart_write(void *opaque, hwaddr offset, case UFSTAT: case UMSTAT: case URXH: - PRINT_DEBUG("UART%d: Trying to write into RO register: %s [%04x]\n", + trace_exynos_uart_ro_write( s->channel, exynos4210_uart_regname(offset), offset); break; case UINTSP: @@ -439,6 +392,8 @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset, case UERSTAT: /* Read Only */ res = s->reg[I_(UERSTAT)]; s->reg[I_(UERSTAT)] = 0; + trace_exynos_uart_read(s->channel, offset, + exynos4210_uart_regname(offset), res); return res; case UFSTAT: /* Read Only */ s->reg[I_(UFSTAT)] = fifo_elements_number(&s->rx) & 0xff; @@ -446,20 +401,22 @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset, s->reg[I_(UFSTAT)] |= UFSTAT_Rx_FIFO_FULL; s->reg[I_(UFSTAT)] &= ~0xff; } + trace_exynos_uart_read(s->channel, offset, + exynos4210_uart_regname(offset), + s->reg[I_(UFSTAT)]); return s->reg[I_(UFSTAT)]; case URXH: if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) { if (fifo_elements_number(&s->rx)) { res = fifo_retrieve(&s->rx); -#if DEBUG_Rx_DATA - fprintf(stderr, "%c", res); -#endif + trace_exynos_uart_rx(s->channel, res); if (!fifo_elements_number(&s->rx)) { s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY; } else { s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY; } } else { + trace_exynos_uart_rx_error(s->channel); s->reg[I_(UINTSP)] |= UINTSP_ERROR; exynos4210_uart_update_irq(s); res = 0; @@ -468,15 +425,22 @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset, s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY; res = s->reg[I_(URXH)]; } + trace_exynos_uart_read(s->channel, offset, + exynos4210_uart_regname(offset), res); return res; case UTXH: - PRINT_DEBUG("UART%d: Trying to read from WO register: %s [%04x]\n", - s->channel, exynos4210_uart_regname(offset), offset); + trace_exynos_uart_wo_read(s->channel, exynos4210_uart_regname(offset), + offset); break; default: + trace_exynos_uart_read(s->channel, offset, + exynos4210_uart_regname(offset), + s->reg[I_(offset)]); return s->reg[I_(offset)]; } + trace_exynos_uart_read(s->channel, offset, exynos4210_uart_regname(offset), + 0); return 0; } @@ -555,7 +519,7 @@ static void exynos4210_uart_reset(DeviceState *dev) fifo_reset(&s->rx); fifo_reset(&s->tx); - PRINT_DEBUG("UART%d: Rx FIFO size: %d\n", s->channel, s->rx.size); + trace_exynos_uart_rxsize(s->channel, s->rx.size); } static const VMStateDescription vmstate_exynos4210_uart_fifo = { diff --git a/hw/char/trace-events b/hw/char/trace-events index 2ce7f2f998..ba28b45b53 100644 --- a/hw/char/trace-events +++ b/hw/char/trace-events @@ -77,3 +77,20 @@ cmsdk_apb_uart_set_params(int speed) "CMSDK APB UART: params set to %d 8N1" # nrf51_uart.c nrf51_uart_read(uint64_t addr, uint64_t r, unsigned int size) "addr 0x%" PRIx64 " value 0x%" PRIx64 " size %u" nrf51_uart_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%" PRIx64 " value 0x%" PRIx64 " size %u" + +# exynos4210_uart.c +exynos_uart_irq_raised(uint32_t channel, uint32_t reg) "UART%d: IRQ raised: 0x%08"PRIx32 +exynos_uart_irq_lowered(uint32_t channel) "UART%d: IRQ lowered" +exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d" +exynos_uart_write(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s <- 0x%" PRIx64 +exynos_uart_read(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s -> 0x%" PRIx64 +exynos_uart_rx_fifo_reset(uint32_t channel) "UART%d: Rx FIFO Reset" +exynos_uart_tx_fifo_reset(uint32_t channel) "UART%d: Tx FIFO Reset" +exynos_uart_tx(uint32_t channel, uint8_t ch) "UART%d: Tx 0x%02"PRIx32 +exynos_uart_intclr(uint32_t channel, uint32_t reg) "UART%d: interrupts cleared: 0x%08"PRIx32 +exynos_uart_ro_write(uint32_t channel, const char *name, uint32_t reg) "UART%d: Trying to write into RO register: %s [0x%04"PRIx32"]" +exynos_uart_rx(uint32_t channel, uint8_t ch) "UART%d: Rx 0x%02"PRIx32 +exynos_uart_rx_error(uint32_t channel) "UART%d: Rx error" +exynos_uart_wo_read(uint32_t channel, const char *name, uint32_t reg) "UART%d: Trying to read from WO register: %s [0x%04"PRIx32"]" +exynos_uart_rxsize(uint32_t channel, uint32_t size) "UART%d: Rx FIFO size: %d" +exynos_uart_channel_error(uint32_t channel) "Wrong UART channel number: %d" From patchwork Sat Jan 18 16:42:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11340153 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9F05917EA for ; Sat, 18 Jan 2020 16:44:12 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 75ED62469A for ; Sat, 18 Jan 2020 16:44:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="uPz//ZtF" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 75ED62469A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=roeck-us.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:42560 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrCl-0006Mi-3B for patchwork-qemu-devel@patchwork.kernel.org; Sat, 18 Jan 2020 11:44:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36160) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrBL-00046W-OL for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:44 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1isrBK-0002CU-LQ for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:43 -0500 Received: from mail-yb1-xb41.google.com ([2607:f8b0:4864:20::b41]:40115) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1isrBI-0002Ao-HV; Sat, 18 Jan 2020 11:42:40 -0500 Received: by mail-yb1-xb41.google.com with SMTP id l197so6015446ybf.7; Sat, 18 Jan 2020 08:42:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=vU+VqIHGN1BijkfK3vPdPlxjr39cqTq4olg29px/6oo=; b=uPz//ZtFoeXIRURh/9ksxf+hkfCDupjqzy4v7RMYejungSB8UGniLRo0oUwKrbhS1o yVZL+p2z32a/UtiggylKrVWXE4Z01CVCFPvi5ww4nailqxfRUH5enIzXWvkLyIkwsja3 69zS4IdOpzygUEuLtiQGGvmHvON8ovi6SplW0/ZY9tO02oji32TBBkXXL7qc/RiauLdP /QKKwTBoW8+Ln+ohvsbfoBYCz3EsZaQf5q2PzEei4WOReaPcGMVl2v9kMBKRs9v7Hl2Y xX9mqGJVaZIbyJt/7OG0MnpZohvfYaCKBtRKIkjDTVpFJNwOwR61p1p9dSeQCJ86+2wX 5xpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=vU+VqIHGN1BijkfK3vPdPlxjr39cqTq4olg29px/6oo=; b=XlcYGjs+351/PhjLztbrBYNd3gonKLMd/dNRkjtqafLAYDW4IygVXUM4eEL2WDCD88 xeRt1ryItsR4NDXvB8531hm+J0XRnnqLeFwByvYRn4WH2KrAlRPVcN8qniGv/IEoVDon e1IqS1ycS8smSdNBSIE+GUFaskE2+TRB/wy8/8uPlF4duln52UN4ql4bvOuG1tArhMPw hBPgPQncg0TeC3cx8oTD1du8xXmVIRKiju8OLxX+/qpOP4mVU8HClIALsHOGRqVN7FZK NlZKTCIUrQ52uxcP9Y4jEgUF+yxXvSqVTG6t9EsJekMcbhLaYugtLbNJoWAgLjSahcNZ pWjw== X-Gm-Message-State: APjAAAXBupivMl9WV/vn3NYPHeSpOHKeb5Lc0I7GY9bkli208G39CTaT NtGx7CpOdjMUo4GXk+ZKjlE= X-Google-Smtp-Source: APXvYqxuI8jlZ/9JfRavArGuLtrk2ZcU5phOrvHEE3ldyyRLCqEPGjYFlmx86VZnUZcF/ptz2kkURg== X-Received: by 2002:a25:5944:: with SMTP id n65mr5248639ybb.291.1579365760077; Sat, 18 Jan 2020 08:42:40 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id a128sm13431651ywh.60.2020.01.18.08.42.39 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 18 Jan 2020 08:42:39 -0800 (PST) From: Guenter Roeck To: Peter Maydell Subject: [PATCH v2 4/7] hw/char/exynos4210_uart: Implement post_load function Date: Sat, 18 Jan 2020 08:42:26 -0800 Message-Id: <20200118164229.22539-5-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200118164229.22539-1-linux@roeck-us.net> References: <20200118164229.22539-1-linux@roeck-us.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::b41 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Igor Mitsyanko , Paolo Bonzini , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" After restoring a VM, serial parameters need to be updated to reflect restored register values. Implement a post_load function to handle this situation. Signed-off-by: Guenter Roeck Reviewed-by: Peter Maydell --- v4: Additional patch to implement post-load functionality in exynos uart driver. Required for next patch in series. hw/char/exynos4210_uart.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index fb7a3ebd09..5d48701b6d 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -522,10 +522,20 @@ static void exynos4210_uart_reset(DeviceState *dev) trace_exynos_uart_rxsize(s->channel, s->rx.size); } +static int exynos4210_uart_post_load(void *opaque, int version_id) +{ + Exynos4210UartState *s = (Exynos4210UartState *)opaque; + + exynos4210_uart_update_parameters(s); + + return 0; +} + static const VMStateDescription vmstate_exynos4210_uart_fifo = { .name = "exynos4210.uart.fifo", .version_id = 1, .minimum_version_id = 1, + .post_load = exynos4210_uart_post_load, .fields = (VMStateField[]) { VMSTATE_UINT32(sp, Exynos4210UartFIFO), VMSTATE_UINT32(rp, Exynos4210UartFIFO), From patchwork Sat Jan 18 16:42:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11340163 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3C9A817EA for ; Sat, 18 Jan 2020 16:50:35 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id ED8B72469A for ; Sat, 18 Jan 2020 16:50:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ca4FcaZb" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org ED8B72469A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=roeck-us.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:42682 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrIv-0005v1-Rs for patchwork-qemu-devel@patchwork.kernel.org; Sat, 18 Jan 2020 11:50:33 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36215) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrBQ-0004Dl-1X for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1isrBO-0002F3-7r for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:47 -0500 Received: from mail-yw1-xc44.google.com ([2607:f8b0:4864:20::c44]:36335) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1isrBK-0002C9-Hg; Sat, 18 Jan 2020 11:42:42 -0500 Received: by mail-yw1-xc44.google.com with SMTP id n184so15871828ywc.3; Sat, 18 Jan 2020 08:42:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=td1yGNfjfUpZYYkn6uLD6QjKcoSaUeLpRJm2pQ2sVF0=; b=ca4FcaZb5GX65G3hmHJPY1QlbOvNrOHwT1dnJqlXa/LF3/ovvLiY3yAJOPZVZok7EI pKirS/6AdRtlrQTtttckovGbhDz0qwOkK3QnVsqZ0Ut40HaAvAPxrqs2G/BfDaj4SP2z toc7hFXuPVgOSuMEAfdkSkI1H1Iv6Jg8Xn/ywGbAji53kYLQD+nSFQx80ztA+2+wYpRQ zYCou7+NC1I4avbhzrk8oo8GQ9c+OaKOhwJtktUMvNL7PsroLmaRM0ZQHWKjT032TvfE Ra5LFkURtfFhT4X53jmNgsqiodixrRbA4COuyo/pvIb8g+fwTkrG6BU4YFl9us0YtPbx J65w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=td1yGNfjfUpZYYkn6uLD6QjKcoSaUeLpRJm2pQ2sVF0=; b=FDFrxvwd82F6F7NsU15fM6Kbb4BmB7n+wAM7VGrIPvcO3jjxFjRm4PYFvHWu2wwoEr ApP4C1vJaSdByXuwjIHC5HW2RvxI0YyE9R4wyWzqXh93M4SUt0mGcCYggzk4QCaobpLk qIMi1KQJyaOy1xjmFWou53KQNfZGcyQ6H/pAn8h4gaclJ8PN/Uy10r70HK3ArllkfQEb 628f/An8Yj4NfSp3tPsHd/YsnvBGO5diTaHhK4I1DiER5aIQA2gJNCQTiKMmuudnK/qZ uavrYtjJJDdcmWDSIcjBrQo06I7/fK7KYBrZ9DhhDBqDy184GQ+tE5062fczDlTdhYMA FuOA== X-Gm-Message-State: APjAAAXCYCGaPDbGWraylawUMOiOsFpbPuh1yRlcOIEiANyp07mM29mQ SeHQhWpv8OpLGB2/XEJ01ek= X-Google-Smtp-Source: APXvYqxzT2iCBuP8bEXAyyy8Lg49yR1L2KxIPOS1WIxgvWDJv08BLC+Qag6pY81Dg4gKTUFzisDyZw== X-Received: by 2002:a0d:f106:: with SMTP id a6mr29070376ywf.318.1579365761873; Sat, 18 Jan 2020 08:42:41 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id h203sm12623797ywb.98.2020.01.18.08.42.41 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 18 Jan 2020 08:42:41 -0800 (PST) From: Guenter Roeck To: Peter Maydell Subject: [PATCH v2 5/7] hw/char/exynos4210_uart: Implement Rx FIFO level triggers and timeouts Date: Sat, 18 Jan 2020 08:42:27 -0800 Message-Id: <20200118164229.22539-6-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200118164229.22539-1-linux@roeck-us.net> References: <20200118164229.22539-1-linux@roeck-us.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c44 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Igor Mitsyanko , Paolo Bonzini , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" The driver already implements a receive FIFO, but it does not handle receive FIFO trigger levels and timeout. Implement the missing functionality. Signed-off-by: Guenter Roeck --- v2: Call exynos4210_uart_rx_timeout_set() from new post_load function to set the receive timeout timer. Add timer to vmstate_exynos4210_uart. hw/char/exynos4210_uart.c | 122 ++++++++++++++++++++++++++++++-------- hw/char/trace-events | 3 +- 2 files changed, 99 insertions(+), 26 deletions(-) diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index 5d48701b6d..63ea9663f2 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -24,6 +24,7 @@ #include "migration/vmstate.h" #include "qemu/error-report.h" #include "qemu/module.h" +#include "qemu/timer.h" #include "chardev/char-fe.h" #include "chardev/char-serial.h" @@ -118,6 +119,7 @@ static const Exynos4210UartReg exynos4210_uart_regs[] = { #define ULCON_STOP_BIT_SHIFT 1 /* UART Tx/Rx Status */ +#define UTRSTAT_Rx_TIMEOUT 0x8 #define UTRSTAT_TRANSMITTER_EMPTY 0x4 #define UTRSTAT_Tx_BUFFER_EMPTY 0x2 #define UTRSTAT_Rx_BUFFER_DATA_READY 0x1 @@ -147,6 +149,9 @@ typedef struct Exynos4210UartState { Exynos4210UartFIFO rx; Exynos4210UartFIFO tx; + QEMUTimer *fifo_timeout_timer; + uint64_t wordtime; /* word time in ns */ + CharBackend chr; qemu_irq irq; @@ -209,15 +214,12 @@ static void fifo_reset(Exynos4210UartFIFO *q) q->rp = 0; } -static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState *s) +static uint32_t exynos4210_uart_FIFO_trigger_level(uint32_t channel, + uint32_t reg) { - uint32_t level = 0; - uint32_t reg; + uint32_t level; - reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >> - UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT; - - switch (s->channel) { + switch (channel) { case 0: level = reg * 32; break; @@ -231,12 +233,34 @@ static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState break; default: level = 0; - trace_exynos_uart_channel_error(s->channel); + trace_exynos_uart_channel_error(channel); + break; } - return level; } +static uint32_t +exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState *s) +{ + uint32_t reg; + + reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >> + UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT; + + return exynos4210_uart_FIFO_trigger_level(s->channel, reg); +} + +static uint32_t +exynos4210_uart_Rx_FIFO_trigger_level(const Exynos4210UartState *s) +{ + uint32_t reg; + + reg = ((s->reg[I_(UFCON)] & UFCON_Rx_FIFO_TRIGGER_LEVEL) >> + UFCON_Rx_FIFO_TRIGGER_LEVEL_SHIFT) + 1; + + return exynos4210_uart_FIFO_trigger_level(s->channel, reg); +} + static void exynos4210_uart_update_irq(Exynos4210UartState *s) { /* @@ -244,13 +268,25 @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s) * transmit FIFO is smaller than the trigger level. */ if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) { - uint32_t count = (s->reg[I_(UFSTAT)] & UFSTAT_Tx_FIFO_COUNT) >> UFSTAT_Tx_FIFO_COUNT_SHIFT; if (count <= exynos4210_uart_Tx_FIFO_trigger_level(s)) { s->reg[I_(UINTSP)] |= UINTSP_TXD; } + + /* + * Rx interrupt if trigger level is reached or if rx timeout + * interrupt is disabled and there is data in the receive buffer + */ + count = fifo_elements_number(&s->rx); + if ((count && !(s->reg[I_(UCON)] & 0x80)) || + count >= exynos4210_uart_Rx_FIFO_trigger_level(s)) { + s->reg[I_(UINTSP)] |= UINTSP_RXD; + timer_del(s->fifo_timeout_timer); + } + } else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) { + s->reg[I_(UINTSP)] |= UINTSP_RXD; } s->reg[I_(UINTP)] = s->reg[I_(UINTSP)] & ~s->reg[I_(UINTM)]; @@ -264,6 +300,21 @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s) } } +static void exynos4210_uart_timeout_int(void *opaque) +{ + Exynos4210UartState *s = opaque; + + trace_exynos_uart_rx_timeout(s->channel, s->reg[I_(UTRSTAT)], + s->reg[I_(UINTSP)]); + + if ((s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) || + (s->reg[I_(UCON)] & (1 << 11))) { + s->reg[I_(UINTSP)] |= UINTSP_RXD; + s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT; + exynos4210_uart_update_irq(s); + } +} + static void exynos4210_uart_update_parameters(Exynos4210UartState *s) { int speed, parity, data_bits, stop_bits; @@ -302,10 +353,24 @@ static void exynos4210_uart_update_parameters(Exynos4210UartState *s) ssp.data_bits = data_bits; ssp.stop_bits = stop_bits; + s->wordtime = NANOSECONDS_PER_SECOND * (data_bits + stop_bits + 1) / speed; + qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); trace_exynos_uart_update_params( - s->channel, speed, parity, data_bits, stop_bits); + s->channel, speed, parity, data_bits, stop_bits, s->wordtime); +} + +static void exynos4210_uart_rx_timeout_set(Exynos4210UartState *s) +{ + if (s->reg[I_(UCON)] & 0x80) { + uint32_t timeout = ((s->reg[I_(UCON)] >> 12) & 0x0f) * s->wordtime; + + timer_mod(s->fifo_timeout_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout); + } else { + timer_del(s->fifo_timeout_timer); + } } static void exynos4210_uart_write(void *opaque, hwaddr offset, @@ -361,6 +426,10 @@ static void exynos4210_uart_write(void *opaque, hwaddr offset, exynos4210_uart_update_irq(s); break; case UTRSTAT: + if (val & UTRSTAT_Rx_TIMEOUT) { + s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_TIMEOUT; + } + break; case UERSTAT: case UFSTAT: case UMSTAT: @@ -376,12 +445,17 @@ static void exynos4210_uart_write(void *opaque, hwaddr offset, exynos4210_uart_update_irq(s); break; case UCON: + s->reg[I_(UCON)] = val; + exynos4210_uart_rx_timeout_set(s); + exynos4210_uart_update_irq(s); + break; case UMCON: default: s->reg[I_(offset)] = val; break; } } + static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset, unsigned size) { @@ -461,7 +535,6 @@ static int exynos4210_uart_can_receive(void *opaque) return fifo_empty_elements_number(&s->rx); } - static void exynos4210_uart_receive(void *opaque, const uint8_t *buf, int size) { Exynos4210UartState *s = (Exynos4210UartState *)opaque; @@ -469,24 +542,17 @@ static void exynos4210_uart_receive(void *opaque, const uint8_t *buf, int size) if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) { if (fifo_empty_elements_number(&s->rx) < size) { - for (i = 0; i < fifo_empty_elements_number(&s->rx); i++) { - fifo_store(&s->rx, buf[i]); - } + size = fifo_empty_elements_number(&s->rx); s->reg[I_(UINTSP)] |= UINTSP_ERROR; - s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY; - } else { - for (i = 0; i < size; i++) { - fifo_store(&s->rx, buf[i]); - } - s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY; } - /* XXX: Around here we maybe should check Rx trigger level */ - s->reg[I_(UINTSP)] |= UINTSP_RXD; + for (i = 0; i < size; i++) { + fifo_store(&s->rx, buf[i]); + } + exynos4210_uart_rx_timeout_set(s); } else { s->reg[I_(URXH)] = buf[0]; - s->reg[I_(UINTSP)] |= UINTSP_RXD; - s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY; } + s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY; exynos4210_uart_update_irq(s); } @@ -527,6 +593,7 @@ static int exynos4210_uart_post_load(void *opaque, int version_id) Exynos4210UartState *s = (Exynos4210UartState *)opaque; exynos4210_uart_update_parameters(s); + exynos4210_uart_rx_timeout_set(s); return 0; } @@ -553,6 +620,7 @@ static const VMStateDescription vmstate_exynos4210_uart = { vmstate_exynos4210_uart_fifo, Exynos4210UartFIFO), VMSTATE_UINT32_ARRAY(reg, Exynos4210UartState, EXYNOS4210_UART_REGS_MEM_SIZE / sizeof(uint32_t)), + VMSTATE_TIMER_PTR(fifo_timeout_timer, Exynos4210UartState), VMSTATE_END_OF_LIST() } }; @@ -588,6 +656,10 @@ static void exynos4210_uart_init(Object *obj) SysBusDevice *dev = SYS_BUS_DEVICE(obj); Exynos4210UartState *s = EXYNOS4210_UART(dev); + s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + exynos4210_uart_timeout_int, s); + s->wordtime = NANOSECONDS_PER_SECOND * 10 / 9600; + /* memory mapping */ memory_region_init_io(&s->iomem, obj, &exynos4210_uart_ops, s, "exynos4210.uart", EXYNOS4210_UART_REGS_MEM_SIZE); diff --git a/hw/char/trace-events b/hw/char/trace-events index ba28b45b53..cb73fee6a9 100644 --- a/hw/char/trace-events +++ b/hw/char/trace-events @@ -81,7 +81,7 @@ nrf51_uart_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%" PR # exynos4210_uart.c exynos_uart_irq_raised(uint32_t channel, uint32_t reg) "UART%d: IRQ raised: 0x%08"PRIx32 exynos_uart_irq_lowered(uint32_t channel) "UART%d: IRQ lowered" -exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d" +exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop, uint64_t wordtime) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d wordtime: %"PRId64"ns" exynos_uart_write(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s <- 0x%" PRIx64 exynos_uart_read(uint32_t channel, uint32_t offset, const char *name, uint64_t val) "UART%d: <0x%04x> %s -> 0x%" PRIx64 exynos_uart_rx_fifo_reset(uint32_t channel) "UART%d: Rx FIFO Reset" @@ -94,3 +94,4 @@ exynos_uart_rx_error(uint32_t channel) "UART%d: Rx error" exynos_uart_wo_read(uint32_t channel, const char *name, uint32_t reg) "UART%d: Trying to read from WO register: %s [0x%04"PRIx32"]" exynos_uart_rxsize(uint32_t channel, uint32_t size) "UART%d: Rx FIFO size: %d" exynos_uart_channel_error(uint32_t channel) "Wrong UART channel number: %d" +exynos_uart_rx_timeout(uint32_t channel, uint32_t stat, uint32_t intsp) "UART%d: Rx timeout stat=0x%x intsp=0x%x" From patchwork Sat Jan 18 16:42:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11340161 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 076F613BD for ; Sat, 18 Jan 2020 16:47:30 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D29A22469A for ; Sat, 18 Jan 2020 16:47:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ph+JP6lA" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D29A22469A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=roeck-us.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:42632 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrFw-0002fW-Lg for patchwork-qemu-devel@patchwork.kernel.org; Sat, 18 Jan 2020 11:47:28 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36219) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrBQ-0004E4-6X for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1isrBO-0002FS-Nd for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:48 -0500 Received: from mail-yw1-xc41.google.com ([2607:f8b0:4864:20::c41]:46325) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1isrBM-0002DL-5i; Sat, 18 Jan 2020 11:42:44 -0500 Received: by mail-yw1-xc41.google.com with SMTP id u139so15847854ywf.13; Sat, 18 Jan 2020 08:42:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=tRwDVw1z7dnvwBqcQOZ2x3vMeHUqSzC7MqSr7UW/FEw=; b=ph+JP6lAQFQIZTaRhGOAaSeRyGCUSHGJ9MDiNca5pbVGF7eZvqLAYZyX50MLNcBg3o /KdA3BSgz/Onzf+hY9tYTcpeGpvtAXfuFHGcN9AevasonL1DAA+siwb6uNN/Gt2btFyd YdIGR00bXiY7dR/28494jezH23H11CbSTbiusolpVkYGmxRzScxJK4GkkeK9l3q8IJem AZcZ0yPu3xRHh0CzgE9VCoMZgSOHVu+gyNcbKwLMlqHRlfhKTfqCo3CyB1llD3eGkcGP xUNfb2thZZgbvHyrIVwvbuCaTXsBC+tWmxvL9R0UHQqqOjdtXrv06C9G10SQRGwlX6Nn gdsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=tRwDVw1z7dnvwBqcQOZ2x3vMeHUqSzC7MqSr7UW/FEw=; b=QPMNhQwZXk1MgIo0Hxv1JyD4Kcoyw0tvHNtCBtprRZYJ71nRVpBYB+qFgOtAhPahat tJ3aAyOrossjytpUkfd1X67jvNQ+CdZVnf6QSvx4EIto9SJOsNffztod9IFmS68KV4/c K3Fih2J/pwRi+lcg2dATzCWA58AZii6LSpXBuygrlJVt7bj+PAGxKxYyXtgcwcqK/wVz O66a5+di2jdiSCLpxNN9e3+Az9N9e4ZrO2yt6QQ0c0Xh6LcMW49Ir1uHTFeQ5ZIYuMJ+ q0A7UhyySbn0MmZAFtksn1zfe65CHQsmlG+1y+Q3gAnseU6Ug2HCVqeTraEpkUUHKE/U 0iGQ== X-Gm-Message-State: APjAAAX9kA5Z+pN3G+7kQo27sOz+BpQ5Jmk5QxEnemcYmsuuVqz5asbb EqeO2Hl0wlhyiqf7sP2bCtQ= X-Google-Smtp-Source: APXvYqwC2A/uKsfuJIoPoUOSBfX8aLZJmZ/PH/Cipz+XO69OUpD1O1B460aHo+krMzYUBWncpf0hvQ== X-Received: by 2002:a0d:ea86:: with SMTP id t128mr32647511ywe.213.1579365763583; Sat, 18 Jan 2020 08:42:43 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id k5sm13220872ywa.80.2020.01.18.08.42.42 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 18 Jan 2020 08:42:43 -0800 (PST) From: Guenter Roeck To: Peter Maydell Subject: [PATCH v2 6/7] hw/char/exynos4210_uart: Add receive DMA support Date: Sat, 18 Jan 2020 08:42:28 -0800 Message-Id: <20200118164229.22539-7-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200118164229.22539-1-linux@roeck-us.net> References: <20200118164229.22539-1-linux@roeck-us.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c41 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Igor Mitsyanko , Paolo Bonzini , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" To support receive DMA, we need to inform the DMA controller if receive data is available. Otherwise the DMA controller keeps requesting data, causing receive errors. Implement this using an interrupt line. The instantiating code then needs to connect the interrupt with the matching DMA controller GPIO pin. Reviewed-by: Peter Maydell Signed-off-by: Guenter Roeck --- v2: Added Reviewed-by: tag hw/char/exynos4210_uart.c | 24 ++++++++++++++++++++++++ hw/char/trace-events | 2 ++ 2 files changed, 26 insertions(+) diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index 63ea9663f2..6fe38fad3e 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -154,6 +154,7 @@ typedef struct Exynos4210UartState { CharBackend chr; qemu_irq irq; + qemu_irq dmairq; uint32_t channel; @@ -261,6 +262,24 @@ exynos4210_uart_Rx_FIFO_trigger_level(const Exynos4210UartState *s) return exynos4210_uart_FIFO_trigger_level(s->channel, reg); } +/* + * Update Rx DMA busy signal if Rx DMA is enabled. For simplicity, + * mark DMA as busy if DMA is enabled and the receive buffer is empty. + */ +static void exynos4210_uart_update_dmabusy(Exynos4210UartState *s) +{ + bool rx_dma_enabled = (s->reg[I_(UCON)] & 0x03) == 0x02; + uint32_t count = fifo_elements_number(&s->rx); + + if (rx_dma_enabled && !count) { + qemu_irq_raise(s->dmairq); + trace_exynos_uart_dmabusy(s->channel); + } else { + qemu_irq_lower(s->dmairq); + trace_exynos_uart_dmaready(s->channel); + } +} + static void exynos4210_uart_update_irq(Exynos4210UartState *s) { /* @@ -282,10 +301,12 @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s) count = fifo_elements_number(&s->rx); if ((count && !(s->reg[I_(UCON)] & 0x80)) || count >= exynos4210_uart_Rx_FIFO_trigger_level(s)) { + exynos4210_uart_update_dmabusy(s); s->reg[I_(UINTSP)] |= UINTSP_RXD; timer_del(s->fifo_timeout_timer); } } else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) { + exynos4210_uart_update_dmabusy(s); s->reg[I_(UINTSP)] |= UINTSP_RXD; } @@ -311,6 +332,7 @@ static void exynos4210_uart_timeout_int(void *opaque) (s->reg[I_(UCON)] & (1 << 11))) { s->reg[I_(UINTSP)] |= UINTSP_RXD; s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT; + exynos4210_uart_update_dmabusy(s); exynos4210_uart_update_irq(s); } } @@ -499,6 +521,7 @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset, s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY; res = s->reg[I_(URXH)]; } + exynos4210_uart_update_dmabusy(s); trace_exynos_uart_read(s->channel, offset, exynos4210_uart_regname(offset), res); return res; @@ -666,6 +689,7 @@ static void exynos4210_uart_init(Object *obj) sysbus_init_mmio(dev, &s->iomem); sysbus_init_irq(dev, &s->irq); + sysbus_init_irq(dev, &s->dmairq); } static void exynos4210_uart_realize(DeviceState *dev, Error **errp) diff --git a/hw/char/trace-events b/hw/char/trace-events index cb73fee6a9..6f938301d9 100644 --- a/hw/char/trace-events +++ b/hw/char/trace-events @@ -79,6 +79,8 @@ nrf51_uart_read(uint64_t addr, uint64_t r, unsigned int size) "addr 0x%" PRIx64 nrf51_uart_write(uint64_t addr, uint64_t value, unsigned int size) "addr 0x%" PRIx64 " value 0x%" PRIx64 " size %u" # exynos4210_uart.c +exynos_uart_dmabusy(uint32_t channel) "UART%d: DMA busy (Rx buffer empty)" +exynos_uart_dmaready(uint32_t channel) "UART%d: DMA ready" exynos_uart_irq_raised(uint32_t channel, uint32_t reg) "UART%d: IRQ raised: 0x%08"PRIx32 exynos_uart_irq_lowered(uint32_t channel) "UART%d: IRQ lowered" exynos_uart_update_params(uint32_t channel, int speed, uint8_t parity, int data, int stop, uint64_t wordtime) "UART%d: speed: %d, parity: %c, data bits: %d, stop bits: %d wordtime: %"PRId64"ns" From patchwork Sat Jan 18 16:42:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11340157 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AB97417EA for ; Sat, 18 Jan 2020 16:46:55 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 783E02469A for ; Sat, 18 Jan 2020 16:46:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="EeHUOeT2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 783E02469A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=roeck-us.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:42628 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrFO-0001uA-2o for patchwork-qemu-devel@patchwork.kernel.org; Sat, 18 Jan 2020 11:46:54 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36237) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1isrBR-0004Gl-Nt for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1isrBQ-0002GQ-EF for qemu-devel@nongnu.org; Sat, 18 Jan 2020 11:42:49 -0500 Received: from mail-yb1-xb41.google.com ([2607:f8b0:4864:20::b41]:42604) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1isrBN-0002EM-Lv; Sat, 18 Jan 2020 11:42:45 -0500 Received: by mail-yb1-xb41.google.com with SMTP id c8so7090726ybk.9; Sat, 18 Jan 2020 08:42:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=c40RYyx9s3sT53ibofaJCji2c/+rsUXzNeVTcJNsgco=; b=EeHUOeT2ynvb0l0grMvGxJrogdt9ELUZXqy2G53G0bdUVaA5MnPZUddKpKkETVEOiA dp27F0lP9yffDhKHJ2PGYN62NgcjWau/QGhQ85l/car79urFv6Da18CjmnMwKusgFrlh wojq6hHOm3cIpkHXRrYXtgYQb8Vt15Opjbsby0qZsyFNS6ToIaLZrSvm2gd0xR6LTNj3 2HFsaO+YmSYBOdnYOhpzHdczsKAhh3L6+1vNY//o224EC1o4OxTdedpQy4/78PPGGXns RgKcL2WFmpNWxSGh6UaP7vk3Hjnpq2KW3cvbRj/9b2LSLBLXWFrWFoRyCQrVL57J95lI tADg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=c40RYyx9s3sT53ibofaJCji2c/+rsUXzNeVTcJNsgco=; b=THLvVfFDvJ8hdOpKBaBpbKAoqojtaErBMCE47l8X0SfDWR0M0XVHiy2Yk5adeZD3Ic IZjvEx3YhGyjXnEBQQ2Xd1WFfJjWmXWuDKdJ0iNeOhR49kUbZ9gSiGmDUMGhsPrLNPSY NKdQByZqWXZHTmJ8E2qz42qyaBcZv8UNte9jV6zCv7POqAsNTGR5g7xIq/gM5MHSy75a Pcks6L3l3k5Uc1VjxoRv9jzSeb1WFMxe6N3EVWjC8et0Kk6hQUCNw5gll24RoEdZAOz8 Cd+58737NabFfl45i3Fq0kQyaCWXf6OlX/taZr274Hb2bGMThLwVFAXhuoNgGgiBNJ9K +tQg== X-Gm-Message-State: APjAAAW8lBI+GYjsA+WB1ubgVlYJpKPZAj1ztHm7COzVBrD8hJO9vCuj Kcs4b+XoTqOnGehSppnYK18= X-Google-Smtp-Source: APXvYqxZ2tZYZQhV7Q8tZKByJQU977sxj/nk47y6UWiQKsaGATrGDtrK9II9JOuKajmbQS1brB9mxQ== X-Received: by 2002:a25:d297:: with SMTP id j145mr32024675ybg.44.1579365765171; Sat, 18 Jan 2020 08:42:45 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id n8sm13263285ywh.75.2020.01.18.08.42.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 18 Jan 2020 08:42:44 -0800 (PST) From: Guenter Roeck To: Peter Maydell Subject: [PATCH v2 7/7] hw/arm/exynos4210: Connect serial port DMA busy signals with pl330 Date: Sat, 18 Jan 2020 08:42:29 -0800 Message-Id: <20200118164229.22539-8-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200118164229.22539-1-linux@roeck-us.net> References: <20200118164229.22539-1-linux@roeck-us.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::b41 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Igor Mitsyanko , Paolo Bonzini , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" The Exynos4210 serial driver uses an interrupt line to signal if receive data is available. Connect that interrupt with the DMA controller's 'peripheral busy' gpio pin to stop the DMA if there is no more receive data available. Without this patch, receive DMA runs wild and fills the entire receive DMA buffer with invalid data. Signed-off-by: Guenter Roeck Reviewed-by: Peter Maydell --- v2: Context changes; improved description This patch has an outstanding review comment, suggesting that uart and pl330 device states should be kept in Exynos4210State. I did not address this comment for a number of reasons. It looks like the problem is hypothetical, the problem may apply to all devices created in exynos4210_realize(), and I am not sure I understand what would need to be done to fix the problem for good (ie for all devices created in the same function which have the same problem). Overall, I think that handling this situation would be better left for a separate patch. hw/arm/exynos4210.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 76c0e2a3e8..6b050bb5c9 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -166,8 +166,8 @@ static uint64_t exynos4210_calc_affinity(int cpu) return (0x9 << ARM_AFF1_SHIFT) | cpu; } -static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq, - int nreq, int nevents, int width) +static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate, + qemu_irq irq, int nreq, int nevents, int width) { SysBusDevice *busdev; DeviceState *dev; @@ -196,6 +196,7 @@ static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq, sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i)); } qdev_connect_gpio_out(DEVICE(orgate), 0, irq); + return dev; } static void exynos4210_realize(DeviceState *socdev, Error **errp) @@ -204,7 +205,7 @@ static void exynos4210_realize(DeviceState *socdev, Error **errp) MemoryRegion *system_mem = get_system_memory(); qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS]; SysBusDevice *busdev; - DeviceState *dev; + DeviceState *dev, *uart[4], *pl330[3]; int i, n; for (n = 0; n < EXYNOS4210_NCPUS; n++) { @@ -390,19 +391,19 @@ static void exynos4210_realize(DeviceState *socdev, Error **errp) /*** UARTs ***/ - exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR, + uart[0] = exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR, EXYNOS4210_UART0_FIFO_SIZE, 0, serial_hd(0), s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]); - exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR, + uart[1] = exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR, EXYNOS4210_UART1_FIFO_SIZE, 1, serial_hd(1), s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]); - exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR, + uart[2] = exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR, EXYNOS4210_UART2_FIFO_SIZE, 2, serial_hd(2), s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]); - exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR, + uart[3] = exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR, EXYNOS4210_UART3_FIFO_SIZE, 3, serial_hd(3), s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]); @@ -450,12 +451,27 @@ static void exynos4210_realize(DeviceState *socdev, Error **errp) s->irq_table[exynos4210_get_irq(28, 3)]); /*** DMA controllers ***/ - pl330_create(EXYNOS4210_PL330_BASE0_ADDR, &s->pl330_irq_orgate[0], - s->irq_table[exynos4210_get_irq(21, 0)], 32, 30, 32); - pl330_create(EXYNOS4210_PL330_BASE1_ADDR, &s->pl330_irq_orgate[1], - s->irq_table[exynos4210_get_irq(21, 1)], 32, 30, 32); - pl330_create(EXYNOS4210_PL330_BASE2_ADDR, &s->pl330_irq_orgate[2], - s->irq_table[exynos4210_get_irq(20, 1)], 1, 30, 64); + pl330[0] = pl330_create(EXYNOS4210_PL330_BASE0_ADDR, + &s->pl330_irq_orgate[0], + s->irq_table[exynos4210_get_irq(21, 0)], + 32, 30, 32); + pl330[1] = pl330_create(EXYNOS4210_PL330_BASE1_ADDR, + &s->pl330_irq_orgate[1], + s->irq_table[exynos4210_get_irq(21, 1)], + 32, 30, 32); + pl330[2] = pl330_create(EXYNOS4210_PL330_BASE2_ADDR, + &s->pl330_irq_orgate[2], + s->irq_table[exynos4210_get_irq(20, 1)], + 1, 30, 64); + + sysbus_connect_irq(SYS_BUS_DEVICE(uart[0]), 1, + qdev_get_gpio_in(pl330[0], 15)); + sysbus_connect_irq(SYS_BUS_DEVICE(uart[1]), 1, + qdev_get_gpio_in(pl330[1], 15)); + sysbus_connect_irq(SYS_BUS_DEVICE(uart[2]), 1, + qdev_get_gpio_in(pl330[0], 17)); + sysbus_connect_irq(SYS_BUS_DEVICE(uart[3]), 1, + qdev_get_gpio_in(pl330[1], 17)); } static void exynos4210_init(Object *obj)