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;
635 if (!flashDefFile
.isEmpty()) {
636 srcName
= flashDefFile
.getValue();
637 timeStamp
= new File(srcName
).lastModified();
638 if (timeStamp
> srcTimeStamp
) {
639 srcTimeStamp
= timeStamp
;
643 if (!mciFile
.isEmpty()) {
644 srcName
= mciFile
.getValue();
645 timeStamp
= new File(srcName
).lastModified();
646 if (timeStamp
> srcTimeStamp
) {
647 srcTimeStamp
= timeStamp
;
651 if (!fdImage
.isEmpty()) {
652 srcName
= fdImage
.getValue();
653 timeStamp
= new File(srcName
).lastModified();
654 if (timeStamp
> srcTimeStamp
) {
655 srcTimeStamp
= timeStamp
;
659 if (inStrFile
.length() != 0) {
661 timeStamp
= new File(srcName
).lastModified();
662 if (timeStamp
> srcTimeStamp
) {
663 srcTimeStamp
= timeStamp
;
667 if (!mciFileArray
.isEmpty()) {
668 for (int i
= 0; i
< mciFileArray
.nameList
.size(); ++i
) {
669 srcName
+= mciFileArray
.nameList
.get(i
) + " ";
670 timeStamp
= new File(mciFileArray
.nameList
.get(i
)).lastModified();
671 if (timeStamp
> srcTimeStamp
) {
672 srcTimeStamp
= timeStamp
;
677 if (!headerFile
.isEmpty()) {
678 dstName
= headerFile
.getValue();
679 File dstFile
= new File(dstName
);
680 if (!dstFile
.isAbsolute()) {
681 dstName
= outputDir
+ File
.separator
+ dstName
;
682 dstFile
= new File(dstName
);
685 if (srcTimeStamp
> dstFile
.lastModified()) {
686 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
691 if (!imageOutFile
.isEmpty()) {
692 dstName
= imageOutFile
.getValue();
693 File dstFile
= new File(dstName
);
694 if (!dstFile
.isAbsolute()) {
695 dstName
= outputDir
+ File
.separator
+ dstName
;
696 dstFile
= new File(dstName
);
699 if (srcTimeStamp
> dstFile
.lastModified()) {
700 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
705 // we need to check the time stamp of each FV file specified in fdf file
707 if (!isFdUptodate(dstName
, getFvFiles(flashDefFile
.getValue()))) {
712 if (!mcoFile
.isEmpty()) {
713 dstName
= mcoFile
.getValue();
714 File dstFile
= new File(dstName
);
715 if (!dstFile
.isAbsolute()) {
716 dstName
= outputDir
+ File
.separator
+ dstName
;
717 dstFile
= new File(dstName
);
720 if (srcTimeStamp
> dstFile
.lastModified()) {
721 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
726 if (!dscFile
.isEmpty()) {
727 dstName
= dscFile
.getValue();
728 File dstFile
= new File(dstName
);
729 if (!dstFile
.isAbsolute()) {
730 dstName
= outputDir
+ File
.separator
+ dstName
;
731 dstFile
= new File(dstName
);
734 if (srcTimeStamp
> dstFile
.lastModified()) {
735 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
740 if (!asmIncFile
.isEmpty()) {
741 dstName
= asmIncFile
.getValue();
742 File dstFile
= new File(dstName
);
743 if (!dstFile
.isAbsolute()) {
744 dstName
= outputDir
+ File
.separator
+ dstName
;
745 dstFile
= new File(dstName
);
748 if (srcTimeStamp
> dstFile
.lastModified()) {
749 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
754 if (outStrFile
.length() != 0) {
755 dstName
= outStrFile
;
756 File dstFile
= new File(dstName
);
757 if (!dstFile
.isAbsolute()) {
758 dstName
= outputDir
+ File
.separator
+ dstName
;
759 dstFile
= new File(dstName
);
762 if (srcTimeStamp
> dstFile
.lastModified()) {
763 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, srcName
+ " has been changed since last build!");
772 // Parse the flash definition file and find out the FV file names
774 private List
<String
> getFvFiles(String fdfFileName
) {
775 File fdfFile
= new File(fdfFileName
);
776 int fileLength
= (int)fdfFile
.length();
777 char[] fdfContent
= new char[fileLength
];
778 List
<String
> fileList
= new ArrayList
<String
>();
781 FileReader reader
= new FileReader(fdfFile
);
782 BufferedReader in
= new BufferedReader(reader
);
784 in
.read(fdfContent
, 0, fileLength
);
785 String str
= new String(fdfContent
);
794 Matcher matcher
= fileBlock
.matcher(str
);
795 while (matcher
.find()) {
796 String fileBlockContent
= str
.substring(matcher
.start(1), matcher
.end(1));
798 // match the definition like
801 Matcher nameMatcher
= fileNameDef
.matcher(fileBlockContent
);
802 if (nameMatcher
.find()) {
803 fileList
.add(fileBlockContent
.substring(nameMatcher
.start(1), nameMatcher
.end(1)));
809 } catch (Exception ex
) {
810 throw new BuildException(ex
.getMessage());
816 private boolean isFdUptodate(String fdFile
, List
<String
> fvFileList
) {
818 File fd
= new File(fdFile
);
820 if (outputDir
.equals(".")) {
821 if (!fd
.isAbsolute()) {
823 // If we cannot get the absolute path of fd file, we caanot
824 // get its time stamp. Re-generate it always in such situation.
826 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, "Cannot retrieve the time stamp of " + fdFile
);
829 fvDir
= fd
.getParent();
832 if (!fd
.isAbsolute()) {
833 fd
= new File(fvDir
+ File
.separator
+ fdFile
);
837 long fdTimeStamp
= fd
.lastModified();
838 for (int i
= 0; i
< fvFileList
.size(); ++i
) {
839 File fv
= new File(fvDir
+ File
.separator
+ fvFileList
.get(i
));
840 if (fv
.lastModified() > fdTimeStamp
) {
841 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, fv
.getPath() + " has been changed since last build!");