build(cmake): add platform variant support

Some platforms offer multiple variants, targeting different but similar
physical boards. For example, the Total Compute platform currently
offers both TC1 and TC2. We'll be using this section to dictate
information that needs to be interpreted before loading the toolchain.

Change-Id: I9fe7450ab42c398a7ca42e0b2303df199fac8567
Signed-off-by: Chris Kay <chris.kay@arm.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b6dcead..2c8d63c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -86,6 +86,19 @@
     TYPE PATH)
 
 #
+# Retrieve the list of variants for the configured platform, and let the user
+# configure the variant.
+#
+
+tfa_platform_variants(variants
+    PLATFORM ${TFA_PLATFORM})
+
+arm_config_option(
+    NAME TFA_PLATFORM_VARIANT
+    HELP "Platform variant to build."
+    STRINGS ${variants})
+
+#
 # We're done with very early setup, so we can now create the project. This will
 # do some of the automatic compiler detection, which we need for setting up
 # further configuration options.
diff --git a/cmake/Modules/TFAMetadata.cmake b/cmake/Modules/TFAMetadata.cmake
index fccb67d..4c9d11f 100644
--- a/cmake/Modules/TFAMetadata.cmake
+++ b/cmake/Modules/TFAMetadata.cmake
@@ -33,6 +33,14 @@
     tfa_platform_target(<out-var> PLATFORM <platform>)
 
 Return the CMake target name for the platform ``<platform>`` in ``<out-var>``.
+
+.. command:: tfa_platform_variants
+
+.. code-block:: cmake
+
+    tfa_platform_variants(<out-var> PLATFORM <platform>)
+
+Return the list of variants for the platform ``<platform>`` in ``<out-var>``.
 #]=======================================================================]
 
 include_guard()
@@ -182,6 +190,15 @@
     JSON "${global-metadata}" PARENT tfa_platform_metadata
     PATH "target")
 
+tfa_json_getter(tfa_platform_metadata_variants
+    JSON "${global-metadata}" PARENT tfa_platform_metadata
+    PATH "variants")
+
+tfa_json_getter(tfa_platform_metadata_variants_variant
+    JSON "${global-metadata}" PARENT tfa_platform_metadata_variants
+    PATH "@VARIANT@" ARGUMENTS VARIANT
+    ERROR_MESSAGE "No such variant `@VARIANT@` for the @PLATFORM@ platform.")
+
 #
 # External platform metadata API.
 #
@@ -189,3 +206,7 @@
 tfa_json_getter(tfa_platform_target
     JSON "${global-metadata}" PARENT tfa_platform_metadata_target
     DECODE STRING)
+
+tfa_json_getter(tfa_platform_variants
+    JSON "${global-metadata}" PARENT tfa_platform_metadata_variants
+    DECODE MEMBERS)
diff --git a/schemas/platform.schema.json b/schemas/platform.schema.json
index 550450f..1960fff 100644
--- a/schemas/platform.schema.json
+++ b/schemas/platform.schema.json
@@ -7,6 +7,14 @@
     "target": {
       "type": "string",
       "pattern": "^(?![0-9])([a-z0-9]+-?)+(?<!-)$"
+    },
+    "variants": {
+      "additionalProperties": false,
+      "patternProperties": {
+        "^(?![0-9])([A-Z0-9][a-z0-9]*-?)+(?<!-)$": {
+          "type": "object"
+        }
+      }
     }
   }
 }