This commit is contained in:
2025-12-24 17:21:08 +09:00
parent a96323de19
commit 96dc62d8dc
2302 changed files with 455822 additions and 0 deletions

View 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) */