mirror of
https://github.com/CTCaer/switch-l4t-atf.git
synced 2024-11-23 09:49:39 +00:00
Tegra210: switch to new r2p smc command
Additionally simplify checks in platform setup.
This commit is contained in:
parent
45110f9628
commit
8902c539ce
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||||
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
|
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
|
||||||
|
* Copyright (c) 2021-2022, CTCaer.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
|
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
|
||||||
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
|
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
|
||||||
|
* Copyright (c) 2021-2022, CTCaer.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
@ -46,7 +47,7 @@ typedef struct uart_clock
|
|||||||
* Table of regions to map using the MMU.
|
* Table of regions to map using the MMU.
|
||||||
*/
|
*/
|
||||||
static const mmap_region_t tegra_mmap[] = {
|
static const mmap_region_t tegra_mmap[] = {
|
||||||
MAP_REGION_FLAT(TEGRA_IRAM_BASE, 0x40000, /* 256KB */
|
MAP_REGION_FLAT(TEGRA_IRAM_BASE, TEGRA_IRAM_SIZE,
|
||||||
MT_DEVICE | MT_RW | MT_SECURE),
|
MT_DEVICE | MT_RW | MT_SECURE),
|
||||||
MAP_REGION_FLAT(MMIO_RANGE_0_ADDR, MMIO_RANGE_SIZE,
|
MAP_REGION_FLAT(MMIO_RANGE_0_ADDR, MMIO_RANGE_SIZE,
|
||||||
MT_DEVICE | MT_RW | MT_SECURE),
|
MT_DEVICE | MT_RW | MT_SECURE),
|
||||||
@ -279,19 +280,20 @@ static const interrupt_prop_t tegra210_interrupt_props[] = {
|
|||||||
void plat_late_platform_setup(void)
|
void plat_late_platform_setup(void)
|
||||||
{
|
{
|
||||||
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
|
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
|
||||||
uint32_t *iram_entry_op = (uint32_t *)(TEGRA_IRAM_BASE + TEGRA_IRAM_A_SIZE);
|
|
||||||
uint64_t __attribute__((unused)) sc7entry_end, r2p_payload_end;
|
|
||||||
int __attribute__((unused)) ret;
|
int __attribute__((unused)) ret;
|
||||||
uint64_t offset = 0;
|
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
/* memmap TZDRAM area containing the r2p payload firmware */
|
/* memmap TZDRAM area containing the r2p payload firmware */
|
||||||
if (plat_params->r2p_payload_base) {
|
if (plat_params->r2p_payload_base) {
|
||||||
/* r2p payload must be _before_ BL31 base */
|
/* r2p payload must be _before_ BL31 base */
|
||||||
assert(plat_params->tzdram_base > plat_params->r2p_payload_base);
|
if (!(plat_params->flags & TEGRA_PLAT_SC7_NO_BASE_RESTRICTION)) {
|
||||||
r2p_payload_end = plat_params->r2p_payload_base +
|
assert(plat_params->tzdram_base >
|
||||||
plat_params->r2p_payload_size;
|
plat_params->r2p_payload_base);
|
||||||
assert(r2p_payload_end < plat_params->tzdram_base);
|
|
||||||
|
assert((plat_params->r2p_payload_base +
|
||||||
|
plat_params->r2p_payload_size) <
|
||||||
|
plat_params->tzdram_base);
|
||||||
|
}
|
||||||
|
|
||||||
/* memmap r2p payload firmware code */
|
/* memmap r2p payload firmware code */
|
||||||
ret = mmap_add_dynamic_region(plat_params->r2p_payload_base,
|
ret = mmap_add_dynamic_region(plat_params->r2p_payload_base,
|
||||||
@ -299,9 +301,6 @@ void plat_late_platform_setup(void)
|
|||||||
plat_params->r2p_payload_size,
|
plat_params->r2p_payload_size,
|
||||||
MT_SECURE | MT_RO_DATA);
|
MT_SECURE | MT_RO_DATA);
|
||||||
assert(ret == 0);
|
assert(ret == 0);
|
||||||
|
|
||||||
/* clear IRAM entry OP in IRAM */
|
|
||||||
*iram_entry_op = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* memmap TZDRAM area containing the SC7 Entry Firmware */
|
/* memmap TZDRAM area containing the SC7 Entry Firmware */
|
||||||
@ -313,18 +312,18 @@ void plat_late_platform_setup(void)
|
|||||||
* aperture, _before_ the BL31 code and the start address is
|
* aperture, _before_ the BL31 code and the start address is
|
||||||
* exactly 1MB from BL31 base.
|
* exactly 1MB from BL31 base.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* sc7entry-fw must be _before_ r2p payload base */
|
|
||||||
assert(plat_params->tzdram_base - offset > plat_params->sc7entry_fw_base);
|
|
||||||
|
|
||||||
sc7entry_end = plat_params->sc7entry_fw_base +
|
|
||||||
plat_params->sc7entry_fw_size;
|
|
||||||
assert(sc7entry_end < plat_params->tzdram_base - offset);
|
|
||||||
|
|
||||||
/* sc7entry-fw start must be exactly 1MB behind BL31 base */
|
|
||||||
offset = plat_params->tzdram_base - plat_params->sc7entry_fw_base;
|
|
||||||
if (!(plat_params->flags & TEGRA_PLAT_SC7_NO_BASE_RESTRICTION)) {
|
if (!(plat_params->flags & TEGRA_PLAT_SC7_NO_BASE_RESTRICTION)) {
|
||||||
assert(offset == 0x100000);
|
/* sc7entry-fw must be _before_ r2p payload base */
|
||||||
|
assert(plat_params->tzdram_base >
|
||||||
|
plat_params->sc7entry_fw_base);
|
||||||
|
|
||||||
|
assert((plat_params->sc7entry_fw_base +
|
||||||
|
plat_params->sc7entry_fw_size) <
|
||||||
|
plat_params->tzdram_base);
|
||||||
|
|
||||||
|
/* sc7entry-fw start must be 1MB behind BL31 base */
|
||||||
|
assert((plat_params->tzdram_base -
|
||||||
|
plat_params->sc7entry_fw_base) == 0x100000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* power off BPMP processor until SC7 entry */
|
/* power off BPMP processor until SC7 entry */
|
||||||
@ -345,7 +344,7 @@ void plat_late_platform_setup(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(plat_params->flags & TEGRA_PLAT_SC7_NO_BASE_RESTRICTION) &&
|
if (!(plat_params->flags & TEGRA_PLAT_SC7_NO_BASE_RESTRICTION) &&
|
||||||
(plat_params->sc7entry_fw_base || plat_params->r2p_payload_base)) {
|
(plat_params->sc7entry_fw_base || plat_params->r2p_payload_base)) {
|
||||||
/* secure TZDRAM area, increased by 1MB */
|
/* secure TZDRAM area, increased by 1MB */
|
||||||
tegra_memctrl_tzdram_setup(plat_params->tzdram_base - 0x100000,
|
tegra_memctrl_tzdram_setup(plat_params->tzdram_base - 0x100000,
|
||||||
|
@ -48,46 +48,19 @@
|
|||||||
#define R2P_WRITE_IRAM (0U << 0)
|
#define R2P_WRITE_IRAM (0U << 0)
|
||||||
#define R2P_READ_IRAM (1U << 0)
|
#define R2P_READ_IRAM (1U << 0)
|
||||||
#define TEGRA_SIP_R2P_DO_REBOOT U(0xC2FFFE03)
|
#define TEGRA_SIP_R2P_DO_REBOOT U(0xC2FFFE03)
|
||||||
|
#define TEGRA_SIP_R2P_SET_CFG U(0xC2FFFE04)
|
||||||
|
|
||||||
|
uint64_t r2p_bcfg[4];
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* R2P Copy to IRAM SMC implementation
|
* R2P Set Configuration SMC implementation
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
static int r2p_iram_copy(uint64_t dram_addr, uint64_t iram_addr, uint32_t size, uint32_t flag)
|
static int r2p_set_cfg(uint64_t cfg0, uint64_t cfg1, uint64_t cfg2, uint64_t cfg3)
|
||||||
{
|
{
|
||||||
volatile uint32_t *src, *dst;
|
r2p_bcfg[0] = cfg0;
|
||||||
uint64_t dram_aligned_addr = TEGRA_ALIGN_DOWN(dram_addr, PAGE_SIZE);
|
r2p_bcfg[1] = cfg1;
|
||||||
uint32_t dram_aligned_size = TEGRA_ALIGN(size + (dram_addr - dram_aligned_addr), PAGE_SIZE);
|
r2p_bcfg[2] = cfg2;
|
||||||
|
r2p_bcfg[3] = cfg3;
|
||||||
/* Error out if invalid or not 32-bit aligned */
|
|
||||||
if (dram_addr < TEGRA_DRAM_BASE || iram_addr < TEGRA_IRAM_BASE ||
|
|
||||||
(iram_addr + size) > (TEGRA_IRAM_BASE + TEGRA_IRAM_SIZE) ||
|
|
||||||
dram_addr & 3 || iram_addr & 3 || size & 3) {
|
|
||||||
ERROR("%s: Invalid parameters dst: %x, src: %x, size: %x\n",
|
|
||||||
__func__, (uint32_t)dram_addr, (uint32_t)iram_addr, size);
|
|
||||||
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map source memory region */
|
|
||||||
mmap_add_dynamic_region(dram_aligned_addr,
|
|
||||||
dram_aligned_addr,
|
|
||||||
dram_aligned_size,
|
|
||||||
MT_MEMORY | MT_RW | MT_NS | MT_EXECUTE_NEVER);
|
|
||||||
|
|
||||||
if (flag & R2P_READ_IRAM) {
|
|
||||||
src = (uint32_t *)iram_addr;
|
|
||||||
dst = (uint32_t *)dram_addr;
|
|
||||||
} else {
|
|
||||||
src = (uint32_t *)dram_addr;
|
|
||||||
dst = (uint32_t *)iram_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy payload */
|
|
||||||
(void)memcpy((void *)(uintptr_t)dst, (const void *)src, size);
|
|
||||||
|
|
||||||
/* Flush data and remove source memory region */
|
|
||||||
flush_dcache_range((uintptr_t)dst, size);
|
|
||||||
mmap_remove_dynamic_region(dram_aligned_addr, dram_aligned_size);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -96,27 +69,25 @@ static int r2p_iram_copy(uint64_t dram_addr, uint64_t iram_addr, uint32_t size,
|
|||||||
* This function is responsible for copying default payload if current is empty
|
* This function is responsible for copying default payload if current is empty
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
static void r2p_ensure_payload_exists(const plat_params_from_bl2_t *plat_params)
|
static void r2p_prepare_payload(const plat_params_from_bl2_t *plat_params)
|
||||||
{
|
{
|
||||||
uint64_t payload_address = TEGRA_IRAM_BASE + TEGRA_IRAM_A_SIZE;
|
uintptr_t payload_address = TEGRA_IRAM_BASE + TEGRA_IRAM_A_SIZE;
|
||||||
uint32_t payload_entry_op = *(uint32_t *)(payload_address);
|
uintptr_t payload_bootcfg = payload_address + 0x94;
|
||||||
|
|
||||||
if (payload_entry_op == 0) {
|
if (plat_params->r2p_payload_base) {
|
||||||
if(plat_params->r2p_payload_base && plat_params->r2p_payload_size) {
|
/* Clean up IRAM of any cruft */
|
||||||
WARN("R2P payload is empty! Using default..\n");
|
zeromem((void *)(uintptr_t)TEGRA_IRAM_BASE, TEGRA_IRAM_SIZE);
|
||||||
|
|
||||||
/* Clean up IRAM of any cruft */
|
/* Copy r2p payload */
|
||||||
zeromem((void *)(uintptr_t)TEGRA_IRAM_BASE,
|
(void)memcpy((void *)payload_address,
|
||||||
TEGRA_IRAM_SIZE);
|
(const void *)(plat_params->r2p_payload_base),
|
||||||
|
plat_params->r2p_payload_size);
|
||||||
|
|
||||||
/* Copy default r2p payload */
|
/* Copy boot configuration */
|
||||||
(void)memcpy((void *)(uintptr_t)payload_address,
|
(void)memcpy((void *)payload_bootcfg, r2p_bcfg, sizeof(r2p_bcfg));
|
||||||
(const void *)(plat_params->r2p_payload_base),
|
} else {
|
||||||
plat_params->r2p_payload_size);
|
ERROR("No R2P payload! Rebooting normally..\n");
|
||||||
} else {
|
tegra_pmc_system_reset();
|
||||||
ERROR("R2P payload is empty! Rebooting normally..\n");
|
|
||||||
tegra_pmc_system_reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,8 +99,8 @@ void r2p_reboot_to_payload()
|
|||||||
uint32_t val;
|
uint32_t val;
|
||||||
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
|
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
|
||||||
|
|
||||||
/* Make sure we have a payload in place */
|
/* Place payload and copy boot configuration */
|
||||||
r2p_ensure_payload_exists(plat_params);
|
r2p_prepare_payload(plat_params);
|
||||||
|
|
||||||
/* Set reset type to warmboot */
|
/* Set reset type to warmboot */
|
||||||
val = tegra_pmc_read_32(PMC_SCRATCH0) | PMC_SCRATCH0_MODE_WARMBOOT;
|
val = tegra_pmc_read_32(PMC_SCRATCH0) | PMC_SCRATCH0_MODE_WARMBOOT;
|
||||||
@ -151,7 +122,7 @@ void r2p_reboot_to_payload()
|
|||||||
val &= ~PMC_SECURITY_EN_BIT;
|
val &= ~PMC_SECURITY_EN_BIT;
|
||||||
mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val);
|
mmio_write_32(TEGRA_MISC_BASE + APB_SLAVE_SECURITY_ENABLE, val);
|
||||||
|
|
||||||
/* Allow non-secure writes to reset vectors for SC7Exit */
|
/* Allow non-secure writes to reset vectors */
|
||||||
plat_secure_cpu_vectors(false);
|
plat_secure_cpu_vectors(false);
|
||||||
|
|
||||||
tegra_pmc_system_reset();
|
tegra_pmc_system_reset();
|
||||||
@ -223,16 +194,16 @@ int plat_sip_handler(uint32_t smc_fid,
|
|||||||
} else {
|
} else {
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
} else if (smc_fid == TEGRA_SIP_R2P_COPY_TO_IRAM) {
|
} else if (!tegra_chipid_is_t210_b01()) {
|
||||||
if (!tegra_chipid_is_t210_b01())
|
if (smc_fid == TEGRA_SIP_R2P_COPY_TO_IRAM) {
|
||||||
return r2p_iram_copy(x1, x2, x3, x4);
|
return -ENOTSUP;
|
||||||
else
|
} else if (smc_fid == TEGRA_SIP_R2P_DO_REBOOT) {
|
||||||
return -ENOTSUP;
|
|
||||||
} else if (smc_fid == TEGRA_SIP_R2P_DO_REBOOT) {
|
|
||||||
if (!tegra_chipid_is_t210_b01())
|
|
||||||
r2p_reboot_to_payload();
|
r2p_reboot_to_payload();
|
||||||
else
|
} else if (TEGRA_SIP_R2P_SET_CFG) {
|
||||||
|
return r2p_set_cfg(x1, x2, x3, x4);
|
||||||
|
} else {
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user