xref: /netbsd-src/sys/arch/mips/rmi/rmixl_fmnvar.h (revision d1913fe4152d38c9019769888255c38e79d1c786)
1 /*	$Id: rmixl_fmnvar.h,v 1.5 2024/06/06 21:18:41 andvar Exp $	*/
2 /*-
3  * Copyright (c) 2010 The NetBSD Foundation, Inc.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to The NetBSD Foundation
7  * by Cliff Neighbors.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef _ARCH_MIPS_RMIXL_RMIXL_FMNVAR_H_
32 #define _ARCH_MIPS_RMIXL_RMIXL_FMNVAR_H_
33 
34 #include <mips/cpuregs.h>
35 
36 #define RMIXL_FMN_CODE_PSB_WAKEUP	200	/* firmware MSGRNG_CODE_BOOT_WAKEUP */
37 #define RMIXL_FMN_CODE_HELLO_REQ	201
38 #define RMIXL_FMN_CODE_HELLO_ACK	202
39 
40 #define RMIXL_FMN_HELLO_REQ_SZ		4
41 #define RMIXL_FMN_HELLO_ACK_SZ		4
42 
43 typedef struct rmixl_fmn_msg {
44 	uint64_t data[4];
45 } rmixl_fmn_msg_t;
46 
47 typedef struct rmixl_fmn_rxmsg {
48 	u_int rxsid;
49 	u_int code;
50 	u_int size;
51 	rmixl_fmn_msg_t msg;
52 } rmixl_fmn_rxmsg_t;
53 
54 
55 /*
56  * compute FMN dest_id from MIPS cpuid
57  * - each Core FMN station has 8 buckets
58  * - each Core has 4 threads
59  * - here we use 1 bucket per thread
60  *   (the first four buckets)
61  * - if we need { hi, lo } priority buckets per thread
62  *   need to adjust the RMIXL_FMN_DESTID macro
63  *   and use the 'pri' parameter
64  * - i.e. for now there is only one priority
65  */
66 #define RMIXL_CPU_CORE(cpuid)	((uint32_t)((cpuid) & __BITS(9,0)) >> 2)
67 #define RMIXL_CPU_THREAD(cpuid)	((uint32_t)((cpuid) & __BITS(1,0)))
68 #define RMIXL_FMN_CORE_DESTID(core, bucket)	\
69 		 (((core) << 3) | (bucket))
70 
71 
72 #define RMIXL_DMFC2(regnum, sel, rv)					\
73 do {									\
74 	uint64_t __val;							\
75 									\
76 	__asm volatile(							\
77 		".set push" 			"\n\t"			\
78 		".set mips64"			"\n\t"			\
79 		".set noat"			"\n\t"			\
80 		"dmfc2 %0,$%1,%2"		"\n\t"			\
81 		".set pop"			"\n\t"			\
82 	    : "=r"(__val) : "n"(regnum), "n"(sel));			\
83 	rv = __val;							\
84 } while (0)
85 
86 #define RMIXL_DMTC2(regnum, sel, val)					\
87 do {									\
88 	uint64_t __val = val;						\
89 									\
90 	__asm volatile(							\
91 		".set push" 			"\n\t"			\
92 		".set mips64"			"\n\t"			\
93 		".set noat"			"\n\t"			\
94 		"dmtc2 %0,$%1,%2"		"\n\t"			\
95 		".set pop"			"\n\t"			\
96 	    :: "r"(__val), "n"(regnum), "n"(sel));			\
97 } while (0)
98 
99 #define RMIXL_MFC2(regnum, sel, rv)					\
100 do {									\
101 	uint32_t __val;							\
102 									\
103 	__asm volatile(							\
104 		".set push"			"\n\t"			\
105 		".set mips64"			"\n\t"			\
106 		"mfc2 %0,$%1,%2"		"\n\t"			\
107 		".set pop"			"\n\t"			\
108 	    : "=r"(__val) : "n"(regnum), "n"(sel));			\
109 	rv = __val;							\
110 } while (0)
111 
112 #define RMIXL_MTC2(regnum, sel, val)					\
113 do {									\
114 	uint32_t __val = val;						\
115 									\
116 	__asm volatile(							\
117 		".set push"			"\n\t"			\
118 		".set mips64"			"\n\t"			\
119 		"mtc2 %0,$%1,%2"		"\n\t"			\
120 		".set pop"			"\n\t"			\
121 	    :: "r"(__val), "n"(regnum), "n"(sel));			\
122 } while (0)
123 
124 #define CPU2_PRINT_8(regno, sel)					\
125 do {									\
126 	uint64_t r;							\
127 	RMIXL_DMFC2(regno, sel, r);					\
128 	printf("%s: CP2(%d,%d) = %#"PRIx64"\n",				\
129 		__func__, regno, sel, r);				\
130 } while (0)
131 
132 #define CPU2_PRINT_4(regno, sel)					\
133 do {									\
134 	uint32_t r;							\
135 	RMIXL_MFC2(regno, sel, r);					\
136 	printf("%s: CP2(%d,%d) = %#x\n",				\
137 		__func__, regno, sel, r);				\
138 } while (0)
139 
140 
141 /*
142  * encode 'dest' for msgsnd op 'rt'
143  */
144 #define RMIXL_MSGSND_DESC(size, code, dest_id)	\
145 		((((size) - 1) << 16) | ((code) << 8) | (dest_id))
146 
147 static inline void
rmixl_msgsnd(uint32_t desc)148 rmixl_msgsnd(uint32_t desc)
149 {
150 	__asm__ volatile (
151 		".set push"		"\n\t"
152 		".set noreorder"	"\n\t"
153 		".set arch=xlr"		"\n\t"
154 		"sync"			"\n\t"
155 		"msgsnd %0"		"\n\t"
156 		".set pop"		"\n\t"
157 			:: "r"(desc));
158 }
159 
160 static inline void
rmixl_msgld(uint32_t bucket)161 rmixl_msgld(uint32_t bucket)
162 {
163 	__asm__ volatile (
164 		".set push"		"\n\t"
165 		".set noreorder"	"\n\t"
166 		".set arch=xlr"		"\n\t"
167 		"msgld %0"		"\n\t"
168 		".set pop"		"\n\t"
169 			:: "r"(bucket));
170 }
171 
172 /*
173  * the seemingly-spurious add is recommended by RMI
174  * see XLS PRM (rev. 3.21) 5.3.9
175  */
176 static inline void
rmixl_fmn_msgwait(u_int mask)177 rmixl_fmn_msgwait(u_int mask)
178 {
179 	__asm__ volatile (
180 		".set push"		"\n\t"
181 		".set noreorder"	"\n\t"
182 		".set arch=xlr"		"\n\t"
183 		"addu %0,%0,0"		"\n\t"
184 		"msgwait %0"		"\n\t"
185 		".set pop"		"\n\t"
186 			:: "r"(mask));
187 }
188 
189 static inline uint32_t
rmixl_cp2_enable(void)190 rmixl_cp2_enable(void)
191 {
192 	uint32_t rv;
193 	uint32_t cu2;
194 
195 	KASSERT(curcpu()->ci_cpl == IPL_HIGH);
196 	__asm volatile(
197 		".set push"		"\n\t"
198 		".set noreorder"	"\n\t"
199 		"li	%1,%3"		"\n\t"
200 		"mfc0	%0,$%2"		"\n\t"
201 		"or	%1,%1,%0"	"\n\t"
202 		"mtc0	%1,$%2"		"\n\t"
203 		".set pop"		"\n\t"
204 			: "=r"(rv), "=r"(cu2)
205 			: "n"(MIPS_COP_0_STATUS), "n"(1 << 30));
206 
207 	return (rv & (1 << 30));
208 }
209 
210 static inline void
rmixl_cp2_restore(uint32_t ocu)211 rmixl_cp2_restore(uint32_t ocu)
212 {
213 	uint32_t cu2;
214 	uint32_t mask = ~(1 << 30);
215 
216 	KASSERT(curcpu()->ci_cpl == IPL_HIGH);
217 	__asm volatile(
218 		".set push"		"\n\t"
219 		".set noreorder"	"\n\t"
220 		"mfc0	%0,$%1"		"\n\t"
221 		"and	%0,%2,%0"	"\n\t"
222 		"or	%0,%3,%0"	"\n\t"
223 		"mtc0	%0,$%1"		"\n\t"
224 		".set pop"		"\n\t"
225 			: "=r"(cu2)
226 			: "n"(MIPS_COP_0_STATUS), "r"(mask), "r"(ocu));
227 }
228 
229 /*
230  * logical station IDs for RMI XLR
231  * see Table 13.2 "Addressable Buckets" in the XLR PRM
232  */
233 #define RMIXLR_FMN_STID_CORE0			0
234 #define RMIXLR_FMN_STID_CORE1			1
235 #define RMIXLR_FMN_STID_CORE2			2
236 #define RMIXLR_FMN_STID_CORE3			3
237 #define RMIXLR_FMN_STID_CORE4			4
238 #define RMIXLR_FMN_STID_CORE5			5
239 #define RMIXLR_FMN_STID_CORE6			6
240 #define RMIXLR_FMN_STID_CORE7			7
241 #define RMIXLR_FMN_STID_TXRX_0			8
242 #define RMIXLR_FMN_STID_TXRX_1			9
243 #define RMIXLR_FMN_STID_RGMII			10
244 #define RMIXLR_FMN_STID_DMA			11
245 #define RMIXLR_FMN_STID_FREE_0			12
246 #define RMIXLR_FMN_STID_FREE_1			13
247 #define RMIXLR_FMN_STID_SAE			14
248 #define RMIXLR_FMN_NSTID			(RMIXLR_FMN_STID_SAE+1)
249 #define RMIXLR_FMN_STID_RESERVED		-1
250 
251 /*
252  * logical station IDs for RMI XLS
253  * see Table 12.1 "Stations and Addressable Buckets ..." in the XLS PRM
254  */
255 #define RMIXLS_FMN_STID_CORE0			0
256 #define RMIXLS_FMN_STID_CORE1			1
257 #define RMIXLS_FMN_STID_CORE2			2
258 #define RMIXLS_FMN_STID_CORE3			3
259 #define RMIXLS_FMN_STID_GMAC_Q0			4
260 #define RMIXLS_FMN_STID_GMAC_Q1			5
261 #define RMIXLS_FMN_STID_DMA			6
262 #define RMIXLS_FMN_STID_CDE			7
263 #define RMIXLS_FMN_STID_PCIE			8
264 #define RMIXLS_FMN_STID_SAE			9
265 #define RMIXLS_FMN_NSTID			(RMIXLS_FMN_STID_SAE+1)
266 #define RMIXLS_FMN_STID_RESERVED		-1
267 
268 /*
269  * logical station IDs for RMI XLP
270  * TBD!
271  */
272 #define RMIXLP_FMN_NSTID			0	/* XXX */
273 
274 
275 #define RMIXL_FMN_NSTID		\
276 		MAX(MAX(RMIXLR_FMN_NSTID, RMIXLS_FMN_NSTID), RMIXLP_FMN_NSTID)
277 
278 
279 #define RMIXL_FMN_INTR_IPL	IPL_HIGH
280 
281 void	rmixl_fmn_init(void);
282 void	rmixl_fmn_init_core(void);
283 void	rmixl_fmn_init_cpu_intr(void);
284 void   *rmixl_fmn_intr_establish(int, int (*)(void *, rmixl_fmn_rxmsg_t *), void *);
285 void	rmixl_fmn_intr_disestablish(void *);
286 void	rmixl_fmn_intr_poll(u_int, rmixl_fmn_rxmsg_t *);
287 int	rmixl_fmn_msg_send(u_int, u_int, u_int, rmixl_fmn_msg_t *);
288 int	rmixl_fmn_msg_recv(u_int, rmixl_fmn_rxmsg_t *);
289 
290 
291 
292 #endif	/* _ARCH_MIPS_RMIXL_RMIXL_FMNVAR_H_ */
293