aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/avocado/acpi-bits/bits-tests/smilatency.py2106
1 files changed, 106 insertions, 0 deletions
diff --git a/tests/avocado/acpi-bits/bits-tests/smilatency.py2 b/tests/avocado/acpi-bits/bits-tests/smilatency.py2
new file mode 100644
index 0000000..48083bf
--- /dev/null
+++ b/tests/avocado/acpi-bits/bits-tests/smilatency.py2
@@ -0,0 +1,106 @@
+# Copyright (c) 2015, Intel Corporation
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of Intel Corporation nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This script runs only from the biosbits VM.
+
+"""SMI latency test."""
+
+import bits
+from collections import namedtuple
+import testsuite
+import time
+import usb
+
+def register_tests():
+ testsuite.add_test("SMI latency test", smi_latency);
+ testsuite.add_test("SMI latency test with USB disabled via BIOS handoff", test_with_usb_disabled, runall=False);
+
+def smi_latency():
+ MSR_SMI_COUNT = 0x34
+
+ print "Warning: touching the keyboard can affect the results of this test."
+
+ tsc_per_sec = bits.tsc_per_sec()
+ tsc_per_usec = tsc_per_sec / (1000 * 1000)
+ bins = [long(tsc_per_usec * 10**i) for i in range(9)]
+ bin_descs = [
+ "0 < t <= 1us",
+ "1us < t <= 10us",
+ "10us < t <= 100us",
+ "100us < t <= 1ms",
+ "1ms < t <= 10ms",
+ "10ms < t <= 100ms",
+ "100ms < t <= 1s ",
+ "1s < t <= 10s ",
+ "10s < t <= 100s ",
+ "100s < t ",
+ ]
+
+ print "Starting test. Wait here, I will be back in 15 seconds."
+ (max_latency, smi_count_delta, bins) = bits.smi_latency(long(15 * tsc_per_sec), bins)
+ BinType = namedtuple('BinType', ("max", "total", "count", "times"))
+ bins = [BinType(*b) for b in bins]
+
+ testsuite.test("SMI latency < 150us to minimize risk of OS timeouts", max_latency / tsc_per_usec <= 150)
+ if not testsuite.show_detail():
+ return
+
+ for bin, desc in zip(bins, bin_descs):
+ if bin.count == 0:
+ continue
+ testsuite.print_detail("{}; average = {}; count = {}".format(desc, bits.format_tsc(bin.total/bin.count), bin.count))
+ deltas = (bits.format_tsc(t2 - t1) for t1,t2 in zip(bin.times, bin.times[1:]))
+ testsuite.print_detail(" Times between first few observations: {}".format(" ".join("{:>6}".format(delta) for delta in deltas)))
+
+ if smi_count_delta is not None:
+ testsuite.print_detail("{} SMI detected using MSR_SMI_COUNT (MSR {:#x})".format(smi_count_delta, MSR_SMI_COUNT))
+
+ testsuite.print_detail("Summary of impact: observed maximum latency = {}".format(bits.format_tsc(max_latency)))
+
+def test_with_usb_disabled():
+ if usb.handoff_to_os():
+ smi_latency()
+
+def average_io_smi(port, value, count):
+ def f():
+ tsc_start = bits.rdtsc()
+ bits.outb(port, value)
+ return bits.rdtsc() - tsc_start
+ counts = [f() for i in range(count)]
+ return sum(counts)/len(counts)
+
+def time_io_smi(port=0xb2, value=0, count=1000):
+ count_for_estimate = 10
+ start = time.time()
+ average_io_smi(port, value, count_for_estimate)
+ avg10 = time.time() - start
+ estimate = avg10 * count/count_for_estimate
+ if estimate > 1:
+ print "Running test, estimated time: {}s".format(int(estimate))
+ average = average_io_smi(port, value, count)
+ print "Average of {} SMIs (via outb, port={:#x}, value={:#x}): {}".format(count, port, value, bits.format_tsc(average))