📄 ixnpedlnpemgrutils.c
字号:
/** * @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__ voidixNpeDlNpeMgrWriteCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr, UINT32 data);PRIVATE __inline__ UINT32ixNpeDlNpeMgrReadCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr);PRIVATE IX_STATUSixNpeDlNpeMgrLogicalRegRead (UINT32 npeBaseAddress, UINT32 regAddr, UINT32 regSize, UINT32 ctxtNum, UINT32 *regVal);PRIVATE IX_STATUSixNpeDlNpeMgrLogicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr, UINT32 regVal, UINT32 regSize, UINT32 ctxtNum, BOOL verify);/* * Function definition: ixNpeDlNpeMgrWriteCommandIssue */PRIVATE __inline__ voidixNpeDlNpeMgrWriteCommandIssue ( 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__ UINT32ixNpeDlNpeMgrReadCommandIssue ( 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_STATUSixNpeDlNpeMgrInsMemWrite ( 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_STATUSixNpeDlNpeMgrDataMemWrite ( 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 */voidixNpeDlNpeMgrExecAccRegWrite ( UINT32 npeBaseAddress, UINT32 regAddress, UINT32 regData){ ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_WR_ECS_REG, regAddress, regData); ixNpeDlNpeMgrUtilsStats.ecsRegWrites++;}/* * Function definition: ixNpeDlNpeMgrExecAccRegRead */UINT32ixNpeDlNpeMgrExecAccRegRead ( UINT32 npeBaseAddress, UINT32 regAddress){ ixNpeDlNpeMgrUtilsStats.ecsRegReads++; return ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_RD_ECS_REG, regAddress);}/* * Function definition: ixNpeDlNpeMgrCommandIssue */voidixNpeDlNpeMgrCommandIssue ( 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 */voidixNpeDlNpeMgrDebugInstructionPreExec( 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_STATUSixNpeDlNpeMgrDebugInstructionExec( 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -