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