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
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER
|
||||||
struct note_filter_irq_s irq_mask;
|
struct note_filter_irq_s irq_mask;
|
||||||
#endif
|
#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
|
#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;
|
return enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: sysview_isenabled_irqhandler
|
* Name: sysview_isenabled_irq
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Check whether the interrupt handler instrumentation is enabled.
|
* Check whether the interrupt handler instrumentation is enabled.
|
||||||
@ -197,6 +214,44 @@ static bool sysview_isenabled_irq(int irq, bool enter)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -310,6 +365,58 @@ void sched_note_irqhandler(int irq, FAR void *handler, bool enter)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
* Name: sysview_get_interrupt_id
|
||||||
*
|
*
|
||||||
@ -490,4 +597,50 @@ void sched_note_filter_irq(struct note_filter_irq_s *oldf,
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
||||||
|
|
||||||
|
#endif /* CONFIG_SCHED_INSTRUMENTATION_FILTER */
|
||||||
|
Loading…
Reference in New Issue
Block a user