187853babSAni Sinha# Copyright (c) 2015, Intel Corporation 287853babSAni Sinha# All rights reserved. 387853babSAni Sinha# 45a373924SAni Sinha# SPDX-License-Identifier: BSD-3-Clause 55a373924SAni Sinha# 687853babSAni Sinha# Redistribution and use in source and binary forms, with or without 787853babSAni Sinha# modification, are permitted provided that the following conditions are met: 887853babSAni Sinha# 987853babSAni Sinha# * Redistributions of source code must retain the above copyright notice, 1087853babSAni Sinha# this list of conditions and the following disclaimer. 1187853babSAni Sinha# * Redistributions in binary form must reproduce the above copyright notice, 1287853babSAni Sinha# this list of conditions and the following disclaimer in the documentation 1387853babSAni Sinha# and/or other materials provided with the distribution. 1487853babSAni Sinha# * Neither the name of Intel Corporation nor the names of its contributors 1587853babSAni Sinha# may be used to endorse or promote products derived from this software 1687853babSAni Sinha# without specific prior written permission. 1787853babSAni Sinha# 1887853babSAni Sinha# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 1987853babSAni Sinha# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 2087853babSAni Sinha# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2187853babSAni Sinha# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 2287853babSAni Sinha# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2387853babSAni Sinha# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2487853babSAni Sinha# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 2587853babSAni Sinha# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2687853babSAni Sinha# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 2787853babSAni Sinha# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2887853babSAni Sinha 295a373924SAni Sinha# This script runs only from the biosbits VM. 305a373924SAni Sinha 3187853babSAni Sinha"""Tests for ACPI""" 3287853babSAni Sinha 3387853babSAni Sinhaimport acpi 3487853babSAni Sinhaimport bits 3587853babSAni Sinhaimport bits.mwait 3687853babSAni Sinhaimport struct 3787853babSAni Sinhaimport testutil 3887853babSAni Sinhaimport testsuite 3987853babSAni Sinhaimport time 4087853babSAni Sinha 4187853babSAni Sinhadef register_tests(): 4287853babSAni Sinha testsuite.add_test("ACPI _MAT (Multiple APIC Table Entry) under Processor objects", test_mat, submenu="ACPI Tests") 4391cab435SAni Sinha# testsuite.add_test("ACPI _PSS (Pstate) table conformance tests", test_pss, submenu="ACPI Tests") 4491cab435SAni Sinha# testsuite.add_test("ACPI _PSS (Pstate) runtime tests", test_pstates, submenu="ACPI Tests") 4587853babSAni Sinha testsuite.add_test("ACPI DSDT (Differentiated System Description Table)", test_dsdt, submenu="ACPI Tests") 4687853babSAni Sinha testsuite.add_test("ACPI FACP (Fixed ACPI Description Table)", test_facp, submenu="ACPI Tests") 4787853babSAni Sinha testsuite.add_test("ACPI HPET (High Precision Event Timer Table)", test_hpet, submenu="ACPI Tests") 4887853babSAni Sinha testsuite.add_test("ACPI MADT (Multiple APIC Description Table)", test_apic, submenu="ACPI Tests") 4987853babSAni Sinha testsuite.add_test("ACPI MPST (Memory Power State Table)", test_mpst, submenu="ACPI Tests") 5087853babSAni Sinha testsuite.add_test("ACPI RSDP (Root System Description Pointer Structure)", test_rsdp, submenu="ACPI Tests") 5187853babSAni Sinha testsuite.add_test("ACPI XSDT (Extended System Description Table)", test_xsdt, submenu="ACPI Tests") 5287853babSAni Sinha 5387853babSAni Sinhadef test_mat(): 5487853babSAni Sinha cpupaths = acpi.get_cpupaths() 5587853babSAni Sinha apic = acpi.parse_apic() 5687853babSAni Sinha procid_apicid = apic.procid_apicid 5787853babSAni Sinha uid_x2apicid = apic.uid_x2apicid 5887853babSAni Sinha for cpupath in cpupaths: 5987853babSAni Sinha # Find the ProcId defined by the processor object 6087853babSAni Sinha processor = acpi.evaluate(cpupath) 6187853babSAni Sinha # Find the UID defined by the processor object's _UID method 6287853babSAni Sinha uid = acpi.evaluate(cpupath + "._UID") 6387853babSAni Sinha mat_buffer = acpi.evaluate(cpupath + "._MAT") 6487853babSAni Sinha if mat_buffer is None: 6587853babSAni Sinha continue 6687853babSAni Sinha # Process each _MAT subtable 6787853babSAni Sinha mat = acpi._MAT(mat_buffer) 6887853babSAni Sinha for index, subtable in enumerate(mat): 6987853babSAni Sinha if subtable.subtype == acpi.MADT_TYPE_LOCAL_APIC: 7087853babSAni Sinha if subtable.flags.bits.enabled: 7187853babSAni Sinha testsuite.test("{} Processor declaration ProcId = _MAT ProcId".format(cpupath), processor.ProcId == subtable.proc_id) 7287853babSAni Sinha testsuite.print_detail("{} ProcId ({:#02x}) != _MAT ProcId ({:#02x})".format(cpupath, processor.ProcId, subtable.proc_id)) 7387853babSAni Sinha testsuite.print_detail("Processor Declaration: {}".format(processor)) 7487853babSAni Sinha testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) 7587853babSAni Sinha if testsuite.test("{} with local APIC in _MAT has local APIC in MADT".format(cpupath), processor.ProcId in procid_apicid): 7687853babSAni Sinha testsuite.test("{} ApicId derived using Processor declaration ProcId = _MAT ApicId".format(cpupath), procid_apicid[processor.ProcId] == subtable.apic_id) 7787853babSAni Sinha testsuite.print_detail("{} ApicId derived from MADT ({:#02x}) != _MAT ApicId ({:#02x})".format(cpupath, procid_apicid[processor.ProcId], subtable.apic_id)) 7887853babSAni Sinha testsuite.print_detail("Processor Declaration: {}".format(processor)) 7987853babSAni Sinha testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) 8087853babSAni Sinha if subtable.subtype == acpi.MADT_TYPE_LOCAL_X2APIC: 8187853babSAni Sinha if subtable.flags.bits.enabled: 8287853babSAni Sinha if testsuite.test("{} with x2Apic in _MAT has _UID".format(cpupath), uid is not None): 8387853babSAni Sinha testsuite.test("{}._UID = _MAT UID".format(cpupath), uid == subtable.uid) 8487853babSAni Sinha testsuite.print_detail("{}._UID ({:#x}) != _MAT UID ({:#x})".format(cpupath, uid, subtable.uid)) 8587853babSAni Sinha testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) 8687853babSAni Sinha if testsuite.test("{} with _MAT x2Apic has x2Apic in MADT".format(cpupath), subtable.uid in uid_x2apicid): 8787853babSAni Sinha testsuite.test("{} x2ApicId derived from MADT using UID = _MAT x2ApicId".format(cpupath), uid_x2apicid[subtable.uid] == subtable.x2apicid) 8887853babSAni Sinha testsuite.print_detail("{} x2ApicId derived from MADT ({:#02x}) != _MAT x2ApicId ({:#02x})".format(cpupath, uid_x2apicid[subtable.uid], subtable.x2apicid)) 8987853babSAni Sinha testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) 9087853babSAni Sinha 9187853babSAni Sinhadef test_pss(): 9287853babSAni Sinha uniques = acpi.parse_cpu_method("_PSS") 9387853babSAni Sinha # We special-case None here to avoid a double-failure for CPUs without a _PSS 9487853babSAni Sinha testsuite.test("_PSS must be identical for all CPUs", len(uniques) <= 1 or (len(uniques) == 2 and None in uniques)) 9587853babSAni Sinha for pss, cpupaths in uniques.iteritems(): 9687853babSAni Sinha if not testsuite.test("_PSS must exist", pss is not None): 9787853babSAni Sinha testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) 9887853babSAni Sinha testsuite.print_detail('No _PSS exists') 9987853babSAni Sinha continue 10087853babSAni Sinha 10187853babSAni Sinha if not testsuite.test("_PSS must not be empty", pss.pstates): 10287853babSAni Sinha testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) 10387853babSAni Sinha testsuite.print_detail('_PSS is empty') 10487853babSAni Sinha continue 10587853babSAni Sinha 10687853babSAni Sinha testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) 10787853babSAni Sinha for index, pstate in enumerate(pss.pstates): 10887853babSAni Sinha testsuite.print_detail("P[{}]: {}".format(index, pstate)) 10987853babSAni Sinha 11087853babSAni Sinha testsuite.test("_PSS must contain at most 16 Pstates", len(pss.pstates) <= 16) 11187853babSAni Sinha testsuite.test("_PSS must have no duplicate Pstates", len(pss.pstates) == len(set(pss.pstates))) 11287853babSAni Sinha 11387853babSAni Sinha frequencies = [p.core_frequency for p in pss.pstates] 11487853babSAni Sinha testsuite.test("_PSS must list Pstates in descending order of frequency", frequencies == sorted(frequencies, reverse=True)) 11587853babSAni Sinha 11687853babSAni Sinha testsuite.test("_PSS must have Pstates with no duplicate frequencies", len(frequencies) == len(set(frequencies))) 11787853babSAni Sinha 11887853babSAni Sinha dissipations = [p.power for p in pss.pstates] 11987853babSAni Sinha testsuite.test("_PSS must list Pstates in descending order of power dissipation", dissipations == sorted(dissipations, reverse=True)) 12087853babSAni Sinha 12187853babSAni Sinhadef test_pstates(): 12287853babSAni Sinha """Execute and verify frequency for each Pstate in the _PSS""" 12387853babSAni Sinha IA32_PERF_CTL = 0x199 12487853babSAni Sinha with bits.mwait.use_hint(), bits.preserve_msr(IA32_PERF_CTL): 12587853babSAni Sinha cpupath_procid = acpi.find_procid() 12687853babSAni Sinha cpupath_uid = acpi.find_uid() 12787853babSAni Sinha apic = acpi.parse_apic() 12887853babSAni Sinha procid_apicid = apic.procid_apicid 12987853babSAni Sinha uid_x2apicid = apic.uid_x2apicid 13087853babSAni Sinha def cpupath_apicid(cpupath): 13187853babSAni Sinha if procid_apicid is not None: 13287853babSAni Sinha procid = cpupath_procid.get(cpupath, None) 13387853babSAni Sinha if procid is not None: 13487853babSAni Sinha apicid = procid_apicid.get(procid, None) 13587853babSAni Sinha if apicid is not None: 13687853babSAni Sinha return apicid 13787853babSAni Sinha if uid_x2apicid is not None: 13887853babSAni Sinha uid = cpupath_uid.get(cpupath, None) 13987853babSAni Sinha if uid is not None: 14087853babSAni Sinha apicid = uid_x2apicid.get(uid, None) 14187853babSAni Sinha if apicid is not None: 14287853babSAni Sinha return apicid 14387853babSAni Sinha return bits.cpus()[0] 14487853babSAni Sinha 14587853babSAni Sinha bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000 14687853babSAni Sinha 14787853babSAni Sinha uniques = acpi.parse_cpu_method("_PSS") 14887853babSAni Sinha for pss, cpupaths in uniques.iteritems(): 14987853babSAni Sinha if not testsuite.test("_PSS must exist", pss is not None): 15087853babSAni Sinha testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) 15187853babSAni Sinha testsuite.print_detail('No _PSS exists') 15287853babSAni Sinha continue 15387853babSAni Sinha 15487853babSAni Sinha for n, pstate in enumerate(pss.pstates): 15587853babSAni Sinha for cpupath in cpupaths: 15687853babSAni Sinha apicid = cpupath_apicid(cpupath) 15787853babSAni Sinha if apicid is None: 15887853babSAni Sinha print 'Failed to find apicid for cpupath {}'.format(cpupath) 15987853babSAni Sinha continue 16087853babSAni Sinha bits.wrmsr(apicid, IA32_PERF_CTL, pstate.control) 16187853babSAni Sinha 16287853babSAni Sinha # Detecting Turbo frequency requires at least 2 pstates 16387853babSAni Sinha # since turbo frequency = max non-turbo frequency + 1 16487853babSAni Sinha turbo = False 16587853babSAni Sinha if len(pss.pstates) >= 2: 16687853babSAni Sinha turbo = (n == 0 and pstate.core_frequency == (pss.pstates[1].core_frequency + 1)) 16787853babSAni Sinha if turbo: 16887853babSAni Sinha # Needs to busywait, not sleep 16987853babSAni Sinha start = time.time() 17087853babSAni Sinha while (time.time() - start < 2): 17187853babSAni Sinha pass 17287853babSAni Sinha 17387853babSAni Sinha for duration in (0.1, 1.0): 17487853babSAni Sinha frequency_data = bits.cpu_frequency(duration) 17587853babSAni Sinha # Abort the test if no cpu frequency is not available 17687853babSAni Sinha if frequency_data is None: 17787853babSAni Sinha continue 17887853babSAni Sinha aperf = frequency_data[1] 17987853babSAni Sinha aperf = testutil.adjust_to_nearest(aperf, bclk/2) 18087853babSAni Sinha aperf = int(aperf / 1000000) 18187853babSAni Sinha if turbo: 18287853babSAni Sinha if aperf >= pstate.core_frequency: 18387853babSAni Sinha break 18487853babSAni Sinha else: 18587853babSAni Sinha if aperf == pstate.core_frequency: 18687853babSAni Sinha break 18787853babSAni Sinha 18887853babSAni Sinha if turbo: 18987853babSAni Sinha testsuite.test("P{}: Turbo measured frequency {} >= expected {} MHz".format(n, aperf, pstate.core_frequency), aperf >= pstate.core_frequency) 19087853babSAni Sinha else: 19187853babSAni Sinha testsuite.test("P{}: measured frequency {} MHz == expected {} MHz".format(n, aperf, pstate.core_frequency), aperf == pstate.core_frequency) 19287853babSAni Sinha 19387853babSAni Sinhadef test_psd_thread_scope(): 19487853babSAni Sinha uniques = acpi.parse_cpu_method("_PSD") 19587853babSAni Sinha if not testsuite.test("_PSD (P-State Dependency) must exist for each processor", None not in uniques): 19687853babSAni Sinha testsuite.print_detail(acpi.factor_commonprefix(uniques[None])) 19787853babSAni Sinha testsuite.print_detail('No _PSD exists') 19887853babSAni Sinha return 19987853babSAni Sinha unique_num_dependencies = {} 20087853babSAni Sinha unique_num_entries = {} 20187853babSAni Sinha unique_revision = {} 20287853babSAni Sinha unique_domain = {} 20387853babSAni Sinha unique_coordination_type = {} 20487853babSAni Sinha unique_num_processors = {} 20587853babSAni Sinha for value, cpupaths in uniques.iteritems(): 20687853babSAni Sinha unique_num_dependencies.setdefault(len(value.dependencies), []).extend(cpupaths) 20787853babSAni Sinha unique_num_entries.setdefault(value.dependencies[0].num_entries, []).extend(cpupaths) 20887853babSAni Sinha unique_revision.setdefault(value.dependencies[0].revision, []).extend(cpupaths) 20987853babSAni Sinha unique_domain.setdefault(value.dependencies[0].domain, []).extend(cpupaths) 21087853babSAni Sinha unique_coordination_type.setdefault(value.dependencies[0].coordination_type, []).extend(cpupaths) 21187853babSAni Sinha unique_num_processors.setdefault(value.dependencies[0].num_processors, []).extend(cpupaths) 21287853babSAni Sinha def detail(d, fmt): 21387853babSAni Sinha for value, cpupaths in sorted(d.iteritems(), key=(lambda (k,v): v)): 21487853babSAni Sinha testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) 21587853babSAni Sinha testsuite.print_detail(fmt.format(value)) 21687853babSAni Sinha 21787853babSAni Sinha testsuite.test('Dependency count for each processor must be 1', unique_num_dependencies.keys() == [1]) 21887853babSAni Sinha detail(unique_num_dependencies, 'Dependency count for each processor = {} (Expected 1)') 21987853babSAni Sinha testsuite.test('_PSD.num_entries must be 5', unique_num_entries.keys() == [5]) 22087853babSAni Sinha detail(unique_num_entries, 'num_entries = {} (Expected 5)') 22187853babSAni Sinha testsuite.test('_PSD.revision must be 0', unique_revision.keys() == [0]) 22287853babSAni Sinha detail(unique_revision, 'revision = {}') 22387853babSAni Sinha testsuite.test('_PSD.coordination_type must be 0xFE (HW_ALL)', unique_coordination_type.keys() == [0xfe]) 22487853babSAni Sinha detail(unique_coordination_type, 'coordination_type = {:#x} (Expected 0xFE HW_ALL)') 22587853babSAni Sinha testsuite.test('_PSD.domain must be unique (thread-scoped) for each processor', len(unique_domain) == len(acpi.get_cpupaths())) 22687853babSAni Sinha detail(unique_domain, 'domain = {:#x} (Expected a unique value for each processor)') 22787853babSAni Sinha testsuite.test('_PSD.num_processors must be 1', unique_num_processors.keys() == [1]) 22887853babSAni Sinha detail(unique_num_processors, 'num_processors = {} (Expected 1)') 22987853babSAni Sinha 23087853babSAni Sinhadef test_table_checksum(data): 23187853babSAni Sinha csum = sum(ord(c) for c in data) % 0x100 23287853babSAni Sinha testsuite.test('ACPI table cumulative checksum must equal 0', csum == 0) 23387853babSAni Sinha testsuite.print_detail("Cumulative checksum = {} (Expected 0)".format(csum)) 23487853babSAni Sinha 23587853babSAni Sinhadef test_apic(): 23687853babSAni Sinha data = acpi.get_table("APIC") 23787853babSAni Sinha if data is None: 23887853babSAni Sinha return 23987853babSAni Sinha test_table_checksum(data) 24087853babSAni Sinha apic = acpi.parse_apic() 24187853babSAni Sinha 24287853babSAni Sinhadef test_dsdt(): 24387853babSAni Sinha data = acpi.get_table("DSDT") 24487853babSAni Sinha if data is None: 24587853babSAni Sinha return 24687853babSAni Sinha test_table_checksum(data) 24787853babSAni Sinha 24887853babSAni Sinhadef test_facp(): 24987853babSAni Sinha data = acpi.get_table("FACP") 25087853babSAni Sinha if data is None: 25187853babSAni Sinha return 25287853babSAni Sinha test_table_checksum(data) 25387853babSAni Sinha facp = acpi.parse_facp() 25487853babSAni Sinha 25587853babSAni Sinhadef test_hpet(): 25687853babSAni Sinha data = acpi.get_table("HPET") 25787853babSAni Sinha if data is None: 25887853babSAni Sinha return 25987853babSAni Sinha test_table_checksum(data) 26087853babSAni Sinha hpet = acpi.parse_hpet() 26187853babSAni Sinha 26287853babSAni Sinhadef test_mpst(): 26387853babSAni Sinha data = acpi.get_table("MPST") 26487853babSAni Sinha if data is None: 26587853babSAni Sinha return 26687853babSAni Sinha test_table_checksum(data) 26787853babSAni Sinha mpst = acpi.MPST(data) 26887853babSAni Sinha 26987853babSAni Sinhadef test_rsdp(): 27087853babSAni Sinha data = acpi.get_table("RSD PTR ") 27187853babSAni Sinha if data is None: 27287853babSAni Sinha return 27387853babSAni Sinha 27487853babSAni Sinha # Checksum the first 20 bytes per ACPI 1.0 27587853babSAni Sinha csum = sum(ord(c) for c in data[:20]) % 0x100 27696420a30SMichael Tokarev testsuite.test('ACPI 1.0 table first 20 bytes cumulative checksum must equal 0', csum == 0) 27796420a30SMichael Tokarev testsuite.print_detail("Cumulative checksum = {} (Expected 0)".format(csum)) 27887853babSAni Sinha 27987853babSAni Sinha test_table_checksum(data) 28087853babSAni Sinha rsdp = acpi.parse_rsdp() 28187853babSAni Sinha 28287853babSAni Sinhadef test_xsdt(): 28387853babSAni Sinha data = acpi.get_table("XSDT") 28487853babSAni Sinha if data is None: 28587853babSAni Sinha return 28687853babSAni Sinha test_table_checksum(data) 28787853babSAni Sinha xsdt = acpi.parse_xsdt() 288