qemu

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

testcpuid.py2 (4136B)


      1 # Copyright (c) 2012, 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 and helpers for CPUID."""
     28 
     29 import bits
     30 import testsuite
     31 import testutil
     32 
     33 def cpuid_helper(function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0):
     34     if index is None:
     35         index = 0
     36         indexdesc = ""
     37     else:
     38         indexdesc = " index {0:#x}".format(index)
     39 
     40     def find_mask(m):
     41         if m == ~0:
     42             return mask
     43         return m
     44     masks = map(find_mask, [eax_mask, ebx_mask, ecx_mask, edx_mask])
     45 
     46     uniques = {}
     47     for cpu in bits.cpus():
     48         regs = bits.cpuid_result(*[(r >> shift) & m for r, m in zip(bits.cpuid(cpu, function, index), masks)])
     49         uniques.setdefault(regs, []).append(cpu)
     50 
     51     desc = ["CPUID function {:#x}{}".format(function, indexdesc)]
     52 
     53     if shift != 0:
     54         desc.append("Register values have been shifted by {}".format(shift))
     55     if mask != ~0 or eax_mask != ~0 or ebx_mask != ~0 or ecx_mask != ~0 or edx_mask != ~0:
     56         desc.append("Register values have been masked:")
     57         shifted_masks = bits.cpuid_result(*[m << shift for m in masks])
     58         desc.append("Masks:           eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**shifted_masks._asdict()))
     59 
     60     if len(uniques) > 1:
     61         regvalues = zip(*uniques.iterkeys())
     62         common_masks = bits.cpuid_result(*map(testutil.find_common_mask, regvalues))
     63         common_values = bits.cpuid_result(*[v[0] & m for v, m in zip(regvalues, common_masks)])
     64         desc.append('Register values are not unique across all logical processors')
     65         desc.append("Common bits:     eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**common_values._asdict()))
     66         desc.append("Mask of common bits: {eax:#010x}     {ebx:#010x}     {ecx:#010x}     {edx:#010x}".format(**common_masks._asdict()))
     67 
     68     for regs in sorted(uniques.iterkeys()):
     69         cpus = uniques[regs]
     70         desc.append("Register value:  eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**regs._asdict()))
     71         desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus)))
     72 
     73     return uniques, desc
     74 
     75 def test_cpuid_consistency(text, function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0):
     76     uniques, desc = cpuid_helper(function, index, shift, mask, eax_mask, ebx_mask, ecx_mask, edx_mask)
     77     desc[0] += " Consistency Check"
     78     if text:
     79         desc.insert(0, text)
     80     status = testsuite.test(desc[0], len(uniques) == 1)
     81     for line in desc[1:]:
     82         testsuite.print_detail(line)
     83     return status