blob: 48d4186ddf5b0d13ff8a248a71b019d605aa3856 [file] [log] [blame]
/*
* Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <debug.h>
#include <smccc.h>
#include <tftf_lib.h>
#include <xlat_tables_v2.h>
#include <platform_def.h>
/*******************************************************************************
* Common Tegra SiP SMCs
******************************************************************************/
#define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003ULL
#define TEGRA_SIP_GET_SMMU_PER 0xC200FF00ULL
/*
* @Test_Aim@ Test to issue VideoMem SiP SMC function IDs.
*
* This test runs on the lead CPU and issues TEGRA_SIP_NEW_VIDEOMEM_REGION
* SMC to resize the memory region.
*/
test_result_t test_sip_videomem_resize(void)
{
uint32_t size_in_bytes = (4U << 20);
uint32_t offset = (8U << 20);
uint64_t vidmem_base = DRAM_END, mem;
uint64_t buf[] = { 0xCAFEBABE, 0xCAFEBABE, 0xCAFEBABE, 0xCAFEBABE };
smc_args args = { TEGRA_SIP_NEW_VIDEOMEM_REGION, vidmem_base, size_in_bytes };
smc_ret_values ret;
test_result_t result = TEST_RESULT_SUCCESS;
int err;
/* Map dummy memory region for the test */
err = mmap_add_dynamic_region(vidmem_base, vidmem_base, size_in_bytes << 2,
MT_DEVICE | MT_RW | MT_NS | MT_EXECUTE_NEVER);
if (err != 0) {
tftf_testcase_printf("%s: could not map memory (%d)\n", __func__, err);
return TEST_RESULT_FAIL;
}
/* copy sample data before setting up the memory protections */
memcpy((char *)vidmem_base, (void *)buf, sizeof(buf));
flush_dcache_range(vidmem_base, sizeof(buf));
/* Issue the SMC to program videomem and expect success */
ret = tftf_smc(&args);
if (ret.ret0 != 0UL) {
tftf_testcase_printf("%s failed. Expected 0, received %ld\n",
__func__, (long int)ret.ret0);
result = TEST_RESULT_FAIL;
goto exit;
}
/* copy sample data before setting up the memory protections */
memcpy((char *)vidmem_base + offset, (void *)buf, sizeof(buf));
flush_dcache_range(vidmem_base + offset, sizeof(buf));
/* Issue request to "move" the protected memory region */
args.arg1 = vidmem_base + offset;
args.arg2 = (u_register_t)size_in_bytes;
ret = tftf_smc(&args);
if (ret.ret0 != 0UL) {
tftf_testcase_printf("%s failed. Expected 0, received %ld\n",
__func__, (long int)ret.ret0);
result = TEST_RESULT_FAIL;
goto exit;
}
/* Verify that memory in the open has been cleared */
mem = vidmem_base;
for (unsigned int i = 0U; i < (size_in_bytes / 8); i++, mem += 8) {
if (*(uint64_t *)(void *)mem != 0ULL) {
tftf_testcase_printf("%s failed. Memory is non-zero (%llx:%llx)\n",
__func__, mem, *(uint64_t *)(void *)mem);
result = TEST_RESULT_FAIL;
goto exit;
}
}
/* copy sample data before setting up the memory protections */
memcpy((char *)vidmem_base, (void *)buf, sizeof(buf));
flush_dcache_range(vidmem_base, sizeof(buf));
/* Issue request to "move" the protected memory region */
args.arg1 = vidmem_base;
args.arg2 = (u_register_t)size_in_bytes;
ret = tftf_smc(&args);
if (ret.ret0 != 0UL) {
tftf_testcase_printf("%s failed. Expected 0, received %ld\n",
__func__, (long int)ret.ret0);
result = TEST_RESULT_FAIL;
goto exit;
}
/* Verify that memory in the open has been cleared */
mem = vidmem_base + offset;
for (unsigned int i = 0U; i < (size_in_bytes / 8); i++, mem += 8) {
if (*(uint64_t *)(void *)mem != 0U) {
tftf_testcase_printf("%s failed. Memory is non-zero (%llx:%llx)\n",
__func__, mem, *(uint64_t *)(void *)mem);
result = TEST_RESULT_FAIL;
goto exit;
}
}
exit:
/* unmap dummy memory region */
err = mmap_remove_dynamic_region(vidmem_base, size_in_bytes << 2);
if (err != 0) {
tftf_testcase_printf("%s: could not unmap memory (%d)\n",
__func__, err);
result = TEST_RESULT_FAIL;
}
return result;
}
/*
* @Test_Aim@ Test to issue common SiP SMC function IDs.
*
* This test runs on the lead CPU and issues TEGRA_SIP_NEW_VIDEOMEM_REGION
* and tests positive and negative scenarios.
*/
test_result_t test_sip_videomem_incorrect_inputs(void)
{
smc_args args = { TEGRA_SIP_NEW_VIDEOMEM_REGION };
smc_ret_values ret;
/* Issue the SMC with no input parameters and expect error */
ret = tftf_smc(&args);
if (ret.ret0 == 0UL) {
tftf_testcase_printf("%s failed. Expected -1, received %ld\n",
__func__, (long int)ret.ret0);
return TEST_RESULT_FAIL;
}
/* Issue the SMC with incorrect parameters and expect error */
args.arg1 = 0x10000000ULL;
args.arg2 = 4ULL << 20;
ret = tftf_smc(&args);
if (ret.ret0 == 0UL) {
tftf_testcase_printf("%s failed. Expected -1, received %ld\n",
__func__, (long int)ret.ret0);
return TEST_RESULT_FAIL;
}
/* Issue the SMC with incorrect parameters and expect error */
args.arg1 = 0x40000000ULL;
args.arg2 = 4ULL << 20;
ret = tftf_smc(&args);
if (ret.ret0 == 0UL) {
tftf_testcase_printf("%s failed. Expected -1, received %ld\n",
__func__, (long int)ret.ret0);
return TEST_RESULT_FAIL;
}
/* Issue the SMC with incorrect parameters and expect error */
args.arg1 = DRAM_END - (4U << 20);
args.arg2 = 0x100ULL;
ret = tftf_smc(&args);
if (ret.ret0 == 0UL) {
tftf_testcase_printf("%s failed. Expected -1, received %ld\n",
__func__, (long int)ret.ret0);
return TEST_RESULT_FAIL;
}
/* Issue the SMC with incorrect parameters and expect error */
args.arg1 = DRAM_END - (4U << 20);
args.arg2 = 0ULL;
ret = tftf_smc(&args);
if (ret.ret0 == 0UL) {
tftf_testcase_printf("%s failed. Expected -1, received %ld\n",
__func__, (long int)ret.ret0);
return TEST_RESULT_FAIL;
}
/* Issue the SMC with incorrect parameters and expect error */
args.arg1 = 0ULL;
args.arg2 = 4ULL << 20;
ret = tftf_smc(&args);
if (ret.ret0 == 0UL) {
tftf_testcase_printf("%s failed. Expected -1, received %ld\n",
__func__, (long int)ret.ret0);
return TEST_RESULT_FAIL;
}
return TEST_RESULT_SUCCESS;
}
/**
* @Test_Aim@ Test to read the SMMU_PER register contents and print the
* values.
*/
test_result_t test_get_smmu_per(void)
{
smc_args tegra_sip_smc = { TEGRA_SIP_GET_SMMU_PER, 0ULL, 0ULL, 0ULL, 0ULL };
smc_ret_values ret;
tftf_testcase_printf("Tegra SIP GET SMMU PER test\n");
ret = tftf_smc(&tegra_sip_smc);
if (ret.ret0 != SMC_OK) {
tftf_testcase_printf("GET_SMMU_PER test Fail, got %ld\n", (long int)ret.ret0);
return TEST_RESULT_FAIL;
}
tftf_testcase_printf("GET_SMMU_PER per[0] = %lu\n", ret.ret1);
tftf_testcase_printf("GET_SMMU_PER per[1] = %lu\n", ret.ret2);
tftf_testcase_printf("GET_SMMU_PER per[2] = %lu\n", ret.ret3);
return TEST_RESULT_SUCCESS;
}