/* Copyright (C) 2006 yopyop Copyright (C) 2006-2010 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with the this software. If not, see . */ #pragma once #include "armcpu.h" const uint32_t CP15_ACCESS_WRITE = 0; const uint32_t CP15_ACCESS_READ = 2; const uint32_t CP15_ACCESS_EXECUTE = 4; const uint32_t CP15_ACCESS_WRITEUSR = CP15_ACCESS_WRITE; const uint32_t CP15_ACCESS_WRITESYS = 1; const uint32_t CP15_ACCESS_READUSR = CP15_ACCESS_READ; const uint32_t CP15_ACCESS_READSYS = 3; const uint32_t CP15_ACCESS_EXECUSR = CP15_ACCESS_EXECUTE; const uint32_t CP15_ACCESS_EXECSYS = 5; struct armcp15_t { public: uint32_t IDCode; uint32_t cacheType; uint32_t TCMSize; uint32_t ctrl; uint32_t DCConfig; uint32_t ICConfig; uint32_t writeBuffCtrl; uint32_t und; uint32_t DaccessPerm; uint32_t IaccessPerm; uint32_t protectBaseSize0; uint32_t protectBaseSize1; uint32_t protectBaseSize2; uint32_t protectBaseSize3; uint32_t protectBaseSize4; uint32_t protectBaseSize5; uint32_t protectBaseSize6; uint32_t protectBaseSize7; uint32_t cacheOp; uint32_t DcacheLock; uint32_t IcacheLock; uint32_t ITCMRegion; uint32_t DTCMRegion; uint32_t processID; uint32_t RAM_TAG; uint32_t testState; uint32_t cacheDbg; /* calculated bitmasks for the regions to decide rights uppon */ /* calculation is done in the MCR instead of on mem access for performance */ uint32_t regionWriteMask_USR[8]; uint32_t regionWriteMask_SYS[8]; uint32_t regionReadMask_USR[8]; uint32_t regionReadMask_SYS[8]; uint32_t regionExecuteMask_USR[8]; uint32_t regionExecuteMask_SYS[8]; uint32_t regionWriteSet_USR[8]; uint32_t regionWriteSet_SYS[8]; uint32_t regionReadSet_USR[8]; uint32_t regionReadSet_SYS[8]; uint32_t regionExecuteSet_USR[8]; uint32_t regionExecuteSet_SYS[8]; armcpu_t *cpu; void setSingleRegionAccess(uint32_t dAccess, uint32_t iAccess, unsigned char num, uint32_t mask, uint32_t set); void maskPrecalc(); public: armcp15_t() : IDCode(0), cacheType(0), TCMSize(0), ctrl(0), DCConfig(0), ICConfig(0), writeBuffCtrl(0), und(0), DaccessPerm(0), IaccessPerm(0), protectBaseSize0(0), protectBaseSize1(0), protectBaseSize2(0), protectBaseSize3(0), protectBaseSize4(0), protectBaseSize5(0), protectBaseSize6(0), protectBaseSize7(0), cacheOp(0), DcacheLock(0), IcacheLock(0), ITCMRegion(0), DTCMRegion(0), processID(0), RAM_TAG(0), testState(0), cacheDbg(0), cpu(nullptr) { memset(&this->regionWriteMask_USR[0], 0, sizeof(this->regionWriteMask_USR)); memset(&this->regionWriteMask_SYS[0], 0, sizeof(this->regionWriteMask_SYS)); memset(&this->regionReadMask_USR[0], 0, sizeof(this->regionReadMask_USR)); memset(&this->regionReadMask_SYS[0], 0, sizeof(this->regionReadMask_SYS)); memset(&this->regionExecuteMask_USR[0], 0, sizeof(this->regionExecuteMask_USR)); memset(&this->regionExecuteMask_SYS[0], 0, sizeof(this->regionExecuteMask_SYS)); memset(&this->regionWriteSet_USR[0], 0, sizeof(this->regionWriteSet_USR)); memset(&this->regionWriteSet_SYS[0], 0, sizeof(this->regionWriteSet_SYS)); memset(&this->regionReadSet_USR[0], 0, sizeof(this->regionReadSet_USR)); memset(&this->regionReadSet_SYS[0], 0, sizeof(this->regionReadSet_SYS)); memset(&this->regionExecuteSet_USR[0], 0, sizeof(this->regionExecuteSet_USR)); memset(&this->regionExecuteSet_SYS[0], 0, sizeof(this->regionExecuteSet_SYS)); } bool reset(armcpu_t *c); bool dataProcess(uint8_t CRd, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2); bool load(uint8_t CRd, uint8_t adr); bool store(uint8_t CRd, uint8_t adr); bool moveCP2ARM(uint32_t *R, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2); bool moveARM2CP(uint32_t val, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2); bool isAccessAllowed(uint32_t address,uint32_t access); }; extern armcp15_t cp15; void maskPrecalc();