?? altivec.c
字號(hào):
/* altivec.c - Altivec support functions */
/*
$RCSfile: altivec.c $
Copyright 2000 by Ixthos, Inc. All Rights Reserved.
$Revision: 1.8 $
$Name: AV4-ISP-R1.2-1 AV4-ISP-R1.2-0 HMTST2 HMTST1 DVT_AV4_4.101 AV4-VSP-R1.0-2 AV4-VSP-R1.0 CT-ISP-1.1 AV4 ISP 1.1 CT_R0.1_AV4/CAV4 champtools2.22 CAV4_CP1 CHAMPtools FW 3.0 champtools2.21_1215 champtools2.21 champ221_build1 champtools2.2 $ $State: Developmental $ $Locker: $
$Source: L:/SWRND/champAV2/src/vx/src/drv/altivec/rcs/altivec.c $
RCS Project Name: vx_7xx
Target: IXA board, 750/7400 processors
DESCRIPTION
This library provides task hook functions that save and
restore the altivec registers during context switches.
BSP CONFIGURATION
This function must be included within the BSP. The function
sysAltivecInit must be called first to install task switch
hooks. This must be called after the OS is initialized but
before the first Altivec functions are called; calling from
sysHwInit2 is recommended.
Tasks wishing to use the Altivec should be created with the
option VX_ALTIVEC. Such tasks will be allocated an Altivec
register save area, and have the Altivec enable bit in the
MSR set.
Alternately, each task wishing to use the Altivec should call
the function sysAltivecEnable. This creates the register
save area, saves the Altivec context (if it was busy), and
sets the Altivec enable bit within the MSR.
INCLUDE FILES:
SEE ALSO:
$Log: altivec.c $
Revision 1.8 2004/07/30 18:52:37Z dsessler
now using proctypes in bsl.h; Probe should now return OK for 7410,7400,7447,7447A;
Enable now calls Probe to check proctype.
Revision 1.7 2003/05/21 21:01:25 dsessler
T2.2 fix for paths of included files under the bsp
Revision 1.6 2002/05/14 18:57:01 coopertr
Revision 1.5 2002/05/14 14:38:35 dsessler
Had old copy.
Revision 1.7 2001/12/13 13:33:13 coopertr
Modified to check for valid register save area address before
saving/restoring AltiVec registers
Revision 1.6 2001/10/17 12:45:03 coopertr
Modified for Tornado 2.1 support. If INCLUDE_ALTIVEC is defined
(indicating OS support for the Altivec), then the functions in this source
file are configured for OS support of the AltiVec.
Revision 1.5 2001/05/16 14:55:29 seckardt
Removed PROCTYPE_MPC_7400 definition; it is already in ixa.h.
Revision 1.4 2000/10/31 18:37:09 dbratton
Updated for man pages.
Revision 1.3 2000/10/24 10:40:54 coopertr
Modified to create task in non-Java mode
Revision 1.2 2000/10/17 14:43:06 coopertr
Added altivec.h file
Revision 1.1 2000/09/26 10:39:00 coopertr
Initial revision
*/
/* includes */
#include <vxWorks.h>
#include <memLib.h>
#include <taskLib.h>
#include <taskHookLib.h>
#include "h/drv/altivec/altivec.h"
#include "bsl.h"
/* defines */
#define MSR_ALTIVEC_ENABLE 0x02000000 /* enable AV in MSR */
#define NJ 0x00010000 /* non-Java mode */
#define VSCR_PTR(x) (((unsigned long *)(x))+32*4)
/* the support method used is different for Tornado 2.1
Altivec support (indicated by INCLUDE_ALTIVEC) versus
non-Tornado support. */
#ifdef INCLUDE_ALTIVEC
LOCAL void taskCreateAV (WIND_TCB *t);
LOCAL void setAltivecNonJavaMode (void);
extern void *_func_altivecProbeRtn;
#else /* INCLUDE_ALTIVEC */
LOCAL void taskCreateAV (WIND_TCB *t);
LOCAL void taskDeleteAV (WIND_TCB *t);
LOCAL void taskSwitchAV (WIND_TCB *old, WIND_TCB *new);
/*
* This pointer remembers the TCB address which last owned
* the Altivec registers. If this pointer is zero, then
* the Altivec registers contain no interesting values,
* and they may be overwritten freely. If the pointer is
* nonzero, then the indicated task owns the register values,
* and the context switch hook must save the registers on
* behalf of that task before switching to another task
* that uses the Altivec registers.
*/
static WIND_TCB *currentAVTask = 0;
#endif /* INCLUDE_ALTIVEC */
/* MACRO Definition for sysAltivecProbe Dino M. Diab Compiler */
#ifdef __DCC__
asm int getAltivecExt()
{
!"r3"
mfspr 3,287
}
#endif
/***********************************************************
*
* sysAltivecProbe - Determine if the processor has AltiVec
* extensions.
*
* This function examines the processor version register to
* determine if the processor includes AltiVec technology.
* The function returns SUCCESS if the processor
* does indeed support the AltiVec.
*
* SEE ALSO: sysAltivecEnable()
* NOMANUAL
*/
static int sysAltivecProbe
(
void
)
{
unsigned long proctype, status;
status = 1;
proctype = 0;
#ifdef __DCC__
proctype = getAltivecExt();
#else
__asm__ (" mfspr %0,287" : "=r" (proctype)); /* read PVR */
#endif
proctype >>= 16;
if ((proctype == MPC7400) || (proctype == MPC7410) ||
(proctype == MPC7447_7457) || (proctype == MPC7447A) || (proctype == MPC7448))
{
status = 0;
}
return (status);
}
/***********************************************************
*
* sysAltivecInit - Install Altivec task hooks
*
* This function installs task management hooks for the Altivec.
* This function should be called once during system initialization,
* before any Altivec tasks are created. This function has no
* effect if called on a non-altivec processor.
*
* RETURNS: None
*
* SEE ALSO: sysAlitivecEnable()
* NOMANUAL
*/
void sysAltivecInit
(
void
)
{
static int firsttime = 1;
unsigned long ilock;
/*
* Verify that we are running on an Altivec.
*/
if (sysAltivecProbe ())
return;
ilock = intLock ();
#ifndef INCLUDE_ALTIVEC
if (firsttime)
{
firsttime = 0;
taskDeleteHookAdd ((FUNCPTR) taskDeleteAV);
taskCreateHookAdd ((FUNCPTR) taskCreateAV);
taskSwitchHookAdd ((FUNCPTR) taskSwitchAV);
}
#else
if (firsttime)
{
firsttime = 0;
taskCreateHookAdd ((FUNCPTR) taskCreateAV);
_func_altivecProbeRtn = sysAltivecProbe;
altivecInit ();
}
#endif
intUnlock (ilock);
return;
}
/***********************************************************
*
* sysAltivecEnable - Enable the Altivec for the calling task
*
* This function enables the Altivec for the task that calls this
* function. This function may not be called from an ISR.
* This function allocates a register save area for Altivec
* registers. If the Altivec registers are live (containing data
* from another task) when this call is made, then this function
* saves the altivec registers as part of the context of the task
* which last used the altivec.
*
* If INCLUDE_ALTIVEC is defined, this indicates that the OS
* supports AltiVec technology. In this case, this function
* verifies that the calling task has been created with
* altivec enabled, and sets the mode to non-Java mode. If
* the task was not created with AltiVec enabled, this function
* returns an error status.
*
* NOTE: This function sets the non-Java (NJ) bit within vscr.
*
* RETURNS: 0 for success; -1 if the processor is not an altivec,
* -2 = not called from a task, -3 = could not malloc
* register save area, -4 = task not created with altivec
* option enabled.
*
* SEE ALSO: sysAltivecInit()
*/
int sysAltivecEnable
(
void
)
{
#ifndef INCLUDE_ALTIVEC
unsigned long proctype, ilock;
int status = 0;
WIND_TCB *mytcb;
/*
* Verify that we are running on an Altivec.
*/
if (sysAltivecProbe ())
return (-1);
/*
* Install task management OS hooks if needed.
*/
sysAltivecInit ();
/*
* Obtain the TCB address of the calling task.
*/
if ((mytcb = taskTcb (taskIdSelf ())) == 0)
return (-2);
ilock = intLock ();
/*
* If no register save area exists, allocate one now
*/
if (mytcb->ALTIVEC_RSAVE == 0)
{
mytcb->options |= VX_ALTIVEC;
taskCreateAV (mytcb);
if (mytcb->ALTIVEC_RSAVE == 0)
status = -3;
else
{
/*
* If an altivec task is currently active,
* save its registers. Reload "our" registers.
*/
if (currentAVTask != 0 && currentAVTask->ALTIVEC_RSAVE != 0)
sysAltivecStore ((void *) (currentAVTask->ALTIVEC_RSAVE));
/*
* Set NJ mode of last 32 bit word within VSCR
*/
VSCR_PTR(mytcb->ALTIVEC_RSAVE)[3] |= NJ;
sysAltivecLoad ((void *) (mytcb->ALTIVEC_RSAVE));
currentAVTask = mytcb;
/*
* Enable the Altivec bit within MSR. Set
* spr 256 to all 1's indicating all regs
* are active.
*/
__asm__ (" mfmsr 3
or 3,3,%0
mtmsr 3
sync
li 3,-1
mtspr 256,3"
: : "r" (MSR_ALTIVEC_ENABLE) : "3");
}
}
intUnlock (ilock);
return (status);
#else
/*
* Place AltiVec in Java mode. The calling task must be
* created with AltiVec enabled.
*/
setAltivecNonJavaMode ();
return (0);
#endif
}
/***********************************************************
*
* taskCreateAV - Altivec task create hook
*
* This local function clears the ALTIVEC RSAVE field within the TCB,
* indicating the task is not altivec enabled. If the ALTIVEC option
* is set, this function creates and clears a register save area
* for the Altivec, and sets the Altivec enable bit within the MSR.
* The VSCR register is set to indicate non-Java mode.
* Note that this hook is installed only for Altivec processors.
*
* If INCLUDE_ALTIVEC is set, this task switch hook translates
* the option field so that the older, non-vxWorks altivec
* option introduced in our past BSPs is translated into the
* newer vxWorks compatible option.
*
* SEE ALSO: taskSwitchAV(), taskDeleteAV()
*/
LOCAL void taskCreateAV
(
WIND_TCB *t /* pointer to TCB of task being created */
)
{
#ifndef INCLUDE_ALTIVEC
int i;
unsigned long *rsave;
t->ALTIVEC_RSAVE = 0;
if (t->options & VX_ALTIVEC)
{
if ((rsave = memalign (32, 4*ALTIVEC_RSAVE_SIZE)) != 0)
{
(void *) (t->ALTIVEC_RSAVE) = rsave;
for (i = 0; i < ALTIVEC_RSAVE_SIZE; i++)
rsave[i] = 0;
VSCR_PTR(rsave)[3] |= NJ;
t->regs.msr |= MSR_ALTIVEC_ENABLE;
}
}
#else
if (t->options & VX_ALTIVEC)
{
t->options &= ~VX_ALTIVEC;
t->options |= VX_ALTIVEC_TASK;
}
#endif
}
/***********************************************************
*
* taskDeleteAV - Altivec task delete hook
*
* This local function is installed as the task delete hook.
* If the task being deleted has an altivec register save area
* allocated, then this function frees that area.
*
* If the task being deleted is the last task to use Altivec
* registers, then clear currentAVTask. This prevents the
* context switch hook from saving registers for this task
* when switching to a new task.
*
* SEE ALSO: taskSwitchAV(), taskCreateAV()
*/
#ifndef INCLUDE_ALTIVEC
LOCAL void taskDeleteAV
(
WIND_TCB *t /* pointer to TCB of task being deleted */
)
{
/*
* If the task being deleted owns the Altivec
* registers (indicated by t == current task),
* then set the current task pointer to zero.
* This signifies that no task owns the Altivec
* registers at this time, and that they need to
* be reloaded when a context switch to an
* Altivec task occurs.
*/
if (t == currentAVTask)
currentAVTask = 0;
/*
* If the task being deleted had an Altivec
* register area, then free it up now.
*/
if ((t->regs.msr & MSR_ALTIVEC_ENABLE) && t->ALTIVEC_RSAVE)
{
free ((void *) (t->ALTIVEC_RSAVE));
t->ALTIVEC_RSAVE = 0;
}
}
#endif
/*******************************************************************************
*
* taskSwitchAV - Altivec task switch hook
*
* This local function is installed as the task switch hook.
* If we are switching into an Altivec enabled task,
* then we need to load registers from the TCB's
* Altivec register save area.
*
* Furthermore, if the Altivec registers still contain
* live values from another task, then we need to
* save those registers within the task's register
* save area.
*
* If the Altivec registers contain live data from
* the task to which we are switching, then no action
* is needed.
*
* SEE ALSO: taskCreateAV(), taskDeleteAV()
*/
#ifndef INCLUDE_ALTIVEC
LOCAL void taskSwitchAV
(
WIND_TCB *old, /* ptr to tcb being switched out */
WIND_TCB *new /* ptr to tcb being switched in */
)
{
/*
* If the new TCB does not require Altivec
* support, then exit.
*/
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -