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 */