Files
test/middleware/remap/remap.c
2025-11-07 20:19:23 +08:00

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;
}