#include "simul.h" /***************************************************************************** Memory Aliasing Simulation This demo is generic, it simulates the memory aliasing of a configurable physical memory range. Usage: SIM.LOAD memaliasing.dll Example use case: Cortex-A15 supports Large Physical Address Extension (LPAE), which allows 40 bit address bus. Access to the range outside the first 4GB of address space is only possible after the MMU is turned ON. In order to give access to the address range above 4GB before the MMU is turned on, certain targets (e.g. keystone2) implements a hardware mechanism in order to map a certain range of high memories to a range in the first 4GB range. *****************************************************************************/ typedef struct { int bustype; int al_bustype; simulWord startaddress; simulWord endaddress; simulWord al_startaddress; } memAliasing; static int SIMULAPI WriteMemAliasing(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) { unsigned char data[8]; memAliasing * memAliasingptr = (memAliasing*)private; simulWord address_temp = cbs->x.bus.address+memAliasingptr->al_startaddress-memAliasingptr->startaddress; SIMUL_SaveWord(processor, data, cbs->x.bus.width, &cbs->x.bus.data); if ( SIMUL_WriteMemory(processor,memAliasingptr->al_bustype,&address_temp, cbs->x.bus.width,0,(simulWord *)data)< 0){ SIMUL_Warning(processor, "ReadMemAliasing callback fail at address: 0x%x, ", cbs->x.bus.address); return SIMUL_MEMORY_FAIL; } return SIMUL_MEMORY_OK; } static int SIMULAPI ReadMemAliasing(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) { unsigned char data[8]; memAliasing * memAliasingptr = (memAliasing*)private; simulWord address_temp = cbs->x.bus.address+memAliasingptr->al_startaddress-memAliasingptr->startaddress; if ( SIMUL_ReadMemory(processor,memAliasingptr->al_bustype,&address_temp, cbs->x.bus.width,0,(simulWord *)data)< 0){ SIMUL_Warning(processor, "ReadMemAliasing callback fail at address: 0x%x, ", cbs->x.bus.address); return SIMUL_MEMORY_FAIL; } SIMUL_LoadWord(processor, data, cbs->x.bus.width, &cbs->x.bus.data); return SIMUL_MEMORY_OK; } static void InitMemAliasing(simulProcessor processor, memAliasing* memAliasingptr) { simulWord from, to; SIMUL_CreateSharedResource(processor, 256); from = memAliasingptr->startaddress; to = memAliasingptr->endaddress; SIMUL_RegisterBusWriteCallback(processor, WriteMemAliasing, (simulPtr) memAliasingptr, memAliasingptr->bustype, &from, &to); SIMUL_RegisterBusReadCallback(processor, ReadMemAliasing, (simulPtr) memAliasingptr, memAliasingptr->bustype, &from, &to); } /************************************************************************** Entry point of the Model **************************************************************************/ int SIMULAPI SIMUL_Init(simulProcessor processor, simulCallbackStruct * cbs) { simulWord64 baseaddress, size, aliasingaddress; memAliasing *memAliasingptr; strcpy(cbs->x.init.modelname, __DATE__ " Memory Aliasing"); memAliasingptr = (memAliasing *) SIMUL_Alloc(processor, sizeof(memAliasing)); if (cbs->x.init.argc != 4) { SIMUL_Warning(processor, "parameters: "); return SIMUL_INIT_FAIL; } baseaddress=cbs->x.init.argpaddress64[1]; size=cbs->x.init.argpaddress64[2]; aliasingaddress=cbs->x.init.argpaddress64[3]; if (size == 0 || size>0xFFFFFFFF) { if (size == 0) SIMUL_Warning(processor, "size should not be 0"); else SIMUL_Warning(processor, "size value (0x%x) should not exceed 0xFFFFFFFF", size); return SIMUL_INIT_FAIL; } if (baseaddress+size >=0x000000FFFFFFFFFF) { SIMUL_Warning(processor, "(base_address+size) should not exceed 0xFF:FFFFFFFF value"); return SIMUL_INIT_FAIL; } if (aliasingaddress+size >=0x000000FFFFFFFFFF) { SIMUL_Warning(processor, "(aliasing_address+size) should not exceed 0xFF:FFFFFFFF value"); return SIMUL_INIT_FAIL; } memAliasingptr->bustype = 0x100+((baseaddress>>32)&0xFF); memAliasingptr->al_bustype = 0x100+((aliasingaddress>>32)&0xFF); memAliasingptr->startaddress = (simulWord)(baseaddress&0xFFFFFFFF); memAliasingptr->endaddress = (simulWord)(memAliasingptr->startaddress+size-1); memAliasingptr->al_startaddress = (simulWord)(aliasingaddress&0xFFFFFFFF); SIMUL_Printf(processor, "SIM Memory Aliasing: A:0x%02X:0x%08X--0x%08X <=> A:0x%02X:0x%08X--0x%08X ", memAliasingptr->bustype&0xFF, memAliasingptr->startaddress, memAliasingptr->endaddress, memAliasingptr->al_bustype&0xFF, memAliasingptr->al_startaddress, memAliasingptr->al_startaddress+size-1); InitMemAliasing(processor, memAliasingptr); return SIMUL_INIT_OK; }