From patchwork Fri Mar 2 11:06: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: 880434 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6324grxz9s4w for ; Fri, 2 Mar 2018 22:07:42 +1100 (AEDT) Received: from localhost ([::1]:34059 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriXM-0002p7-KR for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:07:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43303) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWV-0002lx-UU for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWT-0004l1-JU for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:47 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46748) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWT-0004kH-9J for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:45 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWP-0001IV-SJ for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:41 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:02 +0000 Message-Id: <20180302110640.28004-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 01/39] xlnx-zynqmp-rtc: Initial commit X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Alistair Francis Initial commit of the ZynqMP RTC device. Signed-off-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Peter Maydell --- hw/timer/Makefile.objs | 1 + include/hw/timer/xlnx-zynqmp-rtc.h | 84 +++++++++++++++ hw/timer/xlnx-zynqmp-rtc.c | 214 +++++++++++++++++++++++++++++++++++++ 3 files changed, 299 insertions(+) create mode 100644 include/hw/timer/xlnx-zynqmp-rtc.h create mode 100644 hw/timer/xlnx-zynqmp-rtc.c diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index 8c19eac3b6..8b27a4b7ef 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -21,6 +21,7 @@ common-obj-$(CONFIG_IMX) += imx_epit.o common-obj-$(CONFIG_IMX) += imx_gpt.o common-obj-$(CONFIG_LM32) += lm32_timer.o common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o +common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp-rtc.o obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o diff --git a/include/hw/timer/xlnx-zynqmp-rtc.h b/include/hw/timer/xlnx-zynqmp-rtc.h new file mode 100644 index 0000000000..87649836cc --- /dev/null +++ b/include/hw/timer/xlnx-zynqmp-rtc.h @@ -0,0 +1,84 @@ +/* + * QEMU model of the Xilinx ZynqMP Real Time Clock (RTC). + * + * Copyright (c) 2017 Xilinx Inc. + * + * Written-by: Alistair Francis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "hw/register.h" + +#define TYPE_XLNX_ZYNQMP_RTC "xlnx-zynmp.rtc" + +#define XLNX_ZYNQMP_RTC(obj) \ + OBJECT_CHECK(XlnxZynqMPRTC, (obj), TYPE_XLNX_ZYNQMP_RTC) + +REG32(SET_TIME_WRITE, 0x0) +REG32(SET_TIME_READ, 0x4) +REG32(CALIB_WRITE, 0x8) + FIELD(CALIB_WRITE, FRACTION_EN, 20, 1) + FIELD(CALIB_WRITE, FRACTION_DATA, 16, 4) + FIELD(CALIB_WRITE, MAX_TICK, 0, 16) +REG32(CALIB_READ, 0xc) + FIELD(CALIB_READ, FRACTION_EN, 20, 1) + FIELD(CALIB_READ, FRACTION_DATA, 16, 4) + FIELD(CALIB_READ, MAX_TICK, 0, 16) +REG32(CURRENT_TIME, 0x10) +REG32(CURRENT_TICK, 0x14) + FIELD(CURRENT_TICK, VALUE, 0, 16) +REG32(ALARM, 0x18) +REG32(RTC_INT_STATUS, 0x20) + FIELD(RTC_INT_STATUS, ALARM, 1, 1) + FIELD(RTC_INT_STATUS, SECONDS, 0, 1) +REG32(RTC_INT_MASK, 0x24) + FIELD(RTC_INT_MASK, ALARM, 1, 1) + FIELD(RTC_INT_MASK, SECONDS, 0, 1) +REG32(RTC_INT_EN, 0x28) + FIELD(RTC_INT_EN, ALARM, 1, 1) + FIELD(RTC_INT_EN, SECONDS, 0, 1) +REG32(RTC_INT_DIS, 0x2c) + FIELD(RTC_INT_DIS, ALARM, 1, 1) + FIELD(RTC_INT_DIS, SECONDS, 0, 1) +REG32(ADDR_ERROR, 0x30) + FIELD(ADDR_ERROR, STATUS, 0, 1) +REG32(ADDR_ERROR_INT_MASK, 0x34) + FIELD(ADDR_ERROR_INT_MASK, MASK, 0, 1) +REG32(ADDR_ERROR_INT_EN, 0x38) + FIELD(ADDR_ERROR_INT_EN, MASK, 0, 1) +REG32(ADDR_ERROR_INT_DIS, 0x3c) + FIELD(ADDR_ERROR_INT_DIS, MASK, 0, 1) +REG32(CONTROL, 0x40) + FIELD(CONTROL, BATTERY_DISABLE, 31, 1) + FIELD(CONTROL, OSC_CNTRL, 24, 4) + FIELD(CONTROL, SLVERR_ENABLE, 0, 1) +REG32(SAFETY_CHK, 0x50) + +#define XLNX_ZYNQMP_RTC_R_MAX (R_SAFETY_CHK + 1) + +typedef struct XlnxZynqMPRTC { + SysBusDevice parent_obj; + MemoryRegion iomem; + qemu_irq irq_rtc_int; + qemu_irq irq_addr_error_int; + + uint32_t regs[XLNX_ZYNQMP_RTC_R_MAX]; + RegisterInfo regs_info[XLNX_ZYNQMP_RTC_R_MAX]; +} XlnxZynqMPRTC; diff --git a/hw/timer/xlnx-zynqmp-rtc.c b/hw/timer/xlnx-zynqmp-rtc.c new file mode 100644 index 0000000000..707f145027 --- /dev/null +++ b/hw/timer/xlnx-zynqmp-rtc.c @@ -0,0 +1,214 @@ +/* + * QEMU model of the Xilinx ZynqMP Real Time Clock (RTC). + * + * Copyright (c) 2017 Xilinx Inc. + * + * Written-by: Alistair Francis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "hw/sysbus.h" +#include "hw/register.h" +#include "qemu/bitops.h" +#include "qemu/log.h" +#include "hw/timer/xlnx-zynqmp-rtc.h" + +#ifndef XLNX_ZYNQMP_RTC_ERR_DEBUG +#define XLNX_ZYNQMP_RTC_ERR_DEBUG 0 +#endif + +static void rtc_int_update_irq(XlnxZynqMPRTC *s) +{ + bool pending = s->regs[R_RTC_INT_STATUS] & ~s->regs[R_RTC_INT_MASK]; + qemu_set_irq(s->irq_rtc_int, pending); +} + +static void addr_error_int_update_irq(XlnxZynqMPRTC *s) +{ + bool pending = s->regs[R_ADDR_ERROR] & ~s->regs[R_ADDR_ERROR_INT_MASK]; + qemu_set_irq(s->irq_addr_error_int, pending); +} + +static void rtc_int_status_postw(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + rtc_int_update_irq(s); +} + +static uint64_t rtc_int_en_prew(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + + s->regs[R_RTC_INT_MASK] &= (uint32_t) ~val64; + rtc_int_update_irq(s); + return 0; +} + +static uint64_t rtc_int_dis_prew(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + + s->regs[R_RTC_INT_MASK] |= (uint32_t) val64; + rtc_int_update_irq(s); + return 0; +} + +static void addr_error_postw(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + addr_error_int_update_irq(s); +} + +static uint64_t addr_error_int_en_prew(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + + s->regs[R_ADDR_ERROR_INT_MASK] &= (uint32_t) ~val64; + addr_error_int_update_irq(s); + return 0; +} + +static uint64_t addr_error_int_dis_prew(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + + s->regs[R_ADDR_ERROR_INT_MASK] |= (uint32_t) val64; + addr_error_int_update_irq(s); + return 0; +} + +static const RegisterAccessInfo rtc_regs_info[] = { + { .name = "SET_TIME_WRITE", .addr = A_SET_TIME_WRITE, + },{ .name = "SET_TIME_READ", .addr = A_SET_TIME_READ, + .ro = 0xffffffff, + },{ .name = "CALIB_WRITE", .addr = A_CALIB_WRITE, + },{ .name = "CALIB_READ", .addr = A_CALIB_READ, + .ro = 0x1fffff, + },{ .name = "CURRENT_TIME", .addr = A_CURRENT_TIME, + .ro = 0xffffffff, + },{ .name = "CURRENT_TICK", .addr = A_CURRENT_TICK, + .ro = 0xffff, + },{ .name = "ALARM", .addr = A_ALARM, + },{ .name = "RTC_INT_STATUS", .addr = A_RTC_INT_STATUS, + .w1c = 0x3, + .post_write = rtc_int_status_postw, + },{ .name = "RTC_INT_MASK", .addr = A_RTC_INT_MASK, + .reset = 0x3, + .ro = 0x3, + },{ .name = "RTC_INT_EN", .addr = A_RTC_INT_EN, + .pre_write = rtc_int_en_prew, + },{ .name = "RTC_INT_DIS", .addr = A_RTC_INT_DIS, + .pre_write = rtc_int_dis_prew, + },{ .name = "ADDR_ERROR", .addr = A_ADDR_ERROR, + .w1c = 0x1, + .post_write = addr_error_postw, + },{ .name = "ADDR_ERROR_INT_MASK", .addr = A_ADDR_ERROR_INT_MASK, + .reset = 0x1, + .ro = 0x1, + },{ .name = "ADDR_ERROR_INT_EN", .addr = A_ADDR_ERROR_INT_EN, + .pre_write = addr_error_int_en_prew, + },{ .name = "ADDR_ERROR_INT_DIS", .addr = A_ADDR_ERROR_INT_DIS, + .pre_write = addr_error_int_dis_prew, + },{ .name = "CONTROL", .addr = A_CONTROL, + .reset = 0x1000000, + .rsvd = 0x70fffffe, + },{ .name = "SAFETY_CHK", .addr = A_SAFETY_CHK, + } +}; + +static void rtc_reset(DeviceState *dev) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(dev); + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) { + register_reset(&s->regs_info[i]); + } + + rtc_int_update_irq(s); + addr_error_int_update_irq(s); +} + +static const MemoryRegionOps rtc_ops = { + .read = register_read_memory, + .write = register_write_memory, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + +static void rtc_init(Object *obj) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + RegisterInfoArray *reg_array; + + memory_region_init(&s->iomem, obj, TYPE_XLNX_ZYNQMP_RTC, + XLNX_ZYNQMP_RTC_R_MAX * 4); + reg_array = + register_init_block32(DEVICE(obj), rtc_regs_info, + ARRAY_SIZE(rtc_regs_info), + s->regs_info, s->regs, + &rtc_ops, + XLNX_ZYNQMP_RTC_ERR_DEBUG, + XLNX_ZYNQMP_RTC_R_MAX * 4); + memory_region_add_subregion(&s->iomem, + 0x0, + ®_array->mem); + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->irq_rtc_int); + sysbus_init_irq(sbd, &s->irq_addr_error_int); +} + +static const VMStateDescription vmstate_rtc = { + .name = TYPE_XLNX_ZYNQMP_RTC, + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPRTC, XLNX_ZYNQMP_RTC_R_MAX), + VMSTATE_END_OF_LIST(), + } +}; + +static void rtc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->reset = rtc_reset; + dc->vmsd = &vmstate_rtc; +} + +static const TypeInfo rtc_info = { + .name = TYPE_XLNX_ZYNQMP_RTC, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(XlnxZynqMPRTC), + .class_init = rtc_class_init, + .instance_init = rtc_init, +}; + +static void rtc_register_types(void) +{ + type_register_static(&rtc_info); +} + +type_init(rtc_register_types) From patchwork Fri Mar 2 11:06: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: 880436 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt66C1mk3z9s3m for ; Fri, 2 Mar 2018 22:10:27 +1100 (AEDT) Received: from localhost ([::1]:34067 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eria1-0005PI-3Y for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:10:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43255) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWT-0002kq-Qv for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWS-0004kV-D7 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:45 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46746) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWS-0004jE-40 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:44 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWQ-0001Ij-Hd for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:42 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:03 +0000 Message-Id: <20180302110640.28004-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 02/39] xlnx-zynqmp-rtc: Add basic time support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Alistair Francis Allow the guest to determine the time set from the QEMU command line. This includes adding a trace event to debug the new time. Signed-off-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- include/hw/timer/xlnx-zynqmp-rtc.h | 2 ++ hw/timer/xlnx-zynqmp-rtc.c | 58 ++++++++++++++++++++++++++++++++++++++ hw/timer/trace-events | 3 ++ 3 files changed, 63 insertions(+) diff --git a/include/hw/timer/xlnx-zynqmp-rtc.h b/include/hw/timer/xlnx-zynqmp-rtc.h index 87649836cc..5ba4d8bc4a 100644 --- a/include/hw/timer/xlnx-zynqmp-rtc.h +++ b/include/hw/timer/xlnx-zynqmp-rtc.h @@ -79,6 +79,8 @@ typedef struct XlnxZynqMPRTC { qemu_irq irq_rtc_int; qemu_irq irq_addr_error_int; + uint32_t tick_offset; + uint32_t regs[XLNX_ZYNQMP_RTC_R_MAX]; RegisterInfo regs_info[XLNX_ZYNQMP_RTC_R_MAX]; } XlnxZynqMPRTC; diff --git a/hw/timer/xlnx-zynqmp-rtc.c b/hw/timer/xlnx-zynqmp-rtc.c index 707f145027..c98dc3d94e 100644 --- a/hw/timer/xlnx-zynqmp-rtc.c +++ b/hw/timer/xlnx-zynqmp-rtc.c @@ -29,6 +29,10 @@ #include "hw/register.h" #include "qemu/bitops.h" #include "qemu/log.h" +#include "hw/ptimer.h" +#include "qemu/cutils.h" +#include "sysemu/sysemu.h" +#include "trace.h" #include "hw/timer/xlnx-zynqmp-rtc.h" #ifndef XLNX_ZYNQMP_RTC_ERR_DEBUG @@ -47,6 +51,19 @@ static void addr_error_int_update_irq(XlnxZynqMPRTC *s) qemu_set_irq(s->irq_addr_error_int, pending); } +static uint32_t rtc_get_count(XlnxZynqMPRTC *s) +{ + int64_t now = qemu_clock_get_ns(rtc_clock); + return s->tick_offset + now / NANOSECONDS_PER_SECOND; +} + +static uint64_t current_time_postr(RegisterInfo *reg, uint64_t val64) +{ + XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); + + return rtc_get_count(s); +} + static void rtc_int_status_postw(RegisterInfo *reg, uint64_t val64) { XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(reg->opaque); @@ -97,13 +114,17 @@ static uint64_t addr_error_int_dis_prew(RegisterInfo *reg, uint64_t val64) static const RegisterAccessInfo rtc_regs_info[] = { { .name = "SET_TIME_WRITE", .addr = A_SET_TIME_WRITE, + .unimp = MAKE_64BIT_MASK(0, 32), },{ .name = "SET_TIME_READ", .addr = A_SET_TIME_READ, .ro = 0xffffffff, + .post_read = current_time_postr, },{ .name = "CALIB_WRITE", .addr = A_CALIB_WRITE, + .unimp = MAKE_64BIT_MASK(0, 32), },{ .name = "CALIB_READ", .addr = A_CALIB_READ, .ro = 0x1fffff, },{ .name = "CURRENT_TIME", .addr = A_CURRENT_TIME, .ro = 0xffffffff, + .post_read = current_time_postr, },{ .name = "CURRENT_TICK", .addr = A_CURRENT_TICK, .ro = 0xffff, },{ .name = "ALARM", .addr = A_ALARM, @@ -162,6 +183,7 @@ static void rtc_init(Object *obj) XlnxZynqMPRTC *s = XLNX_ZYNQMP_RTC(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); RegisterInfoArray *reg_array; + struct tm current_tm; memory_region_init(&s->iomem, obj, TYPE_XLNX_ZYNQMP_RTC, XLNX_ZYNQMP_RTC_R_MAX * 4); @@ -178,14 +200,50 @@ static void rtc_init(Object *obj) sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq_rtc_int); sysbus_init_irq(sbd, &s->irq_addr_error_int); + + qemu_get_timedate(¤t_tm, 0); + s->tick_offset = mktimegm(¤t_tm) - + qemu_clock_get_ns(rtc_clock) / NANOSECONDS_PER_SECOND; + + trace_xlnx_zynqmp_rtc_gettime(current_tm.tm_year, current_tm.tm_mon, + current_tm.tm_mday, current_tm.tm_hour, + current_tm.tm_min, current_tm.tm_sec); +} + +static int rtc_pre_save(void *opaque) +{ + XlnxZynqMPRTC *s = opaque; + int64_t now = qemu_clock_get_ns(rtc_clock) / NANOSECONDS_PER_SECOND; + + /* Add the time at migration */ + s->tick_offset = s->tick_offset + now; + + return 0; +} + +static int rtc_post_load(void *opaque, int version_id) +{ + XlnxZynqMPRTC *s = opaque; + int64_t now = qemu_clock_get_ns(rtc_clock) / NANOSECONDS_PER_SECOND; + + /* Subtract the time after migration. This combined with the pre_save + * action results in us having subtracted the time that the guest was + * stopped to the offset. + */ + s->tick_offset = s->tick_offset - now; + + return 0; } static const VMStateDescription vmstate_rtc = { .name = TYPE_XLNX_ZYNQMP_RTC, .version_id = 1, .minimum_version_id = 1, + .pre_save = rtc_pre_save, + .post_load = rtc_post_load, .fields = (VMStateField[]) { VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPRTC, XLNX_ZYNQMP_RTC_R_MAX), + VMSTATE_UINT32(tick_offset, XlnxZynqMPRTC), VMSTATE_END_OF_LIST(), } }; diff --git a/hw/timer/trace-events b/hw/timer/trace-events index 640722b5d1..e6e042fddb 100644 --- a/hw/timer/trace-events +++ b/hw/timer/trace-events @@ -60,3 +60,6 @@ systick_write(uint64_t addr, uint32_t value, unsigned size) "systick write addr cmsdk_apb_timer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" cmsdk_apb_timer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" cmsdk_apb_timer_reset(void) "CMSDK APB timer: reset" + +# hw/timer/xlnx-zynqmp-rtc.c +xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, int sec) "Get time from host: %d-%d-%d %2d:%02d:%02d" From patchwork Fri Mar 2 11:06: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: 880431 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt62w6Mx7z9s5H for ; Fri, 2 Mar 2018 22:07:36 +1100 (AEDT) Received: from localhost ([::1]:34057 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriXG-0002m4-Sj for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:07:34 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43258) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWT-0002kr-RS for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWS-0004kc-JF for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:45 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46748) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWS-0004kH-Bs for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:44 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWR-0001Ix-7p for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:43 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:04 +0000 Message-Id: <20180302110640.28004-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 03/39] xlnx-zynqmp: Connect the RTC device X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Alistair Francis Signed-off-by: Alistair Francis Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Peter Maydell --- include/hw/arm/xlnx-zynqmp.h | 2 ++ hw/arm/xlnx-zynqmp.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 0a2b037c6b..3b613e364d 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -29,6 +29,7 @@ #include "hw/dma/xlnx_dpdma.h" #include "hw/display/xlnx_dp.h" #include "hw/intc/xlnx-zynqmp-ipi.h" +#include "hw/timer/xlnx-zynqmp-rtc.h" #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp" #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \ @@ -92,6 +93,7 @@ typedef struct XlnxZynqMPState { XlnxDPState dp; XlnxDPDMAState dpdma; XlnxZynqMPIPI ipi; + XlnxZynqMPRTC rtc; char *boot_cpu; ARMCPU *boot_cpu_ptr; diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 4b93a3abd2..69227fd4c9 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -53,6 +53,9 @@ #define IPI_ADDR 0xFF300000 #define IPI_IRQ 64 +#define RTC_ADDR 0xffa60000 +#define RTC_IRQ 26 + #define SDHCI_CAPABILITIES 0x280737ec6481 /* Datasheet: UG1085 (v1.7) */ static const uint64_t gem_addr[XLNX_ZYNQMP_NUM_GEMS] = { @@ -191,6 +194,9 @@ static void xlnx_zynqmp_init(Object *obj) object_initialize(&s->ipi, sizeof(s->ipi), TYPE_XLNX_ZYNQMP_IPI); qdev_set_parent_bus(DEVICE(&s->ipi), sysbus_get_default()); + + object_initialize(&s->rtc, sizeof(s->rtc), TYPE_XLNX_ZYNQMP_RTC); + qdev_set_parent_bus(DEVICE(&s->rtc), sysbus_get_default()); } static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) @@ -476,6 +482,14 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) } sysbus_mmio_map(SYS_BUS_DEVICE(&s->ipi), 0, IPI_ADDR); sysbus_connect_irq(SYS_BUS_DEVICE(&s->ipi), 0, gic_spi[IPI_IRQ]); + + object_property_set_bool(OBJECT(&s->rtc), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, RTC_ADDR); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, gic_spi[RTC_IRQ]); } static Property xlnx_zynqmp_props[] = { From patchwork Fri Mar 2 11:06:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880435 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6692hdfz9s3m for ; Fri, 2 Mar 2018 22:10:25 +1100 (AEDT) Received: from localhost ([::1]:34066 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriZz-0005M7-5h for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:10:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43261) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWU-0002kx-6C for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWT-0004kr-9d for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:46 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46746) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWT-0004jE-29 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:45 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWR-0001JE-Th for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:43 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:05 +0000 Message-Id: <20180302110640.28004-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 04/39] decodetree: Propagate return value from translate subroutines X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Allow the translate subroutines to return false for invalid insns. At present we can of course invoke an invalid insn exception from within the translate subroutine, but in the short term this consolidates code. In the long term it would allow the decodetree language to support overlapping patterns for ISA extensions. Signed-off-by: Richard Henderson Message-id: 20180227232618.2908-1-richard.henderson@linaro.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- scripts/decodetree.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/decodetree.py b/scripts/decodetree.py index 6a33f8f8dd..41301c84aa 100755 --- a/scripts/decodetree.py +++ b/scripts/decodetree.py @@ -461,7 +461,7 @@ class Pattern(General): global translate_prefix output('typedef ', self.base.base.struct_name(), ' arg_', self.name, ';\n') - output(translate_scope, 'void ', translate_prefix, '_', self.name, + output(translate_scope, 'bool ', translate_prefix, '_', self.name, '(DisasContext *ctx, arg_', self.name, ' *a, ', insntype, ' insn);\n') @@ -474,9 +474,8 @@ class Pattern(General): output(ind, self.base.extract_name(), '(&u.f_', arg, ', insn);\n') for n, f in self.fields.items(): output(ind, 'u.f_', arg, '.', n, ' = ', f.str_extract(), ';\n') - output(ind, translate_prefix, '_', self.name, + output(ind, 'return ', translate_prefix, '_', self.name, '(ctx, &u.f_', arg, ', insn);\n') - output(ind, 'return true;\n') # end Pattern From patchwork Fri Mar 2 11:06:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880442 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt69V5BXBz9s5H for ; Fri, 2 Mar 2018 22:13:18 +1100 (AEDT) Received: from localhost ([::1]:34085 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ericm-00082N-HP for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:13:16 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43281) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWV-0002l6-0r for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWT-0004lA-QD for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:46 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46750) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWT-0004kl-Ii for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:45 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWS-0001JU-JP for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:44 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:06 +0000 Message-Id: <20180302110640.28004-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 05/39] loader: Add new load_ramdisk_as() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add a function load_ramdisk_as() which behaves like the existing load_ramdisk() but allows the caller to specify the AddressSpace to use. This matches the pattern we have already for various other loader functions. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-2-peter.maydell@linaro.org --- include/hw/loader.h | 12 +++++++++++- hw/core/loader.c | 8 +++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/hw/loader.h b/include/hw/loader.h index 5edbe02b1c..2504cc2259 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -162,16 +162,26 @@ int load_uimage(const char *filename, hwaddr *ep, void *translate_opaque); /** - * load_ramdisk: + * load_ramdisk_as: * @filename: Path to the ramdisk image * @addr: Memory address to load the ramdisk to * @max_sz: Maximum allowed ramdisk size (for non-u-boot ramdisks) + * @as: The AddressSpace to load the ELF to. The value of address_space_memory + * is used if nothing is supplied here. * * Load a ramdisk image with U-Boot header to the specified memory * address. * * Returns the size of the loaded image on success, -1 otherwise. */ +int load_ramdisk_as(const char *filename, hwaddr addr, uint64_t max_sz, + AddressSpace *as); + +/** + * load_ramdisk: + * Same as load_ramdisk_as(), but doesn't allow the caller to specify + * an AddressSpace. + */ int load_ramdisk(const char *filename, hwaddr addr, uint64_t max_sz); ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, size_t srclen); diff --git a/hw/core/loader.c b/hw/core/loader.c index c08f130461..76b244c508 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -729,9 +729,15 @@ int load_uimage_as(const char *filename, hwaddr *ep, hwaddr *loadaddr, /* Load a ramdisk. */ int load_ramdisk(const char *filename, hwaddr addr, uint64_t max_sz) +{ + return load_ramdisk_as(filename, addr, max_sz, NULL); +} + +int load_ramdisk_as(const char *filename, hwaddr addr, uint64_t max_sz, + AddressSpace *as) { return load_uboot_image(filename, NULL, &addr, NULL, IH_TYPE_RAMDISK, - NULL, NULL, NULL); + NULL, NULL, as); } /* Load a gzip-compressed kernel to a dynamically allocated buffer. */ From patchwork Fri Mar 2 11:06: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: 880437 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt66L5Xgyz9s4w for ; Fri, 2 Mar 2018 22:10:34 +1100 (AEDT) Received: from localhost ([::1]:34069 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eria8-0005VR-Op for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:10:32 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43314) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWW-0002mm-NM for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWU-0004mC-Jq for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:48 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46748) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWU-0004kH-9A for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:46 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWT-0001Jm-8g for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:45 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:07 +0000 Message-Id: <20180302110640.28004-7-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 06/39] hw/arm/boot: Honour CPU's address space for image loads X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Instead of loading kernels, device trees, and the like to the system address space, use the CPU's address space. This is important if we're trying to load the file to memory or via an alias memory region that is provided by an SoC object and thus not mapped into the system address space. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-3-peter.maydell@linaro.org --- hw/arm/boot.c | 119 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 43 deletions(-) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 05108bc42f..6d0c92ab88 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -36,6 +36,25 @@ #define ARM64_TEXT_OFFSET_OFFSET 8 #define ARM64_MAGIC_OFFSET 56 +static AddressSpace *arm_boot_address_space(ARMCPU *cpu, + const struct arm_boot_info *info) +{ + /* Return the address space to use for bootloader reads and writes. + * We prefer the secure address space if the CPU has it and we're + * going to boot the guest into it. + */ + int asidx; + CPUState *cs = CPU(cpu); + + if (arm_feature(&cpu->env, ARM_FEATURE_EL3) && info->secure_boot) { + asidx = ARMASIdx_S; + } else { + asidx = ARMASIdx_NS; + } + + return cpu_get_address_space(cs, asidx); +} + typedef enum { FIXUP_NONE = 0, /* do nothing */ FIXUP_TERMINATOR, /* end of insns */ @@ -125,7 +144,8 @@ static const ARMInsnFixup smpboot[] = { }; static void write_bootloader(const char *name, hwaddr addr, - const ARMInsnFixup *insns, uint32_t *fixupcontext) + const ARMInsnFixup *insns, uint32_t *fixupcontext, + AddressSpace *as) { /* Fix up the specified bootloader fragment and write it into * guest memory using rom_add_blob_fixed(). fixupcontext is @@ -164,7 +184,7 @@ static void write_bootloader(const char *name, hwaddr addr, code[i] = tswap32(insn); } - rom_add_blob_fixed(name, code, len * sizeof(uint32_t), addr); + rom_add_blob_fixed_as(name, code, len * sizeof(uint32_t), addr, as); g_free(code); } @@ -173,6 +193,7 @@ static void default_write_secondary(ARMCPU *cpu, const struct arm_boot_info *info) { uint32_t fixupcontext[FIXUP_MAX]; + AddressSpace *as = arm_boot_address_space(cpu, info); fixupcontext[FIXUP_GIC_CPU_IF] = info->gic_cpu_if_addr; fixupcontext[FIXUP_BOOTREG] = info->smp_bootreg_addr; @@ -183,13 +204,14 @@ static void default_write_secondary(ARMCPU *cpu, } write_bootloader("smpboot", info->smp_loader_start, - smpboot, fixupcontext); + smpboot, fixupcontext, as); } void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu, const struct arm_boot_info *info, hwaddr mvbar_addr) { + AddressSpace *as = arm_boot_address_space(cpu, info); int n; uint32_t mvbar_blob[] = { /* mvbar_addr: secure monitor vectors @@ -227,22 +249,23 @@ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu, for (n = 0; n < ARRAY_SIZE(mvbar_blob); n++) { mvbar_blob[n] = tswap32(mvbar_blob[n]); } - rom_add_blob_fixed("board-setup-mvbar", mvbar_blob, sizeof(mvbar_blob), - mvbar_addr); + rom_add_blob_fixed_as("board-setup-mvbar", mvbar_blob, sizeof(mvbar_blob), + mvbar_addr, as); for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) { board_setup_blob[n] = tswap32(board_setup_blob[n]); } - rom_add_blob_fixed("board-setup", board_setup_blob, - sizeof(board_setup_blob), info->board_setup_addr); + rom_add_blob_fixed_as("board-setup", board_setup_blob, + sizeof(board_setup_blob), info->board_setup_addr, as); } static void default_reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info) { + AddressSpace *as = arm_boot_address_space(cpu, info); CPUState *cs = CPU(cpu); - address_space_stl_notdirty(&address_space_memory, info->smp_bootreg_addr, + address_space_stl_notdirty(as, info->smp_bootreg_addr, 0, MEMTXATTRS_UNSPECIFIED, NULL); cpu_set_pc(cs, info->smp_loader_start); } @@ -253,12 +276,12 @@ static inline bool have_dtb(const struct arm_boot_info *info) } #define WRITE_WORD(p, value) do { \ - address_space_stl_notdirty(&address_space_memory, p, value, \ + address_space_stl_notdirty(as, p, value, \ MEMTXATTRS_UNSPECIFIED, NULL); \ p += 4; \ } while (0) -static void set_kernel_args(const struct arm_boot_info *info) +static void set_kernel_args(const struct arm_boot_info *info, AddressSpace *as) { int initrd_size = info->initrd_size; hwaddr base = info->loader_start; @@ -289,8 +312,9 @@ static void set_kernel_args(const struct arm_boot_info *info) int cmdline_size; cmdline_size = strlen(info->kernel_cmdline); - cpu_physical_memory_write(p + 8, info->kernel_cmdline, - cmdline_size + 1); + address_space_write(as, p + 8, MEMTXATTRS_UNSPECIFIED, + (const uint8_t *)info->kernel_cmdline, + cmdline_size + 1); cmdline_size = (cmdline_size >> 2) + 1; WRITE_WORD(p, cmdline_size + 2); WRITE_WORD(p, 0x54410009); @@ -304,7 +328,8 @@ static void set_kernel_args(const struct arm_boot_info *info) atag_board_len = (info->atag_board(info, atag_board_buf) + 3) & ~3; WRITE_WORD(p, (atag_board_len + 8) >> 2); WRITE_WORD(p, 0x414f4d50); - cpu_physical_memory_write(p, atag_board_buf, atag_board_len); + address_space_write(as, p, MEMTXATTRS_UNSPECIFIED, + atag_board_buf, atag_board_len); p += atag_board_len; } /* ATAG_END */ @@ -312,7 +337,8 @@ static void set_kernel_args(const struct arm_boot_info *info) WRITE_WORD(p, 0); } -static void set_kernel_args_old(const struct arm_boot_info *info) +static void set_kernel_args_old(const struct arm_boot_info *info, + AddressSpace *as) { hwaddr p; const char *s; @@ -380,7 +406,8 @@ static void set_kernel_args_old(const struct arm_boot_info *info) } s = info->kernel_cmdline; if (s) { - cpu_physical_memory_write(p, s, strlen(s) + 1); + address_space_write(as, p, MEMTXATTRS_UNSPECIFIED, + (const uint8_t *)s, strlen(s) + 1); } else { WRITE_WORD(p, 0); } @@ -454,6 +481,7 @@ static void fdt_add_psci_node(void *fdt) * @addr: the address to load the image at * @binfo: struct describing the boot environment * @addr_limit: upper limit of the available memory area at @addr + * @as: address space to load image to * * Load a device tree supplied by the machine or by the user with the * '-dtb' command line option, and put it at offset @addr in target @@ -470,7 +498,7 @@ static void fdt_add_psci_node(void *fdt) * Note: Must not be called unless have_dtb(binfo) is true. */ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo, - hwaddr addr_limit) + hwaddr addr_limit, AddressSpace *as) { void *fdt = NULL; int size, rc; @@ -616,7 +644,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo, /* Put the DTB into the memory map as a ROM image: this will ensure * the DTB is copied again upon reset, even if addr points into RAM. */ - rom_add_blob_fixed("dtb", fdt, size, addr); + rom_add_blob_fixed_as("dtb", fdt, size, addr, as); g_free(fdt); @@ -703,13 +731,15 @@ static void do_cpu_reset(void *opaque) } if (cs == first_cpu) { + AddressSpace *as = arm_boot_address_space(cpu, info); + cpu_set_pc(cs, info->loader_start); if (!have_dtb(info)) { if (old_param) { - set_kernel_args_old(info); + set_kernel_args_old(info, as); } else { - set_kernel_args(info); + set_kernel_args(info, as); } } } else { @@ -784,7 +814,7 @@ static int do_arm_linux_init(Object *obj, void *opaque) static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, - int elf_machine) + int elf_machine, AddressSpace *as) { bool elf_is64; union { @@ -827,9 +857,9 @@ static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry, } } - ret = load_elf(info->kernel_filename, NULL, NULL, - pentry, lowaddr, highaddr, big_endian, elf_machine, - 1, data_swab); + ret = load_elf_as(info->kernel_filename, NULL, NULL, + pentry, lowaddr, highaddr, big_endian, elf_machine, + 1, data_swab, as); if (ret <= 0) { /* The header loaded but the image didn't */ exit(1); @@ -839,7 +869,7 @@ static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry, } static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base, - hwaddr *entry) + hwaddr *entry, AddressSpace *as) { hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR; uint8_t *buffer; @@ -874,7 +904,7 @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base, } *entry = mem_base + kernel_load_offset; - rom_add_blob_fixed(filename, buffer, size, *entry); + rom_add_blob_fixed_as(filename, buffer, size, *entry, as); g_free(buffer); @@ -896,6 +926,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data) ARMCPU *cpu = n->cpu; struct arm_boot_info *info = container_of(n, struct arm_boot_info, load_kernel_notifier); + AddressSpace *as = arm_boot_address_space(cpu, info); /* The board code is not supposed to set secure_board_setup unless * running its code in secure mode is actually possible, and KVM @@ -913,7 +944,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data) * the kernel is supposed to be loaded by the bootloader), copy the * DTB to the base of RAM for the bootloader to pick up. */ - if (load_dtb(info->loader_start, info, 0) < 0) { + if (load_dtb(info->loader_start, info, 0, as) < 0) { exit(1); } } @@ -988,7 +1019,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data) /* Assume that raw images are linux kernels, and ELF images are not. */ kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr, - &elf_high_addr, elf_machine); + &elf_high_addr, elf_machine, as); if (kernel_size > 0 && have_dtb(info)) { /* If there is still some room left at the base of RAM, try and put * the DTB there like we do for images loaded with -bios or -pflash. @@ -1001,25 +1032,26 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data) if (elf_low_addr < info->loader_start) { elf_low_addr = 0; } - if (load_dtb(info->loader_start, info, elf_low_addr) < 0) { + if (load_dtb(info->loader_start, info, elf_low_addr, as) < 0) { exit(1); } } } entry = elf_entry; if (kernel_size < 0) { - kernel_size = load_uimage(info->kernel_filename, &entry, NULL, - &is_linux, NULL, NULL); + kernel_size = load_uimage_as(info->kernel_filename, &entry, NULL, + &is_linux, NULL, NULL, as); } if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) { kernel_size = load_aarch64_image(info->kernel_filename, - info->loader_start, &entry); + info->loader_start, &entry, as); is_linux = 1; } else if (kernel_size < 0) { /* 32-bit ARM */ entry = info->loader_start + KERNEL_LOAD_ADDR; - kernel_size = load_image_targphys(info->kernel_filename, entry, - info->ram_size - KERNEL_LOAD_ADDR); + kernel_size = load_image_targphys_as(info->kernel_filename, entry, + info->ram_size - KERNEL_LOAD_ADDR, + as); is_linux = 1; } if (kernel_size < 0) { @@ -1031,15 +1063,16 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data) uint32_t fixupcontext[FIXUP_MAX]; if (info->initrd_filename) { - initrd_size = load_ramdisk(info->initrd_filename, - info->initrd_start, - info->ram_size - - info->initrd_start); + initrd_size = load_ramdisk_as(info->initrd_filename, + info->initrd_start, + info->ram_size - info->initrd_start, + as); if (initrd_size < 0) { - initrd_size = load_image_targphys(info->initrd_filename, - info->initrd_start, - info->ram_size - - info->initrd_start); + initrd_size = load_image_targphys_as(info->initrd_filename, + info->initrd_start, + info->ram_size - + info->initrd_start, + as); } if (initrd_size < 0) { error_report("could not load initrd '%s'", @@ -1080,7 +1113,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data) /* Place the DTB after the initrd in memory with alignment. */ dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size, align); - if (load_dtb(dtb_start, info, 0) < 0) { + if (load_dtb(dtb_start, info, 0, as) < 0) { exit(1); } fixupcontext[FIXUP_ARGPTR] = dtb_start; @@ -1096,7 +1129,7 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data) fixupcontext[FIXUP_ENTRYPOINT] = entry; write_bootloader("bootloader", info->loader_start, - primary_loader, fixupcontext); + primary_loader, fixupcontext, as); if (info->nb_cpus > 1) { info->write_secondary_boot(cpu, info); From patchwork Fri Mar 2 11:06: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: 880433 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6315s9dz9s3m for ; Fri, 2 Mar 2018 22:07:41 +1100 (AEDT) Received: from localhost ([::1]:34058 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriXL-0002oP-Pm for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:07:39 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43308) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWW-0002mG-7I for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWV-0004nN-6u for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:48 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46752) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWV-0004lz-0R for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:47 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWU-0001K3-1q for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:46 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:08 +0000 Message-Id: <20180302110640.28004-8-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 07/39] hw/arm/armv7m: Honour CPU's address space for image loads X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Instead of loading guest images to the system address space, use the CPU's address space. This is important if we're trying to load the file to memory or via an alias memory region that is provided by an SoC object and thus not mapped into the system address space. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-4-peter.maydell@linaro.org --- hw/arm/armv7m.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index 56770a7048..facc536b07 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -270,6 +270,9 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size) uint64_t entry; uint64_t lowaddr; int big_endian; + AddressSpace *as; + int asidx; + CPUState *cs = CPU(cpu); #ifdef TARGET_WORDS_BIGENDIAN big_endian = 1; @@ -282,11 +285,19 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size) exit(1); } + if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) { + asidx = ARMASIdx_S; + } else { + asidx = ARMASIdx_NS; + } + as = cpu_get_address_space(cs, asidx); + if (kernel_filename) { - image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr, - NULL, big_endian, EM_ARM, 1, 0); + image_size = load_elf_as(kernel_filename, NULL, NULL, &entry, &lowaddr, + NULL, big_endian, EM_ARM, 1, 0, as); if (image_size < 0) { - image_size = load_image_targphys(kernel_filename, 0, mem_size); + image_size = load_image_targphys_as(kernel_filename, 0, + mem_size, as); lowaddr = 0; } if (image_size < 0) { From patchwork Fri Mar 2 11:06:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880447 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6Dl151lz9s5H for ; Fri, 2 Mar 2018 22:16:07 +1100 (AEDT) Received: from localhost ([::1]:34106 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erifU-0002Ms-Qm for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:16:04 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43331) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWX-0002nf-ND for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWW-0004om-6F for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:49 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46752) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWV-0004lz-Tf for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:48 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWU-0001KH-Qm for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:46 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:09 +0000 Message-Id: <20180302110640.28004-9-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 08/39] target/arm: Define an IDAU interface X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" In v8M, the Implementation Defined Attribution Unit (IDAU) is a small piece of hardware typically implemented in the SoC which provides board or SoC specific security attribution information for each address that the CPU performs MPU/SAU checks on. For QEMU, we model this with a QOM interface which is implemented by the board or SoC object and connected to the CPU using a link property. This commit defines the new interface class, adds the link property to the CPU object, and makes the SAU checking code call the IDAU interface if one is present. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-5-peter.maydell@linaro.org --- target/arm/cpu.h | 3 +++ target/arm/idau.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++ target/arm/cpu.c | 15 +++++++++++++ target/arm/helper.c | 28 +++++++++++++++++++++--- 4 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 target/arm/idau.h diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 2b9740878b..4710a43110 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -694,6 +694,9 @@ struct ARMCPU { /* MemoryRegion to use for secure physical accesses */ MemoryRegion *secure_memory; + /* For v8M, pointer to the IDAU interface provided by board/SoC */ + Object *idau; + /* 'compatible' string for this CPU for Linux device trees */ const char *dtb_compatible; diff --git a/target/arm/idau.h b/target/arm/idau.h new file mode 100644 index 0000000000..cac27b95fa --- /dev/null +++ b/target/arm/idau.h @@ -0,0 +1,61 @@ +/* + * QEMU ARM CPU -- interface for the Arm v8M IDAU + * + * Copyright (c) 2018 Linaro Ltd + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see + * + * + * In the v8M architecture, the IDAU is a small piece of hardware + * typically implemented in the SoC which provides board or SoC + * specific security attribution information for each address that + * the CPU performs MPU/SAU checks on. For QEMU, we model this with a + * QOM interface which is implemented by the board or SoC object and + * connected to the CPU using a link property. + */ + +#ifndef TARGET_ARM_IDAU_H +#define TARGET_ARM_IDAU_H + +#include "qom/object.h" + +#define TYPE_IDAU_INTERFACE "idau-interface" +#define IDAU_INTERFACE(obj) \ + INTERFACE_CHECK(IDAUInterface, (obj), TYPE_IDAU_INTERFACE) +#define IDAU_INTERFACE_CLASS(class) \ + OBJECT_CLASS_CHECK(IDAUInterfaceClass, (class), TYPE_IDAU_INTERFACE) +#define IDAU_INTERFACE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(IDAUInterfaceClass, (obj), TYPE_IDAU_INTERFACE) + +typedef struct IDAUInterface { + Object parent; +} IDAUInterface; + +#define IREGION_NOTVALID -1 + +typedef struct IDAUInterfaceClass { + InterfaceClass parent; + + /* Check the specified address and return the IDAU security information + * for it by filling in iregion, exempt, ns and nsc: + * iregion: IDAU region number, or IREGION_NOTVALID if not valid + * exempt: true if address is exempt from security attribution + * ns: true if the address is NonSecure + * nsc: true if the address is NonSecure-callable + */ + void (*check)(IDAUInterface *ii, uint32_t address, int *iregion, + bool *exempt, bool *ns, bool *nsc); +} IDAUInterfaceClass; + +#endif diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 1b3ae62db6..291ff0b1db 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "target/arm/idau.h" #include "qemu/error-report.h" #include "qapi/error.h" #include "cpu.h" @@ -688,6 +689,13 @@ static void arm_cpu_post_init(Object *obj) } } + if (arm_feature(&cpu->env, ARM_FEATURE_M_SECURITY)) { + object_property_add_link(obj, "idau", TYPE_IDAU_INTERFACE, &cpu->idau, + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_UNREF_ON_RELEASE, + &error_abort); + } + qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property, &error_abort); } @@ -1821,11 +1829,18 @@ static const TypeInfo arm_cpu_type_info = { .class_init = arm_cpu_class_init, }; +static const TypeInfo idau_interface_type_info = { + .name = TYPE_IDAU_INTERFACE, + .parent = TYPE_INTERFACE, + .class_size = sizeof(IDAUInterfaceClass), +}; + static void arm_cpu_register_types(void) { const ARMCPUInfo *info = arm_cpus; type_register_static(&arm_cpu_type_info); + type_register_static(&idau_interface_type_info); while (info->name) { cpu_register(info); diff --git a/target/arm/helper.c b/target/arm/helper.c index c82f63d440..09893e3f72 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -1,4 +1,5 @@ #include "qemu/osdep.h" +#include "target/arm/idau.h" #include "trace.h" #include "cpu.h" #include "internals.h" @@ -9741,19 +9742,32 @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address, */ ARMCPU *cpu = arm_env_get_cpu(env); int r; + bool idau_exempt = false, idau_ns = true, idau_nsc = true; + int idau_region = IREGION_NOTVALID; - /* TODO: implement IDAU */ + if (cpu->idau) { + IDAUInterfaceClass *iic = IDAU_INTERFACE_GET_CLASS(cpu->idau); + IDAUInterface *ii = IDAU_INTERFACE(cpu->idau); + + iic->check(ii, address, &idau_region, &idau_exempt, &idau_ns, + &idau_nsc); + } if (access_type == MMU_INST_FETCH && extract32(address, 28, 4) == 0xf) { /* 0xf0000000..0xffffffff is always S for insn fetches */ return; } - if (v8m_is_sau_exempt(env, address, access_type)) { + if (idau_exempt || v8m_is_sau_exempt(env, address, access_type)) { sattrs->ns = !regime_is_secure(env, mmu_idx); return; } + if (idau_region != IREGION_NOTVALID) { + sattrs->irvalid = true; + sattrs->iregion = idau_region; + } + switch (env->sau.ctrl & 3) { case 0: /* SAU.ENABLE == 0, SAU.ALLNS == 0 */ break; @@ -9790,7 +9804,15 @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address, } } - /* TODO when we support the IDAU then it may override the result here */ + /* The IDAU will override the SAU lookup results if it specifies + * higher security than the SAU does. + */ + if (!idau_ns) { + if (sattrs->ns || (!idau_nsc && sattrs->nsc)) { + sattrs->ns = false; + sattrs->nsc = idau_nsc; + } + } break; } } From patchwork Fri Mar 2 11:06:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880443 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt69f6hDyz9s3m for ; Fri, 2 Mar 2018 22:13:26 +1100 (AEDT) Received: from localhost ([::1]:34087 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ericr-000880-Va for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:13:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43334) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWX-0002np-Tp for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWW-0004pz-VV for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:49 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46754) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWW-0004oB-NM for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:48 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWV-0001KX-G1 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:47 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:10 +0000 Message-Id: <20180302110640.28004-10-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 09/39] armv7m: Forward idau property to CPU object X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Create an "idau" property on the armv7m container object which we can forward to the CPU object. Annoyingly, we can't use object_property_add_alias() because the CPU object we want to forward to doesn't exist until the armv7m container is realized. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-6-peter.maydell@linaro.org --- include/hw/arm/armv7m.h | 3 +++ hw/arm/armv7m.c | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h index 35ab757264..5c3f406ccc 100644 --- a/include/hw/arm/armv7m.h +++ b/include/hw/arm/armv7m.h @@ -12,6 +12,7 @@ #include "hw/sysbus.h" #include "hw/intc/armv7m_nvic.h" +#include "target/arm/idau.h" #define TYPE_BITBAND "ARM,bitband-memory" #define BITBAND(obj) OBJECT_CHECK(BitBandState, (obj), TYPE_BITBAND) @@ -40,6 +41,7 @@ typedef struct { * + Property "memory": MemoryRegion defining the physical address space * that CPU accesses see. (The NVIC, bitbanding and other CPU-internal * devices will be automatically layered on top of this view.) + * + Property "idau": IDAU interface (forwarded to CPU object) */ typedef struct ARMv7MState { /*< private >*/ @@ -58,6 +60,7 @@ typedef struct ARMv7MState { char *cpu_type; /* MemoryRegion the board provides to us (with its devices, RAM, etc) */ MemoryRegion *board_memory; + Object *idau; } ARMv7MState; #endif diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index facc536b07..9f38d3b254 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -19,6 +19,7 @@ #include "sysemu/qtest.h" #include "qemu/error-report.h" #include "exec/address-spaces.h" +#include "target/arm/idau.h" /* Bitbanded IO. Each word corresponds to a single bit. */ @@ -162,6 +163,13 @@ static void armv7m_realize(DeviceState *dev, Error **errp) object_property_set_link(OBJECT(s->cpu), OBJECT(&s->container), "memory", &error_abort); + if (object_property_find(OBJECT(s->cpu), "idau", NULL)) { + object_property_set_link(OBJECT(s->cpu), s->idau, "idau", &err); + if (err != NULL) { + error_propagate(errp, err); + return; + } + } object_property_set_bool(OBJECT(s->cpu), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); @@ -217,6 +225,7 @@ static Property armv7m_properties[] = { DEFINE_PROP_STRING("cpu-type", ARMv7MState, cpu_type), DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *), DEFINE_PROP_END_OF_LIST(), }; From patchwork Fri Mar 2 11:06:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880445 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6Db61zfz9s3m for ; Fri, 2 Mar 2018 22:15:59 +1100 (AEDT) Received: from localhost ([::1]:34103 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erifN-0002Hq-R8 for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:15:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43357) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWY-0002on-Ur for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWX-0004rB-SY for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:50 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46754) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWX-0004oB-Kx for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:49 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWW-0001Km-CV for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:48 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:11 +0000 Message-Id: <20180302110640.28004-11-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 10/39] target/arm: Define init-svtor property for the reset secure VTOR value X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The Cortex-M33 allows the system to specify the reset value of the secure Vector Table Offset Register (VTOR) by asserting config signals. In particular, guest images for the MPS2 AN505 board rely on the MPS2's initial VTOR being correct for that board. Implement a QEMU property so board and SoC code can set the reset value to the correct value. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-7-peter.maydell@linaro.org --- target/arm/cpu.h | 3 +++ target/arm/cpu.c | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 4710a43110..72b5668377 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -731,6 +731,9 @@ struct ARMCPU { */ uint32_t psci_conduit; + /* For v8M, initial value of the Secure VTOR */ + uint32_t init_svtor; + /* [QEMU_]KVM_ARM_TARGET_* constant for this CPU, or * QEMU_KVM_ARM_TARGET_NONE if the kernel doesn't support this CPU type. */ diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 291ff0b1db..27d9e90308 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -187,6 +187,7 @@ static void arm_cpu_reset(CPUState *s) uint32_t initial_msp; /* Loaded from 0x0 */ uint32_t initial_pc; /* Loaded from 0x4 */ uint8_t *rom; + uint32_t vecbase; if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { env->v7m.secure = true; @@ -214,8 +215,11 @@ static void arm_cpu_reset(CPUState *s) /* Unlike A/R profile, M profile defines the reset LR value */ env->regs[14] = 0xffffffff; - /* Load the initial SP and PC from the vector table at address 0 */ - rom = rom_ptr(0); + env->v7m.vecbase[M_REG_S] = cpu->init_svtor & 0xffffff80; + + /* Load the initial SP and PC from offset 0 and 4 in the vector table */ + vecbase = env->v7m.vecbase[env->v7m.secure]; + rom = rom_ptr(vecbase); if (rom) { /* Address zero is covered by ROM which hasn't yet been * copied into physical memory. @@ -228,8 +232,8 @@ static void arm_cpu_reset(CPUState *s) * it got copied into memory. In the latter case, rom_ptr * will return a NULL pointer and we should use ldl_phys instead. */ - initial_msp = ldl_phys(s->as, 0); - initial_pc = ldl_phys(s->as, 4); + initial_msp = ldl_phys(s->as, vecbase); + initial_pc = ldl_phys(s->as, vecbase + 4); } env->regs[13] = initial_msp & 0xFFFFFFFC; @@ -624,6 +628,10 @@ static Property arm_cpu_pmsav7_dregion_property = pmsav7_dregion, qdev_prop_uint32, uint32_t); +/* M profile: initial value of the Secure VTOR */ +static Property arm_cpu_initsvtor_property = + DEFINE_PROP_UINT32("init-svtor", ARMCPU, init_svtor, 0); + static void arm_cpu_post_init(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); @@ -694,6 +702,8 @@ static void arm_cpu_post_init(Object *obj) qdev_prop_allow_set_link_before_realize, OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); + qdev_property_add_static(DEVICE(obj), &arm_cpu_initsvtor_property, + &error_abort); } qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property, From patchwork Fri Mar 2 11:06:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880450 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6J42VGcz9s3m for ; Fri, 2 Mar 2018 22:18:59 +1100 (AEDT) Received: from localhost ([::1]:34115 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriiG-0004lH-H1 for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:18:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43360) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWZ-0002p1-3x for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWY-0004rp-6u for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:51 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46756) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWY-0004qW-0C for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:50 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWX-0001L2-2a for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:49 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:12 +0000 Message-Id: <20180302110640.28004-12-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 11/39] armv7m: Forward init-svtor property to CPU object X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Create an "init-svtor" property on the armv7m container object which we can forward to the CPU object. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-8-peter.maydell@linaro.org --- include/hw/arm/armv7m.h | 2 ++ hw/arm/armv7m.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h index 5c3f406ccc..78308d1484 100644 --- a/include/hw/arm/armv7m.h +++ b/include/hw/arm/armv7m.h @@ -42,6 +42,7 @@ typedef struct { * that CPU accesses see. (The NVIC, bitbanding and other CPU-internal * devices will be automatically layered on top of this view.) * + Property "idau": IDAU interface (forwarded to CPU object) + * + Property "init-svtor": secure VTOR reset value (forwarded to CPU object) */ typedef struct ARMv7MState { /*< private >*/ @@ -61,6 +62,7 @@ typedef struct ARMv7MState { /* MemoryRegion the board provides to us (with its devices, RAM, etc) */ MemoryRegion *board_memory; Object *idau; + uint32_t init_svtor; } ARMv7MState; #endif diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index 9f38d3b254..f123cc7d3d 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -170,6 +170,14 @@ static void armv7m_realize(DeviceState *dev, Error **errp) return; } } + if (object_property_find(OBJECT(s->cpu), "init-svtor", NULL)) { + object_property_set_uint(OBJECT(s->cpu), s->init_svtor, + "init-svtor", &err); + if (err != NULL) { + error_propagate(errp, err); + return; + } + } object_property_set_bool(OBJECT(s->cpu), true, "realized", &err); if (err != NULL) { error_propagate(errp, err); @@ -226,6 +234,7 @@ static Property armv7m_properties[] = { DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGION, MemoryRegion *), DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *), + DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0), DEFINE_PROP_END_OF_LIST(), }; From patchwork Fri Mar 2 11:06:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880438 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt66r21fXz9s4w for ; Fri, 2 Mar 2018 22:11:00 +1100 (AEDT) Received: from localhost ([::1]:34077 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriaY-00065N-8Z for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:10:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43381) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWa-0002sB-5N for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWZ-0004sc-40 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:52 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46756) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWY-0004qW-Sv for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:51 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWX-0001LJ-Oi for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:49 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:13 +0000 Message-Id: <20180302110640.28004-13-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 12/39] target/arm: Add Cortex-M33 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add a Cortex-M33 definition. The M33 is an M profile CPU which implements the ARM v8M architecture, including the M profile Security Extension. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-9-peter.maydell@linaro.org --- target/arm/cpu.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 27d9e90308..e08b1e7943 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1206,6 +1206,35 @@ static void cortex_m4_initfn(Object *obj) cpu->id_isar5 = 0x00000000; } +static void cortex_m33_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + set_feature(&cpu->env, ARM_FEATURE_V8); + set_feature(&cpu->env, ARM_FEATURE_M); + set_feature(&cpu->env, ARM_FEATURE_M_SECURITY); + set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP); + cpu->midr = 0x410fd213; /* r0p3 */ + cpu->pmsav7_dregion = 16; + cpu->sau_sregion = 8; + cpu->id_pfr0 = 0x00000030; + cpu->id_pfr1 = 0x00000210; + cpu->id_dfr0 = 0x00200000; + cpu->id_afr0 = 0x00000000; + cpu->id_mmfr0 = 0x00101F40; + cpu->id_mmfr1 = 0x00000000; + cpu->id_mmfr2 = 0x01000000; + cpu->id_mmfr3 = 0x00000000; + cpu->id_isar0 = 0x01101110; + cpu->id_isar1 = 0x02212000; + cpu->id_isar2 = 0x20232232; + cpu->id_isar3 = 0x01111131; + cpu->id_isar4 = 0x01310132; + cpu->id_isar5 = 0x00000000; + cpu->clidr = 0x00000000; + cpu->ctr = 0x8000c000; +} + static void arm_v7m_class_init(ObjectClass *oc, void *data) { CPUClass *cc = CPU_CLASS(oc); @@ -1697,6 +1726,8 @@ static const ARMCPUInfo arm_cpus[] = { .class_init = arm_v7m_class_init }, { .name = "cortex-m4", .initfn = cortex_m4_initfn, .class_init = arm_v7m_class_init }, + { .name = "cortex-m33", .initfn = cortex_m33_initfn, + .class_init = arm_v7m_class_init }, { .name = "cortex-r5", .initfn = cortex_r5_initfn }, { .name = "cortex-a7", .initfn = cortex_a7_initfn }, { .name = "cortex-a8", .initfn = cortex_a8_initfn }, From patchwork Fri Mar 2 11:06: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: 880454 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6MX53gwz9s3m for ; Fri, 2 Mar 2018 22:22:00 +1100 (AEDT) Received: from localhost ([::1]:34137 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erilC-0007LC-Of for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:21:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43384) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWa-0002si-Dk for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWZ-0004tD-II for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:52 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46758) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWZ-0004sK-AP for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:51 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWY-0001LZ-EB for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:50 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:14 +0000 Message-Id: <20180302110640.28004-14-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 13/39] hw/misc/unimp: Move struct to header file X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Move the definition of the struct for the unimplemented-device from unimp.c to unimp.h, so that users can embed the struct in their own device structs if they prefer. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-10-peter.maydell@linaro.org --- include/hw/misc/unimp.h | 10 ++++++++++ hw/misc/unimp.c | 10 ---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/hw/misc/unimp.h b/include/hw/misc/unimp.h index 52e068ec3e..2a291ca42d 100644 --- a/include/hw/misc/unimp.h +++ b/include/hw/misc/unimp.h @@ -12,6 +12,16 @@ #define TYPE_UNIMPLEMENTED_DEVICE "unimplemented-device" +#define UNIMPLEMENTED_DEVICE(obj) \ + OBJECT_CHECK(UnimplementedDeviceState, (obj), TYPE_UNIMPLEMENTED_DEVICE) + +typedef struct { + SysBusDevice parent_obj; + MemoryRegion iomem; + char *name; + uint64_t size; +} UnimplementedDeviceState; + /** * create_unimplemented_device: create and map a dummy device * @name: name of the device for debug logging diff --git a/hw/misc/unimp.c b/hw/misc/unimp.c index bcbb585888..1c0ba2f0a7 100644 --- a/hw/misc/unimp.c +++ b/hw/misc/unimp.c @@ -18,16 +18,6 @@ #include "qemu/log.h" #include "qapi/error.h" -#define UNIMPLEMENTED_DEVICE(obj) \ - OBJECT_CHECK(UnimplementedDeviceState, (obj), TYPE_UNIMPLEMENTED_DEVICE) - -typedef struct { - SysBusDevice parent_obj; - MemoryRegion iomem; - char *name; - uint64_t size; -} UnimplementedDeviceState; - static uint64_t unimp_read(void *opaque, hwaddr offset, unsigned size) { UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque); From patchwork Fri Mar 2 11:06: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: 880448 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6FH6CJKz9s3m for ; Fri, 2 Mar 2018 22:16:35 +1100 (AEDT) Received: from localhost ([::1]:34108 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erifx-0002l8-RO for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:16:33 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43402) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWb-0002u1-8C for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWa-0004tx-F5 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:53 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46758) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWa-0004sK-84 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:52 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWZ-0001Lo-4R for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:51 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:15 +0000 Message-Id: <20180302110640.28004-15-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 14/39] include/hw/or-irq.h: Add missing include guard X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The or-irq.h header file is missing the customary guard against multiple inclusion, which means compilation fails if it gets included twice. Fix the omission. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-11-peter.maydell@linaro.org --- include/hw/or-irq.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/hw/or-irq.h b/include/hw/or-irq.h index fd900fcf19..3f6fc1b58a 100644 --- a/include/hw/or-irq.h +++ b/include/hw/or-irq.h @@ -22,6 +22,9 @@ * THE SOFTWARE. */ +#ifndef HW_OR_IRQ_H +#define HW_OR_IRQ_H + #include "hw/irq.h" #include "hw/sysbus.h" #include "qom/object.h" @@ -41,3 +44,5 @@ struct OrIRQState { bool levels[MAX_OR_LINES]; uint16_t num_lines; }; + +#endif From patchwork Fri Mar 2 11:06:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880444 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6B56bFkz9s3m for ; Fri, 2 Mar 2018 22:13:49 +1100 (AEDT) Received: from localhost ([::1]:34089 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eridI-0008Vw-0M for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:13:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43412) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWb-0002us-VY for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWa-0004u8-VO for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:53 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46760) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWa-0004tj-N9 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:52 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWZ-0001M4-Pb for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:51 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:16 +0000 Message-Id: <20180302110640.28004-16-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 15/39] qdev: Add new qdev_init_gpio_in_named_with_opaque() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The function qdev_init_gpio_in_named() passes the DeviceState pointer as the opaque data pointor for the irq handler function. Usually this is what you want, but in some cases it would be helpful to use some other data pointer. Add a new function qdev_init_gpio_in_named_with_opaque() which allows the caller to specify the data pointer they want. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-12-peter.maydell@linaro.org --- include/hw/qdev-core.h | 30 ++++++++++++++++++++++++++++-- hw/core/qdev.c | 8 +++++--- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index fc9d617a76..9453588160 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -311,10 +311,36 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name); /* GPIO inputs also double as IRQ sinks. */ void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); -void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler, - const char *name, int n); void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, const char *name, int n); +/** + * qdev_init_gpio_in_named_with_opaque: create an array of input GPIO lines + * for the specified device + * + * @dev: Device to create input GPIOs for + * @handler: Function to call when GPIO line value is set + * @opaque: Opaque data pointer to pass to @handler + * @name: Name of the GPIO input (must be unique for this device) + * @n: Number of GPIO lines in this input set + */ +void qdev_init_gpio_in_named_with_opaque(DeviceState *dev, + qemu_irq_handler handler, + void *opaque, + const char *name, int n); + +/** + * qdev_init_gpio_in_named: create an array of input GPIO lines + * for the specified device + * + * Like qdev_init_gpio_in_named_with_opaque(), but the opaque pointer + * passed to the handler is @dev (which is the most commonly desired behaviour). + */ +static inline void qdev_init_gpio_in_named(DeviceState *dev, + qemu_irq_handler handler, + const char *name, int n) +{ + qdev_init_gpio_in_named_with_opaque(dev, handler, dev, name, n); +} void qdev_pass_gpios(DeviceState *dev, DeviceState *container, const char *name); diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 7ed1f431f0..f3754ee606 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -385,15 +385,17 @@ static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev, return ngl; } -void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler, - const char *name, int n) +void qdev_init_gpio_in_named_with_opaque(DeviceState *dev, + qemu_irq_handler handler, + void *opaque, + const char *name, int n) { int i; NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name); assert(gpio_list->num_out == 0 || !name); gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler, - dev, n); + opaque, n); if (!name) { name = "unnamed-gpio-in"; From patchwork Fri Mar 2 11:06:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880462 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6SY1zJBz9s4w for ; Fri, 2 Mar 2018 22:26:21 +1100 (AEDT) Received: from localhost ([::1]:34163 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eripP-0002mU-Al for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:26:19 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43482) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWh-00031j-Vw for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWb-0004uQ-U2 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:59 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46760) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWb-0004tj-Km for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:53 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWa-0001MJ-Eu for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:52 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:17 +0000 Message-Id: <20180302110640.28004-17-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 16/39] hw/core/split-irq: Device that splits IRQ lines X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" In some board or SoC models it is necessary to split a qemu_irq line so that one input can feed multiple outputs. We currently have qemu_irq_split() for this, but that has several deficiencies: * it can only handle splitting a line into two * it unavoidably leaks memory, so it can't be used in a device that can be deleted Implement a qdev device that encapsulates splitting of IRQs, with a configurable number of outputs. (This is in some ways the inverse of the TYPE_OR_IRQ device.) Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-13-peter.maydell@linaro.org --- hw/core/Makefile.objs | 1 + include/hw/core/split-irq.h | 57 +++++++++++++++++++++++++++++ include/hw/irq.h | 4 +- hw/core/split-irq.c | 89 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 include/hw/core/split-irq.h create mode 100644 hw/core/split-irq.c diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs index 1240728c87..eb88ca979e 100644 --- a/hw/core/Makefile.objs +++ b/hw/core/Makefile.objs @@ -18,6 +18,7 @@ common-obj-$(CONFIG_FITLOADER) += loader-fit.o common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o common-obj-$(CONFIG_SOFTMMU) += register.o common-obj-$(CONFIG_SOFTMMU) += or-irq.o +common-obj-$(CONFIG_SOFTMMU) += split-irq.o common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o obj-$(CONFIG_SOFTMMU) += generic-loader.o diff --git a/include/hw/core/split-irq.h b/include/hw/core/split-irq.h new file mode 100644 index 0000000000..bb87157c5a --- /dev/null +++ b/include/hw/core/split-irq.h @@ -0,0 +1,57 @@ +/* + * IRQ splitter device. + * + * Copyright (c) 2018 Linaro Limited. + * Written by Peter Maydell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* This is a simple device which has one GPIO input line and multiple + * GPIO output lines. Any change on the input line is forwarded to all + * of the outputs. + * + * QEMU interface: + * + one unnamed GPIO input: the input line + * + N unnamed GPIO outputs: the output lines + * + QOM property "num-lines": sets the number of output lines + */ +#ifndef HW_SPLIT_IRQ_H +#define HW_SPLIT_IRQ_H + +#include "hw/irq.h" +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_SPLIT_IRQ "split-irq" + +#define MAX_SPLIT_LINES 16 + +typedef struct SplitIRQ SplitIRQ; + +#define SPLIT_IRQ(obj) OBJECT_CHECK(SplitIRQ, (obj), TYPE_SPLIT_IRQ) + +struct SplitIRQ { + DeviceState parent_obj; + + qemu_irq out_irq[MAX_SPLIT_LINES]; + uint16_t num_lines; +}; + +#endif diff --git a/include/hw/irq.h b/include/hw/irq.h index 4c4c2eaf9a..7a40e3ed26 100644 --- a/include/hw/irq.h +++ b/include/hw/irq.h @@ -50,7 +50,9 @@ void qemu_free_irq(qemu_irq irq); /* Returns a new IRQ with opposite polarity. */ qemu_irq qemu_irq_invert(qemu_irq irq); -/* Returns a new IRQ which feeds into both the passed IRQs */ +/* Returns a new IRQ which feeds into both the passed IRQs. + * It's probably better to use the TYPE_SPLIT_IRQ device instead. + */ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2); /* Returns a new IRQ set which connects 1:1 to another IRQ set, which diff --git a/hw/core/split-irq.c b/hw/core/split-irq.c new file mode 100644 index 0000000000..7e64cd4969 --- /dev/null +++ b/hw/core/split-irq.c @@ -0,0 +1,89 @@ +/* + * IRQ splitter device. + * + * Copyright (c) 2018 Linaro Limited. + * Written by Peter Maydell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "hw/core/split-irq.h" +#include "qapi/error.h" + +static void split_irq_handler(void *opaque, int n, int level) +{ + SplitIRQ *s = SPLIT_IRQ(opaque); + int i; + + for (i = 0; i < s->num_lines; i++) { + qemu_set_irq(s->out_irq[i], level); + } +} + +static void split_irq_init(Object *obj) +{ + qdev_init_gpio_in(DEVICE(obj), split_irq_handler, 1); +} + +static void split_irq_realize(DeviceState *dev, Error **errp) +{ + SplitIRQ *s = SPLIT_IRQ(dev); + + if (s->num_lines < 1 || s->num_lines >= MAX_SPLIT_LINES) { + error_setg(errp, + "IRQ splitter number of lines %d is not between 1 and %d", + s->num_lines, MAX_SPLIT_LINES); + return; + } + + qdev_init_gpio_out(dev, s->out_irq, s->num_lines); +} + +static Property split_irq_properties[] = { + DEFINE_PROP_UINT16("num-lines", SplitIRQ, num_lines, 1), + DEFINE_PROP_END_OF_LIST(), +}; + +static void split_irq_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + /* No state to reset or migrate */ + dc->props = split_irq_properties; + dc->realize = split_irq_realize; + + /* Reason: Needs to be wired up to work */ + dc->user_creatable = false; +} + +static const TypeInfo split_irq_type_info = { + .name = TYPE_SPLIT_IRQ, + .parent = TYPE_DEVICE, + .instance_size = sizeof(SplitIRQ), + .instance_init = split_irq_init, + .class_init = split_irq_class_init, +}; + +static void split_irq_register_types(void) +{ + type_register_static(&split_irq_type_info); +} + +type_init(split_irq_register_types) From patchwork Fri Mar 2 11:06:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880459 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6Qy1fR6z9s4w for ; Fri, 2 Mar 2018 22:24:58 +1100 (AEDT) Received: from localhost ([::1]:34151 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erio4-0001YG-8W for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:24:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43429) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWe-0002wz-2y for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWc-0004uf-EY for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:56 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46762) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWc-0004uL-3I for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:54 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWb-0001MX-52 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:53 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:18 +0000 Message-Id: <20180302110640.28004-18-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 17/39] hw/misc/mps2-fpgaio: FPGA control block for MPS2 AN505 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The MPS2 AN505 FPGA image includes a "FPGA control block" which is a small set of registers handling LEDs, buttons and some counters. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-14-peter.maydell@linaro.org --- hw/misc/Makefile.objs | 1 + include/hw/misc/mps2-fpgaio.h | 43 ++++++++++ hw/misc/mps2-fpgaio.c | 176 ++++++++++++++++++++++++++++++++++++++++ default-configs/arm-softmmu.mak | 1 + hw/misc/trace-events | 6 ++ 5 files changed, 227 insertions(+) create mode 100644 include/hw/misc/mps2-fpgaio.h create mode 100644 hw/misc/mps2-fpgaio.c diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index f33b37a8e5..31f83dcfe7 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -58,6 +58,7 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o obj-$(CONFIG_MIPS_CPS) += mips_cpc.o obj-$(CONFIG_MIPS_ITU) += mips_itu.o +obj-$(CONFIG_MPS2_FPGAIO) += mps2-fpgaio.o obj-$(CONFIG_MPS2_SCC) += mps2-scc.o obj-$(CONFIG_PVPANIC) += pvpanic.o diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h new file mode 100644 index 0000000000..eedf17ebc6 --- /dev/null +++ b/include/hw/misc/mps2-fpgaio.h @@ -0,0 +1,43 @@ +/* + * ARM MPS2 FPGAIO 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 FPGAIO register block in the AN505 + * FPGA image for the MPS2 dev board; it is documented in the + * application note: + * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html + * + * QEMU interface: + * + sysbus MMIO region 0: the register bank + */ + +#ifndef MPS2_FPGAIO_H +#define MPS2_FPGAIO_H + +#include "hw/sysbus.h" + +#define TYPE_MPS2_FPGAIO "mps2-fpgaio" +#define MPS2_FPGAIO(obj) OBJECT_CHECK(MPS2FPGAIO, (obj), TYPE_MPS2_FPGAIO) + +typedef struct { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + + uint32_t led0; + uint32_t prescale; + uint32_t misc; + + uint32_t prescale_clk; +} MPS2FPGAIO; + +#endif diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c new file mode 100644 index 0000000000..7394a057d8 --- /dev/null +++ b/hw/misc/mps2-fpgaio.c @@ -0,0 +1,176 @@ +/* + * ARM MPS2 AN505 FPGAIO 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 "FPGA system control and I/O" block found + * in the AN505 FPGA image for the MPS2 devboard. + * It is documented in AN505: + * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html + */ + +#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/mps2-fpgaio.h" + +REG32(LED0, 0) +REG32(BUTTON, 8) +REG32(CLK1HZ, 0x10) +REG32(CLK100HZ, 0x14) +REG32(COUNTER, 0x18) +REG32(PRESCALE, 0x1c) +REG32(PSCNTR, 0x20) +REG32(MISC, 0x4c) + +static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size) +{ + MPS2FPGAIO *s = MPS2_FPGAIO(opaque); + uint64_t r; + + switch (offset) { + case A_LED0: + r = s->led0; + break; + case A_BUTTON: + /* User-pressable board buttons. We don't model that, so just return + * zeroes. + */ + r = 0; + break; + case A_PRESCALE: + r = s->prescale; + break; + case A_MISC: + r = s->misc; + break; + case A_CLK1HZ: + case A_CLK100HZ: + case A_COUNTER: + case A_PSCNTR: + /* These are all upcounters of various frequencies. */ + qemu_log_mask(LOG_UNIMP, "MPS2 FPGAIO: counters unimplemented\n"); + r = 0; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "MPS2 FPGAIO read: bad offset %x\n", (int) offset); + r = 0; + break; + } + + trace_mps2_fpgaio_read(offset, r, size); + return r; +} + +static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value, + unsigned size) +{ + MPS2FPGAIO *s = MPS2_FPGAIO(opaque); + + trace_mps2_fpgaio_write(offset, value, size); + + switch (offset) { + case A_LED0: + /* LED bits [1:0] control board LEDs. We don't currently have + * a mechanism for displaying this graphically, so use a trace event. + */ + trace_mps2_fpgaio_leds(value & 0x02 ? '*' : '.', + value & 0x01 ? '*' : '.'); + s->led0 = value & 0x3; + break; + case A_PRESCALE: + s->prescale = value; + break; + case A_MISC: + /* These are control bits for some of the other devices on the + * board (SPI, CLCD, etc). We don't implement that yet, so just + * make the bits read as written. + */ + qemu_log_mask(LOG_UNIMP, + "MPS2 FPGAIO: MISC control bits unimplemented\n"); + s->misc = value; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "MPS2 FPGAIO write: bad offset 0x%x\n", (int) offset); + break; + } +} + +static const MemoryRegionOps mps2_fpgaio_ops = { + .read = mps2_fpgaio_read, + .write = mps2_fpgaio_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void mps2_fpgaio_reset(DeviceState *dev) +{ + MPS2FPGAIO *s = MPS2_FPGAIO(dev); + + trace_mps2_fpgaio_reset(); + s->led0 = 0; + s->prescale = 0; + s->misc = 0; +} + +static void mps2_fpgaio_init(Object *obj) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + MPS2FPGAIO *s = MPS2_FPGAIO(obj); + + memory_region_init_io(&s->iomem, obj, &mps2_fpgaio_ops, s, + "mps2-fpgaio", 0x1000); + sysbus_init_mmio(sbd, &s->iomem); +} + +static const VMStateDescription mps2_fpgaio_vmstate = { + .name = "mps2-fpgaio", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(led0, MPS2FPGAIO), + VMSTATE_UINT32(prescale, MPS2FPGAIO), + VMSTATE_UINT32(misc, MPS2FPGAIO), + VMSTATE_END_OF_LIST() + } +}; + +static Property mps2_fpgaio_properties[] = { + /* Frequency of the prescale counter */ + DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000), + DEFINE_PROP_END_OF_LIST(), +}; + +static void mps2_fpgaio_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->vmsd = &mps2_fpgaio_vmstate; + dc->reset = mps2_fpgaio_reset; + dc->props = mps2_fpgaio_properties; +} + +static const TypeInfo mps2_fpgaio_info = { + .name = TYPE_MPS2_FPGAIO, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(MPS2FPGAIO), + .instance_init = mps2_fpgaio_init, + .class_init = mps2_fpgaio_class_init, +}; + +static void mps2_fpgaio_register_types(void) +{ + type_register_static(&mps2_fpgaio_info); +} + +type_init(mps2_fpgaio_register_types); diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 54f855d072..5eaafee394 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -102,6 +102,7 @@ CONFIG_STM32F205_SOC=y CONFIG_CMSDK_APB_TIMER=y CONFIG_CMSDK_APB_UART=y +CONFIG_MPS2_FPGAIO=y CONFIG_MPS2_SCC=y CONFIG_VERSATILE_PCI=y diff --git a/hw/misc/trace-events b/hw/misc/trace-events index b340d4e81c..ef852ffae7 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -62,6 +62,12 @@ mps2_scc_leds(char led7, char led6, char led5, char led4, char led3, char led2, mps2_scc_cfg_write(unsigned function, unsigned device, uint32_t value) "MPS2 SCC config write: function %d device %d data 0x%" PRIx32 mps2_scc_cfg_read(unsigned function, unsigned device, uint32_t value) "MPS2 SCC config read: function %d device %d data 0x%" PRIx32 +# hw/misc/mps2_fpgaio.c +mps2_fpgaio_read(uint64_t offset, uint64_t data, unsigned size) "MPS2 FPGAIO read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +mps2_fpgaio_write(uint64_t offset, uint64_t data, unsigned size) "MPS2 FPGAIO write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" +mps2_fpgaio_reset(void) "MPS2 FPGAIO: reset" +mps2_fpgaio_leds(char led1, char led0) "MPS2 FPGAIO LEDs: %c%c" + # hw/misc/msf2-sysreg.c msf2_sysreg_write(uint64_t offset, uint32_t val, uint32_t prev) "msf2-sysreg write: addr 0x%08" HWADDR_PRIx " data 0x%" PRIx32 " prev 0x%" PRIx32 msf2_sysreg_read(uint64_t offset, uint32_t val) "msf2-sysreg read: addr 0x%08" HWADDR_PRIx " data 0x%08" PRIx32 From patchwork Fri Mar 2 11:06:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880451 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6Jg6nQBz9s3m for ; Fri, 2 Mar 2018 22:19:31 +1100 (AEDT) Received: from localhost ([::1]:34122 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriio-0005Hp-0o for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:19:30 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43448) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWf-0002ys-K5 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWd-0004us-Ez for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:57 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46762) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWd-0004uL-3w for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:55 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWb-0001Mo-Qf for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:53 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:19 +0000 Message-Id: <20180302110640.28004-19-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 18/39] hw/misc/tz-ppc: Model TrustZone peripheral protection controller X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add a model of the TrustZone peripheral protection controller (PPC), which is used to gate transactions to non-TZ-aware peripherals so that secure software can configure them to not be accessible to non-secure software. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-15-peter.maydell@linaro.org --- hw/misc/Makefile.objs | 2 + include/hw/misc/tz-ppc.h | 101 ++++++++++++++ hw/misc/tz-ppc.c | 302 ++++++++++++++++++++++++++++++++++++++++ default-configs/arm-softmmu.mak | 2 + hw/misc/trace-events | 11 ++ 5 files changed, 418 insertions(+) create mode 100644 include/hw/misc/tz-ppc.h create mode 100644 hw/misc/tz-ppc.c diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 31f83dcfe7..dcf413d730 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -61,6 +61,8 @@ obj-$(CONFIG_MIPS_ITU) += mips_itu.o obj-$(CONFIG_MPS2_FPGAIO) += mps2-fpgaio.o obj-$(CONFIG_MPS2_SCC) += mps2-scc.o +obj-$(CONFIG_TZ_PPC) += tz-ppc.o + obj-$(CONFIG_PVPANIC) += pvpanic.o obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o obj-$(CONFIG_AUX) += auxbus.o diff --git a/include/hw/misc/tz-ppc.h b/include/hw/misc/tz-ppc.h new file mode 100644 index 0000000000..fc8b806e4d --- /dev/null +++ b/include/hw/misc/tz-ppc.h @@ -0,0 +1,101 @@ +/* + * ARM TrustZone peripheral protection 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 peripheral protection controller (PPC). + * 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 PPC sits in front of peripherals and allows secure software to + * configure it to either pass through or reject transactions. + * 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 PPC 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 PPC. + * + * This QEMU model can be used to model either the AHB5 or APB4 TZ PPC, + * since the only difference between them is that the AHB version has a + * "default" port which has no security checks applied. In QEMU the default + * port can be emulated simply by wiring its downstream devices directly + * into the parent address space, since the PPC does not need to intercept + * transactions there. + * + * In the hardware, selection of which downstream port to use is done by + * the user's decode logic asserting one of the hsel[] signals. In QEMU, + * we provide 16 MMIO regions, one per port, and the user maps these into + * the desired addresses to implement the address decode. + * + * QEMU interface: + * + sysbus MMIO regions 0..15: MemoryRegions defining the upstream end + * of each of the 16 ports of the PPC + * + Property "port[0..15]": MemoryRegion defining the downstream device(s) + * for each of the 16 ports of the PPC + * + Named GPIO inputs "cfg_nonsec[0..15]": set to 1 if the port should be + * accessible to NonSecure transactions + * + Named GPIO inputs "cfg_ap[0..15]": set to 1 if the port should be + * accessible to non-privileged transactions + * + 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_enable": set to 1 to enable interrupts + * + Named GPIO input "irq_clear": set to 1 to clear a pending interrupt + * + Named GPIO output "irq": set for a transaction-failed interrupt + * + Property "NONSEC_MASK": if a bit is set in this mask then accesses to + * the associated port do not have the TZ security check performed. (This + * corresponds to the hardware allowing this to be set as a Verilog + * parameter.) + */ + +#ifndef TZ_PPC_H +#define TZ_PPC_H + +#include "hw/sysbus.h" + +#define TYPE_TZ_PPC "tz-ppc" +#define TZ_PPC(obj) OBJECT_CHECK(TZPPC, (obj), TYPE_TZ_PPC) + +#define TZ_NUM_PORTS 16 + +typedef struct TZPPC TZPPC; + +typedef struct TZPPCPort { + TZPPC *ppc; + MemoryRegion upstream; + AddressSpace downstream_as; + MemoryRegion *downstream; +} TZPPCPort; + +struct TZPPC { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + + /* State: these just track the values of our input signals */ + bool cfg_nonsec[TZ_NUM_PORTS]; + bool cfg_ap[TZ_NUM_PORTS]; + bool cfg_sec_resp; + bool irq_enable; + bool irq_clear; + /* State: are we asserting irq ? */ + bool irq_status; + + qemu_irq irq; + + /* Properties */ + uint32_t nonsec_mask; + + TZPPCPort port[TZ_NUM_PORTS]; +}; + +#endif diff --git a/hw/misc/tz-ppc.c b/hw/misc/tz-ppc.c new file mode 100644 index 0000000000..3dd045c15f --- /dev/null +++ b/hw/misc/tz-ppc.c @@ -0,0 +1,302 @@ +/* + * ARM TrustZone peripheral protection 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-ppc.h" + +static void tz_ppc_update_irq(TZPPC *s) +{ + bool level = s->irq_status && s->irq_enable; + + trace_tz_ppc_update_irq(level); + qemu_set_irq(s->irq, level); +} + +static void tz_ppc_cfg_nonsec(void *opaque, int n, int level) +{ + TZPPC *s = TZ_PPC(opaque); + + assert(n < TZ_NUM_PORTS); + trace_tz_ppc_cfg_nonsec(n, level); + s->cfg_nonsec[n] = level; +} + +static void tz_ppc_cfg_ap(void *opaque, int n, int level) +{ + TZPPC *s = TZ_PPC(opaque); + + assert(n < TZ_NUM_PORTS); + trace_tz_ppc_cfg_ap(n, level); + s->cfg_ap[n] = level; +} + +static void tz_ppc_cfg_sec_resp(void *opaque, int n, int level) +{ + TZPPC *s = TZ_PPC(opaque); + + trace_tz_ppc_cfg_sec_resp(level); + s->cfg_sec_resp = level; +} + +static void tz_ppc_irq_enable(void *opaque, int n, int level) +{ + TZPPC *s = TZ_PPC(opaque); + + trace_tz_ppc_irq_enable(level); + s->irq_enable = level; + tz_ppc_update_irq(s); +} + +static void tz_ppc_irq_clear(void *opaque, int n, int level) +{ + TZPPC *s = TZ_PPC(opaque); + + trace_tz_ppc_irq_clear(level); + + s->irq_clear = level; + if (level) { + s->irq_status = false; + tz_ppc_update_irq(s); + } +} + +static bool tz_ppc_check(TZPPC *s, int n, MemTxAttrs attrs) +{ + /* Check whether to allow an access to port n; return true if + * the check passes, and false if the transaction must be blocked. + * If the latter, the caller must check cfg_sec_resp to determine + * whether to abort or RAZ/WI the transaction. + * The checks are: + * + nonsec_mask suppresses any check of the secure attribute + * + otherwise, block if cfg_nonsec is 1 and transaction is secure, + * or if cfg_nonsec is 0 and transaction is non-secure + * + block if transaction is usermode and cfg_ap is 0 + */ + if ((attrs.secure == s->cfg_nonsec[n] && !(s->nonsec_mask & (1 << n))) || + (attrs.user && !s->cfg_ap[n])) { + /* Block the transaction. */ + if (!s->irq_clear) { + /* Note that holding irq_clear high suppresses interrupts */ + s->irq_status = true; + tz_ppc_update_irq(s); + } + return false; + } + return true; +} + +static MemTxResult tz_ppc_read(void *opaque, hwaddr addr, uint64_t *pdata, + unsigned size, MemTxAttrs attrs) +{ + TZPPCPort *p = opaque; + TZPPC *s = p->ppc; + int n = p - s->port; + AddressSpace *as = &p->downstream_as; + uint64_t data; + MemTxResult res; + + if (!tz_ppc_check(s, n, attrs)) { + trace_tz_ppc_read_blocked(n, addr, attrs.secure, attrs.user); + if (s->cfg_sec_resp) { + return MEMTX_ERROR; + } else { + *pdata = 0; + return MEMTX_OK; + } + } + + 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_ppc_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size, MemTxAttrs attrs) +{ + TZPPCPort *p = opaque; + TZPPC *s = p->ppc; + AddressSpace *as = &p->downstream_as; + int n = p - s->port; + MemTxResult res; + + if (!tz_ppc_check(s, n, attrs)) { + trace_tz_ppc_write_blocked(n, addr, attrs.secure, attrs.user); + if (s->cfg_sec_resp) { + return MEMTX_ERROR; + } else { + return MEMTX_OK; + } + } + + 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_ppc_ops = { + .read_with_attrs = tz_ppc_read, + .write_with_attrs = tz_ppc_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void tz_ppc_reset(DeviceState *dev) +{ + TZPPC *s = TZ_PPC(dev); + + trace_tz_ppc_reset(); + s->cfg_sec_resp = false; + memset(s->cfg_nonsec, 0, sizeof(s->cfg_nonsec)); + memset(s->cfg_ap, 0, sizeof(s->cfg_ap)); +} + +static void tz_ppc_init(Object *obj) +{ + DeviceState *dev = DEVICE(obj); + TZPPC *s = TZ_PPC(obj); + + qdev_init_gpio_in_named(dev, tz_ppc_cfg_nonsec, "cfg_nonsec", TZ_NUM_PORTS); + qdev_init_gpio_in_named(dev, tz_ppc_cfg_ap, "cfg_ap", TZ_NUM_PORTS); + qdev_init_gpio_in_named(dev, tz_ppc_cfg_sec_resp, "cfg_sec_resp", 1); + qdev_init_gpio_in_named(dev, tz_ppc_irq_enable, "irq_enable", 1); + qdev_init_gpio_in_named(dev, tz_ppc_irq_clear, "irq_clear", 1); + qdev_init_gpio_out_named(dev, &s->irq, "irq", 1); +} + +static void tz_ppc_realize(DeviceState *dev, Error **errp) +{ + Object *obj = OBJECT(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + TZPPC *s = TZ_PPC(dev); + int i; + + /* 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. + */ + for (i = 0; i < TZ_NUM_PORTS; i++) { + TZPPCPort *port = &s->port[i]; + char *name; + uint64_t size; + + if (!port->downstream) { + continue; + } + + name = g_strdup_printf("tz-ppc-port[%d]", i); + + port->ppc = s; + address_space_init(&port->downstream_as, port->downstream, name); + + size = memory_region_size(port->downstream); + memory_region_init_io(&port->upstream, obj, &tz_ppc_ops, + port, name, size); + sysbus_init_mmio(sbd, &port->upstream); + g_free(name); + } +} + +static const VMStateDescription tz_ppc_vmstate = { + .name = "tz-ppc", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_BOOL_ARRAY(cfg_nonsec, TZPPC, 16), + VMSTATE_BOOL_ARRAY(cfg_ap, TZPPC, 16), + VMSTATE_BOOL(cfg_sec_resp, TZPPC), + VMSTATE_BOOL(irq_enable, TZPPC), + VMSTATE_BOOL(irq_clear, TZPPC), + VMSTATE_BOOL(irq_status, TZPPC), + VMSTATE_END_OF_LIST() + } +}; + +#define DEFINE_PORT(N) \ + DEFINE_PROP_LINK("port[" #N "]", TZPPC, port[N].downstream, \ + TYPE_MEMORY_REGION, MemoryRegion *) + +static Property tz_ppc_properties[] = { + DEFINE_PROP_UINT32("NONSEC_MASK", TZPPC, nonsec_mask, 0), + DEFINE_PORT(0), + DEFINE_PORT(1), + DEFINE_PORT(2), + DEFINE_PORT(3), + DEFINE_PORT(4), + DEFINE_PORT(5), + DEFINE_PORT(6), + DEFINE_PORT(7), + DEFINE_PORT(8), + DEFINE_PORT(9), + DEFINE_PORT(10), + DEFINE_PORT(11), + DEFINE_PORT(12), + DEFINE_PORT(13), + DEFINE_PORT(14), + DEFINE_PORT(15), + DEFINE_PROP_END_OF_LIST(), +}; + +static void tz_ppc_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = tz_ppc_realize; + dc->vmsd = &tz_ppc_vmstate; + dc->reset = tz_ppc_reset; + dc->props = tz_ppc_properties; +} + +static const TypeInfo tz_ppc_info = { + .name = TYPE_TZ_PPC, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(TZPPC), + .instance_init = tz_ppc_init, + .class_init = tz_ppc_class_init, +}; + +static void tz_ppc_register_types(void) +{ + type_register_static(&tz_ppc_info); +} + +type_init(tz_ppc_register_types); diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 5eaafee394..b51ff2db9d 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -105,6 +105,8 @@ CONFIG_CMSDK_APB_UART=y CONFIG_MPS2_FPGAIO=y CONFIG_MPS2_SCC=y +CONFIG_TZ_PPC=y + CONFIG_VERSATILE_PCI=y CONFIG_VERSATILE_I2C=y diff --git a/hw/misc/trace-events b/hw/misc/trace-events index ef852ffae7..0b638de682 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -83,3 +83,14 @@ mos6522_get_next_irq_time(uint16_t latch, int64_t d, int64_t delta) "latch=%d co mos6522_set_sr_int(void) "set sr_int" mos6522_write(uint64_t addr, uint64_t val) "reg=0x%"PRIx64 " val=0x%"PRIx64 mos6522_read(uint64_t addr, unsigned val) "reg=0x%"PRIx64 " val=0x%x" + +# 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" +tz_ppc_cfg_ap(int n, int level) "TZ PPC: cfg_ap[%d] = %d" +tz_ppc_cfg_sec_resp(int level) "TZ PPC: cfg_sec_resp = %d" +tz_ppc_irq_enable(int level) "TZ PPC: int_enable = %d" +tz_ppc_irq_clear(int level) "TZ PPC: int_clear = %d" +tz_ppc_update_irq(int level) "TZ PPC: setting irq line to %d" +tz_ppc_read_blocked(int n, hwaddr offset, bool secure, bool user) "TZ PPC: port %d offset 0x%" HWADDR_PRIx " read (secure %d user %d) blocked" +tz_ppc_write_blocked(int n, hwaddr offset, bool secure, bool user) "TZ PPC: port %d offset 0x%" HWADDR_PRIx " write (secure %d user %d) blocked" From patchwork Fri Mar 2 11:06:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880457 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6P63GrQz9s4w for ; Fri, 2 Mar 2018 22:23:22 +1100 (AEDT) Received: from localhost ([::1]:34144 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erimW-0008PE-EL for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:23:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43454) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWg-0002zD-11 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWd-0004v1-Vn for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:57 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46764) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWd-0004um-IA for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:55 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWc-0001N2-Iq for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:54 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:20 +0000 Message-Id: <20180302110640.28004-20-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 19/39] hw/misc/iotkit-secctl: Arm IoT Kit security controller initial skeleton X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The Arm IoT Kit includes a "security controller" which is largely a collection of registers for controlling the PPCs and other bits of glue in the system. This commit provides the initial skeleton of the device, implementing just the ID registers, and a couple of read-only read-as-zero registers. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-16-peter.maydell@linaro.org --- hw/misc/Makefile.objs | 1 + include/hw/misc/iotkit-secctl.h | 39 ++++ hw/misc/iotkit-secctl.c | 448 ++++++++++++++++++++++++++++++++++++++++ default-configs/arm-softmmu.mak | 1 + hw/misc/trace-events | 7 + 5 files changed, 496 insertions(+) create mode 100644 include/hw/misc/iotkit-secctl.h create mode 100644 hw/misc/iotkit-secctl.c diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index dcf413d730..00e834d0f0 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -62,6 +62,7 @@ obj-$(CONFIG_MPS2_FPGAIO) += mps2-fpgaio.o obj-$(CONFIG_MPS2_SCC) += mps2-scc.o obj-$(CONFIG_TZ_PPC) += tz-ppc.o +obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o obj-$(CONFIG_PVPANIC) += pvpanic.o obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h new file mode 100644 index 0000000000..872f652f8d --- /dev/null +++ b/include/hw/misc/iotkit-secctl.h @@ -0,0 +1,39 @@ +/* + * ARM IoT Kit security controller + * + * 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 security controller which is part of the + * Arm IoT Kit and documented in + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html + * + * QEMU interface: + * + sysbus MMIO region 0 is the "secure privilege control block" registers + * + sysbus MMIO region 1 is the "non-secure privilege control block" registers + */ + +#ifndef IOTKIT_SECCTL_H +#define IOTKIT_SECCTL_H + +#include "hw/sysbus.h" + +#define TYPE_IOTKIT_SECCTL "iotkit-secctl" +#define IOTKIT_SECCTL(obj) OBJECT_CHECK(IoTKitSecCtl, (obj), TYPE_IOTKIT_SECCTL) + +typedef struct IoTKitSecCtl { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + + MemoryRegion s_regs; + MemoryRegion ns_regs; +} IoTKitSecCtl; + +#endif diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c new file mode 100644 index 0000000000..d106de95d7 --- /dev/null +++ b/hw/misc/iotkit-secctl.c @@ -0,0 +1,448 @@ +/* + * Arm IoT Kit security controller + * + * 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/iotkit-secctl.h" + +/* Registers in the secure privilege control block */ +REG32(SECRESPCFG, 0x10) +REG32(NSCCFG, 0x14) +REG32(SECMPCINTSTATUS, 0x1c) +REG32(SECPPCINTSTAT, 0x20) +REG32(SECPPCINTCLR, 0x24) +REG32(SECPPCINTEN, 0x28) +REG32(SECMSCINTSTAT, 0x30) +REG32(SECMSCINTCLR, 0x34) +REG32(SECMSCINTEN, 0x38) +REG32(BRGINTSTAT, 0x40) +REG32(BRGINTCLR, 0x44) +REG32(BRGINTEN, 0x48) +REG32(AHBNSPPC0, 0x50) +REG32(AHBNSPPCEXP0, 0x60) +REG32(AHBNSPPCEXP1, 0x64) +REG32(AHBNSPPCEXP2, 0x68) +REG32(AHBNSPPCEXP3, 0x6c) +REG32(APBNSPPC0, 0x70) +REG32(APBNSPPC1, 0x74) +REG32(APBNSPPCEXP0, 0x80) +REG32(APBNSPPCEXP1, 0x84) +REG32(APBNSPPCEXP2, 0x88) +REG32(APBNSPPCEXP3, 0x8c) +REG32(AHBSPPPC0, 0x90) +REG32(AHBSPPPCEXP0, 0xa0) +REG32(AHBSPPPCEXP1, 0xa4) +REG32(AHBSPPPCEXP2, 0xa8) +REG32(AHBSPPPCEXP3, 0xac) +REG32(APBSPPPC0, 0xb0) +REG32(APBSPPPC1, 0xb4) +REG32(APBSPPPCEXP0, 0xc0) +REG32(APBSPPPCEXP1, 0xc4) +REG32(APBSPPPCEXP2, 0xc8) +REG32(APBSPPPCEXP3, 0xcc) +REG32(NSMSCEXP, 0xd0) +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) + +/* Registers in the non-secure privilege control block */ +REG32(AHBNSPPPC0, 0x90) +REG32(AHBNSPPPCEXP0, 0xa0) +REG32(AHBNSPPPCEXP1, 0xa4) +REG32(AHBNSPPPCEXP2, 0xa8) +REG32(AHBNSPPPCEXP3, 0xac) +REG32(APBNSPPPC0, 0xb0) +REG32(APBNSPPPC1, 0xb4) +REG32(APBNSPPPCEXP0, 0xc0) +REG32(APBNSPPPCEXP1, 0xc4) +REG32(APBNSPPPCEXP2, 0xc8) +REG32(APBNSPPPCEXP3, 0xcc) +/* PID and CID registers are also present in the NS block */ + +static const uint8_t iotkit_secctl_s_idregs[] = { + 0x04, 0x00, 0x00, 0x00, + 0x52, 0xb8, 0x0b, 0x00, + 0x0d, 0xf0, 0x05, 0xb1, +}; + +static const uint8_t iotkit_secctl_ns_idregs[] = { + 0x04, 0x00, 0x00, 0x00, + 0x53, 0xb8, 0x0b, 0x00, + 0x0d, 0xf0, 0x05, 0xb1, +}; + +static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr, + uint64_t *pdata, + unsigned size, MemTxAttrs attrs) +{ + uint64_t r; + uint32_t offset = addr & ~0x3; + + switch (offset) { + case A_AHBNSPPC0: + case A_AHBSPPPC0: + r = 0; + break; + case A_SECRESPCFG: + case A_NSCCFG: + case A_SECMPCINTSTATUS: + case A_SECPPCINTSTAT: + case A_SECPPCINTEN: + case A_SECMSCINTSTAT: + case A_SECMSCINTEN: + case A_BRGINTSTAT: + case A_BRGINTEN: + case A_AHBNSPPCEXP0: + case A_AHBNSPPCEXP1: + case A_AHBNSPPCEXP2: + case A_AHBNSPPCEXP3: + case A_APBNSPPC0: + case A_APBNSPPC1: + case A_APBNSPPCEXP0: + case A_APBNSPPCEXP1: + case A_APBNSPPCEXP2: + case A_APBNSPPCEXP3: + case A_AHBSPPPCEXP0: + case A_AHBSPPPCEXP1: + case A_AHBSPPPCEXP2: + case A_AHBSPPPCEXP3: + case A_APBSPPPC0: + case A_APBSPPPC1: + case A_APBSPPPCEXP0: + case A_APBSPPPCEXP1: + case A_APBSPPPCEXP2: + case A_APBSPPPCEXP3: + case A_NSMSCEXP: + qemu_log_mask(LOG_UNIMP, + "IoTKit SecCtl S block read: " + "unimplemented offset 0x%x\n", offset); + r = 0; + break; + case A_PID4: + case A_PID5: + case A_PID6: + case A_PID7: + case A_PID0: + case A_PID1: + case A_PID2: + case A_PID3: + case A_CID0: + case A_CID1: + case A_CID2: + case A_CID3: + r = iotkit_secctl_s_idregs[(offset - A_PID4) / 4]; + break; + case A_SECPPCINTCLR: + case A_SECMSCINTCLR: + case A_BRGINTCLR: + qemu_log_mask(LOG_GUEST_ERROR, + "IotKit SecCtl S block read: write-only offset 0x%x\n", + offset); + r = 0; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "IotKit SecCtl S block read: bad offset 0x%x\n", offset); + r = 0; + break; + } + + if (size != 4) { + /* None of our registers are access-sensitive, so just pull the right + * byte out of the word read result. + */ + r = extract32(r, (addr & 3) * 8, size * 8); + } + + trace_iotkit_secctl_s_read(offset, r, size); + *pdata = r; + return MEMTX_OK; +} + +static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr, + uint64_t value, + unsigned size, MemTxAttrs attrs) +{ + uint32_t offset = addr; + + trace_iotkit_secctl_s_write(offset, value, size); + + if (size != 4) { + /* Byte and halfword writes are ignored */ + qemu_log_mask(LOG_GUEST_ERROR, + "IotKit SecCtl S block write: bad size, ignored\n"); + return MEMTX_OK; + } + + switch (offset) { + case A_SECRESPCFG: + case A_NSCCFG: + case A_SECPPCINTCLR: + case A_SECPPCINTEN: + case A_SECMSCINTCLR: + case A_SECMSCINTEN: + case A_BRGINTCLR: + case A_BRGINTEN: + case A_AHBNSPPCEXP0: + case A_AHBNSPPCEXP1: + case A_AHBNSPPCEXP2: + case A_AHBNSPPCEXP3: + case A_APBNSPPC0: + case A_APBNSPPC1: + case A_APBNSPPCEXP0: + case A_APBNSPPCEXP1: + case A_APBNSPPCEXP2: + case A_APBNSPPCEXP3: + case A_AHBSPPPCEXP0: + case A_AHBSPPPCEXP1: + case A_AHBSPPPCEXP2: + case A_AHBSPPPCEXP3: + case A_APBSPPPC0: + case A_APBSPPPC1: + case A_APBSPPPCEXP0: + case A_APBSPPPCEXP1: + case A_APBSPPPCEXP2: + case A_APBSPPPCEXP3: + qemu_log_mask(LOG_UNIMP, + "IoTKit SecCtl S block write: " + "unimplemented offset 0x%x\n", offset); + break; + case A_SECMPCINTSTATUS: + case A_SECPPCINTSTAT: + case A_SECMSCINTSTAT: + case A_BRGINTSTAT: + case A_AHBNSPPC0: + case A_AHBSPPPC0: + case A_NSMSCEXP: + case A_PID4: + case A_PID5: + case A_PID6: + case A_PID7: + case A_PID0: + case A_PID1: + case A_PID2: + case A_PID3: + case A_CID0: + case A_CID1: + case A_CID2: + case A_CID3: + qemu_log_mask(LOG_GUEST_ERROR, + "IoTKit SecCtl S block write: " + "read-only offset 0x%x\n", offset); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "IotKit SecCtl S block write: bad offset 0x%x\n", + offset); + break; + } + + return MEMTX_OK; +} + +static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr, + uint64_t *pdata, + unsigned size, MemTxAttrs attrs) +{ + uint64_t r; + uint32_t offset = addr & ~0x3; + + switch (offset) { + case A_AHBNSPPPC0: + r = 0; + break; + case A_AHBNSPPPCEXP0: + case A_AHBNSPPPCEXP1: + case A_AHBNSPPPCEXP2: + case A_AHBNSPPPCEXP3: + case A_APBNSPPPC0: + case A_APBNSPPPC1: + case A_APBNSPPPCEXP0: + case A_APBNSPPPCEXP1: + case A_APBNSPPPCEXP2: + case A_APBNSPPPCEXP3: + qemu_log_mask(LOG_UNIMP, + "IoTKit SecCtl NS block read: " + "unimplemented offset 0x%x\n", offset); + break; + case A_PID4: + case A_PID5: + case A_PID6: + case A_PID7: + case A_PID0: + case A_PID1: + case A_PID2: + case A_PID3: + case A_CID0: + case A_CID1: + case A_CID2: + case A_CID3: + r = iotkit_secctl_ns_idregs[(offset - A_PID4) / 4]; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "IotKit SecCtl NS block write: bad offset 0x%x\n", + offset); + r = 0; + break; + } + + if (size != 4) { + /* None of our registers are access-sensitive, so just pull the right + * byte out of the word read result. + */ + r = extract32(r, (addr & 3) * 8, size * 8); + } + + trace_iotkit_secctl_ns_read(offset, r, size); + *pdata = r; + return MEMTX_OK; +} + +static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr, + uint64_t value, + unsigned size, MemTxAttrs attrs) +{ + uint32_t offset = addr; + + trace_iotkit_secctl_ns_write(offset, value, size); + + if (size != 4) { + /* Byte and halfword writes are ignored */ + qemu_log_mask(LOG_GUEST_ERROR, + "IotKit SecCtl NS block write: bad size, ignored\n"); + return MEMTX_OK; + } + + switch (offset) { + case A_AHBNSPPPCEXP0: + case A_AHBNSPPPCEXP1: + case A_AHBNSPPPCEXP2: + case A_AHBNSPPPCEXP3: + case A_APBNSPPPC0: + case A_APBNSPPPC1: + case A_APBNSPPPCEXP0: + case A_APBNSPPPCEXP1: + case A_APBNSPPPCEXP2: + case A_APBNSPPPCEXP3: + qemu_log_mask(LOG_UNIMP, + "IoTKit SecCtl NS block write: " + "unimplemented offset 0x%x\n", offset); + break; + case A_AHBNSPPPC0: + case A_PID4: + case A_PID5: + case A_PID6: + case A_PID7: + case A_PID0: + case A_PID1: + case A_PID2: + case A_PID3: + case A_CID0: + case A_CID1: + case A_CID2: + case A_CID3: + qemu_log_mask(LOG_GUEST_ERROR, + "IoTKit SecCtl NS block write: " + "read-only offset 0x%x\n", offset); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "IotKit SecCtl NS block write: bad offset 0x%x\n", + offset); + break; + } + + return MEMTX_OK; +} + +static const MemoryRegionOps iotkit_secctl_s_ops = { + .read_with_attrs = iotkit_secctl_s_read, + .write_with_attrs = iotkit_secctl_s_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid.min_access_size = 1, + .valid.max_access_size = 4, + .impl.min_access_size = 1, + .impl.max_access_size = 4, +}; + +static const MemoryRegionOps iotkit_secctl_ns_ops = { + .read_with_attrs = iotkit_secctl_ns_read, + .write_with_attrs = iotkit_secctl_ns_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid.min_access_size = 1, + .valid.max_access_size = 4, + .impl.min_access_size = 1, + .impl.max_access_size = 4, +}; + +static void iotkit_secctl_reset(DeviceState *dev) +{ + +} + +static void iotkit_secctl_init(Object *obj) +{ + IoTKitSecCtl *s = IOTKIT_SECCTL(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + + 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, + s, "iotkit-secctl-ns-regs", 0x1000); + sysbus_init_mmio(sbd, &s->s_regs); + sysbus_init_mmio(sbd, &s->ns_regs); +} + +static const VMStateDescription iotkit_secctl_vmstate = { + .name = "iotkit-secctl", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_END_OF_LIST() + } +}; + +static void iotkit_secctl_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->vmsd = &iotkit_secctl_vmstate; + dc->reset = iotkit_secctl_reset; +} + +static const TypeInfo iotkit_secctl_info = { + .name = TYPE_IOTKIT_SECCTL, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(IoTKitSecCtl), + .instance_init = iotkit_secctl_init, + .class_init = iotkit_secctl_class_init, +}; + +static void iotkit_secctl_register_types(void) +{ + type_register_static(&iotkit_secctl_info); +} + +type_init(iotkit_secctl_register_types); diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index b51ff2db9d..f914a7486e 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -106,6 +106,7 @@ CONFIG_MPS2_FPGAIO=y CONFIG_MPS2_SCC=y CONFIG_TZ_PPC=y +CONFIG_IOTKIT_SECCTL=y CONFIG_VERSATILE_PCI=y CONFIG_VERSATILE_I2C=y diff --git a/hw/misc/trace-events b/hw/misc/trace-events index 0b638de682..eb5ffcc0a8 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -94,3 +94,10 @@ tz_ppc_irq_clear(int level) "TZ PPC: int_clear = %d" tz_ppc_update_irq(int level) "TZ PPC: setting irq line to %d" tz_ppc_read_blocked(int n, hwaddr offset, bool secure, bool user) "TZ PPC: port %d offset 0x%" HWADDR_PRIx " read (secure %d user %d) blocked" tz_ppc_write_blocked(int n, hwaddr offset, bool secure, bool user) "TZ PPC: port %d offset 0x%" HWADDR_PRIx " write (secure %d user %d) blocked" + +# hw/misc/iotkit-secctl.c +iotkit_secctl_s_read(uint32_t offset, uint64_t data, unsigned size) "IoTKit SecCtl S regs read: offset 0x%x data 0x%" PRIx64 " size %u" +iotkit_secctl_s_write(uint32_t offset, uint64_t data, unsigned size) "IoTKit SecCtl S regs write: offset 0x%x data 0x%" PRIx64 " size %u" +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" From patchwork Fri Mar 2 11:06:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880441 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt69V0Nr6z9s3m for ; Fri, 2 Mar 2018 22:13:16 +1100 (AEDT) Received: from localhost ([::1]:34083 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ericj-0007yk-2p for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:13:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43464) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWg-00030Q-P0 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWe-0004vF-GH for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:58 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46762) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWe-0004uL-4a for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:56 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWd-0001NJ-8F for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:55 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:21 +0000 Message-Id: <20180302110640.28004-21-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 20/39] hw/misc/iotkit-secctl: Add handling for PPCs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The IoTKit Security Controller includes various registers that expose to software the controls for the Peripheral Protection Controllers in the system. Implement these. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-17-peter.maydell@linaro.org --- include/hw/misc/iotkit-secctl.h | 64 +++++++++- hw/misc/iotkit-secctl.c | 270 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 315 insertions(+), 19 deletions(-) diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h index 872f652f8d..ea3d62967f 100644 --- a/include/hw/misc/iotkit-secctl.h +++ b/include/hw/misc/iotkit-secctl.h @@ -16,6 +16,28 @@ * QEMU interface: * + sysbus MMIO region 0 is the "secure privilege control block" registers * + sysbus MMIO region 1 is the "non-secure privilege control block" registers + * + named GPIO output "sec_resp_cfg" indicating whether blocked accesses + * should RAZ/WI or bus error + * 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 + * + named GPIO outputs apb_ppc{0,1}_irq_enable + * + named GPIO outputs apb_ppc{0,1}_irq_clear + * + named GPIO inputs apb_ppc{0,1}_irq_status + * Controlling each of the 4 expansion APB PPCs which a system using the IoTKit + * might provide: + * + named GPIO outputs apb_ppcexp{0,1,2,3}_nonsec[0..15] + * + named GPIO outputs apb_ppcexp{0,1,2,3}_ap[0..15] + * + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_enable + * + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_clear + * + named GPIO inputs apb_ppcexp{0,1,2,3}_irq_status + * Controlling each of the 4 expansion AHB PPCs which a system using the IoTKit + * might provide: + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_nonsec[0..15] + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_ap[0..15] + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear + * + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status */ #ifndef IOTKIT_SECCTL_H @@ -26,14 +48,52 @@ #define TYPE_IOTKIT_SECCTL "iotkit-secctl" #define IOTKIT_SECCTL(obj) OBJECT_CHECK(IoTKitSecCtl, (obj), TYPE_IOTKIT_SECCTL) -typedef struct IoTKitSecCtl { +#define IOTS_APB_PPC0_NUM_PORTS 3 +#define IOTS_APB_PPC1_NUM_PORTS 1 +#define IOTS_PPC_NUM_PORTS 16 +#define IOTS_NUM_APB_PPC 2 +#define IOTS_NUM_APB_EXP_PPC 4 +#define IOTS_NUM_AHB_EXP_PPC 4 + +typedef struct IoTKitSecCtl IoTKitSecCtl; + +/* State and IRQ lines relating to a PPC. For the + * PPCs in the IoTKit not all the IRQ lines are used. + */ +typedef struct IoTKitSecCtlPPC { + qemu_irq nonsec[IOTS_PPC_NUM_PORTS]; + qemu_irq ap[IOTS_PPC_NUM_PORTS]; + qemu_irq irq_enable; + qemu_irq irq_clear; + + uint32_t ns; + uint32_t sp; + uint32_t nsp; + + /* Number of ports actually present */ + int numports; + /* Offset of this PPC's interrupt bits in SECPPCINTSTAT */ + int irq_bit_offset; + IoTKitSecCtl *parent; +} IoTKitSecCtlPPC; + +struct IoTKitSecCtl { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ + qemu_irq sec_resp_cfg; MemoryRegion s_regs; MemoryRegion ns_regs; -} IoTKitSecCtl; + + uint32_t secppcintstat; + uint32_t secppcinten; + uint32_t secrespcfg; + + IoTKitSecCtlPPC apb[IOTS_NUM_APB_PPC]; + IoTKitSecCtlPPC apbexp[IOTS_NUM_APB_EXP_PPC]; + IoTKitSecCtlPPC ahbexp[IOTS_NUM_APB_EXP_PPC]; +}; #endif diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c index d106de95d7..1093f2910f 100644 --- a/hw/misc/iotkit-secctl.c +++ b/hw/misc/iotkit-secctl.c @@ -92,12 +92,41 @@ static const uint8_t iotkit_secctl_ns_idregs[] = { 0x0d, 0xf0, 0x05, 0xb1, }; +/* The register sets for the various PPCs (AHB internal, APB internal, + * AHB expansion, APB expansion) are all set up so that they are + * in 16-aligned blocks so offsets 0xN0, 0xN4, 0xN8, 0xNC are PPCs + * 0, 1, 2, 3 of that type, so we can convert a register address offset + * into an an index into a PPC array easily. + */ +static inline int offset_to_ppc_idx(uint32_t offset) +{ + return extract32(offset, 2, 2); +} + +typedef void PerPPCFunction(IoTKitSecCtlPPC *ppc); + +static void foreach_ppc(IoTKitSecCtl *s, PerPPCFunction *fn) +{ + int i; + + for (i = 0; i < IOTS_NUM_APB_PPC; i++) { + fn(&s->apb[i]); + } + for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) { + fn(&s->apbexp[i]); + } + for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) { + fn(&s->ahbexp[i]); + } +} + static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr, uint64_t *pdata, unsigned size, MemTxAttrs attrs) { uint64_t r; uint32_t offset = addr & ~0x3; + IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); switch (offset) { case A_AHBNSPPC0: @@ -105,34 +134,52 @@ static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr, r = 0; break; case A_SECRESPCFG: - case A_NSCCFG: - case A_SECMPCINTSTATUS: + r = s->secrespcfg; + break; case A_SECPPCINTSTAT: + r = s->secppcintstat; + break; case A_SECPPCINTEN: - case A_SECMSCINTSTAT: - case A_SECMSCINTEN: - case A_BRGINTSTAT: - case A_BRGINTEN: + r = s->secppcinten; + break; case A_AHBNSPPCEXP0: case A_AHBNSPPCEXP1: case A_AHBNSPPCEXP2: case A_AHBNSPPCEXP3: + r = s->ahbexp[offset_to_ppc_idx(offset)].ns; + break; case A_APBNSPPC0: case A_APBNSPPC1: + r = s->apb[offset_to_ppc_idx(offset)].ns; + break; case A_APBNSPPCEXP0: case A_APBNSPPCEXP1: case A_APBNSPPCEXP2: case A_APBNSPPCEXP3: + r = s->apbexp[offset_to_ppc_idx(offset)].ns; + break; case A_AHBSPPPCEXP0: case A_AHBSPPPCEXP1: case A_AHBSPPPCEXP2: case A_AHBSPPPCEXP3: + r = s->apbexp[offset_to_ppc_idx(offset)].sp; + break; case A_APBSPPPC0: case A_APBSPPPC1: + r = s->apb[offset_to_ppc_idx(offset)].sp; + break; case A_APBSPPPCEXP0: case A_APBSPPPCEXP1: case A_APBSPPPCEXP2: case A_APBSPPPCEXP3: + r = s->apbexp[offset_to_ppc_idx(offset)].sp; + break; + case A_NSCCFG: + case A_SECMPCINTSTATUS: + case A_SECMSCINTSTAT: + case A_SECMSCINTEN: + case A_BRGINTSTAT: + case A_BRGINTEN: case A_NSMSCEXP: qemu_log_mask(LOG_UNIMP, "IoTKit SecCtl S block read: " @@ -180,11 +227,66 @@ static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr, return MEMTX_OK; } +static void iotkit_secctl_update_ppc_ap(IoTKitSecCtlPPC *ppc) +{ + int i; + + for (i = 0; i < ppc->numports; i++) { + bool v; + + if (extract32(ppc->ns, i, 1)) { + v = extract32(ppc->nsp, i, 1); + } else { + v = extract32(ppc->sp, i, 1); + } + qemu_set_irq(ppc->ap[i], v); + } +} + +static void iotkit_secctl_ppc_ns_write(IoTKitSecCtlPPC *ppc, uint32_t value) +{ + int i; + + ppc->ns = value & MAKE_64BIT_MASK(0, ppc->numports); + for (i = 0; i < ppc->numports; i++) { + qemu_set_irq(ppc->nonsec[i], extract32(ppc->ns, i, 1)); + } + iotkit_secctl_update_ppc_ap(ppc); +} + +static void iotkit_secctl_ppc_sp_write(IoTKitSecCtlPPC *ppc, uint32_t value) +{ + ppc->sp = value & MAKE_64BIT_MASK(0, ppc->numports); + iotkit_secctl_update_ppc_ap(ppc); +} + +static void iotkit_secctl_ppc_nsp_write(IoTKitSecCtlPPC *ppc, uint32_t value) +{ + ppc->nsp = value & MAKE_64BIT_MASK(0, ppc->numports); + iotkit_secctl_update_ppc_ap(ppc); +} + +static void iotkit_secctl_ppc_update_irq_clear(IoTKitSecCtlPPC *ppc) +{ + uint32_t value = ppc->parent->secppcintstat; + + qemu_set_irq(ppc->irq_clear, extract32(value, ppc->irq_bit_offset, 1)); +} + +static void iotkit_secctl_ppc_update_irq_enable(IoTKitSecCtlPPC *ppc) +{ + uint32_t value = ppc->parent->secppcinten; + + qemu_set_irq(ppc->irq_enable, extract32(value, ppc->irq_bit_offset, 1)); +} + static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr, uint64_t value, unsigned size, MemTxAttrs attrs) { + IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); uint32_t offset = addr; + IoTKitSecCtlPPC *ppc; trace_iotkit_secctl_s_write(offset, value, size); @@ -197,33 +299,61 @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr, switch (offset) { case A_SECRESPCFG: - case A_NSCCFG: + value &= 1; + s->secrespcfg = value; + qemu_set_irq(s->sec_resp_cfg, s->secrespcfg); + break; case A_SECPPCINTCLR: + value &= 0x00f000f3; + foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear); + break; case A_SECPPCINTEN: - case A_SECMSCINTCLR: - case A_SECMSCINTEN: - case A_BRGINTCLR: - case A_BRGINTEN: + s->secppcinten = value & 0x00f000f3; + foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable); + break; case A_AHBNSPPCEXP0: case A_AHBNSPPCEXP1: case A_AHBNSPPCEXP2: case A_AHBNSPPCEXP3: + ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; + iotkit_secctl_ppc_ns_write(ppc, value); + break; case A_APBNSPPC0: case A_APBNSPPC1: + ppc = &s->apb[offset_to_ppc_idx(offset)]; + iotkit_secctl_ppc_ns_write(ppc, value); + break; case A_APBNSPPCEXP0: case A_APBNSPPCEXP1: case A_APBNSPPCEXP2: case A_APBNSPPCEXP3: + ppc = &s->apbexp[offset_to_ppc_idx(offset)]; + iotkit_secctl_ppc_ns_write(ppc, value); + break; case A_AHBSPPPCEXP0: case A_AHBSPPPCEXP1: case A_AHBSPPPCEXP2: case A_AHBSPPPCEXP3: + ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; + iotkit_secctl_ppc_sp_write(ppc, value); + break; case A_APBSPPPC0: case A_APBSPPPC1: + ppc = &s->apb[offset_to_ppc_idx(offset)]; + iotkit_secctl_ppc_sp_write(ppc, value); + break; case A_APBSPPPCEXP0: case A_APBSPPPCEXP1: case A_APBSPPPCEXP2: case A_APBSPPPCEXP3: + ppc = &s->apbexp[offset_to_ppc_idx(offset)]; + iotkit_secctl_ppc_sp_write(ppc, value); + break; + case A_NSCCFG: + case A_SECMSCINTCLR: + case A_SECMSCINTEN: + case A_BRGINTCLR: + case A_BRGINTEN: qemu_log_mask(LOG_UNIMP, "IoTKit SecCtl S block write: " "unimplemented offset 0x%x\n", offset); @@ -265,6 +395,7 @@ static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr, uint64_t *pdata, unsigned size, MemTxAttrs attrs) { + IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); uint64_t r; uint32_t offset = addr & ~0x3; @@ -276,15 +407,17 @@ static MemTxResult iotkit_secctl_ns_read(void *opaque, hwaddr addr, case A_AHBNSPPPCEXP1: case A_AHBNSPPPCEXP2: case A_AHBNSPPPCEXP3: + r = s->ahbexp[offset_to_ppc_idx(offset)].nsp; + break; case A_APBNSPPPC0: case A_APBNSPPPC1: + r = s->apb[offset_to_ppc_idx(offset)].nsp; + break; case A_APBNSPPPCEXP0: case A_APBNSPPPCEXP1: case A_APBNSPPPCEXP2: case A_APBNSPPPCEXP3: - qemu_log_mask(LOG_UNIMP, - "IoTKit SecCtl NS block read: " - "unimplemented offset 0x%x\n", offset); + r = s->apbexp[offset_to_ppc_idx(offset)].nsp; break; case A_PID4: case A_PID5: @@ -324,7 +457,9 @@ static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr, uint64_t value, unsigned size, MemTxAttrs attrs) { + IoTKitSecCtl *s = IOTKIT_SECCTL(opaque); uint32_t offset = addr; + IoTKitSecCtlPPC *ppc; trace_iotkit_secctl_ns_write(offset, value, size); @@ -340,15 +475,20 @@ static MemTxResult iotkit_secctl_ns_write(void *opaque, hwaddr addr, case A_AHBNSPPPCEXP1: case A_AHBNSPPPCEXP2: case A_AHBNSPPPCEXP3: + ppc = &s->ahbexp[offset_to_ppc_idx(offset)]; + iotkit_secctl_ppc_nsp_write(ppc, value); + break; case A_APBNSPPPC0: case A_APBNSPPPC1: + ppc = &s->apb[offset_to_ppc_idx(offset)]; + iotkit_secctl_ppc_nsp_write(ppc, value); + break; case A_APBNSPPPCEXP0: case A_APBNSPPPCEXP1: case A_APBNSPPPCEXP2: case A_APBNSPPPCEXP3: - qemu_log_mask(LOG_UNIMP, - "IoTKit SecCtl NS block write: " - "unimplemented offset 0x%x\n", offset); + ppc = &s->apbexp[offset_to_ppc_idx(offset)]; + iotkit_secctl_ppc_nsp_write(ppc, value); break; case A_AHBNSPPPC0: case A_PID4: @@ -397,15 +537,90 @@ static const MemoryRegionOps iotkit_secctl_ns_ops = { .impl.max_access_size = 4, }; +static void iotkit_secctl_reset_ppc(IoTKitSecCtlPPC *ppc) +{ + ppc->ns = 0; + ppc->sp = 0; + ppc->nsp = 0; +} + static void iotkit_secctl_reset(DeviceState *dev) { + IoTKitSecCtl *s = IOTKIT_SECCTL(dev); + s->secppcintstat = 0; + s->secppcinten = 0; + s->secrespcfg = 0; + + foreach_ppc(s, iotkit_secctl_reset_ppc); +} + +static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level) +{ + IoTKitSecCtlPPC *ppc = opaque; + IoTKitSecCtl *s = IOTKIT_SECCTL(ppc->parent); + int irqbit = ppc->irq_bit_offset + n; + + s->secppcintstat = deposit32(s->secppcintstat, irqbit, 1, level); +} + +static void iotkit_secctl_init_ppc(IoTKitSecCtl *s, + IoTKitSecCtlPPC *ppc, + const char *name, + int numports, + int irq_bit_offset) +{ + char *gpioname; + DeviceState *dev = DEVICE(s); + + ppc->numports = numports; + ppc->irq_bit_offset = irq_bit_offset; + ppc->parent = s; + + gpioname = g_strdup_printf("%s_nonsec", name); + qdev_init_gpio_out_named(dev, ppc->nonsec, gpioname, numports); + g_free(gpioname); + gpioname = g_strdup_printf("%s_ap", name); + qdev_init_gpio_out_named(dev, ppc->ap, gpioname, numports); + g_free(gpioname); + gpioname = g_strdup_printf("%s_irq_enable", name); + qdev_init_gpio_out_named(dev, &ppc->irq_enable, gpioname, 1); + g_free(gpioname); + gpioname = g_strdup_printf("%s_irq_clear", name); + qdev_init_gpio_out_named(dev, &ppc->irq_clear, gpioname, 1); + g_free(gpioname); + gpioname = g_strdup_printf("%s_irq_status", name); + qdev_init_gpio_in_named_with_opaque(dev, iotkit_secctl_ppc_irqstatus, + ppc, gpioname, 1); + g_free(gpioname); } static void iotkit_secctl_init(Object *obj) { IoTKitSecCtl *s = IOTKIT_SECCTL(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + DeviceState *dev = DEVICE(obj); + int i; + + iotkit_secctl_init_ppc(s, &s->apb[0], "apb_ppc0", + IOTS_APB_PPC0_NUM_PORTS, 0); + iotkit_secctl_init_ppc(s, &s->apb[1], "apb_ppc1", + IOTS_APB_PPC1_NUM_PORTS, 1); + + for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) { + IoTKitSecCtlPPC *ppc = &s->apbexp[i]; + char *ppcname = g_strdup_printf("apb_ppcexp%d", i); + iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 4 + i); + g_free(ppcname); + } + for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) { + IoTKitSecCtlPPC *ppc = &s->ahbexp[i]; + char *ppcname = g_strdup_printf("ahb_ppcexp%d", i); + iotkit_secctl_init_ppc(s, ppc, ppcname, IOTS_PPC_NUM_PORTS, 20 + i); + g_free(ppcname); + } + + qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1); memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops, s, "iotkit-secctl-s-regs", 0x1000); @@ -415,11 +630,32 @@ static void iotkit_secctl_init(Object *obj) sysbus_init_mmio(sbd, &s->ns_regs); } +static const VMStateDescription iotkit_secctl_ppc_vmstate = { + .name = "iotkit-secctl-ppc", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(ns, IoTKitSecCtlPPC), + VMSTATE_UINT32(sp, IoTKitSecCtlPPC), + VMSTATE_UINT32(nsp, IoTKitSecCtlPPC), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription iotkit_secctl_vmstate = { .name = "iotkit-secctl", .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { + VMSTATE_UINT32(secppcintstat, IoTKitSecCtl), + VMSTATE_UINT32(secppcinten, IoTKitSecCtl), + VMSTATE_UINT32(secrespcfg, IoTKitSecCtl), + VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1, + iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), + VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1, + iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), + VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1, + iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), VMSTATE_END_OF_LIST() } }; From patchwork Fri Mar 2 11:06:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880452 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6KT3sqgz9s3m for ; Fri, 2 Mar 2018 22:20:13 +1100 (AEDT) Received: from localhost ([::1]:34124 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erijR-0005q9-Pm for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:20:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43460) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWg-0002zs-Av for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWf-0004vo-7N for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:58 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46766) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWe-0004v9-W4 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:57 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWe-0001Na-12 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:56 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:22 +0000 Message-Id: <20180302110640.28004-22-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 21/39] hw/misc/iotkit-secctl: Add remaining simple registers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add remaining easy registers to iotkit-secctl: * NSCCFG just routes its two bits out to external GPIO lines * BRGINSTAT/BRGINTCLR/BRGINTEN can be dummies, because QEMU's bus fabric can never report errors Signed-off-by: Peter Maydell Message-id: 20180220180325.29818-18-peter.maydell@linaro.org --- include/hw/misc/iotkit-secctl.h | 4 ++++ hw/misc/iotkit-secctl.c | 32 ++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h index ea3d62967f..faad0c9190 100644 --- a/include/hw/misc/iotkit-secctl.h +++ b/include/hw/misc/iotkit-secctl.h @@ -18,6 +18,7 @@ * + sysbus MMIO region 1 is the "non-secure privilege control block" registers * + 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 * 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 @@ -83,6 +84,7 @@ struct IoTKitSecCtl { /*< public >*/ qemu_irq sec_resp_cfg; + qemu_irq nsc_cfg_irq; MemoryRegion s_regs; MemoryRegion ns_regs; @@ -90,6 +92,8 @@ struct IoTKitSecCtl { uint32_t secppcintstat; uint32_t secppcinten; uint32_t secrespcfg; + uint32_t nsccfg; + uint32_t brginten; IoTKitSecCtlPPC apb[IOTS_NUM_APB_PPC]; IoTKitSecCtlPPC apbexp[IOTS_NUM_APB_EXP_PPC]; diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c index 1093f2910f..ddd1584d34 100644 --- a/hw/misc/iotkit-secctl.c +++ b/hw/misc/iotkit-secctl.c @@ -136,12 +136,24 @@ static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr, case A_SECRESPCFG: r = s->secrespcfg; break; + case A_NSCCFG: + r = s->nsccfg; + break; case A_SECPPCINTSTAT: r = s->secppcintstat; break; case A_SECPPCINTEN: r = s->secppcinten; break; + case A_BRGINTSTAT: + /* QEMU's bus fabric can never report errors as it doesn't buffer + * writes, so we never report bridge interrupts. + */ + r = 0; + break; + case A_BRGINTEN: + r = s->brginten; + break; case A_AHBNSPPCEXP0: case A_AHBNSPPCEXP1: case A_AHBNSPPCEXP2: @@ -174,12 +186,9 @@ static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr, case A_APBSPPPCEXP3: r = s->apbexp[offset_to_ppc_idx(offset)].sp; break; - case A_NSCCFG: case A_SECMPCINTSTATUS: case A_SECMSCINTSTAT: case A_SECMSCINTEN: - case A_BRGINTSTAT: - case A_BRGINTEN: case A_NSMSCEXP: qemu_log_mask(LOG_UNIMP, "IoTKit SecCtl S block read: " @@ -298,6 +307,10 @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr, } switch (offset) { + case A_NSCCFG: + s->nsccfg = value & 3; + qemu_set_irq(s->nsc_cfg_irq, s->nsccfg); + break; case A_SECRESPCFG: value &= 1; s->secrespcfg = value; @@ -311,6 +324,11 @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr, s->secppcinten = value & 0x00f000f3; foreach_ppc(s, iotkit_secctl_ppc_update_irq_enable); break; + case A_BRGINTCLR: + break; + case A_BRGINTEN: + s->brginten = value & 0xffff0000; + break; case A_AHBNSPPCEXP0: case A_AHBNSPPCEXP1: case A_AHBNSPPCEXP2: @@ -349,11 +367,8 @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr, ppc = &s->apbexp[offset_to_ppc_idx(offset)]; iotkit_secctl_ppc_sp_write(ppc, value); break; - case A_NSCCFG: case A_SECMSCINTCLR: case A_SECMSCINTEN: - case A_BRGINTCLR: - case A_BRGINTEN: qemu_log_mask(LOG_UNIMP, "IoTKit SecCtl S block write: " "unimplemented offset 0x%x\n", offset); @@ -551,6 +566,8 @@ static void iotkit_secctl_reset(DeviceState *dev) s->secppcintstat = 0; s->secppcinten = 0; s->secrespcfg = 0; + s->nsccfg = 0; + s->brginten = 0; foreach_ppc(s, iotkit_secctl_reset_ppc); } @@ -621,6 +638,7 @@ static void iotkit_secctl_init(Object *obj) } qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1); + qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1); memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops, s, "iotkit-secctl-s-regs", 0x1000); @@ -650,6 +668,8 @@ static const VMStateDescription iotkit_secctl_vmstate = { VMSTATE_UINT32(secppcintstat, IoTKitSecCtl), VMSTATE_UINT32(secppcinten, IoTKitSecCtl), VMSTATE_UINT32(secrespcfg, IoTKitSecCtl), + VMSTATE_UINT32(nsccfg, IoTKitSecCtl), + VMSTATE_UINT32(brginten, IoTKitSecCtl), VMSTATE_STRUCT_ARRAY(apb, IoTKitSecCtl, IOTS_NUM_APB_PPC, 1, iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC), VMSTATE_STRUCT_ARRAY(apbexp, IoTKitSecCtl, IOTS_NUM_APB_EXP_PPC, 1, From patchwork Fri Mar 2 11:06:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880461 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6ST64nxz9s4w for ; Fri, 2 Mar 2018 22:26:17 +1100 (AEDT) Received: from localhost ([::1]:34161 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eripL-0002hc-Rr for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:26:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43517) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWk-00033K-Bo for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWg-0004wG-CD for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:01 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46766) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWf-0004v9-SV for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:58 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWe-0001No-RX for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:56 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:23 +0000 Message-Id: <20180302110640.28004-23-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 22/39] hw/arm/iotkit: Model Arm IOT Kit X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Model the Arm IoT Kit documented in http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html The Arm IoT Kit is a subsystem which includes a CPU and some devices, and is intended be extended by adding extra devices to form a complete system. It is used in the MPS2 board's AN505 image for the Cortex-M33. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-19-peter.maydell@linaro.org --- hw/arm/Makefile.objs | 1 + include/hw/arm/iotkit.h | 109 ++++++++ hw/arm/iotkit.c | 598 ++++++++++++++++++++++++++++++++++++++++ default-configs/arm-softmmu.mak | 1 + 4 files changed, 709 insertions(+) create mode 100644 include/hw/arm/iotkit.h create mode 100644 hw/arm/iotkit.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 1c896bafb4..79cd30bb92 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -20,3 +20,4 @@ obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o obj-$(CONFIG_MPS2) += mps2.o obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o +obj-$(CONFIG_IOTKIT) += iotkit.o diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h new file mode 100644 index 0000000000..c6129d926b --- /dev/null +++ b/include/hw/arm/iotkit.h @@ -0,0 +1,109 @@ +/* + * ARM IoT Kit + * + * 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 Arm IoT Kit which is documented in + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html + * It contains: + * a Cortex-M33 + * the IDAU + * some timers and watchdogs + * two peripheral protection controllers + * a memory protection controller + * a security controller + * a bus fabric which arranges that some parts of the address + * space are secure and non-secure aliases of each other + * + * QEMU interface: + * + QOM property "memory" is a MemoryRegion containing the devices provided + * by the board model. + * + QOM property "MAINCLK" is the frequency of the main system clock + * + 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 + * 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] + * + named GPIO outputs apb_ppcexp{0,1,2,3}_ap[0..15] + * + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_enable + * + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_clear + * + named GPIO inputs apb_ppcexp{0,1,2,3}_irq_status + * Controlling each of the 4 expansion AHB PPCs which a system using the IoTKit + * might provide: + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_nonsec[0..15] + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_ap[0..15] + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable + * + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear + * + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status + */ + +#ifndef IOTKIT_H +#define IOTKIT_H + +#include "hw/sysbus.h" +#include "hw/arm/armv7m.h" +#include "hw/misc/iotkit-secctl.h" +#include "hw/misc/tz-ppc.h" +#include "hw/timer/cmsdk-apb-timer.h" +#include "hw/misc/unimp.h" +#include "hw/or-irq.h" +#include "hw/core/split-irq.h" + +#define TYPE_IOTKIT "iotkit" +#define IOTKIT(obj) OBJECT_CHECK(IoTKit, (obj), TYPE_IOTKIT) + +/* We have an IRQ splitter and an OR gate input for each external PPC + * and the 2 internal PPCs + */ +#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC) +#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2) + +typedef struct IoTKit { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + ARMv7MState armv7m; + IoTKitSecCtl secctl; + TZPPC apb_ppc0; + TZPPC apb_ppc1; + CMSDKAPBTIMER timer0; + CMSDKAPBTIMER timer1; + qemu_or_irq ppc_irq_orgate; + SplitIRQ sec_resp_splitter; + SplitIRQ ppc_irq_splitter[NUM_PPCS]; + + UnimplementedDeviceState dualtimer; + UnimplementedDeviceState s32ktimer; + + MemoryRegion container; + MemoryRegion alias1; + MemoryRegion alias2; + MemoryRegion alias3; + MemoryRegion sram0; + + qemu_irq *exp_irqs; + qemu_irq ppc0_irq; + qemu_irq ppc1_irq; + qemu_irq sec_resp_cfg; + qemu_irq sec_resp_cfg_in; + qemu_irq nsc_cfg_in; + + qemu_irq irq_status_in[NUM_EXTERNAL_PPCS]; + + uint32_t nsccfg; + + /* Properties */ + MemoryRegion *board_memory; + uint32_t exp_numirq; + uint32_t mainclk_frq; +} IoTKit; + +#endif diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c new file mode 100644 index 0000000000..c5f0a5b98a --- /dev/null +++ b/hw/arm/iotkit.c @@ -0,0 +1,598 @@ +/* + * Arm IoT Kit + * + * 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/arm/iotkit.h" +#include "hw/misc/unimp.h" +#include "hw/arm/arm.h" + +/* Create an alias region of @size bytes starting at @base + * which mirrors the memory starting at @orig. + */ +static void make_alias(IoTKit *s, MemoryRegion *mr, const char *name, + hwaddr base, hwaddr size, hwaddr orig) +{ + memory_region_init_alias(mr, NULL, name, &s->container, orig, size); + /* The alias is even lower priority than unimplemented_device regions */ + memory_region_add_subregion_overlap(&s->container, base, mr, -1500); +} + +static void init_sysbus_child(Object *parent, const char *childname, + void *child, size_t childsize, + const char *childtype) +{ + object_initialize(child, childsize, childtype); + object_property_add_child(parent, childname, OBJECT(child), &error_abort); + qdev_set_parent_bus(DEVICE(child), sysbus_get_default()); +} + +static void irq_status_forwarder(void *opaque, int n, int level) +{ + qemu_irq destirq = opaque; + + qemu_set_irq(destirq, level); +} + +static void nsccfg_handler(void *opaque, int n, int level) +{ + IoTKit *s = IOTKIT(opaque); + + s->nsccfg = level; +} + +static void iotkit_forward_ppc(IoTKit *s, const char *ppcname, int ppcnum) +{ + /* Each of the 4 AHB and 4 APB PPCs that might be present in a + * system using the IoTKit has a collection of control lines which + * are provided by the security controller and which we want to + * expose as control lines on the IoTKit device itself, so the + * code using the IoTKit can wire them up to the PPCs. + */ + SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum]; + DeviceState *iotkitdev = DEVICE(s); + DeviceState *dev_secctl = DEVICE(&s->secctl); + DeviceState *dev_splitter = DEVICE(splitter); + char *name; + + name = g_strdup_printf("%s_nonsec", ppcname); + qdev_pass_gpios(dev_secctl, iotkitdev, name); + g_free(name); + name = g_strdup_printf("%s_ap", ppcname); + qdev_pass_gpios(dev_secctl, iotkitdev, name); + g_free(name); + name = g_strdup_printf("%s_irq_enable", ppcname); + qdev_pass_gpios(dev_secctl, iotkitdev, name); + g_free(name); + name = g_strdup_printf("%s_irq_clear", ppcname); + qdev_pass_gpios(dev_secctl, iotkitdev, name); + g_free(name); + + /* irq_status is a little more tricky, because we need to + * split it so we can send it both to the security controller + * and to our OR gate for the NVIC interrupt line. + * Connect up the splitter's outputs, and create a GPIO input + * which will pass the line state to the input splitter. + */ + name = g_strdup_printf("%s_irq_status", ppcname); + qdev_connect_gpio_out(dev_splitter, 0, + qdev_get_gpio_in_named(dev_secctl, + name, 0)); + qdev_connect_gpio_out(dev_splitter, 1, + qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum)); + s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0); + qdev_init_gpio_in_named_with_opaque(iotkitdev, irq_status_forwarder, + s->irq_status_in[ppcnum], name, 1); + g_free(name); +} + +static void iotkit_forward_sec_resp_cfg(IoTKit *s) +{ + /* Forward the 3rd output from the splitter device as a + * named GPIO output of the iotkit object. + */ + DeviceState *dev = DEVICE(s); + DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter); + + qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1); + s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder, + s->sec_resp_cfg, 1); + qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in); +} + +static void iotkit_init(Object *obj) +{ + IoTKit *s = IOTKIT(obj); + int i; + + memory_region_init(&s->container, obj, "iotkit-container", UINT64_MAX); + + init_sysbus_child(obj, "armv7m", &s->armv7m, sizeof(s->armv7m), + TYPE_ARMV7M); + qdev_prop_set_string(DEVICE(&s->armv7m), "cpu-type", + ARM_CPU_TYPE_NAME("cortex-m33")); + + init_sysbus_child(obj, "secctl", &s->secctl, sizeof(s->secctl), + TYPE_IOTKIT_SECCTL); + init_sysbus_child(obj, "apb-ppc0", &s->apb_ppc0, sizeof(s->apb_ppc0), + TYPE_TZ_PPC); + init_sysbus_child(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1), + TYPE_TZ_PPC); + init_sysbus_child(obj, "timer0", &s->timer0, sizeof(s->timer0), + TYPE_CMSDK_APB_TIMER); + init_sysbus_child(obj, "timer1", &s->timer1, sizeof(s->timer1), + TYPE_CMSDK_APB_TIMER); + init_sysbus_child(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer), + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize(&s->ppc_irq_orgate, sizeof(s->ppc_irq_orgate), + TYPE_OR_IRQ); + object_property_add_child(obj, "ppc-irq-orgate", + OBJECT(&s->ppc_irq_orgate), &error_abort); + object_initialize(&s->sec_resp_splitter, sizeof(s->sec_resp_splitter), + TYPE_SPLIT_IRQ); + object_property_add_child(obj, "sec-resp-splitter", + OBJECT(&s->sec_resp_splitter), &error_abort); + for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) { + char *name = g_strdup_printf("ppc-irq-splitter-%d", i); + SplitIRQ *splitter = &s->ppc_irq_splitter[i]; + + object_initialize(splitter, sizeof(*splitter), TYPE_SPLIT_IRQ); + object_property_add_child(obj, name, OBJECT(splitter), &error_abort); + } + init_sysbus_child(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer), + TYPE_UNIMPLEMENTED_DEVICE); +} + +static void iotkit_exp_irq(void *opaque, int n, int level) +{ + IoTKit *s = IOTKIT(opaque); + + qemu_set_irq(s->exp_irqs[n], level); +} + +static void iotkit_realize(DeviceState *dev, Error **errp) +{ + IoTKit *s = IOTKIT(dev); + int i; + MemoryRegion *mr; + Error *err = NULL; + SysBusDevice *sbd_apb_ppc0; + SysBusDevice *sbd_secctl; + DeviceState *dev_apb_ppc0; + DeviceState *dev_apb_ppc1; + DeviceState *dev_secctl; + DeviceState *dev_splitter; + + if (!s->board_memory) { + error_setg(errp, "memory property was not set"); + return; + } + + if (!s->mainclk_frq) { + error_setg(errp, "MAINCLK property was not set"); + return; + } + + /* Handling of which devices should be available only to secure + * code is usually done differently for M profile than for A profile. + * Instead of putting some devices only into the secure address space, + * devices exist in both address spaces but with hard-wired security + * permissions that will cause the CPU to fault for non-secure accesses. + * + * The IoTKit has an IDAU (Implementation Defined Access Unit), + * which specifies hard-wired security permissions for different + * areas of the physical address space. For the IoTKit IDAU, the + * top 4 bits of the physical address are the IDAU region ID, and + * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS + * region, otherwise it is an S region. + * + * The various devices and RAMs are generally all mapped twice, + * once into a region that the IDAU defines as secure and once + * into a non-secure region. They sit behind either a Memory + * Protection Controller (for RAM) or a Peripheral Protection + * Controller (for devices), which allow a more fine grained + * configuration of whether non-secure accesses are permitted. + * + * (The other place that guest software can configure security + * permissions is in the architected SAU (Security Attribution + * Unit), which is entirely inside the CPU. The IDAU can upgrade + * the security attributes for a region to more restrictive than + * the SAU specifies, but cannot downgrade them.) + * + * 0x10000000..0x1fffffff alias of 0x00000000..0x0fffffff + * 0x20000000..0x2007ffff 32KB FPGA block RAM + * 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff + * 0x40000000..0x4000ffff base peripheral region 1 + * 0x40010000..0x4001ffff CPU peripherals (none for IoTKit) + * 0x40020000..0x4002ffff system control element peripherals + * 0x40080000..0x400fffff base peripheral region 2 + * 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff + */ + + memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1); + + qdev_prop_set_uint32(DEVICE(&s->armv7m), "num-irq", s->exp_numirq + 32); + /* In real hardware the initial Secure VTOR is set from the INITSVTOR0 + * register in the IoT Kit System Control Register block, and the + * initial value of that is in turn specifiable by the FPGA that + * instantiates the IoT Kit. In QEMU we don't implement this wrinkle, + * and simply set the CPU's init-svtor to the IoT Kit default value. + */ + qdev_prop_set_uint32(DEVICE(&s->armv7m), "init-svtor", 0x10000000); + object_property_set_link(OBJECT(&s->armv7m), OBJECT(&s->container), + "memory", &err); + if (err) { + error_propagate(errp, err); + return; + } + object_property_set_link(OBJECT(&s->armv7m), OBJECT(s), "idau", &err); + if (err) { + error_propagate(errp, err); + return; + } + object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + + /* Connect our EXP_IRQ GPIOs to the NVIC's lines 32 and up. */ + s->exp_irqs = g_new(qemu_irq, s->exp_numirq); + for (i = 0; i < s->exp_numirq; i++) { + s->exp_irqs[i] = qdev_get_gpio_in(DEVICE(&s->armv7m), i + 32); + } + qdev_init_gpio_in_named(dev, iotkit_exp_irq, "EXP_IRQ", s->exp_numirq); + + /* Set up the big aliases first */ + make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000); + make_alias(s, &s->alias2, "alias 2", 0x30000000, 0x10000000, 0x20000000); + /* The 0x50000000..0x5fffffff region is not a pure alias: it has + * a few extra devices that only appear there (generally the + * control interfaces for the protection controllers). + * We implement this by mapping those devices over the top of this + * alias MR at a higher priority. + */ + make_alias(s, &s->alias3, "alias 3", 0x50000000, 0x10000000, 0x40000000); + + /* This RAM should be behind a Memory Protection Controller, but we + * don't implement that yet. + */ + memory_region_init_ram(&s->sram0, NULL, "iotkit.sram0", 0x00008000, &err); + if (err) { + error_propagate(errp, err); + return; + } + memory_region_add_subregion(&s->container, 0x20000000, &s->sram0); + + /* Security controller */ + object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + sbd_secctl = SYS_BUS_DEVICE(&s->secctl); + dev_secctl = DEVICE(&s->secctl); + sysbus_mmio_map(sbd_secctl, 0, 0x50080000); + sysbus_mmio_map(sbd_secctl, 1, 0x40080000); + + s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1); + qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in); + + /* The sec_resp_cfg output from the security controller must be split into + * multiple lines, one for each of the PPCs within the IoTKit and one + * that will be an output from the IoTKit to the system. + */ + object_property_set_int(OBJECT(&s->sec_resp_splitter), 3, + "num-lines", &err); + if (err) { + error_propagate(errp, err); + return; + } + object_property_set_bool(OBJECT(&s->sec_resp_splitter), true, + "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + dev_splitter = DEVICE(&s->sec_resp_splitter); + qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0, + qdev_get_gpio_in(dev_splitter, 0)); + + /* Devices behind APB PPC0: + * 0x40000000: timer0 + * 0x40001000: timer1 + * 0x40002000: dual timer + * We must configure and realize each downstream device and connect + * it to the appropriate PPC port; then we can realize the PPC and + * map its upstream ends to the right place in the container. + */ + qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq); + object_property_set_bool(OBJECT(&s->timer0), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0, + qdev_get_gpio_in(DEVICE(&s->armv7m), 3)); + mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0); + object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err); + if (err) { + error_propagate(errp, err); + return; + } + + qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq); + object_property_set_bool(OBJECT(&s->timer1), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0, + qdev_get_gpio_in(DEVICE(&s->armv7m), 3)); + mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0); + object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err); + if (err) { + error_propagate(errp, err); + return; + } + + qdev_prop_set_string(DEVICE(&s->dualtimer), "name", "Dual timer"); + qdev_prop_set_uint64(DEVICE(&s->dualtimer), "size", 0x1000); + object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0); + object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err); + if (err) { + error_propagate(errp, err); + return; + } + + object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + + sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0); + dev_apb_ppc0 = DEVICE(&s->apb_ppc0); + + mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0); + memory_region_add_subregion(&s->container, 0x40000000, mr); + mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1); + memory_region_add_subregion(&s->container, 0x40001000, mr); + mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2); + memory_region_add_subregion(&s->container, 0x40002000, mr); + for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) { + qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i, + qdev_get_gpio_in_named(dev_apb_ppc0, + "cfg_nonsec", i)); + qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i, + qdev_get_gpio_in_named(dev_apb_ppc0, + "cfg_ap", i)); + } + qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0, + qdev_get_gpio_in_named(dev_apb_ppc0, + "irq_enable", 0)); + qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0, + qdev_get_gpio_in_named(dev_apb_ppc0, + "irq_clear", 0)); + qdev_connect_gpio_out(dev_splitter, 0, + qdev_get_gpio_in_named(dev_apb_ppc0, + "cfg_sec_resp", 0)); + + /* All the PPC irq lines (from the 2 internal PPCs and the 8 external + * ones) are sent individually to the security controller, and also + * ORed together to give a single combined PPC interrupt to the NVIC. + */ + object_property_set_int(OBJECT(&s->ppc_irq_orgate), + NUM_PPCS, "num-lines", &err); + if (err) { + error_propagate(errp, err); + return; + } + object_property_set_bool(OBJECT(&s->ppc_irq_orgate), true, + "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0, + qdev_get_gpio_in(DEVICE(&s->armv7m), 10)); + + /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */ + + /* 0x40020000 .. 0x4002ffff : IoTKit system control peripheral region */ + /* 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); + object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + 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) { + error_propagate(errp, err); + return; + } + + object_property_set_bool(OBJECT(&s->apb_ppc1), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0); + memory_region_add_subregion(&s->container, 0x4002f000, mr); + + dev_apb_ppc1 = DEVICE(&s->apb_ppc1); + qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0, + qdev_get_gpio_in_named(dev_apb_ppc1, + "cfg_nonsec", 0)); + qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0, + qdev_get_gpio_in_named(dev_apb_ppc1, + "cfg_ap", 0)); + qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0, + qdev_get_gpio_in_named(dev_apb_ppc1, + "irq_enable", 0)); + qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0, + qdev_get_gpio_in_named(dev_apb_ppc1, + "irq_clear", 0)); + qdev_connect_gpio_out(dev_splitter, 1, + 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); + create_unimplemented_device("S32KWATCHDOG", 0x5002e000, 0x1000); + + /* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */ + + create_unimplemented_device("NS watchdog", 0x40081000, 0x1000); + create_unimplemented_device("S watchdog", 0x50081000, 0x1000); + + create_unimplemented_device("SRAM0 MPC", 0x50083000, 0x1000); + + for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) { + Object *splitter = OBJECT(&s->ppc_irq_splitter[i]); + + object_property_set_int(splitter, 2, "num-lines", &err); + if (err) { + error_propagate(errp, err); + return; + } + object_property_set_bool(splitter, true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + } + + for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) { + char *ppcname = g_strdup_printf("ahb_ppcexp%d", i); + + iotkit_forward_ppc(s, ppcname, i); + g_free(ppcname); + } + + for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) { + char *ppcname = g_strdup_printf("apb_ppcexp%d", i); + + iotkit_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC); + g_free(ppcname); + } + + for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) { + /* Wire up IRQ splitter for internal PPCs */ + DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]); + char *gpioname = g_strdup_printf("apb_ppc%d_irq_status", + i - NUM_EXTERNAL_PPCS); + TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1; + + qdev_connect_gpio_out(devs, 0, + qdev_get_gpio_in_named(dev_secctl, gpioname, 0)); + qdev_connect_gpio_out(devs, 1, + qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i)); + qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0, + qdev_get_gpio_in(devs, 0)); + } + + iotkit_forward_sec_resp_cfg(s); + + system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq; +} + +static void iotkit_idau_check(IDAUInterface *ii, uint32_t address, + int *iregion, bool *exempt, bool *ns, bool *nsc) +{ + /* For IoTKit systems the IDAU responses are simple logical functions + * of the address bits. The NSC attribute is guest-adjustable via the + * NSCCFG register in the security controller. + */ + IoTKit *s = IOTKIT(ii); + int region = extract32(address, 28, 4); + + *ns = !(region & 1); + *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2)); + /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */ + *exempt = (address & 0xeff00000) == 0xe0000000; + *iregion = region; +} + +static const VMStateDescription iotkit_vmstate = { + .name = "iotkit", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(nsccfg, IoTKit), + VMSTATE_END_OF_LIST() + } +}; + +static Property iotkit_properties[] = { + DEFINE_PROP_LINK("memory", IoTKit, board_memory, TYPE_MEMORY_REGION, + MemoryRegion *), + DEFINE_PROP_UINT32("EXP_NUMIRQ", IoTKit, exp_numirq, 64), + DEFINE_PROP_UINT32("MAINCLK", IoTKit, mainclk_frq, 0), + DEFINE_PROP_END_OF_LIST() +}; + +static void iotkit_reset(DeviceState *dev) +{ + IoTKit *s = IOTKIT(dev); + + s->nsccfg = 0; +} + +static void iotkit_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass); + + dc->realize = iotkit_realize; + dc->vmsd = &iotkit_vmstate; + dc->props = iotkit_properties; + dc->reset = iotkit_reset; + iic->check = iotkit_idau_check; +} + +static const TypeInfo iotkit_info = { + .name = TYPE_IOTKIT, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(IoTKit), + .instance_init = iotkit_init, + .class_init = iotkit_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_IDAU_INTERFACE }, + { } + } +}; + +static void iotkit_register_types(void) +{ + type_register_static(&iotkit_info); +} + +type_init(iotkit_register_types); diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index f914a7486e..d724106bd3 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -106,6 +106,7 @@ CONFIG_MPS2_FPGAIO=y CONFIG_MPS2_SCC=y CONFIG_TZ_PPC=y +CONFIG_IOTKIT=y CONFIG_IOTKIT_SECCTL=y CONFIG_VERSATILE_PCI=y From patchwork Fri Mar 2 11:06:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880460 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6Rn1kwSz9s5H for ; Fri, 2 Mar 2018 22:25:38 +1100 (AEDT) Received: from localhost ([::1]:34154 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erioh-00025j-DB for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:25:35 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43522) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWk-00033N-Bv for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWh-0004wf-07 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:01 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46768) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWg-0004w4-Gv for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:58 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWf-0001O4-Hj for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:57 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:24 +0000 Message-Id: <20180302110640.28004-24-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 23/39] mps2-an505: New board model: MPS2 with AN505 Cortex-M33 FPGA image X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Define a new board model for the MPS2 with an AN505 FPGA image containing a Cortex-M33. Since the FPGA images for TrustZone cores (AN505, and the similar AN519 for Cortex-M23) have a significantly different layout of devices to the non-TrustZone images, we use a new source file rather than shoehorning them into the existing mps2.c. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20180220180325.29818-20-peter.maydell@linaro.org --- hw/arm/Makefile.objs | 1 + hw/arm/mps2-tz.c | 503 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 504 insertions(+) create mode 100644 hw/arm/mps2-tz.c diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 79cd30bb92..232258160a 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -19,5 +19,6 @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o obj-$(CONFIG_MPS2) += mps2.o +obj-$(CONFIG_MPS2) += mps2-tz.o obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o obj-$(CONFIG_IOTKIT) += iotkit.o diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c new file mode 100644 index 0000000000..8c86cffa9e --- /dev/null +++ b/hw/arm/mps2-tz.c @@ -0,0 +1,503 @@ +/* + * ARM V2M MPS2 board emulation, trustzone aware FPGA images + * + * Copyright (c) 2017 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. + */ + +/* The MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger + * FPGA but is otherwise the same as the 2). Since the CPU itself + * and most of the devices are in the FPGA, the details of the board + * as seen by the guest depend significantly on the FPGA image. + * This source file covers the following FPGA images, for TrustZone cores: + * "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505 + * + * Links to the TRM for the board itself and to the various Application + * Notes which document the FPGA images can be found here: + * https://developer.arm.com/products/system-design/development-boards/fpga-prototyping-boards/mps2 + * + * Board TRM: + * http://infocenter.arm.com/help/topic/com.arm.doc.100112_0200_06_en/versatile_express_cortex_m_prototyping_systems_v2m_mps2_and_v2m_mps2plus_technical_reference_100112_0200_06_en.pdf + * Application Note AN505: + * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html + * + * The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide + * (ARM ECM0601256) for the details of some of the device layout: + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "hw/arm/arm.h" +#include "hw/arm/armv7m.h" +#include "hw/or-irq.h" +#include "hw/boards.h" +#include "exec/address-spaces.h" +#include "sysemu/sysemu.h" +#include "hw/misc/unimp.h" +#include "hw/char/cmsdk-apb-uart.h" +#include "hw/timer/cmsdk-apb-timer.h" +#include "hw/misc/mps2-scc.h" +#include "hw/misc/mps2-fpgaio.h" +#include "hw/arm/iotkit.h" +#include "hw/devices.h" +#include "net/net.h" +#include "hw/core/split-irq.h" + +typedef enum MPS2TZFPGAType { + FPGA_AN505, +} MPS2TZFPGAType; + +typedef struct { + MachineClass parent; + MPS2TZFPGAType fpga_type; + uint32_t scc_id; +} MPS2TZMachineClass; + +typedef struct { + MachineState parent; + + IoTKit iotkit; + MemoryRegion psram; + MemoryRegion ssram1; + MemoryRegion ssram1_m; + MemoryRegion ssram23; + MPS2SCC scc; + MPS2FPGAIO fpgaio; + TZPPC ppc[5]; + UnimplementedDeviceState ssram_mpc[3]; + UnimplementedDeviceState spi[5]; + UnimplementedDeviceState i2c[4]; + UnimplementedDeviceState i2s_audio; + UnimplementedDeviceState gpio[5]; + UnimplementedDeviceState dma[4]; + UnimplementedDeviceState gfx; + CMSDKAPBUART uart[5]; + SplitIRQ sec_resp_splitter; + qemu_or_irq uart_irq_orgate; +} MPS2TZMachineState; + +#define TYPE_MPS2TZ_MACHINE "mps2tz" +#define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505") + +#define MPS2TZ_MACHINE(obj) \ + OBJECT_CHECK(MPS2TZMachineState, obj, TYPE_MPS2TZ_MACHINE) +#define MPS2TZ_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(MPS2TZMachineClass, obj, TYPE_MPS2TZ_MACHINE) +#define MPS2TZ_MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(MPS2TZMachineClass, klass, TYPE_MPS2TZ_MACHINE) + +/* Main SYSCLK frequency in Hz */ +#define SYSCLK_FRQ 20000000 + +/* Initialize the auxiliary RAM region @mr and map it into + * the memory map at @base. + */ +static void make_ram(MemoryRegion *mr, const char *name, + hwaddr base, hwaddr size) +{ + memory_region_init_ram(mr, NULL, name, size, &error_fatal); + memory_region_add_subregion(get_system_memory(), base, mr); +} + +/* Create an alias of an entire original MemoryRegion @orig + * located at @base in the memory map. + */ +static void make_ram_alias(MemoryRegion *mr, const char *name, + MemoryRegion *orig, hwaddr base) +{ + memory_region_init_alias(mr, NULL, name, orig, 0, + memory_region_size(orig)); + memory_region_add_subregion(get_system_memory(), base, mr); +} + +static void init_sysbus_child(Object *parent, const char *childname, + void *child, size_t childsize, + const char *childtype) +{ + object_initialize(child, childsize, childtype); + object_property_add_child(parent, childname, OBJECT(child), &error_abort); + qdev_set_parent_bus(DEVICE(child), sysbus_get_default()); + +} + +/* Most of the devices in the AN505 FPGA image sit behind + * Peripheral Protection Controllers. These data structures + * define the layout of which devices sit behind which PPCs. + * The devfn for each port is a function which creates, configures + * and initializes the device, returning the MemoryRegion which + * needs to be plugged into the downstream end of the PPC port. + */ +typedef MemoryRegion *MakeDevFn(MPS2TZMachineState *mms, void *opaque, + const char *name, hwaddr size); + +typedef struct PPCPortInfo { + const char *name; + MakeDevFn *devfn; + void *opaque; + hwaddr addr; + hwaddr size; +} PPCPortInfo; + +typedef struct PPCInfo { + const char *name; + PPCPortInfo ports[TZ_NUM_PORTS]; +} PPCInfo; + +static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms, + void *opaque, + const char *name, hwaddr size) +{ + /* Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE, + * and return a pointer to its MemoryRegion. + */ + UnimplementedDeviceState *uds = opaque; + + init_sysbus_child(OBJECT(mms), name, uds, + sizeof(UnimplementedDeviceState), + TYPE_UNIMPLEMENTED_DEVICE); + qdev_prop_set_string(DEVICE(uds), "name", name); + qdev_prop_set_uint64(DEVICE(uds), "size", size); + object_property_set_bool(OBJECT(uds), true, "realized", &error_fatal); + return sysbus_mmio_get_region(SYS_BUS_DEVICE(uds), 0); +} + +static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque, + const char *name, hwaddr size) +{ + CMSDKAPBUART *uart = opaque; + int i = uart - &mms->uart[0]; + Chardev *uartchr = i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL; + int rxirqno = i * 2; + int txirqno = i * 2 + 1; + int combirqno = i + 10; + SysBusDevice *s; + DeviceState *iotkitdev = DEVICE(&mms->iotkit); + DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate); + + init_sysbus_child(OBJECT(mms), name, uart, + sizeof(mms->uart[0]), TYPE_CMSDK_APB_UART); + qdev_prop_set_chr(DEVICE(uart), "chardev", uartchr); + qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ); + object_property_set_bool(OBJECT(uart), true, "realized", &error_fatal); + s = SYS_BUS_DEVICE(uart); + sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev, + "EXP_IRQ", txirqno)); + sysbus_connect_irq(s, 1, qdev_get_gpio_in_named(iotkitdev, + "EXP_IRQ", rxirqno)); + sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2)); + sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1)); + sysbus_connect_irq(s, 4, qdev_get_gpio_in_named(iotkitdev, + "EXP_IRQ", combirqno)); + return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0); +} + +static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque, + const char *name, hwaddr size) +{ + MPS2SCC *scc = opaque; + DeviceState *sccdev; + MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms); + + object_initialize(scc, sizeof(mms->scc), TYPE_MPS2_SCC); + sccdev = DEVICE(scc); + qdev_set_parent_bus(sccdev, sysbus_get_default()); + qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2); + qdev_prop_set_uint32(sccdev, "scc-aid", 0x02000008); + qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id); + object_property_set_bool(OBJECT(scc), true, "realized", &error_fatal); + return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0); +} + +static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque, + const char *name, hwaddr size) +{ + MPS2FPGAIO *fpgaio = opaque; + + object_initialize(fpgaio, sizeof(mms->fpgaio), TYPE_MPS2_FPGAIO); + qdev_set_parent_bus(DEVICE(fpgaio), sysbus_get_default()); + object_property_set_bool(OBJECT(fpgaio), true, "realized", &error_fatal); + return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0); +} + +static void mps2tz_common_init(MachineState *machine) +{ + MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine); + MachineClass *mc = MACHINE_GET_CLASS(machine); + MemoryRegion *system_memory = get_system_memory(); + DeviceState *iotkitdev; + DeviceState *dev_splitter; + int i; + + if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) { + error_report("This board can only be used with CPU %s", + mc->default_cpu_type); + exit(1); + } + + init_sysbus_child(OBJECT(machine), "iotkit", &mms->iotkit, + sizeof(mms->iotkit), TYPE_IOTKIT); + iotkitdev = DEVICE(&mms->iotkit); + object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory), + "memory", &error_abort); + qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", 92); + qdev_prop_set_uint32(iotkitdev, "MAINCLK", SYSCLK_FRQ); + object_property_set_bool(OBJECT(&mms->iotkit), true, "realized", + &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. + */ + 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, + "num-lines", &error_fatal); + object_property_set_bool(OBJECT(&mms->sec_resp_splitter), true, + "realized", &error_fatal); + dev_splitter = DEVICE(&mms->sec_resp_splitter); + qdev_connect_gpio_out_named(iotkitdev, "sec_resp_cfg", 0, + qdev_get_gpio_in(dev_splitter, 0)); + + /* The IoTKit sets up much of the memory layout, including + * the aliases between secure and non-secure regions in the + * address space. The FPGA itself contains: + * + * 0x00000000..0x003fffff SSRAM1 + * 0x00400000..0x007fffff alias of SSRAM1 + * 0x28000000..0x283fffff 4MB SSRAM2 + SSRAM3 + * 0x40100000..0x4fffffff AHB Master Expansion 1 interface devices + * 0x80000000..0x80ffffff 16MB PSRAM + */ + + /* The FPGA images have an odd combination of different RAMs, + * because in hardware they are different implementations and + * connected to different buses, giving varying performance/size + * tradeoffs. For QEMU they're all just RAM, though. We arbitrarily + * call the 16MB our "system memory", as it's the largest lump. + */ + memory_region_allocate_system_memory(&mms->psram, + NULL, "mps.ram", 0x01000000); + memory_region_add_subregion(system_memory, 0x80000000, &mms->psram); + + /* The SSRAM memories should all be behind Memory Protection Controllers, + * but we don't implement that yet. + */ + make_ram(&mms->ssram1, "mps.ssram1", 0x00000000, 0x00400000); + make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", &mms->ssram1, 0x00400000); + + make_ram(&mms->ssram23, "mps.ssram23", 0x28000000, 0x00400000); + + /* The overflow IRQs for all UARTs are ORed together. + * Tx, Rx and "combined" IRQs are sent to the NVIC separately. + * Create the OR gate for this. + */ + object_initialize(&mms->uart_irq_orgate, sizeof(mms->uart_irq_orgate), + TYPE_OR_IRQ); + object_property_add_child(OBJECT(mms), "uart-irq-orgate", + OBJECT(&mms->uart_irq_orgate), &error_abort); + object_property_set_int(OBJECT(&mms->uart_irq_orgate), 10, "num-lines", + &error_fatal); + object_property_set_bool(OBJECT(&mms->uart_irq_orgate), true, + "realized", &error_fatal); + qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0, + qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 15)); + + /* Most of the devices in the FPGA are behind Peripheral Protection + * Controllers. The required order for initializing things is: + * + initialize the PPC + * + initialize, configure and realize downstream devices + * + connect downstream device MemoryRegions to the PPC + * + realize the PPC + * + map the PPC's MemoryRegions to the places in the address map + * where the downstream devices should appear + * + wire up the PPC's control lines to the IoTKit object + */ + + const PPCInfo ppcs[] = { { + .name = "apb_ppcexp0", + .ports = { + { "ssram-mpc0", make_unimp_dev, &mms->ssram_mpc[0], + 0x58007000, 0x1000 }, + { "ssram-mpc1", make_unimp_dev, &mms->ssram_mpc[1], + 0x58008000, 0x1000 }, + { "ssram-mpc2", make_unimp_dev, &mms->ssram_mpc[2], + 0x58009000, 0x1000 }, + }, + }, { + .name = "apb_ppcexp1", + .ports = { + { "spi0", make_unimp_dev, &mms->spi[0], 0x40205000, 0x1000 }, + { "spi1", make_unimp_dev, &mms->spi[1], 0x40206000, 0x1000 }, + { "spi2", make_unimp_dev, &mms->spi[2], 0x40209000, 0x1000 }, + { "spi3", make_unimp_dev, &mms->spi[3], 0x4020a000, 0x1000 }, + { "spi4", make_unimp_dev, &mms->spi[4], 0x4020b000, 0x1000 }, + { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000 }, + { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000 }, + { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 }, + { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 }, + { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 }, + { "i2c0", make_unimp_dev, &mms->i2c[0], 0x40207000, 0x1000 }, + { "i2c1", make_unimp_dev, &mms->i2c[1], 0x40208000, 0x1000 }, + { "i2c2", make_unimp_dev, &mms->i2c[2], 0x4020c000, 0x1000 }, + { "i2c3", make_unimp_dev, &mms->i2c[3], 0x4020d000, 0x1000 }, + }, + }, { + .name = "apb_ppcexp2", + .ports = { + { "scc", make_scc, &mms->scc, 0x40300000, 0x1000 }, + { "i2s-audio", make_unimp_dev, &mms->i2s_audio, + 0x40301000, 0x1000 }, + { "fpgaio", make_fpgaio, &mms->fpgaio, 0x40302000, 0x1000 }, + }, + }, { + .name = "ahb_ppcexp0", + .ports = { + { "gfx", make_unimp_dev, &mms->gfx, 0x41000000, 0x140000 }, + { "gpio0", make_unimp_dev, &mms->gpio[0], 0x40100000, 0x1000 }, + { "gpio1", make_unimp_dev, &mms->gpio[1], 0x40101000, 0x1000 }, + { "gpio2", make_unimp_dev, &mms->gpio[2], 0x40102000, 0x1000 }, + { "gpio3", make_unimp_dev, &mms->gpio[3], 0x40103000, 0x1000 }, + { "gpio4", make_unimp_dev, &mms->gpio[4], 0x40104000, 0x1000 }, + }, + }, { + .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 }, + }, + }, + }; + + for (i = 0; i < ARRAY_SIZE(ppcs); i++) { + const PPCInfo *ppcinfo = &ppcs[i]; + TZPPC *ppc = &mms->ppc[i]; + DeviceState *ppcdev; + int port; + char *gpioname; + + init_sysbus_child(OBJECT(machine), ppcinfo->name, ppc, + sizeof(TZPPC), TYPE_TZ_PPC); + ppcdev = DEVICE(ppc); + + for (port = 0; port < TZ_NUM_PORTS; port++) { + const PPCPortInfo *pinfo = &ppcinfo->ports[port]; + MemoryRegion *mr; + char *portname; + + if (!pinfo->devfn) { + continue; + } + + mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size); + portname = g_strdup_printf("port[%d]", port); + object_property_set_link(OBJECT(ppc), OBJECT(mr), + portname, &error_fatal); + g_free(portname); + } + + object_property_set_bool(OBJECT(ppc), true, "realized", &error_fatal); + + for (port = 0; port < TZ_NUM_PORTS; port++) { + const PPCPortInfo *pinfo = &ppcinfo->ports[port]; + + if (!pinfo->devfn) { + continue; + } + sysbus_mmio_map(SYS_BUS_DEVICE(ppc), port, pinfo->addr); + + gpioname = g_strdup_printf("%s_nonsec", ppcinfo->name); + qdev_connect_gpio_out_named(iotkitdev, gpioname, port, + qdev_get_gpio_in_named(ppcdev, + "cfg_nonsec", + port)); + g_free(gpioname); + gpioname = g_strdup_printf("%s_ap", ppcinfo->name); + qdev_connect_gpio_out_named(iotkitdev, gpioname, port, + qdev_get_gpio_in_named(ppcdev, + "cfg_ap", port)); + g_free(gpioname); + } + + gpioname = g_strdup_printf("%s_irq_enable", ppcinfo->name); + qdev_connect_gpio_out_named(iotkitdev, gpioname, 0, + qdev_get_gpio_in_named(ppcdev, + "irq_enable", 0)); + g_free(gpioname); + gpioname = g_strdup_printf("%s_irq_clear", ppcinfo->name); + qdev_connect_gpio_out_named(iotkitdev, gpioname, 0, + qdev_get_gpio_in_named(ppcdev, + "irq_clear", 0)); + g_free(gpioname); + gpioname = g_strdup_printf("%s_irq_status", ppcinfo->name); + qdev_connect_gpio_out_named(ppcdev, "irq", 0, + qdev_get_gpio_in_named(iotkitdev, + gpioname, 0)); + g_free(gpioname); + + qdev_connect_gpio_out(dev_splitter, i, + qdev_get_gpio_in_named(ppcdev, + "cfg_sec_resp", 0)); + } + + /* In hardware this is a LAN9220; the LAN9118 is software compatible + * except that it doesn't support the checksum-offload feature. + * The ethernet controller is not behind a PPC. + */ + lan9118_init(&nd_table[0], 0x42000000, + qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 16)); + + create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000); + + armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000); +} + +static void mps2tz_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->init = mps2tz_common_init; + mc->max_cpus = 1; +} + +static void mps2tz_an505_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc); + + mc->desc = "ARM MPS2 with AN505 FPGA image for Cortex-M33"; + mmc->fpga_type = FPGA_AN505; + mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33"); + mmc->scc_id = 0x41040000 | (505 << 4); +} + +static const TypeInfo mps2tz_info = { + .name = TYPE_MPS2TZ_MACHINE, + .parent = TYPE_MACHINE, + .abstract = true, + .instance_size = sizeof(MPS2TZMachineState), + .class_size = sizeof(MPS2TZMachineClass), + .class_init = mps2tz_class_init, +}; + +static const TypeInfo mps2tz_an505_info = { + .name = TYPE_MPS2TZ_AN505_MACHINE, + .parent = TYPE_MPS2TZ_MACHINE, + .class_init = mps2tz_an505_class_init, +}; + +static void mps2tz_machine_init(void) +{ + type_register_static(&mps2tz_info); + type_register_static(&mps2tz_an505_info); +} + +type_init(mps2tz_machine_init); From patchwork Fri Mar 2 11:06:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880466 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6Wl4mH8z9s3m for ; Fri, 2 Mar 2018 22:29:07 +1100 (AEDT) Received: from localhost ([::1]:34175 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eris5-0005Ab-E7 for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:29:05 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43493) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWi-00032h-RH for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWh-0004x9-SJ for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:00 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46768) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWh-0004w4-MI for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:06:59 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWg-0001OJ-Aq for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:58 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:25 +0000 Message-Id: <20180302110640.28004-25-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 24/39] target/arm: Add ARM_FEATURE_V8_RDM X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Not enabled anywhere yet. Reviewed-by: Alex Bennée Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20180228193125.20577-2-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 1 + linux-user/elfload.c | 1 + 2 files changed, 2 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 72b5668377..c4d6992f1d 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1433,6 +1433,7 @@ enum arm_features { ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */ ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */ ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */ + ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */ ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */ }; diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 6689089cd2..3a55fb33a8 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -553,6 +553,7 @@ static uint32_t get_elf_hwcap(void) GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512); GET_FEATURE(ARM_FEATURE_V8_FP16, ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP); + GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM); #undef GET_FEATURE return hwcaps; From patchwork Fri Mar 2 11:06:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880446 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6Dg6ytcz9s3m for ; Fri, 2 Mar 2018 22:16:03 +1100 (AEDT) Received: from localhost ([::1]:34104 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erifR-0002Ih-Kn for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:16:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43518) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWk-00033M-By for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWi-0004xR-9a for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:01 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46770) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWh-0004wk-VW for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:00 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWh-0001OX-2q for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:59 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:26 +0000 Message-Id: <20180302110640.28004-26-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 25/39] target/arm: Refactor disas_simd_indexed decode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Include the U bit in the switches rather than testing separately. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20180228193125.20577-3-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate-a64.c | 129 +++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 68 deletions(-) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 32811dc8b0..fc928b61f6 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -11787,49 +11787,39 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) int index; TCGv_ptr fpst; - switch (opcode) { - case 0x0: /* MLA */ - case 0x4: /* MLS */ - if (!u || is_scalar) { + switch (16 * u + opcode) { + case 0x08: /* MUL */ + case 0x10: /* MLA */ + case 0x14: /* MLS */ + if (is_scalar) { unallocated_encoding(s); return; } break; - case 0x2: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */ - case 0x6: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */ - case 0xa: /* SMULL, SMULL2, UMULL, UMULL2 */ + case 0x02: /* SMLAL, SMLAL2 */ + case 0x12: /* UMLAL, UMLAL2 */ + case 0x06: /* SMLSL, SMLSL2 */ + case 0x16: /* UMLSL, UMLSL2 */ + case 0x0a: /* SMULL, SMULL2 */ + case 0x1a: /* UMULL, UMULL2 */ if (is_scalar) { unallocated_encoding(s); return; } is_long = true; break; - case 0x3: /* SQDMLAL, SQDMLAL2 */ - case 0x7: /* SQDMLSL, SQDMLSL2 */ - case 0xb: /* SQDMULL, SQDMULL2 */ + case 0x03: /* SQDMLAL, SQDMLAL2 */ + case 0x07: /* SQDMLSL, SQDMLSL2 */ + case 0x0b: /* SQDMULL, SQDMULL2 */ is_long = true; - /* fall through */ - case 0xc: /* SQDMULH */ - case 0xd: /* SQRDMULH */ - if (u) { - unallocated_encoding(s); - return; - } break; - case 0x8: /* MUL */ - if (u || is_scalar) { - unallocated_encoding(s); - return; - } + case 0x0c: /* SQDMULH */ + case 0x0d: /* SQRDMULH */ break; - case 0x1: /* FMLA */ - case 0x5: /* FMLS */ - if (u) { - unallocated_encoding(s); - return; - } - /* fall through */ - case 0x9: /* FMUL, FMULX */ + case 0x01: /* FMLA */ + case 0x05: /* FMLS */ + case 0x09: /* FMUL */ + case 0x19: /* FMULX */ if (size == 1) { unallocated_encoding(s); return; @@ -11909,21 +11899,20 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) read_vec_element(s, tcg_op, rn, pass, MO_64); - switch (opcode) { - case 0x5: /* FMLS */ + switch (16 * u + opcode) { + case 0x05: /* FMLS */ /* As usual for ARM, separate negation for fused multiply-add */ gen_helper_vfp_negd(tcg_op, tcg_op); /* fall through */ - case 0x1: /* FMLA */ + case 0x01: /* FMLA */ read_vec_element(s, tcg_res, rd, pass, MO_64); gen_helper_vfp_muladdd(tcg_res, tcg_op, tcg_idx, tcg_res, fpst); break; - case 0x9: /* FMUL, FMULX */ - if (u) { - gen_helper_vfp_mulxd(tcg_res, tcg_op, tcg_idx, fpst); - } else { - gen_helper_vfp_muld(tcg_res, tcg_op, tcg_idx, fpst); - } + case 0x09: /* FMUL */ + gen_helper_vfp_muld(tcg_res, tcg_op, tcg_idx, fpst); + break; + case 0x19: /* FMULX */ + gen_helper_vfp_mulxd(tcg_res, tcg_op, tcg_idx, fpst); break; default: g_assert_not_reached(); @@ -11966,10 +11955,10 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) read_vec_element_i32(s, tcg_op, rn, pass, is_scalar ? size : MO_32); - switch (opcode) { - case 0x0: /* MLA */ - case 0x4: /* MLS */ - case 0x8: /* MUL */ + switch (16 * u + opcode) { + case 0x08: /* MUL */ + case 0x10: /* MLA */ + case 0x14: /* MLS */ { static NeonGenTwoOpFn * const fns[2][2] = { { gen_helper_neon_add_u16, gen_helper_neon_sub_u16 }, @@ -11991,8 +11980,8 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) genfn(tcg_res, tcg_op, tcg_res); break; } - case 0x5: /* FMLS */ - case 0x1: /* FMLA */ + case 0x05: /* FMLS */ + case 0x01: /* FMLA */ read_vec_element_i32(s, tcg_res, rd, pass, is_scalar ? size : MO_32); switch (size) { @@ -12023,39 +12012,43 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) g_assert_not_reached(); } break; - case 0x9: /* FMUL, FMULX */ + case 0x09: /* FMUL */ switch (size) { case 1: - if (u) { - if (is_scalar) { - gen_helper_advsimd_mulxh(tcg_res, tcg_op, - tcg_idx, fpst); - } else { - gen_helper_advsimd_mulx2h(tcg_res, tcg_op, - tcg_idx, fpst); - } + if (is_scalar) { + gen_helper_advsimd_mulh(tcg_res, tcg_op, + tcg_idx, fpst); } else { - if (is_scalar) { - gen_helper_advsimd_mulh(tcg_res, tcg_op, - tcg_idx, fpst); - } else { - gen_helper_advsimd_mul2h(tcg_res, tcg_op, - tcg_idx, fpst); - } + gen_helper_advsimd_mul2h(tcg_res, tcg_op, + tcg_idx, fpst); } break; case 2: - if (u) { - gen_helper_vfp_mulxs(tcg_res, tcg_op, tcg_idx, fpst); - } else { - gen_helper_vfp_muls(tcg_res, tcg_op, tcg_idx, fpst); - } + gen_helper_vfp_muls(tcg_res, tcg_op, tcg_idx, fpst); break; default: g_assert_not_reached(); } break; - case 0xc: /* SQDMULH */ + case 0x19: /* FMULX */ + switch (size) { + case 1: + if (is_scalar) { + gen_helper_advsimd_mulxh(tcg_res, tcg_op, + tcg_idx, fpst); + } else { + gen_helper_advsimd_mulx2h(tcg_res, tcg_op, + tcg_idx, fpst); + } + break; + case 2: + gen_helper_vfp_mulxs(tcg_res, tcg_op, tcg_idx, fpst); + break; + default: + g_assert_not_reached(); + } + break; + case 0x0c: /* SQDMULH */ if (size == 1) { gen_helper_neon_qdmulh_s16(tcg_res, cpu_env, tcg_op, tcg_idx); @@ -12064,7 +12057,7 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) tcg_op, tcg_idx); } break; - case 0xd: /* SQRDMULH */ + case 0x0d: /* SQRDMULH */ if (size == 1) { gen_helper_neon_qrdmulh_s16(tcg_res, cpu_env, tcg_op, tcg_idx); From patchwork Fri Mar 2 11:06:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880455 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6NG4wNZz9s4w for ; Fri, 2 Mar 2018 22:22:38 +1100 (AEDT) Received: from localhost ([::1]:34140 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erilo-0007q7-NW for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:22:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43527) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWk-00033O-C3 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWj-0004ye-6b for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:02 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46770) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWi-0004wk-VU for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:01 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWh-0001Oo-OW for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:06:59 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:27 +0000 Message-Id: <20180302110640.28004-27-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 26/39] target/arm: Refactor disas_simd_indexed size checks X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson The integer size check was already outside of the opcode switch; move the floating-point size check outside as well. Unify the size vs index adjustment between fp and integer paths. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20180228193125.20577-4-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate-a64.c | 65 +++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index fc928b61f6..cbb4510e3a 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -11820,10 +11820,6 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) case 0x05: /* FMLS */ case 0x09: /* FMUL */ case 0x19: /* FMULX */ - if (size == 1) { - unallocated_encoding(s); - return; - } is_fp = true; break; default: @@ -11834,45 +11830,48 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) if (is_fp) { /* convert insn encoded size to TCGMemOp size */ switch (size) { - case 2: /* single precision */ - size = MO_32; - index = h << 1 | l; - rm |= (m << 4); - break; - case 3: /* double precision */ - size = MO_64; - if (l || !is_q) { + case 0: /* half-precision */ + if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { unallocated_encoding(s); return; } - index = h; - rm |= (m << 4); - break; - case 0: /* half precision */ size = MO_16; - index = h << 2 | l << 1 | m; - is_fp16 = true; - if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { - break; - } - /* fallthru */ - default: /* unallocated */ - unallocated_encoding(s); - return; - } - } else { - switch (size) { - case 1: - index = h << 2 | l << 1 | m; break; - case 2: - index = h << 1 | l; - rm |= (m << 4); + case MO_32: /* single precision */ + case MO_64: /* double precision */ break; default: unallocated_encoding(s); return; } + } else { + switch (size) { + case MO_8: + case MO_64: + unallocated_encoding(s); + return; + } + } + + /* Given TCGMemOp size, adjust register and indexing. */ + switch (size) { + case MO_16: + index = h << 2 | l << 1 | m; + break; + case MO_32: + index = h << 1 | l; + rm |= m << 4; + break; + case MO_64: + if (l || !is_q) { + unallocated_encoding(s); + return; + } + index = h; + rm |= m << 4; + break; + default: + g_assert_not_reached(); } if (!fp_access_check(s)) { From patchwork Fri Mar 2 11:06:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880456 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6P56XfZz9s3m for ; Fri, 2 Mar 2018 22:23:21 +1100 (AEDT) Received: from localhost ([::1]:34143 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erimV-0008N9-Vw for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:23:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43549) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWl-00034h-FM for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWj-0004zK-O3 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:03 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46772) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWj-0004y8-Cx for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:01 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWi-0001P2-Ff for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:00 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:28 +0000 Message-Id: <20180302110640.28004-28-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 27/39] target/arm: Decode aa64 armv8.1 scalar three same extra X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson Message-id: 20180228193125.20577-5-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/Makefile.objs | 2 +- target/arm/helper.h | 4 ++ target/arm/translate-a64.c | 84 ++++++++++++++++++++++++++++++++++ target/arm/vec_helper.c | 109 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 target/arm/vec_helper.c diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs index 847fb52ee0..1297bead5f 100644 --- a/target/arm/Makefile.objs +++ b/target/arm/Makefile.objs @@ -5,7 +5,7 @@ obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o obj-y += translate.o op_helper.o helper.o cpu.o -obj-y += neon_helper.o iwmmxt_helper.o +obj-y += neon_helper.o iwmmxt_helper.o vec_helper.o obj-y += gdbstub.o obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o obj-y += crypto_helper.o diff --git a/target/arm/helper.h b/target/arm/helper.h index 6dd8504ec3..2075c143d7 100644 --- a/target/arm/helper.h +++ b/target/arm/helper.h @@ -365,8 +365,12 @@ DEF_HELPER_FLAGS_1(neon_rbit_u8, TCG_CALL_NO_RWG_SE, i32, i32) DEF_HELPER_3(neon_qdmulh_s16, i32, env, i32, i32) DEF_HELPER_3(neon_qrdmulh_s16, i32, env, i32, i32) +DEF_HELPER_4(neon_qrdmlah_s16, i32, env, i32, i32, i32) +DEF_HELPER_4(neon_qrdmlsh_s16, i32, env, i32, i32, i32) DEF_HELPER_3(neon_qdmulh_s32, i32, env, i32, i32) DEF_HELPER_3(neon_qrdmulh_s32, i32, env, i32, i32) +DEF_HELPER_4(neon_qrdmlah_s32, i32, env, s32, s32, s32) +DEF_HELPER_4(neon_qrdmlsh_s32, i32, env, s32, s32, s32) DEF_HELPER_1(neon_narrow_u8, i32, i64) DEF_HELPER_1(neon_narrow_u16, i32, i64) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index cbb4510e3a..746ab0e63a 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -7971,6 +7971,89 @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s, tcg_temp_free_ptr(fpst); } +/* AdvSIMD scalar three same extra + * 31 30 29 28 24 23 22 21 20 16 15 14 11 10 9 5 4 0 + * +-----+---+-----------+------+---+------+---+--------+---+----+----+ + * | 0 1 | U | 1 1 1 1 0 | size | 0 | Rm | 1 | opcode | 1 | Rn | Rd | + * +-----+---+-----------+------+---+------+---+--------+---+----+----+ + */ +static void disas_simd_scalar_three_reg_same_extra(DisasContext *s, + uint32_t insn) +{ + int rd = extract32(insn, 0, 5); + int rn = extract32(insn, 5, 5); + int opcode = extract32(insn, 11, 4); + int rm = extract32(insn, 16, 5); + int size = extract32(insn, 22, 2); + bool u = extract32(insn, 29, 1); + TCGv_i32 ele1, ele2, ele3; + TCGv_i64 res; + int feature; + + switch (u * 16 + opcode) { + case 0x10: /* SQRDMLAH (vector) */ + case 0x11: /* SQRDMLSH (vector) */ + if (size != 1 && size != 2) { + unallocated_encoding(s); + return; + } + feature = ARM_FEATURE_V8_RDM; + break; + default: + unallocated_encoding(s); + return; + } + if (!arm_dc_feature(s, feature)) { + unallocated_encoding(s); + return; + } + if (!fp_access_check(s)) { + return; + } + + /* Do a single operation on the lowest element in the vector. + * We use the standard Neon helpers and rely on 0 OP 0 == 0 + * with no side effects for all these operations. + * OPTME: special-purpose helpers would avoid doing some + * unnecessary work in the helper for the 16 bit cases. + */ + ele1 = tcg_temp_new_i32(); + ele2 = tcg_temp_new_i32(); + ele3 = tcg_temp_new_i32(); + + read_vec_element_i32(s, ele1, rn, 0, size); + read_vec_element_i32(s, ele2, rm, 0, size); + read_vec_element_i32(s, ele3, rd, 0, size); + + switch (opcode) { + case 0x0: /* SQRDMLAH */ + if (size == 1) { + gen_helper_neon_qrdmlah_s16(ele3, cpu_env, ele1, ele2, ele3); + } else { + gen_helper_neon_qrdmlah_s32(ele3, cpu_env, ele1, ele2, ele3); + } + break; + case 0x1: /* SQRDMLSH */ + if (size == 1) { + gen_helper_neon_qrdmlsh_s16(ele3, cpu_env, ele1, ele2, ele3); + } else { + gen_helper_neon_qrdmlsh_s32(ele3, cpu_env, ele1, ele2, ele3); + } + break; + default: + g_assert_not_reached(); + } + tcg_temp_free_i32(ele1); + tcg_temp_free_i32(ele2); + + res = tcg_temp_new_i64(); + tcg_gen_extu_i32_i64(res, ele3); + tcg_temp_free_i32(ele3); + + write_fp_dreg(s, rd, res); + tcg_temp_free_i64(res); +} + static void handle_2misc_64(DisasContext *s, int opcode, bool u, TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, TCGv_i32 tcg_rmode, TCGv_ptr tcg_fpstatus) @@ -12798,6 +12881,7 @@ static const AArch64DecodeTable data_proc_simd[] = { { 0x0e000800, 0xbf208c00, disas_simd_zip_trn }, { 0x2e000000, 0xbf208400, disas_simd_ext }, { 0x5e200400, 0xdf200400, disas_simd_scalar_three_reg_same }, + { 0x5e008400, 0xdf208400, disas_simd_scalar_three_reg_same_extra }, { 0x5e200000, 0xdf200c00, disas_simd_scalar_three_reg_diff }, { 0x5e200800, 0xdf3e0c00, disas_simd_scalar_two_reg_misc }, { 0x5e300800, 0xdf3e0c00, disas_simd_scalar_pairwise }, diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c new file mode 100644 index 0000000000..9febdff69c --- /dev/null +++ b/target/arm/vec_helper.c @@ -0,0 +1,109 @@ +/* + * ARM AdvSIMD / SVE Vector Operations + * + * Copyright (c) 2018 Linaro + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/exec-all.h" +#include "exec/helper-proto.h" +#include "tcg/tcg-gvec-desc.h" + + +#define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] |= CPSR_Q + +/* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */ +static uint16_t inl_qrdmlah_s16(CPUARMState *env, int16_t src1, + int16_t src2, int16_t src3) +{ + /* Simplify: + * = ((a3 << 16) + ((e1 * e2) << 1) + (1 << 15)) >> 16 + * = ((a3 << 15) + (e1 * e2) + (1 << 14)) >> 15 + */ + int32_t ret = (int32_t)src1 * src2; + ret = ((int32_t)src3 << 15) + ret + (1 << 14); + ret >>= 15; + if (ret != (int16_t)ret) { + SET_QC(); + ret = (ret < 0 ? -0x8000 : 0x7fff); + } + return ret; +} + +uint32_t HELPER(neon_qrdmlah_s16)(CPUARMState *env, uint32_t src1, + uint32_t src2, uint32_t src3) +{ + uint16_t e1 = inl_qrdmlah_s16(env, src1, src2, src3); + uint16_t e2 = inl_qrdmlah_s16(env, src1 >> 16, src2 >> 16, src3 >> 16); + return deposit32(e1, 16, 16, e2); +} + +/* Signed saturating rounding doubling multiply-subtract high half, 16-bit */ +static uint16_t inl_qrdmlsh_s16(CPUARMState *env, int16_t src1, + int16_t src2, int16_t src3) +{ + /* Similarly, using subtraction: + * = ((a3 << 16) - ((e1 * e2) << 1) + (1 << 15)) >> 16 + * = ((a3 << 15) - (e1 * e2) + (1 << 14)) >> 15 + */ + int32_t ret = (int32_t)src1 * src2; + ret = ((int32_t)src3 << 15) - ret + (1 << 14); + ret >>= 15; + if (ret != (int16_t)ret) { + SET_QC(); + ret = (ret < 0 ? -0x8000 : 0x7fff); + } + return ret; +} + +uint32_t HELPER(neon_qrdmlsh_s16)(CPUARMState *env, uint32_t src1, + uint32_t src2, uint32_t src3) +{ + uint16_t e1 = inl_qrdmlsh_s16(env, src1, src2, src3); + uint16_t e2 = inl_qrdmlsh_s16(env, src1 >> 16, src2 >> 16, src3 >> 16); + return deposit32(e1, 16, 16, e2); +} + +/* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */ +uint32_t HELPER(neon_qrdmlah_s32)(CPUARMState *env, int32_t src1, + int32_t src2, int32_t src3) +{ + /* Simplify similarly to int_qrdmlah_s16 above. */ + int64_t ret = (int64_t)src1 * src2; + ret = ((int64_t)src3 << 31) + ret + (1 << 30); + ret >>= 31; + if (ret != (int32_t)ret) { + SET_QC(); + ret = (ret < 0 ? INT32_MIN : INT32_MAX); + } + return ret; +} + +/* Signed saturating rounding doubling multiply-subtract high half, 32-bit */ +uint32_t HELPER(neon_qrdmlsh_s32)(CPUARMState *env, int32_t src1, + int32_t src2, int32_t src3) +{ + /* Simplify similarly to int_qrdmlsh_s16 above. */ + int64_t ret = (int64_t)src1 * src2; + ret = ((int64_t)src3 << 31) - ret + (1 << 30); + ret >>= 31; + if (ret != (int32_t)ret) { + SET_QC(); + ret = (ret < 0 ? INT32_MIN : INT32_MAX); + } + return ret; +} From patchwork Fri Mar 2 11:06:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880464 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6VB1fhsz9s3m for ; Fri, 2 Mar 2018 22:27:46 +1100 (AEDT) Received: from localhost ([::1]:34170 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriqm-00041x-8H for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:27:44 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43565) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWm-00035n-Cg for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWk-00050V-P8 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:04 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46772) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWk-0004y8-E9 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:02 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWj-0001PJ-4n for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:01 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:29 +0000 Message-Id: <20180302110640.28004-29-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 28/39] target/arm: Decode aa64 armv8.1 three same extra X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20180228193125.20577-6-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.h | 9 +++++ target/arm/translate-a64.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++ target/arm/vec_helper.c | 74 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+) diff --git a/target/arm/helper.h b/target/arm/helper.h index 2075c143d7..7f0d3b2d84 100644 --- a/target/arm/helper.h +++ b/target/arm/helper.h @@ -569,6 +569,15 @@ DEF_HELPER_2(dc_zva, void, env, i64) DEF_HELPER_FLAGS_2(neon_pmull_64_lo, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(neon_pmull_64_hi, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_5(gvec_qrdmlah_s16, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s16, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_qrdmlah_s32, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s32, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) + #ifdef TARGET_AARCH64 #include "helper-a64.h" #endif diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 746ab0e63a..ae16313eb0 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -701,6 +701,18 @@ static void gen_gvec_op3(DisasContext *s, bool is_q, int rd, vec_full_reg_size(s), gvec_op); } +/* Expand a 3-operand + env pointer operation using + * an out-of-line helper. + */ +static void gen_gvec_op3_env(DisasContext *s, bool is_q, int rd, + int rn, int rm, gen_helper_gvec_3_ptr *fn) +{ + tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd), + vec_full_reg_offset(s, rn), + vec_full_reg_offset(s, rm), cpu_env, + is_q ? 16 : 8, vec_full_reg_size(s), 0, fn); +} + /* Set ZF and NF based on a 64 bit result. This is alas fiddlier * than the 32 bit equivalent. */ @@ -10789,6 +10801,76 @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn) clear_vec_high(s, is_q, rd); } +/* AdvSIMD three same extra + * 31 30 29 28 24 23 22 21 20 16 15 14 11 10 9 5 4 0 + * +---+---+---+-----------+------+---+------+---+--------+---+----+----+ + * | 0 | Q | U | 0 1 1 1 0 | size | 0 | Rm | 1 | opcode | 1 | Rn | Rd | + * +---+---+---+-----------+------+---+------+---+--------+---+----+----+ + */ +static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn) +{ + int rd = extract32(insn, 0, 5); + int rn = extract32(insn, 5, 5); + int opcode = extract32(insn, 11, 4); + int rm = extract32(insn, 16, 5); + int size = extract32(insn, 22, 2); + bool u = extract32(insn, 29, 1); + bool is_q = extract32(insn, 30, 1); + int feature; + + switch (u * 16 + opcode) { + case 0x10: /* SQRDMLAH (vector) */ + case 0x11: /* SQRDMLSH (vector) */ + if (size != 1 && size != 2) { + unallocated_encoding(s); + return; + } + feature = ARM_FEATURE_V8_RDM; + break; + default: + unallocated_encoding(s); + return; + } + if (!arm_dc_feature(s, feature)) { + unallocated_encoding(s); + return; + } + if (!fp_access_check(s)) { + return; + } + + switch (opcode) { + case 0x0: /* SQRDMLAH (vector) */ + switch (size) { + case 1: + gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlah_s16); + break; + case 2: + gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlah_s32); + break; + default: + g_assert_not_reached(); + } + return; + + case 0x1: /* SQRDMLSH (vector) */ + switch (size) { + case 1: + gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlsh_s16); + break; + case 2: + gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlsh_s32); + break; + default: + g_assert_not_reached(); + } + return; + + default: + g_assert_not_reached(); + } +} + static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q, int size, int rn, int rd) { @@ -12869,6 +12951,7 @@ static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn) static const AArch64DecodeTable data_proc_simd[] = { /* pattern , mask , fn */ { 0x0e200400, 0x9f200400, disas_simd_three_reg_same }, + { 0x0e008400, 0x9f208400, disas_simd_three_reg_same_extra }, { 0x0e200000, 0x9f200c00, disas_simd_three_reg_diff }, { 0x0e200800, 0x9f3e0c00, disas_simd_two_reg_misc }, { 0x0e300800, 0x9f3e0c00, disas_simd_across_lanes }, diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c index 9febdff69c..3072df4d77 100644 --- a/target/arm/vec_helper.c +++ b/target/arm/vec_helper.c @@ -26,6 +26,16 @@ #define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] |= CPSR_Q +static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz) +{ + uint64_t *d = vd + opr_sz; + uintptr_t i; + + for (i = opr_sz; i < max_sz; i += 8) { + *d++ = 0; + } +} + /* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */ static uint16_t inl_qrdmlah_s16(CPUARMState *env, int16_t src1, int16_t src2, int16_t src3) @@ -52,6 +62,22 @@ uint32_t HELPER(neon_qrdmlah_s16)(CPUARMState *env, uint32_t src1, return deposit32(e1, 16, 16, e2); } +void HELPER(gvec_qrdmlah_s16)(void *vd, void *vn, void *vm, + void *ve, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + int16_t *d = vd; + int16_t *n = vn; + int16_t *m = vm; + CPUARMState *env = ve; + uintptr_t i; + + for (i = 0; i < opr_sz / 2; ++i) { + d[i] = inl_qrdmlah_s16(env, n[i], m[i], d[i]); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + /* Signed saturating rounding doubling multiply-subtract high half, 16-bit */ static uint16_t inl_qrdmlsh_s16(CPUARMState *env, int16_t src1, int16_t src2, int16_t src3) @@ -78,6 +104,22 @@ uint32_t HELPER(neon_qrdmlsh_s16)(CPUARMState *env, uint32_t src1, return deposit32(e1, 16, 16, e2); } +void HELPER(gvec_qrdmlsh_s16)(void *vd, void *vn, void *vm, + void *ve, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + int16_t *d = vd; + int16_t *n = vn; + int16_t *m = vm; + CPUARMState *env = ve; + uintptr_t i; + + for (i = 0; i < opr_sz / 2; ++i) { + d[i] = inl_qrdmlsh_s16(env, n[i], m[i], d[i]); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + /* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */ uint32_t HELPER(neon_qrdmlah_s32)(CPUARMState *env, int32_t src1, int32_t src2, int32_t src3) @@ -93,6 +135,22 @@ uint32_t HELPER(neon_qrdmlah_s32)(CPUARMState *env, int32_t src1, return ret; } +void HELPER(gvec_qrdmlah_s32)(void *vd, void *vn, void *vm, + void *ve, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + int32_t *d = vd; + int32_t *n = vn; + int32_t *m = vm; + CPUARMState *env = ve; + uintptr_t i; + + for (i = 0; i < opr_sz / 4; ++i) { + d[i] = helper_neon_qrdmlah_s32(env, n[i], m[i], d[i]); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + /* Signed saturating rounding doubling multiply-subtract high half, 32-bit */ uint32_t HELPER(neon_qrdmlsh_s32)(CPUARMState *env, int32_t src1, int32_t src2, int32_t src3) @@ -107,3 +165,19 @@ uint32_t HELPER(neon_qrdmlsh_s32)(CPUARMState *env, int32_t src1, } return ret; } + +void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm, + void *ve, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + int32_t *d = vd; + int32_t *n = vn; + int32_t *m = vm; + CPUARMState *env = ve; + uintptr_t i; + + for (i = 0; i < opr_sz / 4; ++i) { + d[i] = helper_neon_qrdmlsh_s32(env, n[i], m[i], d[i]); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} From patchwork Fri Mar 2 11:06:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880453 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6KT4l85z9s4w for ; Fri, 2 Mar 2018 22:20:13 +1100 (AEDT) Received: from localhost ([::1]:34123 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erijT-0005pO-MH for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:20:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43556) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWl-000359-Sv for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWl-00050m-0k for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:03 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46774) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWk-0004zg-QU for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:02 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWj-0001PX-SJ for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:01 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:30 +0000 Message-Id: <20180302110640.28004-30-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 29/39] target/arm: Decode aa64 armv8.1 scalar/vector x indexed element X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson Message-id: 20180228193125.20577-7-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate-a64.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index ae16313eb0..e4d2d548ba 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -11987,6 +11987,13 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) case 0x19: /* FMULX */ is_fp = true; break; + case 0x1d: /* SQRDMLAH */ + case 0x1f: /* SQRDMLSH */ + if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) { + unallocated_encoding(s); + return; + } + break; default: unallocated_encoding(s); return; @@ -12230,6 +12237,28 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) tcg_op, tcg_idx); } break; + case 0x1d: /* SQRDMLAH */ + read_vec_element_i32(s, tcg_res, rd, pass, + is_scalar ? size : MO_32); + if (size == 1) { + gen_helper_neon_qrdmlah_s16(tcg_res, cpu_env, + tcg_op, tcg_idx, tcg_res); + } else { + gen_helper_neon_qrdmlah_s32(tcg_res, cpu_env, + tcg_op, tcg_idx, tcg_res); + } + break; + case 0x1f: /* SQRDMLSH */ + read_vec_element_i32(s, tcg_res, rd, pass, + is_scalar ? size : MO_32); + if (size == 1) { + gen_helper_neon_qrdmlsh_s16(tcg_res, cpu_env, + tcg_op, tcg_idx, tcg_res); + } else { + gen_helper_neon_qrdmlsh_s32(tcg_res, cpu_env, + tcg_op, tcg_idx, tcg_res); + } + break; default: g_assert_not_reached(); } From patchwork Fri Mar 2 11:06:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880470 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6b4490Hz9s4w for ; Fri, 2 Mar 2018 22:32:00 +1100 (AEDT) Received: from localhost ([::1]:34191 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erius-0007ji-J8 for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:31:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43586) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWm-00036H-TR for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWl-00051z-LC for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:04 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46772) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWl-0004y8-Cs for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:03 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWk-0001Po-HB for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:02 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:31 +0000 Message-Id: <20180302110640.28004-31-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 30/39] target/arm: Decode aa32 armv8.1 three same X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20180228193125.20577-8-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate.c | 86 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 19 deletions(-) diff --git a/target/arm/translate.c b/target/arm/translate.c index aa6dcaa577..05fa6a53f9 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -25,6 +25,7 @@ #include "disas/disas.h" #include "exec/exec-all.h" #include "tcg-op.h" +#include "tcg-op-gvec.h" #include "qemu/log.h" #include "qemu/bitops.h" #include "arm_ldst.h" @@ -5374,9 +5375,9 @@ static void gen_neon_narrow_op(int op, int u, int size, #define NEON_3R_VPMAX 20 #define NEON_3R_VPMIN 21 #define NEON_3R_VQDMULH_VQRDMULH 22 -#define NEON_3R_VPADD 23 +#define NEON_3R_VPADD_VQRDMLAH 23 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */ -#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */ +#define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */ #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */ #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */ #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */ @@ -5408,9 +5409,9 @@ static const uint8_t neon_3r_sizes[] = { [NEON_3R_VPMAX] = 0x7, [NEON_3R_VPMIN] = 0x7, [NEON_3R_VQDMULH_VQRDMULH] = 0x6, - [NEON_3R_VPADD] = 0x7, + [NEON_3R_VPADD_VQRDMLAH] = 0x7, [NEON_3R_SHA] = 0xf, /* size field encodes op type */ - [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */ [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */ [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */ [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */ @@ -5589,6 +5590,22 @@ static const uint8_t neon_2rm_sizes[] = { [NEON_2RM_VCVT_UF] = 0x4, }; + +/* Expand v8.1 simd helper. */ +static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn, + int q, int rd, int rn, int rm) +{ + if (arm_dc_feature(s, ARM_FEATURE_V8_RDM)) { + int opr_sz = (1 + q) * 8; + tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), + vfp_reg_offset(1, rn), + vfp_reg_offset(1, rm), cpu_env, + opr_sz, opr_sz, 0, fn); + return 0; + } + return 1; +} + /* Translate a NEON data processing instruction. Return nonzero if the instruction is invalid. We process data in a mixture of 32-bit and 64-bit chunks. @@ -5641,12 +5658,13 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) if (q && ((rd | rn | rm) & 1)) { return 1; } - /* - * The SHA-1/SHA-256 3-register instructions require special treatment - * here, as their size field is overloaded as an op type selector, and - * they all consume their input in a single pass. - */ - if (op == NEON_3R_SHA) { + switch (op) { + case NEON_3R_SHA: + /* The SHA-1/SHA-256 3-register instructions require special + * treatment here, as their size field is overloaded as an + * op type selector, and they all consume their input in a + * single pass. + */ if (!q) { return 1; } @@ -5683,6 +5701,40 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) tcg_temp_free_ptr(ptr2); tcg_temp_free_ptr(ptr3); return 0; + + case NEON_3R_VPADD_VQRDMLAH: + if (!u) { + break; /* VPADD */ + } + /* VQRDMLAH */ + switch (size) { + case 1: + return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16, + q, rd, rn, rm); + case 2: + return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32, + q, rd, rn, rm); + } + return 1; + + case NEON_3R_VFM_VQRDMLSH: + if (!u) { + /* VFM, VFMS */ + if (size == 1) { + return 1; + } + break; + } + /* VQRDMLSH */ + switch (size) { + case 1: + return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16, + q, rd, rn, rm); + case 2: + return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32, + q, rd, rn, rm); + } + return 1; } if (size == 3 && op != NEON_3R_LOGIC) { /* 64-bit element instructions. */ @@ -5768,11 +5820,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) rm = rtmp; } break; - case NEON_3R_VPADD: - if (u) { - return 1; - } - /* Fall through */ + case NEON_3R_VPADD_VQRDMLAH: case NEON_3R_VPMAX: case NEON_3R_VPMIN: pairwise = 1; @@ -5806,8 +5854,8 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) return 1; } break; - case NEON_3R_VFM: - if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) { + case NEON_3R_VFM_VQRDMLSH: + if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) { return 1; } break; @@ -6004,7 +6052,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) } } break; - case NEON_3R_VPADD: + case NEON_3R_VPADD_VQRDMLAH: switch (size) { case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break; @@ -6103,7 +6151,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) } } break; - case NEON_3R_VFM: + case NEON_3R_VFM_VQRDMLSH: { /* VFMA, VFMS: fused multiply-add */ TCGv_ptr fpstatus = get_fpstatus_ptr(1); From patchwork Fri Mar 2 11:06:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880467 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6Wp4ZFFz9s3m for ; Fri, 2 Mar 2018 22:29:10 +1100 (AEDT) Received: from localhost ([::1]:34177 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eris8-0005D6-LT for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:29:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43634) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWq-0003Ag-Bb for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWm-000538-DS for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:08 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46776) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWm-00051l-5Q for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:04 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWl-0001Q5-8A for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:03 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:32 +0000 Message-Id: <20180302110640.28004-32-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 31/39] target/arm: Decode aa32 armv8.1 two reg and a scalar X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-id: 20180228193125.20577-9-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/target/arm/translate.c b/target/arm/translate.c index 05fa6a53f9..9169b6b367 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -76,6 +76,10 @@ static const char *regnames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" }; +/* Function prototypes for gen_ functions calling Neon helpers. */ +typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32, + TCGv_i32, TCGv_i32); + /* initialize TCG globals. */ void arm_translate_init(void) { @@ -6985,11 +6989,45 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) } neon_store_reg64(cpu_V0, rd + pass); } - - break; - default: /* 14 and 15 are RESERVED */ - return 1; + case 14: /* VQRDMLAH scalar */ + case 15: /* VQRDMLSH scalar */ + { + NeonGenThreeOpEnvFn *fn; + + if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) { + return 1; + } + if (u && ((rd | rn) & 1)) { + return 1; + } + if (op == 14) { + if (size == 1) { + fn = gen_helper_neon_qrdmlah_s16; + } else { + fn = gen_helper_neon_qrdmlah_s32; + } + } else { + if (size == 1) { + fn = gen_helper_neon_qrdmlsh_s16; + } else { + fn = gen_helper_neon_qrdmlsh_s32; + } + } + + tmp2 = neon_get_scalar(size, rm); + for (pass = 0; pass < (u ? 4 : 2); pass++) { + tmp = neon_load_reg(rn, pass); + tmp3 = neon_load_reg(rd, pass); + fn(tmp, cpu_env, tmp, tmp2, tmp3); + tcg_temp_free_i32(tmp3); + neon_store_reg(rd, pass, tmp); + } + tcg_temp_free_i32(tmp2); + } + break; + default: + g_assert_not_reached(); } } } else { /* size == 3 */ From patchwork Fri Mar 2 11:06:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880473 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6fl1wPcz9s5H for ; Fri, 2 Mar 2018 22:35:11 +1100 (AEDT) Received: from localhost ([::1]:34211 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erixw-00020L-Me for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:35:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43611) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWo-000381-2I for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWn-00054F-9m for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:06 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46776) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWn-00051l-35 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:05 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWl-0001QJ-UH for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:03 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:33 +0000 Message-Id: <20180302110640.28004-33-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 32/39] target/arm: Enable ARM_FEATURE_V8_RDM X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Enable it for the "any" CPU used by *-linux-user. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20180228193125.20577-10-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.c | 1 + target/arm/cpu64.c | 1 + 2 files changed, 2 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index e08b1e7943..3ee2d32aef 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1697,6 +1697,7 @@ static void arm_any_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V8_SHA256); set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); set_feature(&cpu->env, ARM_FEATURE_CRC); + set_feature(&cpu->env, ARM_FEATURE_V8_RDM); cpu->midr = 0xffffffff; } #endif diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 9743bdc8c3..7246866e7d 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -230,6 +230,7 @@ static void aarch64_any_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V8_SM4); set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); set_feature(&cpu->env, ARM_FEATURE_CRC); + set_feature(&cpu->env, ARM_FEATURE_V8_RDM); set_feature(&cpu->env, ARM_FEATURE_V8_FP16); cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */ cpu->dcz_blocksize = 7; /* 512 bytes */ From patchwork Fri Mar 2 11:06:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880465 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6Vy5DQSz9s3m for ; Fri, 2 Mar 2018 22:28:26 +1100 (AEDT) Received: from localhost ([::1]:34172 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erirQ-0004cJ-KA for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:28:24 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43662) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWr-0003BF-Ij for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWn-00054e-Nt for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:09 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46778) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWn-00053X-GP for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:05 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWm-0001QX-KJ for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:04 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:34 +0000 Message-Id: <20180302110640.28004-34-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 33/39] target/arm: Add ARM_FEATURE_V8_FCMA X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Not enabled anywhere yet. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson Message-id: 20180228193125.20577-11-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 1 + linux-user/elfload.c | 1 + 2 files changed, 2 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index c4d6992f1d..8dd6b788df 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1435,6 +1435,7 @@ enum arm_features { ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */ ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */ ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */ + ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */ }; static inline int arm_feature(CPUARMState *env, int feature) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 3a55fb33a8..e3689c658a 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -554,6 +554,7 @@ static uint32_t get_elf_hwcap(void) GET_FEATURE(ARM_FEATURE_V8_FP16, ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP); GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM); + GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA); #undef GET_FEATURE return hwcaps; From patchwork Fri Mar 2 11:06:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880468 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6YM71p6z9s3m for ; Fri, 2 Mar 2018 22:30:31 +1100 (AEDT) Received: from localhost ([::1]:34182 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eritR-0006Sr-40 for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:30:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43629) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWq-0003AP-4B for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWo-000552-LL for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:08 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46778) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWo-00053X-CD for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:06 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWn-0001Qo-9u for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:05 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:35 +0000 Message-Id: <20180302110640.28004-35-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 34/39] target/arm: Decode aa64 armv8.3 fcadd X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson Message-id: 20180228193125.20577-12-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.h | 7 ++++ target/arm/translate-a64.c | 48 ++++++++++++++++++++++- target/arm/vec_helper.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 1 deletion(-) diff --git a/target/arm/helper.h b/target/arm/helper.h index 7f0d3b2d84..1e2d7025de 100644 --- a/target/arm/helper.h +++ b/target/arm/helper.h @@ -578,6 +578,13 @@ DEF_HELPER_FLAGS_5(gvec_qrdmlah_s32, TCG_CALL_NO_RWG, DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_fcaddh, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_fcadds, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_fcaddd, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) + #ifdef TARGET_AARCH64 #include "helper-a64.h" #endif diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index e4d2d548ba..efed4fd9d2 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -713,6 +713,21 @@ static void gen_gvec_op3_env(DisasContext *s, bool is_q, int rd, is_q ? 16 : 8, vec_full_reg_size(s), 0, fn); } +/* Expand a 3-operand + fpstatus pointer + simd data value operation using + * an out-of-line helper. + */ +static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, int rd, int rn, + int rm, bool is_fp16, int data, + gen_helper_gvec_3_ptr *fn) +{ + TCGv_ptr fpst = get_fpstatus_ptr(is_fp16); + tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd), + vec_full_reg_offset(s, rn), + vec_full_reg_offset(s, rm), fpst, + is_q ? 16 : 8, vec_full_reg_size(s), data, fn); + tcg_temp_free_ptr(fpst); +} + /* Set ZF and NF based on a 64 bit result. This is alas fiddlier * than the 32 bit equivalent. */ @@ -10816,7 +10831,7 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn) int size = extract32(insn, 22, 2); bool u = extract32(insn, 29, 1); bool is_q = extract32(insn, 30, 1); - int feature; + int feature, rot; switch (u * 16 + opcode) { case 0x10: /* SQRDMLAH (vector) */ @@ -10827,6 +10842,16 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn) } feature = ARM_FEATURE_V8_RDM; break; + case 0xc: /* FCADD, #90 */ + case 0xe: /* FCADD, #270 */ + if (size == 0 + || (size == 1 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16)) + || (size == 3 && !is_q)) { + unallocated_encoding(s); + return; + } + feature = ARM_FEATURE_V8_FCMA; + break; default: unallocated_encoding(s); return; @@ -10866,6 +10891,27 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn) } return; + case 0xc: /* FCADD, #90 */ + case 0xe: /* FCADD, #270 */ + rot = extract32(opcode, 1, 1); + switch (size) { + case 1: + gen_gvec_op3_fpst(s, is_q, rd, rn, rm, size == 1, rot, + gen_helper_gvec_fcaddh); + break; + case 2: + gen_gvec_op3_fpst(s, is_q, rd, rn, rm, size == 1, rot, + gen_helper_gvec_fcadds); + break; + case 3: + gen_gvec_op3_fpst(s, is_q, rd, rn, rm, size == 1, rot, + gen_helper_gvec_fcaddd); + break; + default: + g_assert_not_reached(); + } + return; + default: g_assert_not_reached(); } diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c index 3072df4d77..a868ca6aac 100644 --- a/target/arm/vec_helper.c +++ b/target/arm/vec_helper.c @@ -22,8 +22,21 @@ #include "exec/exec-all.h" #include "exec/helper-proto.h" #include "tcg/tcg-gvec-desc.h" +#include "fpu/softfloat.h" +/* Note that vector data is stored in host-endian 64-bit chunks, + so addressing units smaller than that needs a host-endian fixup. */ +#ifdef HOST_WORDS_BIGENDIAN +#define H1(x) ((x) ^ 7) +#define H2(x) ((x) ^ 3) +#define H4(x) ((x) ^ 1) +#else +#define H1(x) (x) +#define H2(x) (x) +#define H4(x) (x) +#endif + #define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] |= CPSR_Q static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz) @@ -181,3 +194,87 @@ void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm, } clear_tail(d, opr_sz, simd_maxsz(desc)); } + +void HELPER(gvec_fcaddh)(void *vd, void *vn, void *vm, + void *vfpst, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + float16 *d = vd; + float16 *n = vn; + float16 *m = vm; + float_status *fpst = vfpst; + uint32_t neg_real = extract32(desc, SIMD_DATA_SHIFT, 1); + uint32_t neg_imag = neg_real ^ 1; + uintptr_t i; + + /* Shift boolean to the sign bit so we can xor to negate. */ + neg_real <<= 15; + neg_imag <<= 15; + + for (i = 0; i < opr_sz / 2; i += 2) { + float16 e0 = n[H2(i)]; + float16 e1 = m[H2(i + 1)] ^ neg_imag; + float16 e2 = n[H2(i + 1)]; + float16 e3 = m[H2(i)] ^ neg_real; + + d[H2(i)] = float16_add(e0, e1, fpst); + d[H2(i + 1)] = float16_add(e2, e3, fpst); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + +void HELPER(gvec_fcadds)(void *vd, void *vn, void *vm, + void *vfpst, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + float32 *d = vd; + float32 *n = vn; + float32 *m = vm; + float_status *fpst = vfpst; + uint32_t neg_real = extract32(desc, SIMD_DATA_SHIFT, 1); + uint32_t neg_imag = neg_real ^ 1; + uintptr_t i; + + /* Shift boolean to the sign bit so we can xor to negate. */ + neg_real <<= 31; + neg_imag <<= 31; + + for (i = 0; i < opr_sz / 4; i += 2) { + float32 e0 = n[H4(i)]; + float32 e1 = m[H4(i + 1)] ^ neg_imag; + float32 e2 = n[H4(i + 1)]; + float32 e3 = m[H4(i)] ^ neg_real; + + d[H4(i)] = float32_add(e0, e1, fpst); + d[H4(i + 1)] = float32_add(e2, e3, fpst); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + +void HELPER(gvec_fcaddd)(void *vd, void *vn, void *vm, + void *vfpst, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + float64 *d = vd; + float64 *n = vn; + float64 *m = vm; + float_status *fpst = vfpst; + uint64_t neg_real = extract64(desc, SIMD_DATA_SHIFT, 1); + uint64_t neg_imag = neg_real ^ 1; + uintptr_t i; + + /* Shift boolean to the sign bit so we can xor to negate. */ + neg_real <<= 63; + neg_imag <<= 63; + + for (i = 0; i < opr_sz / 8; i += 2) { + float64 e0 = n[i]; + float64 e1 = m[i + 1] ^ neg_imag; + float64 e2 = n[i + 1]; + float64 e3 = m[i] ^ neg_real; + + d[i] = float64_add(e0, e1, fpst); + d[i + 1] = float64_add(e2, e3, fpst); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} From patchwork Fri Mar 2 11:06:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880471 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6d00Lbrz9s4w for ; Fri, 2 Mar 2018 22:33:40 +1100 (AEDT) Received: from localhost ([::1]:34202 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriwU-0000Xp-3W for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:33:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43646) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWq-0003B9-Ui for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWp-00055G-9F for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:08 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46780) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWo-00054u-SA for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:07 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWn-0001R4-Vl for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:05 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:36 +0000 Message-Id: <20180302110640.28004-36-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 35/39] target/arm: Decode aa64 armv8.3 fcmla X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Signed-off-by: Richard Henderson Message-id: 20180228193125.20577-13-richard.henderson@linaro.org Signed-off-by: Peter Maydell [PMM: renamed e1/e2/e3/e4 to use the same naming as the version of the pseudocode in the Arm ARM] Reviewed-by: Peter Maydell --- target/arm/helper.h | 11 ++++ target/arm/translate-a64.c | 94 +++++++++++++++++++++++++--- target/arm/vec_helper.c | 149 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 246 insertions(+), 8 deletions(-) diff --git a/target/arm/helper.h b/target/arm/helper.h index 1e2d7025de..0d2094f2be 100644 --- a/target/arm/helper.h +++ b/target/arm/helper.h @@ -585,6 +585,17 @@ DEF_HELPER_FLAGS_5(gvec_fcadds, TCG_CALL_NO_RWG, DEF_HELPER_FLAGS_5(gvec_fcaddd, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_fcmlah, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_fcmlah_idx, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_fcmlas, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_fcmlas_idx, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_5(gvec_fcmlad, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, i32) + #ifdef TARGET_AARCH64 #include "helper-a64.h" #endif diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index efed4fd9d2..31ff0479e6 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -10842,6 +10842,10 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn) } feature = ARM_FEATURE_V8_RDM; break; + case 0x8: /* FCMLA, #0 */ + case 0x9: /* FCMLA, #90 */ + case 0xa: /* FCMLA, #180 */ + case 0xb: /* FCMLA, #270 */ case 0xc: /* FCADD, #90 */ case 0xe: /* FCADD, #270 */ if (size == 0 @@ -10891,6 +10895,29 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn) } return; + case 0x8: /* FCMLA, #0 */ + case 0x9: /* FCMLA, #90 */ + case 0xa: /* FCMLA, #180 */ + case 0xb: /* FCMLA, #270 */ + rot = extract32(opcode, 0, 2); + switch (size) { + case 1: + gen_gvec_op3_fpst(s, is_q, rd, rn, rm, true, rot, + gen_helper_gvec_fcmlah); + break; + case 2: + gen_gvec_op3_fpst(s, is_q, rd, rn, rm, false, rot, + gen_helper_gvec_fcmlas); + break; + case 3: + gen_gvec_op3_fpst(s, is_q, rd, rn, rm, false, rot, + gen_helper_gvec_fcmlad); + break; + default: + g_assert_not_reached(); + } + return; + case 0xc: /* FCADD, #90 */ case 0xe: /* FCADD, #270 */ rot = extract32(opcode, 1, 1); @@ -11993,7 +12020,7 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) int rn = extract32(insn, 5, 5); int rd = extract32(insn, 0, 5); bool is_long = false; - bool is_fp = false; + int is_fp = 0; bool is_fp16 = false; int index; TCGv_ptr fpst; @@ -12031,7 +12058,7 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) case 0x05: /* FMLS */ case 0x09: /* FMUL */ case 0x19: /* FMULX */ - is_fp = true; + is_fp = 1; break; case 0x1d: /* SQRDMLAH */ case 0x1f: /* SQRDMLSH */ @@ -12040,20 +12067,28 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) return; } break; + case 0x11: /* FCMLA #0 */ + case 0x13: /* FCMLA #90 */ + case 0x15: /* FCMLA #180 */ + case 0x17: /* FCMLA #270 */ + if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) { + unallocated_encoding(s); + return; + } + is_fp = 2; + break; default: unallocated_encoding(s); return; } - if (is_fp) { + switch (is_fp) { + case 1: /* normal fp */ /* convert insn encoded size to TCGMemOp size */ switch (size) { case 0: /* half-precision */ - if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { - unallocated_encoding(s); - return; - } size = MO_16; + is_fp16 = true; break; case MO_32: /* single precision */ case MO_64: /* double precision */ @@ -12062,13 +12097,39 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) unallocated_encoding(s); return; } - } else { + break; + + case 2: /* complex fp */ + /* Each indexable element is a complex pair. */ + size <<= 1; + switch (size) { + case MO_32: + if (h && !is_q) { + unallocated_encoding(s); + return; + } + is_fp16 = true; + break; + case MO_64: + break; + default: + unallocated_encoding(s); + return; + } + break; + + default: /* integer */ switch (size) { case MO_8: case MO_64: unallocated_encoding(s); return; } + break; + } + if (is_fp16 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16)) { + unallocated_encoding(s); + return; } /* Given TCGMemOp size, adjust register and indexing. */ @@ -12102,6 +12163,23 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn) fpst = NULL; } + switch (16 * u + opcode) { + case 0x11: /* FCMLA #0 */ + case 0x13: /* FCMLA #90 */ + case 0x15: /* FCMLA #180 */ + case 0x17: /* FCMLA #270 */ + tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd), + vec_full_reg_offset(s, rn), + vec_reg_offset(s, rm, index, size), fpst, + is_q ? 16 : 8, vec_full_reg_size(s), + extract32(insn, 13, 2), /* rot */ + size == MO_64 + ? gen_helper_gvec_fcmlas_idx + : gen_helper_gvec_fcmlah_idx); + tcg_temp_free_ptr(fpst); + return; + } + if (size == 3) { TCGv_i64 tcg_idx = tcg_temp_new_i64(); int pass; diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c index a868ca6aac..ec705cfca5 100644 --- a/target/arm/vec_helper.c +++ b/target/arm/vec_helper.c @@ -278,3 +278,152 @@ void HELPER(gvec_fcaddd)(void *vd, void *vn, void *vm, } clear_tail(d, opr_sz, simd_maxsz(desc)); } + +void HELPER(gvec_fcmlah)(void *vd, void *vn, void *vm, + void *vfpst, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + float16 *d = vd; + float16 *n = vn; + float16 *m = vm; + float_status *fpst = vfpst; + intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1); + uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1); + uint32_t neg_real = flip ^ neg_imag; + uintptr_t i; + + /* Shift boolean to the sign bit so we can xor to negate. */ + neg_real <<= 15; + neg_imag <<= 15; + + for (i = 0; i < opr_sz / 2; i += 2) { + float16 e2 = n[H2(i + flip)]; + float16 e1 = m[H2(i + flip)] ^ neg_real; + float16 e4 = e2; + float16 e3 = m[H2(i + 1 - flip)] ^ neg_imag; + + d[H2(i)] = float16_muladd(e2, e1, d[H2(i)], 0, fpst); + d[H2(i + 1)] = float16_muladd(e4, e3, d[H2(i + 1)], 0, fpst); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + +void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm, + void *vfpst, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + float16 *d = vd; + float16 *n = vn; + float16 *m = vm; + float_status *fpst = vfpst; + intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1); + uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1); + uint32_t neg_real = flip ^ neg_imag; + uintptr_t i; + float16 e1 = m[H2(flip)]; + float16 e3 = m[H2(1 - flip)]; + + /* Shift boolean to the sign bit so we can xor to negate. */ + neg_real <<= 15; + neg_imag <<= 15; + e1 ^= neg_real; + e3 ^= neg_imag; + + for (i = 0; i < opr_sz / 2; i += 2) { + float16 e2 = n[H2(i + flip)]; + float16 e4 = e2; + + d[H2(i)] = float16_muladd(e2, e1, d[H2(i)], 0, fpst); + d[H2(i + 1)] = float16_muladd(e4, e3, d[H2(i + 1)], 0, fpst); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + +void HELPER(gvec_fcmlas)(void *vd, void *vn, void *vm, + void *vfpst, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + float32 *d = vd; + float32 *n = vn; + float32 *m = vm; + float_status *fpst = vfpst; + intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1); + uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1); + uint32_t neg_real = flip ^ neg_imag; + uintptr_t i; + + /* Shift boolean to the sign bit so we can xor to negate. */ + neg_real <<= 31; + neg_imag <<= 31; + + for (i = 0; i < opr_sz / 4; i += 2) { + float32 e2 = n[H4(i + flip)]; + float32 e1 = m[H4(i + flip)] ^ neg_real; + float32 e4 = e2; + float32 e3 = m[H4(i + 1 - flip)] ^ neg_imag; + + d[H4(i)] = float32_muladd(e2, e1, d[H4(i)], 0, fpst); + d[H4(i + 1)] = float32_muladd(e4, e3, d[H4(i + 1)], 0, fpst); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + +void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm, + void *vfpst, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + float32 *d = vd; + float32 *n = vn; + float32 *m = vm; + float_status *fpst = vfpst; + intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1); + uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1); + uint32_t neg_real = flip ^ neg_imag; + uintptr_t i; + float32 e1 = m[H4(flip)]; + float32 e3 = m[H4(1 - flip)]; + + /* Shift boolean to the sign bit so we can xor to negate. */ + neg_real <<= 31; + neg_imag <<= 31; + e1 ^= neg_real; + e3 ^= neg_imag; + + for (i = 0; i < opr_sz / 4; i += 2) { + float32 e2 = n[H4(i + flip)]; + float32 e4 = e2; + + d[H4(i)] = float32_muladd(e2, e1, d[H4(i)], 0, fpst); + d[H4(i + 1)] = float32_muladd(e4, e3, d[H4(i + 1)], 0, fpst); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} + +void HELPER(gvec_fcmlad)(void *vd, void *vn, void *vm, + void *vfpst, uint32_t desc) +{ + uintptr_t opr_sz = simd_oprsz(desc); + float64 *d = vd; + float64 *n = vn; + float64 *m = vm; + float_status *fpst = vfpst; + intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1); + uint64_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1); + uint64_t neg_real = flip ^ neg_imag; + uintptr_t i; + + /* Shift boolean to the sign bit so we can xor to negate. */ + neg_real <<= 63; + neg_imag <<= 63; + + for (i = 0; i < opr_sz / 8; i += 2) { + float64 e2 = n[i + flip]; + float64 e1 = m[i + flip] ^ neg_real; + float64 e4 = e2; + float64 e3 = m[i + 1 - flip] ^ neg_imag; + + d[i] = float64_muladd(e2, e1, d[i], 0, fpst); + d[i + 1] = float64_muladd(e4, e3, d[i + 1], 0, fpst); + } + clear_tail(d, opr_sz, simd_maxsz(desc)); +} From patchwork Fri Mar 2 11:06:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880469 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6ZC72mhz9s4w for ; Fri, 2 Mar 2018 22:31:15 +1100 (AEDT) Received: from localhost ([::1]:34189 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriu9-0007AB-VK for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:31:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43659) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWr-0003BC-7b for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWq-00055W-5f for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:09 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46780) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWp-00054u-VP for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:08 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWo-0001RJ-Ld for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:06 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:37 +0000 Message-Id: <20180302110640.28004-37-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 36/39] target/arm: Decode aa32 armv8.3 3-same X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20180228193125.20577-14-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/target/arm/translate.c b/target/arm/translate.c index 9169b6b367..45513c9d86 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -7680,6 +7680,68 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) return 0; } +/* Advanced SIMD three registers of the same length extension. + * 31 25 23 22 20 16 12 11 10 9 8 3 0 + * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+ + * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm | + * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+ + */ +static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn) +{ + gen_helper_gvec_3_ptr *fn_gvec_ptr; + int rd, rn, rm, rot, size, opr_sz; + TCGv_ptr fpst; + bool q; + + q = extract32(insn, 6, 1); + VFP_DREG_D(rd, insn); + VFP_DREG_N(rn, insn); + VFP_DREG_M(rm, insn); + if ((rd | rn | rm) & q) { + return 1; + } + + if ((insn & 0xfe200f10) == 0xfc200800) { + /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */ + size = extract32(insn, 20, 1); + rot = extract32(insn, 23, 2); + if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA) + || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) { + return 1; + } + fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah; + } else if ((insn & 0xfea00f10) == 0xfc800800) { + /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */ + size = extract32(insn, 20, 1); + rot = extract32(insn, 24, 1); + if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA) + || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) { + return 1; + } + fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh; + } else { + return 1; + } + + if (s->fp_excp_el) { + gen_exception_insn(s, 4, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, false), s->fp_excp_el); + return 0; + } + if (!s->vfp_enabled) { + return 1; + } + + opr_sz = (1 + q) * 8; + fpst = get_fpstatus_ptr(1); + tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), + vfp_reg_offset(1, rn), + vfp_reg_offset(1, rm), fpst, + opr_sz, opr_sz, rot, fn_gvec_ptr); + tcg_temp_free_ptr(fpst); + return 0; +} + static int disas_coproc_insn(DisasContext *s, uint32_t insn) { int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2; @@ -8424,6 +8486,12 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) } } } + } else if ((insn & 0x0e000a00) == 0x0c000800 + && arm_dc_feature(s, ARM_FEATURE_V8)) { + if (disas_neon_insn_3same_ext(s, insn)) { + goto illegal_op; + } + return; } else if ((insn & 0x0fe00000) == 0x0c400000) { /* Coprocessor double register transfer. */ ARCH(5TE); From patchwork Fri Mar 2 11:06:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880475 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6lc6nWSz9s3m for ; Fri, 2 Mar 2018 22:39:24 +1100 (AEDT) Received: from localhost ([::1]:34240 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erj23-0006kI-1R for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:39:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43698) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWw-0003Fu-GW for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWq-00055k-GV for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:14 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46782) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWq-00055M-9v for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:08 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWp-0001RX-Da for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:07 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:38 +0000 Message-Id: <20180302110640.28004-38-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 37/39] target/arm: Decode aa32 armv8.3 2-reg-index X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Signed-off-by: Richard Henderson Message-id: 20180228193125.20577-15-richard.henderson@linaro.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/translate.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/target/arm/translate.c b/target/arm/translate.c index 45513c9d86..3ad8b4031c 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -7742,6 +7742,61 @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn) return 0; } +/* Advanced SIMD two registers and a scalar extension. + * 31 24 23 22 20 16 12 11 10 9 8 3 0 + * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+ + * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm | + * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+ + * + */ + +static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn) +{ + int rd, rn, rm, rot, size, opr_sz; + TCGv_ptr fpst; + bool q; + + q = extract32(insn, 6, 1); + VFP_DREG_D(rd, insn); + VFP_DREG_N(rn, insn); + VFP_DREG_M(rm, insn); + if ((rd | rn) & q) { + return 1; + } + + if ((insn & 0xff000f10) == 0xfe000800) { + /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */ + rot = extract32(insn, 20, 2); + size = extract32(insn, 23, 1); + if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA) + || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) { + return 1; + } + } else { + return 1; + } + + if (s->fp_excp_el) { + gen_exception_insn(s, 4, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, false), s->fp_excp_el); + return 0; + } + if (!s->vfp_enabled) { + return 1; + } + + opr_sz = (1 + q) * 8; + fpst = get_fpstatus_ptr(1); + tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), + vfp_reg_offset(1, rn), + vfp_reg_offset(1, rm), fpst, + opr_sz, opr_sz, rot, + size ? gen_helper_gvec_fcmlas_idx + : gen_helper_gvec_fcmlah_idx); + tcg_temp_free_ptr(fpst); + return 0; +} + static int disas_coproc_insn(DisasContext *s, uint32_t insn) { int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2; @@ -8492,6 +8547,12 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) goto illegal_op; } return; + } else if ((insn & 0x0f000a00) == 0x0e000800 + && arm_dc_feature(s, ARM_FEATURE_V8)) { + if (disas_neon_insn_2reg_scalar_ext(s, insn)) { + goto illegal_op; + } + return; } else if ((insn & 0x0fe00000) == 0x0c400000) { /* Coprocessor double register transfer. */ ARCH(5TE); From patchwork Fri Mar 2 11:06:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880474 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6hl6KYwz9s5H for ; Fri, 2 Mar 2018 22:36:55 +1100 (AEDT) Received: from localhost ([::1]:34227 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erizY-0003sH-4v for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:36:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43681) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWs-0003BG-7O for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWr-000568-Dh for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:10 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46782) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWr-00055M-6e for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:09 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWq-0001Ro-2y for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:08 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:39 +0000 Message-Id: <20180302110640.28004-39-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 38/39] target/arm: Decode t32 simd 3reg and 2reg_scalar extension X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Happily, the bits are in the same places compared to a32. Signed-off-by: Richard Henderson Message-id: 20180228193125.20577-16-richard.henderson@linaro.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/translate.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/target/arm/translate.c b/target/arm/translate.c index 3ad8b4031c..ba6ab7d287 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -10774,7 +10774,19 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) default_exception_el(s)); break; } - if (((insn >> 24) & 3) == 3) { + if ((insn & 0xfe000a00) == 0xfc000800 + && arm_dc_feature(s, ARM_FEATURE_V8)) { + /* The Thumb2 and ARM encodings are identical. */ + if (disas_neon_insn_3same_ext(s, insn)) { + goto illegal_op; + } + } else if ((insn & 0xff000a00) == 0xfe000800 + && arm_dc_feature(s, ARM_FEATURE_V8)) { + /* The Thumb2 and ARM encodings are identical. */ + if (disas_neon_insn_2reg_scalar_ext(s, insn)) { + goto illegal_op; + } + } else if (((insn >> 24) & 3) == 3) { /* Translate into the equivalent ARM encoding. */ insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28); if (disas_neon_data_insn(s, insn)) { From patchwork Fri Mar 2 11:06:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 880472 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zt6dx6q68z9s4w for ; Fri, 2 Mar 2018 22:34:29 +1100 (AEDT) Received: from localhost ([::1]:34209 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erixH-0001Ds-LY for incoming@patchwork.ozlabs.org; Fri, 02 Mar 2018 06:34:27 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43690) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eriWs-0003Bo-Nm for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eriWr-00056L-RJ for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:10 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46784) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eriWr-00055v-KS for qemu-devel@nongnu.org; Fri, 02 Mar 2018 06:07:09 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1eriWq-0001S4-P3 for qemu-devel@nongnu.org; Fri, 02 Mar 2018 11:07:08 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 2 Mar 2018 11:06:40 +0000 Message-Id: <20180302110640.28004-40-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180302110640.28004-1-peter.maydell@linaro.org> References: <20180302110640.28004-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 39/39] target/arm: Enable ARM_FEATURE_V8_FCMA X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Enable it for the "any" CPU used by *-linux-user. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20180228193125.20577-17-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.c | 1 + target/arm/cpu64.c | 1 + 2 files changed, 2 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 3ee2d32aef..6b77aaa445 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1698,6 +1698,7 @@ static void arm_any_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); set_feature(&cpu->env, ARM_FEATURE_CRC); set_feature(&cpu->env, ARM_FEATURE_V8_RDM); + set_feature(&cpu->env, ARM_FEATURE_V8_FCMA); cpu->midr = 0xffffffff; } #endif diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 7246866e7d..4228713b19 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -232,6 +232,7 @@ static void aarch64_any_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_CRC); set_feature(&cpu->env, ARM_FEATURE_V8_RDM); set_feature(&cpu->env, ARM_FEATURE_V8_FP16); + set_feature(&cpu->env, ARM_FEATURE_V8_FCMA); cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */ cpu->dcz_blocksize = 7; /* 512 bytes */ }