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:
parent
d2108bf084
commit
5c6ef8fdb5
9 changed files with 64 additions and 0 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue