 05caa06242
			
		
	
	
		05caa06242
		
	
	
	
	
		
			
			Mostly a straight-forward conversion. Looks like we can simply drop the avocado datadrainer stuff when not using the avocado framework anymore. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20240830133841.142644-30-thuth@redhat.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
		
			
				
	
	
		
			108 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| # 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():
 | |
|      pass
 | |
| #    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))
 |