[Skiboot] [PATCH 13/33] interrupts: Add eoi() callback in preparation for XIVE support

Michael Neuling mikey at neuling.org
Wed Jul 6 16:57:14 AEST 2016


A description would be nice here.  Something like:

    Add eoi() callback to struct irq_source_ops in preparation for XIVE
    support.  

    ...something about the icp changes..

A couple of comments below.

> Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> ---
>  core/interrupts.c    | 23 +++++++++++++++++++----
>  include/interrupts.h | 41 +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 60 insertions(+), 4 deletions(-)
> 
> diff --git a/core/interrupts.c b/core/interrupts.c
> index aafdea9..db39267 100644
> --- a/core/interrupts.c
> +++ b/core/interrupts.c
> @@ -205,7 +205,8 @@ void reset_cpu_icp(void)
>  {
>  	void *icp = this_cpu()->icp_regs;
>  
> -	assert(icp);
> +	if (!icp)
> +		return;
>  
>  	/* Clear pending IPIs */
>  	out_8(icp + ICP_MFRR, 0xff);
> @@ -221,7 +222,8 @@ void icp_send_eoi(uint32_t interrupt)
>  {
>  	void *icp = this_cpu()->icp_regs;
>  
> -	assert(icp);
> +	if (!icp)
> +		return;
>  
>  	/* Set priority to max, ignore all incoming interrupts */
>  	out_be32(icp + ICP_XIRR, interrupt & 0xffffff);
> @@ -234,7 +236,8 @@ void icp_prep_for_rvwinkle(void)
>  {
>  	void *icp = this_cpu()->icp_regs;
>  
> -	assert(icp);
> +	if (!icp)
> +		return;
>  
>  	/* Clear pending IPIs */
>  	out_8(icp + ICP_MFRR, 0xff);
> @@ -248,7 +251,8 @@ void icp_kick_cpu(struct cpu_thread *cpu)
>  {
>  	void *icp = cpu->icp_regs;
>  
> -	assert(icp);
> +	if (!icp)
> +		return;

I'm not sure why these are needed.  Should these bits be in a different
patch? 

>  
>  	/* Send high priority IPI */
>  	out_8(icp + ICP_MFRR, 0);
> @@ -353,6 +357,17 @@ static struct irq_source *irq_find_source(uint32_t
> isn)
>  	return NULL;
>  }
>  
> +bool irq_source_eoi(uint32_t isn)
> +{
> +	struct irq_source *is = irq_find_source(isn);
> +
> +	if (!is || !is->ops->eoi)
> +		return false;
> +
> +	is->ops->eoi(is->data, isn);
> +	return true;
> +}
> +
>  static int64_t opal_set_xive(uint32_t isn, uint16_t server, uint8_t
> priority)
>  {
>  	struct irq_source *is = irq_find_source(isn);
> diff --git a/include/interrupts.h b/include/interrupts.h
> index d144dcd..19f542f 100644
> --- a/include/interrupts.h
> +++ b/include/interrupts.h
> @@ -181,6 +181,38 @@
>   *
>   */
>  
> +/* Note about interrupt numbers on P9
> + * ==================================
> + *
> + * P9 uses a completely different interrupt controller, XIVE.
> + *
> + * It targets objects using a combination of block number and
> + * index within a block. However, we try to avoid exposing that
> + * split to the OS in order to keep some abstraction in case the
> + * way we allocate these change.
> + *
> + * The lowest level entity in Xive is the EST (state bit array).
> + *
> + * Those are spread between PHBs, PSI bridge and XIVE itself which
> + * provide a large amount of state bits for IPIs and other SW and HW
> + * generated interrupts by sources that don't have their own ESB logic
> + *
> + * Due to that spread, they aren't a good representation of a global
> + * interrupt number.
> + *
> + * Each such source however needs to be targetted at an EAS (IVT)
> + * entry in a table which will control targetting information and
> + * associate that interrupt with a logical number.
> + *
> + * Thus that table entry number represents a good "global interrupt
> + * number". Additionally, for the host OS, we will keep the logical
> + * number equal to the global number.
> + *
> + * The details of how these are assigned on P9 can be found in
> + * hw/xive.c. P9 HW will generally not use the definitions and
> + * functions in this file (or the corresponding core/interrupts.c).
> + */

This hunk should probably be in the actual xive patch (next one).

Mikey

> +
>  uint32_t p8_chip_irq_block_base(uint32_t chip, uint32_t block);
>  uint32_t p8_chip_irq_phb_base(uint32_t chip, uint32_t phb);
>  uint32_t p8_irq_to_chip(uint32_t irq);
> @@ -229,6 +261,10 @@ uint32_t p8_irq_to_phb(uint32_t irq);
>   * IRQ sources register themselves here. If an "interrupts" callback
>   * is provided, then all interrupts in that source will appear in
>   * 'opal-interrupts' and will be handled by us.
> + *
> + * The "eoi" callback is optional and can be used for interrupts
> + * requiring a special EOI at the source level. Typically will
> + * be used for XIVE interrupts coming from PHBs.
>   */
>  struct irq_source_ops {
>  	int64_t (*set_xive)(void *data, uint32_t isn, uint16_t server,
> @@ -236,6 +272,8 @@ struct irq_source_ops {
>  	int64_t (*get_xive)(void *data, uint32_t isn, uint16_t *server,
>  			    uint8_t *priority);
>  	void (*interrupt)(void *data, uint32_t isn);
> +
> +	void (*eoi)(void *data, uint32_t isn);
>  };
>  
>  extern void register_irq_source(const struct irq_source_ops *ops, void
> *data,
> @@ -257,4 +295,7 @@ extern void icp_kick_cpu(struct cpu_thread *cpu);
>  
>  extern void init_interrupts(void);
>  
> +extern bool irq_source_eoi(uint32_t isn);
> +
> +
>  #endif /* __INTERRUPTS_H */


More information about the Skiboot mailing list