Add fwu standalone service context
To support service level of the fwu service, a standalone service
context is added that presents a service endpoint for fwu. This
is incorprated into the linux-pc deployment of libts. This allows
clients to discover and connect to the fwu service for the purpose
of testing. To allow different firmware configurations to be tested,
fwu components are configured outside of the fwu service context.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I4f3aa89590eab514a509172a96220b431382263d
diff --git a/components/service/fwu/test/fwu_dut/proxy/component.cmake b/components/service/fwu/test/fwu_dut/proxy/component.cmake
new file mode 100644
index 0000000..c10a4be
--- /dev/null
+++ b/components/service/fwu/test/fwu_dut/proxy/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/proxy_fwu_dut.cpp"
+ )
diff --git a/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.cpp b/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.cpp
new file mode 100644
index 0000000..6c9d97c
--- /dev/null
+++ b/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cassert>
+#include "proxy_fwu_dut.h"
+
+proxy_fwu_dut::proxy_fwu_dut(fwu_dut *remote_dut) :
+ fwu_dut(),
+ m_remote_dut(remote_dut)
+{
+
+}
+
+proxy_fwu_dut::~proxy_fwu_dut()
+{
+ delete m_remote_dut;
+ m_remote_dut = NULL;
+}
+
+void proxy_fwu_dut::boot(bool from_active_bank)
+{
+ assert(m_remote_dut);
+ m_remote_dut->boot(from_active_bank);
+}
+
+void proxy_fwu_dut::shutdown(void)
+{
+ assert(m_remote_dut);
+ m_remote_dut->shutdown();
+}
+
+struct boot_info proxy_fwu_dut::get_boot_info(void) const
+{
+ assert(m_remote_dut);
+ return m_remote_dut->get_boot_info();
+}
+
+metadata_checker *proxy_fwu_dut::create_metadata_checker(bool is_primary) const
+{
+ (void)is_primary;
+ return NULL;
+}
+
+fwu_client *proxy_fwu_dut::create_fwu_client(void)
+{
+ return NULL;
+}
diff --git a/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.h b/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.h
new file mode 100644
index 0000000..9fb7056
--- /dev/null
+++ b/components/service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PROXY_FWU_DUT_H
+#define PROXY_FWU_DUT_H
+
+#include <service/fwu/test/fwu_dut/fwu_dut.h>
+
+/*
+ * A proxy_fwu_dut is an fwu_dut that acts as a proxy for a full fwu_dut
+ * with access to updatable firmware. The proxy_fwu_dut is used in test
+ * integrations where the fwu service is being accessed via RPC e.g. from
+ * Nwd.
+ */
+class proxy_fwu_dut : public fwu_dut
+{
+public:
+
+ /**
+ * \brief proxy_fwu_dut constructor
+ *
+ * \param[in] remote_dut The associated remote fwu dut
+ */
+ proxy_fwu_dut(fwu_dut *remote_dut);
+ ~proxy_fwu_dut();
+
+ void boot(bool from_active_bank);
+ void shutdown(void);
+
+ struct boot_info get_boot_info(void) const;
+
+ metadata_checker *create_metadata_checker(bool is_primary) const;
+ fwu_client *create_fwu_client(void);
+
+private:
+
+ fwu_dut *m_remote_dut;
+};
+
+#endif /* PROXY_FWU_DUT_H */
diff --git a/components/service/fwu/test/fwu_dut_factory/remote_sim/component.cmake b/components/service/fwu/test/fwu_dut_factory/remote_sim/component.cmake
new file mode 100644
index 0000000..3add66d
--- /dev/null
+++ b/components/service/fwu/test/fwu_dut_factory/remote_sim/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/fwu_dut_factory.cpp"
+ )
diff --git a/components/service/fwu/test/fwu_dut_factory/remote_sim/fwu_dut_factory.cpp b/components/service/fwu/test/fwu_dut_factory/remote_sim/fwu_dut_factory.cpp
new file mode 100644
index 0000000..20b7cc5
--- /dev/null
+++ b/components/service/fwu/test/fwu_dut_factory/remote_sim/fwu_dut_factory.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <service/fwu/test/fwu_dut/sim/sim_fwu_dut.h>
+#include <service/fwu/test/fwu_dut/proxy/proxy_fwu_dut.h>
+#include <service/fwu/test/fwu_dut_factory/fwu_dut_factory.h>
+#include <service/locator/standalone/services/fwu/fwu_service_context.h>
+
+/*
+ * A factory for constructing fwu_dut objects for remote access to
+ * the fwu_service associated with a simulated device. The factory
+ * method actually constructs two concrete fwu_dut objects, a
+ * proxy_fwu_dut and a sim_fwu_dut. The proxy_fwu_dut is returned
+ * to the caller and provides the client interface used by test
+ * cases. The sim_fwu_dut forms the backend for the standalone
+ * fwu service.
+ */
+fwu_dut *fwu_dut_factory::create(
+ unsigned int num_locations,
+ bool allow_partial_updates)
+{
+ /* Construct and set the simulated dut that provides the configured
+ * device and fwu service provider.
+ */
+ sim_fwu_dut *sim_dut = new sim_fwu_dut(num_locations, allow_partial_updates);
+
+ fwu_service_context_set_provider(sim_dut->get_service_interface());
+
+ /* Construct a proxy_fwu_dut chained to the sim_fwu_dut. On deletion,
+ * the proxy_fwu_dut deletes the associated sim_fwu_dut.
+ */
+ return new proxy_fwu_dut(sim_dut);
+}
\ No newline at end of file
diff --git a/components/service/locator/standalone/services/fwu/component.cmake b/components/service/locator/standalone/services/fwu/component.cmake
new file mode 100644
index 0000000..6242dce
--- /dev/null
+++ b/components/service/locator/standalone/services/fwu/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/fwu_service_context.cpp"
+ )
diff --git a/components/service/locator/standalone/services/fwu/fwu_service_context.cpp b/components/service/locator/standalone/services/fwu/fwu_service_context.cpp
new file mode 100644
index 0000000..bab0768
--- /dev/null
+++ b/components/service/locator/standalone/services/fwu/fwu_service_context.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fwu_service_context.h"
+
+
+struct rpc_interface *fwu_service_context::m_provider_iface = NULL;
+
+fwu_service_context::fwu_service_context(const char *sn) :
+ standalone_service_context(sn),
+ m_rpc_demux()
+{
+
+}
+
+fwu_service_context::~fwu_service_context()
+{
+
+}
+
+void fwu_service_context::set_provider(
+ struct rpc_interface *iface)
+{
+ m_provider_iface = iface;
+}
+
+void fwu_service_context::do_init()
+{
+ /* For the case where no service interface has been provided,
+ * use an rpc_demux with nothing attached. This will safely
+ * return an error if call requests are made to the rpc endpoint.
+ */
+ struct rpc_interface *rpc_iface = rpc_demux_init(&m_rpc_demux);
+
+ if (m_provider_iface) {
+
+ /* A service provider is available. This facility allows a test
+ * case to apply an fwu_provider with a particular configuration
+ * to suite test goals.
+ */
+ rpc_iface = m_provider_iface;
+ }
+
+ standalone_service_context::set_rpc_interface(rpc_iface);
+}
+
+void fwu_service_context::do_deinit()
+{
+ rpc_demux_deinit(&m_rpc_demux);
+ set_provider(NULL);
+}
+
+void fwu_service_context_set_provider(
+ struct rpc_interface *iface)
+{
+ fwu_service_context::set_provider(iface);
+}
\ No newline at end of file
diff --git a/components/service/locator/standalone/services/fwu/fwu_service_context.h b/components/service/locator/standalone/services/fwu/fwu_service_context.h
new file mode 100644
index 0000000..41084ce
--- /dev/null
+++ b/components/service/locator/standalone/services/fwu/fwu_service_context.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STANDALONE_FWU_SERVICE_CONTEXT_H
+#define STANDALONE_FWU_SERVICE_CONTEXT_H
+
+#include <service/locator/standalone/standalone_service_context.h>
+#include <rpc/common/demux/rpc_demux.h>
+
+class fwu_service_context : public standalone_service_context
+{
+public:
+ fwu_service_context(const char *sn);
+ virtual ~fwu_service_context();
+
+ static void set_provider(
+ struct rpc_interface *iface);
+
+private:
+
+ void do_init();
+ void do_deinit();
+
+ static struct rpc_interface *m_provider_iface;
+
+ struct rpc_demux m_rpc_demux;
+};
+
+/*
+ * Export function to set the service provider
+ */
+#ifdef EXPORT_PUBLIC_INTERFACE_FWU_SERVICE_CONTEXT
+#define FWU_SERVICE_CONTEXT_EXPORTED __attribute__((__visibility__("default")))
+#else
+#define FWU_SERVICE_CONTEXT_EXPORTED
+#endif
+
+FWU_SERVICE_CONTEXT_EXPORTED void fwu_service_context_set_provider(
+ struct rpc_interface *iface);
+
+#endif /* STANDALONE_FWU_SERVICE_CONTEXT_H */
diff --git a/components/service/locator/standalone/standalone_env.cpp b/components/service/locator/standalone/standalone_env.cpp
index c9d7ba1..18b43d8 100644
--- a/components/service/locator/standalone/standalone_env.cpp
+++ b/components/service/locator/standalone/standalone_env.cpp
@@ -11,6 +11,7 @@
#include <service/locator/standalone/services/test-runner/test_runner_service_context.h>
#include <service/locator/standalone/services/attestation/attestation_service_context.h>
#include <service/locator/standalone/services/block-storage/block_storage_service_context.h>
+#include <service/locator/standalone/services/fwu/fwu_service_context.h>
#include <service/locator/standalone/services/smm-variable/smm_variable_service_context.h>
#include "standalone_location_strategy.h"
#include "standalone_service_registry.h"
@@ -35,6 +36,9 @@
static block_storage_service_context block_storage_context("sn:trustedfirmware.org:block-storage:0");
standalone_service_registry::instance()->regsiter_service_instance(&block_storage_context);
+ static fwu_service_context fwu_context("sn:trustedfirmware.org:fwu:0");
+ standalone_service_registry::instance()->regsiter_service_instance(&fwu_context);
+
static smm_variable_service_context smm_variable_context("sn:trustedfirmware.org:smm-variable:0");
standalone_service_registry::instance()->regsiter_service_instance(&smm_variable_context);
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index b23c778..7f8806c 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -67,6 +67,7 @@
"components/service/locator/standalone/services/test-runner"
"components/service/locator/standalone/services/attestation"
"components/service/locator/standalone/services/block-storage"
+ "components/service/locator/standalone/services/fwu"
"components/service/locator/standalone/services/smm-variable"
"components/service/discovery/client"
"components/service/discovery/provider"
diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt
index 44b3b9a..573669f 100644
--- a/deployments/libts/linux-pc/CMakeLists.txt
+++ b/deployments/libts/linux-pc/CMakeLists.txt
@@ -29,6 +29,17 @@
add_tfa_dependency(TARGET "ts")
#-------------------------------------------------------------------------------
+# Define public interfaces for library
+#
+#-------------------------------------------------------------------------------
+
+# Extend libts public interface for linux-pc to allow for alternative fwu
+# device configurations. This is intended for test.
+target_compile_definitions(ts PRIVATE
+ EXPORT_PUBLIC_INTERFACE_FWU_SERVICE_CONTEXT
+)
+
+#-------------------------------------------------------------------------------
# Components that are specific to deployment in the linux-pc environment.
#
#-------------------------------------------------------------------------------
@@ -37,6 +48,7 @@
BASE_DIR ${TS_ROOT}
COMPONENTS
"components/rpc/direct"
+ "components/rpc/common/demux"
"components/common/tlv"
"components/common/uuid"
"components/common/endian"
@@ -57,6 +69,7 @@
"components/service/locator/standalone/services/test-runner"
"components/service/locator/standalone/services/attestation"
"components/service/locator/standalone/services/block-storage"
+ "components/service/locator/standalone/services/fwu"
"components/service/locator/standalone/services/smm-variable"
"components/service/attestation/include"
"components/service/attestation/claims"
diff --git a/deployments/ts-service-test/linux-pc/CMakeLists.txt b/deployments/ts-service-test/linux-pc/CMakeLists.txt
index 99c1db2..00f9480 100644
--- a/deployments/ts-service-test/linux-pc/CMakeLists.txt
+++ b/deployments/ts-service-test/linux-pc/CMakeLists.txt
@@ -71,6 +71,13 @@
target_include_directories(ts-service-test PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
#-------------------------------------------------------------------------------
+# External project source-level dependencies
+#
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/external/tf_a/tf-a.cmake)
+add_tfa_dependency(TARGET "ts-service-test")
+
+#-------------------------------------------------------------------------------
# Components that are specific to deployment in the linux-pc environment.
#
#-------------------------------------------------------------------------------
@@ -78,15 +85,44 @@
TARGET "ts-service-test"
BASE_DIR ${TS_ROOT}
COMPONENTS
+ "components/common/endian"
+ "components/common/uuid"
+ "components/common/crc32/native"
"components/service/test_runner/client/cpp"
"components/service/test_runner/test/service"
"components/service/smm_variable/client/cpp"
"components/service/smm_variable/test/service"
"components/service/block_storage/block_store"
"components/service/block_storage/block_store/client"
+ "components/service/block_storage/block_store/partitioned"
+ "components/service/block_storage/block_store/device"
+ "components/service/block_storage/block_store/device/ram"
"components/service/block_storage/factory/client"
"components/service/block_storage/test/service"
- "components/common/uuid"
+ "components/service/common/provider"
+ "components/service/discovery/provider"
+ "components/service/discovery/provider/serializer/packed-c"
+ "components/service/fwu/agent"
+ "components/service/fwu/fw_store/banked"
+ "components/service/fwu/fw_store/banked/metadata_serializer/v1"
+ "components/service/fwu/installer"
+ "components/service/fwu/installer/raw"
+ "components/service/fwu/installer/copy"
+ "components/service/fwu/inspector/direct"
+ "components/service/fwu/provider"
+ "components/service/fwu/provider/serializer/packed-c"
+ "components/service/fwu/test/fwu_client/direct"
+ "components/service/fwu/test/fwu_dut"
+ "components/service/fwu/test/fwu_dut/sim"
+ "components/service/fwu/test/fwu_dut/proxy"
+ "components/service/fwu/test/fwu_dut_factory/remote_sim"
+ "components/service/fwu/test/image_directory_checker"
+ "components/service/fwu/test/metadata_checker"
+ "components/service/fwu/test/metadata_fetcher/volume"
+ "components/media/volume"
+ "components/media/volume/index"
+ "components/media/volume/base_io_dev"
+ "components/media/volume/block_volume"
)
#-------------------------------------------------------------------------------