Fix bugs in lazy FPU register saving
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4427 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
9c3cac8e3f
commit
8fb3d8b386
@ -1,8 +1,8 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-m/up_blocktask.c
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -68,7 +68,7 @@
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_restorefpu
|
||||
* Name: up_savefpu
|
||||
*
|
||||
* Description:
|
||||
* Given the pointer to a register save area (in R0), save the state of the
|
||||
|
@ -1,8 +1,8 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-m/up_releasepending.c
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -84,15 +84,14 @@ void up_release_pending(void)
|
||||
/* sched_lock(); */
|
||||
if (sched_mergepending())
|
||||
{
|
||||
/* The currently active task has changed! We will need to
|
||||
* switch contexts. First check if we are operating in
|
||||
* interrupt context:
|
||||
/* The currently active task has changed! We will need to switch
|
||||
* contexts. First check if we are operating in interrupt context.
|
||||
*/
|
||||
|
||||
if (current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the current_regs into the OLD rtcb.
|
||||
/* Yes, then we have to do things differently. Just copy the
|
||||
* current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
@ -1,8 +1,8 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-m/up_reprioritizertr.c
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -103,8 +103,8 @@ void up_reprioritize_rtr(_TCB *tcb, uint8_t priority)
|
||||
slldbg("TCB=%p PRI=%d\n", tcb, priority);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list.
|
||||
* sched_removereadytorun will return true if we just
|
||||
* remove the head of the ready to run list.
|
||||
* sched_removereadytorun will return true if we just removed the head
|
||||
* of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = sched_removereadytorun(tcb);
|
||||
@ -113,17 +113,18 @@ void up_reprioritize_rtr(_TCB *tcb, uint8_t priority)
|
||||
|
||||
tcb->sched_priority = (uint8_t)priority;
|
||||
|
||||
/* Return the task to the specified blocked task list.
|
||||
* sched_addreadytorun will return true if the task was
|
||||
* added to the new list. We will need to perform a context
|
||||
* switch only if the EXCLUSIVE or of the two calls is non-zero
|
||||
* (i.e., one and only one the calls changes the head of the
|
||||
* ready-to-run list).
|
||||
/* Return the task to the ready-to-run task list. sched_addreadytorun
|
||||
* will return true if the task was added to the head of ready-to-run
|
||||
* list. We will need to perform a context switch only if the
|
||||
* EXCLUSIVE or of the two calls is non-zero (i.e., one and only one
|
||||
* the calls changes the head of the ready-to-run list).
|
||||
*/
|
||||
|
||||
switch_needed ^= sched_addreadytorun(tcb);
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
/* Now, perform the context switch if one is needed (i.e. if the head
|
||||
* of the ready-to-run list is no longer the same).
|
||||
*/
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-m/up_schedulesigaction.c
|
||||
*
|
||||
* Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -320,6 +320,9 @@ int up_svcall(int irq, FAR void *context)
|
||||
{
|
||||
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
|
||||
memcpy((uint32_t*)regs[REG_R1], regs, XCPTCONTEXT_SIZE);
|
||||
#if defined(CONFIG_ARCH_FPU) && !defined(CONFIG_ARMV7M_CMNVECTOR)
|
||||
up_savefpu((uint32_t*)regs[REG_R1]);
|
||||
#endif
|
||||
current_regs = (uint32_t*)regs[REG_R2];
|
||||
}
|
||||
break;
|
||||
|
@ -77,66 +77,29 @@
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
/* Given a uint8_t array of size CONFIG_EXAMPLES_OSTEST_FPUSIZE, this
|
||||
* function will return the current FPU registers.
|
||||
/* Given an array of size CONFIG_EXAMPLES_OSTEST_FPUSIZE, this function will return
|
||||
* the current FPU registers.
|
||||
*/
|
||||
|
||||
void arch_getfpu(FAR uint8_t *fpusave)
|
||||
void arch_getfpu(FAR uint32_t *fpusave)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t regs[XCPTCONTEXT_REGS];
|
||||
|
||||
flags = irqsave();
|
||||
up_savefpu(regs);
|
||||
up_savefpu(regs); /* Saves the context of the FPU registers to memory */
|
||||
irqrestore(flags);
|
||||
|
||||
memcpy(fpusave, ®s[REG_S0], (4*SW_FPU_REGS));
|
||||
}
|
||||
|
||||
/* Given a uint8_t array of size CONFIG_EXAMPLES_OSTEST_FPUSIZE, this
|
||||
* function will set the current FPU regisers to match the provided
|
||||
* register save set.
|
||||
/* Given two arrays of size CONFIG_EXAMPLES_OSTEST_FPUSIZE this function
|
||||
* will compare then an return true if they are identical.
|
||||
*/
|
||||
|
||||
void arch_setfpu(FAR const uint8_t *fpusave)
|
||||
bool arch_cmpfpu(FAR const uint32_t *fpusave1, FAR const uint32_t *fpusave2)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t regs[XCPTCONTEXT_REGS];
|
||||
|
||||
memcpy(®s[REG_S0], fpusave, (4*SW_FPU_REGS));
|
||||
|
||||
flags = irqsave();
|
||||
up_restorefpu(regs);
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
/* Given a uint8_t array of size CONFIG_EXAMPLES_OSTEST_FPUSIZE and a
|
||||
* seed value, this function will set the FPU registers to a known
|
||||
* values for testing purposes. The contents of the FPU registers
|
||||
* must be uniqe for each sed value.
|
||||
*/
|
||||
|
||||
void arch_initfpu(FAR uint8_t *fpusave, int seed)
|
||||
{
|
||||
FAR uint32_t *dest = (FAR uint32_t *)fpusave;
|
||||
uint32_t mask = 0x01010101;
|
||||
uint32_t incr = 0x01010101;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
*dest = (uint32_t)seed ^ mask;
|
||||
mask += incr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Given two uint8_t arrays of size CONFIG_EXAMPLES_OSTEST_FPUSIZE this
|
||||
* function will compare then an return true if they are identical.
|
||||
*/
|
||||
|
||||
bool arch_cmpfpu(FAR const uint8_t *fpusave1, FAR const uint8_t *fpusave2)
|
||||
{
|
||||
return memcmp(fpusave1, fpusave2, (4*32)) == 0;
|
||||
return memcmp(fpusave1, fpusave2, (4*SW_FPU_REGS)) == 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_FPU */
|
||||
|
Loading…
Reference in New Issue
Block a user