[BACK]Return to octeonvar.h CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / mips / cavium

Annotation of src/sys/arch/mips/cavium/octeonvar.h, Revision 1.4

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

CVSweb <webmaster@jp.NetBSD.org>