1bbbd9b6eSWillian Rampazzo# Functional tests for the MIPS Malta board 2bbbd9b6eSWillian Rampazzo# 3bbbd9b6eSWillian Rampazzo# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org> 4bbbd9b6eSWillian Rampazzo# 5bbbd9b6eSWillian Rampazzo# This work is licensed under the terms of the GNU GPL, version 2 or later. 6bbbd9b6eSWillian Rampazzo# See the COPYING file in the top-level directory. 7bbbd9b6eSWillian Rampazzo# 8bbbd9b6eSWillian Rampazzo# SPDX-License-Identifier: GPL-2.0-or-later 9bbbd9b6eSWillian Rampazzo 10bbbd9b6eSWillian Rampazzoimport os 11bbbd9b6eSWillian Rampazzoimport gzip 12bbbd9b6eSWillian Rampazzoimport logging 13bbbd9b6eSWillian Rampazzo 149b45cc99SAlex Bennéefrom avocado import skipUnless 1514c2b184SPhilippe Mathieu-Daudéfrom avocado import skipUnless 1614c2b184SPhilippe Mathieu-Daudéfrom avocado.utils import archive 1714c2b184SPhilippe Mathieu-Daudéfrom avocado_qemu import QemuSystemTest 1814c2b184SPhilippe Mathieu-Daudéfrom avocado_qemu import exec_command_and_wait_for_pattern 1914c2b184SPhilippe Mathieu-Daudéfrom avocado_qemu import interrupt_interactive_console_until_pattern 2014c2b184SPhilippe Mathieu-Daudéfrom avocado_qemu import wait_for_console_pattern 21bbbd9b6eSWillian Rampazzo 22bbbd9b6eSWillian Rampazzo 23bbbd9b6eSWillian RampazzoNUMPY_AVAILABLE = True 24bbbd9b6eSWillian Rampazzotry: 25bbbd9b6eSWillian Rampazzo import numpy as np 26bbbd9b6eSWillian Rampazzoexcept ImportError: 27bbbd9b6eSWillian Rampazzo NUMPY_AVAILABLE = False 28bbbd9b6eSWillian Rampazzo 29bbbd9b6eSWillian RampazzoCV2_AVAILABLE = True 30bbbd9b6eSWillian Rampazzotry: 31bbbd9b6eSWillian Rampazzo import cv2 32bbbd9b6eSWillian Rampazzoexcept ImportError: 33bbbd9b6eSWillian Rampazzo CV2_AVAILABLE = False 34bbbd9b6eSWillian Rampazzo 35bbbd9b6eSWillian Rampazzo 36bbbd9b6eSWillian Rampazzo@skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed') 37bbbd9b6eSWillian Rampazzo@skipUnless(CV2_AVAILABLE, 'Python OpenCV not installed') 382283b627SPhilippe Mathieu-Daudéclass MaltaMachineFramebuffer(QemuSystemTest): 39bbbd9b6eSWillian Rampazzo 40bbbd9b6eSWillian Rampazzo timeout = 30 41bbbd9b6eSWillian Rampazzo 42bbbd9b6eSWillian Rampazzo KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' 43bbbd9b6eSWillian Rampazzo 44bbbd9b6eSWillian Rampazzo def do_test_i6400_framebuffer_logo(self, cpu_cores_count): 45bbbd9b6eSWillian Rampazzo """ 46bbbd9b6eSWillian Rampazzo Boot Linux kernel and check Tux logo is displayed on the framebuffer. 47bbbd9b6eSWillian Rampazzo """ 48bbbd9b6eSWillian Rampazzo screendump_path = os.path.join(self.workdir, 'screendump.pbm') 49bbbd9b6eSWillian Rampazzo 50bbbd9b6eSWillian Rampazzo kernel_url = ('https://github.com/philmd/qemu-testing-blob/raw/' 51bbbd9b6eSWillian Rampazzo 'a5966ca4b5/mips/malta/mips64el/' 52bbbd9b6eSWillian Rampazzo 'vmlinux-4.7.0-rc1.I6400.gz') 53bbbd9b6eSWillian Rampazzo kernel_hash = '096f50c377ec5072e6a366943324622c312045f6' 54bbbd9b6eSWillian Rampazzo kernel_path_gz = self.fetch_asset(kernel_url, asset_hash=kernel_hash) 55bbbd9b6eSWillian Rampazzo kernel_path = self.workdir + "vmlinux" 56bbbd9b6eSWillian Rampazzo archive.gzip_uncompress(kernel_path_gz, kernel_path) 57bbbd9b6eSWillian Rampazzo 58bbbd9b6eSWillian Rampazzo tuxlogo_url = ('https://github.com/torvalds/linux/raw/v2.6.12/' 59bbbd9b6eSWillian Rampazzo 'drivers/video/logo/logo_linux_vga16.ppm') 60bbbd9b6eSWillian Rampazzo tuxlogo_hash = '3991c2ddbd1ddaecda7601f8aafbcf5b02dc86af' 61bbbd9b6eSWillian Rampazzo tuxlogo_path = self.fetch_asset(tuxlogo_url, asset_hash=tuxlogo_hash) 62bbbd9b6eSWillian Rampazzo 63bbbd9b6eSWillian Rampazzo self.vm.set_console() 64bbbd9b6eSWillian Rampazzo kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + 65bbbd9b6eSWillian Rampazzo 'clocksource=GIC console=tty0 console=ttyS0') 66bbbd9b6eSWillian Rampazzo self.vm.add_args('-kernel', kernel_path, 67bbbd9b6eSWillian Rampazzo '-smp', '%u' % cpu_cores_count, 68bbbd9b6eSWillian Rampazzo '-vga', 'std', 69bbbd9b6eSWillian Rampazzo '-append', kernel_command_line) 70bbbd9b6eSWillian Rampazzo self.vm.launch() 71bbbd9b6eSWillian Rampazzo framebuffer_ready = 'Console: switching to colour frame buffer device' 72bbbd9b6eSWillian Rampazzo wait_for_console_pattern(self, framebuffer_ready, 73bbbd9b6eSWillian Rampazzo failure_message='Kernel panic - not syncing') 74684750abSVladimir Sementsov-Ogievskiy self.vm.cmd('human-monitor-command', command_line='stop') 75684750abSVladimir Sementsov-Ogievskiy self.vm.cmd('human-monitor-command', 76bbbd9b6eSWillian Rampazzo command_line='screendump %s' % screendump_path) 77bbbd9b6eSWillian Rampazzo logger = logging.getLogger('framebuffer') 78bbbd9b6eSWillian Rampazzo 79bbbd9b6eSWillian Rampazzo match_threshold = 0.95 80bbbd9b6eSWillian Rampazzo screendump_bgr = cv2.imread(screendump_path, cv2.IMREAD_COLOR) 81bbbd9b6eSWillian Rampazzo tuxlogo_bgr = cv2.imread(tuxlogo_path, cv2.IMREAD_COLOR) 82bbbd9b6eSWillian Rampazzo result = cv2.matchTemplate(screendump_bgr, tuxlogo_bgr, 83bbbd9b6eSWillian Rampazzo cv2.TM_CCOEFF_NORMED) 84bbbd9b6eSWillian Rampazzo loc = np.where(result >= match_threshold) 85bbbd9b6eSWillian Rampazzo tuxlogo_count = 0 86bbbd9b6eSWillian Rampazzo h, w = tuxlogo_bgr.shape[:2] 87bbbd9b6eSWillian Rampazzo debug_png = os.getenv('AVOCADO_CV2_SCREENDUMP_PNG_PATH') 88bbbd9b6eSWillian Rampazzo for tuxlogo_count, pt in enumerate(zip(*loc[::-1]), start=1): 89bbbd9b6eSWillian Rampazzo logger.debug('found Tux at position (x, y) = %s', pt) 90bbbd9b6eSWillian Rampazzo cv2.rectangle(screendump_bgr, pt, 91bbbd9b6eSWillian Rampazzo (pt[0] + w, pt[1] + h), (0, 0, 255), 2) 92bbbd9b6eSWillian Rampazzo if debug_png: 93bbbd9b6eSWillian Rampazzo cv2.imwrite(debug_png, screendump_bgr) 94bbbd9b6eSWillian Rampazzo self.assertGreaterEqual(tuxlogo_count, cpu_cores_count) 95bbbd9b6eSWillian Rampazzo 96bbbd9b6eSWillian Rampazzo def test_mips_malta_i6400_framebuffer_logo_1core(self): 97bbbd9b6eSWillian Rampazzo """ 98bbbd9b6eSWillian Rampazzo :avocado: tags=arch:mips64el 99bbbd9b6eSWillian Rampazzo :avocado: tags=machine:malta 100bbbd9b6eSWillian Rampazzo :avocado: tags=cpu:I6400 101bbbd9b6eSWillian Rampazzo """ 102bbbd9b6eSWillian Rampazzo self.do_test_i6400_framebuffer_logo(1) 103bbbd9b6eSWillian Rampazzo 1049b45cc99SAlex Bennée @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') 1059b45cc99SAlex Bennée 106bbbd9b6eSWillian Rampazzo def test_mips_malta_i6400_framebuffer_logo_7cores(self): 107bbbd9b6eSWillian Rampazzo """ 108bbbd9b6eSWillian Rampazzo :avocado: tags=arch:mips64el 109bbbd9b6eSWillian Rampazzo :avocado: tags=machine:malta 110bbbd9b6eSWillian Rampazzo :avocado: tags=cpu:I6400 111bbbd9b6eSWillian Rampazzo :avocado: tags=mips:smp 1125d25fcb7SAlex Bennée :avocado: tags=flaky 113bbbd9b6eSWillian Rampazzo """ 114bbbd9b6eSWillian Rampazzo self.do_test_i6400_framebuffer_logo(7) 115bbbd9b6eSWillian Rampazzo 1169b45cc99SAlex Bennée @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') 1179b45cc99SAlex Bennée 118bbbd9b6eSWillian Rampazzo def test_mips_malta_i6400_framebuffer_logo_8cores(self): 119bbbd9b6eSWillian Rampazzo """ 120bbbd9b6eSWillian Rampazzo :avocado: tags=arch:mips64el 121bbbd9b6eSWillian Rampazzo :avocado: tags=machine:malta 122bbbd9b6eSWillian Rampazzo :avocado: tags=cpu:I6400 123bbbd9b6eSWillian Rampazzo :avocado: tags=mips:smp 1245d25fcb7SAlex Bennée :avocado: tags=flaky 125bbbd9b6eSWillian Rampazzo """ 126bbbd9b6eSWillian Rampazzo self.do_test_i6400_framebuffer_logo(8) 12714c2b184SPhilippe Mathieu-Daudé 12814c2b184SPhilippe Mathieu-Daudéclass MaltaMachine(QemuSystemTest): 12914c2b184SPhilippe Mathieu-Daudé 13014c2b184SPhilippe Mathieu-Daudé def do_test_yamon(self): 131*d369ad55SPhilippe Mathieu-Daudé rom_url = ('https://s3-eu-west-1.amazonaws.com/' 132*d369ad55SPhilippe Mathieu-Daudé 'downloads-mips/mips-downloads/' 133*d369ad55SPhilippe Mathieu-Daudé 'YAMON/yamon-bin-02.22.zip') 13414c2b184SPhilippe Mathieu-Daudé rom_hash = '8da7ecddbc5312704b8b324341ee238189bde480' 13514c2b184SPhilippe Mathieu-Daudé zip_path = self.fetch_asset(rom_url, asset_hash=rom_hash) 13614c2b184SPhilippe Mathieu-Daudé 13714c2b184SPhilippe Mathieu-Daudé archive.extract(zip_path, self.workdir) 13814c2b184SPhilippe Mathieu-Daudé yamon_path = os.path.join(self.workdir, 'yamon-02.22.bin') 13914c2b184SPhilippe Mathieu-Daudé 14014c2b184SPhilippe Mathieu-Daudé self.vm.set_console() 14114c2b184SPhilippe Mathieu-Daudé self.vm.add_args('-bios', yamon_path) 14214c2b184SPhilippe Mathieu-Daudé self.vm.launch() 14314c2b184SPhilippe Mathieu-Daudé 14414c2b184SPhilippe Mathieu-Daudé prompt = 'YAMON>' 14514c2b184SPhilippe Mathieu-Daudé pattern = 'YAMON ROM Monitor' 14614c2b184SPhilippe Mathieu-Daudé interrupt_interactive_console_until_pattern(self, pattern, prompt) 14714c2b184SPhilippe Mathieu-Daudé wait_for_console_pattern(self, prompt) 14814c2b184SPhilippe Mathieu-Daudé self.vm.shutdown() 14914c2b184SPhilippe Mathieu-Daudé 15014c2b184SPhilippe Mathieu-Daudé def test_mipsel_malta_yamon(self): 15114c2b184SPhilippe Mathieu-Daudé """ 15214c2b184SPhilippe Mathieu-Daudé :avocado: tags=arch:mipsel 15314c2b184SPhilippe Mathieu-Daudé :avocado: tags=machine:malta 15414c2b184SPhilippe Mathieu-Daudé :avocado: tags=endian:little 15514c2b184SPhilippe Mathieu-Daudé """ 15614c2b184SPhilippe Mathieu-Daudé self.do_test_yamon() 15714c2b184SPhilippe Mathieu-Daudé 15814c2b184SPhilippe Mathieu-Daudé def test_mips64el_malta_yamon(self): 15914c2b184SPhilippe Mathieu-Daudé """ 16014c2b184SPhilippe Mathieu-Daudé :avocado: tags=arch:mips64el 16114c2b184SPhilippe Mathieu-Daudé :avocado: tags=machine:malta 16214c2b184SPhilippe Mathieu-Daudé :avocado: tags=endian:little 16314c2b184SPhilippe Mathieu-Daudé """ 16414c2b184SPhilippe Mathieu-Daudé self.do_test_yamon() 165