1import os 2 3import infra.basetest 4 5 6class TestPCIUtils(infra.basetest.BRTest): 7 config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + \ 8 """ 9 BR2_PACKAGE_PCIUTILS=y 10 BR2_TARGET_ROOTFS_CPIO=y 11 # BR2_TARGET_ROOTFS_TAR is not set 12 """ 13 14 def test_run(self): 15 cpio_file = os.path.join(self.builddir, "images", "rootfs.cpio") 16 17 # Note: we add a qemu pci-testdev in order to have a stable 18 # device ID, and for writing in configuration space without 19 # interfering with the rest of the emulation. See: 20 # https://www.qemu.org/docs/master/specs/pci-testdev.html 21 self.emulator.boot(arch="armv5", 22 kernel="builtin", 23 options=["-initrd", cpio_file, 24 "-device", "pci-testdev"]) 25 self.emulator.login() 26 27 # Check the program executes. This test also check that we 28 # have "lspci" from the pciutils package, rather than the 29 # busybox applet (which does not recognize the --version 30 # option)" 31 self.assertRunOk("lspci --version") 32 33 # Check few program invocations. 34 self.assertRunOk("lspci") 35 for lspci_opt in ["-t", "-n", "-v", "-vv", "-x"]: 36 self.assertRunOk(f"lspci {lspci_opt}") 37 38 # Check we can see the qemu pci-testdev. 39 # Vendor: 1b36: Red Hat, Inc. 40 # Device: 0005: QEMU PCI Test Device 41 pci_vendor_id = "1b36" 42 pci_device_id = "0005" 43 pci_dev = f"{pci_vendor_id}:{pci_device_id}" 44 cmd = f"lspci -d {pci_dev}" 45 output, exit_code = self.emulator.run(cmd) 46 self.assertEqual(exit_code, 0) 47 self.assertIn("Red Hat, Inc.", output[0]) 48 self.assertIn("QEMU PCI Test Device", output[0]) 49 50 # We disable INTx emulation by setting bit 10 of the COMMAND 51 # register in the configuration space. See: 52 # https://git.kernel.org/pub/scm/utils/pciutils/pciutils.git/tree/lib/header.h?h=v3.10.0#n26 53 dis_int_x = 0x400 54 data_mask = f"{hex(dis_int_x)}:{hex(dis_int_x)}" 55 cmd = f"setpci -d {pci_dev} COMMAND.w={data_mask}" 56 self.assertRunOk(cmd) 57 58 # We read back and check the value. 59 cmd = f"setpci -d {pci_dev} COMMAND.w" 60 output, exit_code = self.emulator.run(cmd) 61 read_value = int(output[0], 16) 62 self.assertEqual(exit_code, 0) 63 self.assertTrue((read_value & dis_int_x) == dis_int_x) 64 65 # We check lspci now see the disabled INTx emulation. 66 cmd = f"lspci -vv -d {pci_dev} | grep -F 'DisINTx+'" 67 self.assertRunOk(cmd) 68 69 # We re-enable the INTx emulation by clearing the bit 10. 70 data_mask = f"0x0:{hex(dis_int_x)}" 71 cmd = f"setpci -d {pci_dev} COMMAND.w={data_mask}" 72 self.assertRunOk(cmd) 73 74 # We read back and check the value, again. 75 cmd = f"setpci -d {pci_dev} COMMAND.w" 76 output, exit_code = self.emulator.run(cmd) 77 read_value = int(output[0], 16) 78 self.assertEqual(exit_code, 0) 79 self.assertTrue((read_value & dis_int_x) == 0) 80 81 # We check lspci now see the enabled INTx emulation. 82 cmd = f"lspci -vv -d {pci_dev} | grep -F 'DisINTx-'" 83 self.assertRunOk(cmd) 84