Skip to content

Commit 9e8df3b

Browse files
xiaoxiang781216acassis
authored andcommitted
Revert "arm64: save FPU regs every time"
This reverts commit 3c4f3c1.
1 parent f6f072e commit 9e8df3b

File tree

9 files changed

+359
-53
lines changed

9 files changed

+359
-53
lines changed

arch/arm64/src/common/arm64_arch.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,6 @@ struct regs_context
299299
uint64_t spsr;
300300
uint64_t sp_el0;
301301
uint64_t exe_depth;
302-
#ifdef CONFIG_ARCH_FPU
303-
struct fpu_reg fpu_regs;
304-
#endif
305302
};
306303

307304
/****************************************************************************

arch/arm64/src/common/arm64_exit.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ void up_exit(int status)
6565
*/
6666

6767
enter_critical_section();
68+
69+
/* Destroy the task at the head of the ready to run list. */
70+
#ifdef CONFIG_ARCH_FPU
71+
arm64_destory_fpu(tcb);
72+
#endif
73+
6874
nxtask_exit();
6975

7076
/* Now, perform the context switch to the new ready-to-run task at the

arch/arm64/src/common/arm64_fpu.c

Lines changed: 138 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,11 @@ struct arm64_fpu_procfs_file_s
7777
* Private Data
7878
***************************************************************************/
7979

80-
#ifdef CONFIG_FS_PROCFS_REGISTER
81-
80+
static struct fpu_reg g_idle_thread_fpu[CONFIG_SMP_NCPUS];
8281
static struct arm64_cpu_fpu_context g_cpu_fpu_ctx[CONFIG_SMP_NCPUS];
8382

83+
#ifdef CONFIG_FS_PROCFS_REGISTER
84+
8485
/* procfs methods */
8586

8687
static int arm64_fpu_procfs_open(struct file *filep, const char *relpath,
@@ -261,6 +262,141 @@ static int arm64_fpu_procfs_stat(const char *relpath, struct stat *buf)
261262
}
262263
#endif
263264

265+
/***************************************************************************
266+
* Public Functions
267+
***************************************************************************/
268+
269+
void arm64_init_fpu(struct tcb_s *tcb)
270+
{
271+
if (tcb->pid < CONFIG_SMP_NCPUS)
272+
{
273+
#ifdef CONFIG_SMP
274+
int cpu = tcb->cpu;
275+
#else
276+
int cpu = 0;
277+
#endif
278+
memset(&g_cpu_fpu_ctx[cpu], 0,
279+
sizeof(struct arm64_cpu_fpu_context));
280+
g_cpu_fpu_ctx[cpu].idle_thread = tcb;
281+
282+
tcb->xcp.fpu_regs = (uint64_t *)&g_idle_thread_fpu[cpu];
283+
}
284+
285+
memset(tcb->xcp.fpu_regs, 0, sizeof(struct fpu_reg));
286+
}
287+
288+
void arm64_destory_fpu(struct tcb_s *tcb)
289+
{
290+
struct tcb_s *owner;
291+
292+
/* save current fpu owner's context */
293+
294+
owner = g_cpu_fpu_ctx[this_cpu()].fpu_owner;
295+
296+
if (owner == tcb)
297+
{
298+
g_cpu_fpu_ctx[this_cpu()].fpu_owner = NULL;
299+
}
300+
}
301+
302+
/***************************************************************************
303+
* Name: arm64_fpu_enter_exception
304+
*
305+
* Description:
306+
* called at every time get into a exception
307+
*
308+
***************************************************************************/
309+
310+
void arm64_fpu_enter_exception(void)
311+
{
312+
}
313+
314+
void arm64_fpu_exit_exception(void)
315+
{
316+
}
317+
318+
void arm64_fpu_trap(struct regs_context *regs)
319+
{
320+
struct tcb_s *owner;
321+
322+
UNUSED(regs);
323+
324+
/* disable fpu trap access */
325+
326+
arm64_fpu_access_trap_disable();
327+
328+
/* save current fpu owner's context */
329+
330+
owner = g_cpu_fpu_ctx[this_cpu()].fpu_owner;
331+
332+
if (owner != NULL)
333+
{
334+
arm64_fpu_save((struct fpu_reg *)owner->xcp.fpu_regs);
335+
ARM64_DSB();
336+
g_cpu_fpu_ctx[this_cpu()].save_count++;
337+
g_cpu_fpu_ctx[this_cpu()].fpu_owner = NULL;
338+
}
339+
340+
if (arch_get_exception_depth() > 1)
341+
{
342+
/* if get_exception_depth > 1
343+
* it means FPU access exception occurred in exception context
344+
* switch FPU owner to idle thread
345+
*/
346+
347+
owner = g_cpu_fpu_ctx[this_cpu()].idle_thread;
348+
}
349+
else
350+
{
351+
owner = running_task();
352+
}
353+
354+
/* restore our context */
355+
356+
arm64_fpu_restore((struct fpu_reg *)owner->xcp.fpu_regs);
357+
g_cpu_fpu_ctx[this_cpu()].restore_count++;
358+
359+
/* become new owner */
360+
361+
g_cpu_fpu_ctx[this_cpu()].fpu_owner = owner;
362+
}
363+
364+
void arm64_fpu_context_restore(void)
365+
{
366+
struct tcb_s *new_tcb = running_task();
367+
368+
arm64_fpu_access_trap_disable();
369+
370+
/* FPU trap has happened at this task */
371+
372+
if (new_tcb == g_cpu_fpu_ctx[this_cpu()].fpu_owner)
373+
{
374+
arm64_fpu_access_trap_disable();
375+
}
376+
else
377+
{
378+
arm64_fpu_access_trap_enable();
379+
}
380+
381+
g_cpu_fpu_ctx[this_cpu()].switch_count++;
382+
}
383+
384+
#ifdef CONFIG_SMP
385+
void arm64_fpu_context_save(void)
386+
{
387+
struct tcb_s *tcb = running_task();
388+
389+
if (tcb == g_cpu_fpu_ctx[this_cpu()].fpu_owner)
390+
{
391+
arm64_fpu_access_trap_disable();
392+
arm64_fpu_save((struct fpu_reg *)tcb->xcp.fpu_regs);
393+
ARM64_DSB();
394+
g_cpu_fpu_ctx[this_cpu()].save_count++;
395+
g_cpu_fpu_ctx[this_cpu()].fpu_owner = NULL;
396+
}
397+
}
398+
#endif
399+
264400
void arm64_fpu_enable(void)
265401
{
266402
irqstate_t flags = up_irq_save();

arch/arm64/src/common/arm64_initialstate.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747
#include "chip.h"
4848
#include "arm64_fatal.h"
4949

50+
#ifdef CONFIG_ARCH_FPU
51+
#include "arm64_fpu.h"
52+
#endif
53+
5054
/****************************************************************************
5155
* Public Functions
5256
****************************************************************************/
@@ -66,6 +70,17 @@ void arm64_new_task(struct tcb_s * tcb)
6670
}
6771
#endif
6872

73+
#ifdef CONFIG_ARCH_FPU
74+
struct fpu_reg *pfpuctx;
75+
pfpuctx = STACK_PTR_TO_FRAME(struct fpu_reg, stack_ptr);
76+
tcb->xcp.fpu_regs = (uint64_t *)pfpuctx;
77+
78+
/* set fpu context */
79+
80+
arm64_init_fpu(tcb);
81+
stack_ptr = (uintptr_t)pfpuctx;
82+
#endif
83+
6984
pinitctx = STACK_PTR_TO_FRAME(struct regs_context, stack_ptr);
7085
memset(pinitctx, 0, sizeof(struct regs_context));
7186
pinitctx->elr = (uint64_t)tcb->start;
@@ -135,6 +150,11 @@ void up_initial_state(struct tcb_s *tcb)
135150
tcb->stack_base_ptr = tcb->stack_alloc_ptr;
136151
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;
137152

153+
#ifdef CONFIG_ARCH_FPU
154+
/* set fpu context */
155+
156+
arm64_init_fpu(tcb);
157+
#endif
138158
/* set initialize idle thread tcb and exception depth
139159
* core 0, idle0
140160
*/

arch/arm64/src/common/arm64_schedulesigaction.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
#include "irq/irq.h"
3939
#include "arm64_fatal.h"
4040

41+
#ifdef CONFIG_ARCH_FPU
42+
#include "arm64_fpu.h"
43+
#endif
44+
4145
/****************************************************************************
4246
* Public Functions
4347
****************************************************************************/
@@ -54,6 +58,16 @@ void arm64_init_signal_process(struct tcb_s *tcb, struct regs_context *regs)
5458
struct regs_context *psigctx;
5559
char *stack_ptr = (char *)pctx->sp_elx - sizeof(struct regs_context);
5660

61+
#ifdef CONFIG_ARCH_FPU
62+
struct fpu_reg *pfpuctx;
63+
pfpuctx = STACK_PTR_TO_FRAME(struct fpu_reg, stack_ptr);
64+
tcb->xcp.fpu_regs = (uint64_t *)pfpuctx;
65+
66+
/* set fpu context */
67+
68+
arm64_init_fpu(tcb);
69+
stack_ptr = (char *)pfpuctx;
70+
#endif
5771
psigctx = STACK_PTR_TO_FRAME(struct regs_context, stack_ptr);
5872
memset(psigctx, 0, sizeof(struct regs_context));
5973
psigctx->elr = (uint64_t)arm64_sigdeliver;
@@ -163,6 +177,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
163177
/* create signal process context */
164178

165179
tcb->xcp.saved_reg = up_current_regs();
180+
#ifdef CONFIG_ARCH_FPU
181+
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
182+
#endif
166183
arm64_init_signal_process(tcb,
167184
(struct regs_context *)up_current_regs());
168185

@@ -184,6 +201,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
184201
* have been delivered.
185202
*/
186203

204+
#ifdef CONFIG_ARCH_FPU
205+
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
206+
#endif
187207
/* create signal process context */
188208

189209
tcb->xcp.saved_reg = tcb->xcp.regs;
@@ -259,6 +279,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
259279
* been delivered.
260280
*/
261281

282+
#ifdef CONFIG_ARCH_FPU
283+
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
284+
#endif
262285
/* create signal process context */
263286

264287
tcb->xcp.saved_reg = tcb->xcp.regs;
@@ -277,6 +300,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
277300
/* create signal process context */
278301

279302
tcb->xcp.saved_reg = up_current_regs();
303+
#ifdef CONFIG_ARCH_FPU
304+
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
305+
#endif
280306
arm64_init_signal_process(tcb,
281307
(struct regs_context *)up_current_regs());
282308

@@ -313,6 +339,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
313339
* have been delivered.
314340
*/
315341

342+
#ifdef CONFIG_ARCH_FPU
343+
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
344+
#endif
316345
tcb->xcp.saved_reg = tcb->xcp.regs;
317346

318347
/* create signal process context */

arch/arm64/src/common/arm64_sigdeliver.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
#include "irq/irq.h"
3939
#include "arm64_fatal.h"
4040

41+
#ifdef CONFIG_ARCH_FPU
42+
#include "arm64_fpu.h"
43+
#endif
44+
4145
/****************************************************************************
4246
* Public Functions
4347
****************************************************************************/
@@ -153,6 +157,11 @@ void arm64_sigdeliver(void)
153157
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
154158
rtcb->xcp.regs = rtcb->xcp.saved_reg;
155159

160+
#ifdef CONFIG_ARCH_FPU
161+
arm64_destory_fpu(rtcb);
162+
rtcb->xcp.fpu_regs = rtcb->xcp.saved_fpu_regs;
163+
#endif
164+
156165
/* Then restore the correct state for this thread of execution. */
157166

158167
#ifdef CONFIG_SMP

arch/arm64/src/common/arm64_syscall.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ uint64_t *arm64_syscall_switch(uint64_t * regs)
193193
*/
194194

195195
ret_regs = (uint64_t *)f_regs->regs[REG_X1];
196+
f_regs->regs[REG_X1] = 0; /* set the saveregs = 0 */
196197

197198
DEBUGASSERT(ret_regs);
198199
}

0 commit comments

Comments
 (0)