From patchwork Fri Jan 10 20:39:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11328441 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 014F56C1 for ; Fri, 10 Jan 2020 20:42:24 +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 BADF82082E for ; Fri, 10 Jan 2020 20:42:23 +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="tDYAaFHo" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BADF82082E 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]:51526 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq16s-0003yJ-H7 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 10 Jan 2020 15:42:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:33722) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq14U-0000Yn-FW for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:39:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iq14S-0006zo-8O for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:39:54 -0500 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]:33934) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iq14O-0006mI-5M; Fri, 10 Jan 2020 15:39:48 -0500 Received: by mail-pf1-x441.google.com with SMTP id i6so1681946pfc.1; Fri, 10 Jan 2020 12:39:48 -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=AjYuwcu4CzSnPUYIIJZphHa+VtV0A9D30V28S0+hFPw=; b=tDYAaFHo0kdytfDLDLPVCKxCT8oJYGzJMij7oD6x4Ycz0Y7dxn4LhCAibYFr5znXzp RubCs/ouy+uCFe9RN9RpfN//Hwp5ItQb6G5ivxcxUkiheur8WeYyavNYH7BAwUi9yYH4 n6cugmxg7CtI91XhNOM+w443+rDUrD9Srd/sWDwNgH24p6aUHJobB3NTkcZ/eB3sbY8h F73JwNifozB8elq0yHE8rtEEaykd/u/ZE5ppNpkOYlnNEH3Z2EzlIuR5Y9MuXUUGSu5B K1qn/pz6GFi2kZLnbAitP1hWED5xg+xuRddqgAvFv9d4pH4+BflVcnN4mdaZ0sH+ZfxV sLCw== 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=AjYuwcu4CzSnPUYIIJZphHa+VtV0A9D30V28S0+hFPw=; b=KXsXeyhe+Ncz0/Fa+HpVU3k7/d5DgEQDbQxgdg7iaGg+Wvn/xClnMSVYTEsRFuuum4 9VtolpNvObYCUPa0MNfH33XPTwnsSxdr2dtjEt/ZkRZd0sWczsJzxOlx9KlbbBNruyYg 3j6P9wManh7JvkgyV4ZNJB0OEQoCIq3sJ2Jt7IbnUXJIVyLopRghg1rGZ1BeK0nJvS4B xh2Q6WXGToYwf7ILY7CYDdaB812N6RVDsuZNpvI4U26qjVrQ3dNDndzH/SGvsVwjLSfE +2Le7BEzPc2W+C2k+W1fDHMr/aq8MMH3nBki6orZkfSTTvmPPH1G9k6k9+ieGnPkQnAZ Qvjg== X-Gm-Message-State: APjAAAWjA57fsRhcNKhKyHVR6VymFG52nIiV8aDivaabSQVT3LjmtznW yxTaqWVFA70ryGDF2jGrMcQ= X-Google-Smtp-Source: APXvYqyrHBNHvWxEYFyTdtYoIB2ZPMXJMmScDlY7LKRYjnzhvNkB6T0/6cooAiGQILwzRIXp6Uahdg== X-Received: by 2002:a63:6787:: with SMTP id b129mr6556573pgc.103.1578688786834; Fri, 10 Jan 2020 12:39:46 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id m6sm3764730pjn.21.2020.01.10.12.39.46 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 10 Jan 2020 12:39:46 -0800 (PST) From: Guenter Roeck To: Igor Mitsyanko Subject: [PATCH 1/6] dma/pl330: Convert to support tracing Date: Fri, 10 Jan 2020 12:39:37 -0800 Message-Id: <20200110203942.5745-2-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200110203942.5745-1-linux@roeck-us.net> References: <20200110203942.5745-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::441 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: Peter Maydell , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck , Paolo Bonzini 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 --- hw/dma/pl330.c | 88 +++++++++++++++++++++++---------------------- hw/dma/trace-events | 24 +++++++++++++ 2 files changed, 70 insertions(+), 42 deletions(-) diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c index f2bb2d9ac1..c64cc4e67a 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,11 +1186,8 @@ 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); + pl330_hexdump(buf, len); fifo_res = pl330_fifo_push(&s->fifo, buf, len, q->tag); if (fifo_res == PL330_FIFO_OK) { if (q->inc) { @@ -1207,11 +1215,8 @@ 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); + pl330_hexdump(buf, len); if (q->inc) { q->addr += len; } @@ -1252,8 +1257,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 +1303,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 +1325,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 +1340,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 +1349,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 +1367,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 +1493,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 Fri Jan 10 20:39:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11328437 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 024466C1 for ; Fri, 10 Jan 2020 20:41:40 +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 CB2272082E for ; Fri, 10 Jan 2020 20:41:39 +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="rMroP8xm" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CB2272082E 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]:51522 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq16A-0002ks-HL for patchwork-qemu-devel@patchwork.kernel.org; Fri, 10 Jan 2020 15:41:38 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:33639) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq14S-0000VP-MB for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:39:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iq14R-0006yP-L4 for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:39:52 -0500 Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]:36187) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iq14P-0006py-6Z; Fri, 10 Jan 2020 15:39:49 -0500 Received: by mail-pg1-x542.google.com with SMTP id k3so1526931pgc.3; Fri, 10 Jan 2020 12:39:49 -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=TOSNnijAQMtdjCsblYsegVxJcxGmgJnr/faVUnc8a1A=; b=rMroP8xmQOYDdZIXfGna6r4cgo0YjguFLZOzo1yt4TEKGCLiCCtnSMsXWogTm+oA7X NEhfUVuKfJoLngpiUOPCJ8Pwmi37bSUSqanwX11AAfUhN8ytFSTSkTkBFZLXKlKvhTR/ HOjckg2z3chOWKlYLvRPjmODIW48sYwivvYmIabWNnRlgixTXlCfK0Jc6baD/UvuTg+1 YJ+ZhIK/IrWAFkWNdfYA/kzZMa4xmgn8kMxDAsb1OhDXhIAyVH9tdJ6HHAPP88uxfzKA CT3F+f3jUAniCEtGK0hgv8wbEyuVo4UOY5Dbg9c6SMGyw0B3Yp5iJoeae9VrfLnDBOh2 LBng== 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=TOSNnijAQMtdjCsblYsegVxJcxGmgJnr/faVUnc8a1A=; b=bPus9H/toerYr71bXOW/ZQmF9Twn2H6FOpn2t1OaSH14ecQNBrUAQZ4umGTjagRy3D VCDKHjtK0tWy1PCtGPC7HMOaxCIxvBbs/DR9ic9WXi+7z4xE9fvvzrOfHKuc/UZmrPpj ydsx5ZRQ4UsBSxNa+druaVX8XJcU3w8XoqGXL8w7se0V2Mlz1blKsLEjP08tSBPez+Pi Z7raIp9pwT48PQNXlbUC4MfuBpheL4soDg4kQ9paiQ0olMKK75c6FQtNDe5TFXIEaERR uCpHepodR3JCCRtfgR70H+Q0AaWlyN5jJz5ucq+knwizyxkq8tc4UMmxqJA0SFE8nZmS F7mg== X-Gm-Message-State: APjAAAWjC9a3q5pqcf0PrmR+qR0NnyOI0wd9SanT57bMD+ZzxoSOfYd+ 9XIx0ImnoP5JX5fOos0Kqd0= X-Google-Smtp-Source: APXvYqxQ7tYC3gdBQ+miWHESpf7C1Rh40TLb5MS/2+NC6/6fr2R19l11kaq5IKTlAXtBgrm/6xWTlA== X-Received: by 2002:a63:358a:: with SMTP id c132mr6712499pga.286.1578688788334; Fri, 10 Jan 2020 12:39:48 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id s7sm3960148pjk.22.2020.01.10.12.39.47 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 10 Jan 2020 12:39:47 -0800 (PST) From: Guenter Roeck To: Igor Mitsyanko Subject: [PATCH 2/6] hw/arm/exynos4210: Fix DMA initialization Date: Fri, 10 Jan 2020 12:39:38 -0800 Message-Id: <20200110203942.5745-3-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200110203942.5745-1-linux@roeck-us.net> References: <20200110203942.5745-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::542 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: Peter Maydell , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck , Paolo Bonzini 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). Fixes: 59520dc65e ("hw/arm/exynos4210: Add DMA support for the Exynos4210") Signed-off-by: Guenter Roeck --- hw/arm/exynos4210.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 77fbe1baab..c7b5c587b1 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -166,17 +166,31 @@ 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_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); + sysbus_connect_irq(busdev, 0, irq); /* abort irq line */ + for (i = 0; i < nevents; i++) { + sysbus_connect_irq(busdev, i + 1, irq); /* event irq lines */ + } } static void exynos4210_realize(DeviceState *socdev, Error **errp) @@ -432,11 +446,11 @@ static void exynos4210_realize(DeviceState *socdev, Error **errp) /*** DMA controllers ***/ pl330_create(EXYNOS4210_PL330_BASE0_ADDR, - qemu_irq_invert(s->irq_table[exynos4210_get_irq(35, 1)]), 32); + s->irq_table[exynos4210_get_irq(21, 0)], 32, 32, 32); pl330_create(EXYNOS4210_PL330_BASE1_ADDR, - qemu_irq_invert(s->irq_table[exynos4210_get_irq(36, 1)]), 32); + s->irq_table[exynos4210_get_irq(21, 1)], 32, 32, 32); pl330_create(EXYNOS4210_PL330_BASE2_ADDR, - qemu_irq_invert(s->irq_table[exynos4210_get_irq(34, 1)]), 1); + s->irq_table[exynos4210_get_irq(20, 1)], 1, 31, 64); } static void exynos4210_class_init(ObjectClass *klass, void *data) From patchwork Fri Jan 10 20:39:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11328445 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 2C4CC6C1 for ; Fri, 10 Jan 2020 20:44:14 +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 E741C2082E for ; Fri, 10 Jan 2020 20:44:13 +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="i0w85NdR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E741C2082E 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]:51554 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq18f-0007Cq-0F for patchwork-qemu-devel@patchwork.kernel.org; Fri, 10 Jan 2020 15:44:13 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:33814) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq14W-0000by-AH for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:39:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iq14U-00077B-H9 for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:39:56 -0500 Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]:40479) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iq14Q-0006uQ-N8; Fri, 10 Jan 2020 15:39:50 -0500 Received: by mail-pg1-x542.google.com with SMTP id k25so1518475pgt.7; Fri, 10 Jan 2020 12:39:50 -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=Msbl0U018nPyef86ORZZP2CXtXZYuWc+8l7fCkrM98M=; b=i0w85NdRwM1PDKe+pjdUqvfDOt8GATvBcJdlKbO+mBSYcYxDCihE7iHdCVgFUFUHWc E9+TacB9YU8S2KDUGb//AWP8zzUg+G3SplvgfiF6TuQ8xRnrn0SiSN0bArzpNFD9IoZ4 fZZW0mXtxlnPT/NpSBxEN6hHpW+AvAdsbxCGCVwogvfOHXxgKmeIr3vp9EEHo357OCdg pAeAi7Qroh1Odne/Mu+d+tB6Ns5zgMIqGtcGKrV9BclwI0ip3bw9z7OjAmiCB27peC26 KtPciddPtynG6U+zxuXkBakIK0JHt1IGawHhtRxrMMRYPuOBv36evg15zzIayLlNPhIG 1IIg== 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=Msbl0U018nPyef86ORZZP2CXtXZYuWc+8l7fCkrM98M=; b=qPkMXEWUKh+VtOl3D9IWVofClLlea0EX70WJBVzg82pSfR/uqIo5jRiU7n4aHiohLd jtBzRoZX4BJhriv87nsq2AeHhfzxlu21KdqGl6sKKokS1joQ89keluYq6sBUOzvr2C8s aKLpYc5O/k+xR9U3ALeuwA+Vggz75o8q4I7jH6tE5u4Cd0smUIAKFSbrhCt1+WiaYT/L 7L9kc3Yj2E098ZtQwv1l4/885Ef5rCtdslKpTW5LTYLq/SOAHTSCvKwr9R0OLYlA+QJQ lLQE9KM6hatvaJjnJIprz9fvR1jl4zgZJcFGd3J7SbNF6QnQv29isuSGmItr57viakFd cDOA== X-Gm-Message-State: APjAAAUvwgTGROmip8fJEhTWlYpQp1+t6kmZVNplOm3sJ14y3HuGAh2p +4JbSStwsHJq/Y+G4GuBPEw= X-Google-Smtp-Source: APXvYqxCzJXcouThtxr+gASvyHWCzgqHSZ4Ilshc7a5Vt5uqEuB9B0wopemPDyHPlmUTHHQ8WiXF/Q== X-Received: by 2002:a63:1447:: with SMTP id 7mr6522354pgu.22.1578688789815; Fri, 10 Jan 2020 12:39:49 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id d23sm3771201pfo.176.2020.01.10.12.39.49 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 10 Jan 2020 12:39:49 -0800 (PST) From: Guenter Roeck To: Igor Mitsyanko Subject: [PATCH 3/6] hw/char/exynos4210_uart: Convert to support tracing Date: Fri, 10 Jan 2020 12:39:39 -0800 Message-Id: <20200110203942.5745-4-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200110203942.5745-1-linux@roeck-us.net> References: <20200110203942.5745-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::542 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: Peter Maydell , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck , Paolo Bonzini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Replace debug code with tracing to aid debugging. Signed-off-by: Guenter Roeck Reviewed-by: Peter Maydell --- 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 Fri Jan 10 20:39:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11328439 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 DAC2B6C1 for ; Fri, 10 Jan 2020 20:41:43 +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 A10742082E for ; Fri, 10 Jan 2020 20:41:43 +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="BTmQdRVm" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A10742082E 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]:51524 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq16E-0002sG-8y for patchwork-qemu-devel@patchwork.kernel.org; Fri, 10 Jan 2020 15:41:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:33883) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq14X-0000ev-Vd for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:39:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iq14W-0007CB-1F for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:39:57 -0500 Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]:45982) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iq14S-0006yW-4h; Fri, 10 Jan 2020 15:39:52 -0500 Received: by mail-pg1-x542.google.com with SMTP id b9so1504869pgk.12; Fri, 10 Jan 2020 12:39:52 -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=QqaH3pXRjjA0Ik+eBsaT6RsaZ2EEjfEu0olkmdpV/O4=; b=BTmQdRVmU0zKsOg0YFA5fFWy1g2uFPTS4J0cxFuMVYTxkmEgSvt7EORZFYlZMQeZYn Jjhuk9vu1qyFajPvusoqQBr1Rrg6ybCdUaVPkzezF6wMef/qfQdN12OKStyo/8s6QDvB MKQ7yDIJFJbNZ5t13LpAjLQMDjdGtzuHi9MmWBy4wbr76fOINzacx+3x2GE/obs5NPNE SOTTxArS3Z9TvS8EuZ3Zdakr51jcHXFHzMKXX1cAe2k+PFjlmB8XqY4kpyfW3U9TkoYg NAf/NFJGOqlfcJ7U2YZA08FRCAy8b/b6meUTS+09kHD0Y8dnrSMVafFUTcOcL4xrcz2d /EBw== 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=QqaH3pXRjjA0Ik+eBsaT6RsaZ2EEjfEu0olkmdpV/O4=; b=gzm2GjpMZ/ejQ4n6U46yNNJeuwAA/ZfXieTW/3T4T3rqSQmZBsUswK4FLr7XqPJrtd zDuwY1ZS/aFde9bA+eOneWBLxS2D/EidbXyB5KMnCH9n76IXgtQpfINWfQBDTwKWaFTY 78j/m/84rch9FR5qmYCR+hBXL0/HWHI4EabF2/Agvt0qZ0jOY9lnd879dqbrDbM59GLt XPKy7UnjYSHI2uZFhNekUHaT+J0EYgaviSevfj7Sj95ym+pe7IE5Rt0FGDJU/v8xiugV /2hYUP4RDovT/ynzj95PJ81x6VOUWzFnRE3NwL75yHOkSuzPAPMo66+fR9BP5idgcz0z 9vIg== X-Gm-Message-State: APjAAAVscWhsWE1PPufDRk6YUXrBLlUZms+hvDkMmWQZMKpKoEonu7mM nd7PmHbZO/EWPV4TcZjGoik+/zpk X-Google-Smtp-Source: APXvYqxNZyoHF9kYNkASrtGfZ1CESk9vSC/ShDUAuFCevsj2BKggjM9ATTE5URI7AAPfl1L7usXkgQ== X-Received: by 2002:aa7:8ad9:: with SMTP id b25mr6181713pfd.70.1578688791301; Fri, 10 Jan 2020 12:39:51 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id 83sm3742383pgh.12.2020.01.10.12.39.50 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 10 Jan 2020 12:39:50 -0800 (PST) From: Guenter Roeck To: Igor Mitsyanko Subject: [PATCH 4/6] hw/char/exynos4210_uart: Implement receive FIFO Date: Fri, 10 Jan 2020 12:39:40 -0800 Message-Id: <20200110203942.5745-5-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200110203942.5745-1-linux@roeck-us.net> References: <20200110203942.5745-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::542 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: Peter Maydell , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck , Paolo Bonzini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Guenter Roeck --- hw/char/exynos4210_uart.c | 120 ++++++++++++++++++++++++++++++-------- hw/char/trace-events | 3 +- 2 files changed, 97 insertions(+), 26 deletions(-) diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index fb7a3ebd09..61134a7bdc 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); } @@ -578,6 +644,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 Fri Jan 10 20:39:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11328447 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 CF9EC139A for ; Fri, 10 Jan 2020 20:45:24 +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 5F00F2082E for ; Fri, 10 Jan 2020 20:45:24 +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="QvDvKQ8/" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5F00F2082E 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]:51572 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq19m-0008Ue-Ak for patchwork-qemu-devel@patchwork.kernel.org; Fri, 10 Jan 2020 15:45:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:33861) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq14X-0000e3-GI for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:39:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iq14W-0007Ca-5H for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:39:57 -0500 Received: from mail-pj1-x1044.google.com ([2607:f8b0:4864:20::1044]:55008) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iq14T-00072A-H9; Fri, 10 Jan 2020 15:39:53 -0500 Received: by mail-pj1-x1044.google.com with SMTP id kx11so1422669pjb.4; Fri, 10 Jan 2020 12:39:53 -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=kFcujy5Zx7eAN8ANMQIMiKXRM7AFrv0aiyTTDTv0DLU=; b=QvDvKQ8/BM0nJbYud/2NJPBkiA2ey9H06quY9d54iyPwLKEpMos+p/HpgCmMXH0zvC jsfm4sIGo8eX/lp64nK6fWyUa+gwbweEG1BGwtmppT9YiZky0EJCsMgeHXJa8Ouc9QZ+ ZZPzNq0sFc6DBInHIvRy8MsGfVF8ZVomGoIKVPtKzInSzPG1rJ4SEM2+Qufvq6mYfbuO oy2cQpHVsy4/fFHpNoI+T0DaBkUIyuNuuqrHiV1VLT8Ulpt2SRZrDKto7SkJVRc+7ruL 9m5NQ799VP83XLrO3H/MMoP4UtYEEFp4T0Jn+z6bKe5Rt+/tGaMtn5KhvBJDpdxC9rKh 6aHg== 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=kFcujy5Zx7eAN8ANMQIMiKXRM7AFrv0aiyTTDTv0DLU=; b=NdO58mKYKWOqR5fV3I/hjvq64T0YWrqYjiKnmdxeJ5kyqetVrVpBXoyw4YEHckaQFf w1+NNmMmok62Ox4vMp5n98ql0DxuoiBwCvBSPcZdtT15fGfzWgfYrtLE2P/UcyXJrpm7 XBOgDuicH+/oDnwTwm/qoPgfQzxsRaSiWJeXB/v49eqThClIKEkwSX868iiAv/+rE2AZ JUWhv6FQPLadMX4RYzACLcrfa+MwDC05h9JPVVT0VrAB0o2ezwtm84mb0AA13Qcjd02/ umHDWkDlzhPULQE0GVyM60ZR2bYNoUiRGUTyX3LuxJg/VY2KqpfwLPlHM26C/iEzvsaZ 5UyQ== X-Gm-Message-State: APjAAAVglz7d5lcDYvmygmKHEcs8HqQaL8jMt2VBOjDbs8WrKoHF5Zu7 8gHkhVwCWBAW+s9vkAcjGFM= X-Google-Smtp-Source: APXvYqxqGjsNB6FZJYAmqJt3D9LIL6WDryKGuREiNIdZ0R11mQ0AgxFcpDiXFVdeumbTqbPwdUYKzA== X-Received: by 2002:a17:90a:fa10:: with SMTP id cm16mr7284493pjb.129.1578688792599; Fri, 10 Jan 2020 12:39:52 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id r8sm3604335pjo.22.2020.01.10.12.39.51 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 10 Jan 2020 12:39:52 -0800 (PST) From: Guenter Roeck To: Igor Mitsyanko Subject: [PATCH 5/6] hw/char/exynos4210_uart: Add receive DMA support Date: Fri, 10 Jan 2020 12:39:41 -0800 Message-Id: <20200110203942.5745-6-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200110203942.5745-1-linux@roeck-us.net> References: <20200110203942.5745-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::1044 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: Peter Maydell , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck , Paolo Bonzini 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. Signed-off-by: Guenter Roeck Reviewed-by: Peter Maydell --- 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 61134a7bdc..e23799f93b 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; @@ -654,6 +677,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 Fri Jan 10 20:39:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11328443 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 BBB1392A for ; Fri, 10 Jan 2020 20:44:07 +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 8ED332082E for ; Fri, 10 Jan 2020 20:44:07 +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="BsCNWbxR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8ED332082E 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]:51552 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq18Y-00074o-GF for patchwork-qemu-devel@patchwork.kernel.org; Fri, 10 Jan 2020 15:44:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:33913) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iq14Y-0000fv-L2 for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:40:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iq14X-0007Gt-Cr for qemu-devel@nongnu.org; Fri, 10 Jan 2020 15:39:58 -0500 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]:45075) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iq14U-00076A-NW; Fri, 10 Jan 2020 15:39:54 -0500 Received: by mail-pf1-x441.google.com with SMTP id 2so1657503pfg.12; Fri, 10 Jan 2020 12:39:54 -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=kJL6D43Lk44GZABLgzICULfdZGP31GnZA6iTy8OUmgw=; b=BsCNWbxRViMev+a4DX4+9xeUa52wF6S1322fYGoJDlQzZsEJ3l+GxXET57BfH3m+8R fwaS13ZcNn1CWoMdPojoFz1kZ8rKizegtU/0iAbVzdWHFtGB/2Si0mD/mkFzHnf23OgI psisQthE6QJm2Ep7sCFEfjWyfTR6wIF02zYwDeOIJ3Pjzn6+5OgS7tYVGd504DGtORAq eDjU4OquxYOMgCkMU3vatfjLBE0DxSCc9tWtH+H5gEMRrcrqaEOpuYbaJNuuooUMGnu/ xmBd6VkAR/z3H41BSpgqN1f3vVDFdlO4TKU/6AZ9uViwd2+cMXOzoDR6zjxfSmxNz4L8 ocjg== 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=kJL6D43Lk44GZABLgzICULfdZGP31GnZA6iTy8OUmgw=; b=CmQ1su3Y8XWskNIu2NKim+Z4XdOvxoW8XUOAKH/cAPxzi6L0AomfQEnwzim45JJ+vd VuY7QOLu64CfkYdMACUTN5zYUFsAKGUQdk33JopGoefUnsc/TnuIjoXG65KJ/EJZBRyJ JBClb09LqG8P/B64edmtGaZJf9MXHSDAi6t7cdt96OdlCvraQGF0jWx26xIzrXZtPs8a zHtKp7oeLzkifLxcEP+a2y3ZREA4b5HJQjP20JbJTLEVGDSRz68erJ8VnocCG6MFqF3d 4cE1dkl6z06wGG7rRRpbCfYvLcuu73qNRwExh1hyHSKK+sBF925loMTbNvR6NC0fECYo LuXg== X-Gm-Message-State: APjAAAVW0B6lvQeTxhrM94gNiImX5v9p95kC867SjL63G0o7BEyv4XrV 8SGQRcEhWJhe/b6ho+EVL80= X-Google-Smtp-Source: APXvYqwdOyu3M1mbVELe8etK8mN+WuHKvEzNyQ97i91475aP2ysKfljuyTmMAAVsKWO+3OgHxdDsOg== X-Received: by 2002:a62:788a:: with SMTP id t132mr6234013pfc.134.1578688793976; Fri, 10 Jan 2020 12:39:53 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id d3sm3826240pfn.113.2020.01.10.12.39.53 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 10 Jan 2020 12:39:53 -0800 (PST) From: Guenter Roeck To: Igor Mitsyanko Subject: [PATCH 6/6] hw/arm/exynos4210: Connect serial port DMA busy signals with pl330 Date: Fri, 10 Jan 2020 12:39:42 -0800 Message-Id: <20200110203942.5745-7-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200110203942.5745-1-linux@roeck-us.net> References: <20200110203942.5745-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::441 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: Peter Maydell , qemu-arm@nongnu.org, qemu-devel@nongnu.org, Guenter Roeck , Paolo Bonzini 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. Signed-off-by: Guenter Roeck --- hw/arm/exynos4210.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index c7b5c587b1..498d79ebb2 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_irq irq, int nreq, int nevents, - int width) +static DeviceState *pl330_create(uint32_t base, qemu_irq irq, int nreq, + int nevents, int width) { SysBusDevice *busdev; DeviceState *dev; @@ -191,6 +191,7 @@ static void pl330_create(uint32_t base, qemu_irq irq, int nreq, int nevents, for (i = 0; i < nevents; i++) { sysbus_connect_irq(busdev, i + 1, irq); /* event irq lines */ } + return dev; } static void exynos4210_realize(DeviceState *socdev, Error **errp) @@ -199,7 +200,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++) { @@ -385,19 +386,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)]); @@ -445,12 +446,24 @@ 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->irq_table[exynos4210_get_irq(21, 0)], 32, 32, 32); - pl330_create(EXYNOS4210_PL330_BASE1_ADDR, - s->irq_table[exynos4210_get_irq(21, 1)], 32, 32, 32); - pl330_create(EXYNOS4210_PL330_BASE2_ADDR, - s->irq_table[exynos4210_get_irq(20, 1)], 1, 31, 64); + pl330[0] = pl330_create(EXYNOS4210_PL330_BASE0_ADDR, + s->irq_table[exynos4210_get_irq(21, 0)], + 32, 32, 32); + pl330[1] = pl330_create(EXYNOS4210_PL330_BASE1_ADDR, + s->irq_table[exynos4210_get_irq(21, 1)], + 32, 32, 32); + pl330[2] = pl330_create(EXYNOS4210_PL330_BASE2_ADDR, + s->irq_table[exynos4210_get_irq(20, 1)], + 1, 31, 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_class_init(ObjectClass *klass, void *data)