Hi,
My customer reported "Unhandled fault: asynchronous external abort (0x1211)" when CPU executes strexd instruction.
The issue happens;
- On any boards.
- Whenever function SYS_ATOMIC_COMPARE_AND_SWAP64(pSrc, old_value, old_value, result); is executed.
- The above function accesses to MRAM mapped at 0x1600_0000 to 0x161F_4FFF (physical address).
- MRAM accesses with other functions are working fine.
- RT-Linux SDK is used (kernel version is 4.19).
Here is DBG log.
Thread 17 "BlkDrvUdp" received signal SIGBUS, Bus error. [Switching to Thread 0xb04fe460 (LWP 507)] 0x002fc384 in SysCpuReadInt64 (pResult=<optimized out>, pSrc=<optimized out>) at ../../../Components/SysCpuHandling/SysCpuHandling.c:340 340 ../../../Components/SysCpuHandling/SysCpuHandling.c: No such file or directory. (gdb) bt #0 0x002fc384 in SysCpuReadInt64 (pResult=<optimized out>, pSrc=<optimized out>) at ../../../Components/SysCpuHandling/SysCpuHandling.c:340 #1 SysCpuReadInt64 (pResult=<synthetic pointer>, pSrc=0xb1eb4018) at ../../../Components/SysCpuHandling/SysCpuHandling.c:309 #2 SysCpuReadValueAtomic (pSrc=pSrc@entry=0xb1eb4018, pDest=0xb04fcf98, nLen=<optimized out>) at ../../../Components/SysCpuHandling/SysCpuHandling.c:634 #3 0x0018d1a6 in ReadValueAtomic (pDst=pDst@entry=0xb04fcf98, pSrc=pSrc@entry=0xb1eb4018, nLen=8) at ../../../Components/CmpMonitor2/CmpMonitor2.c:640 #4 0x0018d29e in WriteReadValue (pData=0xb1eb4018 <error: Cannot access memory at address 0xb1eb4018>, pReadExp=0x0, pWriter=0xb04fd18c) at ../../../Components/CmpMonitor2/CmpMonitor2.c:702 #5 ExecuteReadExp (pApp=pApp@entry=0x420678 <s_StaticAppList+60>, pReadExp=pReadExp@entry=0xb04fd030, pWriter=pWriter@entry=0xb04fd18c) at ../../../Components/CmpMonitor2/CmpMonitor2.c:967 #6 0x0018d7e8 in ProcessReadExpList2 (pApp=<optimized out>, pWriter=0xb04fd18c, pReader=0xb04fd044) at ../../../Components/CmpMonitor2/CmpMonitor2.c:1030 #7 ProcessService (pduSendBuffer=..., pWriter=0xb04fd18c, pReader=0xb04fd044, pHeader=<optimized out>) at ../../../Components/CmpMonitor2/CmpMonitor2.c:1733 #8 Monitoring2ServiceHandler (ulChannelId=<optimized out>, pHeader=<optimized out>, pduData=..., pduSendBuffer=...) at ../../../Components/CmpMonitor2/CmpMonitor2.c:363 #9 0x002dba96 in ServerAppHandleRequest3 (ulChannelId=ulChannelId@entry=31296, pduRequest=..., pduReply=..., bFirstCall=1, bFirstCall@entry=1212875) at ../../../Components/CmpSrv/CmpSrv.c:612 #10 0x002d5682 in SecChServerHandleRequest (ui32ChannelHandle=ui32ChannelHandle@entry=31296, pduRequest=..., pduReply=..., bFirstCall=bFirstCall@entry=1) at ../../../Components/CmpSecureChannel/CmpSecureChannelServer.c:440 #11 0x001281ca in NetServerMessageReceived3 (pChBuffer=pChBuffer@entry=0xb490b010, pduData=..., bFirstCall=bFirstCall@entry=1) at ../../../Components/CmpChannelServer/CmpChannelServer.c:971 #12 0x0012736a in HandleL4DataPackage (pChBuffer=0xb490b010, nSize=256, pDataPkg=<optimized out>, addrSender=...) at ../../../Components/CmpChannelMgr/CmpChannelMgr.c:839 #13 HandleL4Data (byPkgType=<optimized out>, pduData=..., addrSender=...) at ../../../Components/CmpChannelMgr/CmpChannelMgr.c:937 #14 ChannelMgrHandleData (hRouter=hRouter@entry=0xb4a01718, hNetworkInterface=hNetworkInterface@entry=0xffff, byServiceId=<optimized out>, byMessageId=<optimized out>, addrSender=..., addrReceiver=..., pduData=..., nRouterError=0) at ../../../Components/CmpChannelMgr/CmpChannelMgr.c:1690 #15 0x002cd300 in HandleLocally (pRouter=pRouter@entry=0xb4a01718, pniSender=pniSender@entry=0xb4a01718, pnaSender=pnaSender@entry=0xb04fd9a0, pHeader=pHeader@entry=0xb04fda58, pduContent=..., addrSender=..., addrReceiver=...) at ../../../Components/CmpRouter/CmpRouter.c:785 #16 0x002cee38 in RoutePackage (pRouter=0xb4a01718, pNetworkSender=pNetworkSender@entry=0xb4a01718, addrReceiver=..., addrSender=..., naSender=..., pduData=..., nDataOffset=2, bUseQueue=-1263770880) at ../../../Components/CmpRouter/CmpRouter.c:1409 #17 0x002cf530 in RouterHandleData (hNetwork=<optimized out>, naSender=..., pduData=..., bIsBroadcast=bIsBroadcast@entry=0) at ../../../Components/CmpRouter/CmpRouter.c:2156 #18 0x000b7eba in UdpReceiveBlock (iDev=<optimized out>, iDev@entry=0, iCount=iCount@entry=2, pfdDataAvailable=pfdDataAvailable@entry=0xb04fdd14) at ../../../Components/CmpBlkDrvUdp/CmpBlkDrvUdp.c:563 #19 0x000b7f4a in UdpReceiveBlocks (pfdDataAvailable=pfdDataAvailable@entry=0xb04fdd14) at ../../../Components/CmpBlkDrvUdp/CmpBlkDrvUdp.c:583 #20 0x000b88f4 in CommunicationThread (ptp=0x51751c <s_StaticTaskList+3204>) at ../../../Components/CmpBlkDrvUdp/CmpBlkDrvUdp.c:393 #21 0x003137f8 in SysTaskFrame (pTask=0x517510 <s_StaticTaskList+3192>) at ../Sys/SysTaskLinux.c:439 #22 0xb4d5fb00 in start_thread (arg=0xaeeece45) at pthread_create.c:486 #23 0xb4cd42fc in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:73 from /lib/libc.so.6 Backtrace stopped: previous frame identical to this frame (corrupt stack?)
The SYS_ATOMIC_COMPARE_AND_SWAP64() is at line 340 in SysCpuHandling.c.
#include "CmpStd.h" #include "SysCpuHandlingDep.h" #include "CmpAppItf.h" /*#define SYSCPUHANDLING_MODULETEST*/ static RTS_HANDLE s_hRWLAtomicOperation = RTS_INVALID_HANDLE; USE_STMT #ifndef SYSCPU_EXTLIBCALL_GET_REGISTER_SAVE_AREA #define SYSCPU_EXTLIBCALL_GET_REGISTER_SAVE_AREA(sa) sa #endif /* ------------- Component Manager functions --------------- */ #ifdef CPLUSPLUS static CSysCpuHandling *s_pCSysCpuHandling = NULL; #endif #ifndef RTS_COMPACT_MICRO #ifdef SYSCPUHANDLING_MODULETEST static RTS_RESULT ModuleTest(void); #endif DLL_DECL int CDECL ComponentEntry(INIT_STRUCT *pInitStruct) /* Used to exchange function pointers between component manager and components. Called at startup for each component. pInitStruct: IN Pointer to structure with: pfExportFunctions OUT Pointer to function that exports component functions pfImportFunctions OUT Pointer to function that imports functions from other components pfGetVersion OUT Pointer to function to get component version pfRegisterAPI IN Pointer to component manager function to register a API function pfGetAPI IN Pointer to component manager function to get a API function pfCallHook IN Pointer to component manager function to call a hook function Return ERR_OK if library could be initialized, else error code */ { pInitStruct->CmpId = COMPONENT_ID; pInitStruct->pfExportFunctions = ExportFunctions; pInitStruct->pfImportFunctions = ImportFunctions; pInitStruct->pfGetVersion = CmpGetVersion; pInitStruct->pfHookFunction = HookFunction; pInitStruct->pfCreateInstance = CreateInstance; pInitStruct->pfDeleteInstance = DeleteInstance; SysCpuHandlingOSInit(pInitStruct); s_pfCMRegisterAPI = pInitStruct->pfCMRegisterAPI; s_pfCMRegisterAPI2 = pInitStruct->pfCMRegisterAPI2; s_pfCMGetAPI = pInitStruct->pfCMGetAPI; s_pfCMGetAPI2 = pInitStruct->pfCMGetAPI2; s_pfCMCallHook = pInitStruct->pfCMCallHook; s_pfCMRegisterClass = pInitStruct->pfCMRegisterClass; s_pfCMCreateInstance = pInitStruct->pfCMCreateInstance; #ifdef CPLUSPLUS INIT_LOCALS_STMT; s_pCSysCpuHandling = NULL; if (pInitStruct->pfCMRegisterClass != NULL) { RTS_HANDLE hClass = pInitStruct->pfCMRegisterClass(COMPONENT_ID, CLASSID_CSysCpuHandling); if (hClass == RTS_INVALID_HANDLE) return ERR_FAILED; } #endif return ERR_OK; } static IBase* CDECL CreateInstance(CLASSID cid, RTS_RESULT *pResult) { #ifdef CPLUSPLUS if (cid == CLASSID_CSysCpuHandling) { if (s_pCSysCpuHandling == NULL) s_pCSysCpuHandling = static_cast<CSysCpuHandling *>(new CSysCpuHandling()); return (IBase*)s_pCSysCpuHandling->QueryInterface(s_pCSysCpuHandling, ITFID_IBase, pResult); } #endif return NULL; } static RTS_RESULT CDECL DeleteInstance(IBase *pIBase) { #ifdef CPLUSPLUS if (pIBase->Release() == 0) s_pCSysCpuHandling = NULL; return ERR_OK; #else return ERR_NOTIMPLEMENTED; #endif } static int CDECL ExportFunctions() { EXPORT_STMT; return ERR_OK; } static int CDECL ImportFunctions() { unsigned char by = 0; IMPORT_STMT; /* If SysCpuTestAndSetBit() returns ERR_NOT_SUPPORTED, the used SysInt functions are not available, so stop loading this component */ if (SysCpuTestAndSetBit(&by, 1, 1, 1) == ERR_NOT_SUPPORTED) { if (CHK_LogAdd) { (void)CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_ERROR, ERR_FAILED, 0, "Import of ApiFunction <api>SysIntEnableAll</api> failed\n"); (void)CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_ERROR, ERR_FAILED, 0, "Import of ApiFunction <api>SysIntDisableAll</api> failed\n"); } return ERR_FAILED; } return ERR_OK; } static RTS_UI32 CDECL CmpGetVersion(void) { return CMP_VERSION; } #endif static RTS_RESULT CDECL HookFunction(RTS_UI32 ulHook, RTS_UINTPTR ulParam1, RTS_UINTPTR ulParam2) { RTS_RESULT Result = ERR_OK; switch (ulHook) { case CH_INIT2: { if (CHK_SysRWLCreate) { RTS_RESULT Res = ERR_FAILED; s_hRWLAtomicOperation = CAL_SysRWLCreate(&Res); if (Res != ERR_OK && CHK_LogAdd) (void)CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_ERROR, ERR_FAILED, 0, "Creating synchronization object for atomic 64bit access failed.\n"); } break; } case CH_COMM_CYCLE: { #ifdef RTS_COMPACT_MICRO return ERR_NO_COMM_CYCLE; #else #ifdef SYSCPUHANDLING_MODULETEST ModuleTest(); #endif break; #endif } case CH_EXIT_SYSTEM: { EXIT_STMT; break; } case CH_EXIT2: { if (CHK_SysRWLDelete && s_hRWLAtomicOperation != RTS_INVALID_HANDLE) { CAL_SysRWLDelete(s_hRWLAtomicOperation); s_hRWLAtomicOperation = RTS_INVALID_HANDLE; } break; } default: break; } if(Result == ERR_OK) return SysCpuHandlingOSHookFunction(ulHook, ulParam1, ulParam2); return Result; } RTS_RESULT CDECL SysCpuTestAndSetBitBase(void* pAddress, int nLen, int iBit, int bSet) { RTS_RESULT Result; SYSCPUTESTANDSETBIT_LOCK(pAddress, nLen, iBit, bSet, Result); return Result; } RTS_RESULT CDECL SysCpuTestAndSet(RTS_UI32* pul, int iBit) { RTS_RESULT Result = SysCpuTestAndSetBit(pul, 4, iBit, 1); if (Result == ERR_NOT_SUPPORTED) return ERR_OK; return Result; } RTS_RESULT CDECL SysCpuTestAndReset(RTS_UI32* pul, int iBit) { RTS_RESULT Result = SysCpuTestAndSetBit(pul, 4, iBit, 0); if (Result == ERR_NOT_SUPPORTED) return ERR_OK; return Result; } RTS_RESULT CDECL SysCpuGetCallstackEntry3(RTS_I32 bIecCode, RegContext *pContext, void **ppAddress) { RTS_RESULT result = ERR_FAILED; RTS_UINTPTR *pSP; if (pContext == NULL || ppAddress == NULL) { if (ppAddress != NULL) *ppAddress = NULL; return ERR_PARAMETER; } /* Try to find investigate the callstack via IEC stack backtrace */ if (bIecCode) return SysCpuGetCallstackEntry(&pContext->BP, ppAddress); /* Try to find the return address in IEC via OS stack backtrace */ while (SysCpuGetCallstackEntry2(bIecCode, &pContext->BP, ppAddress) == ERR_OK) { if (!bIecCode) { if (CAL_SysMemIsValidPointer((void *)*ppAddress, sizeof(void *), 0) != ERR_OK) return ERR_NOMEMORY; if (!CHK_AppGetApplicationByAreaAddress) return ERR_NOT_SUPPORTED; if (CAL_AppGetApplicationByAreaAddress(*ppAddress, NULL) == NULL) continue; } return ERR_OK; } pSP = (RTS_UINTPTR *)pContext->SP; if (CAL_SysMemIsValidPointer((void *)pSP, sizeof(pSP), 0) != ERR_OK) return ERR_NOMEMORY; /* Try to find the return address in IEC via linear search backward on stack for the marker pattern */ pSP = SysCpuSearchOnStack_(pSP, SYSCPU_STACK_MARKER, &result); if (result == ERR_OK && pSP != NULL && *pSP == SYSCPU_STACK_MARKER) { RTS_UINTPTR stackAlignment; RTS_UINTPTR offset = 1; RTS_UINTPTR adjOffset = 1; pContext->SP = (RTS_UINTPTR)pSP; /* The corresponding BP fom the caller in IEC is directly pushed before the marker on the stack! */ #if defined(TRG_DSP) pContext->BP = *(pSP - 1); #else pContext->BP = *(pSP + 1); #endif stackAlignment = SYSCPU_STACK_ALIGNMENT; for (;;) { /* The codegenerator always aligned the stack dependent on the processor width! */ if (((RTS_UINTPTR)pSP % stackAlignment) != 0) { RTS_UINTPTR alignbytes = ((RTS_UINTPTR)pSP % stackAlignment); offset += (alignbytes % sizeof(pSP) + 1); } /* Before calling external library function, the codegenerator reserves register save area on stack! */ offset += SYSCPU_EXTLIBCALL_GET_REGISTER_SAVE_AREA(SYSCPU_EXTLIBCALL_REGISTER_SAVE_AREA); /* Try to locate the return address of the external library call */ *ppAddress = (void *)*(pSP - offset); if (*ppAddress == NULL) *ppAddress = (void *)*(pSP - 1); if (*ppAddress == NULL) break; /* Return address found! It is a valid address in application area */ if (CAL_AppGetApplicationByAreaAddress(*ppAddress, NULL) != NULL) return ERR_OK; /* Some processors ( e.g. SH ) can have variable C calling conventions = entries in stack */ adjOffset = SYSCPU_EXTLIBCALL_ADJUST_OFFSET(offset); if ( adjOffset != offset) { offset = adjOffset; continue; } /* Some processors have a variable stack alignment of 4 or 8 bytes dependant on the Codegenerator setting in the DeviceDescription! */ if (stackAlignment == 4) { stackAlignment = 8; offset = 1; continue; } break; } } return ERR_NOMEMORY; } RTS_RESULT CDECL SysCpuSetRegisterValue(RTS_UINTPTR *pRegBuff, RTS_I32 nRegisterNumber, RTS_UINTPTR newValue) { if (pRegBuff == NULL) return ERR_PARAMETER; pRegBuff[SYSCPU_REGISTER_OFFSET(nRegisterNumber)] = newValue; return ERR_OK; } RTS_I64 CDECL SysCpuReadInt64(RTS_I64 *pSrc, RTS_RESULT *pResult) { if (pSrc == NULL) { RTS_SETRESULT(pResult, ERR_PARAMETER); return 0; } #if SYSCPU_ALIGNMENT_CHECK_64 > 1 /* Check alignment, atomic assignment is only possible if pSrc is aligned to allowed boundary */ if (((RTS_UINTPTR)pSrc % SYSCPU_ALIGNMENT_CHECK_64) != 0) { RTS_SETRESULT(pResult, ERR_ALIGNMENT); return 0; } #endif #if defined(TRG_64BIT) /* on 64bit targets, the atomic assignment is always assured */ RTS_SETRESULT(pResult, ERR_OK); return *pSrc; #else #ifdef SYS_ATOMIC_COMPARE_AND_SWAP64 { /* use operating system function if available */ RTS_RESULT result; RTS_I64 old_value = 0; do { old_value = *pSrc; SYS_ATOMIC_COMPARE_AND_SWAP64(pSrc, old_value, old_value, result); } while (result != ERR_OK && result != ERR_NOT_SUPPORTED); RTS_SETRESULT(pResult, result); if (result != ERR_OK) return 0; return old_value; } #else { /* no atomic assignment possible, so use synchronization object to ensure consistency*/ if (CHK_SysRWLReadLock && CHK_SysRWLReadUnlock && s_hRWLAtomicOperation != RTS_INVALID_HANDLE) { RTS_I64 iReturnValue; CAL_SysRWLReadLock(s_hRWLAtomicOperation); iReturnValue = *pSrc; CAL_SysRWLReadUnlock(s_hRWLAtomicOperation); RTS_SETRESULT(pResult, ERR_OK); return iReturnValue; } /* consistency cannot be assured, so return error */ else { RTS_SETRESULT(pResult, ERR_NOT_SUPPORTED); return 0; } } #endif /* SYS_ATOMIC_COMPARE_AND_SWAP64 */ #endif /* TRG_64BIT */ } RTS_RESULT CDECL SysCpuWriteInt64(RTS_I64 *pDest, RTS_I64 i64Value) { if (pDest == NULL) return ERR_PARAMETER; #if SYSCPU_ALIGNMENT_CHECK_64 > 1 /* Check alignment, atomic assignment is only possible if pDest is aligned to allowed boundary */ if (((RTS_UINTPTR)pDest % SYSCPU_ALIGNMENT_CHECK_64) != 0) { return ERR_ALIGNMENT; } #endif #if defined(TRG_64BIT) /* on 64bit targets, the atomic assignment is always assured */ *pDest = i64Value; return ERR_OK; #else #ifdef SYS_ATOMIC_COMPARE_AND_SWAP64 { /* use operating system function if available */ RTS_RESULT result; do { RTS_I64 old_value = *pDest; SYS_ATOMIC_COMPARE_AND_SWAP64(pDest, i64Value, old_value, result); } while (result != ERR_OK && result != ERR_NOT_SUPPORTED); return result; } #else { /* no atomic assignment possible, so use synchronization object to ensure consistency*/ if (CHK_SysRWLWriteLock && CHK_SysRWLWriteUnlock && s_hRWLAtomicOperation != RTS_INVALID_HANDLE) { CAL_SysRWLWriteLock(s_hRWLAtomicOperation); *pDest = i64Value; CAL_SysRWLWriteUnlock(s_hRWLAtomicOperation); return ERR_OK; } /* consistency cannot be assured, so return error */ else { return ERR_NOT_SUPPORTED; } } #endif /* SYS_ATOMIC_COMPARE_AND_SWAP64 */ #endif /* TRG_64BIT */ } RTS_REAL64 CDECL SysCpuReadReal64(RTS_REAL64 *pSrc, RTS_RESULT *pResult) { if (pSrc == NULL) { RTS_SETRESULT(pResult, ERR_PARAMETER); return 0; } #if SYSCPU_ALIGNMENT_CHECK_64 > 1 /* Check alignment, atomic assignment is only possible if pSrc is aligned to allowed boundary */ if (((RTS_UINTPTR)pSrc % SYSCPU_ALIGNMENT_CHECK_64) != 0) { RTS_SETRESULT(pResult, ERR_ALIGNMENT); return 0; } #endif #if defined(TRG_64BIT) /* on 64bit targets, the atomic assignment is always assured */ RTS_SETRESULT(pResult, ERR_OK); return *pSrc; #else #ifdef SYS_ATOMIC_COMPARE_AND_SWAP64 { /* use operating system function if available */ RTS_RESULT result; RTS_REAL64 read_value; RTS_I64 old_value = 0; do { memcpy(&old_value, pSrc, sizeof(RTS_I64)); SYS_ATOMIC_COMPARE_AND_SWAP64((RTS_I64 *)pSrc, old_value, old_value, result); } while (result != ERR_OK && result != ERR_NOT_SUPPORTED); RTS_SETRESULT(pResult, result); memcpy(&read_value, &old_value, sizeof(RTS_I64)); return read_value; } #else { /* no atomic assignment possible, so use synchronization object to ensure consistency*/ if (CHK_SysRWLReadLock && CHK_SysRWLReadUnlock && s_hRWLAtomicOperation != RTS_INVALID_HANDLE) { RTS_REAL64 rReturnValue; CAL_SysRWLReadLock(s_hRWLAtomicOperation); rReturnValue = *pSrc; CAL_SysRWLReadUnlock(s_hRWLAtomicOperation); RTS_SETRESULT(pResult, ERR_OK); return rReturnValue; } /* consistency cannot be assured, so return error */ else { RTS_SETRESULT(pResult, ERR_NOT_SUPPORTED); return 0; } } #endif /* SYS_ATOMIC_COMPARE_AND_SWAP64 */ #endif /* TRG_64BIT */ } RTS_RESULT CDECL SysCpuWriteReal64(RTS_REAL64 *pDest, RTS_REAL64 r64Value) { if (pDest == NULL) return ERR_PARAMETER; #if SYSCPU_ALIGNMENT_CHECK_64 > 1 /* Check alignment, atomic assignment is only possible if pDest is aligned to allowed boundary */ if (((RTS_UINTPTR)pDest % SYSCPU_ALIGNMENT_CHECK_64) != 0) { return ERR_ALIGNMENT; } #endif #if defined(TRG_64BIT) /* on 64bit targets, the atomic assignment is always assured */ *pDest = r64Value; return ERR_OK; #else #ifdef SYS_ATOMIC_COMPARE_AND_SWAP64 { /* use operating system function if available */ RTS_RESULT result; RTS_I64 old_value; RTS_I64 new_value; do { memcpy(&old_value, pDest, sizeof(RTS_I64)); memcpy(&new_value, &r64Value, sizeof(RTS_I64)); SYS_ATOMIC_COMPARE_AND_SWAP64((RTS_I64 *)pDest, new_value, old_value, result); } while (result != ERR_OK && result != ERR_NOT_SUPPORTED); return result; } #else { /* no atomic assignment possible, so use synchronization object to ensure consistency*/ if (CHK_SysRWLWriteLock && CHK_SysRWLWriteUnlock && s_hRWLAtomicOperation != RTS_INVALID_HANDLE) { CAL_SysRWLWriteLock(s_hRWLAtomicOperation); *pDest = r64Value; CAL_SysRWLWriteUnlock(s_hRWLAtomicOperation); return ERR_OK; } /* consistency cannot be assured, so return error */ else { return ERR_NOT_SUPPORTED; } } #endif /* SYS_ATOMIC_COMPARE_AND_SWAP64 */ #endif /* TRG_64BIT */ } RTS_RESULT CDECL SysCpuWriteValueAtomic(void* pDest, void* pSrc, RTS_UI32 nLen) { RTS_RESULT result = ERR_FAILED; if (pDest == NULL || pSrc == NULL) return ERR_PARAMETER; switch (nLen) { case 8: { RTS_I64 i64; memcpy(&i64, (RTS_I64 *)pSrc, sizeof(RTS_I64)); result = SysCpuWriteInt64((RTS_I64*)pDest, i64); break; } case 4: { #if SYSCPU_ALIGNMENT_CHECK_32 > 1 if (((RTS_UINTPTR)pDest % SYSCPU_ALIGNMENT_CHECK_32) == 0) { if (((RTS_UINTPTR)pSrc % SYSCPU_ALIGNMENT_CHECK_32) != 0) { RTS_UI32 ui32; memcpy(&ui32, pSrc, sizeof(RTS_UI32)); *(RTS_UI32 *)pDest = ui32; } else *(RTS_UI32 *)pDest = *(RTS_UI32 *)pSrc; result = ERR_OK; } else { result = ERR_ALIGNMENT; } #else *(RTS_UI32 *)pDest = *(RTS_UI32 *)pSrc; result = ERR_OK; #endif break; } case 2: { #if SYSCPU_ALIGNMENT_CHECK_16 > 1 if (((RTS_UINTPTR)pDest % SYSCPU_ALIGNMENT_CHECK_16) == 0) { if (((RTS_UINTPTR)pSrc % SYSCPU_ALIGNMENT_CHECK_16) != 0) { RTS_UI16 ui16; memcpy(&ui16, pSrc, sizeof(RTS_UI16)); *(RTS_UI16 *)pDest = ui16; } else *(RTS_UI16 *)pDest = *(RTS_UI16 *)pSrc; result = ERR_OK; } else { result = ERR_ALIGNMENT; } #else *(RTS_UI16 *)pDest = *(RTS_UI16 *)pSrc; result = ERR_OK; #endif break; } case 1: { *(RTS_UI8 *)pDest = *(RTS_UI8 *)pSrc; result = ERR_OK; break; } default: { result = ERR_PARAMETER; break; } } return result; } RTS_RESULT CDECL SysCpuReadValueAtomic(void* pSrc, void* pDest, RTS_UI32 nLen) { RTS_RESULT result = ERR_FAILED; if (pSrc == NULL || pDest == NULL) return ERR_PARAMETER; switch (nLen) { case 8: { RTS_I64 i64; i64 = SysCpuReadInt64((RTS_I64 *)pSrc, &result); if (result == ERR_OK) memcpy(pDest, &i64, sizeof(RTS_I64)); break; } case 4: { #if SYSCPU_ALIGNMENT_CHECK_32 > 1 if (((RTS_UINTPTR)pSrc % SYSCPU_ALIGNMENT_CHECK_32) == 0) { if (((RTS_UINTPTR)pDest % SYSCPU_ALIGNMENT_CHECK_32) != 0) { RTS_UI32 ui32; ui32 = *(RTS_UI32 *)pSrc; memcpy(pDest, &ui32, sizeof(RTS_UI32)); } else *(RTS_UI32 *)pDest = *(RTS_UI32 *)pSrc; result = ERR_OK; } else { result = ERR_ALIGNMENT; } #else *(RTS_UI32 *)pDest = *(RTS_UI32 *)pSrc; result = ERR_OK; #endif break; } case 2: { #if SYSCPU_ALIGNMENT_CHECK_16 > 1 if (((RTS_UINTPTR)pSrc % SYSCPU_ALIGNMENT_CHECK_16) == 0) { if (((RTS_UINTPTR)pDest % SYSCPU_ALIGNMENT_CHECK_16) != 0) { RTS_UI16 ui16; ui16 = *(RTS_UI16 *)pSrc; memcpy(pDest, &ui16, sizeof(RTS_UI16)); } else *(RTS_UI16 *)pDest = *(RTS_UI16 *)pSrc; result = ERR_OK; } else { result = ERR_ALIGNMENT; } #else *(RTS_UI16 *)pDest = *(RTS_UI16 *)pSrc; result = ERR_OK; #endif break; } case 1: { *(RTS_UI8 *)pDest = *(RTS_UI8 *)pSrc; result = ERR_OK; break; } default: { result = ERR_PARAMETER; break; } } return result; } RTS_RESULT CDECL SysCpuAtomicCompareAndSwap(void *pAddress, void *pSwapValue, void *pCompareValue, RTS_UI8 valueSize) { RTS_RESULT Result = ERR_NOT_SUPPORTED; if (pAddress == NULL || pSwapValue == NULL || pCompareValue == NULL) return ERR_PARAMETER; switch (valueSize) { case 4: { #if SYSCPU_ALIGNMENT_CHECK_32 > 1 if (((RTS_UINTPTR)pAddress % SYSCPU_ALIGNMENT_CHECK_32) != 0) return ERR_ALIGNMENT; #endif #ifdef SYS_ATOMIC_COMPARE_AND_SWAP SYS_ATOMIC_COMPARE_AND_SWAP((RTS_I32 *)pAddress, (*(RTS_I32 *)pSwapValue), (*(RTS_I32 *)pCompareValue), Result); #endif break; } case 8: { #if SYSCPU_ALIGNMENT_CHECK_64 > 1 if (((RTS_UINTPTR)pAddress % SYSCPU_ALIGNMENT_CHECK_64) != 0) return ERR_ALIGNMENT; #endif #ifdef SYS_ATOMIC_COMPARE_AND_SWAP64 SYS_ATOMIC_COMPARE_AND_SWAP64((RTS_I64 *)pAddress, (*(RTS_I64 *)pSwapValue), (*(RTS_I64 *)pCompareValue), Result); #endif break; } default: { Result = ERR_PARAMETER; break; } } return Result; } RTS_I64 CDECL SysCpuAtomicAdd64(RTS_I64 *pi64Value, RTS_I64 i64Sum, RTS_RESULT *pResult) { RTS_I64 i64ReturnValue = 0; RTS_RESULT Result = ERR_NOT_SUPPORTED; if (pi64Value == NULL) { RTS_SETRESULT(pResult, ERR_PARAMETER); return 0; } #if SYSCPU_ALIGNMENT_CHECK_64 > 1 if (((RTS_UINTPTR)pi64Value % SYSCPU_ALIGNMENT_CHECK_64) != 0) { RTS_SETRESULT(pResult, ERR_ALIGNMENT); return 0; } #endif #if defined(SYS_ATOMIC_ADD64) SYS_ATOMIC_ADD64(pi64Value, i64Sum, i64ReturnValue, Result); #else { RTS_I64 oldValue; RTS_I64 newValue; do { oldValue = *pi64Value; newValue = oldValue + i64Sum; Result = SysCpuAtomicCompareAndSwap(pi64Value, &newValue, &oldValue, sizeof(oldValue)); } while (Result != ERR_OK && Result != ERR_NOT_SUPPORTED); if (Result == ERR_OK) i64ReturnValue = newValue; } #endif RTS_SETRESULT(pResult, Result); return i64ReturnValue; } /* <SIL2/> */ void CDECL CDECL_EXT syscputestandset(syscputestandset_struct *p) { #ifdef RTS_SIL2 if (CHK_SIL2CheckCallerContext && CAL_SIL2CheckCallerContext(RTS_SIL2_CALLERCTX_UNSAFE) != ERR_OK) return; #endif p->SysCpuTestAndSet = SysCpuTestAndSet(p->pulValue, p->ulBit); } /* <SIL2/> */ void CDECL CDECL_EXT syscputestandreset(syscputestandreset_struct *p) { #ifdef RTS_SIL2 if (CHK_SIL2CheckCallerContext && CAL_SIL2CheckCallerContext(RTS_SIL2_CALLERCTX_UNSAFE) != ERR_OK) return; #endif p->SysCpuTestAndReset = SysCpuTestAndReset(p->pulValue, p->ulBit); } /* <SIL2/> * SysCpuTestAndSetBit() is certified and may therefore be used * within a safe context. */ void CDECL CDECL_EXT syscputestandsetbit(syscputestandsetbit_struct *p) { p->SysCpuTestAndSetBit = SysCpuTestAndSetBit(p->pAddress, p->nLen, p->iBit, p->bSet); } /* <SIL2/> */ void CDECL CDECL_EXT syscpucalliecfuncwithparams(syscpucalliecfuncwithparams_struct *p) { RTS_VOID_FCTPTR* ppfIECFunc; #ifdef RTS_SIL2 if (CHK_SIL2CheckCallerContext && CAL_SIL2CheckCallerContext(RTS_SIL2_CALLERCTX_UNSAFE) != ERR_OK) return; #endif ppfIECFunc = (RTS_VOID_FCTPTR* )(p->pfIECFunc); p->SysCpuCallIecFuncWithParams = SysCpuCallIecFuncWithParams(*ppfIECFunc, p->pParam, p->ulSize); } /* <SIL2/> * SysCpuAtomicAdd() is certified and may therefore be used * within a safe context. */ void CDECL CDECL_EXT syscpuatomicadd(syscpuatomicadd_struct *p) { p->SysCpuAtomicAdd = SysCpuAtomicAdd(p->piValue, p->nSum, p->pResult); } /* <SIL2/> */ void CDECL CDECL_EXT syscpuatomicadd64(syscpuatomicadd64_struct *p) { #ifdef RTS_SIL2 if (CHK_SIL2CheckCallerContext && CAL_SIL2CheckCallerContext(RTS_SIL2_CALLERCTX_UNSAFE) != ERR_OK) return; #endif p->SysCpuAtomicAdd64 = SysCpuAtomicAdd64(p->piValue, p->nSum, p->pResult); } /* <SIL2/> */ void CDECL CDECL_EXT syscpuatomiccompareandswap(syscpuatomiccompareandswap_struct *p) { #ifdef RTS_SIL2 if (CHK_SIL2CheckCallerContext && CAL_SIL2CheckCallerContext(RTS_SIL2_CALLERCTX_UNSAFE) != ERR_OK) return; #endif p->SysCpuAtomicCompareAndSwap = SysCpuAtomicCompareAndSwap(p->pAddress, p->pSwapValue, p->pCompareValue, p->valueSize); } #ifdef SYSCPUHANDLING_MODULETEST static RTS_RESULT ModuleTest(void) { RTS_I64 i64Value = 0; RTS_I64 i64ResultValue = 0; RTS_I64 i64ReadValue = 0; RTS_I64 i64WriteValue = 0; RTS_UI64 ui64Value = 0; RTS_UI64 ui64ReadValue = 0; RTS_UI64 ui64WriteValue = 0; RTS_REAL64 r64Value = 0; RTS_REAL64 r64ReadValue = 0; RTS_REAL64 r64WriteValue = 0; RTS_UI32 errors = 0; RTS_RESULT result; static RTS_BOOL s_bRunOnce = TRUE; if (s_bRunOnce) { #define SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "%" PRI_UI32 ":SysCpuTestAndSetBit2 test:" RTS_UI16 ui16Result; RTS_UI32 ui32Result; RTS_UI32 ui32Expected; #ifdef RTS_SIXTEENBITBYTES static RTS_UI32 aui32AlignedMem[2] = { 0 }; static RTS_UI32 * const pui32Misaligned = (RTS_UI32 *)((char *)&aui32AlignedMem[0] + 1); /* misaligned by 1 char */ static char(*const pacUI32Misaligned)[2] = (char(*)[2])((char *)&aui32AlignedMem[0] + 1); SysCpuTestAndSetBit2(pui32Misaligned, sizeof(RTS_UI32), 0, TRUE); memcpy(&ui32Result, pui32Misaligned, sizeof(RTS_UI32)); if (ui32Result == 0x00000001) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected 0x00000001 Was %08" PRI_X32, __LINE__, ui32Result); SysCpuTestAndSetBit2(pui32Misaligned, sizeof(RTS_UI32), 0, FALSE); SysCpuTestAndSetBit2(pui32Misaligned, sizeof(RTS_UI32), 15, TRUE); memcpy(&ui32Result, pui32Misaligned, sizeof(RTS_UI32)); if (ui32Result == 0x00008000) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected 0x00008000 Was %08" PRI_X32, __LINE__, ui32Result); SysCpuTestAndSetBit2(pui32Misaligned, sizeof(RTS_UI32), 15, FALSE); SysCpuTestAndSetBit2(pui32Misaligned, sizeof(RTS_UI32), 16, TRUE); memcpy(&ui32Result, pui32Misaligned, sizeof(RTS_UI32)); if (ui32Result == 0x00010000) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected 0x00010000 Was %08" PRI_X32, __LINE__, ui32Result); SysCpuTestAndSetBit2(pui32Misaligned, sizeof(RTS_UI32), 16, FALSE); SysCpuTestAndSetBit2(pui32Misaligned, sizeof(RTS_UI32), 31, TRUE); memcpy(&ui32Result, pui32Misaligned, sizeof(RTS_UI32)); if (ui32Result == 0x80000000) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected 0x80000000 Was %08" PRI_X32, __LINE__, ui32Result); #else static RTS_UI32 aui32AlignedMem[6] = { 0 }; static RTS_UI16 * const pui16Misaligned = (RTS_UI16 *)((char *)&aui32AlignedMem[0] + 3); static char(*const pacUI16Misaligned)[2] = (char(*)[2])((char *)&aui32AlignedMem[0] + 3); static RTS_UI32 * const pui32Misaligned3Chars = (RTS_UI32 *)((char *)&aui32AlignedMem[2] + 3); static char(*const pacUI32Misaligned3Chars)[4] = (char(*)[4])((char *)&aui32AlignedMem[2] + 3); static RTS_UI32 * const pui32Misaligned1Char = (RTS_UI32 *)((char *)&aui32AlignedMem[4] + 1); static char(*const pacUI32Misaligned1Char)[4] = (char(*)[4])((char *)&aui32AlignedMem[4] + 1); /* Assignment of the bit in the UINT32 value to the bit in the internal memory representation. Bits in memory to test for pui32Misaligned3Chars: 0, 23, 24, 31 Bits in memory to test for pui32Misaligned1Char: 0, 7, 8, 31 */ #ifdef RTS_BIGENDIAN_BYTEORDER static const RTS_SIZE siBit0 = 0; static const RTS_SIZE siBit7 = 7; static const RTS_SIZE siBit8 = 8; static const RTS_SIZE siBit23 = 23; static const RTS_SIZE siBit24 = 24; static const RTS_SIZE siBit31 = 31; #else static const RTS_SIZE siBit0 = 24; static const RTS_SIZE siBit7 = 31; static const RTS_SIZE siBit8 = 16; static const RTS_SIZE siBit23 = 15; static const RTS_SIZE siBit24 = 1; static const RTS_SIZE siBit31 = 7; #endif SysCpuTestAndSetBit2(pui16Misaligned, sizeof(RTS_UI16), 0, TRUE); memcpy(&ui16Result, pui16Misaligned, sizeof(RTS_UI16)); if (ui16Result == 0x0001) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected 0x0001 Was %04" PRI_X16, __LINE__, ui16Result); SysCpuTestAndSetBit2(pui16Misaligned, sizeof(RTS_UI16), 0, FALSE); SysCpuTestAndSetBit2(pui16Misaligned, sizeof(RTS_UI16), 7, TRUE); memcpy(&ui16Result, pui16Misaligned, sizeof(RTS_UI16)); if (ui16Result == 0x0080) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected 0x0080 Was %04" PRI_X16, __LINE__, ui16Result); SysCpuTestAndSetBit2(pui16Misaligned, sizeof(RTS_UI16), 7, FALSE); SysCpuTestAndSetBit2(pui16Misaligned, sizeof(RTS_UI16), 8, TRUE); memcpy(&ui16Result, pui16Misaligned, sizeof(RTS_UI16)); if (ui16Result == 0x0100) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected 0x0100 Was %04" PRI_X16, __LINE__, ui16Result); SysCpuTestAndSetBit2(pui16Misaligned, sizeof(RTS_UI16), 8, FALSE); SysCpuTestAndSetBit2(pui16Misaligned, sizeof(RTS_UI16), 15, TRUE); memcpy(&ui16Result, pui16Misaligned, sizeof(RTS_UI16)); if (ui16Result == 0x8000) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected 0x8000 Was %04" PRI_X16, __LINE__, ui16Result); /* for pui32Misaligned3Chars: Bits 0, 23, 24, 31 */ SysCpuTestAndSetBit2(pui32Misaligned3Chars, sizeof(RTS_UI32), siBit0, TRUE); ui32Expected = (RTS_UI32)pow(2.0, siBit0); memcpy(&ui32Result, pui32Misaligned3Chars, sizeof(RTS_UI32)); if (ui32Result == ui32Expected) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected %08" PRI_X32 " Was %08" PRI_X32, __LINE__, ui32Expected, ui32Result); SysCpuTestAndSetBit2(pui32Misaligned3Chars, sizeof(RTS_UI32), siBit0, FALSE); SysCpuTestAndSetBit2(pui32Misaligned3Chars, sizeof(RTS_UI32), siBit23, TRUE); ui32Expected = (RTS_UI32)pow(2.0, siBit23); memcpy(&ui32Result, pui32Misaligned3Chars, sizeof(RTS_UI32)); if (ui32Result == ui32Expected) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected %08" PRI_X32 " Was %08" PRI_X32, __LINE__, ui32Expected, ui32Result); SysCpuTestAndSetBit2(pui32Misaligned3Chars, sizeof(RTS_UI32), siBit23, FALSE); SysCpuTestAndSetBit2(pui32Misaligned3Chars, sizeof(RTS_UI32), siBit24, TRUE); ui32Expected = (RTS_UI32)pow(2.0, siBit24); memcpy(&ui32Result, pui32Misaligned3Chars, sizeof(RTS_UI32)); if (ui32Result == ui32Expected) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected %08" PRI_X32 " Was %08" PRI_X32, __LINE__, ui32Expected, ui32Result); SysCpuTestAndSetBit2(pui32Misaligned3Chars, sizeof(RTS_UI32), siBit24, FALSE); SysCpuTestAndSetBit2(pui32Misaligned3Chars, sizeof(RTS_UI32), siBit31, TRUE); memcpy(&ui32Result, pui32Misaligned3Chars, sizeof(RTS_UI32)); ui32Expected = (RTS_UI32)pow(2.0, siBit31); if (ui32Result == ui32Expected) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected %08" PRI_X32 " Was %08" PRI_X32, __LINE__, ui32Expected, ui32Result); /* for pui32Misaligned1Char: Bits 0, 7, 8, 31 */ SysCpuTestAndSetBit2(pui32Misaligned1Char, sizeof(RTS_UI32), siBit0, TRUE); ui32Expected = (RTS_UI32)pow(2.0, siBit0); memcpy(&ui32Result, pui32Misaligned1Char, sizeof(RTS_UI32)); if (ui32Result == ui32Expected) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected %08" PRI_X32 " Was %08" PRI_X32, __LINE__, ui32Expected, ui32Result); SysCpuTestAndSetBit2(pui32Misaligned1Char, sizeof(RTS_UI32), siBit0, FALSE); SysCpuTestAndSetBit2(pui32Misaligned1Char, sizeof(RTS_UI32), siBit7, TRUE); ui32Expected = (RTS_UI32)pow(2.0, siBit7); memcpy(&ui32Result, pui32Misaligned1Char, sizeof(RTS_UI32)); if (ui32Result == ui32Expected) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected %08" PRI_X32 " Was %08" PRI_X32, __LINE__, ui32Expected, ui32Result); SysCpuTestAndSetBit2(pui32Misaligned1Char, sizeof(RTS_UI32), siBit7, FALSE); SysCpuTestAndSetBit2(pui32Misaligned1Char, sizeof(RTS_UI32), siBit8, TRUE); ui32Expected = (RTS_UI32)pow(2.0, siBit8); memcpy(&ui32Result, pui32Misaligned1Char, sizeof(RTS_UI32)); if (ui32Result == ui32Expected) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected %08" PRI_X32 " Was %08" PRI_X32, __LINE__, ui32Expected, ui32Result); SysCpuTestAndSetBit2(pui32Misaligned1Char, sizeof(RTS_UI32), siBit8, FALSE); SysCpuTestAndSetBit2(pui32Misaligned1Char, sizeof(RTS_UI32), siBit31, TRUE); ui32Expected = (RTS_UI32)pow(2.0, siBit31); memcpy(&ui32Result, pui32Misaligned1Char, sizeof(RTS_UI32)); if (ui32Result == ui32Expected) CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_OK, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "PASS", __LINE__); else CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_DEBUG, ERR_FAILED, 0, SYSCPUTESTANDSETBIT2_TEST_RESULT_BEGIN "FAIL: Expected %08" PRI_X32 " Was %08" PRI_X32, __LINE__, ui32Expected, ui32Result); #endif s_bRunOnce = FALSE; } #if defined(BASE64BITTYPES_DEFINED) && !defined(SYSINTERNAL_DISABLE_64BIT) && !defined(RTS_DISABLE_64BIT_SUPPORT) /**** RTS_I64 ****/ i64Value = RTS_I64_MAX; i64ReadValue = SysCpuReadInt64(&i64Value, &result); if (i64ReadValue != i64Value || result != ERR_OK) errors += 1; i64WriteValue = 0; result = SysCpuWriteInt64(&i64WriteValue, i64Value); if (i64WriteValue != i64Value || result != ERR_OK) errors += 1; i64Value = 281474976710655; i64ReadValue = SysCpuReadInt64(&i64Value, &result); if (i64ReadValue != i64Value || result != ERR_OK) errors += 1; i64WriteValue = 0; result = SysCpuWriteInt64(&i64WriteValue, i64Value); if (i64WriteValue != i64Value || result != ERR_OK) errors += 1; i64ResultValue = SysCpuAtomicAdd64(&i64Value, 2, &result); if (result != ERR_OK || i64ResultValue != i64Value) errors += 1; i64WriteValue = 444; i64ReadValue = 123; result = SysCpuAtomicCompareAndSwap(&i64Value, &i64WriteValue, &i64ReadValue, sizeof(i64Value)); if (result != ERR_FAILED) errors += 1; i64ReadValue = i64Value; result = SysCpuAtomicCompareAndSwap(&i64Value, &i64WriteValue, &i64ReadValue, sizeof(i64Value)); if (result != ERR_OK) errors += 1; /**** RTS_UI64 ****/ ui64Value = RTS_UI64_MAX; ui64ReadValue = SysCpuReadInt64((RTS_I64*)&ui64Value, &result); if (ui64ReadValue != ui64Value || result != ERR_OK) errors += 1; ui64WriteValue = 0; result = SysCpuWriteInt64((RTS_I64*)&ui64WriteValue, (RTS_I64)ui64Value); if (ui64WriteValue != ui64Value || result != ERR_OK) errors += 1; ui64Value = 281474976710655; ui64ReadValue = SysCpuReadInt64((RTS_I64*)&ui64Value, &result); if (ui64ReadValue != ui64Value || result != ERR_OK) errors += 1; ui64WriteValue = 0; result = SysCpuWriteInt64((RTS_I64*)&ui64WriteValue, (RTS_I64)ui64Value); if (ui64WriteValue != ui64Value || result != ERR_OK) errors += 1; #endif /**** RTS_REAL64 ****/ r64Value = RTS_REAL64_MAX; r64ReadValue = SysCpuReadReal64(&r64Value, &result); if (r64ReadValue != r64Value || result != ERR_OK) errors += 1; r64WriteValue = 0; result = SysCpuWriteReal64(&r64WriteValue, r64Value); if (r64WriteValue != r64Value || result != ERR_OK) errors += 1; r64Value = 1.23456789; r64ReadValue = SysCpuReadReal64(&r64Value, &result); if (r64ReadValue != r64Value || result != ERR_OK) errors += 1; r64WriteValue = 0; result = SysCpuWriteReal64(&r64WriteValue, r64Value); if (r64WriteValue != r64Value || result != ERR_OK) errors += 1; if (errors == 0) return ERR_OK; return ERR_FAILED; } #endif RTS_RESULT CDECL SysCpuTestAndSetBit2( void *pMemory, RTS_SIZE siLen, /* Size in chars of the value pMemory points to. */ RTS_SIZE siBit, /* Zero-based position of the bit to test within the memory pointed to by pMemory. */ RTS_BOOL bSet) /* TRUE=Set bit, FALSE=Clear bit. */ { RTS_INT *piAlign; RTS_SIZE siBitAligned; SysCpuTestAndSetBit_AlignPtrInt(pMemory, siLen, siBit, &piAlign, &siBitAligned); return SysCpuTestAndSetBit(piAlign, sizeof(RTS_INT), siBitAligned, bSet); }
Disassembly code:
(gdb) disassemble/m Dump of assembler code for function SysCpuReadValueAtomic: 309 RTS_I64 CDECL SysCpuReadInt64(RTS_I64 *pSrc, RTS_RESULT *pResult) 310 { 311 if (pSrc == NULL) 312 { 313 RTS_SETRESULT(pResult, ERR_PARAMETER); 314 return 0; 315 } 316 317 #if SYSCPU_ALIGNMENT_CHECK_64 > 1 318 /* Check alignment, atomic assignment is only possible if pSrc is aligned to allowed boundary */ 319 if (((RTS_UINTPTR)pSrc % SYSCPU_ALIGNMENT_CHECK_64) != 0) 320 { 321 RTS_SETRESULT(pResult, ERR_ALIGNMENT); 322 return 0; 323 } 324 #endif 325 326 #if defined(TRG_64BIT) 327 /* on 64bit targets, the atomic assignment is always assured */ 328 RTS_SETRESULT(pResult, ERR_OK); 329 return *pSrc; 330 #else 331 #ifdef SYS_ATOMIC_COMPARE_AND_SWAP64 332 { 333 /* use operating system function if available */ 334 RTS_RESULT result; 335 RTS_I64 old_value = 0; 336 337 do 338 { 339 old_value = *pSrc; 0x002fc370 <+44>: ldrd r6, r7, [r0] 340 SYS_ATOMIC_COMPARE_AND_SWAP64(pSrc, old_value, old_value, result); 0x002fc374 <+48>: dmb ish 0x002fc378 <+52>: ldrexd r4, r5, [r0] 0x002fc37c <+56>: cmp r5, r7 0x002fc37e <+58>: it eq 0x002fc380 <+60>: cmpeq r4, r6 0x002fc382 <+62>: bne.n 0x2fc38c <SysCpuReadValueAtomic+72> => 0x002fc384 <+64>: strexd r1, r6, r7, [r0] 0x002fc388 <+68>: cmp r1, #0 0x002fc38a <+70>: bne.n 0x2fc378 <SysCpuReadValueAtomic+52> 0x002fc38c <+72>: dmb ish 0x002fc390 <+76>: bne.n 0x2fc370 <SysCpuReadValueAtomic+44> 0x002fc392 <+78>: mov r4, sp 0x002fc394 <+80>: strd r6, r7, [sp]
Information registers:
r0 value is 0xb1eb4018.
(gdb) info registers r0 0xb1eb4018 2984984600 r1 0xb04fcf98 2958020504 r2 0x0 0 r3 0xb04fcf98 2958020504 r4 0x0 0 r5 0x0 0 r6 0x0 0 r7 0x0 0 r8 0x366fa8 3567528 r9 0xf095d44e 4036351054 r10 0xb04fd0d8 2958020824 r11 0x3a88 14984 r12 0x3f6178 4153720 sp 0xb04fcda0 0xb04fcda0 lr 0x18d1a7 1626535 pc 0x2fc384 0x2fc384 <SysCpuReadValueAtomic+64> cpsr 0x60010030 1610678320 fpscr 0x0 0
memory map:
0xb1eb_4000 is mapped at 0x1600_1000(physical address)
root@HX-SDC:/proc/2030# cat maps | grep mem b0e0c000-b0e0d000 rwxs 4a002000 00:06 8957 /dev/mem b1eb4000-b20a8000 rwxs 16001000 00:06 8957 /dev/mem b20c9000-b20ca000 rwxs 16000000 00:06 8957 /dev/mem b20ca000-b20cb000 rwxs 16000000 00:06 8957 /dev/mem b419a000-b421a000 rwxs 18100000 00:06 8957 /dev/mem b4b07000-b4b08000 rwxs 17001000 00:06 8957 /dev/mem b4b08000-b4b09000 r-xs 17001000 00:06 8957 /dev/mem b4b09000-b4b0b000 r-xs 1801c000 00:06 8957 /dev/mem b4b0b000-b4b0d000 r-xs 1800c000 00:06 8957 /dev/mem b4b0d000-b4b0f000 rwxs 1801e000 00:06 8957 /dev/mem b4b0f000-b4b11000 rwxs 1800e000 00:06 8957 /dev/mem b4b11000-b4b13000 rwxs 18014000 00:06 8957 /dev/mem b4b13000-b4b15000 rwxs 18004000 00:06 8957 /dev/mem b6f22000-b6f24000 rwxs 18016000 00:06 8957 /dev/mem b6f24000-b6f26000 rwxs 18006000 00:06 8957 /dev/mem
Questions:
- What does "Unhandled fault: asynchronous external abort (0x1211)" mean?
- What is potential cause of the issue?
Thanks and regards,
Koichiro Tashiro