10b30c4ef3de2406815678f0019889a6e80d8b097David Riley# Copyright (c) 2014 The Chromium Authors. All rights reserved.
20b30c4ef3de2406815678f0019889a6e80d8b097David Riley# Use of this source code is governed by a BSD-style license that can be
30b30c4ef3de2406815678f0019889a6e80d8b097David Riley# found in the LICENSE file.
40b30c4ef3de2406815678f0019889a6e80d8b097David Riley
5e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Rileyimport glob
60b30c4ef3de2406815678f0019889a6e80d8b097David Rileyimport logging
79483778b34c657822f43681631c0a587c5fe1085David Rileyimport os
80b30c4ef3de2406815678f0019889a6e80d8b097David Riley
90b30c4ef3de2406815678f0019889a6e80d8b097David Rileyfrom autotest_lib.client.bin import test, utils
100b30c4ef3de2406815678f0019889a6e80d8b097David Rileyfrom autotest_lib.client.common_lib import error
110b30c4ef3de2406815678f0019889a6e80d8b097David Riley
120b30c4ef3de2406815678f0019889a6e80d8b097David Rileyclass kernel_Delay(test.test):
130b30c4ef3de2406815678f0019889a6e80d8b097David Riley    """
140b30c4ef3de2406815678f0019889a6e80d8b097David Riley    Test to ensure that udelay() delays at least as long as requested
150b30c4ef3de2406815678f0019889a6e80d8b097David Riley    (as compared to ktime()).
160b30c4ef3de2406815678f0019889a6e80d8b097David Riley
170b30c4ef3de2406815678f0019889a6e80d8b097David Riley    Test a variety of delays at mininmum and maximum cpu frequencies.
180b30c4ef3de2406815678f0019889a6e80d8b097David Riley
190b30c4ef3de2406815678f0019889a6e80d8b097David Riley    """
200b30c4ef3de2406815678f0019889a6e80d8b097David Riley    version = 1
210b30c4ef3de2406815678f0019889a6e80d8b097David Riley
229483778b34c657822f43681631c0a587c5fe1085David Riley    MIN_KERNEL_VER = '3.8'
230b30c4ef3de2406815678f0019889a6e80d8b097David Riley    MODULE_NAME = 'udelay_test'
240b30c4ef3de2406815678f0019889a6e80d8b097David Riley    UDELAY_PATH = '/sys/kernel/debug/udelay_test'
25e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    QUIET_GOVERNOR_PATH = '/sys/devices/system/cpu/cpuquiet/current_governor'
26e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    GOVERNOR_GLOB = '/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor'
27e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    SETSPEED_GLOB = '/sys/devices/system/cpu/cpu*/cpufreq/scaling_setspeed'
28e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    CUR_FREQ_GLOB = '/sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq'
290b30c4ef3de2406815678f0019889a6e80d8b097David Riley    CPUFREQ_AVAIL_PATH = (
300b30c4ef3de2406815678f0019889a6e80d8b097David Riley            '/sys/devices/system/cpu/cpu0/cpufreq/'
310b30c4ef3de2406815678f0019889a6e80d8b097David Riley            'scaling_available_frequencies')
320b30c4ef3de2406815678f0019889a6e80d8b097David Riley
330b30c4ef3de2406815678f0019889a6e80d8b097David Riley    # Test a variety of delays
340b30c4ef3de2406815678f0019889a6e80d8b097David Riley    # 1..200, 200..500 (by 10), 500..2000 (by 100)
350b30c4ef3de2406815678f0019889a6e80d8b097David Riley    DELAYS = range(1, 200) + range(200, 500, 10) + range(500, 2001, 100)
360b30c4ef3de2406815678f0019889a6e80d8b097David Riley    ITERATIONS = 100
370b30c4ef3de2406815678f0019889a6e80d8b097David Riley
38e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    _governor_paths = []
39e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    _setspeed_paths = []
40e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    _cur_freq_paths = []
41e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley
420b30c4ef3de2406815678f0019889a6e80d8b097David Riley    def _set_file(self, contents, filename):
430b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
440b30c4ef3de2406815678f0019889a6e80d8b097David Riley        Write a string to a file.
450b30c4ef3de2406815678f0019889a6e80d8b097David Riley
460b30c4ef3de2406815678f0019889a6e80d8b097David Riley        @param contents: the contents to write to the file
470b30c4ef3de2406815678f0019889a6e80d8b097David Riley        @param filename: the filename to use
480b30c4ef3de2406815678f0019889a6e80d8b097David Riley
490b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
500b30c4ef3de2406815678f0019889a6e80d8b097David Riley        logging.debug('setting %s to %s', filename, contents)
510b30c4ef3de2406815678f0019889a6e80d8b097David Riley        with open(filename, 'w') as f:
520b30c4ef3de2406815678f0019889a6e80d8b097David Riley            f.write(contents)
530b30c4ef3de2406815678f0019889a6e80d8b097David Riley
540b30c4ef3de2406815678f0019889a6e80d8b097David Riley
550b30c4ef3de2406815678f0019889a6e80d8b097David Riley    def _get_file(self, filename):
560b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
570b30c4ef3de2406815678f0019889a6e80d8b097David Riley        Read a string from a file.
580b30c4ef3de2406815678f0019889a6e80d8b097David Riley
590b30c4ef3de2406815678f0019889a6e80d8b097David Riley        @returns: the contents of the file (string)
600b30c4ef3de2406815678f0019889a6e80d8b097David Riley
610b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
620b30c4ef3de2406815678f0019889a6e80d8b097David Riley        with open(filename, 'r') as f:
630b30c4ef3de2406815678f0019889a6e80d8b097David Riley            return f.read()
640b30c4ef3de2406815678f0019889a6e80d8b097David Riley
650b30c4ef3de2406815678f0019889a6e80d8b097David Riley
66e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    def _get_freqs(self):
67e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        """
68e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        Get the current CPU frequencies.
69e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley
70e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        @returns: the CPU frequencies of each CPU (list of int)
71e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley
72e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        """
73e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        return [int(self._get_file(p)) for p in self._cur_freq_paths]
74e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley
75e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley
76e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    def _get_freqs_string(self):
770b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
78e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        Get the current CPU frequencies.
790b30c4ef3de2406815678f0019889a6e80d8b097David Riley
80e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        @returns: the CPU frequencies of each CPU (string)
810b30c4ef3de2406815678f0019889a6e80d8b097David Riley
820b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
83e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        return ' '.join(str(x) for x in self._get_freqs())
840b30c4ef3de2406815678f0019889a6e80d8b097David Riley
850b30c4ef3de2406815678f0019889a6e80d8b097David Riley
86e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    def _get_governors(self):
870b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
88e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        Get the current CPU governors.
890b30c4ef3de2406815678f0019889a6e80d8b097David Riley
90e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        @returns: the CPU governors of each CPU (list of string)
910b30c4ef3de2406815678f0019889a6e80d8b097David Riley
920b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
93e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        return [self._get_file(p).rstrip() for p in self._governor_paths]
940b30c4ef3de2406815678f0019889a6e80d8b097David Riley
950b30c4ef3de2406815678f0019889a6e80d8b097David Riley
96e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    def _get_quiet_governor(self):
970b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
98e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        Get the current CPU quiet governor.
990b30c4ef3de2406815678f0019889a6e80d8b097David Riley
100e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        @returns: the CPU quiet governor or None if it does not exist (string)
1010b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1020b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
103e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        if os.path.isfile(self.QUIET_GOVERNOR_PATH):
104e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            return self._get_file(self.QUIET_GOVERNOR_PATH).rstrip()
105e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        else:
106e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            return None
1070b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1080b30c4ef3de2406815678f0019889a6e80d8b097David Riley
109e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    def _reset_freq(self, initial_governors, initial_quiet_governor):
1100b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
1110b30c4ef3de2406815678f0019889a6e80d8b097David Riley        Unlimit the CPU frequency.
1120b30c4ef3de2406815678f0019889a6e80d8b097David Riley
113e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        @param initial_governors: list of initial governors to reset state to
114e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        @param initial_quiet_governor: initial quiet governor to reset state to
1150b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1160b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
117e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        for p, g in zip(self._governor_paths, initial_governors):
118e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            self._set_file(g, p)
119e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        if initial_quiet_governor and os.path.isfile(self.QUIET_GOVERNOR_PATH):
120e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            self._set_file(initial_quiet_governor, self.QUIET_GOVERNOR_PATH)
1210b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1220b30c4ef3de2406815678f0019889a6e80d8b097David Riley
123e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    def _set_freq(self, freq):
1240b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
1250b30c4ef3de2406815678f0019889a6e80d8b097David Riley        Set the CPU frequency.
1260b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1270b30c4ef3de2406815678f0019889a6e80d8b097David Riley        @param freq: desired CPU frequency
1280b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1290b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
130e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        # Prevent CPUs from going up and down during the test if the option
131e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        # is available.
132e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        if os.path.isfile(self.QUIET_GOVERNOR_PATH):
133e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            logging.info('changing to userspace cpuquiet governor');
134e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            self._set_file('userspace', self.QUIET_GOVERNOR_PATH)
1350b30c4ef3de2406815678f0019889a6e80d8b097David Riley
136e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        for p in self._governor_paths:
137e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            self._set_file('userspace', p)
138e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        for p in self._setspeed_paths:
139e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            self._set_file(str(freq), p)
140e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        logging.info(
141e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                'cpu frequencies set to %s with userspace governor',
142e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                self._get_freqs_string())
143e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        self._check_freq(freq)
1440b30c4ef3de2406815678f0019889a6e80d8b097David Riley
145e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley
146e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley    def _check_freq(self, freq):
147e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        """
148e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        Check the CPU frequencies are set as requested.
149e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley
150e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        @param freq: desired CPU frequency
151e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley
152e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        """
153e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        for p in self._governor_paths:
154e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            governor = self._get_file(p).rstrip()
155e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            if governor != 'userspace':
156e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                raise error.TestFail('governor changed from userspace to %s' % (
157e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                        governor))
158e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        for p in self._setspeed_paths:
159e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            speed = int(self._get_file(p))
160e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            if speed != freq:
161e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                raise error.TestFail('setspeed changed from %s to %s' % (
162e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                        freq, speed))
163e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        freqs = self._get_freqs()
164e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        for f in freqs:
165e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            if f != freq:
166e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                raise error.TestFail('frequency set to %s instead of %s' % (
167e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                        f, freq))
1680b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1690b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1700b30c4ef3de2406815678f0019889a6e80d8b097David Riley    def _test_udelay(self, usecs):
1710b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
1720b30c4ef3de2406815678f0019889a6e80d8b097David Riley        Test udelay() for a given amount of time.
1730b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1740b30c4ef3de2406815678f0019889a6e80d8b097David Riley        @param usecs: number of usecs to delay for each iteration
1750b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1760b30c4ef3de2406815678f0019889a6e80d8b097David Riley        """
1770b30c4ef3de2406815678f0019889a6e80d8b097David Riley        self._set_file('%d %d' % (usecs, self.ITERATIONS), self.UDELAY_PATH)
1780b30c4ef3de2406815678f0019889a6e80d8b097David Riley        with open(self.UDELAY_PATH, 'r') as f:
1790b30c4ef3de2406815678f0019889a6e80d8b097David Riley            for line in f:
1800b30c4ef3de2406815678f0019889a6e80d8b097David Riley                line = line.rstrip()
1810b30c4ef3de2406815678f0019889a6e80d8b097David Riley                logging.info('result: %s', line)
1820b30c4ef3de2406815678f0019889a6e80d8b097David Riley                if 'FAIL' in line:
1830b30c4ef3de2406815678f0019889a6e80d8b097David Riley                    raise error.TestFail('udelay failed: %s' % line)
1840b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1850b30c4ef3de2406815678f0019889a6e80d8b097David Riley
1860b30c4ef3de2406815678f0019889a6e80d8b097David Riley    def run_once(self):
1879483778b34c657822f43681631c0a587c5fe1085David Riley        kernel_ver = os.uname()[2]
1889483778b34c657822f43681631c0a587c5fe1085David Riley        if utils.compare_versions(kernel_ver, self.MIN_KERNEL_VER) < 0:
1899483778b34c657822f43681631c0a587c5fe1085David Riley            logging.info(
1909483778b34c657822f43681631c0a587c5fe1085David Riley                    'skipping test: old kernel %s (min %s) missing module %s',
1919483778b34c657822f43681631c0a587c5fe1085David Riley                    kernel_ver, self.MIN_KERNEL_VER, self.MODULE_NAME)
1929483778b34c657822f43681631c0a587c5fe1085David Riley            return
1939483778b34c657822f43681631c0a587c5fe1085David Riley
1940b30c4ef3de2406815678f0019889a6e80d8b097David Riley        utils.load_module(self.MODULE_NAME)
1950b30c4ef3de2406815678f0019889a6e80d8b097David Riley
196e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        self._governor_paths = glob.glob(self.GOVERNOR_GLOB)
197e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        self._setspeed_paths = glob.glob(self.SETSPEED_GLOB)
198e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        self._cur_freq_paths = glob.glob(self.CUR_FREQ_GLOB)
199e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        initial_governors = self._get_governors()
200e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        initial_quiet_governor = self._get_quiet_governor()
201e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley
2020b30c4ef3de2406815678f0019889a6e80d8b097David Riley        with open(self.CPUFREQ_AVAIL_PATH, 'r') as f:
2030b30c4ef3de2406815678f0019889a6e80d8b097David Riley            available_freqs = [int(x) for x in f.readline().split()]
2040b30c4ef3de2406815678f0019889a6e80d8b097David Riley
2050b30c4ef3de2406815678f0019889a6e80d8b097David Riley        max_freq = max(available_freqs)
2060b30c4ef3de2406815678f0019889a6e80d8b097David Riley        min_freq = min(available_freqs)
2070b30c4ef3de2406815678f0019889a6e80d8b097David Riley        logging.info('cpu frequency max %d min %d', max_freq, min_freq)
2080b30c4ef3de2406815678f0019889a6e80d8b097David Riley
2090b30c4ef3de2406815678f0019889a6e80d8b097David Riley        freqs = [ min_freq, max_freq ]
210e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        try:
211e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            for freq in freqs:
212e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                self._set_freq(freq)
213e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                for usecs in self.DELAYS:
214e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                    self._test_udelay(usecs)
215e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley                self._check_freq(freq)
216e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley        finally:
217e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            self._reset_freq(initial_governors, initial_quiet_governor)
218e39a430159ae4950f152cbb1c4d0370b55c9f21aDavid Riley            utils.unload_module(self.MODULE_NAME)
219