cvmx-asm.h revision 215990
1210284Sjmallett/***********************license start***************
2215990Sjmallett * Copyright (c) 2003-2010  Cavium Networks (support@cavium.com). All rights
3215990Sjmallett * reserved.
4210284Sjmallett *
5210284Sjmallett *
6215990Sjmallett * Redistribution and use in source and binary forms, with or without
7215990Sjmallett * modification, are permitted provided that the following conditions are
8215990Sjmallett * met:
9210284Sjmallett *
10215990Sjmallett *   * Redistributions of source code must retain the above copyright
11215990Sjmallett *     notice, this list of conditions and the following disclaimer.
12210284Sjmallett *
13215990Sjmallett *   * Redistributions in binary form must reproduce the above
14215990Sjmallett *     copyright notice, this list of conditions and the following
15215990Sjmallett *     disclaimer in the documentation and/or other materials provided
16215990Sjmallett *     with the distribution.
17215990Sjmallett
18215990Sjmallett *   * Neither the name of Cavium Networks nor the names of
19215990Sjmallett *     its contributors may be used to endorse or promote products
20215990Sjmallett *     derived from this software without specific prior written
21215990Sjmallett *     permission.
22215990Sjmallett
23215990Sjmallett * This Software, including technical data, may be subject to U.S. export  control
24215990Sjmallett * laws, including the U.S. Export Administration Act and its  associated
25215990Sjmallett * regulations, and may be subject to export or import  regulations in other
26215990Sjmallett * countries.
27215990Sjmallett
28215990Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29215990Sjmallett * AND WITH ALL FAULTS AND CAVIUM  NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR
30215990Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31215990Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32215990Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33215990Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34215990Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35215990Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36215990Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37215990Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38210284Sjmallett ***********************license end**************************************/
39210284Sjmallett
40210284Sjmallett
41210284Sjmallett
42210284Sjmallett
43210284Sjmallett
44210284Sjmallett
45215990Sjmallett
46210284Sjmallett/**
47210284Sjmallett * @file
48210284Sjmallett *
49210284Sjmallett * This is file defines ASM primitives for the executive.
50210284Sjmallett
51215990Sjmallett * <hr>$Revision: 52004 $<hr>
52210284Sjmallett *
53210284Sjmallett *
54210284Sjmallett */
55210284Sjmallett#ifndef __CVMX_ASM_H__
56210284Sjmallett#define __CVMX_ASM_H__
57210284Sjmallett
58215990Sjmallett#define COP0_INDEX	$0,0	/* TLB read/write index */
59215990Sjmallett#define COP0_RANDOM	$1,0	/* TLB random index */
60215990Sjmallett#define COP0_ENTRYLO0	$2,0	/* TLB entryLo0 */
61215990Sjmallett#define COP0_ENTRYLO1	$3,0	/* TLB entryLo1 */
62215990Sjmallett#define COP0_CONTEXT	$4,0	/* Context */
63215990Sjmallett#define COP0_PAGEMASK	$5,0	/* TLB pagemask */
64215990Sjmallett#define COP0_PAGEGRAIN	$5,1	/* TLB config for max page sizes */
65215990Sjmallett#define COP0_WIRED	$6,0	/* TLB number of wired entries */
66215990Sjmallett#define COP0_HWRENA	$7,0	/* rdhw instruction enable per register */
67215990Sjmallett#define COP0_BADVADDR	$8,0	/* Bad virtual address */
68215990Sjmallett#define COP0_COUNT	$9,0	/* Mips count register */
69215990Sjmallett#define COP0_CVMCOUNT	$9,6	/* Cavium count register */
70215990Sjmallett#define COP0_CVMCTL	$9,7	/* Cavium control */
71215990Sjmallett#define COP0_ENTRYHI	$10,0	/* TLB entryHi */
72215990Sjmallett#define COP0_COMPARE	$11,0	/* Mips compare register */
73215990Sjmallett#define COP0_POWTHROTTLE $11,6	/* Power throttle register */
74215990Sjmallett#define COP0_CVMMEMCTL	$11,7	/* Cavium memory control */
75215990Sjmallett#define COP0_STATUS	$12,0	/* Mips status register */
76215990Sjmallett#define COP0_INTCTL	$12,1	/* Useless (Vectored interrupts) */
77215990Sjmallett#define COP0_SRSCTL	$12,2	/* Useless (Shadow registers) */
78215990Sjmallett#define COP0_CAUSE	$13,0	/* Mips cause register */
79215990Sjmallett#define COP0_EPC	$14,0	/* Exception program counter */
80215990Sjmallett#define COP0_PRID	$15,0	/* Processor ID */
81215990Sjmallett#define COP0_EBASE	$15,1	/* Exception base */
82215990Sjmallett#define COP0_CONFIG	$16,0	/* Misc config options */
83215990Sjmallett#define COP0_CONFIG1	$16,1	/* Misc config options */
84215990Sjmallett#define COP0_CONFIG2	$16,2	/* Misc config options */
85215990Sjmallett#define COP0_CONFIG3	$16,3	/* Misc config options */
86215990Sjmallett#define COP0_WATCHLO0	$18,0	/* Address watch registers */
87215990Sjmallett#define COP0_WATCHLO1	$18,1	/* Address watch registers */
88215990Sjmallett#define COP0_WATCHHI0	$19,0	/* Address watch registers */
89215990Sjmallett#define COP0_WATCHHI1	$19,1	/* Address watch registers */
90215990Sjmallett#define COP0_XCONTEXT	$20,0	/* OS context */
91215990Sjmallett#define COP0_MULTICOREDEBUG $22,0 /* Cavium debug */
92215990Sjmallett#define COP0_DEBUG	$23,0	/* Debug status */
93215990Sjmallett#define COP0_DEPC	$24,0	/* Debug PC */
94215990Sjmallett#define COP0_PERFCONTROL0 $25,0	/* Performance counter control */
95215990Sjmallett#define COP0_PERFCONTROL1 $25,2	/* Performance counter control */
96215990Sjmallett#define COP0_PERFVALUE0	$25,1	/* Performance counter */
97215990Sjmallett#define COP0_PERFVALUE1	$25,3	/* Performance counter */
98215990Sjmallett#define COP0_CACHEERRI	$27,0	/* I cache error status */
99215990Sjmallett#define COP0_CACHEERRD	$27,1	/* D cache error status */
100215990Sjmallett#define COP0_TAGLOI	$28,0	/* I cache tagLo */
101215990Sjmallett#define COP0_TAGLOD	$28,2	/* D cache tagLo */
102215990Sjmallett#define COP0_DATALOI	$28,1	/* I cache dataLo */
103215990Sjmallett#define COP0_DATALOD	$28,3	/* D cahce dataLo */
104215990Sjmallett#define COP0_TAGHI	$29,2	/* ? */
105215990Sjmallett#define COP0_DATAHII	$29,1	/* ? */
106215990Sjmallett#define COP0_DATAHID	$29,3	/* ? */
107215990Sjmallett#define COP0_ERROREPC	$30,0	/* Error PC */
108215990Sjmallett#define COP0_DESAVE	$31,0	/* Debug scratch area */
109215990Sjmallett
110215990Sjmallett/* This header file can be included from a .S file.  Keep non-preprocessor
111215990Sjmallett   things under !__ASSEMBLER__.  */
112215990Sjmallett#ifndef __ASSEMBLER__
113215990Sjmallett
114215990Sjmallett#include "octeon-model.h"
115215990Sjmallett
116210284Sjmallett#ifdef	__cplusplus
117210284Sjmallettextern "C" {
118210284Sjmallett#endif
119210284Sjmallett
120210284Sjmallett/* turn the variable name into a string */
121210284Sjmallett#define CVMX_TMP_STR(x) CVMX_TMP_STR2(x)
122210284Sjmallett#define CVMX_TMP_STR2(x) #x
123210284Sjmallett
124215990Sjmallett#if !OCTEON_IS_COMMON_BINARY()
125215990Sjmallett #if CVMX_COMPILED_FOR(OCTEON_CN63XX)
126215990Sjmallett   #define CVMX_CAVIUM_OCTEON2
127215990Sjmallett #endif
128215990Sjmallett#endif
129215990Sjmallett
130210284Sjmallett/* other useful stuff */
131210284Sjmallett#define CVMX_BREAK asm volatile ("break")
132210284Sjmallett#define CVMX_SYNC asm volatile ("sync" : : :"memory")
133210284Sjmallett/* String version of SYNCW macro for using in inline asm constructs */
134215990Sjmallett#define CVMX_SYNCW_STR_OCTEON2 "syncw\n"
135215990Sjmallett#ifdef CVMX_CAVIUM_OCTEON2
136215990Sjmallett #define CVMX_SYNCW_STR CVMX_SYNCW_STR_OCTEON2
137215990Sjmallett#else
138215990Sjmallett #define CVMX_SYNCW_STR "syncw\nsyncw\n"
139215990Sjmallett#endif /* CVMX_CAVIUM_OCTEON2 */
140215990Sjmallett
141210284Sjmallett#ifdef __OCTEON__
142210284Sjmallett    #define CVMX_SYNCIO asm volatile ("nop")   /* Deprecated, will be removed in future release */
143210284Sjmallett    #define CVMX_SYNCIOBDMA asm volatile ("synciobdma" : : :"memory")
144210284Sjmallett    #define CVMX_SYNCIOALL asm volatile ("nop")   /* Deprecated, will be removed in future release */
145210284Sjmallett    /* We actually use two syncw instructions in a row when we need a write
146210284Sjmallett        memory barrier. This is because the CN3XXX series of Octeons have
147210284Sjmallett        errata Core-401. This can cause a single syncw to not enforce
148210284Sjmallett        ordering under very rare conditions. Even if it is rare, better safe
149210284Sjmallett        than sorry */
150215990Sjmallett    #define CVMX_SYNCW_OCTEON2 asm volatile ("syncw\n" : : :"memory")
151215990Sjmallett    #ifdef CVMX_CAVIUM_OCTEON2
152215990Sjmallett     #define CVMX_SYNCW CVMX_SYNCW_OCTEON2
153215990Sjmallett    #else
154215990Sjmallett     #define CVMX_SYNCW asm volatile ("syncw\nsyncw\n" : : :"memory")
155215990Sjmallett    #endif /* CVMX_CAVIUM_OCTEON2 */
156210284Sjmallett#if defined(VXWORKS) || defined(__linux__)
157215990Sjmallett        /* Define new sync instructions to be normal SYNC instructions for
158215990Sjmallett           operating systems that use threads */
159215990Sjmallett        #define CVMX_SYNCWS CVMX_SYNCW
160215990Sjmallett        #define CVMX_SYNCS  CVMX_SYNC
161215990Sjmallett        #define CVMX_SYNCWS_STR CVMX_SYNCW_STR
162215990Sjmallett        #define CVMX_SYNCWS_OCTEON2 CVMX_SYNCW_OCTEON2
163215990Sjmallett        #define CVMX_SYNCWS_STR_OCTEON2 CVMX_SYNCW_STR_OCTEON2
164210284Sjmallett#else
165210284Sjmallett    #if defined(CVMX_BUILD_FOR_TOOLCHAIN)
166210284Sjmallett        /* While building simple exec toolchain, always use syncw to
167210284Sjmallett           support all Octeon models. */
168210284Sjmallett        #define CVMX_SYNCWS CVMX_SYNCW
169210284Sjmallett        #define CVMX_SYNCS  CVMX_SYNC
170210284Sjmallett        #define CVMX_SYNCWS_STR CVMX_SYNCW_STR
171215990Sjmallett        #define CVMX_SYNCWS_OCTEON2 CVMX_SYNCW_OCTEON2
172215990Sjmallett        #define CVMX_SYNCWS_STR_OCTEON2 CVMX_SYNCW_STR_OCTEON2
173210284Sjmallett    #else
174210284Sjmallett        /* Again, just like syncw, we may need two syncws instructions in a row due
175215990Sjmallett           errata Core-401. Only one syncws is required for Octeon2 models */
176210284Sjmallett        #define CVMX_SYNCS asm volatile ("syncs" : : :"memory")
177215990Sjmallett        #define CVMX_SYNCWS_OCTEON2 asm volatile ("syncws\n" : : :"memory")
178215990Sjmallett        #define CVMX_SYNCWS_STR_OCTEON2 "syncws\n"
179215990Sjmallett        #ifdef CVMX_CAVIUM_OCTEON2
180215990Sjmallett          #define CVMX_SYNCWS CVMX_SYNCWS_OCTEON2
181215990Sjmallett          #define CVMX_SYNCWS_STR CVMX_SYNCWS_STR_OCTEON2
182215990Sjmallett        #else
183215990Sjmallett          #define CVMX_SYNCWS asm volatile ("syncws\nsyncws\n" : : :"memory")
184215990Sjmallett          #define CVMX_SYNCWS_STR "syncws\nsyncws\n"
185215990Sjmallett        #endif /* CVMX_CAVIUM_OCTEON2 */
186210284Sjmallett    #endif
187210284Sjmallett#endif
188215990Sjmallett#else /* !__OCTEON__ */
189210284Sjmallett    /* Not using a Cavium compiler, always use the slower sync so the assembler stays happy */
190210284Sjmallett    #define CVMX_SYNCIO asm volatile ("nop")   /* Deprecated, will be removed in future release */
191210284Sjmallett    #define CVMX_SYNCIOBDMA asm volatile ("sync" : : :"memory")
192210284Sjmallett    #define CVMX_SYNCIOALL asm volatile ("nop")   /* Deprecated, will be removed in future release */
193210284Sjmallett    #define CVMX_SYNCW asm volatile ("sync" : : :"memory")
194210284Sjmallett    #define CVMX_SYNCWS CVMX_SYNCW
195210284Sjmallett    #define CVMX_SYNCS  CVMX_SYNC
196210284Sjmallett    #define CVMX_SYNCWS_STR CVMX_SYNCW_STR
197215990Sjmallett    #define CVMX_SYNCWS_OCTEON2 CVMX_SYNCW
198215990Sjmallett    #define CVMX_SYNCWS_STR_OCTEON2 CVMX_SYNCW_STR
199210284Sjmallett#endif
200210284Sjmallett#define CVMX_SYNCI(address, offset) asm volatile ("synci " CVMX_TMP_STR(offset) "(%[rbase])" : : [rbase] "d" (address) )
201210284Sjmallett#define CVMX_PREFETCH0(address) CVMX_PREFETCH(address, 0)
202210284Sjmallett#define CVMX_PREFETCH128(address) CVMX_PREFETCH(address, 128)
203210284Sjmallett// a normal prefetch
204210284Sjmallett#define CVMX_PREFETCH(address, offset) CVMX_PREFETCH_PREF0(address, offset)
205210284Sjmallett// normal prefetches that use the pref instruction
206210284Sjmallett#define CVMX_PREFETCH_PREFX(X, address, offset) asm volatile ("pref %[type], %[off](%[rbase])" : : [rbase] "d" (address), [off] "I" (offset), [type] "n" (X))
207210284Sjmallett#define CVMX_PREFETCH_PREF0(address, offset) CVMX_PREFETCH_PREFX(0, address, offset)
208210284Sjmallett#define CVMX_PREFETCH_PREF1(address, offset) CVMX_PREFETCH_PREFX(1, address, offset)
209210284Sjmallett#define CVMX_PREFETCH_PREF6(address, offset) CVMX_PREFETCH_PREFX(6, address, offset)
210210284Sjmallett#define CVMX_PREFETCH_PREF7(address, offset) CVMX_PREFETCH_PREFX(7, address, offset)
211210284Sjmallett// prefetch into L1, do not put the block in the L2
212210284Sjmallett#define CVMX_PREFETCH_NOTL2(address, offset) CVMX_PREFETCH_PREFX(4, address, offset)
213210284Sjmallett#define CVMX_PREFETCH_NOTL22(address, offset) CVMX_PREFETCH_PREFX(5, address, offset)
214210284Sjmallett// prefetch into L2, do not put the block in the L1
215210284Sjmallett#define CVMX_PREFETCH_L2(address, offset) CVMX_PREFETCH_PREFX(28, address, offset)
216210284Sjmallett// CVMX_PREPARE_FOR_STORE makes each byte of the block unpredictable (actually old value or zero) until
217210284Sjmallett// that byte is stored to (by this or another processor. Note that the value of each byte is not only
218210284Sjmallett// unpredictable, but may also change again - up until the point when one of the cores stores to the
219210284Sjmallett// byte.
220210284Sjmallett#define CVMX_PREPARE_FOR_STORE(address, offset) CVMX_PREFETCH_PREFX(30, address, offset)
221210284Sjmallett// This is a command headed to the L2 controller to tell it to clear its dirty bit for a
222210284Sjmallett// block. Basically, SW is telling HW that the current version of the block will not be
223210284Sjmallett// used.
224210284Sjmallett#define CVMX_DONT_WRITE_BACK(address, offset) CVMX_PREFETCH_PREFX(29, address, offset)
225210284Sjmallett
226210284Sjmallett#define CVMX_ICACHE_INVALIDATE  { CVMX_SYNC; asm volatile ("synci 0($0)" : : ); }    // flush stores, invalidate entire icache
227210284Sjmallett#define CVMX_ICACHE_INVALIDATE2 { CVMX_SYNC; asm volatile ("cache 0, 0($0)" : : ); } // flush stores, invalidate entire icache
228210284Sjmallett#define CVMX_DCACHE_INVALIDATE  { CVMX_SYNC; asm volatile ("cache 9, 0($0)" : : ); } // complete prefetches, invalidate entire dcache
229210284Sjmallett
230215990Sjmallett#define CVMX_CACHE(op, address, offset) asm volatile ("cache " CVMX_TMP_STR(op) ", " CVMX_TMP_STR(offset) "(%[rbase])" : : [rbase] "d" (address) )
231215990Sjmallett#define CVMX_CACHE_LCKL2(address, offset) CVMX_CACHE(31, address, offset) // fetch and lock the state.
232215990Sjmallett#define CVMX_CACHE_WBIL2(address, offset) CVMX_CACHE(23, address, offset) // unlock the state.
233215990Sjmallett#define CVMX_CACHE_WBIL2I(address, offset) CVMX_CACHE(3, address, offset) // invalidate the cache block and clear the USED bits for the block
234215990Sjmallett#define CVMX_CACHE_LTGL2I(address, offset) CVMX_CACHE(7, address, offset) // load virtual tag and data for the L2 cache block into L2C_TAD0_TAG register
235215990Sjmallett
236210284Sjmallett/* new instruction to make RC4 run faster */
237210284Sjmallett#define CVMX_BADDU(result, input1, input2) asm ("baddu %[rd],%[rs],%[rt]" : [rd] "=d" (result) : [rs] "d" (input1) , [rt] "d" (input2))
238210284Sjmallett
239210284Sjmallett// misc v2 stuff
240210284Sjmallett#define CVMX_ROTR(result, input1, shiftconst) asm ("rotr %[rd],%[rs]," CVMX_TMP_STR(shiftconst) : [rd] "=d" (result) : [rs] "d" (input1))
241210284Sjmallett#define CVMX_ROTRV(result, input1, input2) asm ("rotrv %[rd],%[rt],%[rs]" : [rd] "=d" (result) : [rt] "d" (input1) , [rs] "d" (input2))
242210284Sjmallett#define CVMX_DROTR(result, input1, shiftconst) asm ("drotr %[rd],%[rs]," CVMX_TMP_STR(shiftconst) : [rd] "=d" (result) : [rs] "d" (input1))
243210284Sjmallett#define CVMX_DROTRV(result, input1, input2) asm ("drotrv %[rd],%[rt],%[rs]" : [rd] "=d" (result) : [rt] "d" (input1) , [rs] "d" (input2))
244210284Sjmallett#define CVMX_SEB(result, input1) asm ("seb %[rd],%[rt]" : [rd] "=d" (result) : [rt] "d" (input1))
245210284Sjmallett#define CVMX_SEH(result, input1) asm ("seh %[rd],%[rt]" : [rd] "=d" (result) : [rt] "d" (input1))
246210284Sjmallett#define CVMX_DSBH(result, input1) asm ("dsbh %[rd],%[rt]" : [rd] "=d" (result) : [rt] "d" (input1))
247210284Sjmallett#define CVMX_DSHD(result, input1) asm ("dshd %[rd],%[rt]" : [rd] "=d" (result) : [rt] "d" (input1))
248210284Sjmallett#define CVMX_WSBH(result, input1) asm ("wsbh %[rd],%[rt]" : [rd] "=d" (result) : [rt] "d" (input1))
249210284Sjmallett
250210284Sjmallett// Endian swap
251210284Sjmallett#define CVMX_ES64(result, input) \
252210284Sjmallett        do {\
253210284Sjmallett        CVMX_DSBH(result, input); \
254210284Sjmallett        CVMX_DSHD(result, result); \
255210284Sjmallett        } while (0)
256210284Sjmallett#define CVMX_ES32(result, input) \
257210284Sjmallett        do {\
258210284Sjmallett        CVMX_WSBH(result, input); \
259210284Sjmallett        CVMX_ROTR(result, result, 16); \
260210284Sjmallett        } while (0)
261210284Sjmallett
262210284Sjmallett
263210284Sjmallett/* extract and insert - NOTE that pos and len variables must be constants! */
264210284Sjmallett/* the P variants take len rather than lenm1 */
265210284Sjmallett/* the M1 variants take lenm1 rather than len */
266210284Sjmallett#define CVMX_EXTS(result,input,pos,lenm1) asm ("exts %[rt],%[rs]," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(lenm1) : [rt] "=d" (result) : [rs] "d" (input))
267210284Sjmallett#define CVMX_EXTSP(result,input,pos,len) CVMX_EXTS(result,input,pos,(len)-1)
268210284Sjmallett
269210284Sjmallett#define CVMX_DEXT(result,input,pos,len) asm ("dext %[rt],%[rs]," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(len) : [rt] "=d" (result) : [rs] "d" (input))
270210284Sjmallett#define CVMX_DEXTM1(result,input,pos,lenm1) CVMX_DEXT(result,input,pos,(lenm1)+1)
271210284Sjmallett
272210284Sjmallett#define CVMX_EXT(result,input,pos,len) asm ("ext %[rt],%[rs]," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(len) : [rt] "=d" (result) : [rs] "d" (input))
273210284Sjmallett#define CVMX_EXTM1(result,input,pos,lenm1) CVMX_EXT(result,input,pos,(lenm1)+1)
274210284Sjmallett
275210284Sjmallett// removed
276210284Sjmallett// #define CVMX_EXTU(result,input,pos,lenm1) asm ("extu %[rt],%[rs]," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(lenm1) : [rt] "=d" (result) : [rs] "d" (input))
277210284Sjmallett// #define CVMX_EXTUP(result,input,pos,len) CVMX_EXTU(result,input,pos,(len)-1)
278210284Sjmallett
279210284Sjmallett#define CVMX_CINS(result,input,pos,lenm1) asm ("cins %[rt],%[rs]," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(lenm1) : [rt] "=d" (result) : [rs] "d" (input))
280210284Sjmallett#define CVMX_CINSP(result,input,pos,len) CVMX_CINS(result,input,pos,(len)-1)
281210284Sjmallett
282210284Sjmallett#define CVMX_DINS(result,input,pos,len) asm ("dins %[rt],%[rs]," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(len): [rt] "=d" (result): [rs] "d" (input), "[rt]" (result))
283210284Sjmallett#define CVMX_DINSM1(result,input,pos,lenm1) CVMX_DINS(result,input,pos,(lenm1)+1)
284210284Sjmallett#define CVMX_DINSC(result,pos,len) asm ("dins %[rt],$0," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(len): [rt] "=d" (result): "[rt]" (result))
285210284Sjmallett#define CVMX_DINSCM1(result,pos,lenm1) CVMX_DINSC(result,pos,(lenm1)+1)
286210284Sjmallett
287210284Sjmallett#define CVMX_INS(result,input,pos,len) asm ("ins %[rt],%[rs]," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(len): [rt] "=d" (result): [rs] "d" (input), "[rt]" (result))
288210284Sjmallett#define CVMX_INSM1(result,input,pos,lenm1) CVMX_INS(result,input,pos,(lenm1)+1)
289210284Sjmallett#define CVMX_INSC(result,pos,len) asm ("ins %[rt],$0," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(len): [rt] "=d" (result): "[rt]" (result))
290210284Sjmallett#define CVMX_INSCM1(result,pos,lenm1) CVMX_INSC(result,pos,(lenm1)+1)
291210284Sjmallett
292210284Sjmallett// removed
293210284Sjmallett// #define CVMX_INS0(result,input,pos,lenm1) asm("ins0 %[rt],%[rs]," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(lenm1): [rt] "=d" (result): [rs] "d" (input), "[rt]" (result))
294210284Sjmallett// #define CVMX_INS0P(result,input,pos,len) CVMX_INS0(result,input,pos,(len)-1)
295210284Sjmallett// #define CVMX_INS0C(result,pos,lenm1) asm ("ins0 %[rt],$0," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(lenm1) : [rt] "=d" (result) : "[rt]" (result))
296210284Sjmallett// #define CVMX_INS0CP(result,pos,len) CVMX_INS0C(result,pos,(len)-1)
297210284Sjmallett
298210284Sjmallett#define CVMX_CLZ(result, input) asm ("clz %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
299210284Sjmallett#define CVMX_DCLZ(result, input) asm ("dclz %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
300210284Sjmallett#define CVMX_CLO(result, input) asm ("clo %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
301210284Sjmallett#define CVMX_DCLO(result, input) asm ("dclo %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
302210284Sjmallett#define CVMX_POP(result, input) asm ("pop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
303210284Sjmallett#define CVMX_DPOP(result, input) asm ("dpop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
304210284Sjmallett
305210284Sjmallett#ifdef CVMX_ABI_O32
306210284Sjmallett
307210284Sjmallett  /* rdhwr $31 is the 64 bit cmvcount register, it needs to be split
308210284Sjmallett     into one or two (depending on the width of the result) properly
309210284Sjmallett     sign extended registers.  All other registers are 32 bits wide
310210284Sjmallett     and already properly sign extended. */
311210284Sjmallett#  define CVMX_RDHWRX(result, regstr, ASM_STMT) ({			\
312210284Sjmallett  if (regstr == 31) {							\
313210284Sjmallett    if (sizeof(result) == 8) {						\
314210284Sjmallett      ASM_STMT (".set\tpush\n"						\
315210284Sjmallett		"\t.set\tmips64r2\n"					\
316210284Sjmallett		"\trdhwr\t%L0,$31\n"					\
317210284Sjmallett		"\tdsra\t%M0,%L0,32\n"					\
318210284Sjmallett		"\tsll\t%L0,%L0,0\n"					\
319210284Sjmallett		"\t.set\tpop": "=d"(result));				\
320210284Sjmallett    } else {								\
321210284Sjmallett      unsigned long _v;							\
322210284Sjmallett      ASM_STMT ("rdhwr\t%0,$31\n"					\
323210284Sjmallett		"\tsll\t%0,%0,0" : "=d"(_v));				\
324210311Sjmallett      result = (__typeof(result))_v;					\
325210284Sjmallett    }									\
326210284Sjmallett  } else {								\
327210284Sjmallett    unsigned long _v;							\
328210284Sjmallett    ASM_STMT ("rdhwr\t%0,$" CVMX_TMP_STR(regstr) : "=d"(_v));		\
329210311Sjmallett    result = (__typeof(result))_v;					\
330210284Sjmallett  }})
331210284Sjmallett
332210284Sjmallett
333215990Sjmallett
334210284Sjmallett#  define CVMX_RDHWR(result, regstr) CVMX_RDHWRX(result, regstr, asm volatile)
335210284Sjmallett#  define CVMX_RDHWRNV(result, regstr) CVMX_RDHWRX(result, regstr, asm)
336210284Sjmallett#else
337210284Sjmallett#  define CVMX_RDHWR(result, regstr) asm volatile ("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d" (result))
338210284Sjmallett#  define CVMX_RDHWRNV(result, regstr) asm ("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d" (result))
339210284Sjmallett#endif
340210284Sjmallett
341210284Sjmallett// some new cop0-like stuff
342210284Sjmallett#define CVMX_DI(result) asm volatile ("di %[rt]" : [rt] "=d" (result))
343210284Sjmallett#define CVMX_DI_NULL asm volatile ("di")
344210284Sjmallett#define CVMX_EI(result) asm volatile ("ei %[rt]" : [rt] "=d" (result))
345210284Sjmallett#define CVMX_EI_NULL asm volatile ("ei")
346210284Sjmallett#define CVMX_EHB asm volatile ("ehb")
347210284Sjmallett
348210284Sjmallett/* mul stuff */
349210284Sjmallett#define CVMX_MTM0(m) asm volatile ("mtm0 %[rs]" : : [rs] "d" (m))
350210284Sjmallett#define CVMX_MTM1(m) asm volatile ("mtm1 %[rs]" : : [rs] "d" (m))
351210284Sjmallett#define CVMX_MTM2(m) asm volatile ("mtm2 %[rs]" : : [rs] "d" (m))
352210284Sjmallett#define CVMX_MTP0(p) asm volatile ("mtp0 %[rs]" : : [rs] "d" (p))
353210284Sjmallett#define CVMX_MTP1(p) asm volatile ("mtp1 %[rs]" : : [rs] "d" (p))
354210284Sjmallett#define CVMX_MTP2(p) asm volatile ("mtp2 %[rs]" : : [rs] "d" (p))
355210284Sjmallett#define CVMX_VMULU(dest,mpcand,accum) asm volatile ("vmulu %[rd],%[rs],%[rt]" : [rd] "=d" (dest) : [rs] "d" (mpcand), [rt] "d" (accum))
356210284Sjmallett#define CVMX_VMM0(dest,mpcand,accum) asm volatile ("vmm0 %[rd],%[rs],%[rt]" : [rd] "=d" (dest) : [rs] "d" (mpcand), [rt] "d" (accum))
357210284Sjmallett#define CVMX_V3MULU(dest,mpcand,accum) asm volatile ("v3mulu %[rd],%[rs],%[rt]" : [rd] "=d" (dest) : [rs] "d" (mpcand), [rt] "d" (accum))
358210284Sjmallett
359210284Sjmallett/* branch stuff */
360210284Sjmallett// these are hard to make work because the compiler does not realize that the
361210284Sjmallett// instruction is a branch so may optimize away the label
362210284Sjmallett// the labels to these next two macros must not include a ":" at the end
363210284Sjmallett#define CVMX_BBIT1(var, pos, label) asm volatile ("bbit1 %[rs]," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(label) : : [rs] "d" (var))
364210284Sjmallett#define CVMX_BBIT0(var, pos, label) asm volatile ("bbit0 %[rs]," CVMX_TMP_STR(pos) "," CVMX_TMP_STR(label) : : [rs] "d" (var))
365210284Sjmallett// the label to this macro must include a ":" at the end
366210284Sjmallett#define CVMX_ASM_LABEL(label) label \
367210284Sjmallett                             asm volatile (CVMX_TMP_STR(label) : : )
368210284Sjmallett
369210284Sjmallett//
370210284Sjmallett// Low-latency memory stuff
371210284Sjmallett//
372210284Sjmallett// set can be 0-1
373210284Sjmallett#define CVMX_MT_LLM_READ_ADDR(set,val)    asm volatile ("dmtc2 %[rt],0x0400+(8*(" CVMX_TMP_STR(set) "))" : : [rt] "d" (val))
374210284Sjmallett#define CVMX_MT_LLM_WRITE_ADDR_INTERNAL(set,val)   asm volatile ("dmtc2 %[rt],0x0401+(8*(" CVMX_TMP_STR(set) "))" : : [rt] "d" (val))
375210284Sjmallett#define CVMX_MT_LLM_READ64_ADDR(set,val)  asm volatile ("dmtc2 %[rt],0x0404+(8*(" CVMX_TMP_STR(set) "))" : : [rt] "d" (val))
376210284Sjmallett#define CVMX_MT_LLM_WRITE64_ADDR_INTERNAL(set,val) asm volatile ("dmtc2 %[rt],0x0405+(8*(" CVMX_TMP_STR(set) "))" : : [rt] "d" (val))
377210284Sjmallett#define CVMX_MT_LLM_DATA(set,val)         asm volatile ("dmtc2 %[rt],0x0402+(8*(" CVMX_TMP_STR(set) "))" : : [rt] "d" (val))
378210284Sjmallett#define CVMX_MF_LLM_DATA(set,val)         asm volatile ("dmfc2 %[rt],0x0402+(8*(" CVMX_TMP_STR(set) "))" : [rt] "=d" (val) : )
379210284Sjmallett
380210284Sjmallett
381210284Sjmallett// load linked, store conditional
382210284Sjmallett#define CVMX_LL(dest, address, offset) asm volatile ("ll %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : [rt] "=d" (dest) : [rbase] "d" (address) )
383210284Sjmallett#define CVMX_LLD(dest, address, offset) asm volatile ("lld %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : [rt] "=d" (dest) : [rbase] "d" (address) )
384210284Sjmallett#define CVMX_SC(srcdest, address, offset) asm volatile ("sc %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : [rt] "=d" (srcdest) : [rbase] "d" (address), "[rt]" (srcdest) )
385210284Sjmallett#define CVMX_SCD(srcdest, address, offset) asm volatile ("scd %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : [rt] "=d" (srcdest) : [rbase] "d" (address), "[rt]" (srcdest) )
386210284Sjmallett
387210284Sjmallett// load/store word left/right
388210284Sjmallett#define CVMX_LWR(srcdest, address, offset) asm volatile ("lwr %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : [rt] "=d" (srcdest) : [rbase] "d" (address), "[rt]" (srcdest) )
389210284Sjmallett#define CVMX_LWL(srcdest, address, offset) asm volatile ("lwl %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : [rt] "=d" (srcdest) : [rbase] "d" (address), "[rt]" (srcdest) )
390210284Sjmallett#define CVMX_LDR(srcdest, address, offset) asm volatile ("ldr %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : [rt] "=d" (srcdest) : [rbase] "d" (address), "[rt]" (srcdest) )
391210284Sjmallett#define CVMX_LDL(srcdest, address, offset) asm volatile ("ldl %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : [rt] "=d" (srcdest) : [rbase] "d" (address), "[rt]" (srcdest) )
392210284Sjmallett
393210284Sjmallett#define CVMX_SWR(src, address, offset) asm volatile ("swr %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : : [rbase] "d" (address), [rt] "d" (src) )
394210284Sjmallett#define CVMX_SWL(src, address, offset) asm volatile ("swl %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : : [rbase] "d" (address), [rt] "d" (src) )
395210284Sjmallett#define CVMX_SDR(src, address, offset) asm volatile ("sdr %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : : [rbase] "d" (address), [rt] "d" (src) )
396210284Sjmallett#define CVMX_SDL(src, address, offset) asm volatile ("sdl %[rt], " CVMX_TMP_STR(offset) "(%[rbase])" : : [rbase] "d" (address), [rt] "d" (src) )
397210284Sjmallett
398210284Sjmallett
399210284Sjmallett
400210284Sjmallett//
401210284Sjmallett// Useful crypto ASM's
402210284Sjmallett//
403210284Sjmallett
404210284Sjmallett// CRC
405210284Sjmallett
406210284Sjmallett#define CVMX_MT_CRC_POLYNOMIAL(val)         asm volatile ("dmtc2 %[rt],0x4200" : : [rt] "d" (val))
407210284Sjmallett#define CVMX_MT_CRC_IV(val)                 asm volatile ("dmtc2 %[rt],0x0201" : : [rt] "d" (val))
408210284Sjmallett#define CVMX_MT_CRC_LEN(val)                asm volatile ("dmtc2 %[rt],0x1202" : : [rt] "d" (val))
409210284Sjmallett#define CVMX_MT_CRC_BYTE(val)               asm volatile ("dmtc2 %[rt],0x0204" : : [rt] "d" (val))
410210284Sjmallett#define CVMX_MT_CRC_HALF(val)               asm volatile ("dmtc2 %[rt],0x0205" : : [rt] "d" (val))
411210284Sjmallett#define CVMX_MT_CRC_WORD(val)               asm volatile ("dmtc2 %[rt],0x0206" : : [rt] "d" (val))
412210284Sjmallett#define CVMX_MT_CRC_DWORD(val)              asm volatile ("dmtc2 %[rt],0x1207" : : [rt] "d" (val))
413210284Sjmallett#define CVMX_MT_CRC_VAR(val)                asm volatile ("dmtc2 %[rt],0x1208" : : [rt] "d" (val))
414210284Sjmallett#define CVMX_MT_CRC_POLYNOMIAL_REFLECT(val) asm volatile ("dmtc2 %[rt],0x4210" : : [rt] "d" (val))
415210284Sjmallett#define CVMX_MT_CRC_IV_REFLECT(val)         asm volatile ("dmtc2 %[rt],0x0211" : : [rt] "d" (val))
416210284Sjmallett#define CVMX_MT_CRC_BYTE_REFLECT(val)       asm volatile ("dmtc2 %[rt],0x0214" : : [rt] "d" (val))
417210284Sjmallett#define CVMX_MT_CRC_HALF_REFLECT(val)       asm volatile ("dmtc2 %[rt],0x0215" : : [rt] "d" (val))
418210284Sjmallett#define CVMX_MT_CRC_WORD_REFLECT(val)       asm volatile ("dmtc2 %[rt],0x0216" : : [rt] "d" (val))
419210284Sjmallett#define CVMX_MT_CRC_DWORD_REFLECT(val)      asm volatile ("dmtc2 %[rt],0x1217" : : [rt] "d" (val))
420210284Sjmallett#define CVMX_MT_CRC_VAR_REFLECT(val)        asm volatile ("dmtc2 %[rt],0x1218" : : [rt] "d" (val))
421210284Sjmallett
422210284Sjmallett#define CVMX_MF_CRC_POLYNOMIAL(val)         asm volatile ("dmfc2 %[rt],0x0200" : [rt] "=d" (val) : )
423210284Sjmallett#define CVMX_MF_CRC_IV(val)                 asm volatile ("dmfc2 %[rt],0x0201" : [rt] "=d" (val) : )
424210284Sjmallett#define CVMX_MF_CRC_IV_REFLECT(val)         asm volatile ("dmfc2 %[rt],0x0203" : [rt] "=d" (val) : )
425210284Sjmallett#define CVMX_MF_CRC_LEN(val)                asm volatile ("dmfc2 %[rt],0x0202" : [rt] "=d" (val) : )
426210284Sjmallett
427210284Sjmallett// MD5 and SHA-1
428210284Sjmallett
429210284Sjmallett// pos can be 0-6
430210284Sjmallett#define CVMX_MT_HSH_DAT(val,pos)    asm volatile ("dmtc2 %[rt],0x0040+" CVMX_TMP_STR(pos) :                 : [rt] "d" (val))
431210284Sjmallett#define CVMX_MT_HSH_DATZ(pos)       asm volatile ("dmtc2    $0,0x0040+" CVMX_TMP_STR(pos) :                 :               )
432210284Sjmallett// pos can be 0-14
433210284Sjmallett#define CVMX_MT_HSH_DATW(val,pos)   asm volatile ("dmtc2 %[rt],0x0240+" CVMX_TMP_STR(pos) :                 : [rt] "d" (val))
434210284Sjmallett#define CVMX_MT_HSH_DATWZ(pos)      asm volatile ("dmtc2    $0,0x0240+" CVMX_TMP_STR(pos) :                 :               )
435210284Sjmallett#define CVMX_MT_HSH_STARTMD5(val)   asm volatile ("dmtc2 %[rt],0x4047"                   :                 : [rt] "d" (val))
436210284Sjmallett#define CVMX_MT_HSH_STARTSHA(val)   asm volatile ("dmtc2 %[rt],0x4057"                   :                 : [rt] "d" (val))
437210284Sjmallett#define CVMX_MT_HSH_STARTSHA256(val)   asm volatile ("dmtc2 %[rt],0x404f"                   :                 : [rt] "d" (val))
438210284Sjmallett#define CVMX_MT_HSH_STARTSHA512(val)   asm volatile ("dmtc2 %[rt],0x424f"                   :                 : [rt] "d" (val))
439210284Sjmallett// pos can be 0-3
440210284Sjmallett#define CVMX_MT_HSH_IV(val,pos)     asm volatile ("dmtc2 %[rt],0x0048+" CVMX_TMP_STR(pos) :                 : [rt] "d" (val))
441210284Sjmallett// pos can be 0-7
442210284Sjmallett#define CVMX_MT_HSH_IVW(val,pos)     asm volatile ("dmtc2 %[rt],0x0250+" CVMX_TMP_STR(pos) :                 : [rt] "d" (val))
443210284Sjmallett
444210284Sjmallett// pos can be 0-6
445210284Sjmallett#define CVMX_MF_HSH_DAT(val,pos)    asm volatile ("dmfc2 %[rt],0x0040+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
446210284Sjmallett// pos can be 0-14
447210284Sjmallett#define CVMX_MF_HSH_DATW(val,pos)   asm volatile ("dmfc2 %[rt],0x0240+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
448210284Sjmallett// pos can be 0-3
449210284Sjmallett#define CVMX_MF_HSH_IV(val,pos)     asm volatile ("dmfc2 %[rt],0x0048+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
450210284Sjmallett// pos can be 0-7
451210284Sjmallett#define CVMX_MF_HSH_IVW(val,pos)     asm volatile ("dmfc2 %[rt],0x0250+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
452210284Sjmallett
453210284Sjmallett// 3DES
454210284Sjmallett
455210284Sjmallett// pos can be 0-2
456210284Sjmallett#define CVMX_MT_3DES_KEY(val,pos)   asm volatile ("dmtc2 %[rt],0x0080+" CVMX_TMP_STR(pos) :                 : [rt] "d" (val))
457210284Sjmallett#define CVMX_MT_3DES_IV(val)        asm volatile ("dmtc2 %[rt],0x0084"                   :                 : [rt] "d" (val))
458210284Sjmallett#define CVMX_MT_3DES_ENC_CBC(val)   asm volatile ("dmtc2 %[rt],0x4088"                   :                 : [rt] "d" (val))
459210284Sjmallett#define CVMX_MT_3DES_ENC(val)       asm volatile ("dmtc2 %[rt],0x408a"                   :                 : [rt] "d" (val))
460210284Sjmallett#define CVMX_MT_3DES_DEC_CBC(val)   asm volatile ("dmtc2 %[rt],0x408c"                   :                 : [rt] "d" (val))
461210284Sjmallett#define CVMX_MT_3DES_DEC(val)       asm volatile ("dmtc2 %[rt],0x408e"                   :                 : [rt] "d" (val))
462210284Sjmallett#define CVMX_MT_3DES_RESULT(val)    asm volatile ("dmtc2 %[rt],0x0098"                   :                 : [rt] "d" (val))
463210284Sjmallett
464210284Sjmallett// pos can be 0-2
465210284Sjmallett#define CVMX_MF_3DES_KEY(val,pos)   asm volatile ("dmfc2 %[rt],0x0080+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
466210284Sjmallett#define CVMX_MF_3DES_IV(val)        asm volatile ("dmfc2 %[rt],0x0084"                   : [rt] "=d" (val) :               )
467210284Sjmallett#define CVMX_MF_3DES_RESULT(val)    asm volatile ("dmfc2 %[rt],0x0088"                   : [rt] "=d" (val) :               )
468210284Sjmallett
469210284Sjmallett// KASUMI
470210284Sjmallett
471210284Sjmallett// pos can be 0-1
472210284Sjmallett#define CVMX_MT_KAS_KEY(val,pos)    CVMX_MT_3DES_KEY(val,pos)
473210284Sjmallett#define CVMX_MT_KAS_ENC_CBC(val)    asm volatile ("dmtc2 %[rt],0x4089"                   :                 : [rt] "d" (val))
474210284Sjmallett#define CVMX_MT_KAS_ENC(val)        asm volatile ("dmtc2 %[rt],0x408b"                   :                 : [rt] "d" (val))
475210284Sjmallett#define CVMX_MT_KAS_RESULT(val)     CVMX_MT_3DES_RESULT(val)
476210284Sjmallett
477210284Sjmallett// pos can be 0-1
478210284Sjmallett#define CVMX_MF_KAS_KEY(val,pos)    CVMX_MF_3DES_KEY(val,pos)
479210284Sjmallett#define CVMX_MF_KAS_RESULT(val)     CVMX_MF_3DES_RESULT(val)
480210284Sjmallett
481210284Sjmallett// AES
482210284Sjmallett
483210284Sjmallett#define CVMX_MT_AES_ENC_CBC0(val)   asm volatile ("dmtc2 %[rt],0x0108"                   :                 : [rt] "d" (val))
484210284Sjmallett#define CVMX_MT_AES_ENC_CBC1(val)   asm volatile ("dmtc2 %[rt],0x3109"                   :                 : [rt] "d" (val))
485210284Sjmallett#define CVMX_MT_AES_ENC0(val)       asm volatile ("dmtc2 %[rt],0x010a"                   :                 : [rt] "d" (val))
486210284Sjmallett#define CVMX_MT_AES_ENC1(val)       asm volatile ("dmtc2 %[rt],0x310b"                   :                 : [rt] "d" (val))
487210284Sjmallett#define CVMX_MT_AES_DEC_CBC0(val)   asm volatile ("dmtc2 %[rt],0x010c"                   :                 : [rt] "d" (val))
488210284Sjmallett#define CVMX_MT_AES_DEC_CBC1(val)   asm volatile ("dmtc2 %[rt],0x310d"                   :                 : [rt] "d" (val))
489210284Sjmallett#define CVMX_MT_AES_DEC0(val)       asm volatile ("dmtc2 %[rt],0x010e"                   :                 : [rt] "d" (val))
490210284Sjmallett#define CVMX_MT_AES_DEC1(val)       asm volatile ("dmtc2 %[rt],0x310f"                   :                 : [rt] "d" (val))
491210284Sjmallett// pos can be 0-3
492210284Sjmallett#define CVMX_MT_AES_KEY(val,pos)    asm volatile ("dmtc2 %[rt],0x0104+" CVMX_TMP_STR(pos) :                 : [rt] "d" (val))
493210284Sjmallett// pos can be 0-1
494210284Sjmallett#define CVMX_MT_AES_IV(val,pos)     asm volatile ("dmtc2 %[rt],0x0102+" CVMX_TMP_STR(pos) :                 : [rt] "d" (val))
495210284Sjmallett#define CVMX_MT_AES_KEYLENGTH(val)  asm volatile ("dmtc2 %[rt],0x0110"                   :                 : [rt] "d" (val)) // write the keylen
496210284Sjmallett// pos can be 0-1
497210284Sjmallett#define CVMX_MT_AES_RESULT(val,pos) asm volatile ("dmtc2 %[rt],0x0100+" CVMX_TMP_STR(pos) :                 : [rt] "d" (val))
498210284Sjmallett
499210284Sjmallett// pos can be 0-1
500210284Sjmallett#define CVMX_MF_AES_RESULT(val,pos) asm volatile ("dmfc2 %[rt],0x0100+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
501210284Sjmallett// pos can be 0-1
502210284Sjmallett#define CVMX_MF_AES_IV(val,pos)     asm volatile ("dmfc2 %[rt],0x0102+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
503210284Sjmallett// pos can be 0-3
504210284Sjmallett#define CVMX_MF_AES_KEY(val,pos)    asm volatile ("dmfc2 %[rt],0x0104+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
505210284Sjmallett#define CVMX_MF_AES_KEYLENGTH(val)  asm volatile ("dmfc2 %[rt],0x0110"                   : [rt] "=d" (val) :               ) // read the keylen
506210284Sjmallett#define CVMX_MF_AES_DAT0(val)       asm volatile ("dmfc2 %[rt],0x0111"                   : [rt] "=d" (val) :               ) // first piece of input data
507210284Sjmallett
508215990Sjmallett// GFM
509210284Sjmallett
510215990Sjmallett// pos can be 0-1
511215990Sjmallett#define CVMX_MF_GFM_MUL(val,pos)             asm volatile ("dmfc2 %[rt],0x0258+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
512215990Sjmallett#define CVMX_MF_GFM_POLY(val)                asm volatile ("dmfc2 %[rt],0x025e"                    : [rt] "=d" (val) :               )
513215990Sjmallett// pos can be 0-1
514215990Sjmallett#define CVMX_MF_GFM_RESINP(val,pos)          asm volatile ("dmfc2 %[rt],0x025a+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
515215990Sjmallett// pos can be 0-1
516215990Sjmallett#define CVMX_MF_GFM_RESINP_REFLECT(val,pos)  asm volatile ("dmfc2 %[rt],0x005a+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
517210284Sjmallett
518215990Sjmallett// pos can be 0-1
519215990Sjmallett#define CVMX_MT_GFM_MUL(val,pos)             asm volatile ("dmtc2 %[rt],0x0258+" CVMX_TMP_STR(pos) :                 : [rt] "d" (val))
520215990Sjmallett#define CVMX_MT_GFM_POLY(val)                asm volatile ("dmtc2 %[rt],0x025e"                    :                 : [rt] "d" (val))
521215990Sjmallett// pos can be 0-1
522215990Sjmallett#define CVMX_MT_GFM_RESINP(val,pos)          asm volatile ("dmtc2 %[rt],0x025a+" CVMX_TMP_STR(pos) :                 : [rt] "d" (val))
523215990Sjmallett#define CVMX_MT_GFM_XOR0(val)                asm volatile ("dmtc2 %[rt],0x025c"                    :                 : [rt] "d" (val))
524215990Sjmallett#define CVMX_MT_GFM_XORMUL1(val)             asm volatile ("dmtc2 %[rt],0x425d"                    :                 : [rt] "d" (val))
525215990Sjmallett// pos can be 0-1
526215990Sjmallett#define CVMX_MT_GFM_MUL_REFLECT(val,pos)     asm volatile ("dmtc2 %[rt],0x0058+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
527215990Sjmallett#define CVMX_MT_GFM_XOR0_REFLECT(val)        asm volatile ("dmtc2 %[rt],0x005c"                    :                 : [rt] "d" (val))
528215990Sjmallett#define CVMX_MT_GFM_XORMUL1_REFLECT(val)     asm volatile ("dmtc2 %[rt],0x405d"                    :                 : [rt] "d" (val))
529215990Sjmallett
530215990Sjmallett// SNOW 3G
531215990Sjmallett
532215990Sjmallett// pos can be 0-7
533215990Sjmallett#define CVMX_MF_SNOW3G_LFSR(val,pos)    asm volatile ("dmfc2 %[rt],0x0240+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
534215990Sjmallett// pos can be 0-2
535215990Sjmallett#define CVMX_MF_SNOW3G_FSM(val,pos)     asm volatile ("dmfc2 %[rt],0x0251+" CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
536215990Sjmallett#define CVMX_MF_SNOW3G_RESULT(val)      asm volatile ("dmfc2 %[rt],0x0250"                    : [rt] "=d" (val) :               )
537215990Sjmallett
538215990Sjmallett// pos can be 0-7
539215990Sjmallett#define CVMX_MT_SNOW3G_LFSR(val,pos)    asm volatile ("dmtc2 %[rt],0x0240+" CVMX_TMP_STR(pos) : : [rt] "d" (val))
540215990Sjmallett// pos can be 0-2
541215990Sjmallett#define CVMX_MT_SNOW3G_FSM(val,pos)     asm volatile ("dmtc2 %[rt],0x0251+" CVMX_TMP_STR(pos) : : [rt] "d" (val))
542215990Sjmallett#define CVMX_MT_SNOW3G_RESULT(val)      asm volatile ("dmtc2 %[rt],0x0250"                    : : [rt] "d" (val))
543215990Sjmallett#define CVMX_MT_SNOW3G_START(val)       asm volatile ("dmtc2 %[rt],0x404d"                    : : [rt] "d" (val))
544215990Sjmallett#define CVMX_MT_SNOW3G_MORE(val)        asm volatile ("dmtc2 %[rt],0x404e"                    : : [rt] "d" (val))
545215990Sjmallett
546215990Sjmallett// SMS4
547215990Sjmallett
548215990Sjmallett// pos can be 0-1
549215990Sjmallett#define CVMX_MF_SMS4_IV(val,pos)	asm volatile ("dmfc2 %[rt],0x0102+"CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
550215990Sjmallett// pos can be 0-1
551215990Sjmallett#define CVMX_MF_SMS4_KEY(val,pos)	asm volatile ("dmfc2 %[rt],0x0104+"CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
552215990Sjmallett// pos can be 0-1
553215990Sjmallett#define CVMX_MF_SMS4_RESINP(val,pos)	asm volatile ("dmfc2 %[rt],0x0100+"CVMX_TMP_STR(pos) : [rt] "=d" (val) :               )
554215990Sjmallett#define CVMX_MT_SMS4_DEC_CBC0(val)	asm volatile ("dmtc2 %[rt],0x010c"                   : : [rt] "d" (val))
555215990Sjmallett#define CVMX_MT_SMS4_DEC_CBC1(val)	asm volatile ("dmtc2 %[rt],0x311d"      : : [rt] "d" (val))
556215990Sjmallett#define CVMX_MT_SMS4_DEC0(val)		asm volatile ("dmtc2 %[rt],0x010e"      : : [rt] "d" (val))
557215990Sjmallett#define CVMX_MT_SMS4_DEC1(val)		asm volatile ("dmtc2 %[rt],0x311f"      : : [rt] "d" (val))
558215990Sjmallett#define CVMX_MT_SMS4_ENC_CBC0(val)	asm volatile ("dmtc2 %[rt],0x0108"      : : [rt] "d" (val))
559215990Sjmallett#define CVMX_MT_SMS4_ENC_CBC1(val)	asm volatile ("dmtc2 %[rt],0x3119"      : : [rt] "d" (val))
560215990Sjmallett#define CVMX_MT_SMS4_ENC0(val)		asm volatile ("dmtc2 %[rt],0x010a"      : : [rt] "d" (val))
561215990Sjmallett#define CVMX_MT_SMS4_ENC1(val)		asm volatile ("dmtc2 %[rt],0x311b"      : : [rt] "d" (val))
562215990Sjmallett// pos can be 0-1
563215990Sjmallett#define CVMX_MT_SMS4_IV(val,pos)	asm volatile ("dmtc2 %[rt],0x0102+"CVMX_TMP_STR(pos) : : [rt] "d" (val))
564215990Sjmallett// pos can be 0-1
565215990Sjmallett#define CVMX_MT_SMS4_KEY(val,pos)	asm volatile ("dmtc2 %[rt],0x0104+"CVMX_TMP_STR(pos) : : [rt] "d" (val))
566215990Sjmallett// pos can be 0-1
567215990Sjmallett#define CVMX_MT_SMS4_RESINP(val,pos)	asm volatile ("dmtc2 %[rt],0x0100+"CVMX_TMP_STR(pos) : : [rt] "d" (val))
568215990Sjmallett
569210284Sjmallett/* check_ordering stuff */
570210284Sjmallett#if 0
571210284Sjmallett#define CVMX_MF_CHORD(dest)         asm volatile ("dmfc2 %[rt],0x400" : [rt] "=d" (dest) : )
572210284Sjmallett#else
573210284Sjmallett#define CVMX_MF_CHORD(dest)         CVMX_RDHWR(dest, 30)
574210284Sjmallett#endif
575210284Sjmallett
576210284Sjmallett#if 0
577210284Sjmallett#define CVMX_MF_CYCLE(dest)         asm volatile ("dmfc0 %[rt],$9,6" : [rt] "=d" (dest) : ) // Use (64-bit) CvmCount register rather than Count
578210284Sjmallett#else
579210284Sjmallett#define CVMX_MF_CYCLE(dest)         CVMX_RDHWR(dest, 31) /* reads the current (64-bit) CvmCount value */
580210284Sjmallett#endif
581210284Sjmallett
582210284Sjmallett#define CVMX_MT_CYCLE(src)         asm volatile ("dmtc0 %[rt],$9,6" :: [rt] "d" (src))
583210284Sjmallett
584215990Sjmallett#define VASTR(...) #__VA_ARGS__
585210284Sjmallett
586215990Sjmallett#define CVMX_MF_COP0(val, cop0)           asm volatile ("dmfc0 %[rt]," VASTR(cop0) : [rt] "=d" (val));
587215990Sjmallett#define CVMX_MT_COP0(val, cop0)           asm volatile ("dmtc0 %[rt]," VASTR(cop0) : : [rt] "d" (val));
588215990Sjmallett
589215990Sjmallett#define CVMX_MF_CACHE_ERR(val)            CVMX_MF_COP0(val, COP0_CACHEERRI)
590215990Sjmallett#define CVMX_MF_DCACHE_ERR(val)           CVMX_MF_COP0(val, COP0_CACHEERRD)
591215990Sjmallett#define CVMX_MF_CVM_MEM_CTL(val)          CVMX_MF_COP0(val, COP0_CVMMEMCTL)
592215990Sjmallett#define CVMX_MF_CVM_CTL(val)              CVMX_MF_COP0(val, COP0_CVMCTL)
593215990Sjmallett#define CVMX_MT_CACHE_ERR(val)            CVMX_MT_COP0(val, COP0_CACHEERRI)
594215990Sjmallett#define CVMX_MT_DCACHE_ERR(val)           CVMX_MT_COP0(val, COP0_CACHEERRD)
595215990Sjmallett#define CVMX_MT_CVM_MEM_CTL(val)          CVMX_MT_COP0(val, COP0_CVMMEMCTL)
596215990Sjmallett#define CVMX_MT_CVM_CTL(val)              CVMX_MT_COP0(val, COP0_CVMCTL)
597215990Sjmallett
598210284Sjmallett/* Macros for TLB */
599210284Sjmallett#define CVMX_TLBWI                       asm volatile ("tlbwi" : : )
600210284Sjmallett#define CVMX_TLBWR                       asm volatile ("tlbwr" : : )
601210284Sjmallett#define CVMX_TLBR                        asm volatile ("tlbr" : : )
602215990Sjmallett#define CVMX_TLBP                        asm volatile ("tlbp" : : )
603210284Sjmallett#define CVMX_MT_ENTRY_HIGH(val)          asm volatile ("dmtc0 %[rt],$10,0" : : [rt] "d" (val))
604210284Sjmallett#define CVMX_MT_ENTRY_LO_0(val)          asm volatile ("dmtc0 %[rt],$2,0" : : [rt] "d" (val))
605210284Sjmallett#define CVMX_MT_ENTRY_LO_1(val)          asm volatile ("dmtc0 %[rt],$3,0" : : [rt] "d" (val))
606210284Sjmallett#define CVMX_MT_PAGEMASK(val)            asm volatile ("mtc0 %[rt],$5,0" : : [rt] "d" (val))
607210284Sjmallett#define CVMX_MT_PAGEGRAIN(val)           asm volatile ("mtc0 %[rt],$5,1" : : [rt] "d" (val))
608210284Sjmallett#define CVMX_MT_TLB_INDEX(val)           asm volatile ("mtc0 %[rt],$0,0" : : [rt] "d" (val))
609210284Sjmallett#define CVMX_MT_TLB_CONTEXT(val)         asm volatile ("dmtc0 %[rt],$4,0" : : [rt] "d" (val))
610210284Sjmallett#define CVMX_MT_TLB_WIRED(val)           asm volatile ("mtc0 %[rt],$6,0" : : [rt] "d" (val))
611210284Sjmallett#define CVMX_MT_TLB_RANDOM(val)          asm volatile ("mtc0 %[rt],$1,0" : : [rt] "d" (val))
612210284Sjmallett#define CVMX_MF_ENTRY_LO_0(val)          asm volatile ("dmfc0 %[rt],$2,0" :  [rt] "=d" (val):)
613210284Sjmallett#define CVMX_MF_ENTRY_LO_1(val)          asm volatile ("dmfc0 %[rt],$3,0" :  [rt] "=d" (val):)
614210284Sjmallett#define CVMX_MF_ENTRY_HIGH(val)          asm volatile ("dmfc0 %[rt],$10,0" :  [rt] "=d" (val):)
615210284Sjmallett#define CVMX_MF_PAGEMASK(val)            asm volatile ("mfc0 %[rt],$5,0" :  [rt] "=d" (val):)
616210284Sjmallett#define CVMX_MF_PAGEGRAIN(val)           asm volatile ("mfc0 %[rt],$5,1" :  [rt] "=d" (val):)
617210284Sjmallett#define CVMX_MF_TLB_WIRED(val)           asm volatile ("mfc0 %[rt],$6,0" :  [rt] "=d" (val):)
618215990Sjmallett#define CVMX_MF_TLB_INDEX(val)           asm volatile ("mfc0 %[rt],$0,0" :  [rt] "=d" (val):)
619210284Sjmallett#define CVMX_MF_TLB_RANDOM(val)          asm volatile ("mfc0 %[rt],$1,0" :  [rt] "=d" (val):)
620210284Sjmallett#define TLB_DIRTY   (0x1ULL<<2)
621210284Sjmallett#define TLB_VALID   (0x1ULL<<1)
622210284Sjmallett#define TLB_GLOBAL  (0x1ULL<<0)
623210284Sjmallett
624210284Sjmallett
625215990Sjmallett#if !defined(__FreeBSD__) || !defined(_KERNEL)
626215990Sjmallett/* Macros to PUSH and POP Octeon2 ISA. */
627215990Sjmallett#define CVMX_PUSH_OCTEON2    asm volatile (".set push\n.set arch=octeon2")
628215990Sjmallett#define CVMX_POP_OCTEON2     asm volatile (".set pop")
629215990Sjmallett#endif
630210284Sjmallett
631210284Sjmallett/* assembler macros to guarantee byte loads/stores are used */
632210284Sjmallett/* for an unaligned 16-bit access (these use AT register) */
633210284Sjmallett/* we need the hidden argument (__a) so that GCC gets the dependencies right */
634210284Sjmallett#define CVMX_LOADUNA_INT16(result, address, offset) \
635210284Sjmallett	{ char *__a = (char *)(address); \
636210284Sjmallett	  asm ("ulh %[rdest], " CVMX_TMP_STR(offset) "(%[rbase])" : [rdest] "=d" (result) : [rbase] "d" (__a), "m"(__a[offset]), "m"(__a[offset + 1])); }
637210284Sjmallett#define CVMX_LOADUNA_UINT16(result, address, offset) \
638210284Sjmallett	{ char *__a = (char *)(address); \
639210284Sjmallett	  asm ("ulhu %[rdest], " CVMX_TMP_STR(offset) "(%[rbase])" : [rdest] "=d" (result) : [rbase] "d" (__a), "m"(__a[offset + 0]), "m"(__a[offset + 1])); }
640210284Sjmallett#define CVMX_STOREUNA_INT16(data, address, offset) \
641210284Sjmallett	{ char *__a = (char *)(address); \
642210284Sjmallett	  asm ("ush %[rsrc], " CVMX_TMP_STR(offset) "(%[rbase])" : "=m"(__a[offset + 0]), "=m"(__a[offset + 1]): [rsrc] "d" (data), [rbase] "d" (__a)); }
643210284Sjmallett
644210284Sjmallett#define CVMX_LOADUNA_INT32(result, address, offset) \
645210284Sjmallett	{ char *__a = (char *)(address); \
646210284Sjmallett	  asm ("ulw %[rdest], " CVMX_TMP_STR(offset) "(%[rbase])" : [rdest] "=d" (result) : \
647210284Sjmallett	       [rbase] "d" (__a), "m"(__a[offset + 0]), "m"(__a[offset + 1]), "m"(__a[offset + 2]), "m"(__a[offset + 3])); }
648210284Sjmallett#define CVMX_STOREUNA_INT32(data, address, offset) \
649210284Sjmallett	{ char *__a = (char *)(address); \
650210284Sjmallett	  asm ("usw %[rsrc], " CVMX_TMP_STR(offset) "(%[rbase])" : \
651210284Sjmallett	       "=m"(__a[offset + 0]), "=m"(__a[offset + 1]), "=m"(__a[offset + 2]), "=m"(__a[offset + 3]) : \
652210284Sjmallett	       [rsrc] "d" (data), [rbase] "d" (__a)); }
653210284Sjmallett
654210284Sjmallett#define CVMX_LOADUNA_INT64(result, address, offset) \
655210284Sjmallett	{ char *__a = (char *)(address); \
656210284Sjmallett	  asm ("uld %[rdest], " CVMX_TMP_STR(offset) "(%[rbase])" : [rdest] "=d" (result) : \
657210284Sjmallett	       [rbase] "d" (__a), "m"(__a[offset + 0]), "m"(__a[offset + 1]), "m"(__a[offset + 2]), "m"(__a[offset + 3]), \
658210284Sjmallett	       "m"(__a[offset + 4]), "m"(__a[offset + 5]), "m"(__a[offset + 6]), "m"(__a[offset + 7])); }
659210284Sjmallett#define CVMX_STOREUNA_INT64(data, address, offset) \
660210284Sjmallett	{ char *__a = (char *)(address); \
661210284Sjmallett	  asm ("usd %[rsrc], " CVMX_TMP_STR(offset) "(%[rbase])" : \
662210284Sjmallett	       "=m"(__a[offset + 0]), "=m"(__a[offset + 1]), "=m"(__a[offset + 2]), "=m"(__a[offset + 3]), \
663210284Sjmallett	       "=m"(__a[offset + 4]), "=m"(__a[offset + 5]), "=m"(__a[offset + 6]), "=m"(__a[offset + 7]) : \
664210284Sjmallett	       [rsrc] "d" (data), [rbase] "d" (__a)); }
665210284Sjmallett
666210284Sjmallett#ifdef	__cplusplus
667210284Sjmallett}
668210284Sjmallett#endif
669210284Sjmallett
670215990Sjmallett#endif	/* __ASSEMBLER__ */
671215990Sjmallett
672210284Sjmallett#endif /* __CVMX_ASM_H__ */
673