/* Copyright (C) 2008 - Ruben Niederhagen
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you will find it online at
 * http://www.gnu.org/licenses/gpl.html
 */

/**
 * \file
 * \author Ruben Niederhagen (ruben@polycephaly.org)
 */


#ifndef _INCLUDE_SPU_TOOLS_H_
#define _INCLUDE_SPU_TOOLS_H_

#include "../types.h"
#include "dma_debug.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef DEBUG

#undef mfc_get
#undef mfc_put

/** 
* \brief Replace mfc_get by debug-version in DEBUG mode.
*
* If DEBUG is defined, mfc_get is replaced by a debug-version of that function 
* which gives additional information in case DMA parameter requirements are
* not satisfied.
*
* See mfc_get_debug() for further details.
*/
#define mfc_get(ls, ea, size, tag, tid, rid)\
        mfc_get_debug(ls, ea, size, tag, tid, rid, __FILE__, __LINE__)

/** 
 * \brief Replace mfc_put by debug-version in DEBUG mode.
 *
 * If DEBUG is defined, mfc_put is replaced by a debug-version of that function 
 * which gives additional information in case DMA parameter requirements are
 * not satisfied.
 *
 * See mfc_put_debug() for further details.
 */
#define mfc_put(ls, ea, size, tag, tid, rid)\
        mfc_put_debug(ls, ea, size, tag, tid, rid, __FILE__, __LINE__)

#endif /* DEBUG */


/** 
* \brief Barrier which uses direct local storage access.
*
* This barrier-implementation uses direct local storage access. The latency
* of this version increases with the number of attending SPEs.
*
* \param tag_id This tag is used for the necessary DMA transfers. 
* Pleas give an unused tag.
*/
void barrier(unsigned int tag_id);

/** 
* \brief Initialize internal values and transfer global and local data.
* 
* \param argp Enter the argp parameter of the SPE-main function here.
* \param envp Enter the envp parameter of the SPE-main function here.
* \param globals The address, the global date should be transfered to.
* \param globals_size The size of the global data.
* \param locals The address, the local data should be transfered to.
* \param locals_size The size of the local data.
*/
void init_spe(addr64_t argp, addr64_t envp, void* globals, uint16_t globals_size, 
													 void *locals, uint16_t locals_size);

/** 
* \brief Returns the ID of this SPE.
*
* This function returns the logical ID of this SPE thread (0...spe_threads).
* 
* \return The logical ID of this thread.
*/
int get_my_id();

/** 
* \brief Returns the physical ID for a given logical SPE id.
*
* This function returns the physical ID (in EIB-order) of a given logical
* SPE ID.
* (See get_log_id()).
* 
* \param log_id The logical ID of the SPE of interest.
* 
* \return The physical ID of the given SPE.
*/
int get_phys_id(int log_id);

/** 
* \brief Returns the logical ID for a given physical SPE id.
*
* This function returns the logical ID of a given physical SPE ID.
* (See get_phys_id()).
* 
* \param phys_id The physical ID of the SPE of interest.
* 
* \return The logical ID of the given SPE.
*/
int get_log_id(int phys_id);

#ifdef __cplusplus
}
#endif

#endif /* _INCLUDE_SPU_TOOLS_H_ */
