Annotation of src/sys/arch/mips/cavium/octeonvar.h, Revision 1.2.2.2
1.2.2.2 ! skrll 1: /* $NetBSD: octeonvar.h,v 1.2 2015/06/01 22:55:12 matt 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 <mips/locore.h>
! 38: #include <dev/pci/pcivar.h>
! 39:
! 40: /* XXX elsewhere */
! 41: #define _ASM_PROLOGUE \
! 42: " .set push \n" \
! 43: " .set noreorder \n"
! 44: #define _ASM_PROLOGUE_MIPS64 \
! 45: _ASM_PROLOGUE \
! 46: " .set mips64 \n"
! 47: #define _ASM_PROLOGUE_OCTEON \
! 48: _ASM_PROLOGUE \
! 49: " .set arch=octeon \n"
! 50: #define _ASM_EPILOGUE \
! 51: " .set pop \n"
! 52: /*
! 53: * subbits = __BITS64_GET(XXX, bits);
! 54: * bits = __BITS64_SET(XXX, subbits);
! 55: */
! 56: #ifndef __BITS64_GET
! 57: #define __BITS64_GET(name, bits) \
! 58: (((uint64_t)(bits) & name) >> name##_SHIFT)
! 59: #endif
! 60: #ifndef __BITS64_SET
! 61: #define __BITS64_SET(name, subbits) \
! 62: (((uint64_t)(subbits) << name##_SHIFT) & name)
! 63: #endif
! 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:
! 74: struct extent *mc_io_ex;
! 75: struct extent *mc_mem_ex;
! 76:
! 77: int mc_mallocsafe;
! 78: };
! 79:
! 80: #define NIRQS 64
! 81:
! 82: struct cpu_softc {
! 83: struct cpu_info *cpu_ci;
! 84: uint64_t cpu_int0_sum0;
! 85: uint64_t cpu_int1_sum0;
! 86: uint64_t cpu_int2_sum0;
! 87:
! 88: uint64_t cpu_int0_en0;
! 89: uint64_t cpu_int1_en0;
! 90: uint64_t cpu_int2_en0;
! 91:
! 92: uint64_t cpu_int0_en1;
! 93: uint64_t cpu_int1_en1;
! 94: uint64_t cpu_int2_en1;
! 95:
! 96: uint64_t cpu_int32_en;
! 97:
! 98: struct evcnt cpu_intr_evs[NIRQS];
! 99:
! 100: uint64_t cpu_int0_enable0;
! 101: uint64_t cpu_int1_enable0;
! 102: uint64_t cpu_int2_enable0;
! 103:
! 104: #ifdef MULTIPROCESSOR
! 105: uint64_t cpu_mbox_set;
! 106: uint64_t cpu_mbox_clr;
! 107: #endif
! 108: };
! 109:
! 110: /*
! 111: * FPA map
! 112: */
! 113:
! 114: #define OCTEON_POOL_NO_PKT 0
! 115: #define OCTEON_POOL_NO_WQE 1
! 116: #define OCTEON_POOL_NO_CMD 2
! 117: #define OCTEON_POOL_NO_SG 3
! 118: #define OCTEON_POOL_NO_XXX_4 4
! 119: #define OCTEON_POOL_NO_XXX_5 5
! 120: #define OCTEON_POOL_NO_XXX_6 6
! 121: #define OCTEON_POOL_NO_DUMP 7 /* FPA debug dump */
! 122:
! 123: #define OCTEON_POOL_SIZE_PKT 2048 /* 128 x 16 */
! 124: #define OCTEON_POOL_SIZE_WQE 128 /* 128 x 1 */
! 125: #define OCTEON_POOL_SIZE_CMD 1024 /* 128 x 8 */
! 126: #define OCTEON_POOL_SIZE_SG 512 /* 128 x 4 */
! 127: #define OCTEON_POOL_SIZE_XXX_4 0
! 128: #define OCTEON_POOL_SIZE_XXX_5 0
! 129: #define OCTEON_POOL_SIZE_XXX_6 0
! 130: #define OCTEON_POOL_SIZE_XXX_7 0
! 131:
! 132: #define OCTEON_POOL_NELEMS_PKT 4096
! 133: #define OCTEON_POOL_NELEMS_WQE 4096
! 134: #define OCTEON_POOL_NELEMS_CMD 32
! 135: #define OCTEON_POOL_NELEMS_SG 1024
! 136: #define OCTEON_POOL_NELEMS_XXX_4 0
! 137: #define OCTEON_POOL_NELEMS_XXX_5 0
! 138: #define OCTEON_POOL_NELEMS_XXX_6 0
! 139: #define OCTEON_POOL_NELEMS_XXX_7 0
! 140:
! 141: /*
! 142: * CVMSEG (``scratch'') memory map
! 143: */
! 144: struct octeon_cvmseg_map {
! 145: /* 0-3 */
! 146: uint64_t csm_xxx_0;
! 147: uint64_t csm_xxx_1;
! 148: uint64_t csm_xxx_2;
! 149: uint64_t csm_pow_intr;
! 150:
! 151: /* 4-19 */
! 152: struct octeon_cvmseg_ether_map {
! 153: uint64_t csm_ether_fau_req;
! 154: uint64_t csm_ether_fau_done;
! 155: uint64_t csm_ether_fau_cmdptr;
! 156: uint64_t csm_ether_xxx_3;
! 157: } csm_ether[4/* XXX */];
! 158:
! 159: /* 20-32 */
! 160: uint64_t xxx_20_32[32 - 20];
! 161: } __packed;
! 162: #define OCTEON_CVMSEG_OFFSET(entry) \
! 163: offsetof(struct octeon_cvmseg_map, entry)
! 164: #define OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \
! 165: (offsetof(struct octeon_cvmseg_map, csm_ether) + \
! 166: sizeof(struct octeon_cvmseg_ether_map) * (n) + \
! 167: offsetof(struct octeon_cvmseg_ether_map, entry))
! 168:
! 169: /*
! 170: * FAU register map
! 171: *
! 172: * => FAU registers exist in FAU unit
! 173: * => devices (PKO) can access these registers
! 174: * => CPU can read those values after loading them into CVMSEG
! 175: */
! 176: struct octeon_fau_map {
! 177: struct {
! 178: /* PKO command index */
! 179: uint64_t _fau_map_port_pkocmdidx;
! 180: /* send requested */
! 181: uint64_t _fau_map_port_txreq;
! 182: /* send completed */
! 183: uint64_t _fau_map_port_txdone;
! 184: /* XXX */
! 185: uint64_t _fau_map_port_pad;
! 186: } __packed _fau_map_port[3];
! 187: };
! 188:
! 189: /*
! 190: * POW qos/group map
! 191: */
! 192:
! 193: #define OCTEON_POW_QOS_PIP 0
! 194: #define OCTEON_POW_QOS_CORE1 1
! 195: #define OCTEON_POW_QOS_XXX_2 2
! 196: #define OCTEON_POW_QOS_XXX_3 3
! 197: #define OCTEON_POW_QOS_XXX_4 4
! 198: #define OCTEON_POW_QOS_XXX_5 5
! 199: #define OCTEON_POW_QOS_XXX_6 6
! 200: #define OCTEON_POW_QOS_XXX_7 7
! 201:
! 202: #define OCTEON_POW_GROUP_PIP 0
! 203: #define OCTEON_POW_GROUP_XXX_1 1
! 204: #define OCTEON_POW_GROUP_XXX_2 2
! 205: #define OCTEON_POW_GROUP_XXX_3 3
! 206: #define OCTEON_POW_GROUP_XXX_4 4
! 207: #define OCTEON_POW_GROUP_XXX_5 5
! 208: #define OCTEON_POW_GROUP_XXX_6 6
! 209: #define OCTEON_POW_GROUP_CORE1_SEND 7
! 210: #define OCTEON_POW_GROUP_CORE1_TASK_0 8
! 211: #define OCTEON_POW_GROUP_CORE1_TASK_1 9
! 212: #define OCTEON_POW_GROUP_CORE1_TASK_2 10
! 213: #define OCTEON_POW_GROUP_CORE1_TASK_3 11
! 214: #define OCTEON_POW_GROUP_CORE1_TASK_4 12
! 215: #define OCTEON_POW_GROUP_CORE1_TASK_5 13
! 216: #define OCTEON_POW_GROUP_CORE1_TASK_6 14
! 217: #define OCTEON_POW_GROUP_CORE1_TASK_7 15
! 218:
! 219: #ifdef _KERNEL
! 220: extern struct octeon_config octeon_configuration;
! 221: #ifdef MULTIPROCESSOR
! 222: extern struct cpu_softc octeon_cpu1_softc;
! 223: #endif
! 224:
! 225: void octeon_bus_io_init(bus_space_tag_t, void *);
! 226: void octeon_bus_mem_init(bus_space_tag_t, void *);
! 227: void octeon_cal_timer(int);
! 228: void octeon_dma_init(struct octeon_config *);
! 229: void octeon_intr_init(struct cpu_info *);
! 230: void octeon_iointr(int, vaddr_t, uint32_t);
! 231: void octeon_pci_init(pci_chipset_tag_t, struct octeon_config *);
! 232: void *octeon_intr_establish(int, int, int (*)(void *), void *);
! 233: void octeon_intr_disestablish(void *cookie);
! 234:
! 235: uint64_t mips_cp0_cvmctl_read(void);
! 236: void mips_cp0_cvmctl_write(uint64_t);
! 237:
! 238: #endif /* _KERNEL */
! 239:
! 240: #if defined(__mips_n32)
! 241: #define ffs64 __builtin_ffsll
! 242: #elif defined(_LP64)
! 243: #define ffs64 __builtin_ffsl
! 244: #else
! 245: #error unknown ABI
! 246: #endif
! 247:
! 248: /*
! 249: * Prefetch
! 250: *
! 251: * OCTEON_PREF normal (L1 and L2)
! 252: * OCTEON_PREF_L1 L1 only
! 253: * OCTEON_PREF_L2 L2 only
! 254: * OCTEON_PREF_DWB don't write back
! 255: * OCTEON_PREF_PFS prepare for store
! 256: */
! 257: #define __OCTEON_PREF_N(n, base, offset) \
! 258: __asm __volatile ( \
! 259: " .set push \
! 260: " .set arch=octeon \n" \
! 261: " pref "#n", "#offset"(%[base]) \n" \
! 262: " .set pop \
! 263: : : [base] "d" (base) \
! 264: )
! 265: #define __OCTEON_PREF_0(base, offset) __OCTEON_PREF_N(0, base, offset)
! 266: #define __OCTEON_PREF_4(base, offset) __OCTEON_PREF_N(4, base, offset)
! 267: #define __OCTEON_PREF_28(base, offset) __OCTEON_PREF_N(28, base, offset)
! 268: #define __OCTEON_PREF_29(base, offset) __OCTEON_PREF_N(29, base, offset)
! 269: #define __OCTEON_PREF_30(base, offset) __OCTEON_PREF_N(30, base, offset)
! 270: #define OCTEON_PREF(base, offset) __OCTEON_PREF_0(base, offset)
! 271: #define OCTEON_PREF_L1(base, offset) __OCTEON_PREF_4(base, offset)
! 272: #define OCTEON_PREF_L2(base, offset) __OCTEON_PREF_28(base, offset)
! 273: #define OCTEON_PREF_DWB(base, offset) __OCTEON_PREF_29(base, offset)
! 274: #define OCTEON_PREF_PFS(base, offset) __OCTEON_PREF_30(base, offset)
! 275:
! 276: /*
! 277: * Sync
! 278: */
! 279: #define OCTEON_SYNCCOMMON(name) \
! 280: __asm __volatile ( \
! 281: _ASM_PROLOGUE_OCTEON \
! 282: " "#name" \n" \
! 283: _ASM_EPILOGUE \
! 284: ::: "memory")
! 285: #define OCTEON_SYNCIOBDMA OCTEON_SYNCCOMMON(synciobdma)
! 286: #define OCTEON_SYNCW OCTEON_SYNCCOMMON(syncw)
! 287: #define OCTEON_SYNC OCTEON_SYNCCOMMON(sync)
! 288: #define OCTEON_SYNCWS OCTEON_SYNCCOMMON(syncws)
! 289: #define OCTEON_SYNCS OCTEON_SYNCCOMMON(syncs)
! 290: /* XXX backward compatibility */
! 291: #if 1
! 292: #define OCT_SYNCIOBDMA OCTEON_SYNCIOBDMA
! 293: #define OCT_SYNCW OCTEON_SYNCW
! 294: #define OCT_SYNC OCTEON_SYNC
! 295: #define OCT_SYNCWS OCTEON_SYNCWS
! 296: #define OCT_SYNCS OCTEON_SYNCS
! 297: #endif
! 298:
! 299: /* octeon core does not use cca to determine cacheability */
! 300: #define OCTEON_CCA_NONE UINT64_C(0)
! 301:
! 302: static inline uint64_t
! 303: octeon_xkphys_read_8(paddr_t address)
! 304: {
! 305: return mips64_ld_a64(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address));
! 306: }
! 307:
! 308: static inline void
! 309: octeon_xkphys_write_8(paddr_t address, uint64_t value)
! 310: {
! 311: mips64_sd_a64(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address), value);
! 312: }
! 313:
! 314: /* XXX backward compatibility */
! 315: #if 1
! 316: #define octeon_read_csr(address) \
! 317: octeon_xkphys_read_8(address)
! 318: #define octeon_write_csr(address, value) \
! 319: octeon_xkphys_write_8(address, value)
! 320: #endif
! 321:
! 322: static inline void
! 323: octeon_iobdma_write_8(uint64_t value)
! 324: {
! 325: uint64_t addr = UINT64_C(0xffffffffffffa200);
! 326:
! 327: octeon_xkphys_write_8(addr, value);
! 328: }
! 329:
! 330: static inline uint64_t
! 331: octeon_cvmseg_read_8(size_t offset)
! 332: {
! 333: return octeon_xkphys_read_8(UINT64_C(0xffffffffffff8000) + offset);
! 334: }
! 335:
! 336: static inline void
! 337: octeon_cvmseg_write_8(size_t offset, uint64_t value)
! 338: {
! 339: octeon_xkphys_write_8(UINT64_C(0xffffffffffff8000) + offset, value);
! 340: }
! 341:
! 342: /* XXX */
! 343: static inline uint32_t
! 344: octeon_disable_interrupt(uint32_t *new)
! 345: {
! 346: uint32_t s, tmp;
! 347:
! 348: __asm __volatile (
! 349: _ASM_PROLOGUE
! 350: " mfc0 %[s], $12 \n"
! 351: " and %[tmp], %[s], ~1 \n"
! 352: " mtc0 %[tmp], $12 \n"
! 353: _ASM_EPILOGUE
! 354: : [s]"=&r"(s), [tmp]"=&r"(tmp));
! 355: if (new)
! 356: *new = tmp;
! 357: return s;
! 358: }
! 359:
! 360: /* XXX */
! 361: static inline void
! 362: octeon_restore_status(uint32_t s)
! 363: {
! 364: __asm __volatile (
! 365: _ASM_PROLOGUE
! 366: " mtc0 %[s], $12 \n"
! 367: _ASM_EPILOGUE
! 368: :: [s]"r"(s));
! 369: }
! 370:
! 371: static inline uint64_t
! 372: octeon_get_cycles(void)
! 373: {
! 374: #if defined(__mips_o32)
! 375: uint32_t s, lo, hi;
! 376:
! 377: s = octeon_disable_interrupt((void *)0);
! 378: __asm __volatile (
! 379: _ASM_PROLOGUE_MIPS64
! 380: " dmfc0 %[lo], $9, 6 \n"
! 381: " add %[hi], %[lo], $0 \n"
! 382: " srl %[hi], 32 \n"
! 383: " sll %[lo], 32 \n"
! 384: " srl %[lo], 32 \n"
! 385: _ASM_EPILOGUE
! 386: : [lo]"=&r"(lo), [hi]"=&r"(hi));
! 387: octeon_restore_status(s);
! 388: return ((uint64_t)hi << 32) + (uint64_t)lo;
! 389: #else
! 390: uint64_t tmp;
! 391:
! 392: __asm __volatile (
! 393: _ASM_PROLOGUE_MIPS64
! 394: " dmfc0 %[tmp], $9, 6 \n"
! 395: _ASM_EPILOGUE
! 396: : [tmp]"=&r"(tmp));
! 397: return tmp;
! 398: #endif
! 399: }
! 400:
! 401: /* -------------------------------------------------------------------------- */
! 402:
! 403: /* ---- event counter */
! 404:
! 405: #if defined(OCTEON_ETH_DEBUG)
! 406: #define OCTEON_EVCNT_INC(sc, name) \
! 407: do { (sc)->sc_ev_##name.ev_count++; } while (0)
! 408: #define OCTEON_EVCNT_ADD(sc, name, n) \
! 409: do { (sc)->sc_ev_##name.ev_count += (n); } while (0)
! 410: #define OCTEON_EVCNT_ATTACH_EVCNTS(sc, entries, devname) \
! 411: do { \
! 412: int i; \
! 413: const struct octeon_evcnt_entry *ee; \
! 414: \
! 415: for (i = 0; i < (int)__arraycount(entries); i++) { \
! 416: ee = &(entries)[i]; \
! 417: evcnt_attach_dynamic( \
! 418: (struct evcnt *)((uintptr_t)(sc) + ee->ee_offset), \
! 419: ee->ee_type, ee->ee_parent, devname, \
! 420: ee->ee_name); \
! 421: } \
! 422: } while (0)
! 423: #else
! 424: #define OCTEON_EVCNT_INC(sc, name)
! 425: #define OCTEON_EVCNT_ADD(sc, name, n)
! 426: #define OCTEON_EVCNT_ATTACH_EVCNTS(sc, entries, devname)
! 427: #endif
! 428:
! 429: struct octeon_evcnt_entry {
! 430: size_t ee_offset;
! 431: int ee_type;
! 432: struct evcnt *ee_parent;
! 433: const char *ee_name;
! 434: };
! 435:
! 436: #define OCTEON_EVCNT_ENTRY(_sc_type, _var, _ev_type, _parent, _name) \
! 437: { \
! 438: .ee_offset = offsetof(_sc_type, sc_ev_##_var), \
! 439: .ee_type = EVCNT_TYPE_##_ev_type, \
! 440: .ee_parent = _parent, \
! 441: .ee_name = _name \
! 442: }
! 443:
! 444: #endif /* _MIPS_OCTEON_OCTEONVAR_H_ */
CVSweb <webmaster@jp.NetBSD.org>