segger/sysview: add syscall support
Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
871291477a
commit
d6bbe4f6a5
@ -47,6 +47,10 @@ struct sysview_s
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
|
||||
struct note_filter_irq_s irq_mask;
|
||||
#endif
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
|
||||
struct note_filter_syscall_s syscall_mask;
|
||||
struct note_filter_syscall_s syscall_marker;
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -155,11 +159,24 @@ static bool sysview_isenabled(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
|
||||
/* Use the Syscall "0" to identify whether the syscall is enabled,
|
||||
* if the host tool is closed abnormally, use this bit to clear
|
||||
* the active set.
|
||||
*/
|
||||
|
||||
if (!enable &&
|
||||
NOTE_FILTER_SYSCALLMASK_ISSET(0, &g_sysview.syscall_marker))
|
||||
{
|
||||
NOTE_FILTER_SYSCALLMASK_ZERO(&g_sysview.syscall_marker);
|
||||
}
|
||||
#endif
|
||||
|
||||
return enable;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sysview_isenabled_irqhandler
|
||||
* Name: sysview_isenabled_irq
|
||||
*
|
||||
* Description:
|
||||
* Check whether the interrupt handler instrumentation is enabled.
|
||||
@ -197,6 +214,44 @@ static bool sysview_isenabled_irq(int irq, bool enter)
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sysview_isenabled_syscall
|
||||
*
|
||||
* Description:
|
||||
* Check whether the syscall instrumentation is enabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
* nr - syscall number
|
||||
*
|
||||
* Returned Value:
|
||||
* True is returned if the instrumentation is enabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
|
||||
static inline int sysview_isenabled_syscall(int nr)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_FILTER
|
||||
if (!sysview_isenabled())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the syscall trace is disabled or the syscall number is masked,
|
||||
* do nothing.
|
||||
*/
|
||||
|
||||
if ((g_sysview.mode.flag & NOTE_FILTER_MODE_FLAG_SYSCALL) == 0 ||
|
||||
NOTE_FILTER_SYSCALLMASK_ISSET(nr, &g_sysview.syscall_mask))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -310,6 +365,58 @@ void sched_note_irqhandler(int irq, FAR void *handler, bool enter)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
|
||||
void sched_note_syscall_enter(int nr, int argc, ...)
|
||||
{
|
||||
nr -= CONFIG_SYS_RESERVED;
|
||||
|
||||
if (sysview_isenabled_syscall(nr) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the name marker if the current syscall nr is not active */
|
||||
|
||||
if (NOTE_FILTER_SYSCALLMASK_ISSET(nr, &g_sysview.syscall_marker) == 0)
|
||||
{
|
||||
/* Set the name marker */
|
||||
|
||||
SEGGER_SYSVIEW_NameMarker(nr, g_funcnames[nr]);
|
||||
|
||||
/* Mark the syscall active */
|
||||
|
||||
NOTE_FILTER_SYSCALLMASK_SET(nr, &g_sysview.syscall_marker);
|
||||
|
||||
/* Use the Syscall "0" to identify whether the syscall is enabled,
|
||||
* if the host tool is closed abnormally, use this bit to clear
|
||||
* the active set.
|
||||
*/
|
||||
|
||||
if (NOTE_FILTER_SYSCALLMASK_ISSET(0, &g_sysview.syscall_marker) == 0)
|
||||
{
|
||||
NOTE_FILTER_SYSCALLMASK_SET(0, &g_sysview.syscall_marker);
|
||||
}
|
||||
}
|
||||
|
||||
SEGGER_SYSVIEW_MarkStart(nr);
|
||||
}
|
||||
|
||||
void sched_note_syscall_leave(int nr, uintptr_t result)
|
||||
{
|
||||
nr -= CONFIG_SYS_RESERVED;
|
||||
|
||||
if (sysview_isenabled_syscall(nr) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (NOTE_FILTER_SYSCALLMASK_ISSET(nr, &g_sysview.syscall_marker) != 0)
|
||||
{
|
||||
SEGGER_SYSVIEW_MarkStop(nr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sysview_get_interrupt_id
|
||||
*
|
||||
@ -490,4 +597,50 @@ void sched_note_filter_irq(struct note_filter_irq_s *oldf,
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sched_note_filter_syscall
|
||||
*
|
||||
* Description:
|
||||
* Set and get syscall filter setting
|
||||
* (Same as NOTECTL_GETSYSCALLFILTER / NOTECTL_SETSYSCALLFILTER ioctls)
|
||||
*
|
||||
* Input Parameters:
|
||||
* oldf - A writable pointer to struct note_filter_syscall_s to get
|
||||
* current syscall filter setting
|
||||
* If 0, no data is written.
|
||||
* newf - A read-only pointer to struct note_filter_syscall_s of the
|
||||
* new syscall filter setting
|
||||
* If 0, the setting is not updated.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_SYSCALL
|
||||
void sched_note_filter_syscall(struct note_filter_syscall_s *oldf,
|
||||
struct note_filter_syscall_s *newf)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
|
||||
if (oldf != NULL)
|
||||
{
|
||||
/* Return the current filter setting */
|
||||
|
||||
*oldf = g_sysview.syscall_mask;
|
||||
}
|
||||
|
||||
if (newf != NULL)
|
||||
{
|
||||
/* Replace the syscall filter mask by the provided setting */
|
||||
|
||||
g_sysview.syscall_mask = *newf;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_SCHED_INSTRUMENTATION_FILTER */
|
||||
|
Loading…
Reference in New Issue
Block a user