Profile interrupt events.
Add the interrupt profile points for x86 and ARM arquitectures. This gives information regarding the time when interrupts occur. Change-Id: Ic876c0e7f9e8819d53e0578416f09146f4456d3d Signed-off-by: Yonattan Louise <yonattan.a.louise.mendoza@intel.com>
This commit is contained in:
parent
46feabf7f7
commit
d2108bf084
12 changed files with 203 additions and 0 deletions
|
@ -17,6 +17,7 @@ CONFIG_XIP=y
|
||||||
# CONFIG_KERNEL_PROFILER is not set
|
# CONFIG_KERNEL_PROFILER is not set
|
||||||
# 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
|
||||||
|
|
||||||
#
|
#
|
||||||
# Nanokernel Options
|
# Nanokernel Options
|
||||||
|
|
|
@ -72,6 +72,12 @@ SECTION_FUNC(TEXT, _isr_wrapper)
|
||||||
|
|
||||||
push {lr} /* lr is now the first item on the stack */
|
push {lr} /* lr is now the first item on the stack */
|
||||||
|
|
||||||
|
#ifdef CONFIG_PROFILER_INTERRUPT
|
||||||
|
push {lr}
|
||||||
|
bl _sys_profiler_interrupt
|
||||||
|
pop {lr}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
|
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
|
||||||
/*
|
/*
|
||||||
* All interrupts are disabled when handling idle wakeup. For tickless
|
* All interrupts are disabled when handling idle wakeup. For tickless
|
||||||
|
|
|
@ -18,6 +18,7 @@ CONFIG_XIP=y
|
||||||
# CONFIG_KERNEL_PROFILER is not set
|
# CONFIG_KERNEL_PROFILER is not set
|
||||||
# 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
|
||||||
|
|
||||||
#
|
#
|
||||||
# Nanokernel Options
|
# Nanokernel Options
|
||||||
|
|
54
arch/arm/include/profiler_arch.h
Normal file
54
arch/arm/include/profiler_arch.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Intel Corporation
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1) Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3) Neither the name of Intel Corporation nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @file
|
||||||
|
* @brief Profiler support for ARM
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PROFILE_ARM_H__
|
||||||
|
#define __PROFILE_ARM_H__
|
||||||
|
|
||||||
|
#include <CortexM/asm_inline_gcc.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the identification of the current interrupt.
|
||||||
|
*
|
||||||
|
* This routine obtain the key of the interrupt that is currently processed
|
||||||
|
* if it is called from a ISR context.
|
||||||
|
*
|
||||||
|
* @return The key of the interrupt that is currently being processed.
|
||||||
|
*/
|
||||||
|
int _sys_current_irq_key_get(void)
|
||||||
|
{
|
||||||
|
return _IpsrGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __PROFILE_ARM_H__ */
|
|
@ -170,6 +170,15 @@ SECTION_FUNC(TEXT, _IntEnt)
|
||||||
popl %eax
|
popl %eax
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PROFILER_INTERRUPT
|
||||||
|
/*
|
||||||
|
* Preserve EAX as it contains the stub return address.
|
||||||
|
*/
|
||||||
|
pushl %eax
|
||||||
|
call _sys_profiler_interrupt
|
||||||
|
popl %eax
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* load %ecx with &_nanokernel */
|
/* load %ecx with &_nanokernel */
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ CONFIG_ENHANCED_SECURITY=y
|
||||||
# CONFIG_KERNEL_PROFILER is not set
|
# CONFIG_KERNEL_PROFILER is not set
|
||||||
# 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
|
||||||
|
|
||||||
#
|
#
|
||||||
# Security Options
|
# Security Options
|
||||||
|
|
54
arch/x86/include/profiler_arch.h
Normal file
54
arch/x86/include/profiler_arch.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Intel Corporation
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1) Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3) Neither the name of Intel Corporation nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @file
|
||||||
|
* @brief Profiler support for x86
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PROFILE_X86_H__
|
||||||
|
#define __PROFILE_X86_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the identification of the current interrupt.
|
||||||
|
*
|
||||||
|
* This routine obtain the key of the interrupt that is currently processed
|
||||||
|
* if it is called from a ISR context.
|
||||||
|
*
|
||||||
|
* @return The key of the interrupt that is currently being processed.
|
||||||
|
*/
|
||||||
|
int _sys_current_irq_key_get(void)
|
||||||
|
{
|
||||||
|
extern int _loapic_isr_vector_get(void);
|
||||||
|
|
||||||
|
return _loapic_isr_vector_get();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __PROFILE_X86_H__ */
|
|
@ -416,3 +416,46 @@ void _loapic_irq_disable(unsigned int irq /* IRQ number of the
|
||||||
*pLvt = *pLvt | LOAPIC_LVT_MASKED;
|
*pLvt = *pLvt | LOAPIC_LVT_MASKED;
|
||||||
irq_unlock(oldLevel);
|
irq_unlock(oldLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find the currently executing interrupt vector, if any
|
||||||
|
*
|
||||||
|
* This routine finds the vector of the interrupt that is being processed.
|
||||||
|
* The ISR (In-Service Register) register contain the vectors of the interrupts
|
||||||
|
* in service. And the higher vector is the indentification of the interrupt
|
||||||
|
* being currently processed.
|
||||||
|
*
|
||||||
|
* ISR registers' offsets:
|
||||||
|
* --------------------
|
||||||
|
* | Offset | bits |
|
||||||
|
* --------------------
|
||||||
|
* | 0100H | 0:31 |
|
||||||
|
* | 0110H | 32:63 |
|
||||||
|
* | 0120H | 64:95 |
|
||||||
|
* | 0130H | 96:127 |
|
||||||
|
* | 0140H | 128:159 |
|
||||||
|
* | 0150H | 160:191 |
|
||||||
|
* | 0160H | 192:223 |
|
||||||
|
* | 0170H | 224:255 |
|
||||||
|
* --------------------
|
||||||
|
*
|
||||||
|
* @return The vector of the interrupt that is currently being processed.
|
||||||
|
*/
|
||||||
|
int _loapic_isr_vector_get(void)
|
||||||
|
{
|
||||||
|
/* pointer to ISR vector table */
|
||||||
|
volatile int *pReg;
|
||||||
|
int block=0;
|
||||||
|
|
||||||
|
while (block < 8) {
|
||||||
|
pReg = (volatile int *)
|
||||||
|
(CONFIG_LOAPIC_BASE_ADDRESS + LOAPIC_ISR + (block * 0x10));
|
||||||
|
if (*pReg) {
|
||||||
|
return (block * 32) + (find_lsb_set(*pReg) - 1);
|
||||||
|
}
|
||||||
|
block++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -263,6 +263,12 @@ void _TIMER_INT_HANDLER(void *unused)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(unused);
|
ARG_UNUSED(unused);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PROFILER_INTERRUPT
|
||||||
|
extern void _sys_profiler_interrupt(void);
|
||||||
|
_sys_profiler_interrupt();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_INT_LATENCY_BENCHMARK
|
#ifdef CONFIG_INT_LATENCY_BENCHMARK
|
||||||
uint32_t value = __scs.systick.val;
|
uint32_t value = __scs.systick.val;
|
||||||
uint32_t delta = __scs.systick.reload - value;
|
uint32_t delta = __scs.systick.reload - value;
|
||||||
|
|
|
@ -45,6 +45,10 @@
|
||||||
#define PROFILER_CONTEXT_SWITCH_EVENT_ID 0x0001
|
#define PROFILER_CONTEXT_SWITCH_EVENT_ID 0x0001
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PROFILER_INTERRUPT
|
||||||
|
#define PROFILER_INTERRUPT_EVENT_ID 0x0002
|
||||||
|
#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
|
||||||
|
|
|
@ -140,6 +140,16 @@ config PROFILER_CONTEXT_SWITCH
|
||||||
depends on KERNEL_PROFILER
|
depends on KERNEL_PROFILER
|
||||||
help
|
help
|
||||||
Enable the context switch event messages.
|
Enable the context switch event messages.
|
||||||
|
|
||||||
|
config PROFILER_INTERRUPT
|
||||||
|
bool
|
||||||
|
prompt "Interrupt profiler point"
|
||||||
|
default n
|
||||||
|
depends on KERNEL_PROFILER
|
||||||
|
help
|
||||||
|
Enable interrupt event messages. These messages provide the following
|
||||||
|
information: The time when interrupts occur.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "Security Options"
|
menu "Security Options"
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <nano_private.h>
|
#include <nano_private.h>
|
||||||
|
#include <profiler_arch.h>
|
||||||
|
|
||||||
uint32_t _sys_profiler_buffer[CONFIG_PROFILER_BUFFER_SIZE];
|
uint32_t _sys_profiler_buffer[CONFIG_PROFILER_BUFFER_SIZE];
|
||||||
|
|
||||||
|
@ -120,3 +121,16 @@ void sys_profiler_register_as_collector(void)
|
||||||
_collector_fiber = _nanokernel.current;
|
_collector_fiber = _nanokernel.current;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PROFILER_CONTEXT_SWITCH */
|
#endif /* CONFIG_PROFILER_CONTEXT_SWITCH */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_PROFILER_INTERRUPT
|
||||||
|
void _sys_profiler_interrupt()
|
||||||
|
{
|
||||||
|
uint32_t data[2];
|
||||||
|
|
||||||
|
data[0] = nano_tick_get_32();
|
||||||
|
data[1] = _sys_current_irq_key_get();
|
||||||
|
|
||||||
|
sys_profiler_put(PROFILER_INTERRUPT_EVENT_ID, data, ARRAY_SIZE(data));
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PROFILER_INTERRUPT */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue