Skip to content

Commit 2c7e764

Browse files
committed
arch: remove up_current_regs in common code
reason: When entering an exception or interrupt, there are two sets of registers: one is the "running regs", which we need to save, and the other is the "ready to running regs", which we may soon use. For consistency in logic, we can always store the "running regs" in the regs field of g_running_tasks, otherwise it may lead to errors in the storage location of the "running regs." When we need to access the "running regs," we should uniformly retrieve them from the regs field of g_running_tasks. As the next step, we will rename the set_current_regs/up_current_regs functions for each architecture to more appropriate names, solely for the purpose of identifying interrupts. Signed-off-by: hujun5 <[email protected]>
1 parent bf130eb commit 2c7e764

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+365
-164
lines changed

arch/arm/src/arm/arm_sigdeliver.c

+2
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,7 @@ void arm_sigdeliver(void)
9797
/* Then restore the correct state for this thread of execution. */
9898

9999
board_autoled_off(LED_SIGNAL);
100+
101+
g_running_tasks[this_cpu()] = NULL;
100102
arm_fullcontextrestore(regs);
101103
}

arch/arm/src/arm/arm_syscall.c

+11-21
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,23 @@
5454

5555
uint32_t *arm_syscall(uint32_t *regs)
5656
{
57-
struct tcb_s *tcb = this_task();
57+
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
58+
FAR struct tcb_s *tcb = this_task();
5859
uint32_t cmd;
59-
int cpu;
6060

6161
/* Nested interrupts are not supported */
6262

6363
DEBUGASSERT(up_current_regs() == NULL);
6464

65+
if (*running_task != NULL)
66+
{
67+
(*running_task)->xcp.regs = regs;
68+
}
69+
6570
/* Current regs non-zero indicates that we are processing an interrupt;
6671
* current_regs is also used to manage interrupt level context switches.
6772
*/
6873

69-
tcb->xcp.regs = regs;
7074
up_set_current_regs(regs);
7175

7276
/* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */
@@ -118,11 +122,6 @@ uint32_t *arm_syscall(uint32_t *regs)
118122
*/
119123

120124
case SYS_switch_context:
121-
{
122-
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
123-
*(uint32_t **)regs[REG_R1] = regs;
124-
up_set_current_regs((uint32_t *)regs[REG_R2]);
125-
}
126125
break;
127126

128127
default:
@@ -134,7 +133,7 @@ uint32_t *arm_syscall(uint32_t *regs)
134133
break;
135134
}
136135

137-
if (regs != tcb->xcp.regs)
136+
if ((*running_task) != tcb)
138137
{
139138
#ifdef CONFIG_ARCH_ADDRENV
140139
/* Make sure that the address environment for the previously
@@ -145,25 +144,16 @@ uint32_t *arm_syscall(uint32_t *regs)
145144

146145
addrenv_switch(NULL);
147146
#endif
148-
149-
/* Record the new "running" task. g_running_tasks[] is only used by
150-
* assertion logic for reporting crashes.
151-
*/
152-
153-
cpu = this_cpu();
154-
tcb = current_task(cpu);
155-
156147
/* Update scheduler parameters */
157148

158-
nxsched_suspend_scheduler(g_running_tasks[cpu]);
149+
nxsched_suspend_scheduler(*running_task);
159150
nxsched_resume_scheduler(tcb);
160151

161-
g_running_tasks[cpu] = tcb;
152+
*running_task = tcb;
162153

163154
/* Restore the cpu lock */
164155

165-
restore_critical_section(tcb, cpu);
166-
regs = up_current_regs();
156+
restore_critical_section(tcb, this_cpu());
167157
}
168158

169159
/* Set current_regs to NULL to indicate that we are no longer in an

arch/arm/src/armv6-m/arm_doirq.c

+9-7
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ void exception_direct(void)
5656

5757
uint32_t *arm_doirq(int irq, uint32_t *regs)
5858
{
59-
struct tcb_s *tcb = this_task();
59+
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
60+
FAR struct tcb_s *tcb;
61+
62+
if (*running_task != NULL)
63+
{
64+
(*running_task)->xcp.regs = regs;
65+
}
6066

6167
board_autoled_on(LED_INIRQ);
6268
#ifdef CONFIG_SUPPRESS_INTERRUPTS
@@ -80,13 +86,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
8086
#endif
8187

8288
up_irq_save();
83-
g_running_tasks[this_cpu()]->xcp.regs = regs;
8489
}
8590
else
8691
{
87-
/* Dispatch irq */
88-
89-
tcb->xcp.regs = regs;
9092
irq_dispatch(irq, regs);
9193
}
9294

@@ -100,15 +102,15 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
100102

101103
/* Update scheduler parameters */
102104

103-
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
105+
nxsched_suspend_scheduler(*running_task);
104106
nxsched_resume_scheduler(tcb);
105107

106108
/* Record the new "running" task when context switch occurred.
107109
* g_running_tasks[] is only used by assertion logic for reporting
108110
* crashes.
109111
*/
110112

111-
g_running_tasks[this_cpu()] = tcb;
113+
*running_task = tcb;
112114
regs = tcb->xcp.regs;
113115
#endif
114116

arch/arm/src/armv6-m/arm_svcall.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ int arm_svcall(int irq, void *context, void *arg)
119119
{
120120
struct tcb_s *tcb = this_task();
121121
uint32_t *regs = (uint32_t *)context;
122+
uint32_t *new_regs = regs;
122123
uint32_t cmd;
123124

124125
cmd = regs[REG_R0];
@@ -167,6 +168,7 @@ int arm_svcall(int irq, void *context, void *arg)
167168
case SYS_restore_context:
168169
{
169170
DEBUGASSERT(regs[REG_R1] != 0);
171+
new_regs = (uint32_t *)regs[REG_R1];
170172
tcb->xcp.regs = (uint32_t *)regs[REG_R1];
171173
}
172174
break;
@@ -191,8 +193,7 @@ int arm_svcall(int irq, void *context, void *arg)
191193
case SYS_switch_context:
192194
{
193195
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
194-
*(uint32_t **)regs[REG_R1] = regs;
195-
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
196+
new_regs = (uint32_t *)regs[REG_R2];
196197
}
197198
break;
198199

@@ -446,12 +447,12 @@ int arm_svcall(int irq, void *context, void *arg)
446447
* switch.
447448
*/
448449

449-
if (regs != tcb->xcp.regs)
450+
if (regs != new_regs)
450451
{
451452
restore_critical_section(tcb, this_cpu());
452453

453454
#ifdef CONFIG_DEBUG_SYSCALL_INFO
454-
regs = (uint32_t *)tcb->xcp.regs;
455+
regs = new_regs;
455456

456457
svcinfo("SVCall Return:\n");
457458
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",

arch/arm/src/armv7-a/arm_sigdeliver.c

+2
Original file line numberDiff line numberDiff line change
@@ -160,5 +160,7 @@ void arm_sigdeliver(void)
160160
leave_critical_section(regs[REG_CPSR]);
161161
rtcb->irqcount--;
162162
#endif
163+
164+
g_running_tasks[this_cpu()] = NULL;
163165
arm_fullcontextrestore(regs);
164166
}

arch/arm/src/armv7-a/arm_syscall.c

+9-14
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ static void dispatch_syscall(void)
160160

161161
uint32_t *arm_syscall(uint32_t *regs)
162162
{
163+
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
163164
struct tcb_s *tcb = this_task();
164165
uint32_t cmd;
165-
int cpu;
166166
#ifdef CONFIG_BUILD_KERNEL
167167
uint32_t cpsr;
168168
#endif
@@ -171,7 +171,10 @@ uint32_t *arm_syscall(uint32_t *regs)
171171

172172
DEBUGASSERT(up_current_regs() == NULL);
173173

174-
tcb->xcp.regs = regs;
174+
if (*running_task != NULL)
175+
{
176+
(*running_task)->xcp.regs = regs;
177+
}
175178

176179
/* Current regs non-zero indicates that we are processing an interrupt;
177180
* current_regs is also used to manage interrupt level context switches.
@@ -297,11 +300,6 @@ uint32_t *arm_syscall(uint32_t *regs)
297300
*/
298301

299302
case SYS_switch_context:
300-
{
301-
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
302-
*(uint32_t **)regs[REG_R1] = regs;
303-
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
304-
}
305303
break;
306304

307305
/* R0=SYS_task_start: This a user task start
@@ -567,7 +565,7 @@ uint32_t *arm_syscall(uint32_t *regs)
567565
break;
568566
}
569567

570-
if (regs != tcb->xcp.regs)
568+
if ((*running_task) != tcb)
571569
{
572570
#ifdef CONFIG_ARCH_ADDRENV
573571
/* Make sure that the address environment for the previously
@@ -579,23 +577,20 @@ uint32_t *arm_syscall(uint32_t *regs)
579577
addrenv_switch(NULL);
580578
#endif
581579

582-
cpu = this_cpu();
583-
tcb = current_task(cpu);
584-
585580
/* Update scheduler parameters */
586581

587-
nxsched_suspend_scheduler(g_running_tasks[cpu]);
582+
nxsched_suspend_scheduler(*running_task);
588583
nxsched_resume_scheduler(tcb);
589584

590585
/* Record the new "running" task. g_running_tasks[] is only used by
591586
* assertion logic for reporting crashes.
592587
*/
593588

594-
g_running_tasks[cpu] = tcb;
589+
*running_task = tcb;
595590

596591
/* Restore the cpu lock */
597592

598-
restore_critical_section(tcb, cpu);
593+
restore_critical_section(tcb, this_cpu());
599594
regs = tcb->xcp.regs;
600595
}
601596

arch/arm/src/armv7-m/arm_doirq.c

+9-7
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ void exception_direct(void)
5656

5757
uint32_t *arm_doirq(int irq, uint32_t *regs)
5858
{
59-
struct tcb_s *tcb = this_task();
59+
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
60+
FAR struct tcb_s *tcb;
61+
62+
if (*running_task != NULL)
63+
{
64+
(*running_task)->xcp.regs = regs;
65+
}
6066

6167
board_autoled_on(LED_INIRQ);
6268
#ifdef CONFIG_SUPPRESS_INTERRUPTS
@@ -80,13 +86,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
8086
#endif
8187

8288
up_irq_save();
83-
g_running_tasks[this_cpu()]->xcp.regs = regs;
8489
}
8590
else
8691
{
87-
/* Dispatch irq */
88-
89-
tcb->xcp.regs = regs;
9092
irq_dispatch(irq, regs);
9193
}
9294

@@ -100,15 +102,15 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
100102

101103
/* Update scheduler parameters */
102104

103-
nxsched_suspend_scheduler(g_running_tasks[this_cpu()]);
105+
nxsched_suspend_scheduler(*running_task);
104106
nxsched_resume_scheduler(tcb);
105107

106108
/* Record the new "running" task when context switch occurred.
107109
* g_running_tasks[] is only used by assertion logic for reporting
108110
* crashes.
109111
*/
110112

111-
g_running_tasks[this_cpu()] = tcb;
113+
*running_task = tcb;
112114
regs = tcb->xcp.regs;
113115
#endif
114116

arch/arm/src/armv7-m/arm_svcall.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ int arm_svcall(int irq, void *context, void *arg)
127127
{
128128
struct tcb_s *tcb = this_task();
129129
uint32_t *regs = (uint32_t *)context;
130+
uint32_t *new_regs = regs;
130131
uint32_t cmd;
131132

132133
cmd = regs[REG_R0];
@@ -176,6 +177,7 @@ int arm_svcall(int irq, void *context, void *arg)
176177
case SYS_restore_context:
177178
{
178179
DEBUGASSERT(regs[REG_R1] != 0);
180+
new_regs = (uint32_t *)regs[REG_R1];
179181
tcb->xcp.regs = (uint32_t *)regs[REG_R1];
180182
}
181183
break;
@@ -200,8 +202,7 @@ int arm_svcall(int irq, void *context, void *arg)
200202
case SYS_switch_context:
201203
{
202204
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
203-
*(uint32_t **)regs[REG_R1] = regs;
204-
tcb->xcp.regs = (uint32_t *)regs[REG_R2];
205+
new_regs = (uint32_t *)regs[REG_R2];
205206
}
206207
break;
207208

@@ -456,12 +457,12 @@ int arm_svcall(int irq, void *context, void *arg)
456457
* switch.
457458
*/
458459

459-
if (regs != tcb->xcp.regs)
460+
if (regs != new_regs)
460461
{
461462
restore_critical_section(tcb, this_cpu());
462463

463464
#ifdef CONFIG_DEBUG_SYSCALL_INFO
464-
regs = (uint32_t *)tcb->xcp.regs;
465+
regs = new_regs;
465466

466467
svcinfo("SVCall Return:\n");
467468
svcinfo(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",

arch/arm/src/armv7-r/arm_sigdeliver.c

+2
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,7 @@ void arm_sigdeliver(void)
157157
leave_critical_section(regs[REG_CPSR]);
158158
rtcb->irqcount--;
159159
#endif
160+
161+
g_running_tasks[this_cpu()] = NULL;
160162
arm_fullcontextrestore(regs);
161163
}

0 commit comments

Comments
 (0)