Build: Non-FFM manifest attribute needs to be registered

Non-FFM manifest attribute keywords are now used in some manifests.
Those Secure Partitions are TF-M specific and not expected to be
portable. Secure partition developers may take those as references
without being aware of the portability issues.
This patch adds the feature to mandate TF-M-specific Secure Partitions
registering the specific attributes they use. The manifest tool will
report errors if Non-FFM keywords that are not registerd specifically
are detected.
Note that this does not mean using TF-M-specific attributes is
encouraged as those attributes might be specific to that Secure
Partition only.

Signed-off-by: Chendi Sun <chendi.sun@arm.com>
Change-Id: I7c6400eb1fec4239d889634a07da04154e722175
diff --git a/tools/tfm_parse_manifest_list.py b/tools/tfm_parse_manifest_list.py
index ed8d3fb..755f2a8 100644
--- a/tools/tfm_parse_manifest_list.py
+++ b/tools/tfm_parse_manifest_list.py
@@ -33,6 +33,11 @@
 
 # variable for checking for duplicated sid
 sid_list = []
+
+# Summary of manifest attributes defined by FFM for use in the Secure Partition manifest file.
+ffm_manifest_attributes = ['psa_framework_version', 'name', 'type', 'priority', 'model', 'entry_point', \
+'stack_size', 'description', 'entry_init', 'heap_size', 'mmio_regions', 'services', 'irqs', 'dependencies']
+
 class TemplateLoader(BaseLoader):
     """
     Template loader class.
@@ -216,6 +221,20 @@
         validate_dependency_chain(dependency, dependency_table, dependency_chain)
     dependency_table[partition]['validated'] = True
 
+def manifest_attribute_check(manifest, manifest_item):
+    """
+    Check whether Non-FF-M compliant attributes are explicitly registered in manifest lists.
+
+    Inputs:
+        - manifest:        next manifest to be checked
+        - manifest_item:   the manifest items in manifest lists
+    """
+    allowed_attributes = ffm_manifest_attributes + manifest_item.get('non_ffm_attributes', [])
+    for keyword in manifest.keys():
+        if keyword not in allowed_attributes:
+            logging.error('The Non-FFM attribute {} is used by {} without registration.'.format(keyword, manifest['name']))
+            exit(1)
+
 def process_partition_manifests(manifest_lists, configs):
     """
     Parse the input manifest lists, check if manifest settings are valid,
@@ -324,6 +343,9 @@
         manifest_path = manifest_item['manifest']
         with open(manifest_path) as manifest_file:
             manifest = yaml.safe_load(manifest_file)
+            # check manifest attribute validity
+            manifest_attribute_check(manifest, manifest_item)
+
             if manifest.get('model', None) == 'dual':
                 # If a Partition supports both models, it can set the "model" to "backend".
                 # The actual model used follows the backend being used.