From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534775357752310.4506630538049; Mon, 20 Aug 2018 07:29:17 -0700 (PDT) Received: from localhost ([::1]:47402 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frlBE-0002NB-4t for importer@patchew.org; Mon, 20 Aug 2018 10:29:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41873) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frku4-0003T9-9k for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frku3-0007Fk-7A for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:32 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44622) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frku0-0007Bt-IK; Mon, 20 Aug 2018 10:11:28 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frkts-0003L2-6c; Mon, 20 Aug 2018 15:11:20 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:10:55 +0100 Message-Id: <20180820141116.9118-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 01/22] hw/misc/mps2-fpgaio: Implement 1Hz and 100Hz counters X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The MPS2 FPGAIO block includes some simple free-running counters. Implement these. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- include/hw/misc/mps2-fpgaio.h | 4 +++ hw/misc/mps2-fpgaio.c | 53 ++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h index eedf17ebc6d..ec057d38c76 100644 --- a/include/hw/misc/mps2-fpgaio.h +++ b/include/hw/misc/mps2-fpgaio.h @@ -38,6 +38,10 @@ typedef struct { uint32_t misc; =20 uint32_t prescale_clk; + + /* These hold the CLOCK_VIRTUAL ns tick when the CLK1HZ/CLK100HZ was z= ero */ + int64_t clk1hz_tick_offset; + int64_t clk100hz_tick_offset; } MPS2FPGAIO; =20 #endif diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c index 7394a057d82..bbc28f641f0 100644 --- a/hw/misc/mps2-fpgaio.c +++ b/hw/misc/mps2-fpgaio.c @@ -22,6 +22,7 @@ #include "hw/sysbus.h" #include "hw/registerfields.h" #include "hw/misc/mps2-fpgaio.h" +#include "qemu/timer.h" =20 REG32(LED0, 0) REG32(BUTTON, 8) @@ -32,10 +33,21 @@ REG32(PRESCALE, 0x1c) REG32(PSCNTR, 0x20) REG32(MISC, 0x4c) =20 +static uint32_t counter_from_tickoff(int64_t now, int64_t tick_offset, int= frq) +{ + return muldiv64(now - tick_offset, frq, NANOSECONDS_PER_SECOND); +} + +static int64_t tickoff_from_counter(int64_t now, uint32_t count, int frq) +{ + return now - muldiv64(count, NANOSECONDS_PER_SECOND, frq); +} + static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned siz= e) { MPS2FPGAIO *s =3D MPS2_FPGAIO(opaque); uint64_t r; + int64_t now; =20 switch (offset) { case A_LED0: @@ -54,10 +66,15 @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr o= ffset, unsigned size) r =3D s->misc; break; case A_CLK1HZ: + now =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + r =3D counter_from_tickoff(now, s->clk1hz_tick_offset, 1); + break; case A_CLK100HZ: + now =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + r =3D counter_from_tickoff(now, s->clk100hz_tick_offset, 100); + break; case A_COUNTER: case A_PSCNTR: - /* These are all upcounters of various frequencies. */ qemu_log_mask(LOG_UNIMP, "MPS2 FPGAIO: counters unimplemented\n"); r =3D 0; break; @@ -76,6 +93,7 @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset= , uint64_t value, unsigned size) { MPS2FPGAIO *s =3D MPS2_FPGAIO(opaque); + int64_t now; =20 trace_mps2_fpgaio_write(offset, value, size); =20 @@ -100,6 +118,14 @@ static void mps2_fpgaio_write(void *opaque, hwaddr off= set, uint64_t value, "MPS2 FPGAIO: MISC control bits unimplemented\n"); s->misc =3D value; break; + case A_CLK1HZ: + now =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + s->clk1hz_tick_offset =3D tickoff_from_counter(now, value, 1); + break; + case A_CLK100HZ: + now =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + s->clk100hz_tick_offset =3D tickoff_from_counter(now, value, 100); + break; default: qemu_log_mask(LOG_GUEST_ERROR, "MPS2 FPGAIO write: bad offset 0x%x\n", (int) offset= ); @@ -116,11 +142,14 @@ static const MemoryRegionOps mps2_fpgaio_ops =3D { static void mps2_fpgaio_reset(DeviceState *dev) { MPS2FPGAIO *s =3D MPS2_FPGAIO(dev); + int64_t now =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); =20 trace_mps2_fpgaio_reset(); s->led0 =3D 0; s->prescale =3D 0; s->misc =3D 0; + s->clk1hz_tick_offset =3D tickoff_from_counter(now, 0, 1); + s->clk100hz_tick_offset =3D tickoff_from_counter(now, 0, 100); } =20 static void mps2_fpgaio_init(Object *obj) @@ -133,6 +162,24 @@ static void mps2_fpgaio_init(Object *obj) sysbus_init_mmio(sbd, &s->iomem); } =20 +static bool mps2_fpgaio_counters_needed(void *opaque) +{ + /* Currently vmstate.c insists all subsections have a 'needed' functio= n */ + return true; +} + +static const VMStateDescription mps2_fpgaio_counters_vmstate =3D { + .name =3D "mps2-fpgaio/counters", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D mps2_fpgaio_counters_needed, + .fields =3D (VMStateField[]) { + VMSTATE_INT64(clk1hz_tick_offset, MPS2FPGAIO), + VMSTATE_INT64(clk100hz_tick_offset, MPS2FPGAIO), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription mps2_fpgaio_vmstate =3D { .name =3D "mps2-fpgaio", .version_id =3D 1, @@ -142,6 +189,10 @@ static const VMStateDescription mps2_fpgaio_vmstate = =3D { VMSTATE_UINT32(prescale, MPS2FPGAIO), VMSTATE_UINT32(misc, MPS2FPGAIO), VMSTATE_END_OF_LIST() + }, + .subsections =3D (const VMStateDescription*[]) { + &mps2_fpgaio_counters_vmstate, + NULL } }; =20 --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534774438350245.0688730770986; Mon, 20 Aug 2018 07:13:58 -0700 (PDT) Received: from localhost ([::1]:47298 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkwD-0004oh-PX for importer@patchew.org; Mon, 20 Aug 2018 10:13:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41745) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frktz-0003O9-RF for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frkty-0007Bb-LN for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:27 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44596) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frktv-00078D-1U; Mon, 20 Aug 2018 10:11:23 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frktt-0003LL-5U; Mon, 20 Aug 2018 15:11:21 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:10:56 +0100 Message-Id: <20180820141116.9118-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 02/22] hw/misc/mps2-fpgaio: Implement PSCNTR and COUNTER X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" In the MPS2 FPGAIO, PSCNTR is a free-running downcounter with a reload value configured via the PRESCALE register, and COUNTER counts up by 1 every time PSCNTR reaches zero. Implement these counters. We can just increment the counters migration subsection's version ID because we only added it in the previous commit, so no released QEMU versions will be using it. Signed-off-by: Peter Maydell Reviewed-by: Alistair Francis Reviewed-by: Richard Henderson --- include/hw/misc/mps2-fpgaio.h | 6 +++ hw/misc/mps2-fpgaio.c | 97 +++++++++++++++++++++++++++++++++-- 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h index ec057d38c76..69e265cd4b2 100644 --- a/include/hw/misc/mps2-fpgaio.h +++ b/include/hw/misc/mps2-fpgaio.h @@ -37,6 +37,12 @@ typedef struct { uint32_t prescale; uint32_t misc; =20 + /* QEMU_CLOCK_VIRTUAL time at which counter and pscntr were last synce= d */ + int64_t pscntr_sync_ticks; + /* Values of COUNTER and PSCNTR at time pscntr_sync_ticks */ + uint32_t counter; + uint32_t pscntr; + uint32_t prescale_clk; =20 /* These hold the CLOCK_VIRTUAL ns tick when the CLK1HZ/CLK100HZ was z= ero */ diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c index bbc28f641f0..5cf10ebd66a 100644 --- a/hw/misc/mps2-fpgaio.c +++ b/hw/misc/mps2-fpgaio.c @@ -43,6 +43,77 @@ static int64_t tickoff_from_counter(int64_t now, uint32_= t count, int frq) return now - muldiv64(count, NANOSECONDS_PER_SECOND, frq); } =20 +static void resync_counter(MPS2FPGAIO *s) +{ + /* + * Update s->counter and s->pscntr to their true current values + * by calculating how many times PSCNTR has ticked since the + * last time we did a resync. + */ + int64_t now =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + int64_t elapsed =3D now - s->pscntr_sync_ticks; + + /* + * Round elapsed down to a whole number of PSCNTR ticks, so we don't + * lose time if we do multiple resyncs in a single tick. + */ + uint64_t ticks =3D muldiv64(elapsed, s->prescale_clk, NANOSECONDS_PER_= SECOND); + + /* + * Work out what PSCNTR and COUNTER have moved to. We assume that + * PSCNTR reloads from PRESCALE one tick-period after it hits zero, + * and that COUNTER increments at the same moment. + */ + if (ticks =3D=3D 0) { + /* We haven't ticked since the last time we were asked */ + return; + } else if (ticks < s->pscntr) { + /* We haven't yet reached zero, just reduce the PSCNTR */ + s->pscntr -=3D ticks; + } else { + if (s->prescale =3D=3D 0) { + /* + * If the reload value is zero then the PSCNTR will stick + * at zero once it reaches it, and so we will increment + * COUNTER every tick after that. + */ + s->counter +=3D ticks - s->pscntr; + s->pscntr =3D 0; + } else { + /* + * This is the complicated bit. This ASCII art diagram gives an + * example with PRESCALE=3D=3D5 PSCNTR=3D=3D7: + * + * ticks 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + * PSCNTR 7 6 5 4 3 2 1 0 5 4 3 2 1 0 5 + * cinc 1 2 + * y 0 1 2 3 4 5 6 7 8 9 10 11 12 + * x 0 1 2 3 4 5 0 1 2 3 4 5 0 + * + * where x =3D y % (s->prescale + 1) + * and so PSCNTR =3D s->prescale - x + * and COUNTER is incremented by y / (s->prescale + 1) + * + * The case where PSCNTR < PRESCALE works out the same, + * though we must be careful to calculate y as 64-bit unsigned + * for all parts of the expression. + * y < 0 is not possible because that implies ticks < s->pscnt= r. + */ + uint64_t y =3D ticks - s->pscntr + s->prescale; + s->pscntr =3D s->prescale - (y % (s->prescale + 1)); + s->counter +=3D y / (s->prescale + 1); + } + } + + /* + * Only advance the sync time to the timestamp of the last PSCNTR tick, + * not all the way to 'now', so we don't lose time if we do multiple + * resyncs in a single tick. + */ + s->pscntr_sync_ticks +=3D muldiv64(ticks, NANOSECONDS_PER_SECOND, + s->prescale_clk); +} + static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned siz= e) { MPS2FPGAIO *s =3D MPS2_FPGAIO(opaque); @@ -74,9 +145,12 @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr o= ffset, unsigned size) r =3D counter_from_tickoff(now, s->clk100hz_tick_offset, 100); break; case A_COUNTER: + resync_counter(s); + r =3D s->counter; + break; case A_PSCNTR: - qemu_log_mask(LOG_UNIMP, "MPS2 FPGAIO: counters unimplemented\n"); - r =3D 0; + resync_counter(s); + r =3D s->pscntr; break; default: qemu_log_mask(LOG_GUEST_ERROR, @@ -107,6 +181,7 @@ static void mps2_fpgaio_write(void *opaque, hwaddr offs= et, uint64_t value, s->led0 =3D value & 0x3; break; case A_PRESCALE: + resync_counter(s); s->prescale =3D value; break; case A_MISC: @@ -126,6 +201,14 @@ static void mps2_fpgaio_write(void *opaque, hwaddr off= set, uint64_t value, now =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); s->clk100hz_tick_offset =3D tickoff_from_counter(now, value, 100); break; + case A_COUNTER: + resync_counter(s); + s->counter =3D value; + break; + case A_PSCNTR: + resync_counter(s); + s->pscntr =3D value; + break; default: qemu_log_mask(LOG_GUEST_ERROR, "MPS2 FPGAIO write: bad offset 0x%x\n", (int) offset= ); @@ -150,6 +233,9 @@ static void mps2_fpgaio_reset(DeviceState *dev) s->misc =3D 0; s->clk1hz_tick_offset =3D tickoff_from_counter(now, 0, 1); s->clk100hz_tick_offset =3D tickoff_from_counter(now, 0, 100); + s->counter =3D 0; + s->pscntr =3D 0; + s->pscntr_sync_ticks =3D now; } =20 static void mps2_fpgaio_init(Object *obj) @@ -170,12 +256,15 @@ static bool mps2_fpgaio_counters_needed(void *opaque) =20 static const VMStateDescription mps2_fpgaio_counters_vmstate =3D { .name =3D "mps2-fpgaio/counters", - .version_id =3D 1, - .minimum_version_id =3D 1, + .version_id =3D 2, + .minimum_version_id =3D 2, .needed =3D mps2_fpgaio_counters_needed, .fields =3D (VMStateField[]) { VMSTATE_INT64(clk1hz_tick_offset, MPS2FPGAIO), VMSTATE_INT64(clk100hz_tick_offset, MPS2FPGAIO), + VMSTATE_UINT32(counter, MPS2FPGAIO), + VMSTATE_UINT32(pscntr, MPS2FPGAIO), + VMSTATE_INT64(pscntr_sync_ticks, MPS2FPGAIO), VMSTATE_END_OF_LIST() } }; --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534775212221892.8208612247797; Mon, 20 Aug 2018 07:26:52 -0700 (PDT) Received: from localhost ([::1]:47384 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl8s-0008N4-Qg for importer@patchew.org; Mon, 20 Aug 2018 10:26:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41823) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frku2-0003R1-MN for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frku0-0007D5-6u for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:30 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44608) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frktv-000797-7i; Mon, 20 Aug 2018 10:11:23 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frktu-0003Lt-6v; Mon, 20 Aug 2018 15:11:22 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:10:57 +0100 Message-Id: <20180820141116.9118-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 03/22] hw/timer/cmsdk-apb-dualtimer: Implement CMSDK dual timer module X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The Arm Cortex-M System Design Kit includes a "dual-input timer module" which combines two programmable down-counters. Implement a model of this device. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/timer/Makefile.objs | 1 + include/hw/timer/cmsdk-apb-dualtimer.h | 72 ++++ hw/timer/cmsdk-apb-dualtimer.c | 515 +++++++++++++++++++++++++ MAINTAINERS | 2 + default-configs/arm-softmmu.mak | 1 + hw/timer/trace-events | 5 + 6 files changed, 596 insertions(+) create mode 100644 include/hw/timer/cmsdk-apb-dualtimer.h create mode 100644 hw/timer/cmsdk-apb-dualtimer.c diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index e16b2b913ce..b32194d153d 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -44,4 +44,5 @@ common-obj-$(CONFIG_ASPEED_SOC) +=3D aspeed_timer.o =20 common-obj-$(CONFIG_SUN4V_RTC) +=3D sun4v-rtc.o common-obj-$(CONFIG_CMSDK_APB_TIMER) +=3D cmsdk-apb-timer.o +common-obj-$(CONFIG_CMSDK_APB_DUALTIMER) +=3D cmsdk-apb-dualtimer.o common-obj-$(CONFIG_MSF2) +=3D mss-timer.o diff --git a/include/hw/timer/cmsdk-apb-dualtimer.h b/include/hw/timer/cmsd= k-apb-dualtimer.h new file mode 100644 index 00000000000..9843a9dbb1d --- /dev/null +++ b/include/hw/timer/cmsdk-apb-dualtimer.h @@ -0,0 +1,72 @@ +/* + * ARM CMSDK APB dual-timer emulation + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "APB dual-input timer" which is part of the Cort= ex-M + * System Design Kit (CMSDK) and documented in the Cortex-M System + * Design Kit Technical Reference Manual (ARM DDI0479C): + * https://developer.arm.com/products/system-design/system-design-kits/cor= tex-m-system-design-kit + * + * QEMU interface: + * + QOM property "pclk-frq": frequency at which the timer is clocked + * + sysbus MMIO region 0: the register bank + * + sysbus IRQ 0: combined timer interrupt TIMINTC + * + sysbus IRO 1: timer block 1 interrupt TIMINT1 + * + sysbus IRQ 2: timer block 2 interrupt TIMINT2 + */ + +#ifndef CMSDK_APB_DUALTIMER_H +#define CMSDK_APB_DUALTIMER_H + +#include "hw/sysbus.h" +#include "hw/ptimer.h" + +#define TYPE_CMSDK_APB_DUALTIMER "cmsdk-apb-dualtimer" +#define CMSDK_APB_DUALTIMER(obj) OBJECT_CHECK(CMSDKAPBDualTimer, (obj), \ + TYPE_CMSDK_APB_DUALTIMER) + +typedef struct CMSDKAPBDualTimer CMSDKAPBDualTimer; + +/* One of the two identical timer modules in the dual-timer module */ +typedef struct CMSDKAPBDualTimerModule { + CMSDKAPBDualTimer *parent; + struct ptimer_state *timer; + qemu_irq timerint; + /* + * We must track the guest LOAD and VALUE register state by hand + * rather than leaving this state only in the ptimer limit/count, + * because if CONTROL.SIZE is 0 then only the low 16 bits of the + * counter actually counts, but the high half is still guest + * accessible. + */ + uint32_t load; + uint32_t value; + uint32_t control; + uint32_t intstatus; +} CMSDKAPBDualTimerModule; + +#define CMSDK_APB_DUALTIMER_NUM_MODULES 2 + +struct CMSDKAPBDualTimer { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + qemu_irq timerintc; + uint32_t pclk_frq; + + CMSDKAPBDualTimerModule timermod[CMSDK_APB_DUALTIMER_NUM_MODULES]; + uint32_t timeritcr; + uint32_t timeritop; +}; + +#endif diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c new file mode 100644 index 00000000000..4b005e28136 --- /dev/null +++ b/hw/timer/cmsdk-apb-dualtimer.c @@ -0,0 +1,515 @@ +/* + * ARM CMSDK APB dual-timer emulation + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "APB dual-input timer" which is part of the Cort= ex-M + * System Design Kit (CMSDK) and documented in the Cortex-M System + * Design Kit Technical Reference Manual (ARM DDI0479C): + * https://developer.arm.com/products/system-design/system-design-kits/cor= tex-m-system-design-kit + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "trace.h" +#include "qapi/error.h" +#include "qemu/main-loop.h" +#include "hw/sysbus.h" +#include "hw/registerfields.h" +#include "hw/timer/cmsdk-apb-dualtimer.h" + +REG32(TIMER1LOAD, 0x0) +REG32(TIMER1VALUE, 0x4) +REG32(TIMER1CONTROL, 0x8) + FIELD(CONTROL, ONESHOT, 0, 1) + FIELD(CONTROL, SIZE, 1, 1) + FIELD(CONTROL, PRESCALE, 2, 2) + FIELD(CONTROL, INTEN, 5, 1) + FIELD(CONTROL, MODE, 6, 1) + FIELD(CONTROL, ENABLE, 7, 1) +#define R_CONTROL_VALID_MASK (R_CONTROL_ONESHOT_MASK | R_CONTROL_SIZE_MASK= | \ + R_CONTROL_PRESCALE_MASK | R_CONTROL_INTEN_MA= SK | \ + R_CONTROL_MODE_MASK | R_CONTROL_ENABLE_MASK) +REG32(TIMER1INTCLR, 0xc) +REG32(TIMER1RIS, 0x10) +REG32(TIMER1MIS, 0x14) +REG32(TIMER1BGLOAD, 0x18) +REG32(TIMER2LOAD, 0x20) +REG32(TIMER2VALUE, 0x24) +REG32(TIMER2CONTROL, 0x28) +REG32(TIMER2INTCLR, 0x2c) +REG32(TIMER2RIS, 0x30) +REG32(TIMER2MIS, 0x34) +REG32(TIMER2BGLOAD, 0x38) +REG32(TIMERITCR, 0xf00) + FIELD(TIMERITCR, ENABLE, 0, 1) +#define R_TIMERITCR_VALID_MASK R_TIMERITCR_ENABLE_MASK +REG32(TIMERITOP, 0xf04) + FIELD(TIMERITOP, TIMINT1, 0, 1) + FIELD(TIMERITOP, TIMINT2, 1, 1) +#define R_TIMERITOP_VALID_MASK (R_TIMERITOP_TIMINT1_MASK | \ + R_TIMERITOP_TIMINT2_MASK) +REG32(PID4, 0xfd0) +REG32(PID5, 0xfd4) +REG32(PID6, 0xfd8) +REG32(PID7, 0xfdc) +REG32(PID0, 0xfe0) +REG32(PID1, 0xfe4) +REG32(PID2, 0xfe8) +REG32(PID3, 0xfec) +REG32(CID0, 0xff0) +REG32(CID1, 0xff4) +REG32(CID2, 0xff8) +REG32(CID3, 0xffc) + +/* PID/CID values */ +static const int timer_id[] =3D { + 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ + 0x23, 0xb8, 0x1b, 0x00, /* PID0..PID3 */ + 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ +}; + +static bool cmsdk_dualtimermod_intstatus(CMSDKAPBDualTimerModule *m) +{ + /* Return masked interrupt status for the timer module */ + return m->intstatus && (m->control & R_CONTROL_INTEN_MASK); +} + +static void cmsdk_apb_dualtimer_update(CMSDKAPBDualTimer *s) +{ + bool timint1, timint2, timintc; + + if (s->timeritcr) { + /* Integration test mode: outputs driven directly from TIMERITOP b= its */ + timint1 =3D s->timeritop & R_TIMERITOP_TIMINT1_MASK; + timint2 =3D s->timeritop & R_TIMERITOP_TIMINT2_MASK; + } else { + timint1 =3D cmsdk_dualtimermod_intstatus(&s->timermod[0]); + timint2 =3D cmsdk_dualtimermod_intstatus(&s->timermod[1]); + } + + timintc =3D timint1 || timint2; + + qemu_set_irq(s->timermod[0].timerint, timint1); + qemu_set_irq(s->timermod[1].timerint, timint2); + qemu_set_irq(s->timerintc, timintc); +} + +static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m, + uint32_t newctrl) +{ + /* Handle a write to the CONTROL register */ + uint32_t changed; + + newctrl &=3D R_CONTROL_VALID_MASK; + + changed =3D m->control ^ newctrl; + + if (changed & ~newctrl & R_CONTROL_ENABLE_MASK) { + /* ENABLE cleared, stop timer before any further changes */ + ptimer_stop(m->timer); + } + + if (changed & R_CONTROL_PRESCALE_MASK) { + int divisor; + + switch (FIELD_EX32(newctrl, CONTROL, PRESCALE)) { + case 0: + divisor =3D 1; + break; + case 1: + divisor =3D 16; + break; + case 2: + divisor =3D 256; + break; + case 3: + /* UNDEFINED; complain, and arbitrarily treat like 2 */ + qemu_log_mask(LOG_GUEST_ERROR, + "CMSDK APB dual-timer: CONTROL.PRESCALE=3D=3D0b1= 1" + " is undefined behaviour\n"); + divisor =3D 256; + break; + default: + g_assert_not_reached(); + } + ptimer_set_freq(m->timer, m->parent->pclk_frq / divisor); + } + + if (changed & R_CONTROL_MODE_MASK) { + uint32_t load; + if (newctrl & R_CONTROL_MODE_MASK) { + /* Periodic: the limit is the LOAD register value */ + load =3D m->load; + } else { + /* Free-running: counter wraps around */ + load =3D ptimer_get_limit(m->timer); + if (!(m->control & R_CONTROL_SIZE_MASK)) { + load =3D deposit32(load, 16, 16, extract32(m->load, 16, 16= )); + } + m->load =3D load; + load =3D 0xffffffff; + } + if (!(m->control & R_CONTROL_SIZE_MASK)) { + load &=3D 0xffff; + } + ptimer_set_limit(m->timer, load, 0); + } + + if (changed & R_CONTROL_SIZE_MASK) { + /* Timer switched between 16 and 32 bit count */ + uint32_t value, load; + + value =3D ptimer_get_count(m->timer); + load =3D ptimer_get_limit(m->timer); + if (newctrl & R_CONTROL_SIZE_MASK) { + /* 16 -> 32, top half of VALUE is in struct field */ + value =3D deposit32(value, 16, 16, extract32(m->value, 16, 16)= ); + } else { + /* 32 -> 16: save top half to struct field and truncate */ + m->value =3D value; + value &=3D 0xffff; + } + + if (newctrl & R_CONTROL_MODE_MASK) { + /* Periodic, timer limit has LOAD value */ + if (newctrl & R_CONTROL_SIZE_MASK) { + load =3D deposit32(load, 16, 16, extract32(m->load, 16, 16= )); + } else { + m->load =3D load; + load &=3D 0xffff; + } + } else { + /* Free-running, timer limit is set to give wraparound */ + if (newctrl & R_CONTROL_SIZE_MASK) { + load =3D 0xffffffff; + } else { + load =3D 0xffff; + } + } + ptimer_set_count(m->timer, value); + ptimer_set_limit(m->timer, load, 0); + } + + if (newctrl & R_CONTROL_ENABLE_MASK) { + /* + * ENABLE is set; start the timer after all other changes. + * We start it even if the ENABLE bit didn't actually change, + * in case the timer was an expired one-shot timer that has + * now been changed into a free-running or periodic timer. + */ + ptimer_run(m->timer, !!(newctrl & R_CONTROL_ONESHOT_MASK)); + } + + m->control =3D newctrl; +} + +static uint64_t cmsdk_apb_dualtimer_read(void *opaque, hwaddr offset, + unsigned size) +{ + CMSDKAPBDualTimer *s =3D CMSDK_APB_DUALTIMER(opaque); + uint64_t r; + + if (offset >=3D A_TIMERITCR) { + switch (offset) { + case A_TIMERITCR: + r =3D s->timeritcr; + break; + case A_PID4 ... A_CID3: + r =3D timer_id[(offset - A_PID4) / 4]; + break; + default: + bad_offset: + qemu_log_mask(LOG_GUEST_ERROR, + "CMSDK APB dual-timer read: bad offset %x\n", + (int) offset); + r =3D 0; + break; + } + } else { + int timer =3D offset >> 5; + CMSDKAPBDualTimerModule *m; + + if (timer >=3D ARRAY_SIZE(s->timermod)) { + goto bad_offset; + } + + m =3D &s->timermod[timer]; + + switch (offset & 0x1F) { + case A_TIMER1LOAD: + case A_TIMER1BGLOAD: + if (m->control & R_CONTROL_MODE_MASK) { + /* + * Periodic: the ptimer limit is the LOAD register value, = (or + * just the low 16 bits of it if the timer is in 16-bit mo= de) + */ + r =3D ptimer_get_limit(m->timer); + if (!(m->control & R_CONTROL_SIZE_MASK)) { + r =3D deposit32(r, 16, 16, extract32(m->load, 16, 16)); + } + } else { + /* Free-running: LOAD register value is just in m->load */ + r =3D m->load; + } + break; + case A_TIMER1VALUE: + r =3D ptimer_get_count(m->timer); + if (!(m->control & R_CONTROL_SIZE_MASK)) { + r =3D deposit32(r, 16, 16, extract32(m->value, 16, 16)); + } + break; + case A_TIMER1CONTROL: + r =3D m->control; + break; + case A_TIMER1RIS: + r =3D m->intstatus; + break; + case A_TIMER1MIS: + r =3D cmsdk_dualtimermod_intstatus(m); + break; + default: + goto bad_offset; + } + } + + trace_cmsdk_apb_dualtimer_read(offset, r, size); + return r; +} + +static void cmsdk_apb_dualtimer_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + CMSDKAPBDualTimer *s =3D CMSDK_APB_DUALTIMER(opaque); + + trace_cmsdk_apb_dualtimer_write(offset, value, size); + + if (offset >=3D A_TIMERITCR) { + switch (offset) { + case A_TIMERITCR: + s->timeritcr =3D value & R_TIMERITCR_VALID_MASK; + cmsdk_apb_dualtimer_update(s); + case A_TIMERITOP: + s->timeritop =3D value & R_TIMERITOP_VALID_MASK; + cmsdk_apb_dualtimer_update(s); + default: + bad_offset: + qemu_log_mask(LOG_GUEST_ERROR, + "CMSDK APB dual-timer write: bad offset %x\n", + (int) offset); + break; + } + } else { + int timer =3D offset >> 5; + CMSDKAPBDualTimerModule *m; + + if (timer >=3D ARRAY_SIZE(s->timermod)) { + goto bad_offset; + } + + m =3D &s->timermod[timer]; + + switch (offset & 0x1F) { + case A_TIMER1LOAD: + /* Set the limit, and immediately reload the count from it */ + m->load =3D value; + m->value =3D value; + if (!(m->control & R_CONTROL_SIZE_MASK)) { + value &=3D 0xffff; + } + if (!(m->control & R_CONTROL_MODE_MASK)) { + /* + * In free-running mode this won't set the limit but will + * still change the current count value. + */ + ptimer_set_count(m->timer, value); + } else { + if (!value) { + ptimer_stop(m->timer); + } + ptimer_set_limit(m->timer, value, 1); + if (value && (m->control & R_CONTROL_ENABLE_MASK)) { + /* Force possibly-expired oneshot timer to restart */ + ptimer_run(m->timer, 1); + } + } + break; + case A_TIMER1BGLOAD: + /* Set the limit, but not the current count */ + m->load =3D value; + if (!(m->control & R_CONTROL_MODE_MASK)) { + /* In free-running mode there is no limit */ + break; + } + if (!(m->control & R_CONTROL_SIZE_MASK)) { + value &=3D 0xffff; + } + ptimer_set_limit(m->timer, value, 0); + break; + case A_TIMER1CONTROL: + cmsdk_dualtimermod_write_control(m, value); + cmsdk_apb_dualtimer_update(s); + break; + case A_TIMER1INTCLR: + m->intstatus =3D 0; + cmsdk_apb_dualtimer_update(s); + break; + default: + goto bad_offset; + } + } +} + +static const MemoryRegionOps cmsdk_apb_dualtimer_ops =3D { + .read =3D cmsdk_apb_dualtimer_read, + .write =3D cmsdk_apb_dualtimer_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + /* byte/halfword accesses are just zero-padded on reads and writes */ + .impl.min_access_size =3D 4, + .impl.max_access_size =3D 4, + .valid.min_access_size =3D 1, + .valid.max_access_size =3D 4, +}; + +static void cmsdk_dualtimermod_tick(void *opaque) +{ + CMSDKAPBDualTimerModule *m =3D opaque; + + m->intstatus =3D 1; + cmsdk_apb_dualtimer_update(m->parent); +} + +static void cmsdk_dualtimermod_reset(CMSDKAPBDualTimerModule *m) +{ + m->control =3D R_CONTROL_INTEN_MASK; + m->intstatus =3D 0; + m->load =3D 0; + m->value =3D 0xffffffff; + ptimer_stop(m->timer); + /* + * We start in free-running mode, with VALUE at 0xffffffff, and + * in 16-bit counter mode. This means that the ptimer count and + * limit must both be set to 0xffff, so we wrap at 16 bits. + */ + ptimer_set_limit(m->timer, 0xffff, 1); + ptimer_set_freq(m->timer, m->parent->pclk_frq); +} + +static void cmsdk_apb_dualtimer_reset(DeviceState *dev) +{ + CMSDKAPBDualTimer *s =3D CMSDK_APB_DUALTIMER(dev); + int i; + + trace_cmsdk_apb_dualtimer_reset(); + + for (i =3D 0; i < ARRAY_SIZE(s->timermod); i++) { + cmsdk_dualtimermod_reset(&s->timermod[i]); + } + s->timeritcr =3D 0; + s->timeritop =3D 0; +} + +static void cmsdk_apb_dualtimer_init(Object *obj) +{ + SysBusDevice *sbd =3D SYS_BUS_DEVICE(obj); + CMSDKAPBDualTimer *s =3D CMSDK_APB_DUALTIMER(obj); + int i; + + memory_region_init_io(&s->iomem, obj, &cmsdk_apb_dualtimer_ops, + s, "cmsdk-apb-dualtimer", 0x1000); + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->timerintc); + + for (i =3D 0; i < ARRAY_SIZE(s->timermod); i++) { + sysbus_init_irq(sbd, &s->timermod[i].timerint); + } +} + +static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp) +{ + CMSDKAPBDualTimer *s =3D CMSDK_APB_DUALTIMER(dev); + int i; + + if (s->pclk_frq =3D=3D 0) { + error_setg(errp, "CMSDK APB timer: pclk-frq property must be set"); + return; + } + + for (i =3D 0; i < ARRAY_SIZE(s->timermod); i++) { + CMSDKAPBDualTimerModule *m =3D &s->timermod[i]; + QEMUBH *bh =3D qemu_bh_new(cmsdk_dualtimermod_tick, m); + + m->parent =3D s; + m->timer =3D ptimer_init(bh, + PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD | + PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT | + PTIMER_POLICY_NO_IMMEDIATE_RELOAD | + PTIMER_POLICY_NO_COUNTER_ROUND_DOWN); + } +} + +static const VMStateDescription cmsdk_dualtimermod_vmstate =3D { + .name =3D "cmsdk-apb-dualtimer-module", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_PTIMER(timer, CMSDKAPBDualTimerModule), + VMSTATE_UINT32(load, CMSDKAPBDualTimerModule), + VMSTATE_UINT32(value, CMSDKAPBDualTimerModule), + VMSTATE_UINT32(control, CMSDKAPBDualTimerModule), + VMSTATE_UINT32(intstatus, CMSDKAPBDualTimerModule), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription cmsdk_apb_dualtimer_vmstate =3D { + .name =3D "cmsdk-apb-dualtimer", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(timermod, CMSDKAPBDualTimer, + CMSDK_APB_DUALTIMER_NUM_MODULES, + 1, cmsdk_dualtimermod_vmstate, + CMSDKAPBDualTimerModule), + VMSTATE_UINT32(timeritcr, CMSDKAPBDualTimer), + VMSTATE_UINT32(timeritop, CMSDKAPBDualTimer), + VMSTATE_END_OF_LIST() + } +}; + +static Property cmsdk_apb_dualtimer_properties[] =3D { + DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBDualTimer, pclk_frq, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D cmsdk_apb_dualtimer_realize; + dc->vmsd =3D &cmsdk_apb_dualtimer_vmstate; + dc->reset =3D cmsdk_apb_dualtimer_reset; + dc->props =3D cmsdk_apb_dualtimer_properties; +} + +static const TypeInfo cmsdk_apb_dualtimer_info =3D { + .name =3D TYPE_CMSDK_APB_DUALTIMER, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(CMSDKAPBDualTimer), + .instance_init =3D cmsdk_apb_dualtimer_init, + .class_init =3D cmsdk_apb_dualtimer_class_init, +}; + +static void cmsdk_apb_dualtimer_register_types(void) +{ + type_register_static(&cmsdk_apb_dualtimer_info); +} + +type_init(cmsdk_apb_dualtimer_register_types); diff --git a/MAINTAINERS b/MAINTAINERS index 6902a568f44..2a4c9d63f2d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -455,6 +455,8 @@ F: hw/timer/pl031.c F: include/hw/arm/primecell.h F: hw/timer/cmsdk-apb-timer.c F: include/hw/timer/cmsdk-apb-timer.h +F: hw/timer/cmsdk-apb-dualtimer.c +F: include/hw/timer/cmsdk-apb-dualtimer.h F: hw/char/cmsdk-apb-uart.c F: include/hw/char/cmsdk-apb-uart.h F: hw/watchdog/cmsdk-apb-watchdog.c diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.= mak index a92bc34fb24..c8137a5d3c7 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -103,6 +103,7 @@ CONFIG_STM32F2XX_SPI=3Dy CONFIG_STM32F205_SOC=3Dy =20 CONFIG_CMSDK_APB_TIMER=3Dy +CONFIG_CMSDK_APB_DUALTIMER=3Dy CONFIG_CMSDK_APB_UART=3Dy CONFIG_CMSDK_APB_WATCHDOG=3Dy =20 diff --git a/hw/timer/trace-events b/hw/timer/trace-events index e6e042fddb7..fa4213df5be 100644 --- a/hw/timer/trace-events +++ b/hw/timer/trace-events @@ -61,5 +61,10 @@ cmsdk_apb_timer_read(uint64_t offset, uint64_t data, uns= igned size) "CMSDK APB t cmsdk_apb_timer_write(uint64_t offset, uint64_t data, unsigned size) "CMSD= K APB timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" cmsdk_apb_timer_reset(void) "CMSDK APB timer: reset" =20 +# hw/timer/cmsdk_apb_dualtimer.c +cmsdk_apb_dualtimer_read(uint64_t offset, uint64_t data, unsigned size) "C= MSDK APB dualtimer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +cmsdk_apb_dualtimer_write(uint64_t offset, uint64_t data, unsigned size) "= CMSDK APB dualtimer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +cmsdk_apb_dualtimer_reset(void) "CMSDK APB dualtimer: reset" + # hw/timer/xlnx-zynqmp-rtc.c xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, i= nt sec) "Get time from host: %d-%d-%d %2d:%02d:%02d" --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534774851749691.5233516258123; Mon, 20 Aug 2018 07:20:51 -0700 (PDT) Received: from localhost ([::1]:47342 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl2v-00030z-Kz for importer@patchew.org; Mon, 20 Aug 2018 10:20:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41818) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frku2-0003Qv-I0 for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frku1-0007EH-M4 for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:30 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44614) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frkty-0007AT-GW; Mon, 20 Aug 2018 10:11:26 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frktv-0003MC-Ec; Mon, 20 Aug 2018 15:11:23 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:10:58 +0100 Message-Id: <20180820141116.9118-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 04/22] hw/arm/iotkit: Wire up the dualtimer X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Now we have a model of the CMSDK dual timer, we can wire it up in the IoTKit. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- include/hw/arm/iotkit.h | 3 ++- hw/arm/iotkit.c | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 2cddde55dd1..3e6d806e352 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -56,6 +56,7 @@ #include "hw/misc/tz-ppc.h" #include "hw/misc/tz-mpc.h" #include "hw/timer/cmsdk-apb-timer.h" +#include "hw/timer/cmsdk-apb-dualtimer.h" #include "hw/misc/unimp.h" #include "hw/or-irq.h" #include "hw/core/split-irq.h" @@ -87,7 +88,7 @@ typedef struct IoTKit { SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC]; qemu_or_irq mpc_irq_orgate; =20 - UnimplementedDeviceState dualtimer; + CMSDKAPBDualTimer dualtimer; UnimplementedDeviceState s32ktimer; =20 MemoryRegion container; diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index 8cadc8b1608..130d013909e 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -139,7 +139,7 @@ static void iotkit_init(Object *obj) sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1), TYPE_CMSDK_APB_TIMER); sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualt= imer), - TYPE_UNIMPLEMENTED_DEVICE); + TYPE_CMSDK_APB_DUALTIMER); object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate, sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ, &error_abort, NULL); @@ -390,13 +390,15 @@ static void iotkit_realize(DeviceState *dev, Error **= errp) return; } =20 - qdev_prop_set_string(DEVICE(&s->dualtimer), "name", "Dual timer"); - qdev_prop_set_uint64(DEVICE(&s->dualtimer), "size", 0x1000); + + qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq= ); object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err= ); if (err) { error_propagate(errp, err); return; } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0, + qdev_get_gpio_in(DEVICE(&s->armv7m), 5)); mr =3D sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0); object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", = &err); if (err) { --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534774611867144.54186290624557; Mon, 20 Aug 2018 07:16:51 -0700 (PDT) Received: from localhost ([::1]:47320 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkzC-0007vr-0R for importer@patchew.org; Mon, 20 Aug 2018 10:16:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41756) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frku0-0003OX-8W for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frktz-0007CK-Fk for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:28 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44614) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frktx-0007AT-Fm; Mon, 20 Aug 2018 10:11:25 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frktw-0003N2-HX; Mon, 20 Aug 2018 15:11:24 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:10:59 +0100 Message-Id: <20180820141116.9118-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 05/22] hw/arm/mps2: Wire up dual-timer in mps2-an385 and mps2-an511 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The MPS2 FPGA images for the Cortex-M3 (mps2-an385 and mps2-511) both include a CMSDK dual-timer module. Wire this up. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- hw/arm/mps2.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c index 0a0ae867d9b..564624629d0 100644 --- a/hw/arm/mps2.c +++ b/hw/arm/mps2.c @@ -34,6 +34,7 @@ #include "hw/misc/unimp.h" #include "hw/char/cmsdk-apb-uart.h" #include "hw/timer/cmsdk-apb-timer.h" +#include "hw/timer/cmsdk-apb-dualtimer.h" #include "hw/misc/mps2-scc.h" #include "hw/devices.h" #include "net/net.h" @@ -64,6 +65,7 @@ typedef struct { MemoryRegion blockram_m3; MemoryRegion sram; MPS2SCC scc; + CMSDKAPBDualTimer dualtimer; } MPS2MachineState; =20 #define TYPE_MPS2_MACHINE "mps2" @@ -297,6 +299,15 @@ static void mps2_common_init(MachineState *machine) cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK= _FRQ); cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK= _FRQ); =20 + sysbus_init_child_obj(OBJECT(mms), "dualtimer", &mms->dualtimer, + sizeof(mms->dualtimer), TYPE_CMSDK_APB_DUALTIMER= ); + qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ); + object_property_set_bool(OBJECT(&mms->dualtimer), true, "realized", + &error_fatal); + sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0, + qdev_get_gpio_in(armv7m, 10)); + sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000); + object_initialize(&mms->scc, sizeof(mms->scc), TYPE_MPS2_SCC); sccdev =3D DEVICE(&mms->scc); qdev_set_parent_bus(sccdev, sysbus_get_default()); --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534775033913410.97088819887165; Mon, 20 Aug 2018 07:23:53 -0700 (PDT) Received: from localhost ([::1]:47362 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl60-0005a8-NI for importer@patchew.org; Mon, 20 Aug 2018 10:23:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41860) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frku3-0003SQ-MH for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frku2-0007F9-FS for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:31 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44614) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frktz-0007AT-Gk; Mon, 20 Aug 2018 10:11:27 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frktx-0003Nb-Gq; Mon, 20 Aug 2018 15:11:25 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:00 +0100 Message-Id: <20180820141116.9118-7-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 06/22] hw/arm/iotkit: Wire up the watchdogs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 The IoTKit includes three different instances of the CMSDK APB watchdog; create and wire them up. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- include/hw/arm/iotkit.h | 6 +++++ hw/arm/iotkit.c | 58 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 3e6d806e352..776d0497087 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -57,6 +57,7 @@ #include "hw/misc/tz-mpc.h" #include "hw/timer/cmsdk-apb-timer.h" #include "hw/timer/cmsdk-apb-dualtimer.h" +#include "hw/watchdog/cmsdk-apb-watchdog.h" #include "hw/misc/unimp.h" #include "hw/or-irq.h" #include "hw/core/split-irq.h" @@ -87,10 +88,15 @@ typedef struct IoTKit { SplitIRQ ppc_irq_splitter[NUM_PPCS]; SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC]; qemu_or_irq mpc_irq_orgate; + qemu_or_irq nmi_orgate; =20 CMSDKAPBDualTimer dualtimer; UnimplementedDeviceState s32ktimer; =20 + CMSDKAPBWatchdog s32kwatchdog; + CMSDKAPBWatchdog nswatchdog; + CMSDKAPBWatchdog swatchdog; + MemoryRegion container; MemoryRegion alias1; MemoryRegion alias2; diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index 130d013909e..5cedfa03570 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -19,6 +19,9 @@ #include "hw/misc/unimp.h" #include "hw/arm/arm.h" =20 +/* Clock frequency in HZ of the 32KHz "slow clock" */ +#define S32KCLK (32 * 1000) + /* Create an alias region of @size bytes starting at @base * which mirrors the memory starting at @orig. */ @@ -140,6 +143,15 @@ static void iotkit_init(Object *obj) TYPE_CMSDK_APB_TIMER); sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualt= imer), TYPE_CMSDK_APB_DUALTIMER); + sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog, + sizeof(s->s32kwatchdog), TYPE_CMSDK_APB_WATCHDOG= ); + sysbus_init_child_obj(obj, "nswatchdog", &s->nswatchdog, + sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG); + sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog, + sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG); + object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, + sizeof(s->nmi_orgate), TYPE_OR_IRQ, + &error_abort, NULL); object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate, sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ, &error_abort, NULL); @@ -510,12 +522,52 @@ static void iotkit_realize(DeviceState *dev, Error **= errp) create_unimplemented_device("SYSINFO", 0x40020000, 0x1000); =20 create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000); - create_unimplemented_device("S32KWATCHDOG", 0x5002e000, 0x1000); + + /* This OR gate wires together outputs from the secure watchdogs to NM= I */ + object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err); + if (err) { + error_propagate(errp, err); + return; + } + object_property_set_bool(OBJECT(&s->nmi_orgate), true, "realized", &er= r); + if (err) { + error_propagate(errp, err); + return; + } + qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0, + qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI"= , 0)); + + qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK); + object_property_set_bool(OBJECT(&s->s32kwatchdog), true, "realized", &= err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, + qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0)); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000); =20 /* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */ =20 - create_unimplemented_device("NS watchdog", 0x40081000, 0x1000); - create_unimplemented_device("S watchdog", 0x50081000, 0x1000); + qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk= _frq); + object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &er= r); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0, + qdev_get_gpio_in(DEVICE(&s->armv7m), 1)); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000); + + qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_= frq); + object_property_set_bool(OBJECT(&s->swatchdog), true, "realized", &err= ); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0, + qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1)); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000); =20 for (i =3D 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) { Object *splitter =3D OBJECT(&s->ppc_irq_splitter[i]); --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534774437281585.2269645336527; Mon, 20 Aug 2018 07:13:57 -0700 (PDT) Received: from localhost ([::1]:47297 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkwD-0004o2-Fc for importer@patchew.org; Mon, 20 Aug 2018 10:13:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41825) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frku2-0003R8-Nc for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frku1-0007EM-Mt for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:30 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44622) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frktz-0007Bt-El; Mon, 20 Aug 2018 10:11:27 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frkty-0003OK-Gc; Mon, 20 Aug 2018 15:11:26 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:01 +0100 Message-Id: <20180820141116.9118-8-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 07/22] hw/arm/iotkit: Wire up the S32KTIMER X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 The IoTKit has a CMSDK timer device that runs on the S32KCLK. Create this and wire it up. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- include/hw/arm/iotkit.h | 2 +- hw/arm/iotkit.c | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 776d0497087..0f5c5101708 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -83,6 +83,7 @@ typedef struct IoTKit { TZMPC mpc; CMSDKAPBTIMER timer0; CMSDKAPBTIMER timer1; + CMSDKAPBTIMER s32ktimer; qemu_or_irq ppc_irq_orgate; SplitIRQ sec_resp_splitter; SplitIRQ ppc_irq_splitter[NUM_PPCS]; @@ -91,7 +92,6 @@ typedef struct IoTKit { qemu_or_irq nmi_orgate; =20 CMSDKAPBDualTimer dualtimer; - UnimplementedDeviceState s32ktimer; =20 CMSDKAPBWatchdog s32kwatchdog; CMSDKAPBWatchdog nswatchdog; diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index 5cedfa03570..cb0ec456f39 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -141,6 +141,8 @@ static void iotkit_init(Object *obj) TYPE_CMSDK_APB_TIMER); sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1), TYPE_CMSDK_APB_TIMER); + sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32kt= imer), + TYPE_CMSDK_APB_TIMER); sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualt= imer), TYPE_CMSDK_APB_DUALTIMER); sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog, @@ -166,8 +168,6 @@ static void iotkit_init(Object *obj) TYPE_SPLIT_IRQ, &error_abort, NULL); g_free(name); } - sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32kt= imer), - TYPE_UNIMPLEMENTED_DEVICE); } =20 static void iotkit_exp_irq(void *opaque, int n, int level) @@ -476,13 +476,14 @@ static void iotkit_realize(DeviceState *dev, Error **= errp) /* Devices behind APB PPC1: * 0x4002f000: S32K timer */ - qdev_prop_set_string(DEVICE(&s->s32ktimer), "name", "S32KTIMER"); - qdev_prop_set_uint64(DEVICE(&s->s32ktimer), "size", 0x1000); + qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK); object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err= ); if (err) { error_propagate(errp, err); return; } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0, + qdev_get_gpio_in(DEVICE(&s->armv7m), 2)); mr =3D sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0); object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", = &err); if (err) { --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534774482115929.192088746704; Mon, 20 Aug 2018 07:14:42 -0700 (PDT) Received: from localhost ([::1]:47301 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkx6-0005ZZ-MX for importer@patchew.org; Mon, 20 Aug 2018 10:14:40 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41967) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frku8-0003Yc-Re for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frku6-0007Hj-2X for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:36 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44622) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frku1-0007Bt-Me; Mon, 20 Aug 2018 10:11:30 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frktz-0003Od-Fc; Mon, 20 Aug 2018 15:11:27 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:02 +0100 Message-Id: <20180820141116.9118-9-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 08/22] hw/misc/iotkit-sysctl: Implement IoTKit system control element X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The Arm IoTKit includes a system control element which provides a block of read-only ID registers and a block of read-write control registers. Implement a minimal version of this. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/misc/Makefile.objs | 1 + include/hw/misc/iotkit-sysctl.h | 49 ++++++ hw/misc/iotkit-sysctl.c | 261 ++++++++++++++++++++++++++++++++ MAINTAINERS | 2 + default-configs/arm-softmmu.mak | 1 + hw/misc/trace-events | 7 + 6 files changed, 321 insertions(+) create mode 100644 include/hw/misc/iotkit-sysctl.h create mode 100644 hw/misc/iotkit-sysctl.c diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 22714b08510..ac1f3bc030c 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -66,6 +66,7 @@ obj-$(CONFIG_MPS2_SCC) +=3D mps2-scc.o obj-$(CONFIG_TZ_MPC) +=3D tz-mpc.o obj-$(CONFIG_TZ_PPC) +=3D tz-ppc.o obj-$(CONFIG_IOTKIT_SECCTL) +=3D iotkit-secctl.o +obj-$(CONFIG_IOTKIT_SYSCTL) +=3D iotkit-sysctl.o =20 obj-$(CONFIG_PVPANIC) +=3D pvpanic.o obj-$(CONFIG_HYPERV_TESTDEV) +=3D hyperv_testdev.o diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysct= l.h new file mode 100644 index 00000000000..e36613cb5ee --- /dev/null +++ b/include/hw/misc/iotkit-sysctl.h @@ -0,0 +1,49 @@ +/* + * ARM IoTKit system control element + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "system control element" which is part of the + * Arm IoTKit and documented in + * http://infocenter.arm.com/help/index.jsp?topic=3D/com.arm.doc.ecm060125= 6/index.html + * Specifically, it implements the "system information block" and + * "system control register" blocks. + * + * QEMU interface: + * + sysbus MMIO region 0: the system information register bank + * + sysbus MMIO region 1: the system control register bank + */ + +#ifndef HW_MISC_IOTKIT_SYSCTL_H +#define HW_MISC_IOTKIT_SYSCTL_H + +#include "hw/sysbus.h" + +#define TYPE_IOTKIT_SYSCTL "iotkit-sysctl" +#define IOTKIT_SYSCTL(obj) OBJECT_CHECK(IoTKitSysCtl, (obj), \ + TYPE_IOTKIT_SYSCTL) + +typedef struct IoTKitSysCtl { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + + uint32_t secure_debug; + uint32_t reset_syndrome; + uint32_t reset_mask; + uint32_t gretreg; + uint32_t initsvrtor0; + uint32_t cpuwait; + uint32_t wicctrl; +} IoTKitSysCtl; + +#endif diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c new file mode 100644 index 00000000000..a21d8bd6789 --- /dev/null +++ b/hw/misc/iotkit-sysctl.c @@ -0,0 +1,261 @@ +/* + * ARM IoTKit system control element + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "system control element" which is part of the + * Arm IoTKit and documented in + * http://infocenter.arm.com/help/index.jsp?topic=3D/com.arm.doc.ecm060125= 6/index.html + * Specifically, it implements the "system control register" blocks. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "trace.h" +#include "qapi/error.h" +#include "sysemu/sysemu.h" +#include "hw/sysbus.h" +#include "hw/registerfields.h" +#include "hw/misc/iotkit-sysctl.h" + +REG32(SECDBGSTAT, 0x0) +REG32(SECDBGSET, 0x4) +REG32(SECDBGCLR, 0x8) +REG32(RESET_SYNDROME, 0x100) +REG32(RESET_MASK, 0x104) +REG32(SWRESET, 0x108) + FIELD(SWRESET, SWRESETREQ, 9, 1) +REG32(GRETREG, 0x10c) +REG32(INITSVRTOR0, 0x110) +REG32(CPUWAIT, 0x118) +REG32(BUSWAIT, 0x11c) +REG32(WICCTRL, 0x120) +REG32(PID4, 0xfd0) +REG32(PID5, 0xfd4) +REG32(PID6, 0xfd8) +REG32(PID7, 0xfdc) +REG32(PID0, 0xfe0) +REG32(PID1, 0xfe4) +REG32(PID2, 0xfe8) +REG32(PID3, 0xfec) +REG32(CID0, 0xff0) +REG32(CID1, 0xff4) +REG32(CID2, 0xff8) +REG32(CID3, 0xffc) + +/* PID/CID values */ +static const int sysctl_id[] =3D { + 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ + 0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */ + 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ +}; + +static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset, + unsigned size) +{ + IoTKitSysCtl *s =3D IOTKIT_SYSCTL(opaque); + uint64_t r; + + switch (offset) { + case A_SECDBGSTAT: + r =3D s->secure_debug; + break; + case A_RESET_SYNDROME: + r =3D s->reset_syndrome; + break; + case A_RESET_MASK: + r =3D s->reset_mask; + break; + case A_GRETREG: + r =3D s->gretreg; + break; + case A_INITSVRTOR0: + r =3D s->initsvrtor0; + break; + case A_CPUWAIT: + r =3D s->cpuwait; + break; + case A_BUSWAIT: + /* In IoTKit BUSWAIT is reserved, R/O, zero */ + r =3D 0; + break; + case A_WICCTRL: + r =3D s->wicctrl; + break; + case A_PID4 ... A_CID3: + r =3D sysctl_id[(offset - A_PID4) / 4]; + break; + case A_SECDBGSET: + case A_SECDBGCLR: + case A_SWRESET: + qemu_log_mask(LOG_GUEST_ERROR, + "IoTKit SysCtl read: read of WO offset %x\n", + (int)offset); + r =3D 0; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "IoTKit SysCtl read: bad offset %x\n", (int)offset); + r =3D 0; + break; + } + trace_iotkit_sysctl_read(offset, r, size); + return r; +} + +static void iotkit_sysctl_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + IoTKitSysCtl *s =3D IOTKIT_SYSCTL(opaque); + + trace_iotkit_sysctl_write(offset, value, size); + + /* + * Most of the state here has to do with control of reset and + * similar kinds of power up -- for instance the guest can ask + * what the reason for the last reset was, or forbid reset for + * some causes (like the non-secure watchdog). Most of this is + * not relevant to QEMU, which doesn't really model anything other + * than a full power-on reset. + * We just model the registers as reads-as-written. + */ + + switch (offset) { + case A_RESET_SYNDROME: + qemu_log_mask(LOG_UNIMP, + "IoTKit SysCtl RESET_SYNDROME unimplemented\n"); + s->reset_syndrome =3D value; + break; + case A_RESET_MASK: + qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n= "); + s->reset_mask =3D value; + break; + case A_GRETREG: + /* + * General retention register, which is only reset by a power-on + * reset. Technically this implementation is complete, since + * QEMU only supports power-on resets... + */ + s->gretreg =3D value; + break; + case A_INITSVRTOR0: + qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVRTOR0 unimplemented\= n"); + s->initsvrtor0 =3D value; + break; + case A_CPUWAIT: + qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CPUWAIT unimplemented\n"); + s->cpuwait =3D value; + break; + case A_WICCTRL: + qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n"); + s->wicctrl =3D value; + break; + case A_SECDBGSET: + /* write-1-to-set */ + qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n"= ); + s->secure_debug |=3D value; + break; + case A_SECDBGCLR: + /* write-1-to-clear */ + s->secure_debug &=3D ~value; + break; + case A_SWRESET: + /* One w/o bit to request a reset; all other bits reserved */ + if (value & R_SWRESET_SWRESETREQ_MASK) { + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + } + break; + case A_BUSWAIT: /* In IoTKit BUSWAIT is reserved, R/O, zero */ + case A_SECDBGSTAT: + case A_PID4 ... A_CID3: + qemu_log_mask(LOG_GUEST_ERROR, + "IoTKit SysCtl write: write of RO offset %x\n", + (int)offset); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "IoTKit SysCtl write: bad offset %x\n", (int)offset); + break; + } +} + +static const MemoryRegionOps iotkit_sysctl_ops =3D { + .read =3D iotkit_sysctl_read, + .write =3D iotkit_sysctl_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + /* byte/halfword accesses are just zero-padded on reads and writes */ + .impl.min_access_size =3D 4, + .impl.max_access_size =3D 4, + .valid.min_access_size =3D 1, + .valid.max_access_size =3D 4, +}; + +static void iotkit_sysctl_reset(DeviceState *dev) +{ + IoTKitSysCtl *s =3D IOTKIT_SYSCTL(dev); + + trace_iotkit_sysctl_reset(); + s->secure_debug =3D 0; + s->reset_syndrome =3D 1; + s->reset_mask =3D 0; + s->gretreg =3D 0; + s->initsvrtor0 =3D 0x10000000; + s->cpuwait =3D 0; + s->wicctrl =3D 0; +} + +static void iotkit_sysctl_init(Object *obj) +{ + SysBusDevice *sbd =3D SYS_BUS_DEVICE(obj); + IoTKitSysCtl *s =3D IOTKIT_SYSCTL(obj); + + memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops, + s, "iotkit-sysctl", 0x1000); + sysbus_init_mmio(sbd, &s->iomem); +} + +static const VMStateDescription iotkit_sysctl_vmstate =3D { + .name =3D "iotkit-sysctl", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(secure_debug, IoTKitSysCtl), + VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl), + VMSTATE_UINT32(reset_mask, IoTKitSysCtl), + VMSTATE_UINT32(gretreg, IoTKitSysCtl), + VMSTATE_UINT32(initsvrtor0, IoTKitSysCtl), + VMSTATE_UINT32(cpuwait, IoTKitSysCtl), + VMSTATE_UINT32(wicctrl, IoTKitSysCtl), + VMSTATE_END_OF_LIST() + } +}; + +static void iotkit_sysctl_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->vmsd =3D &iotkit_sysctl_vmstate; + dc->reset =3D iotkit_sysctl_reset; +} + +static const TypeInfo iotkit_sysctl_info =3D { + .name =3D TYPE_IOTKIT_SYSCTL, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(IoTKitSysCtl), + .instance_init =3D iotkit_sysctl_init, + .class_init =3D iotkit_sysctl_class_init, +}; + +static void iotkit_sysctl_register_types(void) +{ + type_register_static(&iotkit_sysctl_info); +} + +type_init(iotkit_sysctl_register_types); diff --git a/MAINTAINERS b/MAINTAINERS index 2a4c9d63f2d..ea35aa2cca5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -539,6 +539,8 @@ F: hw/misc/mps2-*.c F: include/hw/misc/mps2-*.h F: hw/arm/iotkit.c F: include/hw/arm/iotkit.h +F: hw/misc/iotkit-sysctl.c +F: include/hw/misc/iotkit-sysctl.h =20 Musicpal M: Jan Kiszka diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.= mak index c8137a5d3c7..79aac7702a9 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -114,6 +114,7 @@ CONFIG_TZ_MPC=3Dy CONFIG_TZ_PPC=3Dy CONFIG_IOTKIT=3Dy CONFIG_IOTKIT_SECCTL=3Dy +CONFIG_IOTKIT_SYSCTL=3Dy =20 CONFIG_VERSATILE=3Dy CONFIG_VERSATILE_PCI=3Dy diff --git a/hw/misc/trace-events b/hw/misc/trace-events index 1341508b336..7faf7592832 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -116,3 +116,10 @@ ccm_freq(uint32_t freq) "freq =3D %d\n" ccm_clock_freq(uint32_t clock, uint32_t freq) "(Clock =3D %d) =3D %d\n" ccm_read_reg(const char *reg_name, uint32_t value) "reg[%s] <=3D 0x%" PRIx= 32 "\n" ccm_write_reg(const char *reg_name, uint32_t value) "reg[%s] =3D> 0x%" PRI= x32 "\n" + +# hw/misc/iotkit-sysctl.c +iotkit_sysinfo_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit= SysInfo read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +iotkit_sysinfo_write(uint64_t offset, uint64_t data, unsigned size) "IoTKi= t SysInfo write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +iotkit_sysctl_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit = SysCtl read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +iotkit_sysctl_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit= SysCtl write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +iotkit_sysctl_reset(void) "IoTKit SysCtl: reset" --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534774650038624.4369690546339; Mon, 20 Aug 2018 07:17:30 -0700 (PDT) Received: from localhost ([::1]:47322 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkzo-0008M3-Kj for importer@patchew.org; Mon, 20 Aug 2018 10:17:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41906) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frku6-0003VT-BH for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frku5-0007HE-4V for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:34 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44630) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frku1-0007Du-Lw; Mon, 20 Aug 2018 10:11:29 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frku0-0003PN-Kx; Mon, 20 Aug 2018 15:11:28 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:03 +0100 Message-Id: <20180820141116.9118-10-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 09/22] hw/misc/iotkit-sysinfo: Implement IoTKit system information block X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement the IoTKit system control element's system information block; this is just a pair of read-only version/config registers, plus the usual PID/CID ID registers. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Richard Henderson --- hw/misc/Makefile.objs | 1 + include/hw/misc/iotkit-sysinfo.h | 37 +++++++++ hw/misc/iotkit-sysinfo.c | 128 +++++++++++++++++++++++++++++++ MAINTAINERS | 2 + default-configs/arm-softmmu.mak | 1 + 5 files changed, 169 insertions(+) create mode 100644 include/hw/misc/iotkit-sysinfo.h create mode 100644 hw/misc/iotkit-sysinfo.c diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index ac1f3bc030c..af2b503824e 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -67,6 +67,7 @@ obj-$(CONFIG_TZ_MPC) +=3D tz-mpc.o obj-$(CONFIG_TZ_PPC) +=3D tz-ppc.o obj-$(CONFIG_IOTKIT_SECCTL) +=3D iotkit-secctl.o obj-$(CONFIG_IOTKIT_SYSCTL) +=3D iotkit-sysctl.o +obj-$(CONFIG_IOTKIT_SYSINFO) +=3D iotkit-sysinfo.o =20 obj-$(CONFIG_PVPANIC) +=3D pvpanic.o obj-$(CONFIG_HYPERV_TESTDEV) +=3D hyperv_testdev.o diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysi= nfo.h new file mode 100644 index 00000000000..7b2e1a5e48b --- /dev/null +++ b/include/hw/misc/iotkit-sysinfo.h @@ -0,0 +1,37 @@ +/* + * ARM IoTKit system information block + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "system information block" which is part of the + * Arm IoTKit and documented in + * http://infocenter.arm.com/help/index.jsp?topic=3D/com.arm.doc.ecm060125= 6/index.html + * QEMU interface: + * + sysbus MMIO region 0: the system information register bank + */ + +#ifndef HW_MISC_IOTKIT_SYSINFO_H +#define HW_MISC_IOTKIT_SYSINFO_H + +#include "hw/sysbus.h" + +#define TYPE_IOTKIT_SYSINFO "iotkit-sysinfo" +#define IOTKIT_SYSINFO(obj) OBJECT_CHECK(IoTKitSysInfo, (obj), \ + TYPE_IOTKIT_SYSINFO) + +typedef struct IoTKitSysInfo { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; +} IoTKitSysInfo; + +#endif diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c new file mode 100644 index 00000000000..78955bc45f5 --- /dev/null +++ b/hw/misc/iotkit-sysinfo.c @@ -0,0 +1,128 @@ +/* + * ARM IoTKit system information block + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the "system information block" which is part of the + * Arm IoTKit and documented in + * http://infocenter.arm.com/help/index.jsp?topic=3D/com.arm.doc.ecm060125= 6/index.html + * It consists of 2 read-only version/config registers, plus the + * usual ID registers. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "trace.h" +#include "qapi/error.h" +#include "sysemu/sysemu.h" +#include "hw/sysbus.h" +#include "hw/registerfields.h" +#include "hw/misc/iotkit-sysinfo.h" + +REG32(SYS_VERSION, 0x0) +REG32(SYS_CONFIG, 0x4) +REG32(PID4, 0xfd0) +REG32(PID5, 0xfd4) +REG32(PID6, 0xfd8) +REG32(PID7, 0xfdc) +REG32(PID0, 0xfe0) +REG32(PID1, 0xfe4) +REG32(PID2, 0xfe8) +REG32(PID3, 0xfec) +REG32(CID0, 0xff0) +REG32(CID1, 0xff4) +REG32(CID2, 0xff8) +REG32(CID3, 0xffc) + +/* PID/CID values */ +static const int sysinfo_id[] =3D { + 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ + 0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */ + 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ +}; + +static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset, + unsigned size) +{ + uint64_t r; + + switch (offset) { + case A_SYS_VERSION: + r =3D 0x41743; + break; + + case A_SYS_CONFIG: + r =3D 0x31; + break; + case A_PID4 ... A_CID3: + r =3D sysinfo_id[(offset - A_PID4) / 4]; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "IoTKit SysInfo read: bad offset %x\n", (int)offset); + r =3D 0; + break; + } + trace_iotkit_sysinfo_read(offset, r, size); + return r; +} + +static void iotkit_sysinfo_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + trace_iotkit_sysinfo_write(offset, value, size); + + qemu_log_mask(LOG_GUEST_ERROR, + "IoTKit SysInfo: write to RO offset 0x%x\n", (int)offset= ); +} + +static const MemoryRegionOps iotkit_sysinfo_ops =3D { + .read =3D iotkit_sysinfo_read, + .write =3D iotkit_sysinfo_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + /* byte/halfword accesses are just zero-padded on reads and writes */ + .impl.min_access_size =3D 4, + .impl.max_access_size =3D 4, + .valid.min_access_size =3D 1, + .valid.max_access_size =3D 4, +}; + +static void iotkit_sysinfo_init(Object *obj) +{ + SysBusDevice *sbd =3D SYS_BUS_DEVICE(obj); + IoTKitSysInfo *s =3D IOTKIT_SYSINFO(obj); + + memory_region_init_io(&s->iomem, obj, &iotkit_sysinfo_ops, + s, "iotkit-sysinfo", 0x1000); + sysbus_init_mmio(sbd, &s->iomem); +} + +static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data) +{ + /* + * This device has no guest-modifiable state and so it + * does not need a reset function or VMState. + */ +} + +static const TypeInfo iotkit_sysinfo_info =3D { + .name =3D TYPE_IOTKIT_SYSINFO, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(IoTKitSysInfo), + .instance_init =3D iotkit_sysinfo_init, + .class_init =3D iotkit_sysinfo_class_init, +}; + +static void iotkit_sysinfo_register_types(void) +{ + type_register_static(&iotkit_sysinfo_info); +} + +type_init(iotkit_sysinfo_register_types); diff --git a/MAINTAINERS b/MAINTAINERS index ea35aa2cca5..cb780f463cb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -541,6 +541,8 @@ F: hw/arm/iotkit.c F: include/hw/arm/iotkit.h F: hw/misc/iotkit-sysctl.c F: include/hw/misc/iotkit-sysctl.h +F: hw/misc/iotkit-sysinfo.c +F: include/hw/misc/iotkit-sysinfo.h =20 Musicpal M: Jan Kiszka diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.= mak index 79aac7702a9..ebbdcb29f38 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -115,6 +115,7 @@ CONFIG_TZ_PPC=3Dy CONFIG_IOTKIT=3Dy CONFIG_IOTKIT_SECCTL=3Dy CONFIG_IOTKIT_SYSCTL=3Dy +CONFIG_IOTKIT_SYSINFO=3Dy =20 CONFIG_VERSATILE=3Dy CONFIG_VERSATILE_PCI=3Dy --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534775498909854.7378176127468; Mon, 20 Aug 2018 07:31:38 -0700 (PDT) Received: from localhost ([::1]:47424 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frlDR-0004ma-Iq for importer@patchew.org; Mon, 20 Aug 2018 10:31:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41975) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frku9-0003Yp-1Q for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frku7-0007J0-Vq for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:36 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44638) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frku5-0007GM-OI; Mon, 20 Aug 2018 10:11:33 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frku1-0003Pg-LK; Mon, 20 Aug 2018 15:11:29 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:04 +0100 Message-Id: <20180820141116.9118-11-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 10/22] hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Wire up the system control element's register banks (sysctl and sysinfo). This is the last of the previously completely unimplemented components in the IoTKit. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- include/hw/arm/iotkit.h | 6 +++++- hw/arm/iotkit.c | 26 ++++++++++++++++++-------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 0f5c5101708..426dc326a0d 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -58,7 +58,8 @@ #include "hw/timer/cmsdk-apb-timer.h" #include "hw/timer/cmsdk-apb-dualtimer.h" #include "hw/watchdog/cmsdk-apb-watchdog.h" -#include "hw/misc/unimp.h" +#include "hw/misc/iotkit-sysctl.h" +#include "hw/misc/iotkit-sysinfo.h" #include "hw/or-irq.h" #include "hw/core/split-irq.h" =20 @@ -97,6 +98,9 @@ typedef struct IoTKit { CMSDKAPBWatchdog nswatchdog; CMSDKAPBWatchdog swatchdog; =20 + IoTKitSysCtl sysctl; + IoTKitSysCtl sysinfo; + MemoryRegion container; MemoryRegion alias1; MemoryRegion alias2; diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index cb0ec456f39..f8276b5425c 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -16,7 +16,6 @@ #include "hw/sysbus.h" #include "hw/registerfields.h" #include "hw/arm/iotkit.h" -#include "hw/misc/unimp.h" #include "hw/arm/arm.h" =20 /* Clock frequency in HZ of the 32KHz "slow clock" */ @@ -151,6 +150,10 @@ static void iotkit_init(Object *obj) sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG); sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog, sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG); + sysbus_init_child_obj(obj, "iotkit-sysctl", &s->sysctl, + sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL); + sysbus_init_child_obj(obj, "iotkit-sysinfo", &s->sysinfo, + sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO); object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, sizeof(s->nmi_orgate), TYPE_OR_IRQ, &error_abort, NULL); @@ -516,13 +519,20 @@ static void iotkit_realize(DeviceState *dev, Error **= errp) qdev_get_gpio_in_named(dev_apb_ppc1, "cfg_sec_resp", 0)); =20 - /* Using create_unimplemented_device() maps the stub into the - * system address space rather than into our container, but the - * overall effect to the guest is the same. - */ - create_unimplemented_device("SYSINFO", 0x40020000, 0x1000); - - create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000); + object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + /* System information registers */ + sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000); + /* System control registers */ + object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000); =20 /* This OR gate wires together outputs from the secure watchdogs to NM= I */ object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err); --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 153477461613546.330002133003745; Mon, 20 Aug 2018 07:16:56 -0700 (PDT) Received: from localhost ([::1]:47321 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkzF-0007yh-W6 for importer@patchew.org; Mon, 20 Aug 2018 10:16:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42023) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkuA-0003az-Rt for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frku8-0007Jr-Tg for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:38 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44638) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frku4-0007GM-IK; Mon, 20 Aug 2018 10:11:32 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frku3-0003QV-K3; Mon, 20 Aug 2018 15:11:31 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:05 +0100 Message-Id: <20180820141116.9118-12-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 11/22] hw/misc/tz-msc: Model TrustZone Master Security Controller X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement a model of the TrustZone Master Securtiy Controller, as documented in the Arm CoreLink SIE-200 System IP for Embedded TRM (DDI0571G): https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g The MSC is intended to sit in front of a device which can be a bus master (eg a DMA controller) and programmably gate its transactions. This allows a bus-mastering device to be controlled by non-secure code but still restricted from making accesses to addresses which are secure-only. Signed-off-by: Peter Maydell --- hw/misc/Makefile.objs | 1 + include/hw/misc/tz-msc.h | 79 ++++++++ hw/misc/tz-msc.c | 308 ++++++++++++++++++++++++++++++++ MAINTAINERS | 2 + default-configs/arm-softmmu.mak | 1 + hw/misc/trace-events | 9 + 6 files changed, 400 insertions(+) create mode 100644 include/hw/misc/tz-msc.h create mode 100644 hw/misc/tz-msc.c diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index af2b503824e..6d50b03cfdb 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -64,6 +64,7 @@ obj-$(CONFIG_MPS2_FPGAIO) +=3D mps2-fpgaio.o obj-$(CONFIG_MPS2_SCC) +=3D mps2-scc.o =20 obj-$(CONFIG_TZ_MPC) +=3D tz-mpc.o +obj-$(CONFIG_TZ_MSC) +=3D tz-msc.o obj-$(CONFIG_TZ_PPC) +=3D tz-ppc.o obj-$(CONFIG_IOTKIT_SECCTL) +=3D iotkit-secctl.o obj-$(CONFIG_IOTKIT_SYSCTL) +=3D iotkit-sysctl.o diff --git a/include/hw/misc/tz-msc.h b/include/hw/misc/tz-msc.h new file mode 100644 index 00000000000..116b96ae9b8 --- /dev/null +++ b/include/hw/misc/tz-msc.h @@ -0,0 +1,79 @@ +/* + * ARM TrustZone master security controller emulation + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* + * This is a model of the TrustZone master security controller (MSC). + * It is documented in the ARM CoreLink SIE-200 System IP for Embedded TRM + * (DDI 0571G): + * https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g + * + * The MSC sits in front of a device which can be a bus master (such as + * a DMA controller) and allows secure software to configure it to either + * pass through or reject transactions made by that bus master. + * Rejected transactions may be configured to either be aborted, or to + * behave as RAZ/WI. An interrupt can be signalled for a rejected transact= ion. + * + * The MSC has no register interface -- it is configured purely by a + * collection of input signals from other hardware in the system. Typically + * they are either hardwired or exposed in an ad-hoc register interface by + * the SoC that uses the MSC. + * + * We don't currently implement the irq_enable GPIO input, because on + * the MPS2 FPGA images it is always tied high, which is awkward to + * implement in QEMU. + * + * QEMU interface: + * + Named GPIO input "cfg_nonsec": set to 1 if the bus master should be + * treated as nonsecure, or 0 for secure + * + Named GPIO input "cfg_sec_resp": set to 1 if a rejected transaction s= hould + * result in a transaction error, or 0 for the transaction to RAZ/WI + * + Named GPIO input "irq_clear": set to 1 to clear a pending interrupt + * + Named GPIO output "irq": set for a transaction-failed interrupt + * + Property "downstream": MemoryRegion defining where bus master transac= tions + * are made if they are not blocked + * + Property "idau": an object implementing IDAUInterface, which defines = which + * addresses should be treated as secure and which as non-secure. + * This need not be the same IDAU as the one used by the CPU. + * + sysbus MMIO region 0: MemoryRegion defining the upstream end of the M= SC; + * this should be passed to the bus master device as the region it should + * make memory transactions to + */ + +#ifndef TZ_MSC_H +#define TZ_MSC_H + +#include "hw/sysbus.h" +#include "target/arm/idau.h" + +#define TYPE_TZ_MSC "tz-msc" +#define TZ_MSC(obj) OBJECT_CHECK(TZMSC, (obj), TYPE_TZ_MSC) + +typedef struct TZMSC { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + + /* State: these just track the values of our input signals */ + bool cfg_nonsec; + bool cfg_sec_resp; + bool irq_clear; + /* State: are we asserting irq ? */ + bool irq_status; + + qemu_irq irq; + MemoryRegion *downstream; + AddressSpace downstream_as; + MemoryRegion upstream; + IDAUInterface *idau; +} TZMSC; + +#endif diff --git a/hw/misc/tz-msc.c b/hw/misc/tz-msc.c new file mode 100644 index 00000000000..9e352044ea5 --- /dev/null +++ b/hw/misc/tz-msc.c @@ -0,0 +1,308 @@ +/* + * ARM TrustZone master security controller emulation + * + * Copyright (c) 2018 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "trace.h" +#include "hw/sysbus.h" +#include "hw/registerfields.h" +#include "hw/misc/tz-msc.h" + +static void tz_msc_update_irq(TZMSC *s) +{ + bool level =3D s->irq_status; + + trace_tz_msc_update_irq(level); + qemu_set_irq(s->irq, level); +} + +static void tz_msc_cfg_nonsec(void *opaque, int n, int level) +{ + TZMSC *s =3D TZ_MSC(opaque); + + trace_tz_msc_cfg_nonsec(level); + s->cfg_nonsec =3D level; +} + +static void tz_msc_cfg_sec_resp(void *opaque, int n, int level) +{ + TZMSC *s =3D TZ_MSC(opaque); + + trace_tz_msc_cfg_sec_resp(level); + s->cfg_sec_resp =3D level; +} + +static void tz_msc_irq_clear(void *opaque, int n, int level) +{ + TZMSC *s =3D TZ_MSC(opaque); + + trace_tz_msc_irq_clear(level); + + s->irq_clear =3D level; + if (level) { + s->irq_status =3D false; + tz_msc_update_irq(s); + } +} + +/* The MSC may either block a transaction by aborting it, block a + * transaction by making it RAZ/WI, allow it through with + * MemTxAttrs indicating a secure transaction, or allow it with + * MemTxAttrs indicating a non-secure transaction. + */ +typedef enum MSCAction { + MSCBlockAbort, + MSCBlockRAZWI, + MSCAllowSecure, + MSCAllowNonSecure, +} MSCAction; + +static MSCAction tz_msc_check(TZMSC *s, hwaddr addr) +{ + /* + * Check whether to allow an access from the bus master, returning + * an MSCAction indicating the required behaviour. If the transaction + * is blocked, the caller must check cfg_sec_resp to determine + * whether to abort or RAZ/WI the transaction. + */ + IDAUInterfaceClass *iic =3D IDAU_INTERFACE_GET_CLASS(s->idau); + IDAUInterface *ii =3D IDAU_INTERFACE(s->idau); + bool idau_exempt =3D false, idau_ns =3D true, idau_nsc =3D true; + int idau_region =3D IREGION_NOTVALID; + + iic->check(ii, addr, &idau_region, &idau_exempt, &idau_ns, &idau_nsc); + + if (idau_exempt) { + /* + * Uncheck region -- OK, transaction type depends on + * whether bus master is configured as Secure or NonSecure + */ + return s->cfg_nonsec ? MSCAllowNonSecure : MSCAllowSecure; + } + + if (idau_ns) { + /* NonSecure region -- always forward as NS transaction */ + return MSCAllowNonSecure; + } + + if (!s->cfg_nonsec) { + /* Access to Secure region by Secure bus master: OK */ + return MSCAllowSecure; + } + + /* Attempted access to Secure region by NS bus master: block */ + trace_tz_msc_access_blocked(addr); + if (!s->cfg_sec_resp) { + return MSCBlockRAZWI; + } + + /* + * The TRM isn't clear on behaviour if irq_clear is high when a + * transaction is blocked. We assume that the MSC behaves like the + * PPC, where holding irq_clear high suppresses the interrupt. + */ + if (!s->irq_clear) { + s->irq_status =3D true; + tz_msc_update_irq(s); + } + return MSCBlockAbort; +} + +static MemTxResult tz_msc_read(void *opaque, hwaddr addr, uint64_t *pdata, + unsigned size, MemTxAttrs attrs) +{ + TZMSC *s =3D opaque; + AddressSpace *as =3D &s->downstream_as; + uint64_t data; + MemTxResult res; + + switch (tz_msc_check(s, addr)) { + case MSCBlockAbort: + return MEMTX_ERROR; + case MSCBlockRAZWI: + *pdata =3D 0; + return MEMTX_OK; + case MSCAllowSecure: + attrs.secure =3D 1; + attrs.unspecified =3D 0; + break; + case MSCAllowNonSecure: + attrs.secure =3D 0; + attrs.unspecified =3D 0; + break; + } + + switch (size) { + case 1: + data =3D address_space_ldub(as, addr, attrs, &res); + break; + case 2: + data =3D address_space_lduw_le(as, addr, attrs, &res); + break; + case 4: + data =3D address_space_ldl_le(as, addr, attrs, &res); + break; + case 8: + data =3D address_space_ldq_le(as, addr, attrs, &res); + break; + default: + g_assert_not_reached(); + } + *pdata =3D data; + return res; +} + +static MemTxResult tz_msc_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size, MemTxAttrs attrs) +{ + TZMSC *s =3D opaque; + AddressSpace *as =3D &s->downstream_as; + MemTxResult res; + + switch (tz_msc_check(s, addr)) { + case MSCBlockAbort: + return MEMTX_ERROR; + case MSCBlockRAZWI: + return MEMTX_OK; + case MSCAllowSecure: + attrs.secure =3D 1; + attrs.unspecified =3D 0; + break; + case MSCAllowNonSecure: + attrs.secure =3D 0; + attrs.unspecified =3D 0; + break; + } + + switch (size) { + case 1: + address_space_stb(as, addr, val, attrs, &res); + break; + case 2: + address_space_stw_le(as, addr, val, attrs, &res); + break; + case 4: + address_space_stl_le(as, addr, val, attrs, &res); + break; + case 8: + address_space_stq_le(as, addr, val, attrs, &res); + break; + default: + g_assert_not_reached(); + } + return res; +} + +static const MemoryRegionOps tz_msc_ops =3D { + .read_with_attrs =3D tz_msc_read, + .write_with_attrs =3D tz_msc_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, +}; + +static void tz_msc_reset(DeviceState *dev) +{ + TZMSC *s =3D TZ_MSC(dev); + + trace_tz_msc_reset(); + s->cfg_sec_resp =3D false; + s->cfg_nonsec =3D false; + s->irq_clear =3D 0; + s->irq_status =3D 0; +} + +static void tz_msc_init(Object *obj) +{ + DeviceState *dev =3D DEVICE(obj); + TZMSC *s =3D TZ_MSC(obj); + + qdev_init_gpio_in_named(dev, tz_msc_cfg_nonsec, "cfg_nonsec", 1); + qdev_init_gpio_in_named(dev, tz_msc_cfg_sec_resp, "cfg_sec_resp", 1); + qdev_init_gpio_in_named(dev, tz_msc_irq_clear, "irq_clear", 1); + qdev_init_gpio_out_named(dev, &s->irq, "irq", 1); +} + +static void tz_msc_realize(DeviceState *dev, Error **errp) +{ + Object *obj =3D OBJECT(dev); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + TZMSC *s =3D TZ_MSC(dev); + const char *name =3D "tz-msc-downstream"; + uint64_t size; + + /* + * We can't create the upstream end of the port until realize, + * as we don't know the size of the MR used as the downstream until th= en. + * We insist on having a downstream, to avoid complicating the + * code with handling the "don't know how big this is" case. It's easy + * enough for the user to create an unimplemented_device as downstream + * if they have nothing else to plug into this. + */ + if (!s->downstream) { + error_setg(errp, "MSC 'downstream' link not set"); + return; + } + if (!s->idau) { + error_setg(errp, "MSC 'idau' link not set"); + return; + } + + size =3D memory_region_size(s->downstream); + address_space_init(&s->downstream_as, s->downstream, name); + memory_region_init_io(&s->upstream, obj, &tz_msc_ops, s, name, size); + sysbus_init_mmio(sbd, &s->upstream); +} + +static const VMStateDescription tz_msc_vmstate =3D { + .name =3D "tz-msc", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_BOOL(cfg_nonsec, TZMSC), + VMSTATE_BOOL(cfg_sec_resp, TZMSC), + VMSTATE_BOOL(irq_clear, TZMSC), + VMSTATE_BOOL(irq_status, TZMSC), + VMSTATE_END_OF_LIST() + } +}; + +static Property tz_msc_properties[] =3D { + DEFINE_PROP_LINK("downstream", TZMSC, downstream, + TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_LINK("idau", TZMSC, idau, + TYPE_IDAU_INTERFACE, IDAUInterface *), + DEFINE_PROP_END_OF_LIST(), +}; + +static void tz_msc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D tz_msc_realize; + dc->vmsd =3D &tz_msc_vmstate; + dc->reset =3D tz_msc_reset; + dc->props =3D tz_msc_properties; +} + +static const TypeInfo tz_msc_info =3D { + .name =3D TYPE_TZ_MSC, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(TZMSC), + .instance_init =3D tz_msc_init, + .class_init =3D tz_msc_class_init, +}; + +static void tz_msc_register_types(void) +{ + type_register_static(&tz_msc_info); +} + +type_init(tz_msc_register_types); diff --git a/MAINTAINERS b/MAINTAINERS index cb780f463cb..b2f8b562dc5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -465,6 +465,8 @@ F: hw/misc/tz-ppc.c F: include/hw/misc/tz-ppc.h F: hw/misc/tz-mpc.c F: include/hw/misc/tz-mpc.h +F: hw/misc/tz-msc.c +F: include/hw/misc/tz-msc.h =20 ARM cores M: Peter Maydell diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.= mak index ebbdcb29f38..0483d548d96 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -111,6 +111,7 @@ CONFIG_MPS2_FPGAIO=3Dy CONFIG_MPS2_SCC=3Dy =20 CONFIG_TZ_MPC=3Dy +CONFIG_TZ_MSC=3Dy CONFIG_TZ_PPC=3Dy CONFIG_IOTKIT=3Dy CONFIG_IOTKIT_SECCTL=3Dy diff --git a/hw/misc/trace-events b/hw/misc/trace-events index 7faf7592832..52466c77c4e 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -92,6 +92,15 @@ tz_mpc_mem_blocked_write(uint64_t addr, uint64_t data, u= nsigned size, bool secur tz_mpc_translate(uint64_t addr, int flags, const char *idx, const char *re= s) "TZ MPC translate: addr 0x%" PRIx64 " flags 0x%x iommu_idx %s: %s" tz_mpc_iommu_notify(uint64_t addr) "TZ MPC iommu: notifying UNMAP/MAP for = 0x%" PRIx64 =20 +# hw/misc/tz-msc.c +tz_msc_reset(void) "TZ MSC: reset" +tz_msc_cfg_nonsec(int level) "TZ MSC: cfg_nonsec =3D %d" +tz_msc_cfg_sec_resp(int level) "TZ MSC: cfg_sec_resp =3D %d" +tz_msc_irq_enable(int level) "TZ MSC: int_enable =3D %d" +tz_msc_irq_clear(int level) "TZ MSC: int_clear =3D %d" +tz_msc_update_irq(int level) "TZ MSC: setting irq line to %d" +tz_msc_access_blocked(uint64_t offset) "TZ MSC: offset 0x%" PRIx64 " acces= s blocked" + # hw/misc/tz-ppc.c tz_ppc_reset(void) "TZ PPC: reset" tz_ppc_cfg_nonsec(int n, int level) "TZ PPC: cfg_nonsec[%d] =3D %d" --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534775050174264.354723148037; Mon, 20 Aug 2018 07:24:10 -0700 (PDT) Received: from localhost ([::1]:47363 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl6G-0005kW-Rq for importer@patchew.org; Mon, 20 Aug 2018 10:24:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42018) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkuA-0003ad-JR for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frku9-0007KL-Cq for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:38 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44638) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frku6-0007GM-OY; Mon, 20 Aug 2018 10:11:34 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frku4-0003Qy-Me; Mon, 20 Aug 2018 15:11:32 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:06 +0100 Message-Id: <20180820141116.9118-13-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 12/22] hw/misc/iotkit-secctl: Wire up registers for controlling MSCs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 The IoTKit does not have any Master Security Contollers itself, but it does provide registers in the secure privilege control block which allow control of MSCs in the external system. Add support for these registers. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- include/hw/misc/iotkit-secctl.h | 14 +++++++ hw/misc/iotkit-secctl.c | 73 +++++++++++++++++++++++++++++---- 2 files changed, 79 insertions(+), 8 deletions(-) diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secct= l.h index 082c14c925e..1a193b306f1 100644 --- a/include/hw/misc/iotkit-secctl.h +++ b/include/hw/misc/iotkit-secctl.h @@ -19,6 +19,7 @@ * + named GPIO output "sec_resp_cfg" indicating whether blocked accesses * should RAZ/WI or bus error * + named GPIO output "nsc_cfg" whose value tracks the NSCCFG register v= alue + * + named GPIO output "msc_irq" for the combined IRQ line from the MSCs * Controlling the 2 APB PPCs in the IoTKit: * + named GPIO outputs apb_ppc0_nonsec[0..2] and apb_ppc1_nonsec * + named GPIO outputs apb_ppc0_ap[0..2] and apb_ppc1_ap @@ -44,6 +45,11 @@ * Controlling each of the 16 expansion MPCs which a system using the IoTK= it * might provide: * + named GPIO inputs mpcexp_status[0..15] + * Controlling each of the 16 expansion MSCs which a system using the IoTK= it + * might provide: + * + named GPIO inputs mscexp_status[0..15] + * + named GPIO outputs mscexp_clear[0..15] + * + named GPIO outputs mscexp_ns[0..15] */ =20 #ifndef IOTKIT_SECCTL_H @@ -62,6 +68,7 @@ #define IOTS_NUM_AHB_EXP_PPC 4 #define IOTS_NUM_EXP_MPC 16 #define IOTS_NUM_MPC 1 +#define IOTS_NUM_EXP_MSC 16 =20 typedef struct IoTKitSecCtl IoTKitSecCtl; =20 @@ -103,6 +110,13 @@ struct IoTKitSecCtl { uint32_t brginten; uint32_t mpcintstatus; =20 + uint32_t secmscintstat; + uint32_t secmscinten; + uint32_t nsmscexp; + qemu_irq mscexp_clear[IOTS_NUM_EXP_MSC]; + qemu_irq mscexp_ns[IOTS_NUM_EXP_MSC]; + qemu_irq msc_irq; + IoTKitSecCtlPPC apb[IOTS_NUM_APB_PPC]; IoTKitSecCtlPPC apbexp[IOTS_NUM_APB_EXP_PPC]; IoTKitSecCtlPPC ahbexp[IOTS_NUM_APB_EXP_PPC]; diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c index de4fd8e36d2..2222b3e147d 100644 --- a/hw/misc/iotkit-secctl.c +++ b/hw/misc/iotkit-secctl.c @@ -190,12 +190,13 @@ static MemTxResult iotkit_secctl_s_read(void *opaque,= hwaddr addr, r =3D s->apbexp[offset_to_ppc_idx(offset)].sp; break; case A_SECMSCINTSTAT: + r =3D s->secmscintstat; + break; case A_SECMSCINTEN: + r =3D s->secmscinten; + break; case A_NSMSCEXP: - qemu_log_mask(LOG_UNIMP, - "IoTKit SecCtl S block read: " - "unimplemented offset 0x%x\n", offset); - r =3D 0; + r =3D s->nsmscexp; break; case A_PID4: case A_PID5: @@ -291,6 +292,23 @@ static void iotkit_secctl_ppc_update_irq_enable(IoTKit= SecCtlPPC *ppc) qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1)= ); } =20 +static void iotkit_secctl_update_mscexp_irqs(qemu_irq *msc_irqs, uint32_t = value) +{ + int i; + + for (i =3D 0; i < IOTS_NUM_EXP_MSC; i++) { + qemu_set_irq(msc_irqs[i], extract32(value, i + 16, 1)); + } +} + +static void iotkit_secctl_update_msc_irq(IoTKitSecCtl *s) +{ + /* Update the combined MSC IRQ, based on S_MSCEXP_STATUS and S_MSCEXP_= EN */ + bool level =3D s->secmscintstat & s->secmscinten; + + qemu_set_irq(s->msc_irq, level); +} + static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr, uint64_t value, unsigned size, MemTxAttrs attrs) @@ -370,10 +388,15 @@ static MemTxResult iotkit_secctl_s_write(void *opaque= , hwaddr addr, iotkit_secctl_ppc_sp_write(ppc, value); break; case A_SECMSCINTCLR: + iotkit_secctl_update_mscexp_irqs(s->mscexp_clear, value); + break; case A_SECMSCINTEN: - qemu_log_mask(LOG_UNIMP, - "IoTKit SecCtl S block write: " - "unimplemented offset 0x%x\n", offset); + s->secmscinten =3D value; + iotkit_secctl_update_msc_irq(s); + break; + case A_NSMSCEXP: + s->nsmscexp =3D value; + iotkit_secctl_update_mscexp_irqs(s->mscexp_ns, value); break; case A_SECMPCINTSTATUS: case A_SECPPCINTSTAT: @@ -381,7 +404,6 @@ static MemTxResult iotkit_secctl_s_write(void *opaque, = hwaddr addr, case A_BRGINTSTAT: case A_AHBNSPPC0: case A_AHBSPPPC0: - case A_NSMSCEXP: case A_PID4: case A_PID5: case A_PID6: @@ -588,6 +610,14 @@ static void iotkit_secctl_mpcexp_status(void *opaque, = int n, int level) s->mpcintstatus =3D deposit32(s->mpcintstatus, n + 16, 1, !!level); } =20 +static void iotkit_secctl_mscexp_status(void *opaque, int n, int level) +{ + IoTKitSecCtl *s =3D IOTKIT_SECCTL(opaque); + + s->secmscintstat =3D deposit32(s->secmscintstat, n + 16, 1, !!level); + iotkit_secctl_update_msc_irq(s); +} + static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level) { IoTKitSecCtlPPC *ppc =3D opaque; @@ -660,6 +690,14 @@ static void iotkit_secctl_init(Object *obj) qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status, "mpcexp_status", IOTS_NUM_EXP_MPC); =20 + qdev_init_gpio_in_named(dev, iotkit_secctl_mscexp_status, + "mscexp_status", IOTS_NUM_EXP_MSC); + qdev_init_gpio_out_named(dev, s->mscexp_clear, "mscexp_clear", + IOTS_NUM_EXP_MSC); + qdev_init_gpio_out_named(dev, s->mscexp_ns, "mscexp_ns", + IOTS_NUM_EXP_MSC); + qdev_init_gpio_out_named(dev, &s->msc_irq, "msc_irq", 1); + memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops, s, "iotkit-secctl-s-regs", 0x1000); memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops, @@ -690,6 +728,24 @@ static const VMStateDescription iotkit_secctl_mpcintst= atus_vmstate =3D { } }; =20 +static bool needed_always(void *opaque) +{ + return true; +} + +static const VMStateDescription iotkit_secctl_msc_vmstate =3D { + .name =3D "iotkit-secctl/msc", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D needed_always, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(secmscintstat, IoTKitSecCtl), + VMSTATE_UINT32(secmscinten, IoTKitSecCtl), + VMSTATE_UINT32(nsmscexp, IoTKitSecCtl), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription iotkit_secctl_vmstate =3D { .name =3D "iotkit-secctl", .version_id =3D 1, @@ -710,6 +766,7 @@ static const VMStateDescription iotkit_secctl_vmstate = =3D { }, .subsections =3D (const VMStateDescription*[]) { &iotkit_secctl_mpcintstatus_vmstate, + &iotkit_secctl_msc_vmstate, NULL }, }; --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 153477487846424.58129609613536; Mon, 20 Aug 2018 07:21:18 -0700 (PDT) Received: from localhost ([::1]:47348 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl3V-0003V5-5q for importer@patchew.org; Mon, 20 Aug 2018 10:21:17 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41991) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkuA-0003aA-1L for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frku9-0007K3-0y for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:38 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44646) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frku6-0007Hi-M4; Mon, 20 Aug 2018 10:11:34 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frku5-0003RU-PL; Mon, 20 Aug 2018 15:11:33 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:07 +0100 Message-Id: <20180820141116.9118-14-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 13/22] hw/arm/iotkit: Wire up the lines for MSCs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 The IoTKit doesn't have any MSCs itself but it does need some wiring to connect the external signals from MSCs in the outer board model up to the registers and the NVIC IRQ line. We also need to expose a MemoryRegion corresponding to the AHB bus, so that MSCs in the outer board model can use that as their downstream port. (In the FPGA this is the "AHB Slave Expansion" ports shown in the block diagram in the AN505 documentation.) Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- include/hw/arm/iotkit.h | 8 ++++++++ hw/arm/iotkit.c | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 426dc326a0d..3a8ee639085 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -28,6 +28,9 @@ * + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts * + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts, which * are wired to the NVIC lines 32 .. n+32 + * + sysbus MMIO region 0 is the "AHB Slave Expansion" which allows + * bus master devices in the board model to make transactions into + * all the devices and memory areas in the IoTKit * Controlling up to 4 AHB expansion PPBs which a system using the IoTKit * might provide: * + named GPIO outputs apb_ppcexp{0,1,2,3}_nonsec[0..15] @@ -45,6 +48,11 @@ * Controlling each of the 16 expansion MPCs which a system using the IoTK= it * might provide: * + named GPIO inputs mpcexp_status[0..15] + * Controlling each of the 16 expansion MSCs which a system using the IoTK= it + * might provide: + * + named GPIO inputs mscexp_status[0..15] + * + named GPIO outputs mscexp_clear[0..15] + * + named GPIO outputs mscexp_ns[0..15] */ =20 #ifndef IOTKIT_H diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index f8276b5425c..8742200fb42 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -667,6 +667,21 @@ static void iotkit_realize(DeviceState *dev, Error **e= rrp) =20 iotkit_forward_sec_resp_cfg(s); =20 + /* Forward the MSC related signals */ + qdev_pass_gpios(dev_secctl, dev, "mscexp_status"); + qdev_pass_gpios(dev_secctl, dev, "mscexp_clear"); + qdev_pass_gpios(dev_secctl, dev, "mscexp_ns"); + qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0, + qdev_get_gpio_in(DEVICE(&s->armv7m), 11)); + + /* + * Expose our container region to the board model; this corresponds + * to the AHB Slave Expansion ports which allow bus master devices + * (eg DMA controllers) in the board model to make transactions into + * devices in the IoTKit. + */ + sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container); + system_clock_scale =3D NANOSECONDS_PER_SECOND / s->mainclk_frq; } =20 --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534774974845437.95185558368996; Mon, 20 Aug 2018 07:22:54 -0700 (PDT) Received: from localhost ([::1]:47359 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl53-0004kv-A3 for importer@patchew.org; Mon, 20 Aug 2018 10:22:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42130) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkuF-0003eV-8s for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frkuD-0007OS-V3 for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:43 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44654) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frkuA-0007Jz-I5; Mon, 20 Aug 2018 10:11:38 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frku6-0003Rn-OK; Mon, 20 Aug 2018 15:11:34 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:08 +0100 Message-Id: <20180820141116.9118-15-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 14/22] hw/arm/mps2-tz: Create PL081s and MSCs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 The AN505 FPGA image includes four PL081 DMA controllers, each of which is gated by a Master Security Controller that allows the guest to prevent a non-secure DMA controller from accessing memory that is used by secure guest code. Create and wire up these devices. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- v2 changes: - use 'sizeof(*msc)', 'sizeof(*dma)' as suggested by Phillipe in code review - s/init_sysbus_child/sysbus_init_child_obj/, required by rebase on current master --- hw/arm/mps2-tz.c | 100 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 93 insertions(+), 7 deletions(-) diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index dc0f34abe53..d810e51a1b4 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -45,7 +45,9 @@ #include "hw/misc/mps2-scc.h" #include "hw/misc/mps2-fpgaio.h" #include "hw/misc/tz-mpc.h" +#include "hw/misc/tz-msc.h" #include "hw/arm/iotkit.h" +#include "hw/dma/pl080.h" #include "hw/devices.h" #include "net/net.h" #include "hw/core/split-irq.h" @@ -75,8 +77,9 @@ typedef struct { UnimplementedDeviceState i2c[4]; UnimplementedDeviceState i2s_audio; UnimplementedDeviceState gpio[4]; - UnimplementedDeviceState dma[4]; UnimplementedDeviceState gfx; + PL080State dma[4]; + TZMSC msc[4]; CMSDKAPBUART uart[5]; SplitIRQ sec_resp_splitter; qemu_or_irq uart_irq_orgate; @@ -263,6 +266,64 @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms,= void *opaque, return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0); } =20 +static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque, + const char *name, hwaddr size) +{ + PL080State *dma =3D opaque; + int i =3D dma - &mms->dma[0]; + SysBusDevice *s; + char *mscname =3D g_strdup_printf("%s-msc", name); + TZMSC *msc =3D &mms->msc[i]; + DeviceState *iotkitdev =3D DEVICE(&mms->iotkit); + MemoryRegion *msc_upstream; + MemoryRegion *msc_downstream; + + /* + * Each DMA device is a PL081 whose transaction master interface + * is guarded by a Master Security Controller. The downstream end of + * the MSC connects to the IoTKit AHB Slave Expansion port, so the + * DMA devices can see all devices and memory that the CPU does. + */ + sysbus_init_child_obj(OBJECT(mms), mscname, msc, sizeof(*msc), TYPE_TZ= _MSC); + msc_downstream =3D sysbus_mmio_get_region(SYS_BUS_DEVICE(&mms->iotkit)= , 0); + object_property_set_link(OBJECT(msc), OBJECT(msc_downstream), + "downstream", &error_fatal); + object_property_set_link(OBJECT(msc), OBJECT(mms), + "idau", &error_fatal); + object_property_set_bool(OBJECT(msc), true, "realized", &error_fatal); + + qdev_connect_gpio_out_named(DEVICE(msc), "irq", 0, + qdev_get_gpio_in_named(iotkitdev, + "mscexp_status", i)= ); + qdev_connect_gpio_out_named(iotkitdev, "mscexp_clear", i, + qdev_get_gpio_in_named(DEVICE(msc), + "irq_clear", 0)); + qdev_connect_gpio_out_named(iotkitdev, "mscexp_ns", i, + qdev_get_gpio_in_named(DEVICE(msc), + "cfg_nonsec", 0)); + qdev_connect_gpio_out(DEVICE(&mms->sec_resp_splitter), + ARRAY_SIZE(mms->ppc) + i, + qdev_get_gpio_in_named(DEVICE(msc), + "cfg_sec_resp", 0)); + msc_upstream =3D sysbus_mmio_get_region(SYS_BUS_DEVICE(msc), 0); + + sysbus_init_child_obj(OBJECT(mms), name, dma, sizeof(*dma), TYPE_PL081= ); + object_property_set_link(OBJECT(dma), OBJECT(msc_upstream), + "downstream", &error_fatal); + object_property_set_bool(OBJECT(dma), true, "realized", &error_fatal); + + s =3D SYS_BUS_DEVICE(dma); + /* Wire up DMACINTR, DMACINTERR, DMACINTTC */ + sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev, + "EXP_IRQ", 58 + i * 3)= ); + sysbus_connect_irq(s, 1, qdev_get_gpio_in_named(iotkitdev, + "EXP_IRQ", 56 + i * 3)= ); + sysbus_connect_irq(s, 2, qdev_get_gpio_in_named(iotkitdev, + "EXP_IRQ", 57 + i * 3)= ); + + return sysbus_mmio_get_region(s, 0); +} + static void mps2tz_common_init(MachineState *machine) { MPS2TZMachineState *mms =3D MPS2TZ_MACHINE(machine); @@ -289,13 +350,14 @@ static void mps2tz_common_init(MachineState *machine) &error_fatal); =20 /* The sec_resp_cfg output from the IoTKit must be split into multiple - * lines, one for each of the PPCs we create here. + * lines, one for each of the PPCs we create here, plus one per MSC. */ object_initialize(&mms->sec_resp_splitter, sizeof(mms->sec_resp_splitt= er), TYPE_SPLIT_IRQ); object_property_add_child(OBJECT(machine), "sec-resp-splitter", OBJECT(&mms->sec_resp_splitter), &error_abor= t); - object_property_set_int(OBJECT(&mms->sec_resp_splitter), 5, + object_property_set_int(OBJECT(&mms->sec_resp_splitter), + ARRAY_SIZE(mms->ppc) + ARRAY_SIZE(mms->msc), "num-lines", &error_fatal); object_property_set_bool(OBJECT(&mms->sec_resp_splitter), true, "realized", &error_fatal); @@ -396,10 +458,10 @@ static void mps2tz_common_init(MachineState *machine) }, { .name =3D "ahb_ppcexp1", .ports =3D { - { "dma0", make_unimp_dev, &mms->dma[0], 0x40110000, 0x1000= }, - { "dma1", make_unimp_dev, &mms->dma[1], 0x40111000, 0x1000= }, - { "dma2", make_unimp_dev, &mms->dma[2], 0x40112000, 0x1000= }, - { "dma3", make_unimp_dev, &mms->dma[3], 0x40113000, 0x1000= }, + { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000 }, + { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000 }, + { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000 }, + { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000 }, }, }, }; @@ -480,12 +542,32 @@ static void mps2tz_common_init(MachineState *machine) armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400= 000); } =20 +static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address, + int *iregion, bool *exempt, bool *ns, bool = *nsc) +{ + /* + * The MPS2 TZ FPGA images have IDAUs in them which are connected to + * the Master Security Controllers. Thes have the same logic as + * is used by the IoTKit for the IDAU connected to the CPU, except + * that MSCs don't care about the NSC attribute. + */ + int region =3D extract32(address, 28, 4); + + *ns =3D !(region & 1); + *nsc =3D false; + /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */ + *exempt =3D (address & 0xeff00000) =3D=3D 0xe0000000; + *iregion =3D region; +} + static void mps2tz_class_init(ObjectClass *oc, void *data) { MachineClass *mc =3D MACHINE_CLASS(oc); + IDAUInterfaceClass *iic =3D IDAU_INTERFACE_CLASS(oc); =20 mc->init =3D mps2tz_common_init; mc->max_cpus =3D 1; + iic->check =3D mps2_tz_idau_check; } =20 static void mps2tz_an505_class_init(ObjectClass *oc, void *data) @@ -506,6 +588,10 @@ static const TypeInfo mps2tz_info =3D { .instance_size =3D sizeof(MPS2TZMachineState), .class_size =3D sizeof(MPS2TZMachineClass), .class_init =3D mps2tz_class_init, + .interfaces =3D (InterfaceInfo[]) { + { TYPE_IDAU_INTERFACE }, + { } + }, }; =20 static const TypeInfo mps2tz_an505_info =3D { --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534774991145585.5736280629889; Mon, 20 Aug 2018 07:23:11 -0700 (PDT) Received: from localhost ([::1]:47360 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl5K-0004zo-1N for importer@patchew.org; Mon, 20 Aug 2018 10:23:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42131) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkuF-0003eW-9E for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frkuE-0007Oq-4j for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:43 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44654) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frku9-0007Jz-IW; Mon, 20 Aug 2018 10:11:37 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frku8-0003Sl-Kh; Mon, 20 Aug 2018 15:11:36 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:09 +0100 Message-Id: <20180820141116.9118-16-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 15/22] hw/ssi/pl022: Allow use as embedded-struct device X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Create a new include file for the pl022's device struct, type macros, etc, so that it can be instantiated using the "embedded struct" coding style. While we're adding the new file to MAINTAINERS, add also the .c file, which was missing an entry. Signed-off-by: Peter Maydell --- include/hw/ssi/pl022.h | 51 ++++++++++++++++++++++++++++++++++++++++++ hw/ssi/pl022.c | 26 +-------------------- MAINTAINERS | 2 ++ 3 files changed, 54 insertions(+), 25 deletions(-) create mode 100644 include/hw/ssi/pl022.h diff --git a/include/hw/ssi/pl022.h b/include/hw/ssi/pl022.h new file mode 100644 index 00000000000..a080519366d --- /dev/null +++ b/include/hw/ssi/pl022.h @@ -0,0 +1,51 @@ +/* + * ARM PrimeCell PL022 Synchronous Serial Port + * + * Copyright (c) 2007 CodeSourcery. + * Written by Paul Brook + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +/* This is a model of the Arm PrimeCell PL022 synchronous serial port. + * The PL022 TRM is: + * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0194h/DDI0194H_ssp_= pl022_trm.pdf + * + * QEMU interface: + * + sysbus IRQ: SSPINTR combined interrupt line + * + sysbus MMIO region 0: MemoryRegion for the device's registers + */ + +#ifndef HW_SSI_PL022_H +#define HW_SSI_PL022_H + +#include "hw/sysbus.h" + +#define TYPE_PL022 "pl022" +#define PL022(obj) OBJECT_CHECK(PL022State, (obj), TYPE_PL022) + +typedef struct PL022State { + SysBusDevice parent_obj; + + MemoryRegion iomem; + uint32_t cr0; + uint32_t cr1; + uint32_t bitmask; + uint32_t sr; + uint32_t cpsr; + uint32_t is; + uint32_t im; + /* The FIFO head points to the next empty entry. */ + int tx_fifo_head; + int rx_fifo_head; + int tx_fifo_len; + int rx_fifo_len; + uint16_t tx_fifo[8]; + uint16_t rx_fifo[8]; + qemu_irq irq; + SSIBus *ssi; +} PL022State; + +#endif diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c index c1368018ee3..379d3093987 100644 --- a/hw/ssi/pl022.c +++ b/hw/ssi/pl022.c @@ -9,6 +9,7 @@ =20 #include "qemu/osdep.h" #include "hw/sysbus.h" +#include "hw/ssi/pl022.h" #include "hw/ssi/ssi.h" #include "qemu/log.h" =20 @@ -41,31 +42,6 @@ do { fprintf(stderr, "pl022: error: " fmt , ## __VA_ARGS= __);} while (0) #define PL022_INT_RX 0x04 #define PL022_INT_TX 0x08 =20 -#define TYPE_PL022 "pl022" -#define PL022(obj) OBJECT_CHECK(PL022State, (obj), TYPE_PL022) - -typedef struct PL022State { - SysBusDevice parent_obj; - - MemoryRegion iomem; - uint32_t cr0; - uint32_t cr1; - uint32_t bitmask; - uint32_t sr; - uint32_t cpsr; - uint32_t is; - uint32_t im; - /* The FIFO head points to the next empty entry. */ - int tx_fifo_head; - int rx_fifo_head; - int tx_fifo_len; - int rx_fifo_len; - uint16_t tx_fifo[8]; - uint16_t rx_fifo[8]; - qemu_irq irq; - SSIBus *ssi; -} PL022State; - static const unsigned char pl022_id[8] =3D { 0x22, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; =20 diff --git a/MAINTAINERS b/MAINTAINERS index b2f8b562dc5..1e81ad8d4b1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -451,6 +451,8 @@ F: hw/gpio/pl061.c F: hw/input/pl050.c F: hw/intc/pl190.c F: hw/sd/pl181.c +F: hw/ssi/pl022.c +F: include/hw/ssi/pl022.h F: hw/timer/pl031.c F: include/hw/arm/primecell.h F: hw/timer/cmsdk-apb-timer.c --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534775248031681.7920864995955; Mon, 20 Aug 2018 07:27:28 -0700 (PDT) Received: from localhost ([::1]:47390 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl9S-0000tH-UW for importer@patchew.org; Mon, 20 Aug 2018 10:27:26 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42148) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkuF-0003f5-Ps for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frkuE-0007Oj-2W for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:43 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44654) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frkuB-0007Jz-Kb; Mon, 20 Aug 2018 10:11:39 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frku9-0003T1-JP; Mon, 20 Aug 2018 15:11:37 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:10 +0100 Message-Id: <20180820141116.9118-17-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 16/22] hw/ssi/pl022: Set up reset function in class init X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Currently the PL022 calls pl022_reset() from its class init function. Make it register a DeviceState reset method instead, so that we reset the device on system reset. Signed-off-by: Peter Maydell --- hw/ssi/pl022.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c index 379d3093987..0b5f90b857f 100644 --- a/hw/ssi/pl022.c +++ b/hw/ssi/pl022.c @@ -203,8 +203,10 @@ static void pl022_write(void *opaque, hwaddr offset, } } =20 -static void pl022_reset(PL022State *s) +static void pl022_reset(DeviceState *dev) { + PL022State *s =3D PL022(dev); + s->rx_fifo_len =3D 0; s->tx_fifo_len =3D 0; s->im =3D 0; @@ -277,7 +279,6 @@ static int pl022_init(SysBusDevice *sbd) sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq); s->ssi =3D ssi_create_bus(dev, "ssi"); - pl022_reset(s); vmstate_register(dev, -1, &vmstate_pl022, s); return 0; } @@ -285,8 +286,10 @@ static int pl022_init(SysBusDevice *sbd) static void pl022_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *sdc =3D SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc =3D DEVICE_CLASS(klass); =20 sdc->init =3D pl022_init; + dc->reset =3D pl022_reset; } =20 static const TypeInfo pl022_info =3D { --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 153477479749056.63378396879739; Mon, 20 Aug 2018 07:19:57 -0700 (PDT) Received: from localhost ([::1]:47340 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl22-0001a3-Dp for importer@patchew.org; Mon, 20 Aug 2018 10:19:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42111) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkuE-0003dk-N6 for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frkuE-0007Ob-1N for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:42 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44662) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frkuB-0007La-Fc; Mon, 20 Aug 2018 10:11:39 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frkuA-0003TW-JC; Mon, 20 Aug 2018 15:11:38 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:11 +0100 Message-Id: <20180820141116.9118-18-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 17/22] hw/ssi/pl022: Don't directly call vmstate_register() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Use the DeviceState vmsd pointer rather than calling vmstate_register() directly. Signed-off-by: Peter Maydell --- hw/ssi/pl022.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c index 0b5f90b857f..c9989537062 100644 --- a/hw/ssi/pl022.c +++ b/hw/ssi/pl022.c @@ -279,7 +279,6 @@ static int pl022_init(SysBusDevice *sbd) sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq); s->ssi =3D ssi_create_bus(dev, "ssi"); - vmstate_register(dev, -1, &vmstate_pl022, s); return 0; } =20 @@ -290,6 +289,7 @@ static void pl022_class_init(ObjectClass *klass, void *= data) =20 sdc->init =3D pl022_init; dc->reset =3D pl022_reset; + dc->vmsd =3D &vmstate_pl022; } =20 static const TypeInfo pl022_info =3D { --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534774817028610.5018797242033; Mon, 20 Aug 2018 07:20:17 -0700 (PDT) Received: from localhost ([::1]:47341 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl2R-0001qM-JY for importer@patchew.org; Mon, 20 Aug 2018 10:20:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42134) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkuF-0003eZ-A2 for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frkuE-0007P4-Eh for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:43 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44668) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frkuC-0007MX-J8; Mon, 20 Aug 2018 10:11:40 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frkuB-0003Tp-LB; Mon, 20 Aug 2018 15:11:39 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:12 +0100 Message-Id: <20180820141116.9118-19-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 18/22] hw/ssi/pl022: Use DeviceState::realize rather than SysBusDevice::init X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Move from the legacy SysBusDevice::init method to using DeviceState::realize. Signed-off-by: Peter Maydell --- hw/ssi/pl022.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c index c9989537062..3ac57f4c96a 100644 --- a/hw/ssi/pl022.c +++ b/hw/ssi/pl022.c @@ -270,26 +270,24 @@ static const VMStateDescription vmstate_pl022 =3D { } }; =20 -static int pl022_init(SysBusDevice *sbd) +static void pl022_realize(DeviceState *dev, Error **errp) { - DeviceState *dev =3D DEVICE(sbd); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); PL022State *s =3D PL022(dev); =20 memory_region_init_io(&s->iomem, OBJECT(s), &pl022_ops, s, "pl022", 0x= 1000); sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq); s->ssi =3D ssi_create_bus(dev, "ssi"); - return 0; } =20 static void pl022_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc =3D SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc =3D DEVICE_CLASS(klass); =20 - sdc->init =3D pl022_init; dc->reset =3D pl022_reset; dc->vmsd =3D &vmstate_pl022; + dc->realize =3D pl022_realize; } =20 static const TypeInfo pl022_info =3D { --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534775794195376.4615524789249; Mon, 20 Aug 2018 07:36:34 -0700 (PDT) Received: from localhost ([::1]:47459 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frlIG-0008Pr-VL for importer@patchew.org; Mon, 20 Aug 2018 10:36:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46272) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl70-00070E-15 for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:24:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frl6w-0000U1-8Q for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:24:52 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44690) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frl6s-0000P1-60; Mon, 20 Aug 2018 10:24:47 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frkuC-0003UX-In; Mon, 20 Aug 2018 15:11:40 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:13 +0100 Message-Id: <20180820141116.9118-20-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 19/22] hw/ssi/pl022: Correct wrong value for PL022_INT_RT X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The PL022 interrupt registers have bits allocated as: 0: ROR (receive overrun) 1: RT (receive timeout) 2: RX (receive FIFO half full or less) 3: TX (transmit FIFO half full or less) A cut and paste error meant we had the wrong value for the PL022_INT_RT constant. This bug doesn't affect device behaviour, because we don't implmenet the receive timeout feature and so never set that interrupt bit. Signed-off-by: Peter Maydell --- hw/ssi/pl022.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c index 3ac57f4c96a..d310671d18e 100644 --- a/hw/ssi/pl022.c +++ b/hw/ssi/pl022.c @@ -38,7 +38,7 @@ do { fprintf(stderr, "pl022: error: " fmt , ## __VA_ARGS_= _);} while (0) #define PL022_SR_BSY 0x10 =20 #define PL022_INT_ROR 0x01 -#define PL022_INT_RT 0x04 +#define PL022_INT_RT 0x02 #define PL022_INT_RX 0x04 #define PL022_INT_TX 0x08 =20 --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534775645848539.6303896101176; Mon, 20 Aug 2018 07:34:05 -0700 (PDT) Received: from localhost ([::1]:47438 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frlFs-0006DZ-SQ for importer@patchew.org; Mon, 20 Aug 2018 10:34:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42179) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkuH-0003hf-2r for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frkuG-0007Qn-Dl for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:45 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44676) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frkuE-0007ON-Fb; Mon, 20 Aug 2018 10:11:42 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frkuD-0003VB-JA; Mon, 20 Aug 2018 15:11:41 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:14 +0100 Message-Id: <20180820141116.9118-21-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 20/22] hw/ssi/pl022: Correct wrong DMACR and ICR handling X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" In the PL022, register offset 0x20 is the ICR, a write-only interrupt-clear register. Register offset 0x24 is DMACR, the DMA control register. We were incorrectly implementing (a stub version of) DMACR at 0x20, and not implementing anything at 0x24. Fix this bug. Signed-off-by: Peter Maydell --- hw/ssi/pl022.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c index d310671d18e..e58247554cc 100644 --- a/hw/ssi/pl022.c +++ b/hw/ssi/pl022.c @@ -146,7 +146,7 @@ static uint64_t pl022_read(void *opaque, hwaddr offset, return s->is; case 0x1c: /* MIS */ return s->im & s->is; - case 0x20: /* DMACR */ + case 0x24: /* DMACR */ /* Not implemented. */ return 0; default: @@ -192,7 +192,15 @@ static void pl022_write(void *opaque, hwaddr offset, s->im =3D value; pl022_update(s); break; - case 0x20: /* DMACR */ + case 0x20: /* ICR */ + /* + * write-1-to-clear: bit 0 clears ROR, bit 1 clears RT; + * RX and TX interrupts cannot be cleared this way. + */ + value &=3D PL022_INT_ROR | PL022_INT_RT; + s->is &=3D ~value; + break; + case 0x24: /* DMACR */ if (value) { qemu_log_mask(LOG_UNIMP, "pl022: DMA not implemented\n"); } --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534775395896235.879787521067; Mon, 20 Aug 2018 07:29:55 -0700 (PDT) Received: from localhost ([::1]:47408 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frlBq-0002sc-Pf for importer@patchew.org; Mon, 20 Aug 2018 10:29:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42226) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkuK-0003m1-4D for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frkuJ-0007UF-Cf for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:48 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44684) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frkuH-0007QD-EP; Mon, 20 Aug 2018 10:11:45 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frkuE-0003VR-IH; Mon, 20 Aug 2018 15:11:42 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:15 +0100 Message-Id: <20180820141116.9118-22-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 21/22] hw/arm/mps2-tz: Instantiate SPI controllers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The SPI controllers in the MPS2 AN505 board are PL022s. We have a model of the PL022, so create these devices. We don't currently model the LCD controller that sits behind one of the PL022s; the others are intended to control devices that sit on the FPGA's general purpose SPI connector or "shield" expansion connectors. Signed-off-by: Peter Maydell --- hw/arm/mps2-tz.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index d810e51a1b4..cedf605e20e 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -48,6 +48,7 @@ #include "hw/misc/tz-msc.h" #include "hw/arm/iotkit.h" #include "hw/dma/pl080.h" +#include "hw/ssi/pl022.h" #include "hw/devices.h" #include "net/net.h" #include "hw/core/split-irq.h" @@ -73,7 +74,7 @@ typedef struct { MPS2FPGAIO fpgaio; TZPPC ppc[5]; TZMPC ssram_mpc[3]; - UnimplementedDeviceState spi[5]; + PL022State spi[5]; UnimplementedDeviceState i2c[4]; UnimplementedDeviceState i2s_audio; UnimplementedDeviceState gpio[4]; @@ -324,6 +325,31 @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms,= void *opaque, return sysbus_mmio_get_region(s, 0); } =20 +static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque, + const char *name, hwaddr size) +{ + /* + * The AN505 has five PL022 SPI controllers. + * One of these should have the LCD controller behind it; the others + * are connected only to the FPGA's "general purpose SPI connector" + * or "shield" expansion connectors. + * Note that if we do implement devices behind SPI, the chip select + * lines are set via the "MISC" register in the MPS2 FPGAIO device. + */ + PL022State *spi =3D opaque; + int i =3D spi - &mms->spi[0]; + DeviceState *iotkitdev =3D DEVICE(&mms->iotkit); + SysBusDevice *s; + + sysbus_init_child_obj(OBJECT(mms), name, spi, sizeof(mms->spi[0]), + TYPE_PL022); + object_property_set_bool(OBJECT(spi), true, "realized", &error_fatal); + s =3D SYS_BUS_DEVICE(spi); + sysbus_connect_irq(s, 0, + qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 51 + i= )); + return sysbus_mmio_get_region(s, 0); +} + static void mps2tz_common_init(MachineState *machine) { MPS2TZMachineState *mms =3D MPS2TZ_MACHINE(machine); @@ -422,11 +448,11 @@ static void mps2tz_common_init(MachineState *machine) }, { .name =3D "apb_ppcexp1", .ports =3D { - { "spi0", make_unimp_dev, &mms->spi[0], 0x40205000, 0x1000= }, - { "spi1", make_unimp_dev, &mms->spi[1], 0x40206000, 0x1000= }, - { "spi2", make_unimp_dev, &mms->spi[2], 0x40209000, 0x1000= }, - { "spi3", make_unimp_dev, &mms->spi[3], 0x4020a000, 0x1000= }, - { "spi4", make_unimp_dev, &mms->spi[4], 0x4020b000, 0x1000= }, + { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000 }, + { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000 }, + { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000 }, + { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000 }, + { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000 }, { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000 }, { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000 }, { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 }, --=20 2.18.0 From nobody Wed Nov 5 13:00:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534775147342710.9884607018727; Mon, 20 Aug 2018 07:25:47 -0700 (PDT) Received: from localhost ([::1]:47378 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frl7p-0007Gm-W0 for importer@patchew.org; Mon, 20 Aug 2018 10:25:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42211) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1frkuJ-0003kx-0r for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1frkuI-0007Tb-Bl for qemu-devel@nongnu.org; Mon, 20 Aug 2018 10:11:46 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44684) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1frkuG-0007QD-Dn; Mon, 20 Aug 2018 10:11:44 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1frkuF-0003W2-GQ; Mon, 20 Aug 2018 15:11:43 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Mon, 20 Aug 2018 15:11:16 +0100 Message-Id: <20180820141116.9118-23-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180820141116.9118-1-peter.maydell@linaro.org> References: <20180820141116.9118-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 22/22] hw/arm/mps2-tz: Fix MPS2 SCC config register values X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Some of the config register values we were setting for the MPS2 SCC weren't correct: * the SCC_AID bits [23:20] specify the FPGA build target board revision, and the SCC_CFG4 register specifies the actual board revision, so these should have matching values. Claim to be board revision C, consistently -- we had the revision in the wrong part of SCC_AID. * SCC_ID bits [15:4] should be 0x505, not decimal 505 Signed-off-by: Peter Maydell --- hw/arm/mps2-tz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index cedf605e20e..cb252d8ebcc 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -192,7 +192,7 @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, = void *opaque, sccdev =3D DEVICE(scc); qdev_set_parent_bus(sccdev, sysbus_get_default()); qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2); - qdev_prop_set_uint32(sccdev, "scc-aid", 0x02000008); + qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008); qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id); object_property_set_bool(OBJECT(scc), true, "realized", &error_fatal); return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0); @@ -604,7 +604,7 @@ static void mps2tz_an505_class_init(ObjectClass *oc, vo= id *data) mc->desc =3D "ARM MPS2 with AN505 FPGA image for Cortex-M33"; mmc->fpga_type =3D FPGA_AN505; mc->default_cpu_type =3D ARM_CPU_TYPE_NAME("cortex-m33"); - mmc->scc_id =3D 0x41040000 | (505 << 4); + mmc->scc_id =3D 0x41040000 | (0x505 << 4); } =20 static const TypeInfo mps2tz_info =3D { --=20 2.18.0