/*
 * Copyright (c) 2016 Intel Corporation
 * Copyright (c) 2011-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file Atomic ops in pure C
 *
 * This module provides the atomic operators for processors
 * which do not support native atomic operations.
 *
 * The atomic operations are guaranteed to be atomic with respect
 * to interrupt service routines, and to operations performed by peer
 * processors.
 *
 * (originally from x86's atomic.c)
 */

#include <sys/atomic.h>
#include <toolchain.h>
#include <arch/cpu.h>
#include <spinlock.h>

/* Single global spinlock for atomic operations.  This is fallback
 * code, not performance sensitive.  At least by not using irq_lock()
 * in SMP contexts we won't content with legitimate users of the
 * global lock.
 */
static struct k_spinlock lock;

/* For those rare CPUs which support user mode, but not native atomic
 * operations, the best we can do for them is implement the atomic
 * functions as system calls, since in user mode locking a spinlock is
 * forbidden.
 */
#ifdef CONFIG_USERSPACE
#include <syscall_handler.h>

#define ATOMIC_SYSCALL_HANDLER_TARGET(name) \
	Z_SYSCALL_HANDLER(name, target) { \
		Z_OOPS(Z_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); \
		return z_impl_##name((atomic_t *)target); \
	}

#define ATOMIC_SYSCALL_HANDLER_TARGET_VALUE(name) \
	Z_SYSCALL_HANDLER(name, target, value) { \
		Z_OOPS(Z_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t))); \
		return z_impl_##name((atomic_t *)target, value); \
	}
#else
#define ATOMIC_SYSCALL_HANDLER_TARGET(name)
#define ATOMIC_SYSCALL_HANDLER_TARGET_VALUE(name)
#endif

/**
 *
 * @brief Atomic compare-and-set primitive
 *
 * This routine provides the compare-and-set operator. If the original value at
 * <target> equals <oldValue>, then <newValue> is stored at <target> and the
 * function returns 1.
 *
 * If the original value at <target> does not equal <oldValue>, then the store
 * is not done and the function returns 0.
 *
 * The reading of the original value at <target>, the comparison,
 * and the write of the new value (if it occurs) all happen atomically with
 * respect to both interrupts and accesses of other processors to <target>.
 *
 * @param target address to be tested
 * @param old_value value to compare against
 * @param new_value value to compare against
 * @return Returns 1 if <new_value> is written, 0 otherwise.
 */
int z_impl_atomic_cas(atomic_t *target, atomic_val_t old_value,
		      atomic_val_t new_value)
{
	k_spinlock_key_t key;
	int ret = 0;

	key = k_spin_lock(&lock);

	if (*target == old_value) {
		*target = new_value;
		ret = 1;
	}

	k_spin_unlock(&lock, key);

	return ret;
}

#ifdef CONFIG_USERSPACE
Z_SYSCALL_HANDLER(atomic_cas, target, old_value, new_value)
{
	Z_OOPS(Z_SYSCALL_MEMORY_WRITE(target, sizeof(atomic_t)));

	return z_impl_atomic_cas((atomic_t *)target, old_value, new_value);
}
#endif /* CONFIG_USERSPACE */

/**
 *
 * @brief Atomic addition primitive
 *
 * This routine provides the atomic addition operator. The <value> is
 * atomically added to the value at <target>, placing the result at <target>,
 * and the old value from <target> is returned.
 *
 * @param target memory location to add to
 * @param value the value to add
 *
 * @return The previous value from <target>
 */
atomic_val_t z_impl_atomic_add(atomic_t *target, atomic_val_t value)
{
	k_spinlock_key_t key;
	atomic_val_t ret;

	key = k_spin_lock(&lock);

	ret = *target;
	*target += value;

	k_spin_unlock(&lock, key);

	return ret;
}

ATOMIC_SYSCALL_HANDLER_TARGET_VALUE(atomic_add);

/**
 *
 * @brief Atomic subtraction primitive
 *
 * This routine provides the atomic subtraction operator. The <value> is
 * atomically subtracted from the value at <target>, placing the result at
 * <target>, and the old value from <target> is returned.
 *
 * @param target the memory location to subtract from
 * @param value the value to subtract
 *
 * @return The previous value from <target>
 */
atomic_val_t z_impl_atomic_sub(atomic_t *target, atomic_val_t value)
{
	k_spinlock_key_t key;
	atomic_val_t ret;

	key = k_spin_lock(&lock);

	ret = *target;
	*target -= value;

	k_spin_unlock(&lock, key);

	return ret;
}

ATOMIC_SYSCALL_HANDLER_TARGET_VALUE(atomic_sub);

/**
 *
 * @brief Atomic get primitive
 *
 * @param target memory location to read from
 *
 * This routine provides the atomic get primitive to atomically read
 * a value from <target>. It simply does an ordinary load.  Note that <target>
 * is expected to be aligned to a 4-byte boundary.
 *
 * @return The value read from <target>
 */
atomic_val_t atomic_get(const atomic_t *target)
{
	return *target;
}

/**
 *
 * @brief Atomic get-and-set primitive
 *
 * This routine provides the atomic set operator. The <value> is atomically
 * written at <target> and the previous value at <target> is returned.
 *
 * @param target the memory location to write to
 * @param value the value to write
 *
 * @return The previous value from <target>
 */
atomic_val_t z_impl_atomic_set(atomic_t *target, atomic_val_t value)
{
	k_spinlock_key_t key;
	atomic_val_t ret;

	key = k_spin_lock(&lock);

	ret = *target;
	*target = value;

	k_spin_unlock(&lock, key);

	return ret;
}

ATOMIC_SYSCALL_HANDLER_TARGET_VALUE(atomic_set);

/**
 *
 * @brief Atomic bitwise inclusive OR primitive
 *
 * This routine provides the atomic bitwise inclusive OR operator. The <value>
 * is atomically bitwise OR'ed with the value at <target>, placing the result
 * at <target>, and the previous value at <target> is returned.
 *
 * @param target the memory location to be modified
 * @param value the value to OR
 *
 * @return The previous value from <target>
 */
atomic_val_t z_impl_atomic_or(atomic_t *target, atomic_val_t value)
{
	k_spinlock_key_t key;
	atomic_val_t ret;

	key = k_spin_lock(&lock);

	ret = *target;
	*target |= value;

	k_spin_unlock(&lock, key);

	return ret;
}

ATOMIC_SYSCALL_HANDLER_TARGET_VALUE(atomic_or);

/**
 *
 * @brief Atomic bitwise exclusive OR (XOR) primitive
 *
 * This routine provides the atomic bitwise exclusive OR operator. The <value>
 * is atomically bitwise XOR'ed with the value at <target>, placing the result
 * at <target>, and the previous value at <target> is returned.
 *
 * @param target the memory location to be modified
 * @param value the value to XOR
 *
 * @return The previous value from <target>
 */
atomic_val_t z_impl_atomic_xor(atomic_t *target, atomic_val_t value)
{
	k_spinlock_key_t key;
	atomic_val_t ret;

	key = k_spin_lock(&lock);

	ret = *target;
	*target ^= value;

	k_spin_unlock(&lock, key);

	return ret;
}

ATOMIC_SYSCALL_HANDLER_TARGET_VALUE(atomic_xor);

/**
 *
 * @brief Atomic bitwise AND primitive
 *
 * This routine provides the atomic bitwise AND operator. The <value> is
 * atomically bitwise AND'ed with the value at <target>, placing the result
 * at <target>, and the previous value at <target> is returned.
 *
 * @param target the memory location to be modified
 * @param value the value to AND
 *
 * @return The previous value from <target>
 */
atomic_val_t z_impl_atomic_and(atomic_t *target, atomic_val_t value)
{
	k_spinlock_key_t key;
	atomic_val_t ret;

	key = k_spin_lock(&lock);

	ret = *target;
	*target &= value;

	k_spin_unlock(&lock, key);

	return ret;
}

ATOMIC_SYSCALL_HANDLER_TARGET_VALUE(atomic_and);

/**
 *
 * @brief Atomic bitwise NAND primitive
 *
 * This routine provides the atomic bitwise NAND operator. The <value> is
 * atomically bitwise NAND'ed with the value at <target>, placing the result
 * at <target>, and the previous value at <target> is returned.
 *
 * @param target the memory location to be modified
 * @param value the value to NAND
 *
 * @return The previous value from <target>
 */
atomic_val_t z_impl_atomic_nand(atomic_t *target, atomic_val_t value)
{
	k_spinlock_key_t key;
	atomic_val_t ret;

	key = k_spin_lock(&lock);

	ret = *target;
	*target = ~(*target & value);

	k_spin_unlock(&lock, key);

	return ret;
}

ATOMIC_SYSCALL_HANDLER_TARGET_VALUE(atomic_nand);
