arch: qemu-rv: Fix timer and IPI handling for BUILD_KERNEL+SMP

Summary:
- I noticed that the OS timer sometimes proceeds fast when
  a task is scheduled to run on CPUO via IPI.
- Actually, qemu-rv implementation shares supervisor software
  interrupt for both timer and IPI on CPU0.
- This commit fixes this issue.

Impact:
- qemu-rv only

Testing:
- Tested with qemu-6.2

Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
This commit is contained in:
Masayuki Ishikawa 2022-10-08 15:51:12 +09:00 committed by Xiang Xiao
parent d8f9c60e9e
commit 4b6c9915fe

View File

@ -48,12 +48,19 @@
#define MTIMER_FREQ 10000000
#define TICK_COUNT (10000000 / TICK_PER_SEC)
#ifdef CONFIG_BUILD_KERNEL
/****************************************************************************
* Private Data
****************************************************************************/
static uint32_t g_mtimer_cnt = 0;
static uint32_t g_stimer_pending = false;
/****************************************************************************
* Private Functions
****************************************************************************/
#ifdef CONFIG_BUILD_KERNEL
/****************************************************************************
* Name: qemu_rv_ssoft_interrupt
*
@ -69,9 +76,23 @@ static int qemu_rv_ssoft_interrupt(int irq, void *context, void *arg)
CLEAR_CSR(sip, SIP_SSIP);
/* Proceed the OS timer */
if (g_stimer_pending)
{
g_stimer_pending = false;
/* Proceed the OS timer */
nxsched_process_timer();
}
#ifdef CONFIG_SMP
else
{
/* We assume IPI has been issued */
riscv_pause_handler(irq, context, arg);
}
#endif
nxsched_process_timer();
return 0;
}
@ -174,6 +195,9 @@ void qemu_rv_mtimer_interrupt(void)
next = current + TICK_COUNT;
putreg64(next, QEMU_RV_CLINT_MTIMECMP);
g_mtimer_cnt++;
g_stimer_pending = true;
/* Post Supervisor Software Interrupt */
SET_CSR(sip, SIP_SSIP);