]> rtime.felk.cvut.cz Git - arc.git/blobdiff - memory/NvM/NvM.c
Correction to non-aligned IO read/write.
[arc.git] / memory / NvM / NvM.c
index 6afebef47be752209fd25ecbc0beacfc816dfbae..51876f24928f66687b8ee20e29d43b55be657230 100644 (file)
  *     ID. The NVM_COMPILED_CONFIG_ID is always generated as 0 now.\r
  *   - You can ONLY configure one block type for the entire NvM since NvmNvramDeviceId is not supported.\r
  *     ie "Target Block" must all be eihter FEE or EA blocks.\r
+ *   - Differences from 3.1.5 Release (Follow release 4.0.2 here)\r
+ *     NvM_SetDataIndex(), NvM_GetDataIndex, NvM_SetBlockProtection, NvM_GetErrorStatus, NvM_SetRamBlockStatus,\r
+ *     etc....all return Std_ReturnType instead of void since the RTE expects it.\r
+ *   - NvM_GetErrorStatus() uses NvM_GetErrorStatus instead of uint8 *\r
  */\r
 \r
 /*\r
 #include "io.h"\r
 #include "Crc.h"\r
 #include <string.h>\r
+#include "Cpu.h"\r
 \r
 #define FIXME          0\r
 \r
 #define NVM_ASSERT(_exp)               if( !(_exp) ) { while(1) {}; } //assert(_exp)\r
 #endif\r
 \r
+\r
+#if  ( NVM_DEV_ERROR_DETECT == STD_ON )\r
+#define DET_REPORT_ERROR( _api, _err) Det_ReportError(MODULE_ID_NVM, 0, _api, _err);\r
+#else\r
+#define DET_REPORT_ERROR( _api, _err)\r
+#endif\r
+\r
 #if  ( NVM_DEV_ERROR_DETECT == STD_ON )\r
 #include "Det.h"\r
 #define VALIDATE(_exp,_api,_err ) \\r
@@ -707,7 +719,7 @@ static void DriveBlock( const NvM_BlockDescriptorType       *bPtr,
                        memcpy( Nvm_WorkBuffer, ramData, bPtr->NvBlockLength );\r
                        /* Add the CRC to write */\r
                        writeCrcToBuffer(Nvm_WorkBuffer, bPtr, admPtr );\r
-                       WriteBlock(bPtr, admPtr, 0, Nvm_WorkBuffer);\r
+                       WriteBlock(bPtr, admPtr, admPtr->DataIndex, Nvm_WorkBuffer);\r
                } else {\r
                        uint8 crcLen = 0;\r
                        /* Read to workbuffer */\r
@@ -796,7 +808,10 @@ static void DriveBlock( const NvM_BlockDescriptorType      *bPtr,
                                        /* 3.1.5/NVM201 + 3.1.5/NVM292 NvM_ReadBlock() + NvM_ReadAll() should request\r
                                         * recalculation of the RAM block data if configured with CRC.\r
                                         */\r
-                                       memcpy(admPtr->savedDataPtr, Nvm_WorkBuffer, bPtr->NvBlockLength  + crcLen );\r
+\r
+                                       /* savedDataPtr points to the real data buffers and they do no contain the\r
+                                        * crcLen */\r
+                                       memcpy(admPtr->savedDataPtr, Nvm_WorkBuffer, bPtr->NvBlockLength  );\r
 \r
                                        /* Check if we should re-calculate the RAM checksum now when it's in RAM\r
                                         * 3.1.5/NVM165 */\r
@@ -877,12 +892,22 @@ static void DriveBlock( const NvM_BlockDescriptorType     *bPtr,
        {\r
                uint16 crc16;\r
                uint32 crc32;\r
-               NVM_ASSERT(bPtr->RamBlockDataAddress != NULL );\r
+               void *ramData;\r
+\r
+               if( bPtr->RamBlockDataAddress == NULL ) {\r
+                       /* If we have no buffer to work with something is very very wrong */\r
+                       NVM_ASSERT(dataPtr != NULL );\r
+                       ramData = dataPtr;\r
+               } else {\r
+                       ramData = bPtr->RamBlockDataAddress;\r
+               }\r
+\r
+               admPtr->savedDataPtr = ramData;\r
 \r
                /* Calculate RAM CRC checksum */\r
                if( bPtr->BlockCRCType == NVM_CRC16 ) {\r
 \r
-                       crc16 = Crc_CalculateCRC16(bPtr->RamBlockDataAddress,bPtr->NvBlockLength,0xffff);\r
+                       crc16 = Crc_CalculateCRC16(ramData,bPtr->NvBlockLength,0xffff);\r
                        DEBUG_CHECKSUM("RAM",crc16);\r
 \r
                        /* Just save the checksum */\r
@@ -892,7 +917,7 @@ static void DriveBlock( const NvM_BlockDescriptorType       *bPtr,
                        admPtr->BlockState = BLOCK_STATE_MEMIF_REQ;\r
                } else {\r
                        /* @req 3.1.5/NVM253 */\r
-                       crc32 = Crc_CalculateCRC32(bPtr->RamBlockDataAddress,bPtr->NvBlockLength,0xffffffffUL);\r
+                       crc32 = Crc_CalculateCRC32(ramData,bPtr->NvBlockLength,0xffffffffUL);\r
                        DEBUG_CHECKSUM("RAM",crc32);\r
 \r
                        admPtr->RamCrc.crc32 = crc32;\r
@@ -904,7 +929,7 @@ static void DriveBlock( const NvM_BlockDescriptorType       *bPtr,
        }\r
        case BLOCK_STATE_CALC_CRC_READ:\r
        {\r
-               NVM_ASSERT(bPtr->RamBlockDataAddress != NULL );\r
+               //NVM_ASSERT(bPtr->RamBlockDataAddress != NULL );\r
                NVM_ASSERT(bPtr->CalcRamBlockCrc == true );\r
                uint16 crc16;\r
                uint32 crc32;\r
@@ -915,9 +940,9 @@ static void DriveBlock( const NvM_BlockDescriptorType       *bPtr,
                /* Calculate CRC on the data we just read to RAM. Compare with CRC that is located in NV block */\r
 \r
                if( bPtr->BlockCRCType == NVM_CRC16 ) {\r
-                       crc16 = Crc_CalculateCRC16(bPtr->RamBlockDataAddress,bPtr->NvBlockLength,0xffff);\r
+                       crc16 = Crc_CalculateCRC16(admPtr->savedDataPtr,bPtr->NvBlockLength,0xffff);\r
                } else {\r
-                       crc32 = Crc_CalculateCRC32(bPtr->RamBlockDataAddress,bPtr->NvBlockLength,0xffffffffUL);\r
+                       crc32 = Crc_CalculateCRC32(admPtr->savedDataPtr,bPtr->NvBlockLength,0xffffffffUL);\r
                }\r
 \r
                switch( admPtr->BlockSubState ) {\r
@@ -1273,18 +1298,23 @@ void NvM_Init(void)
 }\r
 \r
 \r
-/*\r
- * Procedure:  NvM_ReadAll\r
- * Reentrant:  No\r
+/**\r
+ *\r
+ * Note!\r
+ *   NvM_ReadAll() does not set status here or need to check status of the\r
+ *   any blocks since it's done after all single reads are done.\r
  */\r
 void NvM_ReadAll(void)\r
 {\r
+    imask_t state;\r
        VALIDATE_NO_RV(nvmState != NVM_UNINITIALIZED, NVM_READ_ALL_ID, NVM_E_NOT_INITIALIZED);\r
 \r
        NVM_ASSERT(nvmState == NVM_IDLE);\r
 \r
+       Irq_Save(state);\r
        AdminMultiReq.state = NVM_READ_ALL;\r
        AdminMultiBlock.ErrorStatus = NVM_REQ_PENDING;\r
+       Irq_Restore(state);\r
 }\r
 \r
 \r
@@ -1295,12 +1325,15 @@ void NvM_ReadAll(void)
  */\r
 void NvM_WriteAll(void)\r
 {\r
+    imask_t state;\r
        VALIDATE_NO_RV(nvmState != NVM_UNINITIALIZED, NVM_READ_ALL_ID, NVM_E_NOT_INITIALIZED);\r
 \r
        NVM_ASSERT(nvmState == NVM_IDLE);\r
 \r
+       Irq_Save(state);\r
        AdminMultiReq.state = NVM_WRITE_ALL;\r
        AdminMultiBlock.ErrorStatus = NVM_REQ_PENDING;\r
+       Irq_Restore(state);\r
 }\r
 \r
 \r
@@ -1318,21 +1351,21 @@ void NvM_CancelWriteAll(void)
  * Procedure:  NvM_GetErrorStatus\r
  * Reentrant:  Yes\r
  */\r
-void NvM_GetErrorStatus(NvM_BlockIdType blockId, uint8 *requestResultPtr)\r
+Std_ReturnType NvM_GetErrorStatus(NvM_BlockIdType blockId, uint8 *requestResultPtr)\r
 {\r
-       VALIDATE_NO_RV(nvmState != NVM_UNINITIALIZED, NVM_GET_ERROR_STATUS_ID, NVM_E_NOT_INITIALIZED);\r
-       VALIDATE_NO_RV(blockId < NVM_NUM_OF_NVRAM_BLOCKS+1, NVM_GET_ERROR_STATUS_ID, NVM_E_PARAM_BLOCK_ID);\r
+       VALIDATE_RV(nvmState != NVM_UNINITIALIZED, NVM_GET_ERROR_STATUS_ID, NVM_E_NOT_INITIALIZED, E_NOT_OK );\r
+       VALIDATE_RV(blockId < NVM_NUM_OF_NVRAM_BLOCKS+1, NVM_GET_ERROR_STATUS_ID, NVM_E_PARAM_BLOCK_ID, E_NOT_OK );\r
 \r
        if (blockId == 0) {\r
                // Multiblock ID\r
                *requestResultPtr = AdminMultiBlock.ErrorStatus;\r
        } else if (blockId == 1) {\r
-               /* TODO */\r
+               /* TODO Configuration ID */\r
          *requestResultPtr = NVM_REQ_OK;\r
        } else {\r
                *requestResultPtr = AdminBlock[blockId-1].ErrorStatus;\r
        }\r
-\r
+       return E_OK;\r
 }\r
 \r
 \r
@@ -1341,20 +1374,21 @@ void NvM_GetErrorStatus(NvM_BlockIdType blockId, uint8 *requestResultPtr)
  * Procedure:  Nvm_SetRamBlockStatus\r
  * Reentrant:  Yes\r
  */\r
-void NvM_SetRamBlockStatus(NvM_BlockIdType blockId, boolean blockChanged)\r
+Std_ReturnType NvM_SetRamBlockStatus(NvM_BlockIdType blockId, boolean blockChanged)\r
 {\r
        const NvM_BlockDescriptorType * bPtr;\r
        AdministrativeBlockType *               admPtr;\r
        Nvm_QueueType qEntry;\r
        int rv;\r
 \r
-       VALIDATE_NO_RV(blockId < NVM_NUM_OF_NVRAM_BLOCKS+1, NVM_SET_RAM_BLOCK_STATUS_ID, NVM_E_PARAM_BLOCK_ID);\r
+       VALIDATE_RV(blockId < NVM_NUM_OF_NVRAM_BLOCKS+1, NVM_SET_RAM_BLOCK_STATUS_ID, NVM_E_PARAM_BLOCK_ID, E_NOT_OK);\r
 \r
        bPtr = &NvM_Config.BlockDescriptor[blockId-1];\r
        admPtr = &AdminBlock[blockId-1];\r
 \r
-       VALIDATE_NO_RV(nvmState != NVM_UNINITIALIZED, NVM_SET_RAM_BLOCK_STATUS_ID, NVM_E_NOT_INITIALIZED);      /** @req NVM497 */\r
-       VALIDATE_NO_RV(blockId > 1, NVM_SET_RAM_BLOCK_STATUS_ID, NVM_E_PARAM_BLOCK_ID);\r
+       VALIDATE_RV(nvmState != NVM_UNINITIALIZED, NVM_SET_RAM_BLOCK_STATUS_ID, NVM_E_NOT_INITIALIZED, E_NOT_OK);       /** @req NVM497 */\r
+       VALIDATE_RV(blockId > 1, NVM_SET_RAM_BLOCK_STATUS_ID, NVM_E_PARAM_BLOCK_ID, E_NOT_OK );\r
+       VALIDATE_RV( (admPtr->ErrorStatus != NVM_REQ_PENDING), 0, NVM_E_BLOCK_PENDING , E_NOT_OK );\r
 \r
        qEntry.blockId = blockId;\r
        qEntry.op = NVM_SETRAMBLOCKSTATUS;\r
@@ -1364,6 +1398,8 @@ void NvM_SetRamBlockStatus(NvM_BlockIdType blockId, boolean blockChanged)
 \r
        /* req 3.1.5/NVM185 */\r
        admPtr->ErrorStatus = NVM_REQ_PENDING;\r
+\r
+       return E_OK;\r
 }\r
 #endif\r
 \r
@@ -1416,12 +1452,12 @@ Std_ReturnType NvM_RestoreBlockDefaults( NvM_BlockIdType blockId, uint8* NvM_Des
        bPtr = &NvM_Config.BlockDescriptor[blockId-1];\r
        admPtr = &AdminBlock[blockId-1];\r
 \r
-       /** @req 3.1.5/NVM196 */ /** @req 3.1.5/NVM278 */\r
-       if( (NvM_DestPtr == NULL) &&  ( bPtr->RamBlockDataAddress == NULL ) ) {\r
-               /* It must be a permanent RAM block but no RamBlockDataAddress -> error */\r
-               NVM_ASSERT(0);          // TODO: See NVM210, DET error\r
-               return E_NOT_OK;\r
-       }\r
+       /** @req 3.1.5/NVM196 */ /** @req 3.1.5/NVM278 */ /** @req 3.1.5/NVM210 */\r
+       /* It must be a permanent RAM block but no RamBlockDataAddress -> error */\r
+       VALIDATE_RV( !((NvM_DestPtr == NULL) &&  ( bPtr->RamBlockDataAddress == NULL )),\r
+                                               NVM_WRITE_BLOCK_ID,NVM_E_PARAM_BLOCK_ID,E_NOT_OK );\r
+\r
+       VALIDATE_RV( (admPtr->ErrorStatus != NVM_REQ_PENDING), 0, NVM_E_BLOCK_PENDING , E_NOT_OK );\r
 \r
        /* @req 3.1.5/NVM195 */\r
        qEntry.blockId = blockId;\r
@@ -1431,9 +1467,6 @@ Std_ReturnType NvM_RestoreBlockDefaults( NvM_BlockIdType blockId, uint8* NvM_Des
        rv = CirqBuffPush(&nvmQueue,&qEntry);\r
        NVM_ASSERT(rv == 0 );\r
 \r
-       /* @req 3.1.5/NVM620 */\r
-       VALIDATE_RV( (admPtr->ErrorStatus != NVM_REQ_PENDING), 0, NVM_E_BLOCK_PENDING , E_NOT_OK );\r
-\r
        /* req 3.1.5/NVM185 */\r
        admPtr->ErrorStatus = NVM_REQ_PENDING;\r
 \r
@@ -1510,10 +1543,10 @@ Std_ReturnType NvM_ReadBlock( NvM_BlockIdType blockId, uint8* NvM_DstPtr )
        int rv;\r
 \r
        /** @req 3.1.5/NVM196 */ /** @req 3.1.5/NVM278 */\r
-       if( (NvM_DstPtr == NULL) &&  ( NvM_Config.BlockDescriptor[blockId-1].RamBlockDataAddress == NULL ) ) {\r
-               /* It must be a permanent RAM block but no RamBlockDataAddress -> error */\r
-               return E_NOT_OK;\r
-       }\r
+    VALIDATE_RV( !(( NvM_DstPtr == NULL) &&\r
+                       ( NvM_Config.BlockDescriptor[blockId-1].RamBlockDataAddress == NULL )),\r
+                       0, NVM_E_PARAM_ADDRESS  , E_NOT_OK );\r
+       VALIDATE_RV( (AdminBlock[blockId-1].ErrorStatus != NVM_REQ_PENDING), 0, NVM_E_BLOCK_PENDING , E_NOT_OK );\r
 \r
        /* @req 3.1.5/NVM195 */\r
        qEntry.blockId = blockId;\r
@@ -1523,8 +1556,6 @@ Std_ReturnType NvM_ReadBlock( NvM_BlockIdType blockId, uint8* NvM_DstPtr )
        rv = CirqBuffPush(&nvmQueue,&qEntry);\r
        NVM_ASSERT(rv == 0 );\r
 \r
-       /* @req 3.1.5/NVM615 */\r
-       VALIDATE_RV( (AdminBlock[blockId-1].ErrorStatus != NVM_REQ_PENDING), 0, NVM_E_BLOCK_PENDING , E_NOT_OK );\r
 \r
        /* req 3.1.5/NVM185 */\r
        AdminBlock[blockId-1].ErrorStatus = NVM_REQ_PENDING;\r
@@ -1557,11 +1588,9 @@ Std_ReturnType NvM_WriteBlock( NvM_BlockIdType blockId, const uint8* NvM_SrcPtr
        admPtr = &AdminBlock[blockId-1];\r
 \r
        /** @req 3.1.5/NVM196 */ /** @req 3.1.5/NVM278 */\r
-       if( (NvM_SrcPtr == NULL) &&  ( bPtr->RamBlockDataAddress == NULL ) ) {\r
-               /* It must be a permanent RAM block but no RamBlockDataAddress -> error */\r
-               NVM_ASSERT(0);          // TODO: See NVM210, DET error\r
-               return E_NOT_OK;\r
-       }\r
+       VALIDATE_RV( !((NvM_SrcPtr == NULL) && ( bPtr->RamBlockDataAddress == NULL )),\r
+                               0, NVM_E_PARAM_ADDRESS, E_NOT_OK );\r
+       VALIDATE_RV( (admPtr->ErrorStatus != NVM_REQ_PENDING), 0, NVM_E_BLOCK_PENDING , E_NOT_OK );\r
 \r
        /* @req 3.1.5/NVM195 */\r
        qEntry.blockId = blockId;\r
@@ -1571,9 +1600,6 @@ Std_ReturnType NvM_WriteBlock( NvM_BlockIdType blockId, const uint8* NvM_SrcPtr
        rv = CirqBuffPush(&nvmQueue,&qEntry);\r
        NVM_ASSERT(rv == 0 );\r
 \r
-       /* @req 3.1.5/NVM620 */\r
-       VALIDATE_RV( (admPtr->ErrorStatus != NVM_REQ_PENDING), 0, NVM_E_BLOCK_PENDING , E_NOT_OK );\r
-\r
        /* req 3.1.5/NVM185 */\r
        admPtr->ErrorStatus = NVM_REQ_PENDING;\r
 \r
@@ -1606,7 +1632,7 @@ Std_ReturnType NvM_WriteBlock( NvM_BlockIdType blockId, const uint8* NvM_SrcPtr
  *   x NVM_E_PARAM_BLOCK_ID\r
  *\r
  */\r
-void NvM_SetDataIndex( NvM_BlockIdType blockId, uint8 dataIndex ) {\r
+Std_ReturnType NvM_SetDataIndex( NvM_BlockIdType blockId, uint8 dataIndex ) {\r
 #if  ( NVM_DEV_ERROR_DETECT == STD_ON )\r
        const NvM_BlockDescriptorType * bPtr = &NvM_Config.BlockDescriptor[blockId-1];\r
        AdministrativeBlockType *               admPtr = &AdminBlock[blockId-1];\r
@@ -1616,11 +1642,11 @@ void NvM_SetDataIndex( NvM_BlockIdType blockId, uint8 dataIndex ) {
 \r
        NVM_ASSERT( blockId >= 2 );     /* No support for lower numbers, yet */\r
 \r
-       VALIDATE_NO_RV(nvmState != NVM_UNINITIALIZED, NVM_SET_DATA_INDEX_ID, NVM_E_NOT_INITIALIZED);\r
-       VALIDATE_NO_RV(blockId < NVM_NUM_OF_NVRAM_BLOCKS+1, NVM_SET_DATA_INDEX_ID, NVM_E_PARAM_BLOCK_ID);\r
-       VALIDATE_NO_RV(bPtr->BlockManagementType != NVM_BLOCK_NATIVE ,  NVM_SET_DATA_INDEX_ID, NVM_E_PARAM_BLOCK_TYPE );\r
-       VALIDATE_NO_RV(dataIndex < bPtr->NvBlockNum + bPtr->RomBlockNum , NVM_SET_DATA_INDEX_ID, NVM_E_PARAM_BLOCK_DATA_IDX );\r
-       VALIDATE_NO_RV( (admPtr->ErrorStatus != NVM_REQ_PENDING), NVM_SET_DATA_INDEX_ID, NVM_E_BLOCK_PENDING );\r
+       VALIDATE_RV(nvmState != NVM_UNINITIALIZED, NVM_SET_DATA_INDEX_ID, NVM_E_NOT_INITIALIZED, E_NOT_OK);\r
+       VALIDATE_RV(blockId < NVM_NUM_OF_NVRAM_BLOCKS+1, NVM_SET_DATA_INDEX_ID, NVM_E_PARAM_BLOCK_ID, E_NOT_OK);\r
+       VALIDATE_RV(bPtr->BlockManagementType != NVM_BLOCK_NATIVE ,  NVM_SET_DATA_INDEX_ID, NVM_E_PARAM_BLOCK_TYPE , E_NOT_OK);\r
+       VALIDATE_RV(dataIndex < bPtr->NvBlockNum + bPtr->RomBlockNum , NVM_SET_DATA_INDEX_ID, NVM_E_PARAM_BLOCK_DATA_IDX ,E_NOT_OK);\r
+       VALIDATE_RV( (admPtr->ErrorStatus != NVM_REQ_PENDING), NVM_SET_DATA_INDEX_ID, NVM_E_BLOCK_PENDING , E_NOT_OK);\r
 \r
        qEntry.blockId = blockId;\r
        qEntry.op = NVM_SETDATAINDEX;\r
@@ -1631,6 +1657,7 @@ void NvM_SetDataIndex( NvM_BlockIdType blockId, uint8 dataIndex ) {
 \r
        /* req 3.1.5/NVM185 */\r
        admPtr->ErrorStatus = NVM_REQ_PENDING;\r
+       return E_OK;\r
 }\r
 //#endif\r
 \r
@@ -1663,7 +1690,7 @@ void NvM_MainFunction(void)
                        DEBUG_PRINTF("### CRC On:%d Ram:%d Type:%d\n",nvmBlock->BlockUseCrc, nvmBlock->CalcRamBlockCrc, nvmBlock->BlockCRCType );\r
                        DEBUG_PRINTF("### RAM:%x ROM:%x\n", nvmBlock->RamBlockDataAddress, nvmBlock->RomBlockDataAdress );\r
                } else {\r
-                       /* Check multiblock req */\r
+                       /* Check multiblock req and do after all single block reads (3.1.5/NVM243) */\r
                        if( AdminMultiReq.state != NVM_UNINITIALIZED ) {\r
                                nvmState = AdminMultiReq.state ;\r
                                nvmSubState = 0;\r