From patchwork Mon Jun 1 16:14:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Patchwork-Id: 281541 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2853FC433DF for ; Mon, 1 Jun 2020 16:16:20 +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 ED03F206C3 for ; Mon, 1 Jun 2020 16:16:19 +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="WckEipYG" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org ED03F206C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=amsat.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:55922 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jfn6p-0006hd-4H for qemu-devel@archiver.kernel.org; Mon, 01 Jun 2020 12:16:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50882) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jfn5L-0004zh-NR for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:47 -0400 Received: from mail-wr1-x434.google.com ([2a00:1450:4864:20::434]:41186) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jfn5L-0001VU-1o for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:47 -0400 Received: by mail-wr1-x434.google.com with SMTP id j10so393963wrw.8 for ; Mon, 01 Jun 2020 09:14:46 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=NA3HxowRBgdQR4zG7dIwLOdIlhd4o6KOpVFcc0np+Vo=; b=WckEipYGy4BfVRPLGjCUxIyU0D8m7ewYNeKhLc8YF5dhV9jVorEXOzOjZxYTUYzi9v RIo1eaLselpStkiiNqk5lzpEB4IN6IvR+t3wULrTE6HXj0aTYwTAdddhU9jjv3rigOII v8Quc3LXUOMIDtV32sqybeaXAZNraFCAOSSg4RmTc0RBKsL10UroyDNPtaiMP/osVzco FzO5HSWKVD4PChhoN/OFsh1oqW86g31WwPMblJwotXS6bH73k8lMW9wI9Y3MPWxDKH2D HDfSp2cb09sgH0SDQTum3gXaJEaEkh8iKdoEVXGpudtsGaqYVUnJew5h7B4W3T9uF9dc gOfQ== 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:mime-version:content-transfer-encoding; bh=NA3HxowRBgdQR4zG7dIwLOdIlhd4o6KOpVFcc0np+Vo=; b=WScANjg05p5zfcr26cGMtNwCdHEb9vPNcZtZCihk3VAbaqR9RtJAodkPXNQNHODUR+ LKxCEuEWWwhkqgrzmNkBx/Cx6A+sGeVVfrbq/9uQqCg8+QSi8C5cdBFzPyOtdJicFoVM 2wSL58cJd22NNMw9v9cEIU2gQ2fdZ+g9OmvkMFVT0nNVdsOiDEcc8CLxOnWAPzU2ECyw xD/eGzUrWJm/S7UIBv9rlgut538oVIUMOt2mqi5ikO+xkJY5Pv5o4eBrf44gak2pAPfo ho+novOapNilKlfUhQ8S+MtmgtjTPhnM4+HpqfKvYFxF+bFL6epMCHmzADMeV0IZVf5B VDhQ== X-Gm-Message-State: AOAM5326+VjaS0njqr/ruoLc789Ers1MjJcXeF5uzC0Uef7+jvxMZFiU u/nO+DeIq8iPidnDo6UPhnA= X-Google-Smtp-Source: ABdhPJztnxojnXyvsP0e2owtr8EjZZGKlhm/iPr+/2vC8upbYpinr992XBlMhAur04oQzHftRtnRlw== X-Received: by 2002:adf:9e03:: with SMTP id u3mr17697473wre.413.1591028085926; Mon, 01 Jun 2020 09:14:45 -0700 (PDT) Received: from localhost.localdomain (43.red-83-51-162.dynamicip.rima-tde.net. [83.51.162.43]) by smtp.gmail.com with ESMTPSA id a6sm21309896wrn.38.2020.06.01.09.14.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jun 2020 09:14:45 -0700 (PDT) From: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= To: Richard Henderson , qemu-devel@nongnu.org, Yoshinori Sato Subject: [PATCH 02/12] MAINTAINERS: Add entry for RX hardware Date: Mon, 1 Jun 2020 18:14:31 +0200 Message-Id: <20200601161441.8086-3-f4bug@amsat.org> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20200601161441.8086-1-f4bug@amsat.org> References: <20200601161441.8086-1-f4bug@amsat.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::434; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-x434.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action 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: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Paolo Bonzini , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?b?w6k=?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Yoshinori Sato Signed-off-by: Yoshinori Sato Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-Id: <20200224141923.82118-2-ysato@users.sourceforge.jp> [PMD: Renamed as gdbsim, add acceptance test file and rST doc] Signed-off-by: Philippe Mathieu-Daudé --- MAINTAINERS | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0944d9c731..ac2e82eb19 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1238,6 +1238,21 @@ F: pc-bios/canyonlands.dt[sb] F: pc-bios/u-boot-sam460ex-20100605.bin F: roms/u-boot-sam460ex +RX Machines +----------- +rx-gdbsim +M: Yoshinori Sato +S: Maintained +F: docs/system/target-rx.rst +F: hw/rx/ +F: hw/intc/rx_icu.c +F: hw/timer/renesas_*.c +F: hw/char/renesas_sci.c +F: include/hw/rx/ +F: include/hw/timer/renesas_*.h +F: include/hw/char/renesas_sci.h +F: tests/acceptance/machine_rx_gdbsim.py + SH4 Machines ------------ R2D From patchwork Mon Jun 1 16:14:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Patchwork-Id: 281539 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 437C7C433DF for ; Mon, 1 Jun 2020 16:18:29 +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 F35B42073B for ; Mon, 1 Jun 2020 16:18:28 +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="VzOrdBJ9" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F35B42073B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=amsat.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:36366 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jfn8u-0001mQ-5q for qemu-devel@archiver.kernel.org; Mon, 01 Jun 2020 12:18:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50894) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jfn5O-00055f-J5 for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:50 -0400 Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]:33642) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jfn5N-0001Vn-5F for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:50 -0400 Received: by mail-wr1-x429.google.com with SMTP id l11so445553wru.0 for ; Mon, 01 Jun 2020 09:14:48 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=p2jgajganxLEDZOO6UpHmOY8HDjZV+a5//BhQvTt+ck=; b=VzOrdBJ9k+p+Mn195V997NXJTci0l8Tb+O0wLIdzbgPVjSooRoSmyHkkuF1D6/TYjl O4EHRj5Cj16Iqp0T9uvhGGiRBdk7hHVCobMUUiAGKdEkQlOXZ2N9ffsKAMM1NfHyuLjl Et4FLamP4IwJoA8uXEDhlzVohV0/yOB1ge1UoA+QQBOZcCqv5BBZUVabvpTORUWPdHGO 2iJEaSzf0E51RgClVIfcSx6M/comRIXziGTXuQ60t8knikZ6QSQNyNfR/nshGjNDmPYX 05hzz+k2aA7AOZO4jGLAiQwQgsuARNtpbuU94QT0AbU13joffTEmwF4fvzZiem2lQPE0 7vaQ== 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:mime-version:content-transfer-encoding; bh=p2jgajganxLEDZOO6UpHmOY8HDjZV+a5//BhQvTt+ck=; b=BdR60uZh6apkD2winyYPu1y38a5pKfhtcF3A1rUL09zUdNLjVDZsRSrjC38IkyPonq pDoTdLYQQuB32cyyPqBRXqfiUx7jRREmF54Tos6XjCXpepCCyMFxPZK0sOyxlgHsap/m LbGXSme/sht/xohxi4SYVr/6/eCyhR5Nx6HtiX9IxXX1NV+To/Wc1nKjWAMItw5OSlCR n6izEP3It0y6IdjynrBbchfJ0n/U0Hv3uMzWbIuEfPfwSwvPNK5kwZXbQKnDZRr8qSs7 pRJ/SwTgVTEixTH/9tx4CJ+/RKADhZCXydUGlkGZln/nBCBEQk69bueucguqJNrZkHTq Ygtg== X-Gm-Message-State: AOAM532UZ5XcBRID8znKtgakWgLphOlDy96yHBuLvtX8k+n4Fzj/k43j 7t6z3Zv8fQybcF88aMgMv6Q= X-Google-Smtp-Source: ABdhPJwvDwEyjLY06BGim3c+Cuj1u9p6olGNdQ58a2aNFlHs0kmPvrjIoXlBEUb6oYKcSqkR87OtlQ== X-Received: by 2002:a5d:694a:: with SMTP id r10mr22801868wrw.266.1591028087581; Mon, 01 Jun 2020 09:14:47 -0700 (PDT) Received: from localhost.localdomain (43.red-83-51-162.dynamicip.rima-tde.net. [83.51.162.43]) by smtp.gmail.com with ESMTPSA id a6sm21309896wrn.38.2020.06.01.09.14.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jun 2020 09:14:46 -0700 (PDT) From: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= To: Richard Henderson , qemu-devel@nongnu.org, Yoshinori Sato Subject: [PATCH 03/12] hw/intc: RX62N interrupt controller (ICUa) Date: Mon, 1 Jun 2020 18:14:32 +0200 Message-Id: <20200601161441.8086-4-f4bug@amsat.org> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20200601161441.8086-1-f4bug@amsat.org> References: <20200601161441.8086-1-f4bug@amsat.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::429; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-x429.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action 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: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Paolo Bonzini , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?b?w6k=?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Yoshinori Sato This implementation supported only ICUa. Hardware manual. https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01uh0033ej0140_rx62n.pdf Signed-off-by: Yoshinori Sato Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-Id: <20200224141923.82118-15-ysato@users.sourceforge.jp> [PMD: Filled VMStateField for migration] Signed-off-by: Philippe Mathieu-Daudé --- include/hw/intc/rx_icu.h | 76 ++++++++ hw/intc/rx_icu.c | 397 +++++++++++++++++++++++++++++++++++++++ hw/intc/Kconfig | 3 + hw/intc/Makefile.objs | 1 + 4 files changed, 477 insertions(+) create mode 100644 include/hw/intc/rx_icu.h create mode 100644 hw/intc/rx_icu.c diff --git a/include/hw/intc/rx_icu.h b/include/hw/intc/rx_icu.h new file mode 100644 index 0000000000..7176015cd9 --- /dev/null +++ b/include/hw/intc/rx_icu.h @@ -0,0 +1,76 @@ +/* + * RX Interrupt Control Unit + * + * Copyright (c) 2019 Yoshinori Sato + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef HW_INTC_RX_ICU_H +#define HW_INTC_RX_ICU_H + +#include "hw/sysbus.h" + +enum TRG_MODE { + TRG_LEVEL = 0, + TRG_NEDGE = 1, /* Falling */ + TRG_PEDGE = 2, /* Raising */ + TRG_BEDGE = 3, /* Both */ +}; + +struct IRQSource { + enum TRG_MODE sense; + int level; +}; + +enum { + /* Software interrupt request */ + SWI = 27, + NR_IRQS = 256 +}; + +struct RXICUState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion memory; + struct IRQSource src[NR_IRQS]; + uint32_t nr_irqs; + uint8_t *map; + uint32_t nr_sense; + uint8_t *init_sense; + + uint8_t ir[NR_IRQS]; + uint8_t dtcer[NR_IRQS]; + uint8_t ier[NR_IRQS / 8]; + uint8_t ipr[142]; + uint8_t dmasr[4]; + uint16_t fir; + uint8_t nmisr; + uint8_t nmier; + uint8_t nmiclr; + uint8_t nmicr; + int16_t req_irq; + qemu_irq _irq; + qemu_irq _fir; + qemu_irq _swi; +}; +typedef struct RXICUState RXICUState; + +#define TYPE_RX_ICU "rx-icu" +#define RX_ICU(obj) OBJECT_CHECK(RXICUState, (obj), TYPE_RX_ICU) + +#endif /* RX_ICU_H */ diff --git a/hw/intc/rx_icu.c b/hw/intc/rx_icu.c new file mode 100644 index 0000000000..df4b6a8d22 --- /dev/null +++ b/hw/intc/rx_icu.c @@ -0,0 +1,397 @@ +/* + * RX Interrupt Control Unit + * + * Warning: Only ICUa is supported. + * + * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware + * (Rev.1.40 R01UH0033EJ0140) + * + * Copyright (c) 2019 Yoshinori Sato + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qemu/error-report.h" +#include "hw/irq.h" +#include "hw/registerfields.h" +#include "hw/qdev-properties.h" +#include "hw/intc/rx_icu.h" +#include "migration/vmstate.h" + +REG8(IR, 0) + FIELD(IR, IR, 0, 1) +REG8(DTCER, 0x100) + FIELD(DTCER, DTCE, 0, 1) +REG8(IER, 0x200) +REG8(SWINTR, 0x2e0) + FIELD(SWINTR, SWINT, 0, 1) +REG16(FIR, 0x2f0) + FIELD(FIR, FVCT, 0, 8) + FIELD(FIR, FIEN, 15, 1) +REG8(IPR, 0x300) + FIELD(IPR, IPR, 0, 4) +REG8(DMRSR, 0x400) +REG8(IRQCR, 0x500) + FIELD(IRQCR, IRQMD, 2, 2) +REG8(NMISR, 0x580) + FIELD(NMISR, NMIST, 0, 1) + FIELD(NMISR, LVDST, 1, 1) + FIELD(NMISR, OSTST, 2, 1) +REG8(NMIER, 0x581) + FIELD(NMIER, NMIEN, 0, 1) + FIELD(NMIER, LVDEN, 1, 1) + FIELD(NMIER, OSTEN, 2, 1) +REG8(NMICLR, 0x582) + FIELD(NMICLR, NMICLR, 0, 1) + FIELD(NMICLR, OSTCLR, 2, 1) +REG8(NMICR, 0x583) + FIELD(NMICR, NMIMD, 3, 1) + +static void set_irq(RXICUState *icu, int n_IRQ, int req) +{ + if ((icu->fir & R_FIR_FIEN_MASK) && + (icu->fir & R_FIR_FVCT_MASK) == n_IRQ) { + qemu_set_irq(icu->_fir, req); + } else { + qemu_set_irq(icu->_irq, req); + } +} + +static uint16_t rxicu_level(RXICUState *icu, unsigned n) +{ + return (icu->ipr[icu->map[n]] << 8) | n; +} + +static void rxicu_request(RXICUState *icu, int n_IRQ) +{ + int enable; + + enable = icu->ier[n_IRQ / 8] & (1 << (n_IRQ & 7)); + if (n_IRQ > 0 && enable != 0 && atomic_read(&icu->req_irq) < 0) { + atomic_set(&icu->req_irq, n_IRQ); + set_irq(icu, n_IRQ, rxicu_level(icu, n_IRQ)); + } +} + +static void rxicu_set_irq(void *opaque, int n_IRQ, int level) +{ + RXICUState *icu = opaque; + struct IRQSource *src; + int issue; + + if (n_IRQ >= NR_IRQS) { + error_report("%s: IRQ %d out of range", __func__, n_IRQ); + return; + } + + src = &icu->src[n_IRQ]; + + level = (level != 0); + switch (src->sense) { + case TRG_LEVEL: + /* level-sensitive irq */ + issue = level; + src->level = level; + break; + case TRG_NEDGE: + issue = (level == 0 && src->level == 1); + src->level = level; + break; + case TRG_PEDGE: + issue = (level == 1 && src->level == 0); + src->level = level; + break; + case TRG_BEDGE: + issue = ((level ^ src->level) & 1); + src->level = level; + break; + default: + g_assert_not_reached(); + } + if (issue == 0 && src->sense == TRG_LEVEL) { + icu->ir[n_IRQ] = 0; + if (atomic_read(&icu->req_irq) == n_IRQ) { + /* clear request */ + set_irq(icu, n_IRQ, 0); + atomic_set(&icu->req_irq, -1); + } + return; + } + if (issue) { + icu->ir[n_IRQ] = 1; + rxicu_request(icu, n_IRQ); + } +} + +static void rxicu_ack_irq(void *opaque, int no, int level) +{ + RXICUState *icu = opaque; + int i; + int n_IRQ; + int max_pri; + + n_IRQ = atomic_read(&icu->req_irq); + if (n_IRQ < 0) { + return; + } + atomic_set(&icu->req_irq, -1); + if (icu->src[n_IRQ].sense != TRG_LEVEL) { + icu->ir[n_IRQ] = 0; + } + + max_pri = 0; + n_IRQ = -1; + for (i = 0; i < NR_IRQS; i++) { + if (icu->ir[i]) { + if (max_pri < icu->ipr[icu->map[i]]) { + n_IRQ = i; + max_pri = icu->ipr[icu->map[i]]; + } + } + } + + if (n_IRQ >= 0) { + rxicu_request(icu, n_IRQ); + } +} + +static uint64_t icu_read(void *opaque, hwaddr addr, unsigned size) +{ + RXICUState *icu = opaque; + int reg = addr & 0xff; + + if ((addr != A_FIR && size != 1) || + (addr == A_FIR && size != 2)) { + qemu_log_mask(LOG_GUEST_ERROR, "rx_icu: Invalid read size 0x%" + HWADDR_PRIX "\n", + addr); + return UINT64_MAX; + } + switch (addr) { + case A_IR ... A_IR + 0xff: + return icu->ir[reg] & R_IR_IR_MASK; + case A_DTCER ... A_DTCER + 0xff: + return icu->dtcer[reg] & R_DTCER_DTCE_MASK; + case A_IER ... A_IER + 0x1f: + return icu->ier[reg]; + case A_SWINTR: + return 0; + case A_FIR: + return icu->fir & (R_FIR_FIEN_MASK | R_FIR_FVCT_MASK); + case A_IPR ... A_IPR + 0x8f: + return icu->ipr[reg] & R_IPR_IPR_MASK; + case A_DMRSR: + case A_DMRSR + 4: + case A_DMRSR + 8: + case A_DMRSR + 12: + return icu->dmasr[reg >> 2]; + case A_IRQCR ... A_IRQCR + 0x1f: + return icu->src[64 + reg].sense << R_IRQCR_IRQMD_SHIFT; + case A_NMISR: + case A_NMICLR: + return 0; + case A_NMIER: + return icu->nmier; + case A_NMICR: + return icu->nmicr; + default: + qemu_log_mask(LOG_UNIMP, "rx_icu: Register 0x%" HWADDR_PRIX " " + "not implemented.\n", + addr); + break; + } + return UINT64_MAX; +} + +static void icu_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) +{ + RXICUState *icu = opaque; + int reg = addr & 0xff; + + if ((addr != A_FIR && size != 1) || + (addr == A_FIR && size != 2)) { + qemu_log_mask(LOG_GUEST_ERROR, "rx_icu: Invalid write size at " + "0x%" HWADDR_PRIX "\n", + addr); + return; + } + switch (addr) { + case A_IR ... A_IR + 0xff: + if (icu->src[reg].sense != TRG_LEVEL && val == 0) { + icu->ir[reg] = 0; + } + break; + case A_DTCER ... A_DTCER + 0xff: + icu->dtcer[reg] = val & R_DTCER_DTCE_MASK; + qemu_log_mask(LOG_UNIMP, "rx_icu: DTC not implemented\n"); + break; + case A_IER ... A_IER + 0x1f: + icu->ier[reg] = val; + break; + case A_SWINTR: + if (val & R_SWINTR_SWINT_MASK) { + qemu_irq_pulse(icu->_swi); + } + break; + case A_FIR: + icu->fir = val & (R_FIR_FIEN_MASK | R_FIR_FVCT_MASK); + break; + case A_IPR ... A_IPR + 0x8f: + icu->ipr[reg] = val & R_IPR_IPR_MASK; + break; + case A_DMRSR: + case A_DMRSR + 4: + case A_DMRSR + 8: + case A_DMRSR + 12: + icu->dmasr[reg >> 2] = val; + qemu_log_mask(LOG_UNIMP, "rx_icu: DMAC not implemented\n"); + break; + case A_IRQCR ... A_IRQCR + 0x1f: + icu->src[64 + reg].sense = val >> R_IRQCR_IRQMD_SHIFT; + break; + case A_NMICLR: + break; + case A_NMIER: + icu->nmier |= val & (R_NMIER_NMIEN_MASK | + R_NMIER_LVDEN_MASK | + R_NMIER_OSTEN_MASK); + break; + case A_NMICR: + if ((icu->nmier & R_NMIER_NMIEN_MASK) == 0) { + icu->nmicr = val & R_NMICR_NMIMD_MASK; + } + break; + default: + qemu_log_mask(LOG_UNIMP, "rx_icu: Register 0x%" HWADDR_PRIX " " + "not implemented\n", + addr); + break; + } +} + +static const MemoryRegionOps icu_ops = { + .write = icu_write, + .read = icu_read, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 2, + }, + .valid = { + .min_access_size = 1, + .max_access_size = 2, + }, +}; + +static void rxicu_realize(DeviceState *dev, Error **errp) +{ + RXICUState *icu = RX_ICU(dev); + int i, j; + + if (icu->init_sense == NULL) { + qemu_log_mask(LOG_GUEST_ERROR, + "rx_icu: trigger-level property must be set."); + return; + } + for (i = j = 0; i < NR_IRQS; i++) { + if (icu->init_sense[j] == i) { + icu->src[i].sense = TRG_LEVEL; + if (j < icu->nr_sense) { + j++; + } + } else { + icu->src[i].sense = TRG_PEDGE; + } + } + icu->req_irq = -1; +} + +static void rxicu_init(Object *obj) +{ + SysBusDevice *d = SYS_BUS_DEVICE(obj); + RXICUState *icu = RX_ICU(obj); + + memory_region_init_io(&icu->memory, OBJECT(icu), &icu_ops, + icu, "rx-icu", 0x600); + sysbus_init_mmio(d, &icu->memory); + + qdev_init_gpio_in(DEVICE(d), rxicu_set_irq, NR_IRQS); + qdev_init_gpio_in_named(DEVICE(d), rxicu_ack_irq, "ack", 1); + sysbus_init_irq(d, &icu->_irq); + sysbus_init_irq(d, &icu->_fir); + sysbus_init_irq(d, &icu->_swi); +} + +static void rxicu_fini(Object *obj) +{ + RXICUState *icu = RX_ICU(obj); + g_free(icu->map); + g_free(icu->init_sense); +} + +static const VMStateDescription vmstate_rxicu = { + .name = "rx-icu", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT8_ARRAY(ir, RXICUState, NR_IRQS), + VMSTATE_UINT8_ARRAY(dtcer, RXICUState, NR_IRQS), + VMSTATE_UINT8_ARRAY(ier, RXICUState, NR_IRQS / 8), + VMSTATE_UINT8_ARRAY(ipr, RXICUState, 142), + VMSTATE_UINT8_ARRAY(dmasr, RXICUState, 4), + VMSTATE_UINT16(fir, RXICUState), + VMSTATE_UINT8(nmisr, RXICUState), + VMSTATE_UINT8(nmier, RXICUState), + VMSTATE_UINT8(nmiclr, RXICUState), + VMSTATE_UINT8(nmicr, RXICUState), + VMSTATE_INT16(req_irq, RXICUState), + VMSTATE_END_OF_LIST() + } +}; + +static Property rxicu_properties[] = { + DEFINE_PROP_ARRAY("ipr-map", RXICUState, nr_irqs, map, + qdev_prop_uint8, uint8_t), + DEFINE_PROP_ARRAY("trigger-level", RXICUState, nr_sense, init_sense, + qdev_prop_uint8, uint8_t), + DEFINE_PROP_END_OF_LIST(), +}; + +static void rxicu_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = rxicu_realize; + dc->vmsd = &vmstate_rxicu; + device_class_set_props(dc, rxicu_properties); +} + +static const TypeInfo rxicu_info = { + .name = TYPE_RX_ICU, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(RXICUState), + .instance_init = rxicu_init, + .instance_finalize = rxicu_fini, + .class_init = rxicu_class_init, +}; + +static void rxicu_register_types(void) +{ + type_register_static(&rxicu_info); +} + +type_init(rxicu_register_types) diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig index a189d6fedd..f562342bab 100644 --- a/hw/intc/Kconfig +++ b/hw/intc/Kconfig @@ -61,3 +61,6 @@ config S390_FLIC_KVM config OMPIC bool + +config RX_ICU + bool diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index f726d87532..98a0b0f3bc 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -20,6 +20,7 @@ common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_dist.o common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_redist.o common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_its_common.o common-obj-$(CONFIG_OPENPIC) += openpic.o +common-obj-$(CONFIG_RX_ICU) += rx_icu.o common-obj-y += intc.o obj-$(CONFIG_APIC) += apic.o apic_common.o From patchwork Mon Jun 1 16:14:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Patchwork-Id: 281540 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57D6AC433DF for ; Mon, 1 Jun 2020 16:18:25 +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 10F89206C3 for ; Mon, 1 Jun 2020 16:18:25 +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="UAEcn3bS" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 10F89206C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=amsat.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:35992 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jfn8q-0001dC-91 for qemu-devel@archiver.kernel.org; Mon, 01 Jun 2020 12:18:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50906) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jfn5Q-00059b-9y for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:52 -0400 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]:38608) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jfn5O-0001W5-Sq for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:51 -0400 Received: by mail-wm1-x32a.google.com with SMTP id f185so90858wmf.3 for ; Mon, 01 Jun 2020 09:14:50 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=ErceqITnGhLCPYkCifzq710iEZfD+Gb1EMJUjvYvPyk=; b=UAEcn3bS8BDbr2dRRdDILGIMQavd9FiDzG9h7aMZNnYWtMzHEfcD2vKkM16q2JqhnK sztjGewD7iEw+zAPedHXak8euOAHscfcOMAHsH//J6nE+tBikRVHZmPMqLXVaO/YbC7X P16tqMfngPIk1Gl1xHgWuPX99t/r4NCXNI0cEiQ7XNGK1LjGHYXMFywAONSHAfEIvyqz Hc0COr+YCQxf3TKA+GfL2QEQYDacXWGCLoLmY1oVOwcPe5rG2131LuQogSZg00NhCpHn ROPh4FpnRN7t7ErzwPaas4c11iabqD6CZLPvlJRrOeVPRtGbBKV7Z0bNSeWBMkpm41yC DVsQ== 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:mime-version:content-transfer-encoding; bh=ErceqITnGhLCPYkCifzq710iEZfD+Gb1EMJUjvYvPyk=; b=KQbDz+G2VhHTOK6qgCgk1IgOm0F3eG8u0qLy9SDo6y/TKh8hiTbv7AEUTCf9GsH8LP 8PYvY7/ajLCsm2WfRxIC2q+2zkxJamArhg6FWUTmXmhNUbMQU5VZH4zzmodO4Fnbzk0r KYHb5lU2kNJ0GJRaZDp5woN2s3YX1Uefaunc/rBfErhrZuaa/D1OiR6aVRJVgwjVsvSj guQvokerP5jDj/HFXKXsBFNWVOgRfKL3HPO/9cGhacrkHr1sMsB/cw4rWe1wltxZnS7N ACgWqudLAvnRvWvftN9hSET6EU106TcshPkMiTyZkydoZY0cvVJSU7DDiZmFZiOtHijO UVAw== X-Gm-Message-State: AOAM531WDniGTBjOHX3L1Q2DfPS3uSx7GOiGSUA0Ky1NiFIjpBnVS1gc aY1vciKr7O/2zJ627wb8xNQ= X-Google-Smtp-Source: ABdhPJxT2KfLyf1O+BdbNLNGQzvFhnfEmVdrHDW2EybFYWktiSNpjg9HXQrXbcePw4/HL4QiM/L52Q== X-Received: by 2002:a1c:c908:: with SMTP id f8mr98912wmb.150.1591028089362; Mon, 01 Jun 2020 09:14:49 -0700 (PDT) Received: from localhost.localdomain (43.red-83-51-162.dynamicip.rima-tde.net. [83.51.162.43]) by smtp.gmail.com with ESMTPSA id a6sm21309896wrn.38.2020.06.01.09.14.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jun 2020 09:14:48 -0700 (PDT) From: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= To: Richard Henderson , qemu-devel@nongnu.org, Yoshinori Sato Subject: [PATCH 04/12] hw/timer: RX62N 8-Bit timer (TMR) Date: Mon, 1 Jun 2020 18:14:33 +0200 Message-Id: <20200601161441.8086-5-f4bug@amsat.org> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20200601161441.8086-1-f4bug@amsat.org> References: <20200601161441.8086-1-f4bug@amsat.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32a; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-x32a.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action 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: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Paolo Bonzini , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?b?w6k=?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Yoshinori Sato renesas_tmr: 8bit timer modules. This part use many renesas's CPU. Hardware manual. https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01uh0033ej0140_rx62n.pdf Signed-off-by: Yoshinori Sato Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-Id: <20200224141923.82118-16-ysato@users.sourceforge.jp> [PMD: Split from CMT, filled VMStateField for migration] Signed-off-by: Philippe Mathieu-Daudé --- include/hw/timer/renesas_tmr.h | 55 ++++ hw/timer/renesas_tmr.c | 477 +++++++++++++++++++++++++++++++++ hw/timer/Kconfig | 3 + hw/timer/Makefile.objs | 1 + 4 files changed, 536 insertions(+) create mode 100644 include/hw/timer/renesas_tmr.h create mode 100644 hw/timer/renesas_tmr.c diff --git a/include/hw/timer/renesas_tmr.h b/include/hw/timer/renesas_tmr.h new file mode 100644 index 0000000000..cf3baa7a28 --- /dev/null +++ b/include/hw/timer/renesas_tmr.h @@ -0,0 +1,55 @@ +/* + * Renesas 8bit timer Object + * + * Copyright (c) 2018 Yoshinori Sato + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_TIMER_RENESAS_TMR_H +#define HW_TIMER_RENESAS_TMR_H + +#include "qemu/timer.h" +#include "hw/sysbus.h" + +#define TYPE_RENESAS_TMR "renesas-tmr" +#define RTMR(obj) OBJECT_CHECK(RTMRState, (obj), TYPE_RENESAS_TMR) + +enum timer_event { + cmia = 0, + cmib = 1, + ovi = 2, + none = 3, + TMR_NR_EVENTS = 4 +}; + +enum { + TMR_CH = 2, + TMR_NR_IRQ = 3 * TMR_CH +}; + +typedef struct RTMRState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + uint64_t input_freq; + MemoryRegion memory; + + int64_t tick; + uint8_t tcnt[TMR_CH]; + uint8_t tcora[TMR_CH]; + uint8_t tcorb[TMR_CH]; + uint8_t tcr[TMR_CH]; + uint8_t tccr[TMR_CH]; + uint8_t tcor[TMR_CH]; + uint8_t tcsr[TMR_CH]; + int64_t div_round[TMR_CH]; + uint8_t next[TMR_CH]; + qemu_irq cmia[TMR_CH]; + qemu_irq cmib[TMR_CH]; + qemu_irq ovi[TMR_CH]; + QEMUTimer timer[TMR_CH]; +} RTMRState; + +#endif diff --git a/hw/timer/renesas_tmr.c b/hw/timer/renesas_tmr.c new file mode 100644 index 0000000000..446f2eacdd --- /dev/null +++ b/hw/timer/renesas_tmr.c @@ -0,0 +1,477 @@ +/* + * Renesas 8bit timer + * + * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware + * (Rev.1.40 R01UH0033EJ0140) + * + * Copyright (c) 2019 Yoshinori Sato + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/irq.h" +#include "hw/registerfields.h" +#include "hw/qdev-properties.h" +#include "hw/timer/renesas_tmr.h" +#include "migration/vmstate.h" + +REG8(TCR, 0) + FIELD(TCR, CCLR, 3, 2) + FIELD(TCR, OVIE, 5, 1) + FIELD(TCR, CMIEA, 6, 1) + FIELD(TCR, CMIEB, 7, 1) +REG8(TCSR, 2) + FIELD(TCSR, OSA, 0, 2) + FIELD(TCSR, OSB, 2, 2) + FIELD(TCSR, ADTE, 4, 2) +REG8(TCORA, 4) +REG8(TCORB, 6) +REG8(TCNT, 8) +REG8(TCCR, 10) + FIELD(TCCR, CKS, 0, 3) + FIELD(TCCR, CSS, 3, 2) + FIELD(TCCR, TMRIS, 7, 1) + +#define INTERNAL 0x01 +#define CASCADING 0x03 +#define CCLR_A 0x01 +#define CCLR_B 0x02 + +static const int clkdiv[] = {0, 1, 2, 8, 32, 64, 1024, 8192}; + +static uint8_t concat_reg(uint8_t *reg) +{ + return (reg[0] << 8) | reg[1]; +} + +static void update_events(RTMRState *tmr, int ch) +{ + uint16_t diff[TMR_NR_EVENTS], min; + int64_t next_time; + int i, event; + + if (tmr->tccr[ch] == 0) { + return ; + } + if (FIELD_EX8(tmr->tccr[ch], TCCR, CSS) == 0) { + /* external clock mode */ + /* event not happened */ + return ; + } + if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) == CASCADING) { + /* cascading mode */ + if (ch == 1) { + tmr->next[ch] = none; + return ; + } + diff[cmia] = concat_reg(tmr->tcora) - concat_reg(tmr->tcnt); + diff[cmib] = concat_reg(tmr->tcorb) - concat_reg(tmr->tcnt); + diff[ovi] = 0x10000 - concat_reg(tmr->tcnt); + } else { + /* separate mode */ + diff[cmia] = tmr->tcora[ch] - tmr->tcnt[ch]; + diff[cmib] = tmr->tcorb[ch] - tmr->tcnt[ch]; + diff[ovi] = 0x100 - tmr->tcnt[ch]; + } + /* Search for the most recently occurring event. */ + for (event = 0, min = diff[0], i = 1; i < none; i++) { + if (min > diff[i]) { + event = i; + min = diff[i]; + } + } + tmr->next[ch] = event; + next_time = diff[event]; + next_time *= clkdiv[FIELD_EX8(tmr->tccr[ch], TCCR, CKS)]; + next_time *= NANOSECONDS_PER_SECOND; + next_time /= tmr->input_freq; + next_time += qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + timer_mod(&tmr->timer[ch], next_time); +} + +static int elapsed_time(RTMRState *tmr, int ch, int64_t delta) +{ + int divrate = clkdiv[FIELD_EX8(tmr->tccr[ch], TCCR, CKS)]; + int et; + + tmr->div_round[ch] += delta; + if (divrate > 0) { + et = tmr->div_round[ch] / divrate; + tmr->div_round[ch] %= divrate; + } else { + /* disble clock. so no update */ + et = 0; + } + return et; +} + +static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch) +{ + int64_t delta, now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + int elapsed, ovf = 0; + uint16_t tcnt[2]; + uint32_t ret; + + delta = (now - tmr->tick) * NANOSECONDS_PER_SECOND / tmr->input_freq; + if (delta > 0) { + tmr->tick = now; + + if (FIELD_EX8(tmr->tccr[1], TCCR, CSS) == INTERNAL) { + /* timer1 count update */ + elapsed = elapsed_time(tmr, 1, delta); + if (elapsed >= 0x100) { + ovf = elapsed >> 8; + } + tcnt[1] = tmr->tcnt[1] + (elapsed & 0xff); + } + switch (FIELD_EX8(tmr->tccr[0], TCCR, CSS)) { + case INTERNAL: + elapsed = elapsed_time(tmr, 0, delta); + tcnt[0] = tmr->tcnt[0] + elapsed; + break; + case CASCADING: + if (ovf > 0) { + tcnt[0] = tmr->tcnt[0] + ovf; + } + break; + } + } else { + tcnt[0] = tmr->tcnt[0]; + tcnt[1] = tmr->tcnt[1]; + } + if (size == 1) { + return tcnt[ch]; + } else { + ret = 0; + ret = deposit32(ret, 0, 8, tcnt[1]); + ret = deposit32(ret, 8, 8, tcnt[0]); + return ret; + } +} + +static uint8_t read_tccr(uint8_t r) +{ + uint8_t tccr = 0; + tccr = FIELD_DP8(tccr, TCCR, TMRIS, + FIELD_EX8(r, TCCR, TMRIS)); + tccr = FIELD_DP8(tccr, TCCR, CSS, + FIELD_EX8(r, TCCR, CSS)); + tccr = FIELD_DP8(tccr, TCCR, CKS, + FIELD_EX8(r, TCCR, CKS)); + return tccr; +} + +static uint64_t tmr_read(void *opaque, hwaddr addr, unsigned size) +{ + RTMRState *tmr = opaque; + int ch = addr & 1; + uint64_t ret; + + if (size == 2 && (ch != 0 || addr == A_TCR || addr == A_TCSR)) { + qemu_log_mask(LOG_GUEST_ERROR, "renesas_tmr: Invalid read size 0x%" + HWADDR_PRIX "\n", + addr); + return UINT64_MAX; + } + switch (addr & 0x0e) { + case A_TCR: + ret = 0; + ret = FIELD_DP8(ret, TCR, CCLR, + FIELD_EX8(tmr->tcr[ch], TCR, CCLR)); + ret = FIELD_DP8(ret, TCR, OVIE, + FIELD_EX8(tmr->tcr[ch], TCR, OVIE)); + ret = FIELD_DP8(ret, TCR, CMIEA, + FIELD_EX8(tmr->tcr[ch], TCR, CMIEA)); + ret = FIELD_DP8(ret, TCR, CMIEB, + FIELD_EX8(tmr->tcr[ch], TCR, CMIEB)); + return ret; + case A_TCSR: + ret = 0; + ret = FIELD_DP8(ret, TCSR, OSA, + FIELD_EX8(tmr->tcsr[ch], TCSR, OSA)); + ret = FIELD_DP8(ret, TCSR, OSB, + FIELD_EX8(tmr->tcsr[ch], TCSR, OSB)); + switch (ch) { + case 0: + ret = FIELD_DP8(ret, TCSR, ADTE, + FIELD_EX8(tmr->tcsr[ch], TCSR, ADTE)); + break; + case 1: /* CH1 ADTE unimplement always 1 */ + ret = FIELD_DP8(ret, TCSR, ADTE, 1); + break; + } + return ret; + case A_TCORA: + if (size == 1) { + return tmr->tcora[ch]; + } else if (ch == 0) { + return concat_reg(tmr->tcora); + } + case A_TCORB: + if (size == 1) { + return tmr->tcorb[ch]; + } else { + return concat_reg(tmr->tcorb); + } + case A_TCNT: + return read_tcnt(tmr, size, ch); + case A_TCCR: + if (size == 1) { + return read_tccr(tmr->tccr[ch]); + } else { + return read_tccr(tmr->tccr[0]) << 8 | read_tccr(tmr->tccr[1]); + } + default: + qemu_log_mask(LOG_UNIMP, "renesas_tmr: Register 0x%" HWADDR_PRIX + " not implemented\n", + addr); + break; + } + return UINT64_MAX; +} + +static void tmr_write_count(RTMRState *tmr, int ch, unsigned size, + uint8_t *reg, uint64_t val) +{ + if (size == 1) { + reg[ch] = val; + update_events(tmr, ch); + } else { + reg[0] = extract32(val, 8, 8); + reg[1] = extract32(val, 0, 8); + update_events(tmr, 0); + update_events(tmr, 1); + } +} + +static void tmr_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) +{ + RTMRState *tmr = opaque; + int ch = addr & 1; + + if (size == 2 && (ch != 0 || addr == A_TCR || addr == A_TCSR)) { + qemu_log_mask(LOG_GUEST_ERROR, + "renesas_tmr: Invalid write size 0x%" HWADDR_PRIX "\n", + addr); + return; + } + switch (addr & 0x0e) { + case A_TCR: + tmr->tcr[ch] = val; + break; + case A_TCSR: + tmr->tcsr[ch] = val; + break; + case A_TCORA: + tmr_write_count(tmr, ch, size, tmr->tcora, val); + break; + case A_TCORB: + tmr_write_count(tmr, ch, size, tmr->tcorb, val); + break; + case A_TCNT: + tmr_write_count(tmr, ch, size, tmr->tcnt, val); + break; + case A_TCCR: + tmr_write_count(tmr, ch, size, tmr->tccr, val); + break; + default: + qemu_log_mask(LOG_UNIMP, "renesas_tmr: Register 0x%" HWADDR_PRIX + " not implemented\n", + addr); + break; + } +} + +static const MemoryRegionOps tmr_ops = { + .write = tmr_write, + .read = tmr_read, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 2, + }, + .valid = { + .min_access_size = 1, + .max_access_size = 2, + }, +}; + +static void timer_events(RTMRState *tmr, int ch); + +static uint16_t issue_event(RTMRState *tmr, int ch, int sz, + uint16_t tcnt, uint16_t tcora, uint16_t tcorb) +{ + uint16_t ret = tcnt; + + switch (tmr->next[ch]) { + case none: + break; + case cmia: + if (tcnt >= tcora) { + if (FIELD_EX8(tmr->tcr[ch], TCR, CCLR) == CCLR_A) { + ret = tcnt - tcora; + } + if (FIELD_EX8(tmr->tcr[ch], TCR, CMIEA)) { + qemu_irq_pulse(tmr->cmia[ch]); + } + if (sz == 8 && ch == 0 && + FIELD_EX8(tmr->tccr[1], TCCR, CSS) == CASCADING) { + tmr->tcnt[1]++; + timer_events(tmr, 1); + } + } + break; + case cmib: + if (tcnt >= tcorb) { + if (FIELD_EX8(tmr->tcr[ch], TCR, CCLR) == CCLR_B) { + ret = tcnt - tcorb; + } + if (FIELD_EX8(tmr->tcr[ch], TCR, CMIEB)) { + qemu_irq_pulse(tmr->cmib[ch]); + } + } + break; + case ovi: + if ((tcnt >= (1 << sz)) && FIELD_EX8(tmr->tcr[ch], TCR, OVIE)) { + qemu_irq_pulse(tmr->ovi[ch]); + } + break; + default: + g_assert_not_reached(); + } + return ret; +} + +static void timer_events(RTMRState *tmr, int ch) +{ + uint16_t tcnt; + + tmr->tcnt[ch] = read_tcnt(tmr, 1, ch); + if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) != CASCADING) { + tmr->tcnt[ch] = issue_event(tmr, ch, 8, + tmr->tcnt[ch], + tmr->tcora[ch], + tmr->tcorb[ch]) & 0xff; + } else { + if (ch == 1) { + return ; + } + tcnt = issue_event(tmr, ch, 16, + concat_reg(tmr->tcnt), + concat_reg(tmr->tcora), + concat_reg(tmr->tcorb)); + tmr->tcnt[0] = (tcnt >> 8) & 0xff; + tmr->tcnt[1] = tcnt & 0xff; + } + update_events(tmr, ch); +} + +static void timer_event0(void *opaque) +{ + RTMRState *tmr = opaque; + + timer_events(tmr, 0); +} + +static void timer_event1(void *opaque) +{ + RTMRState *tmr = opaque; + + timer_events(tmr, 1); +} + +static void rtmr_reset(DeviceState *dev) +{ + RTMRState *tmr = RTMR(dev); + tmr->tcr[0] = tmr->tcr[1] = 0x00; + tmr->tcsr[0] = 0x00; + tmr->tcsr[1] = 0x10; + tmr->tcnt[0] = tmr->tcnt[1] = 0x00; + tmr->tcora[0] = tmr->tcora[1] = 0xff; + tmr->tcorb[0] = tmr->tcorb[1] = 0xff; + tmr->tccr[0] = tmr->tccr[1] = 0x00; + tmr->next[0] = tmr->next[1] = none; + tmr->tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); +} + +static void rtmr_init(Object *obj) +{ + SysBusDevice *d = SYS_BUS_DEVICE(obj); + RTMRState *tmr = RTMR(obj); + int i; + + memory_region_init_io(&tmr->memory, OBJECT(tmr), &tmr_ops, + tmr, "renesas-tmr", 0x10); + sysbus_init_mmio(d, &tmr->memory); + + for (i = 0; i < ARRAY_SIZE(tmr->ovi); i++) { + sysbus_init_irq(d, &tmr->cmia[i]); + sysbus_init_irq(d, &tmr->cmib[i]); + sysbus_init_irq(d, &tmr->ovi[i]); + } + timer_init_ns(&tmr->timer[0], QEMU_CLOCK_VIRTUAL, timer_event0, tmr); + timer_init_ns(&tmr->timer[1], QEMU_CLOCK_VIRTUAL, timer_event1, tmr); +} + +static const VMStateDescription vmstate_rtmr = { + .name = "rx-tmr", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_INT64(tick, RTMRState), + VMSTATE_UINT8_ARRAY(tcnt, RTMRState, TMR_CH), + VMSTATE_UINT8_ARRAY(tcora, RTMRState, TMR_CH), + VMSTATE_UINT8_ARRAY(tcorb, RTMRState, TMR_CH), + VMSTATE_UINT8_ARRAY(tcr, RTMRState, TMR_CH), + VMSTATE_UINT8_ARRAY(tccr, RTMRState, TMR_CH), + VMSTATE_UINT8_ARRAY(tcor, RTMRState, TMR_CH), + VMSTATE_UINT8_ARRAY(tcsr, RTMRState, TMR_CH), + VMSTATE_INT64_ARRAY(div_round, RTMRState, TMR_CH), + VMSTATE_UINT8_ARRAY(next, RTMRState, TMR_CH), + VMSTATE_TIMER_ARRAY(timer, RTMRState, TMR_CH), + VMSTATE_END_OF_LIST() + } +}; + +static Property rtmr_properties[] = { + DEFINE_PROP_UINT64("input-freq", RTMRState, input_freq, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void rtmr_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->vmsd = &vmstate_rtmr; + dc->reset = rtmr_reset; + device_class_set_props(dc, rtmr_properties); +} + +static const TypeInfo rtmr_info = { + .name = TYPE_RENESAS_TMR, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(RTMRState), + .instance_init = rtmr_init, + .class_init = rtmr_class_init, +}; + +static void rtmr_register_types(void) +{ + type_register_static(&rtmr_info); +} + +type_init(rtmr_register_types) diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig index 59b3f44d69..7039c2a686 100644 --- a/hw/timer/Kconfig +++ b/hw/timer/Kconfig @@ -35,3 +35,6 @@ config CMSDK_APB_TIMER config CMSDK_APB_DUALTIMER bool select PTIMER + +config RENESAS_TMR + bool diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index dece235fd7..44fb47a433 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -23,6 +23,7 @@ common-obj-$(CONFIG_OMAP) += omap_gptimer.o common-obj-$(CONFIG_OMAP) += omap_synctimer.o common-obj-$(CONFIG_PXA2XX) += pxa2xx_timer.o common-obj-$(CONFIG_SH4) += sh_timer.o +common-obj-$(CONFIG_RENESAS_TMR) += renesas_tmr.o common-obj-$(CONFIG_DIGIC) += digic-timer.o common-obj-$(CONFIG_MIPS_CPS) += mips_gictimer.o From patchwork Mon Jun 1 16:14:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Patchwork-Id: 281538 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF3D9C433E0 for ; Mon, 1 Jun 2020 16:20:28 +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 68291206C3 for ; Mon, 1 Jun 2020 16:20:28 +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="FzwcUeYW" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 68291206C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=amsat.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:43472 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jfnAp-0004f5-71 for qemu-devel@archiver.kernel.org; Mon, 01 Jun 2020 12:20:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50914) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jfn5R-0005D4-Il for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:53 -0400 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]:50384) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jfn5Q-0001WK-E9 for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:53 -0400 Received: by mail-wm1-x32a.google.com with SMTP id v19so98909wmj.0 for ; Mon, 01 Jun 2020 09:14:52 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=XZACxZccAAi2TopI+c0OP5VJ17b3bi19ygcofM3uJGA=; b=FzwcUeYW2+67f69pfit/uM1xweSHfFruIv7n29na2PvU8rO23rzqGGoFo0I6Mgn6ER 7kslkyVDV6NPFXUBVZkqACwthSqUVLVtWq6uSnWOeOdFS6CqGZshAMsHxhnfMdB5163V Bsfmxx0ROVLAV4R/VxVCmFwB2kVTqaxA/hqD0xb+QfKjdy5iEDf8/YQQmd48fOjaK3m6 svx46cp015xYXUqkLMmU1pm8c5zMQCjFvh1WnLoOvHBPYmFahDLCClkr40z/NFHTPwsi r2BhZHtE0h9Ae1+OcI2iCqDBA5C8DQsvw9HSLCLRwNokd4RIkNlNefIudWWdtqgwfelt VCsQ== 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:mime-version:content-transfer-encoding; bh=XZACxZccAAi2TopI+c0OP5VJ17b3bi19ygcofM3uJGA=; b=Uh3NczRmDTRf3fDraxloxZoNTNng+HkyU34JCpUUkJLbG7UjT1tRUrXyVrwu/2/zfv mXi9YcHlYycphC7l9w0DuezCTprvskOYwN1QnAweZobjMrURKMOAaxvQoMM/Et4DhRr6 mOQuqKxrptnLhMfgcN33biglQezKZ3dbi2LK/ujLseNrkz9X678gnGkEjDpGrHS+47Mv 9n7nhIA/3PBN2/DAmzWkv0GtG74OvvNb3y6K8ktV/GymWQivO2O5dM6OAi+SaAcyX8OC bDQboA9ejpHmEXzDw+a+4Axh+JHYdJXIhILe+N/ulDt66CICzcBXZ5nvutvGd19qaxuH hWvQ== X-Gm-Message-State: AOAM531hBqemI2AC/RyyH1J3v9i3Gj3n5AsGk57qDgKaJZaog7DgzdcH UYpQ+pddUkycR8o8j3R6aGk= X-Google-Smtp-Source: ABdhPJwRdNIqEYeWvz2xgbQzZPCIbKgtd4BA5VEJR7pzvBgCrBmUq5KPA4N2iRX6pWlP/EU7yISMog== X-Received: by 2002:a7b:cb4e:: with SMTP id v14mr122849wmj.54.1591028091100; Mon, 01 Jun 2020 09:14:51 -0700 (PDT) Received: from localhost.localdomain (43.red-83-51-162.dynamicip.rima-tde.net. [83.51.162.43]) by smtp.gmail.com with ESMTPSA id a6sm21309896wrn.38.2020.06.01.09.14.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jun 2020 09:14:49 -0700 (PDT) From: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= To: Richard Henderson , qemu-devel@nongnu.org, Yoshinori Sato Subject: [PATCH 05/12] hw/timer: RX62N compare match timer (CMT) Date: Mon, 1 Jun 2020 18:14:34 +0200 Message-Id: <20200601161441.8086-6-f4bug@amsat.org> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20200601161441.8086-1-f4bug@amsat.org> References: <20200601161441.8086-1-f4bug@amsat.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32a; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-x32a.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action 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: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Paolo Bonzini , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?b?w6k=?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Yoshinori Sato renesas_cmt: 16bit compare match timer modules. This part use many renesas's CPU. Hardware manual. https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01uh0033ej0140_rx62n.pdf Signed-off-by: Yoshinori Sato Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-Id: <20200224141923.82118-16-ysato@users.sourceforge.jp> [PMD: Split from TMR, filled VMStateField for migration] Signed-off-by: Philippe Mathieu-Daudé --- include/hw/timer/renesas_cmt.h | 40 +++++ hw/timer/renesas_cmt.c | 283 +++++++++++++++++++++++++++++++++ hw/timer/Kconfig | 3 + hw/timer/Makefile.objs | 1 + 4 files changed, 327 insertions(+) create mode 100644 include/hw/timer/renesas_cmt.h create mode 100644 hw/timer/renesas_cmt.c diff --git a/include/hw/timer/renesas_cmt.h b/include/hw/timer/renesas_cmt.h new file mode 100644 index 0000000000..e28a15cb38 --- /dev/null +++ b/include/hw/timer/renesas_cmt.h @@ -0,0 +1,40 @@ +/* + * Renesas Compare-match timer Object + * + * Copyright (c) 2019 Yoshinori Sato + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_TIMER_RENESAS_CMT_H +#define HW_TIMER_RENESAS_CMT_H + +#include "qemu/timer.h" +#include "hw/sysbus.h" + +#define TYPE_RENESAS_CMT "renesas-cmt" +#define RCMT(obj) OBJECT_CHECK(RCMTState, (obj), TYPE_RENESAS_CMT) + +enum { + CMT_CH = 2, + CMT_NR_IRQ = 1 * CMT_CH +}; + +typedef struct RCMTState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + uint64_t input_freq; + MemoryRegion memory; + + uint16_t cmstr; + uint16_t cmcr[CMT_CH]; + uint16_t cmcnt[CMT_CH]; + uint16_t cmcor[CMT_CH]; + int64_t tick[CMT_CH]; + qemu_irq cmi[CMT_CH]; + QEMUTimer timer[CMT_CH]; +} RCMTState; + +#endif diff --git a/hw/timer/renesas_cmt.c b/hw/timer/renesas_cmt.c new file mode 100644 index 0000000000..2e0fd21a36 --- /dev/null +++ b/hw/timer/renesas_cmt.c @@ -0,0 +1,283 @@ +/* + * Renesas 16bit Compare-match timer + * + * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware + * (Rev.1.40 R01UH0033EJ0140) + * + * Copyright (c) 2019 Yoshinori Sato + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/irq.h" +#include "hw/registerfields.h" +#include "hw/qdev-properties.h" +#include "hw/timer/renesas_cmt.h" +#include "migration/vmstate.h" + +/* + * +0 CMSTR - common control + * +2 CMCR - ch0 + * +4 CMCNT - ch0 + * +6 CMCOR - ch0 + * +8 CMCR - ch1 + * +10 CMCNT - ch1 + * +12 CMCOR - ch1 + * If we think that the address of CH 0 has an offset of +2, + * we can treat it with the same address as CH 1, so define it like that. + */ +REG16(CMSTR, 0) + FIELD(CMSTR, STR0, 0, 1) + FIELD(CMSTR, STR1, 1, 1) + FIELD(CMSTR, STR, 0, 2) +/* This addeess is channel offset */ +REG16(CMCR, 0) + FIELD(CMCR, CKS, 0, 2) + FIELD(CMCR, CMIE, 6, 1) +REG16(CMCNT, 2) +REG16(CMCOR, 4) + +static void update_events(RCMTState *cmt, int ch) +{ + int64_t next_time; + + if ((cmt->cmstr & (1 << ch)) == 0) { + /* count disable, so not happened next event. */ + return ; + } + next_time = cmt->cmcor[ch] - cmt->cmcnt[ch]; + next_time *= NANOSECONDS_PER_SECOND; + next_time /= cmt->input_freq; + /* + * CKS -> div rate + * 0 -> 8 (1 << 3) + * 1 -> 32 (1 << 5) + * 2 -> 128 (1 << 7) + * 3 -> 512 (1 << 9) + */ + next_time *= 1 << (3 + FIELD_EX16(cmt->cmcr[ch], CMCR, CKS) * 2); + next_time += qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + timer_mod(&cmt->timer[ch], next_time); +} + +static int64_t read_cmcnt(RCMTState *cmt, int ch) +{ + int64_t delta, now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + + if (cmt->cmstr & (1 << ch)) { + delta = (now - cmt->tick[ch]); + delta /= NANOSECONDS_PER_SECOND; + delta /= cmt->input_freq; + delta /= 1 << (3 + FIELD_EX16(cmt->cmcr[ch], CMCR, CKS) * 2); + cmt->tick[ch] = now; + return cmt->cmcnt[ch] + delta; + } else { + return cmt->cmcnt[ch]; + } +} + +static uint64_t cmt_read(void *opaque, hwaddr offset, unsigned size) +{ + RCMTState *cmt = opaque; + int ch = offset / 0x08; + uint64_t ret; + + if (offset == A_CMSTR) { + ret = 0; + ret = FIELD_DP16(ret, CMSTR, STR, + FIELD_EX16(cmt->cmstr, CMSTR, STR)); + return ret; + } else { + offset &= 0x07; + if (ch == 0) { + offset -= 0x02; + } + switch (offset) { + case A_CMCR: + ret = 0; + ret = FIELD_DP16(ret, CMCR, CKS, + FIELD_EX16(cmt->cmstr, CMCR, CKS)); + ret = FIELD_DP16(ret, CMCR, CMIE, + FIELD_EX16(cmt->cmstr, CMCR, CMIE)); + return ret; + case A_CMCNT: + return read_cmcnt(cmt, ch); + case A_CMCOR: + return cmt->cmcor[ch]; + } + } + qemu_log_mask(LOG_UNIMP, "renesas_cmt: Register 0x%" HWADDR_PRIX " " + "not implemented\n", + offset); + return UINT64_MAX; +} + +static void start_stop(RCMTState *cmt, int ch, int st) +{ + if (st) { + update_events(cmt, ch); + } else { + timer_del(&cmt->timer[ch]); + } +} + +static void cmt_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) +{ + RCMTState *cmt = opaque; + int ch = offset / 0x08; + + if (offset == A_CMSTR) { + cmt->cmstr = FIELD_EX16(val, CMSTR, STR); + start_stop(cmt, 0, FIELD_EX16(cmt->cmstr, CMSTR, STR0)); + start_stop(cmt, 1, FIELD_EX16(cmt->cmstr, CMSTR, STR1)); + } else { + offset &= 0x07; + if (ch == 0) { + offset -= 0x02; + } + switch (offset) { + case A_CMCR: + cmt->cmcr[ch] = FIELD_DP16(cmt->cmcr[ch], CMCR, CKS, + FIELD_EX16(val, CMCR, CKS)); + cmt->cmcr[ch] = FIELD_DP16(cmt->cmcr[ch], CMCR, CMIE, + FIELD_EX16(val, CMCR, CMIE)); + break; + case 2: + cmt->cmcnt[ch] = val; + break; + case 4: + cmt->cmcor[ch] = val; + break; + default: + qemu_log_mask(LOG_UNIMP, "renesas_cmt: Register 0x%" HWADDR_PRIX " " + "not implemented\n", + offset); + return; + } + if (FIELD_EX16(cmt->cmstr, CMSTR, STR) & (1 << ch)) { + update_events(cmt, ch); + } + } +} + +static const MemoryRegionOps cmt_ops = { + .write = cmt_write, + .read = cmt_read, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 2, + .max_access_size = 2, + }, + .valid = { + .min_access_size = 2, + .max_access_size = 2, + }, +}; + +static void timer_events(RCMTState *cmt, int ch) +{ + cmt->cmcnt[ch] = 0; + cmt->tick[ch] = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + update_events(cmt, ch); + if (FIELD_EX16(cmt->cmcr[ch], CMCR, CMIE)) { + qemu_irq_pulse(cmt->cmi[ch]); + } +} + +static void timer_event0(void *opaque) +{ + RCMTState *cmt = opaque; + + timer_events(cmt, 0); +} + +static void timer_event1(void *opaque) +{ + RCMTState *cmt = opaque; + + timer_events(cmt, 1); +} + +static void rcmt_reset(DeviceState *dev) +{ + RCMTState *cmt = RCMT(dev); + cmt->cmstr = 0; + cmt->cmcr[0] = cmt->cmcr[1] = 0; + cmt->cmcnt[0] = cmt->cmcnt[1] = 0; + cmt->cmcor[0] = cmt->cmcor[1] = 0xffff; +} + +static void rcmt_init(Object *obj) +{ + SysBusDevice *d = SYS_BUS_DEVICE(obj); + RCMTState *cmt = RCMT(obj); + int i; + + memory_region_init_io(&cmt->memory, OBJECT(cmt), &cmt_ops, + cmt, "renesas-cmt", 0x10); + sysbus_init_mmio(d, &cmt->memory); + + for (i = 0; i < ARRAY_SIZE(cmt->cmi); i++) { + sysbus_init_irq(d, &cmt->cmi[i]); + } + timer_init_ns(&cmt->timer[0], QEMU_CLOCK_VIRTUAL, timer_event0, cmt); + timer_init_ns(&cmt->timer[1], QEMU_CLOCK_VIRTUAL, timer_event1, cmt); +} + +static const VMStateDescription vmstate_rcmt = { + .name = "rx-cmt", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT16(cmstr, RCMTState), + VMSTATE_UINT16_ARRAY(cmcr, RCMTState, CMT_CH), + VMSTATE_UINT16_ARRAY(cmcnt, RCMTState, CMT_CH), + VMSTATE_UINT16_ARRAY(cmcor, RCMTState, CMT_CH), + VMSTATE_INT64_ARRAY(tick, RCMTState, CMT_CH), + VMSTATE_TIMER_ARRAY(timer, RCMTState, CMT_CH), + VMSTATE_END_OF_LIST() + } +}; + +static Property rcmt_properties[] = { + DEFINE_PROP_UINT64("input-freq", RCMTState, input_freq, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void rcmt_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->vmsd = &vmstate_rcmt; + dc->reset = rcmt_reset; + device_class_set_props(dc, rcmt_properties); +} + +static const TypeInfo rcmt_info = { + .name = TYPE_RENESAS_CMT, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(RCMTState), + .instance_init = rcmt_init, + .class_init = rcmt_class_init, +}; + +static void rcmt_register_types(void) +{ + type_register_static(&rcmt_info); +} + +type_init(rcmt_register_types) diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig index 7039c2a686..59a667c503 100644 --- a/hw/timer/Kconfig +++ b/hw/timer/Kconfig @@ -38,3 +38,6 @@ config CMSDK_APB_DUALTIMER config RENESAS_TMR bool + +config RENESAS_CMT + bool diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index 44fb47a433..a39f6ec0c2 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -24,6 +24,7 @@ common-obj-$(CONFIG_OMAP) += omap_synctimer.o common-obj-$(CONFIG_PXA2XX) += pxa2xx_timer.o common-obj-$(CONFIG_SH4) += sh_timer.o common-obj-$(CONFIG_RENESAS_TMR) += renesas_tmr.o +common-obj-$(CONFIG_RENESAS_CMT) += renesas_cmt.o common-obj-$(CONFIG_DIGIC) += digic-timer.o common-obj-$(CONFIG_MIPS_CPS) += mips_gictimer.o From patchwork Mon Jun 1 16:14:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Patchwork-Id: 281537 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6768DC433E0 for ; Mon, 1 Jun 2020 16:21:50 +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 208DA206C3 for ; Mon, 1 Jun 2020 16:21:50 +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="fw8+9A1i" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 208DA206C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=amsat.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:47636 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jfnC9-0006Q5-D5 for qemu-devel@archiver.kernel.org; Mon, 01 Jun 2020 12:21:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50926) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jfn5U-0005KJ-QV for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:56 -0400 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]:51802) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jfn5T-0001Wn-HE for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:56 -0400 Received: by mail-wm1-x32d.google.com with SMTP id u13so93580wml.1 for ; Mon, 01 Jun 2020 09:14:55 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=AyUQ99AduwXqrVguyV5FFF6ZORrAOfJgEUZqhjZDkcg=; b=fw8+9A1ij1hAHlRFRaNzSXIrnsMpcoL76Zdz5tDeHX7LJ8iAx2Hcr6v548qiOBHNai V/tyRU2ghTUDoPqUZt4TydNEuuN0O70QtMFnqBVDPPT/To6urUmUNkWJMxorCc6mfv91 EkRHn5QaeUqBHtor/ethoHlJNnexC85J1eHciZ9G+Zr5p/W9qoYPZCJqCobN1t39pv8e GdFRQWjELftlRwKXtf8pR2ygdeCQ4mqHnwgGNSjQiM/4N2BGcT2kZnA/ZDz9iD+qYXD5 SdpI79rshk1vj/vGF956Urmfq0BZnB/ChSDNQKt22ZRVYLd3fo+6o2+fe8armVQkILFV 04gQ== 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:mime-version:content-transfer-encoding; bh=AyUQ99AduwXqrVguyV5FFF6ZORrAOfJgEUZqhjZDkcg=; b=hKTLNcitMTry/yaIQdhi8SxRGSFcrQcAvMQhPy6GRAuw4ReZ2IURXlnP/XSWeEqaRm GKND409nj8ltMak+bzX48Z2guhq5g6qXFtwhQnyldQE04radVzgqyM76Mke07lms/YYY I2yVfD3oiZQTzHiHufmdHwro9HMbSkIy1yTb5WbYIPIa6l04X6KnRuzBvlLcu/4FWZ1Y HtHYU+D6DFYDPiKfCOq+5x5tf5KcN13USZFgIZtYH7yfdSm2yLpRTm4tIlLWEPskSucG izRlYFx+SXxpffoibZ8ZhGCjerjxpOul/Xki/IwQ4NWrBEUpkfDn9aeFZFnmhJxeLZQr oPKA== X-Gm-Message-State: AOAM533E3yYmDgDqsrRIVMKiTfsLCHg7sjg3X85HmzJnWRMNPG8su41L Bd+/M4JSWjC/LK0P8idiVZM= X-Google-Smtp-Source: ABdhPJz0qVj3+6cjcqJmV0MuU9E8LhSviLqPRqksedoj2xRpHrj09Q7BfO4qRwIRnS4Q3EY+2R5t6w== X-Received: by 2002:a7b:c7d8:: with SMTP id z24mr117489wmk.28.1591028093930; Mon, 01 Jun 2020 09:14:53 -0700 (PDT) Received: from localhost.localdomain (43.red-83-51-162.dynamicip.rima-tde.net. [83.51.162.43]) by smtp.gmail.com with ESMTPSA id a6sm21309896wrn.38.2020.06.01.09.14.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jun 2020 09:14:53 -0700 (PDT) From: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= To: Richard Henderson , qemu-devel@nongnu.org, Yoshinori Sato Subject: [PATCH 07/12] hw/rx: RX62N microcontroller (MCU) Date: Mon, 1 Jun 2020 18:14:36 +0200 Message-Id: <20200601161441.8086-8-f4bug@amsat.org> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20200601161441.8086-1-f4bug@amsat.org> References: <20200601161441.8086-1-f4bug@amsat.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32d; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-x32d.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action 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: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Paolo Bonzini , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?b?w6k=?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Yoshinori Sato rx62n - RX62N cpu. Signed-off-by: Yoshinori Sato Tested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson [PMD: Use TYPE_RX62N_CPU, use #define for RX62N_NR_TMR/CMT/SCI, renamed CPU -> MCU, device -> microcontroller] Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20200224141923.82118-18-ysato@users.sourceforge.jp> [PMD: Split of machine, use &error_abort] Signed-off-by: Philippe Mathieu-Daudé --- include/hw/rx/rx62n.h | 75 ++++++++++++ hw/rx/rx62n.c | 264 ++++++++++++++++++++++++++++++++++++++++++ hw/Kconfig | 1 + hw/rx/Kconfig | 6 + hw/rx/Makefile.objs | 1 + 5 files changed, 347 insertions(+) create mode 100644 include/hw/rx/rx62n.h create mode 100644 hw/rx/rx62n.c create mode 100644 hw/rx/Kconfig create mode 100644 hw/rx/Makefile.objs diff --git a/include/hw/rx/rx62n.h b/include/hw/rx/rx62n.h new file mode 100644 index 0000000000..7c6023bcd6 --- /dev/null +++ b/include/hw/rx/rx62n.h @@ -0,0 +1,75 @@ +/* + * RX62N MCU Object + * + * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware + * (Rev.1.40 R01UH0033EJ0140) + * + * Copyright (c) 2019 Yoshinori Sato + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef HW_RX_RX62N_MCU_H +#define HW_RX_RX62N_MCU_H + +#include "target/rx/cpu.h" +#include "hw/intc/rx_icu.h" +#include "hw/timer/renesas_tmr.h" +#include "hw/timer/renesas_cmt.h" +#include "hw/char/renesas_sci.h" +#include "qemu/units.h" + +#define TYPE_RX62N_MCU "rx62n-mcu" +#define RX62N_MCU(obj) OBJECT_CHECK(RX62NState, (obj), TYPE_RX62N_MCU) + +#define RX62N_NR_TMR 2 +#define RX62N_NR_CMT 2 +#define RX62N_NR_SCI 6 + +typedef struct RX62NState { + /*< private >*/ + DeviceState parent_obj; + /*< public >*/ + + RXCPU cpu; + RXICUState icu; + RTMRState tmr[RX62N_NR_TMR]; + RCMTState cmt[RX62N_NR_CMT]; + RSCIState sci[RX62N_NR_SCI]; + + MemoryRegion *sysmem; + bool kernel; + + MemoryRegion iram; + MemoryRegion iomem1; + MemoryRegion d_flash; + MemoryRegion iomem2; + MemoryRegion iomem3; + MemoryRegion c_flash; + qemu_irq irq[NR_IRQS]; +} RX62NState; + +/* + * RX62N Internal Memory + * It is the value of R5F562N8. + * Please change the size for R5F562N7. + */ +#define RX62N_IRAM_SIZE (96 * KiB) +#define RX62N_DFLASH_SIZE (32 * KiB) +#define RX62N_CFLASH_SIZE (512 * KiB) + +#define RX62N_PCLK (48 * 1000 * 1000) + +#endif diff --git a/hw/rx/rx62n.c b/hw/rx/rx62n.c new file mode 100644 index 0000000000..13c90102b1 --- /dev/null +++ b/hw/rx/rx62n.c @@ -0,0 +1,264 @@ +/* + * RX62N Microcontroller + * + * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware + * (Rev.1.40 R01UH0033EJ0140) + * + * Copyright (c) 2019 Yoshinori Sato + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/hw.h" +#include "hw/rx/rx62n.h" +#include "hw/loader.h" +#include "hw/sysbus.h" +#include "hw/qdev-properties.h" +#include "sysemu/sysemu.h" +#include "cpu.h" + +/* + * RX62N Internal Memory + */ +#define RX62N_IRAM_BASE 0x00000000 +#define RX62N_DFLASH_BASE 0x00100000 +#define RX62N_CFLASH_BASE 0xfff80000 + +/* + * RX62N Peripheral Address + * See users manual section 5 + */ +#define RX62N_ICU_BASE 0x00087000 +#define RX62N_TMR_BASE 0x00088200 +#define RX62N_CMT_BASE 0x00088000 +#define RX62N_SCI_BASE 0x00088240 + +/* + * RX62N Peripheral IRQ + * See users manual section 11 + */ +#define RX62N_TMR_IRQ 174 +#define RX62N_CMT_IRQ 28 +#define RX62N_SCI_IRQ 214 + +/* + * IRQ -> IPR mapping table + * 0x00 - 0x91: IPR no (IPR00 to IPR91) + * 0xff: IPR not assigned + * See "11.3.1 Interrupt Vector Table" in hardware manual. + */ +static const uint8_t ipr_table[NR_IRQS] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 15 */ + 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0x02, + 0xff, 0xff, 0xff, 0x03, 0x04, 0x05, 0x06, 0x07, /* 31 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x14, 0x14, 0x14, /* 47 */ + 0x15, 0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1d, 0x1e, 0x1f, /* 63 */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 79 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x3a, 0x3b, 0x3c, 0xff, 0xff, 0xff, /* 95 */ + 0x40, 0xff, 0x44, 0x45, 0xff, 0xff, 0x48, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 111 */ + 0xff, 0xff, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52, + 0x52, 0x53, 0x53, 0x54, 0x54, 0x55, 0x55, 0x56, /* 127 */ + 0x56, 0x57, 0x57, 0x57, 0x57, 0x58, 0x59, 0x59, + 0x59, 0x59, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, /* 143 */ + 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, + 0x5f, 0x60, 0x60, 0x61, 0x61, 0x62, 0x62, 0x62, /* 159 */ + 0x62, 0x63, 0x64, 0x64, 0x64, 0x64, 0x65, 0x66, + 0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x68, 0x68, /* 175 */ + 0x68, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, + 0x6b, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 191 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0xff, 0xff, 0xff, 0xff, /* 207 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, /* 223 */ + 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0xff, 0xff, + 0xff, 0xff, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, /* 239 */ + 0x86, 0x86, 0xff, 0xff, 0xff, 0xff, 0x88, 0x89, + 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, /* 255 */ +}; + +/* + * Level triggerd IRQ list + * Not listed IRQ is Edge trigger. + * See "11.3.1 Interrupt Vector Table" in hardware manual. + */ +static const uint8_t levelirq[] = { + 16, 21, 32, 44, 47, 48, 51, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 90, 91, 170, 171, 172, 173, 214, + 217, 218, 221, 222, 225, 226, 229, 234, 237, 238, + 241, 246, 249, 250, 253, +}; + +static void register_icu(RX62NState *s) +{ + int i; + SysBusDevice *icu; + + object_initialize_child(OBJECT(s), "icu", &s->icu, sizeof(RXICUState), + TYPE_RX_ICU, &error_abort, NULL); + + icu = SYS_BUS_DEVICE(&s->icu); + qdev_prop_set_uint32(DEVICE(icu), "len-ipr-map", NR_IRQS); + for (i = 0; i < NR_IRQS; i++) { + char propname[32]; + snprintf(propname, sizeof(propname), "ipr-map[%d]", i); + qdev_prop_set_uint32(DEVICE(icu), propname, ipr_table[i]); + } + qdev_prop_set_uint32(DEVICE(icu), "len-trigger-level", + ARRAY_SIZE(levelirq)); + for (i = 0; i < ARRAY_SIZE(levelirq); i++) { + char propname[32]; + snprintf(propname, sizeof(propname), "trigger-level[%d]", i); + qdev_prop_set_uint32(DEVICE(icu), propname, levelirq[i]); + } + + for (i = 0; i < NR_IRQS; i++) { + s->irq[i] = qdev_get_gpio_in(DEVICE(icu), i); + } + qdev_init_nofail(DEVICE(icu)); + + sysbus_connect_irq(icu, 0, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_IRQ)); + sysbus_connect_irq(icu, 1, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_FIR)); + sysbus_connect_irq(icu, 2, s->irq[SWI]); + sysbus_mmio_map(SYS_BUS_DEVICE(icu), 0, RX62N_ICU_BASE); +} + +static void register_tmr(RX62NState *s, int unit) +{ + SysBusDevice *tmr; + int i, irqbase; + + object_initialize_child(OBJECT(s), "tmr[*]", &s->tmr[unit], + sizeof(RTMRState), TYPE_RENESAS_TMR, + &error_abort, NULL); + + tmr = SYS_BUS_DEVICE(&s->tmr[unit]); + qdev_prop_set_uint64(DEVICE(tmr), "input-freq", RX62N_PCLK); + qdev_init_nofail(DEVICE(tmr)); + + irqbase = RX62N_TMR_IRQ + TMR_NR_IRQ * unit; + for (i = 0; i < TMR_NR_IRQ; i++) { + sysbus_connect_irq(tmr, i, s->irq[irqbase + i]); + } + sysbus_mmio_map(tmr, 0, RX62N_TMR_BASE + unit * 0x10); +} + +static void register_cmt(RX62NState *s, int unit) +{ + SysBusDevice *cmt; + int i, irqbase; + + object_initialize_child(OBJECT(s), "cmt[*]", &s->cmt[unit], + sizeof(RCMTState), TYPE_RENESAS_CMT, + &error_abort, NULL); + + cmt = SYS_BUS_DEVICE(&s->cmt[unit]); + qdev_prop_set_uint64(DEVICE(cmt), "input-freq", RX62N_PCLK); + qdev_init_nofail(DEVICE(cmt)); + + irqbase = RX62N_CMT_IRQ + CMT_NR_IRQ * unit; + for (i = 0; i < CMT_NR_IRQ; i++) { + sysbus_connect_irq(cmt, i, s->irq[irqbase + i]); + } + sysbus_mmio_map(cmt, 0, RX62N_CMT_BASE + unit * 0x10); +} + +static void register_sci(RX62NState *s, int unit) +{ + SysBusDevice *sci; + int i, irqbase; + + object_initialize_child(OBJECT(s), "sci[*]", &s->sci[unit], + sizeof(RSCIState), TYPE_RENESAS_SCI, + &error_abort, NULL); + + sci = SYS_BUS_DEVICE(&s->sci[unit]); + qdev_prop_set_chr(DEVICE(sci), "chardev", serial_hd(unit)); + qdev_prop_set_uint64(DEVICE(sci), "input-freq", RX62N_PCLK); + qdev_init_nofail(DEVICE(sci)); + + irqbase = RX62N_SCI_IRQ + SCI_NR_IRQ * unit; + for (i = 0; i < SCI_NR_IRQ; i++) { + sysbus_connect_irq(sci, i, s->irq[irqbase + i]); + } + sysbus_mmio_map(sci, 0, RX62N_SCI_BASE + unit * 0x08); +} + +static void rx62n_realize(DeviceState *dev, Error **errp) +{ + RX62NState *s = RX62N_MCU(dev); + + memory_region_init_ram(&s->iram, OBJECT(dev), "iram", + rxc->ram_size, &error_abort); + memory_region_add_subregion(s->sysmem, RX62N_IRAM_BASE, &s->iram); + memory_region_init_rom(&s->d_flash, OBJECT(dev), "flash-data", + rxc->data_flash_size, &error_abort); + memory_region_add_subregion(s->sysmem, RX62N_DFLASH_BASE, &s->d_flash); + memory_region_init_rom(&s->c_flash, OBJECT(dev), "flash-code", + rxc->rom_flash_size, &error_abort); + memory_region_add_subregion(s->sysmem, RX62N_CFLASH_BASE, &s->c_flash); + + if (!s->kernel) { + rom_add_file_fixed(bios_name, RX62N_CFLASH_BASE, 0); + } + + /* Initialize CPU */ + object_initialize_child(OBJECT(s), "cpu", &s->cpu, sizeof(RXCPU), + TYPE_RX62N_CPU, &error_abort, NULL); + object_property_set_bool(OBJECT(&s->cpu), true, "realized", &error_abort); + + register_icu(s); + s->cpu.env.ack = qdev_get_gpio_in_named(DEVICE(&s->icu), "ack", 0); + register_tmr(s, 0); + register_tmr(s, 1); + register_cmt(s, 0); + register_cmt(s, 1); + register_sci(s, 0); +} + +static Property rx62n_properties[] = { + DEFINE_PROP_LINK("main-bus", RX62NState, sysmem, TYPE_MEMORY_REGION, + MemoryRegion *), + DEFINE_PROP_BOOL("load-kernel", RX62NState, kernel, false), + DEFINE_PROP_END_OF_LIST(), +}; + +static void rx62n_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = rx62n_realize; + device_class_set_props(dc, rx62n_properties); +} + +static const TypeInfo rx62n_info = { + .name = TYPE_RX62N_MCU, + .parent = TYPE_DEVICE, + .instance_size = sizeof(RX62NState), + .class_init = rx62n_class_init, +}; + +static void rx62n_register_types(void) +{ + type_register_static(&rx62n_info); +} + +type_init(rx62n_register_types) diff --git a/hw/Kconfig b/hw/Kconfig index ecf491bf04..62f9ebdc22 100644 --- a/hw/Kconfig +++ b/hw/Kconfig @@ -55,6 +55,7 @@ source nios2/Kconfig source openrisc/Kconfig source ppc/Kconfig source riscv/Kconfig +source rx/Kconfig source s390x/Kconfig source sh4/Kconfig source sparc/Kconfig diff --git a/hw/rx/Kconfig b/hw/rx/Kconfig new file mode 100644 index 0000000000..e7b1c59516 --- /dev/null +++ b/hw/rx/Kconfig @@ -0,0 +1,6 @@ +config RX62N_MCU + bool + select RX_ICU + select RENESAS_TMR + select RENESAS_CMT + select RENESAS_SCI diff --git a/hw/rx/Makefile.objs b/hw/rx/Makefile.objs new file mode 100644 index 0000000000..fe19ee7984 --- /dev/null +++ b/hw/rx/Makefile.objs @@ -0,0 +1 @@ +obj-$(CONFIG_RX62N_MCU) += rx62n.o From patchwork Mon Jun 1 16:14:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Patchwork-Id: 187345 Delivered-To: patch@linaro.org Received: by 2002:a92:5b0a:0:0:0:0:0 with SMTP id p10csp3182999ilb; Mon, 1 Jun 2020 09:22:42 -0700 (PDT) X-Google-Smtp-Source: ABdhPJylKd1x/JlPa+duJBXDZ0ElR8qZ9qyBGYNv/dPNh29w6E538TcAGqGFWW0zCuLksKmw0O43 X-Received: by 2002:a25:ba8d:: with SMTP id s13mr36344310ybg.123.1591028562248; Mon, 01 Jun 2020 09:22:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1591028562; cv=none; d=google.com; s=arc-20160816; b=SZ6SeRdPQCpbSQa6gDcx6EaL1ujdTaRaJjeN9WnbAnSBrhduPj61wpNUexqmn8pgKu /FTsX8elVph8aFBlZ1ZBe8RSOSn5CS7ccjPV3PwSifo1FKcVR08Dljwif4e58HTq6r7y nbPBSinfI6TceJm3VydnzDb8TpsdoEUZAh4DVc9y2GKoC1eRynYoiec0wDBmVGUu8ycx myFJN/K4Fka/B9Igifz9OOYp92wTLnTo9Zc6ZjWntAhQNur8qHgrWpcJP2ImX4sPByIS OA5889AQg6O+Z5AR6WB3UCm4gOw7XdBpNUdEZZNBN+rChdz05rWXwgLMahPvvkZbhwBJ xaQw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=+dT4hPe13b2V1KUy+9YeeyPPkO3c2tsutvWPTSNqBlI=; b=P7HaqJ8WNdOs2NaqO25PDe0gkj8pzAkLHpSM3/Sin4W48mp/g2Dn4F96Jn7br8BT+F j8NEDZO0bCAdHEPzxr+nM+GWnqyh60BvfYmY+8q366B1fbw3IHJPFtvwDpH2noxcdPJy zJYWiXz6OuOE+C3R0niaZJkouXgPBd9jRGauiRmYUfq1w89GIyWjyL4apv/owiHH+x2z oH1c1Aa1aDzxm5Y/ZCrjUD+8pNiLm7O1TrDpfRuuiuiruWdFrkL6M+e4ss+qQLcp5uRn ZnnsXeWBZ/IjvdkdE+B8cpB5o5Pk3lx1L/Yo7yL6698MuTokwkKueHhfyPOgfrDNJ4NJ n+1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=QE9DzSid; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=amsat.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id k13si20311151ybt.389.2020.06.01.09.22.42 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Mon, 01 Jun 2020 09:22:42 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=QE9DzSid; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=amsat.org Received: from localhost ([::1]:48780 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jfnCz-0006uN-Pi for patch@linaro.org; Mon, 01 Jun 2020 12:22:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50936) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jfn5V-0005MQ-Ne for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:57 -0400 Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]:33644) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jfn5V-0001X0-0E for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:14:57 -0400 Received: by mail-wr1-x42a.google.com with SMTP id l11so445940wru.0 for ; Mon, 01 Jun 2020 09:14:56 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=+dT4hPe13b2V1KUy+9YeeyPPkO3c2tsutvWPTSNqBlI=; b=QE9DzSiduZZGcx+EVRldlAhiQa2yGvSqgoiQeNN/i0r9TyM+zD4EznYZizywXAlqNT QC9kdu58She2A/GFmw3V3leLugCCA08ri/3Y43mSLzmThC6lhcLumKlNdZIeNdtmFbfg kEZbi+L1Vl/OjMheFi1e4fA6wp+f+JLaq0plk1/d9I8KTfS8dWrPvz+CmwrNs/r/iepC DvIqWd45O+pbH+fNrJ7c/Q5HhnrIn+wlxeiRZL/LQ9TxK18UpXI8nyDkLu1d7fEgfVez sM3FJdsO+3FO8qzZSFwsMxqRqdQGnaVPq6v+YjEQFtwyl/mZjb7rum4Bkyqb+UyudE51 DiRw== 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:mime-version:content-transfer-encoding; bh=+dT4hPe13b2V1KUy+9YeeyPPkO3c2tsutvWPTSNqBlI=; b=Tcg9KdpFLR5gl6HvxUwMgLhtmahpcm0/9MooFbv6lPcZFtj27BFR6DUVMVnuPrSFlT JJbrySVHIyHN1x12kiLD63triWxw4CNVsNJL0G1kiVShOwZVUEMz+h9aY6rQR1mOEYJf N/5RGDcjSo2Wc8wTnh9zftWucH3cAOmjkBGHpIs1UmM2ssye9TeP7DXbyUZB/qcVlbfv QrJ0kxdw3vfn8UT4kae21yJRsciPZpov4GJVydUd2wsq9fffU49Zz0NqZOfbZcse0w/X nPUtCA3/IWdp5+PxSWFpWtZvbZ2d7UYYuvlf3hUfemgeJFShppGy4Rr4x/aFeMML2szy PdEw== X-Gm-Message-State: AOAM531bQVfvjMuVj83vpPoa8Ut+J9eScwBMTQpVxk2Kbq1eNJpMMh4Z Ri+rNt0NSNKpzMZpQmTFZIE= X-Received: by 2002:adf:f450:: with SMTP id f16mr10793564wrp.307.1591028095675; Mon, 01 Jun 2020 09:14:55 -0700 (PDT) Received: from localhost.localdomain (43.red-83-51-162.dynamicip.rima-tde.net. [83.51.162.43]) by smtp.gmail.com with ESMTPSA id a6sm21309896wrn.38.2020.06.01.09.14.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jun 2020 09:14:54 -0700 (PDT) From: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= To: Richard Henderson , qemu-devel@nongnu.org, Yoshinori Sato Subject: [PATCH 08/12] hw/rx: Honor -accel qtest Date: Mon, 1 Jun 2020 18:14:37 +0200 Message-Id: <20200601161441.8086-9-f4bug@amsat.org> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20200601161441.8086-1-f4bug@amsat.org> References: <20200601161441.8086-1-f4bug@amsat.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42a; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wr1-x42a.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action 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: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Paolo Bonzini , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?b?w6k=?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Issue an error if no kernel, no bios, and not qtest'ing. Fixes make check-qtest-rx: test/qom-test. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Yoshinori Sato Tested-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-Id: <20200224141923.82118-19-ysato@users.sourceforge.jp> Signed-off-by: Philippe Mathieu-Daudé --- hw/rx/rx62n.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) -- 2.21.3 diff --git a/hw/rx/rx62n.c b/hw/rx/rx62n.c index 13c90102b1..92d215f07a 100644 --- a/hw/rx/rx62n.c +++ b/hw/rx/rx62n.c @@ -21,12 +21,14 @@ #include "qemu/osdep.h" #include "qapi/error.h" +#include "qemu/error-report.h" #include "hw/hw.h" #include "hw/rx/rx62n.h" #include "hw/loader.h" #include "hw/sysbus.h" #include "hw/qdev-properties.h" #include "sysemu/sysemu.h" +#include "sysemu/qtest.h" #include "cpu.h" /* @@ -217,7 +219,12 @@ static void rx62n_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(s->sysmem, RX62N_CFLASH_BASE, &s->c_flash); if (!s->kernel) { - rom_add_file_fixed(bios_name, RX62N_CFLASH_BASE, 0); + if (bios_name) { + rom_add_file_fixed(bios_name, RX62N_CFLASH_BASE, 0); + } else if (!qtest_enabled()) { + error_report("No bios or kernel specified"); + exit(1); + } } /* Initialize CPU */ From patchwork Mon Jun 1 16:14:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Patchwork-Id: 281536 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3611AC433E0 for ; Mon, 1 Jun 2020 16:24:08 +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 E51AC206C3 for ; Mon, 1 Jun 2020 16:24: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="r6Wf/8EY" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E51AC206C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=amsat.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:51994 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jfnEN-0008Mm-7E for qemu-devel@archiver.kernel.org; Mon, 01 Jun 2020 12:24:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50952) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jfn5Y-0005Tl-Sx for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:15:00 -0400 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:38121) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jfn5X-0001XV-LL for qemu-devel@nongnu.org; Mon, 01 Jun 2020 12:15:00 -0400 Received: by mail-wm1-x344.google.com with SMTP id f185so91399wmf.3 for ; Mon, 01 Jun 2020 09:14:59 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=RWdudFnYi0EUSMbnOj3UHoO35ptoSzGdI/tJkRX1nw8=; b=r6Wf/8EY9Luxf6B8WKIgqElxzWm5aqquJiEyKEaSAv4F6J03dWmjk98l8CrgK9gJ+p 10+QmunAOVAISmZ9q+MNpk0TBUlbUVg9RFPKhcwyZP28ysIdwurtlFM9LD9kFv7Gdxv8 PQa6W8R4yjfq6AjavM7o510tUoq/TL+C2J9FMO9ajx86+anPB/LFdkHmvWlaBdpDMkQq YVFkoC+MfiwPBIWj3Wt9h6yEVmPla3iAVYuhIZO9fC43ZYkhLfyFwCV9SjlJcG6mShdT bG2y7jUHp0CBguG9L5XIfbHCO4f320pyXtM09WhIJyqY3U2hLSYlxN3068K3RxJfIC9E dq1w== 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:mime-version:content-transfer-encoding; bh=RWdudFnYi0EUSMbnOj3UHoO35ptoSzGdI/tJkRX1nw8=; b=PCa8/pmTCcO4K/yZL3pdehijRZPnG/XY6G+11I4Dn/lCXpAzP7wFPXwzWW3SMLCdEl JF9+zqfNyToB7avYxom1klFkEhVpzOTwhF/1Uhp1E++/qw+PAI+qBuEik6zvkBCsuR/s 5xTG9ywMSZfj484AVJbqQYrF4SOSrkZmwwDxNwVcY6l5gnlF5eZoGLkGiZOcmEKvFOSj 5ShD1xXJb8eqkZmXKZL9XHUEdq0fuspnukSZ03VBIZMnBXOfOKvPZufuXQDVoZICw8VO AX0e3tbh/WOWmsDM8aX1l+L1SNq5xEuz3KCXhCXW0VxvTbgGH1oyMY7H936aeZVIq4cb oYCQ== X-Gm-Message-State: AOAM530tqhFQPrvc7q5fuT4lLeXwyPMdm7LfU9DpE1opgKBdX7nIrTSL iVMk62yZRIBASD6vuuJuvlI= X-Google-Smtp-Source: ABdhPJx1QqnsgsSyopoZc9LyyuPHSK3VVOI2xr1cppW9cxXo+MIpNaVH4NRcHZqIz1wYEFBjsfhOBQ== X-Received: by 2002:a1c:9d09:: with SMTP id g9mr84056wme.31.1591028098209; Mon, 01 Jun 2020 09:14:58 -0700 (PDT) Received: from localhost.localdomain (43.red-83-51-162.dynamicip.rima-tde.net. [83.51.162.43]) by smtp.gmail.com with ESMTPSA id a6sm21309896wrn.38.2020.06.01.09.14.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Jun 2020 09:14:57 -0700 (PDT) From: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= To: Richard Henderson , qemu-devel@nongnu.org, Yoshinori Sato Subject: [PATCH 10/12] hw/rx: Add RX GDB simulator Date: Mon, 1 Jun 2020 18:14:39 +0200 Message-Id: <20200601161441.8086-11-f4bug@amsat.org> X-Mailer: git-send-email 2.21.3 In-Reply-To: <20200601161441.8086-1-f4bug@amsat.org> References: <20200601161441.8086-1-f4bug@amsat.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::344; envelope-from=philippe.mathieu.daude@gmail.com; helo=mail-wm1-x344.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action 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: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Paolo Bonzini , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?b?w6k=?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Yoshinori Sato Add the RX machine internally simulated in GDB. Signed-off-by: Yoshinori Sato Tested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson [PMD: Use TYPE_RX62N_CPU, use #define for RX62N_NR_TMR/CMT/SCI, renamed CPU -> MCU, device -> microcontroller] Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20200224141923.82118-18-ysato@users.sourceforge.jp> [PMD: Split of MCU, rename gdbsim, Add gdbsim-r5f562n7/r5f562n8] Signed-off-by: Philippe Mathieu-Daudé --- default-configs/rx-softmmu.mak | 1 + include/hw/rx/rx62n.h | 4 + hw/rx/rx-gdbsim.c | 198 +++++++++++++++++++++++++++++++++ hw/rx/Kconfig | 4 + hw/rx/Makefile.objs | 1 + 5 files changed, 208 insertions(+) create mode 100644 hw/rx/rx-gdbsim.c diff --git a/default-configs/rx-softmmu.mak b/default-configs/rx-softmmu.mak index 7c4eb2c1a0..df2b4e4f42 100644 --- a/default-configs/rx-softmmu.mak +++ b/default-configs/rx-softmmu.mak @@ -1,2 +1,3 @@ # Default configuration for rx-softmmu +CONFIG_RX_GDBSIM=y diff --git a/include/hw/rx/rx62n.h b/include/hw/rx/rx62n.h index 0421cd6d4d..121caedbe9 100644 --- a/include/hw/rx/rx62n.h +++ b/include/hw/rx/rx62n.h @@ -37,6 +37,10 @@ #define TYPE_R5F562N7_MCU "r5f562n7-mcu" #define TYPE_R5F562N8_MCU "r5f562n8-mcu" +#define EXT_CS_BASE 0x01000000 +#define VECTOR_TABLE_BASE 0xffffff80 +#define RX62N_CFLASH_BASE 0xfff80000 + #define RX62N_NR_TMR 2 #define RX62N_NR_CMT 2 #define RX62N_NR_SCI 6 diff --git a/hw/rx/rx-gdbsim.c b/hw/rx/rx-gdbsim.c new file mode 100644 index 0000000000..01751790ed --- /dev/null +++ b/hw/rx/rx-gdbsim.c @@ -0,0 +1,198 @@ +/* + * RX QEMU GDB simulator + * + * Copyright (c) 2019 Yoshinori Sato + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "hw/loader.h" +#include "hw/rx/rx62n.h" +#include "sysemu/sysemu.h" +#include "sysemu/qtest.h" +#include "sysemu/device_tree.h" +#include "hw/boards.h" + +/* Same address of GDB integrated simulator */ +#define SDRAM_BASE EXT_CS_BASE + +typedef struct RxGdbSimMachineClass { + /*< private >*/ + MachineClass parent_class; + /*< public >*/ + const char *mcu_name; + uint32_t xtal_freq_hz; +} RxGdbSimMachineClass; + +typedef struct RxGdbSimMachineState { + /*< private >*/ + MachineState parent_obj; + /*< public >*/ + RX62NState mcu; +} RxGdbSimMachineState; + +#define TYPE_RX_GDBSIM_MACHINE MACHINE_TYPE_NAME("rx62n-common") + +#define RX_GDBSIM_MACHINE(obj) \ + OBJECT_CHECK(RxGdbSimMachineState, (obj), TYPE_RX_GDBSIM_MACHINE) + +#define RX_GDBSIM_MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(RxGdbSimMachineClass, (klass), TYPE_RX_GDBSIM_MACHINE) +#define RX_GDBSIM_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(RxGdbSimMachineClass, (obj), TYPE_RX_GDBSIM_MACHINE) + +static void rx_load_image(RXCPU *cpu, const char *filename, + uint32_t start, uint32_t size) +{ + static uint32_t extable[32]; + long kernel_size; + int i; + + kernel_size = load_image_targphys(filename, start, size); + if (kernel_size < 0) { + fprintf(stderr, "qemu: could not load kernel '%s'\n", filename); + exit(1); + } + cpu->env.pc = start; + + /* setup exception trap trampoline */ + /* linux kernel only works little-endian mode */ + for (i = 0; i < ARRAY_SIZE(extable); i++) { + extable[i] = cpu_to_le32(0x10 + i * 4); + } + rom_add_blob_fixed("extable", extable, sizeof(extable), VECTOR_TABLE_BASE); +} + +static void rx_gdbsim_init(MachineState *machine) +{ + MachineClass *mc = MACHINE_GET_CLASS(machine); + RxGdbSimMachineState *s = RX_GDBSIM_MACHINE(machine); + RxGdbSimMachineClass *rxc = RX_GDBSIM_MACHINE_GET_CLASS(machine); + MemoryRegion *sysmem = get_system_memory(); + const char *kernel_filename = machine->kernel_filename; + const char *dtb_filename = machine->dtb; + + if (machine->ram_size < mc->default_ram_size) { + error_report("Invalid RAM size, should be more than %" PRIi64 " Bytes", + mc->default_ram_size); + } + + /* Allocate memory space */ + memory_region_add_subregion(sysmem, SDRAM_BASE, machine->ram); + + /* Initialize MCU */ + object_initialize_child(OBJECT(machine), "mcu", &s->mcu, + sizeof(RX62NState), rxc->mcu_name, + &error_fatal, NULL); + object_property_set_link(OBJECT(&s->mcu), OBJECT(sysmem), + "main-bus", &error_abort); + object_property_set_uint(OBJECT(&s->mcu), rxc->xtal_freq_hz, + "xtal-frequency-hz", &error_abort); + object_property_set_bool(OBJECT(&s->mcu), kernel_filename != NULL, + "load-kernel", &error_abort); + object_property_set_bool(OBJECT(&s->mcu), true, "realized", &error_abort); + + /* Load kernel and dtb */ + if (kernel_filename) { + ram_addr_t kernel_offset; + + /* + * The kernel image is loaded into + * the latter half of the SDRAM space. + */ + kernel_offset = machine->ram_size / 2; + rx_load_image(RXCPU(first_cpu), kernel_filename, + SDRAM_BASE + kernel_offset, kernel_offset); + if (dtb_filename) { + ram_addr_t dtb_offset; + int dtb_size; + void *dtb; + + dtb = load_device_tree(dtb_filename, &dtb_size); + if (dtb == NULL) { + error_report("Couldn't open dtb file %s", dtb_filename); + exit(1); + } + if (machine->kernel_cmdline && + qemu_fdt_setprop_string(dtb, "/chosen", "bootargs", + machine->kernel_cmdline) < 0) { + error_report("Couldn't set /chosen/bootargs"); + exit(1); + } + /* DTB is located at the end of SDRAM space. */ + dtb_offset = machine->ram_size - dtb_size; + rom_add_blob_fixed("dtb", dtb, dtb_size, + SDRAM_BASE + dtb_offset); + /* Set dtb address to R1 */ + RXCPU(first_cpu)->env.regs[1] = SDRAM_BASE + dtb_offset; + } + } +} + +static void rx_gdbsim_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->init = rx_gdbsim_init; + mc->default_cpu_type = TYPE_RX62N_CPU; + mc->default_ram_size = 16 * MiB; + mc->default_ram_id = "ext-sdram"; +} + +static void rx62n7_class_init(ObjectClass *oc, void *data) +{ + RxGdbSimMachineClass *rxc = RX_GDBSIM_MACHINE_CLASS(oc); + MachineClass *mc = MACHINE_CLASS(oc); + + rxc->mcu_name = TYPE_R5F562N7_MCU; + rxc->xtal_freq_hz = 12 * 1000 * 1000; + mc->desc = "gdb simulator (R5F562N7 MCU and external RAM)"; +}; + +static void rx62n8_class_init(ObjectClass *oc, void *data) +{ + RxGdbSimMachineClass *rxc = RX_GDBSIM_MACHINE_CLASS(oc); + MachineClass *mc = MACHINE_CLASS(oc); + + rxc->mcu_name = TYPE_R5F562N8_MCU; + rxc->xtal_freq_hz = 12 * 1000 * 1000; + mc->desc = "gdb simulator (R5F562N8 MCU and external RAM)"; +}; + +static const TypeInfo rx_gdbsim_types[] = { + { + .name = MACHINE_TYPE_NAME("gdbsim-r5f562n7"), + .parent = TYPE_RX_GDBSIM_MACHINE, + .class_init = rx62n7_class_init, + }, { + .name = MACHINE_TYPE_NAME("gdbsim-r5f562n8"), + .parent = TYPE_RX_GDBSIM_MACHINE, + .class_init = rx62n8_class_init, + }, { + .name = TYPE_RX_GDBSIM_MACHINE, + .parent = TYPE_MACHINE, + .instance_size = sizeof(RxGdbSimMachineState), + .class_size = sizeof(RxGdbSimMachineClass), + .class_init = rx_gdbsim_class_init, + .abstract = true, + } +}; + +DEFINE_TYPES(rx_gdbsim_types) diff --git a/hw/rx/Kconfig b/hw/rx/Kconfig index e7b1c59516..2b297c5a6a 100644 --- a/hw/rx/Kconfig +++ b/hw/rx/Kconfig @@ -4,3 +4,7 @@ config RX62N_MCU select RENESAS_TMR select RENESAS_CMT select RENESAS_SCI + +config RX_GDBSIM + bool + select RX62N_MCU diff --git a/hw/rx/Makefile.objs b/hw/rx/Makefile.objs index fe19ee7984..4ef6b9e5b1 100644 --- a/hw/rx/Makefile.objs +++ b/hw/rx/Makefile.objs @@ -1 +1,2 @@ obj-$(CONFIG_RX62N_MCU) += rx62n.o +obj-$(CONFIG_RX_GDBSIM) += rx-gdbsim.o