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