Merge "fix(TFTF): ensure robustness of SError inject test"
diff --git a/Makefile b/Makefile
index a758b8a..8eba940 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@
# TFTF Version
VERSION_MAJOR := 2
-VERSION_MINOR := 4
+VERSION_MINOR := 5
MAKE_HELPERS_DIRECTORY := make_helpers/
include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
diff --git a/docs/change-log.rst b/docs/change-log.rst
index 91f3fde..136bbd4 100644
--- a/docs/change-log.rst
+++ b/docs/change-log.rst
@@ -7,6 +7,184 @@
Tests are not guaranteed to be compatible. This also means that a version
upgrade on the TF-A-Tests side might not necessarily introduce any new feature.
+Version 2.5
+-----------
+
+New features
+^^^^^^^^^^^^
+- More tests are made available in this release to help validate the
+ functionalities in the following areas:
+ - True Random Number Generator (TRNG) test scenarios.
+ - Multicore / Power State Controller Interface (PSCI) tests.
+ - v8.6 Activity Monitors Unit (AMU) enhancements test scenarios.
+ - Secure Partition Manager (SPM) / Firmware Framework (FF-A) v1.0 testing.
+ - Interrupt Handling between Non-secure and Secure world.
+ - Direct messages and memory sharing between Secure Partitions(SP).
+ - Many tests to exercise FF-A v1.0 ABIs.
+ - SPM saving/restoring the NS SIMD context enabling a normal world FF-A
+ endpoint (TFTF) and a secure partition to use SIMD vectors and
+ instructions independently.
+
+TFTF
+~~~~
+
+- SPM / FF-A v1.0 testing.
+ - Refactor FF-A memory sharing tests
+ - Created helper functions to initialize ffa_memory_region and to send
+ the respective memory region to the SP, making it possible to reuse
+ the logic in SP-to-SP memory share tests.
+ - Added comments to document relevant aspects about memory sharing.
+
+ - Trigger direct messaging between SPs.
+ - Use cactus command 'CACTUS_REQ_ECHO_SEND_CMD' to make cactus SPs
+ communicate with each other using direct message interfaces.
+
+ - Added helpers for SPM tests.
+ - Checking SPMC has expected FFA_VERSION.
+ - Checking that expected FF-A endpoints are deployed in the system.
+ - Getting global TFTF mailbox.
+
+- Replace '.inst' AArch64 machine directives with CPU Memory Tagging Extension
+ instructions in 'test_mte_instructions' function.
+
+- Add build option for Arm Feature Modifiers.
+ - This patch adds a new ARM_ARCH_FEATURE build option to add support
+ for compiler's feature modifiers.
+
+- Enable 8 cores support for Theodul DSU(DynamIQ Shared Unit) for the
+ Total Compute (TC0) platform.
+
+- New tests:
+
+ - Remove redundant code and add better tests for TRNG SMCs.
+ - Tests that the Version, Features, and RND calls conform to the spec.
+
+ - New tests for v8.6 AMU enhancements (FEAT_AMUv1p1)
+ - Make sure AMU offsets are being saved and restored properly.
+
+ - Tests to request SP-to-SP memory share.
+
+ - SP-to-SP direct messaging deadlock test.
+ - TFTF sends CACTUS_REQ_DEADLOCK_CMD to cactus SP.
+
+Cactus(Secure-EL1 test partition)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- Enable managed exit for primary cactus secure partition.
+
+- Helper commands needed for interrupt testing.
+
+- Add handler from managed exit FIQ interrupt.
+
+- Make ffa_id global.
+
+- Implement HF_INTERRUPT_ENABLE Hafnium hypervisor call wrapper. With this
+ service, a secure partition calls into the SPMC to enable/disable a
+ particular virtual interrupt.
+
+- Invalidate the data cache for the cactus image.
+
+- Helper commands needed for interrupt testing.
+ - CACTUS_SLEEP_CMD & CACTUS_INTERRUPT_CMD added.
+
+- Decouple exception handling from tftf framework.
+ - With new interrupt related tests coming up in Cactus, added separate
+ exception handler code for irq/fiq in Cactus.
+
+- Hypervisor calls moved to a separate module.
+
+- Add secondary entry point register function.
+
+- Declare third SP instance as UP SP.
+
+- Provision a cold boot path for secondary cores (or secondary pinned
+ execution contexts).
+
+- Tidy message loop, commands definitions, direct messaging API definitions.
+
+- Helpers for error logging after FF-A calls.
+
+- Properly placing Cactus test files.
+
+- Tidying FF-A Memory Sharing tests.
+
+- Use CACTUS_ECHO_CMD in direct message tests.
+
+- Refactor handling of commands.
+ - Added helper macros to define a command handler, build a command table
+ in which each element is a pair of the handler and respective command
+ ID. Available tests have been moved to their own command handler.
+
+- Extend arguments in commands responses.
+ - In the test commands framework, added template to extend number of
+ values to include in a command response.
+
+- Check FF-A return is a valid direct response.
+ - Added a helper function to check if return of FFA_MSG_SEND_DIRECT_REQ
+ is FFA_MSG_SEND_DIRECT_RESP.
+
+- FFA_MSG_DIRECT_RESP call extended to use 5 registers.
+
+- Added accessors for arguments from FF-A calls.
+ - Some accessors for arguments from FF-A calls, namely for func id, error
+ code, and direct message destination/source.
+
+- Use virtual counter for sp_sleep.
+ - Changes sp_sleep() to use virtual counter instead of physical counter.
+
+- Checks if SIMD vectors are preserved in the normal world while transitioning
+ from normal world to secure world and back to normal world.
+
+- Tidying common code to tftf and cactus.
+
+- Refactor cactus_test_cmds.h to incorporate static inline functions instead
+ of macros to enforce type checking.
+
+- Removed reference to Hafnium in name from helper function and macro to
+ make them generic.
+
+- For consistency added the cmd id 'CACTUS_MEM_SEND_CMD'.
+
+- Add command to request memory sharing between SPs.
+
+- Add & handle commands 'CACTUS_REQ_ECHO_CMD' and 'CACTUS_ECHO_CMD'.
+
+- Update README with list of sample partitions.
+
+- Remove reference to PSA from xml test file.
+
+- Reduce tests verbosity in release mode.
+ - Update few NOTICE messages to VERBOSE/INFO.
+
+- Fix conversion issues on cactus responses.
+
+- Create RXTX map/configure helper macros and use them.
+
+- Update OP-TEE version used for testing to 3.10.
+ - SPMC as S-EL1 tests using OP-TEE depend on a static binary stored as
+ a CI file. This binary corresponds to a build of OP-TEE v3.10.
+
+- Add uart2 to device-regions node.
+ - First SP no longer has an open access to the full system peripheral
+ range and devices must be explicitly declared in the SP manifest.
+
+- New tests:
+
+ - Test for exercising SMMUv3 driver to perform stage2 translation.
+
+ - Test handling of non-secure interrupt while running SP.
+
+ - Add secondary cores direct messaging test for SPM.
+
+ - Testing deadlock by FF-A direct message.
+ - Added command CACTUS_DEADLOCK_CMD to file cactus_test_cmds.h to create
+ a deadlock scenario using FF-A direct message interfaces.
+
+ - Test SP-to-SP memory share operations
+ - Handle 'CACTUS_REQ_MEM_SEND_CMD' by sending memory to the receiver SP.
+
+ - Implemented test to validate FFA_RXTX_MAP ABI.
+
Version 2.4
-----------
diff --git a/docs/getting_started/build.rst b/docs/getting_started/build.rst
index 27ad580..d0147f9 100644
--- a/docs/getting_started/build.rst
+++ b/docs/getting_started/build.rst
@@ -206,24 +206,11 @@
SPM test images
```````````````
-This repository contains 3 Secure Partitions that exercise the Secure Partition
-Manager (SPM) in TF-A [#]_. Cactus-MM is designed to test the SPM
-implementation based on the `ARM Management Mode Interface`_ (MM), while Cactus
-and Ivy can test the SPM implementation based on the SPCI and SPRT draft
-specifications. Note that it isn't possible to use both communication mechanisms
-at once: If Cactus-MM is used Cactus and Ivy can't be used.
+This repository contains three sample Secure Partitions (SP) meant to be used
+with one implementation of a Secure Partition Manager (SPM):
-They run in Secure-EL0 and perform the following tasks:
-
-- Test that TF-A has correctly setup the secure partition environment: They
- should be allowed to perform cache maintenance operations, access floating
- point registers, etc.
-
-- Test that TF-A accepts to change data access permissions and instruction
- permissions on behalf of the Secure Partitions for memory regions the latter
- owns.
-
-- Test communication with SPM through either MM, or both SPCI and SPRT.
+- Cactus-MM
+- Cactus and Ivy
They are only supported on AArch64 FVP. They can be built independently of the
other test images using the following command:
@@ -232,16 +219,35 @@
make PLAT=fvp cactus ivy cactus_mm
-In the TF-A boot flow, the partitions replace the ``BL32`` image and should be
-injected in the FIP image. To test SPM-MM with Cactus-MM, it is enough to use
-``cactus_mm.bin`` as BL32 image. To test the SPM based on SPCI and SPRT, it is
-needed to use ``sp_tool`` to build a Secure Partition package that can be used
-as BL32 image.
-
To run the full set of tests in the Secure Partitions, they should be used in
conjunction with the TFTF image.
-For SPM-MM, build TF-A following the `TF-A SPM User Guide`_ and the following
+Please refer to the `TF-A documentation`_ for further details.
+
+Cactus-MM
+'''''''''
+
+Cactus-MM is designed to test the TF-A EL3 SPM implementation
+(`TF-A Secure Partition Manager (MM)`_) based on the
+`Arm Management Mode Interface`_ (MM)
+
+This SP runs in Secure-EL0 and performs the following tasks:
+
+- Test that TF-A has correctly setup the secure partition environment: it
+ should be allowed to perform cache maintenance operations, access floating
+ point registers, etc.
+
+- Test that TF-A accepts to change data access permissions and instruction
+ permissions on behalf of the Secure Partition for memory regions the latter
+ owns.
+
+- Test communication with SPM through MM interface.
+
+In the TF-A boot flow, the partition replaces the ``BL32`` image and should be
+injected in the FIP image. To test SPM-MM with Cactus-MM, it is enough to use
+``cactus_mm.bin`` as BL32 image.
+
+For SPM-MM, build TF-A following `Building TF-A Secure Partition Manager (MM)`_ and the following
commands can be used to build the tests:
::
@@ -250,8 +256,40 @@
make PLAT=fvp TESTS=spm-mm tftf cactus_mm
-For SPM based on SPCI and SPRT, build TF-A following the `TF-A SPM User Guide`_
-and the following commands can be used to build the tests:
+Cactus and Ivy
+''''''''''''''
+
+Cactus and Ivy are designed to test the FF-A based SPM implementation with
+secure virtualization enabled. Refer to `Arm Firmware Framework for Armv8-A`_
+
+In the TF-A reference code base, BL31 implements the SPMD and BL32 the SPMC.
+The SPMC runs at S-EL2 and acts as a partition manager for multiple secure
+partitions (`TF-A Secure Partition Manager (FF-A)`_):
+
+- Cactus is a sample FF-A compliant S-EL1 partition. As a matter of providing
+ a realistic test harness, three instances of the same partition binary are
+ launched as separate SPs (hence assigned three different FF-A IDs
+ corresponding each to a different secure partition). Each secure partition
+ instance has a separate manifest (`Cactus sample manifest`_,
+ `Cactus secondary manifest`_, `Cactus tertiary manifest`_ ). First two
+ instances are MP SPs. Third instance is a UP SP. Each instance runs a set
+ of built-in tests at boot time. They exercise SP to SPMC FF-A interfaces
+ contained in the secure world. The partition interacts with the SPMC through
+ SMC. Once the NWd and TFTF are started, another set of run-time tests
+ exercise the normal world to secure world primitives.
+- Ivy is a specific kind of S-EL1 UP partition, where the S-EL1 exception level
+ consists of a thin shim layer. The applicative part of the partition is held
+ at S-EL0. The shim provides early bootstrap code, MMU configuration and a
+ vector table trapping S-EL0 requests. The application interacts with the shim
+ through FF-A protocol by the use of SVC instruction. The shim relays the
+ request to the SPMC by an SMC. The S-EL0 application doesn't require knowledge
+ of the shim, and can be self contained.
+
+This picture illustrates the test setup:
+
+.. image:: ../resources/tftf-cactus.png
+
+To build TFTF with SPM tests, Cactus and Ivy use:
::
@@ -259,31 +297,23 @@
make PLAT=fvp TESTS=spm tftf cactus ivy
- # TF-A repository:
-
- make sptool
-
- tools/sptool/sptool -o sp_package.bin \
- -i path/to/cactus.bin:path/to/cactus.dtb \
- -i path/to/ivy.bin:path/to/ivy.dtb
-
-Please refer to the `TF-A documentation`_ for further details.
-
--------------
.. [#] Therefore, the Trusted Board Boot feature must be enabled in TF-A for
the FWU test images to work. Please refer the `TF-A documentation`_ for
further details.
-.. [#] Therefore, the Secure Partition Manager must be enabled in TF-A for
- any of the test Secure Partitions to work. Please refer to the
- `TF-A documentation`_ for further details.
-
--------------
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
.. _EL3 test payload README file: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/el3_payload/README
-.. _ARM Management Mode Interface: http://infocenter.arm.com/help/topic/com.arm.doc.den0060a/DEN0060A_ARM_MM_Interface_Specification.pdf
+.. _Arm Management Mode Interface: https://developer.arm.com/documentation/den0060/a/
+.. _Arm Firmware Framework for Armv8-A: https://developer.arm.com/docs/den0077/latest
.. _TF-A documentation: https://trustedfirmware-a.readthedocs.org
-.. _TF-A SPM User Guide: https://trustedfirmware-a.readthedocs.io/en/latest/components/secure-partition-manager-design.html#building-tf-a-with-secure-partition-support
+.. _TF-A Secure Partition Manager (FF-A): https://trustedfirmware-a.readthedocs.io/en/latest/components/secure-partition-manager.html
+.. _TF-A Secure Partition Manager (MM): https://trustedfirmware-a.readthedocs.io/en/latest/components/secure-partition-manager-mm.html
+.. _Building TF-A Secure Partition Manager (MM): https://trustedfirmware-a.readthedocs.io/en/latest/components/secure-partition-manager-mm.html#building-tf-a-with-secure-partition-support
+.. _Cactus sample manifest: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/spm/cactus/plat/arm/fvp/fdts/cactus.dts?h=v2.5-rc1
+.. _Cactus secondary manifest: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/spm/cactus/plat/arm/fvp/fdts/cactus-secondary.dts?h=v2.5-rc1
+.. _Cactus tertiary manifest: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts?h=v2.5-rc1
diff --git a/docs/resources/tftf-cactus.png b/docs/resources/tftf-cactus.png
new file mode 100644
index 0000000..29539f7
--- /dev/null
+++ b/docs/resources/tftf-cactus.png
Binary files differ
diff --git a/include/lib/mmio.h b/include/lib/mmio.h
index e8a7df0..c788af3 100644
--- a/include/lib/mmio.h
+++ b/include/lib/mmio.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -24,16 +24,33 @@
*(volatile uint32_t*)addr = value;
}
+static inline void mmio_write32_offset(uintptr_t addr, uint32_t byte_off,
+ uint32_t data)
+{
+ mmio_write_32((uintptr_t)((uint8_t *)addr + byte_off), data);
+}
+
static inline uint32_t mmio_read_32(uintptr_t addr)
{
return *(volatile uint32_t*)addr;
}
+static inline uint32_t mmio_read32_offset(uintptr_t addr, uint32_t byte_off)
+{
+ return mmio_read_32((uintptr_t)((uint8_t *)addr + byte_off));
+}
+
static inline void mmio_write_64(uintptr_t addr, uint64_t value)
{
*(volatile uint64_t*)addr = value;
}
+static inline void mmio_write64_offset(uintptr_t addr, uint32_t byte_off,
+ uint64_t data)
+{
+ mmio_write_64((uintptr_t)((uint8_t *)addr + byte_off), data);
+}
+
static inline uint64_t mmio_read_64(uintptr_t addr)
{
return *(volatile uint64_t*)addr;
diff --git a/include/runtime_services/cactus_test_cmds.h b/include/runtime_services/cactus_test_cmds.h
index d03a97f..0970968 100644
--- a/include/runtime_services/cactus_test_cmds.h
+++ b/include/runtime_services/cactus_test_cmds.h
@@ -37,7 +37,7 @@
* messages interfaces.
*/
static inline smc_ret_values cactus_send_cmd(
- ffa_vm_id_t source, ffa_vm_id_t dest, uint64_t cmd, uint64_t val0,
+ ffa_id_t source, ffa_id_t dest, uint64_t cmd, uint64_t val0,
uint64_t val1, uint64_t val2, uint64_t val3)
{
return ffa_msg_send_direct_req64(source, dest, cmd, val0, val1, val2,
@@ -50,7 +50,7 @@
* a need to propagate more than one value in the response of a command.
*/
static inline smc_ret_values cactus_send_response(
- ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t resp, uint32_t val0,
+ ffa_id_t source, ffa_id_t dest, uint32_t resp, uint32_t val0,
uint64_t val1, uint64_t val2, uint64_t val3)
{
return ffa_msg_send_direct_resp64(source, dest, resp, val0, val1,
@@ -61,7 +61,7 @@
* For responses of one value only.
*/
static inline smc_ret_values cactus_response(
- ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t response)
+ ffa_id_t source, ffa_id_t dest, uint32_t response)
{
return ffa_msg_send_direct_resp64(source, dest, response, 0, 0, 0, 0);
}
@@ -78,7 +78,7 @@
* specific test.
*/
static inline smc_ret_values cactus_success_resp(
- ffa_vm_id_t source, ffa_vm_id_t dest, uint64_t value)
+ ffa_id_t source, ffa_id_t dest, uint64_t value)
{
return cactus_send_response(source, dest, CACTUS_SUCCESS, value,
0, 0, 0);
@@ -90,7 +90,7 @@
* in the error code list.
*/
static inline smc_ret_values cactus_error_resp(
- ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t error_code)
+ ffa_id_t source, ffa_id_t dest, uint32_t error_code)
{
return cactus_send_response(source, dest, CACTUS_ERROR, error_code,
0, 0, 0);
@@ -110,7 +110,7 @@
#define CACTUS_ECHO_CMD U(0x6563686f)
static inline smc_ret_values cactus_echo_send_cmd(
- ffa_vm_id_t source, ffa_vm_id_t dest, uint64_t echo_val)
+ ffa_id_t source, ffa_id_t dest, uint64_t echo_val)
{
return cactus_send_cmd(source, dest, CACTUS_ECHO_CMD, echo_val, 0, 0,
0);
@@ -131,16 +131,16 @@
#define CACTUS_REQ_ECHO_CMD (CACTUS_ECHO_CMD + 1)
static inline smc_ret_values cactus_req_echo_send_cmd(
- ffa_vm_id_t source, ffa_vm_id_t dest, ffa_vm_id_t echo_dest,
+ ffa_id_t source, ffa_id_t dest, ffa_id_t echo_dest,
uint64_t echo_val)
{
return cactus_send_cmd(source, dest, CACTUS_REQ_ECHO_CMD, echo_val,
echo_dest, 0, 0);
}
-static inline ffa_vm_id_t cactus_req_echo_get_echo_dest(smc_ret_values ret)
+static inline ffa_id_t cactus_req_echo_get_echo_dest(smc_ret_values ret)
{
- return (ffa_vm_id_t)ret.ret5;
+ return (ffa_id_t)ret.ret5;
}
/**
@@ -155,15 +155,15 @@
#define CACTUS_DEADLOCK_CMD U(0x64656164)
static inline smc_ret_values cactus_deadlock_send_cmd(
- ffa_vm_id_t source, ffa_vm_id_t dest, ffa_vm_id_t next_dest)
+ ffa_id_t source, ffa_id_t dest, ffa_id_t next_dest)
{
return cactus_send_cmd(source, dest, CACTUS_DEADLOCK_CMD, next_dest, 0,
0, 0);
}
-static inline ffa_vm_id_t cactus_deadlock_get_next_dest(smc_ret_values ret)
+static inline ffa_id_t cactus_deadlock_get_next_dest(smc_ret_values ret)
{
- return (ffa_vm_id_t)ret.ret4;
+ return (ffa_id_t)ret.ret4;
}
/**
@@ -173,17 +173,17 @@
#define CACTUS_REQ_DEADLOCK_CMD (CACTUS_DEADLOCK_CMD + 1)
static inline smc_ret_values cactus_req_deadlock_send_cmd(
- ffa_vm_id_t source, ffa_vm_id_t dest, ffa_vm_id_t next_dest1,
- ffa_vm_id_t next_dest2)
+ ffa_id_t source, ffa_id_t dest, ffa_id_t next_dest1,
+ ffa_id_t next_dest2)
{
return cactus_send_cmd(source, dest, CACTUS_REQ_DEADLOCK_CMD,
next_dest1, next_dest2, 0, 0);
}
/* To get next_dest1 use CACTUS_DEADLOCK_GET_NEXT_DEST */
-static inline ffa_vm_id_t cactus_deadlock_get_next_dest2(smc_ret_values ret)
+static inline ffa_id_t cactus_deadlock_get_next_dest2(smc_ret_values ret)
{
- return (ffa_vm_id_t)ret.ret5;
+ return (ffa_id_t)ret.ret5;
}
/**
@@ -195,7 +195,7 @@
#define CACTUS_MEM_SEND_CMD U(0x6d656d)
static inline smc_ret_values cactus_mem_send_cmd(
- ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t mem_func,
+ ffa_id_t source, ffa_id_t dest, uint32_t mem_func,
ffa_memory_handle_t handle)
{
return cactus_send_cmd(source, dest, CACTUS_MEM_SEND_CMD, mem_func,
@@ -217,8 +217,8 @@
#define CACTUS_REQ_MEM_SEND_CMD U(0x6d656d6f7279)
static inline smc_ret_values cactus_req_mem_send_send_cmd(
- ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t mem_func,
- ffa_vm_id_t receiver)
+ ffa_id_t source, ffa_id_t dest, uint32_t mem_func,
+ ffa_id_t receiver)
{
return cactus_send_cmd(source, dest, CACTUS_REQ_MEM_SEND_CMD, mem_func,
receiver, 0, 0);
@@ -229,9 +229,9 @@
return (uint32_t)ret.ret4;
}
-static inline ffa_vm_id_t cactus_req_mem_send_get_receiver(smc_ret_values ret)
+static inline ffa_id_t cactus_req_mem_send_get_receiver(smc_ret_values ret)
{
- return (ffa_vm_id_t)ret.ret5;
+ return (ffa_id_t)ret.ret5;
}
/**
@@ -244,7 +244,7 @@
#define CACTUS_REQ_SIMD_FILL_CMD U(0x53494d44)
static inline smc_ret_values cactus_req_simd_fill_send_cmd(
- ffa_vm_id_t source, ffa_vm_id_t dest)
+ ffa_id_t source, ffa_id_t dest)
{
return cactus_send_cmd(source, dest, CACTUS_REQ_SIMD_FILL_CMD, 0, 0, 0,
0);
@@ -258,7 +258,7 @@
#define CACTUS_SLEEP_CMD U(0x736c656570)
static inline smc_ret_values cactus_sleep_cmd(
- ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t sleep_time)
+ ffa_id_t source, ffa_id_t dest, uint32_t sleep_time)
{
return cactus_send_cmd(source, dest, CACTUS_SLEEP_CMD, sleep_time, 0, 0,
0);
@@ -277,7 +277,7 @@
#define CACTUS_INTERRUPT_CMD U(0x696e7472)
static inline smc_ret_values cactus_interrupt_cmd(
- ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t interrupt_id,
+ ffa_id_t source, ffa_id_t dest, uint32_t interrupt_id,
bool enable, uint32_t pin)
{
return cactus_send_cmd(source, dest, CACTUS_INTERRUPT_CMD, interrupt_id,
@@ -299,4 +299,17 @@
return (enum interrupt_pin)ret.ret6;
}
+/**
+ * Request to initiate DMA transaction by upstream peripheral.
+ *
+ * The command id is the hex representation of the string "SMMU"
+ */
+#define CACTUS_DMA_SMMUv3_CMD (0x534d4d55)
+
+static inline smc_ret_values cactus_send_dma_cmd(
+ ffa_id_t source, ffa_id_t dest)
+{
+ return cactus_send_cmd(source, dest, CACTUS_DMA_SMMUv3_CMD, 0, 0, 0,
+ 0);
+}
#endif
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index 592327a..3ca9c82 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -14,7 +14,7 @@
/* This error code must be different to the ones used by FFA */
#define FFA_TFTF_ERROR -42
-typedef unsigned short ffa_vm_id_t;
+typedef unsigned short ffa_id_t;
typedef unsigned short ffa_vm_count_t;
typedef unsigned short ffa_vcpu_count_t;
typedef uint64_t ffa_memory_handle_t;
@@ -31,7 +31,7 @@
struct ffa_partition_info {
/** The ID of the VM the information is about */
- ffa_vm_id_t id;
+ ffa_id_t id;
/** The number of execution contexts implemented by the partition */
uint16_t exec_context;
/** The Partition's properties, e.g. supported messaging methods */
@@ -46,6 +46,10 @@
return (int32_t) val.ret2;
}
+static inline ffa_id_t ffa_endpoint_id(smc_ret_values val) {
+ return (ffa_id_t) val.ret2 & 0xffff;
+}
+
enum ffa_data_access {
FFA_DATA_ACCESS_NOT_SPECIFIED,
FFA_DATA_ACCESS_RO,
@@ -196,7 +200,7 @@
*/
struct ffa_memory_region_attributes {
/** The ID of the VM to which the memory is being given or shared. */
- ffa_vm_id_t receiver;
+ ffa_id_t receiver;
/**
* The permissions with which the memory region should be mapped in the
* receiver's page table.
@@ -264,7 +268,7 @@
* The ID of the VM which originally sent the memory region, i.e. the
* owner.
*/
- ffa_vm_id_t sender;
+ ffa_id_t sender;
ffa_memory_attributes_t attributes;
/** Reserved field, must be 0. */
uint8_t reserved_0;
@@ -300,7 +304,7 @@
ffa_memory_handle_t handle;
ffa_memory_region_flags_t flags;
uint32_t endpoint_count;
- ffa_vm_id_t endpoints[];
+ ffa_id_t endpoints[];
};
static inline ffa_memory_handle_t ffa_assemble_handle(uint32_t h1, uint32_t h2)
@@ -335,18 +339,18 @@
static inline uint32_t ffa_mem_relinquish_init(
struct ffa_mem_relinquish *relinquish_request,
ffa_memory_handle_t handle, ffa_memory_region_flags_t flags,
- ffa_vm_id_t sender)
+ ffa_id_t sender)
{
relinquish_request->handle = handle;
relinquish_request->flags = flags;
relinquish_request->endpoint_count = 1;
relinquish_request->endpoints[0] = sender;
- return sizeof(struct ffa_mem_relinquish) + sizeof(ffa_vm_id_t);
+ return sizeof(struct ffa_mem_relinquish) + sizeof(ffa_id_t);
}
uint32_t ffa_memory_retrieve_request_init(
struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
- ffa_vm_id_t sender, ffa_vm_id_t receiver, uint32_t tag,
+ ffa_id_t sender, ffa_id_t receiver, uint32_t tag,
ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
enum ffa_instruction_access instruction_access,
enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
@@ -354,7 +358,7 @@
uint32_t ffa_memory_region_init(
struct ffa_memory_region *memory_region, size_t memory_region_max_size,
- ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ ffa_id_t sender, ffa_id_t receiver,
const struct ffa_memory_region_constituent constituents[],
uint32_t constituent_count, uint32_t tag,
ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
@@ -363,37 +367,38 @@
enum ffa_memory_shareability shareability, uint32_t *total_length,
uint32_t *fragment_length);
-static inline ffa_vm_id_t ffa_dir_msg_dest(smc_ret_values val) {
- return (ffa_vm_id_t)val.ret1 & U(0xFFFF);
+static inline ffa_id_t ffa_dir_msg_dest(smc_ret_values val) {
+ return (ffa_id_t)val.ret1 & U(0xFFFF);
}
-static inline ffa_vm_id_t ffa_dir_msg_source(smc_ret_values val) {
- return (ffa_vm_id_t)(val.ret1 >> 16U);
+static inline ffa_id_t ffa_dir_msg_source(smc_ret_values val) {
+ return (ffa_id_t)(val.ret1 >> 16U);
}
-smc_ret_values ffa_msg_send_direct_req64(ffa_vm_id_t source_id,
- ffa_vm_id_t dest_id, uint64_t arg0,
+smc_ret_values ffa_msg_send_direct_req64(ffa_id_t source_id,
+ ffa_id_t dest_id, uint64_t arg0,
uint64_t arg1, uint64_t arg2,
uint64_t arg3, uint64_t arg4);
-smc_ret_values ffa_msg_send_direct_req32(ffa_vm_id_t source_id,
- ffa_vm_id_t dest_id, uint32_t arg0,
+smc_ret_values ffa_msg_send_direct_req32(ffa_id_t source_id,
+ ffa_id_t dest_id, uint32_t arg0,
uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t arg4);
-smc_ret_values ffa_msg_send_direct_resp64(ffa_vm_id_t source_id,
- ffa_vm_id_t dest_id, uint64_t arg0,
+smc_ret_values ffa_msg_send_direct_resp64(ffa_id_t source_id,
+ ffa_id_t dest_id, uint64_t arg0,
uint64_t arg1, uint64_t arg2,
uint64_t arg3, uint64_t arg4);
-smc_ret_values ffa_msg_send_direct_resp32(ffa_vm_id_t source_id,
- ffa_vm_id_t dest_id, uint32_t arg0,
+smc_ret_values ffa_msg_send_direct_resp32(ffa_id_t source_id,
+ ffa_id_t dest_id, uint32_t arg0,
uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t arg4);
smc_ret_values ffa_run(uint32_t dest_id, uint32_t vcpu_id);
smc_ret_values ffa_version(uint32_t input_version);
smc_ret_values ffa_id_get(void);
+smc_ret_values ffa_spm_id_get(void);
smc_ret_values ffa_msg_wait(void);
smc_ret_values ffa_error(int32_t error_code);
smc_ret_values ffa_features(uint32_t feature);
diff --git a/include/runtime_services/ffa_svc.h b/include/runtime_services/ffa_svc.h
index c970265..3a474e7 100644
--- a/include/runtime_services/ffa_svc.h
+++ b/include/runtime_services/ffa_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,7 +22,7 @@
/* The macros below are used to identify FFA calls from the SMC function ID */
#define FFA_FNUM_MIN_VALUE U(0x60)
-#define FFA_FNUM_MAX_VALUE U(0x84)
+#define FFA_FNUM_MAX_VALUE U(0x85)
#define is_ffa_fid(fid) __extension__ ({ \
__typeof__(fid) _fid = (fid); \
((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) && \
@@ -85,6 +85,7 @@
#define FFA_FNUM_MEM_RELINQUISH U(0x76)
#define FFA_FNUM_MEM_RECLAIM U(0x77)
#define FFA_FNUM_SECONDARY_EP_REGISTER U(0x84)
+#define FFA_FNUM_SPM_ID_GET U(0x85)
/* FFA SMC32 FIDs */
#define FFA_ERROR FFA_FID(SMC_32, FFA_FNUM_ERROR)
@@ -114,6 +115,7 @@
#define FFA_MEM_RETRIEVE_RESP FFA_FID(SMC_32, FFA_FNUM_MEM_RETRIEVE_RESP)
#define FFA_MEM_RELINQUISH FFA_FID(SMC_32, FFA_FNUM_MEM_RELINQUISH)
#define FFA_MEM_RECLAIM FFA_FID(SMC_32, FFA_FNUM_MEM_RECLAIM)
+#define FFA_SPM_ID_GET FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
/* FFA SMC64 FIDs */
#define FFA_SUCCESS_SMC64 FFA_FID(SMC_64, FFA_FNUM_SUCCESS)
diff --git a/include/runtime_services/spm_common.h b/include/runtime_services/spm_common.h
index 50159ec..685e732 100644
--- a/include/runtime_services/spm_common.h
+++ b/include/runtime_services/spm_common.h
@@ -13,6 +13,8 @@
/* Hypervisor ID at physical FFA instance */
#define HYP_ID (0)
+/* SPMC ID */
+#define SPMC_ID U(0x8000)
/* ID for the first Secure Partition. */
#define SPM_VM_ID_FIRST SP_ID(1)
@@ -42,6 +44,7 @@
const char *test_name;
unsigned int feature;
unsigned int expected_ret;
+ unsigned int version_added;
};
struct mailbox_buffers {
@@ -107,7 +110,7 @@
*/
bool memory_retrieve(struct mailbox_buffers *mb,
struct ffa_memory_region **retrieved, uint64_t handle,
- ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ ffa_id_t sender, ffa_id_t receiver,
uint32_t mem_func);
/**
@@ -115,7 +118,7 @@
* after it being done with the memory shared, identified by the 'handle'.
*/
bool memory_relinquish(struct ffa_mem_relinquish *m, uint64_t handle,
- ffa_vm_id_t id);
+ ffa_id_t id);
ffa_memory_handle_t memory_send(
struct ffa_memory_region *memory_region, uint32_t mem_func,
@@ -123,7 +126,7 @@
ffa_memory_handle_t memory_init_and_send(
struct ffa_memory_region *memory_region, size_t memory_region_max_size,
- ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ ffa_id_t sender, ffa_id_t receiver,
const struct ffa_memory_region_constituent* constituents,
uint32_t constituents_count, uint32_t mem_func);
diff --git a/plat/arm/fvp/include/platform_def.h b/plat/arm/fvp/include/platform_def.h
index ed45642..3afc9b8 100644
--- a/plat/arm/fvp/include/platform_def.h
+++ b/plat/arm/fvp/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -217,7 +217,11 @@
#define MAX_XLAT_TABLES 20
#define MAX_MMAP_REGIONS 50
#else
+#if IMAGE_CACTUS
+#define MAX_XLAT_TABLES 6
+#else
#define MAX_XLAT_TABLES 5
+#endif
#define MAX_MMAP_REGIONS 16
#endif
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index a52120f..ae66c1d 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -49,6 +49,7 @@
cactus_test_ffa.c \
cactus_test_interrupts.c \
cactus_test_memory_sharing.c \
+ cactus_tests_smmuv3.c \
)
# TODO: Remove dependency on TFTF files.
diff --git a/spm/cactus/cactus_interrupt.c b/spm/cactus/cactus_interrupt.c
index 7de36cf..f61df94 100644
--- a/spm/cactus/cactus_interrupt.c
+++ b/spm/cactus/cactus_interrupt.c
@@ -13,7 +13,7 @@
#include "cactus_test_cmds.h"
#include "spm_common.h"
-extern ffa_vm_id_t g_ffa_id;
+extern ffa_id_t g_ffa_id;
static void managed_exit_handler(void)
{
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index 45d2db0..73606bd 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -34,7 +34,7 @@
extern void secondary_cold_entry(void);
/* Global ffa_id */
-ffa_vm_id_t g_ffa_id;
+ffa_id_t g_ffa_id;
/*
*
@@ -45,10 +45,10 @@
*
*/
-static void __dead2 message_loop(ffa_vm_id_t vm_id, struct mailbox_buffers *mb)
+static void __dead2 message_loop(ffa_id_t vm_id, struct mailbox_buffers *mb)
{
smc_ret_values ffa_ret;
- ffa_vm_id_t destination;
+ ffa_id_t destination;
/*
* This initial wait call is necessary to inform SPMD that
@@ -93,6 +93,9 @@
/* PLAT_ARM_DEVICE0 area includes UART2 necessary to console */
MAP_REGION_FLAT(PLAT_ARM_DEVICE0_BASE, PLAT_ARM_DEVICE0_SIZE,
MT_DEVICE | MT_RW),
+ /* scratch memory allocated to be used for running SMMU tests */
+ MAP_REGION_FLAT(PLAT_CACTUS_MEMCPY_BASE, PLAT_CACTUS_MEMCPY_RANGE,
+ MT_MEMORY | MT_RW),
{0}
};
@@ -179,7 +182,7 @@
/* Get current FFA id */
smc_ret_values ffa_id_ret = ffa_id_get();
- ffa_vm_id_t ffa_id = (ffa_vm_id_t)(ffa_id_ret.ret2 & 0xffff);
+ ffa_id_t ffa_id = ffa_endpoint_id(ffa_id_ret);
if (ffa_func_id(ffa_id_ret) != FFA_SUCCESS_SMC32) {
ERROR("FFA_ID_GET failed.\n");
panic();
diff --git a/spm/cactus/cactus_tests/cactus_message_loop.c b/spm/cactus/cactus_tests/cactus_message_loop.c
index 11207dc..fde7074 100644
--- a/spm/cactus/cactus_tests/cactus_message_loop.c
+++ b/spm/cactus/cactus_tests/cactus_message_loop.c
@@ -49,7 +49,6 @@
}
}
- ERROR("Unhandled test command!\n");
*ret = cactus_error_resp(ffa_dir_msg_dest(*cmd_args),
ffa_dir_msg_source(*cmd_args),
CACTUS_ERROR_UNHANDLED);
diff --git a/spm/cactus/cactus_tests/cactus_test_direct_messaging.c b/spm/cactus/cactus_tests/cactus_test_direct_messaging.c
index a59cfa2..9b9d1aa 100644
--- a/spm/cactus/cactus_tests/cactus_test_direct_messaging.c
+++ b/spm/cactus/cactus_tests/cactus_test_direct_messaging.c
@@ -24,8 +24,8 @@
CACTUS_CMD_HANDLER(req_echo_cmd, CACTUS_REQ_ECHO_CMD)
{
smc_ret_values ffa_ret;
- ffa_vm_id_t vm_id = ffa_dir_msg_dest(*args);
- ffa_vm_id_t echo_dest = cactus_req_echo_get_echo_dest(*args);
+ ffa_id_t vm_id = ffa_dir_msg_dest(*args);
+ ffa_id_t echo_dest = cactus_req_echo_get_echo_dest(*args);
uint64_t echo_val = cactus_echo_get_val(*args);
VERBOSE("%x requested to send echo to %x, value %llx\n",
@@ -48,10 +48,10 @@
return cactus_success_resp(vm_id, ffa_dir_msg_source(*args), 0);
}
-static smc_ret_values base_deadlock_handler(ffa_vm_id_t vm_id,
- ffa_vm_id_t source,
- ffa_vm_id_t deadlock_dest,
- ffa_vm_id_t deadlock_next_dest)
+static smc_ret_values base_deadlock_handler(ffa_id_t vm_id,
+ ffa_id_t source,
+ ffa_id_t deadlock_dest,
+ ffa_id_t deadlock_next_dest)
{
smc_ret_values ffa_ret;
@@ -92,9 +92,9 @@
CACTUS_CMD_HANDLER(deadlock_cmd, CACTUS_DEADLOCK_CMD)
{
- ffa_vm_id_t source = ffa_dir_msg_source(*args);
- ffa_vm_id_t deadlock_dest = cactus_deadlock_get_next_dest(*args);
- ffa_vm_id_t deadlock_next_dest = source;
+ ffa_id_t source = ffa_dir_msg_source(*args);
+ ffa_id_t deadlock_dest = cactus_deadlock_get_next_dest(*args);
+ ffa_id_t deadlock_next_dest = source;
VERBOSE("%x is creating deadlock. next: %x\n", source, deadlock_dest);
@@ -104,10 +104,10 @@
CACTUS_CMD_HANDLER(req_deadlock_cmd, CACTUS_REQ_DEADLOCK_CMD)
{
- ffa_vm_id_t vm_id = ffa_dir_msg_dest(*args);
- ffa_vm_id_t source = ffa_dir_msg_source(*args);
- ffa_vm_id_t deadlock_dest = cactus_deadlock_get_next_dest(*args);
- ffa_vm_id_t deadlock_next_dest = cactus_deadlock_get_next_dest2(*args);
+ ffa_id_t vm_id = ffa_dir_msg_dest(*args);
+ ffa_id_t source = ffa_dir_msg_source(*args);
+ ffa_id_t deadlock_dest = cactus_deadlock_get_next_dest(*args);
+ ffa_id_t deadlock_next_dest = cactus_deadlock_get_next_dest2(*args);
VERBOSE("%x requested deadlock with %x and %x\n",
ffa_dir_msg_source(*args), deadlock_dest, deadlock_next_dest);
diff --git a/spm/cactus/cactus_tests/cactus_test_ffa.c b/spm/cactus/cactus_tests/cactus_test_ffa.c
index 2ade7bd..93f0403 100644
--- a/spm/cactus/cactus_tests/cactus_test_ffa.c
+++ b/spm/cactus/cactus_tests/cactus_test_ffa.c
@@ -20,6 +20,8 @@
#define FFA_MAJOR 1U
#define FFA_MINOR 0U
+static uint32_t spm_version;
+
static const uint32_t primary_uuid[4] = PRIMARY_UUID;
static const uint32_t secondary_uuid[4] = SECONDARY_UUID;
static const uint32_t tertiary_uuid[4] = TERTIARY_UUID;
@@ -32,23 +34,31 @@
{
const char *test_features = "FFA Features interface";
smc_ret_values ffa_ret;
+ unsigned int expected_ret;
const struct ffa_features_test *ffa_feature_test_target;
unsigned int i, test_target_size =
get_ffa_feature_test_target(&ffa_feature_test_target);
+ struct ffa_features_test test_target;
announce_test_section_start(test_features);
for (i = 0U; i < test_target_size; i++) {
- announce_test_start(ffa_feature_test_target[i].test_name);
+ test_target = ffa_feature_test_target[i];
- ffa_ret = ffa_features(ffa_feature_test_target[i].feature);
- expect(ffa_func_id(ffa_ret), ffa_feature_test_target[i].expected_ret);
- if (ffa_feature_test_target[i].expected_ret == FFA_ERROR) {
+ announce_test_start(test_target.test_name);
+
+ ffa_ret = ffa_features(test_target.feature);
+ expected_ret = FFA_VERSION_COMPILED
+ >= test_target.version_added ?
+ test_target.expected_ret : FFA_ERROR;
+
+ expect(ffa_func_id(ffa_ret), expected_ret);
+ if (expected_ret == FFA_ERROR) {
expect(ffa_error_code(ffa_ret), FFA_ERROR_NOT_SUPPORTED);
}
- announce_test_end(ffa_feature_test_target[i].test_name);
+ announce_test_end(test_target.test_name);
}
announce_test_section_end(test_features);
@@ -147,7 +157,7 @@
announce_test_start(test_ffa_version);
smc_ret_values ret = ffa_version(MAKE_FFA_VERSION(FFA_MAJOR, FFA_MINOR));
- uint32_t spm_version = (uint32_t)ret.ret0;
+ spm_version = (uint32_t)ret.ret0;
bool ffa_version_compatible =
((spm_version >> FFA_VERSION_MAJOR_SHIFT) == FFA_MAJOR &&
@@ -163,6 +173,32 @@
announce_test_end(test_ffa_version);
}
+void ffa_spm_id_get_test(void)
+{
+ const char *test_spm_id_get = "FFA_SPM_ID_GET SMC Function";
+
+ announce_test_start(test_spm_id_get);
+
+ if (spm_version >= MAKE_FFA_VERSION(1, 1)) {
+ smc_ret_values ret = ffa_spm_id_get();
+
+ expect(ffa_func_id(ret), FFA_SUCCESS_SMC32);
+
+ ffa_id_t spm_id = ffa_endpoint_id(ret);
+
+ VERBOSE("SPM ID = 0x%x\n", spm_id);
+ /*
+ * Check the SPMC value given in the fvp_spmc_manifest
+ * is returned.
+ */
+ expect(spm_id, SPMC_ID);
+ } else {
+ NOTICE("FFA_SPM_ID_GET not supported in this version of FF-A."
+ " Test skipped.\n");
+ }
+ announce_test_end(test_spm_id_get);
+}
+
void ffa_tests(struct mailbox_buffers *mb)
{
const char *test_ffa = "FFA Interfaces";
@@ -171,6 +207,7 @@
ffa_features_test();
ffa_version_test();
+ ffa_spm_id_get_test();
ffa_partition_info_get_test(mb);
announce_test_section_end(test_ffa);
diff --git a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
index e7bce50..604058a 100644
--- a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
+++ b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
@@ -24,8 +24,8 @@
int ret;
unsigned int mem_attrs;
uint32_t *ptr;
- ffa_vm_id_t source = ffa_dir_msg_source(*args);
- ffa_vm_id_t vm_id = ffa_dir_msg_dest(*args);
+ ffa_id_t source = ffa_dir_msg_source(*args);
+ ffa_id_t vm_id = ffa_dir_msg_dest(*args);
uint32_t mem_func = cactus_req_mem_send_get_mem_func(*args);
uint64_t handle = cactus_mem_send_get_handle(*args);
@@ -107,10 +107,10 @@
{
smc_ret_values ffa_ret;
uint32_t mem_func = cactus_req_mem_send_get_mem_func(*args);
- ffa_vm_id_t receiver = cactus_req_mem_send_get_receiver(*args);
+ ffa_id_t receiver = cactus_req_mem_send_get_receiver(*args);
ffa_memory_handle_t handle;
- ffa_vm_id_t vm_id = ffa_dir_msg_dest(*args);
- ffa_vm_id_t source = ffa_dir_msg_source(*args);
+ ffa_id_t vm_id = ffa_dir_msg_dest(*args);
+ ffa_id_t source = ffa_dir_msg_source(*args);
VERBOSE("%x requested to send memory to %x (func: %x)\n",
source, receiver, mem_func);
diff --git a/spm/cactus/cactus_tests/cactus_tests_smmuv3.c b/spm/cactus/cactus_tests/cactus_tests_smmuv3.c
new file mode 100644
index 0000000..fbf46c8
--- /dev/null
+++ b/spm/cactus/cactus_tests/cactus_tests_smmuv3.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include "cactus.h"
+#include "cactus_message_loop.h"
+#include <cactus_platform_def.h>
+#include "cactus_test_cmds.h"
+#include "cactus_tests.h"
+#include <debug.h>
+#include <ffa_helpers.h>
+#include <mmio.h>
+#include "smmuv3_test_engine.h"
+#include <sp_helpers.h>
+#include <spm_common.h>
+
+/* Source and target address for memcopy operation */
+#define MEMCPY_SOURCE_BASE PLAT_CACTUS_MEMCPY_BASE
+#define MEMPCY_TOTAL_SIZE (PLAT_CACTUS_MEMCPY_RANGE / 2)
+#define MEMCPY_TARGET_BASE (MEMCPY_SOURCE_BASE + MEMPCY_TOTAL_SIZE)
+
+/* Miscellaneous */
+#define NO_SUBSTREAMID (0xFFFFFFFFU)
+#define TRANSFER_SIZE (MEMPCY_TOTAL_SIZE / FRAME_COUNT)
+#define LOOP_COUNT (5000U)
+
+static bool run_smmuv3_test(void)
+{
+ uint64_t source_addr, cpy_range, target_addr;
+ uint64_t begin_addr, end_addr, dest_addr;
+ uint32_t status;
+ unsigned int i, f, attempts;
+
+ /*
+ * The test engine's MEMCPY command copies data from the region in
+ * range [begin, end_incl] to the region with base address as udata.
+ * In this test, we configure the test engine to initiate memcpy from
+ * scratch page located at MEMCPY_SOURCE_BASE to the page located at
+ * address MEMCPY_TARGET_BASE
+ */
+
+ VERBOSE("CACTUS: Running SMMUv3 test\n");
+
+ source_addr = MEMCPY_SOURCE_BASE;
+ cpy_range = MEMPCY_TOTAL_SIZE;
+ target_addr = MEMCPY_TARGET_BASE;
+ uint32_t streamID_list[] = { 0U, 1U };
+
+ uint64_t data[] = {
+ ULL(0xBAADFEEDCEEBDAAF),
+ ULL(0x0123456776543210)
+ };
+
+ /* Write pre-determined content to source pages */
+ for (i = 0U; i < (cpy_range / 8U); i++) {
+ mmio_write64_offset(source_addr, i * 8, data[i%2]);
+ }
+
+ /* Clean the data caches */
+ clean_dcache_range(source_addr, cpy_range);
+
+ /*
+ * Make sure above load, store and cache maintenance instructions
+ * complete before we start writing to TestEngine frame configuration
+ * fields
+ */
+ dsbsy();
+
+ for (f = 0U; f < FRAME_COUNT; f++) {
+ attempts = 0U;
+ begin_addr = source_addr + (TRANSFER_SIZE * f);
+ end_addr = begin_addr + TRANSFER_SIZE - 1U;
+ dest_addr = target_addr + (TRANSFER_SIZE * f);
+
+ /* Initiate DMA sequence */
+ mmio_write32_offset(PRIV_BASE_FRAME + F_IDX(f), PCTRL_OFF, 0);
+ mmio_write32_offset(PRIV_BASE_FRAME + F_IDX(f), DOWNSTREAM_PORT_OFF, 0);
+ mmio_write32_offset(PRIV_BASE_FRAME + F_IDX(f), STREAM_ID_OFF, streamID_list[f%2]);
+ mmio_write32_offset(PRIV_BASE_FRAME + F_IDX(f), SUBSTREAM_ID_OFF, NO_SUBSTREAMID);
+
+ mmio_write32_offset(USR_BASE_FRAME + F_IDX(f), UCTRL_OFF, 0);
+ mmio_write32_offset(USR_BASE_FRAME + F_IDX(f), SEED_OFF, 0);
+ mmio_write64_offset(USR_BASE_FRAME + F_IDX(f), BEGIN_OFF, begin_addr);
+ mmio_write64_offset(USR_BASE_FRAME + F_IDX(f), END_CTRL_OFF, end_addr);
+
+ /* Legal values for stride: 1 and any multiples of 8 */
+ mmio_write64_offset(USR_BASE_FRAME + F_IDX(f), STRIDE_OFF, 1);
+ mmio_write64_offset(USR_BASE_FRAME + F_IDX(f), UDATA_OFF, dest_addr);
+
+ mmio_write32_offset(USR_BASE_FRAME + F_IDX(f), CMD_OFF, ENGINE_MEMCPY);
+ VERBOSE("SMMUv3TestEngine: Waiting for MEMCPY completion for frame: %u\n", f);
+
+ /*
+ * It is guaranteed that a read of "cmd" fields after writing to it will
+ * immediately return ENGINE_FRAME_MISCONFIGURED if the command was
+ * invalid.
+ */
+ if (mmio_read32_offset(USR_BASE_FRAME + F_IDX(f), CMD_OFF) == ENGINE_MIS_CFG) {
+ ERROR("SMMUv3TestEngine: Misconfigured for frame: %u\n", f);
+ return false;
+ }
+
+ /* Wait for mem copy to be complete */
+ while (attempts++ < LOOP_COUNT) {
+ status = mmio_read32_offset(USR_BASE_FRAME + F_IDX(f), CMD_OFF);
+ if (status == ENGINE_HALTED) {
+ break;
+ } else if (status == ENGINE_ERROR) {
+ ERROR("SMMUv3: Test failed\n");
+ return false;
+ }
+
+ /*
+ * TODO: Introduce a small delay here to make sure the
+ * CPU memory accesses do not starve the interconnect
+ * due to continuous polling.
+ */
+ }
+
+ if (attempts == LOOP_COUNT) {
+ ERROR("SMMUv3: Test failed\n");
+ return false;
+ }
+
+ dsbsy();
+ }
+
+ /*
+ * Invalidate cached entries to force the CPU to fetch the data from
+ * Main memory
+ */
+ inv_dcache_range(source_addr, cpy_range);
+ inv_dcache_range(target_addr, cpy_range);
+
+ /* Compare source and destination memory locations for data */
+ for (i = 0U; i < (cpy_range / 8U); i++) {
+ if (mmio_read_64(source_addr + 8 * i) != mmio_read_64(target_addr + 8 * i)) {
+ ERROR("SMMUv3: Mem copy failed: %llx\n", target_addr + 8 * i);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+CACTUS_CMD_HANDLER(smmuv3_cmd, CACTUS_DMA_SMMUv3_CMD)
+{
+ smc_ret_values ffa_ret;
+ ffa_id_t vm_id = ffa_dir_msg_dest(*args);
+ ffa_id_t source = ffa_dir_msg_source(*args);
+
+ VERBOSE("Received request through direct message for DMA service\n");
+
+ /*
+ * At present, the test cannot be run concurrently on multiple SPs as
+ * there is only one SMMUv3TestEngine IP in the FVP model. Hence, run
+ * the test only on the first SP.
+ */
+ if (vm_id != SPM_VM_ID_FIRST) {
+ return cactus_error_resp(vm_id, source, 0);
+ }
+
+ if (run_smmuv3_test()) {
+ ffa_ret = cactus_success_resp(vm_id, source, 0);
+ } else {
+ ffa_ret = cactus_error_resp(vm_id, source, 0);
+ }
+
+ return ffa_ret;
+}
diff --git a/spm/cactus/cactus_tests/smmuv3_test_engine.h b/spm/cactus/cactus_tests/smmuv3_test_engine.h
new file mode 100644
index 0000000..32d86ac
--- /dev/null
+++ b/spm/cactus/cactus_tests/smmuv3_test_engine.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* The test engine supports numerous frames but we only use a few */
+#define FRAME_COUNT (2U)
+#define FRAME_SIZE (0x80U) /* 128 bytes */
+#define F_IDX(n) (n * FRAME_SIZE)
+
+/* Commands supported by SMMUv3TestEngine built into the AEM */
+#define ENGINE_NO_FRAME (0U)
+#define ENGINE_HALTED (1U)
+
+/*
+ * ENGINE_MEMCPY: Read and Write transactions
+ * ENGINE_RAND48: Only Write transactions: Source address not required
+ * ENGINE_SUM64: Only read transactions: Target address not required
+ */
+#define ENGINE_MEMCPY (2U)
+#define ENGINE_RAND48 (3U)
+#define ENGINE_SUM64 (4U)
+#define ENGINE_ERROR (0xFFFFFFFFU)
+#define ENGINE_MIS_CFG (ENGINE_ERROR - 1)
+
+/*
+ * Refer to:
+ * https://developer.arm.com/documentation/100964/1111-00/Trace-components/SMMUv3TestEngine---trace
+ */
+
+/* Offset of various control fields belonging to User Frame */
+#define CMD_OFF (0x0U)
+#define UCTRL_OFF (0x4U)
+#define SEED_OFF (0x24U)
+#define BEGIN_OFF (0x28U)
+#define END_CTRL_OFF (0x30U)
+#define STRIDE_OFF (0x38U)
+#define UDATA_OFF (0x40U)
+
+/* Offset of various control fields belonging to PRIV Frame */
+#define PCTRL_OFF (0x0U)
+#define DOWNSTREAM_PORT_OFF (0x4U)
+#define STREAM_ID_OFF (0x8U)
+#define SUBSTREAM_ID_OFF (0xCU)
diff --git a/spm/cactus/plat/arm/fvp/fdts/cactus.dts b/spm/cactus/plat/arm/fvp/fdts/cactus.dts
index eb569f7..1c28fde 100644
--- a/spm/cactus/plat/arm/fvp/fdts/cactus.dts
+++ b/spm/cactus/plat/arm/fvp/fdts/cactus.dts
@@ -62,6 +62,24 @@
pages-count = <4>;
attributes = <0x7>; /* read-write-execute */
};
+
+ /*
+ * Scratch memory used for the purpose of testing SMMUv3 driver
+ * through Cactus SP
+ */
+ smmuv3-memcpy-src {
+ description = "smmuv3-memcpy-source";
+ pages-count = <4>;
+ base-address = <0x00000000 0x7400000>;
+ attributes = <0x3>; /* read-write */
+ };
+
+ smmuv3-memcpy-dst {
+ description = "smmuv3-memcpy-destination";
+ pages-count = <4>;
+ base-address = <0x00000000 0x7404000>;
+ attributes = <0x3>; /* read-write */
+ };
};
device-regions {
@@ -73,6 +91,20 @@
attributes = <0x3>; /* read-write */
};
+ smmuv3-testengine {
+ /*
+ * SMMUv3TestEngine is a DMA IP modeled in the
+ * Base-RevC FVP Model.
+ * User Frame: 0x2bfe0000
+ * Privileged Frame: 0x2bff0000
+ */
+ base-address = <0x00000000 0x2bfe0000>;
+ pages-count = <32>; /* Two 64KB pages */
+ attributes = <0x3>; /* read-write */
+ smmu-id = <0>;
+ stream-ids = <0x0 0x1>;
+ };
+
test-reg {
/* Dummy Values */
base-address = <0x00000000 0x22000000>;
diff --git a/spm/cactus/plat/arm/fvp/include/cactus_platform_def.h b/spm/cactus/plat/arm/fvp/include/cactus_platform_def.h
index b4c57ef..8940c83 100644
--- a/spm/cactus/plat/arm/fvp/include/cactus_platform_def.h
+++ b/spm/cactus/plat/arm/fvp/include/cactus_platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,8 +18,16 @@
#define PLAT_CACTUS_RX_BASE ULL(0x7300000)
#define PLAT_CACTUS_CORE_COUNT (8U)
+/* Scratch memory used for SMMUv3 driver testing purposes in Cactus SP */
+#define PLAT_CACTUS_MEMCPY_BASE ULL(0x7400000)
+#define PLAT_CACTUS_MEMCPY_RANGE ULL(0x8000)
+
#define CACTUS_PRIMARY_EC_COUNT (8U)
#define CACTUS_SECONDARY_EC_COUNT (8U)
#define CACTUS_TERTIARY_EC_COUNT (1U)
+/* Base address of user and PRIV frames in SMMUv3TestEngine */
+#define USR_BASE_FRAME ULL(0x2BFE0000)
+#define PRIV_BASE_FRAME ULL(0x2BFF0000)
+
#endif /* CACTUS_PLATFORM_DEF_H */
diff --git a/tftf/tests/runtime_services/secure_service/ffa_helpers.c b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
index 8e7b58c..4c69eb1 100644
--- a/tftf/tests/runtime_services/secure_service/ffa_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
@@ -55,8 +55,8 @@
* -BUSY: Message target is busy
* -ABORTED: Message target ran into an unexpected error and has aborted
*/
-smc_ret_values ffa_msg_send_direct_req64(ffa_vm_id_t source_id,
- ffa_vm_id_t dest_id, uint64_t arg0,
+smc_ret_values ffa_msg_send_direct_req64(ffa_id_t source_id,
+ ffa_id_t dest_id, uint64_t arg0,
uint64_t arg1, uint64_t arg2,
uint64_t arg3, uint64_t arg4)
{
@@ -74,8 +74,8 @@
return tftf_smc(&args);
}
-smc_ret_values ffa_msg_send_direct_req32(ffa_vm_id_t source_id,
- ffa_vm_id_t dest_id, uint32_t arg0,
+smc_ret_values ffa_msg_send_direct_req32(ffa_id_t source_id,
+ ffa_id_t dest_id, uint32_t arg0,
uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t arg4)
{
@@ -93,8 +93,8 @@
return tftf_smc(&args);
}
-smc_ret_values ffa_msg_send_direct_resp64(ffa_vm_id_t source_id,
- ffa_vm_id_t dest_id, uint64_t arg0,
+smc_ret_values ffa_msg_send_direct_resp64(ffa_id_t source_id,
+ ffa_id_t dest_id, uint64_t arg0,
uint64_t arg1, uint64_t arg2,
uint64_t arg3, uint64_t arg4)
{
@@ -112,8 +112,8 @@
return tftf_smc(&args);
}
-smc_ret_values ffa_msg_send_direct_resp32(ffa_vm_id_t source_id,
- ffa_vm_id_t dest_id, uint32_t arg0,
+smc_ret_values ffa_msg_send_direct_resp32(ffa_id_t source_id,
+ ffa_id_t dest_id, uint32_t arg0,
uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t arg4)
{
@@ -137,9 +137,9 @@
* composite memory region offset.
*/
static void ffa_memory_region_init_header(
- struct ffa_memory_region *memory_region, ffa_vm_id_t sender,
+ struct ffa_memory_region *memory_region, ffa_id_t sender,
ffa_memory_attributes_t attributes, ffa_memory_region_flags_t flags,
- ffa_memory_handle_t handle, uint32_t tag, ffa_vm_id_t receiver,
+ ffa_memory_handle_t handle, uint32_t tag, ffa_id_t receiver,
ffa_memory_access_permissions_t permissions)
{
memory_region->sender = sender;
@@ -168,7 +168,7 @@
*/
uint32_t ffa_memory_region_init(
struct ffa_memory_region *memory_region, size_t memory_region_max_size,
- ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ ffa_id_t sender, ffa_id_t receiver,
const struct ffa_memory_region_constituent constituents[],
uint32_t constituent_count, uint32_t tag,
ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
@@ -259,7 +259,7 @@
*/
uint32_t ffa_memory_retrieve_request_init(
struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
- ffa_vm_id_t sender, ffa_vm_id_t receiver, uint32_t tag,
+ ffa_id_t sender, ffa_id_t receiver, uint32_t tag,
ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
enum ffa_instruction_access instruction_access,
enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
@@ -291,7 +291,6 @@
memory_region->receiver_count * sizeof(struct ffa_memory_access);
}
-
/*
* FFA Version ABI helper.
* Version fields:
@@ -317,6 +316,15 @@
return tftf_smc(&args);
}
+smc_ret_values ffa_spm_id_get(void)
+{
+ smc_args args = {
+ .fid = FFA_SPM_ID_GET
+ };
+
+ return tftf_smc(&args);
+}
+
smc_ret_values ffa_msg_wait(void)
{
smc_args args = {
diff --git a/tftf/tests/runtime_services/secure_service/spm_common.c b/tftf/tests/runtime_services/secure_service/spm_common.c
index 12b70a9..e2d3392 100644
--- a/tftf/tests/runtime_services/secure_service/spm_common.c
+++ b/tftf/tests/runtime_services/secure_service/spm_common.c
@@ -6,6 +6,7 @@
#include <debug.h>
#include <ffa_endpoints.h>
+#include <ffa_svc.h>
#include <spm_common.h>
#include <xlat_tables_v2.h>
@@ -19,7 +20,7 @@
bool is_ffa_call_error(smc_ret_values ret)
{
if (ffa_func_id(ret) == FFA_ERROR) {
- ERROR("FF-A call returned error (%x): %d\n",
+ VERBOSE("FF-A call returned error (%x): %d\n",
ffa_func_id(ret), ffa_error_code(ret));
return true;
}
@@ -38,7 +39,7 @@
return true;
}
- ERROR("%x is not FF-A response.\n", ffa_func_id(ret));
+ VERBOSE("%x is not FF-A response.\n", ffa_func_id(ret));
/* To log error in case it is FFA_ERROR*/
is_ffa_call_error(ret);
@@ -54,7 +55,7 @@
return true;
}
- ERROR("Expecting %x, FF-A return was %x\n", func_id, ffa_func_id(ret));
+ VERBOSE("Expecting %x, FF-A return was %x\n", func_id, ffa_func_id(ret));
return false;
}
@@ -166,6 +167,8 @@
{"FFA_RXTX_UNMAP_32 check", FFA_RXTX_UNMAP, FFA_ERROR},
{"FFA_PARTITION_INFO_GET_32 check", FFA_PARTITION_INFO_GET, FFA_SUCCESS_SMC32},
{"FFA_ID_GET_32 check", FFA_ID_GET, FFA_SUCCESS_SMC32},
+ {"FFA_SPM_ID_GET_32 check", FFA_SPM_ID_GET, FFA_SUCCESS_SMC32,
+ MAKE_FFA_VERSION(1, 1)},
{"FFA_MSG_POLL_32 check", FFA_MSG_POLL, FFA_SUCCESS_SMC32},
{"FFA_MSG_WAIT_32 check", FFA_MSG_WAIT, FFA_SUCCESS_SMC32},
{"FFA_YIELD_32 check", FFA_MSG_YIELD, FFA_SUCCESS_SMC32},
@@ -199,7 +202,7 @@
bool memory_retrieve(struct mailbox_buffers *mb,
struct ffa_memory_region **retrieved, uint64_t handle,
- ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ ffa_id_t sender, ffa_id_t receiver,
uint32_t mem_func)
{
smc_ret_values ret;
@@ -269,7 +272,7 @@
}
bool memory_relinquish(struct ffa_mem_relinquish *m, uint64_t handle,
- ffa_vm_id_t id)
+ ffa_id_t id)
{
smc_ret_values ret;
@@ -297,7 +300,7 @@
uint32_t fragment_length, uint32_t total_length)
{
smc_ret_values ret;
- ffa_vm_id_t receiver =
+ ffa_id_t receiver =
memory_region->receivers[0].receiver_permissions.receiver;
if (fragment_length != total_length) {
@@ -336,7 +339,7 @@
*/
ffa_memory_handle_t memory_init_and_send(
struct ffa_memory_region *memory_region, size_t memory_region_max_size,
- ffa_vm_id_t sender, ffa_vm_id_t receiver,
+ ffa_id_t sender, ffa_id_t receiver,
const struct ffa_memory_region_constituent *constituents,
uint32_t constituents_count, uint32_t mem_func)
{
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
index 0a722e4..1b9abe9 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
@@ -27,8 +27,8 @@
static event_t cpu_booted[PLATFORM_CORE_COUNT];
-static test_result_t send_cactus_echo_cmd(ffa_vm_id_t sender,
- ffa_vm_id_t dest,
+static test_result_t send_cactus_echo_cmd(ffa_id_t sender,
+ ffa_id_t dest,
uint64_t value)
{
smc_ret_values ret;
@@ -92,9 +92,9 @@
* otherwise.
* For the CACTUS_SUCCESS response, the test returns TEST_RESULT_SUCCESS.
*/
-static test_result_t send_cactus_req_echo_cmd(ffa_vm_id_t sender,
- ffa_vm_id_t dest,
- ffa_vm_id_t echo_dest,
+static test_result_t send_cactus_req_echo_cmd(ffa_id_t sender,
+ ffa_id_t dest,
+ ffa_id_t echo_dest,
uint64_t value)
{
smc_ret_values ret;
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_features.c b/tftf/tests/runtime_services/secure_service/test_ffa_features.c
deleted file mode 100644
index e4cd845..0000000
--- a/tftf/tests/runtime_services/secure_service/test_ffa_features.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <spm_common.h>
-#include <test_helpers.h>
-#include <tftf_lib.h>
-
-test_result_t test_ffa_features(void)
-{
- SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 0);
-
- /* Check if SPMC is OP-TEE at S-EL1 */
- if (check_spmc_execution_level()) {
- /* FFA_FEATURES is not yet supported in OP-TEE */
- return TEST_RESULT_SUCCESS;
- }
-
- smc_ret_values ffa_ret;
- const struct ffa_features_test *ffa_feature_test_target;
- unsigned int i, test_target_size =
- get_ffa_feature_test_target(&ffa_feature_test_target);
-
- for (i = 0U; i < test_target_size; i++) {
- ffa_ret = ffa_features(ffa_feature_test_target[i].feature);
- if (ffa_func_id(ffa_ret) != ffa_feature_test_target[i].expected_ret) {
- tftf_testcase_printf("%s returned %x, expected %x\n",
- ffa_feature_test_target[i].test_name,
- ffa_func_id(ffa_ret),
- ffa_feature_test_target[i].expected_ret);
- return TEST_RESULT_FAIL;
- }
- if ((ffa_feature_test_target[i].expected_ret == FFA_ERROR) &&
- (ffa_error_code(ffa_ret) != FFA_ERROR_NOT_SUPPORTED)) {
- tftf_testcase_printf("%s failed for the wrong reason: "
- "returned %x, expected %x\n",
- ffa_feature_test_target[i].test_name,
- ffa_error_code(ffa_ret),
- FFA_ERROR_NOT_SUPPORTED);
- return TEST_RESULT_FAIL;
- }
- }
-
- return TEST_RESULT_SUCCESS;
-}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
index f126c57..46a7349 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
@@ -130,8 +130,8 @@
* Cactus SP should reply to TFTF on whether the test succeeded or not.
*/
static test_result_t test_req_mem_send_sp_to_sp(uint32_t mem_func,
- ffa_vm_id_t sender_sp,
- ffa_vm_id_t receiver_sp)
+ ffa_id_t sender_sp,
+ ffa_id_t receiver_sp)
{
smc_ret_values ret;
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_rxtx_map.c b/tftf/tests/runtime_services/secure_service/test_ffa_rxtx_map.c
deleted file mode 100644
index 1b47c5f..0000000
--- a/tftf/tests/runtime_services/secure_service/test_ffa_rxtx_map.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <debug.h>
-
-#include <test_helpers.h>
-#include <xlat_tables_defs.h>
-
-static struct mailbox_buffers mb;
-
-static test_result_t test_ffa_rxtx_map(uint32_t expected_return)
-{
- smc_ret_values ret;
-
- /**********************************************************************
- * Verify that FFA is there and that it has the correct version.
- **********************************************************************/
- SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 0);
-
- /**********************************************************************
- * If OP-TEE is SPMC skip this test.
- **********************************************************************/
- if (check_spmc_execution_level()) {
- VERBOSE("OP-TEE as SPMC at S-EL1. Skipping test!\n");
- return TEST_RESULT_SKIPPED;
- }
-
- /*
- * Declare RXTX buffers, assign them to the mailbox and call
- * FFA_RXTX_MAP.
- */
- CONFIGURE_AND_MAP_MAILBOX(mb, PAGE_SIZE, ret);
- if (ffa_func_id(ret) != expected_return) {
- ERROR("Failed to map RXTX buffers %x!\n", ffa_error_code(ret));
- return TEST_RESULT_FAIL;
- }
-
- return TEST_RESULT_SUCCESS;
-}
-
-/**
- * Test mapping RXTX buffers from NWd.
- * This test also sets the Mailbox for other SPM related tests that need to use
- * RXTX buffers.
- */
-test_result_t test_ffa_rxtx_map_success(void)
-{
- test_result_t ret = test_ffa_rxtx_map(FFA_SUCCESS_SMC32);
-
- if (ret == TEST_RESULT_SUCCESS) {
- INFO("Set RXTX Mailbox for remaining spm tests!\n");
- set_tftf_mailbox(&mb);
- }
- return ret;
-}
-
-/**
- * Test to verify that 2nd call to FFA_RXTX_MAP should fail.
- */
-test_result_t test_ffa_rxtx_map_fail(void)
-{
- INFO("This test expects error log.\n");
- return test_ffa_rxtx_map(FFA_ERROR);
-}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
new file mode 100644
index 0000000..f8a5ace
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+
+#include <ffa_svc.h>
+#include <ffa_helpers.h>
+#include <spm_common.h>
+#include <test_helpers.h>
+#include <tftf_lib.h>
+#include <xlat_tables_defs.h>
+
+static bool should_skip_version_test;
+
+static struct mailbox_buffers mb;
+
+/*
+ * Using FFA version expected for SPM.
+ */
+#define SPM_VERSION MAKE_FFA_VERSION(FFA_VERSION_MAJOR, FFA_VERSION_MINOR)
+
+/******************************************************************************
+ * FF-A Features ABI Tests
+ ******************************************************************************/
+
+test_result_t test_ffa_features(void)
+{
+ SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 0);
+
+ /* Check if SPMC is OP-TEE at S-EL1 */
+ if (check_spmc_execution_level()) {
+ /* FFA_FEATURES is not yet supported in OP-TEE */
+ return TEST_RESULT_SUCCESS;
+ }
+
+ smc_ret_values ffa_ret;
+ unsigned int expected_ret;
+ const struct ffa_features_test *ffa_feature_test_target;
+ unsigned int i, test_target_size =
+ get_ffa_feature_test_target(&ffa_feature_test_target);
+ struct ffa_features_test test_target;
+
+ for (i = 0U; i < test_target_size; i++) {
+ test_target = ffa_feature_test_target[i];
+ ffa_ret = ffa_features(test_target.feature);
+ expected_ret = FFA_VERSION_COMPILED
+ >= test_target.version_added ?
+ test_target.expected_ret : FFA_ERROR;
+ if (ffa_func_id(ffa_ret) != expected_ret) {
+ tftf_testcase_printf("%s returned %x, expected %x\n",
+ test_target.test_name,
+ ffa_func_id(ffa_ret),
+ expected_ret);
+ return TEST_RESULT_FAIL;
+ }
+ if ((expected_ret == FFA_ERROR) &&
+ (ffa_error_code(ffa_ret) != FFA_ERROR_NOT_SUPPORTED)) {
+ tftf_testcase_printf("%s failed for the wrong reason: "
+ "returned %x, expected %x\n",
+ test_target.test_name,
+ ffa_error_code(ffa_ret),
+ FFA_ERROR_NOT_SUPPORTED);
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/******************************************************************************
+ * FF-A Version ABI Tests
+ ******************************************************************************/
+
+/*
+ * Calls FFA Version ABI, and checks if the result as expected.
+ */
+static test_result_t test_ffa_version(uint32_t input_version,
+ uint32_t expected_return)
+{
+ if (should_skip_version_test) {
+ return TEST_RESULT_SKIPPED;
+ }
+
+ smc_ret_values ret_values = ffa_version(input_version);
+
+ uint32_t spm_version = (uint32_t)(0xFFFFFFFF & ret_values.ret0);
+
+ if (spm_version == expected_return) {
+ return TEST_RESULT_SUCCESS;
+ }
+
+ tftf_testcase_printf("Input Version: 0x%x\n"
+ "Return: 0x%x\nExpected: 0x%x\n",
+ input_version, spm_version, expected_return);
+
+ return TEST_RESULT_FAIL;
+}
+
+/*
+ * @Test_Aim@ Validate what happens when using same version as SPM.
+ */
+test_result_t test_ffa_version_equal(void)
+{
+ /*
+ * FFA_VERSION interface is used to check that SPM functionality is
+ * supported. On FFA_VERSION invocation from TFTF, the SPMD returns
+ * either NOT_SUPPORTED or the SPMC version value provided in the SPMC
+ * manifest. The variable "should_skip_test" is set to true when the
+ * SPMD returns NOT_SUPPORTED or a mismatched version, which means that
+ * a TFTF physical FF-A endpoint version (SPM_VERSION) does not match
+ * the SPMC's physical FF-A endpoint version. This prevents running the
+ * subsequent FF-A version tests (and break the test flow), as they're
+ * not relevant when the SPMD is not present within BL31
+ * (FFA_VERSION returns NOT_SUPPORTED).
+ */
+ test_result_t ret = test_ffa_version(SPM_VERSION, SPM_VERSION);
+
+ if (ret != TEST_RESULT_SUCCESS) {
+ should_skip_version_test = true;
+ ret = TEST_RESULT_SKIPPED;
+ }
+ return ret;
+}
+
+/*
+ * @Test_Aim@ Validate what happens when setting bit 31 in
+ * 'input_version'. As per spec, FFA version is 31 bits long.
+ * Bit 31 set is an invalid input.
+ */
+test_result_t test_ffa_version_bit31(void)
+{
+ return test_ffa_version(FFA_VERSION_BIT31_MASK | SPM_VERSION,
+ FFA_ERROR_NOT_SUPPORTED);
+}
+
+/*
+ * @Test_Aim@ Validate what happens for bigger version than SPM's.
+ */
+test_result_t test_ffa_version_bigger(void)
+{
+ return test_ffa_version(MAKE_FFA_VERSION(FFA_VERSION_MAJOR + 1, 0),
+ SPM_VERSION);
+}
+
+/*
+ * @Test_Aim@ Validate what happens for smaller version than SPM's.
+ */
+test_result_t test_ffa_version_smaller(void)
+{
+ return test_ffa_version(MAKE_FFA_VERSION(0, 9), SPM_VERSION);
+}
+
+/******************************************************************************
+ * FF-A RXTX ABI Tests
+ ******************************************************************************/
+
+static test_result_t test_ffa_rxtx_map(uint32_t expected_return)
+{
+ smc_ret_values ret;
+
+ /**********************************************************************
+ * Verify that FFA is there and that it has the correct version.
+ **********************************************************************/
+ SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 0);
+
+ /**********************************************************************
+ * If OP-TEE is SPMC skip this test.
+ **********************************************************************/
+ if (check_spmc_execution_level()) {
+ VERBOSE("OP-TEE as SPMC at S-EL1. Skipping test!\n");
+ return TEST_RESULT_SKIPPED;
+ }
+
+ /*
+ * Declare RXTX buffers, assign them to the mailbox and call
+ * FFA_RXTX_MAP.
+ */
+ CONFIGURE_AND_MAP_MAILBOX(mb, PAGE_SIZE, ret);
+ if (ffa_func_id(ret) != expected_return) {
+ ERROR("Failed to map RXTX buffers %x!\n", ffa_error_code(ret));
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/**
+ * Test mapping RXTX buffers from NWd.
+ * This test also sets the Mailbox for other SPM related tests that need to use
+ * RXTX buffers.
+ */
+test_result_t test_ffa_rxtx_map_success(void)
+{
+ test_result_t ret = test_ffa_rxtx_map(FFA_SUCCESS_SMC32);
+
+ if (ret == TEST_RESULT_SUCCESS) {
+ INFO("Set RXTX Mailbox for remaining spm tests!\n");
+ set_tftf_mailbox(&mb);
+ }
+ return ret;
+}
+
+/**
+ * Test to verify that 2nd call to FFA_RXTX_MAP should fail.
+ */
+test_result_t test_ffa_rxtx_map_fail(void)
+{
+ INFO("This test expects error log.\n");
+ return test_ffa_rxtx_map(FFA_ERROR);
+}
+
+/******************************************************************************
+ * FF-A SPM_ID_GET ABI Tests
+ ******************************************************************************/
+
+test_result_t test_ffa_spm_id_get(void)
+{
+ SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
+
+ smc_ret_values ffa_ret = ffa_spm_id_get();
+
+ if (is_ffa_call_error(ffa_ret)) {
+ ERROR("FFA_SPM_ID_GET call failed! Error code: 0x%x\n",
+ ffa_error_code(ffa_ret));
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Check the SPMC value given in the fvp_spmc_manifest is returned */
+ ffa_id_t spm_id = ffa_endpoint_id(ffa_ret);
+
+ if (spm_id != SPMC_ID) {
+ ERROR("Expected SPMC_ID of 0x%x\n received: 0x%x\n",
+ SPMC_ID, spm_id);
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_version.c b/tftf/tests/runtime_services/secure_service/test_ffa_version.c
deleted file mode 100644
index 41eca5a..0000000
--- a/tftf/tests/runtime_services/secure_service/test_ffa_version.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <ffa_svc.h>
-#include <test_helpers.h>
-#include <tftf_lib.h>
-
-/*
- * Using FFA version expected for SPM.
- */
-#define SPM_VERSION MAKE_FFA_VERSION(FFA_VERSION_MAJOR, FFA_VERSION_MINOR)
-
-static bool should_skip_test;
-
-/*
- * Calls FFA Version ABI, and checks if the result as expected.
- */
-static test_result_t test_ffa_version(uint32_t input_version, uint32_t expected_return)
-{
- if (should_skip_test) {
- return TEST_RESULT_SKIPPED;
- }
-
- smc_ret_values ret_values = ffa_version(input_version);
-
- uint32_t spm_version = (uint32_t)(0xFFFFFFFF & ret_values.ret0);
-
- if (spm_version == expected_return) {
- return TEST_RESULT_SUCCESS;
- }
-
- tftf_testcase_printf("Input Version: 0x%x\nReturn: 0x%x\nExpected: 0x%x\n",
- input_version, spm_version, expected_return);
-
- return TEST_RESULT_FAIL;
-}
-
-/*
- * @Test_Aim@ Validate what happens when using same version as SPM.
- */
-test_result_t test_ffa_version_equal(void)
-{
- /*
- * FFA_VERSION interface is used to check that SPM functionality is supported.
- * On FFA_VERSION invocation from TFTF, the SPMD returns either NOT_SUPPORTED or
- * the SPMC version value provided in the SPMC manifest. The variable "should_skip_test"
- * is set to true when the SPMD returns NOT_SUPPORTED or a mismatched version, which
- * means that a TFTF physical FF-A endpoint version (SPM_VERSION) does not match the
- * SPMC's physical FF-A endpoint version. This prevents running the subsequent FF-A
- * version tests (and break the test flow), as they're not relevant when the SPMD is
- * not present within BL31 (FFA_VERSION returns NOT_SUPPORTED).
- */
- test_result_t ret = test_ffa_version(SPM_VERSION, SPM_VERSION);
- if (ret != TEST_RESULT_SUCCESS) {
- should_skip_test = true;
- ret = TEST_RESULT_SKIPPED;
- }
- return ret;
-}
-
-/*
- * @Test_Aim@ Validate what happens when setting bit 31 in
- * 'input_version'. As per spec, FFA version is 31 bits long.
- * Bit 31 set is an invalid input.
- */
-test_result_t test_ffa_version_bit31(void)
-{
- return test_ffa_version(FFA_VERSION_BIT31_MASK | SPM_VERSION, FFA_ERROR_NOT_SUPPORTED);
-}
-
-/*
- * @Test_Aim@ Validate what happens for bigger version than SPM's.
- */
-test_result_t test_ffa_version_bigger(void)
-{
- return test_ffa_version(MAKE_FFA_VERSION(FFA_VERSION_MAJOR + 1, 0), SPM_VERSION);
-}
-
-/*
- * @Test_Aim@ Validate what happens for smaller version than SPM's.
- */
-test_result_t test_ffa_version_smaller(void)
-{
- return test_ffa_version(MAKE_FFA_VERSION(0, 9), SPM_VERSION);
-}
diff --git a/tftf/tests/runtime_services/secure_service/test_spm_smmu.c b/tftf/tests/runtime_services/secure_service/test_spm_smmu.c
new file mode 100644
index 0000000..b041a97
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/test_spm_smmu.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cactus_test_cmds.h>
+#include <debug.h>
+#include <ffa_endpoints.h>
+#include <smccc.h>
+#include <test_helpers.h>
+
+static const struct ffa_uuid expected_sp_uuids[] = { {PRIMARY_UUID} };
+
+/**************************************************************************
+ * Send a command to SP1 initiate DMA service with the help of a peripheral
+ * device upstream of an SMMUv3 IP
+ **************************************************************************/
+test_result_t test_smmu_spm(void)
+{
+ smc_ret_values ret;
+
+ /**********************************************************************
+ * Check SPMC has ffa_version and expected FFA endpoints are deployed.
+ **********************************************************************/
+ CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
+
+ VERBOSE("Sending command to SP %x for initiating DMA transfer\n",
+ SP_ID(1));
+ ret = cactus_send_dma_cmd(HYP_ID, SP_ID(1));
+
+ if (cactus_get_response(ret) != CACTUS_SUCCESS) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index 9364052..dc99337 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -9,10 +9,9 @@
ffa_helpers.c \
spm_common.c \
test_ffa_direct_messaging.c \
- test_ffa_features.c \
test_ffa_interrupts.c \
test_ffa_memory_sharing.c \
- test_ffa_rxtx_map.c \
- test_ffa_version.c \
+ test_ffa_setup_and_discovery.c \
test_spm_cpu_features.c \
+ test_spm_smmu.c \
)
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 01ebcea..cafbc46 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -7,27 +7,27 @@
-->
<testsuites>
+ <testsuite name="FF-A Setup and Discovery"
+ description="Test FF-A Setup and Discovery interfaces" >
+ <testcase name="Test FFA_FEATURES"
+ function="test_ffa_features" />
- <testsuite name="FF-A Version"
- description="Test FF-A Version ABI" >
+ <testcase name="Same FFA version as SPM"
+ function="test_ffa_version_equal" />
+ <testcase name="Setting bit 31 in input version"
+ function="test_ffa_version_bit31"/>
+ <testcase name="Bigger FFA version than SPM"
+ function="test_ffa_version_bigger" />
+ <testcase name="Smaller FFA version than SPM"
+ function="test_ffa_version_smaller" />
- <testcase name="Same FFA version as SPM"
- function="test_ffa_version_equal" />
- <testcase name="Setting bit 31 in input version"
- function="test_ffa_version_bit31"/>
- <testcase name="Bigger FFA version than SPM"
- function="test_ffa_version_bigger" />
- <testcase name="Smaller FFA version than SPM"
- function="test_ffa_version_smaller" />
-
- </testsuite>
-
- <testsuite name="FF-A RXTX Mapping"
- description="Test to FF-A RXTX mapping ABI" >
<testcase name="FF-A RXTX Map API success"
function="test_ffa_rxtx_map_success" />
<testcase name="FF-A RXTX Map API consecutive"
function="test_ffa_rxtx_map_fail" />
+
+ <testcase name="Test FFA_SPM_ID_GET"
+ function="test_ffa_spm_id_get" />
</testsuite>
<testsuite name="FF-A Direct messaging"
@@ -66,12 +66,6 @@
function="test_req_mem_donate_sp_to_sp" />
</testsuite>
- <testsuite name="FF-A features"
- description="Test FFA_FEATURES ABI" >
- <testcase name="Test FFA_FEATURES"
- function="test_ffa_features" />
- </testsuite>
-
<testsuite name="SIMD,SVE Registers context"
description="Validate context switch between NWd and SWd" >
<testcase name="Check that SIMD registers context is preserved"
@@ -84,4 +78,10 @@
function="test_ffa_ns_interrupt" />
</testsuite>
+ <testsuite name="SMMUv3 tests"
+ description="Initiate stage2 translation for streams from upstream peripherals" >
+ <testcase name="Check DMA command by SMMUv3TestEngine completes"
+ function="test_smmu_spm" />
+ </testsuite>
+
</testsuites>