// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 SmartLogic.
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : ucp_utility.c
// Author        : xianfeng.du
// Created On    : 2022-06-25
// Last Modified :
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------

#include "ucp_utility.h"

int32_t isPowerOf2(uint32_t n)
{
    return n && !(n & (n - 1));
}

void ucp_nop(uint32_t cycleCnt)
{
    for (uint32_t i=0; i<cycleCnt; i++) {
        __ucps2_delay();
    }
    return;
}

void ucp_spinlock_init()
{
    int32_t core_id = get_core_id();
    int32_t rev = 0;
    rev = spin_lock_init(LOCK_UL_TX_ALLOC);
    if (0 != rev)
    {
        debug_write(DBG_DDR_ERR_IDX(core_id, 34), rev);
    }

    rev = spin_lock_init(LOCK_UL_TX_PUT);
    if (0 != rev)
    {
        debug_write(DBG_DDR_ERR_IDX(core_id, 35), rev);
    }

    rev = spin_lock_init(LOCK_DL_RX_GET);
    if (0 != rev)
    {
        debug_write(DBG_DDR_ERR_IDX(core_id, 36), rev);
    }

    rev = spin_lock_init(LOCK_DL_RX_FREE);
    if (0 != rev)
    {
        debug_write(DBG_DDR_ERR_IDX(core_id, 37), rev);
    }

    rev = spin_lock_init(LOCK_BUILD_CELL);
    if (0 != rev)
    {
        debug_write(DBG_DDR_ERR_IDX(core_id, 38), rev);
    }
    return;
}

ALWAYS_INLINE int32_t atomic_fetch_add(void* object, int32_t operand)
{
	//Atomic memory access object must be external share memory;
	int32_t value,flag;

	do{
		value = atomic_load(object);
		flag = atomic_store(object,(value+operand));
	}while(flag == 0);

	return value;
}

#ifdef DBG_DDR_PALLADIUM
void pld_debug_write(uint32_t idx, uint32_t value)
{
    uint32_t addr = DBG_DDR_ADDR_BASE + (idx * 4);
    do_write(addr, value);
    return;
}

void pld_debug_write_splice_short(uint32_t idx, uint16_t hi, uint16_t lo)
{
    uint32_t addr = DBG_DDR_ADDR_BASE + (idx * 4);
	uint32_t value = (hi << 16) + lo;
    do_write(addr, value);
    return;
}

void pld_debug_write_splice_byte(uint32_t idx, uint8_t hi0, uint8_t hi1, uint8_t lo0, uint8_t lo1)
{
    uint32_t addr = DBG_DDR_ADDR_BASE + (idx * 4);
	uint32_t value = (hi0 << 24) + (hi1 << 16) + (lo0 << 8) + lo1;
    do_write(addr, value);
    return;
}
#endif

