xref: /dpdk/drivers/common/cnxk/roc_io.h (revision 93998f3c5f22747e4f2c5e8714fa5cbe6c9d1574)
1014a9e22SJerin Jacob /* SPDX-License-Identifier: BSD-3-Clause
2014a9e22SJerin Jacob  * Copyright(C) 2021 Marvell.
3014a9e22SJerin Jacob  */
4014a9e22SJerin Jacob 
5014a9e22SJerin Jacob #ifndef _ROC_IO_H_
6014a9e22SJerin Jacob #define _ROC_IO_H_
7014a9e22SJerin Jacob 
83d171da6SBruce Richardson #include "roc_platform.h" /* for __plt_always_inline macro */
93d171da6SBruce Richardson 
1070b6be62SNithin Dabilpuram #ifndef ROC_LMT_BASE_ID_GET
11014a9e22SJerin Jacob #define ROC_LMT_BASE_ID_GET(lmt_addr, lmt_id)                                  \
12014a9e22SJerin Jacob 	do {                                                                   \
13014a9e22SJerin Jacob 		/* 32 Lines per core */                                        \
14014a9e22SJerin Jacob 		lmt_id = plt_lcore_id() << ROC_LMT_LINES_PER_CORE_LOG2;        \
15014a9e22SJerin Jacob 		/* Each line is of 128B */                                     \
16014a9e22SJerin Jacob 		(lmt_addr) += ((uint64_t)lmt_id << ROC_LMT_LINE_SIZE_LOG2);    \
17014a9e22SJerin Jacob 	} while (0)
1870b6be62SNithin Dabilpuram #endif
19014a9e22SJerin Jacob 
2070b6be62SNithin Dabilpuram /* Define it if not defined in roc_platform.h */
2170b6be62SNithin Dabilpuram #ifndef ROC_LMT_CPT_BASE_ID_GET
22ee48f711SNithin Dabilpuram #define ROC_LMT_CPT_BASE_ID_GET(lmt_addr, lmt_id)                              \
23ee48f711SNithin Dabilpuram 	do {                                                                   \
24ee48f711SNithin Dabilpuram 		/* 16 Lines per core */                                        \
25ee48f711SNithin Dabilpuram 		lmt_id = ROC_LMT_CPT_BASE_ID_OFF;                              \
26ee48f711SNithin Dabilpuram 		lmt_id += (plt_lcore_id() << ROC_LMT_CPT_LINES_PER_CORE_LOG2); \
27ee48f711SNithin Dabilpuram 		/* Each line is of 128B */                                     \
28ee48f711SNithin Dabilpuram 		(lmt_addr) += ((uint64_t)lmt_id << ROC_LMT_LINE_SIZE_LOG2);    \
29ee48f711SNithin Dabilpuram 	} while (0)
3070b6be62SNithin Dabilpuram #endif
31ee48f711SNithin Dabilpuram 
32014a9e22SJerin Jacob #define roc_load_pair(val0, val1, addr)                                        \
33*93998f3cSTyler Retzlaff 	__extension__ ({                                                                     \
34014a9e22SJerin Jacob 		asm volatile("ldp %x[x0], %x[x1], [%x[p1]]"                    \
35014a9e22SJerin Jacob 			     : [x0] "=r"(val0), [x1] "=r"(val1)                \
36014a9e22SJerin Jacob 			     : [p1] "r"(addr));                                \
37014a9e22SJerin Jacob 	})
38014a9e22SJerin Jacob 
39014a9e22SJerin Jacob #define roc_store_pair(val0, val1, addr)                                       \
40*93998f3cSTyler Retzlaff 	__extension__ ({                                                                     \
41014a9e22SJerin Jacob 		asm volatile(                                                  \
42014a9e22SJerin Jacob 			"stp %x[x0], %x[x1], [%x[p1], #0]!" ::[x0] "r"(val0),  \
43014a9e22SJerin Jacob 			[x1] "r"(val1), [p1] "r"(addr));                       \
44014a9e22SJerin Jacob 	})
45014a9e22SJerin Jacob 
46014a9e22SJerin Jacob #define roc_prefetch_store_keep(ptr)                                           \
47*93998f3cSTyler Retzlaff 	__extension__ ({ asm volatile("prfm pstl1keep, [%x0]\n" : : "r"(ptr)); })
48014a9e22SJerin Jacob 
49014a9e22SJerin Jacob #if defined(__clang__)
50014a9e22SJerin Jacob static __plt_always_inline void
roc_atomic128_cas_noreturn(uint64_t swap0,uint64_t swap1,int64_t * ptr)51014a9e22SJerin Jacob roc_atomic128_cas_noreturn(uint64_t swap0, uint64_t swap1, int64_t *ptr)
52014a9e22SJerin Jacob {
53014a9e22SJerin Jacob 	register uint64_t x0 __asm("x0") = swap0;
54014a9e22SJerin Jacob 	register uint64_t x1 __asm("x1") = swap1;
55014a9e22SJerin Jacob 
56014a9e22SJerin Jacob 	asm volatile(PLT_CPU_FEATURE_PREAMBLE
57014a9e22SJerin Jacob 		     "casp %[x0], %[x1], %[x0], %[x1], [%[ptr]]\n"
58014a9e22SJerin Jacob 		     : [x0] "+r"(x0), [x1] "+r"(x1)
59014a9e22SJerin Jacob 		     : [ptr] "r"(ptr)
60014a9e22SJerin Jacob 		     : "memory");
61014a9e22SJerin Jacob }
62014a9e22SJerin Jacob #else
63014a9e22SJerin Jacob static __plt_always_inline void
roc_atomic128_cas_noreturn(uint64_t swap0,uint64_t swap1,uint64_t ptr)64014a9e22SJerin Jacob roc_atomic128_cas_noreturn(uint64_t swap0, uint64_t swap1, uint64_t ptr)
65014a9e22SJerin Jacob {
66014a9e22SJerin Jacob 	__uint128_t wdata = swap0 | ((__uint128_t)swap1 << 64);
67014a9e22SJerin Jacob 
68014a9e22SJerin Jacob 	asm volatile(PLT_CPU_FEATURE_PREAMBLE
69014a9e22SJerin Jacob 		     "casp %[wdata], %H[wdata], %[wdata], %H[wdata], [%[ptr]]\n"
70014a9e22SJerin Jacob 		     : [wdata] "+r"(wdata)
71014a9e22SJerin Jacob 		     : [ptr] "r"(ptr)
72014a9e22SJerin Jacob 		     : "memory");
73014a9e22SJerin Jacob }
74014a9e22SJerin Jacob #endif
75014a9e22SJerin Jacob 
76014a9e22SJerin Jacob static __plt_always_inline uint64_t
roc_atomic64_cas(uint64_t compare,uint64_t swap,int64_t * ptr)77014a9e22SJerin Jacob roc_atomic64_cas(uint64_t compare, uint64_t swap, int64_t *ptr)
78014a9e22SJerin Jacob {
79014a9e22SJerin Jacob 	asm volatile(PLT_CPU_FEATURE_PREAMBLE
80014a9e22SJerin Jacob 		     "cas %[compare], %[swap], [%[ptr]]\n"
81014a9e22SJerin Jacob 		     : [compare] "+r"(compare)
82014a9e22SJerin Jacob 		     : [swap] "r"(swap), [ptr] "r"(ptr)
83014a9e22SJerin Jacob 		     : "memory");
84014a9e22SJerin Jacob 
85014a9e22SJerin Jacob 	return compare;
86014a9e22SJerin Jacob }
87014a9e22SJerin Jacob 
88014a9e22SJerin Jacob static __plt_always_inline uint64_t
roc_atomic64_casl(uint64_t compare,uint64_t swap,int64_t * ptr)8909cad550SAshwin Sekhar T K roc_atomic64_casl(uint64_t compare, uint64_t swap, int64_t *ptr)
9009cad550SAshwin Sekhar T K {
9109cad550SAshwin Sekhar T K 	asm volatile(PLT_CPU_FEATURE_PREAMBLE
9209cad550SAshwin Sekhar T K 		     "casl %[compare], %[swap], [%[ptr]]\n"
9309cad550SAshwin Sekhar T K 		     : [compare] "+r"(compare)
9409cad550SAshwin Sekhar T K 		     : [swap] "r"(swap), [ptr] "r"(ptr)
9509cad550SAshwin Sekhar T K 		     : "memory");
9609cad550SAshwin Sekhar T K 
9709cad550SAshwin Sekhar T K 	return compare;
9809cad550SAshwin Sekhar T K }
9909cad550SAshwin Sekhar T K 
10009cad550SAshwin Sekhar T K static __plt_always_inline uint64_t
roc_atomic64_add_nosync(int64_t incr,int64_t * ptr)101014a9e22SJerin Jacob roc_atomic64_add_nosync(int64_t incr, int64_t *ptr)
102014a9e22SJerin Jacob {
103014a9e22SJerin Jacob 	uint64_t result;
104014a9e22SJerin Jacob 
105014a9e22SJerin Jacob 	/* Atomic add with no ordering */
106014a9e22SJerin Jacob 	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldadd %x[i], %x[r], [%[b]]"
107014a9e22SJerin Jacob 		     : [r] "=r"(result), "+m"(*ptr)
108014a9e22SJerin Jacob 		     : [i] "r"(incr), [b] "r"(ptr)
109014a9e22SJerin Jacob 		     : "memory");
110014a9e22SJerin Jacob 	return result;
111014a9e22SJerin Jacob }
112014a9e22SJerin Jacob 
113014a9e22SJerin Jacob static __plt_always_inline uint64_t
roc_atomic64_add_sync(int64_t incr,int64_t * ptr)114014a9e22SJerin Jacob roc_atomic64_add_sync(int64_t incr, int64_t *ptr)
115014a9e22SJerin Jacob {
116014a9e22SJerin Jacob 	uint64_t result;
117014a9e22SJerin Jacob 
118014a9e22SJerin Jacob 	/* Atomic add with ordering */
119014a9e22SJerin Jacob 	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldadda %x[i], %x[r], [%[b]]"
120014a9e22SJerin Jacob 		     : [r] "=r"(result), "+m"(*ptr)
121014a9e22SJerin Jacob 		     : [i] "r"(incr), [b] "r"(ptr)
122014a9e22SJerin Jacob 		     : "memory");
123014a9e22SJerin Jacob 	return result;
124014a9e22SJerin Jacob }
125014a9e22SJerin Jacob 
126014a9e22SJerin Jacob static __plt_always_inline uint64_t
roc_lmt_submit_ldeor(plt_iova_t io_address)127014a9e22SJerin Jacob roc_lmt_submit_ldeor(plt_iova_t io_address)
128014a9e22SJerin Jacob {
129014a9e22SJerin Jacob 	uint64_t result;
130014a9e22SJerin Jacob 
131014a9e22SJerin Jacob 	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldeor xzr, %x[rf], [%[rs]]"
132014a9e22SJerin Jacob 		     : [rf] "=r"(result)
133a032b598SNithin Dabilpuram 		     : [rs] "r"(io_address)
134a032b598SNithin Dabilpuram 		     : "memory");
135014a9e22SJerin Jacob 	return result;
136014a9e22SJerin Jacob }
137014a9e22SJerin Jacob 
138014a9e22SJerin Jacob static __plt_always_inline uint64_t
roc_lmt_submit_ldeorl(plt_iova_t io_address)139014a9e22SJerin Jacob roc_lmt_submit_ldeorl(plt_iova_t io_address)
140014a9e22SJerin Jacob {
141014a9e22SJerin Jacob 	uint64_t result;
142014a9e22SJerin Jacob 
143014a9e22SJerin Jacob 	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldeorl xzr,%x[rf],[%[rs]]"
144014a9e22SJerin Jacob 		     : [rf] "=r"(result)
145a032b598SNithin Dabilpuram 		     : [rs] "r"(io_address)
146a032b598SNithin Dabilpuram 		     : "memory");
147014a9e22SJerin Jacob 	return result;
148014a9e22SJerin Jacob }
149014a9e22SJerin Jacob 
150014a9e22SJerin Jacob static __plt_always_inline void
roc_lmt_submit_steor(uint64_t data,plt_iova_t io_address)151014a9e22SJerin Jacob roc_lmt_submit_steor(uint64_t data, plt_iova_t io_address)
152014a9e22SJerin Jacob {
153014a9e22SJerin Jacob 	asm volatile(PLT_CPU_FEATURE_PREAMBLE
154014a9e22SJerin Jacob 		     "steor %x[d], [%[rs]]" ::[d] "r"(data),
155a032b598SNithin Dabilpuram 		     [rs] "r"(io_address)
156a032b598SNithin Dabilpuram 		     : "memory");
157014a9e22SJerin Jacob }
158014a9e22SJerin Jacob 
159014a9e22SJerin Jacob static __plt_always_inline void
roc_lmt_submit_steorl(uint64_t data,plt_iova_t io_address)160014a9e22SJerin Jacob roc_lmt_submit_steorl(uint64_t data, plt_iova_t io_address)
161014a9e22SJerin Jacob {
162014a9e22SJerin Jacob 	asm volatile(PLT_CPU_FEATURE_PREAMBLE
163014a9e22SJerin Jacob 		     "steorl %x[d], [%[rs]]" ::[d] "r"(data),
164a032b598SNithin Dabilpuram 		     [rs] "r"(io_address)
165a032b598SNithin Dabilpuram 		     : "memory");
166014a9e22SJerin Jacob }
167014a9e22SJerin Jacob 
168014a9e22SJerin Jacob static __plt_always_inline void
roc_lmt_mov(void * out,const void * in,const uint32_t lmtext)169014a9e22SJerin Jacob roc_lmt_mov(void *out, const void *in, const uint32_t lmtext)
170014a9e22SJerin Jacob {
171014a9e22SJerin Jacob 	volatile const __uint128_t *src128 = (const __uint128_t *)in;
172014a9e22SJerin Jacob 	volatile __uint128_t *dst128 = (__uint128_t *)out;
173f1cdb3c5SPavan Nikhilesh 	uint32_t i;
174014a9e22SJerin Jacob 
175014a9e22SJerin Jacob 	dst128[0] = src128[0];
176014a9e22SJerin Jacob 	dst128[1] = src128[1];
177014a9e22SJerin Jacob 	/* lmtext receives following value:
178014a9e22SJerin Jacob 	 * 1: NIX_SUBDC_EXT needed i.e. tx vlan case
179014a9e22SJerin Jacob 	 */
180f1cdb3c5SPavan Nikhilesh 	for (i = 0; i < lmtext; i++)
181f1cdb3c5SPavan Nikhilesh 		dst128[2 + i] = src128[2 + i];
182ae2c2cb6SPavan Nikhilesh }
183ae2c2cb6SPavan Nikhilesh 
184ae2c2cb6SPavan Nikhilesh static __plt_always_inline void
roc_lmt_mov64(void * out,const void * in)185ae2c2cb6SPavan Nikhilesh roc_lmt_mov64(void *out, const void *in)
186ae2c2cb6SPavan Nikhilesh {
187ae2c2cb6SPavan Nikhilesh 	volatile const __uint128_t *src128 = (const __uint128_t *)in;
188ae2c2cb6SPavan Nikhilesh 	volatile __uint128_t *dst128 = (__uint128_t *)out;
189ae2c2cb6SPavan Nikhilesh 
190ae2c2cb6SPavan Nikhilesh 	dst128[0] = src128[0];
191ae2c2cb6SPavan Nikhilesh 	dst128[1] = src128[1];
192ae2c2cb6SPavan Nikhilesh 	dst128[2] = src128[2];
193014a9e22SJerin Jacob 	dst128[3] = src128[3];
194014a9e22SJerin Jacob }
195ae2c2cb6SPavan Nikhilesh 
196ae2c2cb6SPavan Nikhilesh static __plt_always_inline void
roc_lmt_mov_nv(void * out,const void * in,const uint32_t lmtext)197ae2c2cb6SPavan Nikhilesh roc_lmt_mov_nv(void *out, const void *in, const uint32_t lmtext)
198ae2c2cb6SPavan Nikhilesh {
199ae2c2cb6SPavan Nikhilesh 	const __uint128_t *src128 = (const __uint128_t *)in;
200ae2c2cb6SPavan Nikhilesh 	__uint128_t *dst128 = (__uint128_t *)out;
201ae2c2cb6SPavan Nikhilesh 
202ae2c2cb6SPavan Nikhilesh 	dst128[0] = src128[0];
203ae2c2cb6SPavan Nikhilesh 	dst128[1] = src128[1];
204ae2c2cb6SPavan Nikhilesh 	/* lmtext receives following value:
205ae2c2cb6SPavan Nikhilesh 	 * 1: NIX_SUBDC_EXT needed i.e. tx vlan case
206ae2c2cb6SPavan Nikhilesh 	 */
207ae2c2cb6SPavan Nikhilesh 	if (lmtext)
208ae2c2cb6SPavan Nikhilesh 		dst128[2] = src128[2];
209014a9e22SJerin Jacob }
210014a9e22SJerin Jacob 
211014a9e22SJerin Jacob static __plt_always_inline void
roc_lmt_mov_seg(void * out,const void * in,const uint16_t segdw)212014a9e22SJerin Jacob roc_lmt_mov_seg(void *out, const void *in, const uint16_t segdw)
213014a9e22SJerin Jacob {
214014a9e22SJerin Jacob 	volatile const __uint128_t *src128 = (const __uint128_t *)in;
215014a9e22SJerin Jacob 	volatile __uint128_t *dst128 = (__uint128_t *)out;
216014a9e22SJerin Jacob 	uint8_t i;
217014a9e22SJerin Jacob 
218014a9e22SJerin Jacob 	for (i = 0; i < segdw; i++)
219014a9e22SJerin Jacob 		dst128[i] = src128[i];
220014a9e22SJerin Jacob }
221014a9e22SJerin Jacob 
222014a9e22SJerin Jacob static __plt_always_inline void
roc_lmt_mov_one(void * out,const void * in)223014a9e22SJerin Jacob roc_lmt_mov_one(void *out, const void *in)
224014a9e22SJerin Jacob {
225014a9e22SJerin Jacob 	volatile const __uint128_t *src128 = (const __uint128_t *)in;
226014a9e22SJerin Jacob 	volatile __uint128_t *dst128 = (__uint128_t *)out;
227014a9e22SJerin Jacob 
228014a9e22SJerin Jacob 	*dst128 = *src128;
229014a9e22SJerin Jacob }
230014a9e22SJerin Jacob 
231014a9e22SJerin Jacob /* Non volatile version of roc_lmt_mov_seg() */
232014a9e22SJerin Jacob static __plt_always_inline void
roc_lmt_mov_seg_nv(void * out,const void * in,const uint16_t segdw)233014a9e22SJerin Jacob roc_lmt_mov_seg_nv(void *out, const void *in, const uint16_t segdw)
234014a9e22SJerin Jacob {
235014a9e22SJerin Jacob 	const __uint128_t *src128 = (const __uint128_t *)in;
236014a9e22SJerin Jacob 	__uint128_t *dst128 = (__uint128_t *)out;
237014a9e22SJerin Jacob 	uint8_t i;
238014a9e22SJerin Jacob 
239014a9e22SJerin Jacob 	for (i = 0; i < segdw; i++)
240014a9e22SJerin Jacob 		dst128[i] = src128[i];
241014a9e22SJerin Jacob }
242014a9e22SJerin Jacob 
243804c108bSTomasz Duszynski static __plt_always_inline void
roc_atf_ret(void)244804c108bSTomasz Duszynski roc_atf_ret(void)
245804c108bSTomasz Duszynski {
246804c108bSTomasz Duszynski 	/* This will allow wfi in EL0 to cause async exception to EL3
247804c108bSTomasz Duszynski 	 * which will optionally perform necessary actions.
248804c108bSTomasz Duszynski 	 */
249804c108bSTomasz Duszynski 	__asm("wfi");
250804c108bSTomasz Duszynski }
251804c108bSTomasz Duszynski 
252014a9e22SJerin Jacob #endif /* _ROC_IO_H_ */
253