129 lines
3.5 KiB
C
129 lines
3.5 KiB
C
/* $Id: VIS.h,v 1.4 1999/05/25 16:52:50 jj Exp $
|
|
* VIS.h: High speed copy/clear operations utilizing the UltraSparc
|
|
* Visual Instruction Set.
|
|
*
|
|
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
|
|
* Copyright (C) 1996, 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
|
|
*/
|
|
|
|
/* VIS code can be used for numerous copy/set operation variants.
|
|
* It can be made to work in the kernel, one single instance,
|
|
* for all of memcpy, copy_to_user, and copy_from_user by setting
|
|
* the ASI src/dest globals correctly. Furthermore it can
|
|
* be used for kernel-->kernel page copies as well, a hook label
|
|
* is put in here just for this purpose.
|
|
*
|
|
* For userland, compiling this without __KERNEL__ defined makes
|
|
* it work just fine as a generic libc bcopy and memcpy.
|
|
* If for userland it is compiled with a 32bit gcc (but you need
|
|
* -Wa,-Av9a), the code will just rely on lower 32bits of
|
|
* IEU registers, if you compile it with 64bit gcc (ie. define
|
|
* __sparc_v9__), the code will use full 64bit.
|
|
*/
|
|
|
|
#ifndef __VIS_H
|
|
#define __VIS_H
|
|
|
|
#ifdef __KERNEL__
|
|
#include <asm/head.h>
|
|
#include <asm/asi.h>
|
|
#else
|
|
#define ASI_AIUS 0x11 /* Secondary, user */
|
|
#define ASI_BLK_AIUS 0x71 /* Secondary, user, blk ld/st */
|
|
#define ASI_P 0x80 /* Primary, implicit */
|
|
#define ASI_S 0x81 /* Secondary, implicit */
|
|
#define ASI_BLK_COMMIT_P 0xe0 /* Primary, blk store commit */
|
|
#define ASI_BLK_COMMIT_S 0xe1 /* Secondary, blk store commit */
|
|
#define ASI_BLK_P 0xf0 /* Primary, blk ld/st */
|
|
#define ASI_BLK_S 0xf1 /* Secondary, blk ld/st */
|
|
#define FPRS_FEF 0x04
|
|
#endif
|
|
|
|
/* I'm telling you, they really did this chip right.
|
|
* Perhaps the SunSoft folks should visit some of the
|
|
* people in Sun Microelectronics and start some brain
|
|
* cell exchange program...
|
|
*/
|
|
#define ASI_BLK_XOR (ASI_P ^ ASI_BLK_P)
|
|
/* Well, things get more hairy if we use ASI_AIUS as
|
|
* USER_DS and ASI_P as KERNEL_DS, we'd reach
|
|
* commit block stores this way which is not what we want...
|
|
*/
|
|
/* ASI_P->ASI_BLK_P && ASI_AIUS->ASI_BLK_AIUS transitions can be done
|
|
* as blkasi = asi | ASI_BLK_OR
|
|
*/
|
|
#define ASI_BLK_OR (ASI_BLK_P & ~ASI_P)
|
|
/* Transition back from ASI_BLK_P->ASI_P && ASI_BLK_AIUS->ASI_AIUS is
|
|
* more complicated:
|
|
* asi = blkasi ^ (blkasi >> 3) ^ ASI_BLK_XOR1
|
|
*/
|
|
#define ASI_BLK_XOR1 (ASI_BLK_P ^ (ASI_BLK_P >> 3) ^ ASI_P)
|
|
|
|
#define asi_src %o3
|
|
#define asi_dest %o4
|
|
|
|
#ifdef __KERNEL__
|
|
#define ASI_SETSRC_BLK wr asi_src, 0, %asi;
|
|
#define ASI_SETSRC_NOBLK wr asi_src, 0, %asi;
|
|
#define ASI_SETDST_BLK wr asi_dest, 0, %asi;
|
|
#define ASI_SETDST_NOBLK wr asi_dest, 0, %asi;
|
|
#define ASIBLK %asi
|
|
#define ASINORMAL %asi
|
|
#define LDUB lduba
|
|
#define LDUH lduha
|
|
#define LDUW lduwa
|
|
#define LDX ldxa
|
|
#define LDD ldda
|
|
#define LDDF ldda
|
|
#define LDBLK ldda
|
|
#define STB stba
|
|
#define STH stha
|
|
#define STW stwa
|
|
#define STD stda
|
|
#define STX stxa
|
|
#define STDF stda
|
|
#define STBLK stda
|
|
#else
|
|
#define ASI_SETSRC_BLK
|
|
#define ASI_SETSRC_NOBLK
|
|
#define ASI_SETDST_BLK
|
|
#define ASI_SETDST_NOBLK
|
|
#define ASI_SETDST_SPECIAL
|
|
#define ASIBLK %asi
|
|
#define ASINORMAL
|
|
#define LDUB ldub
|
|
#define LDUH lduh
|
|
#define LDUW lduw
|
|
#define LDD ldd
|
|
#define LDX ldx
|
|
#define LDDF ldd
|
|
#define LDBLK ldda
|
|
#define STB stb
|
|
#define STH sth
|
|
#define STW stw
|
|
#define STD std
|
|
#define STX stx
|
|
#define STDF std
|
|
#define STBLK stda
|
|
#endif
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
#define REGS_64BIT
|
|
|
|
#else
|
|
|
|
#ifndef REGS_64BIT
|
|
#ifdef __sparc_v9__
|
|
#define REGS_64BIT
|
|
#endif
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#ifndef REGS_64BIT
|
|
#define xcc icc
|
|
#endif
|
|
|
|
#endif
|