[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/6] automation/qtb: add jinja2 device trees for riscv64 smoke tests


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Baptiste Le Duc <baptiste.le-duc@xxxxxxxxxx>
  • Date: Mon, 10 Aug 2026 18:09:52 +0200
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID"
  • Cc: Baptiste Le Duc <baptiste.le-duc@xxxxxxxxxx>, Doug Goldstein <cardoe@xxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>
  • Delivery-date: Mon, 10 Aug 2026 16:10:24 +0000
  • Feedback-id: default:8631fc262581453bbf619ec5b2062170:Sweego
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

The dom0less RISC-V smoke tests need a host device tree describing the
platform (CPUs, APLIC/IMSIC, uart). It varies per machine (hart count, MMU
type), so a single static .dts cannot cover the test matrix.

Add dts/qemu-host.dts.j2, a template of the QEMU virt platform in
aia=aplic-imsic mode: per-hart cpu/cpu-intc nodes, the M- and S-mode APLIC
and IMSIC pairs, CLINT and the ns16550a uart. It takes ncpus, mmu_type and
xen_bootargs as arguments.

Values QEMU hardcodes are set as named constants matching their source
symbols (QEMU_UART0_IRQ, QEMU_IRQCHIP_NUM_SOURCES, ...) rather than
open-coded, so a QEMU-side change is easy to trace.

The template is inert on its own: the generated dtb will be used in next
patch.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Baptiste Le Duc <baptiste.le-duc@xxxxxxxxxx>
---
 .../scripts/qtb/riscv/dts/qemu-host.dts.j2    | 160 ++++++++++++++++++
 1 file changed, 160 insertions(+)
 create mode 100644 automation/scripts/qtb/riscv/dts/qemu-host.dts.j2

diff --git a/automation/scripts/qtb/riscv/dts/qemu-host.dts.j2 
b/automation/scripts/qtb/riscv/dts/qemu-host.dts.j2
new file mode 100644
index 0000000000..13a8e983ce
--- /dev/null
+++ b/automation/scripts/qtb/riscv/dts/qemu-host.dts.j2
@@ -0,0 +1,160 @@
+/dts-v1/;
+
+{#-
+ * Jinja2 QEMU "virt" platform device tree for Xen RISC-V tests.
+ *
+ * Interrupt controller: APLIC in MSI mode + IMSIC
+ * (QEMU -M virt,aia=aplic-imsic).
+ *
+ * Rendered by xen_dt.py.
+ *
+ * Variables:
+ *   ncpus        - number of physical harts                (int, >= 1)
+ *   mmu_type     - Xen host MMU type, e.g. "sv39"          (string)
+ *   xen_bootargs - Xen command line                        (string)
+ *
+ * Per-hart nodes are labelled cpu<i> / cpu<i>_intc and referenced with &label.
+ *
+ * No `aia-guests=N`, so no VS-mode guest files: IMSIC reg size is
+ * ncpus * page size.
+-#}
+{#- Values QEMU hardcodes, need to be described to Xen -#}
+{%- set QEMU_TIMEBASE_FREQUENCY = 10000000 %}   {#- 
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ -#}
+{%- set QEMU_IRQCHIP_NUM_SOURCES = 96 %}        {#- VIRT_IRQCHIP_NUM_SOURCES 
(virt.h) -#}
+{%- set QEMU_IRQCHIP_NUM_MSIS = 255 %}          {#- VIRT_IRQCHIP_NUM_MSIS -#}
+{%- set QEMU_UART_CLOCK_FREQUENCY = 3686400 %}  {#- create_fdt_uart() -#}
+{%- set QEMU_UART0_IRQ = 10 %}                  {#- UART0_IRQ -#}
+{%- set QEMU_IMSIC_PAGE_SZ = 0x1000 %}          {#- IMSIC_MMIO_PAGE_SZ -#}
+
+{%- set IRQ_TYPE_LEVEL_HIGH = 4 %}
+{%- set APLIC_IRQ_CELLS = 2 %}
+
+{%- set IRQ_M_SOFT = 3 %}
+{%- set IRQ_M_TIMER = 7 %}
+{%- set IRQ_S_EXT = 9 %}
+{%- set IRQ_M_EXT = 11 %}
+
+/ {
+    #address-cells = <0x02>;
+    #size-cells = <0x02>;
+    compatible = "riscv-virtio";
+    model = "riscv-virtio,qemu";
+
+    memory@80000000 {
+        device_type = "memory";
+        reg = <0x00 0x80000000 0x00 0x80000000>;
+    };
+
+    cpus {
+        #address-cells = <0x01>;
+        #size-cells = <0x00>;
+        timebase-frequency = <{{ QEMU_TIMEBASE_FREQUENCY }}>;
+{% for i in range(ncpus) %}
+        cpu{{ i }}: cpu@{{ i }} {
+            device_type = "cpu";
+            reg = <0x{{ '%x' % i }}>;
+            status = "okay";
+            compatible = "riscv";
+            riscv,cbop-block-size = <0x40>;
+            riscv,cboz-block-size = <0x40>;
+            riscv,cbom-block-size = <0x40>;
+            riscv,isa = 
"rv64imafdch_zicntr_zicsr_zifencei_zihintpause_zihpm_zba_zbb_zbs_smstateen_svpbmt_smaia_ssaia";
+            mmu-type = "riscv,{{ mmu_type }}";
+
+            cpu{{ i }}_intc: interrupt-controller@{{ i }} {
+                #interrupt-cells = <0x01>;
+                interrupt-controller;
+                compatible = "riscv,cpu-intc";
+            };
+        };
+{% endfor %}
+        cpu-map {
+
+            cluster0 {
+{% for i in range(ncpus) %}
+                core{{ i }} {
+                    cpu = <&cpu{{ i }}>;
+                };
+{% endfor %}
+            };
+        };
+    };
+
+    soc {
+        #address-cells = <0x02>;
+        #size-cells = <0x02>;
+        compatible = "simple-bus";
+        ranges;
+
+        serial@10000000 {
+            interrupts = <{{ QEMU_UART0_IRQ }} {{ IRQ_TYPE_LEVEL_HIGH }}>;
+            interrupt-parent = <&aplic_s>;
+            clock-frequency = <{{ QEMU_UART_CLOCK_FREQUENCY }}>;
+            reg = <0x00 0x10000000 0x00 0x100>;
+            compatible = "ns16550a";
+        };
+
+        aplic_s: aplic@d000000 {
+            riscv,num-sources = <{{ QEMU_IRQCHIP_NUM_SOURCES }}>;
+            reg = <0x00 0xd000000 0x00 0x8000>;
+            msi-parent = <&imsic_s>;
+            interrupt-controller;
+            #interrupt-cells = <{{ APLIC_IRQ_CELLS }}>;
+            compatible = "riscv,aplic";
+        };
+
+        aplic@c000000 {
+            riscv,delegate = <&aplic_s 0x01 {{ QEMU_IRQCHIP_NUM_SOURCES }}>;
+            riscv,children = <&aplic_s>;
+            riscv,num-sources = <{{ QEMU_IRQCHIP_NUM_SOURCES }}>;
+            reg = <0x00 0xc000000 0x00 0x8000>;
+            msi-parent = <&imsic_m>;
+            interrupt-controller;
+            #interrupt-cells = <{{ APLIC_IRQ_CELLS }}>;
+            compatible = "riscv,aplic";
+        };
+
+        imsic_s: imsics@28000000 {
+            riscv,num-ids = <{{ QEMU_IRQCHIP_NUM_MSIS }}>;
+            reg = <0x00 0x28000000 0x00 0x{{ '%x' % (ncpus * 
QEMU_IMSIC_PAGE_SZ) }}>;
+            interrupts-extended = <
+                {%- for i in range(ncpus) %}
+                    &cpu{{ i }}_intc {{ IRQ_S_EXT }}
+                {%- endfor %}
+            >;
+            msi-controller;
+            interrupt-controller;
+            #interrupt-cells = <0x00>;
+            compatible = "riscv,imsics";
+        };
+
+        imsic_m: imsics@24000000 {
+            riscv,num-ids = <{{ QEMU_IRQCHIP_NUM_MSIS }}>;
+            reg = <0x00 0x24000000 0x00 0x{{ '%x' % (ncpus * 
QEMU_IMSIC_PAGE_SZ) }}>;
+            interrupts-extended = <
+                {%- for i in range(ncpus) %}
+                    &cpu{{ i }}_intc {{ IRQ_M_EXT }}
+                {%- endfor %}
+            >;
+            msi-controller;
+            interrupt-controller;
+            #interrupt-cells = <0x00>;
+            compatible = "riscv,imsics";
+        };
+
+        clint@2000000 {
+            interrupts-extended = <
+                {%- for i in range(ncpus) %}
+                    &cpu{{ i }}_intc {{ IRQ_M_SOFT }} &cpu{{ i }}_intc {{ 
IRQ_M_TIMER }}
+                {%- endfor %}
+            >;
+            reg = <0x00 0x2000000 0x00 0x10000>;
+            compatible = "sifive,clint0", "riscv,clint0";
+        };
+    };
+
+    chosen {
+        stdout-path = "/soc/serial@10000000";
+        xen,xen-bootargs = "{{ xen_bootargs }}";
+    };
+};


--
Baptiste Le Duc | Vates Hypervisor & Kernel Engineer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.