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