/************************************************************************* $Archive: /PACS/OnBoard/l_memory.c $ $Revision: 1.10 $ $Date: 2009/04/23 13:51:12 $ $Author: amazy $ $Log: l_memory.c,v $ Revision 1.10 2009/04/23 13:51:12 amazy 6.029 * * 3 28/08/02 11:49 Amazy * Added the header with the history log *************************************************************************/ /***************************************************************************** * * Project name: Plank LFI REBA / Herschel PACS SPU * Product name: LLSW_DRV * Object name: l_memory * Filename: %M% * Language: C (ADSP-21020) * Compiler: G21K - r3.3 * Company: CRISA * Author: F. Torrero * Version: %I% * Creation date: 20/Ago/2001 * Last Modification date: %G% * * Description =============================================================== * * This module defines/implements constants related to the memory map and * functions for memory access * * Change log =============================================================== * * | DATE | NEW VERSION | AUTHOR | REASON FOR CHANGE | * =========================================================================== * * 20/Ago/01 1 F.Torrero Creation * * ****************************************************************************/ /***************************************************************************** INCLUDES *****************************************************************************/ #include "l_gendef.h" #include "l_errcod.h" #include "l_memory.h" /***************************************************************************** PRIVATE CONSTANTS *****************************************************************************/ /* Masks for MS 16 bits and LS 16 bits, out of a 32bit word */ #define K_MASK_MS16BITS 0x0000FFFF #define K_MASK_LS16BITS 0xFFFF0000 /* Mask and constants used to identify if a given PM address is within PRAM or EEPROM. Only bits 20:16 are used, making the identification independent of memory map (could be APSW or SUSW memory maps) */ #define K_BPOS_PRAM_EEPROM_IDENTIFIC 16 /* positions to right-shift */ #define K_MASK_PRAM_EEPROM_IDENTIFIC 0x1F /* Isolate bits once shifted */ /***************************************************************************** PRIVATE TYPES *****************************************************************************/ /***************************************************************************** PRIVATE VARIABLES *****************************************************************************/ /***************************************************************************** DECLARATION OF PRIVATE FUNCTIONS *****************************************************************************/ /***************************************************************************** IMPLEMENTATION OF FUNCTIONS *****************************************************************************/ /* #$# ----------------------------------------------------------------------- * FUNCTION NAME: MEM_CopyDMToDM * * DESCRIPTION * Copy buffer from generic Data memory to generic Data memory (32bit words) * * INPUT ARGUMENTS: * Data Memory Start Address (source) * Data Memory Start Address (destination) * Number of 32bit words to be copied * * OUTPUT ARGUMENTS: * None * * RETURNED VALUE: * None * * PSEUDOCODE * Copy source buffer to destination buffer *---------------------------------------------------------------------- $#$ */ T_VOID MEM_CopyDMToDM(T_UNSIGNED_32 DMSourceStartAddress, T_UNSIGNED_32 DMDestinationStartAddress, T_UNSIGNED_32 NumberOf32bitWords) { T_UNSIGNED_32 *DMSourceBuffer; T_UNSIGNED_32 *DMDestinationBuffer; T_UNSIGNED_32 Index=0; DMSourceBuffer=(T_UNSIGNED_32 *)DMSourceStartAddress; DMDestinationBuffer=(T_UNSIGNED_32 *)DMDestinationStartAddress; for(Index=0;Index> 16) with 16MSB masked * Write P1 * Is C the last 16bit word to copy? then exit loop * Step "D": * PMS2=AuxVar << 16 * Is D the last 16bit word to copy? then write P2, exit loop * Step "E": * AuxVar=D3, PMS2=PMS2 OR ((AuxVar >> 16) with 16MSB masked) * Is E the last 16bit word to copy? then write P2, exit loop * Step "F": * PLS2=AuxVar with 16MSbits Masked * Write PM2 * Actualize Counter and addresses for next loop iteration * *---------------------------------------------------------------------- $#$ */ T_VOID MEM_CopyDMToPM(T_UNSIGNED_32 DMStartAddress, T_UNSIGNED_32 PMStartAddress, T_UNSIGNED_32 NumberOf16bitWords) { T_UNSIGNED_32 DMAddress; /* Source */ T_UNSIGNED_32 PMAddress; /* Destination */ T_UNSIGNED_32 CounterOf16bitWords=0; T_UNSIGNED_32 PMData32MSbits_1=0; T_UNSIGNED_32 PMData16LSbits_1=0; T_UNSIGNED_32 PMData32MSbits_2=0; T_UNSIGNED_32 PMData16LSbits_2=0; T_UNSIGNED_32 AuxVar=0; /* Used to avoid extra accesses to memory */ DMAddress=DMStartAddress; PMAddress=PMStartAddress; for EVER { if(CounterOf16bitWords>=NumberOf16bitWords) { break; } /* Step "A" */ PMData32MSbits_1=MEM_ReadDMWord(DMAddress); CounterOf16bitWords++; if(CounterOf16bitWords>=NumberOf16bitWords) { PMData32MSbits_1=PMData32MSbits_1 & K_MASK_LS16BITS; MEM_WritePMWord(PMAddress,PMData32MSbits_1,0); break; } /* Step "B" */ CounterOf16bitWords++; if(CounterOf16bitWords>=NumberOf16bitWords) { MEM_WritePMWord(PMAddress,PMData32MSbits_1,0); break; } /* Step "C" */ DMAddress++; AuxVar=MEM_ReadDMWord(DMAddress); PMData16LSbits_1=(AuxVar >> 16) & K_MASK_MS16BITS; MEM_WritePMWord(PMAddress,PMData32MSbits_1,PMData16LSbits_1); CounterOf16bitWords++; if(CounterOf16bitWords>=NumberOf16bitWords) { break; } /* Step "D" */ PMAddress++; PMData32MSbits_2=(AuxVar << 16); CounterOf16bitWords++; if(CounterOf16bitWords>=NumberOf16bitWords) { MEM_WritePMWord(PMAddress,PMData32MSbits_2,0); break; } /* Step "E" */ DMAddress++; AuxVar=MEM_ReadDMWord(DMAddress); PMData32MSbits_2=PMData32MSbits_2 | ((AuxVar >> 16) & K_MASK_MS16BITS); CounterOf16bitWords++; if(CounterOf16bitWords>=NumberOf16bitWords) { MEM_WritePMWord(PMAddress,PMData32MSbits_2,0); break; } /* Step "F" */ PMData16LSbits_2=AuxVar & K_MASK_MS16BITS; MEM_WritePMWord(PMAddress,PMData32MSbits_2,PMData16LSbits_2); CounterOf16bitWords++; DMAddress++; PMAddress++; } return; } /* #$# ----------------------------------------------------------------------- * FUNCTION NAME: MEM_CopyPMToDM * * DESCRIPTION * Copy buffer from generic Program memory (48bit words) to generic Data * memory (32bit words). Note that size is specified in number of 16bit words * * INPUT ARGUMENTS: * Program Memory Start Address (source) * Data Memory Start Address (destination) * Number of 16bit words to be copied * * OUTPUT ARGUMENTS: * None * * RETURNED VALUE: * None * * PSEUDOCODE * * Note: Copy will be performed according to the following format: * PROGRAM MEMORY DATA MEMORY * ABC (P1=PMS1/PLS1) A B (D1) * DEF (P2=PMS2/PLS2) C D (D2) * E F (D3) * * Note: Copy will be structured in steps: A, B, C, D, E and F, * A counter of the 16bit words written will be used * Auxiliar variables will be used to avoid extra accesses to memory * * Start writing loop * If nothing to copy then exit loop * Step "A": * D1=PMS1 * Is A the last 16bit word to copy? then mask 16LSbits of D1, write D1, exit loop * Step "B": * Write D1 * Is B the last 16bit word to copy? then exit loop * Step "C": * D2= PLS1 << 16 * Is C the last 16bit word to copy? then write D2, exit loop * Step "D": * AuxVar=PMS2, D2=D2 OR ((AuxVar >> 16) with 16MSB masked) * Write D2 * Is D the last 16bit word to copy? then exit loop * Step "E": * D3= AuxVar << 16 * Is E the last 16bit word to copy? write D3, exit loop * Step "F": * D3=D3 OR (PLS2 with 16MSbits masked) * Write D3 * Actualize Counter and addresses for next loop iteration *---------------------------------------------------------------------- $#$ */ T_VOID MEM_CopyPMToDM(T_UNSIGNED_32 PMStartAddress, T_UNSIGNED_32 DMStartAddress, T_UNSIGNED_32 NumberOf16bitWords) { T_UNSIGNED_32 PMAddress; /* Source */ T_UNSIGNED_32 DMAddress; /* Destination */ T_UNSIGNED_32 CounterOf16bitWords=0; T_UNSIGNED_32 DMData_1=0; T_UNSIGNED_32 DMData_2=0; T_UNSIGNED_32 DMData_3=0; T_UNSIGNED_32 AuxVar=0; /* Used to avoid extra accesses to memory */ PMAddress=PMStartAddress; DMAddress=DMStartAddress; for EVER { if(CounterOf16bitWords>=NumberOf16bitWords) { break; } /* Step "A" */ DMData_1=MEM_ReadPM32bitMSWord(PMAddress); CounterOf16bitWords++; if(CounterOf16bitWords>=NumberOf16bitWords) { DMData_1=DMData_1 & K_MASK_LS16BITS; MEM_WriteDMWord(DMAddress,DMData_1); break; } /* Step "B" */ MEM_WriteDMWord(DMAddress,DMData_1); CounterOf16bitWords++; if(CounterOf16bitWords>=NumberOf16bitWords) { break; } /* Step "C" */ DMData_2=MEM_ReadPM16bitLSWord(PMAddress) << 16; DMAddress++; CounterOf16bitWords++; if(CounterOf16bitWords>=NumberOf16bitWords) { MEM_WriteDMWord(DMAddress,DMData_2); break; } /* Step "D" */ PMAddress++; AuxVar=MEM_ReadPM32bitMSWord(PMAddress); DMData_2=DMData_2 | ((AuxVar >> 16) & K_MASK_MS16BITS); MEM_WriteDMWord(DMAddress,DMData_2); CounterOf16bitWords++; if(CounterOf16bitWords>=NumberOf16bitWords) { break; } /* Step "E" */ DMData_3= AuxVar << 16; DMAddress++; CounterOf16bitWords++; if(CounterOf16bitWords>=NumberOf16bitWords) { MEM_WriteDMWord(DMAddress,DMData_3); break; } /* Step "F" */ DMData_3= DMData_3 | (MEM_ReadPM16bitLSWord(PMAddress) & K_MASK_MS16BITS); MEM_WriteDMWord(DMAddress,DMData_3); CounterOf16bitWords++; PMAddress++; DMAddress++; } return; } /* #$# ----------------------------------------------------------------------- * FUNCTION NAME: MEM_WriteBitInDMWord * * DESCRIPTION * Set specified bit of specified DM Address to specified value (0=low, 1=high), * keeping the value of the other bits * * INPUT ARGUMENTS: * DM Address * Bit position * Bit value (high/low) * * OUTPUT ARGUMENTS: * None * * RETURNED VALUE: * None * * PSEUDOCODE * Read DM address * Calculate mask by left-shifting 0x1 by BitPosition * If BitValue is High then * New word = old word OR Mask * Else (BitValue is Low) * New word = old word AND ~Mask * Write new word value to DM address *---------------------------------------------------------------------- $#$ */ T_VOID MEM_WriteBitInDMWord(T_UNSIGNED_32 DMAddress, T_UNSIGNED_32 BitPosition, T_UNSIGNED_32 BitValue) { T_UNSIGNED_32 OldDMWord=0; T_UNSIGNED_32 NewDMWord=0; T_UNSIGNED_32 Mask=0; /* Read DM Word */ OldDMWord=MEM_ReadDMWord(DMAddress); /* Calculate mask */ Mask=0x1 << BitPosition; /* Set bit */ if (BitValue==K_HIGH) { /* Set bit to 1 */ NewDMWord=OldDMWord | Mask; } else { /* BitValue = LOW */ /* Set bit to 0 */ NewDMWord=OldDMWord & (~Mask); } /* Write new PM word */ MEM_WriteDMWord(DMAddress,NewDMWord); return; } /* #$# ----------------------------------------------------------------------- * FUNCTION NAME: MEM_WriteBitInPM32bitMSWord * * DESCRIPTION * Set specified bit of specified PM Address-32bitMSWord to specified * value (0=low, 1=high), keeping the value of the other bits * * INPUT ARGUMENTS: * PM Address * Bit position (within MSWord, i.e. bit 16 in full 48bit PM word must be * specified as bit 0) * Bit value (high/low) * * OUTPUT ARGUMENTS: * None * * RETURNED VALUE: * None * * PSEUDOCODE * Read PM Address * Calculate mask by left-shifting 0x1 by BitPosition * If BitValue is High then * New word = old word OR Mask * Else (BitValue is Low) * New word = old word AND ~Mask * Write new word value to PM address *---------------------------------------------------------------------- $#$ */ T_VOID MEM_WriteBitInPM32bitMSWord(T_UNSIGNED_32 PMAddress, T_UNSIGNED_32 BitPosition, T_UNSIGNED_32 BitValue) { T_UNSIGNED_32 OldPM32bitMSWord=0; T_UNSIGNED_32 NewPM32bitMSWord=0; T_UNSIGNED_16 PM16bitLSWord=0; T_UNSIGNED_32 Mask=0; /* Read PM Word */ OldPM32bitMSWord=MEM_ReadPM32bitMSWord(PMAddress); PM16bitLSWord=MEM_ReadPM16bitLSWord(PMAddress); /* Calculate mask */ Mask=0x1 << BitPosition; /* Set bit */ if (BitValue==K_HIGH) { /* Set bit to 1 */ NewPM32bitMSWord=OldPM32bitMSWord | Mask; } else { /* BitValue = LOW */ /* Set bit to 0 */ NewPM32bitMSWord=OldPM32bitMSWord & (~Mask); } /* Write new PM word */ MEM_WritePMWord(PMAddress,NewPM32bitMSWord,PM16bitLSWord); return; } /* #$# ----------------------------------------------------------------------- * FUNCTION NAME: MEM_CheckBitInDMWord * * DESCRIPTION * Check if specified bit in provided DM Address is 1 (returning K_TRUE) * or 0 (returning K_FALSE) * * INPUT ARGUMENTS: * DM Address * Bit position * * OUTPUT ARGUMENTS: * None * * RETURNED VALUE: * Result (True/False) * * PSEUDOCODE * Read DM address * Calculate mask by left-shifting 0x1 by BitPosition * Check bit, using the value (Word & Mask) * Return result, K_TRUE if bit=1, K_FALSE if bit=0 *---------------------------------------------------------------------- $#$ */ T_BOOLEAN MEM_CheckBitInDMWord(T_UNSIGNED_32 DMAddress, T_UNSIGNED_32 BitPosition) { T_UNSIGNED_32 DMWord=0; T_UNSIGNED_32 Mask=0; T_BOOLEAN CheckResult=K_TRUE; /* Read DM Word */ DMWord=MEM_ReadDMWord(DMAddress); /* Calculate mask and check bit */ Mask=0x1 << BitPosition; DMWord=DMWord & Mask; if (DMWord==0) { CheckResult=K_FALSE; } return(CheckResult); } /* #$# ----------------------------------------------------------------------- * FUNCTION NAME: MEM_CheckBitInPM32bitMSWord * * DESCRIPTION * Check if specified bit of 32bitMSWord in provided PM Address is 1 (returning * K_TRUE) or 0 (returning K_FALSE) * * INPUT ARGUMENTS: * DM Address * Bit position (within MSWord, i.e. bit 16 in full 48bit PM word must be * specified as bit 0) * * OUTPUT ARGUMENTS: * None * * RETURNED VALUE: * Result (True/False) * * PSEUDOCODE * Read PM address * Calculate mask by left-shifting 0x1 by BitPosition * Check bit, using the value (Word & Mask) * Return result, K_TRUE if bit=1, K_FALSE if bit=0 *---------------------------------------------------------------------- $#$ */ T_BOOLEAN MEM_CheckBitInPM32bitMSWord(T_UNSIGNED_32 PMAddress, T_UNSIGNED_32 BitPosition) { T_UNSIGNED_32 PM32bitMSWord=0; T_UNSIGNED_32 Mask=0; T_BOOLEAN CheckResult=K_TRUE; /* Read PM Word */ PM32bitMSWord=MEM_ReadPM32bitMSWord(PMAddress); /* Calculate mask and check bit */ Mask=0x1 << BitPosition; PM32bitMSWord=PM32bitMSWord & Mask; if (PM32bitMSWord==0) { CheckResult=K_FALSE; } return(CheckResult); } /* #$# ----------------------------------------------------------------------- * FUNCTION NAME: MEM_IdentifyPRAMOrEEPROMAddress * * DESCRIPTION * Identify if a given PM address is PRAM or EEPROM * * INPUT ARGUMENTS: * Hardware Unit (REBA/SPU, REBA/DPU, PACS/SPU) * PMAddress * * OUTPUT ARGUMENTS: * PRAM or EEPROM flag * * RETURNED VALUE: * Status Return * * PSEUDOCODE * StatusReturn=OK * Isolate bits 20:16 of the first and last addresses for PRAM and * EEPROM, by Right-shift and mask first and last memory addresses * (use constants defined in l_memory.h) for PRAM and EEPROM. * Isolate bits 20:16 of PM address by right-shifting and masking * If "Isolated bits" of PMAddress are within PRAM "isolated" limits then * flag=PRAM * else * If Unit=REBA/SPU then * StatusReturn= error (REBA/SPU has not EEPROM) * else (Unit is REBA/DPU or PACS/SPU) * If "Isolated bits" of PMAddress are within EEPROM "isolated" * limits then * flag=EEPROM * else * StatusReturn= error * Return StatusReturn * * Note: The use of just bits 20:16 allows the use of this function with * the APSW memory map and the SUSW memory map. *---------------------------------------------------------------------- $#$ */ T_SR MEM_IdentifyPRAMOrEEPROMAddress(T_UNSIGNED_32 HardwareUnitID, T_UNSIGNED_32 PMAddress, T_UNSIGNED_32 *MemoryAreaIDPRAMOrEEPROM) { T_UNSIGNED_32 SelectedBitsOfAddress=0; T_UNSIGNED_32 SelectedBitsOfPRAMLowerLimit=0; T_UNSIGNED_32 SelectedBitsOfPRAMUpperLimit=0; T_UNSIGNED_32 SelectedBitsOfEEPROMLowerLimit=0; T_UNSIGNED_32 SelectedBitsOfEEPROMUpperLimit=0; T_SR StatusReturn=K_SR_OK; /* Isolate bits 20:16 of the first and last addresses for PRAM and EEPROM */ SelectedBitsOfPRAMLowerLimit=(K_PMADDR_BASE_PRAM >> K_BPOS_PRAM_EEPROM_IDENTIFIC)&K_MASK_PRAM_EEPROM_IDENTIFIC; SelectedBitsOfPRAMUpperLimit=((K_PMADDR_LAST_PRAM) >> K_BPOS_PRAM_EEPROM_IDENTIFIC)&K_MASK_PRAM_EEPROM_IDENTIFIC; SelectedBitsOfEEPROMLowerLimit=(K_PMADDR_BASE_EEPROM >> K_BPOS_PRAM_EEPROM_IDENTIFIC)&K_MASK_PRAM_EEPROM_IDENTIFIC; SelectedBitsOfEEPROMUpperLimit=((K_PMADDR_LAST_EEPROM) >> K_BPOS_PRAM_EEPROM_IDENTIFIC)&K_MASK_PRAM_EEPROM_IDENTIFIC; /* Isolate bits 20:16 of PM address by right-shifting and masking */ SelectedBitsOfAddress=(PMAddress >> K_BPOS_PRAM_EEPROM_IDENTIFIC)& K_MASK_PRAM_EEPROM_IDENTIFIC; /* If PMAddress is PRAM */ if((SelectedBitsOfAddress>=SelectedBitsOfPRAMLowerLimit)&& (SelectedBitsOfAddress<=SelectedBitsOfPRAMUpperLimit)) { (*MemoryAreaIDPRAMOrEEPROM)=K_MEMAREAID_PROGRAM_RAM; } else { /* PMAddress is not PRAM */ if(HardwareUnitID==K_HWUNITID_REBA_SPU) { StatusReturn=K_SR_ERROR; } else { /* HW Unit is REBA/DPU or PACS/SPU */ if((SelectedBitsOfAddress>=SelectedBitsOfEEPROMLowerLimit)&& (SelectedBitsOfAddress<=SelectedBitsOfEEPROMUpperLimit)) { (*MemoryAreaIDPRAMOrEEPROM)=K_MEMAREAID_EEPROM; } else { /* PMAddress is not EEPROM */ StatusReturn=K_SR_ERROR; } } } return(StatusReturn); }