Hi Drew, On 7/2/20 10:12 AM, Andrew Jones wrote: > The timer can be useful for other tests besides the timer test. > Extract the DT parsing of the irqs out of the timer test into > setup and provide them along with some defines in a new timer.h > file. > > Signed-off-by: Andrew Jones <drjones@xxxxxxxxxx> Reviewed-by: Eric Auger <eric.auger@xxxxxxxxxx> Thanks Eric > --- > arm/timer.c | 26 ++++---------------------- > lib/arm/asm/timer.h | 31 +++++++++++++++++++++++++++++++ > lib/arm/setup.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > lib/arm64/asm/timer.h | 1 + > 4 files changed, 78 insertions(+), 22 deletions(-) > create mode 100644 lib/arm/asm/timer.h > create mode 100644 lib/arm64/asm/timer.h > > diff --git a/arm/timer.c b/arm/timer.c > index 44621b4f2967..09e3f8f6bd7d 100644 > --- a/arm/timer.c > +++ b/arm/timer.c > @@ -8,15 +8,12 @@ > #include <libcflat.h> > #include <devicetree.h> > #include <errata.h> > +#include <asm/timer.h> > #include <asm/delay.h> > #include <asm/processor.h> > #include <asm/gic.h> > #include <asm/io.h> > > -#define ARCH_TIMER_CTL_ENABLE (1 << 0) > -#define ARCH_TIMER_CTL_IMASK (1 << 1) > -#define ARCH_TIMER_CTL_ISTATUS (1 << 2) > - > static void *gic_isenabler; > static void *gic_icenabler; > > @@ -108,7 +105,6 @@ static void write_ptimer_ctl(u64 val) > > struct timer_info { > u32 irq; > - u32 irq_flags; > volatile bool irq_received; > u64 (*read_counter)(void); > u64 (*read_cval)(void); > @@ -304,23 +300,9 @@ static void test_ptimer(void) > > static void test_init(void) > { > - const struct fdt_property *prop; > - const void *fdt = dt_fdt(); > - int node, len; > - u32 *data; > - > - node = fdt_node_offset_by_compatible(fdt, -1, "arm,armv8-timer"); > - assert(node >= 0); > - prop = fdt_get_property(fdt, node, "interrupts", &len); > - assert(prop && len == (4 * 3 * sizeof(u32))); > - > - data = (u32 *)prop->data; > - assert(fdt32_to_cpu(data[3]) == 1); > - ptimer_info.irq = fdt32_to_cpu(data[4]); > - ptimer_info.irq_flags = fdt32_to_cpu(data[5]); > - assert(fdt32_to_cpu(data[6]) == 1); > - vtimer_info.irq = fdt32_to_cpu(data[7]); > - vtimer_info.irq_flags = fdt32_to_cpu(data[8]); > + assert(TIMER_PTIMER_IRQ != -1 && TIMER_VTIMER_IRQ != -1); > + ptimer_info.irq = TIMER_PTIMER_IRQ; > + vtimer_info.irq = TIMER_VTIMER_IRQ; > > install_exception_handler(EL1H_SYNC, ESR_EL1_EC_UNKNOWN, ptimer_unsupported_handler); > ptimer_info.read_ctl(); > diff --git a/lib/arm/asm/timer.h b/lib/arm/asm/timer.h > new file mode 100644 > index 000000000000..f75cc67f3ac4 > --- /dev/null > +++ b/lib/arm/asm/timer.h > @@ -0,0 +1,31 @@ > +/* > + * Copyright (C) 2020, Red Hat Inc, Andrew Jones <drjones@xxxxxxxxxx> > + * > + * This work is licensed under the terms of the GNU LGPL, version 2. > + */ > +#ifndef _ASMARM_TIMER_H_ > +#define _ASMARM_TIMER_H_ > + > +#define ARCH_TIMER_CTL_ENABLE (1 << 0) > +#define ARCH_TIMER_CTL_IMASK (1 << 1) > +#define ARCH_TIMER_CTL_ISTATUS (1 << 2) > + > +#ifndef __ASSEMBLY__ > + > +struct timer_state { > + struct { > + u32 irq; > + u32 irq_flags; > + } ptimer; > + struct { > + u32 irq; > + u32 irq_flags; > + } vtimer; > +}; > +extern struct timer_state __timer_state; > + > +#define TIMER_PTIMER_IRQ (__timer_state.ptimer.irq) > +#define TIMER_VTIMER_IRQ (__timer_state.vtimer.irq) > + > +#endif /* !__ASSEMBLY__ */ > +#endif /* _ASMARM_TIMER_H_ */ > diff --git a/lib/arm/setup.c b/lib/arm/setup.c > index 418b4e58a5f8..78562e47c01c 100644 > --- a/lib/arm/setup.c > +++ b/lib/arm/setup.c > @@ -22,6 +22,7 @@ > #include <asm/page.h> > #include <asm/processor.h> > #include <asm/smp.h> > +#include <asm/timer.h> > > #include "io.h" > > @@ -29,6 +30,8 @@ > > extern unsigned long stacktop; > > +struct timer_state __timer_state; > + > char *initrd; > u32 initrd_size; > > @@ -156,6 +159,43 @@ static void mem_init(phys_addr_t freemem_start) > page_alloc_ops_enable(); > } > > +static void timer_save_state(void) > +{ > + const struct fdt_property *prop; > + const void *fdt = dt_fdt(); > + int node, len; > + u32 *data; > + > + node = fdt_node_offset_by_compatible(fdt, -1, "arm,armv8-timer"); > + assert(node >= 0 || node == -FDT_ERR_NOTFOUND); > + > + if (node == -FDT_ERR_NOTFOUND) { > + __timer_state.ptimer.irq = -1; > + __timer_state.vtimer.irq = -1; > + return; > + } > + > + /* > + * From Linux devicetree timer binding documentation > + * > + * interrupts <type irq flags>: > + * secure timer irq > + * non-secure timer irq (ptimer) > + * virtual timer irq (vtimer) > + * hypervisor timer irq > + */ > + prop = fdt_get_property(fdt, node, "interrupts", &len); > + assert(prop && len == (4 * 3 * sizeof(u32))); > + > + data = (u32 *)prop->data; > + assert(fdt32_to_cpu(data[3]) == 1 /* PPI */); > + __timer_state.ptimer.irq = fdt32_to_cpu(data[4]); > + __timer_state.ptimer.irq_flags = fdt32_to_cpu(data[5]); > + assert(fdt32_to_cpu(data[6]) == 1 /* PPI */); > + __timer_state.vtimer.irq = fdt32_to_cpu(data[7]); > + __timer_state.vtimer.irq_flags = fdt32_to_cpu(data[8]); > +} > + > void setup(const void *fdt) > { > void *freemem = &stacktop; > @@ -211,6 +251,8 @@ void setup(const void *fdt) > io_init(); > > /* finish setup */ > + timer_save_state(); > + > ret = dt_get_bootargs(&bootargs); > assert(ret == 0 || ret == -FDT_ERR_NOTFOUND); > setup_args_progname(bootargs); > diff --git a/lib/arm64/asm/timer.h b/lib/arm64/asm/timer.h > new file mode 100644 > index 000000000000..c0f5f88287de > --- /dev/null > +++ b/lib/arm64/asm/timer.h > @@ -0,0 +1 @@ > +#include "../../arm/asm/timer.h" >