From c71754ae8d013cd6c7cff3f3d32a7b2def3db780 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sun, 15 Feb 2009 01:43:01 +0000 Subject: [PATCH] Add M16C register dump logic git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1503 42af7a65-404d-4744-a932-0658087f49c3 --- arch/sh/include/m16c/irq.h | 15 +- arch/sh/src/m16c/Make.defs | 4 +- arch/sh/src/m16c/chip.h | 24 +++ arch/sh/src/m16c/m16c_dumpstate.c | 241 ++++++++++++++++++++++ arch/sh/src/m16c/m16c_schedulesigaction.c | 28 +-- arch/sh/src/m16c/m16c_sigdeliver.c | 6 +- arch/sh/src/sh1/sh1_dumpstate.c | 8 +- 7 files changed, 293 insertions(+), 33 deletions(-) create mode 100755 arch/sh/src/m16c/m16c_dumpstate.c diff --git a/arch/sh/include/m16c/irq.h b/arch/sh/include/m16c/irq.h index 30ffaf87bc..ec1f333e7c 100644 --- a/arch/sh/include/m16c/irq.h +++ b/arch/sh/include/m16c/irq.h @@ -217,17 +217,18 @@ #define REG_FLGPCHI 0 /* 8-bit FLG (bits 12-14) + PC (bits 16-19) as would be * presented by an interrupt */ #define REG_FLG 1 /* 8-bit FLG register (bits 0-7) */ -#define REG_PC16 2 /* 16-bit PC [0]:bits8-15 [1]:bits 0-7 */ +#define REG_PC 2 /* 16-bit PC [0]:bits8-15 [1]:bits 0-7 */ #define REG_FB 4 /* 16-bit FB register */ #define REG_SB 6 /* 16-bit SB register */ #define REG_A1 8 /* 16-bit A1 register */ -#define REG_R3 10 /* 16-bit R3 register */ -#define REG_R2 12 /* 16-bit R2 register */ -#define REG_R1 14 /* 16-bit R1 register */ -#define REG_R0 16 /* 16-bit R0 register */ -#define REG_SP 18 /* 16-bit user stack pointer */ +#define REG_A0 10 /* 16-bit A0 register */ +#define REG_R3 12 /* 16-bit R3 register */ +#define REG_R2 14 /* 16-bit R2 register */ +#define REG_R1 16 /* 16-bit R1 register */ +#define REG_R0 18 /* 16-bit R0 register */ +#define REG_SP 20 /* 16-bit user stack pointer */ -#define XCPTCONTEXT_SIZE 20 +#define XCPTCONTEXT_SIZE 22 /************************************************************************************ * Public Types diff --git a/arch/sh/src/m16c/Make.defs b/arch/sh/src/m16c/Make.defs index ceba5fd768..60a91314f2 100644 --- a/arch/sh/src/m16c/Make.defs +++ b/arch/sh/src/m16c/Make.defs @@ -44,8 +44,8 @@ CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c \ CHIP_ASRCS = m16c_vectors.S #CHIP_CSRCS = m16c_initialstate.c m16c_copystate.c m16c_lowputc.c m16c_irq.c \ -# m16c_timerisr.c m16c_serial.c -CHIP_CSRCS = m16c_initialstate.c m16c_copystate.c m16c_irq.c +# m16c_timerisr.c m16c_serial.c m16c_dumpstate.c +CHIP_CSRCS = m16c_initialstate.c m16c_copystate.c m16c_irq.c m16c_dumpstate.c ifneq ($(CONFIG_DISABLE_SIGNALS),y) CHIP_CSRCS += m16c_schedulesigaction.c m16c_sigdeliver.c diff --git a/arch/sh/src/m16c/chip.h b/arch/sh/src/m16c/chip.h index bd2655db30..aafe4e5904 100644 --- a/arch/sh/src/m16c/chip.h +++ b/arch/sh/src/m16c/chip.h @@ -245,4 +245,28 @@ #define M16C_PUR2 0x003fe /* Pull-up control 2 */ #define M16C_PCR 0x003ff /* Port control */ +/************************************************************************************ + * Global Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +extern uint16 g_snbss; /* Start of near .bss */ +extern uint16 g_enbss; /* End+1 of near .bss */ +extern uint16 g_sndata; /* Start of near .data */ +extern uint16 g_endata; /* End+1 of near .data */ +extern uint32 g_enronly; /* Start of relocated read-only data in FLASH */ +#ifdef CONFIG_M16C_HAVEFARRAM +extern uint32 g_sfbss; /* Start of far .bss */ +extern uint32 g_efbss; /* End+1 of far .bss */ +extern uint32 g_sfdata; /* Start of far .data */ +extern uint32 g_efdata; /* End_1 of far .data */ +extern uint32 g_efronly; /* Start of relocated read-only data in FLASH */ +#endif +extern uint32 g_svarvect; /* Start of variable vectors */ +extern uint32 g_heapbase; /* Start of the heap */ + +#endif /* __ASSEMBLY__ */ + + #endif /* __ARCH_SH_SRC_M16C_CHIP_H */ diff --git a/arch/sh/src/m16c/m16c_dumpstate.c b/arch/sh/src/m16c/m16c_dumpstate.c new file mode 100755 index 0000000000..6d70d8cee2 --- /dev/null +++ b/arch/sh/src/m16c/m16c_dumpstate.c @@ -0,0 +1,241 @@ +/**************************************************************************** + * arch/sh/src/m16c/m16c_assert.c + * + * 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 + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "os_internal.h" +#include "chip.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/* Output debug info if stack dump is selected -- even if debug is not + * selected. + */ + +#ifdef CONFIG_ARCH_STACKDUMP +# undef lldbg +# define lldbg lib_lowprintf +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: m16c_getsp + ****************************************************************************/ + +static inline uint16 m16c_getsp(void) +{ + uint16 sp; + + __asm__ __volatile__ + ( + "\tstc sp, %0\n\t" + : "=r" (sp) + : + : "memory" + ); + return sp; +} + +/**************************************************************************** + * Name: m16c_stackdump + ****************************************************************************/ + +static void m16c_stackdump(uint16 sp, uint16 stack_base) +{ + uint16 stack; + + for (stack = sp & ~7; stack < stack_base; stack += 8) + { + ubyte *ptr = (ubyte*)stack; + lldbg("%04x: %02x %02x %02x %02x %02x %02x %02x %02x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]); + } +} + +/**************************************************************************** + * Name: m16c_registerdump + ****************************************************************************/ + +static inline void m16c_registerdump(void) +{ + ubyte *ptr = (ubyte*) current_regs; + + /* Are user registers available from interrupt processing? */ + + if (ptr) + { + /* Yes.. dump the interrupt registers */ + + lldbg("PC: %02x%02x%02x FLG: %02x00%02x FB: %02x%02x SB: %02x%02x SP: %02x%02x\n", + ptr[REG_FLGPCHI] & 0xff, ptr[REG_PC], ptr[REG_PC+1], + ptr[REG_FLGPCHI] >> 8, ptr[REG_FLG], + ptr[REG_FB], ptr[REG_FB+1], + ptr[REG_SB], ptr[REG_SB+1], + ptr[REG_SP], ptr[REG_SP+1]); + + lldbg("R0: %02x%02x R1: %02x%02x R2: %02x%02x A0: %02x%02x A1: %02x%02x\n", + ptr[REG_R0], ptr[REG_R0+1], ptr[REG_R1], ptr[REG_R1+1], + ptr[REG_R2], ptr[REG_R2+1], ptr[REG_R3], ptr[REG_R3+1], + ptr[REG_A0], ptr[REG_A0+1], ptr[REG_A1], ptr[REG_A1+1]); + + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_dumpstate + ****************************************************************************/ + +void up_dumpstate(void) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + uint16 sp = m16c_getsp(); + uint16 ustackbase; + uint16 ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint16 istackbase; + uint16 istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_heapbase - 1; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint16)rtcb->adj_stack_ptr; + ustacksize = (uint16)rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory. The near RAM memory map is as follows: + * + * 0x00400 - DATA Size: Determined by linker + * BSS Size: Determined by linker + * Interrupt stack Size: CONFIG_ARCH_INTERRUPTSTACK + * Idle stack Size: CONFIG_IDLETHREAD_STACKSIZE + * Heap Size: Everything remaining + * 0x00bff - (end+1) + */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + istackbase = g_enbss; + istacksize = CONFIG_ARCH_INTERRUPTSTACK; + + /* Show interrupt stack info */ + + lldbg("sp: %04x\n", sp); + lldbg("IRQ stack:\n"); + lldbg(" base: %04x\n", istackbase); + lldbg(" size: %04x\n", istacksize); + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + m16c_stackdump(sp, istackbase); + + /* Extract the user stack pointer which should lie + * at the base of the interrupt stack. + */ + + sp = g_userstack; + lldbg("sp: %04x\n", sp); + } + + /* Show user stack info */ + + lldbg("User stack:\n"); + lldbg(" base: %04x\n", ustackbase); + lldbg(" size: %04x\n", ustacksize); +#else + lldbg("sp: %04x\n", sp); + lldbg("stack base: %04x\n", ustackbase); + lldbg("stack size: %04x\n", ustacksize); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { +#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4 + lldbg("ERROR: Stack pointer is not within allocated stack\n"); +#endif + } + else + { + m16c_stackdump(sp, ustackbase); + } + + /* Then dump the registers (if available) */ + + m16c_registerdump(); +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/sh/src/m16c/m16c_schedulesigaction.c b/arch/sh/src/m16c/m16c_schedulesigaction.c index d33e63378d..c62399b6f1 100644 --- a/arch/sh/src/m16c/m16c_schedulesigaction.c +++ b/arch/sh/src/m16c/m16c_schedulesigaction.c @@ -146,18 +146,18 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver) * the signals have been delivered. */ - tcb->xcp.sigdeliver = sigdeliver; - tcb->xcp.saved_pc[0] = current_regs[REG_PC16]; - tcb->xcp.saved_pc[1] = current_regs[REG_PC16+1]; - tcb->xcp.saved_flg = current_regs[REG_FLG]; + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc[0] = current_regs[REG_PC]; + tcb->xcp.saved_pc[1] = current_regs[REG_PC+1]; + tcb->xcp.saved_flg = current_regs[REG_FLG]; /* Then set up to vector to the trampoline with interrupts * disabled */ - current_regs[REG_PC16] = (uint32)up_sigdeliver >> 8; - current_regs[REG_PC16+1] = (uint32)up_sigdeliver; - current_regs[REG_FLG] &= ~M16C_FLG_I; + current_regs[REG_PC] = (uint32)up_sigdeliver >> 8; + current_regs[REG_PC+1] = (uint32)up_sigdeliver; + current_regs[REG_FLG] &= ~M16C_FLG_I; /* And make sure that the saved context in the TCB * is the same as the interrupt return context. @@ -180,18 +180,18 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver) * the signals have been delivered. */ - tcb->xcp.sigdeliver = sigdeliver; - tcb->xcp.saved_pc[0] = tcb->xcp.regs[REG_PC16]; - tcb->xcp.saved_pc[1] = tcb->xcp.regs[REG_PC16+1]; - tcb->xcp.saved_flg = tcb->xcp.regs[REG_FLG]; + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc[0] = tcb->xcp.regs[REG_PC]; + tcb->xcp.saved_pc[1] = tcb->xcp.regs[REG_PC+1]; + tcb->xcp.saved_flg = tcb->xcp.regs[REG_FLG]; /* Then set up to vector to the trampoline with interrupts * disabled */ - tcb->xcp.regs[REG_PC16] = (uint32)up_sigdeliver >> 8; - tcb->xcp.regs[REG_PC16+1] = (uint32)up_sigdeliver; - tcb->xcp.regs[REG_FLG] &= ~M16C_FLG_I; + tcb->xcp.regs[REG_PC] = (uint32)up_sigdeliver >> 8; + tcb->xcp.regs[REG_PC+1] = (uint32)up_sigdeliver; + tcb->xcp.regs[REG_FLG] &= ~M16C_FLG_I; } irqrestore(flags); diff --git a/arch/sh/src/m16c/m16c_sigdeliver.c b/arch/sh/src/m16c/m16c_sigdeliver.c index 7cea935e43..2d4cf2069d 100644 --- a/arch/sh/src/m16c/m16c_sigdeliver.c +++ b/arch/sh/src/m16c/m16c_sigdeliver.c @@ -102,9 +102,9 @@ void up_sigdeliver(void) /* Save the real return state on the stack. */ up_copystate(regs, rtcb->xcp.regs); - regs[REG_PC16] = rtcb->xcp.saved_pc[0]; - regs[REG_PC16+1] = rtcb->xcp.saved_pc[1]; - regs[REG_FLG] = rtcb->xcp.saved_flg; + regs[REG_PC] = rtcb->xcp.saved_pc[0]; + regs[REG_PC+1] = rtcb->xcp.saved_pc[1]; + regs[REG_FLG] = rtcb->xcp.saved_flg; /* Get a local copy of the sigdeliver function pointer. * we do this so that we can nullify the sigdeliver diff --git a/arch/sh/src/sh1/sh1_dumpstate.c b/arch/sh/src/sh1/sh1_dumpstate.c index 8d41adec42..55f998ccac 100755 --- a/arch/sh/src/sh1/sh1_dumpstate.c +++ b/arch/sh/src/sh1/sh1_dumpstate.c @@ -42,18 +42,12 @@ #include #include -#include "up_internal.h" - -include - -#include -#include - #include #include #include "up_arch.h" #include "up_internal.h" +#include "os_internal.h" #ifdef CONFIG_ARCH_STACKDUMP