diff --git a/misc/config_tools/scenario_config/default_populator.py b/misc/config_tools/scenario_config/default_populator.py
index 560f1a885..bc55b26f1 100755
--- a/misc/config_tools/scenario_config/default_populator.py
+++ b/misc/config_tools/scenario_config/default_populator.py
@@ -7,6 +7,7 @@
import os
import argparse
+import elementpath
from scenario_transformer import ScenarioTransformer
@@ -14,9 +15,32 @@ from pipeline import PipelineObject, PipelineStage, PipelineEngine
from schema_slicer import SlicingSchemaByVMTypeStage
class DefaultValuePopulator(ScenarioTransformer):
+ def get_default_value(self, xsd_element_node, xml_parent_node):
+ # The attribute @default of the xsd:element node
+ v = xsd_element_node.get("default")
+ if v is not None:
+ return v
+
+ # The acrn:defaults and acrn:unique-among annotations which define a set of default values that shall be unique
+ # among a collection of nodes
+ annot_node = self.get_node(xsd_element_node, "xs:annotation")
+ if annot_node is not None:
+ defaults = annot_node.get("{https://projectacrn.org}defaults")
+ unique_among = annot_node.get("{https://projectacrn.org}unique-among")
+ if defaults is not None and unique_among is not None:
+ try:
+ default_values = set(eval(defaults))
+ existing_values = set(elementpath.select(self.xml_etree, unique_among, variables={"parent": xml_parent_node}))
+ available_defaults = default_values - existing_values
+ return sorted(list(available_defaults))[0]
+ except:
+ pass
+
+ return None
+
def add_missing_nodes(self, xsd_element_node, xml_parent_node, new_node_index):
element_name = xsd_element_node.get("name")
- default_value = xsd_element_node.get("default")
+ default_value = self.get_default_value(xsd_element_node, xml_parent_node)
# If the node is neither of a complex type (i.e. it does not have an child node) nor has a default value, do not
# create the node at all. Users are required to fill in proper values in such nodes, and missing any of them
diff --git a/misc/config_tools/scenario_config/scenario_transformer.py b/misc/config_tools/scenario_config/scenario_transformer.py
index 608dff2f6..cec23de2c 100644
--- a/misc/config_tools/scenario_config/scenario_transformer.py
+++ b/misc/config_tools/scenario_config/scenario_transformer.py
@@ -18,6 +18,7 @@ class ScenarioTransformer:
def __init__(self, xsd_etree, visit_optional_node=False):
self.xsd_etree = xsd_etree
+ self.xml_etree = None
self._visit_optional_node = visit_optional_node
@@ -92,7 +93,11 @@ class ScenarioTransformer:
return []
def transform(self, xml_etree):
+ self.xml_etree = xml_etree
+
xml_root_node = xml_etree.getroot()
xsd_root_node = self.get_node(self.xsd_etree, f".//xs:element[@name='{xml_root_node.tag}']")
if xsd_root_node is not None:
self.transform_node(xsd_root_node, xml_root_node)
+
+ self.xml_etree = None
diff --git a/misc/config_tools/schema/VMtypes.xsd b/misc/config_tools/schema/VMtypes.xsd
index bd803bd2b..8c2ec68e9 100644
--- a/misc/config_tools/schema/VMtypes.xsd
+++ b/misc/config_tools/schema/VMtypes.xsd
@@ -203,8 +203,8 @@ CLOSID 0 and the second is mapped to virtual CLOSID 1, etc.
Specify the COM base for each legacy virtual UART.
-
-
+
+
Specify the virtual Bus:Device.Function (BDF) for each PCI virtual UART. Virtual BDF is automatically assigned when the configuration is saved and can be changed if needed.
diff --git a/misc/config_tools/schema/checks/vbdf_assignment.xsd b/misc/config_tools/schema/checks/vbdf_assignment.xsd
new file mode 100644
index 000000000..5f850872a
--- /dev/null
+++ b/misc/config_tools/schema/checks/vbdf_assignment.xsd
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ VM "{$vm/name}" contains multiple virtual UART controllers and/or IVSHMEM interfaces using BDF {$vbdf}. Adjust the BDF of those devices.
+
+
+
+
diff --git a/misc/config_tools/schema/types.xsd b/misc/config_tools/schema/types.xsd
index 2a47703e1..2dc286574 100644
--- a/misc/config_tools/schema/types.xsd
+++ b/misc/config_tools/schema/types.xsd
@@ -219,7 +219,7 @@ Read more about the available scheduling options in :ref:`cpu_sharing`.
-
+
Virtual BDF (Bus Device Function) is automatically assigned and can be changed if needed. Set in Hex.