/* $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 #include #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