diff --git a/MAINTAINERS b/MAINTAINERS index 0acb16cd1b..b66c46dcb9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -365,9 +365,8 @@ S: Maintained F: target/arm/kvm.c MIPS KVM CPUs -M: James Hogan -R: Aleksandar Rikalo -S: Maintained +M: Aleksandar Markovic +S: Odd Fixes F: target/mips/kvm.c PPC KVM CPUs @@ -1006,6 +1005,7 @@ F: hw/mips/mips_malta.c F: hw/mips/gt64xxx_pci.c F: include/hw/southbridge/piix.h F: tests/acceptance/linux_ssh_mips_malta.py +F: tests/acceptance/machine_mips_malta.py Mipssim M: Aleksandar Markovic diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c index c373ab066b..4727b1d3a4 100644 --- a/hw/mips/mips_fulong2e.c +++ b/hw/mips/mips_fulong2e.c @@ -319,9 +319,8 @@ static void mips_fulong2e_init(MachineState *machine) } /* allocate RAM */ - memory_region_init_ram(bios, NULL, "fulong2e.bios", BIOS_SIZE, + memory_region_init_rom(bios, NULL, "fulong2e.bios", BIOS_SIZE, &error_fatal); - memory_region_set_readonly(bios, true); memory_region_add_subregion(address_space_mem, 0, machine->ram); memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios); diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c index 863ed45659..796730b11d 100644 --- a/hw/mips/mips_int.c +++ b/hw/mips/mips_int.c @@ -77,7 +77,7 @@ void cpu_mips_irq_init_cpu(MIPSCPU *cpu) qemu_irq *qi; int i; - qi = qemu_allocate_irqs(cpu_mips_irq_request, env_archcpu(env), 8); + qi = qemu_allocate_irqs(cpu_mips_irq_request, cpu, 8); for (i = 0; i < 8; i++) { env->irq[i] = qi[i]; } diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index 32fbd10b4e..afea52b41b 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -197,9 +197,8 @@ static void mips_jazz_init(MachineState *machine, /* allocate RAM */ memory_region_add_subregion(address_space, 0, machine->ram); - memory_region_init_ram(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE, + memory_region_init_rom(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE, &error_fatal); - memory_region_set_readonly(bios, true); memory_region_init_alias(bios2, NULL, "mips_jazz.bios", bios, 0, MAGNUM_BIOS_SIZE); memory_region_add_subregion(address_space, 0x1fc00000LL, bios); @@ -265,9 +264,8 @@ static void mips_jazz_init(MachineState *machine, { /* Simple ROM, so user doesn't have to provide one */ MemoryRegion *rom_mr = g_new(MemoryRegion, 1); - memory_region_init_ram(rom_mr, NULL, "g364fb.rom", 0x80000, + memory_region_init_rom(rom_mr, NULL, "g364fb.rom", 0x80000, &error_fatal); - memory_region_set_readonly(rom_mr, true); uint8_t *rom = memory_region_get_ram_ptr(rom_mr); memory_region_add_subregion(address_space, 0x60000000, rom_mr); rom[0] = 0x10; /* Mips G364 */ diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c index b2555ddb89..d220318939 100644 --- a/hw/mips/mips_mipssim.c +++ b/hw/mips/mips_mipssim.c @@ -165,9 +165,8 @@ mips_mipssim_init(MachineState *machine) qemu_register_reset(main_cpu_reset, reset_info); /* Allocate RAM. */ - memory_region_init_ram(bios, NULL, "mips_mipssim.bios", BIOS_SIZE, + memory_region_init_rom(bios, NULL, "mips_mipssim.bios", BIOS_SIZE, &error_fatal); - memory_region_set_readonly(bios, true); memory_region_add_subregion(address_space_mem, 0, machine->ram); diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c index 258cd91578..ad8b75e286 100644 --- a/hw/mips/mips_r4k.c +++ b/hw/mips/mips_r4k.c @@ -237,9 +237,8 @@ void mips_r4k_init(MachineState *machine) dinfo = drive_get(IF_PFLASH, 0, 0); if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) { bios = g_new(MemoryRegion, 1); - memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE, + memory_region_init_rom(bios, NULL, "mips_r4k.bios", BIOS_SIZE, &error_fatal); - memory_region_set_readonly(bios, true); memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios); load_image_targphys(filename, 0x1fc00000, BIOS_SIZE); diff --git a/tests/acceptance/machine_mips_malta.py b/tests/acceptance/machine_mips_malta.py new file mode 100644 index 0000000000..92b4f28a11 --- /dev/null +++ b/tests/acceptance/machine_mips_malta.py @@ -0,0 +1,118 @@ +# Functional tests for the MIPS Malta board +# +# Copyright (c) Philippe Mathieu-Daudé +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +import gzip +import logging + +from avocado import skipUnless +from avocado_qemu import Test +from avocado_qemu import wait_for_console_pattern +from avocado.utils import archive + + +NUMPY_AVAILABLE = True +try: + import numpy as np +except ImportError: + NUMPY_AVAILABLE = False + +CV2_AVAILABLE = True +try: + import cv2 +except ImportError: + CV2_AVAILABLE = False + + +@skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed') +@skipUnless(CV2_AVAILABLE, 'Python OpenCV not installed') +class MaltaMachineFramebuffer(Test): + + timeout = 30 + + KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' + + def do_test_i6400_framebuffer_logo(self, cpu_cores_count): + """ + Boot Linux kernel and check Tux logo is displayed on the framebuffer. + """ + screendump_path = os.path.join(self.workdir, 'screendump.pbm') + + kernel_url = ('https://github.com/philmd/qemu-testing-blob/raw/' + 'a5966ca4b5/mips/malta/mips64el/' + 'vmlinux-4.7.0-rc1.I6400.gz') + kernel_hash = '096f50c377ec5072e6a366943324622c312045f6' + kernel_path_gz = self.fetch_asset(kernel_url, asset_hash=kernel_hash) + kernel_path = self.workdir + "vmlinux" + archive.gzip_uncompress(kernel_path_gz, kernel_path) + + tuxlogo_url = ('https://github.com/torvalds/linux/raw/v2.6.12/' + 'drivers/video/logo/logo_linux_vga16.ppm') + tuxlogo_hash = '3991c2ddbd1ddaecda7601f8aafbcf5b02dc86af' + tuxlogo_path = self.fetch_asset(tuxlogo_url, asset_hash=tuxlogo_hash) + + self.vm.set_console() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'clocksource=GIC console=tty0 console=ttyS0') + self.vm.add_args('-kernel', kernel_path, + '-cpu', 'I6400', + '-smp', '%u' % cpu_cores_count, + '-vga', 'std', + '-append', kernel_command_line) + self.vm.launch() + framebuffer_ready = 'Console: switching to colour frame buffer device' + wait_for_console_pattern(self, framebuffer_ready, + failure_message='Kernel panic - not syncing') + self.vm.command('human-monitor-command', command_line='stop') + self.vm.command('human-monitor-command', + command_line='screendump %s' % screendump_path) + logger = logging.getLogger('framebuffer') + + match_threshold = 0.95 + screendump_bgr = cv2.imread(screendump_path, cv2.IMREAD_COLOR) + tuxlogo_bgr = cv2.imread(tuxlogo_path, cv2.IMREAD_COLOR) + result = cv2.matchTemplate(screendump_bgr, tuxlogo_bgr, + cv2.TM_CCOEFF_NORMED) + loc = np.where(result >= match_threshold) + tuxlogo_count = 0 + h, w = tuxlogo_bgr.shape[:2] + debug_png = os.getenv('AVOCADO_CV2_SCREENDUMP_PNG_PATH') + for tuxlogo_count, pt in enumerate(zip(*loc[::-1]), start=1): + logger.debug('found Tux at position (x, y) = %s', pt) + cv2.rectangle(screendump_bgr, pt, + (pt[0] + w, pt[1] + h), (0, 0, 255), 2) + if debug_png: + cv2.imwrite(debug_png, screendump_bgr) + self.assertGreaterEqual(tuxlogo_count, cpu_cores_count) + + def test_mips_malta_i6400_framebuffer_logo_1core(self): + """ + :avocado: tags=arch:mips64el + :avocado: tags=machine:malta + :avocado: tags=cpu:i6400 + """ + self.do_test_i6400_framebuffer_logo(1) + + def test_mips_malta_i6400_framebuffer_logo_7cores(self): + """ + :avocado: tags=arch:mips64el + :avocado: tags=machine:malta + :avocado: tags=cpu:i6400 + :avocado: tags=mips:smp + """ + self.do_test_i6400_framebuffer_logo(7) + + def test_mips_malta_i6400_framebuffer_logo_8cores(self): + """ + :avocado: tags=arch:mips64el + :avocado: tags=machine:malta + :avocado: tags=cpu:i6400 + :avocado: tags=mips:smp + """ + self.do_test_i6400_framebuffer_logo(8)