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: 12295483 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1AF23C47083 for ; Wed, 2 Jun 2021 18:02:38 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 791C460FF3 for ; Wed, 2 Jun 2021 18:02:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 791C460FF3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:44356 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVCO-0002Uv-Gh for qemu-devel@archiver.kernel.org; Wed, 02 Jun 2021 14:02:36 -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-Google-Smtp-Source: ABdhPJwHcpm+NyHXmrOYYsGPQkWV0L3QjnBk89G5M73ds04rKDkZI2LkPVOuRU5sIN9kRX6eHEQ7Bw== 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added register definitions relevant to ITS,implemented overall ITS device framework with stubs for ITS control and translater regions read/write,extended ITS common to handle mmio init between existing kvm device and newer qemu device. Signed-off-by: Shashi Mallela Reviewed-by: Peter Maydell --- 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 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: 12295485 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 737C7C4708F for ; Wed, 2 Jun 2021 18:02:39 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D0E4E610A0 for ; Wed, 2 Jun 2021 18:02:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D0E4E610A0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:44504 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVCP-0002bG-UG for qemu-devel@archiver.kernel.org; Wed, 02 Jun 2021 14:02:37 -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-Google-Smtp-Source: ABdhPJwF0mLMYLJRjP55tUxsangWM2Ib62rRgEguapB5djX/xnJbn3XI404iVX9a04thg62do53dUg== 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Defined descriptors for ITS device table,collection table and ITS command queue entities.Implemented register read/write functions, extract ITS table parameters and command queue parameters,extended gicv3 common to capture qemu address space(which host the ITS table platform memories required for subsequent ITS processing) and initialize the same in ITS device. Signed-off-by: Shashi Mallela Reviewed-by: Peter Maydell --- 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(-) 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: 12295487 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60D1CC47083 for ; Wed, 2 Jun 2021 18:04:30 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id ECC1C61361 for ; Wed, 2 Jun 2021 18:04:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org ECC1C61361 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:49990 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVED-0006Fm-29 for qemu-devel@archiver.kernel.org; Wed, 02 Jun 2021 14:04:29 -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-Google-Smtp-Source: ABdhPJzpXT04RjPc2lac1cvUPXnNZX/PahyEsOxwbbh/8xmFAFRjli8QRzIOtgLiSFr3aV1Ky2XldA== 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added functionality to trigger ITS command queue processing on write to CWRITE register and process each command queue entry to identify the command type and handle commands like MAPD,MAPC,SYNC. Signed-off-by: Shashi Mallela Reviewed-by: Peter Maydell --- hw/intc/arm_gicv3_its.c | 295 +++++++++++++++++++++++++++++++++++++++ hw/intc/gicv3_internal.h | 37 +++++ 2 files changed, 332 insertions(+) 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: 12295489 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26C9FC47083 for ; Wed, 2 Jun 2021 18:05:22 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A0C00613D4 for ; Wed, 2 Jun 2021 18:05:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A0C00613D4 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:53688 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVF2-0000Ge-ND for qemu-devel@archiver.kernel.org; Wed, 02 Jun 2021 14:05:20 -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-Google-Smtp-Source: ABdhPJwZhlqOHTiiViEvQbSjHvy7sIpZlUdBoA74r0rGbceIrYs+Nz0CblrJZ+Kb8fl5O5DA4mcB0Q== 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added ITS command queue handling for MAPTI,MAPI commands,handled ITS translation which triggers an LPI via INT command as well as write to GITS_TRANSLATER register,defined enum to differentiate between ITS command interrupt trigger and GITS_TRANSLATER based interrupt trigger. Each of these commands make use of other functionalities implemented to get device table entry,collection table entry or interrupt translation table entry required for their processing. Signed-off-by: Shashi Mallela --- hw/intc/arm_gicv3_its.c | 334 +++++++++++++++++++++++++++++ hw/intc/gicv3_internal.h | 12 ++ include/hw/intc/arm_gicv3_common.h | 2 + 3 files changed, 348 insertions(+) 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: 12295491 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 73081C47083 for ; Wed, 2 Jun 2021 18:06:30 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DC34E610A0 for ; Wed, 2 Jun 2021 18:06:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DC34E610A0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:58122 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVG8-0003Ll-Uq for qemu-devel@archiver.kernel.org; Wed, 02 Jun 2021 14:06:28 -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-Google-Smtp-Source: ABdhPJzGfkezs3Pc1xxjJMmREdPHcz03/w5gvQmJPLawlnPD3i8N/W+Hd/pYKRLprvyOj86dTfx2yA== 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added properties to enable ITS feature and define qemu system address space memory in gicv3 common,setup distributor and redistributor registers to indicate LPI support. Signed-off-by: Shashi Mallela --- hw/intc/arm_gicv3_common.c | 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(-) 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: 12295493 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 73FD9C47083 for ; Wed, 2 Jun 2021 18:06:57 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EB41E61029 for ; Wed, 2 Jun 2021 18:06:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EB41E61029 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:59752 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVGa-0004QL-2z for qemu-devel@archiver.kernel.org; Wed, 02 Jun 2021 14:06:56 -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-Google-Smtp-Source: ABdhPJyANYEMTg+FP2H7HrBSVCX+EjZwMpUCo7A30vzHzEYJf0YVcpUcBD6yNH5J8U4u4w7dPLwX/g== 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Implemented lpi processing at redistributor to get lpi config info from lpi configuration table,determine priority,set pending state in lpi pending table and forward the lpi to cpuif.Added logic to invoke redistributor lpi processing with translated LPI which set/clear LPI from ITS device as part of ITS INT,CLEAR,DISCARD command and GITS_TRANSLATER processing. Signed-off-by: Shashi Mallela --- hw/intc/arm_gicv3.c | 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(-) 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: 12295495 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86EE7C4708F for ; Wed, 2 Jun 2021 18:08:04 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4331061057 for ; Wed, 2 Jun 2021 18:08:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4331061057 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:34166 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVHf-0006CE-7A for qemu-devel@archiver.kernel.org; Wed, 02 Jun 2021 14:08:03 -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-Google-Smtp-Source: ABdhPJxr3XHUG2qm9p8JztLE3m1ZH+wf1opqP6D8YeigKvGNi/dV3iWyh5EJkwa15cLsbO1fjm+hng== 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Included creation of ITS as part of SBSA platform GIC initialization. Signed-off-by: Shashi Mallela Reviewed-by: Leif Lindholm --- hw/arm/sbsa-ref.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index 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: 12295497 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BDF34C47083 for ; Wed, 2 Jun 2021 18:10:31 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1F4B361029 for ; Wed, 2 Jun 2021 18:10:31 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1F4B361029 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:38476 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loVK2-0000oc-56 for qemu-devel@archiver.kernel.org; Wed, 02 Jun 2021 14:10:30 -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-Google-Smtp-Source: ABdhPJwPX59ZaS/z1h/IXEgOqUwpUQvTnPR5kPR5vFB0hwJbM2+KQDTIoN8hql4dRMK/xp6q3NMWcQ== 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Included creation of ITS as part of virt platform GIC initialization.This Emulated ITS model now co-exists with kvm ITS and is enabled in absence of kvm irq kernel support in a platform. Signed-off-by: Shashi Mallela Reviewed-by: Peter Maydell --- hw/arm/virt.c | 27 +++++++++++++++++++++++++-- include/hw/arm/virt.h | 2 ++ target/arm/kvm_arm.h | 4 ++-- 3 files changed, 29 insertions(+), 4 deletions(-) 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"; } }