arm: tegra: Add traces for SecureOS measurements
Charles Tan [Fri, 26 Oct 2012 23:26:27 +0000 (16:26 -0700)]
These tracepoints are used to measure SecureOS-related latency
using the microseconds timer when entering/exiting LP0, LP1,
and LP2.

Bug 1042455

Signed-off-by: Charles Tan <ctan@nvidia.com>
Change-Id: I6ccc3e3a7b8126bae4fcf2366d3ae7c72d48d7cf
Reviewed-on: http://git-master/r/159372
Reviewed-by: Mrutyunjay Sawant <msawant@nvidia.com>
Tested-by: Mrutyunjay Sawant <msawant@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User

arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/headsmp.S
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/sleep.h
include/trace/events/nvsecurity.h

index 0e91f03..810d4b0 100644 (file)
@@ -35,6 +35,8 @@
 #include <linux/dma-mapping.h>
 #include <linux/sys_soc.h>
 
+#include <trace/events/nvsecurity.h>
+
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/system.h>
 #include <asm/dma-mapping.h>
@@ -347,7 +349,9 @@ void tegra_init_cache(bool init)
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
        /* issue the SMC to enable the L2 */
        aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
+       trace_smc_init_cache(NVSEC_SMC_START);
        tegra_cache_smc(true, aux_ctrl);
+       trace_smc_init_cache(NVSEC_SMC_DONE);
 
        /* after init, reread aux_ctrl and register handlers */
        aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
index f2b0156..a7ec6dc 100644 (file)
@@ -73,6 +73,13 @@ ENDPROC(tegra_secondary_startup)
  *       re-enabling sdram.
  */
 ENTRY(tegra_resume)
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+       mov32   r1, TEGRA_TMRUS_BASE
+       ldr     r0, [r1]
+       adr     r1, tegra_resume_entry_time
+       str     r0, [r1]
+#endif
+
        bl      __invalidate_cpu_state
 
        cpu_id  r0
@@ -101,12 +108,39 @@ ENTRY(tegra_resume)
 #endif
 
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
+       mov32   r1, TEGRA_TMRUS_BASE
+       ldr     r0, [r1]
+       adr     r1, tegra_resume_smc_entry_time
+       str     r0, [r1]
+
        /* wake up (should have specified args?) */
        bl      tegra_generic_smc
+
+       mov32   r1, TEGRA_TMRUS_BASE
+       ldr     r0, [r1]
+       adr     r1, tegra_resume_smc_exit_time
+       str     r0, [r1]
 #endif
 
        b       cpu_resume
 ENDPROC(tegra_resume)
+
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+       .globl tegra_resume_timestamps_start
+       .globl tegra_resume_smc_entry_time
+       .globl tegra_resume_smc_exit_time
+       .globl tegra_resume_entry_time
+       .globl tegra_resume_timestamps_end
+tegra_resume_timestamps_start:
+tegra_resume_smc_entry_time:
+       .long   0
+tegra_resume_smc_exit_time:
+       .long   0
+tegra_resume_entry_time:
+       .long   0
+tegra_resume_timestamps_end:
+ENTRY(__tegra_resume_timestamps_end)
+#endif
 #endif
 
 /*
index ca9da59..1269d3e 100644 (file)
@@ -46,6 +46,9 @@
 #include <linux/console.h>
 #include <linux/tegra_audio.h>
 
+#include <trace/events/power.h>
+#include <trace/events/nvsecurity.h>
+
 #include <asm/cacheflush.h>
 #include <asm/idmap.h>
 #include <asm/localtimer.h>
@@ -74,7 +77,6 @@
 #include "dvfs.h"
 #include "cpu-tegra.h"
 
-#include <trace/events/nvpower.h>
 #define CREATE_TRACE_POINTS
 #include <trace/events/nvpower.h>
 
@@ -546,14 +548,23 @@ static void tegra_sleep_core(enum tegra_suspend_mode mode,
                             unsigned long v2p)
 {
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
+       outer_flush_range(__pa(&tegra_resume_timestamps_start),
+                         __pa(&tegra_resume_timestamps_end));
+
        if (mode == TEGRA_SUSPEND_LP0) {
+               trace_smc_sleep_core(NVSEC_SMC_START);
+
                tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE3,
                                  virt_to_phys(tegra_resume));
        } else {
+               trace_smc_sleep_core(NVSEC_SMC_START);
+
                tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE6,
                                  (TEGRA_RESET_HANDLER_BASE +
                                   tegra_cpu_reset_handler_offset));
        }
+
+       trace_smc_sleep_core(NVSEC_SMC_DONE);
 #endif
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
        cpu_suspend(v2p, tegra2_sleep_core_finish);
@@ -565,9 +576,15 @@ static void tegra_sleep_core(enum tegra_suspend_mode mode,
 static inline void tegra_sleep_cpu(unsigned long v2p)
 {
 #ifdef CONFIG_TRUSTED_FOUNDATIONS
+       outer_flush_range(__pa(&tegra_resume_timestamps_start),
+                         __pa(&tegra_resume_timestamps_end));
+       trace_smc_sleep_cpu(NVSEC_SMC_START);
+
        tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE4,
                          (TEGRA_RESET_HANDLER_BASE +
                           tegra_cpu_reset_handler_offset));
+
+       trace_smc_sleep_cpu(NVSEC_SMC_DONE);
 #endif
        cpu_suspend(v2p, tegra_sleep_cpu_finish);
 }
@@ -666,6 +683,12 @@ unsigned int tegra_idle_power_down_last(unsigned int sleep_time,
        tegra_sleep_cpu(PHYS_OFFSET - PAGE_OFFSET);
 
        tegra_init_cache(false);
+
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+       trace_smc_wake(tegra_resume_smc_entry_time, NVSEC_SMC_START);
+       trace_smc_wake(tegra_resume_smc_exit_time, NVSEC_SMC_DONE);
+#endif
+
        tegra_cluster_switch_time(flags, tegra_cluster_switch_time_id_switch);
        restore_cpu_complex(flags);
        cpu_cluster_pm_exit();
@@ -973,6 +996,16 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags)
 
        tegra_init_cache(true);
 
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+       trace_smc_wake(tegra_resume_smc_entry_time, NVSEC_SMC_START);
+       trace_smc_wake(tegra_resume_smc_exit_time, NVSEC_SMC_DONE);
+
+       if (mode == TEGRA_SUSPEND_LP0) {
+               trace_secureos_init(tegra_resume_entry_time,
+                       NVSEC_SUSPEND_EXIT_DONE);
+       }
+#endif
+
        if (mode == TEGRA_SUSPEND_LP0) {
 
                /* CPUPWRGOOD_EN is not enabled in HW so disabling this, *
index 045fd1f..00d284f 100644 (file)
@@ -266,6 +266,14 @@ int tegra3_sleep_core_finish(unsigned long int);
 int tegra3_sleep_cpu_secondary_finish(unsigned long int);
 #endif
 
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+extern unsigned long tegra_resume_timestamps_start;
+extern unsigned long tegra_resume_timestamps_end;
+extern unsigned long tegra_resume_smc_entry_time;
+extern unsigned long tegra_resume_smc_exit_time;
+extern unsigned long tegra_resume_entry_time;
+#endif
+
 static inline void *tegra_iram_start(void)
 {
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
index 25e90a9..ca059af 100644 (file)
@@ -74,18 +74,40 @@ DEFINE_EVENT(usec_profiling, smc_init_cache,
        TP_ARGS(state)
 );
 
-DEFINE_EVENT(usec_profiling, smc_wake,
+DECLARE_EVENT_CLASS(cntr_profiling,
 
-       TP_PROTO(unsigned long state),
+       TP_PROTO(unsigned long counter, unsigned long state),
 
-       TP_ARGS(state)
+       TP_ARGS(counter, state),
+
+       TP_STRUCT__entry(
+               __field(u32, counter)
+               __field(u32, state)
+       ),
+
+       TP_fast_assign(
+               __entry->counter = counter;
+               __entry->state = state;
+       ),
+
+       TP_printk("counter=%lu, state=%lu",
+               (unsigned long)__entry->counter,
+               (unsigned long)__entry->state
+       )
 );
 
-DEFINE_EVENT(usec_profiling, secureos_init,
+DEFINE_EVENT(cntr_profiling, smc_wake,
 
-       TP_PROTO(unsigned long state),
+       TP_PROTO(unsigned long counter, unsigned long state),
 
-       TP_ARGS(state)
+       TP_ARGS(counter, state)
+);
+
+DEFINE_EVENT(cntr_profiling, secureos_init,
+
+       TP_PROTO(unsigned long counter, unsigned long state),
+
+       TP_ARGS(counter, state)
 );
 
 extern u32 notrace tegra_read_cycle(void);