-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
arm_ffa: introduce sandbox test cases for UCLASS_FFA
Add functional test cases for the FF-A support These tests rely on the FF-A sandbox emulator and FF-A sandbox driver which help in inspecting the FF-A communication. Signed-off-by: Abdellatif El Khlifi <[email protected]> Reviewed-by: Simon Glass <[email protected]> Cc: Tom Rini <[email protected]> Cc: Ilias Apalodimas <[email protected]> Cc: Jens Wiklander <[email protected]> Cc: Heinrich Schuchardt <[email protected]>
- Loading branch information
1 parent
a09852d
commit a2f5c91
Showing
4 changed files
with
265 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -274,6 +274,7 @@ F: arch/sandbox/include/asm/sandbox_arm_ffa_priv.h | |
F: doc/arch/arm64.ffa.rst | ||
F: drivers/firmware/arm-ffa/ | ||
F: include/arm_ffa.h | ||
F: test/dm/ffa.c | ||
|
||
ARM FREESCALE IMX | ||
M: Stefano Babic <[email protected]> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
# SPDX-License-Identifier: GPL-2.0+ | ||
# | ||
# Copyright (c) 2013 Google, Inc | ||
# Copyright 2023 Arm Limited and/or its affiliates <[email protected]> | ||
# Copyright 2022-2023 Arm Limited and/or its affiliates <[email protected]> | ||
|
||
obj-$(CONFIG_UT_DM) += test-dm.o | ||
|
||
|
@@ -92,6 +92,7 @@ obj-$(CONFIG_POWER_DOMAIN) += power-domain.o | |
obj-$(CONFIG_ACPI_PMC) += pmc.o | ||
obj-$(CONFIG_DM_PMIC) += pmic.o | ||
obj-$(CONFIG_DM_PWM) += pwm.o | ||
obj-$(CONFIG_ARM_FFA_TRANSPORT) += ffa.o | ||
obj-$(CONFIG_QFW) += qfw.o | ||
obj-$(CONFIG_RAM) += ram.o | ||
obj-y += regmap.o | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,261 @@ | ||
// SPDX-License-Identifier: GPL-2.0+ | ||
/* | ||
* Functional tests for UCLASS_FFA class | ||
* | ||
* Copyright 2022-2023 Arm Limited and/or its affiliates <[email protected]> | ||
* | ||
* Authors: | ||
* Abdellatif El Khlifi <[email protected]> | ||
*/ | ||
|
||
#include <common.h> | ||
#include <console.h> | ||
#include <dm.h> | ||
#include <asm/sandbox_arm_ffa.h> | ||
#include <asm/sandbox_arm_ffa_priv.h> | ||
#include <dm/test.h> | ||
#include <test/test.h> | ||
#include <test/ut.h> | ||
|
||
/* Functional tests for the UCLASS_FFA */ | ||
|
||
static int check_fwk_version(struct ffa_priv *uc_priv, struct unit_test_state *uts) | ||
{ | ||
struct ffa_sandbox_data func_data; | ||
u32 fwk_version = 0; | ||
|
||
func_data.data0 = &fwk_version; | ||
func_data.data0_size = sizeof(fwk_version); | ||
ut_assertok(sandbox_query_ffa_emul_state(FFA_VERSION, &func_data)); | ||
ut_asserteq(uc_priv->fwk_version, fwk_version); | ||
|
||
return 0; | ||
} | ||
|
||
static int check_endpoint_id(struct ffa_priv *uc_priv, struct unit_test_state *uts) | ||
{ | ||
ut_asserteq(0, uc_priv->id); | ||
|
||
return 0; | ||
} | ||
|
||
static int check_rxtxbuf(struct ffa_priv *uc_priv, struct unit_test_state *uts) | ||
{ | ||
ut_assertnonnull(uc_priv->pair.rxbuf); | ||
ut_assertnonnull(uc_priv->pair.txbuf); | ||
|
||
return 0; | ||
} | ||
|
||
static int check_features(struct ffa_priv *uc_priv, struct unit_test_state *uts) | ||
{ | ||
ut_assert(uc_priv->pair.rxtx_min_pages == RXTX_4K || | ||
uc_priv->pair.rxtx_min_pages == RXTX_16K || | ||
uc_priv->pair.rxtx_min_pages == RXTX_64K); | ||
|
||
return 0; | ||
} | ||
|
||
static int check_rxbuf_mapped_flag(u32 queried_func_id, | ||
u8 rxbuf_mapped, | ||
struct unit_test_state *uts) | ||
{ | ||
switch (queried_func_id) { | ||
case FFA_RXTX_MAP: | ||
ut_asserteq(1, rxbuf_mapped); | ||
break; | ||
case FFA_RXTX_UNMAP: | ||
ut_asserteq(0, rxbuf_mapped); | ||
break; | ||
default: | ||
ut_assert(false); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static int check_rxbuf_release_flag(u8 rxbuf_owned, struct unit_test_state *uts) | ||
{ | ||
ut_asserteq(0, rxbuf_owned); | ||
|
||
return 0; | ||
} | ||
|
||
static int test_ffa_msg_send_direct_req(u16 part_id, struct unit_test_state *uts) | ||
{ | ||
struct ffa_send_direct_data msg; | ||
u8 cnt; | ||
struct udevice *dev; | ||
|
||
ut_assertok(uclass_first_device_err(UCLASS_FFA, &dev)); | ||
|
||
ut_assertok(ffa_sync_send_receive(dev, part_id, &msg, 1)); | ||
|
||
for (cnt = 0; cnt < sizeof(struct ffa_send_direct_data) / sizeof(u64); cnt++) | ||
ut_asserteq_64(-1UL, ((u64 *)&msg)[cnt]); | ||
|
||
return 0; | ||
} | ||
|
||
static int test_partitions_and_comms(const char *service_uuid, | ||
struct unit_test_state *uts) | ||
{ | ||
struct ffa_partition_desc *descs; | ||
u32 count, i, j, valid_sps = 0; | ||
struct udevice *dev; | ||
struct ffa_sandbox_data func_data; | ||
struct ffa_partitions *partitions; | ||
|
||
ut_assertok(uclass_first_device_err(UCLASS_FFA, &dev)); | ||
|
||
/* Get from the driver the count and information of the SPs matching the UUID */ | ||
ut_assertok(ffa_partition_info_get(dev, service_uuid, &count, &descs)); | ||
|
||
/* Make sure the count is correct */ | ||
ut_asserteq(SANDBOX_SP_COUNT_PER_VALID_SERVICE, count); | ||
|
||
/* SPs found , verify the partitions information */ | ||
|
||
func_data.data0 = &partitions; | ||
func_data.data0_size = sizeof(struct ffa_partitions *); | ||
ut_assertok(sandbox_query_ffa_emul_state(FFA_PARTITION_INFO_GET, &func_data)); | ||
|
||
for (i = 0; i < count ; i++) { | ||
for (j = 0; | ||
j < partitions->count; | ||
j++) { | ||
if (descs[i].info.id == | ||
partitions->descs[j].info.id) { | ||
valid_sps++; | ||
ut_asserteq_mem(&descs[i], | ||
&partitions->descs[j], | ||
sizeof(struct ffa_partition_desc)); | ||
/* Send and receive data from the current partition */ | ||
test_ffa_msg_send_direct_req(descs[i].info.id, uts); | ||
} | ||
} | ||
} | ||
|
||
/* Verify expected partitions found in the emulated secure world */ | ||
ut_asserteq(SANDBOX_SP_COUNT_PER_VALID_SERVICE, valid_sps); | ||
|
||
return 0; | ||
} | ||
|
||
static int dm_test_ffa_ack(struct unit_test_state *uts) | ||
{ | ||
struct ffa_priv *uc_priv; | ||
struct ffa_sandbox_data func_data; | ||
u8 rxbuf_flag = 0; | ||
const char *svc1_uuid = SANDBOX_SERVICE1_UUID; | ||
const char *svc2_uuid = SANDBOX_SERVICE2_UUID; | ||
struct udevice *dev; | ||
|
||
/* Test probing the sandbox FF-A bus */ | ||
ut_assertok(uclass_first_device_err(UCLASS_FFA, &dev)); | ||
|
||
/* Get a pointer to the sandbox FF-A bus private data */ | ||
uc_priv = dev_get_uclass_priv(dev); | ||
|
||
/* Make sure the private data pointer is retrieved */ | ||
ut_assertnonnull(uc_priv); | ||
|
||
/* Test FFA_VERSION */ | ||
check_fwk_version(uc_priv, uts); | ||
|
||
/* Test FFA_ID_GET */ | ||
check_endpoint_id(uc_priv, uts); | ||
|
||
/* Test FFA_FEATURES */ | ||
check_features(uc_priv, uts); | ||
|
||
/* Test RX/TX buffers */ | ||
check_rxtxbuf(uc_priv, uts); | ||
|
||
/* Test FFA_RXTX_MAP */ | ||
func_data.data0 = &rxbuf_flag; | ||
func_data.data0_size = sizeof(rxbuf_flag); | ||
|
||
rxbuf_flag = 0; | ||
sandbox_query_ffa_emul_state(FFA_RXTX_MAP, &func_data); | ||
check_rxbuf_mapped_flag(FFA_RXTX_MAP, rxbuf_flag, uts); | ||
|
||
/* FFA_PARTITION_INFO_GET / FFA_MSG_SEND_DIRECT_REQ */ | ||
test_partitions_and_comms(svc1_uuid, uts); | ||
|
||
/* Test FFA_RX_RELEASE */ | ||
rxbuf_flag = 1; | ||
sandbox_query_ffa_emul_state(FFA_RX_RELEASE, &func_data); | ||
check_rxbuf_release_flag(rxbuf_flag, uts); | ||
|
||
/* FFA_PARTITION_INFO_GET / FFA_MSG_SEND_DIRECT_REQ */ | ||
test_partitions_and_comms(svc2_uuid, uts); | ||
|
||
/* Test FFA_RX_RELEASE */ | ||
rxbuf_flag = 1; | ||
ut_assertok(sandbox_query_ffa_emul_state(FFA_RX_RELEASE, &func_data)); | ||
check_rxbuf_release_flag(rxbuf_flag, uts); | ||
|
||
return 0; | ||
} | ||
|
||
DM_TEST(dm_test_ffa_ack, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC); | ||
|
||
static int dm_test_ffa_nack(struct unit_test_state *uts) | ||
{ | ||
struct ffa_priv *uc_priv; | ||
const char *valid_svc_uuid = SANDBOX_SERVICE1_UUID; | ||
const char *unvalid_svc_uuid = SANDBOX_SERVICE3_UUID; | ||
const char *unvalid_svc_uuid_str = SANDBOX_SERVICE4_UUID; | ||
struct ffa_send_direct_data msg; | ||
int ret; | ||
u32 count; | ||
u16 part_id = 0; | ||
struct udevice *dev; | ||
struct ffa_partition_desc *descs = NULL; | ||
|
||
/* Test probing the sandbox FF-A bus */ | ||
ut_assertok(uclass_first_device_err(UCLASS_FFA, &dev)); | ||
|
||
/* Get a pointer to the sandbox FF-A bus private data */ | ||
uc_priv = dev_get_uclass_priv(dev); | ||
|
||
/* Make sure the private data pointer is retrieved */ | ||
ut_assertnonnull(uc_priv); | ||
|
||
/* Query partitions count using invalid arguments */ | ||
ret = ffa_partition_info_get(dev, NULL, NULL, NULL); | ||
ut_asserteq(-EINVAL, ret); | ||
ret = ffa_partition_info_get(dev, unvalid_svc_uuid, NULL, NULL); | ||
ut_asserteq(-EINVAL, ret); | ||
ret = ffa_partition_info_get(dev, unvalid_svc_uuid, &count, NULL); | ||
ut_asserteq(-EINVAL, ret); | ||
|
||
/* Query partitions count using an invalid UUID string */ | ||
ret = ffa_partition_info_get(dev, unvalid_svc_uuid_str, &count, &descs); | ||
ut_asserteq(-EINVAL, ret); | ||
|
||
/* Query partitions count using an invalid UUID (no matching SP) */ | ||
count = 0; | ||
ret = ffa_partition_info_get(dev, unvalid_svc_uuid, &count, &descs); | ||
ut_asserteq(0, count); | ||
|
||
/* Query partitions data using a valid UUID */ | ||
count = 0; | ||
ut_assertok(ffa_partition_info_get(dev, valid_svc_uuid, &count, &descs)); | ||
/* Make sure partitions are detected */ | ||
ut_asserteq(SANDBOX_SP_COUNT_PER_VALID_SERVICE, count); | ||
ut_assertnonnull(descs); | ||
|
||
/* Send data to an invalid partition */ | ||
ret = ffa_sync_send_receive(dev, part_id, &msg, 1); | ||
ut_asserteq(-EINVAL, ret); | ||
|
||
/* Send data to a valid partition */ | ||
part_id = uc_priv->partitions.descs[0].info.id; | ||
ut_assertok(ffa_sync_send_receive(dev, part_id, &msg, 1)); | ||
|
||
return 0; | ||
} | ||
|
||
DM_TEST(dm_test_ffa_nack, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC); |