[PATCH 2/6] automation/qtb: add jinja2 device trees for riscv64 smoke tests
Baptiste Le Duc <[email protected]>
| Newsgroups | gmane.comp.emulators.xen.devel |
|---|---|
| Message-ID | <1786378213.8631fc262581453bbf619ec5b2062170.19fec70581a000e099@vates.tech> |
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 <[email protected]> --- .../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