ARM: am33xx: Fix DDR initialization delays
[platform/kernel/u-boot.git] / tools / moveconfig.py
index 87ced5c..68631b7 100755 (executable)
@@ -135,6 +135,9 @@ Available options
    Surround each portion of the log with escape sequences to display it
    in color on the terminal.
 
+ -d, --defconfigs
+  Specify a file containing a list of defconfigs to move
+
  -n, --dry-run
    Peform a trial run that does not make any changes.  It is useful to
    see what is going to happen before one actually runs it.
@@ -143,10 +146,16 @@ Available options
    Exit immediately if Make exits with a non-zero status while processing
    a defconfig file.
 
+ -H, --headers-only
+   Only cleanup the headers; skip the defconfig processing
+
  -j, --jobs
    Specify the number of threads to run simultaneously.  If not specified,
    the number of threads is the same as the number of CPU cores.
 
+ -v, --verbose
+   Show any build errors as boards are built
+
 To see the complete list of supported options, run
 
   $ tools/moveconfig.py -h
@@ -172,9 +181,12 @@ SLEEP_TIME=0.03
 # (https://www.kernel.org/pub/tools/crosstool/files/bin/), except the followings:
 # arc: https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases
 # blackfin: http://sourceforge.net/projects/adi-toolchain/files/
-# nds32: http://osdk.andestech.com/packages/
+# nds32: http://osdk.andestech.com/packages/nds32le-linux-glibc-v1.tgz
 # nios2: https://sourcery.mentor.com/GNUToolchain/subscription42545
 # sh: http://sourcery.mentor.com/public/gnu_toolchain/sh-linux-gnu
+#
+# openrisc kernel.org toolchain is out of date, download latest one from
+# http://opencores.org/or1k/OpenRISC_GNU_tool_chain#Prebuilt_versions
 CROSS_COMPILE = {
     'arc': 'arc-linux-',
     'aarch64': 'aarch64-linux-',
@@ -186,7 +198,7 @@ CROSS_COMPILE = {
     'mips': 'mips-linux-',
     'nds32': 'nds32le-linux-',
     'nios2': 'nios2-linux-gnu-',
-    'openrisc': 'or32-linux-',
+    'openrisc': 'or1k-elf-',
     'powerpc': 'powerpc-linux-',
     'sh': 'sh-linux-gnu-',
     'sparc': 'sparc-linux-',
@@ -261,12 +273,12 @@ def log_msg(color_enabled, color, defconfig, msg):
         color_text(color_enabled, color, msg) + '\n'
 
 def update_cross_compile():
-    """Update per-arch CROSS_COMPILE via enviroment variables
+    """Update per-arch CROSS_COMPILE via environment variables
 
     The default CROSS_COMPILE values are available
     in the CROSS_COMPILE list above.
 
-    You can override them via enviroment variables
+    You can override them via environment variables
     CROSS_COMPILE_{ARCH}.
 
     For example, if you want to override toolchain prefixes
@@ -342,11 +354,12 @@ def cleanup_headers(config_attrs, dry_run):
         patterns.append(re.compile(r'#\s*define\s+%s\W' % config))
         patterns.append(re.compile(r'#\s*undef\s+%s\W' % config))
 
-    for (dirpath, dirnames, filenames) in os.walk('include'):
-        for filename in filenames:
-            if not fnmatch.fnmatch(filename, '*~'):
-                cleanup_one_header(os.path.join(dirpath, filename), patterns,
-                                   dry_run)
+    for dir in 'include', 'arch', 'board':
+        for (dirpath, dirnames, filenames) in os.walk(dir):
+            for filename in filenames:
+                if not fnmatch.fnmatch(filename, '*~'):
+                    cleanup_one_header(os.path.join(dirpath, filename),
+                                       patterns, dry_run)
 
 ### classes ###
 class KconfigParser:
@@ -549,7 +562,7 @@ class Slot:
                 pass
         shutil.rmtree(self.build_dir)
 
-    def add(self, defconfig):
+    def add(self, defconfig, num, total):
         """Assign a new subprocess for defconfig and add it to the slot.
 
         If the slot is vacant, create a new subprocess for processing the
@@ -566,9 +579,12 @@ class Slot:
             return False
         cmd = list(self.make_cmd)
         cmd.append(defconfig)
-        self.ps = subprocess.Popen(cmd, stdout=self.devnull)
+        self.ps = subprocess.Popen(cmd, stdout=self.devnull,
+                                   stderr=subprocess.PIPE)
         self.defconfig = defconfig
         self.state = STATE_DEFCONFIG
+        self.num = num
+        self.total = total
         return True
 
     def poll(self):
@@ -591,11 +607,21 @@ class Slot:
             return False
 
         if self.ps.poll() != 0:
-
+            errmsg = 'Failed to process.'
+            errout = self.ps.stderr.read()
+            if errout.find('gcc: command not found') != -1:
+                errmsg = 'Compiler not found ('
+                errmsg += color_text(self.options.color, COLOR_YELLOW,
+                                     self.cross_compile)
+                errmsg += color_text(self.options.color, COLOR_LIGHT_RED,
+                                     ')')
             print >> sys.stderr, log_msg(self.options.color,
                                          COLOR_LIGHT_RED,
                                          self.defconfig,
-                                         "failed to process.")
+                                         errmsg),
+            if self.options.verbose:
+                print >> sys.stderr, color_text(self.options.color,
+                                                COLOR_LIGHT_CYAN, errout)
             if self.options.exit_on_error:
                 sys.exit("Exit on error.")
             else:
@@ -609,11 +635,14 @@ class Slot:
         if self.state == STATE_AUTOCONF:
             self.parser.update_defconfig(self.defconfig)
 
+            print ' %d defconfigs out of %d\r' % (self.num + 1, self.total),
+            sys.stdout.flush()
+
             """Save off the defconfig in a consistent way"""
             cmd = list(self.make_cmd)
             cmd.append('savedefconfig')
             self.ps = subprocess.Popen(cmd, stdout=self.devnull,
-                                       stderr=self.devnull)
+                                       stderr=subprocess.PIPE)
             self.state = STATE_SAVEDEFCONFIG
             return False
 
@@ -624,13 +653,17 @@ class Slot:
             self.state = STATE_IDLE
             return True
 
-        cross_compile = self.parser.get_cross_compile()
+        self.cross_compile = self.parser.get_cross_compile()
         cmd = list(self.make_cmd)
-        if cross_compile:
-            cmd.append('CROSS_COMPILE=%s' % cross_compile)
+        if self.cross_compile:
+            cmd.append('CROSS_COMPILE=%s' % self.cross_compile)
         cmd.append('KCONFIG_IGNORE_DUPLICATES=1')
         cmd.append('include/config/auto.conf')
-        self.ps = subprocess.Popen(cmd, stdout=self.devnull)
+        """This will be screen-scraped, so be sure the expected text will be
+        returned consistently on every machine by setting LANG=C"""
+        self.ps = subprocess.Popen(cmd, stdout=self.devnull,
+                                   env=dict(os.environ, LANG='C'),
+                                   stderr=subprocess.PIPE)
         self.state = STATE_AUTOCONF
         return False
 
@@ -658,7 +691,7 @@ class Slots:
         for i in range(options.jobs):
             self.slots.append(Slot(config_attrs, options, devnull, make_cmd))
 
-    def add(self, defconfig):
+    def add(self, defconfig, num, total):
         """Add a new subprocess if a vacant slot is found.
 
         Arguments:
@@ -668,7 +701,7 @@ class Slots:
           Return True on success or False on failure
         """
         for slot in self.slots:
-            if slot.add(defconfig):
+            if slot.add(defconfig, num, total):
                 return True
         return False
 
@@ -709,6 +742,10 @@ class Slots:
                 print >> sys.stderr, color_text(self.options.color,
                                                 COLOR_LIGHT_RED, line)
 
+            with open('moveconfig.failed', 'w') as f:
+                for board in failed_boards:
+                    f.write(board + '\n')
+
 def move_config(config_attrs, options):
     """Move config options to defconfig files.
 
@@ -717,8 +754,6 @@ def move_config(config_attrs, options):
                     the type, and the default value of the target config.
       options: option flags
     """
-    check_top_directory()
-
     if len(config_attrs) == 0:
         print 'Nothing to do. exit.'
         sys.exit(0)
@@ -729,20 +764,29 @@ def move_config(config_attrs, options):
                                                 config_attr['type'],
                                                 config_attr['default'])
 
-    # All the defconfig files to be processed
-    defconfigs = []
-    for (dirpath, dirnames, filenames) in os.walk('configs'):
-        dirpath = dirpath[len('configs') + 1:]
-        for filename in fnmatch.filter(filenames, '*_defconfig'):
-            defconfigs.append(os.path.join(dirpath, filename))
+    if options.defconfigs:
+        defconfigs = [line.strip() for line in open(options.defconfigs)]
+        for i, defconfig in enumerate(defconfigs):
+            if not defconfig.endswith('_defconfig'):
+                defconfigs[i] = defconfig + '_defconfig'
+            if not os.path.exists(os.path.join('configs', defconfigs[i])):
+                sys.exit('%s - defconfig does not exist. Stopping.' %
+                         defconfigs[i])
+    else:
+        # All the defconfig files to be processed
+        defconfigs = []
+        for (dirpath, dirnames, filenames) in os.walk('configs'):
+            dirpath = dirpath[len('configs') + 1:]
+            for filename in fnmatch.filter(filenames, '*_defconfig'):
+                defconfigs.append(os.path.join(dirpath, filename))
 
     slots = Slots(config_attrs, options)
 
     # Main loop to process defconfig files:
     #  Add a new subprocess into a vacant slot.
     #  Sleep if there is no available slot.
-    for defconfig in defconfigs:
-        while not slots.add(defconfig):
+    for i, defconfig in enumerate(defconfigs):
+        while not slots.add(defconfig, i, len(defconfigs)):
             while not slots.available():
                 # No available slot: sleep for a while
                 time.sleep(SLEEP_TIME)
@@ -751,10 +795,9 @@ def move_config(config_attrs, options):
     while not slots.empty():
         time.sleep(SLEEP_TIME)
 
+    print ''
     slots.show_failed_boards()
 
-    cleanup_headers(config_attrs, options.dry_run)
-
 def bad_recipe(filename, linenum, msg):
     """Print error message with the file name and the line number and exit."""
     sys.exit("%s: line %d: error : " % (filename, linenum) + msg)
@@ -835,13 +878,20 @@ def main():
     # Add options here
     parser.add_option('-c', '--color', action='store_true', default=False,
                       help='display the log in color')
+    parser.add_option('-d', '--defconfigs', type='string',
+                      help='a file containing a list of defconfigs to move')
     parser.add_option('-n', '--dry-run', action='store_true', default=False,
                       help='perform a trial run (show log with no changes)')
     parser.add_option('-e', '--exit-on-error', action='store_true',
                       default=False,
                       help='exit immediately on any error')
+    parser.add_option('-H', '--headers-only', dest='cleanup_headers_only',
+                      action='store_true', default=False,
+                      help='only cleanup the headers')
     parser.add_option('-j', '--jobs', type='int', default=cpu_count,
                       help='the number of jobs to run simultaneously')
+    parser.add_option('-v', '--verbose', action='store_true', default=False,
+                      help='show any build errors as boards are built')
     parser.usage += ' recipe_file\n\n' + \
                     'The recipe_file should describe config options you want to move.\n' + \
                     'Each line should contain config_name, type, default_value\n\n' + \
@@ -860,7 +910,12 @@ def main():
 
     update_cross_compile()
 
-    move_config(config_attrs, options)
+    check_top_directory()
+
+    if not options.cleanup_headers_only:
+        move_config(config_attrs, options)
+
+    cleanup_headers(config_attrs, options.dry_run)
 
 if __name__ == '__main__':
     main()