From patchwork Wed Jun 2 18:00: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: 452541 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp791622jao; Wed, 2 Jun 2021 11:01:59 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxpGv2w2a0esue0nVnOjmOhq8YxS48ppRXYT3fsKETDaJknq4xJmDRIAs4cTdB8kGImUyhf X-Received: by 2002:a17:907:c02:: with SMTP id ga2mr8669409ejc.513.1622656919397; Wed, 02 Jun 2021 11:01:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622656919; cv=none; d=google.com; s=arc-20160816; b=LvpU81975eFDtwMXy+LB23kAWW0mzuRDcWlO/qm9Mr1I6JPxsVF+DY76pBdNhxgkL8 f+rXhh6FlKB4m1Nth4UWdXiP0pHk0oUc+4ydPN8yHygrvfWd7FtAXM2WC1zg8cD/l7BM YbKdAod4DSMDDf917Oh7DbAhgpRiDTwlS91GamEGu1G/Rkg5bjB3YwG/35+NjAi5gK+Q lF8eJgrEe1ZTuAPnttyDsEcy3gzfJ1Gr1qe36z8soH1znpQiDGe1IR0f3fbP8Nh0QOjS eTlo/OGQwCfTiXFMAIi0JFCEdgu2ysL6ob449/mM8J2EPM8rZ6fWH+l2hLVzGTVCLEjd +u7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=iG0e24Xu/7wogx6h+PGHJmqIO8v8Gf3F/736hWjR3QE=; b=dCQEmVOIjO5xSobBaorDw+u149DTCu7UEBMBRyWhMArCICjd/YwIDB1bltzYGQYiOd ZixYgfTZP1tbOMwZlEToywY4yxLQTBevE/mph+vba0z+kXygGxHXr7LF/fzewzXHGEfB s6uNavLs1kbGTDEK0di4VDDc9Z/I6PG7UCm6VQ0QFusxc+pmhuMVLxo2pVMeazwN2xFm ICBpKCgBPo3x9it+ndtxwywZ6Z3Xswt29g/iQy25c+u8BC/+yHTLkB/E0lY7UVGD1STb f0TEZMhVuqpN2pyaTJLBPQGuJpD2KKwT1DrRjTMt6qc/dDvAcPYAw6UKZ0NVbxdJq3hO RbLw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="P5Fiix/R"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id zm10si492344ejb.67.2021.06.02.11.01.59 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 02 Jun 2021 11:01:59 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="P5Fiix/R"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:40292 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVBm-00087n-8L for patch@linaro.org; Wed, 02 Jun 2021 14:01:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51070) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1loVAh-00085E-Gp for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:51 -0400 Received: from mail-qk1-x735.google.com ([2607:f8b0:4864:20::735]:34809) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1loVAb-0006Z4-R6 for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:51 -0400 Received: by mail-qk1-x735.google.com with SMTP id k11so1637102qkk.1 for ; Wed, 02 Jun 2021 11:00: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=iG0e24Xu/7wogx6h+PGHJmqIO8v8Gf3F/736hWjR3QE=; b=P5Fiix/RNYk1iLnPW+n0HsemTaSRb+xNq0FFHJ4VsAtT6m8KvtP+00XFzS3OkNkgyj t79wi20bzNxgFC6NXc6uMd2qOMdpMULEOBgIDooxFIuHhM9disqcNyJJZYWwXDVZm+SE lN7URi5qJ3FLMhjgCBr1KXX197Gt2FDAwFTX0G+AfNp+0QRc12vxAf9YAtcfBLTUXH94 Coat9h0ZnZWtz524KBxv2OYjmYsZj1xLiZVFNCprOgkJn57vVM+1TMl1mIPIWtgmuw5B ArTmbZsrhArAoD/Hbdw1RVkfjkiEhp565uVKSLzSiV1xrIA4nw+vsx/sxC+oT7PfvsP6 ny2Q== 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=iG0e24Xu/7wogx6h+PGHJmqIO8v8Gf3F/736hWjR3QE=; b=p2PUEVLcsibLl/ObYW7cJFOPnk0XX2OrbGat02hF6Vt63J1immMs9yEycFAmxbBkv3 Ca4cnsCTwjWQ+pFANGI3OHgWfh3rYBCkbIshZxHVObzeWWvOOIwGYhWJ4XtI40Mk0vpU EIb9FKFihUpIeIysVWeSUkDqmTiGrLqVdZYyfJWV+ikF55LolOFsD0m+zzFFEU9KHlza d0tGCXiGRCBtS7mhN1dxDtE/ueSWaA/jVCsoDfzZ1nz0SaFRqpE3a54N8aNH+M6DnLv2 CrMb6DKmFnzKLI+iicjJlkCKh+AkQeniA0lc68bfNqh7a/PDS0f+CidDQX2rFdT1Kffw QKJg== X-Gm-Message-State: AOAM530mFibkLITBNvfpN5+iyQI/hatVKQ2m8xMR/N8FXfFIDzDMZKnG 4TPzJl/IBLDCSIXM4RvqYKVQZw== X-Received: by 2002:a37:70b:: with SMTP id 11mr6949835qkh.463.1622656844835; Wed, 02 Jun 2021 11:00:44 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-21-142-114-142-78.dsl.bell.ca. [142.114.142.78]) by smtp.googlemail.com with ESMTPSA id 97sm273044qte.20.2021.06.02.11.00.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 11:00:44 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v4 1/8] hw/intc: GICv3 ITS initial framework Date: Wed, 2 Jun 2021 14:00:35 -0400 Message-Id: <20210602180042.111347-2-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602180042.111347-1-shashi.mallela@linaro.org> References: <20210602180042.111347-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=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+patch=linaro.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 | 240 +++++++++++++++++++++++++ hw/intc/arm_gicv3_its_common.c | 8 +- hw/intc/arm_gicv3_its_kvm.c | 2 +- hw/intc/gicv3_internal.h | 88 +++++++-- hw/intc/meson.build | 1 + include/hw/intc/arm_gicv3_its_common.h | 9 +- 6 files changed, 331 insertions(+), 17 deletions(-) create mode 100644 hw/intc/arm_gicv3_its.c -- 2.27.0 Reviewed-by: Peter Maydell diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c new file mode 100644 index 0000000000..545cda3665 --- /dev/null +++ b/hw/intc/arm_gicv3_its.c @@ -0,0 +1,240 @@ +/* + * 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 gicv3_its_translation_write(void *opaque, hwaddr offset, + uint64_t data, unsigned size, + MemTxAttrs attrs) +{ + MemTxResult result = MEMTX_OK; + + return result; +} + +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 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 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, + .valid.min_access_size = 4, + .valid.max_access_size = 8, + .impl.min_access_size = 4, + .impl.max_access_size = 8, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static const MemoryRegionOps gicv3_its_translation_ops = { + .write_with_attrs = gicv3_its_translation_write, + .valid.min_access_size = 2, + .valid.max_access_size = 4, + .impl.min_access_size = 2, + .impl.max_access_size = 4, + .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_translation_ops); + + if (s->gicv3->cpu->gicr_typer & GICR_TYPER_PLPIS) { + /* set the ITS default features supported */ + s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL, + GITS_TYPE_PHYSICAL); + s->typer = FIELD_DP64(s->typer, GITS_TYPER, ITT_ENTRY_SIZE, + ITS_ITT_ENTRY_SIZE - 1); + s->typer = FIELD_DP64(s->typer, GITS_TYPER, IDBITS, ITS_IDBITS); + s->typer = FIELD_DP64(s->typer, GITS_TYPER, DEVBITS, ITS_DEVBITS); + s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIL, 1); + s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIDBITS, ITS_CIDBITS); + } +} + +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); + + /* Quiescent bit reset to 1 */ + s->ctlr = FIELD_DP32(s->ctlr, GITS_CTLR, QUIESCENT, 1); + + /* + * 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] = FIELD_DP64(s->baser[0], GITS_BASER, TYPE, + GITS_ITT_TYPE_DEVICE); + s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, PAGESIZE, + GITS_BASER_PAGESIZE_64K); + s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, ENTRYSIZE, + GITS_DTE_SIZE - 1); + + s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, TYPE, + GITS_ITT_TYPE_COLLECTION); + s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, PAGESIZE, + GITS_BASER_PAGESIZE_64K); + s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, ENTRYSIZE, + GITS_CTE_SIZE - 1); + } +} + +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..f1657c84e0 100644 --- a/hw/intc/arm_gicv3_its_common.c +++ b/hw/intc/arm_gicv3_its_common.c @@ -50,6 +50,8 @@ static int gicv3_its_post_load(void *opaque, int version_id) static const VMStateDescription vmstate_its = { .name = "arm_gicv3_its", + .version_id = 1, + .minimum_version_id = 1, .pre_save = gicv3_its_pre_save, .post_load = gicv3_its_post_load, .priority = MIG_PRI_GICV3_ITS, @@ -99,14 +101,15 @@ 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, + tops ? tops : &gicv3_its_trans_ops, s, "translation", ITS_TRANS_SIZE); /* Our two regions are always adjacent, therefore we now combine them @@ -129,7 +132,6 @@ static void gicv3_its_common_reset(DeviceState *dev) s->cbaser = 0; s->cwriter = 0; s->creadr = 0; - s->iidr = 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..e0b06930a7 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -24,6 +24,7 @@ #ifndef QEMU_ARM_GICV3_INTERNAL_H #define QEMU_ARM_GICV3_INTERNAL_H +#include "hw/registerfields.h" #include "hw/intc/arm_gicv3_common.h" /* Distributor registers, as offsets from the distributor base address */ @@ -67,6 +68,9 @@ #define GICD_CTLR_E1NWF (1U << 7) #define GICD_CTLR_RWP (1U << 31) +/* 16 bits EventId */ +#define GICD_TYPER_IDBITS 0xf + /* * Redistributor frame offsets from RD_base */ @@ -122,18 +126,6 @@ #define GICR_WAKER_ProcessorSleep (1U << 1) #define GICR_WAKER_ChildrenAsleep (1U << 2) -#define GICR_PROPBASER_OUTER_CACHEABILITY_MASK (7ULL << 56) -#define GICR_PROPBASER_ADDR_MASK (0xfffffffffULL << 12) -#define GICR_PROPBASER_SHAREABILITY_MASK (3U << 10) -#define GICR_PROPBASER_CACHEABILITY_MASK (7U << 7) -#define GICR_PROPBASER_IDBITS_MASK (0x1f) - -#define GICR_PENDBASER_PTZ (1ULL << 62) -#define GICR_PENDBASER_OUTER_CACHEABILITY_MASK (7ULL << 56) -#define GICR_PENDBASER_ADDR_MASK (0xffffffffULL << 16) -#define GICR_PENDBASER_SHAREABILITY_MASK (3U << 10) -#define GICR_PENDBASER_CACHEABILITY_MASK (7U << 7) - #define ICC_CTLR_EL1_CBPR (1U << 0) #define ICC_CTLR_EL1_EOIMODE (1U << 1) #define ICC_CTLR_EL1_PMHE (1U << 6) @@ -239,6 +231,78 @@ #define ICH_VTR_EL2_PREBITS_SHIFT 26 #define ICH_VTR_EL2_PRIBITS_SHIFT 29 +/* ITS Registers */ + +FIELD(GITS_BASER, SIZE, 0, 8) +FIELD(GITS_BASER, PAGESIZE, 8, 2) +FIELD(GITS_BASER, SHAREABILITY, 10, 2) +FIELD(GITS_BASER, PHYADDR, 12, 36) +FIELD(GITS_BASER, PHYADDRL_64K, 16, 32) +FIELD(GITS_BASER, PHYADDRH_64K, 48, 4) +FIELD(GITS_BASER, ENTRYSIZE, 48, 5) +FIELD(GITS_BASER, OUTERCACHE, 53, 3) +FIELD(GITS_BASER, TYPE, 56, 3) +FIELD(GITS_BASER, INNERCACHE, 59, 3) +FIELD(GITS_BASER, INDIRECT, 62, 1) +FIELD(GITS_BASER, VALID, 63, 1) + +FIELD(GITS_CTLR, QUIESCENT, 31, 1) + +FIELD(GITS_TYPER, PHYSICAL, 0, 1) +FIELD(GITS_TYPER, ITT_ENTRY_SIZE, 4, 4) +FIELD(GITS_TYPER, IDBITS, 8, 5) +FIELD(GITS_TYPER, DEVBITS, 13, 5) +FIELD(GITS_TYPER, SEIS, 18, 1) +FIELD(GITS_TYPER, PTA, 19, 1) +FIELD(GITS_TYPER, CIDBITS, 32, 4) +FIELD(GITS_TYPER, CIL, 36, 1) + +#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 + +/** + * Default features advertised by this version of ITS + */ +/* Physical LPIs supported */ +#define GITS_TYPE_PHYSICAL (1U << 0) + +/* + * 12 bytes Interrupt translation Table Entry size + * ITE Lower 8 Bytes + * Valid = 1 bit,InterruptType = 1 bit, + * Size of LPI number space[considering max 24 bits], + * Size of LPI number space[considering max 24 bits], + * ITE Higher 4 Bytes + * ICID = 16 bits, + * vPEID = 16 bits + */ +#define ITS_ITT_ENTRY_SIZE 0xC + +/* 16 bits EventId */ +#define ITS_IDBITS GICD_TYPER_IDBITS + +/* 16 bits DeviceId */ +#define ITS_DEVBITS 0xF + +/* 16 bits CollectionId */ +#define ITS_CIDBITS 0xF + +/* + * 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 diff --git a/hw/intc/meson.build b/hw/intc/meson.build index 6e52a166e3..4dcfea6aa8 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..65d1191db1 100644 --- a/include/hw/intc/arm_gicv3_its_common.h +++ b/include/hw/intc/arm_gicv3_its_common.h @@ -25,17 +25,22 @@ #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 + struct GICv3ITSState { SysBusDevice parent_obj; @@ -52,6 +57,7 @@ struct GICv3ITSState { /* Registers */ uint32_t ctlr; uint32_t iidr; + uint64_t typer; uint64_t cbaser; uint64_t cwriter; uint64_t creadr; @@ -62,7 +68,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 Wed Jun 2 18:00: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: 452542 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp791649jao; Wed, 2 Jun 2021 11:02:01 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyxXuqxeS16txnh/vUVEiLGtFhxBGEAZzBhNOl9TnRRglWQFWpfz+e7loaxVW0m+C3R9aVj X-Received: by 2002:aa7:c885:: with SMTP id p5mr14144402eds.234.1622656921109; Wed, 02 Jun 2021 11:02:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622656921; cv=none; d=google.com; s=arc-20160816; b=JSd3dL6DUQ7Mf/OvlzL64pk5qdAztGc9ivh7DVR9u+0BOKEHUf1wI67Ag29HBr7sek UO9Pi7s9DatWHmFI6AIYf80Ceg5Q2XXGQKMg77MNgrMeMqP53SDpM8MyOVPwkOsEHIJg HGUq/pEQEq//KMxKiKl+RWu5rCD7LERKO3ms5PoZr07UF9O8LfovmBiXbFM5UnnqFzVG 2oKL3+S3I6+EVc+/rAXoSIRHJoq05ZXkw/9Rl8ieu+wPUMNWhwp6Pmt3KqD/eRQbaGBz xniE73LdzBT25NFTlAituvjwDWNzkpeNo80m6jepSM4sVrkCMll+35FZiff9vFAgvKTn 58Rw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=3IVN/8rF5fxlsc9q9B9yfI+apQaP68qFmGdTRKzvpgI=; b=qz/UcY5kSn8TBSz08VlwF25Th6hht6jrhN5ctAX7GMqtK8RsZi0ME2QTh9Mta6EqyU GKwahreMUrdBPUQLVcbHvxQlPE8N5sY9jMfhOvCXtVThesJvZjEEt9fRxZIGbMvcYm3w lsUd60UyJij2XEs3FyoL7BMpKtxnSuoGtDtjAy40X4CiEVoYbPrNjZUDmd+hsZdszKeB 0mFg0cmt4o+7mY55+wHS2rdINPDMg2CeG0Edz6uUfxZygG3MTBGN1nrNJPQLi3ysJDhN aZAz2OPGdaGuMDPmGgX6AV29Qt8QM+18dfkyeUwKMoUwubXBpdPHxUTOqO2wEQDNpmv2 yLlg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=cKjjGRwf; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id dy16si484268edb.130.2021.06.02.11.02.00 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 02 Jun 2021 11:02:01 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=cKjjGRwf; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:40394 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVBo-0008CS-0B for patch@linaro.org; Wed, 02 Jun 2021 14:02:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51100) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1loVAi-00087C-Ll for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:52 -0400 Received: from mail-qt1-x836.google.com ([2607:f8b0:4864:20::836]:33546) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1loVAc-0006Zf-M0 for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:52 -0400 Received: by mail-qt1-x836.google.com with SMTP id a15so2519970qta.0 for ; Wed, 02 Jun 2021 11:00: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=3IVN/8rF5fxlsc9q9B9yfI+apQaP68qFmGdTRKzvpgI=; b=cKjjGRwfHst5dCNTn1oSs7gs8pcb2pDFpXK7q8FWliW3Vps8KXq7TVm9WfBI8qgikz x1tHMmylHxmynOLZr94JIQtjfyB8LbtQ6xAIBxAF3geABDPckdpKnDefGuHovg0Hjl81 aVG8W90DniG4bLvv6BV6ms3MeufPWAFN4x6XeWutjbacYbLYGR+wIvpCA7yymCLT1NRi p3xqZMF0FLtb7zAigxzRjhXQxZCQptRShQeSAtAP9gTUrP4YBXr4h4Zv/19mnS4Oubg7 bdhSX8HqVHsGNlMRCR2PyFQqP1FZcz17LHWuOkBA3+nwIR/Qyf7SWiWSHXjeYfEo4SYw 3CUQ== 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=3IVN/8rF5fxlsc9q9B9yfI+apQaP68qFmGdTRKzvpgI=; b=jPqmDhH9XNlmiIq+sencU/JxlasVnFAe1ejn20V4VSX9+/Uc0ZU7OpujZyeONg7Mv5 Im7fZ7eBxn2nIQJLxWmhDNSifMVV+2uSRz+S2hKjsj6Mr9RK0HkveyAQXiM1bAZ6y9/O NVVeVoP1J1Mz4iaisrvhjHqIt6CA3D5Aq5IVHFdpbbStLR8BxbrDaQASOY/QbouphNyy umDVPSkFvP4KBExx8Dc1TAieU4JJh1JCc46sqnPzGMPL1ktZpkSEXWjwqnBrCBpdahdF kxgyInaaIUTOwvuvwhaPGU7f0PPtTOcq1vUj9Htxt0YVvKFspNrVUzC4mXegWxE42919 u3Uw== X-Gm-Message-State: AOAM530z+H+/I+JWDXAwkbXmtR4P7Cppa8kuc+lk2CxdJey2XqFsKwE5 EGJjFsExD/44YUHEVIjZJU3w0g== X-Received: by 2002:a05:622a:1055:: with SMTP id f21mr13672158qte.90.1622656845639; Wed, 02 Jun 2021 11:00:45 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-21-142-114-142-78.dsl.bell.ca. [142.114.142.78]) by smtp.googlemail.com with ESMTPSA id 97sm273044qte.20.2021.06.02.11.00.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 11:00:45 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v4 2/8] hw/intc: GICv3 ITS register definitions added Date: Wed, 2 Jun 2021 14:00:36 -0400 Message-Id: <20210602180042.111347-3-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602180042.111347-1-shashi.mallela@linaro.org> References: <20210602180042.111347-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::836; envelope-from=shashi.mallela@linaro.org; helo=mail-qt1-x836.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+patch=linaro.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 | 335 +++++++++++++++++++++++++ hw/intc/gicv3_internal.h | 28 ++- include/hw/intc/arm_gicv3_common.h | 3 + include/hw/intc/arm_gicv3_its_common.h | 30 +++ 4 files changed, 395 insertions(+), 1 deletion(-) -- 2.27.0 Reviewed-by: Peter Maydell diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index 545cda3665..af60f19c98 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -28,6 +28,157 @@ struct GICv3ITSClass { void (*parent_reset)(DeviceState *dev); }; +static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz) +{ + uint64_t result = 0; + + switch (page_sz) { + case GITS_ITT_PAGE_SIZE_0: + case GITS_ITT_PAGE_SIZE_1: + result = value & R_GITS_BASER_PHYADDR_MASK; + break; + + case GITS_ITT_PAGE_SIZE_2: + result = value & R_GITS_BASER_PHYADDRL_64K_MASK; + result |= FIELD_EX64(value, GITS_BASER, PHYADDRH_64K) << 48; + break; + + default: + break; + } + return result; +} + +static void extract_table_params(GICv3ITSState *s) +{ + uint16_t num_pages = 0; + uint8_t page_sz_type; + uint8_t type; + uint32_t page_sz = 0; + uint64_t value; + + for (int i = 0; i < 8; i++) { + value = s->baser[i]; + + if (!value) { + continue; + } + + page_sz_type = FIELD_EX64(value, GITS_BASER, PAGESIZE); + + switch (page_sz_type) { + case 0: + page_sz = GITS_ITT_PAGE_SIZE_0; + break; + + case 1: + page_sz = GITS_ITT_PAGE_SIZE_1; + break; + + case 2: + case 3: + page_sz = GITS_ITT_PAGE_SIZE_2; + break; + + default: + g_assert_not_reached(); + } + + num_pages = FIELD_EX64(value, GITS_BASER, SIZE); + + type = FIELD_EX64(value, GITS_BASER, TYPE); + + switch (type) { + + case GITS_ITT_TYPE_DEVICE: + memset(&s->dt, 0 , sizeof(s->dt)); + s->dt.valid = FIELD_EX64(value, GITS_BASER, VALID); + + if (!s->dt.valid) { + return; + } + + s->dt.page_sz = page_sz; + s->dt.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT); + s->dt.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE); + + if (!s->dt.indirect) { + s->dt.max_entries = ((num_pages + 1) * page_sz) / + s->dt.entry_sz; + } else { + s->dt.max_entries = ((((num_pages + 1) * page_sz) / + L1TABLE_ENTRY_SIZE) * + (page_sz / s->dt.entry_sz)); + } + + s->dt.max_devids = (1UL << (FIELD_EX64(s->typer, GITS_TYPER, + DEVBITS) + 1)); + + s->dt.base_addr = baser_base_addr(value, page_sz); + + break; + + case GITS_ITT_TYPE_COLLECTION: + memset(&s->ct, 0 , sizeof(s->ct)); + s->ct.valid = FIELD_EX64(value, GITS_BASER, VALID); + + /* + * GITS_TYPER.HCC is 0 for this implementation + * hence writes are discarded if ct.valid is 0 + */ + if (!s->ct.valid) { + return; + } + + s->ct.page_sz = page_sz; + s->ct.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT); + s->ct.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE); + + if (!s->ct.indirect) { + s->ct.max_entries = ((num_pages + 1) * page_sz) / + s->ct.entry_sz; + } else { + s->ct.max_entries = ((((num_pages + 1) * page_sz) / + L1TABLE_ENTRY_SIZE) * + (page_sz / s->ct.entry_sz)); + } + + if (FIELD_EX64(s->typer, GITS_TYPER, CIL)) { + s->ct.max_collids = (1UL << (FIELD_EX64(s->typer, + GITS_TYPER, CIDBITS) + 1)); + } else { + /* 16-bit CollectionId supported when CIL == 0 */ + s->ct.max_collids = (1UL << 16); + } + + s->ct.base_addr = baser_base_addr(value, page_sz); + + break; + + default: + break; + } + } +} + +static void extract_cmdq_params(GICv3ITSState *s) +{ + uint16_t num_pages = 0; + uint64_t value = s->cbaser; + + num_pages = FIELD_EX64(value, GITS_CBASER, SIZE); + + memset(&s->cq, 0 , sizeof(s->cq)); + s->cq.valid = FIELD_EX64(value, GITS_CBASER, VALID); + + if (s->cq.valid) { + s->cq.max_entries = ((num_pages + 1) * GITS_ITT_PAGE_SIZE_0) / + GITS_CMDQ_ENTRY_SIZE; + s->cq.base_addr = FIELD_EX64(value, GITS_CBASER, PHYADDR); + s->cq.base_addr <<= R_GITS_CBASER_PHYADDR_SHIFT; + } +} + static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset, uint64_t data, unsigned size, MemTxAttrs attrs) @@ -41,7 +192,73 @@ static MemTxResult its_writel(GICv3ITSState *s, hwaddr offset, uint64_t value, MemTxAttrs attrs) { MemTxResult result = MEMTX_OK; + int index; + switch (offset) { + case GITS_CTLR: + s->ctlr |= (value & ~(s->ctlr)); + + if (s->ctlr & ITS_CTLR_ENABLED) { + extract_table_params(s); + extract_cmdq_params(s); + s->creadr = 0; + } + break; + case GITS_CBASER: + /* + * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is + * already enabled + */ + if (!(s->ctlr & ITS_CTLR_ENABLED)) { + s->cbaser = deposit64(s->cbaser, 0, 32, value); + s->creadr = 0; + } + break; + case GITS_CBASER + 4: + /* + * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is + * already enabled + */ + if (!(s->ctlr & ITS_CTLR_ENABLED)) { + s->cbaser = deposit64(s->cbaser, 32, 32, value); + } + break; + case GITS_CWRITER: + s->cwriter = deposit64(s->cwriter, 0, 32, + (value & ~R_GITS_CWRITER_RETRY_MASK)); + break; + case GITS_CWRITER + 4: + s->cwriter = deposit64(s->cwriter, 32, 32, + (value & ~R_GITS_CWRITER_RETRY_MASK)); + break; + case GITS_BASER ... GITS_BASER + 0x3f: + /* + * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is + * already enabled + */ + if (!(s->ctlr & ITS_CTLR_ENABLED)) { + index = (offset - GITS_BASER) / 8; + + if (offset & 7) { + s->baser[index] = deposit64(s->baser[index], 32, 32, + (value & ~GITS_BASER_VAL_MASK)); + } else { + s->baser[index] = deposit64(s->baser[index], 0, 32, + (value & ~GITS_BASER_VAL_MASK)); + } + } + break; + case GITS_IIDR: + case GITS_IDREGS ... GITS_IDREGS + 0x2f: + /* 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; } @@ -49,7 +266,55 @@ 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 = gicv3_iidr(); + break; + case GITS_IDREGS ... GITS_IDREGS + 0x2f: + /* ID registers */ + *data = gicv3_idreg(offset - GITS_IDREGS); + 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 = extract64(s->baser[index], 32, 32); + } else { + *data = extract64(s->baser[index], 0, 32); + } + break; + default: + result = MEMTX_ERROR; + break; + } return result; } @@ -57,7 +322,42 @@ 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: + /* + * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is + * already enabled + */ + if (!(s->ctlr & ITS_CTLR_ENABLED)) { + index = (offset - GITS_BASER) / 8; + s->baser[index] |= (value & ~GITS_BASER_VAL_MASK); + } + break; + case GITS_CBASER: + /* + * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is + * already enabled + */ + if (!(s->ctlr & ITS_CTLR_ENABLED)) { + s->cbaser = value; + } + break; + case GITS_CWRITER: + s->cwriter = value & ~R_GITS_CWRITER_RETRY_MASK; + break; + case GITS_CREADR: + case GITS_TYPER: + /* 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; } @@ -65,7 +365,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; } @@ -162,6 +484,9 @@ static void gicv3_arm_its_realize(DeviceState *dev, Error **errp) gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops); if (s->gicv3->cpu->gicr_typer & GICR_TYPER_PLPIS) { + address_space_init(&s->gicv3->dma_as, s->gicv3->dma, + "gicv3-its-sysmem"); + /* set the ITS default features supported */ s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL, GITS_TYPE_PHYSICAL); @@ -208,6 +533,14 @@ static void gicv3_its_reset(DeviceState *dev) } } +static void gicv3_its_post_load(GICv3ITSState *s) +{ + if (s->ctlr & ITS_CTLR_ENABLED) { + extract_table_params(s); + extract_cmdq_params(s); + } +} + static Property gicv3_its_props[] = { DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "arm-gicv3", GICv3State *), @@ -218,10 +551,12 @@ static void gicv3_its_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); GICv3ITSClass *ic = ARM_GICV3_ITS_CLASS(klass); + GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_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); + icc->post_load = gicv3_its_post_load; } static const TypeInfo gicv3_its_info = { diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h index e0b06930a7..d6aaa94e4c 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -238,7 +238,7 @@ FIELD(GITS_BASER, PAGESIZE, 8, 2) FIELD(GITS_BASER, SHAREABILITY, 10, 2) FIELD(GITS_BASER, PHYADDR, 12, 36) FIELD(GITS_BASER, PHYADDRL_64K, 16, 32) -FIELD(GITS_BASER, PHYADDRH_64K, 48, 4) +FIELD(GITS_BASER, PHYADDRH_64K, 12, 4) FIELD(GITS_BASER, ENTRYSIZE, 48, 5) FIELD(GITS_BASER, OUTERCACHE, 53, 3) FIELD(GITS_BASER, TYPE, 56, 3) @@ -246,6 +246,17 @@ FIELD(GITS_BASER, INNERCACHE, 59, 3) FIELD(GITS_BASER, INDIRECT, 62, 1) FIELD(GITS_BASER, VALID, 63, 1) +FIELD(GITS_CBASER, SIZE, 0, 8) +FIELD(GITS_CBASER, SHAREABILITY, 10, 2) +FIELD(GITS_CBASER, PHYADDR, 12, 40) +FIELD(GITS_CBASER, OUTERCACHE, 53, 3) +FIELD(GITS_CBASER, INNERCACHE, 59, 3) +FIELD(GITS_CBASER, VALID, 63, 1) + +FIELD(GITS_CWRITER, RETRY, 0, 1) +FIELD(GITS_CWRITER, OFFSET, 5, 15) + +FIELD(GITS_CTLR, ENABLED, 0, 1) FIELD(GITS_CTLR, QUIESCENT, 31, 1) FIELD(GITS_TYPER, PHYSICAL, 0, 1) @@ -257,6 +268,13 @@ FIELD(GITS_TYPER, PTA, 19, 1) FIELD(GITS_TYPER, CIDBITS, 32, 4) FIELD(GITS_TYPER, CIL, 36, 1) +#define GITS_IDREGS 0xFFD0 + +#define ITS_CTLR_ENABLED (1U) /* ITS Enabled */ + +#define GITS_BASER_VAL_MASK (R_GITS_BASER_ENTRYSIZE_MASK | \ + R_GITS_BASER_TYPE_MASK) + #define GITS_BASER_PAGESIZE_4K 0 #define GITS_BASER_PAGESIZE_16K 1 #define GITS_BASER_PAGESIZE_64K 2 @@ -264,6 +282,14 @@ FIELD(GITS_TYPER, CIL, 36, 1) #define GITS_ITT_TYPE_DEVICE 1ULL #define GITS_ITT_TYPE_COLLECTION 4ULL +#define GITS_ITT_PAGE_SIZE_0 0x1000 +#define GITS_ITT_PAGE_SIZE_1 0x4000 +#define GITS_ITT_PAGE_SIZE_2 0x10000 + +#define L1TABLE_ENTRY_SIZE 8 + +#define GITS_CMDQ_ENTRY_SIZE 32 + /** * Default features advertised by this version of ITS */ diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h index 91491a2f66..1fd5cedbbd 100644 --- a/include/hw/intc/arm_gicv3_common.h +++ b/include/hw/intc/arm_gicv3_common.h @@ -226,6 +226,9 @@ struct GICv3State { int dev_fd; /* kvm device fd if backed by kvm vgic support */ Error *migration_blocker; + MemoryRegion *dma; + AddressSpace dma_as; + /* Distributor */ /* for a GIC with the security extensions the NS banked version of this diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h index 65d1191db1..78b1ba7e6b 100644 --- a/include/hw/intc/arm_gicv3_its_common.h +++ b/include/hw/intc/arm_gicv3_its_common.h @@ -41,6 +41,32 @@ #define GITS_TRANSLATER 0x0040 +typedef struct { + bool valid; + bool indirect; + uint16_t entry_sz; + uint32_t page_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 page_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 GICv3ITSState { SysBusDevice parent_obj; @@ -63,6 +89,10 @@ struct GICv3ITSState { uint64_t creadr; uint64_t baser[8]; + DevTableDesc dt; + CollTableDesc ct; + CmdQDesc cq; + Error *migration_blocker; }; From patchwork Wed Jun 2 18:00: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: 452543 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp792624jao; Wed, 2 Jun 2021 11:03:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw7nHv4pa8TAXMt2Q2C3JpBBrLZnLRjOxbmK6aTR3fX+qXAvNErAjLyQYDXhmylgie7ogFG X-Received: by 2002:a50:ee18:: with SMTP id g24mr10916482eds.11.1622656982924; Wed, 02 Jun 2021 11:03:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622656982; cv=none; d=google.com; s=arc-20160816; b=ZfXafgUuHQbr82hxfTdtJHE0Gc+diVB9qJgjHNoPJaVvxDYfGy37gTevlRI8z84kQ9 yoP6xLG9gnR+opdnbCvV6woi7kID0ZKEBVPAbHyMpQNppkvMDmFu90gBWHIYCCCeH5gv N3asiKbCHud9cxSNltcO00bY1z+erbqqt4oXuTPNTLOzCmtQFz1OOk8EkxwcIV6d3yrv PuXX4gKVOnIzuLO46OEusOKn0QNsla/hTD2A6jdGaelGizYPMfzP7cYNkTPUf2mr3Hus Pk3rX/wQ36K0ycvD5aVzl2Ju4Vl2cPC3G5TpWXFSn5gn2HiEg1xbZF+CZvQOyV67K9TE 0Uzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=C/SlYHFsBbOx8B80G1ZIY7V5qyExe6SSrrZ+O8mGBQ0=; b=lDtuUFi607RTvrtUFFtnYiw21yegQvkoUkj1XfosoCWKZxXYYIXQa2Dz/hgnqRQ2pw 0XD9LgP9HkltzumSkOhalbIMfED0h0eyUKT3o5Xo5toQhEvw8LCt/bBkQbs0unT1LZxS Dck4TE9OatZ0JBxYJpdE+YkFcCvZmVA6UhyAgPDbACaLWg7j7xYjrRnnJAEE/wV9v02i IYc0ev0zjXr//HblUrQ+aoGcWYUINoyFIGuCAA7jyvTkIPTkLMtVTTuVXrXefzGjgIFV 2rTnTOmw/g7SlJEaiiTk6DuB6CAjG5GcJ/5j+la0yLuBefm8RZPO1E82mUKSqiS8urfR 6MPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=CUmUnDw5; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id b23si393419edr.611.2021.06.02.11.03.02 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 02 Jun 2021 11:03:02 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=CUmUnDw5; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:45986 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVCn-0003bD-No for patch@linaro.org; Wed, 02 Jun 2021 14:03:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51122) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1loVAj-00089h-MC for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:53 -0400 Received: from mail-qk1-x729.google.com ([2607:f8b0:4864:20::729]:44781) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1loVAd-0006aQ-GL for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:53 -0400 Received: by mail-qk1-x729.google.com with SMTP id h20so3242851qko.11 for ; Wed, 02 Jun 2021 11:00:47 -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=C/SlYHFsBbOx8B80G1ZIY7V5qyExe6SSrrZ+O8mGBQ0=; b=CUmUnDw5gRcdP+mQYS9CceLNLpIFSAfd8T1KCXj6R2R9EWiuTZXjXIAHUsGxJGWIWU 8adypKYUKuj2Hl7k37chohASwg6+zFq0OEnA1+sFQmhYKX3Qw+yt+5JpAMhbfbNruXIo WS3ZjC0JsTH5rvyCvfMMXm/wAE1fZ79n9iV9DV6HepETy0HA0FRQsYo+7z5KSM9kCD70 OWd/M1MOYUIgeoHURdCUFyBWoSTTcvnJ4uR8NUmYYw9ccmaYMVuuD0TfTE4FWlOicwws jIyzcsAeaYDS11m+rVVSfx2PmvAw+rAv7/WDpXT5QKUmByJadZ2DBPgsy7yISorEG/Mv n3jQ== 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=C/SlYHFsBbOx8B80G1ZIY7V5qyExe6SSrrZ+O8mGBQ0=; b=gsKP/BjiL6T8R4/z0LXR73gqRMEX+7r00OGH9Z875mNLkfNi2aACsCx7Au+Pj3447B hV0ir8B6H/bAMh1XBXEgeMoEy9TrTToaKlE93xFGtUSVijG1TK9jlH9SIhkoS3F01SlB jPR+1Ptajsda+t8s6QTRs1aoqHTzPqO0wWTGUefQLMwLS7ky7HrGF0rm+Qa7fs3LvkNh /WKpviBWX26RCIWGZ50QPhzZ8sCs6cfBLSnI562ViWvtHD4/r2SR53etLmoJEjPpveuW aqwuSUeTTu3T6zORhlRO+9OP4tIuTCuZUpdsLfhTLu5nTO9MMsTtMHl42kg2azLSRHz/ aTSA== X-Gm-Message-State: AOAM532MfKseb5JFlfdrH7EcG5Aq4Ypj7pIVYPMNkMKx4QwCHt63JJ3J wo6BZT9ZH5Shp4yAmekCSy1hxQ== X-Received: by 2002:a37:ac17:: with SMTP id e23mr28975511qkm.184.1622656846655; Wed, 02 Jun 2021 11:00:46 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-21-142-114-142-78.dsl.bell.ca. [142.114.142.78]) by smtp.googlemail.com with ESMTPSA id 97sm273044qte.20.2021.06.02.11.00.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 11:00:46 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v4 3/8] hw/intc: GICv3 ITS command queue framework Date: Wed, 2 Jun 2021 14:00:37 -0400 Message-Id: <20210602180042.111347-4-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602180042.111347-1-shashi.mallela@linaro.org> References: <20210602180042.111347-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::729; envelope-from=shashi.mallela@linaro.org; helo=mail-qk1-x729.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+patch=linaro.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 | 295 +++++++++++++++++++++++++++++++++++++++ hw/intc/gicv3_internal.h | 37 +++++ 2 files changed, 332 insertions(+) -- 2.27.0 Reviewed-by: Peter Maydell diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index af60f19c98..6551c577b3 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -49,6 +49,295 @@ static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz) return result; } +static MemTxResult update_cte(GICv3ITSState *s, uint16_t icid, bool valid, + uint64_t rdbase) +{ + AddressSpace *as = &s->gicv3->dma_as; + uint64_t value; + uint64_t l2t_addr; + bool valid_l2t; + uint32_t l2t_id; + uint32_t max_l2_entries; + uint64_t cte = 0; + MemTxResult res = MEMTX_OK; + + if (!s->ct.valid) { + return res; + } + + if (valid) { + /* add mapping entry to collection table */ + cte = (valid & VALID_MASK) | + ((rdbase & RDBASE_PROCNUM_MASK) << 1ULL); + } + + /* + * The specification defines the format of level 1 entries of a + * 2-level table, but the format of level 2 entries and the format + * of flat-mapped tables is IMPDEF. + */ + if (s->ct.indirect) { + l2t_id = icid / (s->ct.page_sz / L1TABLE_ENTRY_SIZE); + + value = address_space_ldq_le(as, + s->ct.base_addr + + (l2t_id * L1TABLE_ENTRY_SIZE), + MEMTXATTRS_UNSPECIFIED, &res); + + if (res != MEMTX_OK) { + return res; + } + + valid_l2t = (value >> VALID_SHIFT) & VALID_MASK; + + if (valid_l2t) { + max_l2_entries = s->ct.page_sz / s->ct.entry_sz; + + l2t_addr = value & ((1ULL << 51) - 1); + + address_space_stq_le(as, l2t_addr + + ((icid % max_l2_entries) * GITS_CTE_SIZE), + cte, MEMTXATTRS_UNSPECIFIED, &res); + } + } else { + /* Flat level table */ + address_space_stq_le(as, s->ct.base_addr + (icid * GITS_CTE_SIZE), + cte, MEMTXATTRS_UNSPECIFIED, &res); + } + return res; +} + +static MemTxResult process_mapc(GICv3ITSState *s, uint32_t offset) +{ + AddressSpace *as = &s->gicv3->dma_as; + uint16_t icid; + uint64_t rdbase; + bool valid; + MemTxResult res = MEMTX_OK; + uint64_t value; + + offset += NUM_BYTES_IN_DW; + offset += NUM_BYTES_IN_DW; + + value = address_space_ldq_le(as, s->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + + if (res != MEMTX_OK) { + return res; + } + + icid = value & ICID_MASK; + + rdbase = (value >> R_MAPC_RDBASE_SHIFT) & RDBASE_PROCNUM_MASK; + + valid = (value >> VALID_SHIFT) & VALID_MASK; + + if ((icid > s->ct.max_collids) || (rdbase > s->gicv3->num_cpu)) { + qemu_log_mask(LOG_GUEST_ERROR, + "ITS MAPC: invalid collection table attributes " + "icid %d rdbase %lu\n", icid, rdbase); + /* + * in this implementation,in case of error + * we ignore this command and move onto the next + * command in the queue + */ + } else { + res = update_cte(s, icid, valid, rdbase); + } + + return res; +} + +static MemTxResult update_dte(GICv3ITSState *s, uint32_t devid, bool valid, + uint8_t size, uint64_t itt_addr) +{ + AddressSpace *as = &s->gicv3->dma_as; + uint64_t value; + uint64_t l2t_addr; + bool valid_l2t; + uint32_t l2t_id; + uint32_t max_l2_entries; + uint64_t dte = 0; + MemTxResult res = MEMTX_OK; + + if (s->dt.valid) { + if (valid) { + /* add mapping entry to device table */ + dte = (valid & VALID_MASK) | + ((size & SIZE_MASK) << 1U) | + ((itt_addr & ITTADDR_MASK) << 6ULL); + } + } else { + return res; + } + + /* + * The specification defines the format of level 1 entries of a + * 2-level table, but the format of level 2 entries and the format + * of flat-mapped tables is IMPDEF. + */ + if (s->dt.indirect) { + l2t_id = devid / (s->dt.page_sz / L1TABLE_ENTRY_SIZE); + + value = address_space_ldq_le(as, + s->dt.base_addr + + (l2t_id * L1TABLE_ENTRY_SIZE), + MEMTXATTRS_UNSPECIFIED, &res); + + if (res != MEMTX_OK) { + return res; + } + + valid_l2t = (value >> VALID_SHIFT) & VALID_MASK; + + if (valid_l2t) { + max_l2_entries = s->dt.page_sz / s->dt.entry_sz; + + l2t_addr = value & ((1ULL << 51) - 1); + + address_space_stq_le(as, l2t_addr + + ((devid % max_l2_entries) * GITS_DTE_SIZE), + dte, MEMTXATTRS_UNSPECIFIED, &res); + } + } else { + /* Flat level table */ + address_space_stq_le(as, s->dt.base_addr + (devid * GITS_DTE_SIZE), + dte, MEMTXATTRS_UNSPECIFIED, &res); + } + return res; +} + +static MemTxResult process_mapd(GICv3ITSState *s, uint64_t value, + uint32_t offset) +{ + AddressSpace *as = &s->gicv3->dma_as; + uint32_t devid; + uint8_t size; + uint64_t itt_addr; + bool valid; + MemTxResult res = MEMTX_OK; + + devid = (value >> DEVID_SHIFT) & DEVID_MASK; + + offset += NUM_BYTES_IN_DW; + value = address_space_ldq_le(as, s->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + + if (res != MEMTX_OK) { + return res; + } + + size = (value & SIZE_MASK); + + offset += NUM_BYTES_IN_DW; + value = address_space_ldq_le(as, s->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + + if (res != MEMTX_OK) { + return res; + } + + itt_addr = (value >> ITTADDR_SHIFT) & ITTADDR_MASK; + + valid = (value >> VALID_SHIFT) & VALID_MASK; + + if ((devid > s->dt.max_devids) || + (size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS))) { + qemu_log_mask(LOG_GUEST_ERROR, + "ITS MAPD: invalid device table attributes " + "devid %d or size %d\n", devid, size); + /* + * in this implementation, in case of error + * we ignore this command and move onto the next + * command in the queue + */ + } else { + res = update_dte(s, devid, valid, size, itt_addr); + } + + return res; +} + +/* + * Current implementation blocks until all + * commands are processed + */ +static void process_cmdq(GICv3ITSState *s) +{ + uint32_t wr_offset = 0; + uint32_t rd_offset = 0; + uint32_t cq_offset = 0; + uint64_t data; + AddressSpace *as = &s->gicv3->dma_as; + MemTxResult res = MEMTX_OK; + uint8_t cmd; + + if (!(s->ctlr & ITS_CTLR_ENABLED)) { + return; + } + + wr_offset = FIELD_EX64(s->cwriter, GITS_CWRITER, OFFSET); + + if (wr_offset > s->cq.max_entries) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid write offset " + "%d\n", __func__, wr_offset); + return; + } + + rd_offset = FIELD_EX64(s->creadr, GITS_CREADR, OFFSET); + + while (wr_offset != rd_offset) { + cq_offset = (rd_offset * GITS_CMDQ_ENTRY_SIZE); + data = address_space_ldq_le(as, s->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: + /* + * 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. + * Hence no further processing is required for SYNC command. + */ + 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 %= s->cq.max_entries; + s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, OFFSET, rd_offset); + } else { + /* + * in this implementation,in case of dma read/write error + * we stall the command processing + */ + s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, STALLED, 1); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: %x cmd processing failed!!\n", __func__, cmd); + break; + } + } +} + static void extract_table_params(GICv3ITSState *s) { uint16_t num_pages = 0; @@ -226,6 +515,9 @@ static MemTxResult its_writel(GICv3ITSState *s, hwaddr offset, case GITS_CWRITER: s->cwriter = deposit64(s->cwriter, 0, 32, (value & ~R_GITS_CWRITER_RETRY_MASK)); + if (s->cwriter != s->creadr) { + process_cmdq(s); + } break; case GITS_CWRITER + 4: s->cwriter = deposit64(s->cwriter, 32, 32, @@ -346,6 +638,9 @@ static MemTxResult its_writell(GICv3ITSState *s, hwaddr offset, break; case GITS_CWRITER: s->cwriter = value & ~R_GITS_CWRITER_RETRY_MASK; + if (s->cwriter != s->creadr) { + process_cmdq(s); + } break; case GITS_CREADR: case GITS_TYPER: diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h index d6aaa94e4c..0932a30560 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -253,6 +253,9 @@ FIELD(GITS_CBASER, OUTERCACHE, 53, 3) FIELD(GITS_CBASER, INNERCACHE, 59, 3) FIELD(GITS_CBASER, VALID, 63, 1) +FIELD(GITS_CREADR, STALLED, 0, 1) +FIELD(GITS_CREADR, OFFSET, 5, 15) + FIELD(GITS_CWRITER, RETRY, 0, 1) FIELD(GITS_CWRITER, OFFSET, 5, 15) @@ -289,6 +292,40 @@ FIELD(GITS_TYPER, CIL, 36, 1) #define L1TABLE_ENTRY_SIZE 8 #define GITS_CMDQ_ENTRY_SIZE 32 +#define NUM_BYTES_IN_DW 8 + +#define CMD_MASK 0xff + +/* 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 + +/* MAPC command fields */ +#define ICID_LENGTH 16 +#define ICID_MASK ((1U << ICID_LENGTH) - 1) +FIELD(MAPC, RDBASE, 16, 32) + +#define RDBASE_PROCNUM_LENGTH 16 +#define RDBASE_PROCNUM_MASK ((1ULL << RDBASE_PROCNUM_LENGTH) - 1) + +#define DEVID_SHIFT 32 +#define DEVID_LENGTH 32 +#define DEVID_MASK ((1ULL << DEVID_LENGTH) - 1) + +/* MAPD command fields */ +#define ITTADDR_LENGTH 44 +#define ITTADDR_SHIFT 8 +#define ITTADDR_MASK ((1ULL << ITTADDR_LENGTH) - 1) +#define SIZE_MASK 0x1f + +#define VALID_SHIFT 63 +#define VALID_MASK 1ULL /** * Default features advertised by this version of ITS From patchwork Wed Jun 2 18:00: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: 452544 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp794068jao; Wed, 2 Jun 2021 11:04:53 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwpB0wLwVeWCfkvgLfI8/FMKJnzEc7EXc7cvtAQO+2eJ4JvrkoWN5f2EHbgnGQBLbpWe5z3 X-Received: by 2002:aa7:df04:: with SMTP id c4mr9859298edy.147.1622657093412; Wed, 02 Jun 2021 11:04:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622657093; cv=none; d=google.com; s=arc-20160816; b=nPlrvJJ1pTjQIVtRES+lwNzJ1ilyjRuG2G/6bGmZckE9gT3lnFM/f1iQSOyTNLUa98 e0EvMPVjqyEOZDjewcoQFYGWjUvFWjsbvpCBnLb5nZWoYu0c0Z+5j1HNMOcS2LBCzkl3 xPGBRYyL18A/SXNm9fjGBJdop52cuah6AyZRHbt7dbeGLNxrC1I36TIHlUedRi3qcXtq 5PGrkh6TwHCtPd5DuxFoZoXogrzBCGQi2LALwX+r8VC46HVOwfwrHgCiln9OhoT7Ochg rplx+499RSHg4DAwCaNhBdPwmkKze1J7FZD7+YnWL0jo5ca4Ts9mg3cZ4jmWa3eFY6T5 RR9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=vR91bQg6bsOS7D7nYFe5jBbd7zoseWX0x9akFSNuU/w=; b=jjCf8yRMVXxXXK8n5WACnSFJ3cAtuMr/p9LlBjDwvY3bKuwkFHMkfAF/MXhhhhkXxV nqhPvSsbR+YovqH61XWD/tOdM8wrpC+pGEwFsuxdeW7zkLpoJaHh/Sicotg0xhQIf1RY JFNCahX23WxMtyplhBOP96NfEo9d0XFb45g4xIT0ccGGT6HqZUhZEHDgf8FFY89+48CA h3jV6DZIsPm0o4/Pt4X1DmRl6o9FfzYR4YxtDRIGP6sS+egGpMdbGPS+mmA4+R38LPpE QclykmpGLAYrOtuAV7a3ohQC7IVDVrx3+CfF4JlWcmORzauqJtag62w+x66DJNTkXIgi K2RQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=rUUhxqOz; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id i23si397784ejv.640.2021.06.02.11.04.53 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 02 Jun 2021 11:04:53 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=rUUhxqOz; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:50226 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVEa-0006Or-CD for patch@linaro.org; Wed, 02 Jun 2021 14:04:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51148) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1loVAl-0008DM-2U for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:55 -0400 Received: from mail-qt1-x831.google.com ([2607:f8b0:4864:20::831]:37629) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1loVAg-0006b4-KK for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:54 -0400 Received: by mail-qt1-x831.google.com with SMTP id d12so2478960qtq.4 for ; Wed, 02 Jun 2021 11:00:48 -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=vR91bQg6bsOS7D7nYFe5jBbd7zoseWX0x9akFSNuU/w=; b=rUUhxqOzNEmV+LtKUII5mTDg5tIbVWNjh0rgdGQMc8cl0Xt3Uk1R6qut/nJGj3uTfl MmyC5gYkuO3/l/lbaDPtaY+4NJO7fFg3dODa2iiwgQTY+0p8fVx7yWo8FXLRzoYmMCCH 4uwqP8ONE1sXNEmP3p+qIvpVzFqLQAhqu1nJNlZiujyzWgJtkqSTTNYYlWZJoGSG11Pl +nR0kyftx6X+Gx8EuFkZOALLvBV/tycdZ8iKgoCOqm92m/ZUR9YBpTjWDCjOcy6hBDXq eGt0cSEKCefz5lKpE1WK4CerowOb55FONCT2sB0I6LI2LEn4Bndt7Rx2XgcIel9OLomA wV2Q== 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=vR91bQg6bsOS7D7nYFe5jBbd7zoseWX0x9akFSNuU/w=; b=QZL7CprcQ0hweojnpXhKPuqmhz6RSBWXhYWrO7EYJy0fZ5HSJrhcTGXdHF7VDC4vTf yVxZdKaAEqVO+/q3LFYcAY7pliDw6sRjNSswXo3ZE9jKG5/6onlb7Qm6Mcv4zigMypo8 bs0/jsS+pPCqrBP7CrOTtcdHgV4dSWjZv5/DjeECNXV86udaEs2vMIo+W+NuOPgcq4Ak PuNZC7iaCV64nLp+vWeToWGeb2tCXuyth3tDnIGon4MHmeziFVc9G1TPaHv4L/YUL3Ai mX33kmloUcq1uJOs8qy3EWSZJw9+TOVcRRqPfc84kHClqyGIMrYHZ+YcqtpB5UGoLdfH WN0w== X-Gm-Message-State: AOAM532dNZPyV2HiDL7S3Vd5wBgDvmu8WohQLmpMiKMsvIeSlywIiAMP Uz2U+MGXCZ3WNTdrqZuVi1sLGQ== X-Received: by 2002:ac8:6b93:: with SMTP id z19mr25435128qts.61.1622656847584; Wed, 02 Jun 2021 11:00:47 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-21-142-114-142-78.dsl.bell.ca. [142.114.142.78]) by smtp.googlemail.com with ESMTPSA id 97sm273044qte.20.2021.06.02.11.00.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 11:00:47 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v4 4/8] hw/intc: GICv3 ITS Command processing Date: Wed, 2 Jun 2021 14:00:38 -0400 Message-Id: <20210602180042.111347-5-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602180042.111347-1-shashi.mallela@linaro.org> References: <20210602180042.111347-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::831; envelope-from=shashi.mallela@linaro.org; helo=mail-qt1-x831.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+patch=linaro.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 | 334 +++++++++++++++++++++++++++++ hw/intc/gicv3_internal.h | 12 ++ include/hw/intc/arm_gicv3_common.h | 2 + 3 files changed, 348 insertions(+) -- 2.27.0 diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index 6551c577b3..82bb5b84ef 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -28,6 +28,13 @@ struct GICv3ITSClass { void (*parent_reset)(DeviceState *dev); }; +typedef enum ItsCmdType { + NONE = 0, /* internal indication for GITS_TRANSLATER write */ + CLEAR = 1, + DISCARD = 2, + INT = 3, +} ItsCmdType; + static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz) { uint64_t result = 0; @@ -49,6 +56,315 @@ static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz) return result; } +static bool get_cte(GICv3ITSState *s, uint16_t icid, uint64_t *cte, + MemTxResult *res) +{ + AddressSpace *as = &s->gicv3->dma_as; + uint64_t l2t_addr; + uint64_t value; + bool valid_l2t; + uint32_t l2t_id; + uint32_t max_l2_entries; + bool status = false; + + if (s->ct.indirect) { + l2t_id = icid / (s->ct.page_sz / L1TABLE_ENTRY_SIZE); + + value = address_space_ldq_le(as, + s->ct.base_addr + + (l2t_id * L1TABLE_ENTRY_SIZE), + MEMTXATTRS_UNSPECIFIED, res); + + if (*res == MEMTX_OK) { + valid_l2t = (value >> VALID_SHIFT) & VALID_MASK; + + if (valid_l2t) { + max_l2_entries = s->ct.page_sz / s->ct.entry_sz; + + l2t_addr = value & ((1ULL << 51) - 1); + + *cte = address_space_ldq_le(as, l2t_addr + + ((icid % max_l2_entries) * GITS_CTE_SIZE), + MEMTXATTRS_UNSPECIFIED, res); + } + } + } else { + /* Flat level table */ + *cte = address_space_ldq_le(as, s->ct.base_addr + + (icid * GITS_CTE_SIZE), + MEMTXATTRS_UNSPECIFIED, res); + } + + if (*cte & VALID_MASK) { + status = true; + } + + return status; +} + +static MemTxResult update_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte, + uint64_t itel, uint32_t iteh) +{ + AddressSpace *as = &s->gicv3->dma_as; + uint64_t itt_addr; + MemTxResult res = MEMTX_OK; + + itt_addr = (dte >> 6ULL) & ITTADDR_MASK; + itt_addr <<= ITTADDR_SHIFT; /* 256 byte aligned */ + + address_space_stq_le(as, itt_addr + (eventid * sizeof(uint64_t)), + itel, MEMTXATTRS_UNSPECIFIED, &res); + + if (res == MEMTX_OK) { + address_space_stl_le(as, itt_addr + ((eventid + sizeof(uint64_t)) * + sizeof(uint32_t)), iteh, MEMTXATTRS_UNSPECIFIED, + &res); + } + return res; +} + +static bool get_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte, + uint16_t *icid, uint32_t *pIntid, MemTxResult *res) +{ + AddressSpace *as = &s->gicv3->dma_as; + uint64_t itt_addr; + bool status = false; + uint64_t itel = 0; + uint32_t iteh = 0; + + itt_addr = (dte >> 6ULL) & ITTADDR_MASK; + itt_addr <<= ITTADDR_SHIFT; /* 256 byte aligned */ + + itel = address_space_ldq_le(as, itt_addr + (eventid * sizeof(uint64_t)), + MEMTXATTRS_UNSPECIFIED, res); + + if (*res == MEMTX_OK) { + iteh = address_space_ldl_le(as, itt_addr + ((eventid + + sizeof(uint64_t)) * sizeof(uint32_t)), + MEMTXATTRS_UNSPECIFIED, res); + + if (*res == MEMTX_OK) { + if (itel & VALID_MASK) { + if ((itel >> ITE_ENTRY_INTTYPE_SHIFT) & GITS_TYPE_PHYSICAL) { + *pIntid = (itel >> ITE_ENTRY_INTID_SHIFT) & + ITE_ENTRY_INTID_MASK; + *icid = iteh & ITE_ENTRY_ICID_MASK; + status = true; + } + } + } + } + return status; +} + +static uint64_t get_dte(GICv3ITSState *s, uint32_t devid, MemTxResult *res) +{ + AddressSpace *as = &s->gicv3->dma_as; + uint64_t l2t_addr; + uint64_t value; + bool valid_l2t; + uint32_t l2t_id; + uint32_t max_l2_entries; + + if (s->dt.indirect) { + l2t_id = devid / (s->dt.page_sz / L1TABLE_ENTRY_SIZE); + + value = address_space_ldq_le(as, + s->dt.base_addr + + (l2t_id * L1TABLE_ENTRY_SIZE), + MEMTXATTRS_UNSPECIFIED, res); + + if (*res == MEMTX_OK) { + valid_l2t = (value >> VALID_SHIFT) & VALID_MASK; + + if (valid_l2t) { + max_l2_entries = s->dt.page_sz / s->dt.entry_sz; + + l2t_addr = value & ((1ULL << 51) - 1); + + value = address_space_ldq_le(as, l2t_addr + + ((devid % max_l2_entries) * GITS_DTE_SIZE), + MEMTXATTRS_UNSPECIFIED, res); + } + } + } else { + /* Flat level table */ + value = address_space_ldq_le(as, s->dt.base_addr + + (devid * GITS_DTE_SIZE), + MEMTXATTRS_UNSPECIFIED, res); + } + + return value; +} + +static MemTxResult process_int(GICv3ITSState *s, uint64_t value, + uint32_t offset, ItsCmdType cmd) +{ + AddressSpace *as = &s->gicv3->dma_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; + uint64_t itel = 0; + uint32_t iteh = 0; + + if (cmd == NONE) { + devid = offset; + } else { + devid = (value >> DEVID_SHIFT) & DEVID_MASK; + + offset += NUM_BYTES_IN_DW; + value = address_space_ldq_le(as, s->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + } + + if (res != MEMTX_OK) { + return res; + } + + eventid = (value & EVENTID_MASK); + + dte = get_dte(s, devid, &res); + + if (res != MEMTX_OK) { + return res; + } + 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, &res); + + if (res != MEMTX_OK) { + return res; + } + + if (ite_valid) { + cte_valid = get_cte(s, icid, &cte, &res); + } + + if (res != MEMTX_OK) { + return res; + } + } + + if ((devid > s->dt.max_devids) || !dte_valid || !ite_valid || + !cte_valid || (eventid > max_eventid)) { + 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 { + /* + * Current implementation only supports rdbase == procnum + * Hence rdbase physical address is ignored + */ + if (cmd == DISCARD) { + /* remove mapping from interrupt translation table */ + res = update_ite(s, eventid, dte, itel, iteh); + } + } + + return res; +} + +static MemTxResult process_mapti(GICv3ITSState *s, uint64_t value, + uint32_t offset, bool ignore_pInt) +{ + AddressSpace *as = &s->gicv3->dma_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 itel = 0; + uint32_t iteh = 0; + uint32_t int_spurious = INTID_SPURIOUS; + + devid = (value >> DEVID_SHIFT) & DEVID_MASK; + offset += NUM_BYTES_IN_DW; + value = address_space_ldq_le(as, s->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + + if (res != MEMTX_OK) { + return 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, s->cq.base_addr + offset, + MEMTXATTRS_UNSPECIFIED, &res); + + if (res != MEMTX_OK) { + return res; + } + + icid = value & ICID_MASK; + + dte = get_dte(s, devid, &res); + + if (res != MEMTX_OK) { + return res; + } + dte_valid = dte & VALID_MASK; + + max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1)); + + if (!ignore_pInt) { + max_Intid = (1UL << (FIELD_EX64(s->typer, GITS_TYPER, IDBITS) + 1)); + } + + if ((devid > s->dt.max_devids) || (icid > s->ct.max_collids) || + !dte_valid || (eventid > max_eventid) || + (!ignore_pInt && ((pIntid < GICV3_LPI_INTID_START) || + (pIntid > max_Intid)))) { + 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 ite entry to interrupt translation table */ + itel = (dte_valid & VALID_MASK) | (GITS_TYPE_PHYSICAL << + ITE_ENTRY_INTTYPE_SHIFT); + + if (ignore_pInt) { + itel |= (eventid << ITE_ENTRY_INTID_SHIFT); + } else { + itel |= (pIntid << ITE_ENTRY_INTID_SHIFT); + } + itel |= (int_spurious << ITE_ENTRY_INTSP_SHIFT); + iteh |= icid; + + res = update_ite(s, eventid, dte, itel, iteh); + } + + return res; +} + static MemTxResult update_cte(GICv3ITSState *s, uint16_t icid, bool valid, uint64_t rdbase) { @@ -295,8 +611,10 @@ static void 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: /* @@ -313,10 +631,13 @@ static void 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; @@ -472,7 +793,20 @@ static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset, uint64_t data, unsigned size, MemTxAttrs attrs) { + GICv3ITSState *s = (GICv3ITSState *)opaque; MemTxResult result = MEMTX_OK; + uint32_t devid = 0; + + switch (offset) { + case GITS_TRANSLATER: + if (s->ctlr & ITS_CTLR_ENABLED) { + devid = attrs.requester_id; + result = process_int(s, data, devid, NONE); + } + break; + default: + break; + } return result; } diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h index 0932a30560..ce45cd0ef6 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -324,6 +324,13 @@ FIELD(MAPC, RDBASE, 16, 32) #define ITTADDR_MASK ((1ULL << ITTADDR_LENGTH) - 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 1ULL @@ -344,6 +351,11 @@ FIELD(MAPC, RDBASE, 16, 32) * vPEID = 16 bits */ #define ITS_ITT_ENTRY_SIZE 0xC +#define ITE_ENTRY_INTTYPE_SHIFT 1 +#define ITE_ENTRY_INTID_SHIFT 2 +#define ITE_ENTRY_INTID_MASK ((1ULL << 24) - 1) +#define ITE_ENTRY_INTSP_SHIFT 26 +#define ITE_ENTRY_ICID_MASK ((1ULL << 16) - 1) /* 16 bits EventId */ #define ITS_IDBITS GICD_TYPER_IDBITS diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h index 1fd5cedbbd..0715b0bc2a 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 Wed Jun 2 18:00:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 452545 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp795011jao; Wed, 2 Jun 2021 11:06:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJybeeDFXtNclDTUfgQHMYQDfIZjoG6AjvuHo6E+HEsREP0zzEqWNGpXqYUZXloNmaP7tXLX X-Received: by 2002:a05:6638:33a2:: with SMTP id h34mr15862889jav.60.1622657171235; Wed, 02 Jun 2021 11:06:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622657171; cv=none; d=google.com; s=arc-20160816; b=WlO5xPut9tiCi8y5Jf2i09XBFZ3BY/oPQ7lL60SlKhkn1abzMBsW3+BHdHUDOZRYiB 6J93H++ObcvRHJvJK6stkzwQtzEaX11RmPThwdsfw1320JvVHQDM8zRAH0VimvE+PYg7 dawm9qHu9JaIRLlGKGZ69kT5TsZdv4vU2Db0ywRqwkeCXVHHnLq5JnoDJ8yriaga4G/4 wV6AqgEYUstIvbO7gQ+ccAy9riOQ73QdcJLf3cLBYb0w0PJ2/7TomRylSCfsdDPwmdWh 8UVXjDojOo+kzv5W4JJj+WGuWdoof/PJdSU+Y4ZgNJ6hdvPD2Bz8qI6UQhtqPfx9ur7n CZwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=2woulWYT3uxpqpn2RvNQKT7M1BLZsu895mqto08io6A=; b=VBO45qjzkrAJbmdgzR+PV2FVQi2vHKKTa53UUchEl3Z2XQTBwZkyc32SiMHAJQzCdT erYF6y2Ph3dlbSkq4F7uwptPTAt3zLHftHSKpM24mVfGlmJe2gzYi56HWEbE3W7aNJ16 ZjE9nS2lIQSF/o+XBunKTdRoB2WgE79v+Wkw3jad2AKYWv1a/TsIfuTi+gdzzTyltwht Bi0ivn++oZy4hzBYnxbxYj8gu+J7KH6fwNLj9Xlm44HWB4nnNIwDOR/PdX1mxEGVfzpR 0Mux7nlYtaD+3WWtYqJfmlrV6w8CBuDJJH23T75aDJijFSjMhBphMY3B5z+AvRiZH75a a6hQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iSyDZHHA; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id q1si317000jat.103.2021.06.02.11.06.11 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 02 Jun 2021 11:06:11 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iSyDZHHA; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:55612 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVFq-0001a7-N1 for patch@linaro.org; Wed, 02 Jun 2021 14:06:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51176) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1loVAm-0008JH-QR for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:56 -0400 Received: from mail-qt1-x82c.google.com ([2607:f8b0:4864:20::82c]:35448) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1loVAg-0006bD-LS for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:56 -0400 Received: by mail-qt1-x82c.google.com with SMTP id k19so2490907qta.2 for ; Wed, 02 Jun 2021 11:00:49 -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=2woulWYT3uxpqpn2RvNQKT7M1BLZsu895mqto08io6A=; b=iSyDZHHAYPQybL0QqU9eNxqujJ6n6kbB8aKa9ITV7Jw8DndD3RRJVSoKfvm9TiV/AE sY36r/uk52zn3YRyFzPENImX/jlSL6npcb2jD3gxdGIo4QRvglrEHX8UQ0YDgXKrAn39 pj9oBL/BJsKs52036f3QDlPGiJ/D0/Lk2bXuI80d/8GNgWLnwGLlgo8bB3LrtPfXSmTE 6pFu0/VI5ES8x7zDtF5YEIio6NzhtbJ+DrJAXSIGnqcO42yjP/CGm2U1GybhUbF+gFx6 QjkiBd8pYJfGmJj9qRsDE+mRuAW67cpPFTCUBUx0xMG4VxdAD2WvGrK3dOXEDLdH6Vcp HfeQ== 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=2woulWYT3uxpqpn2RvNQKT7M1BLZsu895mqto08io6A=; b=UIyokApc3fb1TJlHkiZx1P+rzsjg6YNCSujmVR9yyNieU91XL4OZzvlmhFXMJOa5wV LZ2OJwjOC+lToh1yr1kDi0Np6/QMZBwn4D5BKNPAgd2c50satlx+qInVmaccw5fwXwuL lAzEjUbyOCrjcBdGM85tO/ouDkQ4Q2VagBXrQ2HuW3A/YuGxuZWMLOwv24YmFdJn+yjV pJaVYF1yfIrNvaxdClLGhQu1L7276BdJjENoxCq2onqrnfsxdzo+4pvx4nfbv1bHdSrS agUilvK67aQiXXl2jQ9bPlAVoXmNJ5S9Z2qFxbjUU6OZpODIUbKUKxfK17rk7Xf88vBC uAMg== X-Gm-Message-State: AOAM533YQa0eg8QPt69GcXrH8j7sLqm2xsWrQQ1C+QkvFh37qOPI01CI j/VU3h2at5N2V6vFqAbpvwwp2Q== X-Received: by 2002:aed:210f:: with SMTP id 15mr25937223qtc.149.1622656848515; Wed, 02 Jun 2021 11:00:48 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-21-142-114-142-78.dsl.bell.ca. [142.114.142.78]) by smtp.googlemail.com with ESMTPSA id 97sm273044qte.20.2021.06.02.11.00.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 11:00:48 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v4 5/8] hw/intc: GICv3 ITS Feature enablement Date: Wed, 2 Jun 2021 14:00:39 -0400 Message-Id: <20210602180042.111347-6-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602180042.111347-1-shashi.mallela@linaro.org> References: <20210602180042.111347-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::82c; envelope-from=shashi.mallela@linaro.org; helo=mail-qt1-x82c.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+patch=linaro.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 | 12 ++++++++++++ hw/intc/arm_gicv3_dist.c | 7 +++++-- hw/intc/arm_gicv3_its.c | 9 ++++++++- hw/intc/arm_gicv3_redist.c | 14 +++++++++++--- hw/intc/gicv3_internal.h | 17 +++++++++++++++++ include/hw/intc/arm_gicv3_common.h | 1 + 6 files changed, 54 insertions(+), 6 deletions(-) -- 2.27.0 diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index 58ef65f589..53dea2a775 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -345,6 +345,11 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) return; } + if (s->lpi_enable && !s->dma) { + error_setg(errp, "Redist-ITS: Guest 'sysmem' reference link not set"); + return; + } + s->cpu = g_new0(GICv3CPUState, s->num_cpu); for (i = 0; i < s->num_cpu; i++) { @@ -381,6 +386,10 @@ 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; + } } } @@ -494,9 +503,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, dma, 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..7e57654061 100644 --- a/hw/intc/arm_gicv3_dist.c +++ b/hw/intc/arm_gicv3_dist.c @@ -371,7 +371,9 @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset, * 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 @@ -386,7 +388,8 @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset, bool sec_extn = !(s->gicd_ctlr & GICD_CTLR_DS); *data = (1 << 25) | (1 << 24) | (sec_extn << 10) | - (0xf << 19) | itlinesnumber; + (s->lpi_enable << GICD_TYPER_LPIS_OFFSET) | + (GICD_TYPER_IDBITS << GICD_TYPER_IDBITS_OFFSET) | itlinesnumber; return MEMTX_OK; } case GICD_IIDR: diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index 82bb5b84ef..0a978cf55b 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -294,6 +294,7 @@ static MemTxResult process_mapti(GICv3ITSState *s, uint64_t value, uint64_t itel = 0; uint32_t iteh = 0; uint32_t int_spurious = INTID_SPURIOUS; + uint64_t idbits; devid = (value >> DEVID_SHIFT) & DEVID_MASK; offset += NUM_BYTES_IN_DW; @@ -330,7 +331,13 @@ static MemTxResult process_mapti(GICv3ITSState *s, uint64_t value, max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1)); if (!ignore_pInt) { - max_Intid = (1UL << (FIELD_EX64(s->typer, GITS_TYPER, IDBITS) + 1)); + idbits = MIN(FIELD_EX64(s->gicv3->cpu->gicr_propbaser, GICR_PROPBASER, + IDBITS), GICD_TYPER_IDBITS); + + if (idbits < GICR_PROPBASER_IDBITS_THRESHOLD) { + return res; + } + max_Intid = (1ULL << (idbits + 1)); } if ((devid > s->dt.max_devids) || (icid > s->ct.max_collids) || diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c index 8645220d61..fb9a4ee3cc 100644 --- a/hw/intc/arm_gicv3_redist.c +++ b/hw/intc/arm_gicv3_redist.c @@ -244,14 +244,21 @@ static MemTxResult gicr_readl(GICv3CPUState *cs, hwaddr offset, static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset, uint64_t value, MemTxAttrs attrs) { + switch (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 */ @@ -395,6 +402,7 @@ static MemTxResult gicr_readll(GICv3CPUState *cs, hwaddr offset, static MemTxResult gicr_writell(GICv3CPUState *cs, hwaddr offset, uint64_t value, MemTxAttrs attrs) { + switch (offset) { case GICR_PROPBASER: cs->gicr_propbaser = value; diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h index ce45cd0ef6..91dbe01176 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -68,6 +68,9 @@ #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 @@ -126,6 +129,20 @@ #define GICR_WAKER_ProcessorSleep (1U << 1) #define GICR_WAKER_ChildrenAsleep (1U << 2) +FIELD(GICR_PROPBASER, IDBITS, 0, 5) +FIELD(GICR_PROPBASER, INNERCACHE, 7, 3) +FIELD(GICR_PROPBASER, SHAREABILITY, 10, 2) +FIELD(GICR_PROPBASER, PHYADDR, 12, 40) +FIELD(GICR_PROPBASER, OUTERCACHE, 56, 3) + +#define GICR_PROPBASER_IDBITS_THRESHOLD 0xd + +FIELD(GICR_PENDBASER, INNERCACHE, 7, 3) +FIELD(GICR_PENDBASER, SHAREABILITY, 10, 2) +FIELD(GICR_PENDBASER, PHYADDR, 16, 36) +FIELD(GICR_PENDBASER, OUTERCACHE, 56, 3) +FIELD(GICR_PENDBASER, PTZ, 62, 1) + #define ICC_CTLR_EL1_CBPR (1U << 0) #define ICC_CTLR_EL1_EOIMODE (1U << 1) #define ICC_CTLR_EL1_PMHE (1U << 6) diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h index 0715b0bc2a..c1348cc60a 100644 --- a/include/hw/intc/arm_gicv3_common.h +++ b/include/hw/intc/arm_gicv3_common.h @@ -221,6 +221,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 Wed Jun 2 18:00:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 452546 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp795362jao; Wed, 2 Jun 2021 11:06:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyf840HeJ1bRhyw2LRECy+WecRt6nhAxR3e0gpTfoLnwk+4/fI1/SzOU0JFDD9CpZlQEGR4 X-Received: by 2002:a05:6402:158e:: with SMTP id c14mr26112206edv.128.1622657201605; Wed, 02 Jun 2021 11:06:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622657201; cv=none; d=google.com; s=arc-20160816; b=BwL8CtZ510OYMSVhtB8hgPK6mGuemk1F8CTR3Kj21m8Y1O1RVt37ycONEheSzRte2J FMRPtVSGGDDOtpENCzXTefFpiJsp42s9AnZZybce1sioN1LYF/0H9j5ZJYku9+L7HX35 KBu9BlmAORz/+PtRr37NaQGTK/qh3N8nUHGba4gSHKH29Ir5Ux73Vlx5nANyWZGV4e46 DyQo6K3Syha3ydQps5TbzONKrryVgcaKN7UzE6Cauguamw7CGriaqfypWUxe0cYyiFCW QZCdezFzLNC2hNQ5sfoT60vf6bOUgHJEHvDspfEGgTHYEPd37d+yFeGRuy/KKqflqC8J F83g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=nV/2og5iNjTvxv5IHohDCBjlVZlJDUJklrLG5YzbJuU=; b=wyBeT474rWbO1xYMOPD0S1LK56oknfKTYmencY6DQzBWaPuuGBVVM2SJn8lGnGURyp LBncTLzJMwJrdAdVHeDqjDpYCa8J9JaneowpPS9r8jLVK3D70Stt7Yf3Alc3yeyP441g 4aleHzyOAwBCVJ+3uk6RQ3iPDZbyj4FpeaP75GzSt/xhD5J8pHfiV5oyfrX0mOWypimU ldGlHNrbA7PA6w/+w4PTBi2Ye/2YV4608D3RYag+LAWYEYW1g/bbFEnu10EBWwjInr2m 5cDp8ltwT1b+RVu/OaIm5aHQAk1ZRNzBCjuI0DRj3ed2XemVv8Q1SdE0hBTa+wP2Zgm4 8Q2Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="iTCr/KLc"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id w19si454393edc.370.2021.06.02.11.06.41 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 02 Jun 2021 11:06:41 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="iTCr/KLc"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:57744 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVGK-00034n-JS for patch@linaro.org; Wed, 02 Jun 2021 14:06:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51220) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1loVAo-0008NX-8K for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:58 -0400 Received: from mail-qk1-x72c.google.com ([2607:f8b0:4864:20::72c]:38545) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1loVAg-0006bS-Lz for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:57 -0400 Received: by mail-qk1-x72c.google.com with SMTP id q10so3279220qkc.5 for ; Wed, 02 Jun 2021 11:00:49 -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=nV/2og5iNjTvxv5IHohDCBjlVZlJDUJklrLG5YzbJuU=; b=iTCr/KLckxrfQDVkBWZTOGxLVmqPwr0bQ66iE/PyyK9NCd6mjoQKfulfw0EHycycLl IvurFuiVid8rLDcKIRGVqHRYZYO6qXMHWXWx8APT4pSstAO8ZT7tktpP5K/+2JnHuT4R pbx3aPr1Gr/dsMAUCTU6lUx9EVEENNA6a3CkFcf+NsvmGP+n1WtBqVg2H1R1pUMpH4V9 umhMTseuROkXCgdITardAb2yG0qTyYX0WnxRxZ+CHlXY6+4FPMdzYGv2k4yTyy9S8D5u GP2cMAzVJE3Foiaon5kqnc3rKIAnTifw71CIMNBpIW2NAgEeyWR3KwIzoxMmSfJhDiA4 72Bg== 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=nV/2og5iNjTvxv5IHohDCBjlVZlJDUJklrLG5YzbJuU=; b=JmF2yxj4AbRiNfteCtwSPyw85fW2Y30K+jjyREbB14+7iLcOsCllAIvgEnSNaZMLgA jJzwmGi81HWfFTdF1hJ2bQhPUZbOJbDPppGYj0XjM/7oe0krSyUsPDfTNJKMDIh8Tjr5 ek+OEwo2LcFXoWtbZIUeJcw/GjqJs7HKYblCinCQsZyw/bYgjoEhuIuCre8tiuMFgcLI kJs1yhOe+PwGpGQM1Vl5KgeaQYUP6r2WivlR7OVeeB6tuFBU1Z8QeiSuwRAHVrDqKNiD KYUQuAm/xL5627tg9G3RYusC+37YnQ0npU4PRpb5A+zyhioRc3WKUNbbfuo8IIqLDA// 4e+A== X-Gm-Message-State: AOAM530IIIG3KyWVDrOzR1ARd353WErHiG2rtb8ogbkgjZYJyxMt6TBy AVSJmlvspUZi+y4O8ZpfWNy4lOxxB4GZmg== X-Received: by 2002:a05:620a:127b:: with SMTP id b27mr27836959qkl.104.1622656849297; Wed, 02 Jun 2021 11:00:49 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-21-142-114-142-78.dsl.bell.ca. [142.114.142.78]) by smtp.googlemail.com with ESMTPSA id 97sm273044qte.20.2021.06.02.11.00.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 11:00:48 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v4 6/8] hw/intc: GICv3 redistributor ITS processing Date: Wed, 2 Jun 2021 14:00:40 -0400 Message-Id: <20210602180042.111347-7-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602180042.111347-1-shashi.mallela@linaro.org> References: <20210602180042.111347-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::72c; envelope-from=shashi.mallela@linaro.org; helo=mail-qk1-x72c.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+patch=linaro.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 | 9 ++ hw/intc/arm_gicv3_common.c | 1 + hw/intc/arm_gicv3_cpuif.c | 7 +- hw/intc/arm_gicv3_its.c | 14 ++- hw/intc/arm_gicv3_redist.c | 145 +++++++++++++++++++++++++++++ hw/intc/gicv3_internal.h | 10 ++ include/hw/intc/arm_gicv3_common.h | 10 ++ 7 files changed, 190 insertions(+), 6 deletions(-) -- 2.27.0 diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c index d63f8af604..4d19190b9c 100644 --- a/hw/intc/arm_gicv3.c +++ b/hw/intc/arm_gicv3.c @@ -165,6 +165,15 @@ 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 && cs->lpivalid) { + if (irqbetter(cs, cs->hpplpi.irq, cs->hpplpi.prio)) { + cs->hppi.irq = cs->hpplpi.irq; + cs->hppi.prio = cs->hpplpi.prio; + cs->hppi.grp = cs->hpplpi.grp; + 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_common.c b/hw/intc/arm_gicv3_common.c index 53dea2a775..223db16fec 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -435,6 +435,7 @@ static void arm_gicv3_common_reset(DeviceState *dev) memset(cs->gicr_ipriorityr, 0, sizeof(cs->gicr_ipriorityr)); cs->hppi.prio = 0xff; + cs->hpplpi.prio = 0xff; /* State in the CPU interface must *not* be reset here, because it * is part of the CPU's reset domain, not the GIC device's. diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c index 81f94c7f4a..5be3efaa3f 100644 --- a/hw/intc/arm_gicv3_cpuif.c +++ b/hw/intc/arm_gicv3_cpuif.c @@ -898,10 +898,12 @@ static void icc_activate_irq(GICv3CPUState *cs, int irq) cs->gicr_iactiver0 = deposit32(cs->gicr_iactiver0, irq, 1, 1); cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 0); gicv3_redist_update(cs); - } else { + } else if (irq < GICV3_LPI_INTID_START) { gicv3_gicd_active_set(cs->gic, irq); gicv3_gicd_pending_clear(cs->gic, irq); gicv3_update(cs->gic, irq, 1); + } else { + gicv3_redist_lpi_pending(cs, irq, 0); } } @@ -1317,7 +1319,8 @@ static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri, trace_gicv3_icc_eoir_write(is_eoir0 ? 0 : 1, gicv3_redist_affid(cs), value); - if (irq >= cs->gic->num_irq) { + if ((irq >= cs->gic->num_irq) && (!(cs->gic->lpi_enable && + (irq >= GICV3_LPI_INTID_START)))) { /* This handles two cases: * 1. If software writes the ID of a spurious interrupt [ie 1020-1023] * to the GICC_EOIR, the GIC ignores that write. diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index 0a978cf55b..e0fbd4041f 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -211,6 +211,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; uint64_t itel = 0; uint32_t iteh = 0; @@ -267,10 +268,15 @@ static MemTxResult process_int(GICv3ITSState *s, uint64_t value, * command in the queue */ } else { - /* - * Current implementation only supports rdbase == procnum - * Hence rdbase physical address is ignored - */ + rdbase = (cte >> 1U) & RDBASE_PROCNUM_MASK; + assert(rdbase <= s->gicv3->num_cpu); + + 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 */ res = update_ite(s, eventid, dte, itel, iteh); diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c index fb9a4ee3cc..bfc6e4e9b9 100644 --- a/hw/intc/arm_gicv3_redist.c +++ b/hw/intc/arm_gicv3_redist.c @@ -255,6 +255,11 @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset, if (cs->gicr_typer & GICR_TYPER_PLPIS) { if (value & GICR_CTLR_ENABLE_LPIS) { cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS; + /* Check for any pending interr in pending table */ + cs->lpivalid = false; + cs->hpplpi.prio = 0xff; + gicv3_redist_update_lpi(cs); + gicv3_redist_update(cs); } else { cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS; } @@ -534,6 +539,146 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data, return r; } +void gicv3_redist_update_lpi(GICv3CPUState *cs) +{ + /* + * This function scans the LPI pending table and for each pending + * LPI, reads the corresponding entry from LPI configuration table + * to extract the priority info and determine if the LPI priority + * is lower than the current high priority interrupt.If yes, update + * high priority pending interrupt to that of LPI. + */ + AddressSpace *as = &cs->gic->dma_as; + uint64_t lpict_baddr, lpipt_baddr; + uint32_t pendt_size = 0; + uint8_t lpite; + uint8_t prio, pend; + int i; + uint64_t idbits; + + idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS), + GICD_TYPER_IDBITS); + + if ((!cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser || + !cs->gicr_pendbaser || (idbits < GICR_PROPBASER_IDBITS_THRESHOLD)) { + return; + } + + lpict_baddr = cs->gicr_propbaser & R_GICR_PROPBASER_PHYADDR_MASK; + + lpipt_baddr = cs->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK; + + /* Determine the highest priority pending interrupt among LPIs */ + pendt_size = (1ULL << (idbits + 1)); + + for (i = 0; i < pendt_size / 8; 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)); + + if (!(lpite & LPI_CTE_ENABLED)) { + continue; + } + + if (cs->gic->gicd_ctlr & GICD_CTLR_DS) { + prio = lpite & LPI_PRIORITY_MASK; + } else { + prio = lpite & LPI_SPRIORITY_MASK; + } + + if (prio <= cs->hpplpi.prio) { + cs->hpplpi.irq = GICV3_LPI_INTID_START + i; + cs->hpplpi.prio = prio; + /* LPIs are always non-secure Grp1 interrupts */ + cs->hpplpi.grp = GICV3_G1NS; + cs->lpivalid = true; + } + } + } +} + +void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level) +{ + AddressSpace *as = &cs->gic->dma_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 & R_GICR_PENDBASER_PHYADDR_MASK; + + 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)); + } + } + cs->lpivalid = false; + cs->hpplpi.prio = 0xff; + gicv3_redist_update_lpi(cs); +} + +void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level) +{ + AddressSpace *as = &cs->gic->dma_as; + uint64_t lpict_baddr; + uint8_t lpite; + uint64_t idbits; + + idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS), + GICD_TYPER_IDBITS); + + if ((!cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser || + !cs->gicr_pendbaser || (idbits < GICR_PROPBASER_IDBITS_THRESHOLD) || + (irq > (1ULL << (idbits + 1)))) { + return; + } + + lpict_baddr = cs->gicr_propbaser & R_GICR_PROPBASER_PHYADDR_MASK; + + /* 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 91dbe01176..bcbccba573 100644 --- a/hw/intc/gicv3_internal.h +++ b/hw/intc/gicv3_internal.h @@ -308,6 +308,13 @@ FIELD(GITS_TYPER, CIL, 36, 1) #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 +#define LPI_SPRIORITY_MASK 0x7e + #define GITS_CMDQ_ENTRY_SIZE 32 #define NUM_BYTES_IN_DW 8 @@ -452,6 +459,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); +void 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); diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h index c1348cc60a..5d839da9c9 100644 --- a/include/hw/intc/arm_gicv3_common.h +++ b/include/hw/intc/arm_gicv3_common.h @@ -204,6 +204,16 @@ struct GICv3CPUState { * real state above; it doesn't need to be migrated. */ PendingIrq hppi; + + /* + * Current highest priority pending lpi for this CPU. + * This is cached information that can be recalculated from the + * real state above; it doesn't need to be migrated. + */ + PendingIrq hpplpi; + + bool lpivalid; /* current highest priority lpi validity status */ + /* This is temporary working state, to avoid a malloc in gicv3_update() */ bool seenbetter; }; From patchwork Wed Jun 2 18:00:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 452547 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp796108jao; Wed, 2 Jun 2021 11:07:37 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxRRtb8wdELATU3mYwEeoXNc+FwbmfXumdHpt9kzvXc0/4lHCxuAaS8+nJz0UHaWKpdMr0G X-Received: by 2002:a50:d54c:: with SMTP id f12mr39464952edj.301.1622657256949; Wed, 02 Jun 2021 11:07:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622657256; cv=none; d=google.com; s=arc-20160816; b=hbWAvCCJb3cWair4xOmIENc6AcXDnZfX1Nkoun4sER+xwkxKKTqKGqCfcrA+1QXzy5 IWcpnp1bBi7RDX2WQmBRNZpvE+rrJwhoxVBRrNeCxtkBTZMooilKq9zofpERrMchluA2 889h4QQfcV0jPdMuMW0/P51vECHO86S4uvsHAUUhyxQEmhCzOpHwOoIW53+1Gih2VeUG sYeGwqMgdyvKBA8KjmqbEH1zlZ18k0TIN1m94qEXZLhXzGCZr/Y6XsNP22ProA8plJbM RoOgmjCLrwfvA3/1ol1dM1WJWa2GaUVyQmedlVCfQQgTDAkQy4a7VVTBe8LeMGlmoOwR 9meA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=U0or+meyzS1O1E+bq0AooMFJPTAGgN/3BFQxbM2exMk=; b=RIFC6FgiaEZc1ZiWi9qTMEU8K0+RXSUK78ywnTWoFGMEzvQCSU2Jg8iaE+c2VXz9lc 4D9NSvU4Q3L3kZk7HOvx1a4YD7jYR6hvET2BcurEuD3zmUFyw4IcbSRPDOrOSPaPVbMR o5y0pJnzGfsY3jZoTeAqitdJyG5VVaDKGBKG1lKAVlTHyvFNHpySOSpDAdOc/u1u4DTG y52vcb1IZrQRUZ+RJe7iVLZHex8okbOpjjtx65V/acPxHWx5zax8gXYHt2dszv/AReo0 P/My6D/xJMs8zQMHDOg6MvYOBjA+r756VyF/a/741nRZ2yZ9DDkPBAktqIej4ggID31X SSxg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=twgJr7n4; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id s6si485201edx.64.2021.06.02.11.07.36 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 02 Jun 2021 11:07:36 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=twgJr7n4; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:60420 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVHE-0004rT-1R for patch@linaro.org; Wed, 02 Jun 2021 14:07:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51232) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1loVAo-0008Pm-Uf for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:58 -0400 Received: from mail-qt1-x833.google.com ([2607:f8b0:4864:20::833]:47037) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1loVAh-0006dD-Mj for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:00:58 -0400 Received: by mail-qt1-x833.google.com with SMTP id m13so2434322qtk.13 for ; Wed, 02 Jun 2021 11:00:51 -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=U0or+meyzS1O1E+bq0AooMFJPTAGgN/3BFQxbM2exMk=; b=twgJr7n4SxsBbnj3r//3N+ZpRABN7Td7f1+zRbGLuMCvFzqrcbaI3RLXSmllzLNVzZ 3XjtzzhjkwY+Swh/W0DLGueV+mbjVRHc5tcI8E/0+VfhZNhFlZjUMnJH2t2Y7T+m23Q1 GUDolFHsOl+aUFJw/RPrxgqV7FMWxiHER5dUV8SVJ3b2nRgh1qI55VqLqOikGB8nVPNe pLDf5c4lFNhMBVxNoMKPZMH2Y4A3pO1AA8c12CdGr46myx4ijEau7AgWeFwcHnulNO3q zGy+FgH/97vExr+D2fPM7quatmJHA29ULvMYh42/HPJhK5SO+/3xy1RkBopHF5I45OeB q4sw== 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=U0or+meyzS1O1E+bq0AooMFJPTAGgN/3BFQxbM2exMk=; b=XAT8GNfl+byy9nHpUyNdh/xl5kIdHvyRDDDVTiwvr+V5LAOy+vYBRi/RRFckDELPKp vBD8cVDgh7X3/NUqTQ2OwgomP9xyIROCjZ07cVNzjMSDQxd+HDvd5gzMdXT/7NB6zdZ7 G1oIkzvljhwpeKqgaS3/yyCIRhF40ktCxlfaBmgDiVGlSe4LWLjr+hxgzsDvGqZQbbmx CeR98qvU9ypf0v3BGneOSC/BLzQiikmOr6u8cS1QG5HZHhbG4zSAWmQH5SSoTtgLn4xJ KB64gcxziekFQrvpWPCd5islHjXBA/E6lOPmz+rj7vEGhT6O5RJbfcDqfucPD3ALWXwK x02g== X-Gm-Message-State: AOAM533sTWnFF1pRooGsYhk/b1gMYOEpSkx52xlZFOPWVvCd5blPFPWT P65RbVmI5wfEgvbHwJqBa9ipGA== X-Received: by 2002:ac8:7d14:: with SMTP id g20mr25447809qtb.298.1622656850739; Wed, 02 Jun 2021 11:00:50 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-21-142-114-142-78.dsl.bell.ca. [142.114.142.78]) by smtp.googlemail.com with ESMTPSA id 97sm273044qte.20.2021.06.02.11.00.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 11:00:49 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v4 7/8] hw/arm/sbsa-ref: add ITS support in SBSA GIC Date: Wed, 2 Jun 2021 14:00:41 -0400 Message-Id: <20210602180042.111347-8-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602180042.111347-1-shashi.mallela@linaro.org> References: <20210602180042.111347-1-shashi.mallela@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::833; envelope-from=shashi.mallela@linaro.org; helo=mail-qt1-x833.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+patch=linaro.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(-) -- 2.27.0 Reviewed-by: Leif Lindholm diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index 43c19b4923..3d9c073636 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -34,7 +34,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" @@ -64,6 +64,7 @@ enum { SBSA_CPUPERIPHS, SBSA_GIC_DIST, SBSA_GIC_REDIST, + SBSA_GIC_ITS, SBSA_SECURE_EC, SBSA_GWDT, SBSA_GWDT_REFRESH, @@ -107,6 +108,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 }, @@ -377,7 +379,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; @@ -404,6 +419,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); @@ -450,6 +469,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, @@ -762,7 +782,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 Wed Jun 2 18:00:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shashi Mallela X-Patchwork-Id: 452548 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp797651jao; Wed, 2 Jun 2021 11:09:40 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwY0940/xX6vm6aazqkz6T6eU5H8cLquMk/QHqKsIdVZfWP4egm5McTi+8nYmOWR3RehhoL X-Received: by 2002:a1f:1cc6:: with SMTP id c189mr5296100vkc.21.1622657380134; Wed, 02 Jun 2021 11:09:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622657380; cv=none; d=google.com; s=arc-20160816; b=mfcXN/d7HB9OeU06vYhsvbxL2dqK+gOxkQKG+VSvjpIW4d45hdOhMaFXiL7UOG5KC2 QSZ50gq2jAWczUipdBL/k2pJvs6eLFmfPqhAx46XLktxsyLsvLPWGJJ/2e3kqf75wH1e XqmsrktSMc1YxC7gMQzRs70ZdBkIsmybAUAErTZNOmaO3KoUCtVgpl/U7RtymvE2X0zV xkFjafjt61vIU0N5rShH5ariFxoBBsEW2DKWMTC5ncHJ9NAhdKR5g3bqO7G+N2YzUHaG 4gAecaqEMtZW4AXQNFsSaDehbQc66htdOYGqpBp41UQI+JXyW93Acqr6OjEeG/36sgG7 MOSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=2vrWwFy10Zdnfu5WX/uUYQ0OSYmANPgzkaZTtR8NbMU=; b=zz/FzgLomK7KiCW/EHodS04jTG2izXjb9B9eYE5QHPcwy/G258h5pG5PWS0/g6jRy6 7AZvctZIDK3UqFlW1j05RZff8pankHbygAYxK2Hbwzhj+yYg80jMR09HoekuAHBKJ7cZ ORd3wCDvZ49V4+UIVtjAgiaTMiNVifaljg4VSAih+2Vl/y7Ijmauz0MtdSbXlCtBfOll 6NbpKI+f5iVDYpHj1h9hQR4DWXfJevmu5XfjN2X5NB/XtEZesT3a3Y3lYHyEqO96nFAH nWCRjRCaSzgDSCNal6pZAxsz4jn8RgmIYMhdXIgw5cEsuCEfMtF0Efv5vPycyASvpzOR RFtg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=B+IwyyBe; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id s186si698203vkb.65.2021.06.02.11.09.40 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 02 Jun 2021 11:09:40 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=B+IwyyBe; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:36476 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVJD-0007s8-HE for patch@linaro.org; Wed, 02 Jun 2021 14:09:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51258) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1loVAq-0008Uh-Gy for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:01:00 -0400 Received: from mail-qk1-x735.google.com ([2607:f8b0:4864:20::735]:46741) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1loVAi-0006eb-F4 for qemu-devel@nongnu.org; Wed, 02 Jun 2021 14:01:00 -0400 Received: by mail-qk1-x735.google.com with SMTP id 76so3226994qkn.13 for ; Wed, 02 Jun 2021 11:00:52 -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=2vrWwFy10Zdnfu5WX/uUYQ0OSYmANPgzkaZTtR8NbMU=; b=B+IwyyBe366B/Rc/89MONYd7AYRGK+fQkTEG/9Z4EOnViVeM0bkdkLXUx6Vnl2cvQW ho/+ZdcR1ZD8FlcthZXIjzf9gXLOWQWPBDJn/US37tTjYR/89rlbTlMSDyeqUDcMLoX3 MtmfsJ+2QQ5dLVlCCpFE6vXD2vNuJEDXb5UagL3oUqs0s8JMzKejorTMf42EWqM970uG Qsn9pTIMYFsiOLAy8KKuFqB4nFDM7uo21dUV/ZDfHbuCKgF6cWx6Kv2btQdJFu/C9jmb X5/XUpXKtCsuw7B8ep/q/Gs70IszEOV4FLJAHIvjj1cPwyIOYWabUGOaFyARz/Ae9Bu3 8EAQ== 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=2vrWwFy10Zdnfu5WX/uUYQ0OSYmANPgzkaZTtR8NbMU=; b=QGDLFq007Fl/igt4FJz+xJCHBliM/va7cQUCjFbrUzqwEMhtmHspz8KQjMkfQLbsYO 4iu8mK1xEM+q/OhEtScAXFy3sX/kRvYRGZeLOuaePh0YgtW3vuySoM5TTg1zYu0Osy/z nmz/g4q2VgklrUv2Epm4KwCqFQCWG0aphLmoMwB3KOnglASD6CzF3mgQ7R7gnM7QPAXg PBuQSSynOiYZQikWWOAf/DYvlEH3sdtIpWFlNeT3zoIWiOAI4DGEPUYT2KXOM3RKZ+a4 w2Fv+d8g7VbNUjXb6f8fc7czHJX8An2Xp0XZ9F7rbs41VZgafpJM75g2iYSbJAJpKPyP IUrg== X-Gm-Message-State: AOAM53277TxqMBhjdDCHX3t1K8qBm+wBHvdcvoJUfzZZLy5M68b5aJFm yg5fWYJaun22wrtdqtpaf0UOYA== X-Received: by 2002:a05:620a:15f7:: with SMTP id p23mr28147906qkm.178.1622656851679; Wed, 02 Jun 2021 11:00:51 -0700 (PDT) Received: from localhost.localdomain (bras-base-stsvon1503w-grc-21-142-114-142-78.dsl.bell.ca. [142.114.142.78]) by smtp.googlemail.com with ESMTPSA id 97sm273044qte.20.2021.06.02.11.00.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jun 2021 11:00:51 -0700 (PDT) From: Shashi Mallela To: peter.maydell@linaro.org, leif@nuviainc.com, rad@semihalf.com Subject: [PATCH v4 8/8] hw/arm/virt: add ITS support in virt GIC Date: Wed, 2 Jun 2021 14:00:42 -0400 Message-Id: <20210602180042.111347-9-shashi.mallela@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210602180042.111347-1-shashi.mallela@linaro.org> References: <20210602180042.111347-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=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+patch=linaro.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 | 27 +++++++++++++++++++++++++-- include/hw/arm/virt.h | 2 ++ target/arm/kvm_arm.h | 4 ++-- 3 files changed, 29 insertions(+), 4 deletions(-) -- 2.27.0 Reviewed-by: Peter Maydell diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 840758666d..f598f048da 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -583,6 +583,12 @@ static void create_its(VirtMachineState *vms) const char *itsclass = its_class_name(); DeviceState *dev; + if (!strcmp(itsclass, "arm-gicv3-its")) { + if (!vms->tcg_its) { + itsclass = NULL; + } + } + if (!itsclass) { /* Do nothing if not supported */ return; @@ -620,7 +626,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 */ @@ -654,6 +660,14 @@ 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()) { + if (vms->tcg_its) { + 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 +2053,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); @@ -2718,6 +2732,12 @@ static void virt_instance_init(Object *obj) } else { /* Default allows ITS instantiation */ vms->its = true; + + if (vmc->no_tcg_its) { + vms->tcg_its = false; + } else { + vms->tcg_its = true; + } } /* Default disallows iommu instantiation */ @@ -2764,6 +2784,9 @@ DEFINE_VIRT_MACHINE_AS_LATEST(6, 1) static void virt_machine_6_0_options(MachineClass *mc) { + VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); + /* qemu ITS was introduced with 6.1 */ + vmc->no_tcg_its = true; } DEFINE_VIRT_MACHINE(6, 0) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 921416f918..f873ab9068 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -120,6 +120,7 @@ struct VirtMachineClass { MachineClass parent; bool disallow_affinity_adjustment; bool no_its; + bool no_tcg_its; bool no_pmu; bool claim_edge_triggered_timers; bool smbios_old_sys_ver; @@ -141,6 +142,7 @@ struct VirtMachineState { bool highmem; bool highmem_ecam; bool its; + bool tcg_its; bool virt; bool ras; bool mte; 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"; } }