add IPL
This commit is contained in:
286
IPL/Customer/Mobis/Gen4_ICUMX_Loader/remap/remap.c
Normal file
286
IPL/Customer/Mobis/Gen4_ICUMX_Loader/remap/remap.c
Normal file
@@ -0,0 +1,286 @@
|
||||
/*******************************************************************************
|
||||
* DISCLAIMER
|
||||
* This software is supplied by Renesas Electronics Corporation and is only
|
||||
* intended for use with Renesas products. No other uses are authorized. This
|
||||
* software is owned by Renesas Electronics Corporation and is protected under
|
||||
* all applicable laws, including copyright laws.
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
|
||||
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
|
||||
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
||||
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
|
||||
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
|
||||
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
|
||||
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
|
||||
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
* Renesas reserves the right, without notice, to make changes to this software
|
||||
* and to discontinue the availability of this software. By using this software,
|
||||
* you agree to the additional terms and conditions found by accessing the
|
||||
* following link:
|
||||
* http://www.renesas.com/disclaimer
|
||||
* Copyright 2021-2023 Renesas Electronics Corporation All rights reserved.
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* DESCRIPTION : remap driver
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
* @file remap.c
|
||||
* - Version : 0.06
|
||||
* @brief 1. Setting of SIC REMAP AREA.
|
||||
* 2. Release of SIC REMAP AREA.
|
||||
* 3. Calculation of logical address.
|
||||
* 4. Calculation of physical address.
|
||||
* .
|
||||
*****************************************************************************/
|
||||
/******************************************************************************
|
||||
* History : DD.MM.YYYY Version Description
|
||||
* : 28.07.2021 0.01 First Release
|
||||
* : 03.09.2021 0.02 Modify remap_reg_write function to inline.
|
||||
* : 06.01.2022 0.03 Static analysis support
|
||||
* : 23.05.2022 0.04 Supported SICREMAP address for S4 ver1.0
|
||||
* S4/V4H differences applied to s_remap_tbl.
|
||||
* : 15.05.2023 0.05 Add get_cfremap_addr() function to jump
|
||||
* the secure firmware on CF remap Area.
|
||||
* : 21.08.2023 0.06 Add support for V4M.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <remap.h>
|
||||
#include <remap_register.h>
|
||||
#include <mem_io.h>
|
||||
#include <log.h>
|
||||
#include <inline_asm.h>
|
||||
|
||||
/* Range of SICREMAP2M register */
|
||||
#define REMAP_REG_MAX (16U)
|
||||
|
||||
#define REMAP_2M_BITS (21U)
|
||||
#define REMAP_2M_SIZE ((uint32_t)1U << REMAP_2M_BITS)
|
||||
#define REMAP_2M_MASK (REMAP_2M_SIZE - 1U)
|
||||
#define REMAP_TBL_MAX (sizeof(s_remap_tbl)/sizeof(s_remap_tbl[0]))
|
||||
#define REMAP_UNUSED (0xFFFFFFFFU)
|
||||
|
||||
typedef struct {
|
||||
uint32_t number;
|
||||
uint32_t address;
|
||||
}st_remap_address_table_t;
|
||||
|
||||
/* Remap management table */
|
||||
static st_remap_address_table_t s_remap_tbl[REMAP_REG_MAX] = {
|
||||
[0] = {REMAP_UNUSED, 0x00000000U},
|
||||
[1] = {REMAP_UNUSED, 0x00000000U},
|
||||
[2] = {REMAP_UNUSED, 0x00000000U},
|
||||
[3] = {REMAP_UNUSED, 0x00000000U},
|
||||
#if (RCAR_LSI == RCAR_S4)
|
||||
[4] = {4, 0xD8E00000}, /* MCU */
|
||||
#elif ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
|
||||
[4] = {REMAP_UNUSED, 0x00000000U},
|
||||
#endif
|
||||
[5] = {5, 0xE7600000U}, /* Region ID */
|
||||
[6] = {6, 0xE7200000U}, /* SYS-DMAC0 */
|
||||
[7] = {7, 0xE6400000U}, /* HSCIF */
|
||||
[8] = {8, 0xEE000000U}, /* MMC */
|
||||
[9] = {9, 0xE6E00000U}, /* SCIF */
|
||||
[10] = {10, 0xFFC00000U}, /* RT-DMAC0,PFC(MCU) */
|
||||
[11] = {11, 0xEE200000U}, /* RPC */
|
||||
[12] = {12, 0xE6200000U}, /* ECM,AP-System Core */
|
||||
[13] = {13, 0xE6000000U}, /* PFC,GPIO,CPGA,RESET */
|
||||
[14] = {14, 0xE6600000U}, /* CC63S,AXMM,QoS,FCPR */
|
||||
[15] = {15, 0xEB200000U}, /* RT-SRAM */
|
||||
};
|
||||
|
||||
static inline uint32_t get_sicremap2m_addr(uint32_t num)
|
||||
{
|
||||
return (REMAP_BASE + (num * 0x0004U));
|
||||
}
|
||||
/* End of function get_sicremap2m_addr(uint32_t num) */
|
||||
|
||||
static inline void remap_reg_write(uint32_t num, uint32_t value)
|
||||
{
|
||||
/* Specific write Procedure for Write-Protected Register. */
|
||||
do
|
||||
{
|
||||
mem_write32(ICUMX_PROT0PCMD, PROTCMD_START);
|
||||
mem_write32(get_sicremap2m_addr(num), value);
|
||||
mem_write32(get_sicremap2m_addr(num), ~value);
|
||||
mem_write32(get_sicremap2m_addr(num), value);
|
||||
} while (mem_read32(ICUMX_PROT0PS) == PROTS0ERR);
|
||||
}
|
||||
/* End of function remap_reg_write(uint32_t num, uint32_t value) */
|
||||
|
||||
void remap_register(uint32_t addr, uint32_t *remap_addr)
|
||||
{
|
||||
uint32_t loop;
|
||||
uint32_t set_addr;
|
||||
|
||||
/* Check unused area in order from the top of
|
||||
the remap management table. */
|
||||
for (loop = 0U; loop < REMAP_TBL_MAX; ++loop)
|
||||
{
|
||||
if (REMAP_UNUSED == s_remap_tbl[loop].number)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* When necessary area can not be secured */
|
||||
if (REMAP_TBL_MAX <= loop)
|
||||
{
|
||||
ERROR("There is no space in the logical address area.\n");
|
||||
panic;
|
||||
}
|
||||
|
||||
syncm();
|
||||
|
||||
/* Set remap area */
|
||||
set_addr = addr & ~REMAP_2M_MASK;
|
||||
|
||||
/* Update the table managing the remap space */
|
||||
s_remap_tbl[loop].address = set_addr;
|
||||
s_remap_tbl[loop].number = (uint8_t)loop;
|
||||
/* Set SICREMAP register */
|
||||
remap_reg_write(loop, set_addr);
|
||||
INFO("s_remap_tbl[%d].number = 0x%x\n",loop,s_remap_tbl[loop].number);
|
||||
INFO("s_remap_tbl[%d].address = 0x%x\n",loop,s_remap_tbl[loop].address);
|
||||
|
||||
syncm();
|
||||
|
||||
/* Calculating the logical address of the
|
||||
address received as an argument */
|
||||
*remap_addr = icu_remap_calc(loop);
|
||||
*remap_addr += addr & REMAP_2M_MASK;
|
||||
}
|
||||
/* End of function remap_register(uint32_t addr, uint32_t size, uint32_t *remap_addr) */
|
||||
|
||||
void remap_unregister(uint32_t remap_addr)
|
||||
{
|
||||
uint32_t loop;
|
||||
|
||||
/* Is the remap space where the address of the argument is used? */
|
||||
for (loop = 0U; loop < REMAP_TBL_MAX; ++loop)
|
||||
{
|
||||
INFO("s_remap_tbl[%d].number = 0x%x\n",loop,s_remap_tbl[loop].number);
|
||||
if ((REMAP_UNUSED != s_remap_tbl[loop].number)
|
||||
&& ((icu_remap_calc(loop) <= remap_addr)
|
||||
&& (remap_addr < icu_remap_calc(loop + 1U))))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* When an area to release can not be found */
|
||||
if (REMAP_TBL_MAX <= loop)
|
||||
{
|
||||
ERROR("Not registered in the logical address.\n"
|
||||
"remap address = 0x%x\n",remap_addr);
|
||||
panic;
|
||||
}
|
||||
syncm();
|
||||
|
||||
/* release remap area */
|
||||
/* Update the table managing the remap space */
|
||||
s_remap_tbl[loop].address = 0U;
|
||||
s_remap_tbl[loop].number = REMAP_UNUSED;
|
||||
/* Release SICREMAP register */
|
||||
remap_reg_write(loop, icu_remap_calc(loop));
|
||||
|
||||
syncm();
|
||||
}
|
||||
/* End of function remap_unregister(uint32_t remap_addr) */
|
||||
|
||||
uint32_t remap_get_phys_addr(uint32_t remap_addr)
|
||||
{
|
||||
uint32_t phys_addr;
|
||||
uint32_t reg;
|
||||
|
||||
/* It checks whether the argument is within the range
|
||||
of the logical address. */
|
||||
if ((ICU_REMAP0 > remap_addr)
|
||||
|| (icu_remap_calc(REMAP_REG_MAX) <= remap_addr))
|
||||
{
|
||||
ERROR("Address convert error.\n"
|
||||
"source address = 0x%x\n",remap_addr);
|
||||
panic;
|
||||
}
|
||||
|
||||
/* Calculate the physical address of the argument */
|
||||
phys_addr = remap_addr - ICU_REMAP0;
|
||||
phys_addr >>= REMAP_2M_BITS;
|
||||
reg = get_sicremap2m_addr(phys_addr);
|
||||
reg = mem_read32(reg);
|
||||
phys_addr = reg + (remap_addr & REMAP_2M_MASK);
|
||||
|
||||
return phys_addr;
|
||||
}
|
||||
/* End of function remap_get_phys_addr(uint32_t remap_addr) */
|
||||
|
||||
uint32_t remap_get_remap_addr(uint32_t phys_addr)
|
||||
{
|
||||
uint32_t remap_addr;
|
||||
uint32_t reg;
|
||||
uint32_t loop;
|
||||
|
||||
/* It checks whether the argument is within the range
|
||||
of the physical address registered in SICREMAP. */
|
||||
for (loop = 0U; loop < REMAP_REG_MAX; loop++)
|
||||
{
|
||||
reg = mem_read32(get_sicremap2m_addr(loop));
|
||||
if ((reg <= phys_addr)
|
||||
&& (phys_addr <= (reg + REMAP_2M_MASK)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* argument value is not used in the remap area. */
|
||||
if (REMAP_REG_MAX <= loop)
|
||||
{
|
||||
ERROR("Address convert error.\n"
|
||||
"source address = 0x%x\n",phys_addr);
|
||||
panic;
|
||||
}
|
||||
|
||||
/* Calculate the logical address of the argument */
|
||||
remap_addr = icu_remap_calc(loop);
|
||||
remap_addr += phys_addr - reg;
|
||||
|
||||
return remap_addr;
|
||||
}
|
||||
/* End of function remap_get_remap_addr(uint32_t phys_addr) */
|
||||
|
||||
uint32_t get_cfremap_addr(uint32_t fetch_addr)
|
||||
{
|
||||
uint32_t cf_remap_addr = 0x0U;
|
||||
uint32_t cf_current_base = mem_read32(ICUMX_CFREMAP);
|
||||
|
||||
/* Get current setting of "physical address for cf remap base",
|
||||
and calculate cf remap address of target fetch */
|
||||
cf_remap_addr = fetch_addr - cf_current_base;
|
||||
|
||||
/* Check whether the calculated address is outside of Code Fetch area */
|
||||
if ((CFREMAP_AREA_SIZE <= cf_remap_addr) || (fetch_addr < cf_current_base))
|
||||
{
|
||||
ERROR("Target fetch address is invalid: 0x%08x\n", fetch_addr);
|
||||
panic;
|
||||
}
|
||||
|
||||
return cf_remap_addr;
|
||||
}
|
||||
|
||||
void set_sicremap_s4v10(void)
|
||||
{
|
||||
#if (RCAR_LSI == RCAR_S4)
|
||||
/* Change the setting of SICREMAP for S4 Ver1.0 to be the setting of SICREMAP for S4 Ver1.1. */
|
||||
remap_reg_write(ICU_REMAP_NUM_RGID, ICU_REMAP_RGID); /* SIC REMAP5:Region ID */
|
||||
remap_reg_write(ICU_REMAP_NUM_MCU , ICU_REMAP_MCU); /* SIC REMAP4:MCU */
|
||||
#endif
|
||||
}
|
||||
/* End of function set_sicremap_s4v10(void) */
|
||||
|
||||
void set_sicremap_fcpr(void)
|
||||
{
|
||||
remap_reg_write(ICU_REMAP_NUM_FCPR, ICU_REMAP_FCPR); /* SIC REMAP14:FCPR */
|
||||
}
|
||||
/* End of function set_sicremap_fcpr(void) */
|
||||
|
||||
Reference in New Issue
Block a user