get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2196412/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2196412,
    "url": "http://patchwork.ozlabs.org/api/patches/2196412/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/opensbi/patch/20260213190459.2540597-2-raymondmaoca@gmail.com/",
    "project": {
        "id": 67,
        "url": "http://patchwork.ozlabs.org/api/projects/67/?format=api",
        "name": "OpenSBI development",
        "link_name": "opensbi",
        "list_id": "opensbi.lists.infradead.org",
        "list_email": "opensbi@lists.infradead.org",
        "web_url": "https://github.com/riscv/opensbi",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": "https://github.com/riscv/opensbi/commit/{}"
    },
    "msgid": "<20260213190459.2540597-2-raymondmaoca@gmail.com>",
    "list_archive_url": null,
    "date": "2026-02-13T19:04:57",
    "name": "[RFC,1/3] lib: sbi: Prototype of Virtual IRQ (VIRQ) layer for mapping/routing/courier/ IRQs",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "67eba5995d37168f228879a0acc80b5cae634c95",
    "submitter": {
        "id": 91989,
        "url": "http://patchwork.ozlabs.org/api/people/91989/?format=api",
        "name": "Raymond Mao",
        "email": "raymondmaoca@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/opensbi/patch/20260213190459.2540597-2-raymondmaoca@gmail.com/mbox/",
    "series": [
        {
            "id": 492133,
            "url": "http://patchwork.ozlabs.org/api/series/492133/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/opensbi/list/?series=492133",
            "date": "2026-02-13T19:04:57",
            "name": "VIRQ (Virtual IRQ) layer to support paravirtual interrupt delivery",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/492133/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2196412/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2196412/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "\n <opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.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 secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=Ge5Qv2e4;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20230601 header.b=R78vqlct;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=patchwork.ozlabs.org)"
        ],
        "Received": [
            "from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fCM7Y3Ssmz1xxR\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 14 Feb 2026 06:05:25 +1100 (AEDT)",
            "from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1vqyTV-00000003pC1-3f6x;\n\tFri, 13 Feb 2026 19:05:09 +0000",
            "from mail-qv1-xf2f.google.com ([2607:f8b0:4864:20::f2f])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1vqyTU-00000003pBK-0VsR\n\tfor opensbi@lists.infradead.org;\n\tFri, 13 Feb 2026 19:05:09 +0000",
            "by mail-qv1-xf2f.google.com with SMTP id\n 6a1803df08f44-896fa834290so15107136d6.1\n        for <opensbi@lists.infradead.org>;\n Fri, 13 Feb 2026 11:05:07 -0800 (PST)",
            "from ubuntu.localdomain (174-138-202-16.cpe.distributel.net.\n [174.138.202.16])\n        by smtp.gmail.com with ESMTPSA id\n 6a1803df08f44-8971cd8b1bfsm70420096d6.28.2026.02.13.11.05.05\n        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n        Fri, 13 Feb 2026 11:05:06 -0800 (PST)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:\n\tMessage-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=MM78SFR+HghiZ6K4hkhNouLTnBvsrVwylEerlpnfMR8=; b=Ge5Qv2e4LhuQ3G\n\tECKw0Tud9iBORmd39b00SCMq6xWbk1XyWYIBg37+bC90p3RhF5s3JM47e+apqj5y+lBEFRliTqbiN\n\tgYuYDyd7ZSuK4hYsFe/cCpi3x8EDSqdbjzDf4yv4U6qFjCBBJbn1bonLRCAFQob+qSefA7RT32Lm1\n\tEVinD+W9dzOCdg8GHghfgMvAyyCkKZe3XuGPQkhXYbLsd98qug3eZw0oTcQdy+tKKIjFwy9YzFAWG\n\tI3uQhfsGywiupIVfHAwKIjpGMer0jAPA8QEbJxanuQFVf6sNDYiqvA0DAHjAQGUj7hneElT3QH0v5\n\twXPi0s+E3k947M2T+2TQ==;",
            "v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=gmail.com; s=20230601; t=1771009506; x=1771614306;\n darn=lists.infradead.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=AYWrT3oMTM/dbLg+zJMuOVaP45AgF0MfBSPRJExINOI=;\n        b=R78vqlctOCHINRL5fIIZF2flEYrwuhNT7LDU0pIsBpbsKg3n7GqyT5UcIRihMWR4HZ\n         qjQ7zMo9sT3+0fcLnYgC0H8eoGnCVI203xAYmDkBu/cFEXPrYsFdv27sicK+3GVhoT7K\n         Sm5QpUPfaFEtEK5q1Rmu9wb0XKWQ/pTONXzCcPXr5cCvpAxW+giGg4pMnhN2ORImiV+c\n         MFMEwd86GtLZVQ+IgpQRp8+wMtxVhMpw1HYbJafZlmTFvYhnRi7XX3OkSmNjAZfgfw7i\n         PBtEdaOxGARR5EDc9f0xc/GrZs14KgT0fmt+Bx7UambGE5uaIk/EotYZAUfI+MeBpiOH\n         /E0A=="
        ],
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=1e100.net; s=20230601; t=1771009506; x=1771614306;\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=AYWrT3oMTM/dbLg+zJMuOVaP45AgF0MfBSPRJExINOI=;\n        b=AC1nL2E0a/yTj0PCUyl/ZAsUXG4EurYHEeJb9B2aLApVwbwumsNzb8F57t9G1CLXJw\n         dU4lnhtxbfJgmQgFyS4GoXduTRs5nNUZtDQqgGeMSgeohstv5E8zVXwShg8AvG8lS9Xw\n         jxAsRnV/QQAIZMEX+qHMh+I1xdRdgYaG9oo5sugxB6sIMD4jzwLpTm26XAMn8XuxwwHD\n         FbC4puHa9B0fqK1cg+EfXM6uUG/I1C+ElcRoNLepZ1IBTsHJzOxClRnojhGsSmwugidG\n         /9+EAY+SY3WSxLVWEaU2zaCKJ+g3a+1ZpnBm0jBr9WHzh58V4J1+/EwOyjNdR6yHW0dF\n         LJkg==",
        "X-Gm-Message-State": "AOJu0YywKDHgYVUqKTQZxEqhz7V0l2hOyvkYWMSeSG+WiYyyBdsMXRJL\n\tni3wZYqrA0NBn2H1ToY67R/lIXwLtW6WjDGgsmmLfnnstw9U+4p1qlCVpfrNXw==",
        "X-Gm-Gg": "AZuq6aICoEj0sOS5zpGAeSx2NjfUmOP7RUUuReeCQVaeg1YlsGl3NSUM8QLHCA1c1YR\n\tLeVvICXEYu6GDZ6mZTfTq6KE89jvJMEy7i53hxIbbaefbfLnn0iu0m5Aq+W4ixUW8djFz+dL/ld\n\tOsle7UGQOGZZnNf6DTaD9p1sKYWkj4S2HFC1GAfg/HoVdrKBq4s0ma53uP7xqfXmH1ERE6KITqU\n\t47Jfljfale5ABjN3vJbc+cMPOEOe/gg9rJKpY4zfsZz7iTBm7Q9h2bgSqOfinmIi+M0sSdxxukP\n\ttTqtjjls0Sk4/dbBHauK708nm1pMyQ/tjiGecXV2Cx31U/TadM406o5Cw5YRwjDfUHk762F0aPI\n\tZLuFLo0Gc4S71f6D/Ce+I8HhiiqHntsnRKr+e7TRB6Gq1kysXK4IgIaRvgugrQ/Xq7tNRF34f4b\n\tHJkRtcwmPofYfgAjcoDyzQ2AuXElvADji099s0Di14sHdU4l8bFvF11Je0sb9l4XkxW07eJCGCS\n\twH4EH0pKqs=",
        "X-Received": "by 2002:a05:6214:29eb:b0:88a:44c8:fe30 with SMTP id\n 6a1803df08f44-8973f294d34mr19395676d6.10.1771009506325;\n        Fri, 13 Feb 2026 11:05:06 -0800 (PST)",
        "From": "Raymond Mao <raymondmaoca@gmail.com>",
        "To": "opensbi@lists.infradead.org",
        "Cc": "scott@riscstar.com,\n\tdave.patel@riscstar.com,\n\traymond.mao@riscstar.com,\n\trobin.randhawa@sifive.com,\n\tsamuel.holland@sifive.com,\n\tanup.patel@qti.qualcomm.com,\n\tanuppate@qti.qualcomm.com,\n\tdhaval@rivosinc.com,\n\tpeter.lin@sifive.com",
        "Subject": "[PATCH RFC 1/3] lib: sbi: Prototype of Virtual IRQ (VIRQ) layer for\n mapping/routing/courier/ IRQs",
        "Date": "Fri, 13 Feb 2026 14:04:57 -0500",
        "Message-Id": "<20260213190459.2540597-2-raymondmaoca@gmail.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20260213190459.2540597-1-raymondmaoca@gmail.com>",
        "References": "<20260213190459.2540597-1-raymondmaoca@gmail.com>",
        "MIME-Version": "1.0",
        "X-CRM114-Version": "20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ",
        "X-CRM114-CacheID": "sfid-20260213_110508_200072_1E2D987C ",
        "X-CRM114-Status": "GOOD (  19.75  )",
        "X-Spam-Score": "-2.1 (--)",
        "X-Spam-Report": "Spam detection software,\n running on the system \"bombadil.infradead.org\",\n has NOT identified this incoming email as spam.  The original\n message has been attached to this so you can view it or label\n similar future email.  If you have any questions, see\n the administrator of that system for details.\n Content preview:  From: Raymond Mao VIRQ is an abstraction layer providing\n IRQ\n    routing and couriering. It manages per-(domain,hart) IRQ pending state\n with\n    HWIRQ->VIRQ mapping and VIRQ dispatching via SSE and ECALL extension. When\n    a HWIR [...]\n Content analysis details:   (-2.1 points, 5.0 required)\n  pts rule name              description\n ---- ----------------------\n --------------------------------------------------\n -0.0 RCVD_IN_DNSWL_NONE     RBL: Sender listed at https://www.dnswl.org/, no\n                             trust\n                             [2607:f8b0:4864:20:0:0:0:f2f listed in]\n                             [list.dnswl.org]\n  0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record\n -0.0 SPF_PASS               SPF: sender matches SPF record\n -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from\n author's\n                             domain\n -0.1 DKIM_VALID             Message has at least one valid DKIM or DK\n signature\n  0.1 DKIM_SIGNED            Message has a DKIM or DK signature,\n not necessarily valid\n -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from\n                             envelope-from domain\n -1.9 BAYES_00               BODY: Bayes spam probability is 0 to 1%\n                             [score: 0.0000]\n  0.0 FREEMAIL_FROM          Sender email is commonly abused enduser mail\n provider\n                             [raymondmaoca(at)gmail.com]",
        "X-BeenThere": "opensbi@lists.infradead.org",
        "X-Mailman-Version": "2.1.34",
        "Precedence": "list",
        "List-Id": "<opensbi.lists.infradead.org>",
        "List-Unsubscribe": "<http://lists.infradead.org/mailman/options/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.infradead.org/pipermail/opensbi/>",
        "List-Post": "<mailto:opensbi@lists.infradead.org>",
        "List-Help": "<mailto:opensbi-request@lists.infradead.org?subject=help>",
        "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=subscribe>",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Sender": "\"opensbi\" <opensbi-bounces@lists.infradead.org>",
        "Errors-To": "opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org"
    },
    "content": "From: Raymond Mao <raymond.mao@riscstar.com>\n\nVIRQ is an abstraction layer providing IRQ routing and couriering.\nIt manages per-(domain,hart) IRQ pending state with HWIRQ->VIRQ\nmapping and VIRQ dispatching via SSE and ECALL extension.\nWhen a HWIRQ is asserted, the layer maps it to VIRQ and push into the\nrouted domain's per-hart pending queue, then inject SSE to notify\nS-mode payload and provides ecall extension for S-mode payload to pop\nand complete the VIRQ.\n\nVIRQ layer is composed of three major parts:\n1. VIRQ mapping and allocation\n   - Provides a stable mapping between a host interrupt endpoint\n     (chip_uid, hwirq) and a VIRQ number.\n   - VIRQ number allocation uses a scalable bitmap.\n2. HWIRQ->Domain route rules\n   - Route rules are described in DeviceTree under the OpenSBI\n     domain configuration using:\n       'opensbi,host-irqs = <first_hwirq count> ...;'\n   - Each <first_hwirq count> entry is converted into an internal\n     inclusive range [first .. first+count-1] and cached as a route\n     rule.\n   - Default behavior: if an asserted HWIRQ does not match any route\n     rule, it is routed to the root domain.\n3. Per-(domain,hart) pending queue couriering\n   - Each domain maintains a per-hart ring buffer queue of pending\n     VIRQs.\n   - On an asserted HWIRQ, the courier handler:\n       maps (chip_uid,hwirq) -> VIRQ;\n       finds destination domain via route rules;\n       masks the host HWIRQ (to avoid level-trigger storms);\n       pushes the VIRQ into the per-(domain,hart) pending queue;\n       injects an SSE event to notify the destination S-mode payload.\n   - In S-mode, the payload’s SSE trap handler:\n       issues ecall to pop pending VIRQ from the per-hart queue;\n       runs its ISR for the device;\n       issues ecall to complete the VIRQ, which unmasks the\n       corresponding host HWIRQ.\n\nSigned-off-by: Raymond Mao <raymond.mao@riscstar.com>\n---\n include/sbi/sbi_virq.h | 401 +++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 401 insertions(+)\n create mode 100644 include/sbi/sbi_virq.h",
    "diff": "diff --git a/include/sbi/sbi_virq.h b/include/sbi/sbi_virq.h\nnew file mode 100644\nindex 00000000..d7ec9da9\n--- /dev/null\n+++ b/include/sbi/sbi_virq.h\n@@ -0,0 +1,401 @@\n+/*\n+ * SPDX-License-Identifier: BSD-2-Clause\n+ *\n+ * Virtual IRQ (VIRQ) courier/routing layer for OpenSBI.\n+ *\n+ * This header defines:\n+ *   1) VIRQ number allocation and (chip_uid,hwirq) <-> VIRQ mapping\n+ *   2) HWIRQ -> Domain routing rules (from DeviceTree \"opensbi,host-irqs\")\n+ *   3) Per-(domain,hart) pending queue (push in M-mode, pop/complete in S-mode)\n+ *\n+ * High-level design intent:\n+ *   - All physical host IRQs are handled in M-mode by host irqchip drivers.\n+ *   - For each incoming HWIRQ, OpenSBI determines the destination domain using\n+ *     DT-defined routing rules and enqueues a VIRQ into the per-(domain,hart)\n+ *     pending queue.\n+ *   - S-mode payload consumes pending VIRQs via pop(), and completes them via\n+ *     complete(), which unmasks the corresponding host HWIRQ line.\n+ *\n+ * Notes:\n+ *   - \"opensbi,host-irqs\" is treated as *routing metadata* only. It does not\n+ *     encode which privilege level receives the interrupt. Hardware delivery\n+ *     (MEI vs SEI) is determined by platform IRQ topology and interrupt-parent.\n+ *\n+ * Copyright (c) 2026 RISCstar Solutions Corporation.\n+ *\n+ * Author: Raymond Mao <raymond.mao@riscstar.com>\n+ */\n+\n+#ifndef __SBI_VIRQ_H__\n+#define __SBI_VIRQ_H__\n+\n+#include <sbi/sbi_domain.h>\n+#include <sbi/sbi_irqchip.h>\n+#include <sbi/riscv_locks.h>\n+#include <sbi/sbi_types.h>\n+\n+/*\n+ * Keep the VIRQ pending queue small for bring-up.\n+ *\n+ * Current implementation behavior when queue overflows:\n+ *   - Drop the incoming VIRQ\n+ *   - Return SBI_ENOMEM\n+ */\n+#define VIRQ_QSIZE  32\n+\n+/*\n+ * Reverse mapping table is chunked to avoid a single large static array.\n+ * VIRQ is used as an index into a chunk; chunks are allocated on demand.\n+ */\n+#define VIRQ_CHUNK_SHIFT   6U\n+#define VIRQ_CHUNK_SIZE    (1U << VIRQ_CHUNK_SHIFT)\n+#define VIRQ_CHUNK_MASK    (VIRQ_CHUNK_SIZE - 1U)\n+\n+/* Minimum growth step for forward mapping vector and related metadata. */\n+#define VEC_GROW_MIN       16U\n+\n+/*------------------------------------------------------------------------------\n+ * VIRQ allocator and (chip_uid,hwirq) <-> VIRQ mapping\n+ *----------------------------------------------------------------------------*/\n+\n+ /*\n+ * VIRQ mapping model:\n+ *   - Forward mapping:  (chip_uid,hwirq) -> VIRQ\n+ *       Implementation: dynamic vector of entries (linear search).\n+ *\n+ *   - Reverse mapping:  VIRQ -> (chip_uid,hwirq)\n+ *       Implementation: chunked table allocated on demand, O(1) lookup.\n+ *\n+ *   - VIRQ number allocation:\n+ *       Implementation: growable bitmap; capacity expands as needed.\n+ *\n+ * Memory usage scales with the number of installed mappings.\n+ */\n+\n+/* Entry of reverse mapping table: represents (chip_uid,hwirq) endpoint */\n+struct virq_entry {\n+\tu32 chip_uid;\n+\tu32 hwirq;\n+};\n+\n+/* Chunked reverse mapping table: VIRQ -> (chip_uid,hwirq) */\n+struct virq_chunk {\n+\tstruct virq_entry e[VIRQ_CHUNK_SIZE];\n+};\n+\n+/*------------------------------------------------------------------------------\n+ * HWIRQ -> Domain routing rules\n+ *----------------------------------------------------------------------------*/\n+\n+/*\n+ * A routing rule maps a closed interval of HWIRQs [first..last] to a domain.\n+ *\n+ * Rules are populated once during cold boot while parsing the DT\n+ * opensbi-domains configuration (property \"opensbi,host-irqs\").\n+ *\n+ * DT encodes ranges as:\n+ *   opensbi,host-irqs = <first_hwirq count> ...\n+ *\n+ * Internally they are converted to:\n+ *   [first .. last] (inclusive), where:\n+ *       last = first + count - 1\n+ *\n+ * Policy notes:\n+ *   - Range overlap is rejected and returns SBI_EALREADY.\n+ *   - If no rule matches, routing falls back to the root domain (&root).\n+ */\n+struct sbi_virq_route_rule {\n+\tu32 first;\n+\tu32 last;                 /* inclusive */\n+\tstruct sbi_domain *dom;   /* owner domain */\n+};\n+\n+/*\n+ * Courier context passed as 'opaque' to sbi_virq_courier_handler(), created\n+ * per host irqchip.\n+ *\n+ * The courier handler needs to:\n+ *   - map (chip_uid,hwirq) -> VIRQ\n+ *   - mask/unmask HWIRQ using the correct irqchip device\n+ * Therefore the irqchip device pointer is carried here.\n+ */\n+struct sbi_virq_courier_ctx {\n+\tstruct sbi_irqchip_device *chip;\n+};\n+\n+/*------------------------------------------------------------------------------\n+ * Per-(domain,hart) pending VIRQ state and queue management\n+ *----------------------------------------------------------------------------*/\n+\n+/*\n+ * Per-(domain,hart) VIRQ state.\n+ *\n+ * Locking:\n+ *   - lock protects head/tail and q[].\n+ *\n+ * Queue semantics:\n+ *   - q[] stores VIRQs pending handling for this (domain,hart).\n+ *   - enqueue is performed by M-mode (courier handler) according to route rule\n+ *     populated from DT.\n+ *   - pop/complete is performed by S-mode payload running in the destination\n+ *     domain on the current hart.\n+ *   - chip caches the irqchip device for unmasking on complete().\n+ */\n+struct sbi_domain_virq_state {\n+\tspinlock_t lock;\n+\tu32 head;\n+\tu32 tail;\n+\n+\t/* Pending VIRQ ring buffer. */\n+\tu32 q[VIRQ_QSIZE];\n+\n+\t/* Cached irqchip device. */\n+\tstruct sbi_irqchip_device *chip;\n+};\n+\n+/*\n+ * Per-domain private VIRQ context.\n+ *\n+ * Attached to struct sbi_domain and contains per-hart states.\n+ */\n+struct sbi_domain_virq_priv {\n+\t/* number of harts in the domain */\n+\tu32 nharts;\n+\n+\t/* per-hart VIRQ state array */\n+\tstruct sbi_domain_virq_state st[];\n+};\n+\n+/* Courier binding used when enqueuing a VIRQ. */\n+struct sbi_virq_courier_binding {\n+\t/* destination domain */\n+\tstruct sbi_domain *dom;\n+\n+\t/* irqchip device that asserted the HWIRQ */\n+\tstruct sbi_irqchip_device *chip;\n+\n+\t/* VIRQ number to enqueue */\n+\tu32 virq;\n+};\n+\n+/*------------------------------------------------------------------------------\n+ * Public APIs\n+ *----------------------------------------------------------------------------*/\n+\n+/*\n+ * Initialize the VIRQ allocator/mapping state.\n+ *\n+ * @init_virq_cap:\n+ *   Initial capacity in VIRQ bits (e.g., 256). Implementation may grow beyond.\n+ *\n+ * Return:\n+ *   SBI_OK on success\n+ *   SBI_ENOMEM on allocation failure\n+ */\n+int sbi_virq_map_init(u32 init_virq_cap);\n+\n+/*\n+ * Create or get a stable mapping for (chip_uid, hwirq) -> VIRQ.\n+ *\n+ * @chip_uid:\n+ *   Unique 32-bit ID of the host irqchip device.\n+ *\n+ * @hwirq:\n+ *   Host HWIRQ number as produced by the irqchip driver (e.g. APLIC claim ID).\n+ *\n+ * @allow_identity:\n+ *   If true, allocator may attempt VIRQ == hwirq for small ranges.\n+ *\n+ * @identity_limit:\n+ *   Upper bound (exclusive) for identity mapping trial: hwirq < identity_limit.\n+ *\n+ * @out_virq:\n+ *   Output pointer receiving the mapped/allocated VIRQ (non-zero on success).\n+ *\n+ * Return:\n+ *   SBI_OK on success\n+ *   SBI_ENOMEM on allocation failure\n+ *   SBI_ENOSPC if allocator cannot allocate\n+ *   SBI_EINVAL on invalid parameters\n+ */\n+int sbi_virq_map_one(u32 chip_uid, u32 hwirq,\n+\t\t     bool allow_identity, u32 identity_limit, u32 *out_virq);\n+\n+/*\n+ * Lookup existing mapping: (chip_uid, hwirq) -> VIRQ.\n+ *\n+ * @chip_uid: irqchip unique id\n+ * @hwirq:    host hwirq number\n+ * @out_virq: output VIRQ (non-zero on success)\n+ *\n+ * Return:\n+ *   SBI_OK if found\n+ *   SBI_ENOENT if not mapped\n+ *   SBI_EINVAL on invalid input\n+ */\n+int sbi_virq_hwirq2virq(u32 chip_uid, u32 hwirq, u32 *out_virq);\n+\n+/*\n+ * Reverse lookup: VIRQ -> (chip_uid, hwirq).\n+ *\n+ * @virq:\n+ *   VIRQ number to look up.\n+ *\n+ * @out_chip_uid:\n+ *   Output pointer receiving irqchip unique id.\n+ *\n+ * @out_hwirq:\n+ *   Output pointer receiving host hwirq number.\n+ *\n+ * Return:\n+ *   SBI_OK on success\n+ *   SBI_EINVAL if virq is 0, out of range, not allocated, or reverse entry\n+ *     missing\n+ */\n+int sbi_virq_virq2hwirq(u32 virq, u32 *out_chip_uid, u32 *out_hwirq);\n+\n+/*\n+ * Unmap a single VIRQ mapping and free the VIRQ number.\n+ *\n+ * @virq:\n+ *   VIRQ number to unmap.\n+ *\n+ * Return:\n+ *   SBI_OK on success\n+ *   SBI_EINVAL if virq is invalid or state is inconsistent\n+ */\n+int sbi_virq_unmap_one(u32 virq);\n+\n+/*\n+ * Uninitialize the VIRQ mapping allocator and free all resources.\n+ *\n+ * Notes:\n+ *   - This frees bitmap, forward vector, and reverse chunks.\n+ */\n+void sbi_virq_map_uninit(void);\n+\n+/*\n+ * Reset all HWIRQ->Domain routing rules (frees the rule array).\n+ *\n+ * Typical usage:\n+ *   - Called once at cold boot during init before parsing DT domains.\n+ */\n+void sbi_virq_route_reset(void);\n+\n+/*\n+ * Add a routing rule: [first .. first+count-1] -> dom.\n+ *\n+ * @dom:\n+ *   Target domain that should receive HWIRQs in this range.\n+ *\n+ * @first:\n+ *   First HWIRQ number (inclusive).\n+ *\n+ * @count:\n+ *   Number of HWIRQs in the range.\n+ *\n+ * Return:\n+ *   SBI_OK on success\n+ *   SBI_EINVAL on invalid parameters\n+ *   SBI_ENOMEM on allocation failure\n+ *   SBI_EALREADY if the new range overlaps an existing rule\n+ */\n+int sbi_virq_route_add_range(struct sbi_domain *dom, u32 first, u32 count);\n+\n+/*\n+ * Lookup destination domain for a given HWIRQ.\n+ *\n+ * @hwirq:\n+ *   Incoming host HWIRQ number.\n+ *\n+ * Return:\n+ *   Pointer to destination domain. If no rule matches, returns &root.\n+ */\n+struct sbi_domain *sbi_virq_route_lookup_domain(u32 hwirq);\n+\n+/*\n+ * Enqueue a VIRQ for the destination domain on the current hart.\n+ *\n+ * @c:\n+ *   Courier binding containing:\n+ *     - c->dom  : destination domain\n+ *     - c->chip : irqchip device pointer\n+ *     - c->virq : VIRQ number\n+ *\n+ * Return:\n+ *   SBI_OK on success\n+ *   SBI_EINVAL on invalid parameters\n+ *   SBI_ENODEV if per-(domain,hart) state is not available\n+ *   SBI_ENOMEM if queue is full\n+ */\n+int sbi_virq_enqueue(struct sbi_virq_courier_binding *c);\n+\n+/*\n+ * Pop the next pending VIRQ for the current domain on the current hart.\n+ *\n+ * Return:\n+ *   0 if none pending or state not available\n+ *   otherwise a non-zero VIRQ number\n+ */\n+u32 sbi_virq_pop_thishart(void);\n+\n+/*\n+ * Complete a previously couriered VIRQ for the current domain/hart.\n+ *\n+ * @virq:\n+ *   VIRQ to complete.\n+ */\n+void sbi_virq_complete_thishart(u32 virq);\n+\n+/*\n+ * Courier handler intended to be registered by host irqchip driver.\n+ *\n+ * @hwirq:\n+ *   Incoming host HWIRQ number asserted on the irqchip.\n+ *\n+ * @opaque:\n+ *   Point to a valid struct sbi_virq_courier_ctx, which provides the\n+ *   irqchip device pointer used for mapping and mask/unmask.\n+ *\n+ * Return:\n+ *   SBI_OK on success\n+ *   SBI_EINVAL on invalid parameters\n+ *   Other SBI_E* propagated from mapping or enqueue\n+ */\n+int sbi_virq_courier_handler(u32 hwirq, void *opaque);\n+\n+/*\n+ * Initialize per-domain VIRQ state.\n+ *\n+ * @dom:\n+ *   Domain to initialize.\n+ *\n+ * Return:\n+ *   SBI_OK on success\n+ *   SBI_EINVAL on invalid parameters\n+ *   SBI_ENOMEM on allocation failure\n+ */\n+int sbi_virq_domain_init(struct sbi_domain *dom);\n+\n+/*\n+ * Free per-domain VIRQ state.\n+ *\n+ * @dom:\n+ *   Free the per-domain VIRQ state.\n+ */\n+void sbi_virq_domain_exit(struct sbi_domain *dom);\n+\n+/*\n+ * Initialize VIRQ subsystem (mapping allocator + route rules).\n+ *\n+ * @init_virq_cap:\n+ *   Initial VIRQ bitmap capacity in bits\n+ *\n+ * Return:\n+ *   SBI_OK on success\n+ *   SBI_ENOMEM on allocation failure\n+ *   Other SBI_E* error codes propagated from mapping init\n+ */\n+int sbi_virq_init(u32 init_virq_cap);\n+\n+#endif\n",
    "prefixes": [
        "RFC",
        "1/3"
    ]
}