From nobody Sun Apr 27 12:03:17 2025
Delivered-To: importer@patchew.org
Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as
 permitted sender) client-ip=209.51.188.17;
 envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org;
 helo=lists.gnu.org;
Authentication-Results: mx.zohomail.com;
	dkim=fail;
	spf=pass (zoho.com: domain of gnu.org designates 209.51.188.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: <qemu-devel-bounces+importer=patchew.org@nongnu.org>
Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by
 mx.zohomail.com
	with SMTPS id 1550776360502613.8330823220122;
 Thu, 21 Feb 2019 11:12:40 -0800 (PST)
Received: from localhost ([127.0.0.1]:37068 helo=lists.gnu.org)
	by lists.gnu.org with esmtp (Exim 4.71)
	(envelope-from <qemu-devel-bounces+importer=patchew.org@nongnu.org>)
	id 1gwtls-0004E2-As
	for importer@patchew.org; Thu, 21 Feb 2019 14:12:36 -0500
Received: from eggs.gnu.org ([209.51.188.92]:52291)
	by lists.gnu.org with esmtp (Exim 4.71)
	(envelope-from <peter.maydell@linaro.org>) id 1gwtXu-00005v-9i
	for qemu-devel@nongnu.org; Thu, 21 Feb 2019 13:58:11 -0500
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
	(envelope-from <peter.maydell@linaro.org>) id 1gwtXq-0007Uq-SM
	for qemu-devel@nongnu.org; Thu, 21 Feb 2019 13:58:10 -0500
Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]:38584)
	by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16)
	(Exim 4.71) (envelope-from <peter.maydell@linaro.org>)
	id 1gwtXq-0007TD-Fs
	for qemu-devel@nongnu.org; Thu, 21 Feb 2019 13:58:06 -0500
Received: by mail-wm1-x333.google.com with SMTP id v26so10307435wmh.3
	for <qemu-devel@nongnu.org>; Thu, 21 Feb 2019 10:58:06 -0800 (PST)
Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148])
	by smtp.gmail.com with ESMTPSA id
	c18sm29065085wre.32.2019.02.21.10.58.03 for <qemu-devel@nongnu.org>
	(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
	Thu, 21 Feb 2019 10:58:04 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google;
	h=from:to:subject:date:message-id:in-reply-to:references:mime-version
	:content-transfer-encoding;
	bh=lgt/0TfncrjZFHVUqY1F5/RCWOdn69qBp1Opyed3kCU=;
	b=zS3CWtCJjPb2eac+vZYcEUXymGClddjTQuO+aq6MUuPVUAjCvOou1RGBSjCloQGC9S
	EnJzSOEvpdmAvimgpG+QsvSLXpF3oplLfZMHXkm4/oSEVjKm8KEIox3qan5R7aCHAkrZ
	EHFVvV+iYxVhFNqz6Ix82PBW2EdfFqwdcKo0LwXVjyNBOpiU/SJPxwl60Je5MQslKvby
	bGhwtkEuQXqyO/fscka/mqVqIumqaGqfOAtarZ6JSNP8IQyjHEKOXTAmk7cSmTFXa0AP
	2ZQFpdmMa4d+Lb6lzwXyMi8U2IV5BfN+IuH2x5YqPcWqzMxn1lNdzoNZj6mnXjtU6tEV
	whUA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
	d=1e100.net; s=20161025;
	h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to
	:references:mime-version:content-transfer-encoding;
	bh=lgt/0TfncrjZFHVUqY1F5/RCWOdn69qBp1Opyed3kCU=;
	b=R0wsFQXawdwyxBQlSvF6bfE2lopb0kk6MqUKzsxayEodkZ+paKVmaOw3svfL8mweYh
	ADGKPXvZvO2qyPGNUp77rWwooUeWh24r8Urut5/I8TBLzBvOMcGr5lfFLptZs/ZL/3kC
	uE4dDFbXUTQ+JrGb8FWQNWCeWnPzUVoqhjWvGEW/1ULIJMuQXD2iqPHes3PGqEr2/FNf
	RdRiSzqbqZ/PJDBT6/VzNc1FOQtuViKU13/NwvziLvM74Ih0fd34CoXKBTymld3v/BPv
	iwTLtgD8DIw20R6EzZiEd2AiHIXpc8qebJHL/DsluzYQA94+a0Sz0HVp963jL8S4K3U7
	oAYg==
X-Gm-Message-State: AHQUAuYvVFOsGROiZSJYy3B21jPTFtHGEOhNvaI1xbJbJ8n4UmXObF4D
	PKCL+gINJRY65z7owE5X4VxkqAlmerg=
X-Google-Smtp-Source: 
 AHgI3Ib84EDm3JK/VejsC/L02vgR8hxR664DPXKdoa8fM39ftMKVsk+TGdv6n6RV6MgrrUwVJ3znwQ==
X-Received: by 2002:a1c:7610:: with SMTP id
 r16mr11333777wmc.139.1550775484814;
	Thu, 21 Feb 2019 10:58:04 -0800 (PST)
From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Date: Thu, 21 Feb 2019 18:57:36 +0000
Message-Id: <20190221185739.25362-19-peter.maydell@linaro.org>
X-Mailer: git-send-email 2.20.1
In-Reply-To: <20190221185739.25362-1-peter.maydell@linaro.org>
References: <20190221185739.25362-1-peter.maydell@linaro.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: Genre and OS details not
	recognized.
X-Received-From: 2a00:1450:4864:20::333
Subject: [Qemu-devel] [PULL 18/21] hw/arm/musca: Add MPCs
X-BeenThere: qemu-devel@nongnu.org
X-Mailman-Version: 2.1.21
Precedence: list
List-Id: <qemu-devel.nongnu.org>
List-Unsubscribe: <https://lists.nongnu.org/mailman/options/qemu-devel>,
	<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>
List-Archive: <http://lists.nongnu.org/archive/html/qemu-devel/>
List-Post: <mailto:qemu-devel@nongnu.org>
List-Help: <mailto:qemu-devel-request@nongnu.org?subject=help>
List-Subscribe: <https://lists.nongnu.org/mailman/listinfo/qemu-devel>,
	<mailto:qemu-devel-request@nongnu.org?subject=subscribe>
Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org
Sender: "Qemu-devel" <qemu-devel-bounces+importer=patchew.org@nongnu.org>
X-ZohoMail-DKIM: fail (Header signature does not verify)
Content-Type: text/plain; charset="utf-8"

The Musca board puts its SRAM and flash behind TrustZone
Memory Protection Controllers (MPCs). Each MPC sits between
the CPU and the RAM/flash, and also has a set of memory mapped
control registers. Wire up the MPCs, and the memory behind them.
For the moment we implement the flash as simple ROM, which
cannot be reprogrammed by the guest.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 hw/arm/musca.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 147 insertions(+), 8 deletions(-)

diff --git a/hw/arm/musca.c b/hw/arm/musca.c
index 8774e0b87b7..c4095c4579b 100644
--- a/hw/arm/musca.c
+++ b/hw/arm/musca.c
@@ -27,11 +27,15 @@
 #include "hw/arm/armsse.h"
 #include "hw/boards.h"
 #include "hw/core/split-irq.h"
+#include "hw/misc/tz-mpc.h"
 #include "hw/misc/tz-ppc.h"
 #include "hw/misc/unimp.h"
=20
 #define MUSCA_NUMIRQ_MAX 96
 #define MUSCA_PPC_MAX 3
+#define MUSCA_MPC_MAX 5
+
+typedef struct MPCInfo MPCInfo;
=20
 typedef enum MuscaType {
     MUSCA_A,
@@ -44,19 +48,23 @@ typedef struct {
     uint32_t init_svtor;
     int sram_addr_width;
     int num_irqs;
+    const MPCInfo *mpc_info;
+    int num_mpcs;
 } MuscaMachineClass;
=20
 typedef struct {
     MachineState parent;
=20
     ARMSSE sse;
+    /* RAM and flash */
+    MemoryRegion ram[MUSCA_MPC_MAX];
     SplitIRQ cpu_irq_splitter[MUSCA_NUMIRQ_MAX];
     SplitIRQ sec_resp_splitter;
     TZPPC ppc[MUSCA_PPC_MAX];
     MemoryRegion container;
     UnimplementedDeviceState eflash[2];
     UnimplementedDeviceState qspi;
-    UnimplementedDeviceState mpc[5];
+    TZMPC mpc[MUSCA_MPC_MAX];
     UnimplementedDeviceState mhu[2];
     UnimplementedDeviceState pwm[3];
     UnimplementedDeviceState i2s;
@@ -69,6 +77,7 @@ typedef struct {
     UnimplementedDeviceState pvt;
     UnimplementedDeviceState sdio;
     UnimplementedDeviceState gpio;
+    UnimplementedDeviceState cryptoisland;
 } MuscaMachineState;
=20
 #define TYPE_MUSCA_MACHINE "musca"
@@ -131,6 +140,131 @@ static MemoryRegion *make_unimp_dev(MuscaMachineState=
 *mms,
     return sysbus_mmio_get_region(SYS_BUS_DEVICE(uds), 0);
 }
=20
+typedef enum MPCInfoType {
+    MPC_RAM,
+    MPC_ROM,
+    MPC_CRYPTOISLAND,
+} MPCInfoType;
+
+struct MPCInfo {
+    const char *name;
+    hwaddr addr;
+    hwaddr size;
+    MPCInfoType type;
+};
+
+/* Order of the MPCs here must match the order of the bits in SECMPCINTSTA=
TUS */
+static const MPCInfo a_mpc_info[] =3D { {
+        .name =3D "qspi",
+        .type =3D MPC_ROM,
+        .addr =3D 0x00200000,
+        .size =3D 0x00800000,
+    }, {
+        .name =3D "sram",
+        .type =3D MPC_RAM,
+        .addr =3D 0x00000000,
+        .size =3D 0x00200000,
+    }
+};
+
+static const MPCInfo b1_mpc_info[] =3D { {
+        .name =3D "qspi",
+        .type =3D MPC_ROM,
+        .addr =3D 0x00000000,
+        .size =3D 0x02000000,
+    }, {
+        .name =3D "sram",
+        .type =3D MPC_RAM,
+        .addr =3D 0x0a400000,
+        .size =3D 0x00080000,
+    }, {
+        .name =3D "eflash0",
+        .type =3D MPC_ROM,
+        .addr =3D 0x0a000000,
+        .size =3D 0x00200000,
+    }, {
+        .name =3D "eflash1",
+        .type =3D MPC_ROM,
+        .addr =3D 0x0a200000,
+        .size =3D 0x00200000,
+    }, {
+        .name =3D "cryptoisland",
+        .type =3D MPC_CRYPTOISLAND,
+        .addr =3D 0x0a000000,
+        .size =3D 0x00200000,
+    }
+};
+
+static MemoryRegion *make_mpc(MuscaMachineState *mms, void *opaque,
+                              const char *name, hwaddr size)
+{
+    /*
+     * Create an MPC and the RAM or flash behind it.
+     * MPC 0: eFlash 0
+     * MPC 1: eFlash 1
+     * MPC 2: SRAM
+     * MPC 3: QSPI flash
+     * MPC 4: CryptoIsland
+     * For now we implement the flash regions as ROM (ie not programmable)
+     * (with their control interface memory regions being unimplemented
+     * stubs behind the PPCs).
+     * The whole CryptoIsland region behind its MPC is an unimplemented st=
ub.
+     */
+    MuscaMachineClass *mmc =3D MUSCA_MACHINE_GET_CLASS(mms);
+    TZMPC *mpc =3D opaque;
+    int i =3D mpc - &mms->mpc[0];
+    MemoryRegion *downstream;
+    MemoryRegion *upstream;
+    UnimplementedDeviceState *uds;
+    char *mpcname;
+    const MPCInfo *mpcinfo =3D mmc->mpc_info;
+
+    mpcname =3D g_strdup_printf("%s-mpc", mpcinfo[i].name);
+
+    switch (mpcinfo[i].type) {
+    case MPC_ROM:
+        downstream =3D &mms->ram[i];
+        memory_region_init_rom(downstream, NULL, mpcinfo[i].name,
+                               mpcinfo[i].size, &error_fatal);
+        break;
+    case MPC_RAM:
+        downstream =3D &mms->ram[i];
+        memory_region_init_ram(downstream, NULL, mpcinfo[i].name,
+                               mpcinfo[i].size, &error_fatal);
+        break;
+    case MPC_CRYPTOISLAND:
+        /* We don't implement the CryptoIsland yet */
+        uds =3D &mms->cryptoisland;
+        sysbus_init_child_obj(OBJECT(mms), name, uds,
+                              sizeof(UnimplementedDeviceState),
+                              TYPE_UNIMPLEMENTED_DEVICE);
+        qdev_prop_set_string(DEVICE(uds), "name", mpcinfo[i].name);
+        qdev_prop_set_uint64(DEVICE(uds), "size", mpcinfo[i].size);
+        object_property_set_bool(OBJECT(uds), true, "realized", &error_fat=
al);
+        downstream =3D sysbus_mmio_get_region(SYS_BUS_DEVICE(uds), 0);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+
+    sysbus_init_child_obj(OBJECT(mms), mpcname, mpc, sizeof(mms->mpc[0]),
+                          TYPE_TZ_MPC);
+    object_property_set_link(OBJECT(mpc), OBJECT(downstream),
+                             "downstream", &error_fatal);
+    object_property_set_bool(OBJECT(mpc), true, "realized", &error_fatal);
+    /* Map the upstream end of the MPC into system memory */
+    upstream =3D sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
+    memory_region_add_subregion(get_system_memory(), mpcinfo[i].addr, upst=
ream);
+    /* and connect its interrupt to the SSE-200 */
+    qdev_connect_gpio_out_named(DEVICE(mpc), "irq", 0,
+                                qdev_get_gpio_in_named(DEVICE(&mms->sse),
+                                                       "mpcexp_status", i)=
);
+
+    g_free(mpcname);
+    /* Return the register interface MR for our caller to map behind the P=
PC */
+    return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
+}
+
 static MemoryRegion *make_musca_a_devs(MuscaMachineState *mms, void *opaqu=
e,
                                        const char *name, hwaddr size)
 {
@@ -160,8 +294,8 @@ static MemoryRegion *make_musca_a_devs(MuscaMachineStat=
e *mms, void *opaque,
         { "pwm1", make_unimp_dev, &mms->pwm[1], 0xe000, 0x1000 },
         { "pwm2", make_unimp_dev, &mms->pwm[2], 0xf000, 0x1000 },
         { "gpio", make_unimp_dev, &mms->gpio, 0x10000, 0x1000 },
-        { "mpc0", make_unimp_dev, &mms->mpc[0], 0x12000, 0x1000 },
-        { "mpc1", make_unimp_dev, &mms->mpc[1], 0x13000, 0x1000 },
+        { "mpc0", make_mpc, &mms->mpc[0], 0x12000, 0x1000 },
+        { "mpc1", make_mpc, &mms->mpc[1], 0x13000, 0x1000 },
     };
=20
     memory_region_init(container, OBJECT(mms), "musca-device-container", s=
ize);
@@ -190,6 +324,7 @@ static void musca_init(MachineState *machine)
     int i;
=20
     assert(mmc->num_irqs <=3D MUSCA_NUMIRQ_MAX);
+    assert(mmc->num_mpcs <=3D MUSCA_MPC_MAX);
=20
     if (strcmp(machine->cpu_type, mc->default_cpu_type) !=3D 0) {
         error_report("This board can only be used with CPU %s",
@@ -285,10 +420,10 @@ static void musca_init(MachineState *machine)
                 { "eflash1", make_unimp_dev, &mms->eflash[1],
                   0x52500000, 0x1000 },
                 { "qspi", make_unimp_dev, &mms->qspi, 0x42800000, 0x100000=
 },
-                { "mpc0", make_unimp_dev, &mms->mpc[0], 0x52000000, 0x1000=
 },
-                { "mpc1", make_unimp_dev, &mms->mpc[1], 0x52100000, 0x1000=
 },
-                { "mpc2", make_unimp_dev, &mms->mpc[2], 0x52200000, 0x1000=
 },
-                { "mpc3", make_unimp_dev, &mms->mpc[3], 0x52300000, 0x1000=
 },
+                { "mpc0", make_mpc, &mms->mpc[0], 0x52000000, 0x1000 },
+                { "mpc1", make_mpc, &mms->mpc[1], 0x52100000, 0x1000 },
+                { "mpc2", make_mpc, &mms->mpc[2], 0x52200000, 0x1000 },
+                { "mpc3", make_mpc, &mms->mpc[3], 0x52300000, 0x1000 },
                 { "mhu0", make_unimp_dev, &mms->mhu[0], 0x42600000, 0x1000=
00 },
                 { "mhu1", make_unimp_dev, &mms->mhu[1], 0x42700000, 0x1000=
00 },
                 { }, /* port 9: unused */
@@ -296,7 +431,7 @@ static void musca_init(MachineState *machine)
                 { }, /* port 11: unused */
                 { }, /* port 12: unused */
                 { }, /* port 13: unused */
-                { "mpc4", make_unimp_dev, &mms->mpc[4], 0x52e00000, 0x1000=
 },
+                { "mpc4", make_mpc, &mms->mpc[4], 0x52e00000, 0x1000 },
             },
         }, {
             .name =3D "apb_ppcexp1",
@@ -434,6 +569,8 @@ static void musca_a_class_init(ObjectClass *oc, void *d=
ata)
     mmc->init_svtor =3D 0x10200000;
     mmc->sram_addr_width =3D 15;
     mmc->num_irqs =3D 64;
+    mmc->mpc_info =3D a_mpc_info;
+    mmc->num_mpcs =3D ARRAY_SIZE(a_mpc_info);
 }
=20
 static void musca_b1_class_init(ObjectClass *oc, void *data)
@@ -453,6 +590,8 @@ static void musca_b1_class_init(ObjectClass *oc, void *=
data)
     mmc->init_svtor =3D 0x10000000;
     mmc->sram_addr_width =3D 17;
     mmc->num_irqs =3D 96;
+    mmc->mpc_info =3D b1_mpc_info;
+    mmc->num_mpcs =3D ARRAY_SIZE(b1_mpc_info);
 }
=20
 static const TypeInfo musca_info =3D {
--=20
2.20.1