287 lines
6.3 KiB
C
287 lines
6.3 KiB
C
/**
|
|
* @file remap.c
|
|
* @brief remap source file
|
|
*
|
|
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#include <armv7-r/barriers.h>
|
|
#include <armv7-r/irq.h>
|
|
#include <core_id.h>
|
|
#include <part.h>
|
|
#include <reg.h>
|
|
#include <regs_base.h>
|
|
#include <remap/remap.h>
|
|
#include <reset_ip.h>
|
|
#include <scr_hw.h>
|
|
#include <sdrv_rstgen.h>
|
|
#include <sdrv_scr.h>
|
|
|
|
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;
|
|
}
|