/*
 * Copyright (C) 2010, 2013-2014, 2016 ARM Limited. All rights reserved.
 * 
 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
 * 
 * A copy of the licence is included with the program, and can also be obtained from Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

/**
 * @file mali_osk_bitops.h
 * Implementation of the OS abstraction layer for the kernel device driver
 */

#ifndef __MALI_OSK_BITOPS_H__
#define __MALI_OSK_BITOPS_H__

#ifdef __cplusplus
extern "C" {
#endif

MALI_STATIC_INLINE void _mali_internal_clear_bit(u32 bit, u32 *addr)
{
	MALI_DEBUG_ASSERT(bit < 32);
	MALI_DEBUG_ASSERT(NULL != addr);

	(*addr) &= ~(1 << bit);
}

MALI_STATIC_INLINE void _mali_internal_set_bit(u32 bit, u32 *addr)
{
	MALI_DEBUG_ASSERT(bit < 32);
	MALI_DEBUG_ASSERT(NULL != addr);

	(*addr) |= (1 << bit);
}

MALI_STATIC_INLINE u32 _mali_internal_test_bit(u32 bit, u32 value)
{
	MALI_DEBUG_ASSERT(bit < 32);
	return value & (1 << bit);
}

MALI_STATIC_INLINE int _mali_internal_find_first_zero_bit(u32 value)
{
	u32 inverted;
	u32 negated;
	u32 isolated;
	u32 leading_zeros;

	/* Begin with xxx...x0yyy...y, where ys are 1, number of ys is in range  0..31 */
	inverted = ~value; /* zzz...z1000...0 */
	/* Using count_trailing_zeros on inverted value -
	 * See ARM System Developers Guide for details of count_trailing_zeros */

	/* Isolate the zero: it is preceeded by a run of 1s, so add 1 to it */
	negated = (u32) - inverted ; /* -a == ~a + 1 (mod 2^n) for n-bit numbers */
	/* negated = xxx...x1000...0 */

	isolated = negated & inverted ; /* xxx...x1000...0 & zzz...z1000...0, zs are ~xs */
	/* And so the first zero bit is in the same position as the 1 == number of 1s that preceeded it
	 * Note that the output is zero if value was all 1s */

	leading_zeros = _mali_osk_clz(isolated);

	return 31 - leading_zeros;
}


/** @defgroup _mali_osk_bitops OSK Non-atomic Bit-operations
 * @{ */

/**
 * These bit-operations do not work atomically, and so locks must be used if
 * atomicity is required.
 *
 * Reference implementations for Little Endian are provided, and so it should
 * not normally be necessary to re-implement these. Efficient bit-twiddling
 * techniques are used where possible, implemented in portable C.
 *
 * Note that these reference implementations rely on _mali_osk_clz() being
 * implemented.
 */

/** @brief Clear a bit in a sequence of 32-bit words
 * @param nr bit number to clear, starting from the (Little-endian) least
 * significant bit
 * @param addr starting point for counting.
 */
MALI_STATIC_INLINE void _mali_osk_clear_nonatomic_bit(u32 nr, u32 *addr)
{
	addr += nr >> 5; /* find the correct word */
	nr = nr & ((1 << 5) - 1); /* The bit number within the word */

	_mali_internal_clear_bit(nr, addr);
}

/** @brief Set a bit in a sequence of 32-bit words
 * @param nr bit number to set, starting from the (Little-endian) least
 * significant bit
 * @param addr starting point for counting.
 */
MALI_STATIC_INLINE void _mali_osk_set_nonatomic_bit(u32 nr, u32 *addr)
{
	addr += nr >> 5; /* find the correct word */
	nr = nr & ((1 << 5) - 1); /* The bit number within the word */

	_mali_internal_set_bit(nr, addr);
}

/** @brief Test a bit in a sequence of 32-bit words
 * @param nr bit number to test, starting from the (Little-endian) least
 * significant bit
 * @param addr starting point for counting.
 * @return zero if bit was clear, non-zero if set. Do not rely on the return
 * value being related to the actual word under test.
 */
MALI_STATIC_INLINE u32 _mali_osk_test_bit(u32 nr, u32 *addr)
{
	addr += nr >> 5; /* find the correct word */
	nr = nr & ((1 << 5) - 1); /* The bit number within the word */

	return _mali_internal_test_bit(nr, *addr);
}

/* Return maxbit if not found */
/** @brief Find the first zero bit in a sequence of 32-bit words
 * @param addr starting point for search.
 * @param maxbit the maximum number of bits to search
 * @return the number of the first zero bit found, or maxbit if none were found
 * in the specified range.
 */
MALI_STATIC_INLINE u32 _mali_osk_find_first_zero_bit(const u32 *addr, u32 maxbit)
{
	u32 total;

	for (total = 0; total < maxbit; total += 32, ++addr) {
		int result;
		result = _mali_internal_find_first_zero_bit(*addr);

		/* non-negative signifies the bit was found */
		if (result >= 0) {
			total += (u32)result;
			break;
		}
	}

	/* Now check if we reached maxbit or above */
	if (total >= maxbit) {
		total = maxbit;
	}

	return total; /* either the found bit nr, or maxbit if not found */
}
/** @} */ /* end group _mali_osk_bitops */

#ifdef __cplusplus
}
#endif

#endif /* __MALI_OSK_BITOPS_H__ */
