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