[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 13/16] xen/riscv: implementation of aplic and imsic operations
On 5/15/25 11:44 AM, Jan Beulich wrote:
@@ -159,6 +270,8 @@ static int __init aplic_preinit(struct dt_device_node *node, const void *dat) dt_irq_xlate = aplic_irq_xlate; + spin_lock_init(&aplic.lock);Can't you have the struct field have a suitable initializer? Sure, I will use struct initializer: static struct aplic_priv aplic = { .lock = SPIN_LOCK_UNLOCKED, }; +static void imsic_local_eix_update(unsigned long base_id, unsigned long num_id, + bool pend, bool val) +{ + unsigned long id = base_id, last_id = base_id + num_id; + + while ( id < last_id ) + { + unsigned long isel, ireg; + unsigned long start_id = id & (__riscv_xlen - 1); + unsigned long chunk = __riscv_xlen - start_id; + unsigned long count = (last_id - id < chunk) ? last_id - id : chunk; + + isel = id / __riscv_xlen; + isel *= __riscv_xlen / IMSIC_EIPx_BITS; + isel += pend ? IMSIC_EIP0 : IMSIC_EIE0; + + ireg = GENMASK(start_id + count - 1, start_id); + + id += count; + + if ( val ) + imsic_csr_set(isel, ireg); + else + imsic_csr_clear(isel, ireg); + } +} + +void imsic_irq_enable(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&imsic_cfg.lock, flags); + /* + * There is no irq - 1 here (look at aplic_set_irq_type()) because: + * From the spec: + * When an interrupt file supports distinct interrupt identities, + * valid identity numbers are between 1 and inclusive. The identity + * numbers within this range are said to be implemented by the interrupt + * file; numbers outside this range are not implemented. The number zero + * is never a valid interrupt identity. + * ... + * Bit positions in a valid eiek register that don’t correspond to a + * supported interrupt identity (such as bit 0 of eie0) are read-only zeros. + * + * So in EIx registers interrupt i corresponds to bit i in comparison wiht + * APLIC's sourcecfg which starts from 0. (l)What's this 'l' in parentheses here to indicate? I don't really remember, it seems like I want to point to the spec, but then just make a quote from the spec instead. I'll just drop it. + */ + imsic_local_eix_update(irq, 1, false, true); + spin_unlock_irqrestore(&imsic_cfg.lock, flags); +} + +void imsic_irq_disable(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&imsic_cfg.lock, flags); + imsic_local_eix_update(irq, 1, false, false); + spin_unlock_irqrestore(&imsic_cfg.lock, flags); +}The sole caller of the function has doubly turned off IRQs already; perhaps no need to it a 3rd time, unless other callers are to appear? Same for imsic_irq_enable() as it looks. I checked a code in private branches and it seems like these functions are called only in aplic_irq_{enable,disable}(), so we could do, at least,spin_lock(&imsic_cfg.lock) + ASSERT(!local_irq_is_enabled()); ~ Oleksii
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |