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