Add hw TRNG from SEL0 SP
Intgrates the FVP TRNG into the crypto sp to provide a hw
entropy source. Includes tests that check SP device
region configuration loading and MMIO access within the
region.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Ia9af8b044596e1c7d194f039fdf64c2468bb3221
diff --git a/components/config/interface/platform_config.h b/components/config/interface/platform_config.h
index d11f0eb..3f7eb94 100644
--- a/components/config/interface/platform_config.h
+++ b/components/config/interface/platform_config.h
@@ -46,6 +46,13 @@
*/
int platform_config_device_add(const struct device_region *device_region);
+/**
+ * \brief Returns a count of the number of device regions
+ *
+ * \return 0 if successful
+ */
+unsigned int platform_config_device_region_count(void);
+
#ifdef __cplusplus
}
diff --git a/components/config/loader/sp/component.cmake b/components/config/loader/sp/component.cmake
new file mode 100644
index 0000000..82b9fbd
--- /dev/null
+++ b/components/config/loader/sp/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, 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}/sp_config_loader.c"
+ )
+
diff --git a/components/config/loader/sp/sp_config_loader.c b/components/config/loader/sp/sp_config_loader.c
new file mode 100644
index 0000000..a1c8804
--- /dev/null
+++ b/components/config/loader/sp/sp_config_loader.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include <string.h>
+#include <config/interface/platform_config.h>
+#include <platform/interface/device_region.h>
+#include "sp_config_loader.h"
+
+
+struct sp_param_device_region
+{
+ char name[16];
+ uintptr_t location;
+ size_t size;
+};
+
+/**
+ * Loads externally provided configuration data originating from
+ * theh SP manifest.
+ */
+void sp_config_load(struct ffa_init_info *init_info)
+{
+ /* Load deployment specific configuration */
+ for (size_t param_index = 0; param_index < init_info->count; param_index++) {
+
+ if (!strcmp((const char *)init_info->nvp[param_index].name,"DEVICE_REGIONS")) {
+
+ struct sp_param_device_region *d = (struct sp_param_device_region *)init_info->nvp[param_index].value;
+
+ /*Iterate over the device regions*/
+ while ((uintptr_t)d < (init_info->nvp[param_index].value + init_info->nvp[param_index].size)) {
+
+ struct device_region device_region;
+
+ strcpy(device_region.dev_class, d->name);
+ device_region.dev_instance = 0;
+ device_region.base_addr = d->location;
+ device_region.io_region_size = d->size;
+
+ platform_config_device_add(&device_region);
+
+ ++d;
+ }
+ }
+ }
+}
diff --git a/components/config/loader/sp/sp_config_loader.h b/components/config/loader/sp/sp_config_loader.h
new file mode 100644
index 0000000..a1c8bf0
--- /dev/null
+++ b/components/config/loader/sp/sp_config_loader.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SP_CONFIG_LOADER_H
+#define SP_CONFIG_LOADER_H
+
+#include <ffa_api.h>
+
+/**
+ * Loads the secure partition specific configuration passed as
+ * SP initialization parameters.
+ */
+void sp_config_load(struct ffa_init_info *init_info);
+
+
+#endif /* SP_CONFIG_LOADER_H */
diff --git a/components/config/ramstore/config_ramstore.c b/components/config/ramstore/config_ramstore.c
index 548ba4b..2e24645 100644
--- a/components/config/ramstore/config_ramstore.c
+++ b/components/config/ramstore/config_ramstore.c
@@ -114,3 +114,18 @@
{
free(device_region);
}
+
+unsigned int platform_config_device_region_count(void)
+{
+ unsigned int count = 0;
+
+ const struct config_container *container = ramstore.device_region_list;
+
+ while (container) {
+
+ ++count;
+ container = container->next;
+ }
+
+ return count;
+}
diff --git a/components/config/ramstore/test/ramstore_tests.cpp b/components/config/ramstore/test/ramstore_tests.cpp
index c597b57..aadb62b 100644
--- a/components/config/ramstore/test/ramstore_tests.cpp
+++ b/components/config/ramstore/test/ramstore_tests.cpp
@@ -38,7 +38,7 @@
/* This would be external configuration, obtained say from device tree */
strcpy(config.dev_class, "fs");
config.dev_instance = 2;
- config.base_addr = (uint8_t*)0x0f000010;
+ config.base_addr = (uintptr_t)0x0f000010;
config.io_region_size = 0x100;
/* Add the configuration object */
@@ -65,7 +65,7 @@
strcpy(config1.dev_class, "flash");
config1.dev_instance = 0;
- config1.base_addr = (uint8_t*)0x0f000010;
+ config1.base_addr = (uintptr_t)0x0f000010;
config1.io_region_size = 0x100;
status = platform_config_device_add(&config1);
@@ -76,12 +76,14 @@
strcpy(config2.dev_class, "flash");
config2.dev_instance = 1;
- config2.base_addr = (uint8_t*)0x0f000010;
+ config2.base_addr = (uintptr_t)0x0f000010;
config2.io_region_size = 0x100;
status = platform_config_device_add(&config2);
CHECK_EQUAL(0, status);
+ CHECK_EQUAL(2, platform_config_device_region_count());
+
/* Expect queries for both objects to work */
struct device_region *query1_result = platform_config_device_query(config1.dev_class, config1.dev_instance);
CHECK(query1_result);
diff --git a/components/config/test/sp/component.cmake b/components/config/test/sp/component.cmake
new file mode 100644
index 0000000..9869e73
--- /dev/null
+++ b/components/config/test/sp/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, 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}/sp_config_tests.c"
+ )
+
diff --git a/components/config/test/sp/sp_config_tests.c b/components/config/test/sp/sp_config_tests.c
new file mode 100644
index 0000000..94ba268
--- /dev/null
+++ b/components/config/test/sp/sp_config_tests.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <service/test_runner/provider/backend/simple_c/simple_c_test_runner.h>
+#include <config/interface/platform_config.h>
+#include <stdint.h>
+
+/**
+ * Secure Partition configuration tests for checking configuartion
+ * data passed to an SP at initialisation. These tests assume
+ * use of the FFA manifest for any SP deployments of
+ * deployments/env_test.
+ */
+
+/*
+ * Check that the loaded configuration includes one or more
+ * device regions.
+ */
+static bool check_device_region_loaded(struct test_failure *failure)
+{
+ return platform_config_device_region_count() > 0;
+}
+
+/*
+ * Check that a device region for a 'trng' device has been loaded
+ * and that values are as expected.
+ */
+static bool check_trng_device_region_loaded(struct test_failure *failure)
+{
+ bool passed = false;
+ struct device_region *dev_region = platform_config_device_query("trng", 0);
+
+ if (dev_region) {
+
+ passed =
+ (dev_region->dev_instance == 0) &&
+ (dev_region->io_region_size == 0x1000);
+ }
+
+ platform_config_device_query_free(dev_region);
+
+ return passed;
+}
+
+/*
+ * Check access to some trng registers
+ */
+static bool check_trng_register_access(struct test_failure *failure)
+{
+ bool passed = false;
+
+ struct device_region *dev_region = platform_config_device_query("trng", 0);
+
+ if (dev_region) {
+
+ /* Expect reset values to be read from a selection of TRNG registers */
+ uint32_t reg_val;
+ passed = true;
+
+ /* PID4 */
+ if (passed) {
+ reg_val = *((volatile uint32_t*)((uint8_t*)dev_region->base_addr + 0xfd0));
+ passed = (reg_val == 0x00000004);
+ failure->line_num = __LINE__;
+ failure->info = reg_val;
+ }
+
+ /* PID0 */
+ if (passed) {
+ reg_val = *((volatile uint32_t*)((uint8_t*)dev_region->base_addr + 0xfe0));
+ passed = (reg_val == 0x000000aa);
+ failure->line_num = __LINE__;
+ failure->info = reg_val;
+ }
+ }
+
+ return passed;
+}
+
+
+/**
+ * Define an register test group
+ */
+void sp_config_tests_register(void)
+{
+ static const struct simple_c_test_case sp_config_tests[] = {
+ {.name = "DevRegionLoaded", .test_func = check_device_region_loaded},
+ {.name = "TrngDevRegionLoaded", .test_func = check_trng_device_region_loaded},
+ {.name = "TrngRegAccess", .test_func = check_trng_register_access}
+ };
+
+ static const struct simple_c_test_group sp_config_test_group =
+ {
+ .group = "SpConfigTests",
+ .num_test_cases = sizeof(sp_config_tests)/sizeof(struct simple_c_test_case),
+ .test_cases = sp_config_tests
+ };
+
+ simple_c_test_runner_register_group(&sp_config_test_group);
+}
\ No newline at end of file
diff --git a/components/config/test/sp/sp_config_tests.h b/components/config/test/sp/sp_config_tests.h
new file mode 100644
index 0000000..516d2b1
--- /dev/null
+++ b/components/config/test/sp/sp_config_tests.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SP_CONFIG_TESTS_H
+#define SP_CONFIG_TESTS_H
+
+void sp_config_tests_register(void);
+
+#endif /* SP_CONFIG_TESTS_H */