Tools: Relax the services and irqs list validation

FF-M requires a Secure Partition to have at least one serivces or
irqs (in manifest).
This check is done in template.

This patch moves the check to the manifest tool and perform it only on
Secure Partitions whose PIDs are greater than 256 (TFM_SP_BASE).
PIDs less than 256 are reserved for TF-M special SPs so the check is
not necessary.

Since the audit log Partition is not FF-M compliant, this patch also
change its PID to be less than 256 to skip FF-M compliance check.

Change-Id: I49a13e95e6eb191ae8f2e1bc57190f8d5c7e590c
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
diff --git a/tools/tfm_parse_manifest_list.py b/tools/tfm_parse_manifest_list.py
index 5eb13c0..cb742c6 100644
--- a/tools/tfm_parse_manifest_list.py
+++ b/tools/tfm_parse_manifest_list.py
@@ -52,18 +52,24 @@
             source = f.read()
         return source, template, False
 
-def manifest_validation(partition_manifest):
+def manifest_validation(partition_manifest, pid):
     """
     This function validates FF-M compliance for partition manifest, and sets
     default values for optional attributes.
+    The validation is skipped for TF-M specific Partitions (PID < 256).
     More validation items will be added.
     """
 
-    # Service FF-M manifest validation
-    if 'services' not in partition_manifest.keys():
-        return partition_manifest
+    service_list = partition_manifest.get('services', [])
+    irq_list     = partition_manifest.get('irqs', [])
 
-    for service in partition_manifest['services']:
+    if (pid == None or pid >= 256) \
+       and len(service_list) == 0 and len(irq_list) == 0:
+        raise Exception('{} must declare at least either a secure service or an IRQ!'
+                        .format(partition_manifest['name']))
+
+    # Service FF-M manifest validation
+    for service in service_list:
         if 'version' not in service.keys():
             service['version'] = 1
         if 'version_policy' not in service.keys():
@@ -152,11 +158,15 @@
         # Check if partition ID is manually set
         if 'pid' not in manifest_item.keys():
             no_pid_manifest_idx.append(i)
-        # Check if partition ID is duplicated
-        elif manifest_item['pid'] in pid_list:
-            raise Exception('PID No. {pid} has already been used!'.format(pid=manifest_item['pid']))
+            pid = None
         else:
-            pid_list.append(manifest_item['pid'])
+            pid = manifest_item['pid']
+
+            # Check if partition ID is duplicated
+            if pid in pid_list:
+                raise Exception('PID No. {pid} has already been used!'.format(pid))
+            else:
+                pid_list.append(pid)
 
         # Replace environment variables in the manifest path
         manifest_path = os.path.expandvars(manifest_item['manifest'])
@@ -164,7 +174,7 @@
         manifest_path = os.path.join(manifest_item['list_path'], manifest_path).replace('\\', '/')
 
         with open(manifest_path) as manifest_file:
-            manifest = manifest_validation(yaml.safe_load(manifest_file))
+            manifest = manifest_validation(yaml.safe_load(manifest_file), pid)
 
         # Count the number of IPC partitions
         if manifest['psa_framework_version'] == 1.1 and manifest['model'] == 'IPC':
@@ -324,7 +334,10 @@
         # Skip the FF-M 1.0 partitions
         if partition['manifest']['psa_framework_version'] < 1.1:
             continue
-        for service in partition['manifest']['services']:
+
+        service_list = partition['manifest'].get('services', [])
+
+        for service in service_list:
             if 'connection_based' not in service:
                 raise Exception("'connection_based' is mandatory in FF-M 1.1 service!")
             if service['connection_based'] is False: