TF-RMM Release v0.1.0

This is the first external release of TF-RMM and provides a reference
implementation of Realm Management Monitor (RMM) as specified by the
RMM Beta0 specification[1].

The `docs/readme.rst` has more details about the project and
`docs/getting_started/getting-started.rst` has details on how to get
started with TF-RMM.

[1] https://developer.arm.com/documentation/den0137/1-0bet0/?lang=en

Signed-off-by: Soby Mathew <soby.mathew@arm.com>
Change-Id: I205ef14c015e4a37ae9ae1a64e4cd22eb8da746e
diff --git a/plat/host/common/src/host_utils.c b/plat/host/common/src/host_utils.c
new file mode 100644
index 0000000..f1f9103
--- /dev/null
+++ b/plat/host/common/src/host_utils.c
@@ -0,0 +1,94 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
+ */
+
+#include <debug.h>
+#include <errno.h>
+#include <host_defs.h>
+#include <host_utils.h>
+#include <plat_common.h>
+#include <string.h>
+#include <xlat_tables.h>
+
+static struct sysreg_cb callbacks[SYSREG_MAX_CBS];
+static unsigned int installed_cb_idx;
+
+/*
+ * Allocate memory to emulate physical memory to initialize the
+ * granule library.
+ */
+static unsigned char granules_buffer[HOST_MEM_SIZE] __aligned(GRANULE_SIZE);
+
+/*
+ * Generic callback to access a sysreg for reading.
+ */
+static u_register_t sysreg_rd_cb(u_register_t *reg)
+{
+	return *reg;
+}
+
+/*
+ * Generic callback to access a sysreg for writing.
+ */
+static void sysreg_wr_cb(u_register_t val, u_register_t *reg)
+{
+	*reg = val;
+}
+
+struct sysreg_cb *host_util_get_sysreg_cb(char *name)
+{
+	for (unsigned int i = 0U; i < SYSREG_MAX_CBS; i++) {
+		if (strncmp(name, &callbacks[i].sysreg[0],
+			    MAX_SYSREG_NAME_LEN) == 0) {
+			return &callbacks[i];
+		}
+	}
+
+	return (struct sysreg_cb *)NULL;
+}
+
+int host_util_set_sysreg_cb(char *name, rd_cb_t rd_cb, wr_cb_t wr_cb,
+			    u_register_t init)
+{
+	if (installed_cb_idx < SYSREG_MAX_CBS) {
+		callbacks[installed_cb_idx].rd_cb = rd_cb;
+		callbacks[installed_cb_idx].wr_cb = wr_cb;
+		callbacks[installed_cb_idx].value = init;
+
+		(void)strncpy(&(callbacks[installed_cb_idx].sysreg[0]),
+			      &name[0], MAX_SYSREG_NAME_LEN);
+
+		/*
+		 * Add a string termination character in case the
+		 * name were truncated.
+		 */
+		callbacks[installed_cb_idx].sysreg[MAX_SYSREG_NAME_LEN] = '\0';
+
+		++installed_cb_idx;
+
+		return 0;
+	}
+
+	return -ENOMEM;
+}
+
+void host_util_reset_all_sysreg_cb(void)
+{
+
+	(void)memset((void *)callbacks, 0,
+		     sizeof(struct sysreg_cb) * SYSREG_MAX_CBS);
+
+	installed_cb_idx = 0U;
+}
+
+int host_util_set_default_sysreg_cb(char *name, u_register_t init)
+{
+	return host_util_set_sysreg_cb(name, &sysreg_rd_cb,
+				     &sysreg_wr_cb, init);
+}
+
+unsigned long host_util_get_granule_base(void)
+{
+	return (unsigned long)granules_buffer;
+}