⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sigctxlib.c

📁 vxworks source code, used for develop vxworks system.
💻 C
字号:
/* sigCtxLib.c - software signal architecture support library *//* Copyright 1994-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01t,24oct01,zl   fixes for doc builds.01s,30aug00,hk   change _sigCtxSetup() to import intUnlockSR (ex-brandNewTaskSR)01r,21aug00,hk   merge SH7729 to SH7700. merge SH7410 and SH7040 to SH7600.01q,16jul98,st   added SH7750 support.01q,08may98,jmc  added support for SH-DSP and SH3-DSP.01q,26nov97,hms  added fpp support definition.01p,18may97,hk   changed last _sigfaulttable[] member to {0,0} from {0,SIGILL}.01o,25apr97,hk   changed SH704X to SH7040.01n,03mar97,hk   fixed _sigCtxStackEnd for SH7700 to just return sp.01m,09aug96,hk   added FPE_INTDIV_TRAP for SH7700.01l,08aug96,hk   added more signals for SH7700.01k,04aug96,hk   enabled ILL_xxx for SH7700.01j,21may96,hk   workarounded _sigfaulttable for SH7700 build.01i,15nov95,hk   changed _sigfaulttable[] to use definitions in sigCodes.h.01h,23may95,hk   saved stack space by fixing _sigCtxStackEnd.01g,01apr95,hk   changed _sigfaulttable member to use INUM_ directly.01f,31mar95,hk   added INT_NMI entry to _sigfaulttable.01e,16mar95,hk   added picture, some refinements.01d,15mar95,hk   initial functional version.01c,07mar95,hk   wrote body.01b,28feb95,hk   adding arch port kit docs. copyright 1995.01a,08oct94,hk   written based on sparc 01f.*//*This library provides the architecture specific support needed bysoftware signals.[APK]The architecture-dependent signal library contains routines that support thearchitecture-independent sigLib.c.  The complex portions of the signal supporthas been abstracted.  The signal support should be modeled after the contextswitch code in windExit() and windLoadContext(), and various tasking routines.*//* includes */#include "vxWorks.h"#include "private/sigLibP.h"#include "string.h"#include "sigCodes.h"/* defines */#define	SIG_STACK_ARGS		((pArgs[0] > 4) ? pArgs[0] - 4 : 0)/* [APK] * The table of signal handlers is a subset of the vector table.  The exceptions * defined by the hardware should be matched with a handler if possible.  The * example below is not for any particular architecture, but is merely and * example of common signals. * * struct sigfaulttable _sigfaulttable [] = *     { *     {ILLEGAL_INSTRUCTION,SIGILL},		{sigf_fault,     sigf_signo}, *     {DATA_ACCESS_ERROR,  SIGBUS}, *     {MMU_VIOLATION,      SIGSEGV}, *     {FPU_DISABLED,       SIGFPE}, *     {FPU_EXCEPTION,      SIGFPE}, *     {COPROCESSOR_ERROR,  SIGILL}, *     <additional offsets and handlers> *     }; * * NOTE:  This table is referenced only from `sigExcKill()' in sigLib.c. *        Here the last member {0, 0} is mandatory as the table terminator. *        The bus timeout error is not registered in `_sigfaulttable[]', and *        it is directly handled in `sigExcKill()'.  In the shell context, *        all signals are caught by the `shellSigHandler()', and it restarts *        the shell regardless of signal number.  On the dve7604 board, the *        VME bus error is reported to SH7604 CPU as an interrupt request. *        Typically the NMI is used for this purpose, and it leads to send *        SIGBUS to shell task, then the shell is automatically restarted *        by shellSigHandler. */struct sigfaulttable _sigfaulttable [] =    {#if (CPU==SH7750 || CPU==SH7700)    {TLB_LOAD_MISS,		SIGSEGV},    {TLB_STORE_MISS,		SIGSEGV},    {TLB_INITITIAL_PAGE_WRITE,	SIGSEGV},    {TLB_LOAD_PROTEC_VIOLATION,	SIGSEGV},    {TLB_STORE_PROTEC_VIOLATION,SIGSEGV},    {BUS_LOAD_ADDRESS_ERROR,	SIGBUS},    {BUS_STORE_ADDRESS_ERROR,	SIGBUS},    {FPU_EXCEPTION,		SIGFPE},    {ILLEGAL_INSTR_GENERAL,	SIGILL},    {ILLEGAL_SLOT_INSTR,	SIGILL},    {FPE_INTDIV_TRAP,		SIGFPE},#elif (CPU==SH7600 || CPU==SH7000)    {ILL_ILLINSTR_GENERAL,	SIGILL},    {ILL_ILLINSTR_SLOT,		SIGILL},    {BUS_ADDERR_CPU,		SIGBUS},    {BUS_ADDERR_DMA,		SIGBUS},    {FPE_INTDIV_TRAP,		SIGFPE},#endif    {0,				0},    };/******************************************************************************** _sigCtxRtnValSet - set the return value of a context** Set the return value of a context.* This routine should be almost the same as taskRtnValueSet in taskArchLib.c** [APK]* This one-line function sets the register for return values to the second input* argument.  The first argument is a pointer to the REG_SET in the task's TCB.*/void _sigCtxRtnValSet    (    REG_SET *pRegs,    int      val    )    {    pRegs->voreg[0] = val;    }/******************************************************************************** _sigCtxStackEnd - get the end of the stack for a context** Get the end of the stack for a context, the context will not be running.* If during a context switch, stuff is pushed onto the stack, room must* be left for that (on the 68k the fmt, pc, and sr are pushed just before* a ctx switch)** [APK]* This function returns the stack pointer for the task, whose type is a void.* The input argument is a pointer to the REG_SET in the task's TCB.** NOTE:  This routine is only called from sigWindPendKill in sigLib.c.*	 The sigWindPendKill builds a sigcontext structure on this return*	 address (pCtx), then passes it to _sigCtxSetup as pStackBase.*/void *_sigCtxStackEnd    (    const REG_SET * pRegs    )    {#if (CPU==SH7750 || CPU==SH7700)    return (void *)(pRegs->nvreg[7]);#elif (CPU==SH7600 || CPU==SH7000)    /*     * The 8 is pad for the pc and sr which are pushed onto the stack.     */    return (void *)(pRegs->nvreg[7] - 8);#endif /* CPU==SH7600 || CPU==SH7000 */#if FALSE    /*     * The 8 is pad for the pc and sr which are pushed onto the stack.     * The (sizeof(REG_SET) + 32) is size of sigcontext, see sigLibP.h.     */    return (void *)(pRegs->nvreg[7] - (sizeof(REG_SET) + 32) - 8);    /*           = (pRegs->nvreg[7] - (92 + 32) - 8)     *           = (pRegs->nvreg[7] - 132)     */#endif /* FALSE */    }/******************************************************************************** _sigCtxSetup - Setup of a context** This routine will set up a context that can be context switched in.* <pStackBase> points beyond the end of the stack. The first element of* <pArgs> is the number of args to call <taskEntry> with.* When the task gets swapped in, it should start as if called like** (*taskEntry) (pArgs[1], pArgs[2], ..., pArgs[pArgs[0]])** This routine is a blend of taskRegsInit and taskArgsSet.** Currently (for signals) pArgs[0] always equals 1, thus the task should* start as if called like* (*taskEntry) (pArgs[1]);** Furthermore (for signals), the function taskEntry will never return.* For the 68k case, we push vxTaskEntry() onto the stack so a stacktrace* looks good.** [APK]* The signal context set up function is a combination of the taskRegsInit()* and taskArgsSet() routines.  The program counter is set to the task entry* input argument, and all other control registers should be set to their* taskRegsInit() values.  The general-purpose registers should be initialized* to match the input argument list.  A pointer to the REG_SET for the signal* context is the first argument to this funcition.** The stack pointer argument is used to create the signal stack frame, which* contains the REG_SET initialized by this routine.  The stack frame created* is beyond the end of the task stack.  The stack/frame pointers must be set* to accommodate the registers and other stack-based structures for the* architecture.** NOTE:* This routine is only called from sigWindPendKill, in case of delivering a* signal to other task.** INTERNAL**          <target task's TCB>              <target task's stack>* *          |                 |         |                                |*          |                 |         |             used               |*          |_________________|         |________________________________| <---+*          | sr = 0x00000000 |         |        (slot for sr)           |     |*          | pc = sigWrapper |         |_______ (slot_for_pc) __________|____ |*          | sp -------------------+   |.sc_pregs.......................|  ^  |*          | r14             |     |   |         : sr                   |  :  |*          | r13             |     |   |         : pc                   |  :  |*          | r12   REG_SET   |     |   |         : sp ------------------------+*          | r11   structure |     |   |         : r14                  |  :*          | r10   in target |     |   |         : r13                  |  :*          | r9    task's TCB|     |   |         : r12                  |  :*          | r8              |     |   |         : r11                  |  :*          | macl            |     |   |         : r10                  |  :*          | mach            |     |   |         : r9                   |  :*          | r7 = pArgs[4]   |     |   |         : r8     These REG_SET |  :*          | r6 = pArgs[3]   |     |   |         : macl      values are |  S*          | r5 = pArgs[2]   |     |   |         : mach      saved from |  I*          | r4 = pArgs[1] -----+  |   |         : r7        the target |  G*          | r3              |  |  |   |         : r6     task's TCB by |  C*          | r2              |  |  |   |         : r5   sigWindPendKill.|  O*          | r1              |  |  |   |         : r4    (these will be |  N*          | r0              |  |  |   |         : r3      re-loaded by |  T*          | pr = vxTaskEntry|  |  |   |         : r2       _sigCtxLoad)|  E*          | gbr             |  |  |   |         : r1                   |  X* pRegs -> |_vbr_____________|  |  |   |         : r0                   |  T*          |                 |  |  |   |         : pr                   |  :*          |                 |  |  |   |         : gbr                  |  :*          0                    |  |   |.sc_regs.:.vbr..................|  :*                               |  |   |         :          :.sival_ptr.|  :*                               |  |   |         :.si_value.:.sival_int.|  :*           +-------------------+  |   |         :.si_code..............|  :*           |                      |   |.sc_info.:.si_signo.............|  :*           |                      |   |.sc_mask........................|  :*           |                      |   |.sc_restart.....................|  :*           +- pCtx = pStackBase ----> |_sc_onstack_____________________|__v_*                                  |   |                       |        |*                                  |   | pArgs[pArgs[0]]       V        |*                                  |   |    :              stack for    |*                                  |   | pArgs[7]         sigWrapper()  |*                                  |   | pArgs[6]                       |*                                  +-> | pArgs[5]                       |*                                      |                                |*                                      0                            */void _sigCtxSetup    (    REG_SET	 *pRegs,			/* in target task's TCB  */    void	 *pStackBase,			/* stack for sigWrapper  */    void	(*taskEntry)(),			/* address of sigWrapper */    int		 *pArgs				/* pArgs[0] = 1          */    )						/* pArgs[1] = pCtx       */    {#if (CPU==SH7750 || CPU==SH7700)    IMPORT UINT32 intUnlockSR;#endif    extern void  vxTaskEntry();    FAST   int   ix;    FAST   int * sp;    bzero ((void *) pRegs, sizeof(REG_SET));	/* clear everything first */#if (CPU==SH7750 || CPU==SH7700)    pRegs->sr = intUnlockSR;			/* set status register    */#elif (CPU==SH7600 || CPU==SH7000)    pRegs->sr = 0x00000000;			/* set status register    */#endif    pRegs->pc = (INSTR *) taskEntry;		/* set entry point        */    pRegs->pr = (INSTR *) vxTaskEntry;		/* for stack trace ???    */    for (ix = 0; ix < pArgs[0]; ++ix)	pRegs->voreg [ix+4] = pArgs [ix+1];	/* 1st 4 args into registers */    sp = (int *)((int)pStackBase - SIG_STACK_ARGS * (sizeof(int)));    pRegs->nvreg [7] = (ULONG) sp;		/* set stack pointer      */    for (ix = 0; ix < SIG_STACK_ARGS; ++ix)	*sp++ = pArgs [ix+5];			/* Args beyond 4th into stack */    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -