Home | History | Annotate | Line # | Download | only in rmi
      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
    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
    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
    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
    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
    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