cop2.h revision 227722
1/*- 2 * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights 3 * reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * NETLOGIC_BSD 29 * $FreeBSD: head/sys/mips/nlm/hal/cop2.h 227722 2011-11-19 14:06:15Z jchandra $ 30 */ 31 32#ifndef __NLM_HAL_COP2_H__ 33#define __NLM_HAL_COP2_H__ 34 35#define COP2_TX_BUF 0 36#define COP2_RX_BUF 1 37#define COP2_TXMSGSTATUS 2 38#define COP2_RXMSGSTATUS 3 39#define COP2_MSGSTATUS1 4 40#define COP2_MSGCONFIG 5 41#define COP2_MSGCONFIG1 6 42 43#define CROSSTHR_POPQ_EN 0x01 44#define VC0_POPQ_EN 0x02 45#define VC1_POPQ_EN 0x04 46#define VC2_POPQ_EN 0x08 47#define VC3_POPQ_EN 0x10 48#define ALL_VC_POPQ_EN 0x1E 49#define ALL_VC_CT_POPQ_EN 0x1F 50 51struct nlm_fmn_msg { 52 uint64_t msg[4]; 53}; 54 55#define NLM_DEFINE_COP2_ACCESSORS32(name, reg, sel) \ 56static inline uint32_t nlm_read_c2_##name(void) \ 57{ \ 58 uint32_t __rv; \ 59 __asm__ __volatile__ ( \ 60 ".set push\n" \ 61 ".set noreorder\n" \ 62 ".set mips64\n" \ 63 "mfc2 %0, $%1, %2\n" \ 64 ".set pop\n" \ 65 : "=r" (__rv) \ 66 : "i" (reg), "i" (sel)); \ 67 return __rv; \ 68} \ 69 \ 70static inline void nlm_write_c2_##name(uint32_t val) \ 71{ \ 72 __asm__ __volatile__( \ 73 ".set push\n" \ 74 ".set noreorder\n" \ 75 ".set mips64\n" \ 76 "mtc2 %0, $%1, %2\n" \ 77 ".set pop\n" \ 78 : : "r" (val), "i" (reg), "i" (sel)); \ 79} struct __hack 80 81#if (__mips == 64) 82#define NLM_DEFINE_COP2_ACCESSORS64(name, reg, sel) \ 83static inline uint64_t nlm_read_c2_##name(void) \ 84{ \ 85 uint64_t __rv; \ 86 __asm__ __volatile__ ( \ 87 ".set push\n" \ 88 ".set noreorder\n" \ 89 ".set mips64\n" \ 90 "dmfc2 %0, $%1, %2\n" \ 91 ".set pop\n" \ 92 : "=r" (__rv) \ 93 : "i" (reg), "i" (sel)); \ 94 return __rv; \ 95} \ 96 \ 97static inline void nlm_write_c2_##name(uint64_t val) \ 98{ \ 99 __asm__ __volatile__ ( \ 100 ".set push\n" \ 101 ".set noreorder\n" \ 102 ".set mips64\n" \ 103 "dmtc2 %0, $%1, %2\n" \ 104 ".set pop\n" \ 105 : : "r" (val), "i" (reg), "i" (sel)); \ 106} struct __hack 107 108#else 109 110#define NLM_DEFINE_COP2_ACCESSORS64(name, reg, sel) \ 111static inline uint64_t nlm_read_c2_##name(void) \ 112{ \ 113 uint32_t __high, __low; \ 114 __asm__ __volatile__ ( \ 115 ".set push\n" \ 116 ".set noreorder\n" \ 117 ".set mips64\n" \ 118 "dmfc2 $8, $%2, %3\n" \ 119 "dsra32 %0, $8, 0\n" \ 120 "sll %1, $8, 0\n" \ 121 ".set pop\n" \ 122 : "=r"(__high), "=r"(__low) \ 123 : "i"(reg), "i"(sel) \ 124 : "$8"); \ 125 \ 126 return ((uint64_t)__high << 32) | __low; \ 127} \ 128 \ 129static inline void nlm_write_c2_##name(uint64_t val) \ 130{ \ 131 uint32_t __high = val >> 32; \ 132 uint32_t __low = val & 0xffffffff; \ 133 __asm__ __volatile__ ( \ 134 ".set push\n" \ 135 ".set noreorder\n" \ 136 ".set mips64\n" \ 137 "dsll32 $8, %1, 0\n" \ 138 "dsll32 $9, %0, 0\n" \ 139 "dsrl32 $8, $8, 0\n" \ 140 "or $8, $8, $9\n" \ 141 "dmtc2 $8, $%2, %3\n" \ 142 ".set pop\n" \ 143 : : "r"(__high), "r"(__low), "i"(reg), "i"(sel) \ 144 : "$8", "$9"); \ 145} struct __hack 146 147#endif 148 149NLM_DEFINE_COP2_ACCESSORS64(txbuf0, COP2_TX_BUF, 0); 150NLM_DEFINE_COP2_ACCESSORS64(txbuf1, COP2_TX_BUF, 1); 151NLM_DEFINE_COP2_ACCESSORS64(txbuf2, COP2_TX_BUF, 2); 152NLM_DEFINE_COP2_ACCESSORS64(txbuf3, COP2_TX_BUF, 3); 153 154NLM_DEFINE_COP2_ACCESSORS64(rxbuf0, COP2_RX_BUF, 0); 155NLM_DEFINE_COP2_ACCESSORS64(rxbuf1, COP2_RX_BUF, 1); 156NLM_DEFINE_COP2_ACCESSORS64(rxbuf2, COP2_RX_BUF, 2); 157NLM_DEFINE_COP2_ACCESSORS64(rxbuf3, COP2_RX_BUF, 3); 158 159NLM_DEFINE_COP2_ACCESSORS32(txmsgstatus, COP2_TXMSGSTATUS, 0); 160NLM_DEFINE_COP2_ACCESSORS32(rxmsgstatus, COP2_RXMSGSTATUS, 0); 161NLM_DEFINE_COP2_ACCESSORS32(msgstatus1, COP2_MSGSTATUS1, 0); 162NLM_DEFINE_COP2_ACCESSORS32(msgconfig, COP2_MSGCONFIG, 0); 163NLM_DEFINE_COP2_ACCESSORS32(msgconfig1, COP2_MSGCONFIG1, 0); 164 165/* successful completion returns 1, else 0 */ 166static inline int 167nlm_msgsend(int val) 168{ 169 int result; 170 __asm__ volatile ( 171 ".set push\n" 172 ".set noreorder\n" 173 ".set mips64\n" 174 "move $8, %1\n" 175 "sync\n" 176 "/* msgsnds $9, $8 */\n" 177 ".word 0x4a084801\n" 178 "move %0, $9\n" 179 ".set pop\n" 180 : "=r" (result) 181 : "r" (val) 182 : "$8", "$9"); 183 return result; 184} 185 186static inline int 187nlm_msgld(int vc) 188{ 189 int val; 190 __asm__ volatile ( 191 ".set push\n" 192 ".set noreorder\n" 193 ".set mips64\n" 194 "move $8, %1\n" 195 "/* msgld $9, $8 */\n" 196 ".word 0x4a084802\n" 197 "move %0, $9\n" 198 ".set pop\n" 199 : "=r" (val) 200 : "r" (vc) 201 : "$8", "$9"); 202 return val; 203} 204 205static inline void 206nlm_msgwait(int vc) 207{ 208 __asm__ volatile ( 209 ".set push\n" 210 ".set noreorder\n" 211 ".set mips64\n" 212 "move $8, %0\n" 213 "/* msgwait $8 */\n" 214 ".word 0x4a080003\n" 215 ".set pop\n" 216 : : "r" (vc) 217 : "$8"); 218} 219 220static inline int 221nlm_fmn_msgsend(int dstid, int size, int swcode, struct nlm_fmn_msg *m) 222{ 223 uint32_t flags, status; 224 int rv; 225 226 size -= 1; 227 flags = nlm_save_flags_cop2(); 228 switch (size) { 229 case 3: 230 nlm_write_c2_txbuf3(m->msg[3]); 231 case 2: 232 nlm_write_c2_txbuf2(m->msg[2]); 233 case 1: 234 nlm_write_c2_txbuf1(m->msg[1]); 235 case 0: 236 nlm_write_c2_txbuf0(m->msg[0]); 237 } 238 239 dstid |= ((swcode << 24) | (size << 16)); 240 status = nlm_msgsend(dstid); 241 rv = !status; 242 if (rv != 0) 243 rv = nlm_read_c2_txmsgstatus(); 244 nlm_restore_flags(flags); 245 246 return rv; 247} 248 249static inline int 250nlm_fmn_msgrcv(int vc, int *srcid, int *size, int *code, struct nlm_fmn_msg *m) 251{ 252 uint32_t status; 253 uint32_t msg_status, flags; 254 int tmp_sz, rv; 255 256 flags = nlm_save_flags_cop2(); 257 status = nlm_msgld(vc); /* will return 0, if error */ 258 rv = !status; 259 if (rv == 0) { 260 msg_status = nlm_read_c2_rxmsgstatus(); 261 *size = ((msg_status >> 26) & 0x3) + 1; 262 *code = (msg_status >> 18) & 0xff; 263 *srcid = (msg_status >> 4) & 0xfff; 264 tmp_sz = *size - 1; 265 switch (tmp_sz) { 266 case 3: 267 m->msg[3] = nlm_read_c2_rxbuf3(); 268 case 2: 269 m->msg[2] = nlm_read_c2_rxbuf2(); 270 case 1: 271 m->msg[1] = nlm_read_c2_rxbuf1(); 272 case 0: 273 m->msg[0] = nlm_read_c2_rxbuf0(); 274 } 275 } 276 nlm_restore_flags(flags); 277 278 return rv; 279} 280 281static inline void 282nlm_fmn_cpu_init(int int_vec, int ctpe, int v0pe, int v1pe, int v2pe, int v3pe) 283{ 284 uint32_t val = nlm_read_c2_msgconfig(); 285 286 /* Note: in XLP PRM 0.8.1, the int_vec bits are un-documented 287 * in msgconfig register of cop2. 288 * As per chip/cpu RTL, [16:20] bits consist of int_vec. 289 */ 290 val |= ((int_vec & 0x1f) << 16) | 291 ((v3pe & 0x1) << 4) | 292 ((v2pe & 0x1) << 3) | 293 ((v1pe & 0x1) << 2) | 294 ((v0pe & 0x1) << 1) | 295 (ctpe & 0x1); 296 297 nlm_write_c2_msgconfig(val); 298} 299#endif 300