4 FlashMapTask is used to call FlashMap.exe to lay out the flash.
7 Copyright (c) 2006, Intel Corporation
8 All rights reserved. This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 package org
.tianocore
.framework
.tasks
;
20 import java
.io
.FileReader
;
21 import java
.io
.BufferedReader
;
23 import java
.util
.List
;
24 import java
.util
.ArrayList
;
25 import java
.util
.regex
.Pattern
;
26 import java
.util
.regex
.Matcher
;
28 import org
.apache
.tools
.ant
.Task
;
29 import org
.apache
.tools
.ant
.Project
;
30 import org
.apache
.tools
.ant
.BuildException
;
31 import org
.apache
.tools
.ant
.taskdefs
.Execute
;
32 import org
.apache
.tools
.ant
.taskdefs
.LogStreamHandler
;
33 import org
.apache
.tools
.ant
.types
.Commandline
;
35 import org
.tianocore
.common
.logger
.EdkLog
;
40 * FlashMapTask is used to call FlashMap.exe to generate flash map defition files and fd files.
42 public class FlashMapTask
extends Task
implements EfiDefine
{
46 private static final String toolName
= "FlashMap";
51 private static Pattern fileBlock
= Pattern
.compile("\\s*File\\s*\\{([^\\{\\}]+)\\}");
52 private static Pattern fileNameDef
= Pattern
.compile("\\bName\\s*=\\s*\"([^\"]+)\"");
55 // Flash definition file
57 private FileArg flashDefFile
= new FileArg();
62 private ToolArg flashDevice
= new ToolArg();
67 private ToolArg flashDeviceImage
= new ToolArg();
72 private FileArg mciFile
= new FileArg();
77 private FileArg mcoFile
= new FileArg();
82 private ToolArg fdImage
= new ToolArg();
87 private FileArg dscFile
= new FileArg();
92 private FileArg asmIncFile
= new FileArg();
97 private FileArg imageOutFile
= new FileArg();
102 private FileArg headerFile
= new FileArg();
107 private String inStrFile
= "";
110 // Output string file
112 private String outStrFile
= "";
117 private FileArg strFile
= new FileArg();
121 private ToolArg baseAddr
= new ToolArg();
126 private ToolArg aligment
= new ToolArg();
131 private ToolArg padValue
= new ToolArg();
136 private String outputDir
= ".";
141 FileArg mciFileArray
= new FileArg();
146 FlashMapTask execute function is to assemble tool command line & execute
149 @throws BuidException
151 public void execute() throws BuildException
{
153 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, headerFile
.toFileList()
154 + imageOutFile
.toFileList()
155 + mcoFile
.toFileList()
156 + dscFile
.toFileList()
157 + asmIncFile
.toFileList()
159 + " is up-to-date!");
163 Project project
= this.getOwningTarget().getProject();
165 // absolute path of efi tools
167 String path
= project
.getProperty("env.FRAMEWORK_TOOLS_PATH");
172 command
= path
+ File
.separator
+ toolName
;
176 // add substituted input file and output file
178 if (this.inStrFile
!= null && this.outStrFile
!= null
179 && this.inStrFile
.length() > 0 && this.outStrFile
.length() > 0) {
180 strFile
.setPrefix(" -strsub ");
181 strFile
.insValue(this.inStrFile
);
182 strFile
.insValue(this.outStrFile
);
185 String argument
= "" + flashDefFile
+ flashDevice
+ flashDeviceImage
186 + mciFile
+ mcoFile
+ fdImage
+ dscFile
+ asmIncFile
187 + imageOutFile
+ headerFile
+ strFile
+ baseAddr
188 + aligment
+ padValue
+ mciFileArray
;
194 // ProcessBuilder pb = new ProcessBuilder(argList);
195 // pb.directory(new File(outputDir));
198 Commandline cmdline
= new Commandline();
199 cmdline
.setExecutable(command
);
200 cmdline
.createArgument().setLine(argument
);
202 LogStreamHandler streamHandler
= new LogStreamHandler(this,
203 Project
.MSG_INFO
, Project
.MSG_WARN
);
204 Execute runner
= new Execute(streamHandler
, null);
206 runner
.setAntRun(project
);
207 runner
.setCommandline(cmdline
.getCommandline());
209 if (outputDir
!= null) {
210 runner
.setWorkingDirectory(new File(outputDir
));
213 // log command line string.
215 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, Commandline
.toString(cmdline
.getCommandline()));
216 EdkLog
.log(this, flashDefFile
.toFileList()
217 + mciFile
.toFileList()
218 + mciFileArray
.toFileList()
219 + fdImage
.toFileList()
222 + headerFile
.toFileList()
223 + imageOutFile
.toFileList()
224 + mcoFile
.toFileList()
225 + dscFile
.toFileList()
226 + asmIncFile
.toFileList()
229 exitCode
= runner
.execute();
231 EdkLog
.log(this, "ERROR = " + Integer
.toHexString(exitCode
));
233 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, "FlashMap succeeded!");
235 } catch (Exception e
) {
236 throw new BuildException(e
.getMessage());
239 throw new BuildException("FlashMap failed!");
247 This function is to get class member "flashDefFile"
249 @return flashDeFile Name of flash definition file.
251 public String
getFlashDefFile() {
252 return this.flashDefFile
.getValue();
258 This function is to set class member "flashDefFile"
261 Name of flash definition file.
263 public void setFlashDefFile(String flashDefFile
) {
264 this.flashDefFile
.setArg(" -fdf ", flashDefFile
);
270 This function is to get class member "aligment"
272 @return aligment String of aligment value.
274 public String
getAligment() {
275 return this.aligment
.getValue();
281 This function is to set class member "aligment"
284 String of aligment value.
286 public void setAligment(String aligment
) {
287 this.aligment
.setArg(" -align ", aligment
);
293 This function is to get class member "asmIncFile"
295 @return asmIncFile String of ASM include file.
297 public String
getAsmIncFile() {
298 return this.asmIncFile
.getValue();
304 This function is to set class member "asmIncFile"
307 String of ASM include file.
309 public void setAsmIncFile(String asmIncFile
) {
310 this.asmIncFile
.setArg(" -asmincfile ", asmIncFile
);
316 This function is to get class member "baseAddr"
318 @return baseAddr String of base address value.
320 public String
getBaseAddr() {
321 return this.baseAddr
.getValue();
327 This function is to set class member "baseAddr"
330 String of base address value.
332 public void setBaseAddr(String baseAddr
) {
333 this.baseAddr
.setArg(" -baseaddr ", baseAddr
);
339 This function is to get class member "dscFile"
341 @return dscFile name of DSC file
343 public String
getDscFile() {
344 return this.dscFile
.getValue();
350 This function is to set class member "dscFile"
355 public void setDscFile(String dscFile
) {
356 this.dscFile
.setArg(" -dsc ", dscFile
);
362 This function is to get class member "fdImage"
364 @return fdImage name of input FDI image file.
366 public String
getFdImage() {
367 return this.fdImage
.getValue();
373 This function is to set class member "fdImage"
376 name of input FDI image file.
378 public void setFdImage(String fdImage
) {
379 this.fdImage
.setArg(" -discover ", fdImage
);
385 This function is to get class member "flashDevice".
387 @return flashDevice name of flash device.
389 public String
getFlashDevice() {
390 return this.flashDevice
.getValue();
396 This function is to set class member "flashDevice"
399 name of flash device.
401 public void setFlashDevice(String flashDevice
) {
402 this.flashDevice
.setArg(" -flashdevice ", flashDevice
);
408 This function is to get class member "flashDeviceImage"
410 @return flashDeviceImage name of flash device image
412 public String
getFlashDeviceImage() {
413 return this.flashDeviceImage
.getValue();
419 This function is to set class member "flashDeviceImage"
421 @param flashDeviceImage
422 name of flash device image
424 public void setFlashDeviceImage(String flashDeviceImage
) {
425 this.flashDeviceImage
.setArg(" -flashdeviceimage ", flashDeviceImage
);
432 This function is to get class member "headerFile"
434 @return headerFile name of include file
436 public String
getHeaderFile() {
437 return this.headerFile
.getValue();
443 This function is to set class member "headerFile"
448 public void setHeaderFile(String headerFile
) {
449 this.headerFile
.setArg(" -hfile ", headerFile
);
455 This function is to get class member "imageOutFile"
457 @return imageOutFile name of output image file
459 public String
getImageOutFile() {
460 return this.imageOutFile
.getValue();
466 This function is to set class member "ImageOutFile"
469 name of output image file
471 public void setImageOutFile(String imageOutFile
) {
472 this.imageOutFile
.setArg(" -imageout ", imageOutFile
);
478 This function is to get class member "inStrFile"
480 @return inStrFile name of input file which used to replace symbol names.
482 public String
getInStrFile() {
483 return this.inStrFile
;
489 This function is to set class member "inStrFile"
492 name of input file which used to replace symbol names.
494 public void setInStrFile(String inStrFile
) {
495 this.inStrFile
= inStrFile
;
501 This function is to get class member "mciFile"
503 @return mciFile name of input microcode file
505 public String
getMciFile() {
506 return this.mciFile
.getValue();
512 This function is to set class member "mciFile"
515 name of input microcode file
517 public void setMciFile(String mciFile
) {
518 this.mciFile
.setArg(" -mci ", mciFile
);
524 This function is to get class member "mcoFile"
526 @return mcoFile name of output binary microcode image
528 public String
getMcoFile() {
529 return this.mcoFile
.getValue();
535 This function is to set class member "mcoFile"
538 name of output binary microcode image
540 public void setMcoFile(String mcoFile
) {
541 this.mcoFile
.setArg(" -mco ", mcoFile
);
547 This function is to get class member "outStrFile"
549 @return outStrFile name of output string substitution file
551 public String
getOutStrFile() {
552 return this.outStrFile
;
558 This function is to set class member "outStrFile"
561 name of output string substitution file
563 public void setOutStrFile(String outStrFile
) {
564 this.outStrFile
= outStrFile
;
570 This function is to get class member "padValue"
572 @return padValue string of byte value to use as padding
574 public String
getPadValue() {
575 return this.padValue
.getValue();
581 This function is to set class member "padValue"
584 string of byte value to use as padding
586 public void setPadValue(String padValue
) {
587 this.padValue
.setArg(" -padvalue ", padValue
);
593 This function is to add Microcode binary file
596 instance of input class
598 public void addConfiguredMciFile(FileArg mciFile
) {
599 this.mciFileArray
.setPrefix(" -mcmerge ");
600 this.mciFileArray
.insert(mciFile
);
606 This function is to get class member "outputDir"
608 @return outputDir string of output directory
610 public String
getOutputDir() {
617 This function is to set class member "outputDir"
620 string of output directory
622 public void setOutputDir(String outputDir
) {
623 this.outputDir
= outputDir
;
629 private boolean isUptodate() {
630 long srcTimeStamp
= 0;
632 long dstTimeStamp
= 0;
636 if (!flashDefFile
.isEmpty()) {
637 srcName
= flashDefFile
.getValue();
638 timeStamp
= new File(srcName
).lastModified();
639 if (timeStamp
> srcTimeStamp
) {
640 srcTimeStamp
= timeStamp
;
644 if (!mciFile
.isEmpty()) {
645 srcName
= mciFile
.getValue();
646 timeStamp
= new File(srcName
).lastModified();
647 if (timeStamp
> srcTimeStamp
) {
648 srcTimeStamp
= timeStamp
;
652 if (!fdImage
.isEmpty()) {
653 srcName
= fdImage
.getValue();
654 timeStamp
= new File(srcName
).lastModified();
655 if (timeStamp
> srcTimeStamp
) {
656 srcTimeStamp
= timeStamp
;
660 if (inStrFile
.length() != 0) {
662 timeStamp
= new File(srcName
).lastModified();
663 if (timeStamp
> srcTimeStamp
) {
664 srcTimeStamp
= timeStamp
;
668 if (!mciFileArray
.isEmpty()) {
669 for (int i
= 0; i
< mciFileArray
.nameList
.size(); ++i
) {
670 srcName
+= mciFileArray
.nameList
.get(i
) + " ";
671 timeStamp
= new File(mciFileArray
.nameList
.get(i
)).lastModified();
672 if (timeStamp
> srcTimeStamp
) {
673 srcTimeStamp
= timeStamp
;
678 if (!headerFile
.isEmpty()) {
679 dstName
= headerFile
.getValue();
680 File dstFile
= new File(dstName
);
681 if (!dstFile
.isAbsolute()) {
682 dstName
= outputDir
+ File
.separator
+ dstName
;
683 dstFile
= new File(dstName
);
686 if (srcTimeStamp
> dstFile
.lastModified()) {
687 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
692 if (!imageOutFile
.isEmpty()) {
693 dstName
= imageOutFile
.getValue();
694 File dstFile
= new File(dstName
);
695 if (!dstFile
.isAbsolute()) {
696 dstName
= outputDir
+ File
.separator
+ dstName
;
697 dstFile
= new File(dstName
);
700 if (srcTimeStamp
> dstFile
.lastModified()) {
701 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
706 // we need to check the time stamp of each FV file specified in fdf file
708 if (!isFdUptodate(dstName
, getFvFiles(flashDefFile
.getValue()))) {
713 if (!mcoFile
.isEmpty()) {
714 dstName
= mcoFile
.getValue();
715 File dstFile
= new File(dstName
);
716 if (!dstFile
.isAbsolute()) {
717 dstName
= outputDir
+ File
.separator
+ dstName
;
718 dstFile
= new File(dstName
);
721 if (srcTimeStamp
> dstFile
.lastModified()) {
722 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
727 if (!dscFile
.isEmpty()) {
728 dstName
= dscFile
.getValue();
729 File dstFile
= new File(dstName
);
730 if (!dstFile
.isAbsolute()) {
731 dstName
= outputDir
+ File
.separator
+ dstName
;
732 dstFile
= new File(dstName
);
735 if (srcTimeStamp
> dstFile
.lastModified()) {
736 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
741 if (!asmIncFile
.isEmpty()) {
742 dstName
= asmIncFile
.getValue();
743 File dstFile
= new File(dstName
);
744 if (!dstFile
.isAbsolute()) {
745 dstName
= outputDir
+ File
.separator
+ dstName
;
746 dstFile
= new File(dstName
);
749 if (srcTimeStamp
> dstFile
.lastModified()) {
750 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
755 if (outStrFile
.length() != 0) {
756 dstName
= outStrFile
;
757 File dstFile
= new File(dstName
);
758 if (!dstFile
.isAbsolute()) {
759 dstName
= outputDir
+ File
.separator
+ dstName
;
760 dstFile
= new File(dstName
);
763 if (srcTimeStamp
> dstFile
.lastModified()) {
764 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
773 // Parse the flash definition file and find out the FV file names
775 private List
<String
> getFvFiles(String fdfFileName
) {
776 File fdfFile
= new File(fdfFileName
);
777 int fileLength
= (int)fdfFile
.length();
778 char[] fdfContent
= new char[fileLength
];
779 List
<String
> fileList
= new ArrayList
<String
>();
782 FileReader reader
= new FileReader(fdfFile
);
783 BufferedReader in
= new BufferedReader(reader
);
785 in
.read(fdfContent
, 0, fileLength
);
786 String str
= new String(fdfContent
);
795 Matcher matcher
= fileBlock
.matcher(str
);
796 while (matcher
.find()) {
797 String fileBlockContent
= str
.substring(matcher
.start(1), matcher
.end(1));
799 // match the definition like
802 Matcher nameMatcher
= fileNameDef
.matcher(fileBlockContent
);
803 if (nameMatcher
.find()) {
804 fileList
.add(fileBlockContent
.substring(nameMatcher
.start(1), nameMatcher
.end(1)));
810 } catch (Exception ex
) {
811 throw new BuildException(ex
.getMessage());
817 private boolean isFdUptodate(String fdFile
, List
<String
> fvFileList
) {
819 File fd
= new File(fdFile
);
821 if (outputDir
.equals(".")) {
822 if (!fd
.isAbsolute()) {
824 // If we cannot get the absolute path of fd file, we caanot
825 // get its time stamp. Re-generate it always in such situation.
827 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, "Cannot retrieve the time stamp of " + fdFile
);
830 fvDir
= fd
.getParent();
833 if (!fd
.isAbsolute()) {
834 fd
= new File(fvDir
+ File
.separator
+ fdFile
);
838 long fdTimeStamp
= fd
.lastModified();
839 for (int i
= 0; i
< fvFileList
.size(); ++i
) {
840 File fv
= new File(fvDir
+ File
.separator
+ fvFileList
.get(i
));
841 if (fv
.lastModified() > fdTimeStamp
) {
842 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, fv
.getPath() + " has been changed since last build!");