Home | History | Annotate | Line # | Download | only in rmi
rmixl_fmnvar.h revision 1.1.2.7
      1 /*	$Id: rmixl_fmnvar.h,v 1.1.2.7 2012/01/19 09:59:08 matt 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 <sys/cpu.h>
     35 #include <mips/cpuregs.h>
     36 
     37 #define RMIXL_FMN_CODE_PSB_WAKEUP	200	/* firmware MSGRNG_CODE_BOOT_WAKEUP */
     38 #define RMIXL_FMN_CODE_HELLO_REQ	201
     39 #define RMIXL_FMN_CODE_HELLO_ACK	202
     40 
     41 #define RMIXL_FMN_HELLO_REQ_SZ		4
     42 #define RMIXL_FMN_HELLO_ACK_SZ		4
     43 
     44 typedef struct rmixl_fmn_msg {
     45 	uint64_t data[4];
     46 } rmixl_fmn_msg_t;
     47 
     48 typedef struct rmixl_fmn_rxmsg {
     49 	uint16_t rxsid;
     50 	u_int code;
     51 	uint8_t size;
     52 	rmixl_fmn_msg_t msg;
     53 } rmixl_fmn_rxmsg_t;
     54 
     55 
     56 /*
     57  * compute FMN dest_id from MIPS cpuid
     58  * - each Core FMN sation has 8 buckets
     59  * - each Core has 4 threads
     60  * - here we use 1 bucket per thread
     61  *   (the first four buckets)
     62  * - if we need { hi, lo } priority buckets per thread
     63  *   need to adjust the RMIXL_FMN_DESTID macro
     64  *   and use the 'pri' parameter
     65  * - i.e. for now there is only one priority
     66  */
     67 #define RMIXL_CPU_CORE(cpuid)	((uint32_t)__SHIFTOUT((cpuid), __BITS(7,3)))
     68 #define RMIXL_CPU_THREAD(cpuid)	((uint32_t)__SHIFTOUT((cpuid), __BITS(1,0)))
     69 
     70 static inline uint64_t
     71 mips_dmfc2(const u_int regnum, const u_int sel)
     72 {
     73 	uint64_t __val;
     74 
     75 	__asm volatile(
     76 		".set push" 			"\n\t"
     77 		".set mips64"			"\n\t"
     78 		".set noat"			"\n\t"
     79 		"dmfc2 %0,$%1,%2"		"\n\t"
     80 		".set pop"			"\n\t"
     81 	    : "=r"(__val) : "n"(regnum), "n"(sel));
     82 
     83 	return __val;
     84 }
     85 
     86 static inline void
     87 mips_dmtc2(u_int regnum, u_int sel, uint64_t val)
     88 {
     89 	__asm volatile(
     90 		".set push" 			"\n\t"
     91 		".set mips64"			"\n\t"
     92 		".set noat"			"\n\t"
     93 		"dmtc2 %0,$%1,%2"		"\n\t"
     94 		".set pop"			"\n\t"
     95 	    :: "r"(val), "n"(regnum), "n"(sel));
     96 }
     97 
     98 static inline uint64_t
     99 mips_mfc2(const u_int regnum, const u_int sel)
    100 {
    101 	uint32_t __val;
    102 
    103 	__asm volatile(
    104 		".set push"			"\n\t"
    105 		".set mips32"			"\n\t"
    106 		"mfc2 %0,$%1,%2"		"\n\t"
    107 		".set pop"			"\n\t"
    108 	    : "=r"(__val) : "n"(regnum), "n"(sel));
    109 	return __val;
    110 }
    111 
    112 static inline void
    113 mips_mtc2(u_int regnum, u_int sel, uint32_t val)
    114 {
    115 	__asm volatile(
    116 		".set push" 			"\n\t"
    117 		".set mips32"			"\n\t"
    118 		".set noat"			"\n\t"
    119 		"mtc2 %0,$%1,%2"		"\n\t"
    120 		".set pop"			"\n\t"
    121 	    :: "r"(val), "n"(regnum), "n"(sel));
    122 }
    123 
    124 #define COP2_PRINT_8(regno, sel)					\
    125 do {									\
    126 	printf("%s: COP2(%d,%d) = %#"PRIx64"\n",			\
    127 	    __func__, regno, sel, mips_dmfc2(regno, sel));		\
    128 } while (0)
    129 
    130 #define COP2_PRINT_4(regno, sel)					\
    131 do {									\
    132 	printf("%s: COP2(%d,%d) = %#"PRIx32"\n",			\
    133 	    __func__, regno, sel, mips_mfc2(regno, sel));		\
    134 } while (0)
    135 
    136 
    137 /*
    138  * encode 'dest' for msgsnd op 'rt'
    139  */
    140 #define RMIXL_MSGSND_DESC(size, code, dest_id)			\
    141 		(__SHIFTOUT((dest_id), __BITS(7,0))		\
    142 		|__SHIFTOUT((code), __BITS(15,8))		\
    143 		|__SHIFTOUT((size)-1, __BITS(17,16)))
    144 #define RMIXLP_MSGSND_DESC(size, code, dest_id, dest_vc)	\
    145 		(__SHIFTOUT((dest_id), __BITS(11,0))		\
    146 		|__SHIFTOUT((size)-1, __BITS(17,16))		\
    147 		|__SHIFTOUT((dest_vc), __BITS(20,19))		\
    148 		|__SHIFTOUT((code), __BITS(31,24)))
    149 
    150 static inline void
    151 rmixl_msgsnd(uint32_t desc)
    152 {
    153 	__asm__ volatile (
    154 		".set push"		"\n\t"
    155 		".set noreorder"	"\n\t"
    156 		".set arch=xlr"		"\n\t"
    157 		"sync"			"\n\t"
    158 		"msgsnd %0"		"\n\t"
    159 		".set pop"		"\n\t"
    160 	    :: "r"(desc));
    161 }
    162 
    163 static inline uint32_t
    164 rmixlp_msgsnd(uint32_t desc)
    165 {
    166 	uint32_t rv;
    167 
    168 	__asm__ volatile (
    169 		".set push"		"\n\t"
    170 		".set noreorder"	"\n\t"
    171 		".set arch=xlp"		"\n\t"
    172 		"sync"			"\n\t"
    173 		"msgsnds %[desc],%[rv]"	"\n\t"
    174 		".set pop"		"\n\t"
    175 	    :	[rv] "=r" (rv)
    176 	    :	[desc] "r" (desc));
    177 
    178 	return rv;
    179 }
    180 
    181 static inline void
    182 rmixl_msgld(uint32_t bucket)
    183 {
    184 	__asm__ volatile (
    185 		".set push"		"\n\t"
    186 		".set noreorder"	"\n\t"
    187 		".set arch=xlr"		"\n\t"
    188 		"msgld %0"		"\n\t"
    189 		".set pop"		"\n\t"
    190 	    :: "r"(bucket));
    191 }
    192 
    193 static inline uint32_t
    194 rmixlp_msgld(uint32_t rxq)
    195 {
    196 	uint32_t rv;
    197 
    198 	__asm__ volatile (
    199 		".set push"		"\n\t"
    200 		".set noreorder"	"\n\t"
    201 		".set arch=xlp"		"\n\t"
    202 		"msglds %[rxq],%[rv]"	"\n\t"
    203 		".set pop"		"\n\t"
    204 	    :	[rv] "=r"(rv)
    205 	    :	[rxq] "r"(rxq));
    206 
    207 	return rv;
    208 }
    209 
    210 /*
    211  * the seemingly-spurious add is recommended by RMI
    212  * see XLS PRM (rev. 3.21) 5.3.9
    213  */
    214 static inline void
    215 rmixl_msgwait(u_int mask)
    216 {
    217 	__asm__ volatile (
    218 		".set push"		"\n\t"
    219 		".set noreorder"	"\n\t"
    220 		".set arch=xlr"		"\n\t"
    221 		"daddu %0,%0,0"		"\n\t"
    222 		"msgwait %0"		"\n\t"
    223 		".set pop"		"\n\t"
    224 	    :: "r"(mask));
    225 }
    226 
    227 static inline uint32_t
    228 rmixl_cp2_enable(void)
    229 {
    230 	uint32_t rv;
    231 	uint32_t sr;
    232 
    233 	KASSERT(curcpu()->ci_cpl == IPL_HIGH);
    234 	__asm volatile(
    235 		".set push"			"\n\t"
    236 		".set noreorder"		"\n\t"
    237 		".set noat"			"\n\t"
    238 		"mfc0	%[sr],$%[c0_status]"	"\n\t"
    239 		"and	%[rv],%[sr],%[mask]"	"\n\t"
    240 		"or	%[sr],%[mask]"		"\n\t"
    241 		"mtc0	%[sr],$%[c0_status]"	"\n\t"
    242 		".set pop"			"\n\t"
    243 	    :	[rv] "=r" (rv),
    244 		[sr] "=r" (sr)
    245 	    :	[c0_status] "n" (MIPS_COP_0_STATUS),
    246 		[mask] "r" (MIPS_SR_COP_2_BIT));
    247 
    248 	return rv;
    249 }
    250 
    251 static inline void
    252 rmixl_cp2_restore(uint32_t ocu)
    253 {
    254 	uint32_t cu2;
    255 
    256 	KASSERT(curcpu()->ci_cpl == IPL_HIGH);
    257 	__asm volatile(
    258 		".set push"			"\n\t"
    259 		".set noreorder"		"\n\t"
    260 		".set noat"			"\n\t"
    261 		"mfc0	%[sr],$%[c0_status]"	"\n\t"
    262 		"and	%[sr],%[mask]"		"\n\t"
    263 		"or	%[sr],%[ocu]"		"\n\t"
    264 		"mtc0	%[sr],$%[c0_status]"	"\n\t"
    265 		".set pop"			"\n\t"
    266 	    :	[sr] "=r"(cu2)
    267 	    :	[c0_status] "n" (MIPS_COP_0_STATUS),
    268 		[mask] "r" (~MIPS_SR_COP_2_BIT),
    269 		[ocu] "r" (ocu));
    270 }
    271 
    272 #ifdef MIPS64_XLP
    273 /*
    274  * logical station IDs for RMI XLP
    275  */
    276 #define	RMIXLP_FMN_STID_RESERVED	0
    277 #define	RMIXLP_FMN_STID_CPU		1
    278 #define	RMIXLP_FMN_STID_POPQ		2
    279 #define	RMIXLP_FMN_STID_PCIE0		3
    280 #define	RMIXLP_FMN_STID_PCIE1		4
    281 #define	RMIXLP_FMN_STID_PCIE2		5
    282 #define	RMIXLP_FMN_STID_PCIE3		6
    283 #define	RMIXLP_FMN_STID_DMA		7
    284 #define	RMIXLP_FMN_STID_PKE		8
    285 #define	RMIXLP_FMN_STID_SAE		9
    286 #define	RMIXLP_FMN_STID_CDE		10
    287 #define	RMIXLP_FMN_STID_POE		11
    288 #define	RMIXLP_FMN_STID_NAE		12	// NAE Egress
    289 #define	RMIXLP_FMN_STID_RXE		13
    290 #define	RMIXLP_FMN_STID_SRIO		14
    291 #define	RMIXLP_FMN_STID_FMN		15
    292 #define	RMIXLP_FMN_STID_NAE_FREEIN	16
    293 #define	RMIXLP_FMN_NSTID		17
    294 #else
    295 #define	RMIXLP_FMN_NSTID		0
    296 #endif
    297 
    298 #ifdef MIPS64_XLS
    299 /*
    300  * logical station IDs for RMI XLR
    301  * see Table 13.2 "Addressable Buckets" in the XLR PRM
    302  */
    303 #define RMIXLR_FMN_STID_RESERVED		0
    304 #define RMIXLR_FMN_STID_CORE0			1
    305 #define RMIXLR_FMN_STID_CORE1			2
    306 #define RMIXLR_FMN_STID_CORE2			3
    307 #define RMIXLR_FMN_STID_CORE3			4
    308 #define RMIXLR_FMN_STID_CORE4			5
    309 #define RMIXLR_FMN_STID_CORE5			6
    310 #define RMIXLR_FMN_STID_CORE6			7
    311 #define RMIXLR_FMN_STID_CORE7			8
    312 #define RMIXLR_FMN_STID_TXRX_0			9
    313 #define RMIXLR_FMN_STID_TXRX_1			10
    314 #define RMIXLR_FMN_STID_RGMII			11
    315 #define RMIXLR_FMN_STID_DMA			12
    316 #define RMIXLR_FMN_STID_FREE_0			13
    317 #define RMIXLR_FMN_STID_FREE_1			14
    318 #define RMIXLR_FMN_STID_SAE			15
    319 #define RMIXLR_FMN_NSTID			(RMIXLR_FMN_STID_SAE+1)
    320 #else
    321 #define	RMIXLR_FMN_NSTID		0
    322 #endif
    323 
    324 #ifdef MIPS64_XLR
    325 /*
    326  * logical station IDs for RMI XLS
    327  * see Table 12.1 "Stations and Addressable Buckets ..." in the XLS PRM
    328  */
    329 #define RMIXLS_FMN_STID_RESERVED		0
    330 #define RMIXLS_FMN_STID_CORE0			1
    331 #define RMIXLS_FMN_STID_CORE1			2
    332 #define RMIXLS_FMN_STID_CORE2			3
    333 #define RMIXLS_FMN_STID_CORE3			4
    334 #define RMIXLS_FMN_STID_GMAC_Q0			5
    335 #define RMIXLS_FMN_STID_GMAC_Q1			6
    336 #define RMIXLS_FMN_STID_DMA			7
    337 #define RMIXLS_FMN_STID_CDE			8
    338 #define RMIXLS_FMN_STID_PCIE			9
    339 #define RMIXLS_FMN_STID_SAE			10
    340 #define RMIXLS_FMN_NSTID			(RMIXLS_FMN_STID_SAE+1)
    341 #else
    342 #define	RMIXLS_FMN_NSTID		0
    343 #endif
    344 
    345 #define RMIXL_FMN_NSTID		\
    346 	MAX(MAX(RMIXLR_FMN_NSTID, RMIXLS_FMN_NSTID), RMIXLP_FMN_NSTID)
    347 
    348 typedef int (*rmixl_fmn_intr_handler_t)(void *, rmixl_fmn_rxmsg_t *);
    349 
    350 void	rmixl_fmn_cpu_attach(struct cpu_info *ci);
    351 void	rmixl_fmn_init(void);
    352 void	rmixl_fmn_init_thread(void);
    353 void *	rmixl_fmn_intr_establish(size_t, rmixl_fmn_intr_handler_t, void *);
    354 void	rmixl_fmn_intr_disestablish(void *);
    355 void	rmixl_fmn_intr_poll(u_int, rmixl_fmn_rxmsg_t *);
    356 
    357 size_t	rmixl_fmn_qid_to_stid(size_t);
    358 const char *
    359 	rmixl_fmn_stid_name(size_t);
    360 
    361 /*
    362  * true == succes, false = failure
    363  */
    364 bool	rmixl_fmn_msg_send(u_int, u_int, u_int, u_int, const rmixl_fmn_msg_t *);
    365 bool	rmixl_fmn_msg_recv(u_int, rmixl_fmn_rxmsg_t *);
    366 
    367 #endif	/* _ARCH_MIPS_RMIXL_RMIXL_FMNVAR_H_ */
    368