diff --git a/arch/arm/src/common/up_blocktask.c b/arch/arm/src/arm/up_blocktask.c old mode 100644 new mode 100755 similarity index 99% rename from arch/arm/src/common/up_blocktask.c rename to arch/arm/src/arm/up_blocktask.c index f4e31526be..8397209e17 --- a/arch/arm/src/common/up_blocktask.c +++ b/arch/arm/src/arm/up_blocktask.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/common/up_blocktask.c + * arch/arm/src/arm/up_blocktask.c * * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/arch/arm/src/common/up_releasepending.c b/arch/arm/src/arm/up_releasepending.c old mode 100644 new mode 100755 similarity index 99% rename from arch/arm/src/common/up_releasepending.c rename to arch/arm/src/arm/up_releasepending.c index d81479e873..d7000ee9f6 --- a/arch/arm/src/common/up_releasepending.c +++ b/arch/arm/src/arm/up_releasepending.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/common/up_releasepending.c + * arch/arm/src/arm/up_releasepending.c * * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/arch/arm/src/common/up_reprioritizertr.c b/arch/arm/src/arm/up_reprioritizertr.c old mode 100644 new mode 100755 similarity index 99% rename from arch/arm/src/common/up_reprioritizertr.c rename to arch/arm/src/arm/up_reprioritizertr.c index 684ff7f43e..1192a37bbf --- a/arch/arm/src/common/up_reprioritizertr.c +++ b/arch/arm/src/arm/up_reprioritizertr.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/common/up_reprioritizertr.c + * arch/arm/src/arm/up_reprioritizertr.c * * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/arch/arm/src/arm/up_sigdeliver.c b/arch/arm/src/arm/up_sigdeliver.c index 469f274e6c..277a3ba74a 100644 --- a/arch/arm/src/arm/up_sigdeliver.c +++ b/arch/arm/src/arm/up_sigdeliver.c @@ -114,7 +114,7 @@ void up_sigdeliver(void) sigdeliver = rtcb->xcp.sigdeliver; rtcb->xcp.sigdeliver = NULL; - /* Then restore the task interrupt statat. */ + /* Then restore the task interrupt state */ irqrestore(regs[REG_CPSR]); diff --git a/arch/arm/src/common/up_unblocktask.c b/arch/arm/src/arm/up_unblocktask.c old mode 100644 new mode 100755 similarity index 99% rename from arch/arm/src/common/up_unblocktask.c rename to arch/arm/src/arm/up_unblocktask.c index ea64ed1c69..0563f54a73 --- a/arch/arm/src/common/up_unblocktask.c +++ b/arch/arm/src/arm/up_unblocktask.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/common/up_unblocktask.c + * arch/arm/src/arm/up_unblocktask.c * * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/arch/arm/src/common/up_internal.h b/arch/arm/src/common/up_internal.h index 5442f59149..ee58647949 100644 --- a/arch/arm/src/common/up_internal.h +++ b/arch/arm/src/common/up_internal.h @@ -155,9 +155,10 @@ extern uint32 _ebss; /* End+1 of .bss */ extern void up_boot(void); extern void up_copystate(uint32 *dest, uint32 *src); extern void up_decodeirq(uint32 *regs); -extern void up_fullcontextrestore(uint32 *regs) __attribute__ ((noreturn)); extern void up_irqinitialize(void); -extern int up_saveusercontext(uint32 *regs); +extern int up_saveusercontext(uint32 *saveregs); +extern void up_fullcontextrestore(uint32 *restoreregs) __attribute__ ((noreturn)); +extern void up_switchcontext(uint32 *saveregs, uint32 *restoreregs); extern void up_sigdeliver(void); extern int up_timerisr(int irq, uint32 *regs); extern void up_lowputc(char ch); diff --git a/arch/arm/src/cortexm3/up_blocktask.c b/arch/arm/src/cortexm3/up_blocktask.c new file mode 100755 index 0000000000..e50019809d --- /dev/null +++ b/arch/arm/src/cortexm3/up_blocktask.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * arch/arm/src/cortexm3/up_blocktask.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include + +#include "os_internal.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(_TCB *tcb, tstate_t task_state) +{ + /* Verify that the context switch can be performed */ + + if ((tcb->task_state < FIRST_READY_TO_RUN_STATE) || + (tcb->task_state > LAST_READY_TO_RUN_STATE)) + { + PANIC(OSERR_BADBLOCKSTATE); + } + else + { + _TCB *rtcb = (_TCB*)g_readytorun.head; + boolean switch_needed; + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the g_readytorun + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Are we in an interrupt handler? */ + + if (current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the g_readytorun task list. + */ + + rtcb = (_TCB*)g_readytorun.head; + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + _TCB *nexttcb = (_TCB*)g_readytorun.head; + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } + } +} diff --git a/arch/arm/src/cortexm3/up_fullcontextrestore.S b/arch/arm/src/cortexm3/up_fullcontextrestore.S new file mode 100755 index 0000000000..b5a2092f2b --- /dev/null +++ b/arch/arm/src/cortexm3/up_fullcontextrestore.S @@ -0,0 +1,93 @@ +/************************************************************************************ + * arch/arm/src/cortexm3/up_fullcontextrestore.S + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include "nvic.h" + +/************************************************************************************ + * Preprocessor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Global Symbols + ************************************************************************************/ + + .syntax unified + .thumb + .file "up_fullcontextrestore.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************** + * Name: up_fullcontextrestore + * + * Description: + * Restore the current thread context. Full prototype is: + * + * void up_fullcontextrestore(uint32 *restoreregs) __attribute__ ((noreturn)); + * + * Return: + * None + * + **************************************************************************/ + + .thumb_func + .globl up_fullcontextrestore + .type up_fullcontextrestore, function +up_fullcontextrestore: + + /* Perform the System call with R0=1 and R1=regs */ + + mov r1, r0 /* R1: regs */ + mov r0, #1 /* R0: 1 means restore context */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* This call should not return */ + + bx lr /* Unnecessary ... will not return */ + .size up_fullcontextrestore, .-up_fullcontextrestore + .end + diff --git a/arch/arm/src/cortexm3/up_releasepending.c b/arch/arm/src/cortexm3/up_releasepending.c new file mode 100755 index 0000000000..f3c7ae2098 --- /dev/null +++ b/arch/arm/src/cortexm3/up_releasepending.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/arm/src/cortexm3/up_releasepending.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include "os_internal.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + + slldbg("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the g_readytorun task list */ + + /* 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: + */ + + if (current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the g_readytorun task list. + */ + + rtcb = (_TCB*)g_readytorun.head; + slldbg("New Active Task TCB=%p\n", rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + _TCB *nexttcb = (_TCB*)g_readytorun.head; + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/arm/src/cortexm3/up_reprioritizertr.c b/arch/arm/src/cortexm3/up_reprioritizertr.c new file mode 100755 index 0000000000..4d406de808 --- /dev/null +++ b/arch/arm/src/cortexm3/up_reprioritizertr.c @@ -0,0 +1,178 @@ +/**************************************************************************** + * arch/arm/src/cortexm3/up_reprioritizertr.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include "os_internal.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(_TCB *tcb, ubyte priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE || + priority < SCHED_PRIORITY_MIN || + priority > SCHED_PRIORITY_MAX) + { + PANIC(OSERR_BADREPRIORITIZESTATE); + } + else + { + _TCB *rtcb = (_TCB*)g_readytorun.head; + boolean switch_needed; + + 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. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (ubyte)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). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Are we in an interrupt handler? */ + + if (current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the g_readytorun task list. + */ + + rtcb = (_TCB*)g_readytorun.head; + slldbg("New Active Task TCB=%p\n", rtcb); + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + _TCB *nexttcb = (_TCB*)g_readytorun.head; + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } + } +} diff --git a/arch/arm/src/cortexm3/up_context.S b/arch/arm/src/cortexm3/up_saveusercontext.S old mode 100644 new mode 100755 similarity index 78% rename from arch/arm/src/cortexm3/up_context.S rename to arch/arm/src/cortexm3/up_saveusercontext.S index c3264ce446..fe7305c101 --- a/arch/arm/src/cortexm3/up_context.S +++ b/arch/arm/src/cortexm3/up_saveusercontext.S @@ -1,132 +1,102 @@ -/************************************************************************************ - * arch/arm/src/cortexm3/up_context.S - * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ************************************************************************************/ - -/************************************************************************************ - * Included Files - ************************************************************************************/ - -#include -#include -#include "nvic.h" - -/************************************************************************************ - * Preprocessor Definitions - ************************************************************************************/ - -/************************************************************************************ - * Global Symbols - ************************************************************************************/ - - .syntax unified - .thumb - .file "up_context.S" - -/************************************************************************************ - * Macros - ************************************************************************************/ - -/************************************************************************************ - * Public Functions - ************************************************************************************/ - -/************************************************************************** - * Name: up_saveusercontext - * - * Description: - * Save the current thread context. Full prototype is: - * - * int up_saveusercontext(uint32 *regs); - * - * Return: - * 0: Normal return - * 1: Context switch return - * - **************************************************************************/ - - .text - .thumb_func - .globl up_saveusercontext - .type up_saveusercontext, function -up_saveusercontext: - - /* Perform the System call with R0=0 and R1=regs */ - - mov r1, r0 /* R1: regs */ - mov r0, #0 /* R0: 0 means save context (also return value) */ - svc 0 /* Force synchronous SVCall (or Hard Fault) */ - - /* There are two return conditions. On the first return, R0 (the - * return value will be zero. On the second return we need to - * force R0 to be 1. - */ - - add r2, r1, #(4*REG_R0) - mov r3, #1 - str r3, [r2, #0] - bx lr /* "normal" return with r0=0 or - * context switch with r0=1 */ - .size up_saveusercontext, .-up_saveusercontext - - -/************************************************************************** - * Name: up_fullcontextrestore - * - * Description: - * Restore the current thread context. Full prototype is: - * - * void up_fullcontextrestore(uint32 *regs) __attribute__ ((noreturn)); - * - * Return: - * None - * - **************************************************************************/ - - .thumb_func - .globl up_fullcontextrestore - .type up_fullcontextrestore, function -up_fullcontextrestore: - - /* Perform the System call with R0=1 and R1=regs */ - - mov r1, r0 /* R1: regs */ - mov r0, #1 /* R0: 1 means restore context */ - svc 0 /* Force synchronous SVCall (or Hard Fault) */ - - /* This call should not return */ - - bx lr /* Unnecessary ... will not return */ - .size up_fullcontextrestore, .-up_fullcontextrestore - .end - +/************************************************************************************ + * arch/arm/src/cortexm3/up_saveusercontext.S + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include "nvic.h" + +/************************************************************************************ + * Preprocessor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Global Symbols + ************************************************************************************/ + + .syntax unified + .thumb + .file "up_saveusercontext.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************** + * Name: up_saveusercontext + * + * Description: + * Save the current thread context. Full prototype is: + * + * int up_saveusercontext(uint32 *saveregs); + * + * Return: + * 0: Normal return + * 1: Context switch return + * + **************************************************************************/ + + .text + .thumb_func + .globl up_saveusercontext + .type up_saveusercontext, function +up_saveusercontext: + + /* Perform the System call with R0=0 and R1=regs */ + + mov r1, r0 /* R1: regs */ + mov r0, #0 /* R0: 0 means save context (also return value) */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* There are two return conditions. On the first return, R0 (the + * return value will be zero. On the second return we need to + * force R0 to be 1. + */ + + add r2, r1, #(4*REG_R0) + mov r3, #1 + str r3, [r2, #0] + bx lr /* "normal" return with r0=0 or + * context switch with r0=1 */ + .size up_saveusercontext, .-up_saveusercontext + .end + diff --git a/arch/arm/src/cortexm3/up_sigdeliver.c b/arch/arm/src/cortexm3/up_sigdeliver.c index 98dd94e99e..fa7c6b0bf0 100644 --- a/arch/arm/src/cortexm3/up_sigdeliver.c +++ b/arch/arm/src/cortexm3/up_sigdeliver.c @@ -115,7 +115,7 @@ void up_sigdeliver(void) sigdeliver = rtcb->xcp.sigdeliver; rtcb->xcp.sigdeliver = NULL; - /* Then restore the task interrupt statat. */ + /* Then restore the task interrupt state */ irqrestore((uint16)regs[REG_PRIMASK]); diff --git a/arch/arm/src/cortexm3/up_svcall.c b/arch/arm/src/cortexm3/up_svcall.c index 3a346881f1..e559074cc5 100644 --- a/arch/arm/src/cortexm3/up_svcall.c +++ b/arch/arm/src/cortexm3/up_svcall.c @@ -81,50 +81,98 @@ int up_svcall(int irq, FAR void *context) { - uint32 *svregs = (uint32*)context; - uint32 *tcbregs = (uint32*)svregs[REG_R1]; + uint32 *regs = (uint32*)context; - DEBUGASSERT(svregs && svregs == current_regs && tcbregs); + DEBUGASSERT(regs && regs == current_regs); + DEBUGASSERT(regs[REG_R1] != 0); /* The SVCall software interrupt is called with R0 = SVC command and R1 = * the TCB register save area. */ - sllvdbg("Command: %d svregs: %p tcbregs: %08x\n", svregs[REG_R0], svregs, tcbregs); + sllvdbg("Command: %d regs: %p R1: %08x R2: %08x\n", + regs[REG_R0], regs, regs[REG_R1], regs[REG_R2]); #ifdef DEBUG_SVCALL lldbg("SVCall Entry:\n"); lldbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", - svregs[REG_R0], svregs[REG_R1], svregs[REG_R2], svregs[REG_R3], - svregs[REG_R4], svregs[REG_R5], svregs[REG_R6], svregs[REG_R7]); + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); lldbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", - svregs[REG_R8], svregs[REG_R9], svregs[REG_R10], svregs[REG_R11], - svregs[REG_R12], svregs[REG_R13], svregs[REG_R14], svregs[REG_R15]); - lldbg(" PSR=%08x\n", svregs[REG_XPSR]); + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); + lldbg(" PSR=%08x\n", regs[REG_XPSR]); #endif /* Handle the SVCall according to the command in R0 */ - switch (svregs[REG_R0]) + switch (regs[REG_R0]) { - /* R0=0: This is a save context command. In this case, we simply need - * to copy the svregs to the tdbregs and return. + /* R0=0: This is a save context command: + * + * int up_saveusercontext(uint32 *saveregs); + * + * At this point, the following values are saved in context: + * + * R0 = 0 + * R1 = saveregs + * + * In this case, we simply need to copy the current regsters to the + * save regiser space references in the saved R1 and return. */ case 0: - memcpy(tcbregs, svregs, XCPTCONTEXT_SIZE); + { + memcpy((uint32*)regs[REG_R1], regs, XCPTCONTEXT_SIZE); + } break; - /* R1=1: This a restore context command. In this case, we simply need to - * set current_regs to tcbrgs. svregs == current_regs is the normal exception - * turn. By setting current_regs = tcbregs, we force the return through - * the saved context. + /* R0=1: This a restore context command: + * + * void up_fullcontextrestore(uint32 *restoreregs) __attribute__ ((noreturn)); + * + * At this point, the following values are saved in context: + * + * R0 = 1 + * R1 = restoreregs + * + * In this case, we simply need to set current_regs to restore register + * area referenced in the saved R1. context == current_regs is the normal + * exception return. By setting current_regs = context[R1], we force + * the return to the saved context referenced in R1. */ case 1: - current_regs = tcbregs; + { + current_regs = (uint32*)regs[REG_R1]; + } break; + /* R0=2: This a switch context command: + * + * void up_switchcontext(uint32 *saveregs, uint32 *restoreregs); + * + * At this point, the following values are saved in context: + * + * R0 = 1 + * R1 = saveregs + * R2 = restoreregs + * + * In this case, we do both: We save the context registers to the save + * register area reference by the saved contents of R1 nad then set + * current_regs to to the save register area referenced by the saved + * contents of R2. + */ + + case 2: + { + DEBUGASSERT(regs[REG_R2] != 0); + memcpy((uint32*)regs[REG_R1], regs, XCPTCONTEXT_SIZE); + current_regs = (uint32*)regs[REG_R2]; + } + break; + + default: PANIC(OSERR_INTERNAL); break; diff --git a/arch/arm/src/cortexm3/up_switchcontext.S b/arch/arm/src/cortexm3/up_switchcontext.S new file mode 100755 index 0000000000..055a7a268f --- /dev/null +++ b/arch/arm/src/cortexm3/up_switchcontext.S @@ -0,0 +1,95 @@ +/************************************************************************************ + * arch/arm/src/cortexm3/up_switchcontext.S + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include +#include "nvic.h" + +/************************************************************************************ + * Preprocessor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Global Symbols + ************************************************************************************/ + + .syntax unified + .thumb + .file "up_context.S" + +/************************************************************************************ + * Macros + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************** + * Name: up_switchcontext + * + * Description: + * Save the current thread context and restore the specified context. + * Full prototype is: + * + * void up_switchcontext(uint32 *saveregs, uint32 *restoreregs); + * + * Return: + * None + * + **************************************************************************/ + + .thumb_func + .globl up_switchcontext + .type up_switchcontext, function +up_switchcontext: + + /* Perform the System call with R0=1, R1=saveregs, R2=restoreregs */ + + mov r2, r1 /* R2: restoreregs */ + mov r1, r0 /* R1: saveregs */ + mov r0, #2 /* R0: 2 means context switch */ + svc 0 /* Force synchronous SVCall (or Hard Fault) */ + + /* This call should not return */ + + bx lr /* Unnecessary ... will not return */ + .size up_switchcontext, .-up_switchcontext + .end + diff --git a/arch/arm/src/cortexm3/up_unblocktask.c b/arch/arm/src/cortexm3/up_unblocktask.c new file mode 100755 index 0000000000..0fce2d7062 --- /dev/null +++ b/arch/arm/src/cortexm3/up_unblocktask.c @@ -0,0 +1,156 @@ +/**************************************************************************** + * arch/arm/src/cortexm3/up_unblocktask.c + * + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include "os_internal.h" +#include "clock_internal.h" +#include "up_internal.h" + +/**************************************************************************** + * Private Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run taks, executed. + * + ****************************************************************************/ + +void up_unblock_task(_TCB *tcb) +{ + /* Verify that the context switch can be performed */ + + if ((tcb->task_state < FIRST_BLOCKED_STATE) || + (tcb->task_state > LAST_BLOCKED_STATE)) + { + PANIC(OSERR_BADUNBLOCKSTATE); + } + else + { + _TCB *rtcb = (_TCB*)g_readytorun.head; + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Reset its timeslice. This is only meaningful for round + * robin tasks but it doesn't here to do it for everything + */ + +#if CONFIG_RR_INTERVAL > 0 + tcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK; +#endif + + /* Add the task in the correct location in the prioritized + * g_readytorun task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + * + * Are we in an interrupt handler? + */ + + if (current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the g_readytorun task list. + */ + + rtcb = (_TCB*)g_readytorun.head; + + /* Then switch contexts */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + _TCB *nexttcb = (_TCB*)g_readytorun.head; + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } + } +} diff --git a/arch/arm/src/lm3s/Make.defs b/arch/arm/src/lm3s/Make.defs index c668d74862..0b39880e1d 100644 --- a/arch/arm/src/lm3s/Make.defs +++ b/arch/arm/src/lm3s/Make.defs @@ -35,7 +35,7 @@ HEAD_ASRC = lm3s_vectors.S -CMN_ASRCS = up_context.S +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \ up_createstack.c up_mdelay.c up_udelay.c up_exit.c \ up_idle.c up_initialize.c up_initialstate.c up_interruptcontext.c \ diff --git a/arch/arm/src/stm32/Make.defs b/arch/arm/src/stm32/Make.defs index 95c3ae9774..7cbe728253 100755 --- a/arch/arm/src/stm32/Make.defs +++ b/arch/arm/src/stm32/Make.defs @@ -35,7 +35,7 @@ HEAD_ASRC = stm32_vectors.S -CMN_ASRCS = up_context.S +CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \ up_createstack.c up_mdelay.c up_udelay.c up_exit.c \ up_idle.c up_initialize.c up_initialstate.c up_interruptcontext.c \