From patchwork Sun Jul 10 17:00:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ani Sinha X-Patchwork-Id: 12912584 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6CED8C433EF for ; Sun, 10 Jul 2022 17:07:29 +0000 (UTC) Received: from localhost ([::1]:43452 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oAaP2-0005kr-B8 for qemu-devel@archiver.kernel.org; Sun, 10 Jul 2022 13:07:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53834) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oAaJ5-0006Bx-7J for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:19 -0400 Received: from mail-pf1-x42f.google.com ([2607:f8b0:4864:20::42f]:41916) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oAaJ0-0003LZ-LV for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:18 -0400 Received: by mail-pf1-x42f.google.com with SMTP id l124so3002279pfl.8 for ; Sun, 10 Jul 2022 10:01:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anisinha-ca.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xht0ncKsb6eEvslpZPtZj0ZhnWSbMSQJAWjUWWwDbLI=; b=pFloVc0QOEWPv5e1Df+y0OsVekFt3KFjYpNeU7IsNXB/+a3PQdu+0QbJMq+Cp0ACiM +uKKOW1DmpcBTtExX5oZZNUfmeOBBmjKGEf7V0pPyQWizldbtuie1hovRpg7mY6sUFHW JHxRgWMNJ84/DFvDPw1yxlglBtXCx93PSMflR+qTmP3+GjFM/ZNL1GjG460cHrk9diqo IQAm430sljT1lbHGMQTBq2MqpjkaGzVEufOceUmHrEIPY2UgvpAGyJxBLyoWJLiopFi6 0+sGt8Jej59HgIhJWUgZcQIGQPG7wcWJVTAiL0FdMzEp/GhKm2BRN8J0GUOjx/4ja/uw Ur+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xht0ncKsb6eEvslpZPtZj0ZhnWSbMSQJAWjUWWwDbLI=; b=4o9IS7z49fT4BvkapPKUsFke8HXUvNoKlpR9dkpiGH7mALOT/DIK+OTvcUCUV3DbJ4 01KjPXg4Y6Uu4Sheaq/SE8H8KcZS1acdljRqLKwfcW9D5MnOO8+wc6mARpC76zPmqm/3 xokHzeK70Kk82j3wwnOKC8hRmTeCuoLdLGDs9D082eJeVOPp/UUcCZ0jnfeSTHwcdiiF nZb/M+BsCcUjt1AkOl7OKmSzDpGSmDrAFDVEXoAeBr2tVxgEZ3YdKZc9MYvCfXiq5FGd HVE7fBh4YLFgOmMw/FrrKHkRD2IQ3RcHh99+Zu/4Y+oy91IBGnKe8ISGW/RuQmaHUGLW Y8iA== X-Gm-Message-State: AJIora8JrBiNC/NrFlzO95CYlrksVD1GKRJUdgeYoYPKVySLPS9o4u1k 2rDsuCY8MrHllRfBuHhMnFHohxEu8Rnr5f7s X-Google-Smtp-Source: AGRyM1uadJO8rc22827WYo+biMuulY6GbXJbeJgW3maxtrGNBwSik/MWu3FkFwKVxUG3zQzoTFTenQ== X-Received: by 2002:a05:6a00:b45:b0:525:7ad2:91a7 with SMTP id p5-20020a056a000b4500b005257ad291a7mr14042817pfo.22.1657472471505; Sun, 10 Jul 2022 10:01:11 -0700 (PDT) Received: from anisinha-lenovo.ba.nuagenetworks.net ([115.96.107.107]) by smtp.googlemail.com with ESMTPSA id u14-20020a17090341ce00b0016c19417495sm2930596ple.239.2022.07.10.10.01.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jul 2022 10:01:10 -0700 (PDT) From: Ani Sinha To: qemu-devel@nongnu.org Cc: thuth@redhat.com, peter.maydell@linaro.org, berrange@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, imammedo@redhat.com, mst@redhat.com, Ani Sinha Subject: [PATCH v2 01/11] acpi/tests/bits: initial commit of test scripts that are run by biosbits Date: Sun, 10 Jul 2022 22:30:04 +0530 Message-Id: <20220710170014.1673480-2-ani@anisinha.ca> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710170014.1673480-1-ani@anisinha.ca> References: <20220710170014.1673480-1-ani@anisinha.ca> MIME-Version: 1.0 Received-SPF: none client-ip=2607:f8b0:4864:20::42f; envelope-from=ani@anisinha.ca; helo=mail-pf1-x42f.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This is initial commit of cpuid, acpi and smbios python test scripts for biosbits to execute. No change has been made to them from the original code written by the biosbits author Josh Triplett. They are required to be installed into the bits iso file and then run from within the virtual machine booted off with biosbits iso. The original location of these tests are here: https://github.com/biosbits/bits/blob/master/python/testacpi.py https://github.com/biosbits/bits/blob/master/python/smbios.py https://github.com/biosbits/bits/blob/master/python/testcpuid.py Signed-off-by: Ani Sinha --- tests/pytest/acpi-bits/bits-tests/meson.build | 11 + tests/pytest/acpi-bits/bits-tests/smbios.py | 2430 +++++++++++++++++ tests/pytest/acpi-bits/bits-tests/testacpi.py | 283 ++ .../pytest/acpi-bits/bits-tests/testcpuid.py | 83 + 4 files changed, 2807 insertions(+) create mode 100644 tests/pytest/acpi-bits/bits-tests/meson.build create mode 100644 tests/pytest/acpi-bits/bits-tests/smbios.py create mode 100644 tests/pytest/acpi-bits/bits-tests/testacpi.py create mode 100644 tests/pytest/acpi-bits/bits-tests/testcpuid.py diff --git a/tests/pytest/acpi-bits/bits-tests/meson.build b/tests/pytest/acpi-bits/bits-tests/meson.build new file mode 100644 index 0000000000..3056731a53 --- /dev/null +++ b/tests/pytest/acpi-bits/bits-tests/meson.build @@ -0,0 +1,11 @@ +test_files = ['smbios.py', 'testacpi.py', 'testcpuid.py'] + +copytestfiles = custom_target('copy test files', + input : test_files, + output : test_files, + command : ['cp', '@INPUT@', '@OUTDIR@'], + install : true, + install_dir : 'bits-tests', + build_by_default : true) + +other_deps += copytestfiles diff --git a/tests/pytest/acpi-bits/bits-tests/smbios.py b/tests/pytest/acpi-bits/bits-tests/smbios.py new file mode 100644 index 0000000000..9667d0542c --- /dev/null +++ b/tests/pytest/acpi-bits/bits-tests/smbios.py @@ -0,0 +1,2430 @@ +# Copyright (c) 2015, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Intel Corporation nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""SMBIOS/DMI module.""" + +import bits +import bitfields +import ctypes +import redirect +import struct +import uuid +import unpack +import ttypager +import sys + +class SMBIOS(unpack.Struct): + def __new__(cls): + if sys.platform == "BITS-EFI": + import efi + sm_ptr = efi.system_table.ConfigurationTableDict.get(efi.SMBIOS_TABLE_GUID) + else: + address = 0xF0000 + mem = bits.memory(0xF0000, 0x10000) + for offset in range(0, len(mem), 16): + signature = (ctypes.c_char * 4).from_address(address + offset).value + if signature == "_SM_": + entry_point_length = ctypes.c_ubyte.from_address(address + offset + 5).value + csum = sum(map(ord, mem[offset:offset + entry_point_length])) & 0xff + if csum == 0: + sm_ptr = address + offset + break + else: + return None + + if not sm_ptr: + return None + + sm = super(SMBIOS, cls).__new__(cls) + sm._header_memory = bits.memory(sm_ptr, 0x1f) + return sm + + def __init__(self): + super(SMBIOS, self).__init__() + u = unpack.Unpackable(self._header_memory) + self.add_field('header', Header(u)) + self._structure_memory = bits.memory(self.header.structure_table_address, self.header.structure_table_length) + u = unpack.Unpackable(self._structure_memory) + self.add_field('structures', unpack.unpack_all(u, _smbios_structures, self), unpack.format_each("\n\n{!r}")) + + def structure_type(self, num): + '''Dumps structure of given Type if present''' + try: + types_present = [self.structures[x].smbios_structure_type for x in range(len(self.structures))] + matrix = dict() + for index in range(len(types_present)): + if types_present.count(types_present[index]) == 1: + matrix[types_present[index]] = self.structures[index] + else: # if multiple structures of the same type, return a list of structures for the type number + if matrix.has_key(types_present[index]): + matrix[types_present[index]].append(self.structures[index]) + else: + matrix[types_present[index]] = [self.structures[index]] + return matrix[num] + except: + print "Failure: Type {} - not found".format(num) + +class Header(unpack.Struct): + def __new__(cls, u): + return super(Header, cls).__new__(cls) + + def __init__(self, u): + super(Header, self).__init__() + self.raw_data = u.unpack_rest() + u = unpack.Unpackable(self.raw_data) + self.add_field('anchor_string', u.unpack_one("4s")) + self.add_field('checksum', u.unpack_one("B")) + self.add_field('length', u.unpack_one("B")) + self.add_field('major_version', u.unpack_one("B")) + self.add_field('minor_version', u.unpack_one("B")) + self.add_field('max_structure_size', u.unpack_one(" len(self.strings): + return "(error: string index out of range)" + return self.strings[i - 1] + +class BIOSInformation(SmbiosBaseStructure): + smbios_structure_type = 0 + + def __init__(self, u, sm): + super(BIOSInformation, self).__init__(u, sm) + u = self.u + try: + self.add_field('vendor', u.unpack_one("B"), self.fmtstr) + self.add_field('version', u.unpack_one("B"), self.fmtstr) + self.add_field('starting_address_segment', u.unpack_one("= (2,"4"): + characteristic_bytes = 2 + else: + characteristic_bytes = self.length - 0x12 + self.add_field('characteristics_extensions', [u.unpack_one("B") for b in range(characteristic_bytes)]) + if (sm.header.major_version, minor_version_str) >= (2,"4"): + self.add_field('major_release', u.unpack_one("B")) + self.add_field('minor_release', u.unpack_one("B")) + self.add_field('ec_major_release', u.unpack_one("B")) + self.add_field('ec_minor_release', u.unpack_one("B")) + except: + self.decode_failure = True + print "Error parsing BIOSInformation" + import traceback + traceback.print_exc() + self.fini() + +class SystemInformation(SmbiosBaseStructure): + smbios_structure_type = 1 + + def __init__(self, u, sm): + super(SystemInformation, self).__init__(u, sm) + u = self.u + try: + self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) + self.add_field('product_name', u.unpack_one("B"), self.fmtstr) + self.add_field('version', u.unpack_one("B"), self.fmtstr) + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x8: + self.add_field('uuid', uuid.UUID(bytes_le=u.unpack_one("16s"))) + wakeup_types = { + 0: 'Reserved', + 1: 'Other', + 2: 'Unknown', + 3: 'APM Timer', + 4: 'Modem Ring', + 5: 'LAN Remote', + 6: 'Power Switch', + 7: 'PCI PME#', + 8: 'AC Power Restored' + } + self.add_field('wakeup_type', u.unpack_one("B"), unpack.format_table("{}", wakeup_types)) + if self.length > 0x19: + self.add_field('sku_number', u.unpack_one("B"), self.fmtstr) + self.add_field('family', u.unpack_one("B"), self.fmtstr) + except: + self.decode_failure = True + print "Error parsing SystemInformation" + import traceback + traceback.print_exc() + self.fini() + +_board_types = { + 1: 'Unknown', + 2: 'Other', + 3: 'Server Blade', + 4: 'Connectivity Switch', + 5: 'System Management Module', + 6: 'Processor Module', + 7: 'I/O Module', + 8: 'Memory Module', + 9: 'Daughter Board', + 0xA: 'Motherboard', + 0xB: 'Processor/Memory Module', + 0xC: 'Processor/IO Module', + 0xD: 'Interconnect Board' +} + +class BaseboardInformation(SmbiosBaseStructure): + smbios_structure_type = 2 + + def __init__(self, u, sm): + super(BaseboardInformation, self).__init__(u, sm) + u = self.u + try: + self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) + self.add_field('product', u.unpack_one("B"), self.fmtstr) + self.add_field('version', u.unpack_one("B"), self.fmtstr) + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + + if self.length > 0x8: + self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) + + if self.length > 0x9: + self.add_field('feature_flags', u.unpack_one("B")) + self.add_field('hosting_board', bool(bitfields.getbits(self.feature_flags, 0)), "feature_flags[0]={}") + self.add_field('requires_daughter_card', bool(bitfields.getbits(self.feature_flags, 1)), "feature_flags[1]={}") + self.add_field('removable', bool(bitfields.getbits(self.feature_flags, 2)), "feature_flags[2]={}") + self.add_field('replaceable', bool(bitfields.getbits(self.feature_flags, 3)), "feature_flags[3]={}") + self.add_field('hot_swappable', bool(bitfields.getbits(self.feature_flags, 4)), "feature_flags[4]={}") + + if self.length > 0xA: + self.add_field('location', u.unpack_one("B"), self.fmtstr) + + if self.length > 0xB: + self.add_field('chassis_handle', u.unpack_one(" 0xD: + self.add_field('board_type', u.unpack_one("B"), unpack.format_table("{}", _board_types)) + + if self.length > 0xE: + self.add_field('handle_count', u.unpack_one("B")) + if self.handle_count > 0: + self.add_field('contained_object_handles', tuple(u.unpack_one(" 9: + chassis_states = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Safe', + 0x04: 'Warning', + 0x05: 'Critical', + 0x06: 'Non-recoverable', + } + self.add_field('bootup_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) + self.add_field('power_supply_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) + self.add_field('thermal_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) + security_states = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'None', + 0x04: 'External interface locked out', + 0x05: 'External interface enabled', + } + self.add_field('security_status', u.unpack_one("B"), unpack.format_table("{}", security_states)) + if self.length > 0xd: + self.add_field('oem_defined', u.unpack_one(" 0x11: + self.add_field('height', u.unpack_one("B")) + self.add_field('num_power_cords', u.unpack_one("B")) + self.add_field('contained_element_count', u.unpack_one("B")) + self.add_field('contained_element_length', u.unpack_one("B")) + if getattr(self, 'contained_element_count', 0): + self.add_field('contained_elements', tuple(SystemEnclosureContainedElement(u, self.contained_element_length) for i in range(self.contained_element_count))) + if self.length > (0x15 + (getattr(self, 'contained_element_count', 0) * getattr(self, 'contained_element_length', 0))): + self.add_field('sku_number', u.unpack_one("B"), self.fmtstr) + except: + self.decode_failure = True + print "Error parsing SystemEnclosure" + import traceback + traceback.print_exc() + self.fini() + +class SystemEnclosureContainedElement(unpack.Struct): + def __init__(self, u, length): + super(SystemEnclosureContainedElement, self).__init__() + self.start_offset = u.offset + self.raw_data = u.unpack_raw(length) + self.u = unpack.Unpackable(self.raw_data) + u = self.u + self.add_field('contained_element_type', u.unpack_one("B")) + type_selections = { + 0: 'SMBIOS baseboard type enumeration', + 1: 'SMBIOS structure type enumeration', + } + self.add_field('type_select', bitfields.getbits(self.contained_element_type, 7), unpack.format_table("contained_element_type[7]={}", type_selections)) + self.add_field('type', bitfields.getbits(self.contained_element_type, 6, 0)) + if self.type_select == 0: + self.add_field('smbios_board_type', self.type, unpack.format_table("{}", _board_types)) + else: + self.add_field('smbios_structure_type', self.type) + self.add_field('minimum', u.unpack_one("B")) + self.add_field('maximum', u.unpack_one("B")) + if not u.at_end(): + self.add_field('data', u.unpack_rest()) + del self.u + +class ProcessorInformation(SmbiosBaseStructure): + smbios_structure_type = 4 + + def __init__(self, u, sm): + super(ProcessorInformation, self).__init__(u, sm) + u = self.u + try: + self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr) + processor_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Central Processor', + 0x04: 'Math Processor', + 0x05: 'DSP Processor', + 0x06: 'Video Processor', + } + self.add_field('processor_type', u.unpack_one("B"), unpack.format_table("{}", processor_types)) + self.add_field('processor_family', u.unpack_one("B")) + self.add_field('processor_manufacturer', u.unpack_one("B"), self.fmtstr) + self.add_field('processor_id', u.unpack_one(" 0x1A: + self.add_field('l1_cache_handle', u.unpack_one(" 0x20: + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) + self.add_field('part_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x24: + self.add_field('core_count', u.unpack_one("B")) + self.add_field('core_enabled', u.unpack_one("B")) + self.add_field('thread_count', u.unpack_one("B")) + self.add_field('processor_characteristics', u.unpack_one(" 0x28: + self.add_field('processor_family_2', u.unpack_one(" 0x2A: + self.add_field('core_count2', u.unpack_one(" 0x0F: + self.add_field('cache_speed', u.unpack_one("B")) + if self.length > 0x10: + _error_correction = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'None', + 0x04: 'Parity', + 0x05: 'Single-bit ECC', + 0x06: 'Multi-bit ECC' + } + self.add_field('error_correction', u.unpack_one("B"), unpack.format_table("{}", _error_correction)) + if self.length > 0x10: + _system_cache_type = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Instruction', + 0x04: 'Data', + 0x05: 'Unified' + } + self.add_field('system_cache_type', u.unpack_one("B"), unpack.format_table("{}", _system_cache_type)) + if self.length > 0x12: + _associativity = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Direct Mapped', + 0x04: '2-way Set-Associative', + 0x05: '4-way Set-Associative', + 0x06: 'Fully Associative', + 0x07: '8-way Set-Associative', + 0x08: '16-way Set-Associative', + 0x09: '12-way Set-Associative', + 0x0A: '24-way Set-Associative', + 0x0B: '32-way Set-Associative', + 0x0C: '48-way Set-Associative', + 0x0D: '64-way Set-Associative', + 0x0E: '20-way Set-Associative' + } + self.add_field('associativity', u.unpack_one("B"), unpack.format_table("{}", _associativity)) + + except: + self.decode_failure = True + print "Error parsing CacheInformation" + import traceback + traceback.print_exc() + self.fini() + +class PortConnectorInfo(SmbiosBaseStructure): + smbios_structure_type = 8 + + def __init__(self, u, sm): + super(PortConnectorInfo, self).__init__(u, sm) + u = self.u + try: + self.add_field('internal_reference_designator', u.unpack_one("B"), self.fmtstr) + connector_types = { + 0x00: 'None', + 0x01: 'Centronics', + 0x02: 'Mini Centronics', + 0x03: 'Proprietary', + 0x04: 'DB-25 pin male', + 0x05: 'DB-25 pin female', + 0x06: 'DB-15 pin male', + 0x07: 'DB-15 pin female', + 0x08: 'DB-9 pin male', + 0x09: 'DB-9 pin female', + 0x0A: 'RJ-11', + 0x0B: 'RJ-45', + 0x0C: '50-pin MiniSCSI', + 0x0D: 'Mini-DIN', + 0x0E: 'Micro-DIN', + 0x0F: 'PS/2', + 0x10: 'Infrared', + 0x11: 'HP-HIL', + 0x12: 'Access Bus (USB)', + 0x13: 'SSA SCSI', + 0x14: 'Circular DIN-8 male', + 0x15: 'Circular DIN-8 female', + 0x16: 'On Board IDE', + 0x17: 'On Board Floppy', + 0x18: '9-pin Dual Inline (pin 10 cut)', + 0x19: '25-pin Dual Inline (pin 26 cut)', + 0x1A: '50-pin Dual Inline', + 0x1B: '68-pin Dual Inline', + 0x1C: 'On Board Sound Input from CD-ROM', + 0x1D: 'Mini-Centronics Type-14', + 0x1E: 'Mini-Centronics Type-26', + 0x1F: 'Mini-jack (headphones)', + 0x20: 'BNC', + 0x21: '1394', + 0x22: 'SAS/SATA Plug Receptacle', + 0xA0: 'PC-98', + 0xA1: 'PC-98Hireso', + 0xA2: 'PC-H98', + 0xA3: 'PC-98Note', + 0xA4: 'PC-98Full', + 0xFF: 'Other', + } + self.add_field('internal_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types)) + self.add_field('external_reference_designator', u.unpack_one("B"), self.fmtstr) + self.add_field('external_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types)) + port_types = { + 0x00: 'None', + 0x01: 'Parallel Port XT/AT Compatible', + 0x02: 'Parallel Port PS/2', + 0x03: 'Parallel Port ECP', + 0x04: 'Parallel Port EPP', + 0x05: 'Parallel Port ECP/EPP', + 0x06: 'Serial Port XT/AT Compatible', + 0x07: 'Serial Port 16450 Compatible', + 0x08: 'Serial Port 16550 Compatible', + 0x09: 'Serial Port 16550A Compatible', + 0x0A: 'SCSI Port', + 0x0B: 'MIDI Port', + 0x0C: 'Joy Stick Port', + 0x0D: 'Keyboard Port', + 0x0E: 'Mouse Port', + 0x0F: 'SSA SCSI', + 0x10: 'USB', + 0x11: 'FireWire (IEEE P1394)', + 0x12: 'PCMCIA Type I2', + 0x13: 'PCMCIA Type II', + 0x14: 'PCMCIA Type III', + 0x15: 'Cardbus', + 0x16: 'Access Bus Port', + 0x17: 'SCSI II', + 0x18: 'SCSI Wide', + 0x19: 'PC-98', + 0x1A: 'PC-98-Hireso', + 0x1B: 'PC-H98', + 0x1C: 'Video Port', + 0x1D: 'Audio Port', + 0x1E: 'Modem Port', + 0x1F: 'Network Port', + 0x20: 'SATA', + 0x21: 'SAS', + 0xA0: '8251 Compatible', + 0xA1: '8251 FIFO Compatible', + 0xFF: 'Other', + } + self.add_field('port_type', u.unpack_one("B"), unpack.format_table("{}", port_types)) + except: + self.decodeFailure = True + print "Error parsing PortConnectorInfo" + import traceback + traceback.print_exc() + self.fini() + +class SystemSlots(SmbiosBaseStructure): + smbios_structure_type = 9 + + def __init__(self, u, sm): + super(SystemSlots, self).__init__(u, sm) + u = self.u + try: + self.add_field('designation', u.unpack_one("B"), self.fmtstr) + _slot_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'ISA', + 0x04: 'MCA', + 0x05: 'EISA', + 0x06: 'PCI', + 0x07: 'PC Card (PCMCIA)', + 0x08: 'VL-VESA', + 0x09: 'Proprietary', + 0x0A: 'Processor Card Slot', + 0x0B: 'Proprietary Memory Card Slot', + 0x0C: 'I/O Riser Card Slot', + 0x0D: 'NuBus', + 0x0E: 'PCI 66MHz Capable', + 0x0F: 'AGP', + 0x10: 'AGP 2X', + 0x11: 'AGP 4X', + 0x12: 'PCI-X', + 0x13: 'AGP 8X', + 0xA0: 'PC-98/C20', + 0xA1: 'PC-98/C24', + 0xA2: 'PC-98/E', + 0xA3: 'PC-98/Local Bus', + 0xA4: 'PC-98/Card', + 0xA5: 'PCI Express', + 0xA6: 'PCI Express x1', + 0xA7: 'PCI Express x2', + 0xA8: 'PCI Express x4', + 0xA9: 'PCI Express x8', + 0xAA: 'PCI Express x16', + 0xAB: 'PCI Express Gen 2', + 0xAC: 'PCI Express Gen 2 x1', + 0xAD: 'PCI Express Gen 2 x2', + 0xAE: 'PCI Express Gen 2 x4', + 0xAF: 'PCI Express Gen 2 x8', + 0xB0: 'PCI Express Gen 2 x16', + 0xB1: 'PCI Express Gen 3', + 0xB2: 'PCI Express Gen 3 x1', + 0xB3: 'PCI Express Gen 3 x2', + 0xB4: 'PCI Express Gen 3 x4', + 0xB5: 'PCI Express Gen 3 x8', + 0xB6: 'PCI Express Gen 3 x16', + } + self.add_field('slot_type', u.unpack_one("B"), unpack.format_table("{}", _slot_types)) + _slot_data_bus_widths = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: '8 bit', + 0x04: '16 bit', + 0x05: '32 bit', + 0x06: '64 bit', + 0x07: '128 bit', + 0x08: '1x or x1', + 0x09: '2x or x2', + 0x0A: '4x or x4', + 0x0B: '8x or x8', + 0x0C: '12x or x12', + 0x0D: '16x or x16', + 0x0E: '32x or x32', + } + self.add_field('slot_data_bus_width', u.unpack_one('B'), unpack.format_table("{}", _slot_data_bus_widths)) + _current_usages = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Available', + 0x04: 'In use', + } + self.add_field('current_usage', u.unpack_one('B'), unpack.format_table("{}", _current_usages)) + _slot_lengths = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Short Length', + 0x04: 'Long Length', + } + self.add_field('slot_length', u.unpack_one('B'), unpack.format_table("{}", _slot_lengths)) + self.add_field('slot_id', u.unpack_one(' 0x0C: + self.add_field('characteristics2', u.unpack_one('B')) + self.add_field('supports_PME', bool(bitfields.getbits(self.characteristics2, 0)), "characteristics2[0]={}") + self.add_field('supports_hot_plug', bool(bitfields.getbits(self.characteristics2, 1)), "characteristics2[1]={}") + self.add_field('supports_smbus', bool(bitfields.getbits(self.characteristics2, 2)), "characteristics2[2]={}") + if self.length > 0x0D: + self.add_field('segment_group_number', u.unpack_one(' 0x05: + self.add_field('flags', u.unpack_one('B')) + self.add_field('abbreviated_format', bool(bitfields.getbits(self.flags, 0)), "flags[0]={}") + if self.length > 0x6: + u.skip(15) + self.add_field('current_language', u.unpack_one('B'), self.fmtstr) + except: + self.decodeFailure = True + print "Error parsing BIOSLanguageInformation" + import traceback + traceback.print_exc() + self.fini() + +class GroupAssociations(SmbiosBaseStructure): + smbios_structure_type = 14 + + def __init__(self, u, sm): + super(GroupAssociations, self).__init__(u, sm) + u = self.u + try: + self.add_field('group_name', u.unpack_one("B"), self.fmtstr) + self.add_field('item_type', u.unpack_one('B')) + self.add_field('item_handle', u.unpack_one(' 0x14: + _log_header_formats = { + 0: 'No header', + 1: 'Type 1 log header', + xrange(2, 0x7f): 'Available for future assignment', + xrange(0x80, 0xff): 'BIOS vendor or OEM-specific format' + } + self.add_field('log_header_format', u.unpack_one("B"), unpack.format_table("{}", _log_header_formats)) + if self.length > 0x15: + self.add_field('num_supported_log_type_descriptors', u.unpack_one('B')) + if self.length > 0x16: + self.add_field('length_log_type_descriptor', u.unpack_one('B')) + if self.length != (0x17 + (self.num_supported_log_type_descriptors * self.length_log_type_descriptor)): + print "Error: structure length ({}) != 0x17 + (num_supported_log_type_descriptors ({}) * length_log_type_descriptor({}))".format(self.length, self.num_supported_log_type_descriptors, self.length_log_type_descriptor) + print "structure length = {}".format(self.length) + print "num_supported_log_type_descriptors = {}".format(self.num_supported_log_type_descriptors) + print "length_log_type_descriptor = {}".format(self.length_log_type_descriptor) + self.decodeFailure = True + self.add_field('descriptors', tuple(EventLogDescriptor.unpack(u) for i in range(self.num_supported_log_type_descriptors)), unpack.format_each("\n{!r}")) + except: + self.decodeFailure = True + print "Error parsing SystemEventLog" + import traceback + traceback.print_exc() + self.fini() + +class EventLogDescriptor(unpack.Struct): + @staticmethod + def _unpack(u): + _event_log_type_descriptors = { + 0x00: 'Reserved', + 0x01: 'Single-bit ECC memory error', + 0x02: 'Multi-bit ECC memory error', + 0x03: 'Parity memory error', + 0x04: 'Bus time-out', + 0x05: 'I/O Channel Check', + 0x06: 'Software NMI', + 0x07: 'POST Memory Resize', + 0x08: 'POST Error', + 0x09: 'PCI Parity Error', + 0x0A: 'PCI System Error', + 0x0B: 'CPU Failure', + 0x0C: 'EISA FailSafe Timer time-out', + 0x0D: 'Correctable memory log disabled', + 0x0E: 'Logging disabled for a specific Event Type - too many errors of the same type received in a short amount of time', + 0x0F: 'Reserved', + 0x10: 'System Limit Exceeded', + 0x11: 'Asynchronous hardware timer expired and issued a system reset', + 0x12: 'System configuration information', + 0x13: 'Hard-disk information', + 0x14: 'System reconfigured', + 0x15: 'Uncorrectable CPU-complex error', + 0x16: 'Log Area Reset/Cleared', + 0x17: 'System boot', + xrange(0x18, 0x7F): 'Unused, available for assignment', + xrange(0x80, 0xFE): 'Availalbe for system- and OEM-specific assignments', + 0xFF: 'End of log' + } + yield 'log_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_type_descriptors) + _event_log_format = { + 0x00: 'None', + 0x01: 'Handle', + 0x02: 'Multiple-Event', + 0x03: 'Multiple-Event Handle', + 0x04: 'POST Results Bitmap', + 0x05: 'System Management Type', + 0x06: 'Multiple-Event System Management Type', + xrange(0x80, 0xFF): 'OEM assigned' + } + yield 'variable_data_format_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_format) + +class PhysicalMemoryArray(SmbiosBaseStructure): + smbios_structure_type = 16 + + def __init__(self, u, sm): + super(PhysicalMemoryArray, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + _location_field = { + 0x01: "Other", + 0x02: "Unknown", + 0x03: "System board or motherboard", + 0x04: "ISA add-on card", + 0x05: "EISA add-on card", + 0x06: "PCI add-on card", + 0x07: "MCA add-on card", + 0x08: "PCMCIA add-on card", + 0x09: "Proprietary add-on card", + 0x0A: "NuBus", + 0xA0: "PC-98/C20 add-on card", + 0xA1: "PC-98/C24 add-on card", + 0xA2: "PC-98/E add-on card", + 0xA3: "PC-98/Local bus add-on card" + } + self.add_field('location', u.unpack_one("B"), unpack.format_table("{}", _location_field)) + if self.length > 0x05: + _use = { + 0x01: "Other", + 0x02: "Unknown", + 0x03: "System memory", + 0x04: "Video memory", + 0x05: "Flash memory", + 0x06: "Non-volatile RAM", + 0x07: "Cache memory" + } + self.add_field('use', u.unpack_one('B'), unpack.format_table("{}", _use)) + if self.length > 0x06: + _error_correction = { + 0x01: "Other", + 0x02: "Unknown", + 0x03: "None", + 0x04: "Parity", + 0x05: "Single-bit ECC", + 0x06: "Multi-bit ECC", + 0x07: "CRC" + } + self.add_field('memory_error_correction', u.unpack_one('B'), unpack.format_table("{}", _error_correction)) + if self.length > 0x07: + self.add_field('maximum_capacity', u.unpack_one(' 0x0B: + self.add_field('memory_error_information_handle', u.unpack_one(' 0x0D: + self.add_field('num_memory_devices', u.unpack_one(' 0x0F: + self.add_field('extended_maximum_capacity', u.unpack_one(' 0x4: + self.add_field('physical_memory_array_handle', u.unpack_one(" 0x6: + self.add_field('memory_error_information_handle', u.unpack_one(" 0x8: + self.add_field('total_width', u.unpack_one(" 0xA: + self.add_field('data_width', u.unpack_one(" 0xC: + self.add_field('size', u.unpack_one(" 0xE: + _form_factors = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'SIMM', + 0x04: 'SIP', + 0x05: 'Chip', + 0x06: 'DIP', + 0x07: 'ZIP', + 0x08: 'Proprietary Card', + 0x09: 'DIMM', + 0x0A: 'TSOP', + 0x0B: 'Row of chips', + 0x0C: 'RIMM', + 0x0D: 'SODIMM', + 0x0E: 'SRIMM', + 0x0F: 'FB-DIMM' + } + self.add_field('form_factor', u.unpack_one("B"), unpack.format_table("{}", _form_factors)) + if self.length > 0xF: + self.add_field('device_set', u.unpack_one("B")) + if self.length > 0x10: + self.add_field('device_locator', u.unpack_one("B"), self.fmtstr) + if self.length > 0x11: + self.add_field('bank_locator', u.unpack_one("B"), self.fmtstr) + if self.length > 0x12: + _memory_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'DRAM', + 0x04: 'EDRAM', + 0x05: 'VRAM', + 0x06: 'SRAM', + 0x07: 'RAM', + 0x08: 'ROM', + 0x09: 'FLASH', + 0x0A: 'EEPROM', + 0x0B: 'FEPROM', + 0x0C: 'EPROM', + 0x0D: 'CDRAM', + 0x0E: '3DRAM', + 0x0F: 'SDRAM', + 0x10: 'SGRAM', + 0x11: 'RDRAM', + 0x12: 'DDR', + 0x13: 'DDR2', + 0x14: 'DDR2 FB-DIMM', + xrange(0x15, 0x17): 'Reserved', + 0x18: 'DDR3', + 0x19: 'FBD2' + } + self.add_field('memory_type', u.unpack_one("B"), unpack.format_table("{}", _memory_types)) + if self.length > 0x13: + self.add_field('type_detail', u.unpack_one(' 0x15: + self.add_field('speed', u.unpack_one(" 0x17: + self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) + if self.length > 0x18: + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x19: + self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) + if self.length > 0x1A: + self.add_field('part_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x1B: + self.add_field('attributes', u.unpack_one("B")) + self.add_field('rank', bitfields.getbits(self.attributes, 3, 0), "attributes[3:0]={}") + if self.length > 0x1C: + if self.size == 0x7FFF: + self.add_field('extended_size', u.unpack_one(' 0x20: + self.add_field('configured_memory_clock_speed', u.unpack_one(" 0x22: + self.add_field('minimum_voltage', u.unpack_one(" 0x24: + self.add_field('maximum_voltage', u.unpack_one(" 0x26: + self.add_field('configured_voltage', u.unpack_one(" 0x4: + _error_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'OK', + 0x04: 'Bad read', + 0x05: 'Parity error', + 0x06: 'Single-bit error', + 0x07: 'Double-bit error', + 0x08: 'Multi-bit error', + 0x09: 'Nibble error', + 0x0A: 'Checksum error', + 0x0B: 'CRC error', + 0x0C: 'Corrected single-bit error', + 0x0D: 'Corrected error', + 0x0E: 'Uncorrectable error' + } + self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types)) + if self.length > 0x5: + _error_granularity_field = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Device level', + 0x04: 'Memory partition level' + } + self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field)) + if self.length > 0x6: + _error_operation_field = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Read', + 0x04: 'Write', + 0x05: 'Partial write' + } + self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field)) + if self.length > 0x7: + self.add_field('vendor_syndrome', u.unpack_one(" 0xB: + self.add_field('memory_array_error_address', u.unpack_one(" 0xF: + self.add_field('device_error_address', u.unpack_one(" 0x13: + self.add_field('error_resolution', u.unpack_one(" 0x4: + self.add_field('starting_address', u.unpack_one(" 0x8: + self.add_field('ending_address', u.unpack_one(" 0xC: + self.add_field('memory_array_handle', u.unpack_one(" 0xE: + self.add_field('partition_width', u.unpack_one("B")) + if self.length > 0xF: + # valid if starting_address = FFFF FFFF + if self.starting_address == 0xFFFFFFFF: + self.add_field('extended_starting_address', u.unpack_one(" 0x17: + self.add_field('extended_ending_address', u.unpack_one(" 0x4: + self.add_field('starting_address', u.unpack_one(" 0x8: + self.add_field('ending_address', u.unpack_one(" 0xC: + self.add_field('memory_device_handle', u.unpack_one(" 0xE: + self.add_field('memory_array_mapped_address_handle', u.unpack_one(" 0x10: + self.add_field('partition_row_position', u.unpack_one("B")) + if self.length > 0x11: + self.add_field('interleave_position', u.unpack_one("B")) + if self.length > 0x12: + self.add_field('interleave_data_depth', u.unpack_one("B")) + if self.length > 0x13: + # valid if starting_address = FFFF FFFF + if self.starting_address == 0xFFFFFFFF: + self.add_field('extended_starting_address', u.unpack_one(" 0x1B: + self.add_field('extended_ending_address', u.unpack_one(" 0x4: + _pointing_device_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Mouse', + 0x04: 'Track Ball', + 0x05: 'Track Point', + 0x06: 'Glide Point', + 0x07: 'Touch Pad', + 0x08: 'Touch Screen', + 0x09: 'Optical Sensor' + } + self.add_field('pointing_device_type', u.unpack_one("B"), unpack.format_table("{}", _pointing_device_types)) + if self.length > 0x5: + _interfaces = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Serial', + 0x04: 'PS/2', + 0x05: 'Infared', + 0x06: 'HP-HIL', + 0x07: 'Bus mouse', + 0x08: 'ADB (Apple Desktop Bus)', + 0x09: 'Bus mouse DB-9', + 0x0A: 'Bus mouse micro-DIN', + 0x0B: 'USB' + } + self.add_field('interface', u.unpack_one("B"), unpack.format_table("{}", _interfaces)) + if self.length > 0x6: + self.add_field('num_buttons', u.unpack_one("B")) + except: + self.decodeFailure = True + print "Error parsing BuiltInPointingDevice" + import traceback + traceback.print_exc() + self.fini() + +class PortableBattery(SmbiosBaseStructure): + smbios_structure_type = 22 + + def __init__(self, u, sm): + super(PortableBattery, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + self.add_field('location', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) + if self.length > 0x6: + self.add_field('manufacturer_date', u.unpack_one("B"), self.fmtstr) + if self.length > 0x7: + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x8: + self.add_field('device_name', u.unpack_one("B"), self.fmtstr) + if self.length > 0x9: + _device_chemistry = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Lead Acid', + 0x04: 'Nickel Cadmium', + 0x05: 'Nickel metal hydride', + 0x06: 'Lithium-ion', + 0x07: 'Zinc air', + 0x08: 'Lithium Polymer' + } + self.add_field('device_chemistry', u.unpack_one("B"), unpack.format_table("{}", _device_chemistry)) + if self.length > 0xA: + self.add_field('design_capacity', u.unpack_one(" 0xC: + self.add_field('design_voltage', u.unpack_one(" 0xE: + self.add_field('sbds_version_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0xF: + self.add_field('max_error_battery_data', u.unpack_one("B"), self.fmtstr) + if self.length > 0x10: + if self.serial_number == 0: + self.add_field('sbds_serial_number', u.unpack_one(" 0x12: + if self.manufacturer_date == 0: + self.add_field('sbds_manufacture_date', u.unpack_one(" 0x14: + if self.device_chemistry == 0x02: + self.add_field('sbds_device_chemistry', u.unpack_one("B"), self.fmtstr) + else: + u.skip(1) + if self.length > 0x15: + self.add_field('design_capacity_multiplier', u.unpack_one("B")) + if self.length > 0x16: + self.add_field('oem_specific', u.unpack_one(" 0x4: + self.add_field('capabilities', u.unpack_one("B")) + self.add_field('contains_watchdog_timer', bool(bitfields.getbits(self.capabilities, 5)), "capabilities[5]={}") + _boot_option = { + 0b00: 'Reserved, do not use', + 0b01: 'Operating System', + 0b10: 'System utilities', + 0b11: 'Do not reboot' + } + self.add_field('boot_option_on_limit', bitfields.getbits(self.capabilities, 4, 3), unpack.format_table("capabilities[4:3]={}", _boot_option)) + self.add_field('boot_option_after_watchdog_reset', bitfields.getbits(self.capabilities, 2, 1), unpack.format_table("capabilities[2:1]={}", _boot_option)) + self.add_field('system_reset_enabled_by_user', bool(bitfields.getbits(self.capabilities, 0)), "capabilities[0]={}") + if self.length > 0x5: + self.add_field('reset_count', u.unpack_one(" 0x5: + self.add_field('reset_limit', u.unpack_one(" 0x9: + self.add_field('timer_interval', u.unpack_one(" 0xB: + self.add_field('timeout', u.unpack_one(" 0x4: + self.add_field('hardware_security_settings', u.unpack_one("B")) + _status = { + 0x00: 'Disabled', + 0x01: 'Enabled', + 0x02: 'Not Implemented', + 0x03: 'Unknown' + } + self.add_field('power_on_password_status', bitfields.getbits(self.hardware_security_settings, 7, 6), unpack.format_table("hardware_security_settings[7:6]={}", _status)) + self.add_field('keyboard_password_status', bitfields.getbits(self.hardware_security_settings, 5, 4), unpack.format_table("hardware_security_settings[5:4]={}", _status)) + self.add_field('admin_password_status', bitfields.getbits(self.hardware_security_settings, 3, 2), unpack.format_table("hardware_security_settings0[3:2]={}", _status)) + self.add_field('front_panel_reset_status', bitfields.getbits(self.hardware_security_settings, 1, 0), unpack.format_table("hardware_security_settings[1:0]={}", _status)) + except: + self.decodeFailure = True + print "Error parsing HardwareSecurity" + import traceback + traceback.print_exc() + self.fini() + +class SystemPowerControls(SmbiosBaseStructure): + smbios_structure_type = 25 + + def __init__(self, u, sm): + super(SystemPowerControls, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + self.add_field('next_scheduled_poweron_month', u.unpack_one("B")) + self.add_field('next_scheduled_poweron_day_of_month', u.unpack_one("B")) + self.add_field('next_scheduled_poweron_hour', u.unpack_one("B")) + self.add_field('next_scheduled_poweron_minute', u.unpack_one("B")) + self.add_field('next_scheduled_poweron_second', u.unpack_one("B")) + except: + self.decodeFailure = True + print "Error parsing SystemPowerControls" + import traceback + traceback.print_exc() + self.fini() + +class VoltageProbe(SmbiosBaseStructure): + smbios_structure_type = 26 + + def __init__(self, u, sm): + super(VoltageProbe, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('location_and_status', u.unpack_one("B")) + _status = { + 0b001: 'Other', + 0b010: 'Unknown', + 0b011: 'OK', + 0b100: 'Non-critical', + 0b101: 'Critical', + 0b110: 'Non-recoverable' + } + _location = { + 0b00001: 'Other', + 0b00010: 'Unknown', + 0b00011: 'Processor', + 0b00100: 'Disk', + 0b00101: 'Peripheral Bay', + 0b00110: 'System Management Module', + 0b00111: 'Motherboard', + 0b01000: 'Memory Module', + 0b01001: 'Processor Module', + 0b01010: 'Power Unit', + 0b01011: 'Add-in Card' + } + self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) + self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) + if self.length > 0x6: + self.add_field('max_value', u.unpack_one(" 0x8: + self.add_field('min_value', u.unpack_one(" 0xA: + self.add_field('resolution', u.unpack_one(" 0xC: + self.add_field('tolerance', u.unpack_one(" 0xE: + self.add_field('accuracy', u.unpack_one(" 0x10: + self.add_field('oem_defined', u.unpack_one(" 0x14: + self.add_field('nominal_value', u.unpack_one(" 0x4: + self.add_field('temperature_probe_handle', u.unpack_one(" 0x6: + self.add_field('device_type_and_status', u.unpack_one("B")) + _status = { + 0b001: 'Other', + 0b010: 'Unknown', + 0b011: 'OK', + 0b100: 'Non-critical', + 0b101: 'Critical', + 0b110: 'Non-recoverable' + } + _type = { + 0b00001: 'Other', + 0b00010: 'Unknown', + 0b00011: 'Fan', + 0b00100: 'Centrifugal Blower', + 0b00101: 'Chip Fan', + 0b00110: 'Cabinet Fan', + 0b00111: 'Power Supply Fan', + 0b01000: 'Heat Pipe', + 0b01001: 'Integrated Refrigeration', + 0b10000: 'Active Cooling', + 0b10001: 'Passive Cooling' + } + self.add_field('status', bitfields.getbits(self.device_type_and_status, 7, 5), unpack.format_table("device_type_and_status[7:5]={}", _status)) + self.add_field('device_type', bitfields.getbits(self.device_type_and_status, 4, 0), unpack.format_table("device_type_and_status[4:0]={}", _type)) + if self.length > 0x7: + self.add_field('cooling_unit_group', u.unpack_one("B")) + if self.length > 0x8: + self.add_field('OEM_defined', u.unpack_one(" 0xC: + self.add_field('nominal_speed', u.unpack_one(" 0xE: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + except: + self.decodeFailure = True + print "Error parsing CoolingDevice" + import traceback + traceback.print_exc() + self.fini() + +class TemperatureProbe(SmbiosBaseStructure): + smbios_structure_type = 28 + + def __init__(self, u, sm): + super(TemperatureProbe, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('location_and_status', u.unpack_one("B")) + _status = { + 0b001: 'Other', + 0b010: 'Unknown', + 0b011: 'OK', + 0b100: 'Non-critical', + 0b101: 'Critical', + 0b110: 'Non-recoverable' + } + _location = { + 0b00001: 'Other', + 0b00010: 'Unknown', + 0b00011: 'Processor', + 0b00100: 'Disk', + 0b00101: 'Peripheral Bay', + 0b00110: 'System Management Module', + 0b00111: 'Motherboard', + 0b01000: 'Memory Module', + 0b01001: 'Processor Module', + 0b01010: 'Power Unit', + 0b01011: 'Add-in Card', + 0b01100: 'Front Panel Board', + 0b01101: 'Back Panel Board', + 0b01110: 'Power System Board', + 0b01111: 'Drive Back Plane' + } + self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) + self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) + if self.length > 0x6: + self.add_field('maximum_value', u.unpack_one(" 0x8: + self.add_field('minimum_value', u.unpack_one(" 0xA: + self.add_field('resolution', u.unpack_one(" 0xC: + self.add_field('tolerance', u.unpack_one(" 0xE: + self.add_field('accuracy', u.unpack_one(" 0x10: + self.add_field('OEM_defined', u.unpack_one(" 0x14: + self.add_field('nominal_value', u.unpack_one(" 0x4: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('location_and_status', u.unpack_one("B")) + _status = { + 0b001: 'Other', + 0b010: 'Unknown', + 0b011: 'OK', + 0b100: 'Non-critical', + 0b101: 'Critical', + 0b110: 'Non-recoverable' + } + _location = { + 0b00001: 'Other', + 0b00010: 'Unknown', + 0b00011: 'Processor', + 0b00100: 'Disk', + 0b00101: 'Peripheral Bay', + 0b00110: 'System Management Module', + 0b00111: 'Motherboard', + 0b01000: 'Memory Module', + 0b01001: 'Processor Module', + 0b01010: 'Power Unit', + 0b01011: 'Add-in Card', + 0b01100: 'Front Panel Board', + 0b01101: 'Back Panel Board', + 0b01110: 'Power System Board', + 0b01111: 'Drive Back Plane' + } + self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) + self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) + if self.length > 0x6: + self.add_field('maximum_value', u.unpack_one(" 0x8: + self.add_field('minimum_value', u.unpack_one(" 0xA: + self.add_field('resolution', u.unpack_one(" 0xC: + self.add_field('tolerance', u.unpack_one(" 0xE: + self.add_field('accuracy', u.unpack_one(" 0x10: + self.add_field('OEM_defined', u.unpack_one(" 0x14: + self.add_field('nominal_value', u.unpack_one(" 0x4: + self.add_field('manufacturer_name', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('connections', u.unpack_one("B")) + self.add_field('outbound_connection_enabled', bool(bitfields.getbits(self.connections, 1)), "connections[1]={}") + self.add_field('inbound_connection_enabled', bool(bitfields.getbits(self.connections, 0)), "connections[0]={}") + except: + self.decodeFailure = True + print "Error parsing OutOfBandRemoteAccess" + import traceback + traceback.print_exc() + self.fini() + +class BootIntegrityServicesEntryPoint(SmbiosBaseStructure): + smbios_structure_type = 31 + +class SystemBootInformation(SmbiosBaseStructure): + smbios_structure_type = 32 + + def __init__(self, u, sm): + super(SystemBootInformation, self).__init__(u, sm) + u = self.u + try: + if self.length > 0xA: + u.skip(6) + _boot_status = { + 0: 'No errors detected', + 1: 'No bootable media', + 2: '"normal" operating system failed to load', + 3: 'Firmware-detected hardware failure, including "unknown" failure types', + 4: 'Operating system-detected hardware failure', + 5: 'User-requested boot, usually through a keystroke', + 6: 'System security violation', + 7: 'Previously-requested image', + 8: 'System watchdog timer expired, causing the system to reboot', + xrange(9,127): 'Reserved for future assignment', + xrange(128, 191): 'Vendor/OEM-specific implementations', + xrange(192, 255): 'Product-specific implementations' + } + self.add_field('boot_status', u.unpack_one("B"), unpack.format_table("{}", _boot_status)) + except: + self.decodeFailure = True + print "Error parsing SystemBootInformation" + import traceback + traceback.print_exc() + self.fini() + +class MemoryErrorInfo64Bit(SmbiosBaseStructure): + smbios_structure_type = 33 + + def __init__(self, u, sm): + super(MemoryErrorInfo64Bit, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + _error_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'OK', + 0x04: 'Bad read', + 0x05: 'Parity error', + 0x06: 'Single-bit error', + 0x07: 'Double-bit error', + 0x08: 'Multi-bit error', + 0x09: 'Nibble error', + 0x0A: 'Checksum error', + 0x0B: 'CRC error', + 0x0C: 'Corrected single-bit error', + 0x0D: 'Corrected error', + 0x0E: 'Uncorrectable error' + } + self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types)) + if self.length > 0x5: + _error_granularity_field = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Device level', + 0x04: 'Memory partition level' + } + self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field)) + if self.length > 0x6: + _error_operation_field = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Read', + 0x04: 'Write', + 0x05: 'Partial write' + } + self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field)) + if self.length > 0x7: + self.add_field('vendor_syndrome', u.unpack_one(" 0xB: + self.add_field('memory_array_error_address', u.unpack_one(" 0xF: + self.add_field('device_error_address', u.unpack_one(" 0x13: + self.add_field('error_resolution', u.unpack_one(" 0x4: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + _type = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'National Semiconductor LM75', + 0x04: 'National Semiconductor LM78', + 0x05: 'National Semiconductor LM79', + 0x06: 'National Semiconductor LM80', + 0x07: 'National Semiconductor LM81', + 0x08: 'Analog Devices ADM9240', + 0x09: 'Dallas Semiconductor DS1780', + 0x0A: 'Maxim 1617', + 0x0B: 'Genesys GL518SM', + 0x0C: 'Winbond W83781D', + 0x0D: 'Holtek HT82H791' + } + self.add_field('device_type', u.unpack_one("B"), unpack.format_table("{}", _type)) + if self.length > 0x6: + self.add_field('address', u.unpack_one(" 0xA: + _address_type = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'I/O Port', + 0x04: 'Memory', + 0x05: 'SM Bus' + } + self.add_field('address_type', u.unpack_one("B"), unpack.format_table("{}", _address_type)) + except: + self.decodeFailure = True + print "Error parsing ManagementDevice" + import traceback + traceback.print_exc() + self.fini() + +class ManagementDeviceComponent(SmbiosBaseStructure): + smbios_structure_type = 35 + + def __init__(self, u, sm): + super(ManagementDeviceComponent, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('management_device_handle', u.unpack_one(" 0x7: + self.add_field('component_handle', u.unpack_one(" 0x9: + self.add_field('threshold_handle', u.unpack_one(" 0x4: + self.add_field('lower_threshold_noncritical', u.unpack_one(" 0x6: + self.add_field('upper_threshold_noncritical', u.unpack_one(" 0x8: + self.add_field('lower_threshold_critical', u.unpack_one(" 0xA: + self.add_field('upper_threshold_critical', u.unpack_one(" 0xC: + self.add_field('lower_threshold_nonrecoverable', u.unpack_one(" 0xE: + self.add_field('upper_threshold_nonrecoverable', u.unpack_one(" 0x4: + _channel_type = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'RamBus', + 0x04: 'SyncLink' + } + self.add_field('channel_type', u.unpack_one("B"), unpack.format_table("{}", _channel_type)) + if self.length > 0x6: + self.add_field('max_channel_load', u.unpack_one("B")) + if self.length > 0x8: + self.add_field('memory_device_count', u.unpack_one("B")) + if self.length > 0xA: + self.add_field('memory_device_load', u.unpack_one("B")) + if self.length > 0xC: + self.add_field('memory_device_handle', u.unpack_one(" 0x4: + self.add_field('power_unit_group', u.unpack_one("B")) + if self.length > 0x5: + self.add_field('location', u.unpack_one("B"), self.fmtstr) + if self.length > 0x6: + self.add_field('device_name', u.unpack_one("B"), self.fmtstr) + if self.length > 0x7: + self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) + if self.length > 0x8: + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x9: + self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) + if self.length > 0xA: + self.add_field('model_part_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0xB: + self.add_field('revision_level', u.unpack_one("B"), self.fmtstr) + if self.length > 0xC: + self.add_field('max_power_capacity', u.unpack_one(" 0xE: + self.add_field('power_supply_characteristics', u.unpack_one(" 0x10: + self.add_field('input_voltage_probe_handle', u.unpack_one(" 0x12: + self.add_field('cooling_device_handle', u.unpack_one(" 0x14: + self.add_field('input_current_probe_handle', u.unpack_one(" 0x4: + self.add_field('num_additional_information_entries', u.unpack_one("B")) + if self.length > 0x5: + self.add_field('additional_information_entry_length', u.unpack_one("B")) + self.add_field('referenced_handle', u.unpack_one(" 0x4: + self.add_field('reference_designation', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('device_type', u.unpack_one("B")) + self.add_field('device_enabled', bool(bitfields.getbits(self.device_type, 7)), "device_type[7]={}") + _device_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Video', + 0x04: 'SCSI Controller', + 0x05: 'Ethernet', + 0x06: 'Token Ring', + 0x07: 'Sound', + 0x08: 'PATA Controller', + 0x09: 'SATA Controller', + 0x0A: 'SAS Controller' + } + self.add_field('type_of_device', bitfields.getbits(self.device_type, 6, 0), unpack.format_table("device_type[6:0]={}", _device_types)) + if self.length > 0x6: + self.add_field('device_type_instance', u.unpack_one("B")) + if self.length > 0x7: + self.add_field('segment_group_number', u.unpack_one(" 0x9: + self.add_field('bus_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0xA: + self.add_field('device_and_function_number', u.unpack_one("B")) + self.add_field('device_number', bitfields.getbits(self.device_type, 7, 3), "device_and_function_number[7:3]={}") + self.add_field('function_number', bitfields.getbits(self.device_type, 2, 0), "device_and_function_number[2:0]={}") + except: + self.decodeFailure = True + print "Error parsing OnboardDevicesExtendedInformation" + import traceback + traceback.print_exc() + self.fini() + +class ManagementControllerHostInterface(SmbiosBaseStructure): + smbios_structure_type = 42 + + def __init__(self, u, sm): + super(ManagementControllerHostInterface, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + _interface_types = { + 0x00: 'Reserved', + 0x01: 'Reserved', + 0x02: 'KCS: Keyboard Controller Style', + 0x03: '8250 UART Register Compatible', + 0x04: '16450 UART Register Compatible', + 0x05: '16550/16550A UART Register Compatible', + 0x06: '16650/16650A UART Register Compatible', + 0x07: '16750/16750A UART Register Compatible', + 0x08: '16850/16850A UART Register Compatible', + 0xF0: 'OEM' + } + self.add_field('interface_type', u.unpack_one("B"), unpack.format_table("{}", _interface_types)) + if self.length > 0x5: + self.add_field('mc_host_interface_data', u.unpack_rest(), self.fmtstr) + except: + self.decodeFailure = True + print "Error parsing ManagementControllerHostInterface" + import traceback + traceback.print_exc() + self.fini() + +class Inactive(SmbiosBaseStructure): + smbios_structure_type = 126 + + def __init__(self, u, sm): + super(Inactive, self).__init__(u, sm) + self.fini() + +class EndOfTable(SmbiosBaseStructure): + smbios_structure_type = 127 + + def __init__(self, u, sm): + super(EndOfTable, self).__init__(u, sm) + self.fini() + +class SmbiosStructureUnknown(SmbiosBaseStructure): + smbios_structure_type = None + + def __init__(self, u, sm): + super(SmbiosStructureUnknown, self).__init__(u, sm) + self.fini() + +_smbios_structures = [ + BIOSInformation, + SystemInformation, + BaseboardInformation, + SystemEnclosure, + ProcessorInformation, + MemoryControllerInformation, + MemoryModuleInformation, + CacheInformation, + PortConnectorInfo, + SystemSlots, + OnBoardDevicesInformation, + OEMStrings, + SystemConfigOptions, + BIOSLanguageInformation, + GroupAssociations, + SystemEventLog, + PhysicalMemoryArray, + MemoryDevice, + MemoryErrorInfo32Bit, + MemoryArrayMappedAddress, + MemoryDeviceMappedAddress, + BuiltInPointingDevice, + PortableBattery, + SystemReset, + HardwareSecurity, + SystemPowerControls, + VoltageProbe, + CoolingDevice, + TemperatureProbe, + ElectricalCurrentProbe, + OutOfBandRemoteAccess, + BootIntegrityServicesEntryPoint, + SystemBootInformation, + MemoryErrorInfo64Bit, + ManagementDevice, + ManagementDeviceComponent, + ManagementDeviceThresholdData, + MemoryChannel, + IPMIDeviceInformation, + SystemPowerSupply, + AdditionalInformation, + OnboardDevicesExtendedInformation, + ManagementControllerHostInterface, + Inactive, + EndOfTable, + SmbiosStructureUnknown, # Must always come last +] + +def log_smbios_info(): + with redirect.logonly(): + try: + sm = SMBIOS() + print + if sm is None: + print "No SMBIOS structures found" + return + output = {} + known_types = (0, 1) + for sm_struct in sm.structures: + if sm_struct.type in known_types: + output.setdefault(sm_struct.type, []).append(sm_struct) + if len(output) == len(known_types): + break + + print "SMBIOS information:" + for key in sorted(known_types): + for s in output.get(key, ["No structure of type {} found".format(key)]): + print ttypager._wrap("{}: {}".format(key, s)) + except: + print "Error parsing SMBIOS information:" + import traceback + traceback.print_exc() + +def dump_raw(): + try: + sm = SMBIOS() + if sm: + s = "SMBIOS -- Raw bytes and structure decode.\n\n" + + s += str(sm.header) + '\n' + s += bits.dumpmem(sm._header_memory) + '\n' + + s += "Raw bytes for the SMBIOS structures\n" + s += bits.dumpmem(sm._structure_memory) + '\n' + + for sm_struct in sm.structures: + s += str(sm_struct) + '\n' + s += bits.dumpmem(sm_struct.raw_data) + + s += "Strings:\n" + for n in range(1, len(getattr(sm_struct, "strings", [])) + 1): + s += str(sm_struct.fmtstr(n)) + '\n' + s += bits.dumpmem(sm_struct.raw_strings) + '\n' + else: + s = "No SMBIOS structures found" + ttypager.ttypager_wrap(s, indent=False) + except: + print "Error parsing SMBIOS information:" + import traceback + traceback.print_exc() + +def dump(): + try: + sm = SMBIOS() + if sm: + s = str(sm) + else: + s = "No SMBIOS structures found" + ttypager.ttypager_wrap(s, indent=False) + except: + print "Error parsing SMBIOS information:" + import traceback + traceback.print_exc() + +def annex_a_conformance(): + try: + sm = SMBIOS() + + # check: 1. The table anchor string "_SM_" is present in the address range 0xF0000 to 0xFFFFF on a 16-byte bound + + def table_entry_point_verification(): + ''' Verify table entry-point''' + if (sm.header.length < 0x1F): + print "Failure: Table entry-point - The entry-point Length must be at least 0x1F" + if sm.header.checksum != 0: + print "Failure: Table entry-point - The entry-point checksum must evaluate to 0" + if ((sm.header.major_version < 2) and (sm.header.minor_version < 4)): + print "Failure: Table entry-point - SMBIOS version must be at least 2.4" + if (sm.header.intermediate_anchor_string == '_DMI_'): + print "Failure: Table entry-point - The Intermediate Anchor String must be '_DMI_'" + if (sm.header.intermediate_checksum != 0): + print "Failure: Table entry-point - The Intermediate checksum must evaluate to 0" + + #check: 3. The structure-table is traversable and conforms to the entry-point specifications: + + def req_structures(): + '''Checks for required structures and corresponding data''' + types_present = [sm.structures[x].smbios_structure_type for x in range(len(sm.structures))] + required = [0, 1, 4, 7, 9, 16, 17, 19, 31, 32] + for s in required: + if s not in set(types_present): + print "Failure: Type {} required but not found".format(s) + + else: + if s == 0: + if types_present.count(s) > 1: + print "Failure: Type {} - One and only one structure of this type must be present.".format(s) + if sm.structure_type(s).length < 0x18: + print "Failure: Type {} - The structure Length field must be at least 0x18".format(s) + if sm.structure_type(s).version is None: + print "Failure: Type {} - BIOS Version string must be present and non-null.".format(s) + if sm.structure_type(s).release_date is None: + print "Failure: Type {} - BIOS Release Date string must be present, non-null, and include a 4-digit year".format(s) + if bitfields.getbits(sm.structure_type(s).characteristics, 3, 0) != 0 or bitfields.getbits(sm.structure_type(s).characteristics, 31, 4) == 0: + print "Failure: Type {} - BIOS Characteristics: bits 3:0 must all be 0, and at least one of bits 31:4 must be set to 1.".format(s) + elif s == 1: + if types_present.count(s) > 1: + print "Failure: Type {} - One and only one structure of this type must be present.".format(s) + if sm.structure_type(s).length < 0x1B: + print "Failure: Type {} - The structure Length field must be at least 0x1B".format(s) + if sm.structure_type(s).manufacturer == None: + print "Failure: Type {} - Manufacturer string must be present and non-null.".format(s) + if sm.structure_type(s).product_name == None: + print "Failure: Type {} - Product Name string must be present and non-null".format(s) + if sm.structure_type(s).uuid == '00000000 00000000' and sm.structure_type(s).uuid == 'FFFFFFFF FFFFFFFF': + print "Failure: Type {} - UUID field must be neither 00000000 00000000 nor FFFFFFFF FFFFFFFF.".format(s) + if sm.structure_type(s).wakeup_type == 00 and sm.structure_type(s).wakeup_type == 0x02: + print "Failure: Type {} - Wake-up Type field must be neither 00h (Reserved) nor 02h (Unknown).".format(s) + # continue for remaining required types + + # check remaining conformance guidelines + + table_entry_point_verification() + req_structures() + except: + print "Error checking ANNEX A conformance guidelines" + import traceback + traceback.print_exc() diff --git a/tests/pytest/acpi-bits/bits-tests/testacpi.py b/tests/pytest/acpi-bits/bits-tests/testacpi.py new file mode 100644 index 0000000000..9ec452f330 --- /dev/null +++ b/tests/pytest/acpi-bits/bits-tests/testacpi.py @@ -0,0 +1,283 @@ +# Copyright (c) 2015, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Intel Corporation nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests for ACPI""" + +import acpi +import bits +import bits.mwait +import struct +import testutil +import testsuite +import time + +def register_tests(): + testsuite.add_test("ACPI _MAT (Multiple APIC Table Entry) under Processor objects", test_mat, submenu="ACPI Tests") + testsuite.add_test("ACPI _PSS (Pstate) table conformance tests", test_pss, submenu="ACPI Tests") + testsuite.add_test("ACPI _PSS (Pstate) runtime tests", test_pstates, submenu="ACPI Tests") + testsuite.add_test("ACPI DSDT (Differentiated System Description Table)", test_dsdt, submenu="ACPI Tests") + testsuite.add_test("ACPI FACP (Fixed ACPI Description Table)", test_facp, submenu="ACPI Tests") + testsuite.add_test("ACPI HPET (High Precision Event Timer Table)", test_hpet, submenu="ACPI Tests") + testsuite.add_test("ACPI MADT (Multiple APIC Description Table)", test_apic, submenu="ACPI Tests") + testsuite.add_test("ACPI MPST (Memory Power State Table)", test_mpst, submenu="ACPI Tests") + testsuite.add_test("ACPI RSDP (Root System Description Pointer Structure)", test_rsdp, submenu="ACPI Tests") + testsuite.add_test("ACPI XSDT (Extended System Description Table)", test_xsdt, submenu="ACPI Tests") + +def test_mat(): + cpupaths = acpi.get_cpupaths() + apic = acpi.parse_apic() + procid_apicid = apic.procid_apicid + uid_x2apicid = apic.uid_x2apicid + for cpupath in cpupaths: + # Find the ProcId defined by the processor object + processor = acpi.evaluate(cpupath) + # Find the UID defined by the processor object's _UID method + uid = acpi.evaluate(cpupath + "._UID") + mat_buffer = acpi.evaluate(cpupath + "._MAT") + if mat_buffer is None: + continue + # Process each _MAT subtable + mat = acpi._MAT(mat_buffer) + for index, subtable in enumerate(mat): + if subtable.subtype == acpi.MADT_TYPE_LOCAL_APIC: + if subtable.flags.bits.enabled: + testsuite.test("{} Processor declaration ProcId = _MAT ProcId".format(cpupath), processor.ProcId == subtable.proc_id) + testsuite.print_detail("{} ProcId ({:#02x}) != _MAT ProcId ({:#02x})".format(cpupath, processor.ProcId, subtable.proc_id)) + testsuite.print_detail("Processor Declaration: {}".format(processor)) + testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) + if testsuite.test("{} with local APIC in _MAT has local APIC in MADT".format(cpupath), processor.ProcId in procid_apicid): + testsuite.test("{} ApicId derived using Processor declaration ProcId = _MAT ApicId".format(cpupath), procid_apicid[processor.ProcId] == subtable.apic_id) + testsuite.print_detail("{} ApicId derived from MADT ({:#02x}) != _MAT ApicId ({:#02x})".format(cpupath, procid_apicid[processor.ProcId], subtable.apic_id)) + testsuite.print_detail("Processor Declaration: {}".format(processor)) + testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) + if subtable.subtype == acpi.MADT_TYPE_LOCAL_X2APIC: + if subtable.flags.bits.enabled: + if testsuite.test("{} with x2Apic in _MAT has _UID".format(cpupath), uid is not None): + testsuite.test("{}._UID = _MAT UID".format(cpupath), uid == subtable.uid) + testsuite.print_detail("{}._UID ({:#x}) != _MAT UID ({:#x})".format(cpupath, uid, subtable.uid)) + testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) + if testsuite.test("{} with _MAT x2Apic has x2Apic in MADT".format(cpupath), subtable.uid in uid_x2apicid): + testsuite.test("{} x2ApicId derived from MADT using UID = _MAT x2ApicId".format(cpupath), uid_x2apicid[subtable.uid] == subtable.x2apicid) + testsuite.print_detail("{} x2ApicId derived from MADT ({:#02x}) != _MAT x2ApicId ({:#02x})".format(cpupath, uid_x2apicid[subtable.uid], subtable.x2apicid)) + testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) + +def test_pss(): + uniques = acpi.parse_cpu_method("_PSS") + # We special-case None here to avoid a double-failure for CPUs without a _PSS + testsuite.test("_PSS must be identical for all CPUs", len(uniques) <= 1 or (len(uniques) == 2 and None in uniques)) + for pss, cpupaths in uniques.iteritems(): + if not testsuite.test("_PSS must exist", pss is not None): + testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) + testsuite.print_detail('No _PSS exists') + continue + + if not testsuite.test("_PSS must not be empty", pss.pstates): + testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) + testsuite.print_detail('_PSS is empty') + continue + + testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) + for index, pstate in enumerate(pss.pstates): + testsuite.print_detail("P[{}]: {}".format(index, pstate)) + + testsuite.test("_PSS must contain at most 16 Pstates", len(pss.pstates) <= 16) + testsuite.test("_PSS must have no duplicate Pstates", len(pss.pstates) == len(set(pss.pstates))) + + frequencies = [p.core_frequency for p in pss.pstates] + testsuite.test("_PSS must list Pstates in descending order of frequency", frequencies == sorted(frequencies, reverse=True)) + + testsuite.test("_PSS must have Pstates with no duplicate frequencies", len(frequencies) == len(set(frequencies))) + + dissipations = [p.power for p in pss.pstates] + testsuite.test("_PSS must list Pstates in descending order of power dissipation", dissipations == sorted(dissipations, reverse=True)) + +def test_pstates(): + """Execute and verify frequency for each Pstate in the _PSS""" + IA32_PERF_CTL = 0x199 + with bits.mwait.use_hint(), bits.preserve_msr(IA32_PERF_CTL): + cpupath_procid = acpi.find_procid() + cpupath_uid = acpi.find_uid() + apic = acpi.parse_apic() + procid_apicid = apic.procid_apicid + uid_x2apicid = apic.uid_x2apicid + def cpupath_apicid(cpupath): + if procid_apicid is not None: + procid = cpupath_procid.get(cpupath, None) + if procid is not None: + apicid = procid_apicid.get(procid, None) + if apicid is not None: + return apicid + if uid_x2apicid is not None: + uid = cpupath_uid.get(cpupath, None) + if uid is not None: + apicid = uid_x2apicid.get(uid, None) + if apicid is not None: + return apicid + return bits.cpus()[0] + + bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000 + + uniques = acpi.parse_cpu_method("_PSS") + for pss, cpupaths in uniques.iteritems(): + if not testsuite.test("_PSS must exist", pss is not None): + testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) + testsuite.print_detail('No _PSS exists') + continue + + for n, pstate in enumerate(pss.pstates): + for cpupath in cpupaths: + apicid = cpupath_apicid(cpupath) + if apicid is None: + print 'Failed to find apicid for cpupath {}'.format(cpupath) + continue + bits.wrmsr(apicid, IA32_PERF_CTL, pstate.control) + + # Detecting Turbo frequency requires at least 2 pstates + # since turbo frequency = max non-turbo frequency + 1 + turbo = False + if len(pss.pstates) >= 2: + turbo = (n == 0 and pstate.core_frequency == (pss.pstates[1].core_frequency + 1)) + if turbo: + # Needs to busywait, not sleep + start = time.time() + while (time.time() - start < 2): + pass + + for duration in (0.1, 1.0): + frequency_data = bits.cpu_frequency(duration) + # Abort the test if no cpu frequency is not available + if frequency_data is None: + continue + aperf = frequency_data[1] + aperf = testutil.adjust_to_nearest(aperf, bclk/2) + aperf = int(aperf / 1000000) + if turbo: + if aperf >= pstate.core_frequency: + break + else: + if aperf == pstate.core_frequency: + break + + if turbo: + testsuite.test("P{}: Turbo measured frequency {} >= expected {} MHz".format(n, aperf, pstate.core_frequency), aperf >= pstate.core_frequency) + else: + testsuite.test("P{}: measured frequency {} MHz == expected {} MHz".format(n, aperf, pstate.core_frequency), aperf == pstate.core_frequency) + +def test_psd_thread_scope(): + uniques = acpi.parse_cpu_method("_PSD") + if not testsuite.test("_PSD (P-State Dependency) must exist for each processor", None not in uniques): + testsuite.print_detail(acpi.factor_commonprefix(uniques[None])) + testsuite.print_detail('No _PSD exists') + return + unique_num_dependencies = {} + unique_num_entries = {} + unique_revision = {} + unique_domain = {} + unique_coordination_type = {} + unique_num_processors = {} + for value, cpupaths in uniques.iteritems(): + unique_num_dependencies.setdefault(len(value.dependencies), []).extend(cpupaths) + unique_num_entries.setdefault(value.dependencies[0].num_entries, []).extend(cpupaths) + unique_revision.setdefault(value.dependencies[0].revision, []).extend(cpupaths) + unique_domain.setdefault(value.dependencies[0].domain, []).extend(cpupaths) + unique_coordination_type.setdefault(value.dependencies[0].coordination_type, []).extend(cpupaths) + unique_num_processors.setdefault(value.dependencies[0].num_processors, []).extend(cpupaths) + def detail(d, fmt): + for value, cpupaths in sorted(d.iteritems(), key=(lambda (k,v): v)): + testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) + testsuite.print_detail(fmt.format(value)) + + testsuite.test('Dependency count for each processor must be 1', unique_num_dependencies.keys() == [1]) + detail(unique_num_dependencies, 'Dependency count for each processor = {} (Expected 1)') + testsuite.test('_PSD.num_entries must be 5', unique_num_entries.keys() == [5]) + detail(unique_num_entries, 'num_entries = {} (Expected 5)') + testsuite.test('_PSD.revision must be 0', unique_revision.keys() == [0]) + detail(unique_revision, 'revision = {}') + testsuite.test('_PSD.coordination_type must be 0xFE (HW_ALL)', unique_coordination_type.keys() == [0xfe]) + detail(unique_coordination_type, 'coordination_type = {:#x} (Expected 0xFE HW_ALL)') + testsuite.test('_PSD.domain must be unique (thread-scoped) for each processor', len(unique_domain) == len(acpi.get_cpupaths())) + detail(unique_domain, 'domain = {:#x} (Expected a unique value for each processor)') + testsuite.test('_PSD.num_processors must be 1', unique_num_processors.keys() == [1]) + detail(unique_num_processors, 'num_processors = {} (Expected 1)') + +def test_table_checksum(data): + csum = sum(ord(c) for c in data) % 0x100 + testsuite.test('ACPI table cumulative checksum must equal 0', csum == 0) + testsuite.print_detail("Cumulative checksum = {} (Expected 0)".format(csum)) + +def test_apic(): + data = acpi.get_table("APIC") + if data is None: + return + test_table_checksum(data) + apic = acpi.parse_apic() + +def test_dsdt(): + data = acpi.get_table("DSDT") + if data is None: + return + test_table_checksum(data) + +def test_facp(): + data = acpi.get_table("FACP") + if data is None: + return + test_table_checksum(data) + facp = acpi.parse_facp() + +def test_hpet(): + data = acpi.get_table("HPET") + if data is None: + return + test_table_checksum(data) + hpet = acpi.parse_hpet() + +def test_mpst(): + data = acpi.get_table("MPST") + if data is None: + return + test_table_checksum(data) + mpst = acpi.MPST(data) + +def test_rsdp(): + data = acpi.get_table("RSD PTR ") + if data is None: + return + + # Checksum the first 20 bytes per ACPI 1.0 + csum = sum(ord(c) for c in data[:20]) % 0x100 + testsuite.test('ACPI 1.0 table first 20 bytes cummulative checksum must equal 0', csum == 0) + testsuite.print_detail("Cummulative checksum = {} (Expected 0)".format(csum)) + + test_table_checksum(data) + rsdp = acpi.parse_rsdp() + +def test_xsdt(): + data = acpi.get_table("XSDT") + if data is None: + return + test_table_checksum(data) + xsdt = acpi.parse_xsdt() diff --git a/tests/pytest/acpi-bits/bits-tests/testcpuid.py b/tests/pytest/acpi-bits/bits-tests/testcpuid.py new file mode 100644 index 0000000000..ac55d912e1 --- /dev/null +++ b/tests/pytest/acpi-bits/bits-tests/testcpuid.py @@ -0,0 +1,83 @@ +# Copyright (c) 2012, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Intel Corporation nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests and helpers for CPUID.""" + +import bits +import testsuite +import testutil + +def cpuid_helper(function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0): + if index is None: + index = 0 + indexdesc = "" + else: + indexdesc = " index {0:#x}".format(index) + + def find_mask(m): + if m == ~0: + return mask + return m + masks = map(find_mask, [eax_mask, ebx_mask, ecx_mask, edx_mask]) + + uniques = {} + for cpu in bits.cpus(): + regs = bits.cpuid_result(*[(r >> shift) & m for r, m in zip(bits.cpuid(cpu, function, index), masks)]) + uniques.setdefault(regs, []).append(cpu) + + desc = ["CPUID function {:#x}{}".format(function, indexdesc)] + + if shift != 0: + desc.append("Register values have been shifted by {}".format(shift)) + if mask != ~0 or eax_mask != ~0 or ebx_mask != ~0 or ecx_mask != ~0 or edx_mask != ~0: + desc.append("Register values have been masked:") + shifted_masks = bits.cpuid_result(*[m << shift for m in masks]) + desc.append("Masks: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**shifted_masks._asdict())) + + if len(uniques) > 1: + regvalues = zip(*uniques.iterkeys()) + common_masks = bits.cpuid_result(*map(testutil.find_common_mask, regvalues)) + common_values = bits.cpuid_result(*[v[0] & m for v, m in zip(regvalues, common_masks)]) + desc.append('Register values are not unique across all logical processors') + desc.append("Common bits: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**common_values._asdict())) + desc.append("Mask of common bits: {eax:#010x} {ebx:#010x} {ecx:#010x} {edx:#010x}".format(**common_masks._asdict())) + + for regs in sorted(uniques.iterkeys()): + cpus = uniques[regs] + desc.append("Register value: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**regs._asdict())) + desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus))) + + return uniques, desc + +def test_cpuid_consistency(text, function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0): + uniques, desc = cpuid_helper(function, index, shift, mask, eax_mask, ebx_mask, ecx_mask, edx_mask) + desc[0] += " Consistency Check" + if text: + desc.insert(0, text) + status = testsuite.test(desc[0], len(uniques) == 1) + for line in desc[1:]: + testsuite.print_detail(line) + return status From patchwork Sun Jul 10 17:00:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ani Sinha X-Patchwork-Id: 12912582 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 823F9C43334 for ; Sun, 10 Jul 2022 17:04:22 +0000 (UTC) Received: from localhost ([::1]:36042 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oAaM1-0000fj-GS for qemu-devel@archiver.kernel.org; Sun, 10 Jul 2022 13:04:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53828) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oAaJ4-0006A8-Gx for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:18 -0400 Received: from mail-pf1-x433.google.com ([2607:f8b0:4864:20::433]:35359) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oAaJ2-0003M4-Su for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:18 -0400 Received: by mail-pf1-x433.google.com with SMTP id x184so3021752pfx.2 for ; Sun, 10 Jul 2022 10:01:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anisinha-ca.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8xI127TuMpWagqt4gaMUCdmrPt0g4XZZcxZXIgy9RrI=; b=dAfXHOc8Bi/kRYU8m9b2zHwY3kjrvfBARNOentwll5yTdqW5Wj5ZL0WfBDnor1Mjkl f5+IVBJgj7OGgsfH2f3eIa1iHDuodKL8GiBB7HZoFp4aswkHwPzKdW1/21k5F4K74riv NPyBtXun3wsDRG6zvhwdesL4tebfYRIYHJZmPJUJLxEufaM+/+F/Luv45OpVyk/eqWhM 3JY2qRer9j8jNa2GCZCUYiHxkRxf1B1daxihkSXJRiUOR4Yeigx+64YuBNICYIp/vs+C LHqFd1pkkW69K+miFusywmX2iJuPeYi/Taxtg5bMuTW9yAHQvlTgMd5Qk8a3aTdyhf3Y WKDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8xI127TuMpWagqt4gaMUCdmrPt0g4XZZcxZXIgy9RrI=; b=ma8erWcgn78NyPbf3ADB1H/sWqMqSjLBvKbYXj7YnPdwrbZJ17BtFLHXjXoNcyE+EL czHsH/d5gAaZDy50CZlJxXTQtbxyVhTTKwdgKC4Th9XV9771FXPxOhiw4AdT8jrKcNBo qGk91Sce7z4eNkAhY6nGVVXWSNLD0OJGvf7+8oiAMOlSyHXfa+xKChlhjXcE5fVMw3x3 z8eWtcUMluPO87MTcNhQshLYpiVayT9ltnNZyFcTGdGXRFFsP+i++EoegG/idapI87Dm 30jBTHqT/gi4yV3JPKSy4rW5hyA+kRNibzE4olrhq0Xywh0KxWmUoSb+DGpw7vpvzIr9 p+7g== X-Gm-Message-State: AJIora/lZL5ksuzvFIYQVQzon4GeNUVzOUa0Yk8m9KNPxnD7oZr3ZjCT S7+HKi7vJK3ZO9YTPgztFM14uH2K1xM1WsrG X-Google-Smtp-Source: AGRyM1uGBY86Oq6rpSMy2hd7UdaaLxzA/G9pjmt9je/GZjkkL2YlZtpFEBdmPTsIoo98DuiBBNh+Uw== X-Received: by 2002:a05:6a00:22d6:b0:525:74b3:d020 with SMTP id f22-20020a056a0022d600b0052574b3d020mr14130560pfj.80.1657472475361; Sun, 10 Jul 2022 10:01:15 -0700 (PDT) Received: from anisinha-lenovo.ba.nuagenetworks.net ([115.96.107.107]) by smtp.googlemail.com with ESMTPSA id u14-20020a17090341ce00b0016c19417495sm2930596ple.239.2022.07.10.10.01.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jul 2022 10:01:14 -0700 (PDT) From: Ani Sinha To: qemu-devel@nongnu.org Cc: thuth@redhat.com, peter.maydell@linaro.org, berrange@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, imammedo@redhat.com, mst@redhat.com, Ani Sinha Subject: [PATCH v2 02/11] acpi/tests/bits: add SPDX license identifiers for bios bits tests Date: Sun, 10 Jul 2022 22:30:05 +0530 Message-Id: <20220710170014.1673480-3-ani@anisinha.ca> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710170014.1673480-1-ani@anisinha.ca> References: <20220710170014.1673480-1-ani@anisinha.ca> MIME-Version: 1.0 Received-SPF: none client-ip=2607:f8b0:4864:20::433; envelope-from=ani@anisinha.ca; helo=mail-pf1-x433.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added the SPDX license identifiers based on the following output from the licensee tool for bios bits: $ licensee detect bits/ License: NOASSERTION Matched files: COPYING COPYING: Content hash: 7a1fdfa894728ea69588977442c92073aad69e50 License: NOASSERTION Closest non-matching licenses: BSD-3-Clause-Clear similarity: 85.82% BSD-4-Clause similarity: 83.69% BSD-3-Clause similarity: 77.27% Signed-off-by: Ani Sinha --- tests/pytest/acpi-bits/bits-tests/smbios.py | 2 ++ tests/pytest/acpi-bits/bits-tests/testacpi.py | 2 ++ tests/pytest/acpi-bits/bits-tests/testcpuid.py | 2 ++ 3 files changed, 6 insertions(+) diff --git a/tests/pytest/acpi-bits/bits-tests/smbios.py b/tests/pytest/acpi-bits/bits-tests/smbios.py index 9667d0542c..05ee8661c2 100644 --- a/tests/pytest/acpi-bits/bits-tests/smbios.py +++ b/tests/pytest/acpi-bits/bits-tests/smbios.py @@ -1,6 +1,8 @@ # Copyright (c) 2015, Intel Corporation # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause-Clear +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/tests/pytest/acpi-bits/bits-tests/testacpi.py b/tests/pytest/acpi-bits/bits-tests/testacpi.py index 9ec452f330..8e6bb3bbc6 100644 --- a/tests/pytest/acpi-bits/bits-tests/testacpi.py +++ b/tests/pytest/acpi-bits/bits-tests/testacpi.py @@ -1,6 +1,8 @@ # Copyright (c) 2015, Intel Corporation # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause-Clear +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/tests/pytest/acpi-bits/bits-tests/testcpuid.py b/tests/pytest/acpi-bits/bits-tests/testcpuid.py index ac55d912e1..94cc149556 100644 --- a/tests/pytest/acpi-bits/bits-tests/testcpuid.py +++ b/tests/pytest/acpi-bits/bits-tests/testcpuid.py @@ -1,6 +1,8 @@ # Copyright (c) 2012, Intel Corporation # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause-Clear +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # From patchwork Sun Jul 10 17:00:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ani Sinha X-Patchwork-Id: 12912586 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2D5C4C43334 for ; Sun, 10 Jul 2022 17:09:00 +0000 (UTC) Received: from localhost ([::1]:47956 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oAaQV-0000T9-4F for qemu-devel@archiver.kernel.org; Sun, 10 Jul 2022 13:08:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53850) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oAaJ7-0006K9-Ut for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:22 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]:41718) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oAaJ6-0003Mt-EM for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:21 -0400 Received: by mail-pj1-x102d.google.com with SMTP id o31-20020a17090a0a2200b001ef7bd037bbso2984428pjo.0 for ; Sun, 10 Jul 2022 10:01:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anisinha-ca.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Nrjm47IQdvon1pR17nAJV0WFKA1GxTG6ogwhpiImgUE=; b=L6kLDXiH+dT1R7p916zkGnLLfXWEvgvMMg5CzaocefQOw9IjmWK5YujSIKXf9Tm5gb XJ4nvF1VJfLFoCeskKhCVN9P06k1sBDR2VhrHGexMs9sHBNleT/H/bj8vXrWsKwIE3WU NQDhISl7ifNZa0jsyOWUadm+5Ujd8lP1r1pJuI+RvRTeUYuxaWE3DvCxqdpwdTxixnyV jMRfYHBjdplMOW5dsQz1Ldqea2sJEHyCb+Ylo2foU2deoevEvmgvKuIFODmI+t2zqXtD cRQvD3JxdQCnTOZB10YoMCXSJpKDgGLbOlkDcPuBdeN3sFlZcvR8n79OMBtQwEtPXyLK dZjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Nrjm47IQdvon1pR17nAJV0WFKA1GxTG6ogwhpiImgUE=; b=vQMPcdwkjYez12jwA0w99t/baS1xkZR14YG6oTJzwXNQWE5rXTatbHac3v2FmXupDk cQcsJdJoy/kuU7humCOB/YRK24Sz5nTe/QJDVjVRPM4qoeVVF0CT/vD05xr26LwUKpqA e64OKRILg9P2OnVAXRQ2Is2LRxvspXssYjn1CKg87jOJKkZxHSse9GeA16qCjbX2IW5z QO/Vsy+n8yqG4q+GafWNzf/FNDYlA25cdbh9921AMsk8/6Ur0wPOUWHPZnLnzfZUeOV/ Q7OymxWLR4C1vw2HaLp3thQcc11EMgQjVWh/5Lg67/L6RfOLyeWdfK0NB1Ju67IGiasv q1sw== X-Gm-Message-State: AJIora99tvQzKEdxTjQQCRfMaUzerlaao1jn3Q1In6/cfgJyYOxxZE05 mj81JIqyLzEQyMqlfgJcT/UXzXENvAq+eyxq X-Google-Smtp-Source: AGRyM1tRojv9hb+DJ6p3bnBVdMAgl2LCKy7p2HmsvWm7nMf9FKwGQ2A+CUzhHuWzJ6RR9RtUblYX8w== X-Received: by 2002:a17:90b:268f:b0:1ef:ba7e:3fe4 with SMTP id pl15-20020a17090b268f00b001efba7e3fe4mr13092549pjb.23.1657472479010; Sun, 10 Jul 2022 10:01:19 -0700 (PDT) Received: from anisinha-lenovo.ba.nuagenetworks.net ([115.96.107.107]) by smtp.googlemail.com with ESMTPSA id u14-20020a17090341ce00b0016c19417495sm2930596ple.239.2022.07.10.10.01.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jul 2022 10:01:18 -0700 (PDT) From: Ani Sinha To: qemu-devel@nongnu.org Cc: thuth@redhat.com, peter.maydell@linaro.org, berrange@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, imammedo@redhat.com, mst@redhat.com, Ani Sinha Subject: [PATCH v2 03/11] acpi/tests/bits: disable acpi PSS tests that are failing in biosbits Date: Sun, 10 Jul 2022 22:30:06 +0530 Message-Id: <20220710170014.1673480-4-ani@anisinha.ca> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710170014.1673480-1-ani@anisinha.ca> References: <20220710170014.1673480-1-ani@anisinha.ca> MIME-Version: 1.0 Received-SPF: none client-ip=2607:f8b0:4864:20::102d; envelope-from=ani@anisinha.ca; helo=mail-pj1-x102d.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" PSS tests in acpi test suite seems to be failing in biosbits. This is because the test is unable to find PSS support in QEMU bios. Let us disable them for now so that make check does not fail. We can fix the tests and re-enable them later. Example failure: ---- ACPI _PSS (Pstate) table conformance tests ---- [assert] _PSS must exist FAIL \_SB_.CPUS.C000 No _PSS exists Summary: 1 passed, 1 failed ---- ACPI _PSS (Pstate) runtime tests ---- [assert] _PSS must exist FAIL \_SB_.CPUS.C000 No _PSS exists Summary: 0 passed, 1 failed Signed-off-by: Ani Sinha --- tests/pytest/acpi-bits/bits-tests/testacpi.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/pytest/acpi-bits/bits-tests/testacpi.py b/tests/pytest/acpi-bits/bits-tests/testacpi.py index 8e6bb3bbc6..cd2e0ef856 100644 --- a/tests/pytest/acpi-bits/bits-tests/testacpi.py +++ b/tests/pytest/acpi-bits/bits-tests/testacpi.py @@ -38,8 +38,8 @@ def register_tests(): testsuite.add_test("ACPI _MAT (Multiple APIC Table Entry) under Processor objects", test_mat, submenu="ACPI Tests") - testsuite.add_test("ACPI _PSS (Pstate) table conformance tests", test_pss, submenu="ACPI Tests") - testsuite.add_test("ACPI _PSS (Pstate) runtime tests", test_pstates, submenu="ACPI Tests") +# testsuite.add_test("ACPI _PSS (Pstate) table conformance tests", test_pss, submenu="ACPI Tests") +# testsuite.add_test("ACPI _PSS (Pstate) runtime tests", test_pstates, submenu="ACPI Tests") testsuite.add_test("ACPI DSDT (Differentiated System Description Table)", test_dsdt, submenu="ACPI Tests") testsuite.add_test("ACPI FACP (Fixed ACPI Description Table)", test_facp, submenu="ACPI Tests") testsuite.add_test("ACPI HPET (High Precision Event Timer Table)", test_hpet, submenu="ACPI Tests") From patchwork Sun Jul 10 17:00:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ani Sinha X-Patchwork-Id: 12912585 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2BC92C433EF for ; Sun, 10 Jul 2022 17:08:52 +0000 (UTC) Received: from localhost ([::1]:47504 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oAaQN-00007N-C9 for qemu-devel@archiver.kernel.org; Sun, 10 Jul 2022 13:08:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53882) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oAaJC-0006Rn-3S for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:27 -0400 Received: from mail-pl1-x632.google.com ([2607:f8b0:4864:20::632]:45824) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oAaJA-0003OV-7Q for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:25 -0400 Received: by mail-pl1-x632.google.com with SMTP id d5so2626040plo.12 for ; Sun, 10 Jul 2022 10:01:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anisinha-ca.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JfdvqcHmbo+RPt+FsFZbMjLtImA9WyDidr/j6jDQgDQ=; b=YfdP8DOwZtb2UcwPgk/bAYuFHXa6yLz4VamYpEOOvd99y903rXEOLVqnfLfbWM9X8M yLLTEpXL0ylG8qj5FHcN15gHvI6cxkaQ0C3Fiv3OZVt31htcFNsxPxV3cJboSorRSRfF n45DMKBwlBwaJc2wkMSPfpUL4/8s6xmkOi/23r6iPv1IPjUhXwjyA9pdp7x+tqCtb/sE 6uKAMvVzPOGZUJyS7ZIqbeupwxd7H4sGQSIIUQt/SzQXNrKV1lZpdygyde4wYiAriNaT KjuB5baECdT/UZzRiknudY2Qc+QIWYvFxonmsc9CpVIivbfsJIQ3Kcrow5CeFVOkHNTJ Vc8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JfdvqcHmbo+RPt+FsFZbMjLtImA9WyDidr/j6jDQgDQ=; b=R7RSdObUOSEF6JtCNmxwx0NTvuLJKLdO4V/ytzkcljeFLDR2ZPtPG77poCqDucN13E jL+c8r3JV6IQ/J09xp5aSwXsFDludmWTgh5jGWZyX84UxhnSgn3tYiY6pv9Eu2Qu2pdJ skPQd7BPkobv/tynbCVJJ/tKefb6ZCzjhG0GYSdSpfrCMandvZa1Lez+eAOcqRIvkGkc DimGusiRsyCXTgx2Iz+ddAbgbkZqcaCyrDrjXSIinBXHt3vtlBNfWqveBtm09INssfHQ 1gl37AWDh8QhpPofR6fsqAcNyA4Ou7DnyrAxpvRY6e3ZqsKl8YEwIYEAQNUJhpTVCq1k iYXA== X-Gm-Message-State: AJIora+1Dp08eguxAdPhsu7RGB+OzQXmju3dfHdqiNl6PatqqlBMDEvH YrzKMVY2CWR7EUzvMUYBuhwdEMq6TG6LcA2s X-Google-Smtp-Source: AGRyM1uL1F53bzxtjmAtkKtvG4tft0Mwjdkp7g1KAYnvn6258bHyfeMCWSM2gW+cpnkxGXwV8iZXng== X-Received: by 2002:a17:902:ce05:b0:16c:2a1:c335 with SMTP id k5-20020a170902ce0500b0016c02a1c335mr14407627plg.5.1657472482673; Sun, 10 Jul 2022 10:01:22 -0700 (PDT) Received: from anisinha-lenovo.ba.nuagenetworks.net ([115.96.107.107]) by smtp.googlemail.com with ESMTPSA id u14-20020a17090341ce00b0016c19417495sm2930596ple.239.2022.07.10.10.01.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jul 2022 10:01:22 -0700 (PDT) From: Ani Sinha To: qemu-devel@nongnu.org Cc: thuth@redhat.com, peter.maydell@linaro.org, berrange@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, imammedo@redhat.com, mst@redhat.com, Ani Sinha Subject: [PATCH v2 04/11] acpi/tests/bits: add smilatency test suite from bits in order to disable it Date: Sun, 10 Jul 2022 22:30:07 +0530 Message-Id: <20220710170014.1673480-5-ani@anisinha.ca> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710170014.1673480-1-ani@anisinha.ca> References: <20220710170014.1673480-1-ani@anisinha.ca> MIME-Version: 1.0 Received-SPF: none client-ip=2607:f8b0:4864:20::632; envelope-from=ani@anisinha.ca; helo=mail-pl1-x632.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" smilatency tests does not reliably pass every time it is run from QEMU. This change adds the test file unchanged from bits so that the next change can disable the test. Signed-off-by: Ani Sinha --- tests/pytest/acpi-bits/bits-tests/meson.build | 2 +- .../pytest/acpi-bits/bits-tests/smilatency.py | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 tests/pytest/acpi-bits/bits-tests/smilatency.py diff --git a/tests/pytest/acpi-bits/bits-tests/meson.build b/tests/pytest/acpi-bits/bits-tests/meson.build index 3056731a53..06bca75d99 100644 --- a/tests/pytest/acpi-bits/bits-tests/meson.build +++ b/tests/pytest/acpi-bits/bits-tests/meson.build @@ -1,4 +1,4 @@ -test_files = ['smbios.py', 'testacpi.py', 'testcpuid.py'] +test_files = ['smbios.py', 'smilatency.py', 'testacpi.py', 'testcpuid.py'] copytestfiles = custom_target('copy test files', input : test_files, diff --git a/tests/pytest/acpi-bits/bits-tests/smilatency.py b/tests/pytest/acpi-bits/bits-tests/smilatency.py new file mode 100644 index 0000000000..fb1b7228e3 --- /dev/null +++ b/tests/pytest/acpi-bits/bits-tests/smilatency.py @@ -0,0 +1,102 @@ +# Copyright (c) 2015, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Intel Corporation nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""SMI latency test.""" + +import bits +from collections import namedtuple +import testsuite +import time +import usb + +def register_tests(): + testsuite.add_test("SMI latency test", smi_latency); + testsuite.add_test("SMI latency test with USB disabled via BIOS handoff", test_with_usb_disabled, runall=False); + +def smi_latency(): + MSR_SMI_COUNT = 0x34 + + print "Warning: touching the keyboard can affect the results of this test." + + tsc_per_sec = bits.tsc_per_sec() + tsc_per_usec = tsc_per_sec / (1000 * 1000) + bins = [long(tsc_per_usec * 10**i) for i in range(9)] + bin_descs = [ + "0 < t <= 1us", + "1us < t <= 10us", + "10us < t <= 100us", + "100us < t <= 1ms", + "1ms < t <= 10ms", + "10ms < t <= 100ms", + "100ms < t <= 1s ", + "1s < t <= 10s ", + "10s < t <= 100s ", + "100s < t ", + ] + + print "Starting test. Wait here, I will be back in 15 seconds." + (max_latency, smi_count_delta, bins) = bits.smi_latency(long(15 * tsc_per_sec), bins) + BinType = namedtuple('BinType', ("max", "total", "count", "times")) + bins = [BinType(*b) for b in bins] + + testsuite.test("SMI latency < 150us to minimize risk of OS timeouts", max_latency / tsc_per_usec <= 150) + if not testsuite.show_detail(): + return + + for bin, desc in zip(bins, bin_descs): + if bin.count == 0: + continue + testsuite.print_detail("{}; average = {}; count = {}".format(desc, bits.format_tsc(bin.total/bin.count), bin.count)) + deltas = (bits.format_tsc(t2 - t1) for t1,t2 in zip(bin.times, bin.times[1:])) + testsuite.print_detail(" Times between first few observations: {}".format(" ".join("{:>6}".format(delta) for delta in deltas))) + + if smi_count_delta is not None: + testsuite.print_detail("{} SMI detected using MSR_SMI_COUNT (MSR {:#x})".format(smi_count_delta, MSR_SMI_COUNT)) + + testsuite.print_detail("Summary of impact: observed maximum latency = {}".format(bits.format_tsc(max_latency))) + +def test_with_usb_disabled(): + if usb.handoff_to_os(): + smi_latency() + +def average_io_smi(port, value, count): + def f(): + tsc_start = bits.rdtsc() + bits.outb(port, value) + return bits.rdtsc() - tsc_start + counts = [f() for i in range(count)] + return sum(counts)/len(counts) + +def time_io_smi(port=0xb2, value=0, count=1000): + count_for_estimate = 10 + start = time.time() + average_io_smi(port, value, count_for_estimate) + avg10 = time.time() - start + estimate = avg10 * count/count_for_estimate + if estimate > 1: + print "Running test, estimated time: {}s".format(int(estimate)) + average = average_io_smi(port, value, count) + print "Average of {} SMIs (via outb, port={:#x}, value={:#x}): {}".format(count, port, value, bits.format_tsc(average)) From patchwork Sun Jul 10 17:00:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ani Sinha X-Patchwork-Id: 12912590 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8A26FC43334 for ; Sun, 10 Jul 2022 17:13:38 +0000 (UTC) Received: from localhost ([::1]:56216 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oAaUz-0006Co-L7 for qemu-devel@archiver.kernel.org; Sun, 10 Jul 2022 13:13:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53908) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oAaJF-0006UN-50 for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:29 -0400 Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]:36830) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oAaJD-0003Ox-PQ for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:28 -0400 Received: by mail-pl1-x634.google.com with SMTP id r6so203636plg.3 for ; Sun, 10 Jul 2022 10:01:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anisinha-ca.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=TsboKHDJYIu5BEIJqCkd76aYeMsV8T9uXdlh43KjXMY=; b=D7jL9jV3XAedCj/pmVxB9eyJWctK/GqAWiiv/M9KURIpupPQfstxDIOaczjSN6Wmqu X0Qd3oNS2sOT1XXfBdsBfcG/Zdn30lphuGautcXO7hh6WL/cKrK8mTiyul8/Pxjt05GA 97KnElZwd8u6B2aH0reJiC8uBm26FRMC5t7xxsa2Z5VO9jdJKx896ZPtOjuyJXGylvRr bnZINVnxLywAfxgVgmttRQvkZOv5RCjdMyrVqIgoi8hIc5cg8wVj07j9orPRrzu6TyM7 YE11pLudO86ibynqNgtDnfLLSYtK6FoTjurkoBLSNN1Qs+q+6vjHpZyZAhRNpyzCAj/5 S6wg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TsboKHDJYIu5BEIJqCkd76aYeMsV8T9uXdlh43KjXMY=; b=ab+SnmUi8qxR33raEssA1Qg08AoDZLEzPcEUlw672Hq5P6RmMggmmyJQQbZIqE4ogv DX3LeI6CRJCa4GNvW5r+ejONm/urYR0TKwPTJ7yQqT1z0wzUqUQPIMLDK/ufI8/01Zjy svcgukZtoGCMkGzVzheDTzenPQf2eWaBSeslWvYtnbEsSDwO5kPwdIdoC3aM2fwdMo5g ngdLEitRAk6dcyVZwPrryPFOvShYzJ2fi1dBQt14RTdU9USonf9fcYReoUG93Mgi7YG+ 5VeuAwG8ZqTh7tNbFgvk7YN/KR9MzYUu9kES/YZvs7ZbkdLXUW0wZM3vLSD2rcF4U8um y9vA== X-Gm-Message-State: AJIora96/H3Qa1PDfsid4Ta6l1lundsq24HrQKpZ6DH+9aQriCmpVx7w b6/IOa1WkgnnT0k2shn5SfiX4He47eJAcGJR X-Google-Smtp-Source: AGRyM1vYOirkFeXB7XpxhGA7J7CwaAQERUzBajhurlKWzfBSfd2jLADjH+e5/FtzmK7GQuVkW+YnCw== X-Received: by 2002:a17:90b:1d04:b0:1ec:f898:d863 with SMTP id on4-20020a17090b1d0400b001ecf898d863mr12809937pjb.79.1657472486322; Sun, 10 Jul 2022 10:01:26 -0700 (PDT) Received: from anisinha-lenovo.ba.nuagenetworks.net ([115.96.107.107]) by smtp.googlemail.com with ESMTPSA id u14-20020a17090341ce00b0016c19417495sm2930596ple.239.2022.07.10.10.01.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jul 2022 10:01:25 -0700 (PDT) From: Ani Sinha To: qemu-devel@nongnu.org Cc: thuth@redhat.com, peter.maydell@linaro.org, berrange@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, imammedo@redhat.com, mst@redhat.com, Ani Sinha Subject: [PATCH v2 05/11] acpi/tests/bits: add SPDX license identifiers for bios bits smilatency tests Date: Sun, 10 Jul 2022 22:30:08 +0530 Message-Id: <20220710170014.1673480-6-ani@anisinha.ca> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710170014.1673480-1-ani@anisinha.ca> References: <20220710170014.1673480-1-ani@anisinha.ca> MIME-Version: 1.0 Received-SPF: none client-ip=2607:f8b0:4864:20::634; envelope-from=ani@anisinha.ca; helo=mail-pl1-x634.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added the SPDX license identifier based on the following output from the licensee tool for bios bits: $ licensee detect bits/ License: NOASSERTION Matched files: COPYING COPYING: Content hash: 7a1fdfa894728ea69588977442c92073aad69e50 License: NOASSERTION Closest non-matching licenses: BSD-3-Clause-Clear similarity: 85.82% BSD-4-Clause similarity: 83.69% BSD-3-Clause similarity: 77.27% Signed-off-by: Ani Sinha --- tests/pytest/acpi-bits/bits-tests/smilatency.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/pytest/acpi-bits/bits-tests/smilatency.py b/tests/pytest/acpi-bits/bits-tests/smilatency.py index fb1b7228e3..9b11623b2d 100644 --- a/tests/pytest/acpi-bits/bits-tests/smilatency.py +++ b/tests/pytest/acpi-bits/bits-tests/smilatency.py @@ -1,6 +1,8 @@ # Copyright (c) 2015, Intel Corporation # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause-Clear +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # From patchwork Sun Jul 10 17:00:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ani Sinha X-Patchwork-Id: 12912592 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3F6C5C433EF for ; Sun, 10 Jul 2022 17:16:01 +0000 (UTC) Received: from localhost ([::1]:33734 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oAaXI-0001dx-4p for qemu-devel@archiver.kernel.org; Sun, 10 Jul 2022 13:16:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53926) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oAaJI-0006ih-VM for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:32 -0400 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]:35381) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oAaJH-0003PQ-Dm for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:32 -0400 Received: by mail-pj1-x1033.google.com with SMTP id x18-20020a17090a8a9200b001ef83b332f5so6244355pjn.0 for ; Sun, 10 Jul 2022 10:01:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anisinha-ca.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=TSt/KXB+QPkzcqJElYbGV0pOi+RhJBmDL7INxYmtHuA=; b=TyFdSvtxMNHFHDdBnSfwXoLCi3YALB88GGR8N3O5aURQwLIj63HNp93cI+tNTV+j// 8Ou5wbxfT3ixr/QX699P+YGct/WbEIF0+19+s0UcZvsX+oywpcwur0zIxoRaqsRjH/KC 9Ywl2stp0dRgQ9fCwC6D0794FS3Z5Fj8WmLaKp9pjSFKO1gXTDQduSG8Gp9rgZG/ypFk ZoLWh+GHU+ExGkAROvNsTnzkwE3PtMI1F5xdYjFovRWRE1XBJ+HdtAr++E5eMfj6yFAh LgiiqbqFuz88fejFq+qotpLGKRvsbdCUWZvaltrBZksoqpl5CU7+Nk0AfdeUni2m7AVw T8nQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TSt/KXB+QPkzcqJElYbGV0pOi+RhJBmDL7INxYmtHuA=; b=V1YFfD3sL1tYzMxd03bQM9iAaT6qYelMA5eegY10qnY8BD9Y4gE3ZXwuSJ+VwKQ7BW L5gM1m5toyKG3NK7Tw3SRFGC3+U3GnrdnDN8J3fgBD4wX+3he2RFBHfYY6yrHMftFCKE 3o9eY6msOzQHpE5w+kE8MUjpIF6i16qYrtz2PyazCRVrt/J2AsmX71urlz2HdQxY7sss ZOrIdaJW3S3Axk5aD1JH409/zAn8Mq7lx/g0LkIvy7BwMNdSAzMRpXsh3835it0jU1ck y+IVGrf9rZ3AAoNa4Xpd096o+GnxPgS1lyDhkFKrGzzqda20ZIwURE6M3e+BbrWKTFK5 Dukw== X-Gm-Message-State: AJIora/nYOYyugLuLrpExDnCP5et23RXCL/dfiw7W4qZqbVYnIDgaYrS 2m/V2+6Y8dgyzMhxvM4A6OsK4lsDxzoVRAAo X-Google-Smtp-Source: AGRyM1snbJCAcXRXQ9SqFkyQkFK1DytjrAdak7VO1E+tz69GpG6QtAX657if/P9pdY4X9oWBxYPVrw== X-Received: by 2002:a17:903:1104:b0:16c:2f71:7803 with SMTP id n4-20020a170903110400b0016c2f717803mr9837373plh.101.1657472489945; Sun, 10 Jul 2022 10:01:29 -0700 (PDT) Received: from anisinha-lenovo.ba.nuagenetworks.net ([115.96.107.107]) by smtp.googlemail.com with ESMTPSA id u14-20020a17090341ce00b0016c19417495sm2930596ple.239.2022.07.10.10.01.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jul 2022 10:01:29 -0700 (PDT) From: Ani Sinha To: qemu-devel@nongnu.org Cc: thuth@redhat.com, peter.maydell@linaro.org, berrange@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, imammedo@redhat.com, mst@redhat.com, Ani Sinha Subject: [PATCH v2 06/11] acpi/tests/bits: disable smilatency test since it does not pass everytime Date: Sun, 10 Jul 2022 22:30:09 +0530 Message-Id: <20220710170014.1673480-7-ani@anisinha.ca> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710170014.1673480-1-ani@anisinha.ca> References: <20220710170014.1673480-1-ani@anisinha.ca> MIME-Version: 1.0 Received-SPF: none client-ip=2607:f8b0:4864:20::1033; envelope-from=ani@anisinha.ca; helo=mail-pj1-x1033.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" smilatency test is latency sensitive and does not pass deterministically when run in QEMU environment under biosbits. Disable the test suite for now. Example failure: ==== SMI latency test ==== Warning: touching the keyboard can affect the results of this test. Starting test. Wait here, I will be back in 15 seconds. [assert] SMI latency < 150us to minimize risk of OS timeouts FAIL 1us < t <= 10us; average = 1372ns; count = 10912449 Times between first few observations: 176us 1646ns 1441ns 1450ns 1462ns 10us < t <= 100us; average = 16us; count = 1187 Times between first few observations: 15ms 3148us 5856us 49ms 33ms 100us < t <= 1ms; average = 259us; count = 8 Times between first few observations: 111ms 2227ms 1779ms 999ms 219ms 0 SMI detected using MSR_SMI_COUNT (MSR 0x34) Summary of impact: observed maximum latency = 298us Summary: 0 passed, 1 failed Signed-off-by: Ani Sinha --- tests/pytest/acpi-bits/bits-tests/smilatency.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/pytest/acpi-bits/bits-tests/smilatency.py b/tests/pytest/acpi-bits/bits-tests/smilatency.py index 9b11623b2d..31d588fb18 100644 --- a/tests/pytest/acpi-bits/bits-tests/smilatency.py +++ b/tests/pytest/acpi-bits/bits-tests/smilatency.py @@ -35,8 +35,9 @@ import usb def register_tests(): - testsuite.add_test("SMI latency test", smi_latency); - testsuite.add_test("SMI latency test with USB disabled via BIOS handoff", test_with_usb_disabled, runall=False); + pass + # testsuite.add_test("SMI latency test", smi_latency); + # testsuite.add_test("SMI latency test with USB disabled via BIOS handoff", test_with_usb_disabled, runall=False); def smi_latency(): MSR_SMI_COUNT = 0x34 From patchwork Sun Jul 10 17:00:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ani Sinha X-Patchwork-Id: 12912588 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5C73CC433EF for ; Sun, 10 Jul 2022 17:12:43 +0000 (UTC) Received: from localhost ([::1]:52580 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oAaU6-0003cE-6E for qemu-devel@archiver.kernel.org; Sun, 10 Jul 2022 13:12:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53950) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oAaJO-0006zC-JT for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:38 -0400 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]:44939) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oAaJL-0003Pd-M6 for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:38 -0400 Received: by mail-pl1-x635.google.com with SMTP id q5so2627967plr.11 for ; Sun, 10 Jul 2022 10:01:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anisinha-ca.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6qHNLZ5Gg3ns7o3b7v0RoN7I4gbgxcU42Q1Nbt6y+ug=; b=pCVNHVvoNPncUBUflXh74n4/VAoTlo226sBab2/mosBpX34o69A9Q9zi2OmwmjGceV 4yl0SJb3WHhp+1xuy70M2wNHYtGk0Jei+UoRaId1J0YyOfPkyS5LaYk+9d9Sz3bCOGAb S2MyW55EVS/GroqUfzJrtxit5VT/yYJoFlPd2XUBJ/DnP0EUCaOsnHCluh3wBNDqL4Qk XVI+maNDa1doKbfWdYvhbS2ahsh+LPij3ntfqiF84ioXgRpBIZZtN+DBIYXqGtwgjEEp is/LDX3cL5JciRJmVNJMifeXO8JE58GEd/CZK05HUd2XZCgJ3ISmhxRJyh2/j/uQOL5R olOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6qHNLZ5Gg3ns7o3b7v0RoN7I4gbgxcU42Q1Nbt6y+ug=; b=fXxXdpb8nOmI99K2M4StgQgYhR+Qu6192qQbt46PBKSo68eCK/TAqvT3nMLPI7vAH8 UvVkRnp7XksiXfHrnRWVWXHenezDzQJsvNHP83qcX/W6Lm2YVpdFGbE71+QlFhZf5nJ8 b+d2lLlpvxXRXU/gT05CsMcuCPMOuLcDgSyc7ev1jCMveg/lJyMtSJeQCx0BMrCFFifQ CE/dqzhRHt4JALaeUKjiwmPqTTQLZV8vErGziNqWIc/72R7GcWEPg2ZVAmDIST5IEH9t PnUg571bisJQ9hYwabIowFQn5bXDSeYoD5Utf4uerA9swjF2naJ1ZSNCJaVtJlAPkuUR 1jqA== X-Gm-Message-State: AJIora+llaTqiJ8Ncp2PVbfl02TjxEWcdAuNpU5AAGIR4E/bpCgS4UAy QOsW7rebmEUK+Fg/6sv5WCTTRxrAHTq7aML6 X-Google-Smtp-Source: AGRyM1u6I2lrB+9YjL4pk/zj+38efnuJHGiXj3JNFHv36UA/ukODWGAprhgmDach6aEiDGkARBGIvg== X-Received: by 2002:a17:90a:d50d:b0:1ef:9130:f96b with SMTP id t13-20020a17090ad50d00b001ef9130f96bmr12434712pju.235.1657472493755; Sun, 10 Jul 2022 10:01:33 -0700 (PDT) Received: from anisinha-lenovo.ba.nuagenetworks.net ([115.96.107.107]) by smtp.googlemail.com with ESMTPSA id u14-20020a17090341ce00b0016c19417495sm2930596ple.239.2022.07.10.10.01.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jul 2022 10:01:33 -0700 (PDT) From: Ani Sinha To: qemu-devel@nongnu.org, Ani Sinha Cc: thuth@redhat.com, peter.maydell@linaro.org, berrange@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, imammedo@redhat.com, mst@redhat.com Subject: [PATCH v2 07/11] acpi/tests/bits: add python test that exercizes QEMU bios tables using biosbits Date: Sun, 10 Jul 2022 22:30:10 +0530 Message-Id: <20220710170014.1673480-8-ani@anisinha.ca> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710170014.1673480-1-ani@anisinha.ca> References: <20220710170014.1673480-1-ani@anisinha.ca> MIME-Version: 1.0 Received-SPF: none client-ip=2607:f8b0:4864:20::635; envelope-from=ani@anisinha.ca; helo=mail-pl1-x635.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This change adds python based test environment that can be used to run pytest from within a virtual environment. A bash script sets up a virtual environment and then runs the python based tests from within that environment. All dependent python packages are installed in the virtual environment using pip python module. QEMU python test modules are also available in the environment for spawning the QEMU based VMs. It also introduces QEMU acpi/smbios biosbits python test script which is run from within the python virtual environment. When the bios bits tests are run, bios bits binaries are downloaded from an external repo/location. Currently, the test points to an external private github repo where the bits archives are checked in. Signed-off-by: Ani Sinha --- tests/pytest/acpi-bits/acpi-bits-test-venv.sh | 59 +++ tests/pytest/acpi-bits/acpi-bits-test.py | 382 ++++++++++++++++++ tests/pytest/acpi-bits/meson.build | 33 ++ tests/pytest/acpi-bits/requirements.txt | 1 + 4 files changed, 475 insertions(+) create mode 100644 tests/pytest/acpi-bits/acpi-bits-test-venv.sh create mode 100644 tests/pytest/acpi-bits/acpi-bits-test.py create mode 100644 tests/pytest/acpi-bits/meson.build create mode 100644 tests/pytest/acpi-bits/requirements.txt diff --git a/tests/pytest/acpi-bits/acpi-bits-test-venv.sh b/tests/pytest/acpi-bits/acpi-bits-test-venv.sh new file mode 100644 index 0000000000..186395473b --- /dev/null +++ b/tests/pytest/acpi-bits/acpi-bits-test-venv.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# Generates a python virtual environment for the test to run. +# Then runs python test scripts from within that virtual environment. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Author: Ani Sinha + +set -e + +MYPATH=$(realpath ${BASH_SOURCE:-$0}) +MYDIR=$(dirname $MYPATH) + +if [ -z "$PYTEST_SOURCE_ROOT" ]; then + echo -n "Please set QTEST_SOURCE_ROOT env pointing" + echo " to the root of the qemu source tree." + echo -n "This is required so that the test can find the " + echo "python modules that it needs for execution." + exit 1 +fi +SRCDIR=$PYTEST_SOURCE_ROOT +TESTSCRIPTS=("acpi-bits-test.py") +PIPCMD="-m pip -q --disable-pip-version-check" +# we need to save the old value of PWD before we do a change-dir later +PYTEST_PWD=$PWD + +TESTS_PYTHON=/usr/bin/python3 +TESTS_VENV_REQ=requirements.txt + +# sadly for pip -e and -t options do not work together. +# please see https://github.com/pypa/pip/issues/562 +cd $MYDIR + +$TESTS_PYTHON -m venv . +$TESTS_PYTHON $PIPCMD install -e $SRCDIR/python/ +[ -f $TESTS_VENV_REQ ] && \ + $TESTS_PYTHON $PIPCMD install -r $TESTS_VENV_REQ || exit 0 + +# venv is activated at this point. + +# run the test +for testscript in ${TESTSCRIPTS[@]} ; do + export PYTEST_PWD; python3 $testscript +done + +cd $PYTEST_PWD + +exit 0 diff --git a/tests/pytest/acpi-bits/acpi-bits-test.py b/tests/pytest/acpi-bits/acpi-bits-test.py new file mode 100644 index 0000000000..97e61eb709 --- /dev/null +++ b/tests/pytest/acpi-bits/acpi-bits-test.py @@ -0,0 +1,382 @@ +#!/usr/bin/env python3 +# group: rw quick +# Exercize QEMU generated ACPI/SMBIOS tables using biosbits, +# https://biosbits.org/ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Some parts are slightly taken from qtest.py and iotests.py +# +# Authors: +# Ani Sinha + +# pylint: disable=invalid-name + +""" +QEMU bios tests using biosbits available at +https://biosbits.org/. +""" + +import logging +import os +import re +import shutil +import subprocess +import sys +import tarfile +import tempfile +import time +import unittest +from urllib import request +import zipfile +from typing import ( + List, + Optional, + Sequence, +) +from tap import TAPTestRunner +from qemu.machine import QEMUMachine + +PYTESTQEMUBIN = os.getenv('PYTEST_QEMU_BINARY') +PYTEST_PWD = os.getenv('PYTEST_PWD') + +def get_arch(): + """finds the arch from the qemu binary name""" + match = re.search('.*qemu-system-(.*)', PYTESTQEMUBIN) + if match: + return match.group(1) + return 'x86_64' + +ARCH = get_arch() + +class QEMUBitsMachine(QEMUMachine): + """ + A QEMU VM, with isa-debugcon enabled and bits iso passed + using -cdrom to QEMU commandline. + """ + def __init__(self, + binary: str, + args: Sequence[str] = (), + wrapper: Sequence[str] = (), + name: Optional[str] = None, + base_temp_dir: str = "/var/tmp", + debugcon_log: str = "debugcon-log.txt", + debugcon_addr: str = "0x403", + sock_dir: Optional[str] = None, + qmp_timer: Optional[float] = None): + # pylint: disable=too-many-arguments + + if name is None: + name = "qemu-bits-%d" % os.getpid() + if sock_dir is None: + sock_dir = base_temp_dir + super().__init__(binary, args, wrapper=wrapper, name=name, + base_temp_dir=base_temp_dir, + sock_dir=sock_dir, qmp_timer=qmp_timer) + self.debugcon_log = debugcon_log + self.debugcon_addr = debugcon_addr + self.base_temp_dir = base_temp_dir + + @property + def _base_args(self) -> List[str]: + args = super()._base_args + args.extend([ + '-chardev', + 'file,path=%s,id=debugcon' %os.path.join(self.base_temp_dir, + self.debugcon_log), + '-device', + 'isa-debugcon,iobase=%s,chardev=debugcon' %self.debugcon_addr, + ]) + return args + + def base_args(self): + """return the base argument to QEMU binary""" + return self._base_args + +class AcpiBitsTest(unittest.TestCase): + """ACPI and SMBIOS tests using biosbits.""" + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._vm = None + self._workDir = None + self._bitsVer = 2100 + self._bitsLoc = "https://github.com/ani-sinha/bits/raw/bits-builds/" + self._debugcon_addr = '0x403' + self._debugcon_log = 'debugcon-log.txt' + logging.basicConfig(level=logging.INFO) + + def copy_bits_config(self): + """ copies the bios bits config file into bits. + """ + config_file = 'bits-cfg.txt' + qemu_bits_config_dir = os.path.join(os.getcwd(), 'bits-config') + target_config_dir = os.path.join(self._workDir, + 'bits-%d' %self._bitsVer, 'boot') + self.assertTrue(os.path.exists(qemu_bits_config_dir)) + self.assertTrue(os.path.exists(target_config_dir)) + self.assertTrue(os.access(os.path.join(qemu_bits_config_dir, + config_file), os.R_OK)) + shutil.copy2(os.path.join(qemu_bits_config_dir, config_file), + target_config_dir) + logging.info('copied config file %s to %s', + config_file, target_config_dir) + + def copy_test_scripts(self): + """copies the python test scripts into bits. """ + qemu_test_dir = os.path.join(os.getcwd(), 'bits-tests') + target_test_dir = os.path.join(self._workDir, 'bits-%d' %self._bitsVer, + 'boot', 'python') + + self.assertTrue(os.path.exists(qemu_test_dir)) + self.assertTrue(os.path.exists(target_test_dir)) + + for filename in os.listdir(qemu_test_dir): + if os.path.isfile(os.path.join(qemu_test_dir, filename)) and \ + filename.endswith('.py'): + shutil.copy2(os.path.join(qemu_test_dir, filename), + target_test_dir) + logging.info('copied test file %s to %s', + filename, target_test_dir) + + # now remove the pyc test file if it exists, otherwise the + # changes in the python test script won't be executed. + testfile_pyc = os.path.splitext(filename)[0] + '.pyc' + if os.access(os.path.join(target_test_dir, testfile_pyc), + os.F_OK): + os.remove(os.path.join(target_test_dir, testfile_pyc)) + logging.info('removed compiled file %s', + os.path.join(target_test_dir, testfile_pyc)) + + def fix_mkrescue(self, mkrescue): + """ grub-mkrescue is a bash script with two variables, 'prefix' and + 'libdir'. They must be pointed to the right location so that the + iso can be generated appropriately. We point the two variables to + the directory where we have extracted our pre-built bits grub + tarball. + """ + grub_x86_64_mods = os.path.join(self._workDir, 'grub-inst-x86_64-efi') + grub_i386_mods = os.path.join(self._workDir, 'grub-inst') + + self.assertTrue(os.path.exists(grub_x86_64_mods)) + self.assertTrue(os.path.exists(grub_i386_mods)) + + new_script = "" + with open(mkrescue, 'r') as filehandle: + orig_script = filehandle.read() + new_script = re.sub('(^prefix=)(.*)', + r'\1"%s"' %grub_x86_64_mods, + orig_script, flags=re.M) + new_script = re.sub('(^libdir=)(.*)', r'\1"%s/lib"' %grub_i386_mods, + new_script, flags=re.M) + + with open(mkrescue, 'w') as filehandle: + filehandle.write(new_script) + + def generate_bits_iso(self): + """ Uses grub-mkrescue to generate a fresh bits iso with the python + test scripts + """ + bits_dir = os.path.join(self._workDir, 'bits-%d' %self._bitsVer) + iso_file = os.path.join(self._workDir, 'bits-%d.iso' %self._bitsVer) + mkrescue_script = os.path.join(self._workDir, + 'grub-inst-x86_64-efi', 'bin', + 'grub-mkrescue') + + self.assertTrue(os.access(mkrescue_script, + os.R_OK | os.W_OK | os.X_OK)) + + self.fix_mkrescue(mkrescue_script) + + logging.info('calling grub-mkrescue to generate the biosbits iso ...') + + try: + if os.getenv('V'): + subprocess.check_call([mkrescue_script, '-o', + iso_file, bits_dir], + stdout=subprocess.DEVNULL) + else: + subprocess.check_call([mkrescue_script, '-o', + iso_file, bits_dir], + stderr=subprocess.DEVNULL, + stdout=subprocess.DEVNULL) + except Exception as e: # pylint: disable=broad-except + self.skipTest("Error while generating the bits iso. " + "Pass V=1 in the environment to get more details. " + + str(e)) + + self.assertTrue(os.access(iso_file, os.R_OK)) + + logging.info('iso file %s successfully generated.', iso_file) + + def setUp(self): + BITS_LOC = os.getenv("PYTEST_BITSLOC") + if BITS_LOC: + prefix = BITS_LOC + else: + prefix = os.path.join(os.getcwd(), 'prebuilt') + if not os.path.isdir(prefix): + os.mkdir(prefix, mode=0o775) + + bits_zip_file = os.path.join(prefix, 'bits-%d.zip' + %self._bitsVer) + grub_tar_file = os.path.join(prefix, + 'bits-%d-grub.tar.gz' %self._bitsVer) + # if the location of the bits binaries has been specified by the user + # and they are not found in that location, skip the test. + if BITS_LOC and not os.access(bits_zip_file, os.F_OK): + self.skipTest("test skipped since biosbits binaries " + + "could not be found in the specified location %s." \ + %BITS_LOC) + if BITS_LOC and not os.access(grub_tar_file, os.F_OK): + self.skipTest("test skipped since biosbits binaries " + + "could not be found in the specified location %s." \ + %BITS_LOC) + + self._workDir = tempfile.mkdtemp(prefix='acpi-bits-', + suffix='.tmp') + logging.info('working dir: %s', self._workDir) + + localArchive = "bits-%d.zip" % self._bitsVer + if not os.access(bits_zip_file, os.F_OK): + logging.info("archive %s not found in %s, downloading ...", + localArchive, bits_zip_file) + try: + req = request.urlopen(self._bitsLoc + localArchive) + with open(os.path.join(prefix, localArchive), + 'wb') as archivef: + archivef.write(req.read()) + except Exception as e: # pylint: disable=broad-except + self.skipTest("test skipped since biosbits binaries " + + "could not be obtained." + str(e)) + else: + logging.info('using locally found %s', localArchive) + + localArchive = "bits-%d-grub.tar.gz" % self._bitsVer + if not os.access(grub_tar_file, os.F_OK): + logging.info("archive %s not found in %s, downloading ...", + localArchive, bits_zip_file) + try: + req = request.urlopen(self._bitsLoc + localArchive) + with open(os.path.join(prefix, localArchive), + 'wb') as archivef: + archivef.write(req.read()) + except Exception as e: # pylint: disable=broad-except + self.skipTest("test skipped since biosbits binaries " + + "could not be obtained." + str(e)) + else: + logging.info('using locally found %s', localArchive) + + # extract the bits software in the temp working directory + with zipfile.ZipFile(bits_zip_file, 'r') as zref: + zref.extractall(self._workDir) + + with tarfile.open(grub_tar_file, 'r') as tarball: + tarball.extractall(self._workDir) + + self.copy_test_scripts() + self.copy_bits_config() + self.generate_bits_iso() + + def parse_log(self): + """parse the log generated by running bits tests and + check for failures. + """ + debugconf = os.path.join(self._workDir, self._debugcon_log) + log = "" + with open(debugconf, 'r') as filehandle: + log = filehandle.read() + + if os.getenv('V'): + print('\nlogs from biosbits follows:') + print('==========================================\n') + print(log) + print('==========================================\n') + + matchiter = re.finditer(r'(.*Summary: )(\d+ passed), (\d+ failed).*', + log) + for match in matchiter: + # verify that no test cases failed. + self.assertEqual(match.group(3).split()[0], '0', + 'Some bits tests seems to have failed. ' \ + 'Set V=1 in the environment to get the entire ' \ + 'log from bits.') + + def tearDown(self): + if self._vm: + self.assertFalse(not self._vm.is_running) + logging.info('removing the work directory %s', self._workDir) + shutil.rmtree(self._workDir) + + def test_acpi_smbios_bits(self): + """The main test case implementaion.""" + + qemu_bin = PYTESTQEMUBIN + iso_file = os.path.join(self._workDir, 'bits-%d.iso' %self._bitsVer) + + # PYTESTQEMUBIN could be relative to the current directory + if not os.access(PYTESTQEMUBIN, os.X_OK) and PYTEST_PWD: + qemu_bin = os.path.join(PYTEST_PWD, PYTESTQEMUBIN) + + logging.info('QEMU binary used: %s', qemu_bin) + + self.assertTrue(os.access(qemu_bin, os.X_OK)) + self.assertTrue(os.access(iso_file, os.R_OK)) + + self._vm = QEMUBitsMachine(binary=qemu_bin, + base_temp_dir=self._workDir, + debugcon_log=self._debugcon_log, + debugcon_addr=self._debugcon_addr) + + self._vm.add_args('-cdrom', '%s' %iso_file) + + args = " ".join(str(arg) for arg in self._vm.base_args()) + \ + " " + " ".join(str(arg) for arg in self._vm.args) + + logging.info("launching QEMU vm with the following arguments: %s", + args) + + self._vm.launch() + # biosbits has been configured to run all the specified test suites + # in batch mode and then automatically initiate a vm shutdown. + # sleep for maximum of one minute + max_sleep_time = time.monotonic() + 60 + while self._vm.is_running() and time.monotonic() < max_sleep_time: + time.sleep(1) + + self.assertFalse(time.monotonic() > max_sleep_time, + 'The VM seems to have failed to shutdown in time') + + self.parse_log() + +def execute_unittest(argv: List[str], debug: bool = False, + runner: TAPTestRunner = None) -> None: + """Executes unittests within the calling module.""" + + unittest.main(argv=argv, + testRunner=runner, + verbosity=2 if debug else 1, + warnings=None if sys.warnoptions else 'ignore') + +def main(): + """ The main function where execution begins. """ + + assert PYTESTQEMUBIN is not None, \ + "Environment variable PYTEST_QEMU_BINARY required." + + runner = TAPTestRunner() + runner.set_stream(True) + runner.set_format("%s/acpi-bits-test" %ARCH) + execute_unittest(sys.argv, False, runner) + +main() diff --git a/tests/pytest/acpi-bits/meson.build b/tests/pytest/acpi-bits/meson.build new file mode 100644 index 0000000000..099c191d57 --- /dev/null +++ b/tests/pytest/acpi-bits/meson.build @@ -0,0 +1,33 @@ +xorriso = find_program('xorriso', required: true) +if not xorriso.found() + message('xorriso not found ... disabled bits acpi tests.') + subdir_done() +endif + +subdir('bits-tests') +subdir('bits-config') + +test_files = ['acpi-bits-test.py'] +requirements = 'requirements.txt' + +copytestfiles = custom_target('copy test files', + input : test_files, + output : test_files, + command : ['cp', '@INPUT@', '@OUTPUT@'], + install : false, + build_by_default : true) + +requirementsfiles = custom_target('copy py req files', + input : requirements, + output : requirements, + command : ['cp', '@INPUT@', '@OUTPUT@'], + install : false, + build_by_default : true) + +other_deps += [copytestfiles,requirementsfiles] + +pytest_executables += { + 'acpi-bits-test': configure_file(copy:true, + input:'acpi-bits-test-venv.sh', + output:'acpi-bits-test') +} diff --git a/tests/pytest/acpi-bits/requirements.txt b/tests/pytest/acpi-bits/requirements.txt new file mode 100644 index 0000000000..00cdad09ef --- /dev/null +++ b/tests/pytest/acpi-bits/requirements.txt @@ -0,0 +1 @@ +tap.py From patchwork Sun Jul 10 17:00:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ani Sinha X-Patchwork-Id: 12912589 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0C231C43334 for ; Sun, 10 Jul 2022 17:13:30 +0000 (UTC) Received: from localhost ([::1]:55946 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oAaUq-00062V-Mc for qemu-devel@archiver.kernel.org; Sun, 10 Jul 2022 13:13:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53966) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oAaJQ-000763-Iq for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:40 -0400 Received: from mail-pg1-x52d.google.com ([2607:f8b0:4864:20::52d]:36822) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oAaJO-0003QC-Uk for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:40 -0400 Received: by mail-pg1-x52d.google.com with SMTP id s206so2932890pgs.3 for ; Sun, 10 Jul 2022 10:01:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anisinha-ca.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fMy7spbq2+bUWgIyrJhJfd9Xs4+WXB+8x2SN8PxtJko=; b=H/JsKcYFYSWUuxhrnFHcHc3zpDP098NjyU/2wLpUyKQywwZWHF/PzIzK1X+oTCwTBS X3fTDMs6AWh7q1o3K3DmXFhiepPrdT/ahg54mLcuSqTImeepDVlEmsm5zAVFqH2sx5Lj cpQNZT/GlnG9M0EZb92V8983hWSv+r6gjSOOqG05Vup0H19Z/5IW8YQWzeu1BtPmV1oO Dilcxhbg7TDliYgUWIXNXJsFfsIpDm2C1MQWXcWmJSB0S6dl7Y95LQYR6X760KDiUFPH agSeBmVFuxYesq7h2V8gcJd9A+iSCmCKxZaHun4W3/0fApojHZi33u7B6v+vjOCPr7Q0 apRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fMy7spbq2+bUWgIyrJhJfd9Xs4+WXB+8x2SN8PxtJko=; b=2KEyB5zwXvW6M7hAT0t0qwlTSknsdhgPguaUfjwGVAbZwxk/c8JMih/tGnnRQLVE+o Ca56dCfkV2i0rtyGzkMv5GB/K8edqm6E+pmZh3tL01RYEJi0fHaI51fm4xRPfMhqqkPr NUMCpTle3J8/SiwhPsBYhhPMly+DM7rLDxNH8g3SEY1SyB66viSyuHqyVV8d8L7W/k02 8uWyZyMUQA1N3F7wqMChYbaK6nXfeGj6jX9RYFyw13/cjdS2HRAfB/saYQoyi1RaQ47L 4hCFvTVDqbYRXuKML3I9bA4IdiqhT4QA+6uU6g2NlM6jawMNnZKzrH82qqugNK5+bNwj UiCg== X-Gm-Message-State: AJIora/w4XwX1MJ6XI+7KH9qYM1zmLMsDh4sZovXSglEgUIXm4KRTtJD uIkzOJQwagOXxMARd2Vnt/aJy76SKNlG+trj X-Google-Smtp-Source: AGRyM1unts2MxkBsWgc4PqlPNUmKYsS/cUpLIV5Z7T0oPKzIQ7kA7B7n+pgE9ojsEh9UlQqnkOkS2Q== X-Received: by 2002:a05:6a00:852:b0:528:c669:ad65 with SMTP id q18-20020a056a00085200b00528c669ad65mr14220799pfk.75.1657472497469; Sun, 10 Jul 2022 10:01:37 -0700 (PDT) Received: from anisinha-lenovo.ba.nuagenetworks.net ([115.96.107.107]) by smtp.googlemail.com with ESMTPSA id u14-20020a17090341ce00b0016c19417495sm2930596ple.239.2022.07.10.10.01.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jul 2022 10:01:37 -0700 (PDT) From: Ani Sinha To: qemu-devel@nongnu.org Cc: thuth@redhat.com, peter.maydell@linaro.org, berrange@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, imammedo@redhat.com, mst@redhat.com, Ani Sinha Subject: [PATCH v2 08/11] acpi/tests/bits: add biosbits config file for running bios tests Date: Sun, 10 Jul 2022 22:30:11 +0530 Message-Id: <20220710170014.1673480-9-ani@anisinha.ca> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710170014.1673480-1-ani@anisinha.ca> References: <20220710170014.1673480-1-ani@anisinha.ca> MIME-Version: 1.0 Received-SPF: none client-ip=2607:f8b0:4864:20::52d; envelope-from=ani@anisinha.ca; helo=mail-pg1-x52d.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This change adds initial biosbits config file that instructs biosbits to run bios test suits in batch mode. Additionally acpi and smbios structures are also dumped. Signed-off-by: Ani Sinha --- .../pytest/acpi-bits/bits-config/bits-cfg.txt | 18 ++++++++++++++++++ tests/pytest/acpi-bits/bits-config/meson.build | 11 +++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/pytest/acpi-bits/bits-config/bits-cfg.txt create mode 100644 tests/pytest/acpi-bits/bits-config/meson.build diff --git a/tests/pytest/acpi-bits/bits-config/bits-cfg.txt b/tests/pytest/acpi-bits/bits-config/bits-cfg.txt new file mode 100644 index 0000000000..8010804453 --- /dev/null +++ b/tests/pytest/acpi-bits/bits-config/bits-cfg.txt @@ -0,0 +1,18 @@ +# BITS configuration file +[bits] + +# To run BITS in batch mode, set batch to a list of one or more of the +# following keywords; BITS will then run all of the requested operations, then +# save the log file to disk. +# +# test: Run the full BITS testsuite. +# acpi: Dump all ACPI structures. +# smbios: Dump all SMBIOS structures. +# +# Leave batch set to an empty string to disable batch mode. +# batch = + +# Uncomment the following to run all available batch operations +# please take a look at boot/python/init.py in bits zip file +# to see how these options are parsed and used. +batch = test acpi smbios diff --git a/tests/pytest/acpi-bits/bits-config/meson.build b/tests/pytest/acpi-bits/bits-config/meson.build new file mode 100644 index 0000000000..bbd7a940dc --- /dev/null +++ b/tests/pytest/acpi-bits/bits-config/meson.build @@ -0,0 +1,11 @@ +config_files = ['bits-cfg.txt'] + +copycfgfiles = custom_target('copy cfg files', + input : config_files, + output : config_files, + command : ['cp', '@INPUT@', '@OUTPUT@'], + install : true, + install_dir : 'bits-config', + build_by_default : true) + +other_deps += copycfgfiles From patchwork Sun Jul 10 17:00:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ani Sinha X-Patchwork-Id: 12912587 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F1BFDC433EF for ; Sun, 10 Jul 2022 17:12:05 +0000 (UTC) Received: from localhost ([::1]:51898 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oAaTU-0003B9-0G for qemu-devel@archiver.kernel.org; Sun, 10 Jul 2022 13:12:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54086) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oAaJj-0007Vx-Gb for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:02:00 -0400 Received: from mail-pg1-x534.google.com ([2607:f8b0:4864:20::534]:43742) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oAaJT-0003RB-1s for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:59 -0400 Received: by mail-pg1-x534.google.com with SMTP id 73so2911239pgb.10 for ; Sun, 10 Jul 2022 10:01:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anisinha-ca.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rqrck3b6ak37lapLRK1FZzy7J4xATzPy0icWi2Ir0wI=; b=eCb2gJkLmYc03PNTcoTuqELwNun4ImFsoGlP4B36UdTZnRmuvxOlROXBlElHYm9uAS /ea83jcutn10lydRF9yLhyaa1+fE/Hna/5P+GlDBz3mWdVg9Ga8D5spKvvsszJqNdaZr OJu48W7FzDIZfy9U5C3RWriWdntWHp3aIJovhSbemH+enAXenRR6n1dvzI6Uw7klyw2p OvVPyJCRi2Q+Mq/yOW+gN6g8rUyfI0iDRjyJdEMTckm0/RQPZYCuf6P4OQaGbcU+3NV+ R1JzI0HSwc0rHwutBjk0Ic0JvSWahbv5QRuBeDCg3sR0GL52Ejj1W3QnubyroaTaF6ig Tmkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rqrck3b6ak37lapLRK1FZzy7J4xATzPy0icWi2Ir0wI=; b=geYogkeesN9oZ2Ppoim/XRKIPaei+/9C4ef+Cuy6PpLDXmON41r8oJMSX3x1kxLZFF 2MVW3W0s3sdGR2YcoxVKFAtJJYzu5ua7+qAGY22YlHXSHEIWoqkaF9dUvdsSIXm2PsbP nCXLhVNOpO4RtJdDazE/aRZFGy7ec7nt2JvZ8oA7VWfkM7w7Ukgmc31xDlUpwj904f0H e/q8Msq0VnrkeblTksCXpizyHuixZlbvsmxTkyewq0zbqD23aD/DHPc4cwBZ7a+nW/Mk oA8ls2WQ5n0tyxVCy4sYvwgr09GvIC8aMBqlVXotI6a1WKWVUI1BL/XRkEtHfcgcj7zP FV/A== X-Gm-Message-State: AJIora/+cEQz3uZqBkwyDJpGIuZkFJAgxT5B89e6v3BxVqFu5fscO78q 6bXWinfwviu4yqtk94izyr4jvYknnCcQXcLt X-Google-Smtp-Source: AGRyM1vozyzLldIBOjobmfXhLs0RBcSLw7l2rPzfgu9H+DB/axJ16xNKB8cSt4S1GhApi6wVBav3lw== X-Received: by 2002:a62:2544:0:b0:52a:c1dd:8837 with SMTP id l65-20020a622544000000b0052ac1dd8837mr5691307pfl.85.1657472501156; Sun, 10 Jul 2022 10:01:41 -0700 (PDT) Received: from anisinha-lenovo.ba.nuagenetworks.net ([115.96.107.107]) by smtp.googlemail.com with ESMTPSA id u14-20020a17090341ce00b0016c19417495sm2930596ple.239.2022.07.10.10.01.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jul 2022 10:01:40 -0700 (PDT) From: Ani Sinha To: qemu-devel@nongnu.org, Ani Sinha Cc: thuth@redhat.com, peter.maydell@linaro.org, berrange@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, imammedo@redhat.com, mst@redhat.com Subject: [PATCH v2 09/11] acpi/tests/bits: add a README file describing bits pytests Date: Sun, 10 Jul 2022 22:30:12 +0530 Message-Id: <20220710170014.1673480-10-ani@anisinha.ca> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710170014.1673480-1-ani@anisinha.ca> References: <20220710170014.1673480-1-ani@anisinha.ca> MIME-Version: 1.0 Received-SPF: none client-ip=2607:f8b0:4864:20::534; envelope-from=ani@anisinha.ca; helo=mail-pg1-x534.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" A README file is added describing the directory structure and the purpose of every file it contains. It also describes the test added, how to add new tests, make changes to existing tests or bits config files or regenerate the bios bits software binaries. Signed-off-by: Ani Sinha --- tests/pytest/acpi-bits/README | 129 ++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 tests/pytest/acpi-bits/README diff --git a/tests/pytest/acpi-bits/README b/tests/pytest/acpi-bits/README new file mode 100644 index 0000000000..be2ddba8ec --- /dev/null +++ b/tests/pytest/acpi-bits/README @@ -0,0 +1,129 @@ +============================================================================= +ACPI/SMBIOS PYTESTS USING BIOSBITS +============================================================================= + +Biosbits is a software written by Josh Triplett that can be downloaded by +visiting https://biosbits.org/. The github codebase can be found here: +https://github.com/biosbits/bits/tree/master. It is a software that executes +the bios components such as acpi and smbios tables directly through acpica +bios interpreter (a freely available C based library written by Intel, +downloadable from https://acpica.org/ and is included with biosbits) without an +operating system getting involved in between. +There are several advantages to directly testing the bios in a real physical +machine or VM as opposed to indirectly discovering bios issues through the +operating system. For one thing, the OSes tend to hide bios problems from the +end user. The other is that we have more control of what we wanted to test +and how by directly using acpica interpreter on top of the bios on a running +system. More details on the inspiration for developing biosbits and its real +life uses can be found in (a) and (b). +This directory contains QEMU pytests written in python that tests the QEMU +bios components using biosbits and reports test failures. + +These tests use python virtual environment. In debian/ubuntu system, the tests +would require python3.8-venv and python3-pip packages to be installed. + +A brief description of the contents of this directory follows: + +├── acpi-bits-test.py +├── acpi-bits-test-venv.sh +├── bits-config +│ ├── bits-cfg.txt +│ └── meson.build +├── bits-tests +│ ├── meson.build +│ ├── smbios.py +│ ├── smilatency.py +│ ├── testacpi.py +│ └── testcpuid.py +├── meson.build +├── README +└── requirements.txt + +acpi-bits: + - acpi-bits-test-venv.sh: This is a shell script that sets up the virtual + environment necessary for the actual python test script to run. Amongst + other things, it makes sure that QEMU python library is available within + that venv so that QEMU machines can be forked. QEMU python library can be + found within python/ directory in QEMU source. + After setting up the virtual environment, it runs the python test script + from within that environment. + If you want to enable verbose mode only for bits test and run make check, + one trick is to add V=1 before the call to execute the python script in + this file. + - acpi-bits-test.py: This is the main python test script that generates a + biosbits iso. It then spawns a QEMU VM with it, collects the logs and reports + test failures. This is the script one would be interested in if they wanted + to add or change some component of the log parsing, add a new command line to + how QEMU is spawned etc. Test writers typically would not need to modify + this script unless they wanted to enhance or change the log parsing for + their tests. Following environment variables are used in this test: + - PYTEST_QEMU_BINARY : This should point to the QEMU binary that is being + tested. Passing this environment variable is mandatory. + - PYTEST_BITSLOC : This is the location that should point to the grub tar + archive and the bios bits zip archive needed for this test. If they are + absent in that location, the test is skipped. If this environment + variable is not passed, the test would first check within the prebuilt/ + subdirectory to see if those binaries already exists. If they do, then + the test would use them. If those binaries are absent, the test would + try to download them from a remote repository. If the download fails, + the test is skipped. If the download succeeds, the test uses the + downloaded binaries. + When the user wants to run the test in offline mode, this environment + variable is very useful. The user can check out the bios bits archive + earlier when connectivity existed. Then in the offline mode, the user + can point this environment variable to the location where the archives + were downloaded and run the test. + - V=1 : This enables verbose mode for the test. It dumps the entire log + from bios bits and also more details in case failure happens. It is + useful for debugging the test failures or tests themselves. + - PYTEST_PWD : Present working directory where the test would look for + the QEMU binary. Optional. + +- requirements.txt: This text file contains the dependent python libraries + needed for the tests to run. If a new dependent library is needed, it would + be added here as a new entry and then acpi-bits-test-venv.sh would install + it when setting up the python virtual environment using pip. + - README: This text file. + +acpi-bits/bits-config: + This location contains biosbits config files that determine how the software + runs the tests. + - bits-config.txt: this is the biosbits config file that determines what tests + or actions are performed by bits. The description of the config options are + provided in the file itself. + +acpi-bits/bits-tests: + This directory contains biosbits python based tests that are run from within + the biosbits environment in the spawned VM. New additions of test cases can + be made in the appropriate test file. For example, new acpi tests can go + into testacpi.py and one would call testsuite.add_test() to register the new + test so that it gets executed as a part of the ACPI tests. + It might be occasionally necessary to disable some subtests or add a new + test that belongs to a test suite not already present in this directory. To + do this, please extract the bits source from the zip file mentioned above. + Copy the test suite/script that needs modification (addition of new tests + or disabling them) from boot/python location of the extracted directory + into this directory. + + step (a): copy unmodified test script to this directory. + step (b): update meson.build and add this file to the list. + Commit (a) and (b) together in the same commit. + + step (c): perform modifications to the test. + Commit (c) in a separate commit. + + The test framework will then use your modified test script to run the test. + No further changes would be needed. Please check the logs to make sure that + appropriate changes have taken effect. + +meson.build files makes sure that the bits pytests are appropriately integrated +into the QEMU pytest framework and are run with "make check-pytest". +Currently, the bits test is configured to run only for x86_64 architectures. Bits +has been built only for this architecture. + + +Author: Ani Sinha + +References: +(a) https://blog.linuxplumbersconf.org/2011/ocw/system/presentations/867/original/bits.pdf +(b) https://www.youtube.com/watch?v=36QIepyUuhg From patchwork Sun Jul 10 17:00:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ani Sinha X-Patchwork-Id: 12912583 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CB4B7C43334 for ; Sun, 10 Jul 2022 17:07:30 +0000 (UTC) Received: from localhost ([::1]:43782 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oAaP3-00060t-OM for qemu-devel@archiver.kernel.org; Sun, 10 Jul 2022 13:07:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54034) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oAaJY-0007QL-6h for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:48 -0400 Received: from mail-pj1-x1034.google.com ([2607:f8b0:4864:20::1034]:36355) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oAaJW-0003RZ-Bl for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:47 -0400 Received: by mail-pj1-x1034.google.com with SMTP id z12-20020a17090a7b8c00b001ef84000b8bso6242265pjc.1 for ; Sun, 10 Jul 2022 10:01:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anisinha-ca.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tBe6RKRbi5QkFNalJayEoxBpVJ/vYkp2hV9cPSW8tWU=; b=eaiQK+0OIK6V9RSC7QixbETEeVNXsfB4AVW0CmP7rEBYGrnHgYtMsd2Pehk6UL71rW UGysn4Zyz7rxaguVi6fMKErEof08KS5j7E60+mOUR6fMlbFND2fjC+a+uei5Rs6agQ2o DB1F0EoG2V7AwEmMLhVeV8YDmJoaTnbJpP1YaYYpyQAWlVqmXlxERLbiTJXArSpOD+Jh lO62l8uESyPVR3v1c1MN9S5VQw8PNIt0xgNuH/TRrKXfnTp4EgQtrvXtluDjNkw+PqMz 32GDd5rBv2JVb6x2lK1gfBoDWfN28Yig+3dimEgqdLuWUgfcnmRxtwWel6mZWTZXKQ70 5H3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tBe6RKRbi5QkFNalJayEoxBpVJ/vYkp2hV9cPSW8tWU=; b=HjaCXxZHCWRRrTjG6mvkVXsGOG23piGCoSeHQR2KmHzOxhmDohZcmudthBQoSp0R/D DCPIfpjRdGqpMJKgthz0+93Zna1cfR0gVTDUpxD+fwn+Veo5zB8d86URzrvCzf+ageMt 4sZj/Qf5pw2hDQ9Itp87fBw1Tbw24N8/FtVjeCI+ZG/sRjB5D2HtsQEzLpU5pHPBT9r0 fub2cY7lPCC+zEXsm34KEiZjjevcLQ1L3sXbDiFqUdSyfR3ekuNJG1ltHDOhbZR8RpRD RFXftmXhy6/RZHvA/2cmmlceN1VUsNKI/OyfR7pi8Q0InlRNEBM819UKFYzXCKyjONgW biYg== X-Gm-Message-State: AJIora+afv3n0/SjFpqRw8tJHZxHVmuDNVLH7zWlkB19XrBOvavltIo5 zdYtajr2N0VgFJjQUEuim0f9yN/vw/dtJ4Za X-Google-Smtp-Source: AGRyM1sDkbb29AE1SG5w/dQULWS11YcvC7Bqt5QKiPy/ty6uBBlgSxXsdB5K3VnyorWJLNDi8EinyQ== X-Received: by 2002:a17:902:cf4b:b0:16c:4634:72 with SMTP id e11-20020a170902cf4b00b0016c46340072mr1757964plg.15.1657472504844; Sun, 10 Jul 2022 10:01:44 -0700 (PDT) Received: from anisinha-lenovo.ba.nuagenetworks.net ([115.96.107.107]) by smtp.googlemail.com with ESMTPSA id u14-20020a17090341ce00b0016c19417495sm2930596ple.239.2022.07.10.10.01.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jul 2022 10:01:44 -0700 (PDT) From: Ani Sinha To: qemu-devel@nongnu.org Cc: thuth@redhat.com, peter.maydell@linaro.org, berrange@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, imammedo@redhat.com, mst@redhat.com, Ani Sinha Subject: [PATCH v2 10/11] pytest: add pytest to the meson build system Date: Sun, 10 Jul 2022 22:30:13 +0530 Message-Id: <20220710170014.1673480-11-ani@anisinha.ca> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710170014.1673480-1-ani@anisinha.ca> References: <20220710170014.1673480-1-ani@anisinha.ca> MIME-Version: 1.0 Received-SPF: none client-ip=2607:f8b0:4864:20::1034; envelope-from=ani@anisinha.ca; helo=mail-pj1-x1034.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Integrate the pytest framework with the meson build system. This will make meson run all the pytests under the pytest directory. Signed-off-by: Ani Sinha --- tests/Makefile.include | 4 +++- tests/meson.build | 1 + tests/pytest/meson.build | 49 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/pytest/meson.build diff --git a/tests/Makefile.include b/tests/Makefile.include index 3accb83b13..40755a6bd1 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -3,12 +3,14 @@ .PHONY: check-help check-help: @echo "Regression testing targets:" - @echo " $(MAKE) check Run block, qapi-schema, unit, softfloat, qtest and decodetree tests" + @echo " $(MAKE) check Run block, qapi-schema, unit, softfloat, qtest, pytest and decodetree tests" @echo " $(MAKE) bench Run speed tests" @echo @echo "Individual test suites:" @echo " $(MAKE) check-qtest-TARGET Run qtest tests for given target" @echo " $(MAKE) check-qtest Run qtest tests" + @echo " $(MAKE) check-pytest Run pytest tests" + @echo " $(MAKE) check-pytest-TARGET Run pytest for a given target" @echo " $(MAKE) check-unit Run qobject tests" @echo " $(MAKE) check-qapi-schema Run QAPI schema tests" @echo " $(MAKE) check-block Run block tests" diff --git a/tests/meson.build b/tests/meson.build index 8e318ec513..f344cbdc6c 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -93,3 +93,4 @@ subdir('unit') subdir('qapi-schema') subdir('qtest') subdir('migration') +subdir('pytest') diff --git a/tests/pytest/meson.build b/tests/pytest/meson.build new file mode 100644 index 0000000000..e60d481ae4 --- /dev/null +++ b/tests/pytest/meson.build @@ -0,0 +1,49 @@ +slow_pytests = { + 'acpi-bits' : 120, +} + +pytests_generic = [] + +# biosbits tests are currenly only supported on x86_64 platforms. +pytests_x86_64 = ['acpi-bits-test'] + +pytest_executables = {} +other_deps = [] + +subdir('acpi-bits') + +foreach dir : target_dirs + if not dir.endswith('-softmmu') + continue + endif + + target_base = dir.split('-')[0] + pytest_emulator = emulators['qemu-system-' + target_base] + target_pytests = get_variable('pytests_' + target_base, []) + pytests_generic + + test_deps = roms + pytest_env = environment() + if have_tools + pytest_env.set('QTEST_QEMU_IMG', './qemu-img') + test_deps += [qemu_img] + endif + pytest_env.set('G_TEST_DBUS_DAEMON', meson.project_source_root() / 'tests/dbus-vmstate-daemon.sh') + pytest_env.set('PYTEST_QEMU_BINARY', './qemu-system-' + target_base) + pytest_env.set('PYTEST_SOURCE_ROOT', meson.project_source_root()) + if have_tools and have_vhost_user_blk_server + pytest_env.set('PYTEST_QEMU_STORAGE_DAEMON_BINARY', './storage-daemon/qemu-storage-daemon') + test_deps += [qsd] + endif + + foreach test : target_pytests + test('pytest-@0@/@1@'.format(target_base, test), + pytest_executables[test], + depends: [test_deps, pytest_emulator, emulator_modules, other_deps], + env: pytest_env, + args: ['--tap', '-k'], + protocol: 'tap', + timeout: slow_pytests.get(test, 30), + priority: slow_pytests.get(test, 30), + suite: ['pytest', 'pytest-' + target_base]) + endforeach +endforeach From patchwork Sun Jul 10 17:00:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ani Sinha X-Patchwork-Id: 12912591 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DE52EC43334 for ; Sun, 10 Jul 2022 17:16:00 +0000 (UTC) Received: from localhost ([::1]:33716 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oAaXH-0001dI-TB for qemu-devel@archiver.kernel.org; Sun, 10 Jul 2022 13:15:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:54076) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oAaJb-0007Sx-2z for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:56 -0400 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]:44939) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oAaJZ-0003Pd-ER for qemu-devel@nongnu.org; Sun, 10 Jul 2022 13:01:50 -0400 Received: by mail-pl1-x635.google.com with SMTP id q5so2628218plr.11 for ; Sun, 10 Jul 2022 10:01:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anisinha-ca.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1v3/wckqq7KYJ7X9Xr1gO9bYq9x/4QI0yUUksHCTono=; b=WmmMk/Iroz6NbMzSZfIo8F6ADU7f9IPArGeSrbl+Ogl4pIU4zLBs3zd77NKQCncLjR 05eFysX1RAp9gfUIadf6awnjJ9o1ZW/Co2Jk2bLIJF6cyXy+cEe3bwvsbhND1q+EJJgX wUjqGVL/lcYIlMcGURA/DY1aR2m4pbpoRbuxnP2xgvPU5h5F5vb0gGmVNkaNrGuUtW56 /lNwoxB0hUSqyt14rqFABMfjqr+ELyHrNuIAC8fOyeLIWDPge4ANazq5QC3uzgWEkF/c 03xrkb3pS02Z9aYUB5hDtZlM/B04i7YrLYoEl3Km/8bSaA87xCSV+g35fcmeal1UMdV5 wBKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1v3/wckqq7KYJ7X9Xr1gO9bYq9x/4QI0yUUksHCTono=; b=t5u9YpebUfOJoTXQ8wnJPBbaObDXlNyAgzV00w4aCWXr9XDUqlPkGa6fORGsYsqGP9 f7hHZlV2SMiiaa151jiVXhD/Tpe0KxDbQZ3BWasEIpM9CIfQ84X/S4uNZHNG4mvuet8A WQdoq5n4CABdce6XjmLsOrzmWl+tck2l8GA28FRRe2jNgrS34AeytH8na3u+W1phTU+L +MtLR4nJFWmRTEFrNnQOjwZb5xBtGmgsGTbwTRttNpZUGmfDtBnK29sZ6nGSu1FIUEbs 6DvA3g8hFsXdqAYd68CiHVx/H7IqXNglQghB+9qxzWTCHHF7UfdzMFkw6Fmm9X4yNvYN brlw== X-Gm-Message-State: AJIora9ERGl6O56vtYX40HEnK7YIxDOk0EoNi2z2NXoOQGvDX/FxWv1D 1TfFi4kPBg2evVmVwymBm4od+J5XMqXX1svt X-Google-Smtp-Source: AGRyM1stLIXRSIWgVUYpE1/9c1LT12/9GyCXQKeTl+MfoC8gXrZ6oDhalFzbWo0QCJINfTz13J+k9w== X-Received: by 2002:a17:90b:3a8b:b0:1f0:127:360d with SMTP id om11-20020a17090b3a8b00b001f00127360dmr12783517pjb.64.1657472508542; Sun, 10 Jul 2022 10:01:48 -0700 (PDT) Received: from anisinha-lenovo.ba.nuagenetworks.net ([115.96.107.107]) by smtp.googlemail.com with ESMTPSA id u14-20020a17090341ce00b0016c19417495sm2930596ple.239.2022.07.10.10.01.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jul 2022 10:01:48 -0700 (PDT) From: Ani Sinha To: qemu-devel@nongnu.org Cc: thuth@redhat.com, peter.maydell@linaro.org, berrange@redhat.com, jsnow@redhat.com, pbonzini@redhat.com, imammedo@redhat.com, mst@redhat.com, Ani Sinha Subject: [PATCH v2 11/11] MAINTAINERS: add myself as the maintainer for acpi biosbits pytests Date: Sun, 10 Jul 2022 22:30:14 +0530 Message-Id: <20220710170014.1673480-12-ani@anisinha.ca> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710170014.1673480-1-ani@anisinha.ca> References: <20220710170014.1673480-1-ani@anisinha.ca> MIME-Version: 1.0 Received-SPF: none client-ip=2607:f8b0:4864:20::635; envelope-from=ani@anisinha.ca; helo=mail-pl1-x635.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" I wrote the biosbits test framework, the pytest for testing QEMU with biosbits and all the related changes. Making myself as the maintainer for biosbits related files and test scripts. Signed-off-by: Ani Sinha --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index aaa649a50d..32fbd27b66 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1860,6 +1860,11 @@ S: Supported F: hw/acpi/viot.c F: hw/acpi/viot.h +ACPI/PYTEST/BIOSBITS +M: Ani Sinha +S: Supported +F: tests/pytest/acpi-bits/* + ACPI/HEST/GHES R: Dongjiu Geng L: qemu-arm@nongnu.org