From: Brian Cain <bcain@quicinc.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
MAINTAINERS | 1 +
tests/functional/meson.build | 8 +++++
tests/functional/test_hexagon_minivm.py | 42 +++++++++++++++++++++++++
3 files changed, 51 insertions(+)
create mode 100755 tests/functional/test_hexagon_minivm.py
diff --git a/MAINTAINERS b/MAINTAINERS
index deeb7878c8..48a5e7c005 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -247,6 +247,7 @@ F: gdb-xml/hexagon*.xml
F: docs/system/target-hexagon.rst
F: docs/devel/hexagon-sys.rst
F: docs/devel/hexagon-l2vic.rst
+F: tests/functional/test_hexagon_minivm.py
T: git https://github.com/quic/qemu.git hex-next
Hexagon idef-parser
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index 111d8bab26..78b42e58f9 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -135,6 +135,14 @@ tests_i386_system_quick = [
'migration',
]
+test_timeouts += {
+ 'hexagon_minivm': 180,
+}
+
+tests_hexagon_system_quick = [
+ 'hexagon_minivm',
+]
+
tests_i386_system_thorough = [
'i386_tuxrun',
]
diff --git a/tests/functional/test_hexagon_minivm.py b/tests/functional/test_hexagon_minivm.py
new file mode 100755
index 0000000000..2ba92bcce3
--- /dev/null
+++ b/tests/functional/test_hexagon_minivm.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python3
+#
+# Copyright(c) 2024-2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+from glob import glob
+from qemu_test import QemuSystemTest, Asset
+from qemu_test import wait_for_console_pattern
+
+class MiniVMTest(QemuSystemTest):
+
+ timeout = 180
+ GUEST_ENTRY = 0xc0000000
+
+ REPO = 'https://artifacts.codelinaro.org/artifactory'
+ ASSET_TARBALL = \
+ Asset(f'{REPO}/codelinaro-toolchain-for-hexagon/'
+ '19.1.5/hexagon_minivm_2024_Dec_15.tar.gz',
+ 'd7920b5ff14bed5a10b23ada7d4eb927ede08635281f25067e0d5711feee2c2a')
+
+ def test_minivm(self):
+ self.set_machine('virt')
+ self.archive_extract(self.ASSET_TARBALL)
+ rootfs_path = f'{self.workdir}/hexagon-unknown-linux-musl-rootfs'
+ kernel_path = f'{rootfs_path}/boot/minivm'
+
+ assert(os.path.exists(kernel_path))
+ for test_bin_path in glob(f'{rootfs_path}/boot/test_*'):
+ print(f'# Testing "{os.path.basename(test_bin_path)}"')
+
+ vm = self.get_vm()
+ vm.add_args('-kernel', kernel_path,
+ '-device',
+ f'loader,addr={hex(self.GUEST_ENTRY)},file={test_bin_path}')
+ vm.launch()
+ vm.wait()
+ self.assertEqual(vm.exitcode(), 0)
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
--
2.34.1
Hi Brian, On 1/3/25 18:20, Brian Cain wrote: > From: Brian Cain <bcain@quicinc.com> A bit opaque... > Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com> > --- > MAINTAINERS | 1 + > tests/functional/meson.build | 8 +++++ > tests/functional/test_hexagon_minivm.py | 42 +++++++++++++++++++++++++ > 3 files changed, 51 insertions(+) > create mode 100755 tests/functional/test_hexagon_minivm.py > > diff --git a/MAINTAINERS b/MAINTAINERS > index deeb7878c8..48a5e7c005 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -247,6 +247,7 @@ F: gdb-xml/hexagon*.xml > F: docs/system/target-hexagon.rst > F: docs/devel/hexagon-sys.rst > F: docs/devel/hexagon-l2vic.rst > +F: tests/functional/test_hexagon_minivm.py > T: git https://github.com/quic/qemu.git hex-next > > Hexagon idef-parser > diff --git a/tests/functional/meson.build b/tests/functional/meson.build > index 111d8bab26..78b42e58f9 100644 > --- a/tests/functional/meson.build > +++ b/tests/functional/meson.build > @@ -135,6 +135,14 @@ tests_i386_system_quick = [ > 'migration', > ] > > +test_timeouts += { > + 'hexagon_minivm': 180, > +} > + > +tests_hexagon_system_quick = [ > + 'hexagon_minivm', > +] > + > tests_i386_system_thorough = [ > 'i386_tuxrun', > ] > diff --git a/tests/functional/test_hexagon_minivm.py b/tests/functional/test_hexagon_minivm.py > new file mode 100755 > index 0000000000..2ba92bcce3 > --- /dev/null > +++ b/tests/functional/test_hexagon_minivm.py > @@ -0,0 +1,42 @@ > +#!/usr/bin/env python3 > +# > +# Copyright(c) 2024-2025 Qualcomm Innovation Center, Inc. All Rights Reserved. > +# > +# SPDX-License-Identifier: GPL-2.0-or-later > + > +import os > +from glob import glob > +from qemu_test import QemuSystemTest, Asset > +from qemu_test import wait_for_console_pattern > + > +class MiniVMTest(QemuSystemTest): > + > + timeout = 180 > + GUEST_ENTRY = 0xc0000000 > + > + REPO = 'https://artifacts.codelinaro.org/artifactory' > + ASSET_TARBALL = \ > + Asset(f'{REPO}/codelinaro-toolchain-for-hexagon/' > + '19.1.5/hexagon_minivm_2024_Dec_15.tar.gz', > + 'd7920b5ff14bed5a10b23ada7d4eb927ede08635281f25067e0d5711feee2c2a') > + > + def test_minivm(self): > + self.set_machine('virt') > + self.archive_extract(self.ASSET_TARBALL) > + rootfs_path = f'{self.workdir}/hexagon-unknown-linux-musl-rootfs' > + kernel_path = f'{rootfs_path}/boot/minivm' $ readelf -h hexagon-unknown-linux-musl-rootfs/boot/minivm Entry point address: 0xffff0000 I suppose this is a bootloader which runs guest code at GUEST_ENTRY = 0xc0000000. > + > + assert(os.path.exists(kernel_path)) > + for test_bin_path in glob(f'{rootfs_path}/boot/test_*'): > + print(f'# Testing "{os.path.basename(test_bin_path)}"') $ ls -1 hexagon-unknown-linux-musl-rootfs/boot/test_* hexagon-unknown-linux-musl-rootfs/boot/test_interrupts hexagon-unknown-linux-musl-rootfs/boot/test_mmu hexagon-unknown-linux-musl-rootfs/boot/test_processors I'd rather 1 test per binary to easily see which one failed. > + > + vm = self.get_vm() > + vm.add_args('-kernel', kernel_path, > + '-device', > + f'loader,addr={hex(self.GUEST_ENTRY)},file={test_bin_path}') > + vm.launch() > + vm.wait() > + self.assertEqual(vm.exitcode(), 0) ... ---------------- IN: 0xc0000000: 0x6a09c019 { R25 = C9/pc } 0xc0000004: 0x00004040 { immext(#0x1000) 0xc0000008: 0x7800c018 R24 = ##0x1000 } 0xc000000c: 0xf318d918 { R24 = add(R24,R25) } 0xc0000010: 0x00004000 { immext(#0x0) 0xc0000014: 0x7800c03a R26 = ##0x1 } 0xc0000018: 0x0c004000 { immext(#0xc0000000) 0xc000001c: 0x7800c001 R1 = ##0xc0000000 } 0xc0000020: 0x0ffc4000 { immext(#0xffc00000) 0xc0000024: 0x7601c001 R1 = and(R1,##0xffc00000) } 0xc0000028: 0x8c01d622 { R2 = lsr(R1,#0x16) } 0xc000002c: 0xc402d840 { R0 = addasl(R24,R2,#0x2) } 0xc0000030: 0xb0e1f8a1 { R1 = add(R1,#0xfc5) } 0xc0000034: 0x00044000 { immext(#0x400000) 0xc0000038: 0x7800c002 R2 = ##0x400000 } 0xc000003c: 0x601ac008 { loop0(PC+4,R26) } 0xc0000040: 0xab80c108 { memw(R0++#0x4) = R1 } 0xc0000044: 0xf3018201 { R1 = add(R1,R2) 0xc0000048: 0x7f00c000 nop } :endloop0 ... do_raise_exception: 0x00000002, @ 20000090 hexagon_cpu_do_interrupt: event 0x2:(null), cause 0x25(37) hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x1(1) 0x20000104: 0x5400c000 { trap0(#0x0) } hexagon_cpu_do_interrupt: event 0x8:HEX_EVENT_TRAP0, cause 0x0(0) hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x1(1) 0xc00002a0: 0x7060c002 { R2 = R0 } 0xc00002a4: 0x5480c20c { trap1(R0,#0x13) } hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x13(19) 0xffff0518: 0x5800c02a { jump PC+84 } 0xffff056c: 0x6460c000 { stop(R0) } How can we be sure errors won't exit(0) or hang? (qemu) info mtree address-space: memory 0000000000000000-ffffffffffffffff (prio 0, i/o): system 0000000000000000-00000000ffffffff (prio 0, ram): ddr.ram 0000000010000000-0000000010000fff (prio 0, i/o): pl011 0000000011000000-00000000110001ff (prio 0, i/o): virtio-mmio 0000000012000000-00000000120001ff (prio 0, i/o): virtio-mmio 00000000d81e0000-00000000d81effff (prio 0, i/o): fast 00000000d8400000-00000000d87fffff (prio 0, ram): vtcm.ram 00000000de000000-00000000de0001ff (prio 0, rom): config_table.rom 00000000fc910000-00000000fc910fff (prio 0, i/o): l2vic Could we have minimal debug output on the console? > + > +if __name__ == '__main__': > + QemuSystemTest.main() Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
On 3/4/2025 9:46 AM, Philippe Mathieu-Daudé wrote: > Hi Brian, > > On 1/3/25 18:20, Brian Cain wrote: >> From: Brian Cain <bcain@quicinc.com> > > A bit opaque... > Whoops -- will fix it. >> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com> >> --- >> MAINTAINERS | 1 + >> tests/functional/meson.build | 8 +++++ >> tests/functional/test_hexagon_minivm.py | 42 +++++++++++++++++++++++++ >> 3 files changed, 51 insertions(+) >> create mode 100755 tests/functional/test_hexagon_minivm.py >> >> diff --git a/MAINTAINERS b/MAINTAINERS >> index deeb7878c8..48a5e7c005 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -247,6 +247,7 @@ F: gdb-xml/hexagon*.xml >> F: docs/system/target-hexagon.rst >> F: docs/devel/hexagon-sys.rst >> F: docs/devel/hexagon-l2vic.rst >> +F: tests/functional/test_hexagon_minivm.py >> T: git https://github.com/quic/qemu.git hex-next >> Hexagon idef-parser >> diff --git a/tests/functional/meson.build b/tests/functional/meson.build >> index 111d8bab26..78b42e58f9 100644 >> --- a/tests/functional/meson.build >> +++ b/tests/functional/meson.build >> @@ -135,6 +135,14 @@ tests_i386_system_quick = [ >> 'migration', >> ] >> +test_timeouts += { >> + 'hexagon_minivm': 180, >> +} >> + >> +tests_hexagon_system_quick = [ >> + 'hexagon_minivm', >> +] >> + >> tests_i386_system_thorough = [ >> 'i386_tuxrun', >> ] >> diff --git a/tests/functional/test_hexagon_minivm.py >> b/tests/functional/test_hexagon_minivm.py >> new file mode 100755 >> index 0000000000..2ba92bcce3 >> --- /dev/null >> +++ b/tests/functional/test_hexagon_minivm.py >> @@ -0,0 +1,42 @@ >> +#!/usr/bin/env python3 >> +# >> +# Copyright(c) 2024-2025 Qualcomm Innovation Center, Inc. All Rights >> Reserved. >> +# >> +# SPDX-License-Identifier: GPL-2.0-or-later >> + >> +import os >> +from glob import glob >> +from qemu_test import QemuSystemTest, Asset >> +from qemu_test import wait_for_console_pattern >> + >> +class MiniVMTest(QemuSystemTest): >> + >> + timeout = 180 >> + GUEST_ENTRY = 0xc0000000 >> + >> + REPO = 'https://artifacts.codelinaro.org/artifactory' >> + ASSET_TARBALL = \ >> + Asset(f'{REPO}/codelinaro-toolchain-for-hexagon/' >> + '19.1.5/hexagon_minivm_2024_Dec_15.tar.gz', >> + 'd7920b5ff14bed5a10b23ada7d4eb927ede08635281f25067e0d5711feee2c2a') >> + >> + def test_minivm(self): >> + self.set_machine('virt') >> + self.archive_extract(self.ASSET_TARBALL) >> + rootfs_path = >> f'{self.workdir}/hexagon-unknown-linux-musl-rootfs' >> + kernel_path = f'{rootfs_path}/boot/minivm' > > $ readelf -h hexagon-unknown-linux-musl-rootfs/boot/minivm > Entry point address: 0xffff0000 > > I suppose this is a bootloader which runs guest code at > GUEST_ENTRY = 0xc0000000. > Yes, this is indeed the case. The source for minivm and the test cases is found at https://github.com/quic/hexagonMVM >> + >> + assert(os.path.exists(kernel_path)) >> + for test_bin_path in glob(f'{rootfs_path}/boot/test_*'): >> + print(f'# Testing "{os.path.basename(test_bin_path)}"') > > $ ls -1 hexagon-unknown-linux-musl-rootfs/boot/test_* > hexagon-unknown-linux-musl-rootfs/boot/test_interrupts > hexagon-unknown-linux-musl-rootfs/boot/test_mmu > hexagon-unknown-linux-musl-rootfs/boot/test_processors > > I'd rather 1 test per binary to easily see which one failed. > Okay, I'll make that change. >> + >> + vm = self.get_vm() >> + vm.add_args('-kernel', kernel_path, >> + '-device', >> + f'loader,addr={hex(self.GUEST_ENTRY)},file={test_bin_path}') >> + vm.launch() >> + vm.wait() >> + self.assertEqual(vm.exitcode(), 0) > > ... > ---------------- > IN: > 0xc0000000: 0x6a09c019 { R25 = C9/pc } > 0xc0000004: 0x00004040 { immext(#0x1000) > 0xc0000008: 0x7800c018 R24 = ##0x1000 } > 0xc000000c: 0xf318d918 { R24 = add(R24,R25) } > 0xc0000010: 0x00004000 { immext(#0x0) > 0xc0000014: 0x7800c03a R26 = ##0x1 } > 0xc0000018: 0x0c004000 { immext(#0xc0000000) > 0xc000001c: 0x7800c001 R1 = ##0xc0000000 } > 0xc0000020: 0x0ffc4000 { immext(#0xffc00000) > 0xc0000024: 0x7601c001 R1 = and(R1,##0xffc00000) } > 0xc0000028: 0x8c01d622 { R2 = lsr(R1,#0x16) } > 0xc000002c: 0xc402d840 { R0 = addasl(R24,R2,#0x2) } > 0xc0000030: 0xb0e1f8a1 { R1 = add(R1,#0xfc5) } > 0xc0000034: 0x00044000 { immext(#0x400000) > 0xc0000038: 0x7800c002 R2 = ##0x400000 } > 0xc000003c: 0x601ac008 { loop0(PC+4,R26) } > 0xc0000040: 0xab80c108 { memw(R0++#0x4) = R1 } > 0xc0000044: 0xf3018201 { R1 = add(R1,R2) > 0xc0000048: 0x7f00c000 nop } :endloop0 > ... > do_raise_exception: 0x00000002, @ 20000090 > hexagon_cpu_do_interrupt: event 0x2:(null), cause 0x25(37) > hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x1(1) > 0x20000104: 0x5400c000 { trap0(#0x0) } > > hexagon_cpu_do_interrupt: event 0x8:HEX_EVENT_TRAP0, cause 0x0(0) > hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x1(1) > > 0xc00002a0: 0x7060c002 { R2 = R0 } > 0xc00002a4: 0x5480c20c { trap1(R0,#0x13) } > > hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x13(19) > 0xffff0518: 0x5800c02a { jump PC+84 } > 0xffff056c: 0x6460c000 { stop(R0) } > > How can we be sure errors won't exit(0) or hang? > The most likely failure mode for errors seems like a hang to me. Which is good that it's at least detected but I would agree that it would be preferable to > (qemu) info mtree > address-space: memory > 0000000000000000-ffffffffffffffff (prio 0, i/o): system > 0000000000000000-00000000ffffffff (prio 0, ram): ddr.ram > 0000000010000000-0000000010000fff (prio 0, i/o): pl011 > 0000000011000000-00000000110001ff (prio 0, i/o): virtio-mmio > 0000000012000000-00000000120001ff (prio 0, i/o): virtio-mmio > 00000000d81e0000-00000000d81effff (prio 0, i/o): fast > 00000000d8400000-00000000d87fffff (prio 0, ram): vtcm.ram > 00000000de000000-00000000de0001ff (prio 0, rom): config_table.rom > 00000000fc910000-00000000fc910fff (prio 0, i/o): l2vic > > Could we have minimal debug output on the console? > Hmm - there's no UART support in minivm nor its tests. But it is easy enough to add debug output via semihosting. Since semihosting spec is still under review, I've omitted that from these initial series. How about we revise the minivm tests to emit some debug output and we can also use that kind of thing to verify correctness? But would it suffice to land the test design as-is and follow up after semihosting lands? Or would you prefer to see semihosting be included >> + >> +if __name__ == '__main__': >> + QemuSystemTest.main() > > Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org> >
On 3/4/2025 10:15 AM, Brian Cain wrote: > > On 3/4/2025 9:46 AM, Philippe Mathieu-Daudé wrote: >> Hi Brian, >> >> On 1/3/25 18:20, Brian Cain wrote: >>> From: Brian Cain <bcain@quicinc.com> >> >> A bit opaque... >> > Whoops -- will fix it. >>> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com> >>> --- >>> MAINTAINERS | 1 + >>> tests/functional/meson.build | 8 +++++ >>> tests/functional/test_hexagon_minivm.py | 42 >>> +++++++++++++++++++++++++ >>> 3 files changed, 51 insertions(+) >>> create mode 100755 tests/functional/test_hexagon_minivm.py >>> >>> diff --git a/MAINTAINERS b/MAINTAINERS >>> index deeb7878c8..48a5e7c005 100644 >>> --- a/MAINTAINERS >>> +++ b/MAINTAINERS >>> @@ -247,6 +247,7 @@ F: gdb-xml/hexagon*.xml >>> F: docs/system/target-hexagon.rst >>> F: docs/devel/hexagon-sys.rst >>> F: docs/devel/hexagon-l2vic.rst >>> +F: tests/functional/test_hexagon_minivm.py >>> T: git https://github.com/quic/qemu.git hex-next >>> Hexagon idef-parser >>> diff --git a/tests/functional/meson.build >>> b/tests/functional/meson.build >>> index 111d8bab26..78b42e58f9 100644 >>> --- a/tests/functional/meson.build >>> +++ b/tests/functional/meson.build >>> @@ -135,6 +135,14 @@ tests_i386_system_quick = [ >>> 'migration', >>> ] >>> +test_timeouts += { >>> + 'hexagon_minivm': 180, >>> +} >>> + >>> +tests_hexagon_system_quick = [ >>> + 'hexagon_minivm', >>> +] >>> + >>> tests_i386_system_thorough = [ >>> 'i386_tuxrun', >>> ] >>> diff --git a/tests/functional/test_hexagon_minivm.py >>> b/tests/functional/test_hexagon_minivm.py >>> new file mode 100755 >>> index 0000000000..2ba92bcce3 >>> --- /dev/null >>> +++ b/tests/functional/test_hexagon_minivm.py >>> @@ -0,0 +1,42 @@ >>> +#!/usr/bin/env python3 >>> +# >>> +# Copyright(c) 2024-2025 Qualcomm Innovation Center, Inc. All >>> Rights Reserved. >>> +# >>> +# SPDX-License-Identifier: GPL-2.0-or-later >>> + >>> +import os >>> +from glob import glob >>> +from qemu_test import QemuSystemTest, Asset >>> +from qemu_test import wait_for_console_pattern >>> + >>> +class MiniVMTest(QemuSystemTest): >>> + >>> + timeout = 180 >>> + GUEST_ENTRY = 0xc0000000 >>> + >>> + REPO = 'https://artifacts.codelinaro.org/artifactory' >>> + ASSET_TARBALL = \ >>> + Asset(f'{REPO}/codelinaro-toolchain-for-hexagon/' >>> + '19.1.5/hexagon_minivm_2024_Dec_15.tar.gz', >>> + 'd7920b5ff14bed5a10b23ada7d4eb927ede08635281f25067e0d5711feee2c2a') >>> + >>> + def test_minivm(self): >>> + self.set_machine('virt') >>> + self.archive_extract(self.ASSET_TARBALL) >>> + rootfs_path = >>> f'{self.workdir}/hexagon-unknown-linux-musl-rootfs' >>> + kernel_path = f'{rootfs_path}/boot/minivm' >> >> $ readelf -h hexagon-unknown-linux-musl-rootfs/boot/minivm >> Entry point address: 0xffff0000 >> >> I suppose this is a bootloader which runs guest code at >> GUEST_ENTRY = 0xc0000000. >> > Yes, this is indeed the case. The source for minivm and the test > cases is found at https://github.com/quic/hexagonMVM >>> + >>> + assert(os.path.exists(kernel_path)) >>> + for test_bin_path in glob(f'{rootfs_path}/boot/test_*'): >>> + print(f'# Testing "{os.path.basename(test_bin_path)}"') >> >> $ ls -1 hexagon-unknown-linux-musl-rootfs/boot/test_* >> hexagon-unknown-linux-musl-rootfs/boot/test_interrupts >> hexagon-unknown-linux-musl-rootfs/boot/test_mmu >> hexagon-unknown-linux-musl-rootfs/boot/test_processors >> >> I'd rather 1 test per binary to easily see which one failed. >> > Okay, I'll make that change. >>> + >>> + vm = self.get_vm() >>> + vm.add_args('-kernel', kernel_path, >>> + '-device', >>> + f'loader,addr={hex(self.GUEST_ENTRY)},file={test_bin_path}') >>> + vm.launch() >>> + vm.wait() >>> + self.assertEqual(vm.exitcode(), 0) >> >> ... >> ---------------- >> IN: >> 0xc0000000: 0x6a09c019 { R25 = C9/pc } >> 0xc0000004: 0x00004040 { immext(#0x1000) >> 0xc0000008: 0x7800c018 R24 = ##0x1000 } >> 0xc000000c: 0xf318d918 { R24 = add(R24,R25) } >> 0xc0000010: 0x00004000 { immext(#0x0) >> 0xc0000014: 0x7800c03a R26 = ##0x1 } >> 0xc0000018: 0x0c004000 { immext(#0xc0000000) >> 0xc000001c: 0x7800c001 R1 = ##0xc0000000 } >> 0xc0000020: 0x0ffc4000 { immext(#0xffc00000) >> 0xc0000024: 0x7601c001 R1 = and(R1,##0xffc00000) } >> 0xc0000028: 0x8c01d622 { R2 = lsr(R1,#0x16) } >> 0xc000002c: 0xc402d840 { R0 = addasl(R24,R2,#0x2) } >> 0xc0000030: 0xb0e1f8a1 { R1 = add(R1,#0xfc5) } >> 0xc0000034: 0x00044000 { immext(#0x400000) >> 0xc0000038: 0x7800c002 R2 = ##0x400000 } >> 0xc000003c: 0x601ac008 { loop0(PC+4,R26) } >> 0xc0000040: 0xab80c108 { memw(R0++#0x4) = R1 } >> 0xc0000044: 0xf3018201 { R1 = add(R1,R2) >> 0xc0000048: 0x7f00c000 nop } :endloop0 >> ... >> do_raise_exception: 0x00000002, @ 20000090 >> hexagon_cpu_do_interrupt: event 0x2:(null), cause 0x25(37) >> hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x1(1) >> 0x20000104: 0x5400c000 { trap0(#0x0) } >> >> hexagon_cpu_do_interrupt: event 0x8:HEX_EVENT_TRAP0, cause 0x0(0) >> hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x1(1) >> >> 0xc00002a0: 0x7060c002 { R2 = R0 } >> 0xc00002a4: 0x5480c20c { trap1(R0,#0x13) } >> >> hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x13(19) >> 0xffff0518: 0x5800c02a { jump PC+84 } >> 0xffff056c: 0x6460c000 { stop(R0) } >> >> How can we be sure errors won't exit(0) or hang? >> > The most likely failure mode for errors seems like a hang to me. Which > is good that it's at least detected but I would agree that it would be > preferable to >> (qemu) info mtree >> address-space: memory >> 0000000000000000-ffffffffffffffff (prio 0, i/o): system >> 0000000000000000-00000000ffffffff (prio 0, ram): ddr.ram >> 0000000010000000-0000000010000fff (prio 0, i/o): pl011 >> 0000000011000000-00000000110001ff (prio 0, i/o): virtio-mmio >> 0000000012000000-00000000120001ff (prio 0, i/o): virtio-mmio >> 00000000d81e0000-00000000d81effff (prio 0, i/o): fast >> 00000000d8400000-00000000d87fffff (prio 0, ram): vtcm.ram >> 00000000de000000-00000000de0001ff (prio 0, rom): config_table.rom >> 00000000fc910000-00000000fc910fff (prio 0, i/o): l2vic >> >> Could we have minimal debug output on the console? >> > Hmm - there's no UART support in minivm nor its tests. But it is easy > enough to add debug output via semihosting. Since semihosting spec is > still under review, I've omitted that from these initial series. > > > How about we revise the minivm tests to emit some debug output and we > can also use that kind of thing to verify correctness? But would it > suffice to land the test design as-is and follow up after semihosting > lands? Or would you prefer to see semihosting be included > Oh - I see these tests do already emit `PASS` or `FAIL` via semihosting. See https://github.com/quic/hexagonMVM/blob/ca5704e8fd7aa0b856c947933fca045ff7a9dadd/tests/test_processors.S#L109-L116 for an example. Would it be okay to just check for this output after that semihosting lands? And do you prefer more detailed debug output beyond PASS/FAIL? >>> + >>> +if __name__ == '__main__': >>> + QemuSystemTest.main() >> >> Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org> >>
On 3/4/2025 9:46 AM, Philippe Mathieu-Daudé wrote: > Hi Brian, > > On 1/3/25 18:20, Brian Cain wrote: >> From: Brian Cain <bcain@quicinc.com> > > A bit opaque... > Whoops -- will fix it. >> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com> >> --- >> MAINTAINERS | 1 + >> tests/functional/meson.build | 8 +++++ >> tests/functional/test_hexagon_minivm.py | 42 +++++++++++++++++++++++++ >> 3 files changed, 51 insertions(+) >> create mode 100755 tests/functional/test_hexagon_minivm.py >> >> diff --git a/MAINTAINERS b/MAINTAINERS >> index deeb7878c8..48a5e7c005 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -247,6 +247,7 @@ F: gdb-xml/hexagon*.xml >> F: docs/system/target-hexagon.rst >> F: docs/devel/hexagon-sys.rst >> F: docs/devel/hexagon-l2vic.rst >> +F: tests/functional/test_hexagon_minivm.py >> T: git https://github.com/quic/qemu.git hex-next >> Hexagon idef-parser >> diff --git a/tests/functional/meson.build b/tests/functional/meson.build >> index 111d8bab26..78b42e58f9 100644 >> --- a/tests/functional/meson.build >> +++ b/tests/functional/meson.build >> @@ -135,6 +135,14 @@ tests_i386_system_quick = [ >> 'migration', >> ] >> +test_timeouts += { >> + 'hexagon_minivm': 180, >> +} >> + >> +tests_hexagon_system_quick = [ >> + 'hexagon_minivm', >> +] >> + >> tests_i386_system_thorough = [ >> 'i386_tuxrun', >> ] >> diff --git a/tests/functional/test_hexagon_minivm.py >> b/tests/functional/test_hexagon_minivm.py >> new file mode 100755 >> index 0000000000..2ba92bcce3 >> --- /dev/null >> +++ b/tests/functional/test_hexagon_minivm.py >> @@ -0,0 +1,42 @@ >> +#!/usr/bin/env python3 >> +# >> +# Copyright(c) 2024-2025 Qualcomm Innovation Center, Inc. All Rights >> Reserved. >> +# >> +# SPDX-License-Identifier: GPL-2.0-or-later >> + >> +import os >> +from glob import glob >> +from qemu_test import QemuSystemTest, Asset >> +from qemu_test import wait_for_console_pattern >> + >> +class MiniVMTest(QemuSystemTest): >> + >> + timeout = 180 >> + GUEST_ENTRY = 0xc0000000 >> + >> + REPO = 'https://artifacts.codelinaro.org/artifactory' >> + ASSET_TARBALL = \ >> + Asset(f'{REPO}/codelinaro-toolchain-for-hexagon/' >> + '19.1.5/hexagon_minivm_2024_Dec_15.tar.gz', >> + 'd7920b5ff14bed5a10b23ada7d4eb927ede08635281f25067e0d5711feee2c2a') >> + >> + def test_minivm(self): >> + self.set_machine('virt') >> + self.archive_extract(self.ASSET_TARBALL) >> + rootfs_path = >> f'{self.workdir}/hexagon-unknown-linux-musl-rootfs' >> + kernel_path = f'{rootfs_path}/boot/minivm' > > $ readelf -h hexagon-unknown-linux-musl-rootfs/boot/minivm > Entry point address: 0xffff0000 > > I suppose this is a bootloader which runs guest code at > GUEST_ENTRY = 0xc0000000. > Yes, this is indeed the case. The source for minivm and the test cases is found at https://github.com/quic/hexagonMVM >> + >> + assert(os.path.exists(kernel_path)) >> + for test_bin_path in glob(f'{rootfs_path}/boot/test_*'): >> + print(f'# Testing "{os.path.basename(test_bin_path)}"') > > $ ls -1 hexagon-unknown-linux-musl-rootfs/boot/test_* > hexagon-unknown-linux-musl-rootfs/boot/test_interrupts > hexagon-unknown-linux-musl-rootfs/boot/test_mmu > hexagon-unknown-linux-musl-rootfs/boot/test_processors > > I'd rather 1 test per binary to easily see which one failed. > Okay, I'll make that change. >> + >> + vm = self.get_vm() >> + vm.add_args('-kernel', kernel_path, >> + '-device', >> + f'loader,addr={hex(self.GUEST_ENTRY)},file={test_bin_path}') >> + vm.launch() >> + vm.wait() >> + self.assertEqual(vm.exitcode(), 0) > > ... > ---------------- > IN: > 0xc0000000: 0x6a09c019 { R25 = C9/pc } > 0xc0000004: 0x00004040 { immext(#0x1000) > 0xc0000008: 0x7800c018 R24 = ##0x1000 } > 0xc000000c: 0xf318d918 { R24 = add(R24,R25) } > 0xc0000010: 0x00004000 { immext(#0x0) > 0xc0000014: 0x7800c03a R26 = ##0x1 } > 0xc0000018: 0x0c004000 { immext(#0xc0000000) > 0xc000001c: 0x7800c001 R1 = ##0xc0000000 } > 0xc0000020: 0x0ffc4000 { immext(#0xffc00000) > 0xc0000024: 0x7601c001 R1 = and(R1,##0xffc00000) } > 0xc0000028: 0x8c01d622 { R2 = lsr(R1,#0x16) } > 0xc000002c: 0xc402d840 { R0 = addasl(R24,R2,#0x2) } > 0xc0000030: 0xb0e1f8a1 { R1 = add(R1,#0xfc5) } > 0xc0000034: 0x00044000 { immext(#0x400000) > 0xc0000038: 0x7800c002 R2 = ##0x400000 } > 0xc000003c: 0x601ac008 { loop0(PC+4,R26) } > 0xc0000040: 0xab80c108 { memw(R0++#0x4) = R1 } > 0xc0000044: 0xf3018201 { R1 = add(R1,R2) > 0xc0000048: 0x7f00c000 nop } :endloop0 > ... > do_raise_exception: 0x00000002, @ 20000090 > hexagon_cpu_do_interrupt: event 0x2:(null), cause 0x25(37) > hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x1(1) > 0x20000104: 0x5400c000 { trap0(#0x0) } > > hexagon_cpu_do_interrupt: event 0x8:HEX_EVENT_TRAP0, cause 0x0(0) > hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x1(1) > > 0xc00002a0: 0x7060c002 { R2 = R0 } > 0xc00002a4: 0x5480c20c { trap1(R0,#0x13) } > > hexagon_cpu_do_interrupt: event 0x9:HEX_EVENT_TRAP1, cause 0x13(19) > 0xffff0518: 0x5800c02a { jump PC+84 } > 0xffff056c: 0x6460c000 { stop(R0) } > > How can we be sure errors won't exit(0) or hang? > The most likely failure mode for errors seems like a hang to me. Which is good that it's at least detected but I would agree that it would be preferable to > (qemu) info mtree > address-space: memory > 0000000000000000-ffffffffffffffff (prio 0, i/o): system > 0000000000000000-00000000ffffffff (prio 0, ram): ddr.ram > 0000000010000000-0000000010000fff (prio 0, i/o): pl011 > 0000000011000000-00000000110001ff (prio 0, i/o): virtio-mmio > 0000000012000000-00000000120001ff (prio 0, i/o): virtio-mmio > 00000000d81e0000-00000000d81effff (prio 0, i/o): fast > 00000000d8400000-00000000d87fffff (prio 0, ram): vtcm.ram > 00000000de000000-00000000de0001ff (prio 0, rom): config_table.rom > 00000000fc910000-00000000fc910fff (prio 0, i/o): l2vic > > Could we have minimal debug output on the console? > Hmm - there's no UART support in minivm nor its tests. But it is easy enough to add debug output via semihosting. Since semihosting spec is still under review, I've omitted that from these initial series. How about we revise the minivm tests to emit some debug output and we can also use that kind of thing to verify correctness? But would it suffice to land the test design as-is and follow up after semihosting lands? Or would you prefer to see semihosting be included here before this test is enabled? >> + >> +if __name__ == '__main__': >> + QemuSystemTest.main() > > Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org> >
© 2016 - 2025 Red Hat, Inc.