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