/**************************************************************************** /* F i l e D a t a /* /* Module : BasicSW /* C.I. No. : /* $Revision: 1.9 $ /* $Date: 2005/03/20 18:16:53 $ /* Belonging to : /* : /* $RCSfile: PD_PatchDumpManager_int.c,v $ /* Program Type : /* Sub-modules : /* /**************************************************************************** /* S W D e v e l o p m e n t E n v i r o n m e n t /* /* Host system : /* SW Compiler : /* $Author: sebastiani $ /* : /**************************************************************************** /* U p d a t i n g /* /* $Log: PD_PatchDumpManager_int.c,v $ /* Revision 1.9 2005/03/20 18:16:53 sebastiani /* avoided compilation warning /* /* Revision 1.8 2005/03/06 14:53:22 sebastiani /* fix check different value /* /* Revision 1.7 2005/02/21 08:58:28 sebastiani /* all log comments completed /* /* Revision 1.6 2005/02/19 10:16:17 sebastiani /* efficient write in EEPROM /* /* Revision 1.5 2004/09/28 15:36:17 sebastiani /* interrupt manager fix /* /* Revision 1.4 2004/09/17 15:01:00 faber /* LU_INFN_LOG flags fixing /* /* Revision 1.3 2003/11/18 09:01:14 alfarano /* laben patch fixes some problems /* /* Revision 1.2 2003/10/21 16:09:12 alfarano /* LU_LOG_INFN replacement for all remaining original log functions /* /* Revision 1.1.1.1 2003/08/04 09:40:21 sebastiani /* Imported sources laben rel. 19.06.2003 integrated with pam2 /* /* Revision 1.10 2002/09/11 15:33:39 zulia /* correct checkParameterValue /* (memory address was casted to UWORD) /* /* Revision 1.9 2002/08/06 12:08:27 zulia /* the Patch mcmd is refused if the number of data words not are multiply of 32 bits /* /* Revision 1.8 2002/08/05 14:25:35 zulia /* Fixed Patch & Dump /* /* Revision 1.7 2002/05/09 08:16:34 zulia /* * acceptance release /* /* /*****************************************************************************/ /*============================= Include File ================================*/ #include #include #include #include #define __FILEID__ _PD_PatchDumpManager_int__c #include #include #include LU_DECL_MASK(); /*****************************************************************************/ /*============================= Object constant ============================*/ /*****************************************************************************/ /*============================= Object variables ============================*/ /*****************************************************************************/ /* P a t c h D u m p M a n a g e r O P E R A T I O N A L F U N C T I O N S */ /*****************************************************************************/ /* @Function: PD_ifPatch */ /* @Purpose : */ /* This function executes the Patch macrocommand performing the following */ /* actions: */ /* _ checks the number of words to be patched */ /* _ checks the supervisor memory selection */ /* _ checks if address is in the allowed range */ /* _ writes the patch at the correct address */ /* */ /* @@ */ /* @Parameter Name @Mode @Description */ /* PtrMcmd IN pointer to the macrocommand header structure */ /* PatchBuff IN pointer to the patch RAM area */ /* @@ */ /*****************************************************************************/ void PD_ifPatch(MA_HEADER_MCMD* PtrMcmd, UWORD* PatchBuff) { UINT* memAddrToPatch; UWORD nWord16ToLoad; UWORD smsPatch; UWORD error; UWORD* pw; UINT timetagFlag; MsgTsk sndMsg; pw = (UWORD*)(PtrMcmd->PtrMCMD); /* retrieves the number of words to be patched from the macrocommand length (expressed in multiples of 16bit words) */ nWord16ToLoad = pw[2] & 0x0FFF; /* subtracts 8 words from Mcmd length (mcmd header+end identifier) */ if ( nWord16ToLoad > 8 ) { nWord16ToLoad -= 8; } /* determinates if it is a RAM or EEPROM patch */ if( pw[5] & PD_PATCH_SMS_MASK ) { if ( pw[5] & PD_EEPROM_BANK_SELECT ) { memAddrToPatch = (UINT*)(PD_EEPROM_BANK1_ADDR_START + (((pw[5]&0x00FF)<<16) | pw[6])); smsPatch = PD_EEPROM_BANK1_PATCH; } else { memAddrToPatch = (UINT*)(PD_EEPROM_BANK0_ADDR_START + (((pw[5]&0x00FF)<<16) | pw[6])); smsPatch = PD_EEPROM_BANK0_PATCH; } } else { smsPatch = PD_RAM_PATCH; memAddrToPatch = (UINT*)(PD_RAM_ADDR_START + (((pw[5]&0x00FF)<<16) | pw[6])); } error = PD_ifCheckParamValues(memAddrToPatch, nWord16ToLoad>>1, smsPatch ); if ( nWord16ToLoad % 2) { /* The number of word must be 32-bit multiply */ error = HA_E2_INVALID_LENGTH; } if ( error == PD_PARAM_VALUES_NO_ERROR ) { /* copies into private buffer the data to be patched */ memcpy(PatchBuff, &pw[7], nWord16ToLoad<<1); } /* The function has been called by a MCMD, delete it from the partition */ timetagFlag = *(((unsigned short* )PtrMcmd->PtrMCMD)+1) & TIMETAG_MASK ? TIMETAG_MCMD : IMMEDIATE_MCMD; MA_piDelBufferMCMD(PtrMcmd->PtrMCMD, timetagFlag); if ( error == PD_PARAM_VALUES_NO_ERROR ) { /* writes the patch */ if( smsPatch == PD_RAM_PATCH ) { memcpy(memAddrToPatch, PatchBuff, nWord16ToLoad<<1); } else { PD_ifEEPROMWrite(memAddrToPatch, PatchBuff, nWord16ToLoad>>1); } } /* log in History Area*/ // LOG_INFN HA_piLogHistoryEntry2(PtrMcmd->Type,error); /*@LOG Patch MCMD - error code */ LU_INFN_LOG(LU_NORMAL_TRACE | LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,error); } /*****************************************************************************/ /* @Function: PD_ifDump */ /* @Purpose : */ /* This function executes the Dump macrocommand performing the following */ /* actions: */ /* _ checks the number of words to be patched */ /* _ checks the supervisor memory selection */ /* _ checks if address is in the allowed range */ /* _ checks the append_next flag */ /* _ copies data into the dump buffer */ /* */ /* @@ */ /* @Parameter Name @Mode @Description */ /* PtrMcmd IN pointer to the macrocommand header structure */ /* DumpBuff IN pointer to the dump RAM area */ /* @@ */ /*****************************************************************************/ void PD_ifDump(MA_HEADER_MCMD* PtrMcmd, UWORD* DumpBuff,PD_INFO* DumpInfo) { UINT* memAddrToDump; UWORD nWordsToDump; UWORD Append_Next; UWORD smsDump; UWORD eepromBankSel; UWORD error; UWORD* pw; UINT timetagFlag; MsgTsk sndMsg; /* The function has been called by a MCMD, delete it from the partition */ pw = (UWORD*)PtrMcmd->PtrMCMD; /* The parameter unit is 32 bit word, and is converted in byte unit */ nWordsToDump = (pw[5] & 0xFF00)>>6; Append_Next = pw[5] & 0x0001; smsDump = pw[5] & 0x0006; eepromBankSel = pw[5] & 0x0004; /* determinates if it is a RAM or EEPROM dump and computes the appropriate address */ if( smsDump == PD_RAM_DUMP ) memAddrToDump = (UINT*)( PD_RAM_ADDR_START + (((pw[6]&0x00FF)<<16) | pw[7]) ); else { if (eepromBankSel == PD_EEPROM_BANK0_DUMP ) memAddrToDump = (UINT*)( PD_EEPROM_BANK0_ADDR_START + (((pw[6]&0x00FF)<<16) | pw[7]) ); else memAddrToDump = (UINT*)( PD_EEPROM_BANK1_ADDR_START + (((pw[6]&0x00FF)<<16) | pw[7]) ); } error = PD_ifCheckParamValues(memAddrToDump, nWordsToDump>>2, smsDump); timetagFlag = *(((unsigned short* )PtrMcmd->PtrMCMD)+1) & TIMETAG_MASK ? TIMETAG_MCMD : IMMEDIATE_MCMD; MA_piDelBufferMCMD(PtrMcmd->PtrMCMD, timetagFlag); if ( error == PD_PARAM_VALUES_NO_ERROR ) { if( Append_Next ) { /* (1): append */ if( DumpInfo->nWordsAvailable >= (nWordsToDump >> 1) ) { /* appends the dump */ /* The number of words is stored into 32 bit word unit */ *DumpInfo->pAppend = (nWordsToDump<<6) | (pw[6]&0x00FF); *(++DumpInfo->pAppend) = pw[7]; memcpy(++DumpInfo->pAppend , memAddrToDump, nWordsToDump); DumpInfo->pAppend += (nWordsToDump>>1); DumpInfo->nWordsAvailable -= ((nWordsToDump >> 1)+2); } else { error = HA_E2_DUMP_BUFFER_FULL; } } else /* (0): no append */ { DumpInfo->pAppend = DumpBuff; DumpInfo->nWordsAvailable = PD_BUFFER_DUMP_MAX_SIZE; /* The number of words is stored into 32 bit word unit */ *DumpInfo->pAppend = (nWordsToDump<<6) | (pw[6]&0x00FF); *(++DumpInfo->pAppend) = pw[7]; memcpy(++DumpInfo->pAppend , memAddrToDump, nWordsToDump); DumpInfo->pAppend += (nWordsToDump>>1); DumpInfo->nWordsAvailable -= ((nWordsToDump >> 1)+2); } } /* log in History Area*/ // LOG_INFN HA_piLogHistoryEntry2(PtrMcmd->Type,error); /*@LOG Dump MCMD - error code */ LU_INFN_LOG(LU_NORMAL_TRACE | LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,error); } /*****************************************************************************/ /* @Function: PD_ifCheckParamValues */ /* @Purpose : */ /* This function checks that the requested patch/dump address is inside */ /* the allowed range, RAM EEPROM respectively */ /* */ /* @@ */ /* @Parameter Name @Mode @Description */ /* memAddrStart IN memory address from which to start patch */ /* or dump */ /* nWords IN number of words (32 bit) to patch/dump */ /* smsFlag IN Supervisor Memory Selection (RAM / EEPROM) */ /* status_code OUT Return code */ /* @@ */ /*****************************************************************************/ UWORD PD_ifCheckParamValues(UINT* memAddrStart, UWORD nWords, UWORD smsFlag) { UWORD status; UINT addrNotAlignedflag; status = PD_PARAM_VALUES_NO_ERROR; if( smsFlag == PD_RAM_PATCH ) { /* checks if address is inside RAM space and/or buffer overflow */ if( memAddrStart < (UINT*)PD_RAM_ADDR_START || memAddrStart > (UINT*)PD_RAM_ADDR_END ) { status = HA_E2_INVALID_ADDRESS; } else if( nWords >= PD_BUFFER_PATCH_MAX_SIZE || memAddrStart + nWords - 1 > (UINT*)PD_RAM_ADDR_END ) { status = HA_E2_INVALID_LENGTH; } } else if ( smsFlag == PD_EEPROM_BANK0_PATCH ) { /* The address must be 32-bit aligned */ addrNotAlignedflag =((UINT)((UINT*)memAddrStart) & 0x00000003); /* checks if address is inside EEPROM space and/or buffer overflow */ if( memAddrStart < (UINT*)PD_EEPROM_BANK0_ADDR_START || memAddrStart > (UINT*)PD_EEPROM_BANK0_ADDR_END || /* The address must be 32-bit aligned */ addrNotAlignedflag ) { status = HA_E2_INVALID_ADDRESS; } else if( nWords >= PD_BUFFER_PATCH_MAX_SIZE || memAddrStart + nWords - 1 > (UINT*)PD_EEPROM_BANK0_ADDR_END ) { status = HA_E2_INVALID_LENGTH; } } else if ( smsFlag == PD_EEPROM_BANK1_PATCH ) { /* The address must be 32-bit aligned */ addrNotAlignedflag =((UINT)((UINT*)memAddrStart) & 0x00000003); /* checks if address is inside EEPROM space and/or buffer overflow */ if( memAddrStart < (UINT*)PD_EEPROM_BANK1_ADDR_START || memAddrStart > (UINT*)PD_EEPROM_BANK1_ADDR_END || /* The address must be 32-bit aligned */ addrNotAlignedflag ) { status = HA_E2_INVALID_ADDRESS; } else if( nWords >= PD_BUFFER_PATCH_MAX_SIZE || memAddrStart + nWords - 1 > (UINT*)PD_EEPROM_BANK1_ADDR_END ) { status = HA_E2_INVALID_LENGTH; } } else status = HA_E2_INVALID_ADDRESS; return status; } /*****************************************************************************/ /* @Function: PD_ifEEPROMWrite */ /* @Purpose : */ /* This function writes a specified number of words from a source buffer */ /* to an EEPROM memory address. When a boundary is reached the process of */ /* writing is suspended for 10 milliseconds. */ /* */ /* @@ */ /* @Parameter Name @Mode @Description */ /* dstAddr IN write destination address */ /* sourceAddr IN read source address */ /* nWords32Bit IN number of words (32 bit) to be written */ /* @@ */ /*****************************************************************************/ void PD_ifEEPROMWrite(void* dstAddr, void* sourceAddr, UINT nWords32Bit ) { unsigned int level; UINT boundaryFlag; UINT boundery; UINT i; /* Enable EEPROM writing by programming CRIMEA register */ CD_EEPROM_WRITE_ENABLE; while ( nWords32Bit > 0 ) { boundaryFlag =FALSE; /* Find number of words until the boundary page */ for (i=0; i0; i++) { boundery =((UINT)((UINT*)dstAddr+i) & 0x000001FF); if (boundery == PD_BOUNDARY_EEPROM) { boundaryFlag =TRUE; } nWords32Bit--; } /* Write specified number of words into EEPROM */ PD_ifCopyRamToEEprom((UINT*)sourceAddr,(UINT*)dstAddr,i); /* Increment destination and source address */ (UINT*)dstAddr +=i; (UINT*)sourceAddr +=i; } /* Disable EEPROM writing by programming CRIMEA register */ CD_EEPROM_WRITE_DISABLE; } /*****************************************************************************/ /* @Function: PD_ifCopyRamToEEprom */ /* @Purpose : */ /* This function writes a specified number of words from a source buffer */ /* a source buffer to an EEPROM memory address. The number of written words */ /* into the EEPROM must not exceed the page boundary. At the end of the */ /* writing procedure the task is suspended for 10 milliseconds. */ /* */ /* @@ */ /* @Parameter Name @Mode @Description */ /* Dest IN write destination address */ /* Source IN read source address */ /* Len IN number of words (32 bit) to be written */ /* @@ */ /*****************************************************************************/ void PD_ifCopyRamToEEprom(UINT* Source, UINT* Dest, UINT Len) { unsigned int c; unsigned int level=0; UINT *ss=Source, *sd=Dest; /* added for safe: if the block is axactly the same, do nothing : */ for (c=0 ; c