arm64: g_current_regs is only used to determine if we are in irq, with other functionalities removed.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
hujun5 2024-07-05 20:53:49 +08:00 committed by Xiang Xiao
parent d573952790
commit 8cd52bee2e
5 changed files with 35 additions and 221 deletions

View File

@ -116,11 +116,7 @@ int up_cpu_paused_save(void)
sched_note_cpu_paused(tcb);
#endif
/* Save the current context at current_regs into the TCB at the head
* of the assigned task list for this CPU.
*/
arm64_savestate(tcb->xcp.regs);
UNUSED(tcb);
return OK;
}
@ -210,11 +206,7 @@ int up_cpu_paused_restore(void)
nxsched_resume_scheduler(tcb);
/* Then switch contexts. Any necessary address environment changes
* will be made when the interrupt returns.
*/
arm64_restorestate(tcb->xcp.regs);
UNUSED(tcb);
return OK;
}

View File

@ -57,6 +57,8 @@
uint64_t *arm64_doirq(int irq, uint64_t * regs)
{
struct tcb_s *tcb = this_task();
/* Nested interrupts are not supported */
DEBUGASSERT(up_current_regs() == NULL);
@ -66,10 +68,12 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs)
*/
up_set_current_regs(regs);
tcb->xcp.regs = regs;
/* Deliver the IRQ */
irq_dispatch(irq, regs);
tcb = this_task();
/* Check for a context switch. If a context switch occurred, then
* current_regs will have a different value than it did on entry. If an
@ -78,7 +82,7 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs)
* returning from the interrupt.
*/
if (regs != up_current_regs())
if (regs != tcb->xcp.regs)
{
/* need to do a context switch */
@ -97,8 +101,8 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs)
* crashes.
*/
g_running_tasks[this_cpu()] = this_task();
regs = up_current_regs();
g_running_tasks[this_cpu()] = tcb;
regs = tcb->xcp.regs;
}
/* Set current_regs to NULL to indicate that we are no longer in an

View File

@ -84,13 +84,6 @@
# define CONFIG_ARCH_INTERRUPTSTACK 0
#endif
/* If the floating point unit is present and enabled, then save the
* floating point registers as well as normal ARM registers.
*/
#define arm64_savestate(regs) (regs = up_current_regs())
#define arm64_restorestate(regs) up_set_current_regs(regs)
/* This is the value used to mark the stack for subsequent stack monitoring
* logic.
*/

View File

@ -126,99 +126,8 @@ void arm64_init_signal_process(struct tcb_s *tcb, struct regs_context *regs)
*
****************************************************************************/
#ifndef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
/* Refuse to handle nested signal actions */
if (!tcb->xcp.sigdeliver)
{
tcb->xcp.sigdeliver = sigdeliver;
/* First, handle some special cases when the signal is being delivered
* to task that is currently executing on this CPU.
*/
if (tcb == this_task())
{
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
*/
if (!up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: We are in an interrupt handler AND the interrupted
* task is the same as the one that must receive the signal, then
* we will have to modify the return state as well as the state
* in the TCB.
*
* Hmmm... there looks like a latent bug here: The following logic
* would fail in the strange case where we are in an interrupt
* handler, the thread is signaling itself, but a context switch
* to another task has occurred so that current_regs does not
* refer to the thread of this_task()!
*/
else
{
/* Save the return lr and cpsr and one scratch register
* These will be restored by the signal trampoline after
* the signals have been delivered.
*/
/* create signal process context */
tcb->xcp.saved_reg = up_current_regs();
#ifdef CONFIG_ARCH_FPU
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
#endif
arm64_init_signal_process(tcb,
(struct regs_context *)up_current_regs());
/* trigger switch to signal process */
up_set_current_regs(tcb->xcp.regs);
}
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling some other non-running task.
*/
else
{
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
*/
#ifdef CONFIG_ARCH_FPU
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
#endif
/* create signal process context */
tcb->xcp.saved_reg = tcb->xcp.regs;
arm64_init_signal_process(tcb, NULL);
}
}
}
#endif /* !CONFIG_SMP */
#ifdef CONFIG_SMP
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
{
int cpu;
int me;
sinfo("tcb=%p sigdeliver=%p\n", tcb, sigdeliver);
/* Refuse to handle nested signal actions */
@ -231,109 +140,29 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
* to task that is currently executing on any CPU.
*/
sinfo("rtcb=%p current_regs=%p\n", this_task(), up_current_regs());
if (tcb->task_state == TSTATE_TASK_RUNNING)
if (tcb == this_task() && !up_interrupt_context())
{
me = this_cpu();
cpu = tcb->cpu;
/* CASE 1: We are not in an interrupt handler and a task is
* signaling itself for some reason.
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
if (cpu == me && !up_current_regs())
{
/* In this case just deliver the signal now.
* REVISIT: Signal handler will run in a critical section!
*/
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* CASE 2: The task that needs to receive the signal is running.
* This could happen if the task is running on another CPU OR if
* we are in an interrupt handler and the task is running on this
* CPU. In the former case, we will have to PAUSE the other CPU
* first. But in either case, we will have to modify the return
* state as well as the state in the TCB.
*/
else
{
/* If we signaling a task running on the other CPU, we have
* to PAUSE the other CPU.
*/
if (cpu != me)
{
/* Pause the CPU */
up_cpu_pause(cpu);
/* Now tcb on the other CPU can be accessed safely */
/* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
* restored by the signal trampoline after the signal has
* been delivered.
*/
#ifdef CONFIG_ARCH_FPU
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
#endif
/* create signal process context */
tcb->xcp.saved_reg = tcb->xcp.regs;
arm64_init_signal_process(tcb, NULL);
}
else
{
/* tcb is running on the same CPU */
/* Save the return PC, CPSR and either the BASEPRI or
* PRIMASK registers (and perhaps also the LR). These will
* be restored by the signal trampoline after the signal
* has been delivered.
*/
/* create signal process context */
tcb->xcp.saved_reg = up_current_regs();
#ifdef CONFIG_ARCH_FPU
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
#endif
arm64_init_signal_process(tcb,
(struct regs_context *)up_current_regs());
/* trigger switch to signal process */
up_set_current_regs(tcb->xcp.regs);
}
/* NOTE: If the task runs on another CPU(cpu), adjusting
* global IRQ controls will be done in the pause handler
* on the CPU(cpu) by taking a critical section.
* If the task is scheduled on this CPU(me), do nothing
* because this CPU already took a critical section
*/
/* RESUME the other CPU if it was PAUSED */
if (cpu != me)
{
up_cpu_resume(cpu);
}
}
sigdeliver(tcb);
tcb->xcp.sigdeliver = NULL;
}
/* Otherwise, we are (1) signaling a task is not running from an
* interrupt handler or (2) we are not in an interrupt handler and the
* running task is signaling some other non-running task.
*/
else
{
#ifdef CONFIG_SMP
int cpu = tcb->cpu;
int me = this_cpu();
if (cpu != me)
{
/* Pause the CPU */
up_cpu_pause(cpu);
}
#endif
/* Save the return lr and cpsr and one scratch register. These
* will be restored by the signal trampoline after the signals
* have been delivered.
@ -347,7 +176,15 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
/* create signal process context */
arm64_init_signal_process(tcb, NULL);
#ifdef CONFIG_SMP
/* RESUME the other CPU if it was PAUSED */
if (cpu != me)
{
up_cpu_resume(cpu);
}
#endif
}
}
}
#endif /* CONFIG_SMP */

View File

@ -63,21 +63,9 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
if (up_interrupt_context())
{
/* Yes, then we have to do things differently.
* Just copy the current_regs into the OLD rtcb.
*/
arm64_savestate(rtcb->xcp.regs);
/* Update scheduler parameters */
nxsched_resume_scheduler(tcb);
/* Then switch contexts. Any necessary address environment
* changes will be made when the interrupt returns.
*/
arm64_restorestate(tcb->xcp.regs);
}
/* No, then we will need to perform the user context switch */