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

📄 excarchlib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
LOCAL INSTR blCompute    (    VOIDFUNCPTR target,			/* target address */    INSTR * branch			/* address of branch instruction */    )    {    INSTR offset;    /* Try a PC-relative branch (bl). */    offset = ((int)target - (int)branch);    if (SEXT_26BIT(offset) == offset)	return (0x48000001 | (offset & 0x03fffffc));    /* Next try an absolute branch (bla). */    offset = (int)target;    if (SEXT_26BIT(offset) == offset)	return (0x48000003 | (offset & 0x03fffffc));    /* Address cannot be reached by a short branch instruction at <branch>. */    return (INSTR) 0;    }/********************************************************************************* blExtract - compute target address of a specified branch instruction** This routine returns the destination address of a branch instruction inst* which is located at address.** RETURNS: target address of the branch.*/LOCAL INSTR blExtract    (    INSTR   inst,			/* branch instruction word */    INSTR * address			/* address of branch instruction */    )    {    INSTR target = SEXT_26BIT(inst & 0x03fffffc);    /* If the AA bit is not set, then this is a PC-relative branch. */    if ( (inst & 0x2) == 0 )	target += (INSTR) address;    return target;    }/***************************************************************************** vecOffRelocMatch - lookup vector table for relocation offset** This routine looks up the exception vector table excBlTbl[] for the vector* offset specified.  If the vector offset is found to be relocated, it* returns the relocated offset.  If it is not relocated, or if such an entry* is not found, it returns the vector offset given to it as input.* The status (found unrelocated, found relocated, not found) has no current* use and thus is not returned to optimize performance.  This can be added* in future if API not published by then.  Probably a user specified* relocation table as well.** RETURNS: The input vector offset if not relocated or if not found in*          excBlTbl[], or the relocated vector offset value.**/UINT32 vecOffRelocMatch    (    UINT32 vector                       /* original vector to match */    )    {    FAST int i = 0;    while (excBlTbl[i].vecOff != 0)        {        if (excBlTbl[i].vecOff == vector)            {            if (excBlTbl[i].vecOffReloc == 0)                return (vector);            else                return (excBlTbl[i].vecOffReloc);            }        i++;        }    return vector;    }/***************************************************************************** vecOffRelocMatchRev - reverse lookup vector table for relocation offset** This routine looks up the exception vector table excBlTbl[] for the* relocated  vector offset specified.  If such a relocated vector offset* is found, it returns the original offset.  If it has not been relocated,* or if such an entry is not found, it returns the vector offset given to* it as input.** RETURNS: The input vector offset if not relocated or if not found in*          excBlTbl[], or the relocated vector offset value.**/UINT32 vecOffRelocMatchRev    (    UINT32 vector                       /* relocated vector to match */    )    {    FAST int i = 0;    while (excBlTbl[i].vecOff != 0)        {        if (excBlTbl[i].vecOffReloc == vector)                return (excBlTbl[i].vecOff);        i++;        }    return vector;    }/********************************************************************************* excConnect - connect a C routine to an exception vector** This routine connects a specified C routine to a specified exception* vector.  An exception stub is created and in placed at <vector> in the* exception table.  The address of <routine> is stored in the exception stub* code.  When an exception occurs, the processor jumps to the exception stub* code, saves the registers, and call the C routines.** The routine can be any normal C code, except that it must not* invoke certain operating system functions that may block or perform* I/O operations.** The registers are saved to an Exception Stack Frame (ESF) which is placed* on the stack of the task that has produced the exception.  The ESF structure* is defined in /h/arch/ppc/esfPpc.h.** The only argument passed by the exception stub to the C routine is a pointer* to the ESF containing the registers values.  The prototype of this C routine* is as follows:* .CS*     void excHandler (ESFPPC *);* .CE** When the C routine returns, the exception stub restores the registers saved* in the ESF and continues execution of the current task.** RETURNS: OK if the routine connected successfully, or*          ERROR if the routine was too far away for a 26-bit offset.* * SEE ALSO: excIntConnect(), excVecSet()* */STATUS excConnect    (    VOIDFUNCPTR * vector,               /* exception vector to attach to */    VOIDFUNCPTR   routine               /* routine to be called */    )    {    return ( excRelocConnect (vector, routine, (VOIDFUNCPTR *) 0) );    }/********************************************************************************* excRelocConnect - connect a C routine to an exception vector with possible*                   relocation** This routine is same as excConnect with an added parameter, which is* the relocation offset of the vector to be installed.  If the extra* parameter is non-zero, the vector is installed at this offset instead* of the standard offset specified in the first parameter.  A branch* instruction is then written to the original offset to reach the* relocated vector.  A relative branch will be used, unless out of the* 26-bit offset range where it will attempt an absolute branch.  The* caller should take care of the branch instruction clobbering useful* data specified by vector, including the stub being installed should* the original offset overlaps the stub of the relocated vector.** RETURNS: OK if the routine connected successfully, or*          ERROR if the routine was too far away for one branch instr.**/STATUS excRelocConnect    (    VOIDFUNCPTR * vector,		/* exception vector to attach to */    VOIDFUNCPTR	  routine,		/* routine to be called */    VOIDFUNCPTR * vectorReloc		/* relocated exception vector */    )    {    FAST STATUS  rc;    FAST INSTR   branch;    FAST INSTR * newVector;    FAST int     base = (int) excVecBaseGet ();    if ((int) vectorReloc == 0)        {        newVector = (INSTR *) ( base | (int) vector );        }    else        {        vector = (VOIDFUNCPTR *) ( base | (int) vector );        newVector = (INSTR *) ( base | (int) vectorReloc );        }    rc = excConnectVector(newVector, VEC_TYPE_NORM, excEnt, routine, excExit);    if ( ((int) vectorReloc != 0) && (rc == OK) )        {        /* if relocated vector, write branch (with link bit cleared) */        branch = blCompute ( (VOIDFUNCPTR) newVector, (INSTR *) vector );        if (branch == 0)            return ERROR;        *vector = (VOIDFUNCPTR) (branch & 0xfffffffe);        CACHE_TEXT_UPDATE ((void *) vector, sizeof(INSTR));        }    return (rc);    }/********************************************************************************* excIntConnect - connect a C routine to an asynchronous exception vector** This routine connects a specified C routine to a specified asynchronous * exception vector, such as the external interrupt vector (0x500) and the* decrementer vector (0x900).  An interrupt stub is created and placed at* <vector> in the exception table.  The address of <routine> is stored in the* interrupt stub code.  When the asynchronous exception occurs, the processor* jumps to the interrupt stub code, saves only the requested registers, and* calls the C routines.** When the C routine is invoked, interrupts are still locked.  It is the* C routine responsibility to re-enable interrupts.** The routine can be any normal C code, except that it must not* invoke certain operating system functions that may block or perform* I/O operations.** Before the requested registers are saved, the interrupt stub switches from the* current task stack to the interrupt stack.  In the case of nested interrupts,* no stack switching is performed, because the interrupt is already set.** RETURNS: OK if the routine connected successfully, or*          ERROR if the routine was too far away for a 26-bit offset.* * SEE ALSO: excConnect(), excVecSet()*/STATUS excIntConnect    (    VOIDFUNCPTR * vector,               /* exception vector to attach to */    VOIDFUNCPTR   routine               /* routine to be called */    )    {    return ( excRelocIntConnect (vector, routine, (VOIDFUNCPTR *) 0) );    }/********************************************************************************* excRelocIntConnect - connect a C routine to an exception vector with*                      possible relocation** This routine is same as excIntConnect with an added parameter, which is* the relocation offset of the vector to be installed.  If the extra* parameter is non-zero, the vector is installed at this offset instead* of the standard offset specified in the first parameter.  A branch* instruction is then written to the original offset to reach the* relocated vector.  A relative branch will be used, unless out of the* 26-bit offset range where it will attempt an absolute branch.  The* caller should take care of the branch instruction clobbering useful* data specified by vector, including the stub being installed should* the original offset overlaps the stub of the relocated vector.** RETURNS: OK if the routine connected successfully, or*          ERROR if the routine was too far away for one branch instr.**/STATUS excRelocIntConnect    (    VOIDFUNCPTR * vector,		/* exception vector to attach to */    VOIDFUNCPTR	  routine,		/* routine to be called */    VOIDFUNCPTR * vectorReloc           /* relocated exception vector */    )    {    FAST STATUS  rc;    FAST INSTR   branch;    FAST INSTR * newVector;    FAST int     base = (int) excVecBaseGet ();    if ((int) vectorReloc == 0)        {        newVector = (INSTR *) ( base | (int) vector );        }    else        {        vector = (VOIDFUNCPTR *) ( base | (int) vector );        newVector = (INSTR *) ( base | (int) vectorReloc );        }    rc = excConnectVector(newVector, VEC_TYPE_NORM, intEnt, routine, intExit);    if ( ((int) vectorReloc != 0) && (rc == OK) )        {        /* if relocated vector, write branch (with link bit cleared) */        branch = blCompute ( (VOIDFUNCPTR) newVector, (INSTR *) vector );        if (branch == 0)            return ERROR;        *vector = (VOIDFUNCPTR) (branch & 0xfffffffe);        CACHE_TEXT_UPDATE ((void *) vector, sizeof(INSTR));        }    return (rc);    }/********************************************************************************* excConnectVector - connect a C routine to an asynchronous exception vector** Code factored from original excIntConnect/excExcConnect.** Should never be called directly except by *   excConnect(),        or excRelocConnect()*   excIntConnect(),     or excRelocIntConnect()

⌨️ 快捷键说明

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