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

📄 fpparchlib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
字号:
/* fppArchLib.c - Coldfire floating-point coprocessor support library *//* Copyright 1984-2000 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01a,27jun00,dh   stolen from 68k*//*DESCRIPTIONThis library provides a low-level interface to the MC68881/MC68882coprocessor.  The routines fppTaskRegsSet() and fppTaskRegsGet()inspect and set coprocessor registers on a per task basis.  Theroutine fppProbe() checks for the presence of the MC68881/MC68882coprocessor.  With the exception of fppProbe(), the higher levelfacilities in dbgLib and usrLib should be used instead of theseroutines.  See fppLib for architecture independent portion.SEE ALSO: fppALib, intConnect(), MC68881/MC68882 User's Manual*/#include "vxWorks.h"#include "objLib.h"#include "taskLib.h"#include "taskArchLib.h"#include "memLib.h"#include "string.h"#include "iv.h"#include "intLib.h"#include "regs.h"#include "fppLib.h"/* globals */REG_INDEX fpRegName [] =    {    {"f0", FPX_OFFSET(0)},    {"f1", FPX_OFFSET(1)},    {"f2", FPX_OFFSET(2)},    {"f3", FPX_OFFSET(3)},    {"f4", FPX_OFFSET(4)},    {"f5", FPX_OFFSET(5)},    {"f6", FPX_OFFSET(6)},    {"f7", FPX_OFFSET(7)},    {NULL, 0},    };REG_INDEX fpCtlRegName [] =    {    {"fpcr",   FPCR},    {"fpsr",   FPSR},    {"fpiar",  FPIAR},    {NULL, 0},    };/* locals */LOCAL FP_CONTEXT fppInitContext;	/* initialized to initial fp context *//********************************************************************************* fppArchInit - initialize floating-point coprocessor support** This routine must be called before using the floating-point coprocessor.* It is typically called from fppInit().** NOMANUAL*/void fppArchInit (void)    {    fppCreateHookRtn = (FUNCPTR) NULL;    fppSave (&fppInitContext);		/* fppProbe() was called in fppInit() */    }/********************************************************************************* fppArchTaskCreateInit - initialize floating-point coprocessor support for task** INTERNAL* We utilize a NULL frame (not possible for the 040) to optimize the* context switch time until an actual floating point instruction is* executed.** On the 040:* It might seem odd that we use a bcopy() to initialize the floating point* context when a fppSave() of an idle frame would accomplish the same thing* without the cost of a 324 byte data structure.  The problem is that we* are not guaranteed to have an idle frame.  Consider the following scenario:* a floating point task is midway through a floating point instruction when* it is preempted by a *non-floting point* task.  In this case the swap-in* hook does not save the coprocessor state as an optimization.  Now if we* create a floating point task the initial coprocessor frame would not be* idle but rather mid-instruction.  To make matters worse when get around* to saving the original fp task's floating point context frame, it would be* incorrectly saved as idle!  One solution would be to fppSave() once to* the original fp task's context, then fppSave() an idle frame to the new task,* and finally restore the old fp task's context (in case we return to it* before another fp task).  The problem with this approach is that it is* *slow* and considering the fact that preemption is locked, the 324 bytes* don't look so bad anymore.  Indeed, when this approach is adopted by all* architectures we will not need to lock out preemption anymore.** NOMANUAL*/void fppArchTaskCreateInit    (    FP_CONTEXT *pFpContext		/* pointer to FP_CONTEXT */    )    {    /* create NULL frame as initial frame */    bzero ((char *)pFpContext, sizeof (FP_CONTEXT));    }/******************************************************************************** fppRegsToCtx - convert FPREG_SET to FP_CONTEXT.*/ void fppRegsToCtx    (    FPREG_SET *  pFpRegSet,		/* input -  fpp reg set */    FP_CONTEXT * pFpContext		/* output - fpp context */    )    {    int ix;    if (pFpContext->stateFrame [NULLFRAME - STATEFRAME] == 0)        bcopy ((const char *) &fppInitContext, (char *)pFpContext,               sizeof (FP_CONTEXT));    /* must have init context to change */    /* normal/idle state */    for (ix = 0; ix < FP_NUM_DREGS; ix++)        fppDtoDx ((DOUBLEX *) &pFpContext->fpRegSet.fpx[ix],                  (double *) &pFpRegSet->fpx [ix]);    pFpContext->fpRegSet.fpcr  = pFpRegSet->fpcr;    pFpContext->fpRegSet.fpsr  = pFpRegSet->fpsr;    pFpContext->fpRegSet.fpiar = pFpRegSet->fpiar;    }/******************************************************************************** fppCtxToRegs - convert FP_CONTEXT to FPREG_SET.*/ void fppCtxToRegs    (    FP_CONTEXT * pFpContext,		/* input -  fpp context */    FPREG_SET *  pFpRegSet		/* output - fpp register set */    )    {    int ix;    if (pFpContext->stateFrame [NULLFRAME - STATEFRAME] == 0)        pFpContext = &fppInitContext;   /* return results of idle frame */    /* normal/idle state */    for (ix = 0; ix < FP_NUM_DREGS; ix++)        fppDxtoD ((double *) &pFpRegSet->fpx[ix],                  (DOUBLEX *) &pFpContext->fpRegSet.fpx[ix]);    pFpRegSet->fpcr  = pFpContext->fpRegSet.fpcr;    pFpRegSet->fpsr  = pFpContext->fpRegSet.fpsr;    pFpRegSet->fpiar = pFpContext->fpRegSet.fpiar;    }/********************************************************************************* fppTaskRegsGet - get the floating-point registers from a task TCB** This routine copies the floating-point registers of a task* (PCR, PSR, and PIAR) to the locations whose pointers are passed as* parameters.  The floating-point registers are copied in* an array containing the 8 registers.** NOTE* This routine only works well if <task> is not the calling task.* If a task tries to discover its own registers, the values will be stale* (i.e., leftover from the last task switch).** RETURNS: OK, or ERROR if there is no floating-point* support or there is an invalid state.** SEE ALSO: fppTaskRegsSet()*/STATUS fppTaskRegsGet    (    int task,           	/* task to get info about */    FPREG_SET *pFpRegSet	/* pointer to floating-point register set */    )    {    FAST FP_CONTEXT *pFpContext;    FAST WIND_TCB *pTcb = taskTcb (task);    if (pTcb == NULL)	return (ERROR);    pFpContext = pTcb->pFpContext;    if (pFpContext == (FP_CONTEXT *)NULL)	return (ERROR);			/* no coprocessor support */    fppCtxToRegs (pFpContext, pFpRegSet);    return (OK);    }/********************************************************************************* fppTaskRegsSet - set the floating-point registers of a task** This routine loads the specified values into the specified task TCB.* The 8 registers f0-f7 are copied to the array <fpregs>.** RETURNS: OK, or ERROR if there is no floating-point* support or there is an invalid state.** SEE ALSO: fppTaskRegsGet()*/STATUS fppTaskRegsSet    (    int task,           	/* task whose registers are to be set */    FPREG_SET *pFpRegSet	/* pointer to floating-point register set */    )    {    FAST WIND_TCB *pTcb = taskTcb (task);    FAST FP_CONTEXT *pFpContext;    if (pTcb == NULL)	return (ERROR);    pFpContext = pTcb->pFpContext;    if (pFpContext == (FP_CONTEXT *)NULL)	return (ERROR);			/* no coprocessor support, PUT ERRNO */    fppRegsToCtx (pFpRegSet, pFpContext);    return (OK);    }/********************************************************************************* fppReset - reset the floating point coprocessor** This routine will reset the floating point coprocessor by issuing a* fppRestore() of a NULL frame.  The contents of the floating point registers* will be reset, as well as all other floating point state information.** Use of this routine will improve context switch time between floating point* tasks if it is issued at points when a consistent floating point context * is no longer required.** CAVEATS* Not all versions of the MC68040 correctly support NULL frames, so the use* of this routine on this processor is not advised.** RETURNS: N/A** SEE ALSO: fppALib, MC68881/MC68882 User's Manual** NOMANUAL*/void fppReset (void)    {    FP_CONTEXT nullContext;    bzero ((char *)&nullContext, sizeof (FP_CONTEXT));    fppRestore (&nullContext);    }/********************************************************************************* fppProbe - probe for the presence of a floating-point coprocessor** This routine determines whether there is an MC68881/MC68882* floating-point coprocessor in the system.** IMPLEMENTATION* This routine sets the illegal coprocessor opcode trap vector and executes* a coprocessor instruction.  If the instruction causes an exception,* fppProbe() will return ERROR.  Note that this routine saves and restores* the illegal coprocessor opcode trap vector that was there prior to this* call.** The probe is only performed the first time this routine is called.* The result is stored in a static and returned on subsequent* calls without actually probing.** RETURNS:* OK if the floating-point coprocessor is present, otherwise ERROR.*/STATUS fppProbe (void)    {    static int fppProbed = -2;		/* -2 = not done, -1 = ERROR, 0 = OK */    FUNCPTR oldVec;    if (fppProbed == -2)	{	/* save error vector */	oldVec = intVecGet ((FUNCPTR *) IV_LINE_1111_EMULATOR);	/* replace error vec */	intVecSet ((FUNCPTR *) IV_LINE_1111_EMULATOR, (FUNCPTR) fppProbeTrap);	fppProbed = fppProbeSup ();	/* execute coprocessor instruction */	/* replace old err vec*/	intVecSet ((FUNCPTR *) IV_LINE_1111_EMULATOR, (FUNCPTR) oldVec);	}    return (fppProbed);    }

⌨️ 快捷键说明

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