Home | History | Annotate | Line # | Download | only in cavium
octeonvar.h revision 1.5.18.1
      1  1.5.18.1  pgoyette /*	$NetBSD: octeonvar.h,v 1.5.18.1 2018/04/22 07:20:18 pgoyette 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.1    hikaru 	/* 20-32 */
    167       1.1    hikaru 	uint64_t	xxx_20_32[32 - 20];
    168       1.1    hikaru } __packed;
    169       1.1    hikaru #define	OCTEON_CVMSEG_OFFSET(entry) \
    170       1.1    hikaru 	offsetof(struct octeon_cvmseg_map, entry)
    171       1.1    hikaru #define	OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \
    172       1.1    hikaru 	(offsetof(struct octeon_cvmseg_map, csm_ether) + \
    173       1.1    hikaru 	 sizeof(struct octeon_cvmseg_ether_map) * (n) + \
    174       1.1    hikaru 	 offsetof(struct octeon_cvmseg_ether_map, entry))
    175       1.1    hikaru 
    176       1.1    hikaru /*
    177       1.1    hikaru  * FAU register map
    178       1.1    hikaru  *
    179       1.1    hikaru  * => FAU registers exist in FAU unit
    180       1.1    hikaru  * => devices (PKO) can access these registers
    181       1.1    hikaru  * => CPU can read those values after loading them into CVMSEG
    182       1.1    hikaru  */
    183       1.1    hikaru struct octeon_fau_map {
    184       1.1    hikaru 	struct {
    185       1.1    hikaru 		/* PKO command index */
    186       1.1    hikaru 		uint64_t	_fau_map_port_pkocmdidx;
    187       1.1    hikaru 		/* send requested */
    188       1.1    hikaru 		uint64_t	_fau_map_port_txreq;
    189       1.1    hikaru 		/* send completed */
    190       1.1    hikaru 		uint64_t	_fau_map_port_txdone;
    191       1.1    hikaru 		/* XXX */
    192       1.1    hikaru 		uint64_t	_fau_map_port_pad;
    193       1.1    hikaru 	} __packed _fau_map_port[3];
    194       1.1    hikaru };
    195       1.1    hikaru 
    196       1.1    hikaru /*
    197       1.1    hikaru  * POW qos/group map
    198       1.1    hikaru  */
    199       1.1    hikaru 
    200       1.1    hikaru #define	OCTEON_POW_QOS_PIP		0
    201       1.1    hikaru #define	OCTEON_POW_QOS_CORE1		1
    202       1.1    hikaru #define	OCTEON_POW_QOS_XXX_2		2
    203       1.1    hikaru #define	OCTEON_POW_QOS_XXX_3		3
    204       1.1    hikaru #define	OCTEON_POW_QOS_XXX_4		4
    205       1.1    hikaru #define	OCTEON_POW_QOS_XXX_5		5
    206       1.1    hikaru #define	OCTEON_POW_QOS_XXX_6		6
    207       1.1    hikaru #define	OCTEON_POW_QOS_XXX_7		7
    208       1.1    hikaru 
    209       1.1    hikaru #define	OCTEON_POW_GROUP_PIP		0
    210       1.1    hikaru #define	OCTEON_POW_GROUP_XXX_1		1
    211       1.1    hikaru #define	OCTEON_POW_GROUP_XXX_2		2
    212       1.1    hikaru #define	OCTEON_POW_GROUP_XXX_3		3
    213       1.1    hikaru #define	OCTEON_POW_GROUP_XXX_4		4
    214       1.1    hikaru #define	OCTEON_POW_GROUP_XXX_5		5
    215       1.1    hikaru #define	OCTEON_POW_GROUP_XXX_6		6
    216       1.1    hikaru #define	OCTEON_POW_GROUP_CORE1_SEND	7
    217       1.1    hikaru #define	OCTEON_POW_GROUP_CORE1_TASK_0	8
    218       1.1    hikaru #define	OCTEON_POW_GROUP_CORE1_TASK_1	9
    219       1.1    hikaru #define	OCTEON_POW_GROUP_CORE1_TASK_2	10
    220       1.1    hikaru #define	OCTEON_POW_GROUP_CORE1_TASK_3	11
    221       1.1    hikaru #define	OCTEON_POW_GROUP_CORE1_TASK_4	12
    222       1.1    hikaru #define	OCTEON_POW_GROUP_CORE1_TASK_5	13
    223       1.1    hikaru #define	OCTEON_POW_GROUP_CORE1_TASK_6	14
    224       1.1    hikaru #define	OCTEON_POW_GROUP_CORE1_TASK_7	15
    225       1.1    hikaru 
    226       1.1    hikaru #ifdef _KERNEL
    227       1.1    hikaru extern struct octeon_config	octeon_configuration;
    228       1.2      matt #ifdef MULTIPROCESSOR
    229       1.4      matt extern kcpuset_t *cpus_booted;
    230       1.2      matt extern struct cpu_softc		octeon_cpu1_softc;
    231       1.2      matt #endif
    232       1.1    hikaru 
    233       1.1    hikaru void	octeon_bus_io_init(bus_space_tag_t, void *);
    234       1.1    hikaru void	octeon_bus_mem_init(bus_space_tag_t, void *);
    235       1.1    hikaru void	octeon_cal_timer(int);
    236       1.1    hikaru void	octeon_dma_init(struct octeon_config *);
    237       1.2      matt void	octeon_intr_init(struct cpu_info *);
    238       1.1    hikaru void	octeon_iointr(int, vaddr_t, uint32_t);
    239       1.1    hikaru void	octeon_pci_init(pci_chipset_tag_t, struct octeon_config *);
    240       1.2      matt void	*octeon_intr_establish(int, int, int (*)(void *), void *);
    241       1.1    hikaru void	octeon_intr_disestablish(void *cookie);
    242       1.2      matt 
    243       1.5      matt void	octeon_reset_vector(void);
    244       1.2      matt uint64_t mips_cp0_cvmctl_read(void);
    245       1.2      matt void	 mips_cp0_cvmctl_write(uint64_t);
    246       1.2      matt 
    247       1.1    hikaru #endif /* _KERNEL */
    248       1.1    hikaru 
    249       1.1    hikaru #if defined(__mips_n32)
    250       1.1    hikaru #define ffs64	__builtin_ffsll
    251       1.1    hikaru #elif defined(_LP64)
    252       1.1    hikaru #define ffs64	__builtin_ffsl
    253       1.1    hikaru #else
    254       1.1    hikaru #error unknown ABI
    255       1.1    hikaru #endif
    256       1.1    hikaru 
    257       1.1    hikaru /*
    258       1.1    hikaru  * Prefetch
    259       1.1    hikaru  *
    260       1.1    hikaru  *	OCTEON_PREF		normal (L1 and L2)
    261       1.1    hikaru  *	OCTEON_PREF_L1		L1 only
    262       1.1    hikaru  *	OCTEON_PREF_L2		L2 only
    263       1.1    hikaru  *	OCTEON_PREF_DWB		don't write back
    264       1.1    hikaru  *	OCTEON_PREF_PFS		prepare for store
    265       1.1    hikaru  */
    266       1.1    hikaru #define __OCTEON_PREF_N(n, base, offset)			\
    267       1.1    hikaru 	__asm __volatile (					\
    268       1.1    hikaru 		"	.set	push				\
    269       1.1    hikaru 		"	.set	arch=octeon			\n" \
    270       1.1    hikaru 		"	pref	"#n", "#offset"(%[base])	\n" \
    271       1.1    hikaru 		"	.set	pop				\
    272       1.1    hikaru 		: : [base] "d" (base)				\
    273       1.1    hikaru 	)
    274       1.1    hikaru #define __OCTEON_PREF_0(base, offset)	__OCTEON_PREF_N(0, base, offset)
    275       1.1    hikaru #define __OCTEON_PREF_4(base, offset)	__OCTEON_PREF_N(4, base, offset)
    276       1.1    hikaru #define __OCTEON_PREF_28(base, offset)	__OCTEON_PREF_N(28, base, offset)
    277       1.1    hikaru #define __OCTEON_PREF_29(base, offset)	__OCTEON_PREF_N(29, base, offset)
    278       1.1    hikaru #define __OCTEON_PREF_30(base, offset)	__OCTEON_PREF_N(30, base, offset)
    279       1.1    hikaru #define OCTEON_PREF(base, offset)	__OCTEON_PREF_0(base, offset)
    280       1.1    hikaru #define OCTEON_PREF_L1(base, offset)	__OCTEON_PREF_4(base, offset)
    281       1.1    hikaru #define OCTEON_PREF_L2(base, offset)	__OCTEON_PREF_28(base, offset)
    282       1.1    hikaru #define OCTEON_PREF_DWB(base, offset)	__OCTEON_PREF_29(base, offset)
    283       1.1    hikaru #define OCTEON_PREF_PFS(base, offset)	__OCTEON_PREF_30(base, offset)
    284       1.1    hikaru 
    285       1.1    hikaru /*
    286       1.1    hikaru  * Sync
    287       1.1    hikaru  */
    288       1.1    hikaru #define OCTEON_SYNCCOMMON(name) \
    289       1.1    hikaru 	__asm __volatile ( \
    290       1.1    hikaru 		_ASM_PROLOGUE_OCTEON			\
    291       1.1    hikaru 		"	"#name"				\n" \
    292       1.1    hikaru 		_ASM_EPILOGUE				\
    293       1.1    hikaru 		::: "memory")
    294       1.1    hikaru #define OCTEON_SYNCIOBDMA	OCTEON_SYNCCOMMON(synciobdma)
    295       1.1    hikaru #define OCTEON_SYNCW		OCTEON_SYNCCOMMON(syncw)
    296       1.1    hikaru #define OCTEON_SYNC		OCTEON_SYNCCOMMON(sync)
    297       1.1    hikaru #define OCTEON_SYNCWS		OCTEON_SYNCCOMMON(syncws)
    298       1.1    hikaru #define OCTEON_SYNCS		OCTEON_SYNCCOMMON(syncs)
    299       1.1    hikaru /* XXX backward compatibility */
    300       1.1    hikaru #if 1
    301       1.1    hikaru #define	OCT_SYNCIOBDMA		OCTEON_SYNCIOBDMA
    302       1.1    hikaru #define	OCT_SYNCW		OCTEON_SYNCW
    303       1.1    hikaru #define	OCT_SYNC		OCTEON_SYNC
    304       1.1    hikaru #define	OCT_SYNCWS		OCTEON_SYNCWS
    305       1.1    hikaru #define	OCT_SYNCS		OCTEON_SYNCS
    306       1.1    hikaru #endif
    307       1.1    hikaru 
    308       1.1    hikaru /* octeon core does not use cca to determine cacheability */
    309       1.1    hikaru #define OCTEON_CCA_NONE UINT64_C(0)
    310       1.1    hikaru 
    311  1.5.18.1  pgoyette static __inline uint64_t
    312       1.1    hikaru octeon_xkphys_read_8(paddr_t address)
    313       1.1    hikaru {
    314       1.5      matt 	return mips3_ld(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address));
    315       1.1    hikaru }
    316       1.1    hikaru 
    317  1.5.18.1  pgoyette static __inline void
    318       1.1    hikaru octeon_xkphys_write_8(paddr_t address, uint64_t value)
    319       1.1    hikaru {
    320       1.5      matt 	mips3_sd(MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, address), value);
    321       1.1    hikaru }
    322       1.1    hikaru 
    323       1.1    hikaru /* XXX backward compatibility */
    324       1.1    hikaru #if 1
    325       1.1    hikaru #define octeon_read_csr(address) \
    326       1.1    hikaru 	octeon_xkphys_read_8(address)
    327       1.1    hikaru #define octeon_write_csr(address, value) \
    328       1.1    hikaru 	octeon_xkphys_write_8(address, value)
    329       1.1    hikaru #endif
    330       1.1    hikaru 
    331  1.5.18.1  pgoyette static __inline void
    332       1.1    hikaru octeon_iobdma_write_8(uint64_t value)
    333       1.1    hikaru {
    334       1.1    hikaru 	uint64_t addr = UINT64_C(0xffffffffffffa200);
    335       1.1    hikaru 
    336       1.1    hikaru 	octeon_xkphys_write_8(addr, value);
    337       1.1    hikaru }
    338       1.1    hikaru 
    339  1.5.18.1  pgoyette static __inline uint64_t
    340       1.1    hikaru octeon_cvmseg_read_8(size_t offset)
    341       1.1    hikaru {
    342       1.1    hikaru 	return octeon_xkphys_read_8(UINT64_C(0xffffffffffff8000) + offset);
    343       1.1    hikaru }
    344       1.1    hikaru 
    345  1.5.18.1  pgoyette static __inline void
    346       1.1    hikaru octeon_cvmseg_write_8(size_t offset, uint64_t value)
    347       1.1    hikaru {
    348       1.1    hikaru 	octeon_xkphys_write_8(UINT64_C(0xffffffffffff8000) + offset, value);
    349       1.1    hikaru }
    350       1.1    hikaru 
    351       1.1    hikaru /* XXX */
    352  1.5.18.1  pgoyette static __inline uint32_t
    353       1.1    hikaru octeon_disable_interrupt(uint32_t *new)
    354       1.1    hikaru {
    355       1.1    hikaru 	uint32_t s, tmp;
    356       1.1    hikaru 
    357       1.1    hikaru 	__asm __volatile (
    358       1.1    hikaru 		_ASM_PROLOGUE
    359       1.1    hikaru 		"	mfc0	%[s], $12		\n"
    360       1.1    hikaru 		"	and	%[tmp], %[s], ~1	\n"
    361       1.1    hikaru 		"	mtc0	%[tmp], $12		\n"
    362       1.1    hikaru 		_ASM_EPILOGUE
    363       1.1    hikaru 		: [s]"=&r"(s), [tmp]"=&r"(tmp));
    364       1.1    hikaru 	if (new)
    365       1.1    hikaru 		*new = tmp;
    366       1.1    hikaru 	return s;
    367       1.1    hikaru }
    368       1.1    hikaru 
    369       1.1    hikaru /* XXX */
    370  1.5.18.1  pgoyette static __inline void
    371       1.1    hikaru octeon_restore_status(uint32_t s)
    372       1.1    hikaru {
    373       1.1    hikaru 	__asm __volatile (
    374       1.1    hikaru 		_ASM_PROLOGUE
    375       1.1    hikaru 		"	mtc0	%[s], $12		\n"
    376       1.1    hikaru 		_ASM_EPILOGUE
    377       1.1    hikaru 		:: [s]"r"(s));
    378       1.1    hikaru }
    379       1.1    hikaru 
    380  1.5.18.1  pgoyette static __inline uint64_t
    381       1.1    hikaru octeon_get_cycles(void)
    382       1.1    hikaru {
    383       1.1    hikaru #if defined(__mips_o32)
    384       1.1    hikaru 	uint32_t s, lo, hi;
    385       1.1    hikaru 
    386       1.1    hikaru 	s = octeon_disable_interrupt((void *)0);
    387       1.1    hikaru 	__asm __volatile (
    388       1.1    hikaru 		_ASM_PROLOGUE_MIPS64
    389       1.1    hikaru 		"	dmfc0	%[lo], $9, 6		\n"
    390       1.1    hikaru 		"	add	%[hi], %[lo], $0	\n"
    391       1.1    hikaru 		"	srl	%[hi], 32		\n"
    392       1.1    hikaru 		"	sll	%[lo], 32		\n"
    393       1.1    hikaru 		"	srl	%[lo], 32		\n"
    394       1.1    hikaru 		_ASM_EPILOGUE
    395       1.1    hikaru 		: [lo]"=&r"(lo), [hi]"=&r"(hi));
    396       1.1    hikaru 	octeon_restore_status(s);
    397       1.1    hikaru 	return ((uint64_t)hi << 32) + (uint64_t)lo;
    398       1.1    hikaru #else
    399       1.1    hikaru 	uint64_t tmp;
    400       1.1    hikaru 
    401       1.1    hikaru 	__asm __volatile (
    402       1.1    hikaru 		_ASM_PROLOGUE_MIPS64
    403       1.1    hikaru 		"	dmfc0	%[tmp], $9, 6		\n"
    404       1.1    hikaru 		_ASM_EPILOGUE
    405       1.1    hikaru 		: [tmp]"=&r"(tmp));
    406       1.1    hikaru 	return tmp;
    407       1.1    hikaru #endif
    408       1.1    hikaru }
    409       1.1    hikaru 
    410       1.1    hikaru /* -------------------------------------------------------------------------- */
    411       1.1    hikaru 
    412       1.1    hikaru /* ---- event counter */
    413       1.1    hikaru 
    414       1.1    hikaru #if defined(OCTEON_ETH_DEBUG)
    415       1.1    hikaru #define	OCTEON_EVCNT_INC(sc, name) \
    416       1.1    hikaru 	do { (sc)->sc_ev_##name.ev_count++; } while (0)
    417       1.1    hikaru #define	OCTEON_EVCNT_ADD(sc, name, n) \
    418       1.1    hikaru 	do { (sc)->sc_ev_##name.ev_count += (n); } while (0)
    419       1.1    hikaru #define	OCTEON_EVCNT_ATTACH_EVCNTS(sc, entries, devname) \
    420       1.1    hikaru do {								\
    421       1.1    hikaru 	int i;							\
    422       1.1    hikaru 	const struct octeon_evcnt_entry *ee;			\
    423       1.1    hikaru 								\
    424       1.1    hikaru 	for (i = 0; i < (int)__arraycount(entries); i++) {	\
    425       1.1    hikaru 		ee = &(entries)[i];				\
    426       1.1    hikaru 		evcnt_attach_dynamic(				\
    427       1.1    hikaru 		    (struct evcnt *)((uintptr_t)(sc) + ee->ee_offset), \
    428       1.1    hikaru 		    ee->ee_type, ee->ee_parent, devname,	\
    429       1.1    hikaru 		    ee->ee_name);				\
    430       1.1    hikaru 	}							\
    431       1.1    hikaru } while (0)
    432       1.1    hikaru #else
    433       1.1    hikaru #define	OCTEON_EVCNT_INC(sc, name)
    434       1.1    hikaru #define	OCTEON_EVCNT_ADD(sc, name, n)
    435       1.1    hikaru #define	OCTEON_EVCNT_ATTACH_EVCNTS(sc, entries, devname)
    436       1.1    hikaru #endif
    437       1.1    hikaru 
    438       1.1    hikaru struct octeon_evcnt_entry {
    439       1.1    hikaru 	size_t		ee_offset;
    440       1.1    hikaru 	int		ee_type;
    441       1.1    hikaru 	struct evcnt	*ee_parent;
    442       1.1    hikaru 	const char	*ee_name;
    443       1.1    hikaru };
    444       1.1    hikaru 
    445       1.1    hikaru #define	OCTEON_EVCNT_ENTRY(_sc_type, _var, _ev_type, _parent, _name) \
    446       1.1    hikaru 	{							\
    447       1.1    hikaru 		.ee_offset = offsetof(_sc_type, sc_ev_##_var),	\
    448       1.1    hikaru 		.ee_type = EVCNT_TYPE_##_ev_type,		\
    449       1.1    hikaru 		.ee_parent = _parent,				\
    450       1.1    hikaru 		.ee_name = _name				\
    451       1.1    hikaru 	}
    452       1.1    hikaru 
    453       1.1    hikaru #endif	/* _MIPS_OCTEON_OCTEONVAR_H_ */
    454