xref: /qemu/tests/functional/acpi-bits/bits-tests/smilatency.py2 (revision fc7c144b23bf6eb291691f83d885e0291850176e)
1*fc7c144bSAni Sinha# Copyright (c) 2015, Intel Corporation
2*fc7c144bSAni Sinha# All rights reserved.
3*fc7c144bSAni Sinha#
4*fc7c144bSAni Sinha# SPDX-License-Identifier: BSD-3-Clause
5*fc7c144bSAni Sinha
6*fc7c144bSAni Sinha# Redistribution and use in source and binary forms, with or without
7*fc7c144bSAni Sinha# modification, are permitted provided that the following conditions are met:
8*fc7c144bSAni Sinha#
9*fc7c144bSAni Sinha#     * Redistributions of source code must retain the above copyright notice,
10*fc7c144bSAni Sinha#       this list of conditions and the following disclaimer.
11*fc7c144bSAni Sinha#     * Redistributions in binary form must reproduce the above copyright notice,
12*fc7c144bSAni Sinha#       this list of conditions and the following disclaimer in the documentation
13*fc7c144bSAni Sinha#       and/or other materials provided with the distribution.
14*fc7c144bSAni Sinha#     * Neither the name of Intel Corporation nor the names of its contributors
15*fc7c144bSAni Sinha#       may be used to endorse or promote products derived from this software
16*fc7c144bSAni Sinha#       without specific prior written permission.
17*fc7c144bSAni Sinha#
18*fc7c144bSAni Sinha# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19*fc7c144bSAni Sinha# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20*fc7c144bSAni Sinha# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21*fc7c144bSAni Sinha# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22*fc7c144bSAni Sinha# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23*fc7c144bSAni Sinha# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24*fc7c144bSAni Sinha# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25*fc7c144bSAni Sinha# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*fc7c144bSAni Sinha# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27*fc7c144bSAni Sinha# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*fc7c144bSAni Sinha
29*fc7c144bSAni Sinha# This script runs only from the biosbits VM.
30*fc7c144bSAni Sinha
31*fc7c144bSAni Sinha"""SMI latency test."""
32*fc7c144bSAni Sinha
33*fc7c144bSAni Sinhaimport bits
34*fc7c144bSAni Sinhafrom collections import namedtuple
35*fc7c144bSAni Sinhaimport testsuite
36*fc7c144bSAni Sinhaimport time
37*fc7c144bSAni Sinhaimport usb
38*fc7c144bSAni Sinha
39*fc7c144bSAni Sinhadef register_tests():
40*fc7c144bSAni Sinha    testsuite.add_test("SMI latency test", smi_latency);
41*fc7c144bSAni Sinha    testsuite.add_test("SMI latency test with USB disabled via BIOS handoff", test_with_usb_disabled, runall=False);
42*fc7c144bSAni Sinha
43*fc7c144bSAni Sinhadef smi_latency():
44*fc7c144bSAni Sinha    MSR_SMI_COUNT = 0x34
45*fc7c144bSAni Sinha
46*fc7c144bSAni Sinha    print "Warning: touching the keyboard can affect the results of this test."
47*fc7c144bSAni Sinha
48*fc7c144bSAni Sinha    tsc_per_sec = bits.tsc_per_sec()
49*fc7c144bSAni Sinha    tsc_per_usec = tsc_per_sec / (1000 * 1000)
50*fc7c144bSAni Sinha    bins = [long(tsc_per_usec * 10**i) for i in range(9)]
51*fc7c144bSAni Sinha    bin_descs = [
52*fc7c144bSAni Sinha        "0     < t <=   1us",
53*fc7c144bSAni Sinha        "1us   < t <=  10us",
54*fc7c144bSAni Sinha        "10us  < t <= 100us",
55*fc7c144bSAni Sinha        "100us < t <=   1ms",
56*fc7c144bSAni Sinha        "1ms   < t <=  10ms",
57*fc7c144bSAni Sinha        "10ms  < t <= 100ms",
58*fc7c144bSAni Sinha        "100ms < t <=   1s ",
59*fc7c144bSAni Sinha        "1s    < t <=  10s ",
60*fc7c144bSAni Sinha        "10s   < t <= 100s ",
61*fc7c144bSAni Sinha        "100s  < t         ",
62*fc7c144bSAni Sinha    ]
63*fc7c144bSAni Sinha
64*fc7c144bSAni Sinha    print "Starting test. Wait here, I will be back in 15 seconds."
65*fc7c144bSAni Sinha    (max_latency, smi_count_delta, bins) = bits.smi_latency(long(15 * tsc_per_sec), bins)
66*fc7c144bSAni Sinha    BinType = namedtuple('BinType', ("max", "total", "count", "times"))
67*fc7c144bSAni Sinha    bins = [BinType(*b) for b in bins]
68*fc7c144bSAni Sinha
69*fc7c144bSAni Sinha    testsuite.test("SMI latency < 150us to minimize risk of OS timeouts", max_latency / tsc_per_usec <= 150)
70*fc7c144bSAni Sinha    if not testsuite.show_detail():
71*fc7c144bSAni Sinha        return
72*fc7c144bSAni Sinha
73*fc7c144bSAni Sinha    for bin, desc in zip(bins, bin_descs):
74*fc7c144bSAni Sinha        if bin.count == 0:
75*fc7c144bSAni Sinha            continue
76*fc7c144bSAni Sinha        testsuite.print_detail("{}; average = {}; count = {}".format(desc, bits.format_tsc(bin.total/bin.count), bin.count))
77*fc7c144bSAni Sinha        deltas = (bits.format_tsc(t2 - t1) for t1,t2 in zip(bin.times, bin.times[1:]))
78*fc7c144bSAni Sinha        testsuite.print_detail(" Times between first few observations: {}".format(" ".join("{:>6}".format(delta) for delta in deltas)))
79*fc7c144bSAni Sinha
80*fc7c144bSAni Sinha    if smi_count_delta is not None:
81*fc7c144bSAni Sinha        testsuite.print_detail("{} SMI detected using MSR_SMI_COUNT (MSR {:#x})".format(smi_count_delta, MSR_SMI_COUNT))
82*fc7c144bSAni Sinha
83*fc7c144bSAni Sinha    testsuite.print_detail("Summary of impact: observed maximum latency = {}".format(bits.format_tsc(max_latency)))
84*fc7c144bSAni Sinha
85*fc7c144bSAni Sinhadef test_with_usb_disabled():
86*fc7c144bSAni Sinha    if usb.handoff_to_os():
87*fc7c144bSAni Sinha        smi_latency()
88*fc7c144bSAni Sinha
89*fc7c144bSAni Sinhadef average_io_smi(port, value, count):
90*fc7c144bSAni Sinha    def f():
91*fc7c144bSAni Sinha        tsc_start = bits.rdtsc()
92*fc7c144bSAni Sinha        bits.outb(port, value)
93*fc7c144bSAni Sinha        return bits.rdtsc() - tsc_start
94*fc7c144bSAni Sinha    counts = [f() for i in range(count)]
95*fc7c144bSAni Sinha    return sum(counts)/len(counts)
96*fc7c144bSAni Sinha
97*fc7c144bSAni Sinhadef time_io_smi(port=0xb2, value=0, count=1000):
98*fc7c144bSAni Sinha    count_for_estimate = 10
99*fc7c144bSAni Sinha    start = time.time()
100*fc7c144bSAni Sinha    average_io_smi(port, value, count_for_estimate)
101*fc7c144bSAni Sinha    avg10 = time.time() - start
102*fc7c144bSAni Sinha    estimate = avg10 * count/count_for_estimate
103*fc7c144bSAni Sinha    if estimate > 1:
104*fc7c144bSAni Sinha        print "Running test, estimated time: {}s".format(int(estimate))
105*fc7c144bSAni Sinha    average = average_io_smi(port, value, count)
106*fc7c144bSAni Sinha    print "Average of {} SMIs (via outb, port={:#x}, value={:#x}): {}".format(count, port, value, bits.format_tsc(average))
107