From patchwork Thu Aug 9 13:01:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143841 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065705ljj; Thu, 9 Aug 2018 06:01:20 -0700 (PDT) X-Google-Smtp-Source: AA+uWPw9WY0SeCPP+w6nucjO1lYWzQF7ajfXwlcaBYG2cUsEdig+XoD0aRxPWmlvCF4kngDpU0aU X-Received: by 2002:a1c:3a8f:: with SMTP id h137-v6mr1696908wma.41.1533819680372; Thu, 09 Aug 2018 06:01:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819680; cv=none; d=google.com; s=arc-20160816; b=ywnucwcuWM+4IZI8QWmfXLKUWSscJboL7JXnUEkIpyUDVz+PDRhAGRih2dD24QkDSA PpcNqLm+oNLpb9p09uKRdx0OQiGbGupT5XA9mh7fMxN2eXwLTVWJfDhNuVQyogvpGM9u gq57Cp0NPfTYz6jBS6O6btmi3+0DD7cRppblo1spRt9sqM5EJLkSmQLayLgHNfmcR0xZ j6KZa1kOQ7QOmos9tJdsnCfP7LCxABSnlfXYkksRHRlA9wQqynbEIc6G4wTbepy46GHV CBSqSKETID76nBdnZmt4w3NnkSVa+mOpBuSfKOBontC37YHHU+sQbB6f6bW834Hu5eo3 FPBA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=wTv07+L3FSslnXYTxMyE4rd9HcbfDwqPDBQ1SXm04eo=; b=pBitN/1F/adI9SzJw7WY6dIM/o2UmrutFiAWuOdxd2LtQGbLKeZBfEWTKzBM5xav0C Z+T3V7Sux7s0DRIeZ5Txxtdox55UqNCpurgSbqJGAIJ/UICsuM6wIuJ08Fwn6IzZy24o np30ubIynqw309i2J+YLozXSy0RNHeEioitZVQ928cI4+RhF4WkUo1V2EUmMVBA3EeW4 mP6NXNmKRqFKdkxLXZYGiStilKRLpkwm5JsH0dWmn5Z6UgfmIsMFoz/fCDQm3HvTDtMd rPNbvMo2QZmEwbrP0FopLBvznr72qSHwkomFeNbf6uyCoeDDYZriGktmRlMB7Aa9YM1g bcqw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id n1-v6si4771834wrr.373.2018.08.09.06.01.20 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZ5-0003Ey-PY; Thu, 09 Aug 2018 14:01:19 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 01/16] hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module Date: Thu, 9 Aug 2018 14:01:00 +0100 Message-Id: <20180809130115.28951-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> The Arm Cortex-M System Design Kit includes a simple watchdog module based on a 32-bit down-counter. Implement this. Signed-off-by: Peter Maydell --- Makefile.objs | 1 + hw/watchdog/Makefile.objs | 1 + include/hw/watchdog/cmsdk-apb-watchdog.h | 59 ++++ hw/watchdog/cmsdk-apb-watchdog.c | 326 +++++++++++++++++++++++ MAINTAINERS | 2 + default-configs/arm-softmmu.mak | 1 + hw/watchdog/trace-events | 6 + 7 files changed, 396 insertions(+) create mode 100644 include/hw/watchdog/cmsdk-apb-watchdog.h create mode 100644 hw/watchdog/cmsdk-apb-watchdog.c create mode 100644 hw/watchdog/trace-events -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/Makefile.objs b/Makefile.objs index 7a9828da282..ce9c79235e6 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -240,6 +240,7 @@ trace-events-subdirs += hw/tpm trace-events-subdirs += hw/usb trace-events-subdirs += hw/vfio trace-events-subdirs += hw/virtio +trace-events-subdirs += hw/watchdog trace-events-subdirs += hw/xen trace-events-subdirs += io trace-events-subdirs += linux-user diff --git a/hw/watchdog/Makefile.objs b/hw/watchdog/Makefile.objs index 9589bed63a3..3f536d1cad8 100644 --- a/hw/watchdog/Makefile.objs +++ b/hw/watchdog/Makefile.objs @@ -1,4 +1,5 @@ common-obj-y += watchdog.o +common-obj-$(CONFIG_CMSDK_APB_WATCHDOG) += cmsdk-apb-watchdog.o common-obj-$(CONFIG_WDT_IB6300ESB) += wdt_i6300esb.o common-obj-$(CONFIG_WDT_IB700) += wdt_ib700.o common-obj-$(CONFIG_WDT_DIAG288) += wdt_diag288.o diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h new file mode 100644 index 00000000000..ab8b5987a19 --- /dev/null +++ b/include/hw/watchdog/cmsdk-apb-watchdog.h @@ -0,0 +1,59 @@ +/* + * ARM CMSDK APB watchdog 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 watchdog" which is part of the Cortex-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/cortex-m-system-design-kit + * + * QEMU interface: + * + QOM property "wdogclk-frq": frequency at which the watchdog is clocked + * + sysbus MMIO region 0: the register bank + * + sysbus IRQ 0: watchdog interrupt + * + * In real hardware the watchdog's reset output is just a GPIO line + * which can then be masked by the board or treated as a simple interrupt. + * (For instance the IoTKit does this with the non-secure watchdog, so that + * secure code can control whether non-secure code can perform a system + * reset via its watchdog.) In QEMU, we just wire up the watchdog reset + * to watchdog_perform_action(), at least for the moment. + */ + +#ifndef CMSDK_APB_WATCHDOG_H +#define CMSDK_APB_WATCHDOG_H + +#include "hw/sysbus.h" +#include "hw/ptimer.h" + +#define TYPE_CMSDK_APB_WATCHDOG "cmsdk-apb-watchdog" +#define CMSDK_APB_WATCHDOG(obj) OBJECT_CHECK(CMSDKAPBWatchdog, (obj), \ + TYPE_CMSDK_APB_WATCHDOG) + +typedef struct CMSDKAPBWatchdog { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + qemu_irq wdogint; + uint32_t wdogclk_frq; + struct ptimer_state *timer; + + uint32_t control; + uint32_t intstatus; + uint32_t lock; + uint32_t itcr; + uint32_t itop; + uint32_t resetstatus; +} CMSDKAPBWatchdog; + +#endif diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c new file mode 100644 index 00000000000..eb79a73fa6c --- /dev/null +++ b/hw/watchdog/cmsdk-apb-watchdog.c @@ -0,0 +1,326 @@ +/* + * ARM CMSDK APB watchdog 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 watchdog" which is part of the Cortex-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/cortex-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 "sysemu/watchdog.h" +#include "hw/sysbus.h" +#include "hw/registerfields.h" +#include "hw/watchdog/cmsdk-apb-watchdog.h" + +REG32(WDOGLOAD, 0x0) +REG32(WDOGVALUE, 0x4) +REG32(WDOGCONTROL, 0x8) + FIELD(WDOGCONTROL, INTEN, 0, 1) + FIELD(WDOGCONTROL, RESEN, 1, 1) +#define R_WDOGCONTROL_VALID_MASK (R_WDOGCONTROL_INTEN_MASK | \ + R_WDOGCONTROL_RESEN_MASK) +REG32(WDOGINTCLR, 0xc) +REG32(WDOGRIS, 0x10) + FIELD(WDOGRIS, INT, 0, 1) +REG32(WDOGMIS, 0x14) +REG32(WDOGLOCK, 0xc00) +#define WDOG_UNLOCK_VALUE 0x1ACCE551 +REG32(WDOGITCR, 0xf00) + FIELD(WDOGITCR, ENABLE, 0, 1) +#define R_WDOGITCR_VALID_MASK R_WDOGITCR_ENABLE_MASK +REG32(WDOGITOP, 0xf04) + FIELD(WDOGITOP, WDOGRES, 0, 1) + FIELD(WDOGITOP, WDOGINT, 1, 1) +#define R_WDOGITOP_VALID_MASK (R_WDOGITOP_WDOGRES_MASK | \ + R_WDOGITOP_WDOGINT_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 watchdog_id[] = { + 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ + 0x24, 0xb8, 0x1b, 0x00, /* PID0..PID3 */ + 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ +}; + +static bool cmsdk_apb_watchdog_intstatus(CMSDKAPBWatchdog *s) +{ + /* Return masked interrupt status */ + return s->intstatus && (s->control & R_WDOGCONTROL_INTEN_MASK); +} + +static bool cmsdk_apb_watchdog_resetstatus(CMSDKAPBWatchdog *s) +{ + /* Return masked reset status */ + return s->resetstatus && (s->control & R_WDOGCONTROL_RESEN_MASK); +} + +static void cmsdk_apb_watchdog_update(CMSDKAPBWatchdog *s) +{ + bool wdogint; + bool wdogres; + + if (s->itcr) { + wdogint = s->itop & R_WDOGITOP_WDOGINT_MASK; + wdogres = s->itop & R_WDOGITOP_WDOGRES_MASK; + } else { + wdogint = cmsdk_apb_watchdog_intstatus(s); + wdogres = cmsdk_apb_watchdog_resetstatus(s); + } + + qemu_set_irq(s->wdogint, wdogint); + if (wdogres) { + watchdog_perform_action(); + } +} + +static uint64_t cmsdk_apb_watchdog_read(void *opaque, hwaddr offset, + unsigned size) +{ + CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque); + uint64_t r; + + switch (offset) { + case A_WDOGLOAD: + r = ptimer_get_limit(s->timer); + break; + case A_WDOGVALUE: + r = ptimer_get_count(s->timer); + break; + case A_WDOGCONTROL: + r = s->control; + break; + case A_WDOGRIS: + r = s->intstatus; + break; + case A_WDOGMIS: + r = cmsdk_apb_watchdog_intstatus(s); + break; + case A_WDOGLOCK: + r = s->lock; + break; + case A_WDOGITCR: + r = s->itcr; + break; + case A_PID4 ... A_CID3: + r = watchdog_id[(offset - A_PID4) / 4]; + break; + case A_WDOGINTCLR: + case A_WDOGITOP: + qemu_log_mask(LOG_GUEST_ERROR, + "CMSDK APB watchdog read: read of WO offset %x\n", + (int)offset); + r = 0; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "CMSDK APB watchdog read: bad offset %x\n", (int)offset); + r = 0; + break; + } + trace_cmsdk_apb_watchdog_read(offset, r, size); + return r; +} + +static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque); + + trace_cmsdk_apb_watchdog_write(offset, value, size); + + if (s->lock && offset != A_WDOGLOCK) { + /* Write access is disabled via WDOGLOCK */ + qemu_log_mask(LOG_GUEST_ERROR, + "CMSDK APB watchdog write: write to locked watchdog\n"); + return; + } + + switch (offset) { + case A_WDOGLOAD: + /* + * Reset the load value and the current count, and make sure + * we're counting. + */ + ptimer_set_limit(s->timer, value, 1); + ptimer_run(s->timer, 0); + break; + case A_WDOGCONTROL: + s->control = value & R_WDOGCONTROL_VALID_MASK; + cmsdk_apb_watchdog_update(s); + break; + case A_WDOGINTCLR: + s->intstatus = 0; + ptimer_set_count(s->timer, ptimer_get_limit(s->timer)); + cmsdk_apb_watchdog_update(s); + break; + case A_WDOGLOCK: + s->lock = (value != WDOG_UNLOCK_VALUE); + break; + case A_WDOGITCR: + s->itcr = value & R_WDOGITCR_VALID_MASK; + cmsdk_apb_watchdog_update(s); + break; + case A_WDOGITOP: + s->itop = value & R_WDOGITOP_VALID_MASK; + cmsdk_apb_watchdog_update(s); + break; + case A_WDOGVALUE: + case A_WDOGRIS: + case A_WDOGMIS: + case A_PID4 ... A_CID3: + qemu_log_mask(LOG_GUEST_ERROR, + "CMSDK APB watchdog write: write to RO offset 0x%x\n", + (int)offset); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "CMSDK APB watchdog write: bad offset 0x%x\n", + (int)offset); + break; + } +} + +static const MemoryRegionOps cmsdk_apb_watchdog_ops = { + .read = cmsdk_apb_watchdog_read, + .write = cmsdk_apb_watchdog_write, + .endianness = DEVICE_LITTLE_ENDIAN, + /* byte/halfword accesses are just zero-padded on reads and writes */ + .impl.min_access_size = 4, + .impl.max_access_size = 4, + .valid.min_access_size = 1, + .valid.max_access_size = 4, +}; + +static void cmsdk_apb_watchdog_tick(void *opaque) +{ + CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque); + + if (!s->intstatus) { + /* Count expired for the first time: raise interrupt */ + s->intstatus = R_WDOGRIS_INT_MASK; + } else { + /* Count expired for the second time: raise reset and stop clock */ + s->resetstatus = 1; + ptimer_stop(s->timer); + } + cmsdk_apb_watchdog_update(s); +} + +static void cmsdk_apb_watchdog_reset(DeviceState *dev) +{ + CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev); + + trace_cmsdk_apb_watchdog_reset(); + s->control = 0; + s->intstatus = 0; + s->lock = 0; + s->itcr = 0; + s->itop = 0; + s->resetstatus = 0; + /* Set the limit and the count */ + ptimer_set_limit(s->timer, 0xffffffff, 1); + ptimer_run(s->timer, 0); +} + +static void cmsdk_apb_watchdog_init(Object *obj) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(obj); + + memory_region_init_io(&s->iomem, obj, &cmsdk_apb_watchdog_ops, + s, "cmsdk-apb-watchdog", 0x1000); + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->wdogint); +} + +static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp) +{ + CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev); + QEMUBH *bh; + + if (s->wdogclk_frq == 0) { + error_setg(errp, + "CMSDK APB watchdog: wdogclk-frq property must be set"); + return; + } + + bh = qemu_bh_new(cmsdk_apb_watchdog_tick, s); + s->timer = 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); + + ptimer_set_freq(s->timer, s->wdogclk_frq); +} + +static const VMStateDescription cmsdk_apb_watchdog_vmstate = { + .name = "cmsdk-apb-watchdog", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_PTIMER(timer, CMSDKAPBWatchdog), + VMSTATE_UINT32(control, CMSDKAPBWatchdog), + VMSTATE_UINT32(intstatus, CMSDKAPBWatchdog), + VMSTATE_UINT32(lock, CMSDKAPBWatchdog), + VMSTATE_UINT32(itcr, CMSDKAPBWatchdog), + VMSTATE_UINT32(itop, CMSDKAPBWatchdog), + VMSTATE_UINT32(resetstatus, CMSDKAPBWatchdog), + VMSTATE_END_OF_LIST() + } +}; + +static Property cmsdk_apb_watchdog_properties[] = { + DEFINE_PROP_UINT32("wdogclk-frq", CMSDKAPBWatchdog, wdogclk_frq, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = cmsdk_apb_watchdog_realize; + dc->vmsd = &cmsdk_apb_watchdog_vmstate; + dc->reset = cmsdk_apb_watchdog_reset; + dc->props = cmsdk_apb_watchdog_properties; +} + +static const TypeInfo cmsdk_apb_watchdog_info = { + .name = TYPE_CMSDK_APB_WATCHDOG, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(CMSDKAPBWatchdog), + .instance_init = cmsdk_apb_watchdog_init, + .class_init = cmsdk_apb_watchdog_class_init, +}; + +static void cmsdk_apb_watchdog_register_types(void) +{ + type_register_static(&cmsdk_apb_watchdog_info); +} + +type_init(cmsdk_apb_watchdog_register_types); diff --git a/MAINTAINERS b/MAINTAINERS index 2c1a55ca207..7ea39c0176b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -457,6 +457,8 @@ 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 +F: include/hw/watchdog/cmsdk-apb-watchdog.h F: hw/misc/tz-ppc.c F: include/hw/misc/tz-ppc.h F: hw/misc/tz-mpc.c diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 046e8903839..521c3d459fa 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -105,6 +105,7 @@ CONFIG_STM32F205_SOC=y CONFIG_CMSDK_APB_TIMER=y CONFIG_CMSDK_APB_DUALTIMER=y CONFIG_CMSDK_APB_UART=y +CONFIG_CMSDK_APB_WATCHDOG=y CONFIG_MPS2_FPGAIO=y CONFIG_MPS2_SCC=y diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events new file mode 100644 index 00000000000..fee95847df0 --- /dev/null +++ b/hw/watchdog/trace-events @@ -0,0 +1,6 @@ +# See docs/devel/tracing.txt for syntax documentation. + +# hw/char/cmsdk_apb_watchdog.c +cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset" From patchwork Thu Aug 9 13:01:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143842 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065738ljj; Thu, 9 Aug 2018 06:01:21 -0700 (PDT) X-Google-Smtp-Source: AA+uWPxeKIZ+caqYCUtIxIFUSsJi2kwo44pWlIBYkCWe2s8PzbCGKZSyGo80AePkJqq9EMB+WVQA X-Received: by 2002:a1c:3545:: with SMTP id c66-v6mr1606211wma.120.1533819681290; Thu, 09 Aug 2018 06:01:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819681; cv=none; d=google.com; s=arc-20160816; b=XodElS7zdw6718ToiX/HbLUaBCEhK7OICBS7D3IxwMFuY8fRA7FbFyv8FA7bZl/aVS 9q3HP+HnLvi95jD/oQtz93wgGsfZMAa2aKRpqQ7u9Xolmgo/u1dpjsb/nDhIz2YLUpEG bIlSx2r09cqIDXX+5M+ntXztTKlFM3nhRckT3tyP67cW6LrbUg8UwGC4MMY8ARYwSlE9 BJc04knfhw9Y4PYVWrAQCuHGGSEt67fvIapjK/M4c0HQ0L/mzUxoRcHSQsAumapq/D00 qUrkirjGX5RnchaDCklyx8LjESSH8FBYZEH2fIDRvMRjLBVmmhbqmyKz7blOKVdP6L+Y JJoA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=a3Zao1ZvQ3fjlmo0uyayNuSe423Fh21AC+fuAiIKCQk=; b=XBP0EIrDlBbVtYzZgaKtaEIx8hJK0tXT0ZM9KUfxESMn6fqCiVrMQ3Vyjxf7640Gh/ L2UQago3HX8HDxblw8RhlQwcugZp4iabsehSkh5/VriHRMQxM1nL5U7MNpYQiahvE3q+ bPl8dD+ca7LqFja8VVFWoQSX8L3HUPiUl05wM9mBVA+anzQOl1bssr9Pi9NXp2m/QPWk 51NKTQ0IGLc4JQkxBGVN6lZIKiwlhwNEuvD7R3AxACtiDkmy8zRJaY5gsg8Nghtiv6Cy OzNbBQFu/w1q7Mg3MbrZmRW0Eft/hC/uI1MXzBC3hEwsJ0LXoSdTadc/15R+KdMVWew/ asUA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id 69-v6si3836912wmq.3.2018.08.09.06.01.21 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:21 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZ6-0003FV-P9; Thu, 09 Aug 2018 14:01:20 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 02/16] nvic: Expose NMI line Date: Thu, 9 Aug 2018 14:01:01 +0100 Message-Id: <20180809130115.28951-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> On real v7M hardware, the NMI line is an externally visible signal that an SoC or board can toggle to assert an NMI. Expose it in our QEMU NVIC and armv7m container objects so that a board model can wire it up if it needs to. In particular, the MPS2 watchdog is wired to NMI. Signed-off-by: Peter Maydell --- hw/arm/armv7m.c | 1 + hw/intc/armv7m_nvic.c | 19 +++++++++++++++++++ hw/intc/trace-events | 1 + 3 files changed, 21 insertions(+) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index 6b076660574..66217a6053a 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -202,6 +202,7 @@ static void armv7m_realize(DeviceState *dev, Error **errp) */ qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL); qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ"); + qdev_pass_gpios(DEVICE(&s->nvic), dev, "NMI"); /* Wire the NVIC up to the CPU */ sbd = SYS_BUS_DEVICE(&s->nvic); diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index cd1e7f17299..be7771e9d1f 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -772,6 +772,24 @@ static void set_irq_level(void *opaque, int n, int level) } } +/* callback when external NMI line is changed */ +static void nvic_nmi_trigger(void *opaque, int n, int level) +{ + NVICState *s = opaque; + + trace_nvic_set_nmi_level(level); + + /* + * The architecture doesn't specify whether NMI should share + * the normal-interrupt behaviour of being resampled on + * exception handler return. We choose not to, so just + * set NMI pending here and don't track the current level. + */ + if (level) { + armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false); + } +} + static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) { ARMCPU *cpu = s->cpu; @@ -2310,6 +2328,7 @@ static void armv7m_nvic_instance_init(Object *obj) qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1); qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger", M_REG_NUM_BANKS); + qdev_init_gpio_in_named(dev, nvic_nmi_trigger, "NMI", 1); } static void armv7m_nvic_class_init(ObjectClass *klass, void *data) diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 5fb18e65c97..33e932fb918 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -184,6 +184,7 @@ nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (pr nvic_get_pending_irq_info(int irq, bool secure) "NVIC next IRQ %d: targets_secure: %d" nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)" nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d" +nvic_set_nmi_level(int level) "NVIC external NMI level set to %d" nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" From patchwork Thu Aug 9 13:01:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143844 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065753ljj; Thu, 9 Aug 2018 06:01:22 -0700 (PDT) X-Google-Smtp-Source: AA+uWPw1USvulSWo6EhBEih7oka3C6j/ZGyDubF/WYby/B0ARxMe3ynJKPMc46nRo8k6+zBYnfFy X-Received: by 2002:a5d:62c7:: with SMTP id o7-v6mr1491693wrv.83.1533819682146; Thu, 09 Aug 2018 06:01:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819682; cv=none; d=google.com; s=arc-20160816; b=HlUtEJz9Um1SX5MQWlkrXltYarFWvgYAd1rBQu93FndrUJvImNhte2FHQhs7slT7YB hCWmIw/2p1gt6vLzyq89CCpsrYCS9/q++ArNPLpgcwV9UTlj4veF9jtVNQJbLqdfddt7 u6Ca+snu9h2tgUiLxawxHXie2+haN/LQTH4XvCZU39U1403MX1xJtFfQha9BFpNE0Lm2 SN+KCQCmI7z8+7t1wGvemglcHu3fwBkw/cpiSl47D3Ss4Nj4EtI0hL5lHeUcSMY29kZs LoukhRKPSvDm9VYZivixPgkTX3fcNOuiPMBxyZ/P1/kszrs6k7vowVQUMgG6nwjYPZe1 Q2Cw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=0Jz+Eb8e6otRJbbxXrmPYDc1XCYA80Yv63sZDnWMjYY=; b=oi8aOLXb8GGNksuxJ6m+xEgd1o95B39G5Z1lgR9w62bjl2vxUYIXKc0YtlGtrTIilm KVcEGb7mY39MpqUNq8KDCZnQQXHddOwmgytqo0ordf84Otyqsj7MwE0DL3TlXO6uwsjS XGAyelp79OyvEfTib3O9s5Qw8WxHV4R7Gs1MPvF63fOovZAEHnsx5WrfjFBb90dfcE8L ZOMM8/Bab40Ccc4G5VQwt7GG0e9wHRzXpIwH1pFEBD4Ltlf2hMlA+zDAMcyCeyoC7bMD o42QvtzAF6ea9fhF8R0H8DAG3JLtHV3JCfis6mxKh+zHH1T+shbiaGIMt/x0mcV0MMMz eiaw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id f132-v6si5812699wmd.171.2018.08.09.06.01.22 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:22 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZ7-0003G1-Lf; Thu, 09 Aug 2018 14:01:21 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 03/16] hw/arm/iotkit: Wire up the watchdogs Date: Thu, 9 Aug 2018 14:01:02 +0100 Message-Id: <20180809130115.28951-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> The IoTKit includes three different instances of the CMSDK APB watchdog; create and wire them up. Signed-off-by: Peter Maydell --- include/hw/arm/iotkit.h | 6 +++++ hw/arm/iotkit.c | 58 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 3 deletions(-) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé 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; CMSDKAPBDualTimer dualtimer; UnimplementedDeviceState s32ktimer; + 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" +/* 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->dualtimer), 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); create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000); - create_unimplemented_device("S32KWATCHDOG", 0x5002e000, 0x1000); + + /* This OR gate wires together outputs from the secure watchdogs to NMI */ + 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", &err); + 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); /* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */ - 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", &err); + 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); for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) { Object *splitter = OBJECT(&s->ppc_irq_splitter[i]); From patchwork Thu Aug 9 13:01:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143845 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065776ljj; Thu, 9 Aug 2018 06:01:23 -0700 (PDT) X-Google-Smtp-Source: AA+uWPyQG8udDg0efYdLLpTUTIkNqr0NOouRVR+v+yvep/kwrudQWatJdvCzWwPWg72X/RSONYcM X-Received: by 2002:a1c:19c2:: with SMTP id 185-v6mr1625674wmz.79.1533819683022; Thu, 09 Aug 2018 06:01:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819683; cv=none; d=google.com; s=arc-20160816; b=rTNDqaLfb5vsUqyHm/WzLCtecNkxvXNq6h38NlDE9oSSVfvXUe9ZUdhdfguV0QZK/J usKueDjf4YwlPqIYswmzBpCzwgTPh1k3fhAgw9LPOix5olblqk8qEEN8FzvWWeqyYifx ehQwKAGGLkcztDCPIIZ2Ehgrt6TavLObXf+ybiy149rLy1mrDI/xTpZNna4k5lp67ORu e90d7Er2P0jhW/xL9PeRbqtnZEEp/nmuD7lKrdgiABG/1ptzsWBSx/JUFIvhk40ax/Jb UpDe3JrhVeUilWMCS1V7fq1WGswwY29crahAMTiCGEme8Gf09Ai5V7TcSuTDlRSpAJk9 olhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=Cj9VrUsJC3OYMxyXNBhMkzrmxw9kBxnxz3Sb4XPN2fE=; b=O4cD1yLdOCeOmfPKG7XvoCsYIvZEu+57Y0K6cXOVqOdWVwDjia3IM4gbWYj9KJQY9q q5usGnyWgiygXbDskW8Kmr+o//A1OH7VhDXWoJqOOgMnQ7/RaMZloPh2DxGbrrrafqMb fZ0BatC08SmXJNLgcx9mx0uNz6aYmetEN/CfMHbx2oPZ3EB0VXJkCbl9xCgQJNjR0YNa j/En+VGJIRPzFjCzPiDs8LlMFBK+lgbmndHcyPQm+oB2oQNrwvveuka0KIuLGiSD1O9Q auP/wqQl6x0mwo87ppVyOr/7iZnfv176BsD/kcuCtQM5uutAGH7Pns0q5Y4P33CGNTwY Hl0Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id v3-v6si5578326wrd.213.2018.08.09.06.01.22 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:23 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZ8-0003GV-Hn; Thu, 09 Aug 2018 14:01:22 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 04/16] hw/arm/iotkit: Wire up the S32KTIMER Date: Thu, 9 Aug 2018 14:01:03 +0100 Message-Id: <20180809130115.28951-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> The IoTKit has a CMSDK timer device that runs on the S32KCLK. Create this and wire it up. Signed-off-by: Peter Maydell --- include/hw/arm/iotkit.h | 2 +- hw/arm/iotkit.c | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé 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; CMSDKAPBDualTimer dualtimer; - UnimplementedDeviceState s32ktimer; 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->s32ktimer), + TYPE_CMSDK_APB_TIMER); sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer), 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->s32ktimer), - TYPE_UNIMPLEMENTED_DEVICE); } 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 = 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) { From patchwork Thu Aug 9 13:01:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143846 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065791ljj; Thu, 9 Aug 2018 06:01:24 -0700 (PDT) X-Google-Smtp-Source: AA+uWPz0f6bixAjRR1idxstrM2DSsJ0r07kLkgCouf98pM4/dgIdWa0jO4I9uZkItl/ghl2SYujJ X-Received: by 2002:adf:ec41:: with SMTP id w1-v6mr1426669wrn.128.1533819684049; Thu, 09 Aug 2018 06:01:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819684; cv=none; d=google.com; s=arc-20160816; b=jniW29QNB0ZXbvIdl5aVugk21KfJQSWPJI/HVn5Gnht1JV3f6ZDOCuSAmvndA8K2JH T56exUfzinRsOQVnqb9GCoqw1ovk2e0mGlhhcEARGmZELfOt8v7sUXdtoAiYLByTVjm8 SMQ/aaK14yI3tKvp9emGmHYDZgqZI8FyfndPBy/ql42/hdqiuyuR9k9acnXnXb+z5oMV NKQFU7YEFQ5eyBuSobJdMyHrmB+b3meYbvBBdfp9wuSoBERQiKN5oarjfTGB0FKRK+MJ esH/bqy2CUl4UrWA6uSkjhgKN13ZXLp/+kM1B8E3ieC54gWop80z2QIlTtWD6uYUcjQR oj1w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=2brRhtbZ0b3woZkn8CIDCjnoQTrRZ3sT54YYOMUzVHk=; b=f2QExXzwfSl5A1KUC6sCr0Lxouc8VLv7MSq2fHBmFW/+qALLwCXFyoIhBgI5JdGgjJ D3DbNK1SmY64TXM1bUyzCbOT43QKvYP5qI1B3MdC7n9XY8aFWN1A+N1bI3C3mlyfN4E8 uGNm/tfm7IA5VmVPV622z6JYhydKKkheTZ9y50vFfNgm7tOajJmljDaaZzIQ0jbnIMJV QivcG4KVm6Kf/odHzeU7+ad2XCbA4F3644xVeAgz5orwSmo2V14vuBHyO/9Y/k6GsdmX WBYXQX1GstMU0N5h83n6/MgOy9loXPuBqJp/QCsYMok7jl4H0yK5VT7TtkKcNRPQKidE YsAA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id u12-v6si5041135wri.169.2018.08.09.06.01.23 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZ9-0003Gy-Fz; Thu, 09 Aug 2018 14:01:23 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 05/16] hw/misc/iotkit-sysctl: Implement IoTKit system control element Date: Thu, 9 Aug 2018 14:01:04 +0100 Message-Id: <20180809130115.28951-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> 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 --- hw/misc/Makefile.objs | 1 + include/hw/misc/iotkit-sysctl.h | 50 +++++ hw/misc/iotkit-sysctl.c | 324 ++++++++++++++++++++++++++++++++ MAINTAINERS | 2 + default-configs/arm-softmmu.mak | 1 + hw/misc/trace-events | 7 + 6 files changed, 385 insertions(+) create mode 100644 include/hw/misc/iotkit-sysctl.h create mode 100644 hw/misc/iotkit-sysctl.c -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 93509008451..dbadb41d57a 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -65,6 +65,7 @@ obj-$(CONFIG_MPS2_SCC) += mps2-scc.o obj-$(CONFIG_TZ_MPC) += tz-mpc.o obj-$(CONFIG_TZ_PPC) += tz-ppc.o obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o +obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o obj-$(CONFIG_PVPANIC) += pvpanic.o obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h new file mode 100644 index 00000000000..c3b14ccee4c --- /dev/null +++ b/include/hw/misc/iotkit-sysctl.h @@ -0,0 +1,50 @@ +/* + * 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=/com.arm.doc.ecm0601256/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 sysinfo_iomem; + MemoryRegion sysctl_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..9445500be76 --- /dev/null +++ b/hw/misc/iotkit-sysctl.c @@ -0,0 +1,324 @@ +/* + * 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=/com.arm.doc.ecm0601256/index.html + * Specifically, it implements the "system information block" and + * "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" + +/* sysinfo block registers */ +REG32(SYS_VERSION, 0x0) +REG32(SYS_CONFIG, 0x4) + +/* sysctl block registers */ +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) + +/* PID registers, same offset in both blocks */ +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[] = { + 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ + 0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */ + 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ +}; + +static const int sysctl_id[] = { + 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ + 0x54, 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 = 0x41743; + break; + + case A_SYS_CONFIG: + r = 0x31; + break; + case A_PID4 ... A_CID3: + r = sysinfo_id[(offset - A_PID4) / 4]; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "IoTKit SysInfo read: bad offset %x\n", (int)offset); + r = 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 = { + .read = iotkit_sysinfo_read, + .write = iotkit_sysinfo_write, + .endianness = DEVICE_LITTLE_ENDIAN, + /* byte/halfword accesses are just zero-padded on reads and writes */ + .impl.min_access_size = 4, + .impl.max_access_size = 4, + .valid.min_access_size = 1, + .valid.max_access_size = 4, +}; + +static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset, + unsigned size) +{ + IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque); + uint64_t r; + + switch (offset) { + case A_SECDBGSTAT: + r = s->secure_debug; + break; + case A_RESET_SYNDROME: + r = s->reset_syndrome; + break; + case A_RESET_MASK: + r = s->reset_mask; + break; + case A_GRETREG: + r = s->gretreg; + break; + case A_INITSVRTOR0: + r = s->initsvrtor0; + break; + case A_CPUWAIT: + r = s->cpuwait; + break; + case A_BUSWAIT: + /* In IoTKit BUSWAIT is reserved, R/O, zero */ + r = 0; + break; + case A_WICCTRL: + r = s->wicctrl; + break; + case A_PID4 ... A_CID3: + r = 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 = 0; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "IoTKit SysCtl read: bad offset %x\n", (int)offset); + r = 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 = 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 = value; + break; + case A_RESET_MASK: + qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n"); + s->reset_mask = 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 = value; + break; + case A_INITSVRTOR0: + qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVRTOR0 unimplemented\n"); + s->initsvrtor0 = value; + break; + case A_CPUWAIT: + qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CPUWAIT unimplemented\n"); + s->cpuwait = value; + break; + case A_WICCTRL: + qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n"); + s->wicctrl = value; + break; + case A_SECDBGSET: + /* write-1-to-set */ + qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n"); + s->secure_debug |= value; + break; + case A_SECDBGCLR: + /* write-1-to-clear */ + s->secure_debug &= ~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 = { + .read = iotkit_sysctl_read, + .write = iotkit_sysctl_write, + .endianness = DEVICE_LITTLE_ENDIAN, + /* byte/halfword accesses are just zero-padded on reads and writes */ + .impl.min_access_size = 4, + .impl.max_access_size = 4, + .valid.min_access_size = 1, + .valid.max_access_size = 4, +}; + +static void iotkit_sysctl_reset(DeviceState *dev) +{ + IoTKitSysCtl *s = IOTKIT_SYSCTL(dev); + + trace_iotkit_sysctl_reset(); + s->secure_debug = 0; + s->reset_syndrome = 1; + s->reset_mask = 0; + s->gretreg = 0; + s->initsvrtor0 = 0x10000000; + s->cpuwait = 0; + s->wicctrl = 0; +} + +static void iotkit_sysctl_init(Object *obj) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + IoTKitSysCtl *s = IOTKIT_SYSCTL(obj); + + memory_region_init_io(&s->sysinfo_iomem, obj, &iotkit_sysinfo_ops, + s, "iotkit-sysinfo", 0x1000); + memory_region_init_io(&s->sysctl_iomem, obj, &iotkit_sysctl_ops, + s, "iotkit-sysctl", 0x1000); + sysbus_init_mmio(sbd, &s->sysinfo_iomem); + sysbus_init_mmio(sbd, &s->sysctl_iomem); +} + +static const VMStateDescription iotkit_sysctl_vmstate = { + .name = "iotkit-sysctl", + .version_id = 1, + .minimum_version_id = 1, + .fields = (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 = DEVICE_CLASS(klass); + + dc->vmsd = &iotkit_sysctl_vmstate; + dc->reset = iotkit_sysctl_reset; +} + +static const TypeInfo iotkit_sysctl_info = { + .name = TYPE_IOTKIT_SYSCTL, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(IoTKitSysCtl), + .instance_init = iotkit_sysctl_init, + .class_init = 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 7ea39c0176b..96fe011e952 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -537,6 +537,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 Musicpal M: Jan Kiszka diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 521c3d459fa..da59b820a4f 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -114,6 +114,7 @@ CONFIG_TZ_MPC=y CONFIG_TZ_PPC=y CONFIG_IOTKIT=y CONFIG_IOTKIT_SECCTL=y +CONFIG_IOTKIT_SYSCTL=y CONFIG_VERSATILE=y CONFIG_VERSATILE_PCI=y diff --git a/hw/misc/trace-events b/hw/misc/trace-events index c956e1419b7..83ab58c30f5 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -109,3 +109,10 @@ iotkit_secctl_s_write(uint32_t offset, uint64_t data, unsigned size) "IoTKit Sec iotkit_secctl_ns_read(uint32_t offset, uint64_t data, unsigned size) "IoTKit SecCtl NS regs read: offset 0x%x data 0x%" PRIx64 " size %u" iotkit_secctl_ns_write(uint32_t offset, uint64_t data, unsigned size) "IoTKit SecCtl NS regs write: offset 0x%x data 0x%" PRIx64 " size %u" iotkit_secctl_reset(void) "IoTKit SecCtl: reset" + +# 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) "IoTKit 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" From patchwork Thu Aug 9 13:01:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143847 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065820ljj; Thu, 9 Aug 2018 06:01:25 -0700 (PDT) X-Google-Smtp-Source: AA+uWPxMrafN4wsw9+qzNW1T9r4TOGyMxkVLN4LeOKskQt/WVcaVBH1QFB4Ht3bT/jo1LCMTNnW5 X-Received: by 2002:a1c:a6cc:: with SMTP id p195-v6mr1675664wme.76.1533819685125; Thu, 09 Aug 2018 06:01:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819685; cv=none; d=google.com; s=arc-20160816; b=INEaLIm6HX3NhYbikBmB1lW4dFl7Psm8ircbrIijYPz5ULgltpfl2GRJXLoKQLD50h JFUaW68icGF9U3euaEj8r45Uiu/iPdOFqAi8KXon9nlyz2278c4yL5mgcGH/nA9C8J8R cgOLkrkmzYxPTKYxAXVL6jQ3f+Ue/BnHz424y85IeoCzOajpcVsAyUfqHcLAgNwQY6mT t25N9JLsqux+LLouuqs1qjaHVPkjc0NNeCt3rvKO4CdsYumLTAEEDZhYmF7tqJ9Friih wm2QWhOANFI6FNVQgQ4WtnRuI0avDNglcjeEk/VCQGdAATKQLTC/GkvGslUUyQg+eW7r 2dHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=UTgAwKsRzaWzVJiEbqM2Wr0I3FBYVwIq6h31cPjpn/4=; b=oq9m/8MFBQXK4sP34HRsVe8Yr+Tg7VRz882AZlx8IYAH92wfv+wq51qk+bPRLBdYR1 yiI7dM4Z3KriXlc7dodjiq87mkUiKjv8sMC/noqThQFRvESyuc6Jxc5mjZ9i/5QKUryR f62B4V+iLg+0hEyNjk/54KoMGnQDmt+6glMouxO2+cWhqlKOvKwJydsS/e+85lPTPtXX xMBwa1t4P15DxWxKoYRVGiW5YcmE38NawP2+Q6MDB1Ndlfpk6m82zsqBnz5OUG9ALWY3 NEf8b0K5CkKi2MRj3UipWKLtYMTAohA4xDtrb2dAY6W72GhYTcFrcr1ZyiJRd9lzpDhs Gt2w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id 81-v6si6198986wrb.2.2018.08.09.06.01.25 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZA-0003HQ-Lh; Thu, 09 Aug 2018 14:01:24 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 06/16] hw/misc/iotkit: Wire up the system control element Date: Thu, 9 Aug 2018 14:01:05 +0100 Message-Id: <20180809130115.28951-7-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> Wire up the system control element's register banks. This is the last of the previously completely unimplemented components in the IoTKit. Signed-off-by: Peter Maydell --- include/hw/arm/iotkit.h | 4 +++- hw/arm/iotkit.c | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 0f5c5101708..1ffa31d521b 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -58,7 +58,7 @@ #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/or-irq.h" #include "hw/core/split-irq.h" @@ -97,6 +97,8 @@ typedef struct IoTKit { CMSDKAPBWatchdog nswatchdog; CMSDKAPBWatchdog swatchdog; + IoTKitSysCtl sysctl; + MemoryRegion container; MemoryRegion alias1; MemoryRegion alias2; diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index cb0ec456f39..5d59ed5489f 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" /* Clock frequency in HZ of the 32KHz "slow clock" */ @@ -151,6 +150,8 @@ 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); object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, sizeof(s->nmi_orgate), TYPE_OR_IRQ, &error_abort, NULL); @@ -516,13 +517,15 @@ static void iotkit_realize(DeviceState *dev, Error **errp) qdev_get_gpio_in_named(dev_apb_ppc1, "cfg_sec_resp", 0)); - /* 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->sysctl), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + /* System information registers */ + sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x40020000); + /* System control registers */ + sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 1, 0x50021000); /* This OR gate wires together outputs from the secure watchdogs to NMI */ object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err); From patchwork Thu Aug 9 13:01:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143848 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065844ljj; Thu, 9 Aug 2018 06:01:26 -0700 (PDT) X-Google-Smtp-Source: AA+uWPyOeEROBk8s9ECAl/T32RdAVA0jHDcOCoYlwiqdEOpT5zF5oR6Ym9kBOR4S1kyaNEKeqCWl X-Received: by 2002:adf:fe42:: with SMTP id m2-v6mr1333513wrs.171.1533819686096; Thu, 09 Aug 2018 06:01:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819686; cv=none; d=google.com; s=arc-20160816; b=l5TDo/F1L3wYDJ4nim6v2WanZKGQ8qbMln+sJiLCMnxGcFgZlK84BTSzP/GJxaCYdc JCa/PXkfA96H/WTGrxquCxteZFjwDjwB0xhpZaB5ewFFK9o7HUsfbQkURi5x6fcoOIT0 1aK3eoGBdYEshF4GUSmvGdIIYbfJbmtflDkEM3SYx/FwFWkEk3AlCJShr5hg/MfotEnL KRBmsmGAsAiLESIS3nzyWhERsjfcujuyKsElSEhtD2YUxrs6hNib1TEMPuWt0Ffiowa9 qqS7PdtNbvZyOer278/iOeB97OYTYm/2CtdWTDRx4Vx2g7F8RiIE78U8jBnPKPrkUiM7 zG0A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=C+uN9VQ8tXd2/juC2cKyoQgKSH9i1FnAU5/Tr+al5YA=; b=jVpg17s7idIHkSrIyVb3LUpwV0spo74jLHVXVgDH155kCrff1C637eRlqZrb5GB1Jx jVvfm303Fw8mYuY0Q++UPwbaI4TmQ0WizAcXgpheGSLn6hdN/sb2PdDfE9MzPNHsSp/t Lf3sjDDm84qGrpeZ/Yv/5oqY5bM4O0gx/uxcxmHlKo48cgT41t4Vk3ydUmZaADqllNwG xflbDWDqc1CjYcN+d0jF/YEDfiMjPrn3bD/LTuQY62d6/i91WTERywuIlYxLi9tr+ki9 bJ2Pu1yBoWCG53dcokmLwsu2LWh+6932MfIGAQr+aYd+8PNzAU4Mk47H1sB6EryObWNh IT6w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id f12-v6si5362314wrm.65.2018.08.09.06.01.25 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:26 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZB-0003Hs-Hh; Thu, 09 Aug 2018 14:01:25 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 07/16] hw/misc/tz-msc: Model TrustZone Master Security Controller Date: Thu, 9 Aug 2018 14:01:06 +0100 Message-Id: <20180809130115.28951-8-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> 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 -- 2.17.1 diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index dbadb41d57a..d168f8ac304 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -63,6 +63,7 @@ obj-$(CONFIG_MPS2_FPGAIO) += mps2-fpgaio.o obj-$(CONFIG_MPS2_SCC) += mps2-scc.o obj-$(CONFIG_TZ_MPC) += tz-mpc.o +obj-$(CONFIG_TZ_MSC) += tz-msc.o obj-$(CONFIG_TZ_PPC) += tz-ppc.o obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o obj-$(CONFIG_IOTKIT_SYSCTL) += 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 transaction. + * + * 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 should + * 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 transactions + * 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 MSC; + * 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 = 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 = TZ_MSC(opaque); + + trace_tz_msc_cfg_nonsec(level); + s->cfg_nonsec = level; +} + +static void tz_msc_cfg_sec_resp(void *opaque, int n, int level) +{ + TZMSC *s = TZ_MSC(opaque); + + trace_tz_msc_cfg_sec_resp(level); + s->cfg_sec_resp = level; +} + +static void tz_msc_irq_clear(void *opaque, int n, int level) +{ + TZMSC *s = TZ_MSC(opaque); + + trace_tz_msc_irq_clear(level); + + s->irq_clear = level; + if (level) { + s->irq_status = 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 = IDAU_INTERFACE_GET_CLASS(s->idau); + IDAUInterface *ii = IDAU_INTERFACE(s->idau); + bool idau_exempt = false, idau_ns = true, idau_nsc = true; + int idau_region = 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 = 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 = opaque; + AddressSpace *as = &s->downstream_as; + uint64_t data; + MemTxResult res; + + switch (tz_msc_check(s, addr)) { + case MSCBlockAbort: + return MEMTX_ERROR; + case MSCBlockRAZWI: + *pdata = 0; + return MEMTX_OK; + case MSCAllowSecure: + attrs.secure = 1; + attrs.unspecified = 0; + break; + case MSCAllowNonSecure: + attrs.secure = 0; + attrs.unspecified = 0; + break; + } + + switch (size) { + case 1: + data = address_space_ldub(as, addr, attrs, &res); + break; + case 2: + data = address_space_lduw_le(as, addr, attrs, &res); + break; + case 4: + data = address_space_ldl_le(as, addr, attrs, &res); + break; + case 8: + data = address_space_ldq_le(as, addr, attrs, &res); + break; + default: + g_assert_not_reached(); + } + *pdata = data; + return res; +} + +static MemTxResult tz_msc_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size, MemTxAttrs attrs) +{ + TZMSC *s = opaque; + AddressSpace *as = &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 = 1; + attrs.unspecified = 0; + break; + case MSCAllowNonSecure: + attrs.secure = 0; + attrs.unspecified = 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 = { + .read_with_attrs = tz_msc_read, + .write_with_attrs = tz_msc_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void tz_msc_reset(DeviceState *dev) +{ + TZMSC *s = TZ_MSC(dev); + + trace_tz_msc_reset(); + s->cfg_sec_resp = false; + s->cfg_nonsec = false; + s->irq_clear = 0; + s->irq_status = 0; +} + +static void tz_msc_init(Object *obj) +{ + DeviceState *dev = DEVICE(obj); + TZMSC *s = 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 = OBJECT(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + TZMSC *s = TZ_MSC(dev); + const char *name = "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 then. + * 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 = 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 = { + .name = "tz-msc", + .version_id = 1, + .minimum_version_id = 1, + .fields = (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[] = { + 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 = DEVICE_CLASS(klass); + + dc->realize = tz_msc_realize; + dc->vmsd = &tz_msc_vmstate; + dc->reset = tz_msc_reset; + dc->props = tz_msc_properties; +} + +static const TypeInfo tz_msc_info = { + .name = TYPE_TZ_MSC, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(TZMSC), + .instance_init = tz_msc_init, + .class_init = 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 96fe011e952..5d1a3645dd4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -463,6 +463,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 ARM cores M: Peter Maydell diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index da59b820a4f..1f2ac3b1767 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -111,6 +111,7 @@ CONFIG_MPS2_FPGAIO=y CONFIG_MPS2_SCC=y CONFIG_TZ_MPC=y +CONFIG_TZ_MSC=y CONFIG_TZ_PPC=y CONFIG_IOTKIT=y CONFIG_IOTKIT_SECCTL=y diff --git a/hw/misc/trace-events b/hw/misc/trace-events index 83ab58c30f5..f9be1b822e7 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, unsigned size, bool secur tz_mpc_translate(uint64_t addr, int flags, const char *idx, const char *res) "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 +# hw/misc/tz-msc.c +tz_msc_reset(void) "TZ MSC: reset" +tz_msc_cfg_nonsec(int level) "TZ MSC: cfg_nonsec = %d" +tz_msc_cfg_sec_resp(int level) "TZ MSC: cfg_sec_resp = %d" +tz_msc_irq_enable(int level) "TZ MSC: int_enable = %d" +tz_msc_irq_clear(int level) "TZ MSC: int_clear = %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 " access 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] = %d" From patchwork Thu Aug 9 13:01:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143849 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065866ljj; Thu, 9 Aug 2018 06:01:27 -0700 (PDT) X-Google-Smtp-Source: AA+uWPxPu2mLm2kVcr/gPT8TbsmiTawea2ZX/pxgeccz4qr6rcxMg93tes+u+9iVAmMUAlVYvX/T X-Received: by 2002:a1c:6354:: with SMTP id x81-v6mr1448911wmb.23.1533819686996; Thu, 09 Aug 2018 06:01:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819686; cv=none; d=google.com; s=arc-20160816; b=liMLwWjAZQhXZ5Iq1mzcAm6JCPfyvL1/ATx1viWYD7bBvgejRJOv9MDULwGzSHJW52 6XwqjA3E4k6sGatDf72uAS0uOrUZUkU32LMnJYXDGaHPxssUCD1oVZ5VdhBo/hFDC2gt QtYH5eUmb4LHYt3kiw88Wr4jS1X5hcGBuX0xf38TUDrcS/0vY6tKU0KGCwFYPo4FodSD Y6fGPNqt7+ir6WxdP9BXqolJHYtTbLxGOmptL7heOHBhElSYvHs02Y6NTu1LYbred/OE AIxBxaXoLjxX9l9W7gY0l1Egvn010ANi4Zj2u3TaSFRD82Ik4jwsVmeB5GvZWPAo3zBp 7FqQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=H5cK4IuX3xuLw1G2kJuND+rjJ/WhcaxP1LLhn+sM9MU=; b=zV/Dzd44IzJHpuYcIMuD1iFgjEjItmU+2spYyPcWEkdzj+Y8FLft81yUQbrJ32sWAs VYfXdrUopnFqnhsbgP66zqO86Ql/0jrL0pg2pGFD4ZmRM6nkiqbQF9yIbIrCDYdcbktW cSL6GZ0WKw3P4yyTuc2Fl5a4fkPppMBlb7iZAZA6yY/84WGPtmzTcEcU0at/YMhwYgjJ iuCJ/iJrZKcFgLiQhuXQucpp2suKI0oaEXaeECt2EC5n8amaZuK5OzhyirNOBnEYMW+f l8iavPmy+Ib8i9Uev1PV4IPvhzOSrWSL5k8hCPWNKm0FVWpPnVmSfuKFlTMt2GRsKqZa JdJw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id z74-v6si6074709wmc.51.2018.08.09.06.01.26 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:26 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZC-0003IK-GG; Thu, 09 Aug 2018 14:01:26 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 08/16] hw/misc/iotkit-secctl: Wire up registers for controlling MSCs Date: Thu, 9 Aug 2018 14:01:07 +0100 Message-Id: <20180809130115.28951-9-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> 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 --- include/hw/misc/iotkit-secctl.h | 14 +++++++ hw/misc/iotkit-secctl.c | 73 +++++++++++++++++++++++++++++---- 2 files changed, 79 insertions(+), 8 deletions(-) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.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 value + * + 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 IoTKit * might provide: * + named GPIO inputs mpcexp_status[0..15] + * Controlling each of the 16 expansion MSCs which a system using the IoTKit + * might provide: + * + named GPIO inputs mscexp_status[0..15] + * + named GPIO outputs mscexp_clear[0..15] + * + named GPIO outputs mscexp_ns[0..15] */ #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 typedef struct IoTKitSecCtl IoTKitSecCtl; @@ -103,6 +110,13 @@ struct IoTKitSecCtl { uint32_t brginten; uint32_t mpcintstatus; + 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 = s->apbexp[offset_to_ppc_idx(offset)].sp; break; case A_SECMSCINTSTAT: + r = s->secmscintstat; + break; case A_SECMSCINTEN: + r = s->secmscinten; + break; case A_NSMSCEXP: - qemu_log_mask(LOG_UNIMP, - "IoTKit SecCtl S block read: " - "unimplemented offset 0x%x\n", offset); - r = 0; + r = s->nsmscexp; break; case A_PID4: case A_PID5: @@ -291,6 +292,23 @@ static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc) qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1)); } +static void iotkit_secctl_update_mscexp_irqs(qemu_irq *msc_irqs, uint32_t value) +{ + int i; + + for (i = 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 = 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 = value; + iotkit_secctl_update_msc_irq(s); + break; + case A_NSMSCEXP: + s->nsmscexp = 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 = deposit32(s->mpcintstatus, n + 16, 1, !!level); } +static void iotkit_secctl_mscexp_status(void *opaque, int n, int level) +{ + IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); + + s->secmscintstat = 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 = 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); + 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_mpcintstatus_vmstate = { } }; +static bool needed_always(void *opaque) +{ + return true; +} + +static const VMStateDescription iotkit_secctl_msc_vmstate = { + .name = "iotkit-secctl/msc", + .version_id = 1, + .minimum_version_id = 1, + .needed = needed_always, + .fields = (VMStateField[]) { + VMSTATE_UINT32(secmscintstat, IoTKitSecCtl), + VMSTATE_UINT32(secmscinten, IoTKitSecCtl), + VMSTATE_UINT32(nsmscexp, IoTKitSecCtl), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription iotkit_secctl_vmstate = { .name = "iotkit-secctl", .version_id = 1, @@ -710,6 +766,7 @@ static const VMStateDescription iotkit_secctl_vmstate = { }, .subsections = (const VMStateDescription*[]) { &iotkit_secctl_mpcintstatus_vmstate, + &iotkit_secctl_msc_vmstate, NULL }, }; From patchwork Thu Aug 9 13:01:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143850 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065901ljj; Thu, 9 Aug 2018 06:01:28 -0700 (PDT) X-Google-Smtp-Source: AA+uWPzmUEfTCaXQzGU9+jR3io2k9tCvlhIkQgkAUOf9uzTCJhka1FcHI6pwZZ5W8nE5hfhI+EWN X-Received: by 2002:adf:adae:: with SMTP id w43-v6mr1464020wrc.251.1533819687953; Thu, 09 Aug 2018 06:01:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819687; cv=none; d=google.com; s=arc-20160816; b=D0gbXSGrDbLaNXQCrbVLJZ0cWIuRrxgEh5R4xSoyDPw/kSAj0yrF4iHA4TYl2Lzi3k c7DVY1vXdbNBOuJNL9F4VAN3k5nstX50UXjVAMCAsMMuHeyW77PuZErB43yuIV/IbmAK oK+hClYwJFMW46lFu5Beiu3McldGLaztdCFEIQwjsk0EZOFFIoANjA9Eirf/9kZ/DP13 gUX8pMvpJ6bP2Z987iqW5h1pTle9XPgVvCpswdRo90vusDWvP8DTnx8iWNT67tE7GzmT QKnP3vK0YrEn4otlZYhfA+oqHIvDd0ocf8nL/8/Q9YLvAq1O8yFPTLHlFMwkXJkBHnPo 2Jzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=Pq44vsSwXW/FFbzQY6qdIFSkxtnEjBjFQAxc5Q3OSC4=; b=JpZ9sYmTWRPrR6aQ20yxEmUaCqtM6v9iv2ZMzdsw9mZB7DPn4A+1+yIHBMxpXR1zsd Eq/r7MejPjuWu/OHa1XOsLOqxhmM3O31OU2Eh/BUXaNu2/jSTb4D/sR7OfLzBEmyZ3E0 9Drh4nqjpOytItrxu9Tc9cG1Z5jyWbrXfRJ2y2xSBXBRsYqnieTZA8hBSATiXT6sgAVs AcxF4AgT0am/GBudBZR7kK+1xec5XpJaSzHcZYZOrZM1zg/UtAiP8VIVJrbLY5zlIjX1 n4WgT97t/ma/hf8G9R+L78+SPdiBbztpuWgZxNLokxBqvZDk1dToAGjOdyu12lm216Sr Lh6g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id q15-v6si5008155wrn.382.2018.08.09.06.01.27 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:27 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZD-0003Ip-Cd; Thu, 09 Aug 2018 14:01:27 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 09/16] hw/arm/iotkit: Wire up the lines for MSCs Date: Thu, 9 Aug 2018 14:01:08 +0100 Message-Id: <20180809130115.28951-10-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> 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 --- include/hw/arm/iotkit.h | 8 ++++++++ hw/arm/iotkit.c | 15 +++++++++++++++ 2 files changed, 23 insertions(+) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 1ffa31d521b..5bb66b10468 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 IoTKit * might provide: * + named GPIO inputs mpcexp_status[0..15] + * Controlling each of the 16 expansion MSCs which a system using the IoTKit + * might provide: + * + named GPIO inputs mscexp_status[0..15] + * + named GPIO outputs mscexp_clear[0..15] + * + named GPIO outputs mscexp_ns[0..15] */ #ifndef IOTKIT_H diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index 5d59ed5489f..8ae2a052517 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -660,6 +660,21 @@ static void iotkit_realize(DeviceState *dev, Error **errp) iotkit_forward_sec_resp_cfg(s); + /* 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 = NANOSECONDS_PER_SECOND / s->mainclk_frq; } From patchwork Thu Aug 9 13:01:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143851 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065926ljj; Thu, 9 Aug 2018 06:01:28 -0700 (PDT) X-Google-Smtp-Source: AA+uWPwsHGOp7mpWjk3s3bjbypjv7qpcQYtUX6bS8WbKxtCpgPlio1Ij7MsH7jgvIjJA4ghUsF6N X-Received: by 2002:a1c:b49:: with SMTP id 70-v6mr1652642wml.149.1533819688859; Thu, 09 Aug 2018 06:01:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819688; cv=none; d=google.com; s=arc-20160816; b=UY9WsOLnYfc4PSmVBrwITIz6JYf32233+jH1hfFvDchVwn333YPhTZ8R5EoNw0+TXF jHCRibw+/bZtSMVjPP4xE86OC8ZfDCG7+Sq0mp1Ks0Mcy9RUKiFkTOLpxhiTwFiggIpc TT5evwKE/J0hUiJPFqRxEEiJwQBOjoui/VX/Zba9SDCKXIvlZV8agiI/l4wZzzolY9yo ISDyralkXvZUU7Sz8yR1LjdnM5hm5Tg9SrqerjzACYgHSm/DQg5P5x8Wf2XBoz0+qkX0 Lcmii4CmxyEvdl+eGg0SotEVFNJxWLOfsrrn/CZXZWNoiC1quEAAMrYDGqL6lbylkybD JBew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=kobDFngLI/XKlBst3pxRV5FTylo4OQ8HKEVp/5oGXWM=; b=ZasIG6fBLD1IQWN8cIWSxHvnpOmA5DRimaLsHaMG6AvsPIyIxsTfV5dt8iZFVJKUOy 6jaj4ZUM+ZEXIIWZ1+DXTxP7DhUDaw1UrCY5xwQDU9U+u2O7F9gnCFLaOjBj+SJtpcn9 eqKgr9ge3B/rEaypHkqnZlTEfTZEc9b2Tw1Va0PL+6QYB0xBPcYVKLMHN4tG9d3N2Idk 92oehgEov8YhhnJT10VGs2n8gf+mIQwUeY0PlUzt7FaGCDD01sNgOF64k75JaLUgULY2 7MYqF9SQnk+N+VWcippOHDBt/qyGnQ4Az0zZ1BxM1HuanmdWJWZu2fBtIUwJUwi0RByB ph4w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id 197-v6si5493723wme.98.2018.08.09.06.01.28 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:28 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZE-0003J5-DM; Thu, 09 Aug 2018 14:01:28 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 10/16] hw/dma/pl080: Allow use as embedded-struct device Date: Thu, 9 Aug 2018 14:01:09 +0100 Message-Id: <20180809130115.28951-11-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> Create a new include file for the pl081's device struct, type macros, etc, so that it can be instantiated using the "embedded struct" coding style. Signed-off-by: Peter Maydell --- include/hw/dma/pl080.h | 62 ++++++++++++++++++++++++++++++++++++++++++ hw/dma/pl080.c | 34 ++--------------------- MAINTAINERS | 1 + 3 files changed, 65 insertions(+), 32 deletions(-) create mode 100644 include/hw/dma/pl080.h -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h new file mode 100644 index 00000000000..7deb46c8578 --- /dev/null +++ b/include/hw/dma/pl080.h @@ -0,0 +1,62 @@ +/* + * ARM PrimeCell PL080/PL081 DMA controller + * + * Copyright (c) 2006 CodeSourcery. + * Copyright (c) 2018 Linaro Limited + * Written by Paul Brook, 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 Arm PrimeCell PL080/PL081 DMA controller: + * The PL080 TRM is: + * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0196g/DDI0196.pdf + * and the PL081 TRM is: + * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0218e/DDI0218.pdf + * + * QEMU interface: + * + sysbus IRQ: DMACINTR combined interrupt line + * + sysbus MMIO region 0: MemoryRegion for the device's registers + */ + +#ifndef HW_DMA_PL080_H +#define HW_DMA_PL080_H + +#include "hw/sysbus.h" + +#define PL080_MAX_CHANNELS 8 + +typedef struct { + uint32_t src; + uint32_t dest; + uint32_t lli; + uint32_t ctrl; + uint32_t conf; +} pl080_channel; + +#define TYPE_PL080 "pl080" +#define TYPE_PL081 "pl081" +#define PL080(obj) OBJECT_CHECK(PL080State, (obj), TYPE_PL080) + +typedef struct PL080State { + SysBusDevice parent_obj; + + MemoryRegion iomem; + uint8_t tc_int; + uint8_t tc_mask; + uint8_t err_int; + uint8_t err_mask; + uint32_t conf; + uint32_t sync; + uint32_t req_single; + uint32_t req_burst; + pl080_channel chan[PL080_MAX_CHANNELS]; + int nchannels; + /* Flag to avoid recursive DMA invocations. */ + int running; + qemu_irq irq; +} PL080State; + +#endif diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c index 7724c93b8f2..0f79c2d8a6c 100644 --- a/hw/dma/pl080.c +++ b/hw/dma/pl080.c @@ -11,8 +11,8 @@ #include "hw/sysbus.h" #include "exec/address-spaces.h" #include "qemu/log.h" +#include "hw/dma/pl080.h" -#define PL080_MAX_CHANNELS 8 #define PL080_CONF_E 0x1 #define PL080_CONF_M1 0x2 #define PL080_CONF_M2 0x4 @@ -30,36 +30,6 @@ #define PL080_CCTRL_D 0x02000000 #define PL080_CCTRL_S 0x01000000 -typedef struct { - uint32_t src; - uint32_t dest; - uint32_t lli; - uint32_t ctrl; - uint32_t conf; -} pl080_channel; - -#define TYPE_PL080 "pl080" -#define PL080(obj) OBJECT_CHECK(PL080State, (obj), TYPE_PL080) - -typedef struct PL080State { - SysBusDevice parent_obj; - - MemoryRegion iomem; - uint8_t tc_int; - uint8_t tc_mask; - uint8_t err_int; - uint8_t err_mask; - uint32_t conf; - uint32_t sync; - uint32_t req_single; - uint32_t req_burst; - pl080_channel chan[PL080_MAX_CHANNELS]; - int nchannels; - /* Flag to avoid recursive DMA invocations. */ - int running; - qemu_irq irq; -} PL080State; - static const VMStateDescription vmstate_pl080_channel = { .name = "pl080_channel", .version_id = 1, @@ -408,7 +378,7 @@ static const TypeInfo pl080_info = { }; static const TypeInfo pl081_info = { - .name = "pl081", + .name = TYPE_PL081, .parent = TYPE_PL080, .instance_init = pl081_init, }; diff --git a/MAINTAINERS b/MAINTAINERS index 5d1a3645dd4..92ccca716c6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -444,6 +444,7 @@ F: hw/char/pl011.c F: include/hw/char/pl011.h F: hw/display/pl110* F: hw/dma/pl080.c +F: include/hw/dma/pl080.h F: hw/dma/pl330.c F: hw/gpio/pl061.c F: hw/input/pl050.c From patchwork Thu Aug 9 13:01:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143852 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065947ljj; Thu, 9 Aug 2018 06:01:29 -0700 (PDT) X-Google-Smtp-Source: AA+uWPy2R5pqa21VvxMivlswgyXofWHWfDlk3lmQ+fDPW9xLay7GJn121gxJxVr+ryDQZIJNYxSa X-Received: by 2002:a5d:40c4:: with SMTP id b4-v6mr1278814wrq.133.1533819689801; Thu, 09 Aug 2018 06:01:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819689; cv=none; d=google.com; s=arc-20160816; b=ZAV3F9r00KW7w8QZCq2GFq1qGIsnXKKC6f7m5/F1ssrGSWtbvVELU99Z6gC6aYOg/v YE8XKbzUNgg0ocSMOa8D+YZLfV1cwxN3GbTOP0YzwQFYFU+IUwxGsFjbpSHqh9tl03j+ zDYePGOyLiq7qo5XPcG8ApKhD1JFFzVNouMP7/3wzLdLTK20/9JJcCKaUUSKTBcsHyaL llgDGAOH9xywa/PB+yvYsrE2zLPEkKZVqMk9eAxPH1p5qt9F3NDe1M5E7dkITL60AWHe z37POUc6CqhuYBiS0WhZ9ZMJVigGElnjeA1Ev7QPWMxW1nUaiBSBApiqkiscwHh+g75C kbKg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=hka9hIxdADblY+Ix/TAYRt8XYcW42JEeyxKN78kg7C4=; b=HOYrEZeb4yQxQ/A/eJfgWnfqqvxVnfcqd/ke/svXfL7WBLHsknObi/Gr7Qr18HemQX +SAXJfY96N10s347aDP0DoCAj/UUKAxDw5N6TV2QlxDDNMBqAOMR1IHJUbupW9hVQOiq EAhrg5TxJzwWI+GPysMntFkBKOpQPhd5hwH/h4LY4Jy85j3Zb3IJMO2YOpa+lEoEzd7q pwNyL5aZhtoVFZGVw2G9kjnPXarbZIBzsOoqsfuy/DkWXCRqel+mQd0767SNzmpkon5X +7pMqvUROFFc2q+kCEJ9uo+dmhWGCosLM75h6wdSuZbTXCf3o2i4WYx/i7n/yZQj9vPZ COIA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id y12-v6si4800675wrp.372.2018.08.09.06.01.29 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:29 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZF-0003Jc-Ba; Thu, 09 Aug 2018 14:01:29 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 11/16] hw/dma/pl080: Support all three interrupt lines Date: Thu, 9 Aug 2018 14:01:10 +0100 Message-Id: <20180809130115.28951-12-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> The PL080 and PL081 have three outgoing interrupt lines: * DMACINTERR signals DMA errors * DMACINTTC is the DMA count interrupt * DMACINTR is a combined interrupt, the logical OR of the other two We currently only implement DMACINTR, because that's all the realview and versatile boards needed, but the instances of the PL081 in the MPS2 firmware images use all three interrupt lines. Implement the missing DMACINTERR and DMACINTTC. Signed-off-by: Peter Maydell --- include/hw/dma/pl080.h | 6 +++++- hw/dma/pl080.c | 13 ++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h index 7deb46c8578..7c6a4184833 100644 --- a/include/hw/dma/pl080.h +++ b/include/hw/dma/pl080.h @@ -17,7 +17,9 @@ * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0218e/DDI0218.pdf * * QEMU interface: - * + sysbus IRQ: DMACINTR combined interrupt line + * + sysbus IRQ 0: DMACINTR combined interrupt line + * + sysbus IRQ 1: DMACINTERR error interrupt request + * + sysbus IRQ 2: DMACINTTC count interrupt request * + sysbus MMIO region 0: MemoryRegion for the device's registers */ @@ -57,6 +59,8 @@ typedef struct PL080State { /* Flag to avoid recursive DMA invocations. */ int running; qemu_irq irq; + qemu_irq interr; + qemu_irq inttc; } PL080State; #endif diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c index 0f79c2d8a6c..301030dd118 100644 --- a/hw/dma/pl080.c +++ b/hw/dma/pl080.c @@ -75,11 +75,12 @@ static const unsigned char pl081_id[] = static void pl080_update(PL080State *s) { - if ((s->tc_int & s->tc_mask) - || (s->err_int & s->err_mask)) - qemu_irq_raise(s->irq); - else - qemu_irq_lower(s->irq); + bool tclevel = (s->tc_int & s->tc_mask); + bool errlevel = (s->err_int & s->err_mask); + + qemu_set_irq(s->interr, errlevel); + qemu_set_irq(s->inttc, tclevel); + qemu_set_irq(s->irq, errlevel || tclevel); } static void pl080_run(PL080State *s) @@ -352,6 +353,8 @@ static void pl080_init(Object *obj) memory_region_init_io(&s->iomem, OBJECT(s), &pl080_ops, s, "pl080", 0x1000); sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq); + sysbus_init_irq(sbd, &s->interr); + sysbus_init_irq(sbd, &s->inttc); s->nchannels = 8; } From patchwork Thu Aug 9 13:01:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143853 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2065988ljj; Thu, 9 Aug 2018 06:01:31 -0700 (PDT) X-Google-Smtp-Source: AA+uWPyetstWpmXVTz8oxOJ/WMPgwHPiqrIC5kRoLIAEVyWSXra2mwdi7jhkZhz6ChA0iDfUbQXl X-Received: by 2002:adf:bacf:: with SMTP id w15-v6mr1459035wrg.203.1533819691619; Thu, 09 Aug 2018 06:01:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819691; cv=none; d=google.com; s=arc-20160816; b=UjebbyDnEfnDSUBnv2NXz4H0evi3qzmPjScQio/GqAino8WTZuJ444UVvfte2K4aWo Ygb+9r+4EPI7NrzgOtdBYnmI1bcZ/be1KG4fsmwVH7ZSHijTL1hOdXFMPYqQRLyDJwdN ic3QjZzmTgPS4MO/VKmsOQnb7iAEGnU3PzMZgr3cnKBnXtQ4YwjABl1hk6385zdBhTZl cDyNkahmitdIC3Zhxo92ISSQWMWTzE2qTpPBTwNRDYcBqPlnmFs//WFjHOy0zXUnA4X6 MM1WtqRTdePVFlI4Zdy5pCL2XLOYDKDw8q4vH9Q2SQcfIzDWubrf2Js1HkpAZnZ6RgYL Sgqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=R9VDllhHo9krc8Cn9Ew8nm84DnjJAtMyKYVPctrHlOg=; b=ysCmgY6CkmMcBnroUx8krQezUS06K+mHamm0Drh3zjy1NVco6n6bBCqomYpvyKYQ87 BeRTuuwgUkdGS+8/8LLFjdSuxFE6FJblDm1EE1dsWyAlm8JVl5dm+zszh3fvz23vjxTb d77FhllBcq7y9BErEymDZdojBIWQoHPzM3487XUZgCkE/VcBw/OYiUVFYn1z43A1ezU5 5q4sguMR03s8x7UucSvC0S+z7EZltPvOTDPl2qgQCfJ5nid55ZeHNllkNi+U7Cl8OSSf XjeCVhreCvrSUZvRVLYpBWg2TtX3jNt+BEPp0bm+KMi1yu112/jmGVjt7T1onXFJEFKi 6qrg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id x16-v6si4799858wrs.446.2018.08.09.06.01.31 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZH-0003K6-3f; Thu, 09 Aug 2018 14:01:31 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 12/16] hw/dma/pl080: Don't use CPU address space for DMA accesses Date: Thu, 9 Aug 2018 14:01:11 +0100 Message-Id: <20180809130115.28951-13-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> Currently our PL080/PL081 model uses a combination of the CPU's address space (via cpu_physical_memory_{read,write}()) and the system address space for performing DMA accesses. For the PL081s in the MPS FPGA images, their DMA accesses must go via Master Security Controllers. Switch the PL080/PL081 model to take a MemoryRegion property which defines its downstream for making DMA accesses. Since the PL08x are only used in two board models, we make provision of the 'downstream' link mandatory and convert both users at once, rather than having it be optional with a default to the system address space. Signed-off-by: Peter Maydell --- include/hw/dma/pl080.h | 5 +++++ hw/arm/realview.c | 8 +++++++- hw/arm/versatilepb.c | 9 ++++++++- hw/dma/pl080.c | 35 +++++++++++++++++++++++++++++------ 4 files changed, 49 insertions(+), 8 deletions(-) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h index 7c6a4184833..9d4b3df143f 100644 --- a/include/hw/dma/pl080.h +++ b/include/hw/dma/pl080.h @@ -21,6 +21,8 @@ * + sysbus IRQ 1: DMACINTERR error interrupt request * + sysbus IRQ 2: DMACINTTC count interrupt request * + sysbus MMIO region 0: MemoryRegion for the device's registers + * + QOM property "downstream": MemoryRegion defining where DMA + * bus master transactions are made */ #ifndef HW_DMA_PL080_H @@ -61,6 +63,9 @@ typedef struct PL080State { qemu_irq irq; qemu_irq interr; qemu_irq inttc; + + MemoryRegion *downstream; + AddressSpace downstream_as; } PL080State; #endif diff --git a/hw/arm/realview.c b/hw/arm/realview.c index cd585d94694..ab8c14fde38 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -201,7 +201,13 @@ static void realview_init(MachineState *machine, pl011_create(0x1000c000, pic[15], serial_hd(3)); /* DMA controller is optional, apparently. */ - sysbus_create_simple("pl081", 0x10030000, pic[24]); + dev = qdev_create(NULL, "pl081"); + object_property_set_link(OBJECT(dev), OBJECT(sysmem), "downstream", + &error_fatal); + qdev_init_nofail(dev); + busdev = SYS_BUS_DEVICE(dev); + sysbus_mmio_map(busdev, 0, 0x10030000); + sysbus_connect_irq(busdev, 0, pic[24]); sysbus_create_simple("sp804", 0x10011000, pic[4]); sysbus_create_simple("sp804", 0x10012000, pic[5]); diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index a5a06b6d408..8b748570596 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -287,7 +287,14 @@ static void versatile_init(MachineState *machine, int board_id) pl011_create(0x101f3000, pic[14], serial_hd(2)); pl011_create(0x10009000, sic[6], serial_hd(3)); - sysbus_create_simple("pl080", 0x10130000, pic[17]); + dev = qdev_create(NULL, "pl080"); + object_property_set_link(OBJECT(dev), OBJECT(sysmem), "downstream", + &error_fatal); + qdev_init_nofail(dev); + busdev = SYS_BUS_DEVICE(dev); + sysbus_mmio_map(busdev, 0, 0x10130000); + sysbus_connect_irq(busdev, 0, pic[17]); + sysbus_create_simple("sp804", 0x101e2000, pic[4]); sysbus_create_simple("sp804", 0x101e3000, pic[5]); diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c index 301030dd118..8f9f3e08d9a 100644 --- a/hw/dma/pl080.c +++ b/hw/dma/pl080.c @@ -12,6 +12,7 @@ #include "exec/address-spaces.h" #include "qemu/log.h" #include "hw/dma/pl080.h" +#include "qapi/error.h" #define PL080_CONF_E 0x1 #define PL080_CONF_M1 0x2 @@ -161,14 +162,16 @@ again: swidth = 1 << ((ch->ctrl >> 18) & 7); dwidth = 1 << ((ch->ctrl >> 21) & 7); for (n = 0; n < dwidth; n+= swidth) { - cpu_physical_memory_read(ch->src, buff + n, swidth); + address_space_read(&s->downstream_as, ch->src, + MEMTXATTRS_UNSPECIFIED, buff + n, swidth); if (ch->ctrl & PL080_CCTRL_SI) ch->src += swidth; } xsize = (dwidth < swidth) ? swidth : dwidth; /* ??? This may pad the value incorrectly for dwidth < 32. */ for (n = 0; n < xsize; n += dwidth) { - cpu_physical_memory_write(ch->dest + n, buff + n, dwidth); + address_space_write(&s->downstream_as, ch->dest + n, + MEMTXATTRS_UNSPECIFIED, buff + n, dwidth); if (ch->ctrl & PL080_CCTRL_DI) ch->dest += swidth; } @@ -178,19 +181,19 @@ again: if (size == 0) { /* Transfer complete. */ if (ch->lli) { - ch->src = address_space_ldl_le(&address_space_memory, + ch->src = address_space_ldl_le(&s->downstream_as, ch->lli, MEMTXATTRS_UNSPECIFIED, NULL); - ch->dest = address_space_ldl_le(&address_space_memory, + ch->dest = address_space_ldl_le(&s->downstream_as, ch->lli + 4, MEMTXATTRS_UNSPECIFIED, NULL); - ch->ctrl = address_space_ldl_le(&address_space_memory, + ch->ctrl = address_space_ldl_le(&s->downstream_as, ch->lli + 12, MEMTXATTRS_UNSPECIFIED, NULL); - ch->lli = address_space_ldl_le(&address_space_memory, + ch->lli = address_space_ldl_le(&s->downstream_as, ch->lli + 8, MEMTXATTRS_UNSPECIFIED, NULL); @@ -358,6 +361,18 @@ static void pl080_init(Object *obj) s->nchannels = 8; } +static void pl080_realize(DeviceState *dev, Error **errp) +{ + PL080State *s = PL080(dev); + + if (!s->downstream) { + error_setg(errp, "PL080 'downstream' link not set"); + return; + } + + address_space_init(&s->downstream_as, s->downstream, "pl080-downstream"); +} + static void pl081_init(Object *obj) { PL080State *s = PL080(obj); @@ -365,11 +380,19 @@ static void pl081_init(Object *obj) s->nchannels = 2; } +static Property pl080_properties[] = { + DEFINE_PROP_LINK("downstream", PL080State, downstream, + TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_END_OF_LIST(), +}; + static void pl080_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); dc->vmsd = &vmstate_pl080; + dc->realize = pl080_realize; + dc->props = pl080_properties; } static const TypeInfo pl080_info = { From patchwork Thu Aug 9 13:01:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143854 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2066011ljj; Thu, 9 Aug 2018 06:01:32 -0700 (PDT) X-Google-Smtp-Source: AA+uWPzTJlRQAQEKCuOeTHKuLok0HTb/kg+9DvboBOusouQrPb0Y3hqtlAa9/ZWTXC3uJtCVLLpu X-Received: by 2002:a1c:ec86:: with SMTP id h6-v6mr1591881wmi.53.1533819692605; Thu, 09 Aug 2018 06:01:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819692; cv=none; d=google.com; s=arc-20160816; b=Axngb1UBSk3Ry6XrV35eCLiLfy46F2jFSWAJVyA1BNPbU84JlHWN669g3n+IrO33/6 CjAJTYwLBfbJ6DaQypHaA7BiK0dtT58oeOBEyiI4SrHcgshwkfHl3VywXp5Gx3O3VZLW 0JD6eZi1zOY4MuG/TxQi+77b5HXDSxchmWzmAkl5LAI23vav4p5N0nEiHGVZum6fYBxC DVrUz4U6ofl9iwL11nneln6LqD7a0XlNDTzcn9l0phSPmf2UoMpqhQZlcMeVxVLrFF0O tJo8Tbi3JfuHcAEl/uITInlF+0qHAdA5/164orYbjs9tKrF89Ig8b4cAhB1cMG4z6s2L y8qA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=n8uuyt2ZudM98RA82kXcYbhpvrT9oTgQmSk1xPoMa/0=; b=VsqP7yGOi7ATLKOAdIq9FJMXsC6pEzqJiZ2aFnkVDz1cboMNmb+xV+rFhRxjnmYYgU d8Ucxd3EaD/yMEqW1Dh/GLJ8oybtw/o40s3SRNADeOvxSn+ZIY5QISw3TedoJ8uFzuLQ Y38gAZlZFeB6jCXFXjpjr8OuIOxSzJokyelcMPJJjxq59VwvNLYAw2n95GISo4+LsP3Z MQbQ9iSzHWvxXz3zaZ9xg+uFnMyEXTQQU+ySjyEoJkZFum1a+8ohSIb0tK8vijAgjuAZ kX95WNtxuAYXJg+h7EGhqq57ELWa/Y97NaERB4cm+o4weZCTco4tufGSFSJJyP1iaupv FRvQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id l190-v6si6077300wmb.208.2018.08.09.06.01.32 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZI-0003Ko-1x; Thu, 09 Aug 2018 14:01:32 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 13/16] hw/dma/pl080: Provide device reset function Date: Thu, 9 Aug 2018 14:01:12 +0100 Message-Id: <20180809130115.28951-14-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> The PL080/PL081 model is missing a reset function; implement it. Signed-off-by: Peter Maydell --- hw/dma/pl080.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c index 8f9f3e08d9a..a7aacad74f0 100644 --- a/hw/dma/pl080.c +++ b/hw/dma/pl080.c @@ -348,6 +348,30 @@ static const MemoryRegionOps pl080_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +static void pl080_reset(DeviceState *dev) +{ + PL080State *s = PL080(dev); + int i; + + s->tc_int = 0; + s->tc_mask = 0; + s->err_int = 0; + s->err_mask = 0; + s->conf = 0; + s->sync = 0; + s->req_single = 0; + s->req_burst = 0; + s->running = 0; + + for (i = 0; i < s->nchannels; i++) { + s->chan[i].src = 0; + s->chan[i].dest = 0; + s->chan[i].lli = 0; + s->chan[i].ctrl = 0; + s->chan[i].conf = 0; + } +} + static void pl080_init(Object *obj) { SysBusDevice *sbd = SYS_BUS_DEVICE(obj); @@ -393,6 +417,7 @@ static void pl080_class_init(ObjectClass *oc, void *data) dc->vmsd = &vmstate_pl080; dc->realize = pl080_realize; dc->props = pl080_properties; + dc->reset = pl080_reset; } static const TypeInfo pl080_info = { From patchwork Thu Aug 9 13:01:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143855 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2066029ljj; Thu, 9 Aug 2018 06:01:33 -0700 (PDT) X-Google-Smtp-Source: AA+uWPyOnFL4kq3VL4xFpUP5HHHL3sE2m20YZihCGQ/SppCKNmZ7TiG6CMzp/3y8fnVdkaVz9ir5 X-Received: by 2002:a1c:be13:: with SMTP id o19-v6mr1480624wmf.1.1533819693435; Thu, 09 Aug 2018 06:01:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819693; cv=none; d=google.com; s=arc-20160816; b=luyqd9C6zB/q0XJPlZ0Fpc4RGlghRrwqx5QWmhiHB5+Z42Ls7PxMk+AgDbLaUv55Ts eBNwta5RPtrb2kEecZI0N2X9QEsbO3kV8JuQVj4G2kR+CneUxoCevCQnVevjabH0VQJM HHLH5dYtXELcGh8Cu1zzGRcDJ5c367FlBJ9esUAWVrjz/QFodl5oHW+KArC+snAQoFB/ hJIaOHd8haFRgM9bjcQzEMPVfzZTNSs3cd4dFNAKJf7QzNMlIHNz7lnbnqLk1v3JrwFA xMRQoWEcl6cXM7WWr1cjKQgp0wokkWWKuQJlO9cXAWpaok2hsBYL6UDu6Q4jXkDLG0qA PlxQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=o2lsAfQxR1xak9QI3ZMA5/nQDsh+ke/ih0MwMFezpFA=; b=Ai8Rxo3C+lDI2B768vNi/34IBu23EZmqPZraAIVcjcahhsc/RozgBjrJRzwDwoMhmE VhN8qtxslBA2/bwKRhwU5BqBrocxg8qB8EPNy1MIpgjwXCGAGn+piJz0YyxOW2aeftpq JWJrtLMlWszwSMI7YqQQ5RU0FL7irexf4C6sJ3M++8ToJwOC/eDkX+yMegJ/zpVQNvtG 6KPEo877u2MIcWDKpeGlaq5loz3buw1V3lifM00Q8WbQdYFBukGSdZlcZ3vD6CiA1HAp ZWrx+AkwC+gNEv3VANyC1PgCjz4eOBvjRlxcyxOqs7FASQg3UAFSSiL7J+49GbgXVzUl u7uw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id q21-v6si5829638wra.110.2018.08.09.06.01.33 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:33 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZI-0003Le-W1; Thu, 09 Aug 2018 14:01:32 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 14/16] hw/dma/pl080: Correct bug in register address decode logic Date: Thu, 9 Aug 2018 14:01:13 +0100 Message-Id: <20180809130115.28951-15-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> A bug in the handling of the register address decode logic for the PL08x meant that we were incorrectly treating accesses to the DMA channel registers (DMACCxSrcAddr, DMACCxDestaddr, DMACCxLLI, DMACCxControl, DMACCxConfiguration) as bad offsets. Fix this long-standing bug. Fixes: https://bugs.launchpad.net/qemu/+bug/1637974 Signed-off-by: Peter Maydell --- This has been around for a long time, identified by code inspection several years ago in the LP bug. Now I have some guest code that actually tries to use the PL08x I can test the fix... --- hw/dma/pl080.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c index a7aacad74f0..8f92550392b 100644 --- a/hw/dma/pl080.c +++ b/hw/dma/pl080.c @@ -229,7 +229,7 @@ static uint64_t pl080_read(void *opaque, hwaddr offset, i = (offset & 0xe0) >> 5; if (i >= s->nchannels) goto bad_offset; - switch (offset >> 2) { + switch ((offset >> 2) & 7) { case 0: /* SrcAddr */ return s->chan[i].src; case 1: /* DestAddr */ @@ -290,7 +290,7 @@ static void pl080_write(void *opaque, hwaddr offset, i = (offset & 0xe0) >> 5; if (i >= s->nchannels) goto bad_offset; - switch (offset >> 2) { + switch ((offset >> 2) & 7) { case 0: /* SrcAddr */ s->chan[i].src = value; break; @@ -308,6 +308,7 @@ static void pl080_write(void *opaque, hwaddr offset, pl080_run(s); break; } + return; } switch (offset >> 2) { case 2: /* IntTCClear */ From patchwork Thu Aug 9 13:01:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143856 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2066057ljj; Thu, 9 Aug 2018 06:01:34 -0700 (PDT) X-Google-Smtp-Source: AA+uWPyPZk3cDHkV/9bkxXO3f0R5li9EamGbjP6cZH8Zosw+MbzAO8FTBd8xK0tmn/G8Wr183Bf8 X-Received: by 2002:a1c:b80a:: with SMTP id i10-v6mr893156wmf.30.1533819694361; Thu, 09 Aug 2018 06:01:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819694; cv=none; d=google.com; s=arc-20160816; b=sN3M+dJQ2WaMbPZm1tuJmQTUJK9oPfx+FJv4J8r7QX5cY0pEeI+dmSUCoBwu0tyKgL 13myRAhCDuSNNSyiW98OpjiTI2lTC4jxD/MBvTfYZOMuA3W41boFNg92xR4R+Ah+ltSD FH1bifbAeTCw7X94LLH/TSX7S2rj0UxruMVpki4DYJudY8pMiD0I9G386BI1LeDWOW/o MD9SXliY1wlqDDJDVecQ8SBxkaLxBEKta7ei8U4TkASClyDYz692Dmpcqy/vji62m3SB +38JrkNKpV9AGNrDiygm2YkMZWZMETVQAmTmD+g+TqeFRmxAIr6Ov/Mqn3Zguhzhv945 AiTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=Yzyxy7Xpo00yGZboOw0i4+IUCwfO9/1H4A3BAfZwREE=; b=wsAPao7idd9rhjmogoZBWBLpyJnopWpgdg14EVwgbFji3GrRZfzw01dl4rTW59HnjV owqxJsYmI/gcbyOiWvoFpvNmIEcBzdI/5AviUCdZL4g3/q/Nsdc7VLu6vEqY7J7BQQVJ yaZWKh3BBOuAlK1haM1DZu5bvjAsA/1axFJEYxE8phiQ9cOiEJUgTOkvi/hxBFi7d9Ch JSo/8aN6NYuauo17f53mquQKtqLyO1vZvD0pYEhbmxg4Tpg8v4sR8IYkbXtV+O4DOYqM icEEixPbTxGCuoh8UuWVbr34l7rqAj5SbCHbRnzLs+ytIp6letwYOEHqC1ce1Bn62/5y Nkxw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id w128-v6si5689192wmg.105.2018.08.09.06.01.34 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZJ-0003Lt-SY; Thu, 09 Aug 2018 14:01:33 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 15/16] hw/dma/pl080: Remove hw_error() if DMA is enabled Date: Thu, 9 Aug 2018 14:01:14 +0100 Message-Id: <20180809130115.28951-16-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> The PL08x model currently will unconditionally call hw_error() if the DMA engine is enabled by the guest. This has been present since the PL080 model was edded in 2006, and is presumably either unintentional debug code left enabled, or a guard against untested DMA engine code being used. Remove the hw_error(), since we now have a guest which will actually try to use the DMA engine (the self-test binary for the AN505 MPS2 FPGA image). Signed-off-by: Peter Maydell --- hw/dma/pl080.c | 1 - 1 file changed, 1 deletion(-) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c index 8f92550392b..ef15d3e628d 100644 --- a/hw/dma/pl080.c +++ b/hw/dma/pl080.c @@ -110,7 +110,6 @@ static void pl080_run(PL080State *s) if ((s->conf & PL080_CONF_E) == 0) return; -hw_error("DMA active\n"); /* If we are already in the middle of a DMA operation then indicate that there may be new DMA requests and return immediately. */ if (s->running) { From patchwork Thu Aug 9 13:01:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 143857 Delivered-To: patches@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp2066084ljj; Thu, 9 Aug 2018 06:01:35 -0700 (PDT) X-Google-Smtp-Source: AA+uWPz9bkhYRJAjxNLozk5TWMNIcBzuTHvAwACvcPtKvwyCjFXGk4joiCvekvu8XBOfaO+IaphD X-Received: by 2002:adf:a634:: with SMTP id k49-v6mr1478206wrc.181.1533819695275; Thu, 09 Aug 2018 06:01:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533819695; cv=none; d=google.com; s=arc-20160816; b=p5Nvdlw41Yc6r3qFk0Qh9YQ46cCloGDuN/x0dcjmLywsiCxyLg2MylYG4j6fqYbCd9 oKumYKt8ohTfxJf5DM0fSXLt2k6EITg8zMR7eAErzuFmlKi6yQUQGR5p/Nifdiwy008l f+oq+Iea3k6Ymqh4G2dD5rAMWmntb4dNDflaJ5BfDFrpWyHS4HzXqoZkO4/7aGcotijK hg/XRg+mMaLhfqVxqoBd4JqQ6XEMiQjJJ2FjWepUxQwcD3+7BbbEPwn2UPFwDhBCpmqi kFXrd6koZJHdZlMywiXgFH1C+5bM09T9Bi4PZiihnmqVFyKDRqyBiYTZRP6/dz7/W6iY jifQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=bFG2wbnbPklJEMhvUvAdU7jC1qZyHSVU7O4rXXClIPI=; b=ABbvlKkmgj9wlBBjplvTT6cGibOciI0iaCVy+OlhELtVj72geRNps88S9Zg8KEw79l 1o4ptiVtDtxzNdlJYgv0QpM+H1EGHSyeoUD/GmL9y7/F+6IUzSZRX4C92Mf3zjJa4BSz LjIZndtMkjYT7f2/S4YMWKxclqFZt4zN3R7mCRyNmby2j+Z/9uht8KY7RljGZ2THDUsx 8dij3ncGydZifjAplpMtW+yiIHkcNlc7bMNbGTC4mXqD2+GgE9nb6PPFNfFekbM3SjkI VizJ1uQv2/s4/jwygmph66XpWFwbB6DYHSkPonYbf47kf6R4katFoayth+M00Ij0jpQe Q3Yw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id m17-v6si5173019wro.325.2018.08.09.06.01.35 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 Aug 2018 06:01:35 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fnkZK-0003MN-Og; Thu, 09 Aug 2018 14:01:34 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 16/16] hw/arm/mps2-tz: Create PL081s and MSCs Date: Thu, 9 Aug 2018 14:01:15 +0100 Message-Id: <20180809130115.28951-17-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180809130115.28951-1-peter.maydell@linaro.org> References: <20180809130115.28951-1-peter.maydell@linaro.org> 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 --- hw/arm/mps2-tz.c | 101 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 94 insertions(+), 7 deletions(-) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index 22180c56fb7..7d92bc5fe1c 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; @@ -273,6 +276,65 @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque, return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0); } +static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque, + const char *name, hwaddr size) +{ + PL080State *dma = opaque; + int i = dma - &mms->dma[0]; + SysBusDevice *s; + char *mscname = g_strdup_printf("%s-msc", name); + TZMSC *msc = &mms->msc[i]; + DeviceState *iotkitdev = 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. + */ + init_sysbus_child(OBJECT(mms), mscname, msc, sizeof(mms->msc[0]), + TYPE_TZ_MSC); + msc_downstream = 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 = sysbus_mmio_get_region(SYS_BUS_DEVICE(msc), 0); + + init_sysbus_child(OBJECT(mms), name, dma, sizeof(mms->dma[0]), 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 = 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 = MPS2TZ_MACHINE(machine); @@ -299,13 +361,14 @@ static void mps2tz_common_init(MachineState *machine) &error_fatal); /* 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_splitter), TYPE_SPLIT_IRQ); object_property_add_child(OBJECT(machine), "sec-resp-splitter", OBJECT(&mms->sec_resp_splitter), &error_abort); - 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); @@ -406,10 +469,10 @@ static void mps2tz_common_init(MachineState *machine) }, { .name = "ahb_ppcexp1", .ports = { - { "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 }, }, }, }; @@ -490,12 +553,32 @@ static void mps2tz_common_init(MachineState *machine) armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000); } +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 = extract32(address, 28, 4); + + *ns = !(region & 1); + *nsc = false; + /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */ + *exempt = (address & 0xeff00000) == 0xe0000000; + *iregion = region; +} + static void mps2tz_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc); mc->init = mps2tz_common_init; mc->max_cpus = 1; + iic->check = mps2_tz_idau_check; } static void mps2tz_an505_class_init(ObjectClass *oc, void *data) @@ -516,6 +599,10 @@ static const TypeInfo mps2tz_info = { .instance_size = sizeof(MPS2TZMachineState), .class_size = sizeof(MPS2TZMachineClass), .class_init = mps2tz_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_IDAU_INTERFACE }, + { } + }, }; static const TypeInfo mps2tz_an505_info = {