arm64: add up_this_task and up_change_task macro impl
Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
parent
a567148888
commit
948ac9b4cc
6 changed files with 34 additions and 52 deletions
|
|
@ -55,7 +55,7 @@
|
|||
|
||||
/****************************************************************************
|
||||
* Name:
|
||||
* read_/write_/zero_ sysreg
|
||||
* read_/write_/zero_/modify_ sysreg
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
|
|
@ -84,6 +84,10 @@
|
|||
::: "memory"); \
|
||||
})
|
||||
|
||||
#define modify_sysreg(v,m,a) \
|
||||
write_sysreg((read_sysreg(a) & ~(m)) | \
|
||||
((uintptr_t)(v) & (m)), a)
|
||||
|
||||
/****************************************************************************
|
||||
* Inline functions
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -387,31 +387,17 @@ static inline void up_irq_restore(irqstate_t flags)
|
|||
#endif /* CONFIG_ARCH_HAVE_MULTICPU */
|
||||
|
||||
/****************************************************************************
|
||||
* Name:
|
||||
* up_current_regs/up_set_current_regs
|
||||
*
|
||||
* Description:
|
||||
* We use the following code to manipulate the tpidr_el1 register,
|
||||
* which exists uniquely for each CPU and is primarily designed to store
|
||||
* current thread information. Currently, we leverage it to store interrupt
|
||||
* information, with plans to further optimize its use for storing both
|
||||
* thread and interrupt information in the future.
|
||||
* Schedule acceleration macros
|
||||
*
|
||||
* The lsbit of tpidr_el1 stores information about whether the current
|
||||
* execution is in an interrupt context, where 1 indicates being in an
|
||||
* interrupt context and 0 indicates being in a thread context.
|
||||
****************************************************************************/
|
||||
|
||||
noinstrument_function
|
||||
static inline_function uint64_t *up_current_regs(void)
|
||||
{
|
||||
uint64_t *regs;
|
||||
__asm__ volatile ("mrs %0, " "tpidr_el1" : "=r" (regs));
|
||||
return regs;
|
||||
}
|
||||
|
||||
noinstrument_function
|
||||
static inline_function void up_set_current_regs(uint64_t *regs)
|
||||
{
|
||||
__asm__ volatile ("msr " "tpidr_el1" ", %0" : : "r" (regs));
|
||||
}
|
||||
#define up_current_regs() (this_task()->xcp.regs)
|
||||
#define up_this_task() ((struct tcb_s *)(read_sysreg(tpidr_el1) & ~1ul))
|
||||
#define up_update_task(t) modify_sysreg(t, ~1ul, tpidr_el1)
|
||||
#define up_interrupt_context() (read_sysreg(tpidr_el1) & 1)
|
||||
|
||||
#define up_switch_context(tcb, rtcb) \
|
||||
do { \
|
||||
|
|
@ -422,19 +408,6 @@ static inline_function void up_set_current_regs(uint64_t *regs)
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_interrupt_context
|
||||
*
|
||||
* Description: Return true is we are currently executing in
|
||||
* the interrupt handler context.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline bool up_interrupt_context(void)
|
||||
{
|
||||
return up_current_regs() != NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_getusrpc
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -113,7 +113,11 @@ static inline void local_delay(void)
|
|||
|
||||
static void arm64_smp_init_top(void)
|
||||
{
|
||||
struct tcb_s *tcb = this_task();
|
||||
struct tcb_s *tcb = current_task(this_cpu());
|
||||
|
||||
/* Init idle task to percpu reg */
|
||||
|
||||
up_update_task(tcb);
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
/* And finally, enable interrupts */
|
||||
|
|
|
|||
|
|
@ -61,13 +61,12 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs)
|
|||
|
||||
/* Nested interrupts are not supported */
|
||||
|
||||
DEBUGASSERT(up_current_regs() == NULL);
|
||||
DEBUGASSERT(!up_interrupt_context());
|
||||
|
||||
/* Current regs non-zero indicates that we are processing an interrupt;
|
||||
* current_regs is also used to manage interrupt level context switches.
|
||||
*/
|
||||
/* Set irq flag */
|
||||
|
||||
write_sysreg((uintptr_t)tcb | 1, tpidr_el1);
|
||||
|
||||
up_set_current_regs(regs);
|
||||
tcb->xcp.regs = regs;
|
||||
|
||||
/* Deliver the IRQ */
|
||||
|
|
@ -110,11 +109,9 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs)
|
|||
regs = tcb->xcp.regs;
|
||||
}
|
||||
|
||||
/* Set current_regs to NULL to indicate that we are no longer in an
|
||||
* interrupt handler.
|
||||
*/
|
||||
/* Clear irq flag */
|
||||
|
||||
up_set_current_regs(NULL);
|
||||
write_sysreg((uintptr_t)tcb & ~1ul, tpidr_el1);
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -541,13 +541,18 @@ static int arm64_exception_handler(uint64_t *regs)
|
|||
|
||||
void arm64_fatal_handler(uint64_t *regs)
|
||||
{
|
||||
struct tcb_s *tcb = this_task();
|
||||
int ret;
|
||||
|
||||
/* Nested exception are not supported */
|
||||
|
||||
DEBUGASSERT(up_current_regs() == NULL);
|
||||
DEBUGASSERT(!up_interrupt_context());
|
||||
|
||||
up_set_current_regs((uint64_t *)regs);
|
||||
tcb->xcp.regs = (uint64_t *)regs;
|
||||
|
||||
/* Set irq flag */
|
||||
|
||||
write_sysreg((uintptr_t)tcb | 1, tpidr_el1);
|
||||
|
||||
ret = arm64_exception_handler(regs);
|
||||
|
||||
|
|
@ -558,11 +563,9 @@ void arm64_fatal_handler(uint64_t *regs)
|
|||
PANIC_WITH_REGS("panic", regs);
|
||||
}
|
||||
|
||||
/* Set CURRENT_REGS to NULL to indicate that we are no longer in an
|
||||
* Exception handler.
|
||||
*/
|
||||
/* Clear irq flag */
|
||||
|
||||
up_set_current_regs(NULL);
|
||||
write_sysreg((uintptr_t)tcb & ~1ul, tpidr_el1);
|
||||
}
|
||||
|
||||
void arm64_register_debug_hook(int nr, fatal_handle_func_t fn)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "arm64_arch.h"
|
||||
#include "arm64_internal.h"
|
||||
#include "chip.h"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue