/* * SitaraMcuIsolation.cpp * * Created on: 26.11.2024 * Author: zhih */ #include #include "SitaraMcuIsolation.hpp" #include "rat.h" namespace balluff { namespace bni_safe { namespace pal { namespace sitara { SitaraMcuIsolation::SitaraMcuIsolation() { util::SafeReturn status = util::SafeReturn::RET_ERROR; uint32_t pscMain2MCUDisable, pscMCU2MainDisable, debugIsolationEnable; /* Disabling Main2MCU PSC. This would restrict the main domain from accessing MCU domain peripherals/registers. Care must be taken no Main domain cores access MCU domain registers after this */ pscMain2MCUDisable = 1; /* Disabling MCU2Main PSC. This would restrict the MCU domain from accessing Main domain peripherals/registers. Care must be taken no MCU domain cores access Main domain registers after this */ pscMCU2MainDisable = 0; /* Enabling debug isolation will restrict the JTAG access to MCU domain */ debugIsolationEnable = 0; status = enableResetIsolation(pscMain2MCUDisable, pscMCU2MainDisable, debugIsolationEnable); kprintf(0, "SitaraMcuIsolation::SitaraMcuIsolation: status %x\n", status); } SitaraMcuIsolation::~SitaraMcuIsolation() { // TODO Auto-generated destructor stub } util::SafeReturn SitaraMcuIsolation::enableResetIsolation(uint32_t main2McuIsolation, uint32_t mcu2MainIsolation, uint32_t debugIsolationEnable) { uint32_t baseAddr = 0; util::SafeReturn status = util::SafeReturn::RET_OK; controlModuleUnlockMMR(6); controlModuleUnlockMMR(1); baseAddr = (uint32_t)AddrTranslateP_getLocalAddr(CSL_MCU_CTRL_MMR0_CFG0_BASE); /* Block MAIN domain reset: set bit 18 of CTRLMMR_RST_CTRL to 1.*/ REG32_FINS(baseAddr + CSL_MCU_CTRL_MMR_CFG0_RST_CTRL, 0x0040000U, 0x00000012U, 1); /* Enable timeout gasket */ REG32_FINS(baseAddr + CSL_MCU_CTRL_MMR_CFG0_MCU_MTOG_CTRL, 0x00008000U, 0x0000000FU, 1); /* Write a non zero value to Magic Word */ REG32_WR(baseAddr + CSL_MCU_CTRL_MMR_CFG0_RST_MAGIC_WORD, 0x1); if (debugIsolationEnable == 1) { /* Enable debug Isolation */ REG32_FINS(baseAddr + CSL_MCU_CTRL_MMR_CFG0_ISO_CTRL, 2, 1, 1); } /* Enable reset Isolation */ REG32_FINS(baseAddr + CSL_MCU_CTRL_MMR_CFG0_ISO_CTRL, 1, 0, 1); /* Block DMSC to trigger reset of MCU domain: set bit 16 of CTRLMMR_RST_CTRL to 1.*/ REG32_FINS(baseAddr + CSL_MCU_CTRL_MMR_CFG0_RST_CTRL, 0x00010000U, 0x00000010U, 1); if (main2McuIsolation == 1) { status = setPSCState(CSL_MCU_LPSC_MAIN2MCU, SOC_PSC_DISABLE); } if (status == util::SafeReturn::RET_OK) { if (mcu2MainIsolation == 1) { status = setPSCState(CSL_MCU_LPSC_MCU2MAIN, SOC_PSC_DISABLE); } } controlModuleLockMMR(6); controlModuleLockMMR(1); return status; } util::SafeReturn SitaraMcuIsolation::setPSCState(uint32_t moduleNum, uint32_t pscState) // 032 { util::SafeReturn status = util::SafeReturn::RET_OK; uint32_t baseAddr = 0; uint32_t loopCnt = 0; uint32_t pdTransStatus; baseAddr = (uint32_t)AddrTranslateP_getLocalAddr(CSL_MCU_PSC0_BASE); if (status == util::SafeReturn::RET_OK) { /* get value of bits 0-5 of PSC0_MDSTAT Register*/ if (REG32_FEXT(baseAddr + CSL_MCU_PSC0_MDSTAT, 0x0000003FU, 0x00000000U) == pscState) { ; } else { if (pscState == PSC_MODSTATE_ENABLE) { /* Power Domain Control: set bit NEXT to 1 */ REG32_FINS(baseAddr + CSL_MCU_PSC0_PDCTL, 1, 0, 1); } /* Enable the clock for the module: Module Next State: set bits 0-4 of NEXT to 2 */ REG32_FINS(baseAddr + CSL_MCU_PSC0_MDCTL, 0x1F, 0, pscState); /* Start the state transition */ /* write 1 at PSC_PTCMD */ REG32_WR(baseAddr + CSL_MCU_PSC0_PTCMD, 1); /* check pdTransStatus(Power Domain n Transition Command Status) until it is set */ do { pdTransStatus = REG32_RD(baseAddr + CSL_MCU_PSC0_PTSTAT) & 1U; loopCnt++; } while (pdTransStatus && (loopCnt < PSC_TIMEOUT)); if (pdTransStatus == 0) { status = util::SafeReturn::RET_OK; } else { status = util::SafeReturn::RET_ERROR; } } } return status; } void SitaraMcuIsolation::controlModuleLockMMR(uint32_t partition) { uint32_t baseAddr; uint32_t kickAddr; baseAddr = (uint32_t)AddrTranslateP_getLocalAddr(CSL_MCU_CTRL_MMR0_CFG0_BASE); kickAddr = baseAddr + (0x1008 + 0x4000 * (partition)); REG32_WR(kickAddr, KICK_LOCK_VAL); /* KICK 0 */ kickAddr++; REG32_WR(kickAddr, KICK_LOCK_VAL); /* KICK 1 */ return; } void SitaraMcuIsolation::controlModuleUnlockMMR(uint32_t partition) { uint32_t baseAddr; uint32_t kickAddr; baseAddr = (uint32_t)AddrTranslateP_getLocalAddr(CSL_MCU_CTRL_MMR0_CFG0_BASE); kickAddr = baseAddr + (0x1008 + 0x4000 * (partition)); REG32_WR(kickAddr, KICK0_UNLOCK_VAL); /* KICK 0 */ kickAddr++; REG32_WR(kickAddr, KICK1_UNLOCK_VAL); /* KICK 1 */ return; } } // namespace sitara } // namespace pal } // namespace bni_safe } // namespace balluff