From nobody Mon Dec 15 21:29:38 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1744128110; cv=none; d=zohomail.com; s=zohoarc; b=b4HoeKdxQ42nFVr/NyAHgjsGJ2kwvG39pfX2eS8+TIVKU+jMRn26I+L0Kt2Q84ZynC0JU4cWeqKHdTfJEvh6P9ODhb613mH89ag76JxozvrZCtVipCex9Nm5OvREpt6JpP0oo/Q4NhmNtsk6gPvicEeW/WENG0nvw8vYcIgew1I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1744128110; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=obosTziijTFYXfPLbOAwqyMHx7uiRBVtztO5FdIKDt0=; b=WSZ91+I76NLFGZtdstswTz1Nx5aFD5JbT9Pl+Q76it/nUYavwMWa9se4HPogvt+bC/uVtNKVup7Iy0Egh/x2gVRrZrnnRkJD3CN8rmwdAIzqFFfkRt24k+51eeTWOFC20bdtmiIgBoDKofGSpi02EjRDtKlhOxs4K3ZmHtFxT7o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1744128110958841.6982522797591; Tue, 8 Apr 2025 09:01:50 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.942606.1341752 (Exim 4.92) (envelope-from ) id 1u2BOF-0004gv-5E; Tue, 08 Apr 2025 16:01:31 +0000 Received: by outflank-mailman (output) from mailman id 942606.1341752; Tue, 08 Apr 2025 16:01:31 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u2BOF-0004ga-1p; Tue, 08 Apr 2025 16:01:31 +0000 Received: by outflank-mailman (input) for mailman id 942606; Tue, 08 Apr 2025 16:01:30 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u2BKW-0004Yq-Jf for xen-devel@lists.xenproject.org; Tue, 08 Apr 2025 15:57:40 +0000 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [2a00:1450:4864:20::635]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 30a2b2f0-1492-11f0-9ffb-bf95429c2676; Tue, 08 Apr 2025 17:57:36 +0200 (CEST) Received: by mail-ej1-x635.google.com with SMTP id a640c23a62f3a-ac29af3382dso936870166b.2 for ; Tue, 08 Apr 2025 08:57:36 -0700 (PDT) Received: from fedora.. (user-109-243-64-225.play-internet.pl. [109.243.64.225]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac7c018556bsm929934566b.156.2025.04.08.08.57.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Apr 2025 08:57:34 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 30a2b2f0-1492-11f0-9ffb-bf95429c2676 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1744127855; x=1744732655; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=obosTziijTFYXfPLbOAwqyMHx7uiRBVtztO5FdIKDt0=; b=WTecgZ75a8WNbXJ4hgvY9ID1Hs5jEjE/lJzgKv7ikrrSjl1SeDFDG14YKzlAISkhCX P26IEAlpsPnuow0Oui6GPe6qHtFpRx6B75FaKkmSyWMoF1LJka7lFUxASvPWmR3yD/Cx vFyI2BsXXJNXoQQJvrtxwrVubJITjmBd1lp4Xe61SQe4tKvPsg0604Vq5vpr35IV7QLD 5WBRDL5mQMoPMk1pDqpWiztjBRJShbHDfG1fZl7T8XqJ2yOZ2UbKrVR1FIwZiAVI9F/w f8LTr1QV0rB45O+O5qZUFgK7Qb2rnJiUIvGfaD8UyMnhgHUqSSfpWYUelCB1dLh+nS5w gRtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744127855; x=1744732655; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=obosTziijTFYXfPLbOAwqyMHx7uiRBVtztO5FdIKDt0=; b=KEiTAQpmWcSpcQoVoi3lJ0rgSpypYJc6/YBRqnDC47iCNjUBmiPfHXIsaSzNwn22uS fzHsSIsT4koco61/AhzlVo+0SOd9RQizmOfcCPr3Ie9Vt1VOcQ+SkMGninV0i+FuHZJR nrTUi2GkiOEvxuQ4v4BJSZ6234XYtZhAcjgS9p9XBvpW6Ib4FjaaeEhRnzTDwNVFs7+m pWcbV6SSppn0h3dshmlMR97CfYrpQiofMHO2pMTM4PpedznVtoQitAH/nXoLLP2lxrxL bv9QYuYXAjezfLtt8kiSwntvMs1EQvq7eL2uq77v7lftA4aT9PuGiylICeISdttkSbFb lWQw== X-Gm-Message-State: AOJu0Yx4Laz8P1v5nka0ZCPzvWePg1Z5HFtDJDiEvcJk7fx1WQUOX4Pc pSIcGHjc4/lt+mO6VchYDcUweyL0XBQ3Cv4h25NtYVLwij8RqnyEkJCTvA== X-Gm-Gg: ASbGnctUFOMTA+PikQd6582BsnDomEfClj3ljVDWbJSI8Xp/VZ0fIUlP9jiBuWsd+0v YekJu7Jrcsn/KHJrSidFD0IT1FTMH5UyNowZuYG1Y80sEyjQO4qD4SxvEyt62T/xqWpHjReofp0 uXqIw62kpLoeSmULzh6n3TxhWQjixXFuGHD62ldBlh2rd+K/z9+TCwDKyYrp+pWXwnp5XhYaudY y3wp9vv9kUgTrQ6V9UQfvJJdGjyaHnH+xHiKOo0VyjQn/HeNw76tgH559yHGuuyv54fJuefAMKP ZqMM/AzhN9GAc9JMBeiHQsP8bwuUMVj6eS5DvkyIj8NJFryzoNanCpekG6TEKCzubqwHNx1xmlU Ihe02CkwAEQkIYw== X-Google-Smtp-Source: AGHT+IEGspGPs+MME//LE3RWoyJqDPz+WYmt7DGj67vMc+ReaBhJ3Bcm6MIfxc1z+iw9GyXf45JObA== X-Received: by 2002:a17:907:724f:b0:ac2:cdcb:6a85 with SMTP id a640c23a62f3a-ac7d6d2b3f4mr1436812166b.22.1744127855300; Tue, 08 Apr 2025 08:57:35 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Alistair Francis , Bob Eshleman , Connor Davis , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Romain Caritey Subject: [PATCH v1 10/14] xen/riscv: implementation of aplic and imsic operations Date: Tue, 8 Apr 2025 17:57:15 +0200 Message-ID: <74a07ed7c596bbcf581010685e01bfdfa19164f5.1744126720.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1744128114196019100 Content-Type: text/plain; charset="utf-8" Introduce interrupt controller descriptor for host APLIC to describe the low-lovel hardare. It includes implementation of the following function= s: - aplic_irq_startup() - aplic_irq_shutdown() - aplic_irq_enable() - aplic_irq_disable() - aplic_irq_ack() - aplic_host_irq_end() - aplic_set_irq_affinity() As APLIC is used in MSI mode it requires to enable/disable interrupts not only for APLIC but also for IMSIC. Thereby for the purpose of aplic_irq_{enable,disable}() it is introduced imsic_irq_{enable,disable)(). For the purpose of aplic_set_irq_affinity() aplic_get_cpu_from_mask() is introduced to get hart id. Also, introduce additional interrupt controller h/w operations and host_irq_type for APLIC: - aplic_host_irq_type - aplic_set_irq_priority() - aplic_set_irq_type() Patch is based on the code from [1]. [1] https://gitlab.com/xen-project/people/olkur/xen/-/commit/7390e2365828b8= 3e27ead56b03114a56e3699dd5 Co-developed-by: Romain Caritey Signed-off-by: Oleksii Kurochko --- xen/arch/riscv/aplic.c | 169 ++++++++++++++++++++++++++++- xen/arch/riscv/imsic.c | 63 +++++++++++ xen/arch/riscv/include/asm/aplic.h | 12 ++ xen/arch/riscv/include/asm/imsic.h | 15 +++ 4 files changed, 258 insertions(+), 1 deletion(-) diff --git a/xen/arch/riscv/aplic.c b/xen/arch/riscv/aplic.c index d1aa835c3e..4b60cb9a77 100644 --- a/xen/arch/riscv/aplic.c +++ b/xen/arch/riscv/aplic.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include =20 @@ -110,9 +111,173 @@ static int __init aplic_init(void) return 0; } =20 -static const struct intc_hw_operations __ro_after_init aplic_ops =3D { +static void aplic_set_irq_type(struct irq_desc *desc, unsigned int type) +{ + unsigned int irq =3D desc->irq - 1; + + spin_lock(&aplic.lock); + switch(type) { + case IRQ_TYPE_EDGE_RISING: + aplic.regs->sourcecfg[irq] =3D APLIC_SOURCECFG_SM_EDGE_RISE; + break; + case IRQ_TYPE_EDGE_FALLING: + aplic.regs->sourcecfg[irq] =3D APLIC_SOURCECFG_SM_EDGE_FALL; + break; + case IRQ_TYPE_LEVEL_HIGH: + aplic.regs->sourcecfg[irq] =3D APLIC_SOURCECFG_SM_LEVEL_HIGH; + break; + case IRQ_TYPE_LEVEL_LOW: + aplic.regs->sourcecfg[irq] =3D APLIC_SOURCECFG_SM_LEVEL_LOW; + break; + default: + aplic.regs->sourcecfg[irq] =3D APLIC_SOURCECFG_SM_INACTIVE; + break; + } + spin_unlock(&aplic.lock); +} + +static void aplic_set_irq_priority(struct irq_desc *desc, + unsigned int priority) +{ + /* No priority, do nothing */ +} + +static void aplic_irq_enable(struct irq_desc *desc) +{ + unsigned long flags; + + /* + * TODO: Currently, APLIC is supported only with MSI interrupts. + * If APLIC without MSI interrupts is required in the future, + * this function will need to be updated accordingly. + */ + ASSERT(aplic.imsic_cfg->is_used); + + ASSERT(spin_is_locked(&desc->lock)); + + spin_lock_irqsave(&aplic.lock, flags); + + clear_bit(_IRQ_DISABLED, &desc->status); + + /* enable interrupt in IMSIC */ + imsic_irq_enable(desc->irq); + + /* enable interrupt in APLIC */ + aplic.regs->setienum =3D desc->irq; + + spin_unlock_irqrestore(&aplic.lock, flags); +} + +static void aplic_irq_disable(struct irq_desc *desc) +{ + unsigned long flags; + + /* + * TODO: Currently, APLIC is supported only with MSI interrupts. + * If APLIC without MSI interrupts is required in the future, + * this function will need to be updated accordingly. + */ + ASSERT(aplic.imsic_cfg->is_used); + + ASSERT(spin_is_locked(&desc->lock)); + + spin_lock_irqsave(&aplic.lock, flags); + + set_bit(_IRQ_DISABLED, &desc->status); + + /* disable interrupt in APLIC */ + aplic.regs->clrienum =3D desc->irq; + + /* disable interrupt in IMSIC */ + imsic_irq_disable(desc->irq); + + spin_unlock_irqrestore(&aplic.lock, flags); +} + +static unsigned int aplic_irq_startup(struct irq_desc *desc) +{ + aplic_irq_enable(desc); + + return 0; +} + +static void aplic_irq_shutdown(struct irq_desc *desc) +{ + aplic_irq_disable(desc); +} + +static void aplic_irq_ack(struct irq_desc *desc) +{ + /* nothing to do */ +} + +static void aplic_host_irq_end(struct irq_desc *desc) +{ + /* nothing to do */ +} + +static unsigned int aplic_get_cpu_from_mask(const cpumask_t *cpumask) +{ + unsigned int cpu; + cpumask_t possible_mask; + + cpumask_and(&possible_mask, cpumask, &cpu_possible_map); + cpu =3D cpumask_any(&possible_mask); + + return cpu; +} + +static void aplic_set_irq_affinity(struct irq_desc *desc, const cpumask_t = *mask) +{ + unsigned int cpu; + uint64_t group_index, base_ppn; + uint32_t hhxw, lhxw ,hhxs, value; + const struct imsic_config *imsic =3D aplic.imsic_cfg; + + /* + * TODO: Currently, APLIC is supported only with MSI interrupts. + * If APLIC without MSI interrupts is required in the future, + * this function will need to be updated accordingly. + */ + ASSERT(aplic.imsic_cfg->is_used); + + ASSERT(!cpumask_empty(mask)); + + spin_lock(&aplic.lock); + + cpu =3D cpuid_to_hartid(aplic_get_cpu_from_mask(mask)); + hhxw =3D imsic->group_index_bits; + lhxw =3D imsic->hart_index_bits; + hhxs =3D imsic->group_index_shift - IMSIC_MMIO_PAGE_SHIFT * 2; + base_ppn =3D imsic->msi[cpu].base_addr >> IMSIC_MMIO_PAGE_SHIFT; + + /* update hart and EEID in the target register */ + group_index =3D (base_ppn >> (hhxs + 12)) & (BIT(hhxw, UL) - 1); + value =3D desc->irq; + value |=3D cpu << APLIC_TARGET_HART_IDX_SHIFT; + value |=3D group_index << (lhxw + APLIC_TARGET_HART_IDX_SHIFT) ; + aplic.regs->target[desc->irq - 1] =3D value; + + spin_unlock(&aplic.lock); +} + +static hw_irq_controller aplic_host_irq_type =3D { + .typename =3D "aplic", + .startup =3D aplic_irq_startup, + .shutdown =3D aplic_irq_shutdown, + .enable =3D aplic_irq_enable, + .disable =3D aplic_irq_disable, + .ack =3D aplic_irq_ack, + .end =3D aplic_host_irq_end, + .set_affinity =3D aplic_set_irq_affinity, +}; + +static const struct intc_hw_operations aplic_ops =3D { .info =3D &aplic_info, .init =3D aplic_init, + .host_irq_type =3D &aplic_host_irq_type, + .set_irq_priority =3D aplic_set_irq_priority, + .set_irq_type =3D aplic_set_irq_type, }; =20 static int aplic_irq_xlate(const uint32_t *intspec, unsigned int intsize, @@ -149,6 +314,8 @@ static int __init aplic_preinit(struct dt_device_node *= node, const void *dat) =20 dt_irq_xlate =3D aplic_irq_xlate; =20 + spin_lock_init(&aplic.lock); + register_intc_ops(&aplic_ops); =20 return 0; diff --git a/xen/arch/riscv/imsic.c b/xen/arch/riscv/imsic.c index 99def9af2d..8198d008ef 100644 --- a/xen/arch/riscv/imsic.c +++ b/xen/arch/riscv/imsic.c @@ -14,12 +14,68 @@ #include #include #include +#include #include =20 #include =20 static struct imsic_config imsic_cfg; =20 +#define imsic_csr_set(c, v) \ +do { \ + csr_write(CSR_SISELECT, c); \ + csr_set(CSR_SIREG, v); \ +} while (0) + +#define imsic_csr_clear(c, v) \ +do { \ + csr_write(CSR_SISELECT, c); \ + csr_clear(CSR_SIREG, v); \ +} while (0) + +static void imsic_local_eix_update(unsigned long base_id, unsigned long nu= m_id, + bool pend, bool val) +{ + unsigned long i, isel, ireg; + unsigned long id =3D base_id, last_id =3D base_id + num_id; + + while ( id < last_id ) + { + isel =3D id / __riscv_xlen; + isel *=3D __riscv_xlen / IMSIC_EIPx_BITS; + isel +=3D (pend) ? IMSIC_EIP0 : IMSIC_EIE0; + + ireg =3D 0; + for ( i =3D id & (__riscv_xlen - 1); + (id < last_id) && (i < __riscv_xlen); + i++, id++ ) + ireg |=3D (1 << i); + + if ( val ) + imsic_csr_set(isel, ireg); + else + imsic_csr_clear(isel, ireg); + } +} + +void imsic_irq_enable(unsigned int hwirq) +{ + unsigned long flags; + + spin_lock_irqsave(&imsic_cfg.lock, flags); + imsic_local_eix_update(hwirq, 1, false, true); + spin_unlock_irqrestore(&imsic_cfg.lock, flags); +} + +void imsic_irq_disable(unsigned int hwirq) +{ + unsigned long flags; + + spin_lock_irqsave(&imsic_cfg.lock, flags); + imsic_local_eix_update(hwirq, 1, false, false); + spin_unlock_irqrestore(&imsic_cfg.lock, flags); +} + const struct imsic_config *imsic_get_config(void) { return &imsic_cfg; @@ -277,6 +333,13 @@ int __init imsic_init(struct dt_device_node *node) goto imsic_init_err; } =20 + spin_lock_init(&imsic_cfg.lock); + + /* Enable local interrupt delivery */ + imsic_ids_local_delivery(true); + + imsic_cfg.is_used =3D true; + return 0; =20 imsic_init_err: diff --git a/xen/arch/riscv/include/asm/aplic.h b/xen/arch/riscv/include/as= m/aplic.h index 94b3d0b616..ce858663a9 100644 --- a/xen/arch/riscv/include/asm/aplic.h +++ b/xen/arch/riscv/include/asm/aplic.h @@ -18,6 +18,15 @@ #define APLIC_DOMAINCFG_IE BIT(8, UL) #define APLIC_DOMAINCFG_DM BIT(2, UL) =20 +#define APLIC_SOURCECFG_SM_INACTIVE 0x0 +#define APLIC_SOURCECFG_SM_DETACH 0x1 +#define APLIC_SOURCECFG_SM_EDGE_RISE 0x4 +#define APLIC_SOURCECFG_SM_EDGE_FALL 0x5 +#define APLIC_SOURCECFG_SM_LEVEL_HIGH 0x6 +#define APLIC_SOURCECFG_SM_LEVEL_LOW 0x7 + +#define APLIC_TARGET_HART_IDX_SHIFT 18 + struct aplic_regs { uint32_t domaincfg; uint32_t sourcecfg[1023]; @@ -70,6 +79,9 @@ struct aplic_priv { /* registers */ volatile struct aplic_regs *regs; =20 + /* lock */ + spinlock_t lock; + /* imsic configuration */ const struct imsic_config *imsic_cfg; }; diff --git a/xen/arch/riscv/include/asm/imsic.h b/xen/arch/riscv/include/as= m/imsic.h index 126e651863..d2c0178529 100644 --- a/xen/arch/riscv/include/asm/imsic.h +++ b/xen/arch/riscv/include/asm/imsic.h @@ -11,6 +11,7 @@ #ifndef ASM__RISCV__IMSIC_H #define ASM__RISCV__IMSIC_H =20 +#include #include =20 #define IMSIC_MMIO_PAGE_SHIFT 12 @@ -19,6 +20,11 @@ #define IMSIC_MIN_ID 63 #define IMSIC_MAX_ID 2048 =20 +#define IMSIC_EIP0 0x80 +#define IMSIC_EIPx_BITS 32 + +#define IMSIC_EIE0 0xC0 + struct imsic_msi { paddr_t base_addr; unsigned long offset; @@ -55,6 +61,12 @@ struct imsic_config { =20 /* MSI */ struct imsic_msi msi[NR_CPUS]; + + /* a check that IMSIC is used */ + bool is_used; + + /* lock */ + spinlock_t lock; }; =20 struct dt_device_node; @@ -63,4 +75,7 @@ int imsic_init(struct dt_device_node *n); struct imsic_config; const struct imsic_config *imsic_get_config(void); =20 +void imsic_irq_enable(unsigned int hwirq); +void imsic_irq_disable(unsigned int hwirq); + #endif /* ASM__RISCV__IMSIC_H */ --=20 2.49.0