/** * @file remap.c * @brief remap source file * * @copyright Copyright (c) 2022 Semidrive Semiconductor. * All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include static sdrv_scr_t scr_ctrl = { .base = APB_SCR_SF_BASE, }; #ifdef CORE_SF static scr_signal_t sf_remap_scr[] = { SCR_SF_REMAP_CR5_SF_AR_ADDR_OFFSET_19_0, SCR_SF_REMAP_CR5_SF_AR_REMAP_EN, SCR_SF_REMAP_CR5_SF_AW_ADDR_OFFSET_19_0, SCR_SF_SCR_REMAP_CR5_SF_REMAP_EN, }; #endif #ifdef CORE_SP0 static scr_signal_t sp0_remap_scr[] = { SCR_SF_REMAP_CR5_SP_AR0_ADDR_OFFSET_19_0, SCR_SF_REMAP_CR5_SP_AR0_REMAP_EN, SCR_SF_REMAP_CR5_SP_AW0_ADDR_OFFSET_19_0, SCR_SF_REMAP_CR5_SP_AW0_REMAP_EN, }; #endif #ifdef CORE_SP1 static scr_signal_t sp1_remap_scr[] = { SCR_SF_REMAP_CR5_SP_AR1_ADDR_OFFSET_19_0, SCR_SF_REMAP_CR5_SP_AR1_REMAP_EN, SCR_SF_REMAP_CR5_SP_AW1_ADDR_OFFSET_19_0, SCR_SF_REMAP_CR5_SP_AW1_REMAP_EN, }; #endif #ifdef CORE_SX0 static scr_signal_t sx0_remap_scr[] = { SCR_SF_REMAP_CR5_SX_AR0_ADDR_OFFSET_19_0, SCR_SF_REMAP_CR5_SX_AR0_REMAP_EN, SCR_SF_REMAP_CR5_SX_AW0_ADDR_OFFSET_19_0, SCR_SF_REMAP_CR5_SX_AW0_REMAP_EN, }; #endif #ifdef CORE_SX1 static scr_signal_t sx1_remap_scr[] = { SCR_SF_REMAP_CR5_SX_AR1_ADDR_OFFSET_19_0, SCR_SF_REMAP_CR5_SX_AR1_REMAP_EN, SCR_SF_REMAP_CR5_SX_AW1_ADDR_OFFSET_19_0, SCR_SF_REMAP_CR5_SX_AW1_REMAP_EN, }; #endif static enum sdrv_remap_status sdrv_core_remap_scr_config(scr_signal_t *scrs, uint32_t mem_base) { mem_base >>= 12U; if ((scr_get(&scr_ctrl, &scrs[0]) == mem_base) && (scr_get(&scr_ctrl, &scrs[2]) == mem_base) && (scr_get(&scr_ctrl, &scrs[1]) == 0x1U) && (scr_get(&scr_ctrl, &scrs[3]) == 0x1U)) { return SDRV_REMAP_FAIL; } scr_set(&scr_ctrl, &scrs[0], mem_base); scr_set(&scr_ctrl, &scrs[1], 0x1U); scr_set(&scr_ctrl, &scrs[2], mem_base); scr_set(&scr_ctrl, &scrs[3], 0x1U); return SDRV_REMAP_OK; } /** * @brief Remap specific memory to exception table. * * This function remap memory to exception vector without reset. Remap info will be * valid after reset next time. * * @param [in] core core to be remap * @param [in] mem_base memory base * @return SDRV_REMAP_OK: reset core success, SDRV_REMAP_FAIL: reset core fail */ enum sdrv_remap_status sdrv_core_remap_without_reset(sdrv_remap_core_e core, uint32_t mem_base) { enum sdrv_remap_status ret = SDRV_REMAP_OK; scr_signal_t *scrs; if ((mem_base & 0xFFF) != 0) return SDRV_REMAP_FAIL; switch (core) { #ifdef CORE_SF case SDRV_REMAP_SF: scrs = &sf_remap_scr[0]; break; #endif #ifdef CORE_SP0 case SDRV_REMAP_SP0: scrs = &sp0_remap_scr[0]; break; #endif #ifdef CORE_SP1 case SDRV_REMAP_SP1: scrs = &sp1_remap_scr[0]; break; #endif #ifdef CORE_SX0 case SDRV_REMAP_SX0: scrs = &sx0_remap_scr[0]; break; #endif #ifdef CORE_SX1 case SDRV_REMAP_SX1: scrs = &sx1_remap_scr[0]; break; #endif default: return SDRV_REMAP_FAIL; } ret = sdrv_core_remap_scr_config(scrs, mem_base); if (ret == SDRV_REMAP_OK && core == SDRV_REMAP_SF) { RMWREG32(APB_IROMC_BASE + 0x4, 0, 1, 1); } DSB; ISB; return ret; } /** * @brief Remap specific memory to exception table. * * This function remap memory to exception vector, after call this * function, core will be reset. * * @param [in] core core to be remap * @param [in] mem_base memory base * @return SDRV_REMAP_OK: reset core success, SDRV_REMAP_FAIL: reset core fail */ enum sdrv_remap_status sdrv_core_remap(sdrv_remap_core_e core, uint32_t mem_base) { enum sdrv_remap_status ret = SDRV_REMAP_OK; sdrv_rstgen_sig_t *rst_sig; irq_state_t irq_stat; if ((mem_base & 0xFFF) != 0) return SDRV_REMAP_FAIL; switch (core) { #ifdef CORE_SF case SDRV_REMAP_SF: rst_sig = &rstsig_cr5_saf; break; #endif #ifdef CORE_SP0 case SDRV_REMAP_SP0: rst_sig = &rstsig_cr5_sp0; break; #endif #ifdef CORE_SP1 case SDRV_REMAP_SP1: rst_sig = &rstsig_cr5_sp1; break; #endif #ifdef CORE_SX0 case SDRV_REMAP_SX0: rst_sig = &rstsig_cr5_sx0; break; #endif #ifdef CORE_SX1 case SDRV_REMAP_SX1: rst_sig = &rstsig_cr5_sx1; break; #endif default: return SDRV_REMAP_FAIL; } irq_stat = arch_irq_save(); ret = sdrv_core_remap_without_reset(core, mem_base); if (ret == SDRV_REMAP_OK) { sdrv_rstgen_reset(rst_sig); } arch_irq_restore(irq_stat); return ret; } /** * @brief Force Remap specific memory to exception table. * * This function remap memory to exception vector, after call this * function, core will be reset. This function will force remap * and reset. * * @param [in] core core to be remap * @param [in] mem_base memory base * @return SDRV_REMAP_OK: reset core success, SDRV_REMAP_FAIL: reset core fail */ enum sdrv_remap_status sdrv_core_force_remap(sdrv_remap_core_e core, uint32_t mem_base) { sdrv_rstgen_sig_t *rst_sig; irq_state_t irq_stat; if ((mem_base & 0xFFF) != 0) return SDRV_REMAP_FAIL; switch (core) { #ifdef CORE_SF case SDRV_REMAP_SF: rst_sig = &rstsig_cr5_saf; break; #endif #ifdef CORE_SP0 case SDRV_REMAP_SP0: rst_sig = &rstsig_cr5_sp0; break; #endif #ifdef CORE_SP1 case SDRV_REMAP_SP1: rst_sig = &rstsig_cr5_sp1; break; #endif #ifdef CORE_SX0 case SDRV_REMAP_SX0: rst_sig = &rstsig_cr5_sx0; break; #endif #ifdef CORE_SX1 case SDRV_REMAP_SX1: rst_sig = &rstsig_cr5_sx1; break; #endif default: return SDRV_REMAP_FAIL; } irq_stat = arch_irq_save(); sdrv_core_remap_without_reset(core, mem_base); sdrv_rstgen_reset(rst_sig); arch_irq_restore(irq_stat); return SDRV_REMAP_OK; }