?? ixnpedlnpemgr.c
字號:
/** * @file IxNpeDlNpeMgr.c * * @author Intel Corporation * @date 09 January 2002 * * @brief This file contains the implementation of the private API for the * IXP425 NPE Downloader NpeMgr 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 user defined include files required. *//* * Put the user defined include files required. */#include "IxOsal.h"#include "IxNpeDl.h"#include "IxNpeDlNpeMgr_p.h"#include "IxNpeDlNpeMgrUtils_p.h"#include "IxNpeDlNpeMgrEcRegisters_p.h"#include "IxNpeDlMacros_p.h"#include "IxFeatureCtrl.h"/* * #defines and macros used in this file. */#define IX_NPEDL_BYTES_PER_WORD 4/* used to read download map from version in microcode image */#define IX_NPEDL_BLOCK_TYPE_INSTRUCTION 0x00000000#define IX_NPEDL_BLOCK_TYPE_DATA 0x00000001#define IX_NPEDL_BLOCK_TYPE_STATE 0x00000002#define IX_NPEDL_END_OF_DOWNLOAD_MAP 0x0000000F/* * masks used to extract address info from State information context * register addresses as read from microcode image */#define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG 0x0000000F#define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM 0x000000F0/* LSB offset of Context Number field in State-Info Context Address */#define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM 4/* size (in words) of single State Information entry (ctxt reg address|data) */#define IX_NPEDL_STATE_INFO_ENTRY_SIZE 2 #define IX_NPEDL_RESET_NPE_PARITY 0x0800 #define IX_NPEDL_PARITY_BIT_MASK 0x3F00FFFF #define IX_NPEDL_CONFIG_CTRL_REG_MASK 0x3F3FFFFF/* * Typedefs whose scope is limited to this file. */typedef struct{ UINT32 type; UINT32 offset;} IxNpeDlNpeMgrDownloadMapBlockEntry;typedef union{ IxNpeDlNpeMgrDownloadMapBlockEntry block; UINT32 eodmMarker;} IxNpeDlNpeMgrDownloadMapEntry;typedef struct{ /* 1st entry in the download map (there may be more than one) */ IxNpeDlNpeMgrDownloadMapEntry entry[1];} IxNpeDlNpeMgrDownloadMap;/* used to access an instruction or data block in a microcode image */typedef struct{ UINT32 npeMemAddress; UINT32 size; UINT32 data[1];} IxNpeDlNpeMgrCodeBlock;/* used to access each Context Reg entry state-information block */typedef struct{ UINT32 addressInfo; UINT32 value;} IxNpeDlNpeMgrStateInfoCtxtRegEntry;/* used to access a state-information block in a microcode image */typedef struct{ UINT32 size; IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1];} IxNpeDlNpeMgrStateInfoBlock; /* used to store some useful NPE information for easy access */typedef struct{ UINT32 baseAddress; UINT32 insMemSize; UINT32 dataMemSize;} IxNpeDlNpeInfo;/* used to distinguish instruction and data memory operations */typedef enum { IX_NPEDL_MEM_TYPE_INSTRUCTION = 0, IX_NPEDL_MEM_TYPE_DATA} IxNpeDlNpeMemType;/* used to hold a reset value for a particular ECS register */typedef struct{ UINT32 regAddr; UINT32 regResetVal;} IxNpeDlEcsRegResetValue;/* prototype of function to write either Instruction or Data memory */typedef IX_STATUS (*IxNpeDlNpeMgrMemWrite) (UINT32 npeBaseAddress, UINT32 npeMemAddress, UINT32 npeMemData, BOOL verify);/* module statistics counters */typedef struct{ UINT32 instructionBlocksLoaded; UINT32 dataBlocksLoaded; UINT32 stateInfoBlocksLoaded; UINT32 criticalNpeErrors; UINT32 criticalMicrocodeErrors; UINT32 npeStarts; UINT32 npeStops; UINT32 npeResets;} IxNpeDlNpeMgrStats;/* * Variable declarations global to this file only. Externs are followed by * static variables. */static IxNpeDlNpeInfo ixNpeDlNpeInfo[] ={ { 0, IX_NPEDL_INS_MEMSIZE_WORDS_NPEA, IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA }, { 0, IX_NPEDL_INS_MEMSIZE_WORDS_NPEB, IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB }, { 0, IX_NPEDL_INS_MEMSIZE_WORDS_NPEC, IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC }};/* contains Reset values for Context Store Registers */static UINT32 ixNpeDlCtxtRegResetValues[] ={ IX_NPEDL_CTXT_REG_RESET_STEVT, IX_NPEDL_CTXT_REG_RESET_STARTPC, IX_NPEDL_CTXT_REG_RESET_REGMAP, IX_NPEDL_CTXT_REG_RESET_CINDEX,};/* contains Reset values for Context Store Registers */static IxNpeDlEcsRegResetValue ixNpeDlEcsRegResetValues[] ={ {IX_NPEDL_ECS_BG_CTXT_REG_0, IX_NPEDL_ECS_BG_CTXT_REG_0_RESET}, {IX_NPEDL_ECS_BG_CTXT_REG_1, IX_NPEDL_ECS_BG_CTXT_REG_1_RESET}, {IX_NPEDL_ECS_BG_CTXT_REG_2, IX_NPEDL_ECS_BG_CTXT_REG_2_RESET}, {IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET}, {IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET}, {IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET}, {IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET}, {IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET}, {IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET}, {IX_NPEDL_ECS_DBG_CTXT_REG_0, IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET}, {IX_NPEDL_ECS_DBG_CTXT_REG_1, IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET}, {IX_NPEDL_ECS_DBG_CTXT_REG_2, IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET}, {IX_NPEDL_ECS_INSTRUCT_REG, IX_NPEDL_ECS_INSTRUCT_REG_RESET}};static IxNpeDlNpeMgrStats ixNpeDlNpeMgrStats;/* Set when NPE register memory has been mapped */static BOOL ixNpeDlMemInitialised = FALSE;/* * static function prototypes. */PRIVATE IX_STATUSixNpeDlNpeMgrMemLoad (IxNpeDlNpeId npeId, UINT32 npeBaseAddress, IxNpeDlNpeMgrCodeBlock *codeBlockPtr, BOOL verify, IxNpeDlNpeMemType npeMemType);PRIVATE IX_STATUSixNpeDlNpeMgrStateInfoLoad (UINT32 npeBaseAddress, IxNpeDlNpeMgrStateInfoBlock *codeBlockPtr, BOOL verify);PRIVATE BOOLixNpeDlNpeMgrBitsSetCheck (UINT32 npeBaseAddress, UINT32 regOffset, UINT32 expectedBitsSet);PRIVATE UINT32ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId);/* * Function definition: ixNpeDlNpeMgrBaseAddressGet */PRIVATE UINT32ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId){ IX_OSAL_ASSERT (ixNpeDlMemInitialised); return ixNpeDlNpeInfo[npeId].baseAddress;}/* * Function definition: ixNpeDlNpeMgrInit */voidixNpeDlNpeMgrInit (void){ /* Only map the memory once */ if (!ixNpeDlMemInitialised) { UINT32 virtAddr; /* map the register memory for NPE-A */ virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEA, IX_OSAL_IXP400_NPEA_MAP_SIZE); IX_OSAL_ASSERT(virtAddr); ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = virtAddr; /* map the register memory for NPE-B */ virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEB, IX_OSAL_IXP400_NPEB_MAP_SIZE); IX_OSAL_ASSERT(virtAddr); ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = virtAddr; /* map the register memory for NPE-C */ virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEC, IX_OSAL_IXP400_NPEC_MAP_SIZE); IX_OSAL_ASSERT(virtAddr); ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = virtAddr; ixNpeDlMemInitialised = TRUE; }}/* * Function definition: ixNpeDlNpeMgrUninit */IX_STATUSixNpeDlNpeMgrUninit (void){ if (!ixNpeDlMemInitialised) { return IX_FAIL; } IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress); IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress); IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress); ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = 0; ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = 0; ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = 0; ixNpeDlMemInitialised = FALSE; return IX_SUCCESS;}/* * Function definition: ixNpeDlNpeMgrImageLoad */IX_STATUSixNpeDlNpeMgrImageLoad ( IxNpeDlNpeId npeId, UINT32 *imageCodePtr, BOOL verify){ UINT32 npeBaseAddress; IxNpeDlNpeMgrDownloadMap *downloadMap; UINT32 *blockPtr; UINT32 mapIndex = 0; IX_STATUS status = IX_SUCCESS; IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, "Entering ixNpeDlNpeMgrImageLoad\n"); /* get base memory address of NPE from npeId */ npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId); /* check execution status of NPE to verify NPE Stop was successful */ if (!ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, IX_NPEDL_EXCTL_STATUS_STOP)) { IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageDownload - " "NPE was not stopped before download\n"); status = IX_FAIL; } else { /* * Read Download Map, checking each block type and calling * appropriate function to perform download */ downloadMap = (IxNpeDlNpeMgrDownloadMap *) imageCodePtr; while ((downloadMap->entry[mapIndex].eodmMarker != IX_NPEDL_END_OF_DOWNLOAD_MAP) && (status == IX_SUCCESS)) { /* calculate pointer to block to be downloaded */ blockPtr = imageCodePtr + downloadMap->entry[mapIndex].block.offset; switch (downloadMap->entry[mapIndex].block.type) { case IX_NPEDL_BLOCK_TYPE_INSTRUCTION: status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress, (IxNpeDlNpeMgrCodeBlock *)blockPtr, verify, IX_NPEDL_MEM_TYPE_INSTRUCTION); break; case IX_NPEDL_BLOCK_TYPE_DATA: status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress, (IxNpeDlNpeMgrCodeBlock *)blockPtr, verify, IX_NPEDL_MEM_TYPE_DATA); break; case IX_NPEDL_BLOCK_TYPE_STATE: status = ixNpeDlNpeMgrStateInfoLoad (npeBaseAddress, (IxNpeDlNpeMgrStateInfoBlock *) blockPtr, verify); break; default: IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageLoad: " "unknown block type in download map\n"); status = IX_NPEDL_CRITICAL_MICROCODE_ERR; ixNpeDlNpeMgrStats.criticalMicrocodeErrors++; break; } mapIndex++; }/* loop: for each entry in download map, while status == SUCCESS */ }/* condition: NPE stopped before attempting download */ IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, "Exiting ixNpeDlNpeMgrImageLoad : status = %d\n", status); return status;}/* * Function definition: ixNpeDlNpeMgrMemLoad */PRIVATE IX_STATUSixNpeDlNpeMgrMemLoad ( IxNpeDlNpeId npeId, UINT32 npeBaseAddress, IxNpeDlNpeMgrCodeBlock *blockPtr, BOOL verify, IxNpeDlNpeMemType npeMemType){ UINT32 npeMemAddress; UINT32 blockSize; UINT32 memSize = 0; IxNpeDlNpeMgrMemWrite memWriteFunc = NULL; UINT32 localIndex = 0; IX_STATUS status = IX_SUCCESS; IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, "Entering ixNpeDlNpeMgrMemLoad\n"); /* * select NPE EXCTL reg read/write commands depending on memory * type (instruction/data) to be accessed */ if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION) { memSize = ixNpeDlNpeInfo[npeId].insMemSize; memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrInsMemWrite; } else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA) { memSize = ixNpeDlNpeInfo[npeId].dataMemSize; memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrDataMemWrite; } /* * NPE memory is loaded contiguously from each block, so only address * of 1st word in block is needed */ npeMemAddress = blockPtr->npeMemAddress; /* number of words of instruction/data microcode in block to download */ blockSize = blockPtr->size; if ((npeMemAddress + blockSize) > memSize) { IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: " "Block size too big for NPE memory\n"); status = IX_NPEDL_CRITICAL_MICROCODE_ERR; ixNpeDlNpeMgrStats.criticalMicrocodeErrors++; } else { for (localIndex = 0; localIndex < blockSize; localIndex++) { status = memWriteFunc (npeBaseAddress, npeMemAddress, blockPtr->data[localIndex], verify); if (status != IX_SUCCESS) { IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: " "write to NPE memory failed\n"); status = IX_NPEDL_CRITICAL_NPE_ERR; ixNpeDlNpeMgrStats.criticalNpeErrors++;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -