diff --git a/arch/c5471/src/Makefile b/arch/c5471/src/Makefile index b75b1daf62..a4f953c6f9 100644 --- a/arch/c5471/src/Makefile +++ b/arch/c5471/src/Makefile @@ -44,7 +44,7 @@ ASRCS += up_lowputc.S endif AOBJS = $(ASRCS:.S=.o) -CSRCS = up_initialize.c up_initialstate.c up_idle.c \ +CSRCS = up_initialize.c up_initialstate.c up_idle.c up_doirq.c \ up_irq.c up_syscall.c up_dataabort.c up_prefetchabort.c \ up_undefinedinsn.c up_interruptcontext.c up_timerisr.c \ up_createstack.c up_usestack.c up_releasestack.c \ diff --git a/arch/c5471/src/up_createstack.c b/arch/c5471/src/up_createstack.c index 20276bff09..90919e265f 100644 --- a/arch/c5471/src/up_createstack.c +++ b/arch/c5471/src/up_createstack.c @@ -116,7 +116,7 @@ STATUS up_create_stack(_TCB *tcb, uint32 stack_size) /* Save the adjusted stack values in the _TCB */ - tcb->adj_stack_size = top_of_stack; + tcb->adj_stack_ptr = (uint32*)top_of_stack; tcb->adj_stack_size = size_of_stack; return OK; diff --git a/arch/c5471/src/up_doirq.c b/arch/c5471/src/up_doirq.c new file mode 100644 index 0000000000..339b285966 --- /dev/null +++ b/arch/c5471/src/up_doirq.c @@ -0,0 +1,83 @@ +/************************************************************ + * up_doirq.c + * + * Copyright (C) 2007 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 Gregory Nutt 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 "c5471.h" +#include "up_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Public Data + ************************************************************/ + +/************************************************************ + * Private Data + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Funtions + ************************************************************/ + +void up_doirq(int irq, uint32* regs) +{ + if ((unsigned)irq < NR_IRQS) + { + /* Mask and acknowledge the interrupt */ + + up_maskack_irq(irq); + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + + /* Then unmask it */ + + up_enable_irq(irq); + } +} diff --git a/arch/c5471/src/up_fullcontextrestore.S b/arch/c5471/src/up_fullcontextrestore.S index 572d3c20ca..4d0303ba25 100644 --- a/arch/c5471/src/up_fullcontextrestore.S +++ b/arch/c5471/src/up_fullcontextrestore.S @@ -87,11 +87,11 @@ up_fullcontextrestore: sub sp, sp, #(3*4) /* Frame for three registers */ ldr r1, [r0, #(4*REG_R0)] /* Fetch the stored r0 value */ - str r2, [sp, #8] /* Save it at the top of the stack */ + str r1, [sp] /* Save it at the top of the stack */ ldr r1, [r0, #(4*REG_R1)] /* Fetch the stored r1 value */ - str r2, [sp, #4] /* Save it in the stack */ + str r1, [sp, #4] /* Save it in the stack */ ldr r1, [r0, #(4*REG_PC)] /* Fetch the stored pc value */ - str r2, [sp] /* Save it at the bottom of the stack */ + str r1, [sp, #8] /* Save it at the bottom of the frame */ /* Now we can restore the CPSR. We wait until we are completely * finished with the context save data to do this. Restore the CPSR @@ -104,7 +104,7 @@ up_fullcontextrestore: /* Now recover r0 and r1 */ - ldr r0, [sp, #8] + ldr r0, [sp] ldr r1, [sp, #4] add sp, sp, #(2*4) diff --git a/arch/c5471/src/up_internal.h b/arch/c5471/src/up_internal.h index e11783e023..88ed459f3c 100644 --- a/arch/c5471/src/up_internal.h +++ b/arch/c5471/src/up_internal.h @@ -75,6 +75,7 @@ extern uint32 *current_regs; extern void up_copystate(uint32 *dest, uint32 *src); extern void up_dataabort(uint32 *regs); +extern void up_doirq(int irq, uint32* regs); extern void up_fullcontextrestore(uint32 *regs) __attribute__ ((noreturn)); extern void up_irqinitialize(void); extern void up_prefetchabort(uint32 *regs); diff --git a/arch/c5471/src/up_irq.c b/arch/c5471/src/up_irq.c index d388f6446a..3c8a173712 100644 --- a/arch/c5471/src/up_irq.c +++ b/arch/c5471/src/up_irq.c @@ -48,8 +48,8 @@ * Definitions ************************************************************/ -#define EdgeSensitive 0x00000020 -#define Priority 0x0000001E +#define ILR_EDGESENSITIVE 0x00000020 +#define ILR_PRIORITY 0x0000001E /************************************************************ * Public Data @@ -164,10 +164,10 @@ void up_irqinitialize(void) /* Override hardware defaults */ - putreg32(EdgeSensitive | Priority, ILR_IRQ2_REG); - putreg32(EdgeSensitive | Priority, ILR_IRQ4_REG); - putreg32(Priority, ILR_IRQ6_REG); - putreg32(EdgeSensitive | Priority, ILR_IRQ15_REG); + putreg32(ILR_EDGESENSITIVE | ILR_PRIORITY, ILR_IRQ2_REG); + putreg32(ILR_EDGESENSITIVE | ILR_PRIORITY, ILR_IRQ4_REG); + putreg32(ILR_PRIORITY, ILR_IRQ6_REG); + putreg32(ILR_EDGESENSITIVE | ILR_PRIORITY, ILR_IRQ15_REG); /* Initialize hardware interrupt vectors */ @@ -214,30 +214,26 @@ void up_enable_irq(int irq) } /************************************************************ - * Name: up_acknowledge_irq + * Name: up_maskack_irq * * Description: - * Disable the IRQ specified by 'irq' + * Mask the IRQ and acknowledge it * ************************************************************/ -/* Bit 0 of the Interrupt Control Rigster == New IRQ - * agreement (NEW_IRQ_AGR). Reset IRQ output. Clear source - * IRQ register. Enables a new IRQ generation. Reset by - * internal logic. - * - * IRQ (FIQ) output and SRC_IRQ_REG and SRC_IRQ_BIN_REG - * (SRC_FIQ_REG) registers are reset only if the bit in the - * Interrupt register (IT_REG) corresponding to the interrupt - * having requested MCU action is already cleared or masked. - * - * For an edge-sensitive interrupt, the Interrupt register bit is - * deactivated when reading the SRC_IRQ_REG or SRC_IRQ_BIN_REG - * (SRC_FIQ_REG) registers. - */ - -void up_acknowledge_irq(int irq) +void up_maskack_irq(int irq) { uint32 reg = getreg32(INT_CTRL_REG); + + /* Mask the interrupt */ + + reg = getreg32(MASK_IT_REG); + putreg32(reg | (1 << irq), MASK_IT_REG); + + /* Set the NEW_IRQ_AGR bit. This clears the IRQ src register + * enables generation of a new IRQ. + */ + + reg = getreg32(INT_CTRL_REG); putreg32(reg | 0x00000001, INT_CTRL_REG); /* write the NEW_IRQ_AGR bit. */ } diff --git a/arch/c5471/src/up_vectors.S b/arch/c5471/src/up_vectors.S index b9a4e6d6c4..110fcce693 100644 --- a/arch/c5471/src/up_vectors.S +++ b/arch/c5471/src/up_vectors.S @@ -147,7 +147,7 @@ up_vectorirq: mov fp, #0 /* Init frame pointer */ mov r1, sp /* Get r1=xcp */ - bl up_prefetchabort /* Call the handler */ + bl up_doirq /* Call the handler */ /* Restore the CPSR, SVC modr registers and return */ .Lnoirqset: diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 30f47029a3..a5731b7a0e 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -367,7 +367,7 @@ EXTERN void up_disable_irq(int irq); EXTERN void up_enable_irq(int irq); /************************************************************ - * Name: up_acknowledge_irq + * Name: up_disable_irq * * Description: * Disable the IRQ specified by 'irq' diff --git a/sched/os_start.c b/sched/os_start.c index b4bae75c55..1b249a5b91 100644 --- a/sched/os_start.c +++ b/sched/os_start.c @@ -192,7 +192,7 @@ void os_start(void) int init_taskid; int i; - lldbg("os_start:\n"); + lldbg("%s: Entry\n", __FUNCTION__); /* Initialize all task lists */ @@ -349,7 +349,7 @@ void os_start(void) * started by spawning the user init thread of execution. */ - dbg("os_start: Starting init thread\n"); + dbg("%s: Starting init thread\n", __FUNCTION__); init_taskid = task_create("init", SCHED_PRIORITY_DEFAULT, CONFIG_PROC_STACK_SIZE, (main_t)user_start, 0, 0, 0, 0); @@ -357,7 +357,7 @@ void os_start(void) /* When control is return to this point, the system is idle. */ - dbg("os_start: Beginning Idle Loop\n"); + dbg("%s: Beginning Idle Loop\n", __FUNCTION__); for (;;) { /* Check if there is anything in the delayed deallocation list. */ diff --git a/sched/task_create.c b/sched/task_create.c index ecfd68056d..dd7da112e4 100644 --- a/sched/task_create.c +++ b/sched/task_create.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include "os_internal.h" @@ -225,6 +226,8 @@ STATUS _task_init(_TCB *tcb, char *name, int priority, { STATUS ret; + vdbg("%s: Entry\n", __FUNCTION__); + /* Assign a unique task ID to the task. */ ret = task_assignpid(tcb); @@ -376,33 +379,35 @@ STATUS task_init(_TCB *tcb, char *name, int priority, STATUS task_activate(_TCB *tcb) { #ifdef CONFIG_SCHED_INSTRUMENTATION - uint32 savedState; + uint32 flags; #endif + vdbg("%s: Entry\n", __FUNCTION__); + #ifdef CONFIG_SCHED_INSTRUMENTATION - savedState = irqsave(); + flags = irqsave(); - /* Check if this is really a re-start */ + /* Check if this is really a re-start */ - if (tcb->task_state != TSTATE_TASK_INACTIVE) - { - /* Inform the instrumentation layer that the task - * has stopped - */ + if (tcb->task_state != TSTATE_TASK_INACTIVE) + { + /* Inform the instrumentation layer that the task + * has stopped + */ - sched_note_stop(tcb); - } + sched_note_stop(tcb); + } - /* Inform the instrumentation layer that the task - * has started - */ + /* Inform the instrumentation layer that the task + * has started + */ - sched_note_start(tcb); - irqrestore(savedState); + sched_note_start(tcb); + irqrestore(flags); #endif - up_unblock_task(tcb); - return OK; + up_unblock_task(tcb); + return OK; } /************************************************************ @@ -444,6 +449,8 @@ int task_create(char *name, int priority, STATUS status; pid_t pid; + vdbg("%s: Entry\n", __FUNCTION__); + /* Allocate a TCB for the new task. */ tcb = (_TCB*)kzmalloc(sizeof(_TCB));