On Fri, 16 Jun 2023 at 10:48, Takahiro Akashi
<takahiro.aka...@linaro.org> wrote:
>
> On Fri, Jun 16, 2023 at 10:37:01AM +0530, Sughosh Ganu wrote:
> > hi Takahiro,
> >
> > On Fri, 16 Jun 2023 at 10:16, Takahiro Akashi
> > <takahiro.aka...@linaro.org> wrote:
> > >
> > > Hi Sughosh,
> > >
> > > On Fri, Jun 16, 2023 at 09:56:33AM +0530, Sughosh Ganu wrote:
> > > > On Thu, 15 Jun 2023 at 11:19, Takahiro Akashi
> > > > <takahiro.aka...@linaro.org> wrote:
> > > > >
> > > > > On Thu, Jun 15, 2023 at 10:09:06AM +0530, Sughosh Ganu wrote:
> > > > > > On Wed, 14 Jun 2023 at 11:23, Takahiro Akashi
> > > > > > <takahiro.aka...@linaro.org> wrote:
> > > > > > >
> > > > > > > On Wed, Jun 14, 2023 at 10:56:23AM +0530, Sughosh Ganu wrote:
> > > > > > > > hi Takahiro,
> > > > > > > >
> > > > > > > > On Wed, 14 Jun 2023 at 09:09, Takahiro Akashi
> > > > > > > > <takahiro.aka...@linaro.org> wrote:
> > > > > > > > >
> > > > > > > > > Hi Sughosh,
> > > > > > > > >
> > > > > > > > > I think this is a good extension to mkeficapsule, but
> > > > > > > > >
> > > > > > > > > On Tue, Jun 13, 2023 at 04:08:03PM +0530, Sughosh Ganu wrote:
> > > > > > > > > > Add support for specifying the parameters needed for capsule
> > > > > > > > > > generation through a config file, instead of passing them 
> > > > > > > > > > through
> > > > > > > > > > command-line. Parameters for more than a single capsule 
> > > > > > > > > > file can be
> > > > > > > > > > specified, resulting in generation of multiple capsules 
> > > > > > > > > > through a
> > > > > > > > > > single invocation of the command.
> > > > > > > > > >
> > > > > > > > > > This path is to be used for generating capsules through a 
> > > > > > > > > > make target,
> > > > > > > > > > with the parameters being parsed from the config file.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Sughosh Ganu <sughosh.g...@linaro.org>
> > > > > > > > > > ---
> > > > > > > > > >  tools/Kconfig              |   9 +
> > > > > > > > > >  tools/Makefile             |   1 +
> > > > > > > > > >  tools/eficapsule.h         | 110 ++++++++++++
> > > > > > > > > >  tools/mkeficapsule.c       | 106 +++++++-----
> > > > > > > > > >  tools/mkeficapsule_parse.c | 345 
> > > > > > > > > > +++++++++++++++++++++++++++++++++++++
> > > > > > > > > >  5 files changed, 531 insertions(+), 40 deletions(-)
> > > > > > > > > >  create mode 100644 tools/mkeficapsule_parse.c
> > > > > > > > > >
> > > > > > > > > > diff --git a/tools/Kconfig b/tools/Kconfig
> > > > > > > > > > index 539708f277..95f27b7c45 100644
> > > > > > > > > > --- a/tools/Kconfig
> > > > > > > > > > +++ b/tools/Kconfig
> > > > > > > > > > @@ -98,6 +98,15 @@ config TOOLS_MKEFICAPSULE
> > > > > > > > > >         optionally sign that file. If you want to enable 
> > > > > > > > > > UEFI capsule
> > > > > > > > > >         update feature on your target, you certainly need 
> > > > > > > > > > this.
> > > > > > > > > >
> > > > > > > > > > +config EFI_CAPSULE_CFG_FILE
> > > > > > > > > > +     string "Path to the EFI Capsule Config File"
> > > > > > > > > > +     default ""
> > > > > > > > > > +     help
> > > > > > > > > > +       Path to the EFI capsule config file which provides 
> > > > > > > > > > the
> > > > > > > > > > +       parameters needed to build capsule(s). Parameters 
> > > > > > > > > > can be
> > > > > > > > > > +       provided for multiple payloads resulting in 
> > > > > > > > > > corresponding
> > > > > > > > > > +       capsule images being generated.
> > > > > > > > > > +
> > > > > > > > > >  menuconfig FSPI_CONF_HEADER
> > > > > > > > > >       bool "FlexSPI Header Configuration"
> > > > > > > > > >       help
> > > > > > > > > > diff --git a/tools/Makefile b/tools/Makefile
> > > > > > > > > > index d793cf3bec..ef366f3d61 100644
> > > > > > > > > > --- a/tools/Makefile
> > > > > > > > > > +++ b/tools/Makefile
> > > > > > > > > > @@ -250,6 +250,7 @@ HOSTLDLIBS_mkeficapsule += \
> > > > > > > > > >  HOSTLDLIBS_mkeficapsule += \
> > > > > > > > > >       $(shell pkg-config --libs uuid 2> /dev/null || echo 
> > > > > > > > > > "-luuid")
> > > > > > > > > >  hostprogs-$(CONFIG_TOOLS_MKEFICAPSULE) += mkeficapsule
> > > > > > > > > > +mkeficapsule-objs := mkeficapsule.o mkeficapsule_parse.o
> > > > > > > > > >
> > > > > > > > > >  # We build some files with extra pedantic flags to try to 
> > > > > > > > > > minimize things
> > > > > > > > > >  # that won't build on some weird host compiler -- though 
> > > > > > > > > > there are lots of
> > > > > > > > > > diff --git a/tools/eficapsule.h b/tools/eficapsule.h
> > > > > > > > > > index 072a4b5598..42e66c6d6a 100644
> > > > > > > > > > --- a/tools/eficapsule.h
> > > > > > > > > > +++ b/tools/eficapsule.h
> > > > > > > > > > @@ -52,6 +52,38 @@ typedef struct {
> > > > > > > > > >  /* flags */
> > > > > > > > > >  #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET      0x00010000
> > > > > > > > > >
> > > > > > > > > > +enum capsule_type {
> > > > > > > > > > +     CAPSULE_NORMAL_BLOB = 0,
> > > > > > > > > > +     CAPSULE_ACCEPT,
> > > > > > > > > > +     CAPSULE_REVERT,
> > > > > > > > > > +};
> > > > > > > > > > +
> > > > > > > > > > +/**
> > > > > > > > > > + * struct efi_capsule_params - Capsule parameters
> > > > > > > > > > + * @image_guid: Guid value of the payload input image
> > > > > > > > > > + * @image_index: Image index value
> > > > > > > > > > + * @hardware_instance: Hardware instance to be used for 
> > > > > > > > > > the image
> > > > > > > > > > + * @monotonic_count: Monotonic count value to be used for 
> > > > > > > > > > signed capsule
> > > > > > > > > > + * @privkey_file: Path to private key used in capsule 
> > > > > > > > > > signing
> > > > > > > > > > + * @cert_file: Path to public key certificate used in 
> > > > > > > > > > capsule signing
> > > > > > > > > > + * @input_file: Path to payload input image
> > > > > > > > > > + * @capsule_file: Path to the output capsule file
> > > > > > > > > > + * @oemflags: Oemflags to be populated in the capsule 
> > > > > > > > > > header
> > > > > > > > > > + * @capsule: Capsule Type, normal or accept or revert
> > > > > > > > > > + */
> > > > > > > > > > +struct efi_capsule_params {
> > > > > > > > > > +     efi_guid_t *image_guid;
> > > > > > > > > > +     unsigned long image_index;
> > > > > > > > > > +     unsigned long hardware_instance;
> > > > > > > > > > +     uint64_t monotonic_count;
> > > > > > > > > > +     char *privkey_file;
> > > > > > > > > > +     char *cert_file;
> > > > > > > > > > +     char *input_file;
> > > > > > > > > > +     char *capsule_file;
> > > > > > > > > > +     unsigned long oemflags;
> > > > > > > > > > +     enum capsule_type capsule;
> > > > > > > > > > +};
> > > > > > > > > > +
> > > > > > > > > >  struct efi_capsule_header {
> > > > > > > > > >       efi_guid_t capsule_guid;
> > > > > > > > > >       uint32_t header_size;
> > > > > > > > > > @@ -113,4 +145,82 @@ struct 
> > > > > > > > > > efi_firmware_image_authentication {
> > > > > > > > > >       struct win_certificate_uefi_guid auth_info;
> > > > > > > > > >  } __packed;
> > > > > > > > > >
> > > > > > > > > > +/**
> > > > > > > > > > + * capsule_with_cfg_file() - Generate capsule from config 
> > > > > > > > > > file
> > > > > > > > > > + * @cfg_file: Path to the config file
> > > > > > > > > > + *
> > > > > > > > > > + * Parse the capsule parameters from the config file and 
> > > > > > > > > > use the
> > > > > > > > > > + * parameters for generating one or more capsules.
> > > > > > > > > > + *
> > > > > > > > > > + * Return: None
> > > > > > > > > > + *
> > > > > > > > > > + */
> > > > > > > > > > +void capsule_with_cfg_file(const char *cfg_file);
> > > > > > > > > > +
> > > > > > > > > > +/**
> > > > > > > > > > + * convert_uuid_to_guid() - convert UUID to GUID
> > > > > > > > > > + * @buf:     UUID binary
> > > > > > > > > > + *
> > > > > > > > > > + * UUID and GUID have the same data structure, but their 
> > > > > > > > > > binary
> > > > > > > > > > + * formats are different due to the endianness. See 
> > > > > > > > > > lib/uuid.c.
> > > > > > > > > > + * Since uuid_parse() can handle only UUID, this function 
> > > > > > > > > > must
> > > > > > > > > > + * be called to get correct data for GUID when parsing a 
> > > > > > > > > > string.
> > > > > > > > > > + *
> > > > > > > > > > + * The correct data will be returned in @buf.
> > > > > > > > > > + */
> > > > > > > > > > +void convert_uuid_to_guid(unsigned char *buf);
> > > > > > > > > > +
> > > > > > > > > > +/**
> > > > > > > > > > + * create_empty_capsule() - Generate an empty capsule
> > > > > > > > > > + * @path: Path to the empty capsule file to be generated
> > > > > > > > > > + * @guid: Guid value of the image for which empty capsule 
> > > > > > > > > > is generated
> > > > > > > > > > + * @fw_accept: Flag to specify whether to generate accept 
> > > > > > > > > > or revert capsule
> > > > > > > > > > + *
> > > > > > > > > > + * Generate an empty capsule, either an accept or a revert 
> > > > > > > > > > capsule to be
> > > > > > > > > > + * used to flag acceptance or rejection of an earlier 
> > > > > > > > > > executed firmware
> > > > > > > > > > + * update operation. Being used in the FWU Multi Bank 
> > > > > > > > > > firmware update
> > > > > > > > > > + * feature.
> > > > > > > > > > + *
> > > > > > > > > > + * Return: 0 if OK, -ve on error
> > > > > > > > > > + *
> > > > > > > > > > + */
> > > > > > > > > > +int create_empty_capsule(char *path, efi_guid_t *guid, 
> > > > > > > > > > bool fw_accept);
> > > > > > > > > > +
> > > > > > > > > > +/**
> > > > > > > > > > + * create_fwbin - create an uefi capsule file
> > > > > > > > > > + * @path:    Path to a created capsule file
> > > > > > > > > > + * @bin:     Path to a firmware binary to encapsulate
> > > > > > > > > > + * @guid:    GUID of related FMP driver
> > > > > > > > > > + * @index:   Index number in capsule
> > > > > > > > > > + * @instance:        Instance number in capsule
> > > > > > > > > > + * @mcount:  Monotonic count in authentication information
> > > > > > > > > > + * @private_file:    Path to a private key file
> > > > > > > > > > + * @cert_file:       Path to a certificate file
> > > > > > > > > > + * @oemflags:  Capsule OEM Flags, bits 0-15
> > > > > > > > > > + *
> > > > > > > > > > + * This function actually does the job of creating an uefi 
> > > > > > > > > > capsule file.
> > > > > > > > > > + * All the arguments must be supplied.
> > > > > > > > > > + * If either @private_file ror @cert_file is NULL, the 
> > > > > > > > > > capsule file
> > > > > > > > > > + * won't be signed.
> > > > > > > > > > + *
> > > > > > > > > > + * Return:
> > > > > > > > > > + * * 0  - on success
> > > > > > > > > > + * * -1 - on failure
> > > > > > > > > > + */
> > > > > > > > > > +int create_fwbin(char *path, char *bin, efi_guid_t *guid,
> > > > > > > > > > +              unsigned long index, unsigned long instance,
> > > > > > > > > > +              uint64_t mcount, char *privkey_file, char 
> > > > > > > > > > *cert_file,
> > > > > > > > > > +              uint16_t oemflags);
> > > > > > > > > > +
> > > > > > > > > > +/**
> > > > > > > > > > + * print_usage() - Print the command usage string
> > > > > > > > > > + *
> > > > > > > > > > + * Prints the standard command usage string. Called in the 
> > > > > > > > > > case
> > > > > > > > > > + * of incorrect parameters being passed to the tool.
> > > > > > > > > > + *
> > > > > > > > > > + * Return: None
> > > > > > > > > > + *
> > > > > > > > > > + */
> > > > > > > > > > +void print_usage(void);
> > > > > > > > > > +
> > > > > > > > > >  #endif /* _EFI_CAPSULE_H */
> > > > > > > > > > diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
> > > > > > > > > > index b71537beee..711adf0439 100644
> > > > > > > > > > --- a/tools/mkeficapsule.c
> > > > > > > > > > +++ b/tools/mkeficapsule.c
> > > > > > > > > > @@ -31,12 +31,6 @@ efi_guid_t efi_guid_cert_type_pkcs7 = 
> > > > > > > > > > EFI_CERT_TYPE_PKCS7_GUID;
> > > > > > > > > >
> > > > > > > > > >  static const char *opts_short = "g:i:I:v:p:c:m:o:dhAR";
> > > > > > > > > >
> > > > > > > > > > -enum {
> > > > > > > > > > -     CAPSULE_NORMAL_BLOB = 0,
> > > > > > > > > > -     CAPSULE_ACCEPT,
> > > > > > > > > > -     CAPSULE_REVERT,
> > > > > > > > > > -} capsule_type;
> > > > > > > > > > -
> > > > > > > > > >  static struct option options[] = {
> > > > > > > > > >       {"guid", required_argument, NULL, 'g'},
> > > > > > > > > >       {"index", required_argument, NULL, 'i'},
> > > > > > > > > > @@ -52,7 +46,16 @@ static struct option options[] = {
> > > > > > > > > >       {NULL, 0, NULL, 0},
> > > > > > > > > >  };
> > > > > > > > > >
> > > > > > > > > > -static void print_usage(void)
> > > > > > > > > > +/**
> > > > > > > > > > + * print_usage() - Print the command usage string
> > > > > > > > > > + *
> > > > > > > > > > + * Prints the standard command usage string. Called in the 
> > > > > > > > > > case
> > > > > > > > > > + * of incorrect parameters being passed to the tool.
> > > > > > > > > > + *
> > > > > > > > > > + * Return: None
> > > > > > > > > > + *
> > > > > > > > > > + */
> > > > > > > > > > +void print_usage(void)
> > > > > > > > > >  {
> > > > > > > > > >       fprintf(stderr, "Usage: %s [options] <image blob> 
> > > > > > > > > > <output file>\n"
> > > > > > > > > >               "Options:\n"
> > > > > > > > > > @@ -400,10 +403,10 @@ static void free_sig_data(struct 
> > > > > > > > > > auth_context *ctx)
> > > > > > > > > >   * * 0  - on success
> > > > > > > > > >   * * -1 - on failure
> > > > > > > > > >   */
> > > > > > > > > > -static int create_fwbin(char *path, char *bin, efi_guid_t 
> > > > > > > > > > *guid,
> > > > > > > > > > -                     unsigned long index, unsigned long 
> > > > > > > > > > instance,
> > > > > > > > > > -                     uint64_t mcount, char *privkey_file, 
> > > > > > > > > > char *cert_file,
> > > > > > > > > > -                     uint16_t oemflags)
> > > > > > > > > > +int create_fwbin(char *path, char *bin, efi_guid_t *guid,
> > > > > > > > > > +              unsigned long index, unsigned long instance,
> > > > > > > > > > +              uint64_t mcount, char *privkey_file, char 
> > > > > > > > > > *cert_file,
> > > > > > > > > > +              uint16_t oemflags)
> > > > > > > > > >  {
> > > > > > > > > >       struct efi_capsule_header header;
> > > > > > > > > >       struct efi_firmware_management_capsule_header capsule;
> > > > > > > > > > @@ -580,7 +583,21 @@ void convert_uuid_to_guid(unsigned 
> > > > > > > > > > char *buf)
> > > > > > > > > >       buf[7] = c;
> > > > > > > > > >  }
> > > > > > > > > >
> > > > > > > > > > -static int create_empty_capsule(char *path, efi_guid_t 
> > > > > > > > > > *guid, bool fw_accept)
> > > > > > > > > > +/**
> > > > > > > > > > + * create_empty_capsule() - Generate an empty capsule
> > > > > > > > > > + * @path: Path to the empty capsule file to be generated
> > > > > > > > > > + * @guid: Guid value of the image for which empty capsule 
> > > > > > > > > > is generated
> > > > > > > > > > + * @fw_accept: Flag to specify whether to generate accept 
> > > > > > > > > > or revert capsule
> > > > > > > > > > + *
> > > > > > > > > > + * Generate an empty capsule, either an accept or a revert 
> > > > > > > > > > capsule to be
> > > > > > > > > > + * used to flag acceptance or rejection of an earlier 
> > > > > > > > > > executed firmware
> > > > > > > > > > + * update operation. Being used in the FWU Multi Bank 
> > > > > > > > > > firmware update
> > > > > > > > > > + * feature.
> > > > > > > > > > + *
> > > > > > > > > > + * Return: 0 if OK, -ve on error
> > > > > > > > > > + *
> > > > > > > > > > + */
> > > > > > > > > > +int create_empty_capsule(char *path, efi_guid_t *guid, 
> > > > > > > > > > bool fw_accept)
> > > > > > > > > >  {
> > > > > > > > > >       struct efi_capsule_header header = { 0 };
> > > > > > > > > >       FILE *f = NULL;
> > > > > > > > > > @@ -623,19 +640,7 @@ err:
> > > > > > > > > >       return ret;
> > > > > > > > > >  }
> > > > > > > > > >
> > > > > > > > > > -/**
> > > > > > > > > > - * main - main entry function of mkeficapsule
> > > > > > > > > > - * @argc:    Number of arguments
> > > > > > > > > > - * @argv:    Array of pointers to arguments
> > > > > > > > > > - *
> > > > > > > > > > - * Create an uefi capsule file, optionally signing it.
> > > > > > > > > > - * Parse all the arguments and pass them on to 
> > > > > > > > > > create_fwbin().
> > > > > > > > > > - *
> > > > > > > > > > - * Return:
> > > > > > > > > > - * * 0  - on success
> > > > > > > > > > - * * -1 - on failure
> > > > > > > > > > - */
> > > > > > > > > > -int main(int argc, char **argv)
> > > > > > > > > > +static void capsule_with_cmdline_params(int argc, char 
> > > > > > > > > > **argv)
> > > > > > > > > >  {
> > > > > > > > > >       efi_guid_t *guid;
> > > > > > > > > >       unsigned char uuid_buf[16];
> > > > > > > > > > @@ -643,6 +648,7 @@ int main(int argc, char **argv)
> > > > > > > > > >       uint64_t mcount;
> > > > > > > > > >       unsigned long oemflags;
> > > > > > > > > >       char *privkey_file, *cert_file;
> > > > > > > > > > +     enum capsule_type capsule;
> > > > > > > > > >       int c, idx;
> > > > > > > > > >
> > > > > > > > > >       guid = NULL;
> > > > > > > > > > @@ -652,7 +658,7 @@ int main(int argc, char **argv)
> > > > > > > > > >       privkey_file = NULL;
> > > > > > > > > >       cert_file = NULL;
> > > > > > > > > >       dump_sig = 0;
> > > > > > > > > > -     capsule_type = CAPSULE_NORMAL_BLOB;
> > > > > > > > > > +     capsule = CAPSULE_NORMAL_BLOB;
> > > > > > > > > >       oemflags = 0;
> > > > > > > > > >       for (;;) {
> > > > > > > > > >               c = getopt_long(argc, argv, opts_short, 
> > > > > > > > > > options, &idx);
> > > > > > > > > > @@ -702,20 +708,20 @@ int main(int argc, char **argv)
> > > > > > > > > >                       dump_sig = 1;
> > > > > > > > > >                       break;
> > > > > > > > > >               case 'A':
> > > > > > > > > > -                     if (capsule_type) {
> > > > > > > > > > +                     if (capsule) {
> > > > > > > > > >                               fprintf(stderr,
> > > > > > > > > >                                       "Select either of 
> > > > > > > > > > Accept or Revert capsule generation\n");
> > > > > > > > > >                               exit(1);
> > > > > > > > > >                       }
> > > > > > > > > > -                     capsule_type = CAPSULE_ACCEPT;
> > > > > > > > > > +                     capsule = CAPSULE_ACCEPT;
> > > > > > > > > >                       break;
> > > > > > > > > >               case 'R':
> > > > > > > > > > -                     if (capsule_type) {
> > > > > > > > > > +                     if (capsule) {
> > > > > > > > > >                               fprintf(stderr,
> > > > > > > > > >                                       "Select either of 
> > > > > > > > > > Accept or Revert capsule generation\n");
> > > > > > > > > >                               exit(1);
> > > > > > > > > >                       }
> > > > > > > > > > -                     capsule_type = CAPSULE_REVERT;
> > > > > > > > > > +                     capsule = CAPSULE_REVERT;
> > > > > > > > > >                       break;
> > > > > > > > > >               case 'o':
> > > > > > > > > >                       oemflags = strtoul(optarg, NULL, 0);
> > > > > > > > > > @@ -732,21 +738,21 @@ int main(int argc, char **argv)
> > > > > > > > > >       }
> > > > > > > > > >
> > > > > > > > > >       /* check necessary parameters */
> > > > > > > > > > -     if ((capsule_type == CAPSULE_NORMAL_BLOB &&
> > > > > > > > > > -         ((argc != optind + 2) || !guid ||
> > > > > > > > > > -          ((privkey_file && !cert_file) ||
> > > > > > > > > > -           (!privkey_file && cert_file)))) ||
> > > > > > > > > > -         (capsule_type != CAPSULE_NORMAL_BLOB &&
> > > > > > > > > > -         ((argc != optind + 1) ||
> > > > > > > > > > -          ((capsule_type == CAPSULE_ACCEPT) && !guid) ||
> > > > > > > > > > -          ((capsule_type == CAPSULE_REVERT) && guid)))) {
> > > > > > > > > > +     if ((capsule == CAPSULE_NORMAL_BLOB &&
> > > > > > > > > > +          ((argc != optind + 2) || !guid ||
> > > > > > > > > > +           ((privkey_file && !cert_file) ||
> > > > > > > > > > +            (!privkey_file && cert_file)))) ||
> > > > > > > > > > +         (capsule != CAPSULE_NORMAL_BLOB &&
> > > > > > > > > > +          ((argc != optind + 1) ||
> > > > > > > > > > +           (capsule == CAPSULE_ACCEPT && !guid) ||
> > > > > > > > > > +           (capsule == CAPSULE_REVERT && guid)))) {
> > > > > > > > > >               print_usage();
> > > > > > > > > >               exit(EXIT_FAILURE);
> > > > > > > > > >       }
> > > > > > > > > >
> > > > > > > > > > -     if (capsule_type != CAPSULE_NORMAL_BLOB) {
> > > > > > > > > > +     if (capsule != CAPSULE_NORMAL_BLOB) {
> > > > > > > > > >               if (create_empty_capsule(argv[argc - 1], guid,
> > > > > > > > > > -                                      capsule_type == 
> > > > > > > > > > CAPSULE_ACCEPT) < 0) {
> > > > > > > > > > +                                      capsule == 
> > > > > > > > > > CAPSULE_ACCEPT) < 0) {
> > > > > > > > > >                       fprintf(stderr, "Creating empty 
> > > > > > > > > > capsule failed\n");
> > > > > > > > > >                       exit(EXIT_FAILURE);
> > > > > > > > > >               }
> > > > > > > > > > @@ -756,6 +762,26 @@ int main(int argc, char **argv)
> > > > > > > > > >               fprintf(stderr, "Creating firmware capsule 
> > > > > > > > > > failed\n");
> > > > > > > > > >               exit(EXIT_FAILURE);
> > > > > > > > > >       }
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > +/**
> > > > > > > > > > + * main - main entry function of mkeficapsule
> > > > > > > > > > + * @argc:    Number of arguments
> > > > > > > > > > + * @argv:    Array of pointers to arguments
> > > > > > > > > > + *
> > > > > > > > > > + * Create an uefi capsule file, optionally signing it.
> > > > > > > > > > + * Parse all the arguments and pass them on to 
> > > > > > > > > > create_fwbin().
> > > > > > > > > > + *
> > > > > > > > > > + * Return:
> > > > > > > > > > + * * 0  - on success
> > > > > > > > > > + * * -1 - on failure
> > > > > > > > > > + */
> > > > > > > > > > +int main(int argc, char **argv)
> > > > > > > > > > +{
> > > > > > > > > > +     if (!strcmp(CONFIG_EFI_CAPSULE_CFG_FILE, ""))
> > > > > > > > > > +             capsule_with_cmdline_params(argc, argv);
> > > > > > > > > > +     else
> > > > > > > > > > +             
> > > > > > > > > > capsule_with_cfg_file(CONFIG_EFI_CAPSULE_CFG_FILE);
> > > > > > > > >
> > > > > > > > > I don't know where the macro, CONFIG_EFI_CAPSULE_CFG_FILE, 
> > > > > > > > > comes from.
> > > > > > > > > Anyhow, as a general rule, any host tool must be as generic 
> > > > > > > > > as it should not
> > > > > > > > > depend on a target's config.
> > > > > > > > > (I was told so before.)
> > > > > > > > >
> > > > > > > > > So I would suggest that you add another command line, say 
> > > > > > > > > "--config-file <file>",
> > > > > > > > > to make the command generic.
> > > > > > > >
> > > > > > > > Yes, that would be something followed by most of the tools. The 
> > > > > > > > reason
> > > > > > > > I did not add a command-line option for the confile file is 
> > > > > > > > because I
> > > > > > > > want the capsule generation added as a make target. With the 
> > > > > > > > path to
> > > > > > > > the config file specified through the Kconfig symbol, we can 
> > > > > > > > invoke
> > > > > > > > 'make capsule', and it would build the capsules by parsing the
> > > > > > > > parameters from the config file, taken from the Kconfig symbol. 
> > > > > > > > I know
> > > > > > > > there are ways of specifying options when using a make command, 
> > > > > > > > but I
> > > > > > > > don't think that is a clean way of doing things.
> > > > > > >
> > > > > > > Not sure, but in your [5/7],
> > > > > > > cmd_mkeficapsule = $(objtree)/tools/mkeficapsule --config-file 
> > > > > > > $(CONFIG_EFI_CAPSULE_CFG_FILE)
> > > > > > >
> > > > > > > Doesn't this change work?
> > > > > >
> > > > > > So, I tried the above suggested change. But trying to run a make
> > > > > > 'target' does not work without the .config file being present.
> > > > >
> > > > > Not sure what you meant to say here.
> > > > > Why don't you have .config when building U-Boot (or rather 'target')?
> > > >
> > > > Maybe I misunderstood your earlier comment, but I thought you were
> > > > looking to build capsules without relying on a target config.
> > >
> > > Not exactly.
> > > The basic requirement, I believe, is that the exact same binary (with
> > > the same set of functionalities) should be generated for any host tool
> > > whatever a target's config, including tools-only_defconfig, is.
> >
> > Okay. I think I now understand what you are looking for. However, I
> > believe if you want the same binary for both scenarios, the only way
> > might be to drop the make target to generate capsules, and do it
> > through the --config-file command-line option.
>
> Again not sure what you're trying to do.

Never mind. It works with the cfg-file being passed as a command-line
parameter. I will make the change for the next version.

-sughosh

>
> > I will check if we can
> > pass the config file as a parameter when building capsules as a
> > target. I could not get it working when I tried it earlier though. If
> > this is indeed not possible, do you have a strong opinion on having
> > the same binary for both scenarios?
>
>  I have no reason why you can't.
>  If you see any failure, please give me more details about how
>  you are going to manage so that I can help you.
>
>  -Takahiro Akashi
>
> > -sughosh
> >
> > >
> > > Is it clear now?
> > >
> > > -Takahiro Akashi
> > >
> > > > Which I
> > > > believe cannot be done for a make target.
> > > >
> > > > -sughosh
> > > >
> > > > >
> > > > > -Takahiro Akashi
> > > > >
> > > > > > FWIW,
> > > > > > the same is the case for building tools as well. I think that is the
> > > > > > reason for the tools-only_defconfig.
> > > > > >
> > > > > > -sughosh
> > > > > >
> > > > > > >
> > > > > > > -Takahiro Akashi
> > > > > > >
> > > > > > >
> > > > > > > > Given the use case of
> > > > > > > > a make target, I hope we can use the Kconfig symbol for 
> > > > > > > > specifying the
> > > > > > > > config file path.
> > > > > > > >
> > > > > > > > -sughosh
> > > > > > > >
> > > > > > > > >
> > > > > > > > > -Takahiro Akashi
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >       exit(EXIT_SUCCESS);
> > > > > > > > > >  }
> > > > > > > > > > diff --git a/tools/mkeficapsule_parse.c 
> > > > > > > > > > b/tools/mkeficapsule_parse.c
> > > > > > > > > > new file mode 100644
> > > > > > > > > > index 0000000000..ef4f3f6705
> > > > > > > > > > --- /dev/null
> > > > > > > > > > +++ b/tools/mkeficapsule_parse.c
> > > > > > > > > > @@ -0,0 +1,345 @@
> > > > > > > > > > +// SPDX-License-Identifier: GPL-2.0
> > > > > > > > > > +/*
> > > > > > > > > > + * Copyright 2023 Linaro Limited
> > > > > > > > > > + */
> > > > > > > > > > +
> > > > > > > > > > +/*
> > > > > > > > > > + * The code in this file adds parsing ability to the 
> > > > > > > > > > mkeficapsule
> > > > > > > > > > + * tool. This allows specifying parameters needed to build 
> > > > > > > > > > the capsule
> > > > > > > > > > + * through the config file instead of specifying them on 
> > > > > > > > > > the command-line.
> > > > > > > > > > + * Parameters can be specified for more than one payload, 
> > > > > > > > > > generating the
> > > > > > > > > > + * corresponding capsule files.
> > > > > > > > > > + *
> > > > > > > > > > + * The parameters are specified in a "key:value" pair. All 
> > > > > > > > > > the parameters
> > > > > > > > > > + * that are currently supported by the mkeficapsule tool 
> > > > > > > > > > can be specified
> > > > > > > > > > + * in the config file.
> > > > > > > > > > + *
> > > > > > > > > > + * The example below shows four payloads. The first 
> > > > > > > > > > payload is an example
> > > > > > > > > > + * of generating a signed capsule. The second payload is 
> > > > > > > > > > an example of
> > > > > > > > > > + * generating an unsigned capsule. The third payload is an 
> > > > > > > > > > accept empty
> > > > > > > > > > + * capsule, while the fourth payload is the revert empty 
> > > > > > > > > > capsule, used
> > > > > > > > > > + * for the multi-bank firmware update feature.
> > > > > > > > > > + *
> > > > > > > > > > + * This functionality can be easily extended to generate a 
> > > > > > > > > > single capsule
> > > > > > > > > > + * comprising multiple payloads.
> > > > > > > > > > +
> > > > > > > > > > +     {
> > > > > > > > > > +         image-guid: 02f4d760-cfd5-43bd-8e2d-a42acb33c660
> > > > > > > > > > +         hardware-instance: 0
> > > > > > > > > > +         monotonic-count: 1
> > > > > > > > > > +         payload: u-boot.bin
> > > > > > > > > > +         image-index: 1
> > > > > > > > > > +         private-key: /path/to/priv/key
> > > > > > > > > > +         pub-key-cert: /path/to/pub/key
> > > > > > > > > > +         capsule: u-boot.capsule
> > > > > > > > > > +     }
> > > > > > > > > > +     {
> > > > > > > > > > +         image-guid: 4ce292da-1dd8-428d-a1c2-77743ef8b96e
> > > > > > > > > > +         hardware-instance: 0
> > > > > > > > > > +         payload: u-boot.itb
> > > > > > > > > > +         image-index: 2
> > > > > > > > > > +         oemflags: 0x8000
> > > > > > > > > > +         capsule: fit.capsule
> > > > > > > > > > +     }
> > > > > > > > > > +     {
> > > > > > > > > > +         capsule-type: accept
> > > > > > > > > > +         image-guid: 4ce292da-1dd8-428d-a1c2-77743ef8b96e
> > > > > > > > > > +         capsule: accept.capsule
> > > > > > > > > > +     }
> > > > > > > > > > +     {
> > > > > > > > > > +         capsule-type: revert
> > > > > > > > > > +         capsule: revert.capsule
> > > > > > > > > > +     }
> > > > > > > > > > +*/
> > > > > > > > > > +
> > > > > > > > > > +#include <ctype.h>
> > > > > > > > > > +#include <limits.h>
> > > > > > > > > > +#include <stdio.h>
> > > > > > > > > > +#include <stdlib.h>
> > > > > > > > > > +#include <string.h>
> > > > > > > > > > +
> > > > > > > > > > +#include <uuid/uuid.h>
> > > > > > > > > > +
> > > > > > > > > > +#include "eficapsule.h"
> > > > > > > > > > +
> > > > > > > > > > +#define PARAMS_START "{"
> > > > > > > > > > +#define PARAMS_END   "}"
> > > > > > > > > > +
> > > > > > > > > > +#define PSTART               2
> > > > > > > > > > +#define PEND         3
> > > > > > > > > > +
> > > > > > > > > > +#define MALLOC_FAIL_STR              "Unable to allocate 
> > > > > > > > > > memory\n"
> > > > > > > > > > +
> > > > > > > > > > +#define ARRAY_SIZE(x)                (sizeof(x) / 
> > > > > > > > > > sizeof((x)[0]))
> > > > > > > > > > +
> > > > > > > > > > +const char *capsule_params[] = {
> > > > > > > > > > +     "image-guid", "image-index", "private-key",
> > > > > > > > > > +     "pub-key-cert", "payload", "capsule",
> > > > > > > > > > +     "hardware-instance", "monotonic-count",
> > > > > > > > > > +     "capsule-type", "oemflags" };
> > > > > > > > > > +
> > > > > > > > > > +static unsigned char params_start;
> > > > > > > > > > +static unsigned char params_end;
> > > > > > > > > > +
> > > > > > > > > > +static void print_and_exit(const char *str)
> > > > > > > > > > +{
> > > > > > > > > > +     fprintf(stderr, "%s", str);
> > > > > > > > > > +     exit(EXIT_FAILURE);
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > +static int param_delim_checks(char *line, unsigned char 
> > > > > > > > > > *token)
> > > > > > > > > > +{
> > > > > > > > > > +     if (!strcmp(line, PARAMS_START)) {
> > > > > > > > > > +             if (params_start || !params_end) {
> > > > > > > > > > +                     fprintf(stderr, "Earlier params 
> > > > > > > > > > processing still in progress. ");
> > > > > > > > > > +                     fprintf(stderr, "Can't start 
> > > > > > > > > > processing a new params.\n");
> > > > > > > > > > +                     exit(EXIT_FAILURE);
> > > > > > > > > > +             } else {
> > > > > > > > > > +                     params_start = 1;
> > > > > > > > > > +                     params_end = 0;
> > > > > > > > > > +                     *token = PSTART;
> > > > > > > > > > +                     return 1;
> > > > > > > > > > +             }
> > > > > > > > > > +     } else if (!strcmp(line, PARAMS_END)) {
> > > > > > > > > > +             if (!params_start) {
> > > > > > > > > > +                     fprintf(stderr, "Cannot put end 
> > > > > > > > > > braces without start braces. ");
> > > > > > > > > > +                     fprintf(stderr, "Please check the 
> > > > > > > > > > documentation for reference config file syntax\n");
> > > > > > > > > > +                     exit(EXIT_FAILURE);
> > > > > > > > > > +             } else {
> > > > > > > > > > +                     params_start = 0;
> > > > > > > > > > +                     params_end = 1;
> > > > > > > > > > +                     *token = PEND;
> > > > > > > > > > +                     return 1;
> > > > > > > > > > +             }
> > > > > > > > > > +     } else if (!params_start) {
> > > > > > > > > > +             fprintf(stderr, "Params should be passed 
> > > > > > > > > > within braces. ");
> > > > > > > > > > +             fprintf(stderr, "Please check the 
> > > > > > > > > > documentation for reference config file syntax\n");
> > > > > > > > > > +             exit(EXIT_FAILURE);
> > > > > > > > > > +     }
> > > > > > > > > > +
> > > > > > > > > > +     return 0;
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > +static void add_guid(efi_guid_t **guid_param, char *guid)
> > > > > > > > > > +{
> > > > > > > > > > +     unsigned char uuid_buf[16];
> > > > > > > > > > +
> > > > > > > > > > +     *guid_param = malloc(sizeof(efi_guid_t));
> > > > > > > > > > +     if (!*guid_param)
> > > > > > > > > > +             print_and_exit(MALLOC_FAIL_STR);
> > > > > > > > > > +
> > > > > > > > > > +     if (uuid_parse(guid, uuid_buf))
> > > > > > > > > > +             print_and_exit("Wrong guid format\n");
> > > > > > > > > > +
> > > > > > > > > > +     convert_uuid_to_guid(uuid_buf);
> > > > > > > > > > +     memcpy(*guid_param, uuid_buf, sizeof(efi_guid_t));
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > +static void add_string(char **dst, char *val)
> > > > > > > > > > +{
> > > > > > > > > > +     *dst = strdup(val);
> > > > > > > > > > +     if (!*dst)
> > > > > > > > > > +             print_and_exit(MALLOC_FAIL_STR);
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > +static void match_and_populate_param(char *key, char *val,
> > > > > > > > > > +                                  struct 
> > > > > > > > > > efi_capsule_params *param)
> > > > > > > > > > +{
> > > > > > > > > > +     int i;
> > > > > > > > > > +
> > > > > > > > > > +     for (i = 0; i < ARRAY_SIZE(capsule_params); i++) {
> > > > > > > > > > +             if (!strcmp(key, capsule_params[i])) {
> > > > > > > > > > +                     switch (i) {
> > > > > > > > > > +                     case 0:
> > > > > > > > > > +                             add_guid(&param->image_guid, 
> > > > > > > > > > val);
> > > > > > > > > > +                             return;
> > > > > > > > > > +                     case 1:
> > > > > > > > > > +                             param->image_index = 
> > > > > > > > > > strtoul(val, NULL, 0);
> > > > > > > > > > +                             if (param->image_index == 
> > > > > > > > > > ULONG_MAX)
> > > > > > > > > > +                                     print_and_exit("Enter 
> > > > > > > > > > a valid value of index bewtween 1-255");
> > > > > > > > > > +                             return;
> > > > > > > > > > +                     case 2:
> > > > > > > > > > +                             
> > > > > > > > > > add_string(&param->privkey_file, val);
> > > > > > > > > > +                             return;
> > > > > > > > > > +                     case 3:
> > > > > > > > > > +                             add_string(&param->cert_file, 
> > > > > > > > > > val);
> > > > > > > > > > +                             return;
> > > > > > > > > > +                     case 4:
> > > > > > > > > > +                             
> > > > > > > > > > add_string(&param->input_file, val);
> > > > > > > > > > +                             return;
> > > > > > > > > > +                     case 5:
> > > > > > > > > > +                             
> > > > > > > > > > add_string(&param->capsule_file, val);
> > > > > > > > > > +                             return;
> > > > > > > > > > +                     case 6:
> > > > > > > > > > +                             param->hardware_instance = 
> > > > > > > > > > strtoul(val, NULL, 0);
> > > > > > > > > > +                             if (param->hardware_instance 
> > > > > > > > > > == ULONG_MAX)
> > > > > > > > > > +                                     print_and_exit("Enter 
> > > > > > > > > > a valid hardware instance value");
> > > > > > > > > > +                             return;
> > > > > > > > > > +                     case 7:
> > > > > > > > > > +                             param->monotonic_count = 
> > > > > > > > > > strtoull(val, NULL, 0);
> > > > > > > > > > +                             if (param->monotonic_count == 
> > > > > > > > > > ULLONG_MAX)
> > > > > > > > > > +                                     print_and_exit("Enter 
> > > > > > > > > > a valid monotonic count value");
> > > > > > > > > > +                             return;
> > > > > > > > > > +                     case 8:
> > > > > > > > > > +                             if (!strcmp(val, "normal"))
> > > > > > > > > > +                                     param->capsule = 
> > > > > > > > > > CAPSULE_NORMAL_BLOB;
> > > > > > > > > > +                             else if (!strcmp(val, 
> > > > > > > > > > "accept"))
> > > > > > > > > > +                                     param->capsule = 
> > > > > > > > > > CAPSULE_ACCEPT;
> > > > > > > > > > +                             else if (!strcmp(val, 
> > > > > > > > > > "revert"))
> > > > > > > > > > +                                     param->capsule = 
> > > > > > > > > > CAPSULE_REVERT;
> > > > > > > > > > +                             else
> > > > > > > > > > +                                     
> > > > > > > > > > print_and_exit("Invalid type of capsule");
> > > > > > > > > > +
> > > > > > > > > > +                             return;
> > > > > > > > > > +                     case 9:
> > > > > > > > > > +                             param->oemflags = 
> > > > > > > > > > strtoul(val, NULL, 0);
> > > > > > > > > > +                             if (param->oemflags > 0xffff)
> > > > > > > > > > +                                     
> > > > > > > > > > print_and_exit("OemFlags must be between 0x0 and 0xffff\n");
> > > > > > > > > > +                             return;
> > > > > > > > > > +                     }
> > > > > > > > > > +             }
> > > > > > > > > > +     }
> > > > > > > > > > +
> > > > > > > > > > +     fprintf(stderr, "Undefined param %s specified. ", 
> > > > > > > > > > key);
> > > > > > > > > > +     fprintf(stderr, "Please check the documentation for 
> > > > > > > > > > reference config file syntax\n");
> > > > > > > > > > +     exit(EXIT_FAILURE);
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > +static int get_capsule_params(char *line, struct 
> > > > > > > > > > efi_capsule_params *params)
> > > > > > > > > > +{
> > > > > > > > > > +     char *key = NULL;
> > > > > > > > > > +     char *val = NULL;
> > > > > > > > > > +     unsigned char token;
> > > > > > > > > > +
> > > > > > > > > > +     if (param_delim_checks(line, &token))
> > > > > > > > > > +             return token;
> > > > > > > > > > +
> > > > > > > > > > +     key = strtok(line, ":");
> > > > > > > > > > +     if (key)
> > > > > > > > > > +             val = strtok(NULL, "\0");
> > > > > > > > > > +     else
> > > > > > > > > > +             print_and_exit("Expect the params in a 
> > > > > > > > > > key:value pair\n");
> > > > > > > > > > +
> > > > > > > > > > +     match_and_populate_param(key, val, params);
> > > > > > > > > > +
> > > > > > > > > > +     return 0;
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > +static char *skip_whitespace(char *line)
> > > > > > > > > > +{
> > > > > > > > > > +     char *ptr, *newline;
> > > > > > > > > > +
> > > > > > > > > > +     ptr = malloc(strlen(line) + 1);
> > > > > > > > > > +     if (!ptr)
> > > > > > > > > > +             print_and_exit(MALLOC_FAIL_STR);
> > > > > > > > > > +
> > > > > > > > > > +     for (newline = ptr; *line; line++)
> > > > > > > > > > +             if (!isblank(*line))
> > > > > > > > > > +                     *ptr++ = *line;
> > > > > > > > > > +     *ptr = '\0';
> > > > > > > > > > +     return newline;
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > +static int parse_capsule_payload_params(FILE *fp, struct 
> > > > > > > > > > efi_capsule_params *params)
> > > > > > > > > > +{
> > > > > > > > > > +     char *line = NULL;
> > > > > > > > > > +     char *newline;
> > > > > > > > > > +     size_t n = 0;
> > > > > > > > > > +     ssize_t len;
> > > > > > > > > > +
> > > > > > > > > > +     while ((len = getline(&line, &n, fp)) != -1) {
> > > > > > > > > > +             if (len == 1 && line[len - 1] == '\n')
> > > > > > > > > > +                     continue;
> > > > > > > > > > +
> > > > > > > > > > +             line[len - 1] = '\0';
> > > > > > > > > > +
> > > > > > > > > > +             newline = skip_whitespace(line);
> > > > > > > > > > +
> > > > > > > > > > +             if (newline[0] == '#')
> > > > > > > > > > +                     continue;
> > > > > > > > > > +
> > > > > > > > > > +             if (get_capsule_params(newline, params) == 
> > > > > > > > > > PEND)
> > > > > > > > > > +                     return 0;
> > > > > > > > > > +     }
> > > > > > > > > > +
> > > > > > > > > > +     if (errno == EINVAL || errno == ENOMEM) {
> > > > > > > > > > +             fprintf(stderr, "getline() returned an error 
> > > > > > > > > > %s reading the line\n",
> > > > > > > > > > +                     strerror(errno));
> > > > > > > > > > +             exit(EXIT_FAILURE);
> > > > > > > > > > +     } else if (params_start == 1 || params_end == 0) {
> > > > > > > > > > +             fprintf(stderr, "Params should be passed 
> > > > > > > > > > within braces. ");
> > > > > > > > > > +             fprintf(stderr, "Please check the 
> > > > > > > > > > documentation for reference config file syntax\n");
> > > > > > > > > > +             exit(EXIT_FAILURE);
> > > > > > > > > > +     } else {
> > > > > > > > > > +             return -1;
> > > > > > > > > > +     }
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > +static void params_dependency_check(struct 
> > > > > > > > > > efi_capsule_params *params)
> > > > > > > > > > +{
> > > > > > > > > > +     /* check necessary parameters */
> > > > > > > > > > +     if ((params->capsule == CAPSULE_NORMAL_BLOB &&
> > > > > > > > > > +          ((!params->input_file || !params->capsule_file ||
> > > > > > > > > > +            !params->image_guid) ||
> > > > > > > > > > +           ((params->privkey_file && !params->cert_file) ||
> > > > > > > > > > +            (!params->privkey_file && 
> > > > > > > > > > params->cert_file)))) ||
> > > > > > > > > > +         (params->capsule != CAPSULE_NORMAL_BLOB &&
> > > > > > > > > > +          (!params->capsule_file ||
> > > > > > > > > > +           (params->capsule == CAPSULE_ACCEPT && 
> > > > > > > > > > !params->image_guid) ||
> > > > > > > > > > +           (params->capsule == CAPSULE_REVERT && 
> > > > > > > > > > params->image_guid)))) {
> > > > > > > > > > +             print_usage();
> > > > > > > > > > +             exit(EXIT_FAILURE);
> > > > > > > > > > +     }
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > +static void generate_capsule(struct efi_capsule_params 
> > > > > > > > > > *params)
> > > > > > > > > > +{
> > > > > > > > > > +     if (params->capsule != CAPSULE_NORMAL_BLOB) {
> > > > > > > > > > +             if (create_empty_capsule(params->capsule_file,
> > > > > > > > > > +                                      params->image_guid,
> > > > > > > > > > +                                      params->capsule ==
> > > > > > > > > > +                                      CAPSULE_ACCEPT) < 0)
> > > > > > > > > > +                     print_and_exit("Creating empty 
> > > > > > > > > > capsule failed\n");
> > > > > > > > > > +     } else if (create_fwbin(params->capsule_file, 
> > > > > > > > > > params->input_file,
> > > > > > > > > > +                           params->image_guid, 
> > > > > > > > > > params->image_index,
> > > > > > > > > > +                           params->hardware_instance,
> > > > > > > > > > +                           params->monotonic_count,
> > > > > > > > > > +                           params->privkey_file,
> > > > > > > > > > +                           params->cert_file,
> > > > > > > > > > +                           (uint16_t)params->oemflags) < 
> > > > > > > > > > 0) {
> > > > > > > > > > +             print_and_exit("Creating firmware capsule 
> > > > > > > > > > failed\n");
> > > > > > > > > > +     }
> > > > > > > > > > +}
> > > > > > > > > > +
> > > > > > > > > > +/**
> > > > > > > > > > + * capsule_with_cfg_file() - Generate capsule from config 
> > > > > > > > > > file
> > > > > > > > > > + * @cfg_file: Path to the config file
> > > > > > > > > > + *
> > > > > > > > > > + * Parse the capsule parameters from the config file and 
> > > > > > > > > > use the
> > > > > > > > > > + * parameters for generating one or more capsules.
> > > > > > > > > > + *
> > > > > > > > > > + * Return: None
> > > > > > > > > > + *
> > > > > > > > > > + */
> > > > > > > > > > +void capsule_with_cfg_file(const char *cfg_file)
> > > > > > > > > > +{
> > > > > > > > > > +     FILE *fp;
> > > > > > > > > > +     struct efi_capsule_params params = { 0 };
> > > > > > > > > > +
> > > > > > > > > > +     fp = fopen(cfg_file, "r");
> > > > > > > > > > +     if (!fp) {
> > > > > > > > > > +             fprintf(stderr, "Unable to open the capsule 
> > > > > > > > > > config file %s\n",
> > > > > > > > > > +                     cfg_file);
> > > > > > > > > > +             exit(EXIT_FAILURE);
> > > > > > > > > > +     }
> > > > > > > > > > +
> > > > > > > > > > +     params_start = 0;
> > > > > > > > > > +     params_end = 1;
> > > > > > > > > > +
> > > > > > > > > > +     while (parse_capsule_payload_params(fp, &params) != 
> > > > > > > > > > -1) {
> > > > > > > > > > +             params_dependency_check(&params);
> > > > > > > > > > +             generate_capsule(&params);
> > > > > > > > > > +
> > > > > > > > > > +             memset(&params, 0, sizeof(struct 
> > > > > > > > > > efi_capsule_params));
> > > > > > > > > > +     }
> > > > > > > > > > +}
> > > > > > > > > > --
> > > > > > > > > > 2.34.1
> > > > > > > > > >

Reply via email to