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_PROFILER_BUFFER_SIZE is not set
|
||||
# CONFIG_PROFILER_CONTEXT_SWITCH is not set
|
||||
# CONFIG_PROFILER_INTERRUPT is not set
|
||||
|
||||
#
|
||||
# Nanokernel Options
|
||||
|
|
|
@ -72,6 +72,12 @@ SECTION_FUNC(TEXT, _isr_wrapper)
|
|||
|
||||
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
|
||||
/*
|
||||
* All interrupts are disabled when handling idle wakeup. For tickless
|
||||
|
|
|
@ -18,6 +18,7 @@ CONFIG_XIP=y
|
|||
# CONFIG_KERNEL_PROFILER is not set
|
||||
# CONFIG_PROFILER_BUFFER_SIZE is not set
|
||||
# CONFIG_PROFILER_CONTEXT_SWITCH is not set
|
||||
# CONFIG_PROFILER_INTERRUPT is not set
|
||||
|
||||
#
|
||||
# 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
|
||||
#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 */
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ CONFIG_ENHANCED_SECURITY=y
|
|||
# CONFIG_KERNEL_PROFILER is not set
|
||||
# CONFIG_PROFILER_BUFFER_SIZE is not set
|
||||
# CONFIG_PROFILER_CONTEXT_SWITCH is not set
|
||||
# CONFIG_PROFILER_INTERRUPT is not set
|
||||
|
||||
#
|
||||
# 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;
|
||||
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);
|
||||
|
||||
#ifdef CONFIG_PROFILER_INTERRUPT
|
||||
extern void _sys_profiler_interrupt(void);
|
||||
_sys_profiler_interrupt();
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_INT_LATENCY_BENCHMARK
|
||||
uint32_t value = __scs.systick.val;
|
||||
uint32_t delta = __scs.systick.reload - value;
|
||||
|
|
|
@ -45,6 +45,10 @@
|
|||
#define PROFILER_CONTEXT_SWITCH_EVENT_ID 0x0001
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PROFILER_INTERRUPT
|
||||
#define PROFILER_INTERRUPT_EVENT_ID 0x0002
|
||||
#endif
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
/**
|
||||
* Global variable of the ring buffer that allows user to implement
|
||||
|
|
|
@ -140,6 +140,16 @@ config PROFILER_CONTEXT_SWITCH
|
|||
depends on KERNEL_PROFILER
|
||||
help
|
||||
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
|
||||
|
||||
menu "Security Options"
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <misc/util.h>
|
||||
#include <init.h>
|
||||
#include <nano_private.h>
|
||||
#include <profiler_arch.h>
|
||||
|
||||
uint32_t _sys_profiler_buffer[CONFIG_PROFILER_BUFFER_SIZE];
|
||||
|
||||
|
@ -120,3 +121,16 @@ void sys_profiler_register_as_collector(void)
|
|||
_collector_fiber = _nanokernel.current;
|
||||
}
|
||||
#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