arm-trusted-firmware/plat/nvidia/tegra/common/tegra_sip_calls.c
Masahiro Yamada 57d1e5faf2 Fix pointer type mismatch of handlers
Commit 4c0d039076 ("Rework type usage in Trusted Firmware") changed
the type usage in struct declarations, but did not touch the definition
side.  Fix the type mismatch.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2018-04-27 18:35:02 +09:00

182 lines
4.7 KiB
C

/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
#include <bl_common.h>
#include <debug.h>
#include <errno.h>
#include <memctrl.h>
#include <mmio.h>
#include <runtime_svc.h>
#include <tegra_platform.h>
#include <tegra_private.h>
/*******************************************************************************
* Common Tegra SiP SMCs
******************************************************************************/
#define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003
#define TEGRA_SIP_FIQ_NS_ENTRYPOINT 0x82000005
#define TEGRA_SIP_FIQ_NS_GET_CONTEXT 0x82000006
#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND 0xC2000007
/*******************************************************************************
* Fake system suspend mode control var
******************************************************************************/
extern uint8_t tegra_fake_system_suspend;
/*******************************************************************************
* SoC specific SiP handler
******************************************************************************/
#pragma weak plat_sip_handler
int plat_sip_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
void *cookie,
void *handle,
uint64_t flags)
{
return -ENOTSUP;
}
/*******************************************************************************
* This function is responsible for handling all SiP calls
******************************************************************************/
uintptr_t tegra_sip_handler(uint32_t smc_fid,
u_register_t x1,
u_register_t x2,
u_register_t x3,
u_register_t x4,
void *cookie,
void *handle,
u_register_t flags)
{
uint32_t regval;
int err;
/* Check if this is a SoC specific SiP */
err = plat_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
if (err == 0)
SMC_RET1(handle, (uint64_t)err);
switch (smc_fid) {
case TEGRA_SIP_NEW_VIDEOMEM_REGION:
/* clean up the high bits */
x2 = (uint32_t)x2;
/*
* Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
* or falls outside of the valid DRAM range
*/
err = bl31_check_ns_address(x1, x2);
if (err)
SMC_RET1(handle, err);
/*
* Check if Video Memory is aligned to 1MB.
*/
if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) {
ERROR("Unaligned Video Memory base address!\n");
SMC_RET1(handle, -ENOTSUP);
}
/*
* The GPU is the user of the Video Memory region. In order to
* transition to the new memory region smoothly, we program the
* new base/size ONLY if the GPU is in reset mode.
*/
regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
TEGRA_GPU_RESET_REG_OFFSET);
if ((regval & GPU_RESET_BIT) == 0U) {
ERROR("GPU not in reset! Video Memory setup failed\n");
SMC_RET1(handle, -ENOTSUP);
}
/* new video memory carveout settings */
tegra_memctrl_videomem_setup(x1, x2);
SMC_RET1(handle, 0);
break;
/*
* The NS world registers the address of its handler to be
* used for processing the FIQ. This is normally used by the
* NS FIQ debugger driver to detect system hangs by programming
* a watchdog timer to fire a FIQ interrupt.
*/
case TEGRA_SIP_FIQ_NS_ENTRYPOINT:
if (!x1)
SMC_RET1(handle, SMC_UNK);
/*
* TODO: Check if x1 contains a valid DRAM address
*/
/* store the NS world's entrypoint */
tegra_fiq_set_ns_entrypoint(x1);
SMC_RET1(handle, 0);
break;
/*
* The NS world's FIQ handler issues this SMC to get the NS EL1/EL0
* CPU context when the FIQ interrupt was triggered. This allows the
* NS world to understand the CPU state when the watchdog interrupt
* triggered.
*/
case TEGRA_SIP_FIQ_NS_GET_CONTEXT:
/* retrieve context registers when FIQ triggered */
tegra_fiq_get_intr_context();
SMC_RET0(handle);
break;
case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
/*
* System suspend fake mode is set if we are on VDK and we make
* a debug SIP call. This mode ensures that we excercise debug
* path instead of the regular code path to suit the pre-silicon
* platform needs. These include replacing the call to WFI by
* a warm reset request.
*/
if (tegra_platform_is_emulation() != 0U) {
tegra_fake_system_suspend = 1;
SMC_RET1(handle, 0);
}
/*
* We return to the external world as if this SIP is not
* implemented in case, we are not running on VDK.
*/
break;
default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
break;
}
SMC_RET1(handle, SMC_UNK);
}
/* Define a runtime service descriptor for fast SMC calls */
DECLARE_RT_SVC(
tegra_sip_fast,
OEN_SIP_START,
OEN_SIP_END,
SMC_TYPE_FAST,
NULL,
tegra_sip_handler
);