Re: [PATCH kvm-unit-tests] arm/arm64: timer: Extract irqs at setup time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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"
> 




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux