]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FlashMapTask.java
1. Remove some unuseful import in Framework's EfiRomTask.java, FlashMapTask.java...
[mirror_edk2.git] / Tools / Source / FrameworkTasks / org / tianocore / framework / tasks / FlashMapTask.java
index dc3463890e14bcd9149d1ce3b3431e92ce2bbb24..9a3c61e6c879c5765b8530af61f3f83388dafcbb 100644 (file)
@@ -2,14 +2,14 @@
  FlashMapTask class.\r
 \r
  FlashMapTask is used to call FlashMap.exe to lay out the flash.\r
\r
\r
+\r
+\r
  Copyright (c) 2006, Intel Corporation\r
  All rights reserved. This program and the accompanying materials\r
  are licensed and made available under the terms and conditions of the BSD License\r
  which accompanies this distribution.  The full text of the license may be found at\r
  http://opensource.org/licenses/bsd-license.php\r
\r
+\r
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 package org.tianocore.framework.tasks;\r
 \r
 import java.io.File;\r
-import java.io.InputStreamReader;\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.LinkedList;\r
+import java.io.FileReader;\r
+import java.io.BufferedReader;\r
+\r
 import java.util.List;\r
+import java.util.ArrayList;\r
+import java.util.regex.Pattern;\r
+import java.util.regex.Matcher;\r
 \r
 import org.apache.tools.ant.Task;\r
 import org.apache.tools.ant.Project;\r
 import org.apache.tools.ant.BuildException;\r
-import org.tianocore.logger.EdkLog;\r
+import org.apache.tools.ant.taskdefs.Execute;\r
+import org.apache.tools.ant.taskdefs.LogStreamHandler;\r
+import org.apache.tools.ant.types.Commandline;\r
+\r
+import org.tianocore.common.logger.EdkLog;\r
 \r
 /**\r
- * SecFixupTask class.\r
- * \r
- * SecFixupTask is used to call SecFixup.exe to fix up sec image.\r
+ * FlashMapTask class.\r
+ *\r
+ * FlashMapTask is used to call FlashMap.exe to generate flash map defition files and fd files.\r
  */\r
 public class FlashMapTask extends Task implements EfiDefine {\r
-    // /\r
-    // / tool name\r
-    // /\r
-    private final String toolName = "FlashMap";\r
-\r
-    // /\r
-    // / Flash default file\r
-    // /\r
-    private String flashDefFile = "";\r
-\r
-    // /\r
-    // / Flash device\r
-    // /\r
-    private String flashDevice = "";\r
-\r
-    // /\r
-    // / Flash device Image\r
-    // /\r
-    private String flashDeviceImage = "";\r
-\r
-    // /\r
-    // / MCI file\r
-    // /\r
-    private String mciFile = "";\r
-\r
-    // /\r
-    // / MCO file\r
-    // /\r
-    private String mcoFile = "";\r
-\r
-    // /\r
-    // / Discover FD image\r
-    // /\r
-    private String fdImage = "";\r
-\r
-    // /\r
-    // / Dsc file\r
-    // /\r
-    private String dscFile = "";\r
-\r
-    // /\r
-    // / Asm INC file\r
-    // /\r
-    private String asmIncFile = "";\r
-\r
-    // /\r
-    // / Image out file\r
-    // /\r
-    private String imageOutFile = "";\r
-\r
-    // /\r
-    // / Header file\r
-    // /\r
-    private String headerFile = "";\r
-\r
-    // /\r
-    // / Input string file\r
-    // /\r
+    //\r
+    // tool name\r
+    //\r
+    private static final String toolName = "FlashMap";\r
+\r
+    //\r
+    // \r
+    // \r
+    private static Pattern fileBlock = Pattern.compile("\\s*File\\s*\\{([^\\{\\}]+)\\}");\r
+    private static Pattern fileNameDef = Pattern.compile("\\bName\\s*=\\s*\"([^\"]+)\"");\r
+    \r
+    //\r
+    // Flash definition file\r
+    //\r
+    private FileArg flashDefFile = new FileArg();\r
+\r
+    //\r
+    // Flash device\r
+    //\r
+    private ToolArg flashDevice = new ToolArg();\r
+\r
+    //\r
+    // Flash device Image\r
+    //\r
+    private ToolArg flashDeviceImage = new ToolArg();\r
+\r
+    //\r
+    // MCI file\r
+    //\r
+    private FileArg mciFile = new FileArg();\r
+\r
+    //\r
+    // MCO file\r
+    //\r
+    private FileArg mcoFile = new FileArg();\r
+\r
+    //\r
+    // Discover FD image\r
+    //\r
+    private ToolArg fdImage = new ToolArg();\r
+\r
+    //\r
+    // Dsc file\r
+    //\r
+    private FileArg dscFile = new FileArg();\r
+\r
+    //\r
+    // Asm INC file\r
+    //\r
+    private FileArg asmIncFile = new FileArg();\r
+\r
+    //\r
+    // Image out file\r
+    //\r
+    private FileArg imageOutFile = new FileArg();\r
+\r
+    //\r
+    // Header file\r
+    //\r
+    private FileArg headerFile = new FileArg();\r
+\r
+    //\r
+    // Input string file\r
+    //\r
     private String inStrFile = "";\r
 \r
-    // /\r
-    // Output string file\r
-    // /\r
+    //\r
+    // Output string file\r
+    //\r
     private String outStrFile = "";\r
 \r
-    // /\r
-    // / Base address\r
-    // /\r
-    private String baseAddr = "";\r
-\r
-    // /\r
-    // / Aligment\r
-    // /\r
-    private String aligment = "";\r
-\r
-    // /\r
-    // / Padding value\r
-    // /\r
-    private String padValue = "";\r
-\r
-    // /\r
-    // / output directory\r
-    // /\r
-    private String outputDir = "";\r
-\r
-    // /\r
-    // / MCI file array\r
-    // /\r
-    List<Input> mciFileArray = new ArrayList<Input>();\r
-\r
-    // /\r
-    // / command and argument list\r
-    // /\r
-    LinkedList<String> argList = new LinkedList<String>();\r
-\r
-    /**\r
-     * execute\r
-     * \r
-     * FlashMapTask execute function is to assemble tool command line & execute\r
-     * tool command line\r
-     * \r
-     * @throws BuidException\r
-     */\r
+    //\r
+    //\r
+    //\r
+    private FileArg strFile = new FileArg();\r
+    //\r
+    // Base address\r
+    //\r
+    private ToolArg baseAddr = new ToolArg();\r
+\r
+    //\r
+    // Aligment\r
+    //\r
+    private ToolArg aligment = new ToolArg();\r
+\r
+    //\r
+    // Padding value\r
+    //\r
+    private ToolArg padValue = new ToolArg();\r
+\r
+    //\r
+    // output directory\r
+    //\r
+    private String outputDir = ".";\r
+\r
+    //\r
+    // MCI file array\r
+    //\r
+    FileArg mciFileArray = new FileArg();\r
+\r
+    /**\r
+      execute\r
+\r
+      FlashMapTask execute function is to assemble tool command line & execute\r
+      tool command line\r
+\r
+      @throws BuidException\r
+     **/\r
     public void execute() throws BuildException {\r
+        if (isUptodate()) {\r
+            EdkLog.log(this, EdkLog.EDK_VERBOSE, headerFile.toFileList()\r
+                                                 + imageOutFile.toFileList()\r
+                                                 + mcoFile.toFileList()\r
+                                                 + dscFile.toFileList()\r
+                                                 + asmIncFile.toFileList()\r
+                                                 + outStrFile\r
+                                                 + " is up-to-date!");\r
+            return;\r
+        }\r
 \r
         Project project = this.getOwningTarget().getProject();\r
         //\r
-        // set Logger\r
-        //\r
-        FrameworkLogger logger = new FrameworkLogger(project, "flashmap");\r
-        EdkLog.setLogLevel(project.getProperty("env.LOGLEVEL"));\r
-        EdkLog.setLogger(logger);\r
-        //\r
         // absolute path of efi tools\r
         //\r
         String path = project.getProperty("env.FRAMEWORK_TOOLS_PATH");\r
@@ -154,471 +169,680 @@ public class FlashMapTask extends Task implements EfiDefine {
         if (path == null) {\r
             command = toolName;\r
         } else {\r
-            command = path + File.separatorChar + toolName;\r
+            command = path + File.separator + toolName;\r
         }\r
-        argList.addFirst(command);\r
 \r
         //\r
         // add substituted input file and output file\r
         //\r
         if (this.inStrFile != null && this.outStrFile != null\r
-                && !this.inStrFile.equalsIgnoreCase("")\r
-                && !this.inStrFile.equalsIgnoreCase("")) {\r
-            argList.add("-strsub");\r
-            argList.add(this.inStrFile);\r
-            argList.add(this.outStrFile);\r
-        }\r
-    \r
-       \r
-        //\r
-        // add microcode binary files\r
-        //\r
-        if (mciFileArray.size() > 0) {\r
-            argList.add("-mcmerge");\r
-            Iterator mciList = mciFileArray.iterator();\r
-            while (mciList.hasNext()) {\r
-                argList.add(((Input) mciList.next()).getFile());\r
-            }\r
+            && this.inStrFile.length() > 0 && this.outStrFile.length() > 0) {\r
+            strFile.setPrefix(" -strsub ");\r
+            strFile.insValue(this.inStrFile);\r
+            strFile.insValue(this.outStrFile);\r
         }\r
 \r
-        EdkLog.log(EdkLog.EDK_INFO, argList.toString().replace(",",""));\r
+        String argument = "" + flashDefFile + flashDevice + flashDeviceImage\r
+                             + mciFile + mcoFile + fdImage + dscFile + asmIncFile\r
+                             + imageOutFile + headerFile + strFile + baseAddr\r
+                             + aligment + padValue + mciFileArray;\r
+\r
+\r
         //\r
         // lauch the program\r
         //\r
-        ProcessBuilder pb = new ProcessBuilder(argList);\r
-        pb.directory(new File(outputDir));\r
+        // ProcessBuilder pb = new ProcessBuilder(argList);\r
+        // pb.directory(new File(outputDir));\r
         int exitCode = 0;\r
         try {\r
-            Process cmdProc = pb.start();\r
-            InputStreamReader cmdOut = new InputStreamReader(cmdProc\r
-                    .getInputStream());\r
-            char[] buf = new char[1024];\r
+            Commandline cmdline = new Commandline();\r
+            cmdline.setExecutable(command);\r
+            cmdline.createArgument().setLine(argument);\r
+\r
+            LogStreamHandler streamHandler = new LogStreamHandler(this,\r
+                    Project.MSG_INFO, Project.MSG_WARN);\r
+            Execute runner = new Execute(streamHandler, null);\r
 \r
-            exitCode = cmdProc.waitFor();\r
+            runner.setAntRun(project);\r
+            runner.setCommandline(cmdline.getCommandline());\r
+\r
+            if (outputDir != null) {\r
+                runner.setWorkingDirectory(new File(outputDir));\r
+            }\r
             //\r
             // log command line string.\r
             //\r
-            EdkLog.log(EdkLog.EDK_INFO, cmdProc.getOutputStream().toString());\r
+            EdkLog.log(this, EdkLog.EDK_VERBOSE, Commandline.toString(cmdline.getCommandline()));\r
+            EdkLog.log(this, flashDefFile.toFileList()\r
+                             + mciFile.toFileList()\r
+                             + mciFileArray.toFileList()\r
+                             + fdImage.toFileList()\r
+                             + inStrFile\r
+                             + " => "\r
+                             + headerFile.toFileList()\r
+                             + imageOutFile.toFileList()\r
+                             + mcoFile.toFileList()\r
+                             + dscFile.toFileList()\r
+                             + asmIncFile.toFileList()\r
+                             + outStrFile);\r
+\r
+            exitCode = runner.execute();\r
             if (exitCode != 0) {\r
-                int len = cmdOut.read(buf, 0, 1024);\r
-                EdkLog.log(EdkLog.EDK_ERROR, new String(buf, 0, len));\r
+                EdkLog.log(this, "ERROR = " + Integer.toHexString(exitCode));\r
             } else {\r
-                EdkLog.log(EdkLog.EDK_INFO, "FlashMap succeed!");\r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, "FlashMap succeeded!");\r
             }\r
         } catch (Exception e) {\r
             throw new BuildException(e.getMessage());\r
         } finally {\r
             if (exitCode != 0) {\r
-                // throw new BuildException("GenFvImage: failed to generate FV\r
-                // file!");\r
+                throw new BuildException("FlashMap failed!");\r
             }\r
         }\r
     }\r
 \r
     /**\r
-     * getFlashDefFile\r
-     * \r
-     * This function is to get class member "flashDefFile"\r
-     * \r
-     * @return flashDeFile Name of flash definition file.\r
-     */\r
+      getFlashDefFile\r
+\r
+      This function is to get class member "flashDefFile"\r
+\r
+      @return flashDeFile Name of flash definition file.\r
+     **/\r
     public String getFlashDefFile() {\r
-        return flashDefFile;\r
+        return this.flashDefFile.getValue();\r
     }\r
 \r
     /**\r
-     * setFlashDefFile\r
-     * \r
-     * This function is to set class member "flashDefFile"\r
-     * \r
-     * @param flashDefFile\r
-     *            Name of flash definition file.\r
-     */\r
+      setFlashDefFile\r
+\r
+      This function is to set class member "flashDefFile"\r
+\r
+      @param flashDefFile\r
+                 Name of flash definition file.\r
+     **/\r
     public void setFlashDefFile(String flashDefFile) {\r
-        this.flashDefFile = flashDefFile;\r
-        argList.add("-fdf");\r
-        argList.add(this.flashDefFile);\r
+        this.flashDefFile.setArg(" -fdf ", flashDefFile);\r
     }\r
 \r
     /**\r
-     * getAligment\r
-     * \r
-     * This function is to get class member "aligment"\r
-     * \r
-     * @return aligment String of aligment value.\r
-     */\r
+      getAligment\r
+\r
+      This function is to get class member "aligment"\r
+\r
+      @return aligment String of aligment value.\r
+     **/\r
     public String getAligment() {\r
-        return aligment;\r
+        return this.aligment.getValue();\r
     }\r
 \r
     /**\r
-     * setAligment\r
-     * \r
-     * This function is to set class member "aligment"\r
-     * \r
-     * @param aligment\r
-     *            String of aligment value.\r
-     */\r
+      setAligment\r
+\r
+      This function is to set class member "aligment"\r
+\r
+      @param aligment\r
+                 String of aligment value.\r
+     **/\r
     public void setAligment(String aligment) {\r
-        this.aligment = aligment;\r
-        argList.add("-align");\r
-        argList.add(this.aligment);\r
+        this.aligment.setArg(" -align ", aligment);\r
     }\r
 \r
     /**\r
-     * getAsmIncFile\r
-     * \r
-     * This function is to get class member "asmIncFile"\r
-     * \r
-     * @return asmIncFile String of ASM include file.\r
-     */\r
+      getAsmIncFile\r
+\r
+      This function is to get class member "asmIncFile"\r
+\r
+      @return asmIncFile String of ASM include file.\r
+     **/\r
     public String getAsmIncFile() {\r
-        return asmIncFile;\r
+        return this.asmIncFile.getValue();\r
     }\r
 \r
     /**\r
-     * setAsmIncFile\r
-     * \r
-     * This function is to set class member "asmIncFile"\r
-     * \r
-     * @param asmIncFile\r
-     *            String of ASM include file.\r
-     */\r
+      setAsmIncFile\r
+\r
+      This function is to set class member "asmIncFile"\r
+\r
+      @param asmIncFile\r
+                 String of ASM include file.\r
+     **/\r
     public void setAsmIncFile(String asmIncFile) {\r
-        this.asmIncFile = asmIncFile;\r
-        argList.add("-asmincfile");\r
-        argList.add(this.asmIncFile);\r
+        this.asmIncFile.setArg(" -asmincfile ", asmIncFile);\r
     }\r
 \r
     /**\r
-     * getBaseAddr\r
-     * \r
-     * This function is to get class member "baseAddr"\r
-     * \r
-     * @return baseAddr String of base address value.\r
-     */\r
+      getBaseAddr\r
+\r
+      This function is to get class member "baseAddr"\r
+\r
+      @return baseAddr String of base address value.\r
+     **/\r
     public String getBaseAddr() {\r
-        return baseAddr;\r
+        return this.baseAddr.getValue();\r
     }\r
 \r
     /**\r
-     * setBaseAddr\r
-     * \r
-     * This function is to set class member "baseAddr"\r
-     * \r
-     * @param baseAddr\r
-     *            String of base address value.\r
-     */\r
+      setBaseAddr\r
+\r
+      This function is to set class member "baseAddr"\r
+\r
+      @param baseAddr\r
+                 String of base address value.\r
+     **/\r
     public void setBaseAddr(String baseAddr) {\r
-        this.baseAddr = baseAddr;\r
-        argList.add("-baseaddr");\r
-        argList.add(this.baseAddr);\r
+        this.baseAddr.setArg(" -baseaddr ", baseAddr);\r
     }\r
 \r
     /**\r
-     * getDscFile\r
-     * \r
-     * This function is to get class member "dscFile"\r
-     * \r
-     * @return dscFile name of DSC file\r
-     */\r
+      getDscFile\r
+\r
+      This function is to get class member "dscFile"\r
+\r
+      @return dscFile name of DSC file\r
+     **/\r
     public String getDscFile() {\r
-        return dscFile;\r
+        return this.dscFile.getValue();\r
     }\r
 \r
     /**\r
-     * setDscFile\r
-     * \r
-     * This function is to set class member "dscFile"\r
-     * \r
-     * @param dscFile\r
-     *            name of DSC file\r
-     */\r
+      setDscFile\r
+\r
+      This function is to set class member "dscFile"\r
+\r
+      @param dscFile\r
+                 name of DSC file\r
+     **/\r
     public void setDscFile(String dscFile) {\r
-        this.dscFile = dscFile;\r
-        argList.add("-dsc");\r
-        argList.add(this.dscFile);\r
+        this.dscFile.setArg(" -dsc ", dscFile);\r
     }\r
 \r
     /**\r
-     * getFdImage\r
-     * \r
-     * This function is to get class member "fdImage"\r
-     * \r
-     * @return fdImage name of input FDI image file.\r
-     */\r
+      getFdImage\r
+\r
+      This function is to get class member "fdImage"\r
+\r
+      @return fdImage name of input FDI image file.\r
+     **/\r
     public String getFdImage() {\r
-        return fdImage;\r
+        return this.fdImage.getValue();\r
     }\r
 \r
     /**\r
-     * setFdImage\r
-     * \r
-     * This function is to set class member "fdImage"\r
-     * \r
-     * @param fdImage\r
-     *            name of input FDI image file.\r
-     */\r
+      setFdImage\r
+\r
+      This function is to set class member "fdImage"\r
+\r
+      @param fdImage\r
+                 name of input FDI image file.\r
+     **/\r
     public void setFdImage(String fdImage) {\r
-        this.fdImage = fdImage;\r
-        argList.add("-discover");\r
-        argList.add(this.fdImage);\r
+        this.fdImage.setArg(" -discover ", fdImage);\r
     }\r
 \r
     /**\r
-     * getFlashDevice\r
-     * \r
-     * This function is to get class member "flashDevice".\r
-     * \r
-     * @return flashDevice name of flash device.\r
-     */\r
+      getFlashDevice\r
+\r
+      This function is to get class member "flashDevice".\r
+\r
+      @return flashDevice name of flash device.\r
+     **/\r
     public String getFlashDevice() {\r
-        return flashDevice;\r
+        return this.flashDevice.getValue();\r
     }\r
 \r
     /**\r
-     * setFlashDevice\r
-     * \r
-     * This function is to set class member "flashDevice"\r
-     * \r
-     * @param flashDevice\r
-     *            name of flash device.\r
-     */\r
+      setFlashDevice\r
+\r
+      This function is to set class member "flashDevice"\r
+\r
+      @param flashDevice\r
+                 name of flash device.\r
+     **/\r
     public void setFlashDevice(String flashDevice) {\r
-        this.flashDevice = flashDevice;\r
-        argList.add("-flashdevice");\r
-        argList.add(this.flashDevice);\r
+        this.flashDevice.setArg(" -flashdevice ", flashDevice);\r
     }\r
 \r
     /**\r
-     * getFlashDeviceImage\r
-     * \r
-     * This function is to get class member "flashDeviceImage"\r
-     * \r
-     * @return flashDeviceImage name of flash device image\r
-     */\r
+      getFlashDeviceImage\r
+\r
+      This function is to get class member "flashDeviceImage"\r
+\r
+      @return flashDeviceImage name of flash device image\r
+     **/\r
     public String getFlashDeviceImage() {\r
-        return flashDeviceImage;\r
+        return this.flashDeviceImage.getValue();\r
     }\r
 \r
     /**\r
-     * setFlashDeviceImage\r
-     * \r
-     * This function is to set class member "flashDeviceImage"\r
-     * \r
-     * @param flashDeviceImage\r
-     *            name of flash device image\r
-     */\r
+      setFlashDeviceImage\r
+\r
+      This function is to set class member "flashDeviceImage"\r
+\r
+      @param flashDeviceImage\r
+                 name of flash device image\r
+     **/\r
     public void setFlashDeviceImage(String flashDeviceImage) {\r
-        this.flashDeviceImage = flashDeviceImage;\r
-        argList.add("-flashdeviceimage");\r
-        argList.add(this.flashDeviceImage);\r
+        this.flashDeviceImage.setArg(" -flashdeviceimage ", flashDeviceImage);\r
 \r
     }\r
 \r
     /**\r
-     * getHeaderFile\r
-     * \r
-     * This function is to get class member "headerFile"\r
-     * \r
-     * @return headerFile name of include file\r
-     */\r
+      getHeaderFile\r
+\r
+      This function is to get class member "headerFile"\r
+\r
+      @return headerFile name of include file\r
+     **/\r
     public String getHeaderFile() {\r
-        return headerFile;\r
+        return this.headerFile.getValue();\r
     }\r
 \r
     /**\r
-     * setHeaderFile\r
-     * \r
-     * This function is to set class member "headerFile"\r
-     * \r
-     * @param headerFile\r
-     *            name of include file\r
-     */\r
+      setHeaderFile\r
+\r
+      This function is to set class member "headerFile"\r
+\r
+      @param headerFile\r
+                 name of include file\r
+     **/\r
     public void setHeaderFile(String headerFile) {\r
-        this.headerFile = headerFile;\r
-        argList.add("-hfile");\r
-        argList.add(this.headerFile);\r
+        this.headerFile.setArg(" -hfile ", headerFile);\r
     }\r
 \r
     /**\r
-     * getImageOutFile\r
-     * \r
-     * This function is to get class member "imageOutFile"\r
-     * \r
-     * @return imageOutFile name of output image file\r
-     */\r
+      getImageOutFile\r
+\r
+      This function is to get class member "imageOutFile"\r
+\r
+      @return imageOutFile name of output image file\r
+     **/\r
     public String getImageOutFile() {\r
-        return imageOutFile;\r
+        return this.imageOutFile.getValue();\r
     }\r
 \r
     /**\r
-     * setImageOutFile\r
-     * \r
-     * This function is to set class member "ImageOutFile"\r
-     * \r
-     * @param imageOutFile\r
-     *            name of output image file\r
-     */\r
+      setImageOutFile\r
+\r
+      This function is to set class member "ImageOutFile"\r
+\r
+      @param imageOutFile\r
+                 name of output image file\r
+     **/\r
     public void setImageOutFile(String imageOutFile) {\r
-        this.imageOutFile = imageOutFile;\r
-        argList.add("-imageout");\r
-        argList.add(this.imageOutFile);\r
+        this.imageOutFile.setArg(" -imageout ", imageOutFile);\r
     }\r
 \r
     /**\r
-     * getInStrFile\r
-     * \r
-     * This function is to get class member "inStrFile"\r
-     * \r
-     * @return inStrFile name of input file which used to replace symbol names.\r
-     */\r
+      getInStrFile\r
+\r
+      This function is to get class member "inStrFile"\r
+\r
+      @return inStrFile name of input file which used to replace symbol names.\r
+     **/\r
     public String getInStrFile() {\r
-        return inStrFile;\r
+        return this.inStrFile;\r
     }\r
 \r
     /**\r
-     * setInStrFile\r
-     * \r
-     * This function is to set class member "inStrFile"\r
-     * \r
-     * @param inStrFile\r
-     *            name of input file which used to replace symbol names.\r
-     */\r
+      setInStrFile\r
+\r
+      This function is to set class member "inStrFile"\r
+\r
+      @param inStrFile\r
+                 name of input file which used to replace symbol names.\r
+     **/\r
     public void setInStrFile(String inStrFile) {\r
         this.inStrFile = inStrFile;\r
     }\r
 \r
     /**\r
-     * getMciFile\r
-     * \r
-     * This function is to get class member "mciFile"\r
-     * \r
-     * @return mciFile name of input microcode file\r
-     */\r
+      getMciFile\r
+\r
+      This function is to get class member "mciFile"\r
+\r
+      @return mciFile name of input microcode file\r
+     **/\r
     public String getMciFile() {\r
-        return mciFile;\r
+        return this.mciFile.getValue();\r
     }\r
 \r
     /**\r
-     * setMciFile\r
-     * \r
-     * This function is to set class member "mciFile"\r
-     * \r
-     * @param mciFile\r
-     *            name of input microcode file\r
-     */\r
+      setMciFile\r
+\r
+      This function is to set class member "mciFile"\r
+\r
+      @param mciFile\r
+                 name of input microcode file\r
+     **/\r
     public void setMciFile(String mciFile) {\r
-        this.mciFile = mciFile;\r
-        argList.add("-mci");\r
-        argList.add(this.mciFile);\r
+        this.mciFile.setArg(" -mci ", mciFile);\r
     }\r
 \r
     /**\r
-     * getMcoFile\r
-     * \r
-     * This function is to get class member "mcoFile"\r
-     * \r
-     * @return mcoFile name of output binary microcode image\r
-     */\r
+      getMcoFile\r
+\r
+      This function is to get class member "mcoFile"\r
+\r
+      @return mcoFile name of output binary microcode image\r
+     **/\r
     public String getMcoFile() {\r
-        return mcoFile;\r
+        return this.mcoFile.getValue();\r
     }\r
 \r
     /**\r
-     * setMcoFile\r
-     * \r
-     * This function is to set class member "mcoFile"\r
-     * \r
-     * @param mcoFile\r
-     *            name of output binary microcode image\r
-     */\r
+      setMcoFile\r
+\r
+      This function is to set class member "mcoFile"\r
+\r
+      @param mcoFile\r
+                 name of output binary microcode image\r
+     **/\r
     public void setMcoFile(String mcoFile) {\r
-        this.mcoFile = mcoFile;\r
-        argList.add("-mco");\r
-        argList.add(this.mcoFile);\r
+        this.mcoFile.setArg(" -mco ", mcoFile);\r
     }\r
 \r
     /**\r
-     * getOutStrFile\r
-     * \r
-     * This function is to get class member "outStrFile"\r
-     * \r
-     * @return outStrFile name of output string substitution file\r
-     */\r
+      getOutStrFile\r
+\r
+      This function is to get class member "outStrFile"\r
+\r
+      @return outStrFile name of output string substitution file\r
+     **/\r
     public String getOutStrFile() {\r
-        return outStrFile;\r
+        return this.outStrFile;\r
     }\r
 \r
     /**\r
-     * setOutStrFile\r
-     * \r
-     * This function is to set class member "outStrFile"\r
-     * \r
-     * @param outStrFile\r
-     *            name of output string substitution file\r
-     */\r
+      setOutStrFile\r
+\r
+      This function is to set class member "outStrFile"\r
+\r
+      @param outStrFile\r
+                 name of output string substitution file\r
+     **/\r
     public void setOutStrFile(String outStrFile) {\r
         this.outStrFile = outStrFile;\r
     }\r
 \r
     /**\r
-     * getPadValue\r
-     * \r
-     * This function is to get class member "padValue"\r
-     * \r
-     * @return padValue string of byte value to use as padding\r
-     */\r
+      getPadValue\r
+\r
+      This function is to get class member "padValue"\r
+\r
+      @return padValue string of byte value to use as padding\r
+     **/\r
     public String getPadValue() {\r
-        return padValue;\r
+        return this.padValue.getValue();\r
     }\r
 \r
     /**\r
-     * setPadValue\r
-     * \r
-     * This function is to set class member "padValue"\r
-     * \r
-     * @param padValue\r
-     *            string of byte value to use as padding\r
-     */\r
+      setPadValue\r
+\r
+      This function is to set class member "padValue"\r
+\r
+      @param padValue\r
+                 string of byte value to use as padding\r
+     **/\r
     public void setPadValue(String padValue) {\r
-        this.padValue = padValue;\r
-        argList.add("-padvalue");\r
-        argList.add(this.padValue);\r
+        this.padValue.setArg(" -padvalue ", padValue);\r
     }\r
 \r
     /**\r
-     * addMciFile\r
-     * \r
-     * This function is to add Microcode binary file\r
-     * \r
-     * @param mciFile\r
-     *            instance of input class\r
-     */\r
-    public void addMciFile(Input mciFile) {\r
-        this.mciFileArray.add(mciFile);\r
+      addMciFile\r
+\r
+      This function is to add Microcode binary file\r
+\r
+      @param mciFile\r
+                 instance of input class\r
+     **/\r
+    public void addConfiguredMciFile(FileArg mciFile) {\r
+        this.mciFileArray.setPrefix(" -mcmerge ");\r
+        this.mciFileArray.insert(mciFile);\r
     }\r
 \r
     /**\r
-     * getOutputDir\r
-     * \r
-     * This function is to get class member "outputDir"\r
-     * \r
-     * @return outputDir string of output directory\r
-     */\r
+      getOutputDir\r
+\r
+      This function is to get class member "outputDir"\r
+\r
+      @return outputDir string of output directory\r
+     **/\r
     public String getOutputDir() {\r
         return outputDir;\r
     }\r
 \r
     /**\r
-     * setOutputDir\r
-     * \r
-     * This function is to set class member "outputDir"\r
-     * \r
-     * @param outputDir\r
-     *            string of output directory\r
-     */\r
+      setOutputDir\r
+\r
+      This function is to set class member "outputDir"\r
+\r
+      @param outputDir\r
+                 string of output directory\r
+     **/\r
     public void setOutputDir(String outputDir) {\r
         this.outputDir = outputDir;\r
     }\r
+\r
+    //\r
+    // Dependency check\r
+    //\r
+    private boolean isUptodate() {\r
+        long srcTimeStamp = 0;\r
+        String srcName = "";\r
+        String dstName = "";\r
+        long timeStamp = 0;\r
+\r
+        if (!flashDefFile.isEmpty()) {\r
+            srcName = flashDefFile.getValue();\r
+            timeStamp = new File(srcName).lastModified();\r
+            if (timeStamp > srcTimeStamp) {\r
+                srcTimeStamp = timeStamp;\r
+            }\r
+        }\r
+\r
+        if (!mciFile.isEmpty()) {\r
+            srcName = mciFile.getValue();\r
+            timeStamp = new File(srcName).lastModified();\r
+            if (timeStamp > srcTimeStamp) {\r
+                srcTimeStamp = timeStamp;\r
+            }\r
+        }\r
+\r
+        if (!fdImage.isEmpty()) {\r
+            srcName = fdImage.getValue();\r
+            timeStamp = new File(srcName).lastModified();\r
+            if (timeStamp > srcTimeStamp) {\r
+                srcTimeStamp = timeStamp;\r
+            }\r
+        }\r
+\r
+        if (inStrFile.length() != 0) {\r
+            srcName = inStrFile;\r
+            timeStamp = new File(srcName).lastModified();\r
+            if (timeStamp > srcTimeStamp) {\r
+                srcTimeStamp = timeStamp;\r
+            }\r
+        }\r
+\r
+        if (!mciFileArray.isEmpty()) {\r
+            for (int i = 0; i < mciFileArray.nameList.size(); ++i) {\r
+                srcName += mciFileArray.nameList.get(i) + " ";\r
+                timeStamp = new File(mciFileArray.nameList.get(i)).lastModified();\r
+                if (timeStamp > srcTimeStamp) {\r
+                    srcTimeStamp = timeStamp;\r
+                }\r
+            }\r
+        }\r
+\r
+        if (!headerFile.isEmpty()) {\r
+            dstName = headerFile.getValue();\r
+            File dstFile = new File(dstName);\r
+            if (!dstFile.isAbsolute()) {\r
+                dstName = outputDir + File.separator + dstName;\r
+                dstFile = new File(dstName);\r
+            }\r
+\r
+            if (srcTimeStamp > dstFile.lastModified()) {\r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, srcName + " has been changed since last build!");\r
+                return false;\r
+            }\r
+        }\r
+\r
+        if (!imageOutFile.isEmpty()) {\r
+            dstName = imageOutFile.getValue();\r
+            File dstFile = new File(dstName);\r
+            if (!dstFile.isAbsolute()) {\r
+                dstName = outputDir + File.separator + dstName;\r
+                dstFile = new File(dstName);\r
+            }\r
+\r
+            if (srcTimeStamp > dstFile.lastModified()) {\r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, srcName + " has been changed since last build!");\r
+                return false;\r
+            }\r
+\r
+            //\r
+            // we need to check the time stamp of each FV file specified in fdf file\r
+            // \r
+            if (!isFdUptodate(dstName, getFvFiles(flashDefFile.getValue()))) {\r
+                return false;\r
+            }\r
+        }\r
+\r
+        if (!mcoFile.isEmpty()) {\r
+            dstName = mcoFile.getValue();\r
+            File dstFile = new File(dstName);\r
+            if (!dstFile.isAbsolute()) {\r
+                dstName = outputDir + File.separator + dstName;\r
+                dstFile = new File(dstName);\r
+            }\r
+\r
+            if (srcTimeStamp > dstFile.lastModified()) {\r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, srcName + " has been changed since last build!");\r
+                return false;\r
+            }\r
+        }\r
+\r
+        if (!dscFile.isEmpty()) {\r
+            dstName = dscFile.getValue();\r
+            File dstFile = new File(dstName);\r
+            if (!dstFile.isAbsolute()) {\r
+                dstName = outputDir + File.separator + dstName;\r
+                dstFile = new File(dstName);\r
+            }\r
+\r
+            if (srcTimeStamp > dstFile.lastModified()) {\r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, srcName + " has been changed since last build!");\r
+                return false;\r
+            }\r
+        }\r
+\r
+        if (!asmIncFile.isEmpty()) {\r
+            dstName = asmIncFile.getValue();\r
+            File dstFile = new File(dstName);\r
+            if (!dstFile.isAbsolute()) {\r
+                dstName = outputDir + File.separator + dstName;\r
+                dstFile = new File(dstName);\r
+            }\r
+\r
+            if (srcTimeStamp > dstFile.lastModified()) {\r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, srcName + " has been changed since last build!");\r
+                return false;\r
+            }\r
+        }\r
+\r
+        if (outStrFile.length() != 0) {\r
+            dstName = outStrFile;\r
+            File dstFile = new File(dstName);\r
+            if (!dstFile.isAbsolute()) {\r
+                dstName = outputDir + File.separator + dstName;\r
+                dstFile = new File(dstName);\r
+            }\r
+\r
+            if (srcTimeStamp > dstFile.lastModified()) {\r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, srcName + " has been changed since last build!");\r
+                return false;\r
+            }\r
+        }\r
+\r
+        return true;\r
+    }\r
+\r
+    //\r
+    // Parse the flash definition file and find out the FV file names\r
+    // \r
+    private List<String> getFvFiles(String fdfFileName) {\r
+        File fdfFile = new File(fdfFileName);\r
+        int fileLength = (int)fdfFile.length();\r
+        char[] fdfContent = new char[fileLength];\r
+        List<String> fileList = new ArrayList<String>();\r
+\r
+        try {\r
+            FileReader reader = new FileReader(fdfFile);\r
+            BufferedReader in = new BufferedReader(reader);\r
+\r
+            in.read(fdfContent, 0, fileLength);\r
+            String str = new String(fdfContent);\r
+\r
+            //\r
+            // match the \r
+            //      File {\r
+            //        ...\r
+            //      }\r
+            // block\r
+            // \r
+            Matcher matcher = fileBlock.matcher(str);\r
+            while (matcher.find()) {\r
+                String fileBlockContent = str.substring(matcher.start(1), matcher.end(1));\r
+                //\r
+                // match the definition like\r
+                //      Name = "..."\r
+                //  \r
+                Matcher nameMatcher = fileNameDef.matcher(fileBlockContent);\r
+                if (nameMatcher.find()) {\r
+                    fileList.add(fileBlockContent.substring(nameMatcher.start(1), nameMatcher.end(1)));\r
+                }\r
+            }\r
+\r
+            in.close();\r
+            reader.close();\r
+        } catch (Exception ex) {\r
+            throw new BuildException(ex.getMessage());\r
+        }\r
+\r
+        return fileList;\r
+    }\r
+\r
+    private boolean isFdUptodate(String fdFile, List<String> fvFileList) {\r
+        String fvDir = ".";\r
+        File fd = new File(fdFile);\r
+\r
+        if (outputDir.equals(".")) {\r
+            if (!fd.isAbsolute()) {\r
+                //\r
+                // If we cannot get the absolute path of fd file, we caanot\r
+                // get its time stamp. Re-generate it always in such situation.\r
+                // \r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, "Cannot retrieve the time stamp of " + fdFile);\r
+                return false;\r
+            }\r
+            fvDir = fd.getParent();\r
+        } else {\r
+            fvDir = outputDir;\r
+            if (!fd.isAbsolute()) {\r
+                fd = new File(fvDir + File.separator + fdFile);\r
+            }\r
+        }\r
+\r
+        long fdTimeStamp = fd.lastModified();\r
+        for (int i = 0; i < fvFileList.size(); ++i) {\r
+            File fv = new File(fvDir + File.separator + fvFileList.get(i));\r
+            if (fv.lastModified() > fdTimeStamp) {\r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, fv.getPath() + " has been changed since last build!");\r
+                return false;\r
+            }\r
+        }\r
+\r
+        return true;\r
+    }\r
 }\r