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
|
* arch/arm/src/armv7-m/up_blocktask.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
@ -68,7 +68,7 @@
|
|||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: up_restorefpu
|
* Name: up_savefpu
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Given the pointer to a register save area (in R0), save the state of the
|
* 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
|
* arch/arm/src/armv7-m/up_releasepending.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -84,15 +84,14 @@ void up_release_pending(void)
|
|||||||
/* sched_lock(); */
|
/* sched_lock(); */
|
||||||
if (sched_mergepending())
|
if (sched_mergepending())
|
||||||
{
|
{
|
||||||
/* The currently active task has changed! We will need to
|
/* The currently active task has changed! We will need to switch
|
||||||
* switch contexts. First check if we are operating in
|
* contexts. First check if we are operating in interrupt context.
|
||||||
* interrupt context:
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (current_regs)
|
if (current_regs)
|
||||||
{
|
{
|
||||||
/* Yes, then we have to do things differently.
|
/* Yes, then we have to do things differently. Just copy the
|
||||||
* Just copy the current_regs into the OLD rtcb.
|
* current_regs into the OLD rtcb.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
up_savestate(rtcb->xcp.regs);
|
up_savestate(rtcb->xcp.regs);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/arm/src/armv7-m/up_reprioritizertr.c
|
* arch/arm/src/armv7-m/up_reprioritizertr.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* 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);
|
slldbg("TCB=%p PRI=%d\n", tcb, priority);
|
||||||
|
|
||||||
/* Remove the tcb task from the ready-to-run list.
|
/* Remove the tcb task from the ready-to-run list.
|
||||||
* sched_removereadytorun will return true if we just
|
* sched_removereadytorun will return true if we just removed the head
|
||||||
* remove the head of the ready to run list.
|
* of the ready to run list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch_needed = sched_removereadytorun(tcb);
|
switch_needed = sched_removereadytorun(tcb);
|
||||||
@ -113,17 +113,18 @@ void up_reprioritize_rtr(_TCB *tcb, uint8_t priority)
|
|||||||
|
|
||||||
tcb->sched_priority = (uint8_t)priority;
|
tcb->sched_priority = (uint8_t)priority;
|
||||||
|
|
||||||
/* Return the task to the specified blocked task list.
|
/* Return the task to the ready-to-run task list. sched_addreadytorun
|
||||||
* sched_addreadytorun will return true if the task was
|
* will return true if the task was added to the head of ready-to-run
|
||||||
* added to the new list. We will need to perform a context
|
* list. We will need to perform a context switch only if the
|
||||||
* switch only if the EXCLUSIVE or of the two calls is non-zero
|
* EXCLUSIVE or of the two calls is non-zero (i.e., one and only one
|
||||||
* (i.e., one and only one the calls changes the head of the
|
* the calls changes the head of the ready-to-run list).
|
||||||
* ready-to-run list).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch_needed ^= sched_addreadytorun(tcb);
|
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)
|
if (switch_needed)
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/arm/src/armv7-m/up_schedulesigaction.c
|
* arch/arm/src/armv7-m/up_schedulesigaction.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* 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);
|
DEBUGASSERT(regs[REG_R1] != 0 && regs[REG_R2] != 0);
|
||||||
memcpy((uint32_t*)regs[REG_R1], regs, XCPTCONTEXT_SIZE);
|
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];
|
current_regs = (uint32_t*)regs[REG_R2];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -77,66 +77,29 @@
|
|||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
/* Given a uint8_t array of size CONFIG_EXAMPLES_OSTEST_FPUSIZE, this
|
/* Given an array of size CONFIG_EXAMPLES_OSTEST_FPUSIZE, this function will return
|
||||||
* function will return the current FPU registers.
|
* the current FPU registers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void arch_getfpu(FAR uint8_t *fpusave)
|
void arch_getfpu(FAR uint32_t *fpusave)
|
||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
uint32_t regs[XCPTCONTEXT_REGS];
|
uint32_t regs[XCPTCONTEXT_REGS];
|
||||||
|
|
||||||
flags = irqsave();
|
flags = irqsave();
|
||||||
up_savefpu(regs);
|
up_savefpu(regs); /* Saves the context of the FPU registers to memory */
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
|
|
||||||
memcpy(fpusave, ®s[REG_S0], (4*SW_FPU_REGS));
|
memcpy(fpusave, ®s[REG_S0], (4*SW_FPU_REGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Given a uint8_t array of size CONFIG_EXAMPLES_OSTEST_FPUSIZE, this
|
/* Given two arrays of size CONFIG_EXAMPLES_OSTEST_FPUSIZE this function
|
||||||
* function will set the current FPU regisers to match the provided
|
* will compare then an return true if they are identical.
|
||||||
* register save set.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void arch_setfpu(FAR const uint8_t *fpusave)
|
bool arch_cmpfpu(FAR const uint32_t *fpusave1, FAR const uint32_t *fpusave2)
|
||||||
{
|
{
|
||||||
irqstate_t flags;
|
return memcmp(fpusave1, fpusave2, (4*SW_FPU_REGS)) == 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_FPU */
|
#endif /* HAVE_FPU */
|
||||||
|
Loading…
Reference in New Issue
Block a user