xref: /openbsd-src/sys/arch/octeon/include/octeonvar.h (revision dd81489db8c6745c0e25d81d82e97f90d8886b12)
1*dd81489dSjsg /*	$OpenBSD: octeonvar.h,v 1.54 2022/08/29 02:01:18 jsg Exp $	*/
24a04f2fdSsyuu /*	$NetBSD: maltavar.h,v 1.3 2002/03/18 10:10:16 simonb Exp $	*/
34a04f2fdSsyuu 
44a04f2fdSsyuu /*-
54a04f2fdSsyuu  * Copyright (c) 2001 The NetBSD Foundation, Inc.
64a04f2fdSsyuu  * All rights reserved.
74a04f2fdSsyuu  *
84a04f2fdSsyuu  * This code is derived from software contributed to The NetBSD Foundation
94a04f2fdSsyuu  * by Jason R. Thorpe.
104a04f2fdSsyuu  *
114a04f2fdSsyuu  * Redistribution and use in source and binary forms, with or without
124a04f2fdSsyuu  * modification, are permitted provided that the following conditions
134a04f2fdSsyuu  * are met:
144a04f2fdSsyuu  * 1. Redistributions of source code must retain the above copyright
154a04f2fdSsyuu  *    notice, this list of conditions and the following disclaimer.
164a04f2fdSsyuu  * 2. Redistributions in binary form must reproduce the above copyright
174a04f2fdSsyuu  *    notice, this list of conditions and the following disclaimer in the
184a04f2fdSsyuu  *    documentation and/or other materials provided with the distribution.
194a04f2fdSsyuu  *
204a04f2fdSsyuu  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
214a04f2fdSsyuu  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
224a04f2fdSsyuu  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
234a04f2fdSsyuu  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
244a04f2fdSsyuu  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
254a04f2fdSsyuu  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
264a04f2fdSsyuu  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
274a04f2fdSsyuu  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
284a04f2fdSsyuu  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
294a04f2fdSsyuu  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
304a04f2fdSsyuu  * POSSIBILITY OF SUCH DAMAGE.
314a04f2fdSsyuu  */
324a04f2fdSsyuu 
334a04f2fdSsyuu #ifndef _MIPS_OCTEON_OCTEONVAR_H_
344a04f2fdSsyuu #define _MIPS_OCTEON_OCTEONVAR_H_
354a04f2fdSsyuu 
364a04f2fdSsyuu #include <machine/bus.h>
374a04f2fdSsyuu 
384a04f2fdSsyuu /* XXX elsewhere */
394a04f2fdSsyuu #define	_ASM_PROLOGUE \
404a04f2fdSsyuu 		"	.set push			\n" \
414a04f2fdSsyuu 		"	.set noreorder			\n"
424a04f2fdSsyuu #define	_ASM_PROLOGUE_MIPS64 \
434a04f2fdSsyuu 		_ASM_PROLOGUE				\
444a04f2fdSsyuu 		"	.set mips64			\n"
454a04f2fdSsyuu #define	_ASM_PROLOGUE_OCTEON \
464a04f2fdSsyuu 		_ASM_PROLOGUE				\
474a04f2fdSsyuu 		"	.set arch=octeon		\n"
484a04f2fdSsyuu #define	_ASM_EPILOGUE \
494a04f2fdSsyuu 		"	.set pop			\n"
504a04f2fdSsyuu /*
514a04f2fdSsyuu  * subbits = __BITS64_GET(XXX, bits);
524a04f2fdSsyuu  * bits = __BITS64_SET(XXX, subbits);
534a04f2fdSsyuu  */
544a04f2fdSsyuu #ifndef	__BITS64_GET
554a04f2fdSsyuu #define	__BITS64_GET(name, bits)	\
564a04f2fdSsyuu 	    (((uint64_t)(bits) & name) >> name##_SHIFT)
574a04f2fdSsyuu #endif
584a04f2fdSsyuu #ifndef	__BITS64_SET
594a04f2fdSsyuu #define	__BITS64_SET(name, subbits)	\
604a04f2fdSsyuu 	    (((uint64_t)(subbits) << name##_SHIFT) & name)
614a04f2fdSsyuu #endif
624a04f2fdSsyuu 
634a04f2fdSsyuu struct octeon_config {
644a04f2fdSsyuu 	bus_space_tag_t mc_iobus_bust;
654a04f2fdSsyuu 	bus_space_tag_t mc_bootbus_bust;
664a04f2fdSsyuu 
674a04f2fdSsyuu 	bus_dma_tag_t mc_iobus_dmat;
684a04f2fdSsyuu 	bus_dma_tag_t mc_bootbus_dmat;
694a04f2fdSsyuu };
704a04f2fdSsyuu 
71cc838d97Svisa #define	GPIO_CONFIG_MD_OUTPUT_SEL_MASK	(GPIO_CONFIG_MD0 | GPIO_CONFIG_MD1)
72cc838d97Svisa #define	GPIO_CONFIG_MD_USB0_VBUS_CTRL	GPIO_CONFIG_MD0
73cc838d97Svisa #define	GPIO_CONFIG_MD_USB1_VBUS_CTRL	GPIO_CONFIG_MD1
74cc838d97Svisa 
754a04f2fdSsyuu /*
764a04f2fdSsyuu  * FPA map
774a04f2fdSsyuu  */
784a04f2fdSsyuu 
794a04f2fdSsyuu #define	OCTEON_POOL_NO_PKT	0
804a04f2fdSsyuu #define	OCTEON_POOL_NO_WQE	1
814a04f2fdSsyuu #define	OCTEON_POOL_NO_CMD	2
824a04f2fdSsyuu #define	OCTEON_POOL_NO_SG	3
834a04f2fdSsyuu #define	OCTEON_POOL_NO_XXX_4	4
844a04f2fdSsyuu #define	OCTEON_POOL_NO_XXX_5	5
854a04f2fdSsyuu #define	OCTEON_POOL_NO_XXX_6	6
864a04f2fdSsyuu #define	OCTEON_POOL_NO_DUMP	7	/* FPA debug dump */
874a04f2fdSsyuu 
888d999ab0Svisa #define	OCTEON_POOL_SIZE_PKT	1920	/* 128 x 15 */
894a04f2fdSsyuu #define	OCTEON_POOL_SIZE_WQE	128	/* 128 x 1 */
904a04f2fdSsyuu #define	OCTEON_POOL_SIZE_CMD	1024	/* 128 x 8 */
91a5754d3bSvisa #define	OCTEON_POOL_SIZE_SG	128	/* 128 x 1 */
924a04f2fdSsyuu #define	OCTEON_POOL_SIZE_XXX_4	0
934a04f2fdSsyuu #define	OCTEON_POOL_SIZE_XXX_5	0
944a04f2fdSsyuu #define	OCTEON_POOL_SIZE_XXX_6	0
954a04f2fdSsyuu #define	OCTEON_POOL_SIZE_XXX_7	0
964a04f2fdSsyuu 
974a04f2fdSsyuu #define	OCTEON_POOL_NELEMS_PKT		4096
984a04f2fdSsyuu #define	OCTEON_POOL_NELEMS_WQE		4096
994a04f2fdSsyuu #define	OCTEON_POOL_NELEMS_CMD		32
100a5754d3bSvisa #define	OCTEON_POOL_NELEMS_SG		4096
1014a04f2fdSsyuu #define	OCTEON_POOL_NELEMS_XXX_4	0
1024a04f2fdSsyuu #define	OCTEON_POOL_NELEMS_XXX_5	0
1034a04f2fdSsyuu #define	OCTEON_POOL_NELEMS_XXX_6	0
1044a04f2fdSsyuu #define	OCTEON_POOL_NELEMS_XXX_7	0
1054a04f2fdSsyuu 
1064a04f2fdSsyuu /*
1074a04f2fdSsyuu  * CVMSEG (``scratch'') memory map
1084a04f2fdSsyuu  */
1094a04f2fdSsyuu struct octeon_cvmseg_map {
1104a04f2fdSsyuu 	uint64_t		csm_pow_intr;
1114a04f2fdSsyuu 
1124a04f2fdSsyuu 	struct octeon_cvmseg_ether_map {
1134a04f2fdSsyuu 		uint64_t	csm_ether_fau_done;
114959570ccSvisa 	} csm_ether[12/* XXX */];
1154a04f2fdSsyuu } __packed;
1164a04f2fdSsyuu #define	OCTEON_CVMSEG_OFFSET(entry) \
1174a04f2fdSsyuu 	offsetof(struct octeon_cvmseg_map, entry)
1184a04f2fdSsyuu #define	OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \
1194a04f2fdSsyuu 	(offsetof(struct octeon_cvmseg_map, csm_ether) + \
1204a04f2fdSsyuu 	 sizeof(struct octeon_cvmseg_ether_map) * (n) + \
1214a04f2fdSsyuu 	 offsetof(struct octeon_cvmseg_ether_map, entry))
1224a04f2fdSsyuu 
1234a04f2fdSsyuu /*
1244a04f2fdSsyuu  * FAU register map
1254a04f2fdSsyuu  *
1264a04f2fdSsyuu  * => FAU registers exist in FAU unit
1274a04f2fdSsyuu  * => devices (PKO) can access these registers
1284a04f2fdSsyuu  * => CPU can read those values after loading them into CVMSEG
1294a04f2fdSsyuu  */
1304a04f2fdSsyuu struct octeon_fau_map {
1314a04f2fdSsyuu 	struct {
1324a04f2fdSsyuu 		/* PKO command index */
1334a04f2fdSsyuu 		uint64_t	_fau_map_port_pkocmdidx;
1344a04f2fdSsyuu 		/* send requested */
1354a04f2fdSsyuu 		uint64_t	_fau_map_port_txreq;
1364a04f2fdSsyuu 		/* send completed */
1374a04f2fdSsyuu 		uint64_t	_fau_map_port_txdone;
1384a04f2fdSsyuu 		/* XXX */
1394a04f2fdSsyuu 		uint64_t	_fau_map_port_pad;
1404a04f2fdSsyuu 	} __packed _fau_map_port[3];
1414a04f2fdSsyuu };
1424a04f2fdSsyuu 
1434a04f2fdSsyuu /*
1444a04f2fdSsyuu  * POW qos/group map
1454a04f2fdSsyuu  */
1464a04f2fdSsyuu 
1474a04f2fdSsyuu #define	OCTEON_POW_QOS_PIP		0
1484a04f2fdSsyuu #define	OCTEON_POW_QOS_CORE1		1
1494a04f2fdSsyuu #define	OCTEON_POW_QOS_XXX_2		2
1504a04f2fdSsyuu #define	OCTEON_POW_QOS_XXX_3		3
1514a04f2fdSsyuu #define	OCTEON_POW_QOS_XXX_4		4
1524a04f2fdSsyuu #define	OCTEON_POW_QOS_XXX_5		5
1534a04f2fdSsyuu #define	OCTEON_POW_QOS_XXX_6		6
1544a04f2fdSsyuu #define	OCTEON_POW_QOS_XXX_7		7
1554a04f2fdSsyuu 
156e842824bSvisa #define	OCTEON_POW_GROUP_MAX		16
1574a04f2fdSsyuu 
1586ece48ccSvisa enum cnmac_stat {
1596ece48ccSvisa 	cnmac_stat_rx_toto_gmx,
1606ece48ccSvisa 	cnmac_stat_rx_totp_gmx,
1616ece48ccSvisa 	cnmac_stat_rx_toto_pip,
1626ece48ccSvisa 	cnmac_stat_rx_totp_pip,
1636ece48ccSvisa 	cnmac_stat_rx_h64,
1646ece48ccSvisa 	cnmac_stat_rx_h127,
1656ece48ccSvisa 	cnmac_stat_rx_h255,
1666ece48ccSvisa 	cnmac_stat_rx_h511,
1676ece48ccSvisa 	cnmac_stat_rx_h1023,
1686ece48ccSvisa 	cnmac_stat_rx_h1518,
1696ece48ccSvisa 	cnmac_stat_rx_hmax,
1706ece48ccSvisa 	cnmac_stat_rx_bcast,
1716ece48ccSvisa 	cnmac_stat_rx_mcast,
1726ece48ccSvisa 	cnmac_stat_rx_qdpo,
1736ece48ccSvisa 	cnmac_stat_rx_qdpp,
1746ece48ccSvisa 	cnmac_stat_rx_fcs,
1756ece48ccSvisa 	cnmac_stat_rx_frag,
1766ece48ccSvisa 	cnmac_stat_rx_undersz,
1776ece48ccSvisa 	cnmac_stat_rx_jabber,
1786ece48ccSvisa 	cnmac_stat_rx_oversz,
1796ece48ccSvisa 	cnmac_stat_rx_raw,
1806ece48ccSvisa 	cnmac_stat_rx_bad,
1816ece48ccSvisa 	cnmac_stat_rx_drop,
1826ece48ccSvisa 	cnmac_stat_rx_ctl,
1836ece48ccSvisa 	cnmac_stat_rx_dmac,
1846ece48ccSvisa 	cnmac_stat_tx_toto,
1856ece48ccSvisa 	cnmac_stat_tx_totp,
1866ece48ccSvisa 	cnmac_stat_tx_hmin,
1876ece48ccSvisa 	cnmac_stat_tx_h64,
1886ece48ccSvisa 	cnmac_stat_tx_h127,
1896ece48ccSvisa 	cnmac_stat_tx_h255,
1906ece48ccSvisa 	cnmac_stat_tx_h511,
1916ece48ccSvisa 	cnmac_stat_tx_h1023,
1926ece48ccSvisa 	cnmac_stat_tx_h1518,
1936ece48ccSvisa 	cnmac_stat_tx_hmax,
1946ece48ccSvisa 	cnmac_stat_tx_bcast,
1956ece48ccSvisa 	cnmac_stat_tx_mcast,
1966ece48ccSvisa 	cnmac_stat_tx_coll,
1976ece48ccSvisa 	cnmac_stat_tx_defer,
1986ece48ccSvisa 	cnmac_stat_tx_scol,
1996ece48ccSvisa 	cnmac_stat_tx_mcol,
2006ece48ccSvisa 	cnmac_stat_tx_ctl,
2016ece48ccSvisa 	cnmac_stat_tx_uflow,
2026ece48ccSvisa 	cnmac_stat_count
2036ece48ccSvisa };
2046ece48ccSvisa 
205b4d4f400Sjasper #if defined(_KERNEL) || defined(_STANDALONE)
206039136e6Sjasper #define OCTEON_ARGV_MAX 64
2075e0ee076Sjasper 
2082bbf581cSvisa /*
2092bbf581cSvisa  * OCTEON board types recognized by OpenBSD/octeon.
2102bbf581cSvisa  *
2112bbf581cSvisa  * It is fine to use BOARD_UNKNOWN when the board does not need
2122bbf581cSvisa  * special treatment.
2132bbf581cSvisa  */
2142bbf581cSvisa enum octeon_board {
2152bbf581cSvisa 	BOARD_UNKNOWN,
2164d62617aSvisa 	BOARD_CHECKPOINT_N100,
2172bbf581cSvisa 	BOARD_CN3010_EVB_HS5,
2182bbf581cSvisa 	BOARD_DLINK_DSR_500,
219133fffbaSvisa 	BOARD_NETGEAR_UTM25,
2202bbf581cSvisa 	BOARD_RHINOLABS_UTM8,
2212bbf581cSvisa 	BOARD_UBIQUITI_E100,
2222bbf581cSvisa 	BOARD_UBIQUITI_E120,
2232bbf581cSvisa 	BOARD_UBIQUITI_E200,
2242bbf581cSvisa 	BOARD_UBIQUITI_E220,
2252bbf581cSvisa 	BOARD_UBIQUITI_E300,
2262bbf581cSvisa 	BOARD_UBIQUITI_E1000,
2272bbf581cSvisa };
2282bbf581cSvisa 
2297b0d27bbSjasper struct boot_desc {
2307b0d27bbSjasper 	uint32_t	desc_ver;
2317b0d27bbSjasper 	uint32_t	desc_size;
2327b0d27bbSjasper 	uint64_t	stack_top;
2337b0d27bbSjasper 	uint64_t 	heap_start;
2347b0d27bbSjasper 	uint64_t	heap_end;
2357b0d27bbSjasper 	uint64_t      	__unused17;
2367b0d27bbSjasper 	uint64_t     	__unused16;
2377b0d27bbSjasper 	uint32_t      	__unused18;
2387b0d27bbSjasper 	uint32_t      	__unused15;
2397b0d27bbSjasper 	uint32_t      	__unused14;
2407b0d27bbSjasper 	uint32_t	argc;
241039136e6Sjasper 	uint32_t	argv[OCTEON_ARGV_MAX];
2427b0d27bbSjasper 	uint32_t	flags;
2437b0d27bbSjasper 	uint32_t	core_mask;
2447b0d27bbSjasper 	uint32_t	dram_size;
2457b0d27bbSjasper 	uint32_t	phy_mem_desc_addr;
2467b0d27bbSjasper 	uint32_t	debugger_flag_addr;
2477b0d27bbSjasper 	uint32_t	eclock;
2487b0d27bbSjasper 	uint32_t      	__unused10;
2497b0d27bbSjasper 	uint32_t      	__unused9;
2507b0d27bbSjasper 	uint16_t      	__unused8;
2517b0d27bbSjasper 	uint8_t 	__unused7;
2527b0d27bbSjasper 	uint8_t 	__unused6;
2537b0d27bbSjasper 	uint16_t 	__unused5;
2547b0d27bbSjasper 	uint8_t 	__unused4;
2557b0d27bbSjasper 	uint8_t 	__unused3;
2567b0d27bbSjasper 	uint8_t 	__unused2[20];
2577b0d27bbSjasper 	uint8_t 	__unused1[6];
2587b0d27bbSjasper 	uint8_t 	__unused0;
2597b0d27bbSjasper 	uint64_t 	boot_info_addr;
2607b0d27bbSjasper };
2617b0d27bbSjasper 
2627b0d27bbSjasper struct boot_info {
2637b0d27bbSjasper 	uint32_t ver_major;
2647b0d27bbSjasper 	uint32_t ver_minor;
2657b0d27bbSjasper 	uint64_t stack_top;
2667b0d27bbSjasper 	uint64_t heap_start;
2677b0d27bbSjasper 	uint64_t heap_end;
2687b0d27bbSjasper 	uint64_t boot_desc_addr;
2697b0d27bbSjasper 	uint32_t exception_base_addr;
2707b0d27bbSjasper 	uint32_t stack_size;
2717b0d27bbSjasper 	uint32_t flags;
2727b0d27bbSjasper 	uint32_t core_mask;
2737b0d27bbSjasper 	uint32_t dram_size;
2747b0d27bbSjasper 	uint32_t phys_mem_desc_addr;
2757b0d27bbSjasper 	uint32_t debugger_flags_addr;
2767b0d27bbSjasper 	uint32_t eclock;
2777b0d27bbSjasper 	uint32_t dclock;
2787b0d27bbSjasper 	uint32_t __unused0;
2797b0d27bbSjasper 	uint16_t board_type;
2807b0d27bbSjasper 	uint8_t board_rev_major;
2817b0d27bbSjasper 	uint8_t board_rev_minor;
2827b0d27bbSjasper 	uint16_t __unused1;
2837b0d27bbSjasper 	uint8_t __unused2;
2847b0d27bbSjasper 	uint8_t __unused3;
2857b0d27bbSjasper 	char board_serial[20];
2867b0d27bbSjasper 	uint8_t mac_addr_base[6];
2877b0d27bbSjasper 	uint8_t mac_addr_count;
2887b0d27bbSjasper 	uint64_t cf_common_addr;
2897b0d27bbSjasper 	uint64_t cf_attr_addr;
2907b0d27bbSjasper 	uint64_t led_display_addr;
2917b0d27bbSjasper 	uint32_t dfaclock;
2927b0d27bbSjasper 	uint32_t config_flags;
2938a4f0236Svisa 	/* The fields below are available when ver_minor >= 3. */
2948a4f0236Svisa 	uint64_t fdt_addr;
2957b0d27bbSjasper };
2967b0d27bbSjasper 
297fe08f639Svisa struct octeon_bootmem_desc {
298fe08f639Svisa 	uint32_t	lock;
299fe08f639Svisa 	uint32_t	flags;
300fe08f639Svisa 	uint64_t	head_addr;
301fe08f639Svisa 	uint32_t	major_version;
302fe08f639Svisa 	uint32_t	minor_version;
303fe08f639Svisa 	uint64_t	app_data_addr;
304fe08f639Svisa 	uint64_t	app_data_size;
305fe08f639Svisa 	uint32_t	named_block_num_blocks;
306fe08f639Svisa 	uint32_t	named_block_name_len;
307fe08f639Svisa 	uint64_t	named_block_array_addr;
308fe08f639Svisa };
309fe08f639Svisa 
310fe08f639Svisa struct octeon_bootmem_block {
311fe08f639Svisa 	uint64_t	next;
312fe08f639Svisa 	uint64_t	size;
313fe08f639Svisa };
314fe08f639Svisa 
3152bbf581cSvisa extern enum octeon_board octeon_board;
3165a60bedeSjasper extern struct boot_desc *octeon_boot_desc;
3175a60bedeSjasper extern struct boot_info *octeon_boot_info;
3187b0d27bbSjasper 
319b4d4f400Sjasper #ifdef _KERNEL
32034fd053eSjasper /* Device capabilities advertised in boot_info->config_flags */
32134fd053eSjasper #define BOOTINFO_CFG_FLAG_PCI_HOST	(1ull << 0)
32234fd053eSjasper #define BOOTINFO_CFG_FLAG_PCI_TARGET	(1ull << 1)
32334fd053eSjasper #define BOOTINFO_CFG_FLAG_DEBUG		(1ull << 2)
32434fd053eSjasper #define BOOTINFO_CFG_FLAG_NO_MAGIC	(1ull << 3)
3254a04f2fdSsyuu 
3263a62b615Svisa #define BOOTMEM_BLOCK_ALIGN		16
3273a62b615Svisa #define BOOTMEM_BLOCK_MASK		(BOOTMEM_BLOCK_ALIGN - 1)
3283a62b615Svisa #define BOOTMEM_BLOCK_MIN_SIZE		16
3293a62b615Svisa 
3303a62b615Svisa int	bootmem_alloc_region(paddr_t, size_t);
3313a62b615Svisa void	bootmem_free(paddr_t, size_t);
3323a62b615Svisa 
3335f139a3aSjmatthew int	octeon_ioclock_speed(void);
3345f139a3aSjmatthew 
3354a04f2fdSsyuu #endif /* _KERNEL */
336b4d4f400Sjasper #endif /* _KERNEL || _STANDALONE */
3374a04f2fdSsyuu 
3384a04f2fdSsyuu static inline int
ffs64(uint64_t val)3394a04f2fdSsyuu ffs64(uint64_t val)
3404a04f2fdSsyuu {
3414a04f2fdSsyuu 	int ret;
3424a04f2fdSsyuu 
3432df76cc2Sguenther 	__asm volatile ( \
3444a04f2fdSsyuu 		_ASM_PROLOGUE_MIPS64
3454a04f2fdSsyuu 		"	dclz	%0, %1			\n"
3464a04f2fdSsyuu 		_ASM_EPILOGUE
3474a04f2fdSsyuu 		: "=r"(ret) : "r"(val));
3484a04f2fdSsyuu 	return 64 - ret;
3494a04f2fdSsyuu }
3504a04f2fdSsyuu 
351cc12d4ddSpirofti static inline int
ffs32(uint32_t val)352cc12d4ddSpirofti ffs32(uint32_t val)
353cc12d4ddSpirofti {
354cc12d4ddSpirofti 	int ret;
355cc12d4ddSpirofti 
356*dd81489dSjsg 	__asm volatile ( \
357cc12d4ddSpirofti 		_ASM_PROLOGUE_MIPS64
358cc12d4ddSpirofti 		"	clz	%0, %1			\n"
359cc12d4ddSpirofti 		_ASM_EPILOGUE
360cc12d4ddSpirofti 		: "=r"(ret) : "r"(val));
361cc12d4ddSpirofti 	return 32 - ret;
362cc12d4ddSpirofti }
363cc12d4ddSpirofti 
3644a04f2fdSsyuu static inline uint64_t
octeon_xkphys_read_8(paddr_t address)3654a04f2fdSsyuu octeon_xkphys_read_8(paddr_t address)
3664a04f2fdSsyuu {
3674a04f2fdSsyuu 	volatile uint64_t *p =
3684a04f2fdSsyuu 	    (volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC));
3694a04f2fdSsyuu 	return (*p);
3704a04f2fdSsyuu }
3714a04f2fdSsyuu 
372123df2afSpirofti #define	MIO_BOOT_BIST_STAT			0x00011800000000f8ULL
3734a04f2fdSsyuu static inline void
octeon_xkphys_write_8(paddr_t address,uint64_t value)3744a04f2fdSsyuu octeon_xkphys_write_8(paddr_t address, uint64_t value)
3754a04f2fdSsyuu {
3764a04f2fdSsyuu 	*(volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC)) = value;
377123df2afSpirofti 
378123df2afSpirofti 	/*
379123df2afSpirofti 	 * It seems an immediate read is necessary when doing a write to an RSL
380123df2afSpirofti 	 * register in order to complete the write.
381123df2afSpirofti 	 * We use MIO_BOOT_BIST_STAT because it's apparently the fastest
382123df2afSpirofti 	 * write.
383123df2afSpirofti 	 */
384123df2afSpirofti 
385123df2afSpirofti 	/*
386123df2afSpirofti 	 * XXX
38736fd90dcSjsg 	 * This if would be better written as:
388123df2afSpirofti 	 * if ((address & 0xffffff0000000000ULL) == OCTEON_MIO_BOOT_BASE) {
389123df2afSpirofti 	 * but octeonreg.h can't be included here and we want this inlined
390123df2afSpirofti 	 *
391123df2afSpirofti 	 * Note that the SDK masks with 0x7ffff but that doesn't make sense.
392123df2afSpirofti 	 * This is a physical address.
393123df2afSpirofti 	 */
394123df2afSpirofti 	if (((address >> 40) & 0xfffff) == (0x118)) {
395123df2afSpirofti 		value = *(volatile uint64_t *)
396123df2afSpirofti 		    (PHYS_TO_XKPHYS(MIO_BOOT_BIST_STAT, CCA_NC));
397123df2afSpirofti 	}
3984a04f2fdSsyuu }
3994a04f2fdSsyuu 
4004a04f2fdSsyuu static inline void
octeon_iobdma_write_8(uint64_t value)4014a04f2fdSsyuu octeon_iobdma_write_8(uint64_t value)
4024a04f2fdSsyuu {
4034a04f2fdSsyuu 	uint64_t addr = 0xffffffffffffa200ULL;
4044a04f2fdSsyuu 
4054a04f2fdSsyuu 	*(volatile uint64_t *)addr = value;
4064a04f2fdSsyuu }
4074a04f2fdSsyuu 
408f4fee9beSvisa static inline void
octeon_lmtdma_write_8(off_t offset,uint64_t value)409f4fee9beSvisa octeon_lmtdma_write_8(off_t offset, uint64_t value)
410f4fee9beSvisa {
411f4fee9beSvisa 	*(volatile uint64_t *)(0xffffffffffffa400ULL + offset) = value;
412f4fee9beSvisa }
413f4fee9beSvisa 
4144a04f2fdSsyuu static inline uint64_t
octeon_cvmseg_read_8(size_t offset)4154a04f2fdSsyuu octeon_cvmseg_read_8(size_t offset)
4164a04f2fdSsyuu {
4177b8d932aSvisa 	return *(volatile uint64_t *)(0xffffffffffff8000ULL + offset);
4184a04f2fdSsyuu }
4194a04f2fdSsyuu 
4204a04f2fdSsyuu static inline void
octeon_cvmseg_write_8(size_t offset,uint64_t value)4214a04f2fdSsyuu octeon_cvmseg_write_8(size_t offset, uint64_t value)
4224a04f2fdSsyuu {
4237b8d932aSvisa 	*(volatile uint64_t *)(0xffffffffffff8000ULL + offset) = value;
4244a04f2fdSsyuu }
4254a04f2fdSsyuu 
4264a5681b7Svisa static inline uint32_t
octeon_get_coreid(void)4274a5681b7Svisa octeon_get_coreid(void)
4284a5681b7Svisa {
4294a5681b7Svisa 	uint32_t coreid;
4304a5681b7Svisa 
4314a5681b7Svisa 	__asm volatile (
4324a5681b7Svisa 		_ASM_PROLOGUE_OCTEON
4334a5681b7Svisa 		"	rdhwr	%0, $0\n"
4344a5681b7Svisa 		_ASM_EPILOGUE
4354a5681b7Svisa 		: "=r" (coreid));
4364a5681b7Svisa 	return coreid;
4374a5681b7Svisa }
4384a5681b7Svisa 
4394a04f2fdSsyuu static inline uint64_t
octeon_get_cycles(void)4404a04f2fdSsyuu octeon_get_cycles(void)
4414a04f2fdSsyuu {
4424a04f2fdSsyuu 	uint64_t tmp;
4434a04f2fdSsyuu 
4442df76cc2Sguenther 	__asm volatile (
4454a04f2fdSsyuu 		_ASM_PROLOGUE_MIPS64
4464a04f2fdSsyuu 		"	dmfc0	%[tmp], $9, 6		\n"
4474a04f2fdSsyuu 		_ASM_EPILOGUE
4484a04f2fdSsyuu 		: [tmp]"=&r"(tmp));
4494a04f2fdSsyuu 	return tmp;
4504a04f2fdSsyuu }
4514a04f2fdSsyuu 
452f4fee9beSvisa static inline uint64_t
octeon_get_cvmctl(void)453d4086a48Svisa octeon_get_cvmctl(void)
454d4086a48Svisa {
455d4086a48Svisa 	uint64_t tmp;
456d4086a48Svisa 
457d4086a48Svisa 	__asm volatile (
458d4086a48Svisa 		_ASM_PROLOGUE_OCTEON
459d4086a48Svisa 		"	dmfc0	%[tmp], $9, 7		\n"
460d4086a48Svisa 		_ASM_EPILOGUE
461d4086a48Svisa 		: [tmp]"=r"(tmp));
462d4086a48Svisa 	return tmp;
463d4086a48Svisa }
464d4086a48Svisa 
465d4086a48Svisa static inline uint64_t
octeon_get_cvmmemctl(void)466f4fee9beSvisa octeon_get_cvmmemctl(void)
467f4fee9beSvisa {
468f4fee9beSvisa 	uint64_t tmp;
469f4fee9beSvisa 
470f4fee9beSvisa 	__asm volatile (
471f4fee9beSvisa 		_ASM_PROLOGUE_OCTEON
472f4fee9beSvisa 		"	dmfc0	%[tmp], $11, 7		\n"
473f4fee9beSvisa 		_ASM_EPILOGUE
474f4fee9beSvisa 		: [tmp]"=r"(tmp));
475f4fee9beSvisa 	return tmp;
476f4fee9beSvisa }
477f4fee9beSvisa 
478f4fee9beSvisa static inline void
octeon_set_cvmmemctl(uint64_t val)479f4fee9beSvisa octeon_set_cvmmemctl(uint64_t val)
480f4fee9beSvisa {
481f4fee9beSvisa 	__asm volatile (
482f4fee9beSvisa 		_ASM_PROLOGUE_OCTEON
483f4fee9beSvisa 		"	dmtc0	%[tmp], $11, 7		\n"
484f4fee9beSvisa 		_ASM_EPILOGUE
485f4fee9beSvisa 		: : [tmp]"r"(val) : "memory");
486f4fee9beSvisa }
487f4fee9beSvisa 
48890de25d4Svisa static inline void
octeon_synciobdma(void)48990de25d4Svisa octeon_synciobdma(void)
49090de25d4Svisa {
49190de25d4Svisa 	__asm volatile (
49290de25d4Svisa 		_ASM_PROLOGUE_OCTEON
49390de25d4Svisa 		"	synciobdma\n"
49490de25d4Svisa 		_ASM_EPILOGUE
49590de25d4Svisa 		: : : "memory");
49690de25d4Svisa }
49790de25d4Svisa 
4984a04f2fdSsyuu #endif	/* _MIPS_OCTEON_OCTEONVAR_H_ */
499