| 1 | /** @file\r |
| 2 | GenFfsFileTask class.\r |
| 3 | \r |
| 4 | GenFfsFileTaks is to generate ffs file.\r |
| 5 | \r |
| 6 | Copyright (c) 2006, Intel Corporation\r |
| 7 | All rights reserved. This program and the accompanying materials\r |
| 8 | are licensed and made available under the terms and conditions of the BSD License\r |
| 9 | which accompanies this distribution. The full text of the license may be found at\r |
| 10 | http://opensource.org/licenses/bsd-license.php\r |
| 11 | \r |
| 12 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r |
| 13 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r |
| 14 | \r |
| 15 | **/\r |
| 16 | package org.tianocore.framework.tasks;\r |
| 17 | \r |
| 18 | import java.io.DataInputStream;\r |
| 19 | import java.io.DataOutputStream;\r |
| 20 | import java.io.File;\r |
| 21 | import java.io.FileInputStream;\r |
| 22 | import java.io.FileOutputStream;\r |
| 23 | import java.util.ArrayList;\r |
| 24 | import java.util.Iterator;\r |
| 25 | import java.util.List;\r |
| 26 | \r |
| 27 | import org.apache.tools.ant.BuildException;\r |
| 28 | import org.apache.tools.ant.Project;\r |
| 29 | import org.apache.tools.ant.Task;\r |
| 30 | \r |
| 31 | /**\r |
| 32 | GenFfsFileTask\r |
| 33 | \r |
| 34 | GenFfsFileTaks is to generate ffs file.\r |
| 35 | \r |
| 36 | **/\r |
| 37 | public class GenFfsFileTask extends Task implements EfiDefine, FfsTypes {\r |
| 38 | /**\r |
| 39 | * GenFfsFile Task Class\r |
| 40 | * class member \r |
| 41 | * -baseName : module baseName\r |
| 42 | * -ffsFileGuid : module Guid.\r |
| 43 | * -ffsFileType : Ffs file type. \r |
| 44 | * -ffsAttributeRecovery : The file is required for recovery.\r |
| 45 | * -ffsAligment : The file data alignment (0 if none required). See FFS \r |
| 46 | * specification for supported alignments (0-7 are only possible \r |
| 47 | * values). *\r |
| 48 | * -ffsAttributeCheckSum : The file data is checksummed. If this is FALSE a \r |
| 49 | * value of 0x5A will be inserted in the file \r |
| 50 | * checksum field of the file header. *\r |
| 51 | * -sectFileDir : specifies the full path to the component build directory.\r |
| 52 | * Required.\r |
| 53 | * -ffsAttrib : Data recorde attribute added result.\r |
| 54 | * -sectionList : List recorded all section elemet in task.\r |
| 55 | */\r |
| 56 | ///\r |
| 57 | /// module baseName\r |
| 58 | ///\r |
| 59 | String baseName = "";\r |
| 60 | ///\r |
| 61 | /// \r |
| 62 | /// \r |
| 63 | String moduleType;\r |
| 64 | ///\r |
| 65 | /// module Guid\r |
| 66 | ///\r |
| 67 | String ffsFileGuid = "";\r |
| 68 | ///\r |
| 69 | /// Ffs file type\r |
| 70 | ///\r |
| 71 | String ffsFileType = "";\r |
| 72 | ///\r |
| 73 | /// ffsAttribHeaderExtension value is used to set the corresponding bit in \r |
| 74 | /// the output FFS file header \r |
| 75 | ///\r |
| 76 | boolean ffsAttribHeaderExtension = false;\r |
| 77 | ///\r |
| 78 | /// ffsAttribTailPresent value is used to set the corresponding bit in the \r |
| 79 | /// output FFS file header\r |
| 80 | ///\r |
| 81 | boolean ffsAttribTailPresent = false;\r |
| 82 | ///\r |
| 83 | /// ffsAttribRecovery value is used to set the corresponding bit in the \r |
| 84 | /// output FFS file header\r |
| 85 | ///\r |
| 86 | boolean ffsAttribRecovery = false;\r |
| 87 | ///\r |
| 88 | /// ffsAligenment value is used to set the corresponding bit in the output \r |
| 89 | /// FFS file header.The specified FFS alignment must be a value between 0 \r |
| 90 | /// and 7 inclusive\r |
| 91 | ///\r |
| 92 | int ffsAlignment = 0;\r |
| 93 | ///\r |
| 94 | /// ffsAttribChecksum value is used to set the corresponding bit in the \r |
| 95 | /// output FFS file header\r |
| 96 | ///\r |
| 97 | boolean FfsAttribChecksum = false;\r |
| 98 | ///\r |
| 99 | /// Attribute is used to record the sum of all bit in the output FFS file.\r |
| 100 | ///\r |
| 101 | byte attributes = 0;\r |
| 102 | ///\r |
| 103 | /// The output directory of ffs file.\r |
| 104 | ///\r |
| 105 | String outputDir = "";\r |
| 106 | ///\r |
| 107 | /// List of section.\r |
| 108 | ///\r |
| 109 | List<Object> sectionList = new ArrayList<Object>();\r |
| 110 | \r |
| 111 | ///\r |
| 112 | /// The path of Framewor_Tools_Paht.\r |
| 113 | ///\r |
| 114 | static String path = ""; \r |
| 115 | \r |
| 116 | /**\r |
| 117 | execute\r |
| 118 | \r |
| 119 | GenFfsFileTask execute is to generate ffs file according to input section \r |
| 120 | dscriptive information.\r |
| 121 | **/\r |
| 122 | public void execute() throws BuildException {\r |
| 123 | Section sect;\r |
| 124 | int fileSize;\r |
| 125 | int orgFileSize;\r |
| 126 | int fileDataSize;\r |
| 127 | int orgFileDataSize;\r |
| 128 | File ffsFile;\r |
| 129 | File ffsOrgFile;\r |
| 130 | FfsHeader ffsHeader = new FfsHeader(); \r |
| 131 | FfsHeader orgFfsHeader = new FfsHeader();\r |
| 132 | String ffsSuffix = "";\r |
| 133 | String outputPath = "";\r |
| 134 | \r |
| 135 | //\r |
| 136 | // Get Fraemwork_Tools_Path\r |
| 137 | //\r |
| 138 | Project pj = this.getOwningTarget().getProject();\r |
| 139 | path = pj.getProperty("env.FRAMEWORK_TOOLS_PATH");\r |
| 140 | \r |
| 141 | //\r |
| 142 | // Check does the BaseName, Guid, FileType set value.\r |
| 143 | //\r |
| 144 | if (this.baseName.equals("")) {\r |
| 145 | throw new BuildException ("Must set BaseName!\n");\r |
| 146 | }\r |
| 147 | \r |
| 148 | if (this.ffsFileGuid.equals("")) {\r |
| 149 | throw new BuildException ("Must set ffsFileGuid!\n");\r |
| 150 | }\r |
| 151 | \r |
| 152 | if (this.ffsFileType.equals("")) {\r |
| 153 | throw new BuildException ("Must set ffsFileType!\n");\r |
| 154 | }\r |
| 155 | \r |
| 156 | //\r |
| 157 | // Create ffs file. File name = FfsFileGuid + BaseName + ffsSuffix.\r |
| 158 | // If outputDir's value was set, file will output to the outputDir.\r |
| 159 | //\r |
| 160 | ffsSuffix = TypeToSuffix (this.moduleType);\r |
| 161 | if (!this.outputDir.equals("")) {\r |
| 162 | String temp;\r |
| 163 | outputPath = this.outputDir;\r |
| 164 | temp = outputPath.replace('\\', File.separatorChar);\r |
| 165 | outputPath = temp.replace('/', File.separatorChar);\r |
| 166 | if (outputPath.charAt(outputPath.length()-1) != File.separatorChar) {\r |
| 167 | outputPath = outputPath + File.separator;\r |
| 168 | }\r |
| 169 | \r |
| 170 | }\r |
| 171 | \r |
| 172 | String ffsFilePath = outputPath + this.ffsFileGuid + '-' + this.baseName + ffsSuffix;\r |
| 173 | ffsFile = new File (ffsFilePath); \r |
| 174 | //\r |
| 175 | // Create ffs ORG file. fileName = FfsFileGuid + BaseName + ffsSuffix +\r |
| 176 | // ".org".\r |
| 177 | //\r |
| 178 | ffsOrgFile = new File(ffsFilePath + ".org");\r |
| 179 | \r |
| 180 | log(ffsFile.getName());\r |
| 181 | log(ffsOrgFile.getName());\r |
| 182 | try {\r |
| 183 | //\r |
| 184 | // Create file output stream -- dataBuffer.\r |
| 185 | //\r |
| 186 | FileOutputStream dataFs = new FileOutputStream (ffsFile.getAbsolutePath());\r |
| 187 | DataOutputStream dataBuffer = new DataOutputStream (dataFs);\r |
| 188 | \r |
| 189 | //\r |
| 190 | // Create org file output stream -- orgDataBuffer\r |
| 191 | //\r |
| 192 | FileOutputStream orgDataFs = new FileOutputStream (ffsOrgFile.getAbsolutePath());\r |
| 193 | DataOutputStream orgDataBuffer = new DataOutputStream (orgDataFs);\r |
| 194 | \r |
| 195 | //\r |
| 196 | // Search SectionList find earch section and call it's \r |
| 197 | // ToBuffer function.\r |
| 198 | //\r |
| 199 | Iterator sectionIter = this.sectionList.iterator();\r |
| 200 | while (sectionIter.hasNext()) {\r |
| 201 | sect = (Section)sectionIter.next(); \r |
| 202 | \r |
| 203 | try {\r |
| 204 | //\r |
| 205 | // The last section don't need 4 byte ffsAligment.\r |
| 206 | //\r |
| 207 | sect.toBuffer((DataOutputStream)dataBuffer, (DataOutputStream) orgDataBuffer);\r |
| 208 | } catch (Exception e) {\r |
| 209 | throw new BuildException (e.getMessage());\r |
| 210 | }\r |
| 211 | }\r |
| 212 | dataBuffer.close();\r |
| 213 | orgDataBuffer.close();\r |
| 214 | } catch (Exception e) {\r |
| 215 | throw new BuildException (e.getMessage());\r |
| 216 | }\r |
| 217 | \r |
| 218 | //\r |
| 219 | // Creat Ffs file header\r |
| 220 | //\r |
| 221 | try {\r |
| 222 | \r |
| 223 | //\r |
| 224 | // create input stream to read file data\r |
| 225 | //\r |
| 226 | byte[] fileBuffer = new byte[(int)ffsFile.length()];\r |
| 227 | FileInputStream fi = new FileInputStream (ffsFile.getAbsolutePath());\r |
| 228 | DataInputStream di = new DataInputStream (fi);\r |
| 229 | di.read(fileBuffer);\r |
| 230 | di.close();\r |
| 231 | \r |
| 232 | //\r |
| 233 | // create input org stream to read file data\r |
| 234 | //\r |
| 235 | byte[] orgFileBuffer = new byte[(int)ffsOrgFile.length()];\r |
| 236 | FileInputStream ofi = new FileInputStream (ffsOrgFile.getAbsolutePath());\r |
| 237 | DataInputStream odi = new DataInputStream (ofi);\r |
| 238 | odi.read(orgFileBuffer);\r |
| 239 | odi.close();\r |
| 240 | \r |
| 241 | //\r |
| 242 | // Add GUID to header struct\r |
| 243 | //\r |
| 244 | if (this.ffsFileGuid != null) {\r |
| 245 | stringToGuid (this.ffsFileGuid, ffsHeader.name);\r |
| 246 | //\r |
| 247 | // Add Guid to org header struct\r |
| 248 | //\r |
| 249 | stringToGuid (this.ffsFileGuid, orgFfsHeader.name);\r |
| 250 | }\r |
| 251 | \r |
| 252 | ffsHeader.ffsAttributes = this.attributes;\r |
| 253 | if ((ffsHeader.fileType = stringToType(this.ffsFileType))== -1) {\r |
| 254 | throw new BuildException ("FFS_FILE_TYPE unknow!\n");\r |
| 255 | }\r |
| 256 | \r |
| 257 | //\r |
| 258 | // Copy ffsHeader.ffsAttribute and fileType to orgFfsHeader.ffsAttribute\r |
| 259 | // and fileType\r |
| 260 | // \r |
| 261 | orgFfsHeader.ffsAttributes = ffsHeader.ffsAttributes;\r |
| 262 | orgFfsHeader.fileType = ffsHeader.fileType;\r |
| 263 | \r |
| 264 | //\r |
| 265 | // Adjust file size. The function is used to tripe the last \r |
| 266 | // section padding of 4 binary boundary. \r |
| 267 | // \r |
| 268 | //\r |
| 269 | if (ffsHeader.fileType != EFI_FV_FILETYPE_RAW) {\r |
| 270 | \r |
| 271 | fileDataSize = adjustFileSize (fileBuffer);\r |
| 272 | orgFileDataSize = adjustFileSize (orgFileBuffer);\r |
| 273 | \r |
| 274 | } else {\r |
| 275 | fileDataSize = fileBuffer.length;\r |
| 276 | orgFileDataSize = orgFileBuffer.length;\r |
| 277 | }\r |
| 278 | \r |
| 279 | //\r |
| 280 | // 1. add header size to file size\r |
| 281 | //\r |
| 282 | fileSize = fileDataSize + ffsHeader.getSize();\r |
| 283 | //\r |
| 284 | // add header size to org file size\r |
| 285 | //\r |
| 286 | orgFileSize = orgFileDataSize + ffsHeader.getSize();\r |
| 287 | \r |
| 288 | if ((ffsHeader.ffsAttributes & FFS_ATTRIB_TAIL_PRESENT) != 0) {\r |
| 289 | if (ffsHeader.fileType == EFI_FV_FILETYPE_FFS_PAD) {\r |
| 290 | \r |
| 291 | throw new BuildException (\r |
| 292 | "FFS_ATTRIB_TAIL_PRESENT=TRUE is " +\r |
| 293 | "invalid for PAD files"\r |
| 294 | );\r |
| 295 | }\r |
| 296 | if (fileSize == ffsHeader.getSize()) {\r |
| 297 | throw new BuildException (\r |
| 298 | "FFS_ATTRIB_TAIL_PRESENT=TRUE is " +\r |
| 299 | "invalid for 0-length files"\r |
| 300 | ); \r |
| 301 | }\r |
| 302 | fileSize = fileSize + 2;\r |
| 303 | orgFileSize = orgFileSize + 2;\r |
| 304 | }\r |
| 305 | \r |
| 306 | //\r |
| 307 | // 2. set file size to header struct\r |
| 308 | //\r |
| 309 | ffsHeader.ffsFileSize[0] = (byte)(fileSize & 0x00FF);\r |
| 310 | ffsHeader.ffsFileSize[1] = (byte)((fileSize & 0x00FF00)>>8);\r |
| 311 | ffsHeader.ffsFileSize[2] = (byte)(((int)fileSize & 0xFF0000)>>16);\r |
| 312 | \r |
| 313 | //\r |
| 314 | // set file size to org header struct\r |
| 315 | //\r |
| 316 | orgFfsHeader.ffsFileSize[0] = (byte)(orgFileSize & 0x00FF);\r |
| 317 | orgFfsHeader.ffsFileSize[1] = (byte)((orgFileSize & 0x00FF00)>>8);\r |
| 318 | orgFfsHeader.ffsFileSize[2] = (byte)(((int)orgFileSize & 0xFF0000)>>16);\r |
| 319 | \r |
| 320 | //\r |
| 321 | // Fill in checksums and state, these must be zero for checksumming\r |
| 322 | //\r |
| 323 | ffsHeader.integrityCheck.header = calculateChecksum8 (\r |
| 324 | ffsHeader.structToBuffer(),\r |
| 325 | ffsHeader.getSize()\r |
| 326 | );\r |
| 327 | //\r |
| 328 | // Fill in org file's header check sum and state\r |
| 329 | //\r |
| 330 | orgFfsHeader.integrityCheck.header = calculateChecksum8 (\r |
| 331 | orgFfsHeader.structToBuffer(),\r |
| 332 | orgFfsHeader.getSize()\r |
| 333 | );\r |
| 334 | \r |
| 335 | if ((this.attributes & FFS_ATTRIB_CHECKSUM) != 0) {\r |
| 336 | if ((this.attributes & FFS_ATTRIB_TAIL_PRESENT) != 0) {\r |
| 337 | ffsHeader.integrityCheck.file = calculateChecksum8 (\r |
| 338 | fileBuffer, \r |
| 339 | fileDataSize\r |
| 340 | );\r |
| 341 | //\r |
| 342 | // Add org file header\r |
| 343 | //\r |
| 344 | orgFfsHeader.integrityCheck.file = calculateChecksum8 (\r |
| 345 | orgFileBuffer,\r |
| 346 | orgFileDataSize\r |
| 347 | );\r |
| 348 | } else {\r |
| 349 | ffsHeader.integrityCheck.file = calculateChecksum8 (\r |
| 350 | fileBuffer,\r |
| 351 | fileDataSize\r |
| 352 | );\r |
| 353 | //\r |
| 354 | // Add org file header\r |
| 355 | //\r |
| 356 | orgFfsHeader.integrityCheck.file = calculateChecksum8 (\r |
| 357 | orgFileBuffer,\r |
| 358 | orgFileDataSize\r |
| 359 | );\r |
| 360 | }\r |
| 361 | } else {\r |
| 362 | ffsHeader.integrityCheck.file = FFS_FIXED_CHECKSUM;\r |
| 363 | orgFfsHeader.integrityCheck.file = FFS_FIXED_CHECKSUM;\r |
| 364 | }\r |
| 365 | \r |
| 366 | //\r |
| 367 | // Set the state now. Spec says the checksum assumes the state is 0.\r |
| 368 | //\r |
| 369 | ffsHeader.ffsState = EFI_FILE_HEADER_CONSTRUCTION | \r |
| 370 | EFI_FILE_HEADER_VALID | \r |
| 371 | EFI_FILE_DATA_VALID;\r |
| 372 | orgFfsHeader.ffsState = ffsHeader.ffsState;\r |
| 373 | \r |
| 374 | //\r |
| 375 | // create output stream to first write header data in file, then write sect data in file.\r |
| 376 | //\r |
| 377 | FileOutputStream headerFfs = new FileOutputStream (ffsFile.getAbsolutePath());\r |
| 378 | DataOutputStream ffsBuffer = new DataOutputStream (headerFfs);\r |
| 379 | \r |
| 380 | FileOutputStream orgHeaderFfs = new FileOutputStream (ffsOrgFile.getAbsolutePath());\r |
| 381 | DataOutputStream orgFfsBuffer = new DataOutputStream (orgHeaderFfs);\r |
| 382 | \r |
| 383 | //\r |
| 384 | // Add header struct and file data to FFS file\r |
| 385 | //\r |
| 386 | ffsBuffer.write(ffsHeader.structToBuffer());\r |
| 387 | orgFfsBuffer.write(orgFfsHeader.structToBuffer());\r |
| 388 | \r |
| 389 | for (int i = 0; i< fileDataSize; i++) {\r |
| 390 | ffsBuffer.write(fileBuffer[i]);\r |
| 391 | }\r |
| 392 | \r |
| 393 | for (int i = 0; i < orgFileDataSize; i++){\r |
| 394 | orgFfsBuffer.write(orgFileBuffer[i]);\r |
| 395 | }\r |
| 396 | \r |
| 397 | //\r |
| 398 | // If there is a tail, then set it\r |
| 399 | //\r |
| 400 | if ((this.attributes & FFS_ATTRIB_TAIL_PRESENT) != 0) {\r |
| 401 | short tailValue ;\r |
| 402 | byte [] tailByte = new byte[2];\r |
| 403 | \r |
| 404 | //\r |
| 405 | // reverse tailvalue , integritycheck.file as hight byte, and \r |
| 406 | // integritycheck.header as low byte.\r |
| 407 | //\r |
| 408 | tailValue = (short)(ffsHeader.integrityCheck.header & 0xff);\r |
| 409 | tailValue = (short)((tailValue) | ((ffsHeader.integrityCheck.file << 8) & 0xff00)); \r |
| 410 | tailValue = (short)~tailValue;\r |
| 411 | \r |
| 412 | //\r |
| 413 | // Change short to byte[2]\r |
| 414 | //\r |
| 415 | tailByte[0] = (byte)(tailValue & 0xff);\r |
| 416 | tailByte[1] = (byte)((tailValue & 0xff00)>>8); \r |
| 417 | ffsBuffer.write(tailByte[0]);\r |
| 418 | ffsBuffer.write(tailByte[1]);\r |
| 419 | \r |
| 420 | orgFfsBuffer.write(tailByte[0]);\r |
| 421 | orgFfsBuffer.write(tailByte[1]);\r |
| 422 | }\r |
| 423 | \r |
| 424 | //\r |
| 425 | // close output stream. Note if don't close output stream \r |
| 426 | // the buffer can't be rewritten to file. \r |
| 427 | //\r |
| 428 | ffsBuffer.close();\r |
| 429 | orgFfsBuffer.close();\r |
| 430 | } catch (Exception e) {\r |
| 431 | log("genffsfile failed!");\r |
| 432 | throw new BuildException (e.getMessage());\r |
| 433 | }\r |
| 434 | } \r |
| 435 | \r |
| 436 | /**\r |
| 437 | addCompress\r |
| 438 | \r |
| 439 | This function is to add compress section to section list.\r |
| 440 | @param compress Section of compress \r |
| 441 | **/\r |
| 442 | public void addCompress(CompressSection compress) {\r |
| 443 | this.sectionList.add(compress);\r |
| 444 | }\r |
| 445 | \r |
| 446 | /**\r |
| 447 | addTool\r |
| 448 | \r |
| 449 | This function is to add tool section to section list.\r |
| 450 | @param tool Section of tool\r |
| 451 | **/\r |
| 452 | public void addTool(Tool tool) {\r |
| 453 | this.sectionList.add(tool);\r |
| 454 | }\r |
| 455 | \r |
| 456 | /**\r |
| 457 | addSectionFile\r |
| 458 | \r |
| 459 | This function is to add sectFile section to section list.\r |
| 460 | @param sectFile Section of sectFile.\r |
| 461 | **/\r |
| 462 | public void addSectFile (SectFile sectFile) {\r |
| 463 | this.sectionList.add(sectFile); \r |
| 464 | }\r |
| 465 | \r |
| 466 | /**\r |
| 467 | getBaseName\r |
| 468 | \r |
| 469 | This function is to get basename\r |
| 470 | \r |
| 471 | @return String of base name\r |
| 472 | **/\r |
| 473 | public String getBaseName() {\r |
| 474 | return this.baseName;\r |
| 475 | }\r |
| 476 | \r |
| 477 | /**\r |
| 478 | setBaseName\r |
| 479 | \r |
| 480 | This function is to set base name.\r |
| 481 | @param baseName\r |
| 482 | **/\r |
| 483 | public void setBaseName(String baseName) {\r |
| 484 | this.baseName = baseName.trim();\r |
| 485 | }\r |
| 486 | \r |
| 487 | /**\r |
| 488 | getFfsAligment\r |
| 489 | \r |
| 490 | This function is to get the ffsAligment\r |
| 491 | @return The value of ffsAligment.\r |
| 492 | **/\r |
| 493 | public int getFfsAlignment() {\r |
| 494 | return this.ffsAlignment;\r |
| 495 | }\r |
| 496 | \r |
| 497 | /**\r |
| 498 | setFfsAligment\r |
| 499 | \r |
| 500 | This function is to set ffsAligment \r |
| 501 | @param ffsAligment The value of ffsAligment.\r |
| 502 | **/\r |
| 503 | public void setFfsAlignment(int ffsAligment) {\r |
| 504 | this.ffsAlignment = ffsAligment;\r |
| 505 | if (this.ffsAlignment > 7) {\r |
| 506 | throw new BuildException ("FFS_ALIGMENT Scope is 0-7");\r |
| 507 | } else {\r |
| 508 | attributes |= (((byte)this.ffsAlignment) << 3);\r |
| 509 | }\r |
| 510 | }\r |
| 511 | \r |
| 512 | /**\r |
| 513 | getFfsAttribCheckSum\r |
| 514 | \r |
| 515 | This function is to get ffsAttribCheckSum\r |
| 516 | \r |
| 517 | @return Value of ffsAttribChecksum \r |
| 518 | **/\r |
| 519 | public boolean getFfsAttribChecksum() {\r |
| 520 | return this.FfsAttribChecksum;\r |
| 521 | }\r |
| 522 | \r |
| 523 | /**\r |
| 524 | setFfsAttribChecksum\r |
| 525 | \r |
| 526 | This function is to set ffsAttribChecksum\r |
| 527 | @param ffsAttributeCheckSum Value of ffsAttribCheckSum\r |
| 528 | **/\r |
| 529 | public void setFfsAttribChecksum(boolean ffsAttributeCheckSum) {\r |
| 530 | this.FfsAttribChecksum = ffsAttributeCheckSum;\r |
| 531 | if (ffsAttributeCheckSum) {\r |
| 532 | attributes |= FFS_ATTRIB_CHECKSUM;\r |
| 533 | }\r |
| 534 | }\r |
| 535 | \r |
| 536 | /**\r |
| 537 | getFfsAttribRecovery\r |
| 538 | \r |
| 539 | This function is to get ffsAttribRecovery\r |
| 540 | @return Value of ffsAttribRecovery\r |
| 541 | **/\r |
| 542 | public boolean getFfsAttribRecovery() {\r |
| 543 | return this.ffsAttribRecovery;\r |
| 544 | }\r |
| 545 | \r |
| 546 | /**\r |
| 547 | setRecovery\r |
| 548 | \r |
| 549 | This function is to set ffsAttributeRecovery\r |
| 550 | \r |
| 551 | @param ffsAttributeRecovery Value of ffsAttributeRecovery\r |
| 552 | **/\r |
| 553 | public void setRecovery(boolean ffsAttributeRecovery) {\r |
| 554 | this.ffsAttribRecovery = ffsAttributeRecovery;\r |
| 555 | if (ffsAttributeRecovery) {\r |
| 556 | attributes |= FFS_ATTRIB_RECOVERY;\r |
| 557 | }\r |
| 558 | }\r |
| 559 | \r |
| 560 | /**\r |
| 561 | getFileGuid\r |
| 562 | \r |
| 563 | This function is to get fileGuid\r |
| 564 | @return Guid\r |
| 565 | **/\r |
| 566 | public String getFileGuid() {\r |
| 567 | return this.ffsFileGuid;\r |
| 568 | }\r |
| 569 | \r |
| 570 | /**\r |
| 571 | setFileGuid\r |
| 572 | \r |
| 573 | This function is to set fileGuid\r |
| 574 | @param ffsFileGuid String of GUID\r |
| 575 | **/\r |
| 576 | public void setFileGuid(String ffsFileGuid) {\r |
| 577 | this.ffsFileGuid = ffsFileGuid.trim();\r |
| 578 | }\r |
| 579 | \r |
| 580 | /**\r |
| 581 | getFfsFileType\r |
| 582 | \r |
| 583 | This function is to get ffsFileType.\r |
| 584 | \r |
| 585 | @return value of ffsFileType\r |
| 586 | **/\r |
| 587 | public String getFfsFileType() {\r |
| 588 | return this.ffsFileType;\r |
| 589 | }\r |
| 590 | \r |
| 591 | /**\r |
| 592 | setFfsFileType\r |
| 593 | \r |
| 594 | This function is to set ffsFileType.\r |
| 595 | \r |
| 596 | @param ffsFileType \r |
| 597 | **/\r |
| 598 | public void setFfsFileType(String ffsFileType) {\r |
| 599 | this.ffsFileType = ffsFileType.trim();\r |
| 600 | }\r |
| 601 | \r |
| 602 | /**\r |
| 603 | ffsAttribHeaderExtension\r |
| 604 | \r |
| 605 | This function is to get ffsAttribHeaderExtension\r |
| 606 | \r |
| 607 | @return Value of ffsAttribHeaderExtension\r |
| 608 | **/\r |
| 609 | public boolean isFfsAttribHeaderExtension() {\r |
| 610 | return this.ffsAttribHeaderExtension;\r |
| 611 | }\r |
| 612 | \r |
| 613 | /**\r |
| 614 | setHeaderExension\r |
| 615 | \r |
| 616 | This function is to set headerExtension\r |
| 617 | @param headerExtension Value of headerExension\r |
| 618 | **/\r |
| 619 | public void setHeaderExtension(boolean headerExtension) {\r |
| 620 | this.ffsAttribHeaderExtension = headerExtension;\r |
| 621 | if (headerExtension) {\r |
| 622 | attributes |= FFS_ATTRIB_HEADER_EXTENSION;\r |
| 623 | }\r |
| 624 | }\r |
| 625 | \r |
| 626 | /**\r |
| 627 | isFfsAttribTailPresent\r |
| 628 | \r |
| 629 | This function is to get ffsAttribTailPresent value.\r |
| 630 | @return Value of ffsAttribTailPresent.\r |
| 631 | **/\r |
| 632 | public boolean isFfsAttribTailPresent() {\r |
| 633 | return this.ffsAttribTailPresent;\r |
| 634 | }\r |
| 635 | \r |
| 636 | /**\r |
| 637 | setFfsAttribTailPresent\r |
| 638 | \r |
| 639 | This function is to set ffsAttribTailPresent.\r |
| 640 | @param tailPresent Value of ffsAttribTailPresent.\r |
| 641 | **/\r |
| 642 | public void setFfsAttribTailPresent(boolean tailPresent) {\r |
| 643 | this.ffsAttribTailPresent = tailPresent;\r |
| 644 | if (tailPresent) {\r |
| 645 | attributes |= FFS_ATTRIB_TAIL_PRESENT;\r |
| 646 | }\r |
| 647 | } \r |
| 648 | \r |
| 649 | \r |
| 650 | /**\r |
| 651 | stringToGuid\r |
| 652 | \r |
| 653 | This function is to convert string to GUID.\r |
| 654 | * @param GuidStr String of GUID.\r |
| 655 | * @param Guid GUID form.\r |
| 656 | */\r |
| 657 | private void stringToGuid (String GuidStr, FfsHeader.FfsGuid Guid){ \r |
| 658 | \r |
| 659 | int i = 0;\r |
| 660 | int j = 0;\r |
| 661 | int k = 0;\r |
| 662 | char [] charArry;\r |
| 663 | String [] SplitStr;\r |
| 664 | \r |
| 665 | byte[] buffer = new byte[16];\r |
| 666 | if (GuidStr.length()!=36) {\r |
| 667 | throw new BuildException ("Guid length is not correct!");\r |
| 668 | }\r |
| 669 | \r |
| 670 | \r |
| 671 | SplitStr = GuidStr.split("-");\r |
| 672 | if (SplitStr.length != 5) {\r |
| 673 | throw new BuildException ("Guid type is not correct!");\r |
| 674 | }\r |
| 675 | \r |
| 676 | \r |
| 677 | \r |
| 678 | for (i= 0; i < SplitStr.length; i++) {\r |
| 679 | String str = SplitStr[i]; \r |
| 680 | charArry = str.toCharArray();\r |
| 681 | \r |
| 682 | for (j =0; j < (str.toCharArray().length)/2; j++) {\r |
| 683 | \r |
| 684 | buffer[k] = hexCharToByte (charArry[j*2]); \r |
| 685 | buffer[k] = (byte)( buffer[k]& 0x0f); \r |
| 686 | buffer[k] = (byte)((buffer[k]<< 4));\r |
| 687 | buffer[k] = (byte)( buffer[k]& 0xf0); \r |
| 688 | buffer[k] = (byte)( buffer[k]|hexCharToByte(charArry[j*2+1]));\r |
| 689 | k++; \r |
| 690 | }\r |
| 691 | }\r |
| 692 | Guid.bufferToStruct(buffer);\r |
| 693 | }\r |
| 694 | \r |
| 695 | /**\r |
| 696 | typeToSuffix\r |
| 697 | \r |
| 698 | This function is to get suffix of ffs file according to ffsFileType.\r |
| 699 | \r |
| 700 | @param ffsFileType ffsFileType\r |
| 701 | @return The suffix of ffs file\r |
| 702 | **/\r |
| 703 | private String TypeToSuffix (String ffsFileType){\r |
| 704 | String[][] suffix = { { "BASE", ".FFS"},\r |
| 705 | { "SEC", ".SEC" }, { "PEI_CORE", ".PEI" }, \r |
| 706 | { "PEIM", ".PEI" }, { "DXE_CORE", ".DXE" },\r |
| 707 | { "DXE_DRIVER", ".DXE" }, { "DXE_RUNTIME_DRIVER", ".DXE" }, \r |
| 708 | { "DXE_SAL_DRIVER", ".DXE" }, { "DXE_SMM_DRIVER", ".DXE" }, \r |
| 709 | { "TOOL", ".FFS" }, { "UEFI_DRIVER", ".DXE" },\r |
| 710 | { "UEFI_APPLICATION", ".APP" }, { "USER_DEFINED", ".FFS" } };\r |
| 711 | \r |
| 712 | for (int i = 0; i < suffix.length; i++) {\r |
| 713 | if (suffix[i][0].equalsIgnoreCase(moduleType)) {\r |
| 714 | return suffix[i][1];\r |
| 715 | }\r |
| 716 | }\r |
| 717 | \r |
| 718 | return ".FFS";\r |
| 719 | }\r |
| 720 | \r |
| 721 | \r |
| 722 | /**\r |
| 723 | stringToType\r |
| 724 | \r |
| 725 | This function is to get ffsFileType integer value according to ffsFileType.\r |
| 726 | @param ffsFileType String value of ffsFileType\r |
| 727 | @return Integer value of ffsFileType.\r |
| 728 | **/\r |
| 729 | private byte stringToType (String ffsFileType){\r |
| 730 | \r |
| 731 | if (ffsFileType.equals("EFI_FV_FILETYPE_ALL")) {\r |
| 732 | return(byte)EFI_FV_FILETYPE_ALL;\r |
| 733 | }\r |
| 734 | \r |
| 735 | if (ffsFileType.equals("EFI_FV_FILETYPE_RAW")) {\r |
| 736 | return(byte)EFI_FV_FILETYPE_RAW;\r |
| 737 | }\r |
| 738 | \r |
| 739 | if (ffsFileType.equals("EFI_FV_FILETYPE_FREEFORM")) {\r |
| 740 | return(byte)EFI_FV_FILETYPE_FREEFORM;\r |
| 741 | }\r |
| 742 | \r |
| 743 | if (ffsFileType.equals("EFI_FV_FILETYPE_SECURITY_CORE")) {\r |
| 744 | return(byte)EFI_FV_FILETYPE_SECURITY_CORE;\r |
| 745 | }\r |
| 746 | \r |
| 747 | if (ffsFileType.equals("EFI_FV_FILETYPE_PEI_CORE")) {\r |
| 748 | return(byte) EFI_FV_FILETYPE_PEI_CORE;\r |
| 749 | }\r |
| 750 | \r |
| 751 | if (ffsFileType.equals("EFI_FV_FILETYPE_DXE_CORE")) {\r |
| 752 | return(byte)EFI_FV_FILETYPE_DXE_CORE;\r |
| 753 | }\r |
| 754 | \r |
| 755 | if (ffsFileType.equals("EFI_FV_FILETYPE_PEIM")) {\r |
| 756 | return(byte)EFI_FV_FILETYPE_PEIM;\r |
| 757 | }\r |
| 758 | \r |
| 759 | if (ffsFileType.equals("EFI_FV_FILETYPE_DRIVER")) {\r |
| 760 | return(byte) EFI_FV_FILETYPE_DRIVER;\r |
| 761 | }\r |
| 762 | \r |
| 763 | if (ffsFileType.equals("EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER")) {\r |
| 764 | return(byte)EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER;\r |
| 765 | }\r |
| 766 | \r |
| 767 | if (ffsFileType.equals("EFI_FV_FILETYPE_APPLICATION")) {\r |
| 768 | return(byte)EFI_FV_FILETYPE_APPLICATION;\r |
| 769 | }\r |
| 770 | \r |
| 771 | if (ffsFileType.equals("EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE")) {\r |
| 772 | return(byte)EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE;\r |
| 773 | }\r |
| 774 | if (ffsFileType.equals("EFI_FV_FILETYPE_FFS_PAD")) {\r |
| 775 | return(byte) EFI_FV_FILETYPE_FFS_PAD;\r |
| 776 | }\r |
| 777 | \r |
| 778 | return -1;\r |
| 779 | }\r |
| 780 | \r |
| 781 | \r |
| 782 | \r |
| 783 | /**\r |
| 784 | calculateCheckSum8\r |
| 785 | \r |
| 786 | This function is to calculate the value needed for a valid UINT8 checksum\r |
| 787 | @param buffer Byte buffer containing byte data of component.\r |
| 788 | @param size Size of the buffer.\r |
| 789 | @return The 8 bit checksum value needed.\r |
| 790 | **/\r |
| 791 | private byte calculateChecksum8 (byte[] buffer, int size){\r |
| 792 | return(byte) (0x100 - calculateSum8 (buffer, size));\r |
| 793 | }\r |
| 794 | \r |
| 795 | \r |
| 796 | /**\r |
| 797 | calculateSum8\r |
| 798 | \r |
| 799 | This function is to calculate the UINT8 sum for the requested region.\r |
| 800 | @param buffer Byte buffer containing byte data of component\r |
| 801 | @param size Size of the buffer.\r |
| 802 | @return The 8 bit checksum value needed.\r |
| 803 | **/ \r |
| 804 | private short calculateSum8 (byte[] buffer, int size){\r |
| 805 | int Index;\r |
| 806 | byte Sum;\r |
| 807 | Sum = 0;\r |
| 808 | \r |
| 809 | //\r |
| 810 | // Perform the word sum for buffer\r |
| 811 | //\r |
| 812 | for (Index = 0; Index < size; Index++) {\r |
| 813 | Sum = (byte) (Sum + buffer[Index]); \r |
| 814 | }\r |
| 815 | \r |
| 816 | return(byte) Sum; \r |
| 817 | }\r |
| 818 | \r |
| 819 | /**\r |
| 820 | hexCharToByte\r |
| 821 | \r |
| 822 | This function is to convert hex character to byte\r |
| 823 | \r |
| 824 | @param hexChar hex character\r |
| 825 | @return Byte which corresponding to the character.\r |
| 826 | **/\r |
| 827 | private byte hexCharToByte (char hexChar){\r |
| 828 | switch (hexChar) {\r |
| 829 | case '0':\r |
| 830 | return(byte)0x00;\r |
| 831 | case '1':\r |
| 832 | return(byte)0x01;\r |
| 833 | case '2':\r |
| 834 | return(byte)0x02;\r |
| 835 | case '3':\r |
| 836 | return(byte)0x03;\r |
| 837 | case '4':\r |
| 838 | return(byte)0x04;\r |
| 839 | case '5':\r |
| 840 | return(byte)0x05;\r |
| 841 | case '6':\r |
| 842 | return(byte)0x06;\r |
| 843 | case '7':\r |
| 844 | return(byte)0x07;\r |
| 845 | case '8':\r |
| 846 | return(byte)0x08;\r |
| 847 | case '9':\r |
| 848 | return(byte)0x09;\r |
| 849 | case 'a':\r |
| 850 | case 'A':\r |
| 851 | return(byte)0x0a;\r |
| 852 | case 'b':\r |
| 853 | case 'B':\r |
| 854 | return(byte)0x0b;\r |
| 855 | case 'c':\r |
| 856 | case 'C':\r |
| 857 | return(byte)0x0c;\r |
| 858 | \r |
| 859 | case 'd':\r |
| 860 | case 'D': \r |
| 861 | return(byte)0x0d;\r |
| 862 | \r |
| 863 | case 'e':\r |
| 864 | case 'E':\r |
| 865 | return(byte)0x0e;\r |
| 866 | case 'f':\r |
| 867 | case 'F':\r |
| 868 | return(byte)0x0f;\r |
| 869 | \r |
| 870 | default:\r |
| 871 | return(byte)0xff; \r |
| 872 | }\r |
| 873 | }\r |
| 874 | \r |
| 875 | /**\r |
| 876 | adjustFileSize\r |
| 877 | \r |
| 878 | This function is used to adjusts file size to insure sectioned file is exactly the right length such\r |
| 879 | that it ends on exactly the last byte of the last section. ProcessScript()\r |
| 880 | may have padded beyond the end of the last section out to a 4 byte boundary.\r |
| 881 | This padding is stripped. \r |
| 882 | \r |
| 883 | @param buffer Byte buffer contains a section stream\r |
| 884 | @return Corrected size of file.\r |
| 885 | **/\r |
| 886 | private int adjustFileSize (byte[] buffer){ \r |
| 887 | \r |
| 888 | int orignalLen = buffer.length;\r |
| 889 | int adjustLen = 0;\r |
| 890 | int sectionPoint = 0;\r |
| 891 | int nextSectionPoint = 0;\r |
| 892 | int sectionLen = 0;\r |
| 893 | int totalLen = 0;\r |
| 894 | int firstSectionHeader = 0;\r |
| 895 | \r |
| 896 | \r |
| 897 | firstSectionHeader = buffer[0]& 0xff;\r |
| 898 | firstSectionHeader = ((buffer[1]&0xff)<<8) | firstSectionHeader;\r |
| 899 | firstSectionHeader = ((buffer[2]&0xff)<<16)| firstSectionHeader;\r |
| 900 | \r |
| 901 | \r |
| 902 | while (sectionPoint < buffer.length) {\r |
| 903 | sectionLen = buffer[0 + sectionPoint]& 0xff;\r |
| 904 | sectionLen = ((buffer[1 + sectionPoint]&0xff)<<8)| sectionLen;\r |
| 905 | sectionLen = ((buffer[2 + sectionPoint]&0xff)<<16)| sectionLen; \r |
| 906 | totalLen = totalLen + sectionLen;\r |
| 907 | \r |
| 908 | if (totalLen == orignalLen) {\r |
| 909 | return totalLen;\r |
| 910 | }\r |
| 911 | \r |
| 912 | sectionPoint = sectionPoint + sectionLen;\r |
| 913 | adjustLen = sectionPoint;\r |
| 914 | \r |
| 915 | nextSectionPoint = (sectionPoint + 0x03) & (~0x03);\r |
| 916 | totalLen = totalLen + nextSectionPoint - sectionLen;\r |
| 917 | sectionPoint = nextSectionPoint;\r |
| 918 | }\r |
| 919 | return adjustLen;\r |
| 920 | }\r |
| 921 | \r |
| 922 | /**\r |
| 923 | getOutputDir\r |
| 924 | \r |
| 925 | This function is to get output directory.\r |
| 926 | \r |
| 927 | @return Path of output directory.\r |
| 928 | **/\r |
| 929 | public String getOutputDir() {\r |
| 930 | return outputDir;\r |
| 931 | }\r |
| 932 | \r |
| 933 | /**\r |
| 934 | setOutputDir\r |
| 935 | \r |
| 936 | This function is to set output directory.\r |
| 937 | \r |
| 938 | @param outputDir The output direcotry.\r |
| 939 | **/\r |
| 940 | public void setOutputDir(String outputDir) {\r |
| 941 | this.outputDir = outputDir;\r |
| 942 | }\r |
| 943 | \r |
| 944 | public String getModuleType() {\r |
| 945 | return this.moduleType;\r |
| 946 | }\r |
| 947 | \r |
| 948 | public void setModuleType(String moduleType) {\r |
| 949 | this.moduleType = moduleType;\r |
| 950 | }\r |
| 951 | }\r |