1 1.5 mrg /* $NetBSD: rmixl_fmn.c,v 1.5 2023/08/11 07:05:39 mrg Exp $ */ 2 1.2 matt /*- 3 1.2 matt * Copyright (c) 2010 The NetBSD Foundation, Inc. 4 1.2 matt * All rights reserved. 5 1.2 matt * 6 1.2 matt * This code is derived from software contributed to The NetBSD Foundation 7 1.2 matt * by Cliff Neighbors. 8 1.2 matt * 9 1.2 matt * Redistribution and use in source and binary forms, with or without 10 1.2 matt * modification, are permitted provided that the following conditions 11 1.2 matt * are met: 12 1.2 matt * 1. Redistributions of source code must retain the above copyright 13 1.2 matt * notice, this list of conditions and the following disclaimer. 14 1.2 matt * 2. Redistributions in binary form must reproduce the above copyright 15 1.2 matt * notice, this list of conditions and the following disclaimer in the 16 1.2 matt * documentation and/or other materials provided with the distribution. 17 1.2 matt * 18 1.2 matt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 1.2 matt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 1.2 matt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 1.2 matt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 1.2 matt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 1.2 matt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 1.2 matt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 1.2 matt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 1.2 matt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 1.2 matt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 1.2 matt * POSSIBILITY OF SUCH DAMAGE. 29 1.2 matt */ 30 1.2 matt 31 1.2 matt #include "opt_ddb.h" 32 1.2 matt 33 1.2 matt #include <sys/cdefs.h> 34 1.2 matt #include <sys/param.h> 35 1.2 matt #include <sys/systm.h> 36 1.2 matt #include <sys/cpu.h> 37 1.2 matt #include <mips/cpuregs.h> 38 1.2 matt #include <mips/rmi/rmixlreg.h> 39 1.2 matt #include <mips/rmi/rmixlvar.h> 40 1.2 matt #include <mips/rmi/rmixl_intr.h> 41 1.2 matt #include <mips/rmi/rmixl_fmnvar.h> 42 1.2 matt 43 1.2 matt #ifdef FMN_DEBUG 44 1.2 matt # define DPRINTF(x) do { printf x ; } while(0) 45 1.2 matt #else 46 1.2 matt # define DPRINTF(x) 47 1.2 matt #endif 48 1.2 matt 49 1.2 matt #ifdef DIAGNOSTIC 50 1.2 matt # define DIAG_PRF(x) do { printf x ; } while(0) 51 1.2 matt #else 52 1.2 matt # define DIAG_PRF(x) 53 1.2 matt #endif 54 1.2 matt 55 1.2 matt 56 1.2 matt 57 1.2 matt /* 58 1.2 matt * index CPU-dependent table by (global) bucket ID to obtain logical Station ID 59 1.2 matt * see Table 12.1 in the XLS PRM 60 1.2 matt */ 61 1.2 matt /* use this table for XLS6xx, XLS4xx */ 62 1.2 matt static const int station_xls_4xx[] = { 63 1.2 matt [0 ... 7] = RMIXLS_FMN_STID_CORE0, 64 1.2 matt [8 ... 15] = RMIXLS_FMN_STID_CORE1, 65 1.2 matt [16 ... 23] = RMIXLS_FMN_STID_CORE2, 66 1.2 matt [24 ... 31] = RMIXLS_FMN_STID_CORE3, 67 1.2 matt [32 ... 63] = RMIXLS_FMN_STID_RESERVED, 68 1.2 matt [64 ... 71] = RMIXLS_FMN_STID_PCIE, 69 1.2 matt [72 ... 79] = RMIXLS_FMN_STID_RESERVED, 70 1.2 matt [80 ... 87] = RMIXLS_FMN_STID_GMAC_Q1, 71 1.2 matt [88 ... 95] = RMIXLS_FMN_STID_RESERVED, 72 1.2 matt [96 ... 103] = RMIXLS_FMN_STID_GMAC_Q0, 73 1.2 matt [104 ... 107] = RMIXLS_FMN_STID_DMA, 74 1.2 matt [108 ... 109] = RMIXLS_FMN_STID_CDE, 75 1.2 matt [110 ... 119] = RMIXLS_FMN_STID_RESERVED, 76 1.2 matt [120 ... 127] = RMIXLS_FMN_STID_SAE, 77 1.2 matt }; 78 1.2 matt 79 1.2 matt /* use this table for XLS408Lite, XLS404Lite */ 80 1.2 matt static const int station_xls_4xx_lite[] = { 81 1.2 matt [0 ... 7] = RMIXLS_FMN_STID_CORE0, 82 1.2 matt [8 ... 15] = RMIXLS_FMN_STID_CORE1, 83 1.2 matt [16 ... 23] = RMIXLS_FMN_STID_CORE2, 84 1.2 matt [24 ... 31] = RMIXLS_FMN_STID_CORE3, 85 1.2 matt [32 ... 79] = RMIXLS_FMN_STID_RESERVED, 86 1.2 matt [80 ... 87] = RMIXLS_FMN_STID_GMAC_Q1, 87 1.2 matt [88 ... 95] = RMIXLS_FMN_STID_RESERVED, 88 1.2 matt [96 ... 103] = RMIXLS_FMN_STID_GMAC_Q0, 89 1.2 matt [104 ... 107] = RMIXLS_FMN_STID_DMA, 90 1.2 matt [108 ... 109] = RMIXLS_FMN_STID_CDE, 91 1.2 matt [110 ... 115] = RMIXLS_FMN_STID_RESERVED, 92 1.2 matt [116 ... 119] = RMIXLS_FMN_STID_PCIE, 93 1.2 matt [120 ... 127] = RMIXLS_FMN_STID_SAE, 94 1.2 matt }; 95 1.2 matt 96 1.2 matt /* use this table for XLS2xx */ 97 1.2 matt static const int station_xls_2xx[] = { 98 1.2 matt [0 ... 7] = RMIXLS_FMN_STID_CORE0, 99 1.2 matt [8 ... 15] = RMIXLS_FMN_STID_CORE1, 100 1.2 matt [16 ... 23] = RMIXLS_FMN_STID_CORE2, 101 1.2 matt [24 ... 31] = RMIXLS_FMN_STID_CORE3, 102 1.2 matt [32 ... 63] = RMIXLS_FMN_STID_RESERVED, 103 1.2 matt [64 ... 71] = RMIXLS_FMN_STID_PCIE, 104 1.2 matt [72 ... 95] = RMIXLS_FMN_STID_RESERVED, 105 1.2 matt [96 ... 103] = RMIXLS_FMN_STID_GMAC_Q0, 106 1.2 matt [104 ... 107] = RMIXLS_FMN_STID_DMA, 107 1.2 matt [108 ... 119] = RMIXLS_FMN_STID_RESERVED, 108 1.2 matt [120 ... 127] = RMIXLS_FMN_STID_SAE, 109 1.2 matt }; 110 1.2 matt 111 1.2 matt /* use this table for XLS1xx */ 112 1.2 matt static const int station_xls_1xx[] = { 113 1.2 matt [0 ... 7] = RMIXLS_FMN_STID_CORE0, 114 1.2 matt [8 ... 15] = RMIXLS_FMN_STID_CORE1, 115 1.2 matt [16 ... 23] = RMIXLS_FMN_STID_CORE2, 116 1.2 matt [24 ... 31] = RMIXLS_FMN_STID_CORE3, 117 1.2 matt [32 ... 63] = RMIXLS_FMN_STID_RESERVED, 118 1.2 matt [64 ... 71] = RMIXLS_FMN_STID_PCIE, 119 1.2 matt [72 ... 95] = RMIXLS_FMN_STID_RESERVED, 120 1.2 matt [96 ... 101] = RMIXLS_FMN_STID_GMAC_Q0, 121 1.2 matt [102 ... 103] = RMIXLS_FMN_STID_RESERVED, 122 1.2 matt [104 ... 107] = RMIXLS_FMN_STID_DMA, 123 1.2 matt [108 ... 119] = RMIXLS_FMN_STID_RESERVED, 124 1.2 matt [120 ... 127] = RMIXLS_FMN_STID_SAE, 125 1.2 matt }; 126 1.2 matt 127 1.2 matt /* use this table for XLRxxx */ 128 1.2 matt static const int station_xlr_xxx[] = { 129 1.2 matt [0 ... 7] = RMIXLR_FMN_STID_CORE0, 130 1.2 matt [8 ... 15] = RMIXLR_FMN_STID_CORE1, 131 1.2 matt [16 ... 23] = RMIXLR_FMN_STID_CORE2, 132 1.2 matt [24 ... 31] = RMIXLR_FMN_STID_CORE3, 133 1.2 matt [32 ... 39] = RMIXLR_FMN_STID_CORE4, 134 1.2 matt [40 ... 47] = RMIXLR_FMN_STID_CORE5, 135 1.2 matt [48 ... 55] = RMIXLR_FMN_STID_CORE6, 136 1.2 matt [56 ... 63] = RMIXLR_FMN_STID_CORE7, 137 1.2 matt [64 ... 79] = RMIXLR_FMN_STID_TXRX_0, 138 1.2 matt [80 ... 95] = RMIXLR_FMN_STID_TXRX_1, 139 1.2 matt [96 ... 103] = RMIXLR_FMN_STID_RGMII, 140 1.2 matt [104 ... 107] = RMIXLR_FMN_STID_DMA, 141 1.2 matt [108 ... 111] = RMIXLR_FMN_STID_RESERVED, 142 1.2 matt [112 ... 113] = RMIXLR_FMN_STID_FREE_0, 143 1.2 matt [114 ... 115] = RMIXLR_FMN_STID_FREE_0, 144 1.2 matt [116 ... 119] = RMIXLR_FMN_STID_RESERVED, 145 1.2 matt [120 ... 127] = RMIXLR_FMN_STID_SAE, 146 1.2 matt }; 147 1.2 matt 148 1.2 matt typedef struct fmn_station_info { 149 1.2 matt const char *si_name; 150 1.2 matt const u_int si_buckets_max; 151 1.2 matt const u_int si_stid_first; 152 1.2 matt const u_int si_stid_last; 153 1.2 matt const u_int si_bucket_size_dflt; 154 1.2 matt const u_int si_credits_min; 155 1.2 matt const u_int si_regbase; 156 1.2 matt } fmn_station_info_t; 157 1.2 matt 158 1.2 matt /* use this table for XLS6xx, XLS4xx */ 159 1.2 matt static const fmn_station_info_t station_info_xls_4xx[RMIXLS_FMN_NSTID] = { 160 1.2 matt [RMIXLS_FMN_STID_CORE0] = { "core0", 8, 0, 7, 32, 4, 0 }, 161 1.2 matt [RMIXLS_FMN_STID_CORE1] = { "core1", 8, 8, 15, 32, 4, 0 }, 162 1.2 matt [RMIXLS_FMN_STID_CORE2] = { "core2", 8, 16, 23, 32, 4, 0 }, 163 1.2 matt [RMIXLS_FMN_STID_CORE3] = { "core3", 8, 24, 31, 32, 4, 0 }, 164 1.2 matt [RMIXLS_FMN_STID_GMAC_Q0] = { "gmac_q0", 3, 80, 87, 32, 0, RMIXL_IO_DEV_GMAC_0 }, 165 1.2 matt [RMIXLS_FMN_STID_GMAC_Q1] = { "gmac_q1", 3, 96, 103, 32, 0, RMIXL_IO_DEV_GMAC_4 }, 166 1.2 matt [RMIXLS_FMN_STID_DMA] = { "dma", 4, 104, 107, 64, 0, RMIXL_IO_DEV_DMA }, 167 1.2 matt [RMIXLS_FMN_STID_CDE] = { "cde", 4, 108, 109, 128, 0, RMIXL_IO_DEV_CDE }, 168 1.2 matt [RMIXLS_FMN_STID_PCIE] = { "pcie", 8, 64, 71, 32, 0, RMIXL_IO_DEV_PCIE_BE }, 169 1.2 matt [RMIXLS_FMN_STID_SAE] = { "sae", 2, 120, 121, 128, 0, RMIXL_IO_DEV_SAE }, 170 1.2 matt }; 171 1.2 matt 172 1.2 matt /* use this table for XLS4xxLite */ 173 1.2 matt static const fmn_station_info_t station_info_xls_4xx_lite[RMIXLS_FMN_NSTID] = { 174 1.2 matt [RMIXLS_FMN_STID_CORE0] = { "core0", 8, 0, 7, 32, 4, 0 }, 175 1.2 matt [RMIXLS_FMN_STID_CORE1] = { "core1", 8, 8, 15, 32, 4, 0 }, 176 1.2 matt [RMIXLS_FMN_STID_CORE2] = { "core2", 8, 16, 23, 32, 4, 0 }, 177 1.2 matt [RMIXLS_FMN_STID_CORE3] = { "core3", 8, 24, 31, 32, 4, 0 }, 178 1.2 matt [RMIXLS_FMN_STID_GMAC_Q0] = { "gmac_q0", 3, 80, 87, 32, 0, RMIXL_IO_DEV_GMAC_0 }, 179 1.2 matt [RMIXLS_FMN_STID_GMAC_Q1] = { "gmac_q1", 3, 96, 103, 32, 0, RMIXL_IO_DEV_GMAC_4 }, 180 1.2 matt [RMIXLS_FMN_STID_DMA] = { "dma", 4, 104, 107, 64, 0, RMIXL_IO_DEV_DMA }, 181 1.2 matt [RMIXLS_FMN_STID_CDE] = { "cde", 4, 108, 109, 128, 0, RMIXL_IO_DEV_CDE }, 182 1.2 matt [RMIXLS_FMN_STID_PCIE] = { "pcie", 4, 116, 119, 64, 0, RMIXL_IO_DEV_PCIE_BE }, 183 1.2 matt [RMIXLS_FMN_STID_SAE] = { "sae", 2, 120, 121, 128, 0, RMIXL_IO_DEV_SAE }, 184 1.2 matt }; 185 1.2 matt 186 1.2 matt /* use this table for XLS2xx */ 187 1.2 matt static const fmn_station_info_t station_info_xls_2xx[RMIXLS_FMN_NSTID] = { 188 1.2 matt [RMIXLS_FMN_STID_CORE0] = { "core0", 8, 0, 7, 32, 4, 0 }, 189 1.2 matt [RMIXLS_FMN_STID_CORE1] = { "core1", 8, 8, 15, 32, 4, 0 }, 190 1.2 matt [RMIXLS_FMN_STID_CORE2] = { "core2", 8, 16, 23, 32, 4, 0 }, 191 1.2 matt [RMIXLS_FMN_STID_CORE3] = { "core3", 8, 24, 31, 32, 4, 0 }, 192 1.2 matt [RMIXLS_FMN_STID_GMAC_Q0] = { "gmac_q0", 3, 96, 103, 32, 0, RMIXL_IO_DEV_GMAC_0 }, 193 1.2 matt [RMIXLS_FMN_STID_DMA] = { "dma", 4, 104, 107, 64, 0, RMIXL_IO_DEV_DMA }, 194 1.2 matt [RMIXLS_FMN_STID_PCIE] = { "pcie", 8, 64, 71, 32, 0, RMIXL_IO_DEV_PCIE_BE }, 195 1.2 matt [RMIXLS_FMN_STID_SAE] = { "sae", 2, 120, 121, 128, 0, RMIXL_IO_DEV_SAE }, 196 1.2 matt }; 197 1.2 matt 198 1.2 matt /* use this table for XLS1xx */ 199 1.2 matt static const fmn_station_info_t station_info_xls_1xx[RMIXLS_FMN_NSTID] = { 200 1.2 matt [RMIXLS_FMN_STID_CORE0] = { "core0", 8, 0, 7, 32, 4, 0 }, 201 1.2 matt [RMIXLS_FMN_STID_CORE1] = { "core1", 8, 8, 15, 32, 4, 0 }, 202 1.2 matt [RMIXLS_FMN_STID_CORE2] = { "core2", 8, 16, 23, 32, 4, 0 }, 203 1.2 matt [RMIXLS_FMN_STID_CORE3] = { "core3", 8, 24, 31, 32, 4, 0 }, 204 1.2 matt [RMIXLS_FMN_STID_GMAC_Q0] = { "gmac_q0", 3, 96, 101, 32, 0, RMIXL_IO_DEV_GMAC_0 }, 205 1.2 matt [RMIXLS_FMN_STID_DMA] = { "dma", 4, 104, 107, 64, 0, RMIXL_IO_DEV_PCIE_BE }, 206 1.2 matt [RMIXLS_FMN_STID_PCIE] = { "pcie", 4, 64, 67, 32, 0, RMIXL_IO_DEV_PCIE_BE }, 207 1.2 matt [RMIXLS_FMN_STID_SAE] = { "sae", 2, 120, 121, 128, 0, RMIXL_IO_DEV_SAE }, 208 1.2 matt }; 209 1.2 matt 210 1.2 matt /* 211 1.2 matt * use this table for XLRxxx 212 1.2 matt * caution: 213 1.2 matt * - the XGMII/SPI4 stations si_regbase are 'special' 214 1.2 matt * - the RGMII station si_regbase is 'special' 215 1.2 matt */ 216 1.2 matt static const fmn_station_info_t station_info_xlr_xxx[RMIXLR_FMN_NSTID] = { 217 1.2 matt [RMIXLR_FMN_STID_CORE0] = { "core0", 8, 0, 7, 32, 4, 0 }, 218 1.2 matt [RMIXLR_FMN_STID_CORE1] = { "core1", 8, 8, 15, 32, 4, 0 }, 219 1.2 matt [RMIXLR_FMN_STID_CORE2] = { "core2", 8, 16, 23, 32, 4, 0 }, 220 1.2 matt [RMIXLR_FMN_STID_CORE3] = { "core3", 8, 24, 31, 32, 4, 0 }, 221 1.2 matt [RMIXLR_FMN_STID_CORE4] = { "core4", 8, 32, 39, 32, 4, 0 }, 222 1.2 matt [RMIXLR_FMN_STID_CORE5] = { "core5", 8, 40, 47, 32, 4, 0 }, 223 1.2 matt [RMIXLR_FMN_STID_CORE6] = { "core6", 8, 48, 55, 32, 4, 0 }, 224 1.2 matt [RMIXLR_FMN_STID_CORE7] = { "core7", 8, 56, 63, 32, 4, 0 }, 225 1.2 matt [RMIXLR_FMN_STID_TXRX_0] = { "txrx0", 1, 64, 79, 16, 0, RMIXL_IO_DEV_XGMAC_A }, 226 1.2 matt [RMIXLR_FMN_STID_TXRX_1] = { "txrx1", 1, 80, 95, 16, 0, RMIXL_IO_DEV_XGMAC_B }, 227 1.2 matt [RMIXLR_FMN_STID_RGMII] = { "rgmii", 8, 96, 103, 32, 0, RMIXL_IO_DEV_GMAC_A }, 228 1.2 matt [RMIXLR_FMN_STID_DMA] = { "dma", 4, 104, 107, 64, 0, RMIXL_IO_DEV_DMA }, 229 1.2 matt [RMIXLR_FMN_STID_FREE_0] = { "free0", 2, 112, 113, 128, 0, RMIXL_IO_DEV_XGMAC_A }, 230 1.2 matt [RMIXLR_FMN_STID_FREE_1] = { "free1", 2, 114, 115, 128, 0, RMIXL_IO_DEV_XGMAC_B }, 231 1.2 matt [RMIXLR_FMN_STID_SAE] = { "sae", 5, 120, 124, 32, 0, RMIXL_IO_DEV_SAE }, 232 1.2 matt }; 233 1.2 matt 234 1.2 matt 235 1.2 matt typedef struct fmn_intrhand { 236 1.2 matt int (*ih_func)(void *, rmixl_fmn_rxmsg_t *); 237 1.2 matt void *ih_arg; 238 1.2 matt struct evcnt ih_count; 239 1.2 matt } fmn_intrhand_t; 240 1.2 matt 241 1.2 matt /* 242 1.2 matt * per-core FMN structure 243 1.2 matt */ 244 1.2 matt typedef struct fmn { 245 1.2 matt kmutex_t *fmn_lock; 246 1.2 matt u_int fmn_core; 247 1.2 matt u_int fmn_thread; 248 1.2 matt u_int fmn_nstid; 249 1.2 matt const int *fmn_stidtab; 250 1.2 matt const fmn_station_info_t *fmn_stinfo; 251 1.2 matt void *fmn_ih; 252 1.2 matt fmn_intrhand_t fmn_intrhand[RMIXL_FMN_NSTID]; 253 1.2 matt } fmn_t; 254 1.2 matt 255 1.2 matt static fmn_t fmn_store[1 << 10]; /* index by cpuid) *//* XXX assumes 1 node */ 256 1.2 matt #define NFMN (sizeof(fmn_store) / sizeof(fmn_store[0])) 257 1.2 matt 258 1.2 matt static fmn_t * 259 1.2 matt fmn_lookup(cpuid_t cpuid) 260 1.2 matt { 261 1.2 matt KASSERT(cpuid < (cpuid_t)NFMN); 262 1.2 matt return &fmn_store[cpuid]; 263 1.2 matt } 264 1.2 matt 265 1.2 matt static void rmixl_fmn_init_core_xlr(fmn_t *); 266 1.2 matt static void rmixl_fmn_init_core_xls(fmn_t *); 267 1.2 matt static void rmixl_fmn_config_noncore(fmn_t *); 268 1.2 matt static void rmixl_fmn_config_core(fmn_t *); 269 1.2 matt #ifdef NOTYET 270 1.2 matt static int rmixl_fmn_intr_dispatch(void *); 271 1.2 matt #endif /* NOTYET */ 272 1.2 matt static int rmixl_fmn_msg_recv_subr(u_int, rmixl_fmn_rxmsg_t *); 273 1.2 matt 274 1.2 matt #ifdef FMN_DEBUG 275 1.2 matt void rmixl_fmn_cp2_dump(void); 276 1.2 matt void rmixl_fmn_cc_dump(void); 277 1.2 matt #endif 278 1.2 matt 279 1.2 matt /* 280 1.2 matt * macros used because mtc2, mfc2, dmtc2, dmfc2 instructions 281 1.2 matt * must use literal values for rd and sel operands 282 1.2 matt * so let the compiler sort it out 283 1.2 matt */ 284 1.2 matt 285 1.2 matt /* 286 1.2 matt * write v to all 8 SELs for given RD 287 1.2 matt */ 288 1.2 matt #define FMN_CP2_4SEL_READ(rd, sel, vp) \ 289 1.2 matt do { \ 290 1.2 matt uint32_t *rp = vp; \ 291 1.2 matt RMIXL_MFC2(rd, sel, rp[0]); \ 292 1.2 matt RMIXL_MFC2(rd, sel+1, rp[1]); \ 293 1.2 matt RMIXL_MFC2(rd, sel+2, rp[2]); \ 294 1.2 matt RMIXL_MFC2(rd, sel+3, rp[3]); \ 295 1.2 matt } while (0) 296 1.2 matt 297 1.2 matt /* 298 1.2 matt * write v to all 8 SELs for given RD 299 1.2 matt */ 300 1.2 matt #define FMN_CP2_4SEL_WRITE(rd, sel, v) \ 301 1.2 matt do { \ 302 1.2 matt RMIXL_MTC2(rd, sel, v); \ 303 1.2 matt RMIXL_MTC2(rd, sel+1, v); \ 304 1.2 matt RMIXL_MTC2(rd, sel+2, v); \ 305 1.2 matt RMIXL_MTC2(rd, sel+3, v); \ 306 1.2 matt } while (0) 307 1.2 matt 308 1.2 matt #define FMN_CP2_8SEL_WRITE(rd, v) \ 309 1.2 matt do { \ 310 1.2 matt RMIXL_MTC2(rd, 0, v); \ 311 1.2 matt RMIXL_MTC2(rd, 1, v); \ 312 1.2 matt RMIXL_MTC2(rd, 2, v); \ 313 1.2 matt RMIXL_MTC2(rd, 3, v); \ 314 1.2 matt RMIXL_MTC2(rd, 4, v); \ 315 1.2 matt RMIXL_MTC2(rd, 5, v); \ 316 1.2 matt RMIXL_MTC2(rd, 6, v); \ 317 1.2 matt RMIXL_MTC2(rd, 7, v); \ 318 1.2 matt } while (0) 319 1.2 matt 320 1.2 matt 321 1.2 matt #define FMN_CP2_SEL_CASE_READ(rd, sel, v) \ 322 1.2 matt case sel: \ 323 1.2 matt RMIXL_MFC2(rd, sel, v); \ 324 1.2 matt break 325 1.2 matt #define FMN_CP2_SEL_CASE_WRITE(rd, sel, v) \ 326 1.2 matt case sel: \ 327 1.2 matt RMIXL_MTC2(rd, sel, v); \ 328 1.2 matt break 329 1.2 matt /* 330 1.2 matt * read/write a single arbitrary sel for the given rd 331 1.2 matt */ 332 1.2 matt #define FMN_CP2_SEL_SWITCH_RW(rw, rd, sel, val) \ 333 1.2 matt do { \ 334 1.2 matt switch (sel) { \ 335 1.2 matt FMN_CP2_SEL_CASE_ ## rw(rd, 0, val); \ 336 1.2 matt FMN_CP2_SEL_CASE_ ## rw(rd, 1, val); \ 337 1.2 matt FMN_CP2_SEL_CASE_ ## rw(rd, 2, val); \ 338 1.2 matt FMN_CP2_SEL_CASE_ ## rw(rd, 3, val); \ 339 1.2 matt FMN_CP2_SEL_CASE_ ## rw(rd, 4, val); \ 340 1.2 matt FMN_CP2_SEL_CASE_ ## rw(rd, 5, val); \ 341 1.2 matt FMN_CP2_SEL_CASE_ ## rw(rd, 6, val); \ 342 1.2 matt FMN_CP2_SEL_CASE_ ## rw(rd, 7, val); \ 343 1.2 matt default: \ 344 1.2 matt panic("%s:%d: bad sel %d\n", \ 345 1.2 matt __func__, __LINE__, sel); \ 346 1.2 matt } \ 347 1.2 matt } while (0) 348 1.2 matt 349 1.2 matt #define FMN_CP2_RD_CASE_RW(rw, rd, sel, val) \ 350 1.2 matt case rd: \ 351 1.2 matt FMN_CP2_SEL_SWITCH_RW(rw, rd, sel, val); \ 352 1.2 matt break 353 1.2 matt /* 354 1.2 matt * read/write a single arbitrary Credit Counter at (rd, sel) 355 1.2 matt * eg: 356 1.2 matt * FMN_CP2_RD_SWITCH_RW(READ, 16, 2, val) 357 1.2 matt * FMN_CP2_RD_SWITCH_RW(WRITE, 18, 0, val) 358 1.2 matt */ 359 1.2 matt #define FMN_CP2_RD_SWITCH_RW(rw, rd, sel, val) \ 360 1.2 matt do { \ 361 1.2 matt switch(rd) { \ 362 1.2 matt FMN_CP2_RD_CASE_RW(rw, 0, sel, val); \ 363 1.2 matt FMN_CP2_RD_CASE_RW(rw, 1, sel, val); \ 364 1.2 matt FMN_CP2_RD_CASE_RW(rw, 2, sel, val); \ 365 1.2 matt FMN_CP2_RD_CASE_RW(rw, 3, sel, val); \ 366 1.2 matt FMN_CP2_RD_CASE_RW(rw, 4, sel, val); \ 367 1.2 matt FMN_CP2_RD_CASE_RW(rw, 5, sel, val); \ 368 1.2 matt FMN_CP2_RD_CASE_RW(rw, 6, sel, val); \ 369 1.2 matt FMN_CP2_RD_CASE_RW(rw, 7, sel, val); \ 370 1.2 matt FMN_CP2_RD_CASE_RW(rw, 8, sel, val); \ 371 1.2 matt FMN_CP2_RD_CASE_RW(rw, 9, sel, val); \ 372 1.2 matt FMN_CP2_RD_CASE_RW(rw, 10, sel, val); \ 373 1.2 matt FMN_CP2_RD_CASE_RW(rw, 11, sel, val); \ 374 1.2 matt FMN_CP2_RD_CASE_RW(rw, 12, sel, val); \ 375 1.2 matt FMN_CP2_RD_CASE_RW(rw, 13, sel, val); \ 376 1.2 matt FMN_CP2_RD_CASE_RW(rw, 14, sel, val); \ 377 1.2 matt FMN_CP2_RD_CASE_RW(rw, 15, sel, val); \ 378 1.2 matt FMN_CP2_RD_CASE_RW(rw, 16, sel, val); \ 379 1.2 matt FMN_CP2_RD_CASE_RW(rw, 17, sel, val); \ 380 1.2 matt FMN_CP2_RD_CASE_RW(rw, 18, sel, val); \ 381 1.2 matt FMN_CP2_RD_CASE_RW(rw, 19, sel, val); \ 382 1.2 matt FMN_CP2_RD_CASE_RW(rw, 20, sel, val); \ 383 1.2 matt FMN_CP2_RD_CASE_RW(rw, 21, sel, val); \ 384 1.2 matt FMN_CP2_RD_CASE_RW(rw, 22, sel, val); \ 385 1.2 matt FMN_CP2_RD_CASE_RW(rw, 23, sel, val); \ 386 1.2 matt FMN_CP2_RD_CASE_RW(rw, 24, sel, val); \ 387 1.2 matt FMN_CP2_RD_CASE_RW(rw, 25, sel, val); \ 388 1.2 matt FMN_CP2_RD_CASE_RW(rw, 26, sel, val); \ 389 1.2 matt FMN_CP2_RD_CASE_RW(rw, 27, sel, val); \ 390 1.2 matt FMN_CP2_RD_CASE_RW(rw, 28, sel, val); \ 391 1.2 matt FMN_CP2_RD_CASE_RW(rw, 29, sel, val); \ 392 1.2 matt FMN_CP2_RD_CASE_RW(rw, 30, sel, val); \ 393 1.2 matt FMN_CP2_RD_CASE_RW(rw, 31, sel, val); \ 394 1.2 matt default: \ 395 1.2 matt panic("%s:%d: bad regno %d\n", \ 396 1.2 matt __func__, __LINE__, rd); \ 397 1.2 matt } \ 398 1.2 matt } while (0) 399 1.2 matt 400 1.2 matt 401 1.2 matt void 402 1.2 matt rmixl_fmn_init(void) 403 1.2 matt { 404 1.2 matt int cpu; 405 1.2 matt fmn_t *fmnp; 406 1.2 matt static bool once=false; 407 1.2 matt 408 1.4 jym KASSERTMSG((CPU_IS_PRIMARY(curcpu())), "ci=%p, index=%d\n", 409 1.4 jym curcpu(), cpu_index(curcpu())); 410 1.2 matt fmnp = fmn_lookup(curcpu()->ci_cpuid); 411 1.2 matt 412 1.2 matt if (once == true) 413 1.2 matt panic("%s: call only once!", __func__); 414 1.2 matt once = true; 415 1.2 matt 416 1.2 matt for (cpu=0; cpu < NFMN; cpu++) { 417 1.2 matt fmnp[cpu].fmn_core = RMIXL_CPU_CORE(cpu); 418 1.2 matt fmnp[cpu].fmn_thread = RMIXL_CPU_THREAD(cpu); 419 1.2 matt } 420 1.2 matt 421 1.2 matt rmixl_fmn_init_core(); /* for initial boot cpu (#0) */ 422 1.2 matt rmixl_fmn_config_noncore(fmnp); /* boot cpu initializes noncore */ 423 1.2 matt } 424 1.2 matt 425 1.2 matt /* 426 1.2 matt * link to TX station ID table for RMI XLR type chip 427 1.2 matt */ 428 1.2 matt static void 429 1.2 matt rmixl_fmn_init_core_xlr(fmn_t *fmnp) 430 1.2 matt { 431 1.2 matt fmnp->fmn_nstid = RMIXLR_FMN_NSTID; 432 1.2 matt fmnp->fmn_stidtab = station_xlr_xxx; 433 1.2 matt fmnp->fmn_stinfo = station_info_xlr_xxx; 434 1.2 matt } 435 1.2 matt 436 1.2 matt /* 437 1.2 matt * link to TX station ID table for RMI XLS type chip 438 1.2 matt */ 439 1.2 matt static void 440 1.2 matt rmixl_fmn_init_core_xls(fmn_t *fmnp) 441 1.2 matt { 442 1.2 matt const fmn_station_info_t *info = NULL; 443 1.2 matt const int *tab = NULL; 444 1.2 matt 445 1.2 matt switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) { 446 1.2 matt case MIPS_XLS104: 447 1.2 matt case MIPS_XLS108: 448 1.2 matt tab = station_xls_1xx; 449 1.2 matt info = station_info_xls_1xx; 450 1.2 matt break; 451 1.2 matt case MIPS_XLS204: 452 1.2 matt case MIPS_XLS208: 453 1.2 matt tab = station_xls_2xx; 454 1.2 matt info = station_info_xls_2xx; 455 1.2 matt break; 456 1.2 matt case MIPS_XLS404: 457 1.2 matt case MIPS_XLS408: 458 1.2 matt case MIPS_XLS416: 459 1.2 matt case MIPS_XLS608: 460 1.2 matt case MIPS_XLS616: 461 1.2 matt tab = station_xls_4xx; 462 1.2 matt info = station_info_xls_4xx; 463 1.2 matt break; 464 1.2 matt case MIPS_XLS404LITE: 465 1.2 matt case MIPS_XLS408LITE: 466 1.2 matt tab = station_xls_4xx_lite; 467 1.2 matt info = station_info_xls_4xx_lite; 468 1.2 matt break; 469 1.2 matt default: 470 1.2 matt panic("%s: unknown PRID IMPL %#x\n", __func__, 471 1.2 matt MIPS_PRID_IMPL(mips_options.mips_cpu_id)); 472 1.2 matt } 473 1.2 matt 474 1.2 matt fmnp->fmn_nstid = RMIXLS_FMN_NSTID; 475 1.2 matt fmnp->fmn_stidtab = tab; 476 1.2 matt fmnp->fmn_stinfo = info; 477 1.2 matt } 478 1.2 matt 479 1.2 matt void 480 1.2 matt rmixl_fmn_init_core(void) 481 1.2 matt { 482 1.2 matt fmn_t *fmnp; 483 1.2 matt kmutex_t *lk; 484 1.2 matt 485 1.2 matt fmnp = fmn_lookup(curcpu()->ci_cpuid); 486 1.2 matt KASSERT(fmnp != NULL); 487 1.2 matt KASSERT(fmnp->fmn_core == RMIXL_CPU_CORE(curcpu()->ci_cpuid)); 488 1.2 matt KASSERT(fmnp->fmn_thread == RMIXL_CPU_THREAD(curcpu()->ci_cpuid)); 489 1.2 matt 490 1.2 matt lk = mutex_obj_alloc(MUTEX_DEFAULT, RMIXL_FMN_INTR_IPL); 491 1.2 matt if (lk == NULL) 492 1.2 matt panic("%s: mutex_obj_alloc failed", __func__); 493 1.2 matt fmnp->fmn_lock = lk; 494 1.2 matt 495 1.2 matt mutex_enter(fmnp->fmn_lock); 496 1.2 matt 497 1.2 matt /* 498 1.2 matt * do chip-dependent per-core FMN initialization 499 1.2 matt */ 500 1.2 matt switch(cpu_rmixl_chip_type(mips_options.mips_cpu)) { 501 1.2 matt case CIDFL_RMI_TYPE_XLR: 502 1.2 matt rmixl_fmn_init_core_xlr(fmnp); 503 1.2 matt break; 504 1.2 matt case CIDFL_RMI_TYPE_XLS: 505 1.2 matt rmixl_fmn_init_core_xls(fmnp); 506 1.2 matt break; 507 1.2 matt case CIDFL_RMI_TYPE_XLP: 508 1.2 matt panic("%s: RMI XLP not yet supported", __func__); 509 1.2 matt default: 510 1.2 matt panic("%s: RMI chip type %#x unknown", __func__, 511 1.2 matt cpu_rmixl_chip_type(mips_options.mips_cpu)); 512 1.2 matt } 513 1.2 matt 514 1.2 matt /* 515 1.2 matt * thread #0 for each core owns 'global' CP2 regs 516 1.2 matt */ 517 1.2 matt if (fmnp->fmn_thread == 0) 518 1.2 matt rmixl_fmn_config_core(fmnp); 519 1.2 matt 520 1.2 matt mutex_exit(fmnp->fmn_lock); 521 1.2 matt } 522 1.2 matt 523 1.2 matt /* 524 1.2 matt * rmixl_fmn_config_noncore 525 1.2 matt * 526 1.2 matt * initialize bucket sizes and (minimum) credits for non-core stations to ZERO 527 1.2 matt * configured through memory write operations instead of CP2 528 1.2 matt */ 529 1.2 matt static void 530 1.2 matt rmixl_fmn_config_noncore(fmn_t *fmnp) 531 1.2 matt { 532 1.2 matt for (u_int sid=0; sid < fmnp->fmn_nstid; sid++) { 533 1.2 matt u_int regoff = fmnp->fmn_stinfo[sid].si_regbase; 534 1.2 matt if (regoff != 0) { 535 1.2 matt u_int buckets_max = fmnp->fmn_stinfo[sid].si_buckets_max; 536 1.2 matt regoff += RMIXL_FMN_BS_FIRST; 537 1.2 matt for (u_int bucket=0; bucket < buckets_max; bucket++) { 538 1.2 matt RMIXL_IOREG_WRITE(regoff, 0); 539 1.2 matt regoff += sizeof(uint32_t); 540 1.2 matt } 541 1.2 matt } 542 1.2 matt } 543 1.2 matt } 544 1.2 matt 545 1.2 matt /* 546 1.2 matt * rmixl_fmn_config_core 547 1.2 matt * 548 1.2 matt * - assumes fmn_mutex is owned 549 1.2 matt * - configure FMN 550 1.2 matt * - initialize bucket sizes and (minimum) credits for a core 551 1.2 matt */ 552 1.2 matt static void 553 1.2 matt rmixl_fmn_config_core(fmn_t *fmnp) 554 1.2 matt { 555 1.2 matt const fmn_station_info_t *info = fmnp->fmn_stinfo; 556 1.2 matt uint32_t sts1; 557 1.2 matt uint32_t cfg; 558 1.2 matt uint32_t cp0_status; 559 1.2 matt 560 1.2 matt KASSERT(mutex_owned(fmnp->fmn_lock) != 0); 561 1.2 matt KASSERT(fmnp->fmn_thread == 0); 562 1.2 matt cp0_status = rmixl_cp2_enable(); 563 1.2 matt 564 1.2 matt /* check/clear any pre-existing status1 error(s) */ 565 1.2 matt RMIXL_MFC2(RMIXL_COP_2_MSG_STS, 1, sts1); 566 1.2 matt if ((sts1 & RMIXL_MSG_STS1_ERRS) != 0) 567 1.2 matt RMIXL_MTC2(RMIXL_COP_2_MSG_STS, 1, sts1); 568 1.2 matt 569 1.2 matt /* set up MsgConfig reg */ 570 1.2 matt cfg = ((1 << RMIXL_MSG_CFG0_WMSHIFT) /* watermark */ 571 1.2 matt | (RMIXL_INTRVEC_FMN << RMIXL_MSG_CFG0_IV_SHIFT) /* irq */ 572 1.2 matt | (1 << RMIXL_MSG_CFG0_ITM_SHIFT) /* thread mask */ 573 1.2 matt | RMIXL_MSG_CFG0_WIE /* watermark intr enb */ 574 1.2 matt | RMIXL_MSG_CFG0_EIE); /* rx not empty intr enb */ 575 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_MSG_CFG, 0, cfg); 576 1.2 matt 577 1.2 matt /* disable trace mode, credit overrun intr, messaging errors intr */ 578 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_MSG_CFG, 0, 0); 579 1.2 matt 580 1.2 matt /* XXX using 4 buckets per core */ 581 1.2 matt KASSERT(4 <= info->si_buckets_max); 582 1.2 matt 583 1.2 matt /* 584 1.2 matt * initialize default sizes for core buckets 585 1.2 matt * zero sizes for unused buckets 586 1.2 matt */ 587 1.2 matt KASSERT(info->si_buckets_max == 8); 588 1.2 matt uint32_t sz = info->si_bucket_size_dflt; 589 1.2 matt KASSERT((sz & ~RMIXL_MSG_BSZ_SIZE) == 0); 590 1.2 matt RMIXL_MTC2(RMIXL_COP_2_MSG_BSZ, 0, sz); 591 1.2 matt RMIXL_MTC2(RMIXL_COP_2_MSG_BSZ, 1, sz); 592 1.2 matt RMIXL_MTC2(RMIXL_COP_2_MSG_BSZ, 2, sz); 593 1.2 matt RMIXL_MTC2(RMIXL_COP_2_MSG_BSZ, 3, sz); 594 1.2 matt RMIXL_MTC2(RMIXL_COP_2_MSG_BSZ, 4, 0); 595 1.2 matt RMIXL_MTC2(RMIXL_COP_2_MSG_BSZ, 5, 0); 596 1.2 matt RMIXL_MTC2(RMIXL_COP_2_MSG_BSZ, 6, 0); 597 1.2 matt RMIXL_MTC2(RMIXL_COP_2_MSG_BSZ, 7, 0); 598 1.2 matt 599 1.2 matt /* 600 1.2 matt * configure minimum credits for each core, 4 buckets 601 1.2 matt * zero all unused credit counters for this core 602 1.2 matt */ 603 1.2 matt uint32_t cr = info->si_credits_min; 604 1.2 matt 605 1.2 matt FMN_CP2_4SEL_WRITE(RMIXL_COP_2_CREDITS, 0, cr); 606 1.2 matt FMN_CP2_4SEL_WRITE(RMIXL_COP_2_CREDITS, 4, 0); 607 1.2 matt FMN_CP2_4SEL_WRITE(RMIXL_COP_2_CREDITS+1, 0, cr); 608 1.2 matt FMN_CP2_4SEL_WRITE(RMIXL_COP_2_CREDITS+1, 4, 0); 609 1.2 matt FMN_CP2_4SEL_WRITE(RMIXL_COP_2_CREDITS+2, 0, cr); 610 1.2 matt FMN_CP2_4SEL_WRITE(RMIXL_COP_2_CREDITS+2, 4, 0); 611 1.2 matt FMN_CP2_4SEL_WRITE(RMIXL_COP_2_CREDITS+3, 0, cr); 612 1.2 matt FMN_CP2_4SEL_WRITE(RMIXL_COP_2_CREDITS+3, 4, 0); 613 1.2 matt 614 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+4, 0); 615 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+5, 0); 616 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+6, 0); 617 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+7, 0); 618 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+8, 0); 619 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+9, 0); 620 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+10, 0); 621 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+11, 0); 622 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+12, 0); 623 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+13, 0); 624 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+14, 0); 625 1.2 matt FMN_CP2_8SEL_WRITE(RMIXL_COP_2_CREDITS+15, 0); 626 1.2 matt 627 1.2 matt RMIXL_MFC2(RMIXL_COP_2_MSG_STS, 1, sts1); 628 1.2 matt KASSERT((sts1 & RMIXL_MSG_STS1_ERRS) == 0); 629 1.2 matt 630 1.2 matt rmixl_cp2_restore(cp0_status); 631 1.2 matt } 632 1.2 matt 633 1.2 matt void 634 1.2 matt rmixl_fmn_init_cpu_intr(void) 635 1.2 matt { 636 1.2 matt fmn_t *fmnp; 637 1.2 matt 638 1.2 matt fmnp = fmn_lookup(curcpu()->ci_cpuid); 639 1.2 matt mutex_enter(fmnp->fmn_lock); 640 1.2 matt 641 1.2 matt for (int i=0; i < fmnp->fmn_nstid; i++) 642 1.2 matt evcnt_attach_dynamic(&fmnp->fmn_intrhand[i].ih_count, 643 1.2 matt EVCNT_TYPE_INTR, NULL, "rmixl_fmn", fmnp->fmn_stinfo[i].si_name); 644 1.2 matt 645 1.2 matt #ifdef NOTYET 646 1.2 matt /* 647 1.2 matt * establish dispatcher for FMN interrupt 648 1.2 matt */ 649 1.2 matt extern kmutex_t rmixl_intr_lock; 650 1.2 matt void *ih; 651 1.2 matt 652 1.2 matt mutex_enter(&rmixl_intr_lock); 653 1.2 matt ih = rmixl_vec_establish(RMIXL_INTRVEC_FMN, -1, RMIXL_FMN_INTR_IPL, 654 1.2 matt rmixl_fmn_intr_dispatch, fmnp, "fmn"); 655 1.2 matt if (ih == NULL) 656 1.2 matt panic("%s: rmixl_vec_establish failed", __func__); 657 1.2 matt mutex_exit(&rmixl_intr_lock); 658 1.2 matt fmnp->fmn_ih = ih; 659 1.2 matt #endif 660 1.2 matt 661 1.2 matt mutex_exit(fmnp->fmn_lock); 662 1.2 matt } 663 1.2 matt 664 1.2 matt void * 665 1.2 matt rmixl_fmn_intr_establish(int txstid, int (*func)(void *, rmixl_fmn_rxmsg_t *), void *arg) 666 1.2 matt { 667 1.2 matt fmn_t *fmnp; 668 1.2 matt fmn_intrhand_t *ih; 669 1.2 matt 670 1.2 matt fmnp = fmn_lookup(curcpu()->ci_cpuid); 671 1.2 matt 672 1.2 matt mutex_enter(fmnp->fmn_lock); 673 1.2 matt 674 1.2 matt ih = &fmnp->fmn_intrhand[txstid]; 675 1.2 matt 676 1.2 matt if (ih->ih_func != NULL) { 677 1.2 matt #ifdef DEBUG 678 1.2 matt panic("%s: intrhand[%d] busy", __func__, txstid); 679 1.2 matt #endif 680 1.2 matt ih = NULL; 681 1.2 matt } else { 682 1.2 matt ih->ih_func = func; 683 1.2 matt ih->ih_arg = arg; 684 1.2 matt } 685 1.2 matt 686 1.2 matt mutex_exit(fmnp->fmn_lock); 687 1.2 matt 688 1.2 matt return ih; 689 1.2 matt } 690 1.2 matt 691 1.2 matt void 692 1.2 matt rmixl_fmn_intr_disestablish(void *cookie) 693 1.2 matt { 694 1.2 matt fmn_t *fmnp; 695 1.2 matt fmn_intrhand_t *ih = cookie; 696 1.2 matt 697 1.2 matt fmnp = fmn_lookup(curcpu()->ci_cpuid); 698 1.2 matt mutex_enter(fmnp->fmn_lock); 699 1.2 matt 700 1.2 matt if (ih->ih_func != NULL) { 701 1.2 matt ih->ih_func = NULL; 702 1.2 matt ih->ih_arg = NULL; 703 1.2 matt } 704 1.2 matt #ifdef DEBUG 705 1.2 matt else { 706 1.2 matt panic("%s: intrhand[%ld] not in use", 707 1.2 matt __func__, ih - &fmnp->fmn_intrhand[0]); 708 1.2 matt } 709 1.2 matt #endif 710 1.2 matt 711 1.2 matt mutex_exit(fmnp->fmn_lock); 712 1.2 matt } 713 1.2 matt 714 1.2 matt void 715 1.2 matt rmixl_fmn_intr_poll(u_int bucket, rmixl_fmn_rxmsg_t *rxmsg) 716 1.2 matt { 717 1.2 matt uint32_t bit = 1 << bucket; 718 1.2 matt uint32_t cp0_status; 719 1.2 matt 720 1.2 matt KASSERT(bucket < 8); 721 1.2 matt 722 1.2 matt cp0_status = rmixl_cp2_enable(); 723 1.2 matt 724 1.2 matt for(;;) { 725 1.2 matt rmixl_fmn_msgwait(bit); 726 1.2 matt if (rmixl_fmn_msg_recv(bucket, rxmsg) == 0) 727 1.2 matt break; 728 1.2 matt DELAY(10); /* XXX */ 729 1.2 matt } 730 1.2 matt 731 1.2 matt rmixl_cp2_restore(cp0_status); 732 1.2 matt } 733 1.2 matt 734 1.2 matt #ifdef NOTYET 735 1.2 matt static int 736 1.2 matt rmixl_fmn_intr_dispatch(void *arg) 737 1.2 matt { 738 1.2 matt fmn_t *fmnp = arg; 739 1.2 matt uint32_t msg_status; 740 1.2 matt uint32_t cp0_status; 741 1.2 matt uint32_t rfbne; 742 1.2 matt int txstid; 743 1.2 matt int rv = 0; 744 1.2 matt 745 1.2 matt mutex_enter(fmnp->fmn_lock); 746 1.2 matt cp0_status = rmixl_cp2_enable(); 747 1.2 matt 748 1.2 matt RMIXL_MFC2(RMIXL_COP_2_MSG_STS, 0, msg_status); 749 1.2 matt rfbne = (~msg_status) >> RMIXL_MSG_STS0_RFBE_SHIFT; 750 1.2 matt 751 1.2 matt if (rfbne != 0) { 752 1.2 matt DPRINTF(("%s: rfbne %#x\n", __func__, rfbne)); 753 1.2 matt for (u_int bucket=0; bucket < 8; bucket++) { 754 1.2 matt rmixl_fmn_rxmsg_t rxmsg; 755 1.2 matt fmn_intrhand_t *ih; 756 1.2 matt 757 1.2 matt if ((rfbne & (1 << bucket)) == 0) 758 1.2 matt continue; 759 1.2 matt if (rmixl_fmn_msg_recv_subr(bucket, &rxmsg) != 0) 760 1.2 matt continue; 761 1.2 matt rv = 1; 762 1.2 matt txstid = fmnp->fmn_stidtab[rxmsg.rxsid]; 763 1.2 matt ih = &fmnp->fmn_intrhand[txstid]; 764 1.2 matt if (ih->ih_func != NULL) 765 1.2 matt if ((ih->ih_func)(ih->ih_arg, &rxmsg) != 0) 766 1.2 matt ih->ih_count.ev_count++; 767 1.2 matt } 768 1.2 matt 769 1.2 matt } 770 1.2 matt rmixl_cp2_restore(cp0_status); 771 1.2 matt mutex_exit(fmnp->fmn_lock); 772 1.2 matt 773 1.2 matt return rv; 774 1.2 matt } 775 1.2 matt #endif /* NOTYET */ 776 1.2 matt 777 1.2 matt int 778 1.2 matt rmixl_fmn_msg_send(u_int size, u_int code, u_int dest_id, rmixl_fmn_msg_t *msg) 779 1.2 matt { 780 1.2 matt fmn_t *fmnp; 781 1.2 matt uint32_t cp0_status; 782 1.2 matt uint32_t msg_status; 783 1.2 matt uint32_t msg_status1; 784 1.2 matt uint32_t desc; 785 1.2 matt int rv = 0; 786 1.2 matt 787 1.2 matt KASSERT((size >= 1) && size <= 4); 788 1.2 matt KASSERT(code <= 0xff); 789 1.2 matt KASSERT(dest_id <= 0xff); 790 1.2 matt 791 1.2 matt fmnp = fmn_lookup(curcpu()->ci_cpuid); 792 1.2 matt mutex_enter(fmnp->fmn_lock); 793 1.2 matt cp0_status = rmixl_cp2_enable(); 794 1.2 matt 795 1.2 matt switch(size) { 796 1.2 matt case 1: 797 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_TXBUF, 0, msg->data[0]); 798 1.2 matt break; 799 1.2 matt case 2: 800 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_TXBUF, 0, msg->data[0]); 801 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_TXBUF, 1, msg->data[1]); 802 1.2 matt break; 803 1.2 matt case 3: 804 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_TXBUF, 0, msg->data[0]); 805 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_TXBUF, 1, msg->data[1]); 806 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_TXBUF, 2, msg->data[2]); 807 1.2 matt break; 808 1.2 matt case 4: 809 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_TXBUF, 0, msg->data[0]); 810 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_TXBUF, 1, msg->data[1]); 811 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_TXBUF, 2, msg->data[2]); 812 1.2 matt RMIXL_DMTC2(RMIXL_COP_2_TXBUF, 3, msg->data[3]); 813 1.2 matt break; 814 1.2 matt default: 815 1.2 matt DIAG_PRF(("%s: bad size %d", __func__, size)); 816 1.2 matt rv = -1; 817 1.2 matt goto out; 818 1.2 matt } 819 1.2 matt 820 1.2 matt for (int try=16; try--; ) { 821 1.2 matt RMIXL_MFC2(RMIXL_COP_2_MSG_STS, 0, msg_status); 822 1.2 matt if ((msg_status & (RMIXL_MSG_STS0_LPF|RMIXL_MSG_STS0_SPF|RMIXL_MSG_STS0_SMP)) == 0) 823 1.2 matt goto send; 824 1.2 matt DELAY(10); /* XXX ??? */ 825 1.2 matt } 826 1.2 matt DIAG_PRF(("%s: cpu%u, msg %p, dst_id=%d, sts=%#x: can't send\n", 827 1.2 matt __func__, cpu_number(), msg, dest_id, msg_status)); 828 1.2 matt rv = -1; 829 1.2 matt goto out; 830 1.2 matt send: 831 1.2 matt desc = RMIXL_MSGSND_DESC(size, code, dest_id); 832 1.2 matt DPRINTF(("%s: cpu%u, desc %#x\n", __func__, cpu_number(), desc)); 833 1.2 matt for (int try=16; try--; ) { 834 1.2 matt rmixl_msgsnd(desc); 835 1.2 matt RMIXL_MFC2(RMIXL_COP_2_MSG_STS, 0, msg_status); 836 1.2 matt RMIXL_MFC2(RMIXL_COP_2_MSG_STS, 1, msg_status1); 837 1.2 matt if (((msg_status & RMIXL_MSG_STS0_SCF) == 0) 838 1.2 matt && ((msg_status1 & RMIXL_MSG_STS1_ERRS) == 0)) 839 1.2 matt goto out; 840 1.2 matt #if 0 841 1.2 matt #ifdef DEBUG 842 1.2 matt if ((msg_status & RMIXL_MSG_STS0_SCF) != 0) { 843 1.2 matt uint32_t r; 844 1.2 matt u_int regno = RMIXL_COP_2_CREDITS+fmnp->fmn_core; 845 1.2 matt u_int sel = fmnp->fmn_thread; 846 1.2 matt printf("%s: CC[%d,%d]=", __func__, regno, sel); 847 1.2 matt FMN_CP2_RD_SWITCH_RW(READ, regno, sel, r); 848 1.2 matt printf("%s: CC[%d,%d]=%d\n", __func__, regno, sel, r); 849 1.2 matt } 850 1.2 matt #endif /* DEBUG */ 851 1.2 matt #endif /* 0 */ 852 1.2 matt /* clear status1 error(s) */ 853 1.2 matt if ((msg_status1 & RMIXL_MSG_STS1_ERRS) != 0) { 854 1.2 matt RMIXL_MFC2(RMIXL_COP_2_MSG_STS, 1, msg_status1); 855 1.2 matt RMIXL_MTC2(RMIXL_COP_2_MSG_STS, 1, msg_status1); 856 1.2 matt } 857 1.2 matt DIAG_PRF(("%s: src=%ld, dst=%d, sts=%#x, %#x: send error, try %d\n", 858 1.2 matt __func__, curcpu()->ci_cpuid, dest_id, msg_status, msg_status1, try)); 859 1.2 matt DELAY(10); 860 1.2 matt } 861 1.2 matt rv = -1; 862 1.2 matt out: 863 1.2 matt rmixl_cp2_restore(cp0_status); 864 1.2 matt mutex_exit(fmnp->fmn_lock); 865 1.2 matt 866 1.2 matt return rv; 867 1.2 matt } 868 1.2 matt 869 1.2 matt /* 870 1.2 matt * rmixl_fmn_msg_recv 871 1.2 matt * 872 1.2 matt * - grab fmn_lock and call rmixl_fmn_msg_recv_subr to do the real work 873 1.2 matt * - assume cp2 access is already enabled 874 1.2 matt */ 875 1.2 matt int 876 1.2 matt rmixl_fmn_msg_recv(u_int bucket, rmixl_fmn_rxmsg_t *rxmsg) 877 1.2 matt { 878 1.2 matt fmn_t *fmnp; 879 1.2 matt int rv; 880 1.2 matt 881 1.2 matt fmnp = fmn_lookup(curcpu()->ci_cpuid); 882 1.2 matt mutex_enter(fmnp->fmn_lock); 883 1.2 matt rv = rmixl_fmn_msg_recv_subr(bucket, rxmsg); 884 1.2 matt mutex_exit(fmnp->fmn_lock); 885 1.2 matt 886 1.2 matt return rv; 887 1.2 matt } 888 1.2 matt 889 1.2 matt /* 890 1.2 matt * rmixl_fmn_msg_recv_subr 891 1.2 matt * 892 1.2 matt * - assume fmn_lock is owned 893 1.2 matt * - assume cp2 access is already enabled 894 1.2 matt */ 895 1.2 matt static int 896 1.2 matt rmixl_fmn_msg_recv_subr(u_int bucket, rmixl_fmn_rxmsg_t *rxmsg) 897 1.2 matt { 898 1.2 matt fmn_t *fmnp; 899 1.5 mrg uint32_t msg_status = 0 /* XXXGCC12 */; 900 1.2 matt int rv; 901 1.2 matt 902 1.2 matt fmnp = fmn_lookup(curcpu()->ci_cpuid); 903 1.2 matt KASSERT(mutex_owned(fmnp->fmn_lock) != 0); 904 1.2 matt 905 1.2 matt for (int try=16; try--; ) { 906 1.2 matt RMIXL_MFC2(RMIXL_COP_2_MSG_STS, 0, msg_status); 907 1.2 matt if ((msg_status & (RMIXL_MSG_STS0_LPF)) == 0) 908 1.2 matt goto recv; 909 1.2 matt } 910 1.3 matt DIAG_PRF(("%s: cpu%u, bucket=%d, sts=%#x: Load Pending Fail\n", 911 1.2 matt __func__, cpu_number(), bucket, msg_status)); 912 1.2 matt rv = -1; 913 1.2 matt goto out; 914 1.2 matt recv: 915 1.2 matt rmixl_msgld(bucket); 916 1.2 matt RMIXL_MFC2(RMIXL_COP_2_MSG_STS, 0, msg_status); 917 1.3 matt DPRINTF(("%s: cpu%u, bucket=%d, sts=%#x\n", 918 1.2 matt __func__, cpu_number(), bucket, msg_status)); 919 1.2 matt rv = msg_status & (RMIXL_MSG_STS0_LEF|RMIXL_MSG_STS0_LPF); 920 1.2 matt if (rv == 0) { 921 1.2 matt rxmsg->rxsid = (msg_status & RMIXL_MSG_STS0_RMSID) 922 1.2 matt >> RMIXL_MSG_STS0_RMSID_SHIFT; 923 1.2 matt rxmsg->code = (msg_status & RMIXL_MSG_STS0_RMSC) 924 1.2 matt >> RMIXL_MSG_STS0_RMSC_SHIFT; 925 1.2 matt rxmsg->size = ((msg_status & RMIXL_MSG_STS0_RMS) 926 1.2 matt >> RMIXL_MSG_STS0_RMS_SHIFT) + 1; 927 1.2 matt switch(rxmsg->size) { 928 1.2 matt case 1: 929 1.2 matt RMIXL_DMFC2(RMIXL_COP_2_RXBUF, 0, rxmsg->msg.data[0]); 930 1.2 matt break; 931 1.2 matt case 2: 932 1.2 matt RMIXL_DMFC2(RMIXL_COP_2_RXBUF, 0, rxmsg->msg.data[0]); 933 1.2 matt RMIXL_DMFC2(RMIXL_COP_2_RXBUF, 1, rxmsg->msg.data[1]); 934 1.2 matt break; 935 1.2 matt case 3: 936 1.2 matt RMIXL_DMFC2(RMIXL_COP_2_RXBUF, 0, rxmsg->msg.data[0]); 937 1.2 matt RMIXL_DMFC2(RMIXL_COP_2_RXBUF, 1, rxmsg->msg.data[1]); 938 1.2 matt RMIXL_DMFC2(RMIXL_COP_2_RXBUF, 2, rxmsg->msg.data[2]); 939 1.2 matt break; 940 1.2 matt case 4: 941 1.2 matt RMIXL_DMFC2(RMIXL_COP_2_RXBUF, 0, rxmsg->msg.data[0]); 942 1.2 matt RMIXL_DMFC2(RMIXL_COP_2_RXBUF, 1, rxmsg->msg.data[1]); 943 1.2 matt RMIXL_DMFC2(RMIXL_COP_2_RXBUF, 2, rxmsg->msg.data[2]); 944 1.2 matt RMIXL_DMFC2(RMIXL_COP_2_RXBUF, 3, rxmsg->msg.data[3]); 945 1.2 matt break; 946 1.2 matt default: 947 1.2 matt /* "impossible" due to bitfield width */ 948 1.2 matt panic("%s: bad size %d", __func__, rxmsg->size); 949 1.2 matt } 950 1.2 matt } 951 1.2 matt out: 952 1.2 matt 953 1.2 matt return rv; 954 1.2 matt } 955 1.2 matt 956 1.2 matt #ifdef FMN_DEBUG 957 1.2 matt void 958 1.2 matt rmixl_fmn_cp2_dump(void) 959 1.2 matt { 960 1.2 matt uint32_t cp0_status; 961 1.2 matt 962 1.2 matt cp0_status = rmixl_cp2_enable(); 963 1.2 matt 964 1.2 matt CPU2_PRINT_8(RMIXL_COP_2_TXBUF, 0); 965 1.2 matt CPU2_PRINT_8(RMIXL_COP_2_TXBUF, 1); 966 1.2 matt CPU2_PRINT_8(RMIXL_COP_2_TXBUF, 2); 967 1.2 matt CPU2_PRINT_8(RMIXL_COP_2_TXBUF, 3); 968 1.2 matt 969 1.2 matt CPU2_PRINT_8(RMIXL_COP_2_RXBUF, 0); 970 1.2 matt CPU2_PRINT_8(RMIXL_COP_2_RXBUF, 1); 971 1.2 matt CPU2_PRINT_8(RMIXL_COP_2_RXBUF, 2); 972 1.2 matt CPU2_PRINT_8(RMIXL_COP_2_RXBUF, 3); 973 1.2 matt 974 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_STS, 0); 975 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_STS, 1); 976 1.2 matt 977 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_CFG, 0); 978 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_CFG, 1); 979 1.2 matt 980 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_BSZ, 0); 981 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_BSZ, 1); 982 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_BSZ, 2); 983 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_BSZ, 3); 984 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_BSZ, 4); 985 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_BSZ, 5); 986 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_BSZ, 6); 987 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_MSG_BSZ, 7); 988 1.2 matt 989 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 0, 0); 990 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 0, 1); 991 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 0, 2); 992 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 0, 3); 993 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 0, 4); 994 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 0, 5); 995 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 0, 6); 996 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 0, 7); 997 1.2 matt 998 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 1, 0); 999 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 1, 1); 1000 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 1, 2); 1001 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 1, 3); 1002 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 1, 4); 1003 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 1, 5); 1004 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 1, 6); 1005 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 1, 7); 1006 1.2 matt 1007 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 2, 0); 1008 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 2, 1); 1009 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 2, 2); 1010 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 2, 3); 1011 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 2, 4); 1012 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 2, 5); 1013 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 2, 6); 1014 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 2, 7); 1015 1.2 matt 1016 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 3, 0); 1017 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 3, 1); 1018 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 3, 2); 1019 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 3, 3); 1020 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 3, 4); 1021 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 3, 5); 1022 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 3, 6); 1023 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 3, 7); 1024 1.2 matt 1025 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 4, 0); 1026 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 4, 1); 1027 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 4, 2); 1028 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 4, 3); 1029 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 4, 4); 1030 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 4, 5); 1031 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 4, 6); 1032 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 4, 7); 1033 1.2 matt 1034 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 5, 0); 1035 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 5, 1); 1036 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 5, 2); 1037 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 5, 3); 1038 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 5, 4); 1039 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 5, 5); 1040 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 5, 6); 1041 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 5, 7); 1042 1.2 matt 1043 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 6, 0); 1044 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 6, 1); 1045 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 6, 2); 1046 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 6, 3); 1047 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 6, 4); 1048 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 6, 5); 1049 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 6, 6); 1050 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 6, 7); 1051 1.2 matt 1052 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 7, 0); 1053 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 7, 1); 1054 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 7, 2); 1055 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 7, 3); 1056 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 7, 4); 1057 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 7, 5); 1058 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 7, 6); 1059 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 7, 7); 1060 1.2 matt 1061 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 8, 0); 1062 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 8, 1); 1063 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 8, 2); 1064 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 8, 3); 1065 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 8, 4); 1066 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 8, 5); 1067 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 8, 6); 1068 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 8, 7); 1069 1.2 matt 1070 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 9, 0); 1071 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 9, 1); 1072 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 9, 2); 1073 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 9, 3); 1074 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 9, 4); 1075 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 9, 5); 1076 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 9, 6); 1077 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 9, 7); 1078 1.2 matt 1079 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 10, 0); 1080 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 10, 1); 1081 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 10, 2); 1082 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 10, 3); 1083 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 10, 4); 1084 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 10, 5); 1085 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 10, 6); 1086 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 10, 7); 1087 1.2 matt 1088 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 11, 0); 1089 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 11, 1); 1090 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 11, 2); 1091 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 11, 3); 1092 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 11, 4); 1093 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 11, 5); 1094 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 11, 6); 1095 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 11, 7); 1096 1.2 matt 1097 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 12, 0); 1098 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 12, 1); 1099 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 12, 2); 1100 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 12, 3); 1101 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 12, 4); 1102 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 12, 5); 1103 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 12, 6); 1104 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 12, 7); 1105 1.2 matt 1106 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 13, 0); 1107 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 13, 1); 1108 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 13, 2); 1109 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 13, 3); 1110 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 13, 4); 1111 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 13, 5); 1112 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 13, 6); 1113 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 13, 7); 1114 1.2 matt 1115 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 14, 0); 1116 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 14, 1); 1117 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 14, 2); 1118 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 14, 3); 1119 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 14, 4); 1120 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 14, 5); 1121 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 14, 6); 1122 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 14, 7); 1123 1.2 matt 1124 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 15, 0); 1125 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 15, 1); 1126 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 15, 2); 1127 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 15, 3); 1128 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 15, 4); 1129 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 15, 5); 1130 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 15, 6); 1131 1.2 matt CPU2_PRINT_4(RMIXL_COP_2_CREDITS + 15, 7); 1132 1.2 matt 1133 1.2 matt rmixl_cp2_restore(cp0_status); 1134 1.2 matt } 1135 1.2 matt 1136 1.2 matt 1137 1.2 matt void 1138 1.2 matt rmixl_fmn_cc_dump(void) 1139 1.2 matt { 1140 1.2 matt uint32_t cc[4][8]; 1141 1.2 matt 1142 1.2 matt FMN_CP2_4SEL_READ(RMIXL_COP_2_CREDITS, 0, &cc[0][0]); 1143 1.2 matt FMN_CP2_4SEL_READ(RMIXL_COP_2_CREDITS, 4, &cc[0][4]); 1144 1.2 matt FMN_CP2_4SEL_READ(RMIXL_COP_2_CREDITS+1, 0, &cc[1][0]); 1145 1.2 matt FMN_CP2_4SEL_READ(RMIXL_COP_2_CREDITS+1, 4, &cc[1][4]); 1146 1.2 matt FMN_CP2_4SEL_READ(RMIXL_COP_2_CREDITS+2, 0, &cc[2][0]); 1147 1.2 matt FMN_CP2_4SEL_READ(RMIXL_COP_2_CREDITS+2, 4, &cc[2][4]); 1148 1.2 matt FMN_CP2_4SEL_READ(RMIXL_COP_2_CREDITS+3, 0, &cc[3][0]); 1149 1.2 matt FMN_CP2_4SEL_READ(RMIXL_COP_2_CREDITS+3, 4, &cc[3][4]); 1150 1.2 matt 1151 1.3 matt printf("%s: cpu%u\n", __func__, cpu_number()); 1152 1.2 matt for (int i=0; i < 4; i++) { 1153 1.2 matt for (int j=0; j < 8; j++) 1154 1.2 matt printf(" %#x,", cc[i][j]); 1155 1.2 matt printf("\n"); 1156 1.2 matt } 1157 1.2 matt } 1158 1.2 matt 1159 1.2 matt #endif /* FMN_DEBUG */ 1160