/**
 * @file IxNpeDlNpeMgrUtils.c
 *
 * @author Intel Corporation
 * @date 18 February 2002
 *
 * @brief This file contains the implementation of the private API for the 
 *        IXP425 NPE Downloader NpeMgr Utils module
 *
 * 
 * @par
 * IXP400 SW Release version 2.0
 * 
 * -- Copyright Notice --
 * 
 * @par
 * Copyright 2001-2005, Intel Corporation.
 * All rights reserved.
 * 
 * @par
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Intel Corporation nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * @par
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * @par
 * -- End of Copyright Notice --
*/


/*
 * Put the system defined include files required.
 */
#define IX_NPE_DL_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
                                              * retries before
                                              * timeout
					                          */  

/*
 * Put the user defined include files required.
 */
#include "IxOsal.h"
#include "IxNpeDl.h"
#include "IxNpeDlNpeMgrUtils_p.h"
#include "IxNpeDlNpeMgrEcRegisters_p.h"
#include "IxNpeDlMacros_p.h"

/*
 * #defines and macros used in this file.
 */

/* used to bit-mask a number of bytes */
#define IX_NPEDL_MASK_LOWER_BYTE_OF_WORD  0x000000FF
#define IX_NPEDL_MASK_LOWER_SHORT_OF_WORD 0x0000FFFF
#define IX_NPEDL_MASK_FULL_WORD           0xFFFFFFFF

#define IX_NPEDL_BYTES_PER_WORD           4
#define IX_NPEDL_BYTES_PER_SHORT          2

#define IX_NPEDL_REG_SIZE_BYTE            8
#define IX_NPEDL_REG_SIZE_SHORT           16
#define IX_NPEDL_REG_SIZE_WORD            32

/*
 * Introduce extra read cycles after issuing read command to NPE
 * so that we read the register after the NPE has updated it
 * This is to overcome race condition between XScale and NPE
 */
#define IX_NPEDL_DELAY_READ_CYCLES        2
/*
 * To mask top three MSBs of 32bit word to download into NPE IMEM
 */
#define IX_NPEDL_MASK_UNUSED_IMEM_BITS    0x1FFFFFFF;


/*
 * typedefs
 */
typedef struct
{
    UINT32 regAddress;
    UINT32 regSize;
} IxNpeDlCtxtRegAccessInfo;

/* module statistics counters */
typedef struct
{
    UINT32 insMemWrites;
    UINT32 insMemWriteFails;
    UINT32 dataMemWrites;
    UINT32 dataMemWriteFails;
    UINT32 ecsRegWrites;
    UINT32 ecsRegReads;
    UINT32 dbgInstructionExecs;
    UINT32 contextRegWrites;
    UINT32 physicalRegWrites;
    UINT32 nextPcWrites;
} IxNpeDlNpeMgrUtilsStats;


/*
 * Variable declarations global to this file only.  Externs are followed by
 * static variables.
 */

/* 
 * contains useful address and function pointers to read/write Context Regs, 
 * eliminating some switch or if-else statements in places
 */
static IxNpeDlCtxtRegAccessInfo ixNpeDlCtxtRegAccInfo[IX_NPEDL_CTXT_REG_MAX] =
{
    {
	IX_NPEDL_CTXT_REG_ADDR_STEVT,
	IX_NPEDL_REG_SIZE_BYTE
    },
    {
	IX_NPEDL_CTXT_REG_ADDR_STARTPC,
	IX_NPEDL_REG_SIZE_SHORT
    },
    {
	IX_NPEDL_CTXT_REG_ADDR_REGMAP,
	IX_NPEDL_REG_SIZE_SHORT
    },
    {
	IX_NPEDL_CTXT_REG_ADDR_CINDEX,
	IX_NPEDL_REG_SIZE_BYTE
    }
};

static UINT32 ixNpeDlSavedExecCount = 0;
static UINT32 ixNpeDlSavedEcsDbgCtxtReg2 = 0;

static IxNpeDlNpeMgrUtilsStats ixNpeDlNpeMgrUtilsStats;


/*
 * static function prototypes.
 */
PRIVATE __inline__ void
ixNpeDlNpeMgrWriteCommandIssue (UINT32 npeBaseAddress, UINT32 cmd,
				UINT32 addr, UINT32 data);

PRIVATE __inline__ UINT32
ixNpeDlNpeMgrReadCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr);

PRIVATE IX_STATUS
ixNpeDlNpeMgrLogicalRegRead (UINT32 npeBaseAddress, UINT32 regAddr,
			     UINT32 regSize, UINT32 ctxtNum, UINT32 *regVal);

PRIVATE IX_STATUS
ixNpeDlNpeMgrLogicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr,
			      UINT32 regVal, UINT32 regSize,
			      UINT32 ctxtNum, BOOL verify);

/*
 * Function definition: ixNpeDlNpeMgrWriteCommandIssue
 */
PRIVATE __inline__ void
ixNpeDlNpeMgrWriteCommandIssue (
    UINT32 npeBaseAddress,
    UINT32 cmd,
    UINT32 addr,
    UINT32 data)
{
    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, data);
    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
}


/*
 * Function definition: ixNpeDlNpeMgrReadCommandIssue
 */
PRIVATE __inline__ UINT32
ixNpeDlNpeMgrReadCommandIssue (
    UINT32 npeBaseAddress,
    UINT32 cmd,
    UINT32 addr)
{
    UINT32 data = 0;
    int i;

    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
    for (i = 0; i <= IX_NPEDL_DELAY_READ_CYCLES; i++)
    {
	IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, &data);
    }

    return data;
}

/*
 * Function definition: ixNpeDlNpeMgrInsMemWrite
 */
IX_STATUS
ixNpeDlNpeMgrInsMemWrite (
    UINT32 npeBaseAddress,
    UINT32 insMemAddress,
    UINT32 insMemData,
    BOOL verify)
{
    UINT32 insMemDataRtn;

    ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
				    IX_NPEDL_EXCTL_CMD_WR_INS_MEM,
				    insMemAddress, insMemData);
    if (verify)
    {
        /* write invalid data to this reg, so we can see if we're reading 
	   the EXDATA register too early */
	IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA,
			    ~insMemData);

        /*Disabled since top 3 MSB are not used for Azusa hardware Refer WR:IXA00053900*/
        insMemData&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;

        insMemDataRtn=ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
                                           IX_NPEDL_EXCTL_CMD_RD_INS_MEM,
                                           insMemAddress);

        insMemDataRtn&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;

	if (insMemData != insMemDataRtn)
	{
	    ixNpeDlNpeMgrUtilsStats.insMemWriteFails++;
	    return IX_FAIL;
	}
    }

    ixNpeDlNpeMgrUtilsStats.insMemWrites++;
    return IX_SUCCESS;
}


/*
 * Function definition: ixNpeDlNpeMgrDataMemWrite
 */
IX_STATUS
ixNpeDlNpeMgrDataMemWrite (
    UINT32 npeBaseAddress,
    UINT32 dataMemAddress,
    UINT32 dataMemData,
    BOOL verify)
{
    ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
				    IX_NPEDL_EXCTL_CMD_WR_DATA_MEM,
				    dataMemAddress, dataMemData);
    if (verify)
    {
        /* write invalid data to this reg, so we can see if we're reading 
	   the EXDATA register too early */
	IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, ~dataMemData);

	if (dataMemData !=
	    ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
					   IX_NPEDL_EXCTL_CMD_RD_DATA_MEM,
					   dataMemAddress))
	{
	    ixNpeDlNpeMgrUtilsStats.dataMemWriteFails++;
	    return IX_FAIL;
	}
    }

    ixNpeDlNpeMgrUtilsStats.dataMemWrites++;
    return IX_SUCCESS;
}


/*
 * Function definition: ixNpeDlNpeMgrExecAccRegWrite
 */
void
ixNpeDlNpeMgrExecAccRegWrite (
    UINT32 npeBaseAddress,
    UINT32 regAddress,
    UINT32 regData)
{
    ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
				    IX_NPEDL_EXCTL_CMD_WR_ECS_REG,
				    regAddress, regData);
    ixNpeDlNpeMgrUtilsStats.ecsRegWrites++;
}


/*
 * Function definition: ixNpeDlNpeMgrExecAccRegRead
 */
UINT32
ixNpeDlNpeMgrExecAccRegRead (
    UINT32 npeBaseAddress,
    UINT32 regAddress)
{
    ixNpeDlNpeMgrUtilsStats.ecsRegReads++;
    return ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
					  IX_NPEDL_EXCTL_CMD_RD_ECS_REG,
					  regAddress);
}


/*
 * Function definition: ixNpeDlNpeMgrCommandIssue
 */
void
ixNpeDlNpeMgrCommandIssue (
    UINT32 npeBaseAddress,
    UINT32 command)     
{
    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
		     "Entering ixNpeDlNpeMgrCommandIssue\n");

    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, command);

    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
		     "Exiting ixNpeDlNpeMgrCommandIssue\n");
}


/*
 * Function definition: ixNpeDlNpeMgrDebugInstructionPreExec
 */
void
ixNpeDlNpeMgrDebugInstructionPreExec(
    UINT32 npeBaseAddress)
{
    /* turn off the halt bit by clearing Execution Count register. */
    /* save reg contents 1st and restore later */
    IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
		       &ixNpeDlSavedExecCount);
    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, 0);

    /* ensure that IF and IE are on (temporarily), so that we don't end up
     * stepping forever */
    ixNpeDlSavedEcsDbgCtxtReg2 = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
				                   IX_NPEDL_ECS_DBG_CTXT_REG_2);

    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
				  (ixNpeDlSavedEcsDbgCtxtReg2 |
				   IX_NPEDL_MASK_ECS_DBG_REG_2_IF |
				   IX_NPEDL_MASK_ECS_DBG_REG_2_IE));
}


/*
 * Function definition: ixNpeDlNpeMgrDebugInstructionExec
 */
IX_STATUS
ixNpeDlNpeMgrDebugInstructionExec(
    UINT32 npeBaseAddress,
    UINT32 npeInstruction,
    UINT32 ctxtNum,
    UINT32 ldur)
{
    UINT32 ecsDbgRegVal;
    UINT32 oldWatchcount, newWatchcount;
    UINT32 retriesCount = 0;
    IX_STATUS status = IX_SUCCESS;

    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
		     "Entering ixNpeDlNpeMgrDebugInstructionExec\n");

    /* set the Active bit, and the LDUR, in the debug level */
    ecsDbgRegVal = IX_NPEDL_MASK_ECS_REG_0_ACTIVE |
	(ldur << IX_NPEDL_OFFSET_ECS_REG_0_LDUR);

    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
				  ecsDbgRegVal);

    /*
     * set CCTXT at ECS DEBUG L3 to specify in which context to execute the
     * instruction, and set SELCTXT at ECS DEBUG Level to specify which context
     * store to access.
     * Debug ECS Level Reg 1 has form  0x000n000n, where n = context number
     */
    ecsDbgRegVal = (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_CCTXT) |
	(ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT);

    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_1,
				  ecsDbgRegVal);

    /* clear the pipeline */
    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);

    /* load NPE instruction into the instruction register */
    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_INSTRUCT_REG,
				  npeInstruction);

    /* we need this value later to wait for completion of NPE execution step */
    IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, &oldWatchcount);

    /* issue a Step One command via the Execution Control register */
    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STEP);

	/* Watch Count register increments when NPE completes an instruction */
	IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
        &newWatchcount);
        
    /*
     * force the XScale to wait until the NPE has finished execution step
     * NOTE that this delay will be very small, just long enough to allow a
     * single NPE instruction to complete execution; if instruction execution
     * is not completed before timeout retries, exit the while loop
     */
    while ((IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount) 
        && (newWatchcount == oldWatchcount))
    {
	    /* Watch Count register increments when NPE completes an instruction */
	    IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
		    &newWatchcount);
			   
        retriesCount++;
    }    

    if (IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount)
    {
        ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs++;
    }
    else
    {
        /* Return timeout status as the instruction has not been executed
         * after maximum retries */
        status = IX_NPEDL_CRITICAL_NPE_ERR;
    }
    
    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
		     "Exiting ixNpeDlNpeMgrDebugInstructionExec\n");
		     
    return status;
}    


/*
 * Function definition: ixNpeDlNpeMgrDebugInstructionPostExec
 */
void
ixNpeDlNpeMgrDebugInstructionPostExec(
    UINT32 npeBaseAddress)
{
    /* clear active bit in debug level */
    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
				  0);

    /* clear the pipeline */
    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
    
    /* restore Execution Count register contents. */
    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
			ixNpeDlSavedExecCount);

    /* restore IF and IE bits to original values */
    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
				  ixNpeDlSavedEcsDbgCtxtReg2);
}


/*
 * Function definition: ixNpeDlNpeMgrLogicalRegRead
 */
PRIVATE IX_STATUS
ixNpeDlNpeMgrLogicalRegRead (
    UINT32 npeBaseAddress, 
    UINT32 regAddr,
    UINT32 regSize,
    UINT32 ctxtNum,
    UINT32 *regVal)
{
    IX_STATUS status = IX_SUCCESS;
    UINT32 npeInstruction = 0;
    UINT32 mask = 0;

    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
		     "Entering ixNpeDlNpeMgrLogicalRegRead\n");

    switch (regSize)
    {
    case IX_NPEDL_REG_SIZE_BYTE:
      npeInstruction = IX_NPEDL_INSTR_RD_REG_BYTE;
      mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD;  break;
    case IX_NPEDL_REG_SIZE_SHORT:
      npeInstruction = IX_NPEDL_INSTR_RD_REG_SHORT;
      mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD;  break;
    case IX_NPEDL_REG_SIZE_WORD:
      npeInstruction = IX_NPEDL_INSTR_RD_REG_WORD;
      mask = IX_NPEDL_MASK_FULL_WORD;  break;
    }

    /* make regAddr be the SRC and DEST operands (e.g. movX d0, d0) */
    npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_SRC) |
	(regAddr << IX_NPEDL_OFFSET_INSTR_DEST);

    /* step execution of NPE intruction using Debug Executing Context stack */
    status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, npeInstruction,
				       ctxtNum, IX_NPEDL_RD_INSTR_LDUR);

    if (IX_SUCCESS != status)
    {
        return status;
    }
    
    /* read value of register from Execution Data register */
    IX_NPEDL_REG_READ (npeBaseAddress,	IX_NPEDL_REG_OFFSET_EXDATA, regVal);

   /* align value from left to right */
    *regVal = (*regVal >> (IX_NPEDL_REG_SIZE_WORD - regSize)) & mask;

    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
		     "Exiting ixNpeDlNpeMgrLogicalRegRead\n");
    
    return IX_SUCCESS;
}


/*
 * Function definition: ixNpeDlNpeMgrLogicalRegWrite
 */
PRIVATE IX_STATUS
ixNpeDlNpeMgrLogicalRegWrite (
    UINT32 npeBaseAddress, 
    UINT32 regAddr,
    UINT32 regVal,
    UINT32 regSize,
    UINT32 ctxtNum,
    BOOL verify)
{
    UINT32 npeInstruction = 0;
    UINT32 mask = 0;
    IX_STATUS status = IX_SUCCESS;
    UINT32 retRegVal;

    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
		     "Entering ixNpeDlNpeMgrLogicalRegWrite\n");

    if (regSize == IX_NPEDL_REG_SIZE_WORD)
    {
	/* NPE register addressing is left-to-right: e.g. |d0|d1|d2|d3| */
	/* Write upper half-word (short) to |d0|d1| */
	status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr,
				      regVal >> IX_NPEDL_REG_SIZE_SHORT,
				      IX_NPEDL_REG_SIZE_SHORT,
				      ctxtNum, verify);
				      
	if (IX_SUCCESS != status)
	{
	    return status;
	}
	
	/* Write lower half-word (short) to |d2|d3| */
	status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
				      regAddr + IX_NPEDL_BYTES_PER_SHORT,
                                    regVal & IX_NPEDL_MASK_LOWER_SHORT_OF_WORD,
				      IX_NPEDL_REG_SIZE_SHORT,
				      ctxtNum, verify);
    
    if (IX_SUCCESS != status)
	{
	    return status;
	}
	}
    else
    {
        switch (regSize)
	{ 
	case IX_NPEDL_REG_SIZE_BYTE:
	    npeInstruction = IX_NPEDL_INSTR_WR_REG_BYTE;
	    mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD;  break;
	case IX_NPEDL_REG_SIZE_SHORT:
            npeInstruction = IX_NPEDL_INSTR_WR_REG_SHORT;
	    mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD;  break;
	}
	/* mask out any redundant bits, so verify will work later */
	regVal &= mask;

	/* fill dest operand field of  instruction with destination reg addr */
	npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_DEST);

	/* fill src operand field of instruction with least-sig 5 bits of val*/
	npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA) <<
			   IX_NPEDL_OFFSET_INSTR_SRC);

	/* fill coprocessor field of instruction with most-sig 11 bits of val*/
	npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) <<
			   IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA);

	/* step execution of NPE intruction using Debug ECS */
	status = ixNpeDlNpeMgrDebugInstructionExec(npeBaseAddress, npeInstruction,
					  ctxtNum, IX_NPEDL_WR_INSTR_LDUR);
					  
	if (IX_SUCCESS != status)
	{
	    return status;  
	} 
    }/* condition: if reg to be written is 8-bit or 16-bit (not 32-bit) */

    if (verify)
    {
    	status = ixNpeDlNpeMgrLogicalRegRead (npeBaseAddress, regAddr,
    						   regSize, ctxtNum, &retRegVal);
    						   
        if (IX_SUCCESS == status)
        {
            if (regVal != retRegVal)
            {
                status = IX_FAIL;
            }
        }        
    }

    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
		     "Exiting ixNpeDlNpeMgrLogicalRegWrite : status = %d\n",
		     status);
    
    return status;
}


/*
 * Function definition: ixNpeDlNpeMgrPhysicalRegWrite
 */
IX_STATUS
ixNpeDlNpeMgrPhysicalRegWrite (
    UINT32 npeBaseAddress,
    UINT32 regAddr,
    UINT32 regValue,
    BOOL verify)
{
    IX_STATUS status;

    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
		     "Entering ixNpeDlNpeMgrPhysicalRegWrite\n");

/*
 * There are 32 physical registers used in an NPE.  These are
 * treated as 16 pairs of 32-bit registers.  To write one of the pair,
 * write the pair number (0-16) to the REGMAP for Context 0.  Then write
 * the value to register  0 or 4 in the regfile, depending on which
 * register of the pair is to be written
 */

    /*
     * set REGMAP for context 0 to (regAddr >> 1) to choose which pair (0-16)
     * of physical registers to write 
     */
    status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
					   IX_NPEDL_CTXT_REG_ADDR_REGMAP,
					   (regAddr >>
					  IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP),
					   IX_NPEDL_REG_SIZE_SHORT, 0, verify);
    if (status == IX_SUCCESS)
    {
	/* regAddr = 0 or 4  */
	regAddr = (regAddr & IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR) *
	    IX_NPEDL_BYTES_PER_WORD;
    
    status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr, regValue, 
					   IX_NPEDL_REG_SIZE_WORD, 0, verify);
    }
    
    if (status != IX_SUCCESS)
    {
	IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrPhysicalRegWrite: "
			       "error writing to physical register\n");
    }

    ixNpeDlNpeMgrUtilsStats.physicalRegWrites++;

    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
		     "Exiting ixNpeDlNpeMgrPhysicalRegWrite : status = %d\n",
		     status);
    return status;
}


/*
 * Function definition: ixNpeDlNpeMgrCtxtRegWrite
 */
IX_STATUS
ixNpeDlNpeMgrCtxtRegWrite (
    UINT32 npeBaseAddress,
    UINT32 ctxtNum,
    IxNpeDlCtxtRegNum ctxtReg,
    UINT32 ctxtRegVal,
    BOOL verify)
{
    UINT32 tempRegVal;
    UINT32 ctxtRegAddr;
    UINT32 ctxtRegSize;
    IX_STATUS status = IX_SUCCESS;

    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
		     "Entering ixNpeDlNpeMgrCtxtRegWrite\n");

    /*
     * Context 0 has no STARTPC. Instead, this value is used to set
     * NextPC for Background ECS, to set where NPE starts executing code
     */
    if ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STARTPC))
    {
	/* read BG_CTXT_REG_0, update NEXTPC bits, and write back to reg */
	tempRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
						  IX_NPEDL_ECS_BG_CTXT_REG_0);
	tempRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
	tempRegVal |= (ctxtRegVal << IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC) &
	    IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
	
	ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress,
				      IX_NPEDL_ECS_BG_CTXT_REG_0, tempRegVal);

	ixNpeDlNpeMgrUtilsStats.nextPcWrites++;
    }
    else
    {
	ctxtRegAddr = ixNpeDlCtxtRegAccInfo[ctxtReg].regAddress;
	ctxtRegSize = ixNpeDlCtxtRegAccInfo[ctxtReg].regSize;
	status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, ctxtRegAddr,
					       ctxtRegVal, ctxtRegSize,
					       ctxtNum, verify);
	if (status != IX_SUCCESS)
	{
	    IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrCtxtRegWrite: "
				   "error writing to context store register\n");
	}
	
	ixNpeDlNpeMgrUtilsStats.contextRegWrites++;
    }

    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
		     "Exiting ixNpeDlNpeMgrCtxtRegWrite : status = %d\n",
		     status);

    return status;
}


/*
 * Function definition: ixNpeDlNpeMgrUtilsStatsShow
 */
void
ixNpeDlNpeMgrUtilsStatsShow (void)
{
    ixOsalLog (IX_OSAL_LOG_LVL_USER,
               IX_OSAL_LOG_DEV_STDOUT,
               "\nixNpeDlNpeMgrUtilsStatsShow:\n"
               "\tInstruction Memory writes: %u\n"
               "\tInstruction Memory writes failed: %u\n"
               "\tData Memory writes: %u\n"
               "\tData Memory writes failed: %u\n",
               ixNpeDlNpeMgrUtilsStats.insMemWrites,
               ixNpeDlNpeMgrUtilsStats.insMemWriteFails,
               ixNpeDlNpeMgrUtilsStats.dataMemWrites,
               ixNpeDlNpeMgrUtilsStats.dataMemWriteFails,
               0,0);

    ixOsalLog (IX_OSAL_LOG_LVL_USER,
               IX_OSAL_LOG_DEV_STDOUT,
               "\tExecuting Context Stack Register writes: %u\n"
               "\tExecuting Context Stack Register reads: %u\n"
               "\tPhysical Register writes: %u\n"
               "\tContext Store Register writes: %u\n"
               "\tExecution Backgound Context NextPC writes: %u\n"
               "\tDebug Instructions Executed: %u\n\n",
               ixNpeDlNpeMgrUtilsStats.ecsRegWrites,
               ixNpeDlNpeMgrUtilsStats.ecsRegReads,
               ixNpeDlNpeMgrUtilsStats.physicalRegWrites,
               ixNpeDlNpeMgrUtilsStats.contextRegWrites,
               ixNpeDlNpeMgrUtilsStats.nextPcWrites,
               ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs);
}


/*
 * Function definition: ixNpeDlNpeMgrUtilsStatsReset
 */
void
ixNpeDlNpeMgrUtilsStatsReset (void)
{
    ixNpeDlNpeMgrUtilsStats.insMemWrites = 0;
    ixNpeDlNpeMgrUtilsStats.insMemWriteFails = 0;
    ixNpeDlNpeMgrUtilsStats.dataMemWrites = 0;
    ixNpeDlNpeMgrUtilsStats.dataMemWriteFails = 0;
    ixNpeDlNpeMgrUtilsStats.ecsRegWrites = 0;
    ixNpeDlNpeMgrUtilsStats.ecsRegReads = 0;
    ixNpeDlNpeMgrUtilsStats.physicalRegWrites = 0;
    ixNpeDlNpeMgrUtilsStats.contextRegWrites = 0;
    ixNpeDlNpeMgrUtilsStats.nextPcWrites = 0;
    ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs = 0;
}
