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