return EFI_SUCCESS;\r
}\r
\r
+EFI_STATUS\r
+GenSectionSubtypeGuidSection (\r
+ CHAR8 **InputFileName,\r
+ UINT32 *InputFileAlign,\r
+ UINT32 InputFileNum,\r
+ EFI_GUID *SubTypeGuid,\r
+ UINT8 **OutFileBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Generate a section of type EFI_SECTION_FREEFORM_SUBTYPE_GUID\r
+ The function won't validate the input file contents.\r
+ The utility will add section header to the file.\r
+\r
+Arguments:\r
+\r
+ InputFileName - Name of the input file.\r
+\r
+ InputFileAlign - Alignment required by the input file data.\r
+\r
+ InputFileNum - Number of input files. Should be 1 for this section.\r
+\r
+ SubTypeGuid - Specify vendor guid value.\r
+\r
+ OutFileBuffer - Buffer pointer to Output file contents\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS on successful return\r
+ EFI_INVALID_PARAMETER if InputFileNum is less than 1\r
+ EFI_ABORTED if unable to open input file.\r
+ EFI_OUT_OF_RESOURCES No resource to complete the operation.\r
+\r
+--*/\r
+{\r
+ UINT32 TotalLength;\r
+ UINT32 InputLength;\r
+ UINT32 Offset;\r
+ UINT8 *FileBuffer;\r
+ EFI_STATUS Status;\r
+ EFI_FREEFORM_SUBTYPE_GUID_SECTION *SubtypeGuidSect;\r
+ EFI_FREEFORM_SUBTYPE_GUID_SECTION2 *SubtypeGuidSect2;\r
+\r
+\r
+ InputLength = 0;\r
+ Offset = 0;\r
+ FileBuffer = NULL;\r
+ TotalLength = 0;\r
+\r
+ if (InputFileNum > 1) {\r
+ Error (NULL, 0, 2000, "Invalid parameter", "more than one input file specified");\r
+ return STATUS_ERROR;\r
+ } else if (InputFileNum < 1) {\r
+ Error (NULL, 0, 2000, "Invalid parameter", "no input file specified");\r
+ return STATUS_ERROR;\r
+ }\r
+\r
+ //\r
+ // read all input file contents into a buffer\r
+ // first get the size of all file contents\r
+ //\r
+ Status = GetSectionContents (\r
+ InputFileName,\r
+ InputFileAlign,\r
+ InputFileNum,\r
+ FileBuffer,\r
+ &InputLength\r
+ );\r
+\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ Offset = sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION);\r
+ if (InputLength + Offset >= MAX_SECTION_SIZE) {\r
+ Offset = sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION2);\r
+ }\r
+ TotalLength = InputLength + Offset;\r
+\r
+ FileBuffer = (UINT8 *) malloc (InputLength + Offset);\r
+ if (FileBuffer == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // read all input file contents into a buffer\r
+ //\r
+ Status = GetSectionContents (\r
+ InputFileName,\r
+ InputFileAlign,\r
+ InputFileNum,\r
+ FileBuffer + Offset,\r
+ &InputLength\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ if (FileBuffer != NULL) {\r
+ free (FileBuffer);\r
+ }\r
+ Error (NULL, 0, 0001, "Error opening file for reading", InputFileName[0]);\r
+ return Status;\r
+ }\r
+\r
+ if (InputLength == 0) {\r
+ if (FileBuffer != NULL) {\r
+ free (FileBuffer);\r
+ }\r
+ Error (NULL, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // InputLength != 0, but FileBuffer == NULL means out of resources.\r
+ //\r
+ if (FileBuffer == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Now data is in FileBuffer + Offset\r
+ //\r
+ if (TotalLength >= MAX_SECTION_SIZE) {\r
+ SubtypeGuidSect2 = (EFI_FREEFORM_SUBTYPE_GUID_SECTION2 *) FileBuffer;\r
+ SubtypeGuidSect2->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
+ SubtypeGuidSect2->CommonHeader.Size[0] = (UINT8) 0xff;\r
+ SubtypeGuidSect2->CommonHeader.Size[1] = (UINT8) 0xff;\r
+ SubtypeGuidSect2->CommonHeader.Size[2] = (UINT8) 0xff;\r
+ SubtypeGuidSect2->CommonHeader.ExtendedSize = InputLength + sizeof (EFI_FREEFORM_SUBTYPE_GUID_SECTION2);\r
+ memcpy (&(SubtypeGuidSect2->SubTypeGuid), SubTypeGuid, sizeof (EFI_GUID));\r
+ } else {\r
+ SubtypeGuidSect = (EFI_FREEFORM_SUBTYPE_GUID_SECTION *) FileBuffer;\r
+ SubtypeGuidSect->CommonHeader.Type = EFI_SECTION_FREEFORM_SUBTYPE_GUID;\r
+ SubtypeGuidSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);\r
+ SubtypeGuidSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+ SubtypeGuidSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+ memcpy (&(SubtypeGuidSect->SubTypeGuid), SubTypeGuid, sizeof (EFI_GUID));\r
+ }\r
+\r
+ VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
+\r
+ //\r
+ // Set OutFileBuffer\r
+ //\r
+ *OutFileBuffer = FileBuffer;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
EFI_STATUS\r
FfsRebaseImageRead (\r
IN VOID *FileHandle,\r
}\r
\r
//\r
- // GuidValue is only required by Guided section.\r
+ // GuidValue is only required by Guided section and SubtypeGuid section.\r
//\r
- if ((SectType != EFI_SECTION_GUID_DEFINED) &&\r
+ if ((SectType != EFI_SECTION_GUID_DEFINED) && (SectType != EFI_SECTION_FREEFORM_SUBTYPE_GUID) &&\r
(SectionName != NULL) &&\r
(CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
fprintf (stdout, "Warning: the input guid value is not required for this section type %s\n", SectionName);\r
}\r
\r
+ //\r
+ // Check whether there is GUID for the SubtypeGuid section\r
+ //\r
+ if ((SectType == EFI_SECTION_FREEFORM_SUBTYPE_GUID) && (CompareGuid (&VendorGuid, &mZeroGuid) == 0)) {\r
+ Error (NULL, 0, 1001, "Missing options", "GUID");\r
+ goto Finish;\r
+ }\r
+\r
//\r
// Check whether there is input file\r
//\r
);\r
break;\r
\r
+ case EFI_SECTION_FREEFORM_SUBTYPE_GUID:\r
+ Status = GenSectionSubtypeGuidSection (\r
+ InputFileName,\r
+ InputFileAlign,\r
+ InputFileNum,\r
+ &VendorGuid,\r
+ &OutFileBuffer\r
+ );\r
+ break;\r
+\r
case EFI_SECTION_VERSION:\r
Index = sizeof (EFI_COMMON_SECTION_HEADER);\r
//\r