RE: [PATCH] OMAP GPTimer for OProfile(Errata#628216)

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

 



Tarun,
> -----Original Message-----
> From: linux-omap-owner@xxxxxxxxxxxxxxx [mailto:linux-omap-owner@xxxxxxxxxxxxxxx] On Behalf Of
> Manjunatha GK
> Sent: Thursday, April 01, 2010 8:54 PM
> To: linux-omap@xxxxxxxxxxxxxxx
> Cc: DebBarma, Tarun Kanti; Siarhei Siamashka; G, Manjunath Kondaiah
> Subject: [PATCH] OMAP GPTimer for OProfile(Errata#628216)
> 
> From: DebBarma, Tarun Kanti <tarun.kanti@xxxxxx>
> 
> [ARM Cortex-A8 Errata 628216]
> If a Perf Counter OVFL occurs simultaneously with an update to a CP14 or
> CP15 register, the OVFL status can be lost.
> 
> In order to workaround problem in Cortex-A8 Performance Counter, OMAP
> GPTIMER is used by OProfile.
> 
> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@xxxxxx>
> Cc: Siarhei Siamashka <siarhei.siamashka@xxxxxxxxx>
> Cc: Manjunatha GK <manjugk@xxxxxx>
> ---
>  arch/arm/Kconfig                          |   59 +++++++++++++++---
>  arch/arm/oprofile/Makefile                |    1 +
>  arch/arm/oprofile/common.c                |    4 +
>  arch/arm/oprofile/op_arm_model.h          |    1 +
>  arch/arm/oprofile/op_model_omap_gptimer.c |   96 +++++++++++++++++++++++++++++
>  5 files changed, 153 insertions(+), 8 deletions(-)
>  create mode 100644 arch/arm/oprofile/op_model_omap_gptimer.c
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 410d3e3..a753c8c 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -175,27 +175,70 @@ config ARM_L1_CACHE_SHIFT_6
>  	help
>  	  Setting ARM L1 cache line size to 64 Bytes.
> 
> -if OPROFILE
> +menuconfig INSTRUMENTATION
> +	bool	"Instrumentation Support"
> +	default y
> +	---help---
> +	  Say Y here to get to see options related to performance measurement,
> +	  system-wide debugging and testing. This option alone does not add any
> +	  kernel code.
> +
> +	  If you say N, all options in this submenu will be skipped and
> +	  disabled. If you're trying to debug the kernel itself, check the
> +	  Kernel Hacking menu.
> +
> +if INSTRUMENTATION
> +
> +config PROFILING
> +	bool "Profiling support"
> +	help
> +	  Say Y here to enable the extended profiling support mechanisms
> +	  used by profilers such as OProfile.
> +
> +config OPROFILE
> +	tristate "OProfile system profiling"
> +	depends on PROFILING
> +	help
> +	  OProfile is a profiling system capable of profiling the
> +	  whole system, including the kernel, kernel modules, libraries,
> +	  and applications.
> +
> +	  If unsure, say N.
> +choice
> +        prompt "Oprofile Mode"
> +        depends on OPROFILE
> +        default OPROFILE_OMAP_GPTIMER
> 
>  config OPROFILE_ARMV6
> -	def_bool y
> +	bool "Oprofile ARMv6"
>  	depends on CPU_V6 && !SMP
>  	select OPROFILE_ARM11_CORE
> 
>  config OPROFILE_MPCORE
> -	def_bool y
> +	bool "Oprofile MPcore"
>  	depends on CPU_V6 && SMP
>  	select OPROFILE_ARM11_CORE
> 
> -config OPROFILE_ARM11_CORE
> -	bool
> -
>  config OPROFILE_ARMV7
> -	def_bool y
> +	bool "Oprofile ARMv7"
>  	depends on CPU_V7 && !SMP
> +	help
> +	  Uses Performance counters for profiling
> +
> +config OPROFILE_OMAP_GPTIMER
> +	bool "Oprofile GPTimer"
> +	depends on ARCH_OMAP
> +	select OMAP_32K_TIMER
> +	select OMAP_DM_TIMER
> +	help
> +	  Uses GPTIMER for profiling. Currently this is the preferred
> +	  way since Performance counters have known bugs in Cortex-A8
> +endchoice
> +
> +config OPROFILE_ARM11_CORE
>  	bool
> 
> -endif
> +endif # INSTRUMENTATION

Do you need so many KConfig entries??
>  config VECTORS_BASE
>  	hex
> diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
> index 88e31f5..fc2bc02 100644
> --- a/arch/arm/oprofile/Makefile
> +++ b/arch/arm/oprofile/Makefile
> @@ -8,6 +8,7 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
> 
>  oprofile-y				:= $(DRIVER_OBJS) common.o backtrace.o
>  oprofile-$(CONFIG_CPU_XSCALE)		+= op_model_xscale.o
> +oprofile-$(CONFIG_OPROFILE_OMAP_GPTIMER)	+= op_model_omap_gptimer.o
>  oprofile-$(CONFIG_OPROFILE_ARM11_CORE)	+= op_model_arm11_core.o
>  oprofile-$(CONFIG_OPROFILE_ARMV6)	+= op_model_v6.o
>  oprofile-$(CONFIG_OPROFILE_MPCORE)	+= op_model_mpcore.o
> diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
> index 3fcd752..9eb2b9b 100644
> --- a/arch/arm/oprofile/common.c
> +++ b/arch/arm/oprofile/common.c
> @@ -133,6 +133,10 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
> 
>  	ops->backtrace = arm_backtrace;
> 
> +#ifdef CONFIG_OPROFILE_OMAP_GPTIMER
> +	spec = &op_omap_gptimer_spec;
> +#endif
> +
>  #ifdef CONFIG_CPU_XSCALE
>  	spec = &op_xscale_spec;
>  #endif
> diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
> index 8c4e4f6..55f22e4 100644
> --- a/arch/arm/oprofile/op_arm_model.h
> +++ b/arch/arm/oprofile/op_arm_model.h
> @@ -24,6 +24,7 @@ struct op_arm_model_spec {
>  extern struct op_arm_model_spec op_xscale_spec;
>  #endif
> 
> +extern struct op_arm_model_spec op_omap_gptimer_spec;
>  extern struct op_arm_model_spec op_armv6_spec;
>  extern struct op_arm_model_spec op_mpcore_spec;
>  extern struct op_arm_model_spec op_armv7_spec;
> diff --git a/arch/arm/oprofile/op_model_omap_gptimer.c b/arch/arm/oprofile/op_model_omap_gptimer.c
> new file mode 100644
> index 0000000..49bab30
> --- /dev/null
> +++ b/arch/arm/oprofile/op_model_omap_gptimer.c
> @@ -0,0 +1,96 @@
> +/**
> + * OMAP gptimer based event monitor driver for oprofile
> + *
> + * Copyright (C) 2009 Nokia Corporation
> + * Author: Siarhei Siamashka <siarhei.siamashka@xxxxxxxxx>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/types.h>
> +#include <linux/oprofile.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <plat/dmtimer.h>
> +
> +#include "op_counter.h"
> +#include "op_arm_model.h"
> +
> +static struct omap_dm_timer *gptimer;
> +
> +static int gptimer_init(void)
> +{
> +	return 0;
> +}
> +
> +static int gptimer_setup(void)
> +{
> +	return 0;
> +}
> +
> +static irqreturn_t gptimer_interrupt(int irq, void *arg)
> +{
> +	omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW);
> +	oprofile_add_sample(get_irq_regs(), 0);
> +	return IRQ_HANDLED;
> +}
> +
> +static int gptimer_start(void)
> +{
> +	int err;
> +	u32 count = counter_config[0].count;
> +
> +	BUG_ON(gptimer != NULL);
> +	/* First try to request timers from CORE power domain for OMAP3 */
If any timer is ok, why specific timer ?

> +	if (cpu_is_omap34xx()) {
> +		gptimer = omap_dm_timer_request_specific(10);
> +		if (gptimer == NULL)
> +			gptimer = omap_dm_timer_request_specific(11);
> +	}
> +	/* Just any timer would be fine */
> +	if (gptimer == NULL)
> +		gptimer = omap_dm_timer_request();
> +
> +	if (gptimer == NULL)
> +		return -ENODEV;
> +
> +	omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ);
With Sys clock this can give better resolution o.w any accuracy below ~30 uS is lost.

> +	err = request_irq(omap_dm_timer_get_irq(gptimer), gptimer_interrupt,
> +				IRQF_DISABLED, "oprofile gptimer", NULL);
> +	if (err) {
> +		omap_dm_timer_free(gptimer);
> +		gptimer = NULL;
> +		printk(KERN_ERR "oprofile: unable to request gptimer IRQ\n");
> +		return err;
> +	}
> +
> +	/* opcontrol sets default value as 100000 which makes the sample rate
> +	 * too low, hence resetting
> +	 */
> +	if ((count < 0) || (count == 100000))
> +		count = 1;
> +
> +	omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - count);
> +	omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
> +	return 0;
> +}
> +
> +static void gptimer_stop(void)
> +{
> +	omap_dm_timer_set_int_enable(gptimer, 0);
> +	free_irq(omap_dm_timer_get_irq(gptimer), NULL);
> +	omap_dm_timer_free(gptimer);
> +	gptimer = NULL;
> +}
> +
> +struct op_arm_model_spec op_omap_gptimer_spec = {
> +	.init		= gptimer_init,
> +	.num_counters	= 1,
> +	.setup_ctrs	= gptimer_setup,
> +	.start		= gptimer_start,
> +	.stop		= gptimer_stop,
> +	.name		= "arm/armv6",
This is done for Cortex-A8 right which is armv7
> +};
> --
> 1.6.0.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux