1 /* $OpenBSD: octeonvar.h,v 1.31 2016/07/16 10:19:55 visa Exp $ */ 2 /* $NetBSD: maltavar.h,v 1.3 2002/03/18 10:10:16 simonb Exp $ */ 3 4 /*- 5 * Copyright (c) 2001 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 #ifndef _MIPS_OCTEON_OCTEONVAR_H_ 41 #define _MIPS_OCTEON_OCTEONVAR_H_ 42 43 #include <machine/bus.h> 44 45 /* XXX elsewhere */ 46 #define _ASM_PROLOGUE \ 47 " .set push \n" \ 48 " .set noreorder \n" 49 #define _ASM_PROLOGUE_MIPS64 \ 50 _ASM_PROLOGUE \ 51 " .set mips64 \n" 52 #define _ASM_PROLOGUE_OCTEON \ 53 _ASM_PROLOGUE \ 54 " .set arch=octeon \n" 55 #define _ASM_EPILOGUE \ 56 " .set pop \n" 57 /* 58 * subbits = __BITS64_GET(XXX, bits); 59 * bits = __BITS64_SET(XXX, subbits); 60 */ 61 #ifndef __BITS64_GET 62 #define __BITS64_GET(name, bits) \ 63 (((uint64_t)(bits) & name) >> name##_SHIFT) 64 #endif 65 #ifndef __BITS64_SET 66 #define __BITS64_SET(name, subbits) \ 67 (((uint64_t)(subbits) << name##_SHIFT) & name) 68 #endif 69 70 struct octeon_config { 71 bus_space_tag_t mc_iobus_bust; 72 bus_space_tag_t mc_bootbus_bust; 73 74 bus_dma_tag_t mc_iobus_dmat; 75 bus_dma_tag_t mc_bootbus_dmat; 76 }; 77 78 /* 79 * FPA map 80 */ 81 82 #define OCTEON_POOL_NO_PKT 0 83 #define OCTEON_POOL_NO_WQE 1 84 #define OCTEON_POOL_NO_CMD 2 85 #define OCTEON_POOL_NO_SG 3 86 #define OCTEON_POOL_NO_XXX_4 4 87 #define OCTEON_POOL_NO_XXX_5 5 88 #define OCTEON_POOL_NO_XXX_6 6 89 #define OCTEON_POOL_NO_DUMP 7 /* FPA debug dump */ 90 91 #define OCTEON_POOL_SIZE_PKT 1920 /* 128 x 15 */ 92 #define OCTEON_POOL_SIZE_WQE 128 /* 128 x 1 */ 93 #define OCTEON_POOL_SIZE_CMD 1024 /* 128 x 8 */ 94 #define OCTEON_POOL_SIZE_SG 128 /* 128 x 1 */ 95 #define OCTEON_POOL_SIZE_XXX_4 0 96 #define OCTEON_POOL_SIZE_XXX_5 0 97 #define OCTEON_POOL_SIZE_XXX_6 0 98 #define OCTEON_POOL_SIZE_XXX_7 0 99 100 #define OCTEON_POOL_NELEMS_PKT 4096 101 #define OCTEON_POOL_NELEMS_WQE 4096 102 #define OCTEON_POOL_NELEMS_CMD 32 103 #define OCTEON_POOL_NELEMS_SG 4096 104 #define OCTEON_POOL_NELEMS_XXX_4 0 105 #define OCTEON_POOL_NELEMS_XXX_5 0 106 #define OCTEON_POOL_NELEMS_XXX_6 0 107 #define OCTEON_POOL_NELEMS_XXX_7 0 108 109 /* 110 * CVMSEG (``scratch'') memory map 111 */ 112 struct octeon_cvmseg_map { 113 uint64_t csm_pow_intr; 114 115 struct octeon_cvmseg_ether_map { 116 uint64_t csm_ether_fau_done; 117 } csm_ether[12/* XXX */]; 118 } __packed; 119 #define OCTEON_CVMSEG_OFFSET(entry) \ 120 offsetof(struct octeon_cvmseg_map, entry) 121 #define OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \ 122 (offsetof(struct octeon_cvmseg_map, csm_ether) + \ 123 sizeof(struct octeon_cvmseg_ether_map) * (n) + \ 124 offsetof(struct octeon_cvmseg_ether_map, entry)) 125 126 /* 127 * FAU register map 128 * 129 * => FAU registers exist in FAU unit 130 * => devices (PKO) can access these registers 131 * => CPU can read those values after loading them into CVMSEG 132 */ 133 struct octeon_fau_map { 134 struct { 135 /* PKO command index */ 136 uint64_t _fau_map_port_pkocmdidx; 137 /* send requested */ 138 uint64_t _fau_map_port_txreq; 139 /* send completed */ 140 uint64_t _fau_map_port_txdone; 141 /* XXX */ 142 uint64_t _fau_map_port_pad; 143 } __packed _fau_map_port[3]; 144 }; 145 146 /* 147 * POW qos/group map 148 */ 149 150 #define OCTEON_POW_QOS_PIP 0 151 #define OCTEON_POW_QOS_CORE1 1 152 #define OCTEON_POW_QOS_XXX_2 2 153 #define OCTEON_POW_QOS_XXX_3 3 154 #define OCTEON_POW_QOS_XXX_4 4 155 #define OCTEON_POW_QOS_XXX_5 5 156 #define OCTEON_POW_QOS_XXX_6 6 157 #define OCTEON_POW_QOS_XXX_7 7 158 159 #define OCTEON_POW_GROUP_PIP 0 160 #define OCTEON_POW_GROUP_XXX_1 1 161 #define OCTEON_POW_GROUP_XXX_2 2 162 #define OCTEON_POW_GROUP_XXX_3 3 163 #define OCTEON_POW_GROUP_XXX_4 4 164 #define OCTEON_POW_GROUP_XXX_5 5 165 #define OCTEON_POW_GROUP_XXX_6 6 166 #define OCTEON_POW_GROUP_CORE1_SEND 7 167 #define OCTEON_POW_GROUP_CORE1_TASK_0 8 168 #define OCTEON_POW_GROUP_CORE1_TASK_1 9 169 #define OCTEON_POW_GROUP_CORE1_TASK_2 10 170 #define OCTEON_POW_GROUP_CORE1_TASK_3 11 171 #define OCTEON_POW_GROUP_CORE1_TASK_4 12 172 #define OCTEON_POW_GROUP_CORE1_TASK_5 13 173 #define OCTEON_POW_GROUP_CORE1_TASK_6 14 174 #define OCTEON_POW_GROUP_CORE1_TASK_7 15 175 176 /* 177 * Octeon board types known to work with OpenBSD/octeon. 178 * NB: BOARD_TYPE_UBIQUITI_E100 is also used by other vendors, but we don't run 179 * on those boards yet. 180 */ 181 #define BOARD_TYPE_UBIQUITI_E100 20002 182 #define BOARD_TYPE_UBIQUITI_E200 20003 183 #define BOARD_TYPE_DSR_500 20015 184 185 #if defined(_KERNEL) || defined(_STANDALONE) 186 #define OCTEON_ARGV_MAX 64 187 188 /* Maximum number of cores on <= CN52XX */ 189 #define OCTEON_MAXCPUS 4 190 191 struct boot_desc { 192 uint32_t desc_ver; 193 uint32_t desc_size; 194 uint64_t stack_top; 195 uint64_t heap_start; 196 uint64_t heap_end; 197 uint64_t __unused17; 198 uint64_t __unused16; 199 uint32_t __unused18; 200 uint32_t __unused15; 201 uint32_t __unused14; 202 uint32_t argc; 203 uint32_t argv[OCTEON_ARGV_MAX]; 204 uint32_t flags; 205 uint32_t core_mask; 206 uint32_t dram_size; 207 uint32_t phy_mem_desc_addr; 208 uint32_t debugger_flag_addr; 209 uint32_t eclock; 210 uint32_t __unused10; 211 uint32_t __unused9; 212 uint16_t __unused8; 213 uint8_t __unused7; 214 uint8_t __unused6; 215 uint16_t __unused5; 216 uint8_t __unused4; 217 uint8_t __unused3; 218 uint8_t __unused2[20]; 219 uint8_t __unused1[6]; 220 uint8_t __unused0; 221 uint64_t boot_info_addr; 222 }; 223 224 struct boot_info { 225 uint32_t ver_major; 226 uint32_t ver_minor; 227 uint64_t stack_top; 228 uint64_t heap_start; 229 uint64_t heap_end; 230 uint64_t boot_desc_addr; 231 uint32_t exception_base_addr; 232 uint32_t stack_size; 233 uint32_t flags; 234 uint32_t core_mask; 235 uint32_t dram_size; 236 uint32_t phys_mem_desc_addr; 237 uint32_t debugger_flags_addr; 238 uint32_t eclock; 239 uint32_t dclock; 240 uint32_t __unused0; 241 uint16_t board_type; 242 uint8_t board_rev_major; 243 uint8_t board_rev_minor; 244 uint16_t __unused1; 245 uint8_t __unused2; 246 uint8_t __unused3; 247 char board_serial[20]; 248 uint8_t mac_addr_base[6]; 249 uint8_t mac_addr_count; 250 uint64_t cf_common_addr; 251 uint64_t cf_attr_addr; 252 uint64_t led_display_addr; 253 uint32_t dfaclock; 254 uint32_t config_flags; 255 /* The fields below are available when ver_minor >= 3. */ 256 uint64_t fdt_addr; 257 }; 258 259 struct octeon_bootmem_desc { 260 uint32_t lock; 261 uint32_t flags; 262 uint64_t head_addr; 263 uint32_t major_version; 264 uint32_t minor_version; 265 uint64_t app_data_addr; 266 uint64_t app_data_size; 267 uint32_t named_block_num_blocks; 268 uint32_t named_block_name_len; 269 uint64_t named_block_array_addr; 270 }; 271 272 struct octeon_bootmem_block { 273 uint64_t next; 274 uint64_t size; 275 }; 276 277 extern struct boot_desc *octeon_boot_desc; 278 extern struct boot_info *octeon_boot_info; 279 280 #ifdef _KERNEL 281 /* Device capabilities advertised in boot_info->config_flags */ 282 #define BOOTINFO_CFG_FLAG_PCI_HOST (1ull << 0) 283 #define BOOTINFO_CFG_FLAG_PCI_TARGET (1ull << 1) 284 #define BOOTINFO_CFG_FLAG_DEBUG (1ull << 2) 285 #define BOOTINFO_CFG_FLAG_NO_MAGIC (1ull << 3) 286 287 int octeon_ioclock_speed(void); 288 289 #endif /* _KERNEL */ 290 #endif /* _KERNEL || _STANDALONE */ 291 292 static inline int 293 ffs64(uint64_t val) 294 { 295 int ret; 296 297 __asm volatile ( \ 298 _ASM_PROLOGUE_MIPS64 299 " dclz %0, %1 \n" 300 _ASM_EPILOGUE 301 : "=r"(ret) : "r"(val)); 302 return 64 - ret; 303 } 304 305 static inline int 306 ffs32(uint32_t val) 307 { 308 int ret; 309 310 __asm __volatile ( \ 311 _ASM_PROLOGUE_MIPS64 312 " clz %0, %1 \n" 313 _ASM_EPILOGUE 314 : "=r"(ret) : "r"(val)); 315 return 32 - ret; 316 } 317 318 static inline uint64_t 319 octeon_xkphys_read_8(paddr_t address) 320 { 321 volatile uint64_t *p = 322 (volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC)); 323 return (*p); 324 } 325 326 #define MIO_BOOT_BIST_STAT 0x00011800000000f8ULL 327 static inline void 328 octeon_xkphys_write_8(paddr_t address, uint64_t value) 329 { 330 *(volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC)) = value; 331 332 /* 333 * It seems an immediate read is necessary when doing a write to an RSL 334 * register in order to complete the write. 335 * We use MIO_BOOT_BIST_STAT because it's apparently the fastest 336 * write. 337 */ 338 339 /* 340 * XXX 341 * This if would be better writen as: 342 * if ((address & 0xffffff0000000000ULL) == OCTEON_MIO_BOOT_BASE) { 343 * but octeonreg.h can't be included here and we want this inlined 344 * 345 * Note that the SDK masks with 0x7ffff but that doesn't make sense. 346 * This is a physical address. 347 */ 348 if (((address >> 40) & 0xfffff) == (0x118)) { 349 value = *(volatile uint64_t *) 350 (PHYS_TO_XKPHYS(MIO_BOOT_BIST_STAT, CCA_NC)); 351 } 352 } 353 354 static inline void 355 octeon_iobdma_write_8(uint64_t value) 356 { 357 uint64_t addr = 0xffffffffffffa200ULL; 358 359 *(volatile uint64_t *)addr = value; 360 } 361 362 static inline uint64_t 363 octeon_cvmseg_read_8(size_t offset) 364 { 365 return octeon_xkphys_read_8(0xffffffffffff8000ULL + offset); 366 } 367 368 static inline void 369 octeon_cvmseg_write_8(size_t offset, uint64_t value) 370 { 371 octeon_xkphys_write_8(0xffffffffffff8000ULL + offset, value); 372 } 373 374 static inline uint64_t 375 octeon_get_cycles(void) 376 { 377 uint64_t tmp; 378 379 __asm volatile ( 380 _ASM_PROLOGUE_MIPS64 381 " dmfc0 %[tmp], $9, 6 \n" 382 _ASM_EPILOGUE 383 : [tmp]"=&r"(tmp)); 384 return tmp; 385 } 386 387 static inline void 388 octeon_synciobdma(void) 389 { 390 __asm volatile ( 391 _ASM_PROLOGUE_OCTEON 392 " synciobdma\n" 393 _ASM_EPILOGUE 394 : : : "memory"); 395 } 396 397 #endif /* _MIPS_OCTEON_OCTEONVAR_H_ */ 398