Skip to content

Commit

Permalink
arm64: add up_this_task and up_change_task macro impl
Browse files Browse the repository at this point in the history
Signed-off-by: hujun5 <hujun5@xiaomi.com>
  • Loading branch information
hujun260 committed Oct 10, 2024
1 parent 17fe847 commit 6a83100
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 68 deletions.
34 changes: 17 additions & 17 deletions arch/arm64/include/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@

/****************************************************************************
* Name:
* read_/write_/zero_ sysreg
* read_/write_/zero_/modify_ sysreg
*
* Description:
*
Expand All @@ -64,25 +64,25 @@
*
****************************************************************************/

#define read_sysreg(reg) \
({ \
uint64_t __val; \
__asm__ volatile ("mrs %0, " STRINGIFY(reg) \
: "=r" (__val) :: "memory"); \
__val; \
#define read_sysreg(reg) \
({ \
uint64_t __val; \
__asm__ volatile ("mrs %0, " STRINGIFY(reg) \
: "=r" (__val) :: "memory"); \
__val; \
})

#define write_sysreg(__val, reg) \
({ \
__asm__ volatile ("msr " STRINGIFY(reg) ", %0" \
: : "r" (__val) : "memory"); \
})
#define write_sysreg(__val, reg) \
__asm__ volatile ("msr " STRINGIFY(reg) ", %0" \
:: "r" (__val) : "memory")

#define zero_sysreg(reg) \
({ \
__asm__ volatile ("msr " STRINGIFY(reg) ", xzr" \
::: "memory"); \
})
#define zero_sysreg(reg) \
__asm__ volatile ("msr " STRINGIFY(reg) ", xzr" \
::: "memory")

#define modify_sysreg(v,m,a) \
write_sysreg((read_sysreg(a) & ~(m)) | \
((uintptr_t)(v) & (m)), a)

/****************************************************************************
* Inline functions
Expand Down
43 changes: 8 additions & 35 deletions arch/arm64/include/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,31 +377,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 { \
Expand All @@ -412,19 +398,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
****************************************************************************/
Expand Down
6 changes: 5 additions & 1 deletion arch/arm64/src/common/arm64_cpustart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
15 changes: 6 additions & 9 deletions arch/arm64/src/common/arm64_doirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
}
Expand Down
15 changes: 9 additions & 6 deletions arch/arm64/src/common/arm64_fatal.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,13 +544,18 @@ static int arm64_exception_handler(struct regs_context *regs)

void arm64_fatal_handler(struct regs_context *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);

Expand All @@ -561,11 +566,9 @@ void arm64_fatal_handler(struct regs_context *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)
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/src/common/arm64_registerdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 6a83100

Please sign in to comment.