9
0
Fork 0

More PIC32 debug updates

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4083 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2011-11-09 23:59:46 +00:00
parent b9c781e695
commit 9f1923db12
16 changed files with 649 additions and 443 deletions

View File

@ -76,7 +76,7 @@
# define CONFIG_ARCH_INTERRUPTSTACK 0
#endif
/* In the MIPS model, the state is copied from the stack to the TCB, but
/* In the MIPS model, the state is copied from the stack to the TCB, but
* only a referenced is passed to get the state from the TCB.
*/
@ -182,6 +182,10 @@ extern void up_dumpstate(void);
extern uint32_t *up_doirq(int irq, uint32_t *regs);
/* Software interrupt 0 handler */
extern int up_swint0(int irq, FAR void *context);
/* Signals */
extern void up_sigdeliver(void);

View File

@ -326,7 +326,7 @@ int up_swint0(int irq, FAR void *context)
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
memcpy((uint32_t*)regs[REG_A1], regs, XCPTCONTEXT_SIZE);
up_copystate((uint32_t*)regs[REG_A1], regs);
current_regs = (uint32_t*)regs[REG_A2];
}
break;

View File

@ -1,413 +1,413 @@
/********************************************************************************************
* arch/mips/src/pic32mx/excptmacros.h
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* 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.
*
********************************************************************************************/
#ifndef __ARCH_MIPS_SRC_PIC32MX_EXCPTMACROS_H
#define __ARCH_MIPS_SRC_PIC32MX_EXCPTMACROS_H
/********************************************************************************************
* Included Files
********************************************************************************************/
#include <nuttx/config.h>
#include <arch/irq.h>
#include <arch/pic32mx/cp0.h>
#ifdef __ASSEMBLY__
/********************************************************************************************
* Pre-Processor Definitions
********************************************************************************************/
/********************************************************************************************
* Global Symbols
********************************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 3
.global g_intstackbase
.global g_nestlevel
#endif
/********************************************************************************************
* Assembly Language Macros
********************************************************************************************/
/********************************************************************************************
* General Usage Example:
*
* my_exception:
* EXCPT_PROLOGUE t0 - Save registers on stack, enable nested interrupts
* move a0, sp - Pass register save structure as the parameter 1
* USE_INTSTACK t0, t1, t2 - Switch to the interrupt stack
* jal handler - Handle the exception IN=old regs OUT=new regs
* di - Disable interrupts
* RESTORE_STACK t0, t1 - Undo the operations of USE_STACK
* EXCPT_EPILOGUE v0 - Return to the context returned by handler()
*
********************************************************************************************/
/********************************************************************************************
* Name: EXCPT_PROLOGUE
*
* Description:
* Provides the "prologue" logic that should appear at the beginning of every exception
* handler.
*
* On Entry:
* sp - Points to the top of the stack
* tmp - Is a register the can be modified for scratch usage (after it has been saved)
* k0 and k1 - Since we are in an exception handler, these are available for use
*
* At completion:
* Register state is saved on the stack; All registers are available for usage except sp
* and k1:
*
* - sp points the beginning of the register save area
* - k1 holds the value of the STATUS register
*
* The following registers are modified: k0, k1, sp, a0
*
********************************************************************************************/
.macro EXCPT_PROLOGUE, tmp
.set noat
/* Get the SP from the previous shadow set */
#if 0
rdpgpr sp, sp
#endif
/* "When entering the interrupt handler routine, the interrupt controller must first
* save the current priority and exception PC counter from Interrupt Priority (IPL)
* bits (Status<15:10>) and the ErrorEPC register, respectively, on the stack. ..."
*/
mfc0 k0, MIPS32_CP0_CAUSE
mfc0 k1, MIPS32_CP0_EPC
/* Isolate the pending interrupt level in bits 0-5 of k0 */
srl k0, k0, CP0_CAUSE_IP_SHIFT
/* Create the register context stack frame large enough to hold the entire register save
* array.
*/
addiu sp, sp, -XCPTCONTEXT_SIZE
/* Save the EPC and STATUS in the register context array */
sw k1, REG_EPC(sp)
mfc0 k1, MIPS32_CP0_STATUS
sw k1, REG_STATUS(sp)
/* Then insert pending interrupt level as the current mask level in the CP0 status
* register. Also clear bits 1-4 in new value of the status register:
*
* Bit 1: Exception Level
* Bit 2: Error Level
* Bit 3: (not used in PIC32MX)
* Bit 4: Operating mode == USER
*/
ins k1, \tmp, CP0_STATUS_IPL_SHIFT, 6
ins k1, zero, 1, 4
/* And Enable interrupts */
mtc0 k1, MIPS32_CP0_STATUS
/* Save floating point registers */
mfhi k0
sw k0, REG_MFHI(sp)
mflo k0
sw k0, REG_MFLO(sp)
/* Save general purpose registers */
/* $1: at_reg, assembler temporary */
sw $1, REG_AT(sp)
/* $2-$3 = v0-v1: Return value registers */
sw v0, REG_V0(sp)
sw v1, REG_V1(sp)
/* $4-$7 = a0-a3: Argument registers */
sw a0, REG_A0(sp)
sw a1, REG_A1(sp)
sw a2, REG_A2(sp)
sw a3, REG_A3(sp)
/* $8-$15 = t0-t7: Volatile registers */
sw t0, REG_T0(sp)
sw t1, REG_T1(sp)
sw t2, REG_T2(sp)
sw t3, REG_T3(sp)
sw t4, REG_T4(sp)
sw t5, REG_T5(sp)
sw t6, REG_T6(sp)
sw t7, REG_T7(sp)
/* $16-$23 = s0-s7: Static registers */
sw s0, REG_S0(sp)
sw s1, REG_S1(sp)
sw s2, REG_S2(sp)
sw s3, REG_S3(sp)
sw s4, REG_S4(sp)
sw s5, REG_S5(sp)
sw s6, REG_S6(sp)
sw s7, REG_S7(sp)
/* $24-25 = t8-t9: More Volatile registers */
sw t8, REG_T8(sp)
sw t9, REG_T9(sp)
/* $26-$27 = ko-k1: Reserved for use in exeption handers. These do not need to be
* saved.
*
* $28 = gp: Only needs to be saved under conditions where there are multiple, per-
* thread values for the GP.
*/
#ifdef MIPS32_SAVE_GP
sw gp, REG_GP(sp)
#endif
/* $30 = either s8 or fp: Depends if a frame pointer is used or not */
sw s8, REG_S8(sp)
/* $31 = ra: Return address */
sw ra, REG_RA(sp)
/* $29 = sp: The value of the stack pointer on return from the exception. a0 is
* used as a temporary
*/
addiu \tmp, sp, XCPTCONTEXT_SIZE
sw \tmp, REG_SP(sp)
.endm
/********************************************************************************************
* Name: EXCPT_EPILOGUE
*
* Description:
* Provides the "epilogue" logic that should appear at the end of every exception handler.
*
* On input:
* regs - points to the register save structure. NOTE: This *may not* be an address
* lying in a stack! It might be an address in a TCB!
* Interrupts are disabled (via 'di')
*
* On completion:
* All registers restored
* eret is executed to return from the exception
*
********************************************************************************************/
.macro EXCPT_EPILOGUE, regs
.set noat
/* Since interrupts are disabled via di can now use k0 and k1 again. Use k1 as the
* pointer to the register save array.
*/
move k1, \regs
/* Restore the floating point register state */
lw k0, REG_MFLO(k1)
mtlo k0
lw k0, REG_MFHI(k1)
mthi k0
/* Restore general purpose registers */
/* $1: at_reg, assembler temporary */
lw $1, REG_AT(k1)
/* $2-$3 = v0-v1: Return value registers */
lw v0, REG_V0(k1)
lw v1, REG_V1(k1)
/* $4-$7 = a0-a3: Argument registers */
lw a0, REG_A0(k1)
lw a1, REG_A1(k1)
lw a2, REG_A2(k1)
lw a3, REG_A3(k1)
/* $8-$15 = t0-t7: Volatile registers */
lw t0, REG_T0(k1)
lw t1, REG_T1(k1)
lw t2, REG_T2(k1)
lw t3, REG_T3(k1)
lw t4, REG_T4(k1)
lw t5, REG_T5(k1)
lw t6, REG_T6(k1)
lw t7, REG_T7(k1)
/* $16-$23 = s0-s7: Static registers */
lw s0, REG_S0(k1)
lw s1, REG_S1(k1)
lw s2, REG_S2(k1)
lw s3, REG_S3(k1)
lw s4, REG_S4(k1)
lw s5, REG_S5(k1)
lw s6, REG_S6(k1)
lw s7, REG_S7(k1)
/* $24-25 = t8-t9: More Volatile registers */
lw t8, REG_T8(k1)
lw t9, REG_T9(k1)
/* $26-$27 = ko-k1: Reserved for use in exeption handers. These do not need to be
* saved.
*
* $28 = gp: Only needs to be saved under conditions where there are multiple, per-
* thread values for the GP.
*/
#ifdef MIPS32_SAVE_GP
lw gp, REG_GP(k1)
#endif
/* $30 = either s8 or fp: Depends if a frame pointer is used or not */
lw s8, REG_S8(k1)
/* $31 = ra: Return address */
lw ra, REG_RA(k1)
/* Finally, restore CP status and the EPC */
lw k0, REG_STATUS(k1)
lw k1, REG_EPC(k1)
mtc0 k0, MIPS32_CP0_STATUS
ehb
mtc0 k1, MIPS32_CP0_EPC
eret
nop
.endm
/********************************************************************************************
* Name: USE_INTSTACK
*
* Description:
* Switch to the interrupt stack (if enabled in the configuration).
*
* On Entry:
* sp - Current value of the user stack pointer
* tmp1, tmp2, and tmp3 are registers that can be used temporarily.
* All interrupts should still be disabled.
*
* At completion:
* If the nesting level is 0, then (1) the user stack pointer is saved at the base of the
* interrupt stack and sp points to the interrupt stack.
* The values of tmp1, tmp2, tmp3, and sp have been altered
*
********************************************************************************************/
.macro USE_INTSTACK, tmp1, tmp2, tmp3
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Check the nesting level. If there are no nested interrupts, then we can
* claim the interrupt stack.
*/
la \tmp1, g_nestlevel
lw \tmp2, (\tmp1)
bne 1f
nop
/* Use the interrupt stack, pushing the user stack pointer onto the interrupt
* stack first.
*/
la \tmp3, g_intstackbase
lw \tmp, (\tmp3)
sw sp, (\tmp3)
move sp, \tmp3
1:
/* Increment the interrupt nesting level */
addiu \tmp2, \tmp2, 1
sw \tmp2, 0(\tmp1)
#endif
.endm
/********************************************************************************************
* Name: RESTORE_STACK
*
* Description:
* Restore the user stack. Not really.. actually only decrements the nesting level. We
* always get the new stack pointer for the register save array.
*
* On Entry:
* tmp1 and tmp2 are registers that can be used temporarily.
* All interrupts must be disabled.
*
* At completion:
* Current nesting level is decremented
* The values of tmp1 and tmp2 have been altered
*
********************************************************************************************/
.macro RESTORE_STACK, tmp1, tmp2
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Decrement the nesting level */
la \tmp1, g_nestlevel
lw \tmp2, (\tmp1)
addiu \tmp2, \tmp2, -1
sw \tmp2, 0(\tmp1)
#endif
.endm
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_MIPS_SRC_PIC32MX_EXCPTMACROS_H */
/********************************************************************************************
* arch/mips/src/pic32mx/excptmacros.h
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* 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.
*
********************************************************************************************/
#ifndef __ARCH_MIPS_SRC_PIC32MX_EXCPTMACROS_H
#define __ARCH_MIPS_SRC_PIC32MX_EXCPTMACROS_H
/********************************************************************************************
* Included Files
********************************************************************************************/
#include <nuttx/config.h>
#include <arch/irq.h>
#include <arch/pic32mx/cp0.h>
#ifdef __ASSEMBLY__
/********************************************************************************************
* Pre-Processor Definitions
********************************************************************************************/
/********************************************************************************************
* Global Symbols
********************************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 3
.global g_intstackbase
.global g_nestlevel
#endif
/********************************************************************************************
* Assembly Language Macros
********************************************************************************************/
/********************************************************************************************
* General Usage Example:
*
* my_exception:
* EXCPT_PROLOGUE t0 - Save registers on stack, enable nested interrupts
* move a0, sp - Pass register save structure as the parameter 1
* USE_INTSTACK t0, t1, t2 - Switch to the interrupt stack
* jal handler - Handle the exception IN=old regs OUT=new regs
* di - Disable interrupts
* RESTORE_STACK t0, t1 - Undo the operations of USE_STACK
* EXCPT_EPILOGUE v0 - Return to the context returned by handler()
*
********************************************************************************************/
/********************************************************************************************
* Name: EXCPT_PROLOGUE
*
* Description:
* Provides the "prologue" logic that should appear at the beginning of every exception
* handler.
*
* On Entry:
* sp - Points to the top of the stack
* tmp - Is a register the can be modified for scratch usage (after it has been saved)
* k0 and k1 - Since we are in an exception handler, these are available for use
*
* At completion:
* Register state is saved on the stack; All registers are available for usage except sp
* and k1:
*
* - sp points the beginning of the register save area
* - k1 holds the value of the STATUS register
*
* The following registers are modified: k0, k1, sp, a0
*
********************************************************************************************/
.macro EXCPT_PROLOGUE, tmp
.set noat
/* Get the SP from the previous shadow set */
#if 0
rdpgpr sp, sp
#endif
/* "When entering the interrupt handler routine, the interrupt controller must first
* save the current priority and exception PC counter from Interrupt Priority (IPL)
* bits (Status<15:10>) and the ErrorEPC register, respectively, on the stack. ..."
*/
mfc0 k0, MIPS32_CP0_CAUSE
mfc0 k1, MIPS32_CP0_EPC
/* Isolate the pending interrupt level in bits 0-5 of k0 */
srl k0, k0, CP0_CAUSE_IP_SHIFT
/* Create the register context stack frame large enough to hold the entire register save
* array.
*/
addiu sp, sp, -XCPTCONTEXT_SIZE
/* Save the EPC and STATUS in the register context array */
sw k1, REG_EPC(sp)
mfc0 k1, MIPS32_CP0_STATUS
sw k1, REG_STATUS(sp)
/* Then insert pending interrupt level as the current mask level in the CP0 status
* register. Also clear bits 1-4 in new value of the status register:
*
* Bit 1: Exception Level
* Bit 2: Error Level
* Bit 3: (not used in PIC32MX)
* Bit 4: Operating mode == USER
*/
ins k1, \tmp, CP0_STATUS_IPL_SHIFT, 6
ins k1, zero, 1, 4
/* And Enable interrupts */
mtc0 k1, MIPS32_CP0_STATUS
/* Save floating point registers */
mfhi k0
sw k0, REG_MFHI(sp)
mflo k0
sw k0, REG_MFLO(sp)
/* Save general purpose registers */
/* $1: at_reg, assembler temporary */
sw $1, REG_AT(sp)
/* $2-$3 = v0-v1: Return value registers */
sw v0, REG_V0(sp)
sw v1, REG_V1(sp)
/* $4-$7 = a0-a3: Argument registers */
sw a0, REG_A0(sp)
sw a1, REG_A1(sp)
sw a2, REG_A2(sp)
sw a3, REG_A3(sp)
/* $8-$15 = t0-t7: Volatile registers */
sw t0, REG_T0(sp)
sw t1, REG_T1(sp)
sw t2, REG_T2(sp)
sw t3, REG_T3(sp)
sw t4, REG_T4(sp)
sw t5, REG_T5(sp)
sw t6, REG_T6(sp)
sw t7, REG_T7(sp)
/* $16-$23 = s0-s7: Static registers */
sw s0, REG_S0(sp)
sw s1, REG_S1(sp)
sw s2, REG_S2(sp)
sw s3, REG_S3(sp)
sw s4, REG_S4(sp)
sw s5, REG_S5(sp)
sw s6, REG_S6(sp)
sw s7, REG_S7(sp)
/* $24-25 = t8-t9: More Volatile registers */
sw t8, REG_T8(sp)
sw t9, REG_T9(sp)
/* $26-$27 = ko-k1: Reserved for use in exeption handers. These do not need to be
* saved.
*
* $28 = gp: Only needs to be saved under conditions where there are multiple, per-
* thread values for the GP.
*/
#ifdef MIPS32_SAVE_GP
sw gp, REG_GP(sp)
#endif
/* $30 = either s8 or fp: Depends if a frame pointer is used or not */
sw s8, REG_S8(sp)
/* $31 = ra: Return address */
sw ra, REG_RA(sp)
/* $29 = sp: The value of the stack pointer on return from the exception. a0 is
* used as a temporary
*/
addiu \tmp, sp, XCPTCONTEXT_SIZE
sw \tmp, REG_SP(sp)
.endm
/********************************************************************************************
* Name: EXCPT_EPILOGUE
*
* Description:
* Provides the "epilogue" logic that should appear at the end of every exception handler.
*
* On input:
* regs - points to the register save structure. NOTE: This *may not* be an address
* lying in a stack! It might be an address in a TCB!
* Interrupts are disabled (via 'di')
*
* On completion:
* All registers restored
* eret is executed to return from the exception
*
********************************************************************************************/
.macro EXCPT_EPILOGUE, regs
.set noat
/* Since interrupts are disabled via di can now use k0 and k1 again. Use k1 as the
* pointer to the register save array.
*/
move k1, \regs
/* Restore the floating point register state */
lw k0, REG_MFLO(k1)
mtlo k0
lw k0, REG_MFHI(k1)
mthi k0
/* Restore general purpose registers */
/* $1: at_reg, assembler temporary */
lw $1, REG_AT(k1)
/* $2-$3 = v0-v1: Return value registers */
lw v0, REG_V0(k1)
lw v1, REG_V1(k1)
/* $4-$7 = a0-a3: Argument registers */
lw a0, REG_A0(k1)
lw a1, REG_A1(k1)
lw a2, REG_A2(k1)
lw a3, REG_A3(k1)
/* $8-$15 = t0-t7: Volatile registers */
lw t0, REG_T0(k1)
lw t1, REG_T1(k1)
lw t2, REG_T2(k1)
lw t3, REG_T3(k1)
lw t4, REG_T4(k1)
lw t5, REG_T5(k1)
lw t6, REG_T6(k1)
lw t7, REG_T7(k1)
/* $16-$23 = s0-s7: Static registers */
lw s0, REG_S0(k1)
lw s1, REG_S1(k1)
lw s2, REG_S2(k1)
lw s3, REG_S3(k1)
lw s4, REG_S4(k1)
lw s5, REG_S5(k1)
lw s6, REG_S6(k1)
lw s7, REG_S7(k1)
/* $24-25 = t8-t9: More Volatile registers */
lw t8, REG_T8(k1)
lw t9, REG_T9(k1)
/* $26-$27 = ko-k1: Reserved for use in exeption handers. These do not need to be
* saved.
*
* $28 = gp: Only needs to be saved under conditions where there are multiple, per-
* thread values for the GP.
*/
#ifdef MIPS32_SAVE_GP
lw gp, REG_GP(k1)
#endif
/* $30 = either s8 or fp: Depends if a frame pointer is used or not */
lw s8, REG_S8(k1)
/* $31 = ra: Return address */
lw ra, REG_RA(k1)
/* Finally, restore CP status and the EPC */
lw k0, REG_STATUS(k1)
lw k1, REG_EPC(k1)
mtc0 k0, MIPS32_CP0_STATUS
ehb
mtc0 k1, MIPS32_CP0_EPC
eret
nop
.endm
/********************************************************************************************
* Name: USE_INTSTACK
*
* Description:
* Switch to the interrupt stack (if enabled in the configuration).
*
* On Entry:
* sp - Current value of the user stack pointer
* tmp1, tmp2, and tmp3 are registers that can be used temporarily.
* All interrupts should still be disabled.
*
* At completion:
* If the nesting level is 0, then (1) the user stack pointer is saved at the base of the
* interrupt stack and sp points to the interrupt stack.
* The values of tmp1, tmp2, tmp3, and sp have been altered
*
********************************************************************************************/
.macro USE_INTSTACK, tmp1, tmp2, tmp3
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Check the nesting level. If there are no nested interrupts, then we can
* claim the interrupt stack.
*/
la \tmp1, g_nestlevel
lw \tmp2, (\tmp1)
bne 1f
nop
/* Use the interrupt stack, pushing the user stack pointer onto the interrupt
* stack first.
*/
la \tmp3, g_intstackbase
lw \tmp, (\tmp3)
sw sp, (\tmp3)
move sp, \tmp3
1:
/* Increment the interrupt nesting level */
addiu \tmp2, \tmp2, 1
sw \tmp2, 0(\tmp1)
#endif
.endm
/********************************************************************************************
* Name: RESTORE_STACK
*
* Description:
* Restore the user stack. Not really.. actually only decrements the nesting level. We
* always get the new stack pointer for the register save array.
*
* On Entry:
* tmp1 and tmp2 are registers that can be used temporarily.
* All interrupts must be disabled.
*
* At completion:
* Current nesting level is decremented
* The values of tmp1 and tmp2 have been altered
*
********************************************************************************************/
.macro RESTORE_STACK, tmp1, tmp2
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Decrement the nesting level */
la \tmp1, g_nestlevel
lw \tmp2, (\tmp1)
addiu \tmp2, \tmp2, -1
sw \tmp2, 0(\tmp1)
#endif
.endm
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_MIPS_SRC_PIC32MX_EXCPTMACROS_H */

View File

@ -127,21 +127,9 @@ uint32_t *pic32mx_decodeirq(uint32_t *regs)
irq = ((regval) & INT_INTSTAT_VEC_MASK) >> INT_INTSTAT_VEC_SHIFT;
/* Disable further interrupts from this source until the driver has
* cleared the pending interrupt sources.
*/
up_disable_irq(irq);
/* Deliver the IRQ */
irq_dispatch(irq, regs);
/* Unmask the last interrupt (global interrupt below the current interrupt
* level are are still disabled)
*/
up_enable_irq(irq);
}
/* If a context switch occurred while processing the interrupt then

View File

@ -435,6 +435,7 @@ _bev_handler:
USE_INTSTACK t0, t1, t2 /* Switch to the interrupt stack */
la t0, pic32mx_dobev /* Call up_dobev(regs) */
jalr ra, t0
nop
di /* Disable interrupts */
RESTORE_STACK t0, t1 /* Undo the operations of USE_STACK */
EXCPT_EPILOGUE v0 /* Return to the context returned by up_dobev() */
@ -457,6 +458,7 @@ _int_handler:
USE_INTSTACK t0, t1, t2 /* Switch to the interrupt stack */
la t0, pic32mx_decodeirq /* Call pic32mx_decodeirq(regs) */
jalr ra, t0
nop
di /* Disable interrupts */
RESTORE_STACK t0, t1 /* Undo the operations of USE_STACK */
EXCPT_EPILOGUE v0 /* Return to the context returned by pic32mx_decodeirq() */
@ -480,6 +482,7 @@ _nmi_handler:
USE_INTSTACK t0, t1, t2 /* Switch to the interrupt stack */
la t0, pic32mx_donmi /* Call up_donmi(regs) */
jalr ra, t0
nop
di /* Disable interrupts */
RESTORE_STACK t0, t1 /* Undo the operations of USE_STACK */
EXCPT_EPILOGUE v0 /* Return to the context returned by pic32mx_donmi() */

View File

@ -143,12 +143,17 @@ void up_irqinitialize(void)
putreg32(INT_INTCON_MVEC, PIC32MX_INT_INTCONCLR);
#endif
/* Initialize GPIO change notifiction handling */
/* Initialize GPIO change notification handling */
#ifdef CONFIG_GPIO_IRQ
pic32mx_gpioirqinitialize();
#endif
/* Attach and enable software interrupts */
irq_attach(PIC32MX_IRQ_CS0, up_swint0);
up_enable_irq(PIC32MX_IRQSRC_CS0);
/* currents_regs is non-NULL only while processing an interrupt */
current_regs = NULL;
@ -194,14 +199,14 @@ void up_disable_irq(int irq)
/* Use IEC0 */
regaddr = PIC32MX_INT_IEC0CLR;
bitno -= PIC32MX_IRQSRC0_FIRST;
bitno = irq - PIC32MX_IRQSRC0_FIRST;
}
else if (irq <= PIC32MX_IRQSRC1_LAST)
{
/* Use IEC1 */
regaddr = PIC32MX_INT_IEC1CLR;
bitno -= PIC32MX_IRQSRC1_FIRST;
bitno = irq - PIC32MX_IRQSRC1_FIRST;
}
#ifdef PIC32MX_IRQSRC2_FIRST
else if (irq <= PIC32MX_IRQSRC2_LAST)
@ -209,7 +214,7 @@ void up_disable_irq(int irq)
/* Use IEC2 */
regaddr = PIC32MX_INT_IEC2CLR;
bitno -= PIC32MX_IRQSRC2_FIRST;
bitno = irq - PIC32MX_IRQSRC2_FIRST;
}
#endif
else
@ -248,14 +253,14 @@ void up_enable_irq(int irq)
/* Use IEC0 */
regaddr = PIC32MX_INT_IEC0SET;
bitno -= PIC32MX_IRQSRC0_FIRST;
bitno = irq - PIC32MX_IRQSRC0_FIRST;
}
else if (irq <= PIC32MX_IRQSRC1_LAST)
{
/* Use IEC1 */
regaddr = PIC32MX_INT_IEC1SET;
bitno -= PIC32MX_IRQSRC1_FIRST;
bitno = irq - PIC32MX_IRQSRC1_FIRST;
}
#ifdef PIC32MX_IRQSRC2_FIRST
else if (irq <= PIC32MX_IRQSRC2_LAST)
@ -263,7 +268,7 @@ void up_enable_irq(int irq)
/* Use IEC2 */
regaddr = PIC32MX_INT_IEC2SET;
bitno -= PIC32MX_IRQSRC2_FIRST;
bitno = irq - PIC32MX_IRQSRC2_FIRST;
}
#endif
else

View File

@ -871,7 +871,7 @@ CONFIG_BOOT_RUNFROMFLASH=n
CONFIG_BOOT_COPYTORAM=n
CONFIG_CUSTOM_STACK=n
CONFIG_STACK_POINTER=
CONFIG_IDLETHREAD_STACKSIZE=1024
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_USERMAIN_STACKSIZE=2048
CONFIG_PTHREAD_STACK_MIN=256
CONFIG_PTHREAD_STACK_DEFAULT=2048

View File

@ -60,7 +60,7 @@ MEMORY
* Debug code 0x1fc02000 KSEG1 4096-16 12272
* DEVCFG3-0 0x1fc02ff0 KSEG1 16 12288 (12Kb)
*
* Exceptions assme:
* Exceptions assume:
*
* STATUS: BEV=1 and EXL=0
* CAUSE: IV=1
@ -79,9 +79,12 @@ MEMORY
/* The PIC32MX460F512L has 32Kb of data memory at physical address
* 0x00000000. Since the PIC32MX has no data cache, this memory is
* always accessed through KSEG1.
*
* When used with MPLAB, we need to set aside 512 bytes of memory
* for use by MPLAB.
*/
kseg1_datamem (w!x) : ORIGIN = 0xa0000000, LENGTH = 32K
kseg1_datamem (w!x) : ORIGIN = 0xa0000200, LENGTH = 32K - 512
}
OUTPUT_FORMAT("elf32-tradlittlemips")

View File

@ -902,7 +902,7 @@ CONFIG_BOOT_RUNFROMFLASH=n
CONFIG_BOOT_COPYTORAM=n
CONFIG_CUSTOM_STACK=n
CONFIG_STACK_POINTER=
CONFIG_IDLETHREAD_STACKSIZE=1024
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_USERMAIN_STACKSIZE=2048
CONFIG_PTHREAD_STACK_MIN=256
CONFIG_PTHREAD_STACK_DEFAULT=2048

View File

@ -60,7 +60,7 @@ MEMORY
* Debug code 0x1fc02000 KSEG1 4096-16 12272
* DEVCFG3-0 0x1fc02ff0 KSEG1 16 12288 (12Kb)
*
* Exceptions assme:
* Exceptions assume:
*
* STATUS: BEV=1 and EXL=0
* CAUSE: IV=1
@ -79,9 +79,12 @@ MEMORY
/* The PIC32MX795F512L has 128Kb of data memory at physical address
* 0x00000000. Since the PIC32MX has no data cache, this memory is
* always accessed through KSEG1.
*
* When used with MPLAB, we need to set aside 512 bytes of memory
* for use by MPLAB.
*/
kseg1_datamem (w!x) : ORIGIN = 0xa0000000, LENGTH = 128K
kseg1_datamem (w!x) : ORIGIN = 0xa0000200, LENGTH = 128K - 512
}
OUTPUT_FORMAT("elf32-tradlittlemips")

View File

@ -12,6 +12,7 @@ Contents
- IDEs
- NuttX buildroot Toolchain
- DFU and JTAG
- OpenOCD
- LEDs
- Temperature Sensor
- RTC
@ -238,6 +239,32 @@ DFU and JTAG
The default setting (none of the above defined) is SWJ_CFG[2:0] set to 100
which disable JTAG-DP and SW-DP.
OpenOCD
=======
I have also used OpenOCD with the STM3210E-EVAL. In this case, I used
the Olimex USB ARM OCD. See the script in configs/stm3210e-eval/tools/oocd.sh
for more information. Using the script:
1) Start the OpenOCD GDB server
cd <nuttx-build-directory>
configs/stm3210e-eval/tools/oocd.sh $PWD
2) Load Nuttx
cd <nuttx-built-directory>
arm-none-eabi-gdb nuttx
gdb> target remote localhost:3333
gdb> mon reset
gdb> mon halt
gdb> load nuttx
3) Running NuttX
gdb> mon reset
gdb> c
LEDs
====

View File

@ -0,0 +1,11 @@
#
# Olimex ARM-USB-OCD
#
# http://www.olimex.com/dev/arm-usb-ocd.html
#
interface ft2232
ft2232_device_desc "Olimex OpenOCD JTAG"
ft2232_layout olimex-jtag
ft2232_vid_pid 0x15ba 0x0003

View File

@ -0,0 +1,90 @@
#!/bin/sh
# Get command line parameters
USAGE="USAGE: $0 [-dh] <TOPDIR>"
ADVICE="Try '$0 -h' for more information"
while [ ! -z "$1" ]; do
case $1 in
-d )
set -x
;;
-h )
echo "$0 is a tool for generation of proper version files for the NuttX build"
echo ""
echo $USAGE
echo ""
echo "Where:"
echo " -d"
echo " Enable script debug"
echo " -h"
echo " show this help message and exit"
echo " Use the OpenOCD 0.4.0"
echo " <TOPDIR>"
echo " The full path to the top-level NuttX directory"
exit 0
;;
* )
break;
;;
esac
shift
done
TOPDIR=$1
if [ -z "${TOPDIR}" ]; then
echo "Missing argument"
echo $USAGE
echo $ADVICE
exit 1
fi
# This script *probably* only works with the following versions of OpenOCD:
# Local search directory and configurations
OPENOCD_SEARCHDIR="${TOPDIR}/configs/stm3210e-eval/tools"
OPENOCD_WSEARCHDIR="`cygpath -w ${OPENOCD_SEARCHDIR}`"
OPENOCD_PATH="/cygdrive/c/Program Files (x86)/OpenOCD/0.4.0/bin"
OPENOCD_EXE=openocd.exe
OPENOCD_INTERFACE="olimex-arm-usb-ocd.cfg"
OPENOCD_TARGET="stm32.cfg"
OPENOCD_ARGS="-s ${OPENOCD_WSEARCHDIR} -f ${OPENOCD_INTERFACE} -f ${OPENOCD_TARGET}"
echo "Trying OpenOCD 0.4.0 path: ${OPENOCD_PATH}/${OPENOCD_EXE}"
# Verify that everything is what it claims it is and is located where it claims it is.
if [ ! -x "${OPENOCD_PATH}/${OPENOCD_EXE}" ]; then
echo "OpenOCD executable does not exist: ${OPENOCD_PATH}/${OPENOCD_EXE}"
exit 1
fi
if [ ! -f "${OPENOCD_SEARCHDIR}/${OPENOCD_TARGET}" ]; then
echo "OpenOCD target config file does not exist: ${OPENOCD_SEARCHDIR}/${OPENOCD_TARGET}"
exit 1
fi
if [ ! -f "${OPENOCD_SEARCHDIR}/${OPENOCD_INTERFACE}" ]; then
echo "OpenOCD interface config file does not exist: ${OPENOCD_SEARCHDIR}/${OPENOCD_INTERFACE}"
exit 1
fi
# Enable debug if so requested
if [ "X$2" = "X-d" ]; then
OPENOCD_ARGS=$OPENOCD_ARGS" -d3"
set -x
fi
# Okay... do it!
echo "Starting OpenOCD"
"${OPENOCD_PATH}/${OPENOCD_EXE}" ${OPENOCD_ARGS} &
echo "OpenOCD daemon started"
ps -ef | grep openocd
echo "In GDB: target remote localhost:3333"

View File

@ -0,0 +1,69 @@
# script for stm32
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME stm32
}
if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
set _ENDIAN little
}
# Work-area is a space in RAM used for flash programming
# By default use 16kB
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x4000
}
# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz
jtag_khz 1000
jtag_nsrst_delay 100
jtag_ntrst_delay 100
#jtag scan chain
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
# See STM Document RM0008
# Section 26.6.3
set _CPUTAPID 0x3ba00477
}
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
if { [info exists BSTAPID ] } {
# FIXME this never gets used to override defaults...
set _BSTAPID $BSTAPID
} else {
# See STM Document RM0008
# Section 29.6.2
# Low density devices, Rev A
set _BSTAPID1 0x06412041
# Medium density devices, Rev A
set _BSTAPID2 0x06410041
# Medium density devices, Rev B and Rev Z
set _BSTAPID3 0x16410041
# High density devices, Rev A
set _BSTAPID4 0x06414041
# Connectivity line devices, Rev A and Rev Z
set _BSTAPID5 0x06418041
}
jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \
-expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \
-expected-id $_BSTAPID4 -expected-id $_BSTAPID5
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME stm32x 0 0 0 0 $_TARGETNAME
# For more information about the configuration files, take a look at:
# openocd.texi

View File

@ -870,7 +870,7 @@ CONFIG_BOOT_RUNFROMFLASH=n
CONFIG_BOOT_COPYTORAM=n
CONFIG_CUSTOM_STACK=n
CONFIG_STACK_POINTER=
CONFIG_IDLETHREAD_STACKSIZE=1024
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_USERMAIN_STACKSIZE=2048
CONFIG_PTHREAD_STACK_MIN=256
CONFIG_PTHREAD_STACK_DEFAULT=2048

View File

@ -60,7 +60,7 @@ MEMORY
* Debug code 0x1fc02000 KSEG1 4096-16 12272
* DEVCFG3-0 0x1fc02ff0 KSEG1 16 12288 (12Kb)
*
* Exceptions assme:
* Exceptions assume:
*
* STATUS: BEV=1 and EXL=0
* CAUSE: IV=1
@ -79,9 +79,12 @@ MEMORY
/* The PIC32MX440F512H has 32Kb of data memory at physical address
* 0x00000000. Since the PIC32MX has no data cache, this memory is
* always accessed through KSEG1.
*
* When used with MPLAB, we need to set aside 512 bytes of memory
* for use by MPLAB.
*/
kseg1_datamem (w!x) : ORIGIN = 0xa0000000, LENGTH = 32K
kseg1_datamem (w!x) : ORIGIN = 0xa0000200, LENGTH = 32K - 512
}
OUTPUT_FORMAT("elf32-tradlittlemips")