qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

testacpi.py2 (14628B)


      1 # Copyright (c) 2015, Intel Corporation
      2 # All rights reserved.
      3 #
      4 # Redistribution and use in source and binary forms, with or without
      5 # modification, are permitted provided that the following conditions are met:
      6 #
      7 #     * Redistributions of source code must retain the above copyright notice,
      8 #       this list of conditions and the following disclaimer.
      9 #     * Redistributions in binary form must reproduce the above copyright notice,
     10 #       this list of conditions and the following disclaimer in the documentation
     11 #       and/or other materials provided with the distribution.
     12 #     * Neither the name of Intel Corporation nor the names of its contributors
     13 #       may be used to endorse or promote products derived from this software
     14 #       without specific prior written permission.
     15 #
     16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
     20 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     21 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     23 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     25 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 """Tests for ACPI"""
     28 
     29 import acpi
     30 import bits
     31 import bits.mwait
     32 import struct
     33 import testutil
     34 import testsuite
     35 import time
     36 
     37 def register_tests():
     38     testsuite.add_test("ACPI _MAT (Multiple APIC Table Entry) under Processor objects", test_mat, submenu="ACPI Tests")
     39 #    testsuite.add_test("ACPI _PSS (Pstate) table conformance tests", test_pss, submenu="ACPI Tests")
     40 #    testsuite.add_test("ACPI _PSS (Pstate) runtime tests", test_pstates, submenu="ACPI Tests")
     41     testsuite.add_test("ACPI DSDT (Differentiated System Description Table)", test_dsdt, submenu="ACPI Tests")
     42     testsuite.add_test("ACPI FACP (Fixed ACPI Description Table)", test_facp, submenu="ACPI Tests")
     43     testsuite.add_test("ACPI HPET (High Precision Event Timer Table)", test_hpet, submenu="ACPI Tests")
     44     testsuite.add_test("ACPI MADT (Multiple APIC Description Table)", test_apic, submenu="ACPI Tests")
     45     testsuite.add_test("ACPI MPST (Memory Power State Table)", test_mpst, submenu="ACPI Tests")
     46     testsuite.add_test("ACPI RSDP (Root System Description Pointer Structure)", test_rsdp, submenu="ACPI Tests")
     47     testsuite.add_test("ACPI XSDT (Extended System Description Table)", test_xsdt, submenu="ACPI Tests")
     48 
     49 def test_mat():
     50     cpupaths = acpi.get_cpupaths()
     51     apic = acpi.parse_apic()
     52     procid_apicid = apic.procid_apicid
     53     uid_x2apicid = apic.uid_x2apicid
     54     for cpupath in cpupaths:
     55         # Find the ProcId defined by the processor object
     56         processor = acpi.evaluate(cpupath)
     57         # Find the UID defined by the processor object's _UID method
     58         uid = acpi.evaluate(cpupath + "._UID")
     59         mat_buffer = acpi.evaluate(cpupath + "._MAT")
     60         if mat_buffer is None:
     61             continue
     62         # Process each _MAT subtable
     63         mat = acpi._MAT(mat_buffer)
     64         for index, subtable in enumerate(mat):
     65             if subtable.subtype == acpi.MADT_TYPE_LOCAL_APIC:
     66                 if subtable.flags.bits.enabled:
     67                     testsuite.test("{} Processor declaration ProcId = _MAT ProcId".format(cpupath), processor.ProcId == subtable.proc_id)
     68                     testsuite.print_detail("{} ProcId ({:#02x}) != _MAT ProcId ({:#02x})".format(cpupath, processor.ProcId, subtable.proc_id))
     69                     testsuite.print_detail("Processor Declaration: {}".format(processor))
     70                     testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable))
     71                     if testsuite.test("{} with local APIC in _MAT has local APIC in MADT".format(cpupath), processor.ProcId in procid_apicid):
     72                         testsuite.test("{} ApicId derived using Processor declaration ProcId = _MAT ApicId".format(cpupath), procid_apicid[processor.ProcId] == subtable.apic_id)
     73                         testsuite.print_detail("{} ApicId derived from MADT ({:#02x}) != _MAT ApicId ({:#02x})".format(cpupath, procid_apicid[processor.ProcId], subtable.apic_id))
     74                         testsuite.print_detail("Processor Declaration: {}".format(processor))
     75                         testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable))
     76             if subtable.subtype == acpi.MADT_TYPE_LOCAL_X2APIC:
     77                 if subtable.flags.bits.enabled:
     78                     if testsuite.test("{} with x2Apic in _MAT has _UID".format(cpupath), uid is not None):
     79                         testsuite.test("{}._UID = _MAT UID".format(cpupath), uid == subtable.uid)
     80                         testsuite.print_detail("{}._UID ({:#x}) != _MAT UID ({:#x})".format(cpupath, uid, subtable.uid))
     81                         testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable))
     82                     if testsuite.test("{} with _MAT x2Apic has x2Apic in MADT".format(cpupath), subtable.uid in uid_x2apicid):
     83                         testsuite.test("{} x2ApicId derived from MADT using UID = _MAT x2ApicId".format(cpupath), uid_x2apicid[subtable.uid] == subtable.x2apicid)
     84                         testsuite.print_detail("{} x2ApicId derived from MADT ({:#02x}) != _MAT x2ApicId ({:#02x})".format(cpupath, uid_x2apicid[subtable.uid], subtable.x2apicid))
     85                         testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable))
     86 
     87 def test_pss():
     88     uniques = acpi.parse_cpu_method("_PSS")
     89     # We special-case None here to avoid a double-failure for CPUs without a _PSS
     90     testsuite.test("_PSS must be identical for all CPUs", len(uniques) <= 1 or (len(uniques) == 2 and None in uniques))
     91     for pss, cpupaths in uniques.iteritems():
     92         if not testsuite.test("_PSS must exist", pss is not None):
     93             testsuite.print_detail(acpi.factor_commonprefix(cpupaths))
     94             testsuite.print_detail('No _PSS exists')
     95             continue
     96 
     97         if not testsuite.test("_PSS must not be empty", pss.pstates):
     98             testsuite.print_detail(acpi.factor_commonprefix(cpupaths))
     99             testsuite.print_detail('_PSS is empty')
    100             continue
    101 
    102         testsuite.print_detail(acpi.factor_commonprefix(cpupaths))
    103         for index, pstate in enumerate(pss.pstates):
    104             testsuite.print_detail("P[{}]: {}".format(index, pstate))
    105 
    106         testsuite.test("_PSS must contain at most 16 Pstates", len(pss.pstates) <= 16)
    107         testsuite.test("_PSS must have no duplicate Pstates", len(pss.pstates) == len(set(pss.pstates)))
    108 
    109         frequencies = [p.core_frequency for p in pss.pstates]
    110         testsuite.test("_PSS must list Pstates in descending order of frequency", frequencies == sorted(frequencies, reverse=True))
    111 
    112         testsuite.test("_PSS must have Pstates with no duplicate frequencies", len(frequencies) == len(set(frequencies)))
    113 
    114         dissipations = [p.power for p in pss.pstates]
    115         testsuite.test("_PSS must list Pstates in descending order of power dissipation", dissipations == sorted(dissipations, reverse=True))
    116 
    117 def test_pstates():
    118     """Execute and verify frequency for each Pstate in the _PSS"""
    119     IA32_PERF_CTL = 0x199
    120     with bits.mwait.use_hint(), bits.preserve_msr(IA32_PERF_CTL):
    121         cpupath_procid = acpi.find_procid()
    122         cpupath_uid = acpi.find_uid()
    123         apic = acpi.parse_apic()
    124         procid_apicid = apic.procid_apicid
    125         uid_x2apicid = apic.uid_x2apicid
    126         def cpupath_apicid(cpupath):
    127             if procid_apicid is not None:
    128                 procid = cpupath_procid.get(cpupath, None)
    129                 if procid is not None:
    130                     apicid = procid_apicid.get(procid, None)
    131                     if apicid is not None:
    132                         return apicid
    133             if uid_x2apicid is not None:
    134                 uid = cpupath_uid.get(cpupath, None)
    135                 if uid is not None:
    136                     apicid = uid_x2apicid.get(uid, None)
    137                     if apicid is not None:
    138                         return apicid
    139             return bits.cpus()[0]
    140 
    141         bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000
    142 
    143         uniques = acpi.parse_cpu_method("_PSS")
    144         for pss, cpupaths in uniques.iteritems():
    145             if not testsuite.test("_PSS must exist", pss is not None):
    146                 testsuite.print_detail(acpi.factor_commonprefix(cpupaths))
    147                 testsuite.print_detail('No _PSS exists')
    148                 continue
    149 
    150             for n, pstate in enumerate(pss.pstates):
    151                 for cpupath in cpupaths:
    152                     apicid = cpupath_apicid(cpupath)
    153                     if apicid is None:
    154                         print 'Failed to find apicid for cpupath {}'.format(cpupath)
    155                         continue
    156                     bits.wrmsr(apicid, IA32_PERF_CTL, pstate.control)
    157 
    158                 # Detecting Turbo frequency requires at least 2 pstates
    159                 # since turbo frequency = max non-turbo frequency + 1
    160                 turbo = False
    161                 if len(pss.pstates) >= 2:
    162                     turbo = (n == 0 and pstate.core_frequency == (pss.pstates[1].core_frequency + 1))
    163                     if turbo:
    164                         # Needs to busywait, not sleep
    165                         start = time.time()
    166                         while (time.time() - start < 2):
    167                             pass
    168 
    169                 for duration in (0.1, 1.0):
    170                     frequency_data = bits.cpu_frequency(duration)
    171                     # Abort the test if no cpu frequency is not available
    172                     if frequency_data is None:
    173                         continue
    174                     aperf = frequency_data[1]
    175                     aperf = testutil.adjust_to_nearest(aperf, bclk/2)
    176                     aperf = int(aperf / 1000000)
    177                     if turbo:
    178                         if aperf >= pstate.core_frequency:
    179                             break
    180                     else:
    181                         if aperf == pstate.core_frequency:
    182                             break
    183 
    184                 if turbo:
    185                     testsuite.test("P{}: Turbo measured frequency {} >= expected {} MHz".format(n, aperf, pstate.core_frequency), aperf >= pstate.core_frequency)
    186                 else:
    187                     testsuite.test("P{}: measured frequency {} MHz == expected {} MHz".format(n, aperf, pstate.core_frequency), aperf == pstate.core_frequency)
    188 
    189 def test_psd_thread_scope():
    190     uniques = acpi.parse_cpu_method("_PSD")
    191     if not testsuite.test("_PSD (P-State Dependency) must exist for each processor", None not in uniques):
    192         testsuite.print_detail(acpi.factor_commonprefix(uniques[None]))
    193         testsuite.print_detail('No _PSD exists')
    194         return
    195     unique_num_dependencies = {}
    196     unique_num_entries = {}
    197     unique_revision = {}
    198     unique_domain = {}
    199     unique_coordination_type = {}
    200     unique_num_processors = {}
    201     for value, cpupaths in uniques.iteritems():
    202         unique_num_dependencies.setdefault(len(value.dependencies), []).extend(cpupaths)
    203         unique_num_entries.setdefault(value.dependencies[0].num_entries, []).extend(cpupaths)
    204         unique_revision.setdefault(value.dependencies[0].revision, []).extend(cpupaths)
    205         unique_domain.setdefault(value.dependencies[0].domain, []).extend(cpupaths)
    206         unique_coordination_type.setdefault(value.dependencies[0].coordination_type, []).extend(cpupaths)
    207         unique_num_processors.setdefault(value.dependencies[0].num_processors, []).extend(cpupaths)
    208     def detail(d, fmt):
    209         for value, cpupaths in sorted(d.iteritems(), key=(lambda (k,v): v)):
    210             testsuite.print_detail(acpi.factor_commonprefix(cpupaths))
    211             testsuite.print_detail(fmt.format(value))
    212 
    213     testsuite.test('Dependency count for each processor must be 1', unique_num_dependencies.keys() == [1])
    214     detail(unique_num_dependencies, 'Dependency count for each processor = {} (Expected 1)')
    215     testsuite.test('_PSD.num_entries must be 5', unique_num_entries.keys() == [5])
    216     detail(unique_num_entries, 'num_entries = {} (Expected 5)')
    217     testsuite.test('_PSD.revision must be 0', unique_revision.keys() == [0])
    218     detail(unique_revision, 'revision = {}')
    219     testsuite.test('_PSD.coordination_type must be 0xFE (HW_ALL)', unique_coordination_type.keys() == [0xfe])
    220     detail(unique_coordination_type, 'coordination_type = {:#x} (Expected 0xFE HW_ALL)')
    221     testsuite.test('_PSD.domain must be unique (thread-scoped) for each processor', len(unique_domain) == len(acpi.get_cpupaths()))
    222     detail(unique_domain, 'domain = {:#x} (Expected a unique value for each processor)')
    223     testsuite.test('_PSD.num_processors must be 1', unique_num_processors.keys() == [1])
    224     detail(unique_num_processors, 'num_processors = {} (Expected 1)')
    225 
    226 def test_table_checksum(data):
    227     csum = sum(ord(c) for c in data) % 0x100
    228     testsuite.test('ACPI table cumulative checksum must equal 0', csum == 0)
    229     testsuite.print_detail("Cumulative checksum = {} (Expected 0)".format(csum))
    230 
    231 def test_apic():
    232     data = acpi.get_table("APIC")
    233     if data is None:
    234         return
    235     test_table_checksum(data)
    236     apic = acpi.parse_apic()
    237 
    238 def test_dsdt():
    239     data = acpi.get_table("DSDT")
    240     if data is None:
    241         return
    242     test_table_checksum(data)
    243 
    244 def test_facp():
    245     data = acpi.get_table("FACP")
    246     if data is None:
    247         return
    248     test_table_checksum(data)
    249     facp = acpi.parse_facp()
    250 
    251 def test_hpet():
    252     data = acpi.get_table("HPET")
    253     if data is None:
    254         return
    255     test_table_checksum(data)
    256     hpet = acpi.parse_hpet()
    257 
    258 def test_mpst():
    259     data = acpi.get_table("MPST")
    260     if data is None:
    261         return
    262     test_table_checksum(data)
    263     mpst = acpi.MPST(data)
    264 
    265 def test_rsdp():
    266     data = acpi.get_table("RSD PTR ")
    267     if data is None:
    268         return
    269 
    270     # Checksum the first 20 bytes per ACPI 1.0
    271     csum = sum(ord(c) for c in data[:20]) % 0x100
    272     testsuite.test('ACPI 1.0 table first 20 bytes cummulative checksum must equal 0', csum == 0)
    273     testsuite.print_detail("Cummulative checksum = {} (Expected 0)".format(csum))
    274 
    275     test_table_checksum(data)
    276     rsdp = acpi.parse_rsdp()
    277 
    278 def test_xsdt():
    279     data = acpi.get_table("XSDT")
    280     if data is None:
    281         return
    282     test_table_checksum(data)
    283     xsdt = acpi.parse_xsdt()