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/runtime/core/vmid.c b/runtime/core/vmid.c
new file mode 100644
index 0000000..64c30b3
--- /dev/null
+++ b/runtime/core/vmid.c
@@ -0,0 +1,65 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
+ */
+
+#include <arch_features.h>
+#include <assert.h>
+#include <atomics.h>
+#include <sizes.h>
+#include <spinlock.h>
+#include <vmid.h>
+
+#define VMID8_COUNT		(1U << 8)
+#define VMID16_COUNT		(1U << 16)
+#define MAX_VMID_COUNT		VMID16_COUNT
+#define VMID_ARRAY_LONG_SIZE	(MAX_VMID_COUNT / BITS_PER_UL)
+
+/*
+ * The bitmap for the reserved/used VMID values.
+ */
+static unsigned long vmids[VMID_ARRAY_LONG_SIZE];
+
+/*
+ * Marks the VMID value to be in use. It returns:
+ * - True, on success
+ * - False, if the vmid is out of range,
+ *   or if it was already reserved (in use).
+ */
+bool vmid_reserve(unsigned int vmid)
+{
+	unsigned int offset;
+	unsigned int vmid_count;
+
+	/* Number of supported VMID values */
+	vmid_count = is_feat_vmid16_present() ?	VMID16_COUNT : VMID8_COUNT;
+	/*
+	 * The input from NS as part of RMI_REALM_CREATE is 'short int' type,
+	 * so this check will not fail on systems with FEAT_VMID16 implemented.
+	 */
+	if (vmid >= vmid_count) {
+		return false;
+	}
+
+	offset = vmid / BITS_PER_UL;
+
+	return !atomic_bit_set_acquire_release_64(&vmids[offset], vmid);
+}
+
+/*
+ * Marks the VMID value to be not in use.
+ */
+void vmid_free(unsigned int vmid)
+{
+	unsigned int offset;
+	unsigned int __unused vmid_count;
+
+	/* Number of supported VMID values */
+	vmid_count = is_feat_vmid16_present() ? VMID16_COUNT : VMID8_COUNT;
+
+	/* Check the number of supported VMID values */
+	assert(vmid < vmid_count);
+	offset = vmid / BITS_PER_UL;
+
+	atomic_bit_clear_release_64(&vmids[offset], vmid);
+}