arm-trusted-firmware/plat/renesas/rcar/aarch64/platform_common.c

270 lines
7.8 KiB
C
Raw Normal View History

rcar-gen3: initial commit for the rcar-gen3 boards Reference code: ============== rar_gen3: IPL and Secure Monitor Rev1.0.22 https://github.com/renesas-rcar/arm-trusted-firmware [rcar_gen3] Author: Takuya Sakata <takuya.sakata.wz@bp.renesas.com> Date: Thu Aug 30 21:26:41 2018 +0900 Update IPL and Secure Monitor Rev1.0.22 General Information: =================== This port has been tested on the Salvator-X Soc_id r8a7795 revision ES1.1 (uses an SPD). Build Tested: ------------- ATFW_OPT="LSI=H3 RCAR_DRAM_SPLIT=1 RCAR_LOSSY_ENABLE=1" MBEDTLS_DIR=$mbedtls $ make clean bl2 bl31 rcar PLAT=rcar ${ATFW_OPT} SPD=opteed Other dependencies: ------------------ * mbed_tls: git@github.com:ARMmbed/mbedtls.git [devel] Merge: 68dbc94 f34a4c1 Author: Simon Butcher <simon.butcher@arm.com> Date: Thu Aug 30 00:57:28 2018 +0100 * optee_os: https://github.com/BayLibre/optee_os Until it gets merged into OP-TEE, the port requires Renesas' Trusted Environment with a modification to support power management. Author: Jorge Ramirez-Ortiz <jramirez@baylibre.com> Date: Thu Aug 30 16:49:49 2018 +0200 plat-rcar: cpu-suspend: handle the power level Signed-off-by: Jorge Ramirez-Ortiz <jramirez@baylibre.com> * u-boot: The port has beent tested using mainline uboot. Author: Fabio Estevam <festevam@gmail.com> Date: Tue Sep 4 10:23:12 2018 -0300 *linux: The port has beent tested using mainline kernel. Author: Linus Torvalds <torvalds@linux-foundation.org> Date: Sun Sep 16 11:52:37 2018 -0700 Linux 4.19-rc4 Overview --------- BOOTROM starts the cpu at EL3; In this port BL2 will therefore be entered at this exception level (the Renesas' ATF reference tree [1] resets into EL1 before entering BL2 - see its bl2.ld.S) BL2 initializes DDR (and i2c to talk to the PMIC on some platforms) before determining the boot reason (cold or warm). During suspend all CPUs are switched off and the DDR is put in backup mode (some kind of self-refresh mode). This means that BL2 is always entered in a cold boot scenario. Once BL2 boots, it determines the boot reason, writes it to shared memory (BOOT_KIND_BASE) together with the BL31 parameters (PARAMS_BASE) and jumps to BL31. To all effects, BL31 is as if it is being entered in reset mode since it still needs to initialize the rest of the cores; this is the reason behind using direct shared memory access to BOOT_KIND_BASE and PARAMS_BASE instead of using registers to get to those locations (see el3_common_macros.S and bl31_entrypoint.S for the RESET_TO_BL31 use case). Depending on the boot reason BL31 initializes the rest of the cores: in case of suspend, it uses a MBOX memory region to recover the program counters. [1] https://github.com/renesas-rcar/arm-trusted-firmware Tests ----- * cpuidle ------- enable kernel's cpuidle arm_idle driver and boot * system suspend -------------- $ cat suspend.sh #!/bin/bash i2cset -f -y 7 0x30 0x20 0x0F read -p "Switch off SW23 and press return " foo echo mem > /sys/power/state * cpu hotplug: ------------ $ cat offline.sh #!/bin/bash nbr=$1 echo 0 > /sys/devices/system/cpu/cpu$nbr/online printf "ONLINE: " && cat /sys/devices/system/cpu/online printf "OFFLINE: " && cat /sys/devices/system/cpu/offline $ cat online.sh #!/bin/bash nbr=$1 echo 1 > /sys/devices/system/cpu/cpu$nbr/online printf "ONLINE: " && cat /sys/devices/system/cpu/online printf "OFFLINE: " && cat /sys/devices/system/cpu/offline Signed-off-by: ldts <jramirez@baylibre.com>
2018-09-23 08:36:13 +01:00
/*
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <bl_common.h>
#include <debug.h>
#include <gicv2.h>
#include <gic_common.h>
#include <interrupt_props.h>
#include <mmio.h>
#include <platform.h>
#include <platform_def.h>
#include <xlat_tables_v2.h>
#include "rcar_def.h"
#include "rcar_private.h"
#include "rcar_version.h"
#if (IMAGE_BL2)
extern void rcar_read_certificate(uint64_t cert, uint32_t *len, uintptr_t *p);
extern int32_t rcar_get_certificate(const int32_t name, uint32_t *cert);
#endif
const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]
__attribute__ ((__section__("ro"))) = VERSION_OF_RENESAS;
#define MAP_SHARED_RAM MAP_REGION_FLAT(RCAR_SHARED_MEM_BASE, \
RCAR_SHARED_MEM_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#define MAP_FLASH0 MAP_REGION_FLAT(FLASH0_BASE, \
FLASH0_SIZE, \
MT_MEMORY | MT_RO | MT_SECURE)
#define MAP_DRAM1_NS MAP_REGION_FLAT(DRAM1_NS_BASE, \
DRAM1_NS_SIZE, \
MT_MEMORY | MT_RW | MT_NS)
#define MAP_DEVICE_RCAR MAP_REGION_FLAT(DEVICE_RCAR_BASE, \
DEVICE_RCAR_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
#define MAP_DEVICE_RCAR2 MAP_REGION_FLAT(DEVICE_RCAR_BASE2, \
DEVICE_RCAR_SIZE2, \
MT_DEVICE | MT_RW | MT_SECURE)
#define MAP_SRAM MAP_REGION_FLAT(DEVICE_SRAM_BASE, \
DEVICE_SRAM_SIZE, \
MT_MEMORY | MT_RO | MT_SECURE)
#define MAP_SRAM_STACK MAP_REGION_FLAT(DEVICE_SRAM_STACK_BASE, \
DEVICE_SRAM_STACK_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#define MAP_ATFW_CRASH MAP_REGION_FLAT(RCAR_BL31_CRASH_BASE, \
RCAR_BL31_CRASH_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#define MAP_ATFW_LOG MAP_REGION_FLAT(RCAR_BL31_LOG_BASE, \
RCAR_BL31_LOG_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
#if IMAGE_BL2
#define MAP_DRAM0 MAP_REGION_FLAT(DRAM1_BASE, \
DRAM1_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#define MAP_REG0 MAP_REGION_FLAT(DEVICE_RCAR_BASE, \
DEVICE_RCAR_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
#define MAP_RAM0 MAP_REGION_FLAT(RCAR_SYSRAM_BASE, \
RCAR_SYSRAM_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#define MAP_REG1 MAP_REGION_FLAT(REG1_BASE, \
REG1_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
#define MAP_ROM MAP_REGION_FLAT(ROM0_BASE, \
ROM0_SIZE, \
MT_MEMORY | MT_RO | MT_SECURE)
#define MAP_REG2 MAP_REGION_FLAT(REG2_BASE, \
REG2_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
#define MAP_DRAM1 MAP_REGION_FLAT(DRAM_40BIT_BASE, \
DRAM_40BIT_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#endif
#ifdef BL32_BASE
#define MAP_BL32_MEM MAP_REGION_FLAT(BL32_BASE, \
BL32_LIMIT - BL32_BASE, \
MT_MEMORY | MT_RW | MT_SECURE)
#endif
#if IMAGE_BL2
const mmap_region_t rcar_mmap[] = {
MAP_FLASH0, /* 0x08000000 - 0x0BFFFFFF RPC area */
MAP_DRAM0, /* 0x40000000 - 0xBFFFFFFF DRAM area(Legacy) */
MAP_REG0, /* 0xE6000000 - 0xE62FFFFF SoC register area */
MAP_RAM0, /* 0xE6300000 - 0xE6303FFF System RAM area */
MAP_REG1, /* 0xE6400000 - 0xEAFFFFFF SoC register area */
MAP_ROM, /* 0xEB100000 - 0xEB127FFF boot ROM area */
MAP_REG2, /* 0xEC000000 - 0xFFFFFFFF SoC register area */
MAP_DRAM1, /* 0x0400000000 - 0x07FFFFFFFF DRAM area(4GB over) */
{0}
};
#endif
#if IMAGE_BL31
const mmap_region_t rcar_mmap[] = {
MAP_SHARED_RAM,
MAP_ATFW_CRASH,
MAP_ATFW_LOG,
MAP_DEVICE_RCAR,
MAP_DEVICE_RCAR2,
MAP_SRAM,
MAP_SRAM_STACK,
{0}
};
#endif
#if IMAGE_BL32
const mmap_region_t rcar_mmap[] = {
MAP_DEVICE0,
MAP_DEVICE1,
{0}
};
#endif
CASSERT(ARRAY_SIZE(rcar_mmap) + RCAR_BL_REGIONS
<= MAX_MMAP_REGIONS, assert_max_mmap_regions);
/*
* Macro generating the code for the function setting up the pagetables as per
* the platform memory map & initialize the mmu, for the given exception level
*/
#if USE_COHERENT_MEM
void rcar_configure_mmu_el3(unsigned long total_base,
unsigned long total_size,
unsigned long ro_start,
unsigned long ro_limit,
unsigned long coh_start,
unsigned long coh_limit)
{
mmap_add_region(total_base, total_base, total_size,
MT_MEMORY | MT_RW | MT_SECURE);
mmap_add_region(ro_start, ro_start, ro_limit - ro_start,
MT_MEMORY | MT_RO | MT_SECURE);
mmap_add_region(coh_start, coh_start, coh_limit - coh_start,
MT_DEVICE | MT_RW | MT_SECURE);
mmap_add(rcar_mmap);
init_xlat_tables();
enable_mmu_el3(0);
}
#else
void rcar_configure_mmu_el3(unsigned long total_base,
unsigned long total_size,
unsigned long ro_start,
unsigned long ro_limit)
{
mmap_add_region(total_base, total_base, total_size,
MT_MEMORY | MT_RW | MT_SECURE);
mmap_add_region(ro_start, ro_start, ro_limit - ro_start,
MT_MEMORY | MT_RO | MT_SECURE);
mmap_add(rcar_mmap);
init_xlat_tables();
enable_mmu_el3(0);
}
#endif
uintptr_t plat_get_ns_image_entrypoint(void)
{
#if (IMAGE_BL2)
uint32_t cert, len;
uintptr_t dst;
int32_t ret;
ret = rcar_get_certificate(NON_TRUSTED_FW_CONTENT_CERT_ID, &cert);
if (ret) {
ERROR("%s : cert file load error", __func__);
return NS_IMAGE_OFFSET;
}
rcar_read_certificate((uint64_t) cert, &len, &dst);
return dst;
#else
return NS_IMAGE_OFFSET;
#endif
}
unsigned int plat_get_syscnt_freq2(void)
{
unsigned int freq;
freq = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF);
if (freq == 0)
panic();
return freq;
}
void plat_rcar_gic_init(void)
{
gicv2_distif_init();
gicv2_pcpu_distif_init();
gicv2_cpuif_enable();
}
static const interrupt_prop_t interrupt_props[] = {
#if IMAGE_BL2
INTR_PROP_DESC(ARM_IRQ_SEC_WDT, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
#else
INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
INTR_PROP_DESC(ARM_IRQ_SEC_RPC, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
INTR_PROP_DESC(ARM_IRQ_SEC_TIMER, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
INTR_PROP_DESC(ARM_IRQ_SEC_TIMER_UP, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
INTR_PROP_DESC(ARM_IRQ_SEC_WDT, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
INTR_PROP_DESC(ARM_IRQ_SEC_CRYPT, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
INTR_PROP_DESC(ARM_IRQ_SEC_CRYPT_SecPKA, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
INTR_PROP_DESC(ARM_IRQ_SEC_CRYPT_PubPKA, GIC_HIGHEST_SEC_PRIORITY,
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
#endif
};
static const gicv2_driver_data_t plat_gicv2_driver_data = {
.interrupt_props = interrupt_props,
.interrupt_props_num = (uint32_t) ARRAY_SIZE(interrupt_props),
.gicd_base = RCAR_GICD_BASE,
.gicc_base = RCAR_GICC_BASE,
};
void plat_rcar_gic_driver_init(void)
{
gicv2_driver_init(&plat_gicv2_driver_data);
}