Message ID | d3ada7bf473937a0cb470bc0e7dea1a6078c97d9.1367188423.git.julien.grall@linaro.org |
---|---|
State | Changes Requested, archived |
Headers | show |
On Mon, 2013-04-29 at 00:01 +0100, Julien Grall wrote: > This function translates an interrupt specifier to an IRQ number and IRQ > type (ie: level trigger, edge trigger,...). It's GIC specific. > > Signed-off-by: Julien Grall <julien.grall@linaro.org> > --- > xen/arch/arm/gic.c | 20 ++++++++++++++++++++ > xen/arch/arm/setup.c | 1 + > xen/include/asm-arm/gic.h | 4 ++++ > 3 files changed, 25 insertions(+) > > diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c > index e03bb67..1f44fea 100644 > --- a/xen/arch/arm/gic.c > +++ b/xen/arch/arm/gic.c > @@ -329,6 +329,26 @@ static void __cpuinit gic_hyp_disable(void) > GICH[GICH_HCR] = 0; > } > > +int gic_irq_xlate(const u32 *intspec, unsigned int intsize, > + unsigned int *out_hwirq, > + unsigned int *out_type) > +{ > + if ( intsize < 3 ) > + return -EINVAL; > + > + /* Get the interrupt number and add 16 to skip over SGIs */ > + *out_hwirq = intspec[1] + 16; > + > + /* For SPIs, we need to add 16 more to get the GIC irq ID number */ > + if ( !intspec[0] ) > + *out_hwirq += 16; > + > + if ( out_type ) > + *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; These defines could replace the hardcoded 0xf08 in make_hypervisor_node? Super! > + > + return 0; > +} > + > /* Set up the GIC */ > void __init gic_init(void) > { > diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c > index 77d0879..51f4bba 100644 > --- a/xen/arch/arm/setup.c > +++ b/xen/arch/arm/setup.c > @@ -429,6 +429,7 @@ void __init start_xen(unsigned long boot_phys_offset, > setup_mm(fdt_paddr, fdt_size); > > dt_unflatten_host_device_tree(); > + dt_irq_xlate = gic_irq_xlate; It feels like this ought to belong in a gic_init function of some sort? > > #ifdef EARLY_UART_ADDRESS > /* TODO Need to get device tree or command line for UART address */ > diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h > index 2fac673..945e8db 100644 > --- a/xen/include/asm-arm/gic.h > +++ b/xen/include/asm-arm/gic.h > @@ -187,6 +187,10 @@ extern void send_SGI_allbutself(enum gic_sgi sgi); > /* print useful debug info */ > extern void gic_dump_info(struct vcpu *v); > > +/* IRQ translation function for the device tree */ > +int gic_irq_xlate(const u32 *intspec, unsigned int intsize, > + unsigned int *out_hwirq, unsigned int *out_type); > + > #endif /* __ASSEMBLY__ */ > #endif >
On 04/29/2013 04:31 PM, Ian Campbell wrote: > On Mon, 2013-04-29 at 00:01 +0100, Julien Grall wrote: >> This function translates an interrupt specifier to an IRQ number and IRQ >> type (ie: level trigger, edge trigger,...). It's GIC specific. >> >> Signed-off-by: Julien Grall <julien.grall@linaro.org> >> --- >> xen/arch/arm/gic.c | 20 ++++++++++++++++++++ >> xen/arch/arm/setup.c | 1 + >> xen/include/asm-arm/gic.h | 4 ++++ >> 3 files changed, 25 insertions(+) >> >> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c >> index e03bb67..1f44fea 100644 >> --- a/xen/arch/arm/gic.c >> +++ b/xen/arch/arm/gic.c >> @@ -329,6 +329,26 @@ static void __cpuinit gic_hyp_disable(void) >> GICH[GICH_HCR] = 0; >> } >> >> +int gic_irq_xlate(const u32 *intspec, unsigned int intsize, >> + unsigned int *out_hwirq, >> + unsigned int *out_type) >> +{ >> + if ( intsize < 3 ) >> + return -EINVAL; >> + >> + /* Get the interrupt number and add 16 to skip over SGIs */ >> + *out_hwirq = intspec[1] + 16; >> + >> + /* For SPIs, we need to add 16 more to get the GIC irq ID number */ >> + if ( !intspec[0] ) >> + *out_hwirq += 16; >> + >> + if ( out_type ) >> + *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; > > These defines could replace the hardcoded 0xf08 in make_hypervisor_node? > Super! Right. >> + >> + return 0; >> +} >> + >> /* Set up the GIC */ >> void __init gic_init(void) >> { >> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c >> index 77d0879..51f4bba 100644 >> --- a/xen/arch/arm/setup.c >> +++ b/xen/arch/arm/setup.c >> @@ -429,6 +429,7 @@ void __init start_xen(unsigned long boot_phys_offset, >> setup_mm(fdt_paddr, fdt_size); >> >> dt_unflatten_host_device_tree(); >> + dt_irq_xlate = gic_irq_xlate; > > It feels like this ought to belong in a gic_init function of some sort? The device tree needs this function to translate interrupt for the UART driver. The GIC is initialized too late (few lines after serial setup). Is there a drawback to move gic initialization before the serial setup? The only one I have found is we must use early printk in the function. So most of the time the user can't see the output, assuming he doesn't compile Xen with CONFIG_EARLY_PRINTK.
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index e03bb67..1f44fea 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -329,6 +329,26 @@ static void __cpuinit gic_hyp_disable(void) GICH[GICH_HCR] = 0; } +int gic_irq_xlate(const u32 *intspec, unsigned int intsize, + unsigned int *out_hwirq, + unsigned int *out_type) +{ + if ( intsize < 3 ) + return -EINVAL; + + /* Get the interrupt number and add 16 to skip over SGIs */ + *out_hwirq = intspec[1] + 16; + + /* For SPIs, we need to add 16 more to get the GIC irq ID number */ + if ( !intspec[0] ) + *out_hwirq += 16; + + if ( out_type ) + *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; + + return 0; +} + /* Set up the GIC */ void __init gic_init(void) { diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 77d0879..51f4bba 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -429,6 +429,7 @@ void __init start_xen(unsigned long boot_phys_offset, setup_mm(fdt_paddr, fdt_size); dt_unflatten_host_device_tree(); + dt_irq_xlate = gic_irq_xlate; #ifdef EARLY_UART_ADDRESS /* TODO Need to get device tree or command line for UART address */ diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 2fac673..945e8db 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -187,6 +187,10 @@ extern void send_SGI_allbutself(enum gic_sgi sgi); /* print useful debug info */ extern void gic_dump_info(struct vcpu *v); +/* IRQ translation function for the device tree */ +int gic_irq_xlate(const u32 *intspec, unsigned int intsize, + unsigned int *out_hwirq, unsigned int *out_type); + #endif /* __ASSEMBLY__ */ #endif
This function translates an interrupt specifier to an IRQ number and IRQ type (ie: level trigger, edge trigger,...). It's GIC specific. Signed-off-by: Julien Grall <julien.grall@linaro.org> --- xen/arch/arm/gic.c | 20 ++++++++++++++++++++ xen/arch/arm/setup.c | 1 + xen/include/asm-arm/gic.h | 4 ++++ 3 files changed, 25 insertions(+)