////////////////////////////////////////////////////////////////////////////////////////
//                                                                     
//                  I N T E L   P R O P R I E T A R Y                   
//                                                                      
//     COPYRIGHT (c)  2001-2002 BY  INTEL  CORPORATION.  ALL RIGHTS          
//     RESERVED.   NO  PART  OF THIS PROGRAM  OR  PUBLICATION  MAY      
//     BE  REPRODUCED,   TRANSMITTED,   TRANSCRIBED,   STORED  IN  A    
//     RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER    
//     LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL,    
//     MAGNETIC,  OPTICAL,  CHEMICAL, MANUAL, OR OTHERWISE,  WITHOUT    
//     THE PRIOR WRITTEN PERMISSION OF :                                
//                                                                      
//                        INTEL  CORPORATION                            
//                                                                     
//                     2200 MISSION COLLEGE BLVD                        
//                                                                      
//               SANTA  CLARA,  CALIFORNIA  95052-8119                  
//                                                                      
////////////////////////////////////////////////////////////////////////////////////////
//
//
//      File Name: sig_functions.c
//
//      Purpose: This file provides a set of simple functions used for signalling 
//				 threads and micro engines.
//
/////////////////////////////////////////////////////////////////////////////////////////
#ifndef	__SIG_FUNCTIONS_C__
#define	__SIG_FUNCTIONS_C__

#include "sig_functions.h"

/////////////////////////////////////////////////////////////////////////////////////////
// GetCurrentCtx()
//		Description:
//			Returns the context (or thread) number of the current context.
//
//		Outputs:
//			The context number (valid range: 0-7).			
//
//		Inputs:
//			None.
//
/////////////////////////////////////////////////////////////////////////////////////////
static __forceinline 
int GetCurrentCtx()
{
	return local_csr_read(local_csr_active_ctx_sts) & 0x7;
}

/////////////////////////////////////////////////////////////////////////////////////////
// GetCurrentMe()
//		Description:
//			Returns the number of the microengine this code is running on.
//
//		Outputs:
//			The me number.
//				For IXP2400
//					valid values:	 0x00 0x01 0x02 0x03 0x10 0x11 0x12 0x13
//					(representing me:   0    1    2    3    4    5    6    7)
// 
//				For IXP2800
//					valid values:	 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
//					(representing me:   0    1    2    3    4    5    6    7)
//					valid values:	 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17
//					(representing me:   8    9   10   11   12   13   14   15) 
//
//		Inputs:
//			None.
//
/////////////////////////////////////////////////////////////////////////////////////////
static __forceinline 
int GetCurrentMe()
{
	return (local_csr_read(local_csr_active_ctx_sts) >> 3) & 0x1F;
}

/////////////////////////////////////////////////////////////////////////////////////////
// InitInterthreadSig
//		Description:
//			This function sets up the correct value to put into the SAME_ME_SIGNAL CSR
//			for the given signal. Using this function once saves the recurring overhead
//			of setting up the value for this CSR everytime the signal needs to be sent.
//
//		Outputs:
//			The value to put in the SAME_ME_SIGNAL CSR for the given signal.
//
//		Inputs:
//			next_ctx_sig_gpr: The address of the inter thread signal you want to send.
//			next_ctx: The context you want to signal.
//
/////////////////////////////////////////////////////////////////////////////////////////
static __forceinline 
same_me_signal_t InitInterthreadSig(int sigval_next_ctx)
{
	same_me_signal_t x;

	x.value = 0;
	x.next_ctx = 1;
	x.sig = sigval_next_ctx;

	return x;
}

/////////////////////////////////////////////////////////////////////////////////////////
// SignalNextCtx()
//		Description:
//			This function writes to the SAME_ME_SIGNAL CSR.
//			Writing to this CSR sends signal 's' to context 'c'.
//
//		Outputs:
//			None
//
//		Inputs:
//			The value returned by InitInterthreadSig(&s, c).
//
/////////////////////////////////////////////////////////////////////////////////////////
static __forceinline
void SignalNextCtx(same_me_signal_t u)
{
	local_csr_write(local_csr_same_me_signal, u.value);
}

/////////////////////////////////////////////////////////////////////////////////////////
// SignalMe()
//		Description:
//			This function writes to the INTERTHREAD_SIG CAP.
//			Writing to this CSR sends signal 's' to me 'm'.
//
//		Outputs:
//			None
//
//		Inputs:
//			The value returned by init_interme_sig(&s, m). 
//
/////////////////////////////////////////////////////////////////////////////////////////
static __forceinline 
void SignalMe(int me, int sig)
{

	__declspec(gp_reg) int sig_gpr;

	// [11-7] = ME_NUMBER
	// [6:4]  = 0x0, THREAD_NUMBER
	// [3:0]  = SIGNAL

	sig_gpr = sig | (me << 7);

	cap_fast_write(sig_gpr, csr_interthread_sig);
}




#endif	//	__SIG_FUNCTIONS_C__
