| /** |
| * @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 |
| * SPDX-License-Identifier: BSD-3-Clause |
| * @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; |
| } |