config-tools: allow vm to configure up to 8 legacy vuarts

Expand the capacity of legacy vuarts per VM. This change is applied to
manual scenario xml editing only.

A SOS VM can choose io port 0x3F8, 0x2F8, 0x3E8, 0x2E8 by selecting
SOS_COM1_BASE, SOS_COM2_BASE, SOS_COM3_BASE, SOS_COM4_BASE respectively.

Non SOS VM can choose io port 0x3F8, 0x2F8, 0x3E8, 0x2E8 by selecting
COM1_BASE, COM2_BASE, COM3_BASE, COM4_BASE respectively.

For any type of VM, selecting "CONFIG_COM_BASE" allows configuration tool
to pick an available io port from hardcoded list:
['0xA000', '0xA010', '0xA020', '0xA030', '0xA040', '0xA050', '0xA060', '0xA070']

A SOS VM can choose irq 4 by selecting SOS_COM1_IRQ and SOS_COM3_IRQ, and choose irq 3 by selecting SOS_COM2_IRQ and SOS_COM4_IRQ.

Non SOS VM can choose irq 4 by selecting COM1_IRQ and COM3_IRQ, and choose irq 3 by selecting COM2_IRQ and COM4_IRQ.

For SOS VM, selecting "CONFIG_COM_IRQ" allows configuration tool
to pick an available irq based on AVAILABLE_IRQ_INFO. For non SOS VM, it
will allocate an available irq from [1, 15].

Tracked-On: #6652
Signed-off-by: Yang,Yu-chu <yu-chu.yang@intel.com>
This commit is contained in:
Yang,Yu-chu 2021-09-27 12:13:27 -07:00 committed by wenlingz
parent 89bbc44962
commit 69e37b96f3
7 changed files with 116 additions and 120 deletions

View File

@ -18,8 +18,8 @@ KERN_BOOT_ADDR_LIST = ['0x100000']
VUART_TYPE = ['VUART_LEGACY_PIO', 'VUART_PCI']
INVALID_COM_BASE = 'INVALID_COM_BASE'
VUART_BASE = ['SOS_COM1_BASE', 'SOS_COM2_BASE', 'COM1_BASE',
'COM2_BASE', 'COM3_BASE', 'COM4_BASE', INVALID_COM_BASE]
VUART_BASE = ['SOS_COM1_BASE', 'SOS_COM2_BASE', 'SOS_COM3_BASE', 'SOS_COM4_BASE', 'COM1_BASE',
'COM2_BASE', 'COM3_BASE', 'COM4_BASE', 'CONFIG_COM_BASE', INVALID_COM_BASE]
INVALID_PCI_BASE = 'INVALID_PCI_BASE'
PCI_VUART = 'PCI_VUART'
PCI_VUART_BASE = [PCI_VUART, INVALID_PCI_BASE]
@ -27,8 +27,8 @@ PCI_VUART_BASE = [PCI_VUART, INVALID_PCI_BASE]
AVALIBLE_COM1_BASE = [INVALID_COM_BASE, 'COM1_BASE']
AVALIBLE_COM2_BASE = [INVALID_COM_BASE, 'COM2_BASE']
VUART_IRQ = ['SOS_COM1_IRQ', 'SOS_COM2_IRQ', 'COM1_IRQ', 'COM2_IRQ', 'COM3_IRQ',
'COM4_IRQ', 'CONFIG_COM_IRQ', '3', '4', '6', '7']
VUART_IRQ = ['SOS_COM1_IRQ', 'SOS_COM2_IRQ', 'SOS_COM3_IRQ', 'SOS_COM4_IRQ',
'COM1_IRQ', 'COM2_IRQ', 'COM3_IRQ', 'COM4_IRQ', 'CONFIG_COM_IRQ']
# Support 512M, 1G, 2G
# pre launch less then 2G, sos vm less than 24G

View File

@ -218,16 +218,20 @@ must exactly match the module tag in the GRUB multiboot cmdline.</xs:documentati
<xs:simpleType name="LegacyVuartBase">
<xs:annotation>
<xs:documentation>A string with either ``SOS_COM1_BASE``,
``SOS_COM2_BASE``, ``COM1_BASE``, ``COM2_BASE``, ``COM3_BASE``,
``COM4_BASE``, or indicating it's disabled with ``INVALID_COM_BASE``.</xs:documentation>
``SOS_COM2_BASE``, ``SOS_COM3_BASE``, ``SOS_COM4_BASE``,
``COM1_BASE``, ``COM2_BASE``, ``COM3_BASE``, ``COM4_BASE``,
``CONFIG_COM_BASE``, or indicating it's disabled with ``INVALID_COM_BASE``.</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="SOS_COM1_BASE" />
<xs:enumeration value="SOS_COM2_BASE" />
<xs:enumeration value="SOS_COM3_BASE" />
<xs:enumeration value="SOS_COM4_BASE" />
<xs:enumeration value="COM1_BASE" />
<xs:enumeration value="COM2_BASE" />
<xs:enumeration value="COM3_BASE" />
<xs:enumeration value="COM4_BASE" />
<xs:enumeration value="CONFIG_COM_BASE" />
<xs:enumeration value="INVALID_COM_BASE" />
</xs:restriction>
</xs:simpleType>
@ -235,21 +239,20 @@ must exactly match the module tag in the GRUB multiboot cmdline.</xs:documentati
<xs:simpleType name="LegacyVuartIrq">
<xs:annotation acrn:configurable="n">
<xs:documentation>A string with either ``SOS_COM1_IRQ``,
``SOS_COM2_IRQ``, ``COM1_IRQ``, ``COM2_IRQ``, ``COM3_IRQ``,
``COM4_IRQ``, ``CONFIG_COM_IRQ``, ``3``, ``4``, ``6``, or ``7``.</xs:documentation>
``SOS_COM2_IRQ``, ``SOS_COM3_IRQ``, ``SOS_COM4_IRQ``,
``COM1_IRQ``, ``COM2_IRQ``, ``COM3_IRQ``, ``COM4_IRQ``
or ``CONFIG_COM_IRQ``.</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="SOS_COM1_IRQ" />
<xs:enumeration value="SOS_COM2_IRQ" />
<xs:enumeration value="SOS_COM3_IRQ" />
<xs:enumeration value="SOS_COM4_IRQ" />
<xs:enumeration value="COM1_IRQ" />
<xs:enumeration value="COM2_IRQ" />
<xs:enumeration value="COM3_IRQ" />
<xs:enumeration value="COM4_IRQ" />
<xs:enumeration value="CONFIG_COM_IRQ" />
<xs:enumeration value="3" />
<xs:enumeration value="4" />
<xs:enumeration value="6" />
<xs:enumeration value="7" />
</xs:restriction>
</xs:simpleType>

View File

@ -411,7 +411,7 @@ Refer SDM 17.19.2 for details, and use with caution.</xs:documentation>
argument and memory.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="legacy_vuart" type="LegacyVuartConfiguration" minOccurs="2" maxOccurs="2">
<xs:element name="legacy_vuart" type="LegacyVuartConfiguration" minOccurs="2" maxOccurs="8">
<xs:annotation>
<xs:documentation>Specify the vUART (aka COM) with the vUART ID by its ``id`` attribute.
Refer to :ref:`vuart_config` for detailed vUART settings.</xs:documentation>

View File

@ -31,47 +31,62 @@ def alloc_irq(irq_list):
remove_irq(irq_list, irq)
return irq
except IndexError as e:
raise lib.error.ResourceError("Cannot allocate legacy irq, the available legacy irq list: {}, {}".format(e, irq_list)) from e
raise lib.error.ResourceError("Cannot allocate legacy irq, the available irq list: {}, {}".format(e, irq_list)) from e
def remove_irq(irq_list, irq):
try:
irq_list.remove(irq)
except ValueError as e:
raise ValueError("Cannot remove irq:{} from available legacy irq list:{}, {}". format(irq, e, irq_list)) from e
raise ValueError("Cannot remove irq:{} from available irq list:{}, {}". format(irq, e, irq_list)) from e
def create_vuart_irq_node(etree, vm_id, vuart_id, irq):
allocation_sos_vm_node = common.get_node(f"/acrn-config/vm[@id = '{vm_id}']", etree)
if allocation_sos_vm_node is None:
allocation_sos_vm_node = common.append_node("/acrn-config/vm", None, etree, id = vm_id)
if common.get_node("./vm_type", allocation_sos_vm_node) is None:
common.append_node("./vm_type", "SOS_VM", allocation_sos_vm_node)
if common.get_node(f"./legacy_vuart[@id = '{vuart_id}']", allocation_sos_vm_node) is None:
common.append_node("./legacy_vuart", None, allocation_sos_vm_node, id = vuart_id)
def create_vuart_irq_node(etree, vm_id, vm_type, vuart_id, irq):
allocation_vm_node = common.get_node(f"/acrn-config/vm[@id = '{vm_id}']", etree)
if allocation_vm_node is None:
allocation_vm_node = common.append_node("/acrn-config/vm", None, etree, id = vm_id)
if common.get_node("./vm_type", allocation_vm_node) is None:
common.append_node("./vm_type", vm_type, allocation_vm_node)
if common.get_node(f"./legacy_vuart[@id = '{vuart_id}']", allocation_vm_node) is None:
common.append_node("./legacy_vuart", None, allocation_vm_node, id = vuart_id)
common.append_node(f"./legacy_vuart[@id = '{vuart_id}']/irq", irq, allocation_sos_vm_node)
common.append_node(f"./legacy_vuart[@id = '{vuart_id}']/irq", irq, allocation_vm_node)
def alloc_sos_vuart_irqs(board_etree, scenario_etree, allocation_etree):
irq_list = get_native_valid_irq()
hv_debug_console = lib.lib.parse_hv_console(scenario_etree)
def alloc_legacy_vuart_irqs(board_etree, scenario_etree, allocation_etree):
native_ttys = lib.lib.get_native_ttys()
vuart_valid = ['ttyS0', 'ttyS1', 'ttyS2', 'ttyS3']
hv_debug_console = lib.lib.parse_hv_console(scenario_etree)
scenario_sos_vm_node = common.get_node("//vm[vm_type = 'SOS_VM']", scenario_etree)
if scenario_sos_vm_node is not None:
vm_id = common.get_node("./@id", scenario_sos_vm_node)
if common.get_node("./legacy_vuart[@id = '0']/base/text()", scenario_sos_vm_node) != "INVALID_COM_BASE":
vuart0_irq = -1
if hv_debug_console in vuart_valid and hv_debug_console in native_ttys.keys() and native_ttys[hv_debug_console]['irq'] < LEGACY_IRQ_MAX:
vuart0_irq = native_ttys[hv_debug_console]['irq']
vm_node_list = scenario_etree.xpath("//vm")
for vm_node in vm_node_list:
vm_type = common.get_node("./vm_type/text()", vm_node)
irq_list = get_native_valid_irq() if vm_type == "SOS_VM" else [f"{d}" for d in list(range(1,15))]
legacy_vuart_id_list = vm_node.xpath("legacy_vuart[base != 'INVALID_COM_BASE']/@id")
legacy_vuart_irq = -1
for legacy_vuart_id in legacy_vuart_id_list:
if legacy_vuart_id == '0' and vm_type == "SOS_VM":
if hv_debug_console in native_ttys.keys():
if native_ttys[hv_debug_console]['irq'] < LEGACY_IRQ_MAX:
legacy_vuart_irq = native_ttys[hv_debug_console]['irq']
if legacy_vuart_irq in irq_list:
remove_irq(irq_list, legacy_vuart_irq)
else:
legacy_vuart_irq = alloc_irq(irq_list)
else:
raise lib.error.ResourceError(f"{hv_debug_console} is not in the native environment! The ttyS available are: {native_ttys.keys()}")
else:
vuart0_irq = alloc_irq(irq_list)
legacy_vuart_node_irq_text = common.get_node(f"legacy_vuart[@id = '{legacy_vuart_id}']/irq/text()", vm_node)
if legacy_vuart_node_irq_text == 'COM1_IRQ' or legacy_vuart_node_irq_text == 'SOS_COM1_IRQ' \
or legacy_vuart_node_irq_text == 'COM3_IRQ' or legacy_vuart_node_irq_text == 'SOS_COM3_IRQ':
legacy_vuart_irq = '4'
if legacy_vuart_irq in irq_list:
remove_irq(irq_list, legacy_vuart_irq)
elif legacy_vuart_node_irq_text == 'COM2_IRQ' or legacy_vuart_node_irq_text == 'SOS_COM2_IRQ' \
or legacy_vuart_node_irq_text == 'COM4_IRQ' or legacy_vuart_node_irq_text == 'SOS_COM4_IRQ':
legacy_vuart_irq = '3'
if legacy_vuart_irq in irq_list:
remove_irq(irq_list, legacy_vuart_irq)
else:
legacy_vuart_irq = alloc_irq(irq_list)
create_vuart_irq_node(allocation_etree, vm_id, "0", vuart0_irq)
if common.get_node("./legacy_vuart[@id = '1']/base/text()", scenario_sos_vm_node) != "INVALID_COM_BASE":
vuart1_irq = alloc_irq(irq_list)
create_vuart_irq_node(allocation_etree, vm_id, "1", vuart1_irq)
create_vuart_irq_node(allocation_etree, common.get_node("./@id", vm_node), vm_type, legacy_vuart_id, legacy_vuart_irq)
def get_irqs_of_device(device_node):
irqs = set()
@ -200,5 +215,5 @@ def alloc_device_irqs(board_etree, scenario_etree, allocation_etree):
pt_intx_node.text += f" ({irq}, {virq})"
def fn(board_etree, scenario_etree, allocation_etree):
alloc_sos_vuart_irqs(board_etree, scenario_etree, allocation_etree)
alloc_legacy_vuart_irqs(board_etree, scenario_etree, allocation_etree)
alloc_device_irqs(board_etree, scenario_etree, allocation_etree)

View File

@ -5,11 +5,11 @@
# SPDX-License-Identifier: BSD-3-Clause
#
import sys, os
import sys, os, logging
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'library'))
import common, lib.lib
VALID_PIO = ['0x3F8', '0x2F8', '0x3E8', '0x2E8']
VALID_PIO = ['0xA000', '0xA010', '0xA020', '0xA030', '0xA040', '0xA050', '0xA060', '0xA070']
def alloc_pio(pio_list):
try:
@ -25,50 +25,47 @@ def remove_pio(pio_list, base):
except ValueError as e:
raise ValueError("Cannot remove a pio base:{} from the available pio base list:{}, {}". format(base, e, pio_list)) from e
def create_vuart_base_node(etree, vm_id, vuart_id, vuart_base):
allocation_sos_vm_node = common.get_node(f"/acrn-config/vm[@id = '{vm_id}']", etree)
if allocation_sos_vm_node is None:
allocation_sos_vm_node = common.append_node("/acrn-config/vm", None, etree, id = vm_id)
if common.get_node("./vm_type", allocation_sos_vm_node) is None:
common.append_node("./vm_type", "SOS_VM", allocation_sos_vm_node)
if common.get_node(f"./legacy_vuart[@id = '{vuart_id}']", allocation_sos_vm_node) is None:
common.append_node("./legacy_vuart", None, allocation_sos_vm_node, id = vuart_id)
def create_vuart_base_node(etree, vm_id, vm_type, vuart_id, vuart_base):
allocation_vm_node = common.get_node(f"/acrn-config/vm[@id = '{vm_id}']", etree)
if allocation_vm_node is None:
allocation_vm_node = common.append_node("/acrn-config/vm", None, etree, id = vm_id)
if common.get_node("./vm_type", allocation_vm_node) is None:
common.append_node("./vm_type", vm_type, allocation_vm_node)
if common.get_node(f"./legacy_vuart[@id = '{vuart_id}']", allocation_vm_node) is None:
common.append_node("./legacy_vuart", None, allocation_vm_node, id = vuart_id)
common.append_node(f"./legacy_vuart[@id = '{vuart_id}']/base", vuart_base, allocation_sos_vm_node)
common.append_node(f"./legacy_vuart[@id = '{vuart_id}']/base", vuart_base, allocation_vm_node)
def fn(board_etree, scenario_etree, allocation_etree):
native_ttys = lib.lib.get_native_ttys()
pio_list = [base for base in VALID_PIO if all(native_ttys[tty]['base'] != base for tty in native_ttys.keys())]
# This pio_list is workaround. Since there are whl-ipc-i7 and whl-ipc-i5 which occupy all valid pio ports.
# It would fail to allocate pio base for enabled sos legacy vuart1. In that case, we allow vuart1 take one pio
# base which is used in native.
full = False
if len(pio_list) == 0:
full = True
pio_list = VALID_PIO
vuart_valid = ['ttyS0', 'ttyS1', 'ttyS2', 'ttyS3']
hv_debug_console = lib.lib.parse_hv_console(scenario_etree)
scenario_sos_vm_node = common.get_node("//vm[vm_type = 'SOS_VM']", scenario_etree)
if scenario_sos_vm_node is not None:
vm_id = common.get_node("./@id", scenario_sos_vm_node)
if common.get_node("./legacy_vuart[@id = '0']/base/text()", scenario_sos_vm_node) != "INVALID_COM_BASE":
vuart0_base = ""
if hv_debug_console in vuart_valid and hv_debug_console in native_ttys.keys() and native_ttys[hv_debug_console]['type'] == "portio":
vuart0_base = native_ttys[hv_debug_console]['base']
if vuart0_base in pio_list:
remove_pio(pio_list, vuart0_base)
vm_node_list = scenario_etree.xpath("//vm")
for vm_node in vm_node_list:
vm_type = common.get_node("./vm_type/text()", vm_node)
pio_list = [base for base in VALID_PIO if all(native_ttys[tty]['base'] != base for tty in native_ttys.keys())]
legacy_vuart_base = ""
legacy_vuart_id_list = vm_node.xpath("legacy_vuart[base != 'INVALID_COM_BASE']/@id")
for legacy_vuart_id in legacy_vuart_id_list:
if legacy_vuart_id == '0' and vm_type == "SOS_VM":
if hv_debug_console in native_ttys.keys():
if native_ttys[hv_debug_console]['type'] == "portio":
legacy_vuart_base = native_ttys[hv_debug_console]['base']
else:
legacy_vuart_base = alloc_pio(pio_list)
else:
raise lib.error.ResourceError(f"{hv_debug_console} is not in the native environment! The ttyS available are: {native_ttys.keys()}")
else:
vuart0_base = alloc_pio(pio_list)
if full:
common.print_yel("All available pio bases are used by native fully. '{}' is taken by sos legacy vuart 0.".format(vuart0_base), warn=True)
legacy_vuart_node_base_text = common.get_node(f"./legacy_vuart[@id = '{legacy_vuart_id}']/base/text()", vm_node)
if legacy_vuart_node_base_text == 'COM1_BASE' or legacy_vuart_node_base_text == 'SOS_COM1_BASE':
legacy_vuart_base = '0x3F8'
elif legacy_vuart_node_base_text == 'COM2_BASE' or legacy_vuart_node_base_text == 'SOS_COM2_BASE':
legacy_vuart_base = '0x2F8'
elif legacy_vuart_node_base_text == 'COM3_BASE' or legacy_vuart_node_base_text == 'SOS_COM3_BASE':
legacy_vuart_base = '0x3E8'
elif legacy_vuart_node_base_text == 'COM4_BASE' or legacy_vuart_node_base_text == 'SOS_COM4_BASE':
legacy_vuart_base = '0x2E8'
else:
legacy_vuart_base = alloc_pio(pio_list)
create_vuart_base_node(allocation_etree, str(vm_id), "0", vuart0_base)
if common.get_node("./legacy_vuart[@id = '1']/base/text()", scenario_sos_vm_node) != "INVALID_COM_BASE":
vuart1_base = alloc_pio(pio_list)
if full:
common.print_yel("All available pio bases are used by native fully. '{}' is taken by sos legacy vuart 1.".format(vuart1_base), warn=True)
create_vuart_base_node(allocation_etree, str(vm_id), "1", vuart1_base)
create_vuart_base_node(allocation_etree, common.get_node("./@id", vm_node), vm_type, legacy_vuart_id, legacy_vuart_base)

View File

@ -37,7 +37,6 @@
<xsl:if test="count(vm[acrn:is-sos-vm(vm_type)])">
<xsl:call-template name="sos_rootfs" />
<xsl:call-template name="sos_serial_console" />
<xsl:call-template name="sos_com_vuarts" />
<xsl:call-template name="sos_bootargs_diff" />
</xsl:if>
<xsl:call-template name="cpu_affinity" />
@ -88,28 +87,6 @@
<xsl:value-of select="acrn:define('SOS_CONSOLE', $sos_console, '')" />
</xsl:template>
<xsl:template name="sos_com_vuarts">
<xsl:for-each select="vm">
<xsl:if test="acrn:is-sos-vm(vm_type)">
<xsl:choose>
<xsl:when test="legacy_vuart[@id = 0]/base[text() != 'INVALID_COM_BASE']">
<xsl:value-of select="acrn:define('SOS_COM1_BASE', //allocation-data/acrn-config/vm[acrn:is-sos-vm(vm_type)]/legacy_vuart[@id = 0]/base, 'U')" />
<xsl:value-of select="acrn:define('SOS_COM1_IRQ', //allocation-data/acrn-config/vm[acrn:is-sos-vm(vm_type)]/legacy_vuart[@id = 0]/irq, 'U')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="acrn:define('SOS_COM1_BASE', '0', 'U')" />
<xsl:value-of select="acrn:define('SOS_COM1_IRQ', '0', 'U')" />
</xsl:otherwise>
</xsl:choose>
<xsl:if test="legacy_vuart[@id = 1]/base[text() != 'INVALID_COM_BASE']">
<xsl:value-of select="acrn:define('SOS_COM2_BASE', //allocation-data/acrn-config/vm[acrn:is-sos-vm(vm_type)]/legacy_vuart[@id = 1]/base, 'U')" />
<xsl:value-of select="acrn:define('SOS_COM2_IRQ', //allocation-data/acrn-config/vm[acrn:is-sos-vm(vm_type)]/legacy_vuart[@id = 1]/irq, 'U')" />
</xsl:if>
<xsl:value-of select="$newline" />
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="sos_bootargs_diff">
<xsl:variable name="bootargs" select="normalize-space(vm[acrn:is-sos-vm(vm_type)]/board_private/bootargs[text()])" />
<xsl:variable name="maxcpunum" select="count(//vm[acrn:is-sos-vm(vm_type)]/cpu_affinity/pcpu_id)" />

View File

@ -76,7 +76,7 @@
<xsl:apply-templates select="memory" />
<xsl:apply-templates select="os_config" />
<xsl:call-template name="acpi_config" />
<xsl:apply-templates select="legacy_vuart" />
<xsl:call-template name="legacy_vuart" />
<xsl:call-template name="pci_dev_num" />
<xsl:call-template name="pci_devs" />
<xsl:if test="acrn:is-pre-launched-vm(vm_type)">
@ -199,19 +199,23 @@
</xsl:if>
</xsl:template>
<xsl:template match="legacy_vuart">
<xsl:value-of select="acrn:initializer(concat('vuart[', @id, ']'), '{', true())" />
<xsl:value-of select="acrn:initializer('type', type)" />
<xsl:value-of select="acrn:initializer('addr.port_base', base)" />
<xsl:if test="base != 'INVALID_COM_BASE'">
<xsl:value-of select="acrn:initializer('irq', irq)" />
<xsl:if test="@id = '1'">
<xsl:value-of select="acrn:initializer('t_vuart.vm_id', concat(target_vm_id, 'U'))" />
<xsl:value-of select="acrn:initializer('t_vuart.vuart_id', concat(target_uart_id, 'U'))" />
<xsl:template name="legacy_vuart">
<xsl:variable name="vm_id" select="@id" />
<xsl:for-each select="legacy_vuart">
<xsl:variable name="vuart_id" select="@id" />
<xsl:value-of select="acrn:initializer(concat('vuart[', $vuart_id, ']'), '{', true())" />
<xsl:value-of select="acrn:initializer('type', type)" />
<xsl:if test="base != 'INVALID_COM_BASE'">
<xsl:value-of select="acrn:initializer('addr.port_base', concat(../../../../allocation-data/acrn-config/vm[@id=$vm_id]/legacy_vuart[@id=$vuart_id]/base, 'U'))" />
<xsl:value-of select="acrn:initializer('irq', concat(../../../../allocation-data/acrn-config/vm[@id=$vm_id]/legacy_vuart[@id=$vuart_id]/irq, 'U'))" />
<xsl:if test="@id != '0'">
<xsl:value-of select="acrn:initializer('t_vuart.vm_id', concat(target_vm_id, 'U'))" />
<xsl:value-of select="acrn:initializer('t_vuart.vuart_id', concat(target_uart_id, 'U'))" />
</xsl:if>
</xsl:if>
</xsl:if>
<xsl:text>},</xsl:text>
<xsl:value-of select="$newline" />
<xsl:text>},</xsl:text>
<xsl:value-of select="$newline" />
</xsl:for-each>
</xsl:template>
<xsl:template name="pci_dev_num">