Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2216918/?format=api
{ "id": 2216918, "url": "http://patchwork.ozlabs.org/api/patches/2216918/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260327111700.795099-6-peter.maydell@linaro.org/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260327111700.795099-6-peter.maydell@linaro.org>", "list_archive_url": null, "date": "2026-03-27T11:16:00", "name": "[v2,05/65] hw/intc/arm_gicv5: Implement skeleton code for IRS register frames", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "32e67fc643959f4cee11ae28ceed054002db3060", "submitter": { "id": 5111, "url": "http://patchwork.ozlabs.org/api/people/5111/?format=api", "name": "Peter Maydell", "email": "peter.maydell@linaro.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260327111700.795099-6-peter.maydell@linaro.org/mbox/", "series": [ { "id": 497750, "url": "http://patchwork.ozlabs.org/api/series/497750/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=497750", "date": "2026-03-27T11:16:25", "name": "arm: Implement an emulation of GICv5 interrupt controller", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/497750/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2216918/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2216918/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256\n header.s=google header.b=ZgqDApvp;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fhywb2w1kz1xy1\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 27 Mar 2026 22:24:47 +1100 (AEDT)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1w65Bi-0006OL-8m; Fri, 27 Mar 2026 07:17:14 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <peter.maydell@linaro.org>)\n id 1w65Bf-0006Mj-4l\n for qemu-devel@nongnu.org; Fri, 27 Mar 2026 07:17:12 -0400", "from mail-wr1-x430.google.com ([2a00:1450:4864:20::430])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <peter.maydell@linaro.org>)\n id 1w65Bc-0007cz-Cl\n for qemu-devel@nongnu.org; Fri, 27 Mar 2026 07:17:10 -0400", "by mail-wr1-x430.google.com with SMTP id\n ffacd0b85a97d-439af7d77f0so1576599f8f.0\n for <qemu-devel@nongnu.org>; Fri, 27 Mar 2026 04:17:07 -0700 (PDT)", "from lanath.. (wildly.archaic.org.uk. [81.2.115.145])\n by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-43b919cf2b2sm15484227f8f.18.2026.03.27.04.17.05\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Fri, 27 Mar 2026 04:17:05 -0700 (PDT)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=linaro.org; s=google; t=1774610227; x=1775215027; darn=nongnu.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=AYuqw3HFZoF9226pvAWhjUsB9lC+vN3nYVgH2xmrsaQ=;\n b=ZgqDApvphhAFANZ/oUZGcy44/Xo/d7Ge5YApUy9OEPXgd46vUmuLUqPHf2dPt9WZug\n Az+vJCbvKPClEjvk7OuS1rNsAx6e8OfCJGJzILSaTDzzPvBmEaxxfbQSTM2PxXR/FaHq\n RT8XY+GwCiqSVvAMqxkVZFx0OCr4K3wPmLznd3YqGrIEWDTlWdIuWMWhmXTlaLtoIngX\n YP9pY8cZwjBFLEr8M1j2Udodn2VKilmFgW+GYmicf+guGR9hm7GvOKXF/arG35Au4nJn\n d8eGqb3Ck0OLPl4n/esNEmuxhUhGLIHpWSmXSpfaJitDCfsWAaWSM9CAzx+IdEy9/K+b\n jaFw==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1774610227; x=1775215027;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=AYuqw3HFZoF9226pvAWhjUsB9lC+vN3nYVgH2xmrsaQ=;\n b=fxsxiP2AD+ppdW3K6P1yrIDLugt2j7qndWkD3jYDUy7VBpCq4ssdgPlgww+6W8UyCl\n B25nVcZ7Pr6t9dd5p2OC3/Ca0PqB809d2MyDL3ub6cTVzb/7N6Rlj9Gr+tj/3HUJq1KN\n w88Zf6Vyvj3M0eD3gukFhitO1KVCeCN4WFsQwdwjdcMZoSHL/C32/aRHAghdGaRl/a3K\n FgaXtWUlyUzL2CUj2ajrJSoMRqsJ++aBmXUzg+EeX57Y7n6xeq3rsHUNV/9qM7mFL5Zj\n nyIn8Gvl6ssKn8W6sp3uq00SFZCXbxytEbbvQvPaL9pQibsVDaS3UOciWguI9AKpYHJg\n mv9g==", "X-Forwarded-Encrypted": "i=1;\n AJvYcCU/KngusHe+3LZSbDtbe8F+zpcWiiba50fWC1SAc/Y45Fepw2FqkM0AdwpfUb/nvVMc+HNUR2kKirid@nongnu.org", "X-Gm-Message-State": "AOJu0Yy2pQoNW3m0FejwIiSo8r4mh0YjKC/GGzvonekOoyZCzdkeGnwY\n GkvLeK8B9w0+r5Ygl6jc/eqL5hwa4+seiJkDwR7jCelTOTdR1K+iH6xTNMHO+soP5J4=", "X-Gm-Gg": "ATEYQzyVWVv4U6hpHwnKRTf8Xp80qeaMlfwM/qdXLAYapk3XMjQV87MgRMEGXdnpug7\n 3Ih15Wbwm2c6/GPvu0Y6Q5EM6f+j/ulOik1z7uFuynAUBxHmMPkBQk4qXjz+QdGyRUQViY87GIa\n objWS/g1GcXDensuphmn7fzI2ZbMwa9PXyYb7jy/hRq9KRW1kyhDrgW9V2E+LaiR5zbVhrDR3rO\n 0xUDwBVXSO0ZEJXXzuDqKEfHfeoUB/FyWs4+mvyRRMvponGXY5aO/lZZJN7LeKiaqzBOZt67yhV\n +PpWxKlvGK7aLETjJf15K0a8xg6ZfACXU5LfTx0Oju99SfcdWuDMInPxyNoi2ekS6lXvItdrx3B\n WbY3MZgokcCoHiYsvK14afDlwIr/U8/0k671zSuCPaRsPKC715J25ySWSDMeYPqaNqCJ69qX+/4\n VQwWMXDvxTsnxQ3F5DyUwjh4jTPvqeIXpjP48gtr7t4u/5V5HPGP+Z3ZD8FrPZXxCEqok7g2rpR\n 6FC3BaiR8Fk1bDEwEol2IYI5YAZYNQ=", "X-Received": "by 2002:a05:6000:310c:b0:43b:4f7d:e085 with SMTP id\n ffacd0b85a97d-43b9e9ee634mr3531010f8f.35.1774610226582;\n Fri, 27 Mar 2026 04:17:06 -0700 (PDT)", "From": "Peter Maydell <peter.maydell@linaro.org>", "To": "qemu-arm@nongnu.org,\n\tqemu-devel@nongnu.org", "Cc": "Jonathan Cameron <jonathan.cameron@huawei.com>", "Subject": "[PATCH v2 05/65] hw/intc/arm_gicv5: Implement skeleton code for IRS\n register frames", "Date": "Fri, 27 Mar 2026 11:16:00 +0000", "Message-ID": "<20260327111700.795099-6-peter.maydell@linaro.org>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<20260327111700.795099-1-peter.maydell@linaro.org>", "References": "<20260327111700.795099-1-peter.maydell@linaro.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Received-SPF": "pass client-ip=2a00:1450:4864:20::430;\n envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x430.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,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n 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.29", "Precedence": "list", "List-Id": "qemu development <qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "The GICv5 IRS has one mandatory register frame (the config frame) for\neach of up to four supported physical interrupt domains. Implement\nthe skeleton of the code needed to create these as sysbus MMIO\nregions.\n\nThe config frame has a mix of 32-bit and 64-bit registers, and it is\nvalid to access the 64-bit registers with 32-bit accesses. In a\nsimilar way to the various GICv3 devices, we turn the MemoryRegionOps\nread_with_attrs and write_with_attrs calls into calls on functions\nspecifically to read 32 or 64 bit values. (We can't trivially\nimplement one in terms of the other because various registers have\nside effects on write which must only trigger when the \"correct\" half\nof the 64-bit register is written to.)\n\nUnlike the GICv3, we choose to expose a sysbus MMIO region for each\ninterrupt domain even if the config of the GICv5 means that it\ndoesn't implement that domain. This avoids having the config frame\nfor a domain ending up at a different MMIO region index depending on\nthe config of the GICv5. (This matters more for GICv5 because it\nsupports Realm, and so there are more possible valid configurations.)\n\ngicv5_common_init_irqs_and_mmio() does not yet create any IRQs, but\nwe name it this way to parallel the equivalent GICv3 function and to\navoid having to rename it when we add the IRQ line creation in a\nsubsequent commit.\n\nThe arm_gicv5_types.h header is a little undermotivated at this\npoint, but the aim is to have somewhere to put definitions that we\nwant in both the GIC proper and the CPU interface.\n\nSigned-off-by: Peter Maydell <peter.maydell@linaro.org>\nReviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>\n---\n hw/intc/arm_gicv5.c | 172 +++++++++++++++++++++++++++++\n hw/intc/arm_gicv5_common.c | 35 ++++++\n hw/intc/trace-events | 6 +\n include/hw/intc/arm_gicv5.h | 1 +\n include/hw/intc/arm_gicv5_common.h | 50 +++++++++\n include/hw/intc/arm_gicv5_types.h | 28 +++++\n 6 files changed, 292 insertions(+)\n create mode 100644 include/hw/intc/arm_gicv5_types.h", "diff": "diff --git a/hw/intc/arm_gicv5.c b/hw/intc/arm_gicv5.c\nindex f9dab710d3..3a9d566924 100644\n--- a/hw/intc/arm_gicv5.c\n+++ b/hw/intc/arm_gicv5.c\n@@ -8,9 +8,157 @@\n \n #include \"qemu/osdep.h\"\n #include \"hw/intc/arm_gicv5.h\"\n+#include \"qapi/error.h\"\n+#include \"qemu/log.h\"\n+#include \"trace.h\"\n \n OBJECT_DEFINE_TYPE(GICv5, gicv5, ARM_GICV5, ARM_GICV5_COMMON)\n \n+static const char *domain_name[] = {\n+ [GICV5_ID_S] = \"Secure\",\n+ [GICV5_ID_NS] = \"NonSecure\",\n+ [GICV5_ID_EL3] = \"EL3\",\n+ [GICV5_ID_REALM] = \"Realm\",\n+};\n+\n+static bool config_readl(GICv5 *s, GICv5Domain domain, hwaddr offset,\n+ uint64_t *data, MemTxAttrs attrs)\n+{\n+ return false;\n+}\n+\n+static bool config_writel(GICv5 *s, GICv5Domain domain, hwaddr offset,\n+ uint64_t data, MemTxAttrs attrs)\n+{\n+ return false;\n+}\n+\n+static bool config_readll(GICv5 *s, GICv5Domain domain, hwaddr offset,\n+ uint64_t *data, MemTxAttrs attrs)\n+{\n+ return false;\n+}\n+\n+static bool config_writell(GICv5 *s, GICv5Domain domain, hwaddr offset,\n+ uint64_t data, MemTxAttrs attrs)\n+{\n+ return false;\n+}\n+\n+static MemTxResult config_read(void *opaque, GICv5Domain domain, hwaddr offset,\n+ uint64_t *data, unsigned size,\n+ MemTxAttrs attrs)\n+{\n+ GICv5 *s = ARM_GICV5(opaque);\n+ bool result;\n+\n+ switch (size) {\n+ case 4:\n+ result = config_readl(s, domain, offset, data, attrs);\n+ break;\n+ case 8:\n+ result = config_readll(s, domain, offset, data, attrs);\n+ break;\n+ default:\n+ result = false;\n+ break;\n+ }\n+\n+ if (!result) {\n+ qemu_log_mask(LOG_GUEST_ERROR,\n+ \"%s: invalid guest read for IRS %s config frame \"\n+ \"at offset \" HWADDR_FMT_plx\n+ \" size %u\\n\", __func__, domain_name[domain],\n+ offset, size);\n+ trace_gicv5_badread(domain_name[domain], offset, size);\n+ /*\n+ * The spec requires that reserved registers are RAZ/WI; so we\n+ * log the error but return MEMTX_OK so we don't cause a\n+ * spurious data abort.\n+ */\n+ *data = 0;\n+ } else {\n+ trace_gicv5_read(domain_name[domain], offset, *data, size);\n+ }\n+\n+ return MEMTX_OK;\n+}\n+\n+static MemTxResult config_write(void *opaque, GICv5Domain domain,\n+ hwaddr offset, uint64_t data, unsigned size,\n+ MemTxAttrs attrs)\n+{\n+ GICv5 *s = ARM_GICV5(opaque);\n+ bool result;\n+\n+ switch (size) {\n+ case 4:\n+ result = config_writel(s, domain, offset, data, attrs);\n+ break;\n+ case 8:\n+ result = config_writell(s, domain, offset, data, attrs);\n+ break;\n+ default:\n+ result = false;\n+ break;\n+ }\n+\n+ if (!result) {\n+ qemu_log_mask(LOG_GUEST_ERROR,\n+ \"%s: invalid guest write for IRS %s config frame \"\n+ \"at offset \" HWADDR_FMT_plx\n+ \" size %u\\n\", __func__, domain_name[domain],\n+ offset, size);\n+ trace_gicv5_badwrite(domain_name[domain], offset, data, size);\n+ /*\n+ * The spec requires that reserved registers are RAZ/WI; so we\n+ * log the error but return MEMTX_OK so we don't cause a\n+ * spurious data abort.\n+ */\n+ } else {\n+ trace_gicv5_write(domain_name[domain], offset, data, size);\n+ }\n+\n+ return MEMTX_OK;\n+}\n+\n+#define DEFINE_READ_WRITE_WRAPPERS(NAME, DOMAIN) \\\n+ static MemTxResult config_##NAME##_read(void *opaque, hwaddr offset, \\\n+ uint64_t *data, unsigned size, \\\n+ MemTxAttrs attrs) \\\n+ { \\\n+ return config_read(opaque, DOMAIN, offset, data, size, attrs); \\\n+ } \\\n+ static MemTxResult config_##NAME##_write(void *opaque, hwaddr offset, \\\n+ uint64_t data, unsigned size, \\\n+ MemTxAttrs attrs) \\\n+ { \\\n+ return config_write(opaque, DOMAIN, offset, data, size, attrs); \\\n+ }\n+\n+DEFINE_READ_WRITE_WRAPPERS(ns, GICV5_ID_NS)\n+DEFINE_READ_WRITE_WRAPPERS(realm, GICV5_ID_REALM)\n+DEFINE_READ_WRITE_WRAPPERS(secure, GICV5_ID_S)\n+DEFINE_READ_WRITE_WRAPPERS(el3, GICV5_ID_EL3)\n+\n+#define FRAME_OP_ENTRY(NAME, DOMAIN) \\\n+ [DOMAIN] = { \\\n+ .read_with_attrs = config_##NAME##_read, \\\n+ .write_with_attrs = config_##NAME##_write, \\\n+ .endianness = DEVICE_LITTLE_ENDIAN, \\\n+ .valid.min_access_size = 4, \\\n+ .valid.max_access_size = 8, \\\n+ .impl.min_access_size = 4, \\\n+ .impl.max_access_size = 8, \\\n+ }\n+\n+static const MemoryRegionOps config_frame_ops[NUM_GICV5_DOMAINS] = {\n+ FRAME_OP_ENTRY(ns, GICV5_ID_NS),\n+ FRAME_OP_ENTRY(realm, GICV5_ID_REALM),\n+ FRAME_OP_ENTRY(secure, GICV5_ID_S),\n+ FRAME_OP_ENTRY(el3, GICV5_ID_EL3),\n+};\n+\n static void gicv5_reset_hold(Object *obj, ResetType type)\n {\n GICv5 *s = ARM_GICV5(obj);\n@@ -21,6 +169,28 @@ static void gicv5_reset_hold(Object *obj, ResetType type)\n }\n }\n \n+static void gicv5_realize(DeviceState *dev, Error **errp)\n+{\n+ GICv5Common *cs = ARM_GICV5_COMMON(dev);\n+ GICv5Class *gc = ARM_GICV5_GET_CLASS(dev);\n+\n+ ERRP_GUARD();\n+\n+ gc->parent_realize(dev, errp);\n+ if (*errp) {\n+ return;\n+ }\n+\n+ /*\n+ * When we implement support for more than one interrupt domain,\n+ * we will provide some QOM properties so the board can configure\n+ * which domains are implemented. For now, we only implement the\n+ * NS domain.\n+ */\n+ cs->implemented_domains = (1 << GICV5_ID_NS);\n+ gicv5_common_init_irqs_and_mmio(cs, config_frame_ops);\n+}\n+\n static void gicv5_init(Object *obj)\n {\n }\n@@ -32,8 +202,10 @@ static void gicv5_finalize(Object *obj)\n static void gicv5_class_init(ObjectClass *oc, const void *data)\n {\n ResettableClass *rc = RESETTABLE_CLASS(oc);\n+ DeviceClass *dc = DEVICE_CLASS(oc);\n GICv5Class *gc = ARM_GICV5_CLASS(oc);\n \n+ device_class_set_parent_realize(dc, gicv5_realize, &gc->parent_realize);\n resettable_class_set_parent_phases(rc, NULL, gicv5_reset_hold, NULL,\n &gc->parent_phases);\n }\ndiff --git a/hw/intc/arm_gicv5_common.c b/hw/intc/arm_gicv5_common.c\nindex b0194f7f26..bf990bfa54 100644\n--- a/hw/intc/arm_gicv5_common.c\n+++ b/hw/intc/arm_gicv5_common.c\n@@ -11,6 +11,41 @@\n \n OBJECT_DEFINE_ABSTRACT_TYPE(GICv5Common, gicv5_common, ARM_GICV5_COMMON, SYS_BUS_DEVICE)\n \n+static bool bad_frame_accepts(void *opaque, hwaddr addr, unsigned size,\n+ bool is_write, MemTxAttrs attrs)\n+{\n+ return false;\n+}\n+\n+/*\n+ * Used for the sysbus MMIO regions corresponding to IRS frames where\n+ * this IRS does not implement the interrupt domain. It's probably a\n+ * board/SoC error to create an IRS and try to wire up this MMIO\n+ * region, but if it does then the region will behave as unassigned\n+ * memory (generating a decode error). These frames are just here so\n+ * that changing which domains are implemented doesn't reorder which\n+ * sysbus MMIO region is which.\n+ */\n+static const MemoryRegionOps bad_frame_ops = {\n+ .valid.accepts = bad_frame_accepts,\n+ .endianness = DEVICE_LITTLE_ENDIAN,\n+};\n+\n+void gicv5_common_init_irqs_and_mmio(GICv5Common *cs,\n+ const MemoryRegionOps config_ops[NUM_GICV5_DOMAINS])\n+{\n+ SysBusDevice *sbd = SYS_BUS_DEVICE(cs);\n+\n+ for (int i = 0; i < NUM_GICV5_DOMAINS; i++) {\n+ g_autofree char *memname = g_strdup_printf(\"gicv5-irs-%d\", i);\n+ const MemoryRegionOps *ops = gicv5_domain_implemented(cs, i) ?\n+ &config_ops[i] : &bad_frame_ops;\n+ memory_region_init_io(&cs->iomem[i], OBJECT(cs), ops, cs,\n+ memname, IRS_CONFIG_FRAME_SIZE);\n+ sysbus_init_mmio(sbd, &cs->iomem[i]);\n+ }\n+}\n+\n static void gicv5_common_reset_hold(Object *obj, ResetType type)\n {\n }\ndiff --git a/hw/intc/trace-events b/hw/intc/trace-events\nindex 018c609ca5..edd3c49c5f 100644\n--- a/hw/intc/trace-events\n+++ b/hw/intc/trace-events\n@@ -227,6 +227,12 @@ gicv3_its_vte_read(uint32_t vpeid, int valid, uint32_t vptsize, uint64_t vptaddr\n gicv3_its_vte_read_fault(uint32_t vpeid) \"GICv3 ITS: vPE Table read for vPEID 0x%x: faulted\"\n gicv3_its_vte_write(uint32_t vpeid, int valid, uint32_t vptsize, uint64_t vptaddr, uint32_t rdbase) \"GICv3 ITS: vPE Table write for vPEID 0x%x: valid %d VPTsize 0x%x VPTaddr 0x%\" PRIx64 \" RDbase 0x%x\"\n \n+# arm_gicv5.c\n+gicv5_read(const char *domain, uint64_t offset, uint64_t data, unsigned size) \"GICv5 IRS %s config frame read: offset 0x%\" PRIx64 \" data 0x%\" PRIx64 \" size %u\"\n+gicv5_badread(const char *domain, uint64_t offset, unsigned size) \"GICv5 IRS %s config frame read: offset 0x%\" PRIx64 \" size %u: error\"\n+gicv5_write(const char *domain, uint64_t offset, uint64_t data, unsigned size) \"GICv5 IRS %s config frame write: offset 0x%\" PRIx64 \" data 0x%\" PRIx64 \" size %u\"\n+gicv5_badwrite(const char *domain, uint64_t offset, uint64_t data, unsigned size) \"GICv5 IRS %s config frame write: offset 0x%\" PRIx64 \" data 0x%\" PRIx64 \" size %u: error\"\n+\n # armv7m_nvic.c\n nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) \"NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d\"\n nvic_recompute_state_secure(int vectpending, bool vectpending_is_s_banked, int vectpending_prio, int exception_prio) \"NVIC state recomputed: vectpending %d is_s_banked %d vectpending_prio %d exception_prio %d\"\ndiff --git a/include/hw/intc/arm_gicv5.h b/include/hw/intc/arm_gicv5.h\nindex 3cd9652f6f..42ccef8474 100644\n--- a/include/hw/intc/arm_gicv5.h\n+++ b/include/hw/intc/arm_gicv5.h\n@@ -26,6 +26,7 @@ struct GICv5 {\n \n struct GICv5Class {\n GICv5CommonClass parent_class;\n+ DeviceRealize parent_realize;\n ResettablePhases parent_phases;\n };\n \ndiff --git a/include/hw/intc/arm_gicv5_common.h b/include/hw/intc/arm_gicv5_common.h\nindex d2243c7660..b7a17aac31 100644\n--- a/include/hw/intc/arm_gicv5_common.h\n+++ b/include/hw/intc/arm_gicv5_common.h\n@@ -11,6 +11,26 @@\n \n #include \"qom/object.h\"\n #include \"hw/core/sysbus.h\"\n+#include \"hw/intc/arm_gicv5_types.h\"\n+\n+/*\n+ * QEMU interface:\n+ *\n+ * sysbus MMIO regions (in order matching IRS_IDR0.INT_DOM encoding):\n+ * - IRS config frame for the Secure Interrupt Domain\n+ * - IRS config frame for the Non-secure Interrupt Domain\n+ * - IRS config frame for the EL3 Interrupt Domain\n+ * - IRS config frame for the Realm Interrupt Domain\n+ *\n+ * Note that even if this particular IRS does not implement all four\n+ * interrupt domains it will still expose four sysbus MMIO regions.\n+ * The regions corresponding to unimplemented domains will always fail\n+ * accesses with a decode error. Generally the SoC/board should\n+ * probably not map a region for a domain that it configured the IRS\n+ * to not implement; the regions are only exposed so that changing\n+ * which domains are implemented doesn't reorder which sysbus MMIO\n+ * region is which (e.g. NS will always be 1 and EL3 will always be 2).\n+ */\n \n #define TYPE_ARM_GICV5_COMMON \"arm-gicv5-common\"\n \n@@ -22,10 +42,40 @@ OBJECT_DECLARE_TYPE(GICv5Common, GICv5CommonClass, ARM_GICV5_COMMON)\n */\n struct GICv5Common {\n SysBusDevice parent_obj;\n+\n+ MemoryRegion iomem[NUM_GICV5_DOMAINS];\n+\n+ /* Bits here are set for each physical interrupt domain implemented */\n+ uint8_t implemented_domains;\n };\n \n struct GICv5CommonClass {\n SysBusDeviceClass parent_class;\n };\n \n+\n+#define IRS_CONFIG_FRAME_SIZE 0x10000\n+\n+/**\n+ * gicv5_common_init_irqs_and_mmio: Create IRQs and MMIO regions for the GICv5\n+ * @s: GIC object\n+ * @ops: array of MemoryRegionOps that implement the config frames behaviour\n+ *\n+ * Subclasses of ARM_GICV5_COMMON should call this to create the sysbus\n+ * MemoryRegions for the IRS config frames, passing in a four element array\n+ * of MemoryRegionOps structs.\n+ */\n+void gicv5_common_init_irqs_and_mmio(GICv5Common *cs,\n+ const MemoryRegionOps ops[NUM_GICV5_DOMAINS]);\n+\n+/**\n+ * gicv5_domain_implemented: Return true if this IRS implements this domain\n+ * @s: GIC object\n+ * @domain: domain to check\n+ */\n+static inline bool gicv5_domain_implemented(GICv5Common *cs, GICv5Domain domain)\n+{\n+ return cs->implemented_domains & (1 << domain);\n+}\n+\n #endif\ndiff --git a/include/hw/intc/arm_gicv5_types.h b/include/hw/intc/arm_gicv5_types.h\nnew file mode 100644\nindex 0000000000..49dc1d6e95\n--- /dev/null\n+++ b/include/hw/intc/arm_gicv5_types.h\n@@ -0,0 +1,28 @@\n+/*\n+ * Type definitions for GICv5\n+ *\n+ * This file is for type definitions that we want to share between\n+ * the GIC proper and the CPU interface.\n+ *\n+ * Copyright (c) 2025 Linaro Limited\n+ *\n+ * SPDX-License-Identifier: GPL-2.0-or-later\n+ */\n+\n+#ifndef HW_INTC_ARM_GICv5_TYPES_H\n+#define HW_INTC_ARM_GICv5_TYPES_H\n+\n+/*\n+ * The GICv5 has four physical Interrupt Domains. This numbering must\n+ * match the encoding used in IRS_IDR0.INT_DOM.\n+ */\n+typedef enum GICv5Domain {\n+ GICV5_ID_S = 0,\n+ GICV5_ID_NS = 1,\n+ GICV5_ID_EL3 = 2,\n+ GICV5_ID_REALM = 3,\n+} GICv5Domain;\n+\n+#define NUM_GICV5_DOMAINS 4\n+\n+#endif\n", "prefixes": [ "v2", "05/65" ] }