arm-trusted-firmware/plat/renesas/rcar/plat_storage.c

424 lines
9.6 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) 2015-2017, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <string.h>
#include <platform_def.h>
#include <common/debug.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_storage.h>
#include <drivers/io/io_semihosting.h>
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
#include "io_common.h"
#include "io_rcar.h"
#include "io_memdrv.h"
#include "io_emmcdrv.h"
#include "io_private.h"
static uintptr_t emmcdrv_dev_handle;
static uintptr_t memdrv_dev_handle;
static uintptr_t rcar_dev_handle;
static uintptr_t boot_io_drv_id;
static const io_block_spec_t rcar_block_spec = {
.offset = FLASH0_BASE,
.length = FLASH0_SIZE
};
static const io_block_spec_t bl2_file_spec = {
.offset = BL2_IMAGE_ID,
};
static const io_block_spec_t bl31_file_spec = {
.offset = BL31_IMAGE_ID,
};
static const io_block_spec_t bl32_file_spec = {
.offset = BL32_IMAGE_ID,
};
static const io_block_spec_t bl33_file_spec = {
.offset = BL33_IMAGE_ID,
};
static const io_block_spec_t bl332_file_spec = {
.offset = BL332_IMAGE_ID,
};
static const io_block_spec_t bl333_file_spec = {
.offset = BL333_IMAGE_ID,
};
static const io_block_spec_t bl334_file_spec = {
.offset = BL334_IMAGE_ID,
};
static const io_block_spec_t bl335_file_spec = {
.offset = BL335_IMAGE_ID,
};
static const io_block_spec_t bl336_file_spec = {
.offset = BL336_IMAGE_ID,
};
static const io_block_spec_t bl337_file_spec = {
.offset = BL337_IMAGE_ID,
};
static const io_block_spec_t bl338_file_spec = {
.offset = BL338_IMAGE_ID,
};
#if TRUSTED_BOARD_BOOT
static const io_block_spec_t trusted_key_cert_file_spec = {
.offset = TRUSTED_KEY_CERT_ID,
};
static const io_block_spec_t bl31_key_cert_file_spec = {
.offset = SOC_FW_KEY_CERT_ID,
};
static const io_block_spec_t bl32_key_cert_file_spec = {
.offset = TRUSTED_OS_FW_KEY_CERT_ID,
};
static const io_block_spec_t bl33_key_cert_file_spec = {
.offset = NON_TRUSTED_FW_KEY_CERT_ID,
};
static const io_block_spec_t bl332_key_cert_file_spec = {
.offset = BL332_KEY_CERT_ID,
};
static const io_block_spec_t bl333_key_cert_file_spec = {
.offset = BL333_KEY_CERT_ID,
};
static const io_block_spec_t bl334_key_cert_file_spec = {
.offset = BL334_KEY_CERT_ID,
};
static const io_block_spec_t bl335_key_cert_file_spec = {
.offset = BL335_KEY_CERT_ID,
};
static const io_block_spec_t bl336_key_cert_file_spec = {
.offset = BL336_KEY_CERT_ID,
};
static const io_block_spec_t bl337_key_cert_file_spec = {
.offset = BL337_KEY_CERT_ID,
};
static const io_block_spec_t bl338_key_cert_file_spec = {
.offset = BL338_KEY_CERT_ID,
};
static const io_block_spec_t bl31_cert_file_spec = {
.offset = SOC_FW_CONTENT_CERT_ID,
};
static const io_block_spec_t bl32_cert_file_spec = {
.offset = TRUSTED_OS_FW_CONTENT_CERT_ID,
};
static const io_block_spec_t bl33_cert_file_spec = {
.offset = NON_TRUSTED_FW_CONTENT_CERT_ID,
};
static const io_block_spec_t bl332_cert_file_spec = {
.offset = BL332_CERT_ID,
};
static const io_block_spec_t bl333_cert_file_spec = {
.offset = BL333_CERT_ID,
};
static const io_block_spec_t bl334_cert_file_spec = {
.offset = BL334_CERT_ID,
};
static const io_block_spec_t bl335_cert_file_spec = {
.offset = BL335_CERT_ID,
};
static const io_block_spec_t bl336_cert_file_spec = {
.offset = BL336_CERT_ID,
};
static const io_block_spec_t bl337_cert_file_spec = {
.offset = BL337_CERT_ID,
};
static const io_block_spec_t bl338_cert_file_spec = {
.offset = BL338_CERT_ID,
};
#endif
static int32_t open_emmcdrv(const uintptr_t spec);
static int32_t open_memmap(const uintptr_t spec);
static int32_t open_rcar(const uintptr_t spec);
struct plat_io_policy {
uintptr_t *dev_handle;
uintptr_t image_spec;
int32_t(*check) (const uintptr_t spec);
};
static const struct plat_io_policy policies[] = {
[FIP_IMAGE_ID] = {
&memdrv_dev_handle,
(uintptr_t) &rcar_block_spec,
&open_memmap},
[BL2_IMAGE_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl2_file_spec,
&open_rcar},
[BL31_IMAGE_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl31_file_spec,
&open_rcar},
[BL32_IMAGE_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl32_file_spec,
&open_rcar},
[BL33_IMAGE_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl33_file_spec,
&open_rcar},
[BL332_IMAGE_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl332_file_spec,
&open_rcar},
[BL333_IMAGE_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl333_file_spec,
&open_rcar},
[BL334_IMAGE_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl334_file_spec,
&open_rcar},
[BL335_IMAGE_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl335_file_spec,
&open_rcar},
[BL336_IMAGE_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl336_file_spec,
&open_rcar},
[BL337_IMAGE_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl337_file_spec,
&open_rcar},
[BL338_IMAGE_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl338_file_spec,
&open_rcar},
#if TRUSTED_BOARD_BOOT
[TRUSTED_KEY_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &trusted_key_cert_file_spec,
&open_rcar},
[SOC_FW_KEY_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl31_key_cert_file_spec,
&open_rcar},
[TRUSTED_OS_FW_KEY_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl32_key_cert_file_spec,
&open_rcar},
[NON_TRUSTED_FW_KEY_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl33_key_cert_file_spec,
&open_rcar},
[BL332_KEY_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl332_key_cert_file_spec,
&open_rcar},
[BL333_KEY_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl333_key_cert_file_spec,
&open_rcar},
[BL334_KEY_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl334_key_cert_file_spec,
&open_rcar},
[BL335_KEY_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl335_key_cert_file_spec,
&open_rcar},
[BL336_KEY_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl336_key_cert_file_spec,
&open_rcar},
[BL337_KEY_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl337_key_cert_file_spec,
&open_rcar},
[BL338_KEY_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl338_key_cert_file_spec,
&open_rcar},
[SOC_FW_CONTENT_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl31_cert_file_spec,
&open_rcar},
[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl32_cert_file_spec,
&open_rcar},
[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl33_cert_file_spec,
&open_rcar},
[BL332_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl332_cert_file_spec,
&open_rcar},
[BL333_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl333_cert_file_spec,
&open_rcar},
[BL334_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl334_cert_file_spec,
&open_rcar},
[BL335_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl335_cert_file_spec,
&open_rcar},
[BL336_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl336_cert_file_spec,
&open_rcar},
[BL337_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl337_cert_file_spec,
&open_rcar},
[BL338_CERT_ID] = {
&rcar_dev_handle,
(uintptr_t) &bl338_cert_file_spec,
&open_rcar}, {
#else
{
#endif
0, 0, 0}
};
static io_drv_spec_t io_drv_spec_memdrv = {
FLASH0_BASE,
FLASH0_SIZE,
0,
};
static io_drv_spec_t io_drv_spec_emmcdrv = {
0,
0,
0,
};
static struct plat_io_policy drv_policies[]
__attribute__ ((section(".data"))) = {
/* FLASH_DEV_ID */
{
&memdrv_dev_handle,
(uintptr_t) &io_drv_spec_memdrv, &open_memmap,},
/* EMMC_DEV_ID */
{
&emmcdrv_dev_handle,
(uintptr_t) &io_drv_spec_emmcdrv, &open_emmcdrv,}
};
static int32_t open_rcar(const uintptr_t spec)
{
return io_dev_init(rcar_dev_handle, boot_io_drv_id);
}
static int32_t open_memmap(const uintptr_t spec)
{
uintptr_t handle;
int32_t result;
result = io_dev_init(memdrv_dev_handle, 0);
if (result != IO_SUCCESS)
return result;
result = io_open(memdrv_dev_handle, spec, &handle);
if (result == IO_SUCCESS)
io_close(handle);
return result;
}
static int32_t open_emmcdrv(const uintptr_t spec)
{
return io_dev_init(emmcdrv_dev_handle, 0);
}
void rcar_io_setup(void)
{
const io_dev_connector_t *memmap;
const io_dev_connector_t *rcar;
boot_io_drv_id = FLASH_DEV_ID;
rcar_register_io_dev(&rcar);
rcar_register_io_dev_memdrv(&memmap);
io_dev_open(rcar, 0, &rcar_dev_handle);
io_dev_open(memmap, 0, &memdrv_dev_handle);
}
void rcar_io_emmc_setup(void)
{
const io_dev_connector_t *rcar;
const io_dev_connector_t *emmc;
boot_io_drv_id = EMMC_DEV_ID;
rcar_register_io_dev(&rcar);
rcar_register_io_dev_emmcdrv(&emmc);
io_dev_open(rcar, 0, &rcar_dev_handle);
io_dev_open(emmc, 0, &emmcdrv_dev_handle);
}
int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
uintptr_t *image_spec)
{
const struct plat_io_policy *policy;
int result;
policy = &policies[image_id];
result = policy->check(policy->image_spec);
if (result != IO_SUCCESS)
return result;
*image_spec = policy->image_spec;
*dev_handle = *(policy->dev_handle);
return IO_SUCCESS;
}
int32_t plat_get_drv_source(uint32_t io_drv_id, uintptr_t *dev_handle,
uintptr_t *image_spec)
{
const struct plat_io_policy *policy;
int32_t result;
policy = &drv_policies[io_drv_id];
result = policy->check(policy->image_spec);
if (result != IO_SUCCESS)
return result;
*image_spec = policy->image_spec;
*dev_handle = *(policy->dev_handle);
return IO_SUCCESS;
}