1 /* $NetBSD: octeonvar.h,v 1.18 2022/01/26 11:48:54 andvar Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef _MIPS_OCTEON_OCTEONVAR_H_ 33 #define _MIPS_OCTEON_OCTEONVAR_H_ 34 35 #include <sys/bus.h> 36 #include <sys/evcnt.h> 37 #include <sys/kcpuset.h> 38 #include <mips/locore.h> 39 #include <dev/pci/pcivar.h> 40 41 #include <mips/cavium/octeonreg.h> 42 #include <mips/cache_octeon.h> 43 44 /* XXX elsewhere */ 45 #define _ASM_PROLOGUE \ 46 " .set push \n" \ 47 " .set noreorder \n" 48 #define _ASM_PROLOGUE_MIPS64 \ 49 _ASM_PROLOGUE \ 50 " .set mips64 \n" 51 #define _ASM_PROLOGUE_OCTEON \ 52 _ASM_PROLOGUE \ 53 " .set arch=octeon \n" 54 #define _ASM_EPILOGUE \ 55 " .set pop \n" 56 57 #ifdef _KERNEL 58 extern int octeon_core_ver; 59 #endif /* _KERNEL */ 60 #define OCTEON_1 1 61 #define OCTEON_PLUS 10 /* arbitrary, keep sequence for others */ 62 #define OCTEON_2 2 63 #define OCTEON_3 3 64 65 struct octeon_config { 66 struct mips_bus_space mc_iobus_bust; 67 struct mips_bus_space mc_bootbus_bust; 68 struct mips_pci_chipset mc_pc; 69 70 struct mips_bus_dma_tag mc_iobus_dmat; 71 struct mips_bus_dma_tag mc_bootbus_dmat; 72 struct mips_bus_dma_tag mc_core1_dmat; 73 struct mips_bus_dma_tag mc_fpa_dmat; 74 75 struct extent *mc_io_ex; 76 struct extent *mc_mem_ex; 77 78 int mc_mallocsafe; 79 }; 80 81 #define NIRQS 128 82 #define NBANKS 2 83 84 struct cpu_softc { 85 struct cpu_info *cpu_ci; 86 87 uint64_t cpu_ip2_sum0; 88 uint64_t cpu_ip3_sum0; 89 uint64_t cpu_ip4_sum0; 90 91 uint64_t cpu_int_sum1; 92 93 uint64_t cpu_ip2_en[NBANKS]; 94 uint64_t cpu_ip3_en[NBANKS]; 95 uint64_t cpu_ip4_en[NBANKS]; 96 97 uint64_t cpu_ip2_enable[NBANKS]; 98 uint64_t cpu_ip3_enable[NBANKS]; 99 uint64_t cpu_ip4_enable[NBANKS]; 100 101 struct evcnt cpu_intr_evs[NIRQS]; 102 103 void *cpu_wdog_sih; // wdog softint handler 104 uint64_t cpu_wdog; 105 uint64_t cpu_pp_poke; 106 107 #ifdef MULTIPROCESSOR 108 uint64_t cpu_mbox_set; 109 uint64_t cpu_mbox_clr; 110 #endif 111 } __aligned(OCTEON_CACHELINE_SIZE); 112 113 /* 114 * FPA map 115 */ 116 117 #define OCTEON_POOL_NO_PKT 0 118 #define OCTEON_POOL_NO_WQE 1 119 #define OCTEON_POOL_NO_CMD 2 120 #define OCTEON_POOL_NO_SG 3 121 #define OCTEON_POOL_NO_XXX_4 4 122 #define OCTEON_POOL_NO_XXX_5 5 123 #define OCTEON_POOL_NO_XXX_6 6 124 #define OCTEON_POOL_NO_DUMP 7 /* FPA debug dump */ 125 126 #define OCTEON_POOL_SIZE_PKT 2048 /* 128 x 16 */ 127 #define OCTEON_POOL_SIZE_WQE 128 /* 128 x 1 */ 128 #define OCTEON_POOL_SIZE_CMD 1024 /* 128 x 8 */ 129 #define OCTEON_POOL_SIZE_SG 512 /* 128 x 4 */ 130 #define OCTEON_POOL_SIZE_XXX_4 0 131 #define OCTEON_POOL_SIZE_XXX_5 0 132 #define OCTEON_POOL_SIZE_XXX_6 0 133 #define OCTEON_POOL_SIZE_XXX_7 0 134 135 #define OCTEON_POOL_NELEMS_PKT 4096 136 #define OCTEON_POOL_NELEMS_WQE 4096 137 #define OCTEON_POOL_NELEMS_CMD 32 138 #define OCTEON_POOL_NELEMS_SG 1024 139 #define OCTEON_POOL_NELEMS_XXX_4 0 140 #define OCTEON_POOL_NELEMS_XXX_5 0 141 #define OCTEON_POOL_NELEMS_XXX_6 0 142 #define OCTEON_POOL_NELEMS_XXX_7 0 143 144 /* 145 * CVMSEG (``scratch'') memory map 146 */ 147 148 #define CVMSEG_LM_RNM_SIZE 16 /* limited by CN70XX hardware (why?) */ 149 #define CVMSEG_LM_ETHER_COUNT 4 /* limits number of cnmac devices */ 150 151 struct octeon_cvmseg_map { 152 uint64_t csm_pow_intr; 153 154 struct octeon_cvmseg_ether_map { 155 uint64_t csm_ether_fau_done; 156 } csm_ether[CVMSEG_LM_ETHER_COUNT]; 157 158 uint64_t csm_rnm[CVMSEG_LM_RNM_SIZE]; 159 } __packed; 160 #define OCTEON_CVMSEG_OFFSET(entry) \ 161 offsetof(struct octeon_cvmseg_map, entry) 162 #define OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \ 163 (offsetof(struct octeon_cvmseg_map, csm_ether) + \ 164 sizeof(struct octeon_cvmseg_ether_map) * (n) + \ 165 offsetof(struct octeon_cvmseg_ether_map, entry)) 166 167 /* 168 * FAU register map 169 * 170 * => FAU registers exist in FAU unit 171 * => devices (PKO) can access these registers 172 * => CPU can read those values after loading them into CVMSEG 173 */ 174 struct octfau_map { 175 struct { 176 /* PKO command index */ 177 uint64_t _fau_map_port_pkocmdidx; 178 /* send requested */ 179 uint64_t _fau_map_port_txreq; 180 /* send completed */ 181 uint64_t _fau_map_port_txdone; 182 /* XXX */ 183 uint64_t _fau_map_port_pad; 184 } __packed _fau_map_port[3]; 185 }; 186 187 /* 188 * POW qos/group map 189 */ 190 191 #define OCTEON_POW_QOS_PIP 0 192 #define OCTEON_POW_QOS_CORE1 1 193 #define OCTEON_POW_QOS_XXX_2 2 194 #define OCTEON_POW_QOS_XXX_3 3 195 #define OCTEON_POW_QOS_XXX_4 4 196 #define OCTEON_POW_QOS_XXX_5 5 197 #define OCTEON_POW_QOS_XXX_6 6 198 #define OCTEON_POW_QOS_XXX_7 7 199 200 #define OCTEON_POW_GROUP_MAX 16 201 202 #ifdef _KERNEL 203 extern struct octeon_config octeon_configuration; 204 205 const char *octeon_cpu_model(mips_prid_t); 206 207 void octeon_bus_io_init(bus_space_tag_t, void *); 208 void octeon_bus_mem_init(bus_space_tag_t, void *); 209 void octeon_cal_timer(int); 210 void octeon_dma_init(struct octeon_config *); 211 void octeon_intr_init(struct cpu_info *); 212 void octeon_iointr(int, vaddr_t, uint32_t); 213 void octpci_init(pci_chipset_tag_t, struct octeon_config *); 214 void *octeon_intr_establish(int, int, int (*)(void *), void *); 215 void octeon_intr_disestablish(void *cookie); 216 217 int octeon_ioclock_speed(void); 218 void octeon_soft_reset(void); 219 220 void octeon_reset_vector(void); 221 uint64_t mips_cp0_cvmctl_read(void); 222 void mips_cp0_cvmctl_write(uint64_t); 223 #endif /* _KERNEL */ 224 225 #if defined(__mips_n32) 226 #define ffs64 __builtin_ffsll 227 #elif defined(_LP64) 228 #define ffs64 __builtin_ffsl 229 #else 230 #error unknown ABI 231 #endif 232 233 /* 234 * Prefetch 235 * 236 * OCTEON_PREF normal (L1 and L2) 237 * OCTEON_PREF_L1 L1 only 238 * OCTEON_PREF_L2 L2 only 239 * OCTEON_PREF_DWB don't write back 240 * OCTEON_PREF_PFS prepare for store 241 */ 242 #define __OCTEON_PREF_N(n, base, offset) \ 243 __asm __volatile ( \ 244 " .set push \ 245 " .set arch=octeon \n" \ 246 " pref "#n", "#offset"(%[base]) \n" \ 247 " .set pop \ 248 : : [base] "d" (base) \ 249 ) 250 #define __OCTEON_PREF_0(base, offset) __OCTEON_PREF_N(0, base, offset) 251 #define __OCTEON_PREF_4(base, offset) __OCTEON_PREF_N(4, base, offset) 252 #define __OCTEON_PREF_28(base, offset) __OCTEON_PREF_N(28, base, offset) 253 #define __OCTEON_PREF_29(base, offset) __OCTEON_PREF_N(29, base, offset) 254 #define __OCTEON_PREF_30(base, offset) __OCTEON_PREF_N(30, base, offset) 255 #define OCTEON_PREF(base, offset) __OCTEON_PREF_0(base, offset) 256 #define OCTEON_PREF_L1(base, offset) __OCTEON_PREF_4(base, offset) 257 #define OCTEON_PREF_L2(base, offset) __OCTEON_PREF_28(base, offset) 258 #define OCTEON_PREF_DWB(base, offset) __OCTEON_PREF_29(base, offset) 259 #define OCTEON_PREF_PFS(base, offset) __OCTEON_PREF_30(base, offset) 260 261 /* 262 * Sync 263 */ 264 #define OCTEON_SYNCCOMMON(name) \ 265 __asm __volatile ( \ 266 _ASM_PROLOGUE_OCTEON \ 267 " "#name" \n" \ 268 _ASM_EPILOGUE \ 269 ::: "memory") 270 #define OCTEON_SYNCIOBDMA OCTEON_SYNCCOMMON(synciobdma) 271 #define OCTEON_SYNCW OCTEON_SYNCCOMMON(syncw) 272 #define OCTEON_SYNC OCTEON_SYNCCOMMON(sync) 273 #define OCTEON_SYNCWS OCTEON_SYNCCOMMON(syncws) 274 #define OCTEON_SYNCS OCTEON_SYNCCOMMON(syncs) 275 276 /* octeon core does not use cca to determine cacheability */ 277 #define OCTEON_CCA_NONE UINT64_C(0) 278 279 static __inline uint64_t 280 octeon_xkphys_read_8(paddr_t address) 281 { 282 return mips3_ld(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address)); 283 } 284 285 static __inline void 286 octeon_xkphys_write_8(paddr_t address, uint64_t value) 287 { 288 mips3_sd(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address), value); 289 } 290 291 static __inline void 292 octeon_iobdma_write_8(uint64_t value) 293 { 294 295 octeon_xkphys_write_8(OCTEON_IOBDMA_ADDR, value); 296 } 297 298 static __inline uint64_t 299 octeon_cvmseg_read_8(size_t offset) 300 { 301 302 return octeon_xkphys_read_8(OCTEON_CVMSEG_LM + offset); 303 } 304 305 static __inline void 306 octeon_cvmseg_write_8(size_t offset, uint64_t value) 307 { 308 309 octeon_xkphys_write_8(OCTEON_CVMSEG_LM + offset, value); 310 } 311 312 #endif /* _MIPS_OCTEON_OCTEONVAR_H_ */ 313