Profile low condition events.

Add the sleep events point for x86 and ARM arquitectures that gives
information about when the CPU went to sleep mode, when it woke up
and which interrupt causes the CPU to awake.

Change-Id: Iaa06a678eab661357d084ee1f79c4cfcf19bf85d
Signed-off-by: Yonattan Louise <yonattan.a.louise.mendoza@intel.com>
This commit is contained in:
Yonattan Louise 2015-08-21 19:15:26 -05:00 committed by Anas Nashif
commit 5c6ef8fdb5
9 changed files with 64 additions and 0 deletions

View file

@ -18,6 +18,7 @@ CONFIG_XIP=y
# CONFIG_PROFILER_BUFFER_SIZE is not set # CONFIG_PROFILER_BUFFER_SIZE is not set
# CONFIG_PROFILER_CONTEXT_SWITCH is not set # CONFIG_PROFILER_CONTEXT_SWITCH is not set
# CONFIG_PROFILER_INTERRUPT is not set # CONFIG_PROFILER_INTERRUPT is not set
# CONFIG_PROFILER_SLEEP is not set
# #
# Nanokernel Options # Nanokernel Options

View file

@ -134,6 +134,12 @@ SECTION_FUNC(TEXT, _NanoIdleValClear)
*/ */
SECTION_FUNC(TEXT, nano_cpu_idle) SECTION_FUNC(TEXT, nano_cpu_idle)
#ifdef CONFIG_PROFILER_SLEEP
push {lr}
bl _sys_profiler_enter_sleep
pop {lr}
#endif
/* clear BASEPRI so wfi is awakened by incoming interrupts */ /* clear BASEPRI so wfi is awakened by incoming interrupts */
eors.n r0, r0 eors.n r0, r0
msr BASEPRI, r0 msr BASEPRI, r0
@ -169,6 +175,11 @@ SECTION_FUNC(TEXT, nano_cpu_idle)
*/ */
SECTION_FUNC(TEXT, nano_cpu_atomic_idle) SECTION_FUNC(TEXT, nano_cpu_atomic_idle)
#ifdef CONFIG_PROFILER_SLEEP
push {lr}
bl _sys_profiler_enter_sleep
pop {lr}
#endif
/* /*
* r0: interrupt mask from caller * r0: interrupt mask from caller

View file

@ -19,6 +19,7 @@ CONFIG_XIP=y
# CONFIG_PROFILER_BUFFER_SIZE is not set # CONFIG_PROFILER_BUFFER_SIZE is not set
# CONFIG_PROFILER_CONTEXT_SWITCH is not set # CONFIG_PROFILER_CONTEXT_SWITCH is not set
# CONFIG_PROFILER_INTERRUPT is not set # CONFIG_PROFILER_INTERRUPT is not set
# CONFIG_PROFILER_SLEEP is not set
# #
# Nanokernel Options # Nanokernel Options

View file

@ -84,6 +84,9 @@ SECTION_FUNC(TEXT, nano_cpu_idle)
#ifdef CONFIG_INT_LATENCY_BENCHMARK #ifdef CONFIG_INT_LATENCY_BENCHMARK
call _int_latency_stop call _int_latency_stop
#endif #endif
#ifdef CONFIG_PROFILER_SLEEP
call _sys_profiler_enter_sleep
#endif
#if defined(CONFIG_BOOT_TIME_MEASUREMENT) #if defined(CONFIG_BOOT_TIME_MEASUREMENT)
rdtsc /* record idle timestamp */ rdtsc /* record idle timestamp */
mov %eax, __idle_tsc /* ... low 32 bits */ mov %eax, __idle_tsc /* ... low 32 bits */
@ -123,6 +126,9 @@ SECTION_FUNC(TEXT, nano_cpu_idle)
SECTION_FUNC(TEXT, nano_cpu_atomic_idle) SECTION_FUNC(TEXT, nano_cpu_atomic_idle)
#ifdef CONFIG_INT_LATENCY_BENCHMARK #ifdef CONFIG_INT_LATENCY_BENCHMARK
call _int_latency_stop call _int_latency_stop
#endif
#ifdef CONFIG_PROFILER_SLEEP
call _sys_profiler_enter_sleep
#endif #endif
sti /* make sure interrupts are enabled */ sti /* make sure interrupts are enabled */

View file

@ -21,6 +21,7 @@ CONFIG_ENHANCED_SECURITY=y
# CONFIG_PROFILER_BUFFER_SIZE is not set # CONFIG_PROFILER_BUFFER_SIZE is not set
# CONFIG_PROFILER_CONTEXT_SWITCH is not set # CONFIG_PROFILER_CONTEXT_SWITCH is not set
# CONFIG_PROFILER_INTERRUPT is not set # CONFIG_PROFILER_INTERRUPT is not set
# CONFIG_PROFILER_SLEEP is not set
# #
# Security Options # Security Options

View file

@ -49,6 +49,10 @@
#define PROFILER_INTERRUPT_EVENT_ID 0x0002 #define PROFILER_INTERRUPT_EVENT_ID 0x0002
#endif #endif
#ifdef CONFIG_PROFILER_SLEEP
#define PROFILER_SLEEP_EVENT_ID 0x0003
#endif
#ifndef _ASMLANGUAGE #ifndef _ASMLANGUAGE
/** /**
* Global variable of the ring buffer that allows user to implement * Global variable of the ring buffer that allows user to implement

View file

@ -150,6 +150,17 @@ config PROFILER_INTERRUPT
Enable interrupt event messages. These messages provide the following Enable interrupt event messages. These messages provide the following
information: The time when interrupts occur. information: The time when interrupts occur.
config PROFILER_SLEEP
bool
prompt "Sleep profiler point"
default n
depends on KERNEL_PROFILER && ADVANCED_POWER_MANAGEMENT
help
Enable low power condition event messages. These messages provide the
following information:
- When the CPU went to sleep mode.
- When the CPU woke up.
- The ID of the interrupt that woke the CPU up.
endmenu endmenu
menu "Security Options" menu "Security Options"

View file

@ -370,6 +370,10 @@ void _sys_power_save_idle_exit(int32_t ticks)
#else #else
ARG_UNUSED(ticks); ARG_UNUSED(ticks);
#endif /* CONFIG_TICKLESS_IDLE */ #endif /* CONFIG_TICKLESS_IDLE */
#ifdef CONFIG_PROFILER_SLEEP
extern void _sys_profiler_exit_sleep(void);
_sys_profiler_exit_sleep();
#endif
} }
/** /**

View file

@ -46,6 +46,11 @@ uint32_t _sys_profiler_buffer[CONFIG_PROFILER_BUFFER_SIZE];
void *_collector_fiber=NULL; void *_collector_fiber=NULL;
#endif #endif
#ifdef CONFIG_PROFILER_SLEEP
uint32_t _sys_profiler_sleep_start_time;
#endif
/** /**
* @brief Initialize the profiler system. * @brief Initialize the profiler system.
* *
@ -134,3 +139,23 @@ void _sys_profiler_interrupt()
sys_profiler_put(PROFILER_INTERRUPT_EVENT_ID, data, ARRAY_SIZE(data)); sys_profiler_put(PROFILER_INTERRUPT_EVENT_ID, data, ARRAY_SIZE(data));
} }
#endif /* CONFIG_PROFILER_INTERRUPT */ #endif /* CONFIG_PROFILER_INTERRUPT */
#ifdef CONFIG_PROFILER_SLEEP
void _sys_profiler_enter_sleep(void)
{
_sys_profiler_sleep_start_time = nano_cycle_get_32();
}
void _sys_profiler_exit_sleep(void)
{
uint32_t data[3];
data[0] = nano_tick_get_32();
data[1] = (nano_cycle_get_32() - _sys_profiler_sleep_start_time) / sys_clock_hw_cycles_per_tick;
/* register the cause of exiting sleep mode */
data[2] = _sys_current_irq_key_get();
sys_profiler_put(PROFILER_SLEEP_EVENT_ID, data, ARRAY_SIZE(data));
}
#endif /* CONFIG_PROFILER_SLEEP */