From patchwork Tue Mar 23 04:12:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 12156807 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75AEFC433DB for ; Tue, 23 Mar 2021 04:18:27 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0E872619AD for ; Tue, 23 Mar 2021 04:18:27 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0E872619AD Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:34776 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lOYUs-0005xW-4i for qemu-devel@archiver.kernel.org; Tue, 23 Mar 2021 00:18:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55954) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lOYPR-0000iw-Ej for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:12:50 -0400 Received: from mail-qk1-x72a.google.com ([2607:f8b0:4864:20::72a]:44808) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lOYPM-0006b3-C1 for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:12:49 -0400 Received: by mail-qk1-x72a.google.com with SMTP id y18so13102513qky.11 for ; Mon, 22 Mar 2021 21:12:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5Ke2897yr/aabRiFiMjGPWrw0ecbwZr7UOByU5wL0Qs=; b=v8Pdf5gXGXUfqiFCd5vsRpiAcnTV/+lhqdmM9I+21ZnmVxNL76HWmBAN0aEDsfsq4q km/hD8y+t0QxfjEXn9b8BTkNvlegrA4OFn+9hPJA567oHEioqUTsyfuTo+IeEWCmg7Dw S/z9TY6Pg2XVtCPgmyjPqRl7dM7zkpQUd/FWYYblP/5iGfr2bPKwx37ZGFCkyc9ZajSc t+l3WIN1VFd1LrJ7YYZ8C4Akoo0Caeg4x9+0vKrNSJBW5t92g/U/xTQgjKluEz4/V92M IPOAf7orHu+c1YXwtK9+tnJsNsxZsWYRsuMaXqw07AiSOtJFphDV5QEy41IzMBAXgZd3 1jcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5Ke2897yr/aabRiFiMjGPWrw0ecbwZr7UOByU5wL0Qs=; b=ahWqj9k6U9POb5sZpEx4Nsw3f7bQ6gPf80REPcFKq+JzwdXta/7mEtaxAWhIn1EOwy czPDSVylD4USbubghOP/rKCGJws4+NU/JLcrQ9XFikv4AgIHdhH2cudBjfKWXVJmU8D0 T6pe2v8DH2/q6FKAzJZnThZKENcexgaJyIaLcl1QCpONz21/QkpvlDGSMqPQQt/RSQkw vQiJ3bRzFVR1CxjmYfUMDxxJfU+1nP5nt4jtmXBa3p+gXOkTDYg+8Xf/tjPN2NPwynFz FKV52G2VC6YU3vX315lNgr/tqnHZTurAM1Qt6uZSnw8MIIz7WIfhfMWNxdmIYzOUBxZw IGFQ== X-Gm-Message-State: AOAM530IIiprLceZyNMpUy/FrXAzgfXhyZLge6msXJZrZ0Obzyk5G04z qhM2QDlBnZg4YtDVza5eu8c2bQ== X-Google-Smtp-Source: ABdhPJwOugmI047J4M2OJQvDH2PTL7onVLTDixBW51POomyC3k8qC8gmlS0/MIHh8/mGFwR1U49Xug== X-Received: by 2002:a37:8743:: with SMTP id j64mr3428692qkd.299.1616472761021; Mon, 22 Mar 2021 21:12:41 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-23-174-92-28-28.dsl.bell.ca. [174.92.28.28]) by smtp.googlemail.com with ESMTPSA id m21sm12601181qka.28.2021.03.22.21.12.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 21:12:40 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v1 1/8] hw/intc: GICv3 ITS initial framework Date: Tue, 23 Mar 2021 00:12:31 -0400 Message-Id: <20210323041238.133835-2-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210323041238.133835-1-shashi.mallela@linaro.org> References: <20210323041238.133835-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::72a; envelope-from=shashi.mallela@linaro.org; helo=mail-qk1-x72a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added register definitions relevant to ITS,implemented overall ITS device framework with stubs for ITS control and translater regions read/write,extended ITS common to handle mmio init between existing kvm device and newer qemu device. Signed-off-by: Shashi Mallela --- hw/intc/arm_gicv3_its.c | 323 ++++++++++++++++++++ hw/intc/arm_gicv3_its_common.c | 17 +- hw/intc/arm_gicv3_its_kvm.c | 2 +- hw/intc/gicv3_internal.h | 173 ++++++++++- hw/intc/meson.build | 1 + include/hw/intc/arm_gicv3_its_common.h | 12 +- 6 files changed, 520 insertions(+), 8 deletions(-) diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c new file mode 100644 index 0000000000..34e49b4d63 --- /dev/null +++ b/hw/intc/arm_gicv3_its.c @@ -0,0 +1,323 @@ +/* + * ITS emulation for a GICv3-based system + * + * Copyright Linaro.org 2021 + * + * Authors: + * Shashi Mallela + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at your + * option) any later version. See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/qdev-properties.h" +#include "hw/intc/arm_gicv3_its_common.h" +#include "gicv3_internal.h" +#include "qom/object.h" + +typedef struct GICv3ITSClass GICv3ITSClass; +/* This is reusing the GICv3ITSState typedef from ARM_GICV3_ITS_COMMON */ +DECLARE_OBJ_CHECKERS(GICv3ITSState, GICv3ITSClass, + ARM_GICV3_ITS, TYPE_ARM_GICV3_ITS) + +struct GICv3ITSClass { + GICv3ITSCommonClass parent_class; + void (*parent_reset)(DeviceState *dev); +}; + +static MemTxResult its_trans_writew(GICv3ITSState *s, hwaddr offset, + uint64_t value, MemTxAttrs attrs) +{ + MemTxResult result = MEMTX_OK; + + return result; +} + +static MemTxResult its_trans_writel(GICv3ITSState *s, hwaddr offset, + uint64_t value, MemTxAttrs attrs) +{ + MemTxResult result = MEMTX_OK; + + return result; +} + +static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset, + uint64_t data, unsigned size, MemTxAttrs attrs) +{ + GICv3ITSState *s = (GICv3ITSState *)opaque; + MemTxResult result; + + switch (size) { + case 2: + result = its_trans_writew(s, offset, data, attrs); + break; + case 4: + result = its_trans_writel(s, offset, data, attrs); + break; + default: + result = MEMTX_ERROR; + break; + } + + if (result == MEMTX_ERROR) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid guest write at offset " TARGET_FMT_plx + "size %u\n", __func__, offset, size); + /* + * The spec requires that reserved registers are RAZ/WI; + * so use MEMTX_ERROR returns from leaf functions as a way to + * trigger the guest-error logging but don't return it to + * the caller, or we'll cause a spurious guest data abort. + */ + result = MEMTX_OK; + } + return result; +} + +static MemTxResult gicv3_its_trans_read(void *opaque, hwaddr offset, + uint64_t *data, unsigned size, MemTxAttrs attrs) +{ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Invalid read from transaction register area at offset " + TARGET_FMT_plx "\n", __func__, offset); + return MEMTX_ERROR; +} + +static MemTxResult its_writeb(GICv3ITSState *s, hwaddr offset, + uint64_t value, MemTxAttrs attrs) +{ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: unsupported byte write to register at offset " + TARGET_FMT_plx "\n", __func__, offset); + return MEMTX_ERROR; +} + +static MemTxResult its_readb(GICv3ITSState *s, hwaddr offset, + uint64_t *data, MemTxAttrs attrs) +{ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: unsupported byte read from register at offset " + TARGET_FMT_plx "\n", __func__, offset); + return MEMTX_ERROR; +} + +static MemTxResult its_writew(GICv3ITSState *s, hwaddr offset, + uint64_t value, MemTxAttrs attrs) +{ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: unsupported word write to register at offset " + TARGET_FMT_plx "\n", __func__, offset); + return MEMTX_ERROR; +} + +static MemTxResult its_readw(GICv3ITSState *s, hwaddr offset, + uint64_t *data, MemTxAttrs attrs) +{ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: unsupported word read from register at offset " + TARGET_FMT_plx "\n", __func__, offset); + return MEMTX_ERROR; +} + +static MemTxResult its_writel(GICv3ITSState *s, hwaddr offset, + uint64_t value, MemTxAttrs attrs) +{ + MemTxResult result = MEMTX_OK; + + return result; +} + +static MemTxResult its_readl(GICv3ITSState *s, hwaddr offset, + uint64_t *data, MemTxAttrs attrs) +{ + MemTxResult result = MEMTX_OK; + + return result; +} + +static MemTxResult its_writell(GICv3ITSState *s, hwaddr offset, + uint64_t value, MemTxAttrs attrs) +{ + MemTxResult result = MEMTX_OK; + + return result; +} + +static MemTxResult its_readll(GICv3ITSState *s, hwaddr offset, + uint64_t *data, MemTxAttrs attrs) +{ + MemTxResult result = MEMTX_OK; + + return result; +} + +static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data, + unsigned size, MemTxAttrs attrs) +{ + GICv3ITSState *s = (GICv3ITSState *)opaque; + MemTxResult result; + + switch (size) { + case 1: + result = its_readb(s, offset, data, attrs); + break; + case 2: + result = its_readw(s, offset, data, attrs); + break; + case 4: + result = its_readl(s, offset, data, attrs); + break; + case 8: + result = its_readll(s, offset, data, attrs); + break; + default: + result = MEMTX_ERROR; + break; + } + + if (result == MEMTX_ERROR) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid guest read at offset " TARGET_FMT_plx + "size %u\n", __func__, offset, size); + /* + * The spec requires that reserved registers are RAZ/WI; + * so use MEMTX_ERROR returns from leaf functions as a way to + * trigger the guest-error logging but don't return it to + * the caller, or we'll cause a spurious guest data abort. + */ + result = MEMTX_OK; + *data = 0; + } + return result; +} + +static MemTxResult gicv3_its_write(void *opaque, hwaddr offset, uint64_t data, + unsigned size, MemTxAttrs attrs) +{ + GICv3ITSState *s = (GICv3ITSState *)opaque; + MemTxResult result; + + switch (size) { + case 1: + result = its_writeb(s, offset, data, attrs); + break; + case 2: + result = its_writew(s, offset, data, attrs); + break; + case 4: + result = its_writel(s, offset, data, attrs); + break; + case 8: + result = its_writell(s, offset, data, attrs); + break; + default: + result = MEMTX_ERROR; + break; + } + + if (result == MEMTX_ERROR) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid guest write at offset " TARGET_FMT_plx + "size %u\n", __func__, offset, size); + /* + * The spec requires that reserved registers are RAZ/WI; + * so use MEMTX_ERROR returns from leaf functions as a way to + * trigger the guest-error logging but don't return it to + * the caller, or we'll cause a spurious guest data abort. + */ + result = MEMTX_OK; + } + return result; +} + +static const MemoryRegionOps gicv3_its_control_ops = { + .read_with_attrs = gicv3_its_read, + .write_with_attrs = gicv3_its_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static const MemoryRegionOps gicv3_its_trans_ops = { + .read_with_attrs = gicv3_its_trans_read, + .write_with_attrs = gicv3_its_trans_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static void gicv3_arm_its_realize(DeviceState *dev, Error **errp) +{ + GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev); + + gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_trans_ops); +} + +static void gicv3_its_reset(DeviceState *dev) +{ + GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev); + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + + if (s->gicv3->cpu->gicr_typer & GICR_TYPER_PLPIS) { + c->parent_reset(dev); + + /* set the ITS default features supported */ + s->typer = GITS_TYPER_PHYSICAL | (GITS_TYPER_ITT_ENTRY_SIZE << + GITS_TYPER_ITT_ENTRY_OFFSET) | (GITS_TYPER_IDBITS << + GITS_TYPER_IDBITS_OFFSET) | GITS_TYPER_DEVBITS | + GITS_TYPER_CIL | GITS_TYPER_CIDBITS; + + /* + * We claim to be an ARM r0p0 with a zero ProductID. + * This is the same as an r0p0 GIC-500. + */ + s->iidr = gicv3_iidr(); + + /* Quiescent bit reset to 1 */ + s->ctlr = (1U << 31); + + /* + * setting GITS_BASER0.Type = 0b001 (Device) + * GITS_BASER1.Type = 0b100 (Collection Table) + * GITS_BASER.Type,where n = 3 to 7 are 0b00 (Unimplemented) + * GITS_BASER<0,1>.Page_Size = 64KB + * and default translation table entry size to 16 bytes + */ + s->baser[0] = (GITS_ITT_TYPE_DEVICE << GITS_BASER_TYPE_OFFSET) | + (GITS_BASER_PAGESIZE_64K << GITS_BASER_PAGESIZE_OFFSET) | + (GITS_DTE_SIZE << GITS_BASER_ENTRYSIZE_OFFSET); + s->baser[1] = (GITS_ITT_TYPE_COLLECTION << GITS_BASER_TYPE_OFFSET) | + (GITS_BASER_PAGESIZE_64K << GITS_BASER_PAGESIZE_OFFSET) | + (GITS_CTE_SIZE << GITS_BASER_ENTRYSIZE_OFFSET); + } +} + +static Property gicv3_its_props[] = { + DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "arm-gicv3", + GICv3State *), + DEFINE_PROP_END_OF_LIST(), +}; + +static void gicv3_its_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + GICv3ITSClass *ic = ARM_GICV3_ITS_CLASS(klass); + + dc->realize = gicv3_arm_its_realize; + device_class_set_props(dc, gicv3_its_props); + device_class_set_parent_reset(dc, gicv3_its_reset, &ic->parent_reset); +} + +static const TypeInfo gicv3_its_info = { + .name = TYPE_ARM_GICV3_ITS, + .parent = TYPE_ARM_GICV3_ITS_COMMON, + .instance_size = sizeof(GICv3ITSState), + .class_init = gicv3_its_class_init, + .class_size = sizeof(GICv3ITSClass), +}; + +static void gicv3_its_register_types(void) +{ + type_register_static(&gicv3_its_info); +} + +type_init(gicv3_its_register_types) diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c index 66c4c6a188..c18fe23fae 100644 --- a/hw/intc/arm_gicv3_its_common.c +++ b/hw/intc/arm_gicv3_its_common.c @@ -55,7 +55,9 @@ static const VMStateDescription vmstate_its = { .priority = MIG_PRI_GICV3_ITS, .fields = (VMStateField[]) { VMSTATE_UINT32(ctlr, GICv3ITSState), + VMSTATE_UINT32(translater, GICv3ITSState), VMSTATE_UINT32(iidr, GICv3ITSState), + VMSTATE_UINT64(typer, GICv3ITSState), VMSTATE_UINT64(cbaser, GICv3ITSState), VMSTATE_UINT64(cwriter, GICv3ITSState), VMSTATE_UINT64(creadr, GICv3ITSState), @@ -99,15 +101,21 @@ static const MemoryRegionOps gicv3_its_trans_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops) +void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops, + const MemoryRegionOps *tops) { SysBusDevice *sbd = SYS_BUS_DEVICE(s); memory_region_init_io(&s->iomem_its_cntrl, OBJECT(s), ops, s, "control", ITS_CONTROL_SIZE); - memory_region_init_io(&s->iomem_its_translation, OBJECT(s), - &gicv3_its_trans_ops, s, - "translation", ITS_TRANS_SIZE); + if (tops == NULL) { + memory_region_init_io(&s->iomem_its_translation, OBJECT(s), + &gicv3_its_trans_ops, s, + "translation", ITS_TRANS_SIZE); + } else { + memory_region_init_io(&s->iomem_its_translation, OBJECT(s), + tops, s, "translation", ITS_TRANS_SIZE); + } /* Our two regions are always adjacent, therefore we now combine them * into a single one in order to make our users' life easier. @@ -130,6 +138,7 @@ static void gicv3_its_common_reset(DeviceState *dev) s->cwriter = 0; s->creadr = 0; s->iidr = 0; + s->translater = 0; memset(&s->baser, 0, sizeof(s->baser)); } diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c index b554d2ede0..0b4cbed28b 100644 --- a/hw/intc/arm_gicv3_its_kvm.c +++ b/hw/intc/arm_gicv3_its_kvm.c @@ -106,7 +106,7 @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp) kvm_arm_register_device(&s->iomem_its_cntrl, -1, KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_ITS_ADDR_TYPE, s->dev_fd, 0); - gicv3_its_init_mmio(s, NULL); + gicv3_its_init_mmio(s, NULL, NULL); if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS, GITS_CTLR)) { diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h index 05303a55c8..7c6bc33e97 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -67,6 +67,12 @@ #define GICD_CTLR_E1NWF (1U << 7) #define GICD_CTLR_RWP (1U << 31) +#define GICD_TYPER_LPIS_OFFSET 17 +#define GICD_TYPER_IDBITS_OFFSET 19 +#define GICD_TYPER_IDBITS_MASK 0x1f +/* 16 bits EventId */ +#define GICD_TYPER_IDBITS 0xf + /* * Redistributor frame offsets from RD_base */ @@ -123,14 +129,17 @@ #define GICR_WAKER_ChildrenAsleep (1U << 2) #define GICR_PROPBASER_OUTER_CACHEABILITY_MASK (7ULL << 56) -#define GICR_PROPBASER_ADDR_MASK (0xfffffffffULL << 12) +#define GICR_PROPBASER_ADDR_OFFSET 12 +#define GICR_PROPBASER_ADDR_MASK ((1ULL << 40) - 1) #define GICR_PROPBASER_SHAREABILITY_MASK (3U << 10) #define GICR_PROPBASER_CACHEABILITY_MASK (7U << 7) #define GICR_PROPBASER_IDBITS_MASK (0x1f) +#define GICR_PROPBASER_IDBITS_THRESHOLD 0xd #define GICR_PENDBASER_PTZ (1ULL << 62) #define GICR_PENDBASER_OUTER_CACHEABILITY_MASK (7ULL << 56) -#define GICR_PENDBASER_ADDR_MASK (0xffffffffULL << 16) +#define GICR_PENDBASER_ADDR_OFFSET 16 +#define GICR_PENDBASER_ADDR_MASK ((1ULL << 36) - 1) #define GICR_PENDBASER_SHAREABILITY_MASK (3U << 10) #define GICR_PENDBASER_CACHEABILITY_MASK (7U << 7) @@ -239,11 +248,171 @@ #define ICH_VTR_EL2_PREBITS_SHIFT 26 #define ICH_VTR_EL2_PRIBITS_SHIFT 29 +#define GITS_CTLR_ENABLED (1U << 0) /* ITS Enabled or not */ +#define GITS_CTLR_QUIESCENT (1U << 31) /* Quiescent bit */ + +#define GITS_BASER_SIZE (0xff) +#define GITS_BASER_PAGESIZE_OFFSET 8 +#define GITS_BASER_PAGESIZE_MASK 0x3 +#define GITS_BASER_SHAREABILITY_OFFSET 10 +#define GITS_BASER_SHAREABILITY_MASK 0x3 +#define GITS_BASER_PHYADDR_OFFSET 12 +#define GITS_BASER_PHYADDR_MASK ((1ULL << 36) - 1) +#define GITS_BASER_PHYADDR_OFFSETL_64K 16 +#define GITS_BASER_PHYADDR_MASKL_64K ((1ULL << 32) - 1) +#define GITS_BASER_PHYADDR_OFFSETH_64K 48 +#define GITS_BASER_PHYADDR_MASKH_64K ((1ULL << 4) - 1) +#define GITS_BASER_ENTRYSIZE_OFFSET 48 +#define GITS_BASER_ENTRYSIZE_MASK ((1U << 5) - 1) +#define GITS_BASER_OUTERCACHE_OFFSET 53 +#define GITS_BASER_OUTERCACHE_MASK 0x7 +#define GITS_BASER_TYPE_OFFSET 56 +#define GITS_BASER_TYPE_MASK 0x7 +#define GITS_BASER_INNERCACHE_OFFSET 59 +#define GITS_BASER_INNERCACHE_MASK 0x7 +#define GITS_BASER_INDIRECT_OFFSET 62 +#define GITS_BASER_INDIRECT_MASK 0x1 +#define GITS_BASER_VALID 63 +#define GITS_BASER_VALID_MASK 0x1 + +#define GITS_BASER_VAL_MASK ((0x7ULL << 56) | (0x1fULL << 48)) + +#define GITS_BASER_PAGESIZE_4K 0 +#define GITS_BASER_PAGESIZE_16K 1 +#define GITS_BASER_PAGESIZE_64K 2 + +#define GITS_ITT_TYPE_DEVICE 1ULL +#define GITS_ITT_TYPE_COLLECTION 4ULL + +#define GITS_CBASER_SIZE (0xff) +#define GITS_CBASER_SHAREABILITY_OFFSET 10 +#define GITS_CBASER_SHAREABILITY_MASK 0x3 +#define GITS_CBASER_PHYADDR_OFFSET 12 +#define GITS_CBASER_PHYADDR_MASK ((1ULL << 40) - 1) +#define GITS_CBASER_OUTERCACHE_OFFSET 53 +#define GITS_CBASER_OUTERCACHE_MASK 0x7 +#define GITS_CBASER_INNERCACHE_OFFSET 59 +#define GITS_CBASER_INNERCACHE_MASK 0x7 +#define GITS_CBASER_VALID_OFFSET 63 +#define GITS_CBASER_VALID_MASK 0x1 + +#define GITS_CREADR_STALLED (1U << 0) +#define GITS_CREADR_OFFSET 5 +#define GITS_CREADR_OFFSET_MASK ((1U << 15) - 1) + +#define GITS_CWRITER_RETRY (1U << 0) +#define GITS_CWRITER_OFFSET 5 +#define GITS_CWRITER_OFFSET_MASK ((1U << 15) - 1) + +#define GITS_TYPER_DEVBITS_OFFSET 13 +#define GITS_TYPER_DEVBITS_MASK 0x1f +#define GITS_TYPER_IDBITS_OFFSET 8 +#define GITS_TYPER_IDBITS_MASK 0x1f +#define GITS_TYPER_CIDBITS_OFFSET 32 +#define GITS_TYPER_CIDBITS_MASK 0xf +#define GITS_TYPER_CIL_OFFSET 36 +#define GITS_TYPER_CIL_MASK 0x1 +#define GITS_TYPER_PTA_OFFSET 19 +#define GITS_TYPER_PTA_MASK 0x1 +#define GITS_TYPER_SEIS_OFFSET 18 +#define GITS_TYPER_SEIS_MASK 0x1 + +/* Default features advertised by this version of ITS */ +/* Physical LPIs supported */ +#define GITS_TYPER_PHYSICAL (1U << 0) +/* + * 11 bytes Interrupt translation Table Entry size + * Valid = 1 bit,InterruptType = 1 bit, + * Size of LPI number space[considering max 24 bits], + * Size of LPI number space[considering max 24 bits], + * ICID = 16 bits, + * vPEID = 16 bits + */ +#define GITS_TYPER_ITT_ENTRY_OFFSET 4 +#define GITS_TYPER_ITT_ENTRY_SIZE 0xB +#define GITS_TYPER_IDBITS_OFFSET 8 + +/* 16 bits EventId */ +#define GITS_TYPER_IDBITS GICD_TYPER_IDBITS +/* 16 bits DeviceId */ +#define GITS_TYPER_DEVBITS (0xf << 13) +/* Collection ID Limit indicated by CIDbits(next) */ +#define GITS_TYPER_CIL (1ULL << 36) +/* 16 bits CollectionId */ +#define GITS_TYPER_CIDBITS (0xfULL << 32) +/* + * 8 bytes Device Table Entry size + * Valid = 1 bit,ITTAddr = 44 bits,Size = 5 bits + */ +#define GITS_DTE_SIZE (0x8ULL) +/* + * 8 bytes Collection Table Entry size + * Valid = 1 bit,RDBase = 36 bits(considering max RDBASE) + */ +#define GITS_CTE_SIZE (0x8ULL) + /* Special interrupt IDs */ #define INTID_SECURE 1020 #define INTID_NONSECURE 1021 #define INTID_SPURIOUS 1023 +/* ITS Commands */ +#define GITS_CMD_CLEAR 0x04 +#define GITS_CMD_DISCARD 0x0F +#define GITS_CMD_INT 0x03 +#define GITS_CMD_MAPC 0x09 +#define GITS_CMD_MAPD 0x08 +#define GITS_CMD_MAPI 0x0B +#define GITS_CMD_MAPTI 0x0A +#define GITS_CMD_SYNC 0x05 + +#define GITS_ITT_PAGE_SIZE_0 0x1000 +#define GITS_ITT_PAGE_SIZE_1 0x4000 +#define GITS_ITT_PAGE_SIZE_2 0x10000 + +#define GITS_CMDQ_ENTRY_SIZE 32 +#define GITS_CMDQ_MAX_ENTRIES_PER_PAGE 128 +#define NUM_BYTES_IN_DW 8 + +#define CMD_MASK 0xff + +/* MAPC command fields */ +#define ICID_LEN 16 +#define ICID_MASK ((1U << ICID_LEN) - 1) +#define RDBASE_LEN 32 +#define RDBASE_OFFSET 16 +#define RDBASE_MASK ((1ULL << RDBASE_LEN) - 1) +#define RDBASE_PROCNUM_LEN 16 +#define RDBASE_PROCNUM_MASK ((1ULL << RDBASE_PROCNUM_LEN) - 1) + +#define DEVID_OFFSET 32 +#define DEVID_LEN 32 +#define DEVID_MASK ((1ULL << DEVID_LEN) - 1) + +/* MAPD command fields */ +#define ITTADDR_LEN 44 +#define ITTADDR_OFFSET 8 +#define ITTADDR_MASK ((1ULL << ITTADDR_LEN) - 1) +#define SIZE_MASK 0x1f + +/* MAPI command fields */ +#define EVENTID_MASK ((1ULL << 32) - 1) + +/* MAPTI command fields */ +#define pINTID_OFFSET 32 +#define pINTID_MASK ((1ULL << 32) - 1) + +#define VALID_SHIFT 63 +#define VALID_MASK 0x1 + +#define L1TABLE_ENTRY_SIZE 8 + +#define LPI_CTE_ENABLE_OFFSET 0 +#define LPI_CTE_ENABLED VALID_MASK +#define LPI_CTE_PRIORITY_OFFSET 2 +#define LPI_CTE_PRIORITY_MASK ((1U << 6) - 1) +#define LPI_PRIORITY_MASK 0xfc + /* Functions internal to the emulated GICv3 */ /** diff --git a/hw/intc/meson.build b/hw/intc/meson.build index 1c299039f6..53472239f0 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -8,6 +8,7 @@ softmmu_ss.add(when: 'CONFIG_ARM_GIC', if_true: files( 'arm_gicv3_dist.c', 'arm_gicv3_its_common.c', 'arm_gicv3_redist.c', + 'arm_gicv3_its.c', )) softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c')) softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c')) diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h index 5a0952b404..08bc5652ed 100644 --- a/include/hw/intc/arm_gicv3_its_common.h +++ b/include/hw/intc/arm_gicv3_its_common.h @@ -25,17 +25,24 @@ #include "hw/intc/arm_gicv3_common.h" #include "qom/object.h" +#define TYPE_ARM_GICV3_ITS "arm-gicv3-its" + #define ITS_CONTROL_SIZE 0x10000 #define ITS_TRANS_SIZE 0x10000 #define ITS_SIZE (ITS_CONTROL_SIZE + ITS_TRANS_SIZE) #define GITS_CTLR 0x0 #define GITS_IIDR 0x4 +#define GITS_TYPER 0x8 #define GITS_CBASER 0x80 #define GITS_CWRITER 0x88 #define GITS_CREADR 0x90 #define GITS_BASER 0x100 +#define GITS_TRANSLATER 0x0040 + +#define GITS_PIDR2 0xFFE8 + struct GICv3ITSState { SysBusDevice parent_obj; @@ -52,6 +59,8 @@ struct GICv3ITSState { /* Registers */ uint32_t ctlr; uint32_t iidr; + uint32_t translater; + uint64_t typer; uint64_t cbaser; uint64_t cwriter; uint64_t creadr; @@ -62,7 +71,8 @@ struct GICv3ITSState { typedef struct GICv3ITSState GICv3ITSState; -void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops); +void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops, + const MemoryRegionOps *tops); #define TYPE_ARM_GICV3_ITS_COMMON "arm-gicv3-its-common" typedef struct GICv3ITSCommonClass GICv3ITSCommonClass; From patchwork Tue Mar 23 04:12:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 12156809 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 167F6C433DB for ; Tue, 23 Mar 2021 04:18:44 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9676E6191C for ; Tue, 23 Mar 2021 04:18:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9676E6191C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:36374 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lOYV8-0006c3-L1 for qemu-devel@archiver.kernel.org; Tue, 23 Mar 2021 00:18:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56022) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lOYPi-0000kd-MK for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:13:10 -0400 Received: from mail-qv1-xf32.google.com ([2607:f8b0:4864:20::f32]:40716) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lOYPM-0006bA-Gb for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:13:05 -0400 Received: by mail-qv1-xf32.google.com with SMTP id d10so9846134qve.7 for ; Mon, 22 Mar 2021 21:12:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=pugq0tEYqE43OpGJ8B4HpfYPr11672bH57Wdq34mmcM=; b=AOj4Xvld57QokcfwXUz/TvtEk96xkPkYeBKXEWo1rodQq1hlfNvf5mZ11FtGUZ/7xd Us7QARmquhulkzSG2UgQCzN78fHZhfqw6FcFiUOk4ziFDP3pk3MXATnYYl2l+YfvAMT9 7w+lZeAW4/Z3J01yZJdJOYLfIsnaVOfPODeJSfHvW3KV4CUVA2Qr8tFJdPyvM5HNGdfe HeMazYX70XfZu5w9tLv/T1CIx5H/fRJnqMn6LFyE9/tMpZ68/xSqYYFth07T41va7CHG 5ZuO3b7v1isFnB6fZBvUrZA/JGa1mIfsNMgV4RkSiZ480KwSPzwZwgNJktvkEkarxchE b4pQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pugq0tEYqE43OpGJ8B4HpfYPr11672bH57Wdq34mmcM=; b=qZXzzfQPmOBV/IEzkXgs/dcJJL65xxS7A0mfk+DsEnyA4S8FYig2zL5h6IufM/w24n SnVjq1uNmFRBcuiJxlxl/fsjnIfAmoAmD0d/rQLMOK8nQeJ38S7Al6xfHdmqDMUuK4aY 9AB28HVx7HtpmXPrUDcd4KUukk3/ItUEHPoOvuGhMWqtTdPPG6NyiQgfQHutjb4MaZXV L7TUMjmFK+wDrZsOCYEFLfvyEbosiZiYX7DhPC9e3UmkP6pFph7E13cn3B3eBpXF62Hf cducAK0o22g3lcEPsm951BVkGte7cf+PQ57q4uF6+RVhE+hQRrdkRK2p5DYuk7ENPQBJ bPcw== X-Gm-Message-State: AOAM530NDpZIolfJ36hOnmwGxWXwAx+25Smyx9XWH1/InuQ4Hwnt8zTS tUg1Yoz7Tf4lvDUddq+N48HlHQ== X-Google-Smtp-Source: ABdhPJxsoxUHUxp/xlntp89fvLyQBOl+wCtdPGC0ahoyyNX68mxTmYVWYZmqqoWwRs4IDETkMzgCWg== X-Received: by 2002:a05:6214:20ad:: with SMTP id 13mr2959409qvd.35.1616472761735; Mon, 22 Mar 2021 21:12:41 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-23-174-92-28-28.dsl.bell.ca. [174.92.28.28]) by smtp.googlemail.com with ESMTPSA id m21sm12601181qka.28.2021.03.22.21.12.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 21:12:41 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v1 2/8] hw/intc: GICv3 ITS register definitions added Date: Tue, 23 Mar 2021 00:12:32 -0400 Message-Id: <20210323041238.133835-3-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210323041238.133835-1-shashi.mallela@linaro.org> References: <20210323041238.133835-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::f32; envelope-from=shashi.mallela@linaro.org; helo=mail-qv1-xf32.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Defined descriptors for ITS device table,collection table and ITS command queue entities.Implemented register read/write functions, extract ITS table parameters and command queue parameters,extended gicv3 common to capture qemu address space(which host the ITS table platform memories required for subsequent ITS processing) and initialize the same in its device. Signed-off-by: Shashi Mallela --- hw/intc/arm_gicv3_its.c | 356 ++++++++++++++++++++ include/hw/intc/arm_gicv3_common.h | 4 + 2 files changed, 360 insertions(+) diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index 34e49b4d63..4895d32e67 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -23,11 +23,179 @@ typedef struct GICv3ITSClass GICv3ITSClass; DECLARE_OBJ_CHECKERS(GICv3ITSState, GICv3ITSClass, ARM_GICV3_ITS, TYPE_ARM_GICV3_ITS) +typedef struct { + bool valid; + bool indirect; + uint16_t entry_sz; + uint32_t max_entries; + uint32_t max_devids; + uint64_t base_addr; +} DevTableDesc; + +typedef struct { + bool valid; + bool indirect; + uint16_t entry_sz; + uint32_t max_entries; + uint32_t max_collids; + uint64_t base_addr; +} CollTableDesc; + +typedef struct { + bool valid; + uint32_t max_entries; + uint64_t base_addr; +} CmdQDesc; + struct GICv3ITSClass { GICv3ITSCommonClass parent_class; void (*parent_reset)(DeviceState *dev); + + DevTableDesc dt; + CollTableDesc ct; + CmdQDesc cq; }; +static bool extract_table_params(GICv3ITSState *s, int index) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + uint16_t num_pages = 0; + uint8_t page_sz_type; + uint8_t type; + uint32_t page_sz = 0; + uint64_t value = s->baser[index]; + + num_pages = (value & GITS_BASER_SIZE); + page_sz_type = (value >> GITS_BASER_PAGESIZE_OFFSET) & + GITS_BASER_PAGESIZE_MASK; + + if (page_sz_type == 0) { + page_sz = GITS_ITT_PAGE_SIZE_0; + } else if (page_sz_type == 0) { + page_sz = GITS_ITT_PAGE_SIZE_1; + } else if (page_sz_type == 2) { + page_sz = GITS_ITT_PAGE_SIZE_2; + } else { + return false; + } + + type = (value >> GITS_BASER_TYPE_OFFSET) & + GITS_BASER_TYPE_MASK; + + if (type == GITS_ITT_TYPE_DEVICE) { + c->dt.valid = (value >> GITS_BASER_VALID) & GITS_BASER_VALID_MASK; + + if (c->dt.valid) { + c->dt.indirect = (value >> GITS_BASER_INDIRECT_OFFSET) & + GITS_BASER_INDIRECT_MASK; + c->dt.entry_sz = (value >> GITS_BASER_ENTRYSIZE_OFFSET) & + GITS_BASER_ENTRYSIZE_MASK; + + if (!c->dt.indirect) { + c->dt.max_entries = ((num_pages + 1) * page_sz) / + c->dt.entry_sz; + } else { + c->dt.max_entries = ((((num_pages + 1) * page_sz) / + L1TABLE_ENTRY_SIZE) * + (page_sz / c->dt.entry_sz)); + } + + c->dt.max_devids = (1UL << (((value >> GITS_TYPER_DEVBITS_OFFSET) & + GITS_TYPER_DEVBITS_MASK) + 1)); + + if ((page_sz == GITS_ITT_PAGE_SIZE_0) || + (page_sz == GITS_ITT_PAGE_SIZE_1)) { + c->dt.base_addr = (value >> GITS_BASER_PHYADDR_OFFSET) & + GITS_BASER_PHYADDR_MASK; + c->dt.base_addr <<= GITS_BASER_PHYADDR_OFFSET; + } else if (page_sz == GITS_ITT_PAGE_SIZE_2) { + c->dt.base_addr = ((value >> GITS_BASER_PHYADDR_OFFSETL_64K) & + GITS_BASER_PHYADDR_MASKL_64K) << + GITS_BASER_PHYADDR_OFFSETL_64K; + c->dt.base_addr |= ((value >> GITS_BASER_PHYADDR_OFFSET) & + GITS_BASER_PHYADDR_MASKH_64K) << + GITS_BASER_PHYADDR_OFFSETH_64K; + } + } + } else if (type == GITS_ITT_TYPE_COLLECTION) { + c->ct.valid = (value >> GITS_BASER_VALID) & GITS_BASER_VALID_MASK; + + /* + * GITS_TYPER.HCC is 0 for this implementation + * hence writes are discarded if ct.valid is 0 + */ + if (c->ct.valid) { + c->ct.indirect = (value >> GITS_BASER_INDIRECT_OFFSET) & + GITS_BASER_INDIRECT_MASK; + c->ct.entry_sz = (value >> GITS_BASER_ENTRYSIZE_OFFSET) & + GITS_BASER_ENTRYSIZE_MASK; + + if (!c->ct.indirect) { + c->ct.max_entries = ((num_pages + 1) * page_sz) / + c->ct.entry_sz; + } else { + c->ct.max_entries = ((((num_pages + 1) * page_sz) / + L1TABLE_ENTRY_SIZE) * + (page_sz / c->ct.entry_sz)); + } + + if ((value >> GITS_TYPER_CIL_OFFSET) & GITS_TYPER_CIL_MASK) { + c->ct.max_collids = (1UL << (((value >> + GITS_TYPER_CIDBITS_OFFSET) & + GITS_TYPER_CIDBITS_MASK) + 1)); + } else { + /* 16-bit CollectionId supported when CIL == 0 */ + c->ct.max_collids = (1UL << 16); + } + + if ((page_sz == GITS_ITT_PAGE_SIZE_0) || + (page_sz == GITS_ITT_PAGE_SIZE_1)) { + c->ct.base_addr = (value >> GITS_BASER_PHYADDR_OFFSET) & + GITS_BASER_PHYADDR_MASK; + c->ct.base_addr <<= GITS_BASER_PHYADDR_OFFSET; + } else if (page_sz == GITS_ITT_PAGE_SIZE_2) { + c->ct.base_addr = ((value >> GITS_BASER_PHYADDR_OFFSETL_64K) & + GITS_BASER_PHYADDR_MASKL_64K) << + GITS_BASER_PHYADDR_OFFSETL_64K; + c->ct.base_addr |= ((value >> GITS_BASER_PHYADDR_OFFSET) & + GITS_BASER_PHYADDR_MASKH_64K) << + GITS_BASER_PHYADDR_OFFSETH_64K; + } + } + } else { + /* unsupported ITS table type */ + qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported ITS table type %d", + __func__, type); + return false; + } + return true; +} + +static bool extract_cmdq_params(GICv3ITSState *s) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + uint16_t num_pages = 0; + uint64_t value = s->cbaser; + + num_pages = (value & GITS_CBASER_SIZE); + + c->cq.valid = (value >> GITS_CBASER_VALID_OFFSET) & + GITS_CBASER_VALID_MASK; + + if (!num_pages || !c->cq.valid) { + return false; + } + + if (c->cq.valid) { + c->cq.max_entries = ((num_pages + 1) * GITS_ITT_PAGE_SIZE_0) / + GITS_CMDQ_ENTRY_SIZE; + c->cq.base_addr = (value >> GITS_CBASER_PHYADDR_OFFSET) & + GITS_CBASER_PHYADDR_MASK; + c->cq.base_addr <<= GITS_CBASER_PHYADDR_OFFSET; + } + return true; +} + static MemTxResult its_trans_writew(GICv3ITSState *s, hwaddr offset, uint64_t value, MemTxAttrs attrs) { @@ -126,7 +294,75 @@ static MemTxResult its_writel(GICv3ITSState *s, hwaddr offset, uint64_t value, MemTxAttrs attrs) { MemTxResult result = MEMTX_OK; + int index; + uint64_t temp = 0; + switch (offset) { + case GITS_CTLR: + s->ctlr |= (value & ~(s->ctlr)); + break; + case GITS_CBASER: + /* GITS_CBASER register becomes RO if ITS is already enabled */ + if (!(s->ctlr & GITS_CTLR_ENABLED)) { + s->cbaser = deposit64(s->cbaser, 0, 32, value); + s->creadr = 0; + } + break; + case GITS_CBASER + 4: + /* GITS_CBASER register becomes RO if ITS is already enabled */ + if (!(s->ctlr & GITS_CTLR_ENABLED)) { + s->cbaser = deposit64(s->cbaser, 32, 32, value); + if (!extract_cmdq_params(s)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: error extracting GITS_CBASER parameters " + TARGET_FMT_plx "\n", __func__, offset); + s->cbaser = 0; + result = MEMTX_ERROR; + } else { + s->creadr = 0; + } + } + break; + case GITS_CWRITER: + s->cwriter = deposit64(s->cwriter, 0, 32, value); + break; + case GITS_CWRITER + 4: + s->cwriter = deposit64(s->cwriter, 32, 32, value); + break; + case GITS_BASER ... GITS_BASER + 0x3f: + /* GITS_BASERn registers become RO if ITS is already enabled */ + if (!(s->ctlr & GITS_CTLR_ENABLED)) { + index = (offset - GITS_BASER) / 8; + + if (offset & 7) { + temp = s->baser[index]; + temp = deposit64(temp, 32, 32, (value & ~GITS_BASER_VAL_MASK)); + s->baser[index] |= temp; + + if (!extract_table_params(s, index)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: error extracting GITS_BASER parameters " + TARGET_FMT_plx "\n", __func__, offset); + s->baser[index] = 0; + result = MEMTX_ERROR; + } + } else { + s->baser[index] = deposit64(s->baser[index], 0, 32, value); + } + } + break; + case GITS_IIDR: + case GITS_TYPER: + case GITS_CREADR: + /* RO registers, ignore the write */ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid guest write to RO register at offset " + TARGET_FMT_plx "\n", __func__, offset); + break; + default: + result = MEMTX_ERROR; + break; + } return result; } @@ -134,7 +370,54 @@ static MemTxResult its_readl(GICv3ITSState *s, hwaddr offset, uint64_t *data, MemTxAttrs attrs) { MemTxResult result = MEMTX_OK; + int index; + switch (offset) { + case GITS_CTLR: + *data = s->ctlr; + break; + case GITS_IIDR: + *data = s->iidr; + break; + case GITS_PIDR2: + *data = 0x30; /* GICv3 */ + break; + case GITS_TYPER: + *data = extract64(s->typer, 0, 32); + break; + case GITS_TYPER + 4: + *data = extract64(s->typer, 32, 32); + break; + case GITS_CBASER: + *data = extract64(s->cbaser, 0, 32); + break; + case GITS_CBASER + 4: + *data = extract64(s->cbaser, 32, 32); + break; + case GITS_CREADR: + *data = extract64(s->creadr, 0, 32); + break; + case GITS_CREADR + 4: + *data = extract64(s->creadr, 32, 32); + break; + case GITS_CWRITER: + *data = extract64(s->cwriter, 0, 32); + break; + case GITS_CWRITER + 4: + *data = extract64(s->cwriter, 32, 32); + break; + case GITS_BASER ... GITS_BASER + 0x3f: + index = (offset - GITS_BASER) / 8; + if (offset & 7) { + *data = s->baser[index] >> 32; + } else { + *data = (uint32_t)s->baser[index]; + } + break; + default: + result = MEMTX_ERROR; + break; + } return result; } @@ -142,7 +425,52 @@ static MemTxResult its_writell(GICv3ITSState *s, hwaddr offset, uint64_t value, MemTxAttrs attrs) { MemTxResult result = MEMTX_OK; + int index; + switch (offset) { + case GITS_BASER ... GITS_BASER + 0x3f: + /* GITS_BASERn registers become RO if ITS is already enabled */ + if (!(s->ctlr & GITS_CTLR_ENABLED)) { + index = (offset - GITS_BASER) / 8; + s->baser[index] |= (value & ~GITS_BASER_VAL_MASK); + if (!extract_table_params(s, index)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: error extracting GITS_BASER parameters " + TARGET_FMT_plx "\n", __func__, offset); + s->baser[index] = 0; + result = MEMTX_ERROR; + } + } + break; + case GITS_CBASER: + /* GITS_CBASER register becomes RO if ITS is already enabled */ + if (!(s->ctlr & GITS_CTLR_ENABLED)) { + s->cbaser = value; + if (!extract_cmdq_params(s)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: error extracting GITS_CBASER parameters " + TARGET_FMT_plx "\n", __func__, offset); + s->cbaser = 0; + result = MEMTX_ERROR; + } else { + s->creadr = 0; + } + } + break; + case GITS_CWRITER: + s->cwriter = value; + break; + case GITS_TYPER: + case GITS_CREADR: + /* RO register, ignore the write */ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid guest write to RO register at offset " + TARGET_FMT_plx "\n", __func__, offset); + break; + default: + result = MEMTX_ERROR; + break; + } return result; } @@ -150,7 +478,29 @@ static MemTxResult its_readll(GICv3ITSState *s, hwaddr offset, uint64_t *data, MemTxAttrs attrs) { MemTxResult result = MEMTX_OK; + int index; + switch (offset) { + case GITS_TYPER: + *data = s->typer; + break; + case GITS_BASER ... GITS_BASER + 0x3f: + index = (offset - GITS_BASER) / 8; + *data = s->baser[index]; + break; + case GITS_CBASER: + *data = s->cbaser; + break; + case GITS_CREADR: + *data = s->creadr; + break; + case GITS_CWRITER: + *data = s->cwriter; + break; + default: + result = MEMTX_ERROR; + break; + } return result; } @@ -250,6 +600,9 @@ static void gicv3_arm_its_realize(DeviceState *dev, Error **errp) GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev); gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_trans_ops); + + address_space_init(&s->gicv3->sysmem_as, s->gicv3->sysmem, + "gicv3-its-sysmem"); } static void gicv3_its_reset(DeviceState *dev) @@ -259,6 +612,9 @@ static void gicv3_its_reset(DeviceState *dev) if (s->gicv3->cpu->gicr_typer & GICR_TYPER_PLPIS) { c->parent_reset(dev); + memset(&c->dt, 0 , sizeof(c->dt)); + memset(&c->ct, 0 , sizeof(c->ct)); + memset(&c->cq, 0 , sizeof(c->cq)); /* set the ITS default features supported */ s->typer = GITS_TYPER_PHYSICAL | (GITS_TYPER_ITT_ENTRY_SIZE << diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h index 91491a2f66..b0f2414fa3 100644 --- a/include/hw/intc/arm_gicv3_common.h +++ b/include/hw/intc/arm_gicv3_common.h @@ -226,12 +226,16 @@ struct GICv3State { int dev_fd; /* kvm device fd if backed by kvm vgic support */ Error *migration_blocker; + MemoryRegion *sysmem; + AddressSpace sysmem_as; + /* Distributor */ /* for a GIC with the security extensions the NS banked version of this * register is just an alias of bit 1 of the S banked version. */ uint32_t gicd_ctlr; + uint32_t gicd_typer; uint32_t gicd_statusr[2]; GIC_DECLARE_BITMAP(group); /* GICD_IGROUPR */ GIC_DECLARE_BITMAP(grpmod); /* GICD_IGRPMODR */ From patchwork Tue Mar 23 04:12:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 12156813 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8C4FCC433C1 for ; Tue, 23 Mar 2021 04:20:03 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 10F5961990 for ; Tue, 23 Mar 2021 04:20:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 10F5961990 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:42950 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lOYWQ-0001B2-4S for qemu-devel@archiver.kernel.org; Tue, 23 Mar 2021 00:20:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56002) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lOYPc-0000jt-H8 for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:13:00 -0400 Received: from mail-qk1-x735.google.com ([2607:f8b0:4864:20::735]:36664) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lOYPM-0006bJ-Aq for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:12:57 -0400 Received: by mail-qk1-x735.google.com with SMTP id c4so13111964qkg.3 for ; Mon, 22 Mar 2021 21:12:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=te6zLYq8PJH8MbvrLGCtpL7G2FDmfaJBuFqu6R6k4qU=; b=jcvTIemWcdTOKcPmlG8XLDDFdBSJMDADR1QzBk++IGSU3NTqiBgqnrF95tO3APvJej XeR0CV8xIZISw/F/qcmeXS3yCywA31nFmScfAL7w+bUtxz3thT4OoO3dI3obAD6wp754 UndKxTxoL6LLkeoN6Nzik4EnhCdlsWd1TvwGVisCgaQeiUI6xHlPtqErlgXXg64Kdc4E wHryWlTFMASHnjIyMbeGelD3dUKW2UMGJWdhq6iJJ+JsJU1rvmMTk8uOsISlW4UXVlQJ w9GvL0UkzojB1Lo+0tsDxwHKNydwlwgYOz9MQ9IahAqoXxhMUbRibdqhVDgEW09YMV88 4u4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=te6zLYq8PJH8MbvrLGCtpL7G2FDmfaJBuFqu6R6k4qU=; b=a3HXo17Fp+cUopfYodFBb11cwqiFMaJGC6BzENTL/jfpGMYgJ3iBo4Q/28MRADY39t VG3RcNpFLwn7g1QSB3gqNrObNW5QBRzhB/t3DDHoP5y0x1t53F4jTe+6i4Z8mMghyOiP xHpVudMpCNuXMMQCpFTuySa/2uOc76LHoSWMoJRyXx+ypLGOdszUyiEY6vGhLPtp48Gb pJjeG8bdifrzjsUZ5jEbf135dqW+ujH3moNUdT431Xmbs6Wa2T3wRZke30nhNBqQEFkx d1V4LyaijcyCTthzp0Aa8SQOjro98auvzWScYYXaT0uN4za8dBe2a6zrek5/5l5CdvuU hgzQ== X-Gm-Message-State: AOAM533w/Xxq2vMV9y6tP3Z2dYqagNwSTaOWcWPL20JqFYNXmIsLeWFF KPeaOQqydiTzZ7TCvM4Gok/O2g== X-Google-Smtp-Source: ABdhPJxU7ZQmZr1HHeGjrjpGIcByLFl3ERI5hFaZeoIBcTRqs2srFUgUFBF0JhWw9QmdajxynZtt3w== X-Received: by 2002:a37:5f04:: with SMTP id t4mr3523364qkb.440.1616472762421; Mon, 22 Mar 2021 21:12:42 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-23-174-92-28-28.dsl.bell.ca. [174.92.28.28]) by smtp.googlemail.com with ESMTPSA id m21sm12601181qka.28.2021.03.22.21.12.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 21:12:42 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v1 3/8] hw/intc: GICv3 ITS command queue framework Date: Tue, 23 Mar 2021 00:12:33 -0400 Message-Id: <20210323041238.133835-4-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210323041238.133835-1-shashi.mallela@linaro.org> References: <20210323041238.133835-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::735; envelope-from=shashi.mallela@linaro.org; helo=mail-qk1-x735.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added functionality to trigger ITS command queue processing on write to CWRITE register and process each command queue entry to identify the command type and handle commands like MAPD,MAPC,SYNC. Signed-off-by: Shashi Mallela --- hw/intc/arm_gicv3_its.c | 362 ++++++++++++++++++++ 1 file changed, 362 insertions(+) diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index 4895d32e67..9b094e1f0a 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -56,6 +56,362 @@ struct GICv3ITSClass { CmdQDesc cq; }; +static MemTxResult process_sync(GICv3ITSState *s, uint32_t offset) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + AddressSpace *as = &s->gicv3->sysmem_as; + uint64_t rdbase; + uint64_t value; + bool pta = false; + MemTxResult res = MEMTX_OK; + + offset += NUM_BYTES_IN_DW; + offset += NUM_BYTES_IN_DW; + + value = address_space_ldq_le(as, c->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + + if ((s->typer >> GITS_TYPER_PTA_OFFSET) & GITS_TYPER_PTA_MASK) { + /* + * only bits[47:16] are considered instead of bits [51:16] + * since with a physical address the target address must be + * 64KB aligned + */ + rdbase = (value >> RDBASE_OFFSET) & RDBASE_MASK; + pta = true; + } else { + rdbase = (value >> RDBASE_OFFSET) & RDBASE_PROCNUM_MASK; + } + + if (!pta && (rdbase < (s->gicv3->num_cpu))) { + /* + * Current implementation makes a blocking synchronous call + * for every command issued earlier,hence the internal state + * is already consistent by the time SYNC command is executed. + */ + } + + offset += NUM_BYTES_IN_DW; + return res; +} + +static void update_cte(GICv3ITSState *s, uint16_t icid, uint64_t cte) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + AddressSpace *as = &s->gicv3->sysmem_as; + uint64_t value; + uint8_t page_sz_type; + uint64_t l2t_addr; + bool valid_l2t; + uint32_t l2t_id; + uint32_t page_sz = 0; + uint32_t max_l2_entries; + + if (c->ct.indirect) { + /* 2 level table */ + page_sz_type = (s->baser[0] >> + GITS_BASER_PAGESIZE_OFFSET) & + GITS_BASER_PAGESIZE_MASK; + + if (page_sz_type == 0) { + page_sz = GITS_ITT_PAGE_SIZE_0; + } else if (page_sz_type == 1) { + page_sz = GITS_ITT_PAGE_SIZE_1; + } else if (page_sz_type == 2) { + page_sz = GITS_ITT_PAGE_SIZE_2; + } + + l2t_id = icid / (page_sz / L1TABLE_ENTRY_SIZE); + + value = address_space_ldq_le(as, + c->ct.base_addr + + (l2t_id * L1TABLE_ENTRY_SIZE), + MEMTXATTRS_UNSPECIFIED, NULL); + + valid_l2t = (value >> VALID_SHIFT) & VALID_MASK; + + if (valid_l2t) { + max_l2_entries = page_sz / c->ct.entry_sz; + + l2t_addr = (value >> page_sz_type) & + ((1ULL << (51 - page_sz_type)) - 1); + + address_space_write(as, l2t_addr + + ((icid % max_l2_entries) * GITS_CTE_SIZE), + MEMTXATTRS_UNSPECIFIED, + &cte, sizeof(cte)); + } + } else { + /* Flat level table */ + address_space_write(as, c->ct.base_addr + (icid * GITS_CTE_SIZE), + MEMTXATTRS_UNSPECIFIED, &cte, + sizeof(cte)); + } +} + +static MemTxResult process_mapc(GICv3ITSState *s, uint32_t offset) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + AddressSpace *as = &s->gicv3->sysmem_as; + uint16_t icid; + uint64_t rdbase; + bool valid; + bool pta = false; + MemTxResult res = MEMTX_OK; + uint64_t cte_entry; + uint64_t value; + + offset += NUM_BYTES_IN_DW; + offset += NUM_BYTES_IN_DW; + + value = address_space_ldq_le(as, c->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + + icid = value & ICID_MASK; + + if ((s->typer >> GITS_TYPER_PTA_OFFSET) & GITS_TYPER_PTA_MASK) { + /* + * only bits[47:16] are considered instead of bits [51:16] + * since with a physical address the target address must be + * 64KB aligned + */ + rdbase = (value >> RDBASE_OFFSET) & RDBASE_MASK; + pta = true; + } else { + rdbase = (value >> RDBASE_OFFSET) & RDBASE_PROCNUM_MASK; + } + + valid = (value >> VALID_SHIFT) & VALID_MASK; + + if (valid) { + if ((icid > c->ct.max_collids) || (!pta && + (rdbase > s->gicv3->num_cpu))) { + if ((s->typer >> GITS_TYPER_SEIS_OFFSET) & + GITS_TYPER_SEIS_MASK) { + /* Generate System Error here if supported */ + } + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid collection table attributes " + "icid %d rdbase %lu\n", __func__, icid, rdbase); + /* + * in this implementation,in case of error + * we ignore this command and move onto the next + * command in the queue + */ + } else { + if (c->ct.valid) { + /* add mapping entry to collection table */ + cte_entry = (valid & VALID_MASK) | + (pta ? ((rdbase & RDBASE_MASK) << 1ULL) : + ((rdbase & RDBASE_PROCNUM_MASK) << 1ULL)); + + update_cte(s, icid, cte_entry); + } + } + } else { + if (c->ct.valid) { + /* remove mapping entry from collection table */ + cte_entry = 0; + + update_cte(s, icid, cte_entry); + } + } + + offset += NUM_BYTES_IN_DW; + offset += NUM_BYTES_IN_DW; + + return res; +} + +static void update_dte(GICv3ITSState *s, uint32_t devid, uint64_t dte) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + AddressSpace *as = &s->gicv3->sysmem_as; + uint64_t value; + uint8_t page_sz_type; + uint64_t l2t_addr; + bool valid_l2t; + uint32_t l2t_id; + uint32_t page_sz = 0; + uint32_t max_l2_entries; + + if (c->dt.indirect) { + /* 2 level table */ + page_sz_type = (s->baser[0] >> + GITS_BASER_PAGESIZE_OFFSET) & + GITS_BASER_PAGESIZE_MASK; + + if (page_sz_type == 0) { + page_sz = GITS_ITT_PAGE_SIZE_0; + } else if (page_sz_type == 1) { + page_sz = GITS_ITT_PAGE_SIZE_1; + } else if (page_sz_type == 2) { + page_sz = GITS_ITT_PAGE_SIZE_2; + } + + l2t_id = devid / (page_sz / L1TABLE_ENTRY_SIZE); + + value = address_space_ldq_le(as, + c->dt.base_addr + + (l2t_id * L1TABLE_ENTRY_SIZE), + MEMTXATTRS_UNSPECIFIED, NULL); + + valid_l2t = (value >> VALID_SHIFT) & VALID_MASK; + + if (valid_l2t) { + max_l2_entries = page_sz / c->dt.entry_sz; + + l2t_addr = (value >> page_sz_type) & + ((1ULL << (51 - page_sz_type)) - 1); + + address_space_write(as, l2t_addr + + ((devid % max_l2_entries) * GITS_DTE_SIZE), + MEMTXATTRS_UNSPECIFIED, &dte, sizeof(dte)); + } + } else { + /* Flat level table */ + address_space_write(as, c->dt.base_addr + (devid * GITS_DTE_SIZE), + MEMTXATTRS_UNSPECIFIED, &dte, sizeof(dte)); + } +} + +static MemTxResult process_mapd(GICv3ITSState *s, uint64_t value, + uint32_t offset) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + AddressSpace *as = &s->gicv3->sysmem_as; + uint32_t devid; + uint8_t size; + uint64_t itt_addr; + bool valid; + MemTxResult res = MEMTX_OK; + uint64_t dte_entry = 0; + + devid = (value >> DEVID_OFFSET) & DEVID_MASK; + + offset += NUM_BYTES_IN_DW; + value = address_space_ldq_le(as, c->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + size = (value & SIZE_MASK); + + offset += NUM_BYTES_IN_DW; + value = address_space_ldq_le(as, c->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + itt_addr = (value >> ITTADDR_OFFSET) & ITTADDR_MASK; + + valid = (value >> VALID_SHIFT) & VALID_MASK; + + if (valid) { + if ((devid > c->dt.max_devids) || + (size > ((s->typer >> GITS_TYPER_IDBITS_OFFSET) & + GITS_TYPER_IDBITS_MASK))) { + if ((s->typer >> GITS_TYPER_SEIS_OFFSET) & + GITS_TYPER_SEIS_MASK) { + /* Generate System Error here if supported */ + } + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid device table attributes " + "devid %d or size %d\n", __func__, devid, size); + /* + * in this implementation,in case of error + * we ignore this command and move onto the next + * command in the queue + */ + } else { + if (c->dt.valid) { + /* add mapping entry to device table */ + dte_entry = (valid & VALID_MASK) | + ((size & SIZE_MASK) << 1U) | + ((itt_addr & ITTADDR_MASK) << 6ULL); + + update_dte(s, devid, dte_entry); + } + } + } else { + if (c->dt.valid) { + /* remove mapping entry from device table */ + dte_entry = 0; + update_dte(s, devid, dte_entry); + } + } + + offset += NUM_BYTES_IN_DW; + offset += NUM_BYTES_IN_DW; + + return res; +} + +/* + * Current implementation blocks until all + * commands are processed + */ +static MemTxResult process_cmdq(GICv3ITSState *s) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + uint32_t wr_offset = 0; + uint32_t rd_offset = 0; + uint32_t cq_offset = 0; + uint64_t data; + AddressSpace *as = &s->gicv3->sysmem_as; + MemTxResult res = MEMTX_OK; + uint8_t cmd; + + wr_offset = (s->cwriter >> GITS_CWRITER_OFFSET) & + GITS_CWRITER_OFFSET_MASK; + + if (wr_offset > c->cq.max_entries) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid write offset " + "%d\n", __func__, wr_offset); + res = MEMTX_ERROR; + return res; + } + + rd_offset = (s->creadr >> GITS_CREADR_OFFSET) & + GITS_CREADR_OFFSET_MASK; + + while (wr_offset != rd_offset) { + cq_offset = (rd_offset * GITS_CMDQ_ENTRY_SIZE); + data = address_space_ldq_le(as, c->cq.base_addr + cq_offset, + MEMTXATTRS_UNSPECIFIED, &res); + cmd = (data & CMD_MASK); + + switch (cmd) { + case GITS_CMD_INT: + break; + case GITS_CMD_CLEAR: + break; + case GITS_CMD_SYNC: + res = process_sync(s, cq_offset); + break; + case GITS_CMD_MAPD: + res = process_mapd(s, data, cq_offset); + break; + case GITS_CMD_MAPC: + res = process_mapc(s, cq_offset); + break; + case GITS_CMD_MAPTI: + break; + case GITS_CMD_MAPI: + break; + case GITS_CMD_DISCARD: + break; + default: + break; + } + if (res == MEMTX_OK) { + rd_offset++; + rd_offset %= c->cq.max_entries; + s->creadr = (rd_offset << GITS_CREADR_OFFSET); + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: %x cmd processing failed!!\n", __func__, cmd); + break; + } + } + return res; +} + static bool extract_table_params(GICv3ITSState *s, int index) { GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); @@ -325,6 +681,9 @@ static MemTxResult its_writel(GICv3ITSState *s, hwaddr offset, break; case GITS_CWRITER: s->cwriter = deposit64(s->cwriter, 0, 32, value); + if ((s->ctlr & GITS_CTLR_ENABLED) && (s->cwriter != s->creadr)) { + result = process_cmdq(s); + } break; case GITS_CWRITER + 4: s->cwriter = deposit64(s->cwriter, 32, 32, value); @@ -459,6 +818,9 @@ static MemTxResult its_writell(GICv3ITSState *s, hwaddr offset, break; case GITS_CWRITER: s->cwriter = value; + if ((s->ctlr & GITS_CTLR_ENABLED) && (s->cwriter != s->creadr)) { + result = process_cmdq(s); + } break; case GITS_TYPER: case GITS_CREADR: From patchwork Tue Mar 23 04:12:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 12156801 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 40D5AC433C1 for ; Tue, 23 Mar 2021 04:15:35 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2C8BF619B2 for ; Tue, 23 Mar 2021 04:15:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2C8BF619B2 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:54932 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lOYS5-0002TH-5y for qemu-devel@archiver.kernel.org; Tue, 23 Mar 2021 00:15:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55968) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lOYPX-0000jH-2T for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:12:59 -0400 Received: from mail-qk1-x736.google.com ([2607:f8b0:4864:20::736]:40473) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lOYPM-0006bR-Fu for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:12:54 -0400 Received: by mail-qk1-x736.google.com with SMTP id 7so13099852qka.7 for ; Mon, 22 Mar 2021 21:12:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=sx/vdgfnG+PME1ucFZkuwoOuWJLopYMkS7wb7YTc8wo=; b=aDveTX7u+nvjHuDpVtcdtB+wXbdUl2EoRxvf3zRNmMy/M/KBtzjGUSl1kIMbE3r/sg RiPmeBBLonjhgLeb3i4HIVg3hA2wXSONbym2FDAFxEJH6Eu/11kpPBvg2n7tgsbVhb8F DEKA00fIxcovWF+7sg+MlyZAayzIzXVTkAIusoxLIbU+WgMnfLWjMnxokqWBeHohVKOw 0kwinJYSVWVbmlIB9VhuD9hc4+HUmOTPm+rbwzUyYBZmL+y6C/O80vjFwwKPtqjfIGcM zefKCt7bTSUZQ0znef/0KtAaLQILUXa+xzMNCtnMbZCw1dI4ugaImgAzBRfZD9I8ejyT 2v/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=sx/vdgfnG+PME1ucFZkuwoOuWJLopYMkS7wb7YTc8wo=; b=DOhweBZKe4DVQWEbaVxXc/GtdsTLRZoyIUXBV7W9A4rhbwVzSCIAHZ5vlL/Kp9aBAM yPdcq4Ybk/X9jJeOd1DQRul+TgMOoRcqR93R0Lp/fyH+7g9kcvrYQ+yHefEXq7YrTfNR n/QoEm+wtC4T7yKcYE3jpOWK73pgC22M67R0IPafyWPUMSS/foNvP0Pqy1vx3gFw+bJ0 O8OoNtsnEqsQF41yusNGO/JFBg/cjuULrCgVBn62jHPOBCAeTr5F5MC8U2WkYJewzwfA Vrmiw+Sv+QJfc/QRINfA420FXqPKuK+dUiy+06W23UJGx8tHIwA1URdG7iL8li5Ox8WN Wjdg== X-Gm-Message-State: AOAM531CTnncEw5JlMPU0pU6WlgIdWTESrU+WlYgV9s0/PTiJgsxZ50z V/A16UIxoNDQJpQgtwYYQycMUn8M99+MBw== X-Google-Smtp-Source: ABdhPJyurkUfgn0f0P3CfIB1xvByqINzV6wPNH2H9tkMskJjt9CzUTEkdTspY+hQS1HfSq2ilB2JeA== X-Received: by 2002:a05:620a:122b:: with SMTP id v11mr3474316qkj.461.1616472763101; Mon, 22 Mar 2021 21:12:43 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-23-174-92-28-28.dsl.bell.ca. [174.92.28.28]) by smtp.googlemail.com with ESMTPSA id m21sm12601181qka.28.2021.03.22.21.12.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 21:12:42 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v1 4/8] hw/intc: GICv3 ITS Command processing Date: Tue, 23 Mar 2021 00:12:34 -0400 Message-Id: <20210323041238.133835-5-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210323041238.133835-1-shashi.mallela@linaro.org> References: <20210323041238.133835-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::736; envelope-from=shashi.mallela@linaro.org; helo=mail-qk1-x736.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added ITS command queue handling for MAPTI,MAPI commands,handled ITS translation which triggers an LPI via INT command as well as write to GITS_TRANSLATER register,defined enum to differentiate between ITS command interrupt trigger and GITS_TRANSLATER based interrupt trigger. Each of these commands make use of other functionalities implemented to get device table entry,collection table entry or interrupt translation table entry required for their processing. Signed-off-by: Shashi Mallela --- hw/intc/arm_gicv3_its.c | 371 +++++++++++++++++++- include/hw/intc/arm_gicv3_common.h | 2 + 2 files changed, 372 insertions(+), 1 deletion(-) diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index 9b094e1f0a..de2d179b5e 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -56,6 +56,158 @@ struct GICv3ITSClass { CmdQDesc cq; }; +typedef enum ItsCmdType { + NONE = 0, /* internal indication for GITS_TRANSLATER write */ + CLEAR = 1, + DISCARD = 2, + INT = 3, +} ItsCmdType; + +static bool get_cte(GICv3ITSState *s, uint16_t icid, uint64_t *cte) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + AddressSpace *as = &s->gicv3->sysmem_as; + uint8_t page_sz_type; + uint64_t l2t_addr; + uint64_t value; + bool valid_l2t; + uint32_t l2t_id; + uint32_t page_sz = 0; + uint32_t max_l2_entries; + bool status = false; + + if (c->ct.indirect) { + /* 2 level table */ + page_sz_type = (s->baser[0] >> + GITS_BASER_PAGESIZE_OFFSET) & + GITS_BASER_PAGESIZE_MASK; + + if (page_sz_type == 0) { + page_sz = GITS_ITT_PAGE_SIZE_0; + } else if (page_sz_type == 1) { + page_sz = GITS_ITT_PAGE_SIZE_1; + } else if (page_sz_type == 2) { + page_sz = GITS_ITT_PAGE_SIZE_2; + } + + l2t_id = icid / (page_sz / L1TABLE_ENTRY_SIZE); + + value = address_space_ldq_le(as, + c->ct.base_addr + + (l2t_id * L1TABLE_ENTRY_SIZE), + MEMTXATTRS_UNSPECIFIED, NULL); + + valid_l2t = (value >> VALID_SHIFT) & VALID_MASK; + + if (valid_l2t) { + max_l2_entries = page_sz / c->ct.entry_sz; + + l2t_addr = (value >> page_sz_type) & + ((1ULL << (51 - page_sz_type)) - 1); + + address_space_read(as, l2t_addr + + ((icid % max_l2_entries) * GITS_CTE_SIZE), + MEMTXATTRS_UNSPECIFIED, + cte, sizeof(*cte)); + } + } else { + /* Flat level table */ + address_space_read(as, c->ct.base_addr + (icid * GITS_CTE_SIZE), + MEMTXATTRS_UNSPECIFIED, cte, + sizeof(*cte)); + } + + if (*cte & VALID_MASK) { + status = true; + } + + return status; +} + +static bool get_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte, + uint16_t *icid, uint32_t *pIntid) +{ + AddressSpace *as = &s->gicv3->sysmem_as; + uint8_t buff[GITS_TYPER_ITT_ENTRY_SIZE]; + uint64_t itt_addr; + bool status = false; + + itt_addr = (dte >> 6ULL) & ITTADDR_MASK; + itt_addr <<= ITTADDR_OFFSET; /* 256 byte aligned */ + + address_space_read(as, itt_addr + (eventid * sizeof(buff)), + MEMTXATTRS_UNSPECIFIED, &buff, + sizeof(buff)); + + if (buff[0] & VALID_MASK) { + if ((buff[0] >> 1U) & GITS_TYPER_PHYSICAL) { + memcpy(pIntid, &buff[1], 3); + memcpy(icid, &buff[7], sizeof(*icid)); + status = true; + } + } + + return status; +} + +static uint64_t get_dte(GICv3ITSState *s, uint32_t devid) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + AddressSpace *as = &s->gicv3->sysmem_as; + uint8_t page_sz_type; + uint64_t l2t_addr; + uint64_t value; + bool valid_l2t; + uint32_t l2t_id; + uint32_t page_sz = 0; + uint32_t max_l2_entries; + + if (c->ct.indirect) { + /* 2 level table */ + page_sz_type = (s->baser[0] >> + GITS_BASER_PAGESIZE_OFFSET) & + GITS_BASER_PAGESIZE_MASK; + + if (page_sz_type == 0) { + page_sz = GITS_ITT_PAGE_SIZE_0; + } else if (page_sz_type == 1) { + page_sz = GITS_ITT_PAGE_SIZE_1; + } else if (page_sz_type == 2) { + page_sz = GITS_ITT_PAGE_SIZE_2; + } + + l2t_id = devid / (page_sz / L1TABLE_ENTRY_SIZE); + + value = address_space_ldq_le(as, + c->dt.base_addr + + (l2t_id * L1TABLE_ENTRY_SIZE), + MEMTXATTRS_UNSPECIFIED, NULL); + + valid_l2t = (value >> VALID_SHIFT) & VALID_MASK; + + if (valid_l2t) { + max_l2_entries = page_sz / c->dt.entry_sz; + + l2t_addr = (value >> page_sz_type) & + ((1ULL << (51 - page_sz_type)) - 1); + + value = 0; + address_space_read(as, l2t_addr + + ((devid % max_l2_entries) * GITS_DTE_SIZE), + MEMTXATTRS_UNSPECIFIED, + &value, sizeof(value)); + } + } else { + /* Flat level table */ + value = 0; + address_space_read(as, c->dt.base_addr + (devid * GITS_DTE_SIZE), + MEMTXATTRS_UNSPECIFIED, &value, + sizeof(value)); + } + + return value; +} + static MemTxResult process_sync(GICv3ITSState *s, uint32_t offset) { GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); @@ -95,6 +247,192 @@ static MemTxResult process_sync(GICv3ITSState *s, uint32_t offset) return res; } +static MemTxResult process_int(GICv3ITSState *s, uint64_t value, + uint32_t offset, ItsCmdType cmd) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + AddressSpace *as = &s->gicv3->sysmem_as; + uint32_t devid, eventid; + MemTxResult res = MEMTX_OK; + bool dte_valid; + uint64_t dte = 0; + uint32_t max_eventid; + uint16_t icid = 0; + uint32_t pIntid = 0; + bool ite_valid = false; + uint64_t cte = 0; + bool cte_valid = false; + uint8_t buff[GITS_TYPER_ITT_ENTRY_SIZE]; + uint64_t itt_addr; + + if (cmd == NONE) { + devid = offset; + } else { + devid = (value >> DEVID_OFFSET) & DEVID_MASK; + + offset += NUM_BYTES_IN_DW; + value = address_space_ldq_le(as, c->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + } + + eventid = (value & EVENTID_MASK); + + dte = get_dte(s, devid); + dte_valid = dte & VALID_MASK; + + if (dte_valid) { + max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1)); + + ite_valid = get_ite(s, eventid, dte, &icid, &pIntid); + + if (ite_valid) { + cte_valid = get_cte(s, icid, &cte); + } + } + + if ((devid > c->dt.max_devids) || !dte_valid || !ite_valid || + !cte_valid || (eventid > max_eventid)) { + if ((s->typer >> GITS_TYPER_SEIS_OFFSET) & + GITS_TYPER_SEIS_MASK) { + /* + * Generate System Error here if supported + * for each of the individual error cases + */ + } + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid interrupt translation table attributes " + "devid %d or eventid %d\n", + __func__, devid, eventid); + /* + * in this implementation,in case of error + * we ignore this command and move onto the next + * command in the queue + */ + } else { + if ((s->typer >> GITS_TYPER_PTA_OFFSET) & GITS_TYPER_PTA_MASK) { + /* + * only bits[47:16] are considered instead of bits [51:16] + * since with a physical address the target address must be + * 64KB aligned + */ + + /* + * Current implementation only supports rdbase == procnum + * Hence rdbase physical address is ignored + */ + } else { + + if (cmd == DISCARD) { + /* remove mapping from interrupt translation table */ + memset(buff, 0, sizeof(buff)); + + itt_addr = (dte >> 6ULL) & ITTADDR_MASK; + itt_addr <<= ITTADDR_OFFSET; /* 256 byte aligned */ + + address_space_write(as, itt_addr + (eventid * sizeof(buff)), + MEMTXATTRS_UNSPECIFIED, &buff, + sizeof(buff)); + } + } + } + + if (cmd != NONE) { + offset += NUM_BYTES_IN_DW; + offset += NUM_BYTES_IN_DW; + } + + return res; +} + +static MemTxResult process_mapti(GICv3ITSState *s, uint64_t value, + uint32_t offset, bool ignore_pInt) +{ + GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); + AddressSpace *as = &s->gicv3->sysmem_as; + uint32_t devid, eventid; + uint32_t pIntid = 0; + uint32_t max_eventid, max_Intid; + bool dte_valid; + MemTxResult res = MEMTX_OK; + uint16_t icid = 0; + uint64_t dte = 0; + uint64_t itt_addr; + uint8_t buff[GITS_TYPER_ITT_ENTRY_SIZE]; + uint32_t int_spurious = INTID_SPURIOUS; + + devid = (value >> DEVID_OFFSET) & DEVID_MASK; + offset += NUM_BYTES_IN_DW; + value = address_space_ldq_le(as, c->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + + eventid = (value & EVENTID_MASK); + + if (!ignore_pInt) { + pIntid = (value >> pINTID_OFFSET) & pINTID_MASK; + } + + offset += NUM_BYTES_IN_DW; + value = address_space_ldq_le(as, c->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + + icid = value & ICID_MASK; + + dte = get_dte(s, devid); + dte_valid = dte & VALID_MASK; + + max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1)); + + if (!ignore_pInt) { + max_Intid = (1UL << (((s->typer >> GITS_TYPER_IDBITS_OFFSET) & + GITS_TYPER_IDBITS_MASK) + 1)); + } + + if ((devid > c->dt.max_devids) || (icid > c->ct.max_collids) || + !dte_valid || (eventid > max_eventid) || + (!ignore_pInt && ((pIntid < GICV3_LPI_INTID_START) || + (pIntid > max_Intid)))) { + if ((s->typer >> GITS_TYPER_SEIS_OFFSET) & + GITS_TYPER_SEIS_MASK) { + /* + * Generate System Error here if supported + * for each of the individual error cases + */ + } + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid interrupt translation table attributes " + "devid %d or icid %d or eventid %d or pIntid %d\n", + __func__, devid, icid, eventid, pIntid); + /* + * in this implementation,in case of error + * we ignore this command and move onto the next + * command in the queue + */ + } else { + /* add entry to interrupt translation table */ + memset(buff, 0, sizeof(buff)); + buff[0] = (dte_valid & VALID_MASK) | (GITS_TYPER_PHYSICAL << 1U); + if (ignore_pInt) { + memcpy(&buff[1], &eventid, 3); + } else { + memcpy(&buff[1], &pIntid, 3); + } + memcpy(&buff[4], &int_spurious, 3); + memcpy(&buff[7], &icid, sizeof(icid)); + + itt_addr = (dte >> 6ULL) & ITTADDR_MASK; + itt_addr <<= ITTADDR_OFFSET; /* 256 byte aligned */ + + address_space_write(as, itt_addr + (eventid * sizeof(buff)), + MEMTXATTRS_UNSPECIFIED, &buff, + sizeof(buff)); + } + + offset += NUM_BYTES_IN_DW; + offset += NUM_BYTES_IN_DW; + + return res; +} + static void update_cte(GICv3ITSState *s, uint16_t icid, uint64_t cte) { GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); @@ -276,7 +614,7 @@ static void update_dte(GICv3ITSState *s, uint32_t devid, uint64_t dte) } static MemTxResult process_mapd(GICv3ITSState *s, uint64_t value, - uint32_t offset) + uint32_t offset) { GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s); AddressSpace *as = &s->gicv3->sysmem_as; @@ -378,8 +716,10 @@ static MemTxResult process_cmdq(GICv3ITSState *s) switch (cmd) { case GITS_CMD_INT: + res = process_int(s, data, cq_offset, INT); break; case GITS_CMD_CLEAR: + res = process_int(s, data, cq_offset, CLEAR); break; case GITS_CMD_SYNC: res = process_sync(s, cq_offset); @@ -391,10 +731,13 @@ static MemTxResult process_cmdq(GICv3ITSState *s) res = process_mapc(s, cq_offset); break; case GITS_CMD_MAPTI: + res = process_mapti(s, data, cq_offset, false); break; case GITS_CMD_MAPI: + res = process_mapti(s, data, cq_offset, true); break; case GITS_CMD_DISCARD: + res = process_int(s, data, cq_offset, DISCARD); break; default: break; @@ -556,7 +899,20 @@ static MemTxResult its_trans_writew(GICv3ITSState *s, hwaddr offset, uint64_t value, MemTxAttrs attrs) { MemTxResult result = MEMTX_OK; + uint32_t devid = 0; + switch (offset) { + case GITS_TRANSLATER: + if (s->ctlr & GITS_CTLR_ENABLED) { + s->translater = (value & 0x0000FFFFU); + devid = attrs.requester_id; + result = process_int(s, s->translater, devid, NONE); + } + break; + default: + result = MEMTX_ERROR; + break; + } return result; } @@ -564,7 +920,20 @@ static MemTxResult its_trans_writel(GICv3ITSState *s, hwaddr offset, uint64_t value, MemTxAttrs attrs) { MemTxResult result = MEMTX_OK; + uint32_t devid = 0; + switch (offset) { + case GITS_TRANSLATER: + if (s->ctlr & GITS_CTLR_ENABLED) { + s->translater = value; + devid = attrs.requester_id; + result = process_int(s, s->translater, devid, NONE); + } + break; + default: + result = MEMTX_ERROR; + break; + } return result; } diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h index b0f2414fa3..3a710592a9 100644 --- a/include/hw/intc/arm_gicv3_common.h +++ b/include/hw/intc/arm_gicv3_common.h @@ -36,6 +36,8 @@ #define GICV3_MAXIRQ 1020 #define GICV3_MAXSPI (GICV3_MAXIRQ - GIC_INTERNAL) +#define GICV3_LPI_INTID_START 8192 + #define GICV3_REDIST_SIZE 0x20000 /* Number of SGI target-list bits */ From patchwork Tue Mar 23 04:12:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 12156803 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50AD0C433DB for ; Tue, 23 Mar 2021 04:16:08 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D2319619AE for ; Tue, 23 Mar 2021 04:16:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D2319619AE Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:56076 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lOYSc-0002xE-SE for qemu-devel@archiver.kernel.org; Tue, 23 Mar 2021 00:16:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56052) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lOYPm-0000kr-Kn for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:13:11 -0400 Received: from mail-qk1-x72d.google.com ([2607:f8b0:4864:20::72d]:44811) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lOYPM-0006bZ-O6 for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:13:09 -0400 Received: by mail-qk1-x72d.google.com with SMTP id y18so13102577qky.11 for ; Mon, 22 Mar 2021 21:12:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RWO1mq5fDCkFbZuLM6l5vWRQ6Gsw7T4jwV+JNy5ru+s=; b=O31JiQkLtbAb6N3XMTY7jWvQTiFLvHsb54UssIlBANsDzEmy3e78zXppkgacmTRebr 6HUIfihiit/xJUltkY5O3b85r903lccBMU/wR6aRtzRAOo65QpeP2BWHeR4Qaoh0PXec R1WDwtmjA/GNSTyRa5Jy/5ZRP4TEdxPT94h3CdJQU4R14RgyJNSTrJg/COaLPkEMV161 +JIsw38gC8eOEYLoV2NJJo3Sl0hEd0fkHecZ/SGGJsQg8soZZp50L0pB1xa/K8MsUkWz kR+Eybx8rBIzWEMWYpcyMPgWpGvI5KLUupEVY44LbRXLkzz8fFnXekDCkd3T1KZPxF7U B9aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RWO1mq5fDCkFbZuLM6l5vWRQ6Gsw7T4jwV+JNy5ru+s=; b=fLMu9XnY0JK1s+6MEbdV9GWdN2gr5uNkIU4uTd3Lev32jwAteE2VanfNM4LIlgk3ZJ eTImzfZUNPf2qGVqpbPrlF/NZI+eahi8xXXtTmCzzSAj6+2aV58nyvr1z+iHZDoF0XQe AKiV7uL+ochBA4NUywPJHKk6Z7acDZm8uweAfE9LQvonTsqKiE+H4Y4fPGRt6kcX6fKw pQMU+zv0Xh6LouXFRSvsQ3F+2okGwk8QrxJYrYGhDHWMP/n7w3OC0JrDpLN2Nt/cc4bX 4xZ6CAgdfLt+/VOfMPfw7ompz90lBcN/kzYTtXeptLBNT9+sJnxbfFFJY93K5KttoC3t HaTg== X-Gm-Message-State: AOAM533465IZZZnVubFo2CMBUyeOycPiayeMvx4cXmKutRSsQC+QAP73 xWSMQR1OIf6PWw/yjIHm1smlt4oiFj6rog== X-Google-Smtp-Source: ABdhPJxd0pOOa/jvIWMSNtAPAc8zpTJwdaw+BFMsQgWd7HtZhPgIl7OTQqgPUeTvxvrHiM8VsO4+rw== X-Received: by 2002:a37:ef14:: with SMTP id j20mr3634498qkk.471.1616472763832; Mon, 22 Mar 2021 21:12:43 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-23-174-92-28-28.dsl.bell.ca. [174.92.28.28]) by smtp.googlemail.com with ESMTPSA id m21sm12601181qka.28.2021.03.22.21.12.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 21:12:43 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v1 5/8] hw/intc: GICv3 ITS Feature enablement Date: Tue, 23 Mar 2021 00:12:35 -0400 Message-Id: <20210323041238.133835-6-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210323041238.133835-1-shashi.mallela@linaro.org> References: <20210323041238.133835-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::72d; envelope-from=shashi.mallela@linaro.org; helo=mail-qk1-x72d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added properties to enable ITS feature and define qemu system address space memory in gicv3 common,setup distributor and redistributor registers to indicate LPI support. Signed-off-by: Shashi Mallela --- hw/intc/arm_gicv3_common.c | 16 +++++++++++ hw/intc/arm_gicv3_dist.c | 22 +++++++++++++-- hw/intc/arm_gicv3_redist.c | 29 ++++++++++++++++++-- include/hw/intc/arm_gicv3_common.h | 8 ++++++ 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index 58ef65f589..3bfc52f7fa 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -156,6 +156,7 @@ static const VMStateDescription vmstate_gicv3_cpu = { VMSTATE_UINT32(gicr_waker, GICv3CPUState), VMSTATE_UINT64(gicr_propbaser, GICv3CPUState), VMSTATE_UINT64(gicr_pendbaser, GICv3CPUState), + VMSTATE_BOOL(lpi_outofrange, GICv3CPUState), VMSTATE_UINT32(gicr_igroupr0, GICv3CPUState), VMSTATE_UINT32(gicr_ienabler0, GICv3CPUState), VMSTATE_UINT32(gicr_ipendr0, GICv3CPUState), @@ -227,6 +228,7 @@ static const VMStateDescription vmstate_gicv3 = { .priority = MIG_PRI_GICV3, .fields = (VMStateField[]) { VMSTATE_UINT32(gicd_ctlr, GICv3State), + VMSTATE_UINT32(gicd_typer, GICv3State), VMSTATE_UINT32_ARRAY(gicd_statusr, GICv3State, 2), VMSTATE_UINT32_ARRAY(group, GICv3State, GICV3_BMP_SIZE), VMSTATE_UINT32_ARRAY(grpmod, GICv3State, GICV3_BMP_SIZE), @@ -381,6 +383,16 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) (1 << 24) | (i << 8) | (last << 4); + + if (s->lpi_enable) { + s->cpu[i].gicr_typer |= GICR_TYPER_PLPIS; + + if (!s->sysmem) { + error_setg(errp, + "Redist-ITS: Guest 'sysmem' reference link not set"); + return; + } + } } } @@ -406,6 +418,7 @@ static void arm_gicv3_common_reset(DeviceState *dev) cs->gicr_waker = GICR_WAKER_ProcessorSleep | GICR_WAKER_ChildrenAsleep; cs->gicr_propbaser = 0; cs->gicr_pendbaser = 0; + cs->lpi_outofrange = false; /* If we're resetting a TZ-aware GIC as if secure firmware * had set it up ready to start a kernel in non-secure, we * need to set interrupts to group 1 so the kernel can use them. @@ -494,9 +507,12 @@ static Property arm_gicv3_common_properties[] = { DEFINE_PROP_UINT32("num-cpu", GICv3State, num_cpu, 1), DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32), DEFINE_PROP_UINT32("revision", GICv3State, revision, 3), + DEFINE_PROP_BOOL("has-lpi", GICv3State, lpi_enable, 0), DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0), DEFINE_PROP_ARRAY("redist-region-count", GICv3State, nb_redist_regions, redist_region_count, qdev_prop_uint32, uint32_t), + DEFINE_PROP_LINK("sysmem", GICv3State, sysmem, TYPE_MEMORY_REGION, + MemoryRegion *), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c index b65f56f903..96a317a8ef 100644 --- a/hw/intc/arm_gicv3_dist.c +++ b/hw/intc/arm_gicv3_dist.c @@ -366,12 +366,15 @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset, return MEMTX_OK; case GICD_TYPER: { + bool lpi_supported = false; /* For this implementation: * No1N == 1 (1-of-N SPI interrupts not supported) * A3V == 1 (non-zero values of Affinity level 3 supported) * IDbits == 0xf (we support 16-bit interrupt identifiers) * DVIS == 0 (Direct virtual LPI injection not supported) - * LPIS == 0 (LPIs not supported) + * LPIS == 1 (LPIs are supported if affinity routing is enabled) + * num_LPIs == 0b00000 (bits [15:11],Number of LPIs as indicated + * by GICD_TYPER.IDbits) * MBIS == 0 (message-based SPIs not supported) * SecurityExtn == 1 if security extns supported * CPUNumber == 0 since for us ARE is always 1 @@ -385,8 +388,23 @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset, */ bool sec_extn = !(s->gicd_ctlr & GICD_CTLR_DS); + /* + * With securityextn on,LPIs are supported when affinity routing + * is enabled for non-secure state and if off LPIs are supported + * when affinity routing is enabled. + */ + if (s->lpi_enable) { + if (sec_extn) { + lpi_supported = (s->gicd_ctlr & GICD_CTLR_ARE_NS); + } else { + lpi_supported = (s->gicd_ctlr & GICD_CTLR_ARE); + } + } + *data = (1 << 25) | (1 << 24) | (sec_extn << 10) | - (0xf << 19) | itlinesnumber; + (lpi_supported << GICD_TYPER_LPIS_OFFSET) | (GICD_TYPER_IDBITS << + GICD_TYPER_IDBITS_OFFSET) | itlinesnumber; + s->gicd_typer = *data; return MEMTX_OK; } case GICD_IIDR: diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c index 8645220d61..f4d14811ec 100644 --- a/hw/intc/arm_gicv3_redist.c +++ b/hw/intc/arm_gicv3_redist.c @@ -248,10 +248,16 @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset, case GICR_CTLR: /* For our implementation, GICR_TYPER.DPGS is 0 and so all * the DPG bits are RAZ/WI. We don't do anything asynchronously, - * so UWP and RWP are RAZ/WI. And GICR_TYPER.LPIS is 0 (we don't - * implement LPIs) so Enable_LPIs is RES0. So there are no writable - * bits for us. + * so UWP and RWP are RAZ/WI. GICR_TYPER.LPIS is 1 (we + * implement LPIs) so Enable_LPIs is programmable. */ + if (cs->gicr_typer & GICR_TYPER_PLPIS) { + if (value & GICR_CTLR_ENABLE_LPIS) { + cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS; + } else { + cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS; + } + } return MEMTX_OK; case GICR_STATUSR: /* RAZ/WI for our implementation */ @@ -275,6 +281,14 @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset, cs->gicr_waker = value; return MEMTX_OK; case GICR_PROPBASER: + if ((value & GICR_PROPBASER_IDBITS_MASK) < + GICR_PROPBASER_IDBITS_THRESHOLD) { + cs->lpi_outofrange = true; + } + if ((value & GICR_PROPBASER_IDBITS_MASK) > GICD_TYPER_IDBITS) { + value &= ~GICR_PROPBASER_IDBITS_MASK; + value |= GICD_TYPER_IDBITS; + } cs->gicr_propbaser = deposit64(cs->gicr_propbaser, 0, 32, value); return MEMTX_OK; case GICR_PROPBASER + 4: @@ -397,6 +411,15 @@ static MemTxResult gicr_writell(GICv3CPUState *cs, hwaddr offset, { switch (offset) { case GICR_PROPBASER: + if ((value & GICR_PROPBASER_IDBITS_MASK) < + GICR_PROPBASER_IDBITS_THRESHOLD) { + cs->lpi_outofrange = true; + } + if ((value & GICR_PROPBASER_IDBITS_MASK) > + GICD_TYPER_IDBITS) { + value &= ~GICR_PROPBASER_IDBITS_MASK; + value |= GICD_TYPER_IDBITS; + } cs->gicr_propbaser = value; return MEMTX_OK; case GICR_PENDBASER: diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h index 3a710592a9..db3989484d 100644 --- a/include/hw/intc/arm_gicv3_common.h +++ b/include/hw/intc/arm_gicv3_common.h @@ -175,6 +175,13 @@ struct GICv3CPUState { uint32_t gicr_nsacr; uint8_t gicr_ipriorityr[GIC_INTERNAL]; + /* + * flag to indicate LPIs are out of range + * since IDbits from GICR_PROPBASER is less + * than 0b1101 + */ + bool lpi_outofrange; + /* CPU interface */ uint64_t icc_sre_el1; uint64_t icc_ctlr_el1[2]; @@ -221,6 +228,7 @@ struct GICv3State { uint32_t num_cpu; uint32_t num_irq; uint32_t revision; + bool lpi_enable; bool security_extn; bool irq_reset_nonsecure; bool gicd_no_migration_shift_bug; From patchwork Tue Mar 23 04:12:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 12156805 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EA8FAC433DB for ; Tue, 23 Mar 2021 04:16:55 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7B1CA619AD for ; Tue, 23 Mar 2021 04:16:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7B1CA619AD Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:57090 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lOYTO-0003Oq-J5 for qemu-devel@archiver.kernel.org; Tue, 23 Mar 2021 00:16:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56068) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lOYPn-0000lp-Uk for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:13:11 -0400 Received: from mail-qk1-x733.google.com ([2607:f8b0:4864:20::733]:35459) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lOYPN-0006by-LQ for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:13:11 -0400 Received: by mail-qk1-x733.google.com with SMTP id i9so13090919qka.2 for ; Mon, 22 Mar 2021 21:12:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9MAisyPgu751vN4QCK9P9GO8fD3yVG7ho3//jskpRqU=; b=VeaIuyCDDDOJU0Wk2BBI0m42/iabL8V+vgwprA5rRztfsPhj0DHaM+x7UJwa26s/z7 u7vfic+gbDjMxigQmJ7eTxboEgqQ21uUGjqUWp4GPhMvnIAeJGnEzRipa5Y2H8cjFTSG 9XLGgzPxC+Bb4wA8QQigZJA1I/M7p60eRlAhzbduUNX0sUuHwtq7prSXjVcwWHn39atq Qehl7JoD5j5K0QhwSFxLX0NBGOE5K8gDnVgJciQtmqP4h0kJYKWvf6dJcHs0Sl9vHTQX iWeiTRpWSIqdoNNFRcZ2S4OU2UuGqo2QovnflW+BU1BzU2YX67d6ic7naDB5kdLvPAAi VPBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9MAisyPgu751vN4QCK9P9GO8fD3yVG7ho3//jskpRqU=; b=VQLDR6+FBFkb/Bmo0d8a5frlljCi5MMzI2qJjvExpcKgQntmHyqL8e1JloVt0lR+5o WBy0TqcQ6/pkVWwkr2wQ4rnNnVSX0yiF0H9lNxVv3/1HB8X5IxGX9JPItu8Cy24Vng8A Msot4ebJapvEYZgr68q4w/fd9k1JJRTBZhoHma6W6YNZMeIxV7SMc0PfqwYprMbHRABu F3hEypbJDh4eC27gYhAU6L5MrrP6vA3RjLyvKD15TzuTKRlvjO68nPHYTCnKRnegYF36 sW8O/Mx+GH4Freds4jPFEe4H+B5dAAGBJjrfq7WLdknCiGXLe9eco7Ixagd3ctiioot9 c6yg== X-Gm-Message-State: AOAM53208sl0iQd0imZry/nicsm/qirPgx6BDk2lS+ATo3q8Pt0GrOd7 mhocmQMRsP5QQT+tCm/nXfPdVg== X-Google-Smtp-Source: ABdhPJww/yXnIrmw4dV6nYBUX9LaBGEi0Lku01mI/ZMa1EI2U6o7P5Iwk+L/poIxhMXJUMx+lSt0bQ== X-Received: by 2002:a37:6453:: with SMTP id y80mr3501697qkb.291.1616472764662; Mon, 22 Mar 2021 21:12:44 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-23-174-92-28-28.dsl.bell.ca. [174.92.28.28]) by smtp.googlemail.com with ESMTPSA id m21sm12601181qka.28.2021.03.22.21.12.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 21:12:44 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v1 6/8] hw/intc: GICv3 redistributor ITS processing Date: Tue, 23 Mar 2021 00:12:36 -0400 Message-Id: <20210323041238.133835-7-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210323041238.133835-1-shashi.mallela@linaro.org> References: <20210323041238.133835-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::733; envelope-from=shashi.mallela@linaro.org; helo=mail-qk1-x733.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Implemented lpi processing at redistributor to get lpi config info from lpi configuration table,determine priority,set pending state in lpi pending table and forward the lpi to cpuif.Added logic to invoke redistributor lpi processing with translated LPI which set/clear LPI from ITS device as part of ITS INT,CLEAR,DISCARD command and GITS_TRANSLATER processing. Signed-off-by: Shashi Mallela --- hw/intc/arm_gicv3.c | 6 + hw/intc/arm_gicv3_cpuif.c | 15 ++- hw/intc/arm_gicv3_its.c | 9 +- hw/intc/arm_gicv3_redist.c | 126 ++++++++++++++++++++ hw/intc/gicv3_internal.h | 3 + 5 files changed, 154 insertions(+), 5 deletions(-) diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c index 66eaa97198..618fa1af95 100644 --- a/hw/intc/arm_gicv3.c +++ b/hw/intc/arm_gicv3.c @@ -166,6 +166,12 @@ static void gicv3_redist_update_noirqset(GICv3CPUState *cs) cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq); } + if (cs->gic->lpi_enable) { + if (gicv3_redist_update_lpi(cs)) { + seenbetter = true; + } + } + /* If the best interrupt we just found would preempt whatever * was the previous best interrupt before this update, then * we know it's definitely the best one now. diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c index 43ef1d7a84..c225b80f66 100644 --- a/hw/intc/arm_gicv3_cpuif.c +++ b/hw/intc/arm_gicv3_cpuif.c @@ -899,9 +899,14 @@ static void icc_activate_irq(GICv3CPUState *cs, int irq) cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 0); gicv3_redist_update(cs); } else { - gicv3_gicd_active_set(cs->gic, irq); - gicv3_gicd_pending_clear(cs->gic, irq); - gicv3_update(cs->gic, irq, 1); + if (irq >= GICV3_LPI_INTID_START) { + gicv3_redist_lpi_pending(cs, irq, 0); + gicv3_redist_update(cs); + } else { + gicv3_gicd_active_set(cs->gic, irq); + gicv3_gicd_pending_clear(cs->gic, irq); + gicv3_update(cs->gic, irq, 1); + } } } @@ -1337,7 +1342,9 @@ static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri, * valid interrupt value read from the Interrupt Acknowledge * register" and so this is UNPREDICTABLE. We choose to ignore it. */ - return; + if (!(cs->gic->lpi_enable && (irq >= GICV3_LPI_INTID_START))) { + return; + } } if (icc_highest_active_group(cs) != grp) { diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index de2d179b5e..bb46af92a3 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -262,6 +262,7 @@ static MemTxResult process_int(GICv3ITSState *s, uint64_t value, bool ite_valid = false; uint64_t cte = 0; bool cte_valid = false; + uint64_t rdbase; uint8_t buff[GITS_TYPER_ITT_ENTRY_SIZE]; uint64_t itt_addr; @@ -315,12 +316,18 @@ static MemTxResult process_int(GICv3ITSState *s, uint64_t value, * since with a physical address the target address must be * 64KB aligned */ - + rdbase = (cte >> 1U) & RDBASE_MASK; /* * Current implementation only supports rdbase == procnum * Hence rdbase physical address is ignored */ } else { + rdbase = (cte >> 1U) & RDBASE_PROCNUM_MASK; + if ((cmd == CLEAR) || (cmd == DISCARD)) { + gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 0); + } else { + gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 1); + } if (cmd == DISCARD) { /* remove mapping from interrupt translation table */ diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c index f4d14811ec..dc47ed42d2 100644 --- a/hw/intc/arm_gicv3_redist.c +++ b/hw/intc/arm_gicv3_redist.c @@ -549,6 +549,132 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data, return r; } +bool gicv3_redist_update_lpi(GICv3CPUState *cs) +{ + AddressSpace *as = &cs->gic->sysmem_as; + uint64_t lpict_baddr, lpipt_baddr; + uint32_t pendt_size = 0; + uint8_t lpite; + uint8_t prio, pend; + int i; + bool seenbetter = false; + + if ((!cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser || + !cs->gicr_pendbaser || cs->lpi_outofrange) { + return seenbetter; + } + + lpict_baddr = (cs->gicr_propbaser >> GICR_PROPBASER_ADDR_OFFSET) & + GICR_PROPBASER_ADDR_MASK; + lpict_baddr <<= GICR_PROPBASER_ADDR_OFFSET; + + lpipt_baddr = (cs->gicr_pendbaser >> GICR_PENDBASER_ADDR_OFFSET) & + GICR_PENDBASER_ADDR_MASK; + lpipt_baddr <<= GICR_PENDBASER_ADDR_OFFSET; + + /* Determine the highest priority pending interrupt among LPIs */ + pendt_size = (1UL << ((cs->gicr_propbaser & + GICR_PROPBASER_IDBITS_MASK) - 1)); + + for (i = 0; i < pendt_size; i++) { + address_space_read(as, lpipt_baddr + + (((GICV3_LPI_INTID_START + i) / 8) * sizeof(pend)), + MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend)); + + if ((1 << ((GICV3_LPI_INTID_START + i) % 8)) & pend) { + address_space_read(as, lpict_baddr + (i * sizeof(lpite)), + MEMTXATTRS_UNSPECIFIED, &lpite, sizeof(lpite)); + + prio = ((lpite >> LPI_CTE_PRIORITY_OFFSET) & + LPI_CTE_PRIORITY_MASK); + prio &= LPI_PRIORITY_MASK; + + if (prio < cs->hppi.prio) { + cs->hppi.irq = GICV3_LPI_INTID_START + i; + cs->hppi.prio = prio; + /* LPIs are always non-secure Grp1 interrupts */ + cs->hppi.grp = GICV3_G1NS; + seenbetter = true; + } + } + } + return seenbetter; +} + +void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level) +{ + AddressSpace *as = &cs->gic->sysmem_as; + uint64_t lpipt_baddr; + bool ispend = false; + uint8_t pend; + + /* + * get the bit value corresponding to this irq in the + * lpi pending table + */ + lpipt_baddr = (cs->gicr_pendbaser >> GICR_PENDBASER_ADDR_OFFSET) & + GICR_PENDBASER_ADDR_MASK; + lpipt_baddr <<= GICR_PENDBASER_ADDR_OFFSET; + + address_space_read(as, lpipt_baddr + ((irq / 8) * sizeof(pend)), + MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend)); + ispend = ((pend >> (irq % 8)) & 0x1); + + if (ispend) { + if (!level) { + /* + * clear the pending bit and update the lpi pending table + */ + pend &= ~(1 << (irq % 8)); + + address_space_write(as, lpipt_baddr + ((irq / 8) * sizeof(pend)), + MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend)); + } + } else { + if (level) { + /* + * if pending bit is not already set for this irq,turn-on the + * pending bit and update the lpi pending table + */ + pend |= (1 << (irq % 8)); + + address_space_write(as, lpipt_baddr + ((irq / 8) * sizeof(pend)), + MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend)); + } + } +} + +void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level) +{ + AddressSpace *as = &cs->gic->sysmem_as; + uint64_t lpict_baddr; + uint8_t lpite; + + if ((!cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser || + !cs->gicr_pendbaser || cs->lpi_outofrange) { + return; + } + + lpict_baddr = (cs->gicr_propbaser >> GICR_PROPBASER_ADDR_OFFSET) & + GICR_PROPBASER_ADDR_MASK; + lpict_baddr <<= GICR_PROPBASER_ADDR_OFFSET; + + /* get the lpi config table entry corresponding to this irq */ + address_space_read(as, lpict_baddr + ((irq - GICV3_LPI_INTID_START) * + sizeof(lpite)), MEMTXATTRS_UNSPECIFIED, + &lpite, sizeof(lpite)); + + /* check if this irq is enabled before proceeding further */ + if (!(lpite & LPI_CTE_ENABLED)) { + return; + } + + /* set/clear the pending bit for this irq */ + gicv3_redist_lpi_pending(cs, irq, level); + + gicv3_redist_update(cs); +} + void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level) { /* Update redistributor state for a change in an external PPI input line */ diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h index 7c6bc33e97..cbb7810ec8 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -465,6 +465,9 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data, unsigned size, MemTxAttrs attrs); void gicv3_dist_set_irq(GICv3State *s, int irq, int level); void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level); +void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level); +void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level); +bool gicv3_redist_update_lpi(GICv3CPUState *cs); void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns); void gicv3_init_cpuif(GICv3State *s); From patchwork Tue Mar 23 04:12:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 12156811 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DCFA6C433C1 for ; Tue, 23 Mar 2021 04:18:50 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 769A96191C for ; Tue, 23 Mar 2021 04:18:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 769A96191C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:37024 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lOYVF-0006u6-HA for qemu-devel@archiver.kernel.org; Tue, 23 Mar 2021 00:18:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56108) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lOYPp-0000qK-Q3 for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:13:13 -0400 Received: from mail-qk1-x733.google.com ([2607:f8b0:4864:20::733]:37416) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lOYPO-0006cl-40 for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:13:13 -0400 Received: by mail-qk1-x733.google.com with SMTP id g15so13129172qkl.4 for ; Mon, 22 Mar 2021 21:12:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wi/6RMFD9QHoWMG50SCOYWnSVhyjzRhsQvs0OtM7umo=; b=YavFE91R9Vb/1TGYJ3DBFhoideQrhCEE2tQ8xRjZ5V4UTt+IeYnnfsZoRQ1p29sjDc A3gyKP/e73jqm8mlsIaakdY06gyNMVd3oJLMuNtJe1+jIEOV5QmCeoccZCr7hl4pcyHF C8aZyRJO1lJQitAsoLQGKmL5UeMBs9jGMLkajzmB/hW7fMQbQK+YU1KTaD2BHtjcbelr g6iUmUnvT5TO5x6B/y5gNUpo4opkHRtC8SP7QC1piyjpS5bGRN+8VvM9SOGt+ZnVS3SD 7SoZTtwKJ6wCW95Eu+5+7k5J61MWoBf09YuUlfgdjs8dV6/9G3tDk1g9OFOTJsT8ZBWd vMaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wi/6RMFD9QHoWMG50SCOYWnSVhyjzRhsQvs0OtM7umo=; b=Rgyj7pOyEQPpZfBu0z5jc+ZcOArJbKfNek+Tst+pW2Zl5S00l+wLuTN1PZRFTIKTBw z4tF1C4U/pDqq+afJKBSXO5dLgxNGV1nzo8bW+ikRBCrq04+L1fexCezjvw3dqPW5k9r BMPpwkYWYs9ZXo8uHX2jMuBegaOAHrepsuCesGnhOMtRFk3+OdPql5bZ1/wE7VaU4ZTS Lj17GcJpmrjR6jnd6fo6PWkRSfeK4qQUFkHzu9zZiCliUV9IroprIMQKr16g0wA5vQYa HvnCtB+RgjqDaxWx0kATYswBtnyAis6F26CCqijzrko6hGBruUWSkJIiZg3XNUB+uOiu uFoA== X-Gm-Message-State: AOAM533MFepIdAAUuz32Vu/e0FRqdGsbczx4Xu0Lumh5o6sb7LKf0S4p RzXnM5Nr2JRWEoU4LgA2Vy+NJg== X-Google-Smtp-Source: ABdhPJzfJlu3nbQ/9ueU/t4WMft5xvHIRlm0LlOcGMuPHI1HMflT0gYs1ejzUpbX17XQeE/hgTDPsg== X-Received: by 2002:a37:a0d1:: with SMTP id j200mr3625105qke.426.1616472765321; Mon, 22 Mar 2021 21:12:45 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-23-174-92-28-28.dsl.bell.ca. [174.92.28.28]) by smtp.googlemail.com with ESMTPSA id m21sm12601181qka.28.2021.03.22.21.12.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 21:12:45 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v1 7/8] hw/arm/sbsa-ref: add ITS support in SBSA GIC Date: Tue, 23 Mar 2021 00:12:37 -0400 Message-Id: <20210323041238.133835-8-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210323041238.133835-1-shashi.mallela@linaro.org> References: <20210323041238.133835-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::733; envelope-from=shashi.mallela@linaro.org; helo=mail-qk1-x733.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Included creation of ITS as part of SBSA platform GIC initialization. Signed-off-by: Shashi Mallela --- hw/arm/sbsa-ref.c | 26 +++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index 88dfb2284c..d05cbcae48 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -35,7 +35,7 @@ #include "hw/boards.h" #include "hw/ide/internal.h" #include "hw/ide/ahci_internal.h" -#include "hw/intc/arm_gicv3_common.h" +#include "hw/intc/arm_gicv3_its_common.h" #include "hw/loader.h" #include "hw/pci-host/gpex.h" #include "hw/qdev-properties.h" @@ -65,6 +65,7 @@ enum { SBSA_CPUPERIPHS, SBSA_GIC_DIST, SBSA_GIC_REDIST, + SBSA_GIC_ITS, SBSA_SECURE_EC, SBSA_GWDT, SBSA_GWDT_REFRESH, @@ -108,6 +109,7 @@ static const MemMapEntry sbsa_ref_memmap[] = { [SBSA_CPUPERIPHS] = { 0x40000000, 0x00040000 }, [SBSA_GIC_DIST] = { 0x40060000, 0x00010000 }, [SBSA_GIC_REDIST] = { 0x40080000, 0x04000000 }, + [SBSA_GIC_ITS] = { 0x44090000, 0x00020000 }, [SBSA_SECURE_EC] = { 0x50000000, 0x00001000 }, [SBSA_GWDT_REFRESH] = { 0x50010000, 0x00001000 }, [SBSA_GWDT_CONTROL] = { 0x50011000, 0x00001000 }, @@ -378,7 +380,20 @@ static void create_secure_ram(SBSAMachineState *sms, memory_region_add_subregion(secure_sysmem, base, secram); } -static void create_gic(SBSAMachineState *sms) +static void create_its(SBSAMachineState *sms) +{ + DeviceState *dev; + + dev = qdev_new(TYPE_ARM_GICV3_ITS); + SysBusDevice *s = SYS_BUS_DEVICE(dev); + + object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(sms->gic), + &error_abort); + sysbus_realize_and_unref(s, &error_fatal); + sysbus_mmio_map(s, 0, sbsa_ref_memmap[SBSA_GIC_ITS].base); +} + +static void create_gic(SBSAMachineState *sms, MemoryRegion *mem) { unsigned int smp_cpus = MACHINE(sms)->smp.cpus; SysBusDevice *gicbusdev; @@ -405,6 +420,10 @@ static void create_gic(SBSAMachineState *sms) qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1); qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count); + object_property_set_link(OBJECT(sms->gic), "sysmem", OBJECT(mem), + &error_fatal); + qdev_prop_set_bit(sms->gic, "has-lpi", true); + gicbusdev = SYS_BUS_DEVICE(sms->gic); sysbus_realize_and_unref(gicbusdev, &error_fatal); sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base); @@ -451,6 +470,7 @@ static void create_gic(SBSAMachineState *sms) sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus, qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); } + create_its(sms); } static void create_uart(const SBSAMachineState *sms, int uart, @@ -763,7 +783,7 @@ static void sbsa_ref_init(MachineState *machine) create_secure_ram(sms, secure_sysmem); - create_gic(sms); + create_gic(sms, sysmem); create_uart(sms, SBSA_UART, sysmem, serial_hd(0)); create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1)); From patchwork Tue Mar 23 04:12:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 12156815 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50499C433DB for ; Tue, 23 Mar 2021 04:20:37 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D105061990 for ; Tue, 23 Mar 2021 04:20:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D105061990 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:44260 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lOYWy-0001tl-0F for qemu-devel@archiver.kernel.org; Tue, 23 Mar 2021 00:20:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56112) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lOYPq-0000qp-0T for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:13:18 -0400 Received: from mail-qk1-x730.google.com ([2607:f8b0:4864:20::730]:43634) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lOYPP-0006dT-V4 for qemu-devel@nongnu.org; Tue, 23 Mar 2021 00:13:13 -0400 Received: by mail-qk1-x730.google.com with SMTP id x14so13104009qki.10 for ; Mon, 22 Mar 2021 21:12:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=36CRRigRDg6z7Ps/zHm2nFOe3o4QS1w0QeVs5IpQt88=; b=eOennnAjZl/gXsvTkXxNaPZN2Um9rfxdNAvoYx0ZQbNmML1VizMxrjN0w7CWJNVgYM ea5P/zzYh0igaEngwWO1uMHW4um4uqAVMMfwyKSRwoASUDPSH5xGsRTxHIm0QcqMqOSZ xAQXPUrGWtpS5MWf8w1T/XZmq2eu/AzS6t8h0X0YKwOILJh3+DseGFGgCFNw37x1fGbz g36kjiDLVCG5Mu4AQ8iRkjk93MCOl07zlrnMYud3M2JwRAQ/hskQdOQ1IveXeyYXL38k hqDJK3kjizWYt9vuJLcmKtD2UCdtZ83/mTA/V0/IhRH8Y863qE6QuQVR6DjLTVa+IfL8 UMTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=36CRRigRDg6z7Ps/zHm2nFOe3o4QS1w0QeVs5IpQt88=; b=T81S7v4uu3s5oqL4mEugg1baNBr7phBvRIAJh2KXuwhocIKSLbdFO9k56FqrOOA5ZX 1bg/fNpwSKxqyyQPpxpL+yqxtObc3p+8DTNE4a3PRzieHPGtgU/WRyTjW59KrCUTWMo2 rO5t8b0oJhq9RYDm2eOP4+uEIL3hg/z438nOjU3zdgTQRWDSIAM3N2iC+1iN5Z/WQt7i jXUPVcxL054IemtWp5BWeCnwVhHM/aPwd7JlGGtrLPYY48FhOArRK/YgWxsIrbF9lpG8 13PyZKpci278Bso+abyOTN2E5h2Xqe6IK+4jehI0EGmELdIYuhR+SUxav3WoW7rr7m4S 4xmw== X-Gm-Message-State: AOAM530gplFkfT6rEvLGvxtsjDC5/BeuLO49xJBEQTT5YVqd0EjYj8P6 keJbgD6kcqJyM2xfJX3J8/Pa9A== X-Google-Smtp-Source: ABdhPJzUtBWvfcsxmg8AEDrqly4wvLjxsuLGjLWOlXr0JhRrXWop/37lf+8LvoE24EteudW+q/UbUg== X-Received: by 2002:a05:620a:20db:: with SMTP id f27mr3685575qka.51.1616472765872; Mon, 22 Mar 2021 21:12:45 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-23-174-92-28-28.dsl.bell.ca. [174.92.28.28]) by smtp.googlemail.com with ESMTPSA id m21sm12601181qka.28.2021.03.22.21.12.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 21:12:45 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v1 8/8] hw/arm/virt: add ITS support in virt GIC Date: Tue, 23 Mar 2021 00:12:38 -0400 Message-Id: <20210323041238.133835-9-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210323041238.133835-1-shashi.mallela@linaro.org> References: <20210323041238.133835-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::730; envelope-from=shashi.mallela@linaro.org; helo=mail-qk1-x730.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Included creation of ITS as part of virt platform GIC initialization.This Emulated ITS model now co-exists with kvm ITS and is enabled in absence of kvm irq kernel support in a platform. Signed-off-by: Shashi Mallela --- hw/arm/virt.c | 10 ++++++++-- target/arm/kvm_arm.h | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index aa2bbd14e0..77cf2db90f 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -622,7 +622,7 @@ static void create_v2m(VirtMachineState *vms) vms->msi_controller = VIRT_MSI_CTRL_GICV2M; } -static void create_gic(VirtMachineState *vms) +static void create_gic(VirtMachineState *vms, MemoryRegion *mem) { MachineState *ms = MACHINE(vms); /* We create a standalone GIC */ @@ -656,6 +656,12 @@ static void create_gic(VirtMachineState *vms) nb_redist_regions); qdev_prop_set_uint32(vms->gic, "redist-region-count[0]", redist0_count); + if (!kvm_irqchip_in_kernel()) { + object_property_set_link(OBJECT(vms->gic), "sysmem", OBJECT(mem), + &error_fatal); + qdev_prop_set_bit(vms->gic, "has-lpi", true); + } + if (nb_redist_regions == 2) { uint32_t redist1_capacity = vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE; @@ -2039,7 +2045,7 @@ static void machvirt_init(MachineState *machine) virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem); - create_gic(vms); + create_gic(vms, sysmem); virt_cpu_post_init(vms, sysmem); diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 34f8daa377..0613454975 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -525,8 +525,8 @@ static inline const char *its_class_name(void) /* KVM implementation requires this capability */ return kvm_direct_msi_enabled() ? "arm-its-kvm" : NULL; } else { - /* Software emulation is not implemented yet */ - return NULL; + /* Software emulation based model */ + return "arm-gicv3-its"; } }