From 54b35225d9dcfab41397f17b2ac2a5564bfda233 Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 9 Nov 2011 23:59:46 +0000 Subject: [PATCH] More PIC32 debug updates git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4083 42af7a65-404d-4744-a932-0658087f49c3 --- arch/mips/src/common/up_internal.h | 6 +- arch/mips/src/mips32/up_swint0.c | 2 +- arch/mips/src/pic32mx/excptmacros.h | 826 +++++++++--------- arch/mips/src/pic32mx/pic32mx-decodeirq.c | 12 - arch/mips/src/pic32mx/pic32mx-head.S | 3 + arch/mips/src/pic32mx/pic32mx-irq.c | 19 +- configs/pcblogic-pic32mx/ostest/defconfig | 2 +- configs/pcblogic-pic32mx/ostest/ld.script | 7 +- configs/pic32-starterkit/ostest/defconfig | 2 +- configs/pic32-starterkit/ostest/ld.script | 7 +- configs/stm3210e-eval/README.txt | 27 + .../tools/olimex-arm-usb-ocd.cfg | 11 + configs/stm3210e-eval/tools/oocd.sh | 90 ++ configs/stm3210e-eval/tools/stm32.cfg | 69 ++ configs/sure-pic32mx/ostest/defconfig | 2 +- configs/sure-pic32mx/ostest/ld.script | 7 +- 16 files changed, 649 insertions(+), 443 deletions(-) create mode 100644 configs/stm3210e-eval/tools/olimex-arm-usb-ocd.cfg create mode 100755 configs/stm3210e-eval/tools/oocd.sh create mode 100644 configs/stm3210e-eval/tools/stm32.cfg diff --git a/arch/mips/src/common/up_internal.h b/arch/mips/src/common/up_internal.h index 29d882d24f4..8da7e9605d0 100755 --- a/arch/mips/src/common/up_internal.h +++ b/arch/mips/src/common/up_internal.h @@ -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); diff --git a/arch/mips/src/mips32/up_swint0.c b/arch/mips/src/mips32/up_swint0.c index a23adce67f7..df1a63e350e 100644 --- a/arch/mips/src/mips32/up_swint0.c +++ b/arch/mips/src/mips32/up_swint0.c @@ -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; diff --git a/arch/mips/src/pic32mx/excptmacros.h b/arch/mips/src/pic32mx/excptmacros.h index 1532e2f15c6..9ed66290556 100644 --- a/arch/mips/src/pic32mx/excptmacros.h +++ b/arch/mips/src/pic32mx/excptmacros.h @@ -1,413 +1,413 @@ -/******************************************************************************************** - * arch/mips/src/pic32mx/excptmacros.h - * - * Copyright (C) 2011 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. - * - ********************************************************************************************/ - -#ifndef __ARCH_MIPS_SRC_PIC32MX_EXCPTMACROS_H -#define __ARCH_MIPS_SRC_PIC32MX_EXCPTMACROS_H - -/******************************************************************************************** - * Included Files - ********************************************************************************************/ - -#include - -#include -#include - -#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 + * + * 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 + +#include +#include + +#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 */ diff --git a/arch/mips/src/pic32mx/pic32mx-decodeirq.c b/arch/mips/src/pic32mx/pic32mx-decodeirq.c index 5f1df88c1cb..a7b55e06f6a 100644 --- a/arch/mips/src/pic32mx/pic32mx-decodeirq.c +++ b/arch/mips/src/pic32mx/pic32mx-decodeirq.c @@ -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 diff --git a/arch/mips/src/pic32mx/pic32mx-head.S b/arch/mips/src/pic32mx/pic32mx-head.S index 3a9c6c0e083..8857aee3400 100644 --- a/arch/mips/src/pic32mx/pic32mx-head.S +++ b/arch/mips/src/pic32mx/pic32mx-head.S @@ -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() */ diff --git a/arch/mips/src/pic32mx/pic32mx-irq.c b/arch/mips/src/pic32mx/pic32mx-irq.c index 51b6467b528..ae2b8ce07e2 100644 --- a/arch/mips/src/pic32mx/pic32mx-irq.c +++ b/arch/mips/src/pic32mx/pic32mx-irq.c @@ -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 diff --git a/configs/pcblogic-pic32mx/ostest/defconfig b/configs/pcblogic-pic32mx/ostest/defconfig index 1f29f0e3230..8baa01a9305 100644 --- a/configs/pcblogic-pic32mx/ostest/defconfig +++ b/configs/pcblogic-pic32mx/ostest/defconfig @@ -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 diff --git a/configs/pcblogic-pic32mx/ostest/ld.script b/configs/pcblogic-pic32mx/ostest/ld.script index 79bd3783be3..e888ef964f5 100644 --- a/configs/pcblogic-pic32mx/ostest/ld.script +++ b/configs/pcblogic-pic32mx/ostest/ld.script @@ -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") diff --git a/configs/pic32-starterkit/ostest/defconfig b/configs/pic32-starterkit/ostest/defconfig index 64eaf5fe20b..2aa62e73c6b 100644 --- a/configs/pic32-starterkit/ostest/defconfig +++ b/configs/pic32-starterkit/ostest/defconfig @@ -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 diff --git a/configs/pic32-starterkit/ostest/ld.script b/configs/pic32-starterkit/ostest/ld.script index 4f6b00cd4bb..aa888440c97 100644 --- a/configs/pic32-starterkit/ostest/ld.script +++ b/configs/pic32-starterkit/ostest/ld.script @@ -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") diff --git a/configs/stm3210e-eval/README.txt b/configs/stm3210e-eval/README.txt index f6c21232dca..15d621d5b7f 100755 --- a/configs/stm3210e-eval/README.txt +++ b/configs/stm3210e-eval/README.txt @@ -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 + configs/stm3210e-eval/tools/oocd.sh $PWD + +2) Load Nuttx + + cd + 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 ==== diff --git a/configs/stm3210e-eval/tools/olimex-arm-usb-ocd.cfg b/configs/stm3210e-eval/tools/olimex-arm-usb-ocd.cfg new file mode 100644 index 00000000000..569dcef598f --- /dev/null +++ b/configs/stm3210e-eval/tools/olimex-arm-usb-ocd.cfg @@ -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 + diff --git a/configs/stm3210e-eval/tools/oocd.sh b/configs/stm3210e-eval/tools/oocd.sh new file mode 100755 index 00000000000..d2cd6ae274a --- /dev/null +++ b/configs/stm3210e-eval/tools/oocd.sh @@ -0,0 +1,90 @@ +#!/bin/sh + +# Get command line parameters + +USAGE="USAGE: $0 [-dh] " +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 " " + 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" + diff --git a/configs/stm3210e-eval/tools/stm32.cfg b/configs/stm3210e-eval/tools/stm32.cfg new file mode 100644 index 00000000000..463a85cfd2b --- /dev/null +++ b/configs/stm3210e-eval/tools/stm32.cfg @@ -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 diff --git a/configs/sure-pic32mx/ostest/defconfig b/configs/sure-pic32mx/ostest/defconfig index 3cfa5bd9e4f..730d22db2f9 100644 --- a/configs/sure-pic32mx/ostest/defconfig +++ b/configs/sure-pic32mx/ostest/defconfig @@ -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 diff --git a/configs/sure-pic32mx/ostest/ld.script b/configs/sure-pic32mx/ostest/ld.script index e15af9f6c05..b23719c9f2b 100644 --- a/configs/sure-pic32mx/ostest/ld.script +++ b/configs/sure-pic32mx/ostest/ld.script @@ -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")