blob: 082439a90c6aa441c3a7f722b9bbf6f0fc604c26 [file] [log] [blame]
/*
* Copyright (c) 2018, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*******************************************************************************
* Test the FWU SMC interface in Trusted Firmware-A, which is implemented in
* BL1.
******************************************************************************/
#include <debug.h>
#include <errno.h>
#include <io_fip.h>
#include <platform_def.h>
#include <smccc.h>
#include <status.h>
#include <tftf.h>
#include <tftf_lib.h>
/* Expected number of SMC calls supported in BL1 */
#define BL1_NUM_SMC_CALLS 11
/* Expected version of BL1 SMC implementation */
#define BL1_SMC_VER_VALUE 1
typedef struct {
/* Description to print before sending the SMC */
const char *description;
/* The arguments to pass to the SMC */
const smc_args args;
/* The expected SMC return value */
u_register_t expect;
} ns_bl1u_test_t;
/*
* The tests consist in sending a succession of SMCs to trigger FWU operations
* in BL1. The order of the SMCs is important because they internally change the
* FWU state machine in Trusted Firmware-A.
*/
static const ns_bl1u_test_t tests[] = {
/* Basic FWU SMC handler test cases. */
{
.description = "BL1_SMC_CALL_COUNT",
.args = { BL1_SMC_CALL_COUNT, 0, 0, 0, 0 },
.expect = BL1_NUM_SMC_CALLS,
},
{
.description = "BL1_SMC_VERSION",
.args = { BL1_SMC_VERSION, 0, 0, 0, 0 },
.expect = BL1_SMC_VER_VALUE,
},
{
.description = "Invalid SMC",
.args = { 0xdeadbeef, 0, 0, 0, 0 },
.expect = SMC_UNKNOWN,
},
/* FWU_SMC_IMAGE_COPY test cases. */
{
.description = "IMAGE_COPY with invalid image_id",
.args = { FWU_SMC_IMAGE_COPY, 0xdeadbeef, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_COPY with non-secure image_id",
.args = { FWU_SMC_IMAGE_COPY, NS_BL2U_IMAGE_ID, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_COPY with valid args",
.args = { FWU_SMC_IMAGE_COPY, FWU_CERT_ID, PLAT_ARM_FWU_FIP_BASE, 0x20, 0x20 },
.expect = STATUS_SUCCESS,
},
{
.description = "IMAGE_COPY to copy an image_id again",
.args = { FWU_SMC_IMAGE_COPY, FWU_CERT_ID, PLAT_ARM_FWU_FIP_BASE, 0x20, 0x20 },
.expect = -EPERM,
},
{
.description = "IMAGE_COPY with source address not mapped",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, 0, 0, 0 },
.expect = -ENOMEM,
},
{
.description = "IMAGE_COPY with source size not mapped",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0xdeadbeef, 0xdeadbeef },
.expect = -ENOMEM,
},
{
.description = "IMAGE_COPY with image size more than secure mem",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x40000, 0x40000 },
.expect = -ENOMEM,
},
{
.description = "IMAGE_COPY with image size 0",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0, 0 },
.expect = -ENOMEM,
},
/*
* At this point, the FWU Certificate Image has been copied by a
* previous test. Try to load the BL2U image over it at the same
* address.
*/
{
.description = "IMAGE_COPY with an image that overlaps a different one",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x20, 0x40 },
.expect = -EPERM,
},
/*
* The authentication of the FWU certificate will fail, which will set
* the state of this image to "RESET" for the following tests.
*/
{
.description = "IMAGE_AUTH with an invalid image",
.args = { FWU_SMC_IMAGE_AUTH, FWU_CERT_ID, PLAT_ARM_FWU_FIP_BASE, 0x20, 0x20 },
.expect = -EAUTH,
},
{
.description = "IMAGE_COPY with 1st block size in partial copy",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x20, 0x40 },
.expect = STATUS_SUCCESS,
},
{
.description = "IMAGE_AUTH while copying the image",
.args = { FWU_SMC_IMAGE_AUTH, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x40, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_COPY with last block with invalid source in partial copy",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, 0, 0x21, 0x40 },
.expect = -ENOMEM,
},
{
.description = "IMAGE_COPY with last block size > total size in partial copy",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x21, 0x40 },
.expect = STATUS_SUCCESS,
},
{
.description = "IMAGE_AUTH to RESET the image state",
.args = { FWU_SMC_IMAGE_AUTH, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x40, 0 },
.expect = -EAUTH,
},
{
.description = "IMAGE_COPY with block size > total size",
.args = { FWU_SMC_IMAGE_COPY, BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0x21, 0x20 },
.expect = STATUS_SUCCESS,
},
{
.description = "IMAGE_RESET to RESET the image state",
.args = { FWU_SMC_IMAGE_RESET, BL2U_IMAGE_ID, 0, 0, 0 },
.expect = STATUS_SUCCESS,
},
/* FWU_SMC_IMAGE_AUTH test cases. */
{
.description = "IMAGE_AUTH with invalid image_id",
.args = { FWU_SMC_IMAGE_AUTH, 0, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_AUTH with secure image not copied",
.args = { FWU_SMC_IMAGE_AUTH, BL2U_IMAGE_ID, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_AUTH with source address not mapped",
.args = { FWU_SMC_IMAGE_AUTH, NS_BL2U_IMAGE_ID, 0, 0, 0 },
.expect = -ENOMEM,
},
{
.description = "IMAGE_AUTH with source size not mapped",
.args = { FWU_SMC_IMAGE_AUTH, NS_BL2U_IMAGE_ID, PLAT_ARM_FWU_FIP_BASE, 0xdeadbeef, 0 },
.expect = -ENOMEM,
},
{
.description = "IMAGE_COPY to copy after auth failure",
.args = { FWU_SMC_IMAGE_COPY, FWU_CERT_ID, PLAT_ARM_FWU_FIP_BASE, 0x40, 0x40 },
.expect = STATUS_SUCCESS,
},
{
.description = "IMAGE_AUTH with valid args for copied image",
.args = { FWU_SMC_IMAGE_AUTH, FWU_CERT_ID, 0, 0, 0 },
.expect = -EAUTH,
},
/* FWU_SMC_IMAGE_EXECUTE test cases. */
{
.description = "IMAGE_EXECUTE with invalid image_id",
.args = { FWU_SMC_IMAGE_EXECUTE, 0, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_EXECUTE with non-executable image_id",
.args = { FWU_SMC_IMAGE_EXECUTE, FWU_CERT_ID, 0, 0, 0 },
.expect = -EPERM,
},
{
.description = "IMAGE_EXECUTE with un-authenticated image_id",
.args = { FWU_SMC_IMAGE_EXECUTE, BL2U_IMAGE_ID, 0, 0, 0 },
.expect = -EPERM,
},
/* FWU_SMC_IMAGE_RESUME test case. */
{
.description = "IMAGE_RESUME with invalid args",
.args = { FWU_SMC_IMAGE_RESUME, 0, 0, 0, 0 },
.expect = -EPERM,
},
};
void ns_bl1u_fwu_test_main(void)
{
NOTICE("NS_BL1U: ***** Starting NS_BL1U FWU test *****\n");
for (int i = 0 ; i < ARRAY_SIZE(tests); ++i) {
u_register_t result;
INFO("NS_BL1U: %s\n", tests[i].description);
smc_ret_values smc_ret;
smc_ret = tftf_smc(&tests[i].args);
result = smc_ret.ret0;
if (result != tests[i].expect) {
ERROR("NS_BL1U: Unexpected SMC return value 0x%lX, "
"expected 0x%lX\n", result, tests[i].expect);
panic();
}
}
NOTICE("NS_BL1U: ***** All FWU test passed *****\n\n");
}