Re: [PATCH v8 4/9] sandbox: Build the mkeficapsule tool for the sandbox variants

2023-08-11 Thread Takahiro Akashi
On Fri, Aug 11, 2023 at 07:54:11PM +0530, Sughosh Ganu wrote:
> hi Simon,
> 
> On Fri, 11 Aug 2023 at 19:07, Simon Glass  wrote:
> >
> > Hi Sughosh,
> >
> > On Fri, 11 Aug 2023 at 05:23, Sughosh Ganu  wrote:
> > >
> > > hi Simon,
> > >
> > > On Thu, 10 Aug 2023 at 22:57, Simon Glass  wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Thu, 10 Aug 2023 at 09:52, Tom Rini  wrote:
> > > > >
> > > > > On Thu, Aug 10, 2023 at 07:53:33PM +0530, Sughosh Ganu wrote:
> > > > >
> > > > > > Build the mkeficapsule tool for all the sandbox variants. This tool
> > > > > > will be used subsequently for testing capsule generation in binman.
> > > > > >
> > > > > > Signed-off-by: Sughosh Ganu 
> > > > > > ---
> > > > > > Changes since V7: None
> > > > > >
> > > > > >  tools/Kconfig | 6 +++---
> > > > > >  1 file changed, 3 insertions(+), 3 deletions(-)
> > > > > >
> > > > > > diff --git a/tools/Kconfig b/tools/Kconfig
> > > > > > index 6e23f44d55..353a855243 100644
> > > > > > --- a/tools/Kconfig
> > > > > > +++ b/tools/Kconfig
> > > > > > @@ -91,10 +91,10 @@ config TOOLS_SHA512
> > > > > > Enable SHA512 support in the tools builds
> > > > > >
> > > > > >  config TOOLS_MKEFICAPSULE
> > > > > > - bool "Build efimkcapsule command"
> > > > > > - default y if EFI_CAPSULE_ON_DISK
> > > > > > + bool "Build mkeficapsule tool"
> > > > > > + default y if EFI_CAPSULE_ON_DISK || SANDBOX
> > > > > >   help
> > > > > > -   This command allows users to create a UEFI capsule file and,
> > > > > > +   This tool allows users to create a UEFI capsule file and,
> > > > > > optionally sign that file. If you want to enable UEFI 
> > > > > > capsule
> > > > > > update feature on your target, you certainly need this.
> > > > >
> > > > > Sorry, what is this fixing exactly?
> > > >
> > > > s/command/tool/ is mixed in with this commit, but the main purpose is
> > > > to enable it on sandbox.
> > >
> > > Sorry, I did not understand this statement. The changes made here are
> > > using the same nomenclature(tool) for referring to mkeficapsule.
> > >
> > > >
> > > > The commit message really should mention both changes.
> > >
> > > Which two changes? The commit message states what the commit is doing,
> > > and then states the reason for the change. What more information is
> > > needed in the commit message?
> >
> > The two changes are:
> >
> > 1. The one the commit message mentions
> > 2. Changing 'command' to 'tool' in the Kconfig
> 
> Okay, will put in a mention for the second point as well. Thanks.

There is another use of 'command' in CONFIG_TOOLS_MKFWUDATA.
So it would be better to separate (2) from (1) and to fix
both 'command'.

-Takahiro Akashi


> 
> -sughosh


Re: [PATCH] doc: uefi: explicitly describe manual dtb update is required

2023-06-18 Thread Takahiro Akashi
Hi Heinrich,

On Mon, Jun 19, 2023 at 06:37:14AM +0200, Heinrich Schuchardt wrote:
> 
> 
> Am 19. Juni 2023 02:49:54 MESZ schrieb Takahiro Akashi 
> :
> >On Sat, Jun 17, 2023 at 09:58:13PM +0200, Heinrich Schuchardt wrote:
> >> On 6/15/23 10:03, Masahisa Kojima wrote:
> >> > To enforce anti-rollback to any older version, dtb must be
> >> > always update manually. This should be described in the
> >> > documentation.
> >> > 
> >> > Signed-off-by: Masahisa Kojima 
> >> > ---
> >> >   doc/develop/uefi/uefi.rst | 3 +++
> >> >   1 file changed, 3 insertions(+)
> >> > 
> >> > diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
> >> > index ffd13cebe9..d5f8c5f236 100644
> >> > --- a/doc/develop/uefi/uefi.rst
> >> > +++ b/doc/develop/uefi/uefi.rst
> >> > @@ -552,6 +552,9 @@ update using a capsule file with --fw-version of 5, 
> >> > the update will fail.
> >> >   When the --fw-version in the capsule file is updated, 
> >> > lowest-supported-version
> >> >   in the dtb might be updated accordingly.
> >> > 
> >> > +If user needs to enroce anti-rollback to any older version,
> >> > +the lowest-supported-version property in dtb must be always updated 
> >> > manually.
> >> 
> >> Thank you for updating the documentation.
> >> 
> >> Allowing to circumvent the rollback protection is a security issue. On a
> >> secure system you would probably want to disable console commands like
> >> mc and fdt. Shouldn't we provide an advice for safe settings?
> >
> >Is there any case where a user wants to use fdt for some reason,
> >for example, in CONFIG_PREBOOT or CONFIG_BOOTCOMMAND?
> >
> >-Takahiro Akashi
> 
> Dtb overlays can applied via the fdt command.

What I meant to say was that, if there is an useful use case of fdt
command, it would be too restrictive to recommend disabling the command.
(Questioning if a device tree is the right place to put the data.)

-Takahiro Akashi

> Best regards
> 
> Heinrich
> 
> 
> >
> >> E.g.
> >> 
> >> "If a user wanted to enable a rollback to a version forbidden by the
> >> lowest-supported-version property specified in U-Boot's control
> >> device-tree, they could change this property using the fdt command.
> >> Secure systems should not enable this command."
> >> 
> >> Best regards
> >> 
> >> Heinrich
> >> 
> >> > +
> >> >   To insert the lowest supported version into a dtb
> >> > 
> >> >   .. code-block:: console
> >> > 
> >> > base-commit: e350d0c60d413d441cbdfa9432ebadb56f625903
> >> 


Re: [PATCH] doc: uefi: explicitly describe manual dtb update is required

2023-06-18 Thread Takahiro Akashi
On Sat, Jun 17, 2023 at 09:58:13PM +0200, Heinrich Schuchardt wrote:
> On 6/15/23 10:03, Masahisa Kojima wrote:
> > To enforce anti-rollback to any older version, dtb must be
> > always update manually. This should be described in the
> > documentation.
> > 
> > Signed-off-by: Masahisa Kojima 
> > ---
> >   doc/develop/uefi/uefi.rst | 3 +++
> >   1 file changed, 3 insertions(+)
> > 
> > diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
> > index ffd13cebe9..d5f8c5f236 100644
> > --- a/doc/develop/uefi/uefi.rst
> > +++ b/doc/develop/uefi/uefi.rst
> > @@ -552,6 +552,9 @@ update using a capsule file with --fw-version of 5, the 
> > update will fail.
> >   When the --fw-version in the capsule file is updated, 
> > lowest-supported-version
> >   in the dtb might be updated accordingly.
> > 
> > +If user needs to enroce anti-rollback to any older version,
> > +the lowest-supported-version property in dtb must be always updated 
> > manually.
> 
> Thank you for updating the documentation.
> 
> Allowing to circumvent the rollback protection is a security issue. On a
> secure system you would probably want to disable console commands like
> mc and fdt. Shouldn't we provide an advice for safe settings?

Is there any case where a user wants to use fdt for some reason,
for example, in CONFIG_PREBOOT or CONFIG_BOOTCOMMAND?

-Takahiro Akashi

> E.g.
> 
> "If a user wanted to enable a rollback to a version forbidden by the
> lowest-supported-version property specified in U-Boot's control
> device-tree, they could change this property using the fdt command.
> Secure systems should not enable this command."
> 
> Best regards
> 
> Heinrich
> 
> > +
> >   To insert the lowest supported version into a dtb
> > 
> >   .. code-block:: console
> > 
> > base-commit: e350d0c60d413d441cbdfa9432ebadb56f625903
> 


Re: [PATCH 4/7] tools: mkeficapsule: Add support for parsing capsule params from config file

2023-06-15 Thread Takahiro Akashi
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
>  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
> > >  wrote:
> > > >
> > > > On Thu, Jun 15, 2023 at 10:09:06AM +0530, Sughosh Ganu wrote:
> > > > > On Wed, 14 Jun 2023 at 11:23, Takahiro Akashi
> > > > >  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
> > > > > > >  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 
> > > > > > > > > ---
> > > > > > > > >  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
&

Re: [PATCH 4/7] tools: mkeficapsule: Add support for parsing capsule params from config file

2023-06-15 Thread Takahiro Akashi
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
>  wrote:
> >
> > On Thu, Jun 15, 2023 at 10:09:06AM +0530, Sughosh Ganu wrote:
> > > On Wed, 14 Jun 2023 at 11:23, Takahiro Akashi
> > >  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
> > > > >  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 
> > > > > > > ---
> > > > > > >  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 
> > > > > >

Re: [PATCH 4/7] tools: mkeficapsule: Add support for parsing capsule params from config file

2023-06-14 Thread Takahiro Akashi
On Thu, Jun 15, 2023 at 10:09:06AM +0530, Sughosh Ganu wrote:
> On Wed, 14 Jun 2023 at 11:23, Takahiro Akashi
>  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
> > >  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 
> > > > > ---
> > > > >  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  0x0001
> > > > >
> > > > > +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
> > > > 

Re: [PATCH 4/7] tools: mkeficapsule: Add support for parsing capsule params from config file

2023-06-13 Thread Takahiro Akashi
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
>  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 
> > > ---
> > >  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  0x0001
> > >
> > > +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 *cap

Re: [PATCH 4/7] tools: mkeficapsule: Add support for parsing capsule params from config file

2023-06-13 Thread Takahiro Akashi
*
> + * 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, );
> @@ -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(C

Re: [PATCH v9 08/10] doc: uefi: add anti-rollback documentation

2023-06-07 Thread Takahiro Akashi
On Wed, Jun 07, 2023 at 02:41:58PM +0900, Masahisa Kojima wrote:
> This commit describe the procedure to configure lowest supported
> version in the device tree for anti-rollback protection.
> 
> Signed-off-by: Masahisa Kojima 
> ---
> No update since v7
> 
> Changes in v7:
> - describe the usage
> 
> Newly created in v6
> 
>  doc/develop/uefi/uefi.rst | 39 +++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
> index 30b90a09d5..ffd13cebe9 100644
> --- a/doc/develop/uefi/uefi.rst
> +++ b/doc/develop/uefi/uefi.rst
> @@ -537,6 +537,45 @@ where signature.dts looks like::
>  };
>  };
>  
> +Anti-rollback Protection
> +
> +
> +Anti-rollback prevents unintentional installation of outdated firmware.
> +To enable anti-rollback, you must add the lowest-supported-version property
> +to dtb and specify --fw-version when creating a capsule file with the
> +mkeficapsule tool.
> +When executing capsule update, U-Boot checks if fw_version is greater than
> +or equal to lowest-supported-version. If fw_version is less than
> +lowest-supported-version, the update will fail.
> +For example, if lowest-supported-version is set to 7 and you run capsule
> +update using a capsule file with --fw-version of 5, the update will fail.
> +When the --fw-version in the capsule file is updated, 
> lowest-supported-version
> +in the dtb might be updated accordingly.
  

I think that you should explicitly mention that a user always needs to update 
dtb
*manually* in order to enforce anti-rollback to *any* older version.
Otherwise, people may recognize that dtb be updated by the system (U-Boot).

-Takahiro Akashi

> +
> +To insert the lowest supported version into a dtb
> +
> +.. code-block:: console
> +
> +$ dtc -@ -I dts -O dtb -o version.dtbo version.dts
> +$ fdtoverlay -i orig.dtb -o new.dtb -v version.dtbo
> +
> +where version.dts looks like::
> +
> +/dts-v1/;
> +/plugin/;
> +&{/} {
> +firmware-version {
> +image1 {
> +image-type-id = 
> "09D7CF52-0720-4710-91D1-08469B7FE9C8";
> +image-index = <1>;
> +lowest-supported-version = <3>;
> +};
> +};
> +};
> +
> +The properties of image-type-id and image-index must match the value
> +defined in the efi_fw_image array as image_type_id and image_index.
> +
>  Executing the boot manager
>  ~~
>  
> -- 
> 2.34.1
> 


Re: [PATCH v6 7/8] doc: uefi: add firmware versioning documentation

2023-05-21 Thread Takahiro Akashi
On Fri, May 19, 2023 at 07:32:13PM +0900, Masahisa Kojima wrote:
> This commit describes the procedure to add the firmware version
> into the capsule file.
> 
> Signed-off-by: Masahisa Kojima 
> ---
> Newly created in v6
> 
>  doc/develop/uefi/uefi.rst | 29 +
>  1 file changed, 29 insertions(+)
> 
> diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
> index ffe25ca231..efab0fc7b1 100644
> --- a/doc/develop/uefi/uefi.rst
> +++ b/doc/develop/uefi/uefi.rst
> @@ -510,6 +510,35 @@ where signature.dts looks like::
>  };
>  };
>  
> +Enabling Firmware Versioning
> +
> +
> +The UEFI specification does not define the firmware versioning mechanism.
> +EDK II reference implementation inserts the FMP Payload Header right before
> +the payload. It coutains the fw_version and lowest supported version,
> +EDK II reference implementation uses these information to implement the
> +firmware versioning and anti-rollback protection, the firmware version and
> +lowest supported version is stored into EFI non-volatile variable.
> +
> +In U-Boot, the firmware versioning is implemented utilizing
> +the FMP Payload Header same as EDK II reference implementation,
> +reads the FMP Payload Header and stores the firmware version into
> +"FmpState" EFI non-volatile variable.  indicates the image index,
> +since FMP protocol handles multiple image indexes.

I suggested that you should use "FmState" with the firmware's own guid
as a vendor guid of the variable.
In theory, UEFI may have different FMP drivers, then "index id" may
have the same value for different firmwares.

> +
> +1. Run the following command to add firmware version into the capsule file

Anyhow, you'd better clearly mention that an user needs to specify
"--fw-version" option and what happens (or not happen) if the option
is not there.
I think all the text here can be simply merged in "Creating a capsule file".

-Takahiro Akashi


> +.. code-block:: console
> +
> +$ mkeficapsule --monotonic-count 1 \
> +  --private-key CRT.key \
> +  --certificate CRT.crt \
> +  --index 1 --instance 0 \
> +  --fw-version 5 \
> +  [--fit | --raw | --guid  +   
> +
>  Executing the boot manager
>  ~~
>  
> -- 
> 2.17.1
> 


Re: [PATCH v6 8/8] doc: uefi: add anti-rollback documentation

2023-05-21 Thread Takahiro Akashi
Hi Kojima-san,

On Fri, May 19, 2023 at 07:32:14PM +0900, Masahisa Kojima wrote:
> This commit describe the procedure to configure lowest supported
> version in the device tree for anti-rollback protection.
> 
> Signed-off-by: Masahisa Kojima 
> ---
> Newly created in v6
> 
>  doc/develop/uefi/uefi.rst | 32 
>  1 file changed, 32 insertions(+)
> 
> diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
> index efab0fc7b1..f1f13bb993 100644
> --- a/doc/develop/uefi/uefi.rst
> +++ b/doc/develop/uefi/uefi.rst
> @@ -539,6 +539,38 @@ since FMP protocol handles multiple image indexes.
>[--fit | --raw | --guid  
>  
> +Anti-rollback Protection
> +
> +
> +The anti-rollback protection is implemented differently from firmware 
> versioning.
> +U-Boot implements the file-based EFI variable storage, it can be tampered
> +and not the right place to store the lowest supported version.
> +U-Boot uses device tree to store the lowest supported version, it is secured
> +as long as dtb is authenticated together with U-Boot image by the 
> authenticated
> +capsule update, and the former stage boot loader verifies the image 
> containing the dtb
> +when the system boots.

This is details of implementation.
You should rather mention the usage, i.e. how "anti-rollback" can be managed
and achieved using firmware-version and lowest-supported-version and that users
should always update their device tree to enforce the protection.
(If the lowest-supported-version is kept the same even after the firmware 
update,
anti-rollback won't work.)

-Takahiro Akashi

> +1. Insert the lowest supported version into a device tree
> +
> +.. code-block:: console
> +
> +$ dtc -@ -I dts -O dtb -o version.dtbo version.dts
> +$ fdtoverlay -i orig.dtb -o new.dtb -v version.dtbo
> +
> +where version.dts looks like::
> +
> +/dts-v1/;
> +/plugin/;
> +&{/} {
> +firmware-version {
> +image1 {
> +image-type-id = 
> "09D7CF52-0720-4710-91D1-08469B7FE9C8";
> +image-index = <1>;
> +lowest-supported-version = <3>;
> +};
> +};
> +};
> +
>  Executing the boot manager
>  ~~
>  
> -- 
> 2.17.1
> 


Re: [PATCH v5 1/4] efi_loader: get version information from device tree

2023-05-09 Thread Takahiro Akashi
>>> +u32 *fw_version, u32 *lsv)
> > >>> +{
> > >>> + const void *fdt = gd->fdt_blob;
> > >>> + const fdt32_t *val;
> > >>> + const char *guid_str;
> > >>> + int len, offset, index;
> > >>> + int parent;
> > >>> +
> > >>> + parent = fdt_subnode_offset(fdt, 0, "firmware-version");
> > >>> + if (parent < 0)
> > >>> + return;
> > >>> +
> > >>> + fdt_for_each_subnode(offset, fdt, parent) {
> > >>> + efi_guid_t guid;
> > >>> +
> > >>> + guid_str = fdt_getprop(fdt, offset, "image-type-id", 
> > >>> );
> > >>> + if (!guid_str)
> > >>> + continue;
> > >>> + uuid_str_to_bin(guid_str, guid.b, UUID_STR_FORMAT_GUID);
> > >>> +
> > >>> + val = fdt_getprop(fdt, offset, "image-index", );
> > >>> + if (!val)
> > >>> + continue;
> > >>> + index = fdt32_to_cpu(*val);
> > >>> +
> > >>> + if (!guidcmp(, image_type_id) && index == 
> > >>> image_index) {
> > >>> + val = fdt_getprop(fdt, offset, "fw-version", 
> > >>> );
> > >>> + if (val)
> > >>> + *fw_version = fdt32_to_cpu(*val);
> > >>> +
> > >>> + val = fdt_getprop(fdt, offset,
> > >>> +   "lowest-supported-version", 
> > >>> );
> > >>> + if (val)
> > >>> + *lsv = fdt32_to_cpu(*val);
> > >>> + }
> > >>> + }
> > >>> +}
> > >>> +
> > >>>/**
> > >>> * efi_fill_image_desc_array - populate image descriptor array
> > >>> * @image_info_size:Size of @image_info
> > >>> @@ -148,13 +198,19 @@ static efi_status_t efi_fill_image_desc_array(
> > >>>*package_version_name = NULL; /* not supported */
> > >>>
> > >>>for (i = 0; i < num_image_type_guids; i++) {
> > >>
> > >> Currently we define num_image_type_guids per board in a C file. Using
> > >> the same line of code once per board makes no sense to me. Please, move
> > >> the definition of that variable to lib/efi_loader/efi_firmware.c.
> > >
> > > Sorry for the late reply.
> > >
> > > num_image_type_guids is calculated with "ARRAY_SIZE(fw_images)",
> > > fw_images[] array is also defined in each board file,
> > > so we can not simply move num_image_type_guids into
> > > lib/efi_loader/efi_firmware.c.
> >
> > Why can't we have
> >
> >int num_image_type_guids = ARRAY_SIZE(fw_images);
> >
> > in lib/efi_loader/efi_firmware.c?
> 
> At first thought, I thought it was a matter of abstraction.
> 
> But there is a compilation error when we expose fw_images[].
> fw_images[] array is initialized in each board file,
> and sizeof() of the external fw_images[] array in 
> lib/efi_loader/efi_firmware.c
> will cause compilation failure.
> We need to specify the array size when fw_images is exposed,
> for example:
>   extern struct efi_fw_image fw_images[2];
> 
> but currently there is no method to pre-define the fw_images[] array size,
> it is board specific.
> 
> We can define the macro to indicate the array size or having
> sentinel in the fw_images[] array, but I think the current

I simply wonder if the value should be embedded in "struct 
efi_capsule_update_info".
   struct efi_capsule_update_info {
const char *dfu_string;
int num_images;<- added
struct efi_fw_image *images;
   };
This is the best place because the value must match not only "images"
but also (entries in) "dfu_string".

Even now, efi_fill_image_desc_array() tries to access "fw_images[]"
via the exposed update_info variable. Beautiful, isn't it?

One more comment:
uefi.rst doesn't mention anything about num_image_type_guids.

-Takahiro Akashi

> implementation is simpler,
> I would like to keep the current implementation.
> Correct me if I'm wrong.
&g

Re: [PATCH v5 0/4] FMP versioning support

2023-04-10 Thread Takahiro Akashi
Hi Kojima-san,

On Mon, Apr 10, 2023 at 06:07:28PM +0900, Masahisa Kojima wrote:
> Firmware version management is not implemented in the current
> FMP implementation. This series aims to add the versioning support
> in FMP.
> 
> There is a major design change in v5.
> Until v4, the fw_version and lowest_supported_version are stored
> as a EFI variable. If the backing storage is a file we can't trust
> any of that information since anyone can tamper with the file,
> although the variables are defined as RO.
> With that, we store the version information in the device tree
> in v5. We can trust the information from dtb as long as the former
> stage boot loader verifies the image containing the dtb.

I have a basic question here.
You said that the former-stage boot loader is responsible for maintaining
the dtb with the correct firmware version to be passed to U-Boot.
But how can it obtain the new version number of firmware which is only
contained in a capsule file (and its header)?

Looking into you pytest, you simply always *reboot* the sandbox with
an already-modified dtb (test_ver.dtb).
(Please note that, at the reboot time, a capsule has not been
applied yet.)

I believe that your current approach is rather incomplete
as a workable solution.

-Takahiro Akashi

> The disadvantage of this design change is that we need to maintain
> the fw_version in both device tree and FMP Payload Header.
> It is inevitable since not all the capsule files contain the dtb.
> 
> EDK II reference implementation utilizes the FMP Payload Header
> inserted right before the capsule payload. With this series,
> U-Boot also follows the EDK II implementation.
> 
> Currently, there is no way to know the current running firmware
> version through the EFI interface. FMP->GetImageInfo() returns
> always 0 for the version number. So a user can not know that
> expected firmware is running after the capsule update.
> 
> With this series applied, version number can be specified
> in the capsule file generation with mkeficapsule tool, then
> user can know the running firmware version through
> FMP->GetImageInfo() and ESRT.
> 
> Note that this series does not mandate the FMP Payload Header,
> compatible with boards that are already using the existing
> U-Boot FMP implementation.
> If no FMP Payload Header is found in the capsule file, fw_version,
> lowest supported version, last attempt version and last attempt
> status is set to 0 and this is the same behavior as existing FMP
> implementation.
> 
> Major Changes in v5:
> - major design changes, versioning is implemented with
>   device tree instead of EFI variable
> 
> Major Changes in v4:
> - add python-based test
> 
> Major Changes in v3:
> - exclude CONFIG_FWU_MULTI
> 
> Masahisa Kojima (4):
>   efi_loader: get version information from device tree
>   efi_loader: check lowest supported version
>   mkeficapsule: add FMP Payload Header
>   test/py: efi_capsule: test for FMP versioning
> 
>  .../firmware/firmware-version.txt |  25 +++
>  doc/mkeficapsule.1|  10 +
>  lib/efi_loader/efi_firmware.c | 187 +---
>  test/py/tests/test_efi_capsule/conftest.py|  73 +++
>  .../test_capsule_firmware_fit.py  | 187 
>  .../test_capsule_firmware_raw.py  | 201 ++
>  .../test_capsule_firmware_signed_fit.py   | 165 ++
>  .../test_capsule_firmware_signed_raw.py   | 169 +++
>  test/py/tests/test_efi_capsule/version.dts|  27 +++
>  tools/eficapsule.h|  30 +++
>  tools/mkeficapsule.c  |  37 +++-
>  11 files changed, 1082 insertions(+), 29 deletions(-)
>  create mode 100644 doc/device-tree-bindings/firmware/firmware-version.txt
>  create mode 100644 test/py/tests/test_efi_capsule/version.dts
> 
> -- 
> 2.17.1
> 


Re: [PATCH v2 0/4] FMP versioning support

2023-03-05 Thread Takahiro Akashi
On Mon, Mar 06, 2023 at 03:08:55PM +0900, Masahisa Kojima wrote:
> Hi Akashi-san,
> 
> On Sat, 4 Mar 2023 at 10:28, Takahiro Akashi  
> wrote:
> >
> > Kojima-san,
> >
> > On Wed, Mar 01, 2023 at 06:15:18PM +0900, Masahisa Kojima wrote:
> > > Firmware version management is not implemented in the current
> > > FMP implementation. This series aims to add the versioning support
> > > in FMP.
> >
> > I think that you need to think of A/B update case, especially
> > when a capsule update is *reverted* to an older version.
> 
> A/B update(FWU) has their own version information in the Image Directory
> defined in FWU spec[1], this is not implemented yet on U-Boot.
> On second thought, I think A/B update(FWU) case should be excluded
> from the version management introduced by this series.

I don't think it's a good idea to have two different implementations
for normal case and A/B update unless there is a good reason when
we use the same FMP driver.

-Takahiro Akashi

> >
> > In addition, please don't forget in the next patch set:
> > - update the man page of mkeficapsule command
> > - add test cases (in pytest)
> 
> Yes, noted.
> 
> [1] https://developer.arm.com/documentation/den0118/a/
> 
> Thanks,
> Masahisa Kojima
> 
> >
> > -Takahiro Akashi
> >
> > > EDK2 reference implementation utilizes the FMP Payload Header
> > > inserted right before the capsule payload. With this series,
> > > U-Boot also follows the EDK2 implementation.
> > >
> > > Currently, there is no way to know the current running firmware
> > > version through the EFI interface. FMP->GetImageInfo() returns
> > > always 0 for the version number. So a user can not know that
> > > expected firmware is running after the capsule update.
> > >
> > > With this series applied, version number can be specified
> > > in the capsule file generation with mkeficapsule tool, then
> > > user can know the running firmware version through
> > > FMP->GetImageInfo() and ESRT.
> > >
> > > Note that this series does not mandate the FMP Payload Header,
> > > compatible with boards that are already using the existing
> > > U-Boot FMP implementation.
> > > If no FMP Payload Header is found in the capsule file, fw_version,
> > > lowest supported version, last attempt version and last attempt
> > > status is set to 0 and this is the same behavior as existing FMP
> > > implementation.
> > >
> > > Changes in v2:
> > > - add FMP Payload Header generation in mkeficapsule tool
> > >
> > > Masahisa Kojima (4):
> > >   efi_loader: store firmware version into FmpState variable
> > >   efi_loader: versioning support in GetImageInfo
> > >   efi_loader: check lowest supported version in capsule update
> > >   mkeficapsule: add FMP Payload Header
> > >
> > >  lib/efi_loader/efi_firmware.c | 271 ++
> > >  tools/mkeficapsule.c  |  81 +-
> > >  2 files changed, 319 insertions(+), 33 deletions(-)
> > >
> > > --
> > > 2.17.1
> > >


Re: [PATCH v2 0/4] FMP versioning support

2023-03-03 Thread Takahiro Akashi
Kojima-san,

On Wed, Mar 01, 2023 at 06:15:18PM +0900, Masahisa Kojima wrote:
> Firmware version management is not implemented in the current
> FMP implementation. This series aims to add the versioning support
> in FMP.

I think that you need to think of A/B update case, especially
when a capsule update is *reverted* to an older version.

In addition, please don't forget in the next patch set:
- update the man page of mkeficapsule command
- add test cases (in pytest)

-Takahiro Akashi

> EDK2 reference implementation utilizes the FMP Payload Header
> inserted right before the capsule payload. With this series,
> U-Boot also follows the EDK2 implementation.
> 
> Currently, there is no way to know the current running firmware
> version through the EFI interface. FMP->GetImageInfo() returns
> always 0 for the version number. So a user can not know that
> expected firmware is running after the capsule update.
> 
> With this series applied, version number can be specified
> in the capsule file generation with mkeficapsule tool, then
> user can know the running firmware version through
> FMP->GetImageInfo() and ESRT.
> 
> Note that this series does not mandate the FMP Payload Header,
> compatible with boards that are already using the existing
> U-Boot FMP implementation.
> If no FMP Payload Header is found in the capsule file, fw_version,
> lowest supported version, last attempt version and last attempt
> status is set to 0 and this is the same behavior as existing FMP
> implementation.
> 
> Changes in v2:
> - add FMP Payload Header generation in mkeficapsule tool
> 
> Masahisa Kojima (4):
>   efi_loader: store firmware version into FmpState variable
>   efi_loader: versioning support in GetImageInfo
>   efi_loader: check lowest supported version in capsule update
>   mkeficapsule: add FMP Payload Header
> 
>  lib/efi_loader/efi_firmware.c | 271 ++
>  tools/mkeficapsule.c  |  81 +-
>  2 files changed, 319 insertions(+), 33 deletions(-)
> 
> -- 
> 2.17.1
> 


Re: [PATCH v2 1/4] efi_loader: store firmware version into FmpState variable

2023-03-02 Thread Takahiro Akashi
fmp_hdr_signature = FMP_PAYLOAD_HDR_SIGNATURE;
> - header = (void *)image;
> + *p_image = image;
> + *p_image_size = image_size;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + * efi_firmware_set_fmp_state_var - set FmpState variable
> + * @state:   Pointer to fmp state
> + * @image_index: image index
> + * @updated: flag to indicate firmware update is successful
> + *
> + * Update the FmpState variable with the firmware update state.
> + *
> + * Return:   status code
> + */
> +static
> +efi_status_t efi_firmware_set_fmp_state_var(struct fmp_state *state, u8 
> image_index,
> + bool updated)
> +{
> + u16 varname[13]; /* u"FmpState" */
> + efi_status_t ret;
> + efi_uintn_t size;
> + struct fmp_state var_state = { 0 };
> +
> + efi_create_indexed_name(varname, sizeof(varname), "FmpState",
> + image_index);
> + size = sizeof(var_state);
> + ret = efi_get_variable_int(varname, _guid_fmp_state, NULL, ,
> +_state, NULL);
> + if (ret != EFI_SUCCESS && ret != EFI_NOT_FOUND)
> + return ret;
> +
> + /*
> +  * When the capsule update is successful, FmpState variable is set
> +  * according to the fmp payload header information. If there is no fmp 
> payload
> +  * header in the capsule file, all values are set to 0.
> +  * When the capsule update fails, only last attempt information of 
> FmpState
> +  * variable is updated, fw_version and lowest_supported_version keep 
> original
> +  * value or 0(in case no FmpState variable found).
> +  */
> + if (updated) {
> + var_state.fw_version = state->fw_version;
> + var_state.lowest_supported_version = 
> state->lowest_supported_version;
> + var_state.last_attempt_version = state->last_attempt_version;
> + var_state.last_attempt_status = state->last_attempt_status;
> + } else {
> + var_state.last_attempt_version = state->last_attempt_version;
> + var_state.last_attempt_status = state->last_attempt_status;
> + }
> +
> + ret = efi_set_variable_int(varname, _guid_fmp_state,
> +EFI_VARIABLE_NON_VOLATILE |
> +EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +EFI_VARIABLE_RUNTIME_ACCESS,
> +sizeof(var_state), _state, false);

One of my concerns about using UEFI variables as a storage for internal data
like firmwware status is that they are unnecessarily accessible to users.

In this sense, I think that those variable should be *read-only* and
maintained only by the system.

-Takahiro Akashi


> + return ret;
> +}
>  
> +/**
> + * efi_firmware_parse_payload_header - parse FMP payload header
> + * @p_image: Pointer to new image
> + * @p_image_size:Pointer to size of new image
> + * @statePointer to fmp state
> + *
> + * Parse the FMP payload header and fill the fmp_state structure.
> + * If no FMP payload header is found, fmp_state structure is not updated.
> + *
> + */
> +static
> +void efi_firmware_parse_payload_header(const void **p_image,
> +efi_uintn_t *p_image_size,
> +struct fmp_state *state)
> +{
> + const void *image = *p_image;
> + efi_uintn_t image_size = *p_image_size;
> + const struct fmp_payload_header *header;
> + u32 fmp_hdr_signature = FMP_PAYLOAD_HDR_SIGNATURE;
> +
> + header = image;
>   if (!memcmp(>signature, _hdr_signature,
>   sizeof(fmp_hdr_signature))) {
> - /*
> -  * When building the capsule with the scripts in
> -  * edk2, a FMP header is inserted above the capsule
> -  * payload. Compensate for this header to get the
> -  * actual payload that is to be updated.
> -  */
> + /* FMP header is inserted above the capsule payload */
> + state->fw_version = header->fw_version;
> + state->lowest_supported_version = 
> header->lowest_supported_version;
> + state->last_attempt_version = header->fw_version;
>   image += header->header_size;
>   image_size -= header->header_size;
>   }
>  
>   *p_image = image;
>   *p_image_size = image_size;
> - return EFI_SUCCESS;
> +}
> +
> +/**
> + * efi_firmware_verify_image - 

Re: [PATCH v2 2/4] efi_loader: versioning support in GetImageInfo

2023-03-02 Thread Takahiro Akashi
On Thu, Mar 02, 2023 at 07:05:50PM +0900, Masahisa Kojima wrote:
> On Thu, 2 Mar 2023 at 14:16, Takahiro Akashi  
> wrote:
> >
> > On Wed, Mar 01, 2023 at 06:15:20PM +0900, Masahisa Kojima wrote:
> > > Current FMP->GetImageInfo() always return 0 for the firmware
> > > version, user can not identify which firmware version is currently
> > > running through the EFI interface.
> > >
> > > This commit reads the "FmpState" EFI variable, then fills the
> > > firmware version, lowest supported version, last attempt version
> > > and last attempt status in FMP->GetImageInfo().
> > >
> > > Now FMP->GetImageInfo() and ESRT have the meaningful version number.
> > >
> > > Signed-off-by: Masahisa Kojima 
> > > ---
> > > No update since v1
> > >
> > >  lib/efi_loader/efi_firmware.c | 30 ++
> > >  1 file changed, 26 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
> > > index d1afafb052..ead20fa914 100644
> > > --- a/lib/efi_loader/efi_firmware.c
> > > +++ b/lib/efi_loader/efi_firmware.c
> > > @@ -173,13 +173,38 @@ static efi_status_t efi_fill_image_desc_array(
> > >   *package_version_name = NULL; /* not supported */
> > >
> > >   for (i = 0; i < num_image_type_guids; i++) {
> > > + u16 varname[13]; /* u"FmpState" */
> > > + efi_status_t ret;
> > > + efi_uintn_t size;
> > > + struct fmp_state var_state = { 0 };
> > > +
> > >   image_info[i].image_index = fw_array[i].image_index;
> > >   image_info[i].image_type_id = fw_array[i].image_type_id;
> > >   image_info[i].image_id = fw_array[i].image_index;
> > >
> > >   image_info[i].image_id_name = fw_array[i].fw_name;
> > >
> > > - image_info[i].version = 0; /* not supported */
> > > + efi_create_indexed_name(varname, sizeof(varname), 
> > > "FmpState",
> > > + fw_array[i].image_index);
> >
> > Don't we have to think of the systems where multiple FMP drivers are
> > used? In those cases, 'image_index' doesn't work as an unique ID.
> > It is unlikely under the current code, but we should consider
> > any future extension.
> 
> I assume that other FMP drivers implement their own version management.

I don't have a strong opinion, but my idea about a variable name is
to use 'image_type_id' as a 'vendor' field which allows for making the variable
globally unique.

-Takahiro Akashi


> Thanks,
> Masahisa Kojima
> 
> >
> > -Takahiro Akashi
> >
> >
> > > + size = sizeof(var_state);
> > > + ret = efi_get_variable_int(varname, _guid_fmp_state, 
> > > NULL,
> > > +, _state, NULL);
> > > + if (ret == EFI_SUCCESS) {
> > > + image_info[i].version = var_state.fw_version;
> > > + image_info[i].lowest_supported_image_version =
> > > + var_state.lowest_supported_version;
> > > + image_info[i].last_attempt_version =
> > > + var_state.last_attempt_version;
> > > + image_info[i].last_attempt_status =
> > > + var_state.last_attempt_status;
> > > + } else {
> > > + image_info[i].version = 0;
> > > + image_info[i].lowest_supported_image_version = 0;
> > > + image_info[i].last_attempt_version = 0;
> > > + image_info[i].last_attempt_status =
> > > + LAST_ATTEMPT_STATUS_SUCCESS;
> > > + }
> > > +
> > >   image_info[i].version_name = NULL; /* not supported */
> > >   image_info[i].size = 0;
> > >   image_info[i].attributes_supported =
> > > @@ -193,9 +218,6 @@ static efi_status_t efi_fill_image_desc_array(
> > >   image_info[0].attributes_setting |=
> > >   IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
> > >
> > > - image_info[i].lowest_supported_image_version = 0;
> > > - image_info[i].last_attempt_version = 0;
> > > - image_info[i].last_attempt_status = 
> > > LAST_ATTEMPT_STATUS_SUCCESS;
> > >   image_info[i].hardware_instance = 1;
> > >   image_info[i].dependencies = NULL;
> > >   }
> > > --
> > > 2.17.1
> > >


Re: [PATCH v2 4/4] mkeficapsule: add FMP Payload Header

2023-03-01 Thread Takahiro Akashi
   uint16_t oemflags)
>  {
> @@ -410,10 +447,11 @@ static int create_fwbin(char *path, char *bin, 
> efi_guid_t *guid,
>   struct efi_firmware_management_capsule_image_header image;
>   struct auth_context auth_context;
>   FILE *f;
> - uint8_t *data;
> + uint8_t *data, *new_data, *buf;
>   off_t bin_size;
>   uint64_t offset;
>   int ret;
> + struct fmp_payload_header payload_header;
>  
>  #ifdef DEBUG
>   fprintf(stderr, "For output: %s\n", path);
> @@ -423,6 +461,7 @@ static int create_fwbin(char *path, char *bin, efi_guid_t 
> *guid,
>   auth_context.sig_size = 0;
>   f = NULL;
>   data = NULL;
> + new_data = NULL;
>   ret = -1;
>  
>   /*
> @@ -431,12 +470,31 @@ static int create_fwbin(char *path, char *bin, 
> efi_guid_t *guid,
>   if (read_bin_file(bin, , _size))
>   goto err;
>  
> + buf = data;
> +
> + /* insert fmp payload header right before the payload */
> + if (fmp_ph_params->have_header) {
> + new_data = malloc(bin_size + sizeof(payload_header));
> + if (!new_data)
> + goto err;
> +
> + payload_header.signature = FMP_PAYLOAD_HDR_SIGNATURE;
> + payload_header.header_size = sizeof(payload_header);
> + payload_header.fw_version = fmp_ph_params->fw_version;
> + payload_header.lowest_supported_version =
> + fmp_ph_params->lowest_supported_version;
> + memcpy(new_data, _header, sizeof(payload_header));
> + memcpy(new_data + sizeof(payload_header), data, bin_size);
> + buf = new_data;
> + bin_size += sizeof(payload_header);
> + }
> +
>   /* first, calculate signature to determine its size */
>   if (privkey_file && cert_file) {
>   auth_context.key_file = privkey_file;
>   auth_context.cert_file = cert_file;
>   auth_context.auth.monotonic_count = mcount;
> - auth_context.image_data = data;
> + auth_context.image_data = buf;
>   auth_context.image_size = bin_size;
>  
>   if (create_auth_data(_context)) {
> @@ -536,7 +594,7 @@ static int create_fwbin(char *path, char *bin, efi_guid_t 
> *guid,
>   /*
>* firmware binary
>*/
> - if (write_capsule_file(f, data, bin_size, "Firmware binary"))
> + if (write_capsule_file(f, buf, bin_size, "Firmware binary"))
>   goto err;
>  
>   ret = 0;
> @@ -545,6 +603,7 @@ err:
>   fclose(f);
>   free_sig_data(_context);
>   free(data);
> + free(new_data);
>  
>   return ret;
>  }
> @@ -644,6 +703,7 @@ int main(int argc, char **argv)
>   unsigned long oemflags;
>   char *privkey_file, *cert_file;
>   int c, idx;
> + struct fmp_payload_header_params fmp_ph_params = { 0 };
>  
>   guid = NULL;
>   index = 0;
> @@ -679,6 +739,15 @@ int main(int argc, char **argv)
>   case 'I':
>   instance = strtoul(optarg, NULL, 0);
>   break;
> + case 'f':
> + fmp_ph_params.have_header = true;
> + break;
> + case 'v':
> + fmp_ph_params.fw_version = strtoul(optarg, NULL, 0);
> + break;
> + case 'l':
> + fmp_ph_params.lowest_supported_version = 
> strtoul(optarg, NULL, 0);
> + break;

Should we check dependencies between two options?
Let's say, '-v' is required if '-l' is provided, and
'fw_version' must be greater than 'lowest_supported_version'.

-Takahiro Akashi

>   case 'p':
>   if (privkey_file) {
>   fprintf(stderr,
> @@ -747,11 +816,11 @@ int main(int argc, char **argv)
>   if (capsule_type != CAPSULE_NORMAL_BLOB) {
>   if (create_empty_capsule(argv[argc - 1], guid,
>capsule_type == CAPSULE_ACCEPT) < 0) {
> - fprintf(stderr, "Creating empty capsule failed\n");
> + fprintf(stderr, "Creating empty capsulefailed\n");
>   exit(EXIT_FAILURE);
>   }
>   } else  if (create_fwbin(argv[argc - 1], argv[argc - 2], guid,
> -  index, instance, mcount, privkey_file,
> +  index, instance, _ph_params, mcount, 
> privkey_file,
>cert_file, (uint16_t)oemflags) < 0) {
>   fprintf(stderr, "Creating firmware capsule failed\n");
>   exit(EXIT_FAILURE);
> -- 
> 2.17.1
> 


Re: [PATCH v2 2/4] efi_loader: versioning support in GetImageInfo

2023-03-01 Thread Takahiro Akashi
On Wed, Mar 01, 2023 at 06:15:20PM +0900, Masahisa Kojima wrote:
> Current FMP->GetImageInfo() always return 0 for the firmware
> version, user can not identify which firmware version is currently
> running through the EFI interface.
> 
> This commit reads the "FmpState" EFI variable, then fills the
> firmware version, lowest supported version, last attempt version
> and last attempt status in FMP->GetImageInfo().
> 
> Now FMP->GetImageInfo() and ESRT have the meaningful version number.
> 
> Signed-off-by: Masahisa Kojima 
> ---
> No update since v1
> 
>  lib/efi_loader/efi_firmware.c | 30 ++
>  1 file changed, 26 insertions(+), 4 deletions(-)
> 
> diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
> index d1afafb052..ead20fa914 100644
> --- a/lib/efi_loader/efi_firmware.c
> +++ b/lib/efi_loader/efi_firmware.c
> @@ -173,13 +173,38 @@ static efi_status_t efi_fill_image_desc_array(
>   *package_version_name = NULL; /* not supported */
>  
>   for (i = 0; i < num_image_type_guids; i++) {
> + u16 varname[13]; /* u"FmpState" */
> + efi_status_t ret;
> + efi_uintn_t size;
> + struct fmp_state var_state = { 0 };
> +
>   image_info[i].image_index = fw_array[i].image_index;
>   image_info[i].image_type_id = fw_array[i].image_type_id;
>   image_info[i].image_id = fw_array[i].image_index;
>  
>   image_info[i].image_id_name = fw_array[i].fw_name;
>  
> - image_info[i].version = 0; /* not supported */
> + efi_create_indexed_name(varname, sizeof(varname), "FmpState",
> + fw_array[i].image_index);

Don't we have to think of the systems where multiple FMP drivers are
used? In those cases, 'image_index' doesn't work as an unique ID.
It is unlikely under the current code, but we should consider
any future extension.

-Takahiro Akashi


> + size = sizeof(var_state);
> + ret = efi_get_variable_int(varname, _guid_fmp_state, NULL,
> +, _state, NULL);
> + if (ret == EFI_SUCCESS) {
> + image_info[i].version = var_state.fw_version;
> + image_info[i].lowest_supported_image_version =
> + var_state.lowest_supported_version;
> + image_info[i].last_attempt_version =
> + var_state.last_attempt_version;
> + image_info[i].last_attempt_status =
> + var_state.last_attempt_status;
> + } else {
> + image_info[i].version = 0;
> + image_info[i].lowest_supported_image_version = 0;
> + image_info[i].last_attempt_version = 0;
> + image_info[i].last_attempt_status =
> + LAST_ATTEMPT_STATUS_SUCCESS;
> + }
> +
>   image_info[i].version_name = NULL; /* not supported */
>   image_info[i].size = 0;
>   image_info[i].attributes_supported =
> @@ -193,9 +218,6 @@ static efi_status_t efi_fill_image_desc_array(
>   image_info[0].attributes_setting |=
>   IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
>  
> - image_info[i].lowest_supported_image_version = 0;
> - image_info[i].last_attempt_version = 0;
> - image_info[i].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
>   image_info[i].hardware_instance = 1;
>   image_info[i].dependencies = NULL;
>   }
> -- 
> 2.17.1
> 


Re: [PATCH v2 1/4] efi_loader: store firmware version into FmpState variable

2023-03-01 Thread Takahiro Akashi
 status code
> + */
> +static
> +efi_status_t efi_firmware_verify_image(const void **p_image,
> +efi_uintn_t *p_image_size,
> +u8 image_index,
> +struct fmp_state *state)
> +{
> + efi_status_t ret;
> +
> + ret = efi_firmware_capsule_authenticate(p_image, p_image_size, state);
> + efi_firmware_parse_payload_header(p_image, p_image_size, state);
> +
> + return ret;
>  }
>  
>  /**
> @@ -330,7 +459,9 @@ efi_status_t EFIAPI efi_firmware_fit_set_image(
>   efi_status_t (*progress)(efi_uintn_t completion),
>   u16 **abort_reason)
>  {
> + bool updated;
>   efi_status_t status;
> + struct fmp_state state = { 0 };
>  
>   EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image,
> image_size, vendor_code, progress, abort_reason);
> @@ -338,14 +469,22 @@ efi_status_t EFIAPI efi_firmware_fit_set_image(
>   if (!image || image_index != 1)
>   return EFI_EXIT(EFI_INVALID_PARAMETER);
>  
> - status = efi_firmware_capsule_authenticate(, _size);
> + status = efi_firmware_verify_image(, _size, image_index,
> +);
>   if (status != EFI_SUCCESS)
> - return EFI_EXIT(status);
> + goto err;
>  
> - if (fit_update(image))
> - return EFI_EXIT(EFI_DEVICE_ERROR);
> + if (fit_update(image)) {
> + status = EFI_DEVICE_ERROR;

I think we need to add here:
state.last_attempt_status = 
LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;

-Takahiro Akashi

> + goto err;
> + }
>  
> - return EFI_EXIT(EFI_SUCCESS);
> + state.last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
> +err:
> + updated = (status == EFI_SUCCESS) ? true : false;
> + efi_firmware_set_fmp_state_var(, image_index, updated);
> +
> + return EFI_EXIT(status);
>  }
>  
>  const struct efi_firmware_management_protocol efi_fmp_fit = {
> @@ -391,7 +530,9 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
>   u16 **abort_reason)
>  {
>   int ret;
> + bool updated;
>   efi_status_t status;
> + struct fmp_state state = { 0 };
>  
>   EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image,
> image_size, vendor_code, progress, abort_reason);
> @@ -399,9 +540,10 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
>   if (!image)
>   return EFI_EXIT(EFI_INVALID_PARAMETER);
>  
> - status = efi_firmware_capsule_authenticate(, _size);
> + status = efi_firmware_verify_image(, _size, image_index,
> +);
>   if (status != EFI_SUCCESS)
> - return EFI_EXIT(status);
> + goto err;
>  
>   if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
>   /*
> @@ -410,16 +552,26 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
>*/
>   ret = fwu_get_image_index(_index);
>   if (ret) {
> + state.last_attempt_status = 
> LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
>   log_debug("Unable to get FWU image_index\n");
> - return EFI_EXIT(EFI_DEVICE_ERROR);
> + status = EFI_DEVICE_ERROR;
> + goto err;
>   }
>   }
>  
>   if (dfu_write_by_alt(image_index - 1, (void *)image, image_size,
> -  NULL, NULL))
> - return EFI_EXIT(EFI_DEVICE_ERROR);
> +  NULL, NULL)) {
> + status = EFI_DEVICE_ERROR;
> + state.last_attempt_status = 
> LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
> + goto err;
> + }
> +
> + state.last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
> +err:
> + updated = (status == EFI_SUCCESS) ? true : false;
> + efi_firmware_set_fmp_state_var(, image_index, updated);
>  
> - return EFI_EXIT(EFI_SUCCESS);
> + return EFI_EXIT(status);
>  }
>  
>  const struct efi_firmware_management_protocol efi_fmp_raw = {
> -- 
> 2.17.1
> 


Re: [PATCH v11 15/15] FWU: doc: Add documentation for the FWU feature

2022-10-04 Thread Takahiro Akashi
On Tue, Oct 04, 2022 at 12:10:27PM +0530, Sughosh Ganu wrote:
> hi Takahiro,
> 
> On Tue, 4 Oct 2022 at 08:24, Takahiro Akashi  
> wrote:
> >
> > Sughosh,
> >
> > On Wed, Sep 28, 2022 at 02:59:56PM +0530, Sughosh Ganu wrote:
> > > Add documentation for the FWU Multi Bank Update feature. The document
> > > describes the steps needed for setting up the platform for the
> > > feature, as well as steps for enabling the feature on the platform.
> > >
> > > Signed-off-by: Sughosh Ganu 
> > > ---
> > > Changes since V10:
> > > * Fix review comments suggested by Etienne
> > > * Add a paragraph in the capsule update section to highlight the
> > >   difference in ImageIndex correlation with DFU alt num with FWU feature
> > >   enabled
> > >
> > >  doc/develop/uefi/fwu_updates.rst | 173 +++
> > >  doc/develop/uefi/index.rst   |   1 +
> > >  doc/develop/uefi/uefi.rst|  10 ++
> > >  3 files changed, 184 insertions(+)
> > >  create mode 100644 doc/develop/uefi/fwu_updates.rst
> > >
> > > diff --git a/doc/develop/uefi/fwu_updates.rst 
> > > b/doc/develop/uefi/fwu_updates.rst
> > > new file mode 100644
> > > index 00..292feceb9a
> > > --- /dev/null
> > > +++ b/doc/develop/uefi/fwu_updates.rst
> > > @@ -0,0 +1,173 @@
> > > +.. SPDX-License-Identifier: GPL-2.0+
> > > +.. Copyright (c) 2022 Linaro Limited
> > > +
> > > +FWU Multi Bank Updates in U-Boot
> > > +
> > > +
> > > +The FWU Multi Bank Update feature implements the firmware update
> > > +mechanism described in the PSA Firmware Update for A-profile Arm
> > > +Architecture specification [1]. Certain aspects of the Dependable
> > > +Boot specification [2] are also implemented. The feature provides a
> > > +mechanism to have multiple banks of updatable firmware images and for
> > > +updating the firmware images on the non-booted bank. On a successful
> > > +update, the platform boots from the updated bank on subsequent
> > > +boot. The UEFI capsule-on-disk update feature is used for performing
> > > +the actual updates of the updatable firmware images.
> > > +
> > > +The bookkeeping of the updatable images is done through a structure
> > > +called metadata. Currently, the FWU metadata supports identification
> > > +of images based on image GUIDs stored on a GPT partitioned storage
> > > +media. There are plans to extend the metadata structure for non GPT
> > > +partitioned devices as well.
> > > +
> > > +Accessing the FWU metadata is done through generic API's which are
> > > +defined in a driver which complies with the U-Boot's driver model. A
> > > +new uclass UCLASS_FWU_MDATA has been added for accessing the FWU
> > > +metadata. Individual drivers can be added based on the type of storage
> > > +media, and its partitioning method. Details of the storage device
> > > +containing the FWU metadata partitions are specified through a U-Boot
> > > +specific device tree property `fwu-mdata-store`. Please refer to
> > > +U-Boot `doc `__
> > > +for the device tree bindings.
> > > +
> > > +Enabling the FWU Multi Bank Update feature
> > > +--
> > > +
> > > +The feature can be enabled by specifying the following configs::
> > > +
> > > +CONFIG_EFI_CAPSULE_ON_DISK=y
> > > +CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y
> > > +CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
> > > +
> > > +CONFIG_FWU_MULTI_BANK_UPDATE=y
> > > +CONFIG_CMD_FWU_METADATA=y
> > > +CONFIG_FWU_MDATA=y
> > > +CONFIG_FWU_MDATA_GPT_BLK=y
> > > +CONFIG_FWU_NUM_BANKS=
> > > +CONFIG_FWU_NUM_IMAGES_PER_BANK=
> > > +
> > > +in the .config file
> > > +
> > > +The first group of configuration settings enable the UEFI
> > > +capsule-on-disk update functionality. The second group of configs
> > > +enable the FWU Multi Bank Update functionality. Please refer to the
> > > +section :ref:`uefi_capsule_update_ref` for more details on generation
> > > +of the UEFI capsule.
> > > +
> > > +Setting up the device for GPT partitioned storage
> > > +-
> > > +
> > > +Before enabling the functionality in U-Boot, a GPT partitioned storage
> > > +dev

Re: [PATCH v11 05/15] stm32mp1: dk2: Add image information for capsule updates

2022-10-03 Thread Takahiro Akashi
On Mon, Oct 03, 2022 at 04:40:04PM +0530, Sughosh Ganu wrote:
> hi Takahiro,
> 
> On Mon, 3 Oct 2022 at 16:27, Takahiro Akashi  
> wrote:
> >
> > Hi Sughosh,
> >
> > On Wed, Sep 28, 2022 at 02:59:46PM +0530, Sughosh Ganu wrote:
> > > Enabling capsule update functionality on the platform requires
> > > populating information on the images that are to be updated using the
> > > functionality. Do so for the DK2 board.
> > >
> > > Signed-off-by: Sughosh Ganu 
> > > Reviewed-by: Patrick Delaunay 
> > > Reviewed-by: Ilias Apalodimas 
> > > ---
> > > Changes since V10:
> > > * Use image_index value of 1 for the FIP image as it is now relevant
> > >
> > >  board/st/stm32mp1/stm32mp1.c   | 18 ++
> > >  include/configs/stm32mp15_common.h |  4 
> > >  2 files changed, 22 insertions(+)
> > >
> > > diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
> > > index 8c162b42a5..e43dab018f 100644
> > > --- a/board/st/stm32mp1/stm32mp1.c
> > > +++ b/board/st/stm32mp1/stm32mp1.c
> > > @@ -11,6 +11,7 @@
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > @@ -87,6 +88,16 @@
> > >  #define USB_START_LOW_THRESHOLD_UV   123
> > >  #define USB_START_HIGH_THRESHOLD_UV  215
> > >
> > > +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
> > > +struct efi_fw_image fw_images[1];
> > > +
> > > +struct efi_capsule_update_info update_info = {
> > > + .images = fw_images,
> > > +};
> > > +
> > > +u8 num_image_type_guids = ARRAY_SIZE(fw_images);
> >
> > The definition of num_image_type_guids is always the same
> > across boards. Why do we need it for every platform?
> 
> Yes, but that is because at present every platform is declaring the
> same variable name(fw_images) for the struct efi_fw_image.

That's because fw_images is hard-coded in efi_firmware.c by your change.

> That is not mandatory,

In this sense, it is mandatory unless you want to write a new FMP driver
from the scratch.

> and a subsequent addition can declare a variable with a
> different name. But in case there is consensus on using a fixed
> variable name for the structure, I can make the change that you are
> suggesting subsequently. I will work on it if needed after the FWU
> patches upstreaming work is done.
> 
> 
> > I believe that we can remove it. Anyhow it's not documented
> > in doc/develop/uefi/uefi.rst.
> >
> > > +#endif /* EFI_HAVE_CAPSULE_SUPPORT */
> > > +
> > >  int board_early_init_f(void)
> > >  {
> > >   /* nothing to do, only used in SPL */
> > > @@ -666,6 +677,13 @@ int board_init(void)
> > >
> > >   setup_led(LEDST_ON);
> > >
> > > +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
> > > + efi_guid_t image_type_guid = STM32MP_FIP_IMAGE_GUID;
> > > +
> > > + guidcpy(_images[0].image_type_id, _type_guid);
> > > + fw_images[0].fw_name = u"STM32MP-FIP";
> > > + fw_images[0].image_index = 1;
> >
> > Then, we should describe that image_index must be 1 to num_image_type_guids
> > (or strictly, number of descriptors returned by GetImageInfo()) in
> > the document above.
> 
> Okay
> 
> > (I hope that you add a sanity checker against it as well.)
> 
> Yes, in the efi_fmp_find(), there is a check for the index value
> passed through the capsule against the value returned by the
> GetImageInfo().

I meant that the check takes place at some time in initialization,
but yes, efi_fmp_find() works as a safe guard.

-Takahiro Akashi

> -sughosh
> 
> >
> > -Takahiro Akashi
> >
> > > +#endif
> > >   return 0;
> > >  }
> > >
> > > diff --git a/include/configs/stm32mp15_common.h 
> > > b/include/configs/stm32mp15_common.h
> > > index c5412ffeb3..bb19dae945 100644
> > > --- a/include/configs/stm32mp15_common.h
> > > +++ b/include/configs/stm32mp15_common.h
> > > @@ -34,6 +34,10 @@
> > >  #define CONFIG_SERVERIP 192.168.1.1
> > >  #endif
> > >
> > > +#define STM32MP_FIP_IMAGE_GUID \
> > > + EFI_GUID(0x19d5df83, 0x11b0, 0x457b, 0xbe, 0x2c, \
> > > +  0x75, 0x59, 0xc1, 0x31, 0x42, 0xa5)
> > > +
> > >  
> > > /*/
> > >  #ifdef CONFIG_DISTRO_DEFAULTS
> > >  
> > > /*/
> > > --
> > > 2.34.1
> > >


Re: [PATCH v11 15/15] FWU: doc: Add documentation for the FWU feature

2022-10-03 Thread Takahiro Akashi
 the partitions, a few aspects need to be taken care
> +of. Each GPT partition entry in the GPT header has two GUIDs::
> +
> +* PartitionTypeGUID
> +* UniquePartitionGUID
> +
> +The PartitionTypeGUID value should correspond to the
> +``image_type_uuid`` field of the FWU metadata. This field is used to
> +identify a given type of updatable firmware image, e.g. U-Boot,
> +OP-TEE, FIP etc. This GUID should also be used for specifying the
> +`--guid` parameter when generating the capsule.
> +
> +The UniquePartitionGUID value should correspond to the ``image_uuid``
> +field in the FWU metadata. This GUID is used to identify images of a
> +given image type in different banks.

Well, what is not clear to me here is:
- who is responsible to set up FWU metadata and when
- how FWU metadata is related to fw_images and update_info
  which are used in normal case, which is mentioned in develop/uefi/uefi.rst

I know the whole text here is dedicated to A/B update, but I think
it would also be helpful to have a single document which covers both cases
for developers to understand how differently FWU is configured for those cases.

-Takahiro Akashi

> +
> +Similarly, the FWU specification defines the GUID value to be used
> +for the metadata partitions. This would be the PartitionTypeGUID for
> +the metadata partitions.
> +
> +When generating the metadata, the ``image_type_uuid`` and the
> +``image_uuid`` values should match the *PartitionTypeGUID* and the
> +*UniquePartitionGUID* values respectively.
> +
> +Performing the Update
> +-
> +
> +Once the storage media has been partitioned and populated with the
> +metadata partitions, the UEFI capsule-on-disk update functionality can
> +be used for performing the update. Refer to the section
> +:ref:`uefi_capsule_update_ref` for details on how the update can be
> +invoked.
> +
> +On a successful update, the FWU metadata gets updated to reflect the
> +bank from which the platform would be booting on subsequent boot.
> +
> +Based on the value of bit15 of the Flags member of the capsule header,
> +the updated images would either be accepted by the U-Boot's UEFI
> +implementation, or by the Operating System. If the Operating System is
> +accepting the firmware images, it does so by generating an empty
> +*accept* capsule. The Operating System can also reject the updated
> +firmware by generating a *revert* capsule. The empty capsule can be
> +applied by using the exact same procedure used for performing the
> +capsule-on-disk update.
> +
> +The task of accepting the different firmware images, post an update
> +may be done by multiple, separate components in the Operating
> +System. To help identify the firmware image that is being accepted,
> +the accept capsule passes the image GUID of the firmware image being
> +accepted. The relevant code in U-Boot then sets the Accept bit of the
> +corresponding firmware image for which the accept capsule was
> +found. Only when all the firmware components in a bank have been
> +accepted does the platform transition from trial state to regular
> +state.
> +
> +The revert capsule on the other hand does not pass any image GUID,
> +since reverting any image of the bank has the same result of the
> +platform booting from the other bank on subsequent boot.
> +
> +Generating an empty capsule
> +---
> +
> +The empty capsule can be generated using the mkeficapsule utility. To
> +build the tool, enable::
> +
> +CONFIG_TOOLS_MKEFICAPSULE=y
> +
> +Run the following commands to generate the accept/revert capsules::
> +
> +.. code-block:: bash
> +
> +$ ./tools/mkeficapsule \
> +  [--fw-accept --guid ] | \
> +  [--fw-revert] \
> +  
> +
> +Some examples of using the mkeficapsule tool for generation of the
> +empty capsule would be::
> +
> +.. code-block:: bash
> +
> +$ ./tools/mkeficapsule --fw-accept --guid  \
> +
> +$ ./tools/mkeficapsule --fw-revert 
> +
> +Links
> +-
> +
> +* [1] https://developer.arm.com/documentation/den0118/a/ - FWU Specification
> +* [2] 
> https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
>  - Dependable Boot Specification
> diff --git a/doc/develop/uefi/index.rst b/doc/develop/uefi/index.rst
> index 7e65dbc5d5..e26b1fbe05 100644
> --- a/doc/develop/uefi/index.rst
> +++ b/doc/develop/uefi/index.rst
> @@ -13,3 +13,4 @@ can be run an UEFI payload.
> uefi.rst
> u-boot_on_efi.rst
> iscsi.rst
> +   fwu_updates.rst
> diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
> index 941e427093..b5c83db65a 100644
> --- a/doc/develop/uefi/uefi.rst
> +++ b/doc/develop/uefi/uefi.rst
&g

Re: [PATCH v11 05/15] stm32mp1: dk2: Add image information for capsule updates

2022-10-03 Thread Takahiro Akashi
Hi Sughosh,

On Wed, Sep 28, 2022 at 02:59:46PM +0530, Sughosh Ganu wrote:
> Enabling capsule update functionality on the platform requires
> populating information on the images that are to be updated using the
> functionality. Do so for the DK2 board.
> 
> Signed-off-by: Sughosh Ganu 
> Reviewed-by: Patrick Delaunay 
> Reviewed-by: Ilias Apalodimas 
> ---
> Changes since V10:
> * Use image_index value of 1 for the FIP image as it is now relevant
> 
>  board/st/stm32mp1/stm32mp1.c   | 18 ++
>  include/configs/stm32mp15_common.h |  4 
>  2 files changed, 22 insertions(+)
> 
> diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
> index 8c162b42a5..e43dab018f 100644
> --- a/board/st/stm32mp1/stm32mp1.c
> +++ b/board/st/stm32mp1/stm32mp1.c
> @@ -11,6 +11,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -87,6 +88,16 @@
>  #define USB_START_LOW_THRESHOLD_UV   123
>  #define USB_START_HIGH_THRESHOLD_UV  215
>  
> +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
> +struct efi_fw_image fw_images[1];
> +
> +struct efi_capsule_update_info update_info = {
> + .images = fw_images,
> +};
> +
> +u8 num_image_type_guids = ARRAY_SIZE(fw_images);

The definition of num_image_type_guids is always the same
across boards. Why do we need it for every platform?
I believe that we can remove it. Anyhow it's not documented
in doc/develop/uefi/uefi.rst.

> +#endif /* EFI_HAVE_CAPSULE_SUPPORT */
> +
>  int board_early_init_f(void)
>  {
>   /* nothing to do, only used in SPL */
> @@ -666,6 +677,13 @@ int board_init(void)
>  
>   setup_led(LEDST_ON);
>  
> +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
> + efi_guid_t image_type_guid = STM32MP_FIP_IMAGE_GUID;
> +
> + guidcpy(_images[0].image_type_id, _type_guid);
> + fw_images[0].fw_name = u"STM32MP-FIP";
> + fw_images[0].image_index = 1;

Then, we should describe that image_index must be 1 to num_image_type_guids
(or strictly, number of descriptors returned by GetImageInfo()) in
the document above.
(I hope that you add a sanity checker against it as well.)

-Takahiro Akashi

> +#endif
>   return 0;
>  }
>  
> diff --git a/include/configs/stm32mp15_common.h 
> b/include/configs/stm32mp15_common.h
> index c5412ffeb3..bb19dae945 100644
> --- a/include/configs/stm32mp15_common.h
> +++ b/include/configs/stm32mp15_common.h
> @@ -34,6 +34,10 @@
>  #define CONFIG_SERVERIP 192.168.1.1
>  #endif
>  
> +#define STM32MP_FIP_IMAGE_GUID \
> + EFI_GUID(0x19d5df83, 0x11b0, 0x457b, 0xbe, 0x2c, \
> +  0x75, 0x59, 0xc1, 0x31, 0x42, 0xa5)
> +
>  
> /*/
>  #ifdef CONFIG_DISTRO_DEFAULTS
>  
> /*/
> -- 
> 2.34.1
> 


Re: [PATCH] test/py: efi_secboot: Remove unnecessary cert-to-efi-hash-list option

2022-10-03 Thread Takahiro Akashi
On Mon, Oct 03, 2022 at 04:12:15PM +0900, Masahisa Kojima wrote:
> 'cert-to-efi-hash-list -t 0' does not work as expected, it produces
> indeterminate timestamp.
> 
>   $ cert-to-efi-hash-list -t 0 -s 256 db.crt dbx_hash.crl
>   TimeOfRevocation is 0-113-0 00:00:255
> 
> If we need the CRL revoked for all the time, just don't specify
> '-t' option.

Correct. Thank you for the fix.
(The tests happen to pass since the year is always 0 (or 1900?).)

-Takahiro Akashi

>   $ cert-to-efi-hash-list -s 256 db.crt dbx_hash.crl
>   TimeOfRevocation is 0-0-0 00:00:00
> 
> Signed-off-by: Masahisa Kojima 
> ---
>  test/py/tests/test_efi_secboot/conftest.py | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/test/py/tests/test_efi_secboot/conftest.py 
> b/test/py/tests/test_efi_secboot/conftest.py
> index db6b8d301f..f2f914f617 100644
> --- a/test/py/tests/test_efi_secboot/conftest.py
> +++ b/test/py/tests/test_efi_secboot/conftest.py
> @@ -77,17 +77,17 @@ def efi_boot_env(request, u_boot_config):
> % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
> shell=True)
>  # dbx_hash (digest of TEST_db certificate)
> -check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 256 db.crt 
> dbx_hash.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx 
> dbx_hash.crl dbx_hash.auth'
> +check_call('cd %s; %scert-to-efi-hash-list -g %s -s 256 db.crt 
> dbx_hash.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx 
> dbx_hash.crl dbx_hash.auth'
> % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
> shell=True)
> -check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 384 db.crt 
> dbx_hash384.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key 
> dbx dbx_hash384.crl dbx_hash384.auth'
> +check_call('cd %s; %scert-to-efi-hash-list -g %s -s 384 db.crt 
> dbx_hash384.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key 
> dbx dbx_hash384.crl dbx_hash384.auth'
> % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
> shell=True)
> -check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 512 db.crt 
> dbx_hash512.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key 
> dbx dbx_hash512.crl dbx_hash512.auth'
> +check_call('cd %s; %scert-to-efi-hash-list -g %s -s 512 db.crt 
> dbx_hash512.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key 
> dbx dbx_hash512.crl dbx_hash512.auth'
> % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
> shell=True)
>  # dbx_hash1 (digest of TEST_db1 certificate)
> -check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 256 db1.crt 
> dbx_hash1.crl; %ssign-efi-sig-list -t "2020-04-06" -c KEK.crt -k KEK.key dbx 
> dbx_hash1.crl dbx_hash1.auth'
> +check_call('cd %s; %scert-to-efi-hash-list -g %s -s 256 db1.crt 
> dbx_hash1.crl; %ssign-efi-sig-list -t "2020-04-06" -c KEK.crt -k KEK.key dbx 
> dbx_hash1.crl dbx_hash1.auth'
> % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
> shell=True)
>  # dbx_db (with TEST_db certificate)
> -- 
> 2.17.1
> 


Re: [PATCH v10 10/15] FWU: Add support for the FWU Multi Bank Update feature

2022-09-21 Thread Takahiro Akashi
On Wed, Sep 21, 2022 at 04:56:20PM +0530, Sughosh Ganu wrote:
> hi Takahiro,
> 
> On Wed, 21 Sept 2022 at 10:58, Takahiro Akashi
>  wrote:
> >
> > Sughosh,
> >
> > On Tue, Sep 20, 2022 at 06:34:12PM +0530, Sughosh Ganu wrote:
> > > On Tue, 20 Sept 2022 at 13:46, Takahiro Akashi
> > >  wrote:
> > > >
> > > > On Fri, Sep 16, 2022 at 04:24:35PM +0530, Sughosh Ganu wrote:
> > > > > hi Takahiro,
> > > > >
> > > > > On Fri, 16 Sept 2022 at 12:20, Takahiro Akashi
> > > > >  wrote:
> > > > > >
> > > > > > On Fri, Sep 16, 2022 at 10:52:11AM +0530, Sughosh Ganu wrote:
> > > > > > > () hi Takahiro,
> > > > > > >
> > > > > > > On Fri, 16 Sept 2022 at 07:17, Takahiro Akashi
> > > > > > >  wrote:
> > > > > > > >
> > > > > > > > Hi Sughosh,
> > > > > > > >
> > > > > > > > On Thu, Sep 15, 2022 at 01:44:46PM +0530, Sughosh Ganu wrote:
> > > > > > > > > The FWU Multi Bank Update feature supports updation of 
> > > > > > > > > firmware images
> > > > > > > > > to one of multiple sets(also called banks) of images. The 
> > > > > > > > > firmware
> > > > > > > > > images are clubbed together in banks, with the system booting 
> > > > > > > > > images
> > > > > > > > > from the active bank. Information on the images such as which 
> > > > > > > > > bank
> > > > > > > > > they belong to is stored as part of the metadata structure, 
> > > > > > > > > which is
> > > > > > > > > stored on the same storage media as the firmware images on a 
> > > > > > > > > dedicated
> > > > > > > > > partition.
> > > > > > > > >
> > > > > > > > > At the time of update, the metadata is read to identify the 
> > > > > > > > > bank to
> > > > > > > > > which the images need to be flashed(update bank). On a 
> > > > > > > > > successful
> > > > > > > > > update, the metadata is modified to set the updated bank as 
> > > > > > > > > active
> > > > > > > > > bank to subsequently boot from.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Sughosh Ganu 
> > > > > > > > > ---
> > > > > > > > > Changes since V9:
> > > > > > > > > * Move the global variables into local variables as suggested 
> > > > > > > > > by
> > > > > > > > >   Ilias.
> > > > > > > > > * Change fwu_get_image_alt_num() name to 
> > > > > > > > > fwu_get_image_image_index()
> > > > > > > >
> > > > > > > > -> typo? fwu_get_image_index()?
> > > > > > > >
> > > > > > > > >   as suggested by Takahiro.
> > > > > > > > > * Allow capsule updates to be called from efi_init_obj_list() 
> > > > > > > > > with the
> > > > > > > > >   FWU feature enabled, as suggested by Takahiro.
> > > > > > > > > * Enable EFI_CAPSULE_ON_DISK_EARLY as an imply with the FWU 
> > > > > > > > > feature
> > > > > > > > >   enabled.
> > > > > > > > > * Define the FWU feature related functions as __maybe_unused 
> > > > > > > > > to allow
> > > > > > > > >   for compilation with the FWU feature disabled.
> > > > > > > > >
> > > > > > > > >  drivers/Kconfig  |   2 +
> > > > > > > > >  drivers/Makefile |   1 +
> > > > > > > > >  include/fwu.h|  30 +
> > > > > > > > >  lib/Kconfig  |   6 +
> > > > > > > > >  lib/Makefile |   1 +
> > > > > > > > >  lib/efi_loader/efi_capsule.c | 243 
> > > > > > > > > ++

Re: [PATCH v10 10/15] FWU: Add support for the FWU Multi Bank Update feature

2022-09-20 Thread Takahiro Akashi
Sughosh,

On Tue, Sep 20, 2022 at 06:34:12PM +0530, Sughosh Ganu wrote:
> On Tue, 20 Sept 2022 at 13:46, Takahiro Akashi
>  wrote:
> >
> > On Fri, Sep 16, 2022 at 04:24:35PM +0530, Sughosh Ganu wrote:
> > > hi Takahiro,
> > >
> > > On Fri, 16 Sept 2022 at 12:20, Takahiro Akashi
> > >  wrote:
> > > >
> > > > On Fri, Sep 16, 2022 at 10:52:11AM +0530, Sughosh Ganu wrote:
> > > > > () hi Takahiro,
> > > > >
> > > > > On Fri, 16 Sept 2022 at 07:17, Takahiro Akashi
> > > > >  wrote:
> > > > > >
> > > > > > Hi Sughosh,
> > > > > >
> > > > > > On Thu, Sep 15, 2022 at 01:44:46PM +0530, Sughosh Ganu wrote:
> > > > > > > The FWU Multi Bank Update feature supports updation of firmware 
> > > > > > > images
> > > > > > > to one of multiple sets(also called banks) of images. The firmware
> > > > > > > images are clubbed together in banks, with the system booting 
> > > > > > > images
> > > > > > > from the active bank. Information on the images such as which bank
> > > > > > > they belong to is stored as part of the metadata structure, which 
> > > > > > > is
> > > > > > > stored on the same storage media as the firmware images on a 
> > > > > > > dedicated
> > > > > > > partition.
> > > > > > >
> > > > > > > At the time of update, the metadata is read to identify the bank 
> > > > > > > to
> > > > > > > which the images need to be flashed(update bank). On a successful
> > > > > > > update, the metadata is modified to set the updated bank as active
> > > > > > > bank to subsequently boot from.
> > > > > > >
> > > > > > > Signed-off-by: Sughosh Ganu 
> > > > > > > ---
> > > > > > > Changes since V9:
> > > > > > > * Move the global variables into local variables as suggested by
> > > > > > >   Ilias.
> > > > > > > * Change fwu_get_image_alt_num() name to 
> > > > > > > fwu_get_image_image_index()
> > > > > >
> > > > > > -> typo? fwu_get_image_index()?
> > > > > >
> > > > > > >   as suggested by Takahiro.
> > > > > > > * Allow capsule updates to be called from efi_init_obj_list() 
> > > > > > > with the
> > > > > > >   FWU feature enabled, as suggested by Takahiro.
> > > > > > > * Enable EFI_CAPSULE_ON_DISK_EARLY as an imply with the FWU 
> > > > > > > feature
> > > > > > >   enabled.
> > > > > > > * Define the FWU feature related functions as __maybe_unused to 
> > > > > > > allow
> > > > > > >   for compilation with the FWU feature disabled.
> > > > > > >
> > > > > > >  drivers/Kconfig  |   2 +
> > > > > > >  drivers/Makefile |   1 +
> > > > > > >  include/fwu.h|  30 +
> > > > > > >  lib/Kconfig  |   6 +
> > > > > > >  lib/Makefile |   1 +
> > > > > > >  lib/efi_loader/efi_capsule.c | 243 
> > > > > > > ++-
> > > > > > >  lib/fwu_updates/Kconfig  |  33 +
> > > > > > >  lib/fwu_updates/Makefile |   7 +
> > > > > > >  lib/fwu_updates/fwu.c|  23 
> > > > > > >  9 files changed, 340 insertions(+), 6 deletions(-)
> > > > > > >  create mode 100644 lib/fwu_updates/Kconfig
> > > > > > >  create mode 100644 lib/fwu_updates/Makefile
> > > > > > >
> > >
> > > 
> > >
> > > > > > >
> > > > > > >  /**
> > > > > > >   * efi_capsule_update_firmware - update firmware from capsule
> > > > > > > @@ -410,7 +544,35 @@ static efi_status_t 
> > > > > > > efi_capsule_update_firmware(
> > > > > > >   int item;
> > > > > > >   struct efi_firmware_management_protocol *fmp;
> > > > > > >   u16 *abort_reason;
> >

Re: [PATCH v10 10/15] FWU: Add support for the FWU Multi Bank Update feature

2022-09-20 Thread Takahiro Akashi
On Fri, Sep 16, 2022 at 04:24:35PM +0530, Sughosh Ganu wrote:
> hi Takahiro,
> 
> On Fri, 16 Sept 2022 at 12:20, Takahiro Akashi
>  wrote:
> >
> > On Fri, Sep 16, 2022 at 10:52:11AM +0530, Sughosh Ganu wrote:
> > > () hi Takahiro,
> > >
> > > On Fri, 16 Sept 2022 at 07:17, Takahiro Akashi
> > >  wrote:
> > > >
> > > > Hi Sughosh,
> > > >
> > > > On Thu, Sep 15, 2022 at 01:44:46PM +0530, Sughosh Ganu wrote:
> > > > > The FWU Multi Bank Update feature supports updation of firmware images
> > > > > to one of multiple sets(also called banks) of images. The firmware
> > > > > images are clubbed together in banks, with the system booting images
> > > > > from the active bank. Information on the images such as which bank
> > > > > they belong to is stored as part of the metadata structure, which is
> > > > > stored on the same storage media as the firmware images on a dedicated
> > > > > partition.
> > > > >
> > > > > At the time of update, the metadata is read to identify the bank to
> > > > > which the images need to be flashed(update bank). On a successful
> > > > > update, the metadata is modified to set the updated bank as active
> > > > > bank to subsequently boot from.
> > > > >
> > > > > Signed-off-by: Sughosh Ganu 
> > > > > ---
> > > > > Changes since V9:
> > > > > * Move the global variables into local variables as suggested by
> > > > >   Ilias.
> > > > > * Change fwu_get_image_alt_num() name to fwu_get_image_image_index()
> > > >
> > > > -> typo? fwu_get_image_index()?
> > > >
> > > > >   as suggested by Takahiro.
> > > > > * Allow capsule updates to be called from efi_init_obj_list() with the
> > > > >   FWU feature enabled, as suggested by Takahiro.
> > > > > * Enable EFI_CAPSULE_ON_DISK_EARLY as an imply with the FWU feature
> > > > >   enabled.
> > > > > * Define the FWU feature related functions as __maybe_unused to allow
> > > > >   for compilation with the FWU feature disabled.
> > > > >
> > > > >  drivers/Kconfig  |   2 +
> > > > >  drivers/Makefile |   1 +
> > > > >  include/fwu.h|  30 +
> > > > >  lib/Kconfig  |   6 +
> > > > >  lib/Makefile |   1 +
> > > > >  lib/efi_loader/efi_capsule.c | 243 
> > > > > ++-
> > > > >  lib/fwu_updates/Kconfig  |  33 +
> > > > >  lib/fwu_updates/Makefile |   7 +
> > > > >  lib/fwu_updates/fwu.c|  23 
> > > > >  9 files changed, 340 insertions(+), 6 deletions(-)
> > > > >  create mode 100644 lib/fwu_updates/Kconfig
> > > > >  create mode 100644 lib/fwu_updates/Makefile
> > > > >
> 
> 
> 
> > > > >
> > > > >  /**
> > > > >   * efi_capsule_update_firmware - update firmware from capsule
> > > > > @@ -410,7 +544,35 @@ static efi_status_t efi_capsule_update_firmware(
> > > > >   int item;
> > > > >   struct efi_firmware_management_protocol *fmp;
> > > > >   u16 *abort_reason;
> > > > > + efi_guid_t image_type_id;
> > > > >   efi_status_t ret = EFI_SUCCESS;
> > > > > + int status;
> > > > > + u8 image_index;
> > > > > + u32 update_index;
> > > > > + bool fw_accept_os, image_index_check;
> > > > > +
> > > > > + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
> > > > > + if (!fwu_empty_capsule(capsule_data) &&
> > > > > + !fwu_update_checks_pass()) {
> > > > > + log_err("FWU checks failed. Cannot start 
> > > > > update\n");
> > > > > + return EFI_INVALID_PARAMETER;
> > > > > + }
> > > > > +
> > > > > + if (fwu_empty_capsule(capsule_data))
> > > > > + return fwu_empty_capsule_process(capsule_data);
> > > > > +
> > > > > + /* Obtain the update_index from the platform */
> > > > > + status = f

Re: [PATCH v10 10/15] FWU: Add support for the FWU Multi Bank Update feature

2022-09-16 Thread Takahiro Akashi
On Fri, Sep 16, 2022 at 10:52:11AM +0530, Sughosh Ganu wrote:
> () hi Takahiro,
> 
> On Fri, 16 Sept 2022 at 07:17, Takahiro Akashi
>  wrote:
> >
> > Hi Sughosh,
> >
> > On Thu, Sep 15, 2022 at 01:44:46PM +0530, Sughosh Ganu wrote:
> > > The FWU Multi Bank Update feature supports updation of firmware images
> > > to one of multiple sets(also called banks) of images. The firmware
> > > images are clubbed together in banks, with the system booting images
> > > from the active bank. Information on the images such as which bank
> > > they belong to is stored as part of the metadata structure, which is
> > > stored on the same storage media as the firmware images on a dedicated
> > > partition.
> > >
> > > At the time of update, the metadata is read to identify the bank to
> > > which the images need to be flashed(update bank). On a successful
> > > update, the metadata is modified to set the updated bank as active
> > > bank to subsequently boot from.
> > >
> > > Signed-off-by: Sughosh Ganu 
> > > ---
> > > Changes since V9:
> > > * Move the global variables into local variables as suggested by
> > >   Ilias.
> > > * Change fwu_get_image_alt_num() name to fwu_get_image_image_index()
> >
> > -> typo? fwu_get_image_index()?
> >
> > >   as suggested by Takahiro.
> > > * Allow capsule updates to be called from efi_init_obj_list() with the
> > >   FWU feature enabled, as suggested by Takahiro.
> > > * Enable EFI_CAPSULE_ON_DISK_EARLY as an imply with the FWU feature
> > >   enabled.
> > > * Define the FWU feature related functions as __maybe_unused to allow
> > >   for compilation with the FWU feature disabled.
> > >
> > >  drivers/Kconfig  |   2 +
> > >  drivers/Makefile |   1 +
> > >  include/fwu.h|  30 +
> > >  lib/Kconfig  |   6 +
> > >  lib/Makefile |   1 +
> > >  lib/efi_loader/efi_capsule.c | 243 ++-
> > >  lib/fwu_updates/Kconfig  |  33 +
> > >  lib/fwu_updates/Makefile |   7 +
> > >  lib/fwu_updates/fwu.c|  23 
> > >  9 files changed, 340 insertions(+), 6 deletions(-)
> > >  create mode 100644 lib/fwu_updates/Kconfig
> > >  create mode 100644 lib/fwu_updates/Makefile
> > >
> > > diff --git a/drivers/Kconfig b/drivers/Kconfig
> > > index 8b6fead351..75ac149d31 100644
> > > --- a/drivers/Kconfig
> > > +++ b/drivers/Kconfig
> > > @@ -44,6 +44,8 @@ source "drivers/fuzz/Kconfig"
> > >
> > >  source "drivers/fpga/Kconfig"
> > >
> > > +source "drivers/fwu-mdata/Kconfig"
> > > +
> > >  source "drivers/gpio/Kconfig"
> > >
> > >  source "drivers/hwspinlock/Kconfig"
> > > diff --git a/drivers/Makefile b/drivers/Makefile
> > > index eba9940231..af7ed7bdf3 100644
> > > --- a/drivers/Makefile
> > > +++ b/drivers/Makefile
> > > @@ -84,6 +84,7 @@ obj-y += cache/
> > >  obj-$(CONFIG_CPU) += cpu/
> > >  obj-y += crypto/
> > >  obj-$(CONFIG_FASTBOOT) += fastboot/
> > > +obj-$(CONFIG_FWU_MDATA) += fwu-mdata/
> > >  obj-y += misc/
> > >  obj-$(CONFIG_MMC) += mmc/
> > >  obj-$(CONFIG_NVME) += nvme/
> > > diff --git a/include/fwu.h b/include/fwu.h
> > > index d5f77ce83c..1d15ac98da 100644
> > > --- a/include/fwu.h
> > > +++ b/include/fwu.h
> > > @@ -60,6 +60,7 @@ struct fwu_mdata_ops {
> > >  };
> > >
> > >  #define FWU_MDATA_VERSION0x1
> > > +#define FWU_IMAGE_ACCEPTED   0x1
> > >
> > >  /*
> > >  * GUID value defined in the FWU specification for identification
> > > @@ -69,6 +70,24 @@ struct fwu_mdata_ops {
> > >   EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \
> > >0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23)
> > >
> > > +/*
> > > +* GUID value defined in the Dependable Boot specification for
> > > +* identification of the revert capsule, used for reverting
> > > +* any image in the updated bank.
> > > +*/
> > > +#define FWU_OS_REQUEST_FW_REVERT_GUID \
> > > + EFI_GUID(0xacd58b4b, 0xc0e8, 0x475f, 0x99, 0xb5, \
> > > +  0x6b, 0x3f, 0x7e, 0x07, 0xaa, 0xf0)
> > > +
> > > +/*
> > > +* GUID value defined in the Dependable Boot specification f

Re: [PATCH v10 10/15] FWU: Add support for the FWU Multi Bank Update feature

2022-09-15 Thread Takahiro Akashi
e_instance,
> -handles, no_handles);
> +handles, no_handles,
> +image_index_check);
>   if (!fmp) {
>   log_err("FMP driver not found for firmware type %pUs, 
> hardware instance %lld\n",
>   >update_image_type_id,
> @@ -485,8 +648,30 @@ static efi_status_t efi_capsule_update_firmware(
>   goto out;
>   }
>  
> + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
> + /*
> +  * Based on the value of update_image_type_id,
> +  * derive the image index value. This will be
> +  * passed as update_image_index to the
> +  * set_image function.
> +  */
> + image_type_id = image->update_image_type_id;
> + status = fwu_get_image_index(_type_id,
> +  update_index,
> +  _index);

AS I said in my comment to v9, this function should be moved in FMP driver,
that is, efi_firmware.c and contained in set_image().

You try to use different image_index's to distinguish A and B banks, but
this kind of usage is quite implementation-dependent since other firmware
framework may use a different approach to support multiple banks.

Please remember that, from the viewpoint of API, image_index must be unique
whether it is on A bank or B bank as it is used to identify a specific firmware 
image
within a device, not a "physical" location.

Please re-think.

-Takahiro Akashi


> + ret = fwu_to_efi_error(status);
> + if (ret != EFI_SUCCESS) {
> + log_err("Unable to get the Image Index for the 
> image type %pUs\n",
> + _type_id);
> + goto out;
> + }
> + log_debug("Image Index %u for Image Type Id %pUs\n",
> +   image_index, _type_id);
> + } else {
> + image_index = image->update_image_index;
> + }
>   abort_reason = NULL;
> - ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index,
> + ret = EFI_CALL(fmp->set_image(fmp, image_index,
> image_binary,
> image_binary_size,
> vendor_code, NULL,
> @@ -497,6 +682,33 @@ static efi_status_t efi_capsule_update_firmware(
>   efi_free_pool(abort_reason);
>   goto out;
>   }
> +
> + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
> + if (!fw_accept_os) {
> + /*
> +  * The OS will not be accepting the firmware
> +  * images. Set the accept bit of all the
> +  * images contained in this capsule.
> +  */
> + status = fwu_accept_image(_type_id,
> +   update_index);
> + } else {
> + status = fwu_clear_accept_image(_type_id,
> + update_index);
> + }
> + ret = fwu_to_efi_error(status);
> + if (ret != EFI_SUCCESS) {
> + log_err("Unable to %s the accept bit for the 
> image %pUs\n",
> + fw_accept_os ? "clear" : "set",
> + _type_id);
> + goto out;
> + }
> +
> + log_debug("%s the accepted bit for Image %pUs\n",
> +   fw_accept_os ? "Cleared" : "Set",
> +   _type_id);
> + }
> +
>   }
>  
>  out:
> @@ -1104,6 +1316,9 @@ efi_status_t efi_launch_capsules(void)
>   u16 **files;
>   unsigned int nfiles, index, i;
>   efi_status_t ret;
> + bool capsule_update = true;
> + bool update_status = true;
> + bool fw_accept_os = false;
>  
>   if (check_run_capsules() != EFI_SUCCESS)
>   return EFI_SUCCESS;
> @@ -1131,12 +1346,19 @@ efi_status_t

Re: [PATCH v9 10/15] FWU: Add support for the FWU Multi Bank Update feature

2022-09-07 Thread Takahiro Akashi
  /*
> +  * The OS will not be accepting the firmware
> +  * images. Set the accept bit of all the
> +  * images contained in this capsule.
> +  */
> + status = fwu_accept_image(_type_id,
> +   update_index);
> + } else {
> + status = fwu_clear_accept_image(_type_id,
> + update_index);
> + }
> + ret = fwu_to_efi_error(status);
> + if (ret != EFI_SUCCESS) {
> + log_err("Unable to %s the accept bit for the 
> image %pUs\n",
> + fw_accept_os ? "clear" : "set",
> + _type_id);
> + goto out;
> + }
> +
> + log_debug("%s the accepted bit for Image %pUs\n",
> +   fw_accept_os ? "Cleared" : "Set",
> +   _type_id);
> + }
> +
>   }
>  
>  out:
> @@ -1102,8 +1274,10 @@ efi_status_t efi_launch_capsules(void)
>  {
>   struct efi_capsule_header *capsule = NULL;
>   u16 **files;
> + int status;
>   unsigned int nfiles, index, i;
>   efi_status_t ret;
> + bool update_status = true;
>  
>   if (check_run_capsules() != EFI_SUCCESS)
>   return EFI_SUCCESS;
> @@ -1131,12 +1305,14 @@ efi_status_t efi_launch_capsules(void)
>   ret = efi_capsule_read_file(files[i], );
>   if (ret == EFI_SUCCESS) {
>   ret = efi_capsule_update_firmware(capsule);
> - if (ret != EFI_SUCCESS)
> + if (ret != EFI_SUCCESS) {
>   log_err("Applying capsule %ls failed.\n",
>   files[i]);
> - else
> + update_status = false;
> + } else {
>   log_info("Applying capsule %ls succeeded.\n",
>files[i]);
> + }
>  
>   /* create Capsule */
>   set_capsule_result(index, capsule, ret);
> @@ -1144,6 +1320,7 @@ efi_status_t efi_launch_capsules(void)
>   free(capsule);
>   } else {
>   log_err("Reading capsule %ls failed\n", files[i]);
> + update_status = false;
>   }
>   /* delete a capsule either in case of success or failure */
>   ret = efi_capsule_delete_file(files[i]);
> @@ -1151,7 +1328,33 @@ efi_status_t efi_launch_capsules(void)
>   log_err("Deleting capsule %ls failed\n",
>   files[i]);
>   }
> +
>   efi_capsule_scan_done();
> + if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
> + if (update_status == true && capsule_update == true) {
> + /*
> +  * All the capsules have been updated successfully,
> +  * update the FWU metadata.
> +  */
> + log_debug("Update Complete. Now updating active_index 
> to %u\n",
> +   update_index);
> + status = fwu_update_active_index(update_index);
> + ret = fwu_to_efi_error(status);
> + if (ret != EFI_SUCCESS) {
> + log_err("Failed to update FWU metadata index 
> values\n");
> + } else {
> + log_debug("Successfully updated the 
> active_index\n");
> + ret = EFI_SUCCESS;
> + if (fw_accept_os) {
> + status = fwu_trial_state_ctr_start();
> + if (status < 0)
> + ret = EFI_DEVICE_ERROR;
> + }
> + }
> + } else if (capsule_update == true && update_status == false) {
> + log_err("All capsules were not updated. Not updating 
> FWU metadata\n");
> + }
> + }
>  
>   for (i = 0; i < nfiles; i++)
>   

Re: [PATCH v16 10/10] test: unit test for eficonfig

2022-09-05 Thread Takahiro Akashi
On Mon, Sep 05, 2022 at 05:55:05PM +0200, Heinrich Schuchardt wrote:
> On 9/5/22 14:48, Masahisa Kojima wrote:
> > Provide a unit test for the eficonfig command.
> > 
> > Signed-off-by: Masahisa Kojima 
> > Acked-by: Ilias Apalodimas 
> > ---
> > Changes in v16:
> > - call u_boot_console.restart_uboot() to clean the previous test state
> 
> The test is still failing:
> https://source.denx.de/u-boot/custodians/u-boot-efi/-/jobs/492069/raw
> 
> The same can be seen when running 'make tests' locally.

Well, the screen shown in "Select File" seems to be different
from what the test expects to be seen: 
===
** Select File **

  initrd-2.img
  initrddump.efi
  initrd-1.img
  Quit
===
So, for instance,
# Press down key to select "initrd-1.img" entry followed by the enter 
key
press_up_down_enter_and_wait(0, 0, True, 'Quit')
will incorrectly select "initrd-2.img" instead of "initrd-1.img

-Takahiro Akashi

> Best regards
> 
> Heinrich
> 
> > 
> > Changes in v14:
> > - update to support media device enumeration in eficonfig startup
> > - move no block device test to the last test case
> > 
> > Changes in v12:
> > - update menu handling
> > 
> > Changes in v11:
> > - fix expected result when no BootOrder is defined
> > 
> > Newly added in v10
> > 
> >   configs/sandbox_defconfig |   1 +
> >   test/py/tests/test_eficonfig/conftest.py  |  40 ++
> >   .../py/tests/test_eficonfig/test_eficonfig.py | 354 ++
> >   3 files changed, 395 insertions(+)
> >   create mode 100644 test/py/tests/test_eficonfig/conftest.py
> >   create mode 100644 test/py/tests/test_eficonfig/test_eficonfig.py
> > 
> > diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
> > index eba7bcbb48..48c60c606d 100644
> > --- a/configs/sandbox_defconfig
> > +++ b/configs/sandbox_defconfig
> > @@ -93,6 +93,7 @@ CONFIG_CMD_LINK_LOCAL=y
> >   CONFIG_CMD_ETHSW=y
> >   CONFIG_CMD_BMP=y
> >   CONFIG_CMD_BOOTCOUNT=y
> > +CONFIG_CMD_EFICONFIG=y
> >   CONFIG_CMD_EFIDEBUG=y
> >   CONFIG_CMD_RTC=y
> >   CONFIG_CMD_TIME=y
> > diff --git a/test/py/tests/test_eficonfig/conftest.py 
> > b/test/py/tests/test_eficonfig/conftest.py
> > new file mode 100644
> > index 00..f289df0362
> > --- /dev/null
> > +++ b/test/py/tests/test_eficonfig/conftest.py
> > @@ -0,0 +1,40 @@
> > +# SPDX-License-Identifier:  GPL-2.0+
> > +
> > +"""Fixture for UEFI eficonfig test
> > +"""
> > +
> > +import os
> > +import shutil
> > +from subprocess import check_call
> > +import pytest
> > +
> > +@pytest.fixture(scope='session')
> > +def efi_eficonfig_data(u_boot_config):
> > +"""Set up a file system to be used in UEFI "eficonfig" command
> > +   tests
> > +
> > +Args:
> > +u_boot_config -- U-boot configuration.
> > +
> > +Return:
> > +A path to disk image to be used for testing
> > +"""
> > +mnt_point = u_boot_config.persistent_data_dir + '/test_efi_eficonfig'
> > +image_path = u_boot_config.persistent_data_dir + '/efi_eficonfig.img'
> > +
> > +shutil.rmtree(mnt_point, ignore_errors=True)
> > +os.mkdir(mnt_point, mode = 0o755)
> > +
> > +with open(mnt_point + '/initrd-1.img', 'w', encoding = 'ascii') as 
> > file:
> > +file.write("initrd 1")
> > +
> > +with open(mnt_point + '/initrd-2.img', 'w', encoding = 'ascii') as 
> > file:
> > +file.write("initrd 2")
> > +
> > +shutil.copyfile(u_boot_config.build_dir + 
> > '/lib/efi_loader/initrddump.efi',
> > +mnt_point + '/initrddump.efi')
> > +
> > +check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat 
> > {mnt_point} {image_path}',
> > +   shell=True)
> > +
> > +return image_path
> > diff --git a/test/py/tests/test_eficonfig/test_eficonfig.py 
> > b/test/py/tests/test_eficonfig/test_eficonfig.py
> > new file mode 100644
> > index 00..c1fe07eb8b
> > --- /dev/null
> > +++ b/test/py/tests/test_eficonfig/test_eficonfig.py
> > @@ -0,0 +1,354 @@
> > +# SPDX-License-Identifier:  GPL-2.0+
> > +""" Unit test for UEFI menu-driven configuration
> > +"""
> > +
> > +import pytest
> > +import time
> > +
> > +@pytest.mark.boardspe

Re: [PATCH v13 6/9] eficonfig: add "Change Boot Order" menu entry

2022-08-24 Thread Takahiro Akashi
On Wed, Aug 24, 2022 at 03:37:37PM +0900, Masahisa Kojima wrote:
> This commit adds the menu entry to update UEFI BootOrder variable.
> User moves the entry with UP/DOWN key, changes the order
> with PLUS/MINUS key, press SPACE to activate or deactivate
> the entry, then finalizes the order by ENTER key.
> If the entry is activated, the boot index is added into the
> BootOrder variable in the order of the list.
> 
> The U-Boot menu framework is well designed for static menu,
> this commit implements the own menu display and key handling
> for dynamically change the order of menu entry.
> 
> Signed-off-by: Masahisa Kojima 
> ---
> No update since v12

Well, a minor issue.
When BootOrder is not defined, nothing happens by selecting
"Change Boot Order". For "Edit" or "Delete Boot Option", however,
it causes a menu transition and shows something like:
** Select Boot Option **

  Quit

even if no applicable option is available.

I hope a consistent behavior for "Change Boot Order" as well,
or printing some error message will be better.

-Takahiro Akashi

> Changes in v12:
> - enumerate removable media device
> 
> Changes in v11:
> - remove BootOrder variable dependency
> - use ANSI_CURSOR_POSITION and ANSI_CLEAR_LINE instead of printf("\n")
>   since current eficonfig implementation does not handle console size 
> correctly.
>   printf("\n") at the outside of console size breaks the console output.
> - add KEY_SPACE to toggle the boot option active status
> 
> No update since v9
> 
> Changes in v9:
> - add function comment
> 
> Changes in v8:
> - add "Save" and "Quit" entries
> 
> Changes in v7:
> - use UP/DOWN and PLUS/MINUS key to change to order
> 
> no update in v6:
> 
>  cmd/eficonfig.c | 351 +++-
>  1 file changed, 350 insertions(+), 1 deletion(-)
> 
> diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
> index 92171c4894..0922115138 100644
> --- a/cmd/eficonfig.c
> +++ b/cmd/eficonfig.c
> @@ -91,6 +91,23 @@ struct eficonfig_boot_selection_data {
>   int *selected;
>  };
>  
> +/**
> + * struct eficonfig_boot_order - structure to be used to update BootOrder 
> variable
> + *
> + * @num: index in the menu entry
> + * @description: pointer to the description string
> + * @boot_index:  boot option index
> + * @active:  flag to include the boot option into BootOrder variable
> + * @list:list structure
> + */
> +struct eficonfig_boot_order {
> + u32 num;
> + u16 *description;
> + u32 boot_index;
> + bool active;
> + struct list_head list;
> +};
> +
>  /**
>   * eficonfig_print_msg() - print message
>   *
> @@ -1716,6 +1733,338 @@ out:
>   return ret;
>  }
>  
> +/**
> + * eficonfig_display_change_boot_order() - display the BootOrder list
> + *
> + * @efi_menu:pointer to the efimenu structure
> + * Return:   status code
> + */
> +static void eficonfig_display_change_boot_order(struct efimenu *efi_menu)
> +{
> + bool reverse;
> + struct list_head *pos, *n;
> + struct eficonfig_boot_order *entry;
> +
> + printf(ANSI_CLEAR_CONSOLE ANSI_CURSOR_POSITION
> +"\n  ** Change Boot Order **\n"
> +ANSI_CURSOR_POSITION
> +"  Press UP/DOWN to move, +/- to change order"
> +ANSI_CURSOR_POSITION
> +"  Press SPACE to activate or deactivate the entry"
> +ANSI_CURSOR_POSITION
> +"  Select [Save] to complete, ESC/CTRL+C to quit"
> +ANSI_CURSOR_POSITION ANSI_CLEAR_LINE,
> +1, 1, efi_menu->count + 5, 1, efi_menu->count + 6, 1,
> +efi_menu->count + 7, 1,  efi_menu->count + 8, 1);
> +
> + /* draw boot option list */
> + list_for_each_safe(pos, n, _menu->list) {
> + entry = list_entry(pos, struct eficonfig_boot_order, list);
> + reverse = (entry->num == efi_menu->active);
> +
> + printf(ANSI_CURSOR_POSITION, entry->num + 4, 7);
> +
> + if (reverse)
> + puts(ANSI_COLOR_REVERSE);
> +
> + if (entry->num < efi_menu->count - 2) {
> + if (entry->active)
> + printf("[*]  ");
> + else
> + printf("[ ]  ");
> + }
> +
> + printf("%ls", entry->description);
> +
> + if (reverse)
> + puts(ANSI

Re: [PATCH v11 6/9] bootmenu: add removable media entries

2022-08-23 Thread Takahiro Akashi
On Fri, Aug 19, 2022 at 12:05:50PM +0900, Masahisa Kojima wrote:
> Hi Akashi-san,
> 
> On Fri, 19 Aug 2022 at 10:31, Takahiro Akashi
>  wrote:
> >
> > On Wed, Aug 17, 2022 at 06:36:11PM +0900, Masahisa Kojima wrote:
> > > UEFI specification requires booting from removal media using
> > > a architecture-specific default image name such as BOOTAA64.EFI.
> > > This commit adds the removable media entries into bootmenu,
> > > so that user can select the removable media and boot with
> > > default image.
> > >
> > > The bootmenu automatically enumerates the possible bootable
> > > media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL,
> > > add it as new UEFI boot option(BOOT) and update BootOrder
> > > variable. This automatically generated UEFI boot option
> >
> > Should this feature belong to bootmenu command?
> > Under the current implementation, those boot options are
> > generated only by bootmenu, and so if eficonfig is invoked
> > prior to bootmenu, we won't see them (under "Change Boot Order").
> >
> > I expect that the functionality be also provided in eficonfig
> > (or even as part of system initialization?).
> 
> OK, generating the (removable) media boot options will be added
> in "Change Boot Order".

I found another wrong behavior. What I did was
- eficonfig
  it shows no boot options.
- scsi rescan
  One disk with two partitions was detected.
- eficonfig
  Now it shows two options for removal media.
  I disabled one of two partitions from BootOrder.
- bootmenu
  It still shows both boot options. -> Probably okay?
- eficonfig
  Then a duplicated option comes up:
  ** Change Boot Order **

    [*]  scsi 0:1
[*]  scsi 0:2
[ ]  scsi 0:2
Save
Quit

Internally there exist three boot options now.

-Takahiro Akashi

> Thanks,
> Masahisa Kojima
> 
> >
> > -Takahiro Akashi
> >
> >
> > > has the dedicated guid in the optional_data to distinguish it from
> > > the UEFI boot option user adds manually. This optional_data is
> > > removed when the efi bootmgr loads the selected UEFI boot option.
> > >
> > > This commit also provides the BOOT variable maintenance feature.
> > > Depending on the system hardware setup, some devices
> > > may not exist at a later system boot, so bootmenu checks the
> > > available device in each bootmenu invocation and automatically
> > > removes the BOOT variable corrensponding to the non-existent
> > > media device.
> > >
> > > Signed-off-by: Masahisa Kojima 
> > > ---
> > > Changes in v11:
> > > - update delete_boot_option() parameter
> > >
> > > Changes in v10:
> > > - add function comment
> > > - devname dynamic allocation removes, allocate in stack
> > > - delete BOOT when updating BootOrder fails
> > >
> > > Changes in v9:
> > > - update efi_disk_get_device_name() parameter to pass efi_handle_t
> > > - add function comment
> > >
> > > Changes in v8:
> > > - function and structure prefix is changed to "eficonfig"
> > >
> > > Changes in v7:
> > > - rename prepare_media_device_entry() to 
> > > generate_media_device_boot_option()
> > >
> > > Changes in v6:
> > > - optional_data size is changed to 16bytes
> > > - check the load option size before comparison
> > > - remove guid included in optional_data of auto generated
> > >   entry when loading
> > >
> > > Changes in v5:
> > > - Return EFI_SUCCESS if there is no BootOrder defined
> > > - correctly handle the case if no removable device found
> > > - use guid to identify the automatically generated entry by bootmenu
> > >
> > >  cmd/bootmenu.c   | 106 +--
> > >  cmd/eficonfig.c  | 135 +++
> > >  include/efi_loader.h |  20 ++
> > >  lib/efi_loader/efi_bootmgr.c |   4 ++
> > >  4 files changed, 260 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
> > > index 704d36debe..04df41a0cb 100644
> > > --- a/cmd/bootmenu.c
> > > +++ b/cmd/bootmenu.c
> > > @@ -220,7 +220,93 @@ static int prepare_bootmenu_entry(struct 
> > > bootmenu_data *menu,
> > >   return 1;
> > >  }
> > >
> > > -#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR))
> > > +#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR))

Re: [PATCH v11 8/9] doc:eficonfig: add documentation for eficonfig command

2022-08-19 Thread Takahiro Akashi
On Fri, Aug 19, 2022 at 03:15:09PM +0900, Masahisa Kojima wrote:
> Hi Akashi-san,
> 
> On Fri, 19 Aug 2022 at 14:57, Takahiro Akashi
>  wrote:
> >
> > On Wed, Aug 17, 2022 at 06:36:13PM +0900, Masahisa Kojima wrote:
> > > Add documentation for eficonfig command.
> > >
> > > Signed-off-by: Masahisa Kojima 
> > > ---
> > > No update since v10
> > >
> > > Changes in v10:
> > > - describe how to boot system after editting by eficonfig
> > >
> > > Changes in v8:
> > > - command name is changed from "efimenu" to "eficonfig"
> > >
> > > Newly created in v7
> > >
> > >  doc/usage/cmd/eficonfig.rst | 63 +
> > >  doc/usage/index.rst |  1 +
> > >  2 files changed, 64 insertions(+)
> > >  create mode 100644 doc/usage/cmd/eficonfig.rst
> > >
> > > diff --git a/doc/usage/cmd/eficonfig.rst b/doc/usage/cmd/eficonfig.rst
> > > new file mode 100644
> > > index 00..958e96992c
> > > --- /dev/null
> > > +++ b/doc/usage/cmd/eficonfig.rst
> > > @@ -0,0 +1,63 @@
> > > +.. SPDX-License-Identifier: GPL-2.0+
> > > +.. (C) Copyright 2022, Masahisa Kojima 
> > > +
> > > +eficonfig command
> > > +=
> > > +
> > > +Synopsis
> > > +
> > > +::
> > > +
> > > +eficonfig
> > > +
> > > +Description
> > > +---
> > > +
> > > +The "eficonfig" command uses U-Boot menu interface and privides
> > > +a menu-driven UEFI variable maintenance feature.
> > > +The "eficonfig" has the following menu entries.
> > > +
> > > +Add Boot Option
> > > +Add new UEFI Boot Option.
> > > +User can edit description, file path, and optional_data.
> > > +
> > > +Edit Boot Option
> > > +Edit the existing UEFI Boot Option
> > > +User can edit description, file path, and optional_data.
> > > +
> > > +Change Boot Order
> > > +Change the order of UEFI BootOrder variable.
> > > +
> > > +Delete Boot Option
> > > +Delete the UEFI Boot Option
> > > +
> > > +Configuration
> > > +-
> > > +
> > > +The "eficonfig" command is enabled by::
> > > +
> > > +CONFIG_CMD_EFICONFIG=y
> > > +
> > > +If CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is enabled, user can not enter
> > > +U-Boot console. In this case, bootmenu can be used to invoke 
> > > "eficonfig"::
> > > +
> > > +CONFIG_USE_PREBOOT=y
> > > +CONFIG_PREBOOT="setenv bootmenu_0 UEFI Maintenance Menu=eficonfig"
> > > +
> > > +How to boot the system with newly added UEFI Boot Option
> > > +
> > > +
> > > +"eficonfig" command is responsible to configure the UEFI variables,
> > > +not directly handle the system boot.
> > > +The new Boot Option added by "eficonfig" is appended at the last entry
> > > +of UEFI BootOrder variable, user may want to change the boot order
> > > +through "Change Boot Order".
> > > +If the bootmenu is enabled and "eficonfig" is configured as preboot 
> > > command,
> > > +the newly added Boot Options are enumerated in the bootmenu when user 
> > > exits
> > > +from the eficonfig menu.
> >
> > Right, and when user quits from eficonfig, bootmenu also quits.
> > *If possible*, I expect that we return to bootmenu's screen
> > directly for better user-experience :)
> >
> > Otherwise, we have to enable U-Boot console to re-invoke
> > bootmenu. (we can instead reboot U-Boot, though.)
> 
> If CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is enabled, bootmenu appears
> again when user quits from eficonfig.

Ah, okay but why not always enable this behavior on?

-Takahiro Akashi

> I need to describe this condition in the document.
> 
> Thanks,
> Masahisa Kojima
> 
> >
> > -Takahiro Akashi
> >
> > > +User may select the entry in the bootmenu to boot the system, or follow
> > > +the U-Boot configuration the system already has.
> > > +
> > > +See also
> > > +
> > > +* :doc:`bootmenu` provides a simple mechanism for creating 
> > > menus with different boot items
> > > diff --git a/doc/usage/index.rst b/doc/usage/index.rst
> > > index 28f9683a3e..09f2928970 100644
> > > --- a/doc/usage/index.rst
> > > +++ b/doc/usage/index.rst
> > > @@ -35,6 +35,7 @@ Shell commands
> > > cmd/conitrace
> > > cmd/dm
> > > cmd/echo
> > > +   cmd/eficonfig
> > > cmd/env
> > > cmd/event
> > > cmd/exception
> > > --
> > > 2.17.1
> > >


Re: [PATCH v11 8/9] doc:eficonfig: add documentation for eficonfig command

2022-08-18 Thread Takahiro Akashi
On Wed, Aug 17, 2022 at 06:36:13PM +0900, Masahisa Kojima wrote:
> Add documentation for eficonfig command.
> 
> Signed-off-by: Masahisa Kojima 
> ---
> No update since v10
> 
> Changes in v10:
> - describe how to boot system after editting by eficonfig
> 
> Changes in v8:
> - command name is changed from "efimenu" to "eficonfig"
> 
> Newly created in v7
> 
>  doc/usage/cmd/eficonfig.rst | 63 +
>  doc/usage/index.rst |  1 +
>  2 files changed, 64 insertions(+)
>  create mode 100644 doc/usage/cmd/eficonfig.rst
> 
> diff --git a/doc/usage/cmd/eficonfig.rst b/doc/usage/cmd/eficonfig.rst
> new file mode 100644
> index 00..958e96992c
> --- /dev/null
> +++ b/doc/usage/cmd/eficonfig.rst
> @@ -0,0 +1,63 @@
> +.. SPDX-License-Identifier: GPL-2.0+
> +.. (C) Copyright 2022, Masahisa Kojima 
> +
> +eficonfig command
> +=
> +
> +Synopsis
> +
> +::
> +
> +eficonfig
> +
> +Description
> +---
> +
> +The "eficonfig" command uses U-Boot menu interface and privides
> +a menu-driven UEFI variable maintenance feature.
> +The "eficonfig" has the following menu entries.
> +
> +Add Boot Option
> +Add new UEFI Boot Option.
> +User can edit description, file path, and optional_data.
> +
> +Edit Boot Option
> +Edit the existing UEFI Boot Option
> +User can edit description, file path, and optional_data.
> +
> +Change Boot Order
> +Change the order of UEFI BootOrder variable.
> +
> +Delete Boot Option
> +Delete the UEFI Boot Option
> +
> +Configuration
> +-
> +
> +The "eficonfig" command is enabled by::
> +
> +CONFIG_CMD_EFICONFIG=y
> +
> +If CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is enabled, user can not enter
> +U-Boot console. In this case, bootmenu can be used to invoke "eficonfig"::
> +
> +CONFIG_USE_PREBOOT=y
> +CONFIG_PREBOOT="setenv bootmenu_0 UEFI Maintenance Menu=eficonfig"
> +
> +How to boot the system with newly added UEFI Boot Option
> +
> +
> +"eficonfig" command is responsible to configure the UEFI variables,
> +not directly handle the system boot.
> +The new Boot Option added by "eficonfig" is appended at the last entry
> +of UEFI BootOrder variable, user may want to change the boot order
> +through "Change Boot Order".
> +If the bootmenu is enabled and "eficonfig" is configured as preboot command,
> +the newly added Boot Options are enumerated in the bootmenu when user exits
> +from the eficonfig menu.

Right, and when user quits from eficonfig, bootmenu also quits.
*If possible*, I expect that we return to bootmenu's screen
directly for better user-experience :)

Otherwise, we have to enable U-Boot console to re-invoke
bootmenu. (we can instead reboot U-Boot, though.)

-Takahiro Akashi

> +User may select the entry in the bootmenu to boot the system, or follow
> +the U-Boot configuration the system already has.
> +
> +See also
> +
> +* :doc:`bootmenu` provides a simple mechanism for creating menus 
> with different boot items
> diff --git a/doc/usage/index.rst b/doc/usage/index.rst
> index 28f9683a3e..09f2928970 100644
> --- a/doc/usage/index.rst
> +++ b/doc/usage/index.rst
> @@ -35,6 +35,7 @@ Shell commands
> cmd/conitrace
> cmd/dm
> cmd/echo
> +   cmd/eficonfig
> cmd/env
> cmd/event
> cmd/exception
> -- 
> 2.17.1
> 


Re: [PATCH v11 6/9] bootmenu: add removable media entries

2022-08-18 Thread Takahiro Akashi
On Wed, Aug 17, 2022 at 06:36:11PM +0900, Masahisa Kojima wrote:
> UEFI specification requires booting from removal media using
> a architecture-specific default image name such as BOOTAA64.EFI.
> This commit adds the removable media entries into bootmenu,
> so that user can select the removable media and boot with
> default image.
> 
> The bootmenu automatically enumerates the possible bootable
> media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL,
> add it as new UEFI boot option(BOOT) and update BootOrder
> variable. This automatically generated UEFI boot option

Should this feature belong to bootmenu command?
Under the current implementation, those boot options are
generated only by bootmenu, and so if eficonfig is invoked
prior to bootmenu, we won't see them (under "Change Boot Order").

I expect that the functionality be also provided in eficonfig
(or even as part of system initialization?).

-Takahiro Akashi


> has the dedicated guid in the optional_data to distinguish it from
> the UEFI boot option user adds manually. This optional_data is
> removed when the efi bootmgr loads the selected UEFI boot option.
> 
> This commit also provides the BOOT variable maintenance feature.
> Depending on the system hardware setup, some devices
> may not exist at a later system boot, so bootmenu checks the
> available device in each bootmenu invocation and automatically
> removes the BOOT variable corrensponding to the non-existent
> media device.
> 
> Signed-off-by: Masahisa Kojima 
> ---
> Changes in v11:
> - update delete_boot_option() parameter
> 
> Changes in v10:
> - add function comment
> - devname dynamic allocation removes, allocate in stack
> - delete BOOT when updating BootOrder fails
> 
> Changes in v9:
> - update efi_disk_get_device_name() parameter to pass efi_handle_t
> - add function comment
> 
> Changes in v8:
> - function and structure prefix is changed to "eficonfig"
> 
> Changes in v7:
> - rename prepare_media_device_entry() to generate_media_device_boot_option()
> 
> Changes in v6:
> - optional_data size is changed to 16bytes
> - check the load option size before comparison
> - remove guid included in optional_data of auto generated
>   entry when loading
> 
> Changes in v5:
> - Return EFI_SUCCESS if there is no BootOrder defined
> - correctly handle the case if no removable device found
> - use guid to identify the automatically generated entry by bootmenu
> 
>  cmd/bootmenu.c   | 106 +--
>  cmd/eficonfig.c  | 135 +++
>  include/efi_loader.h |  20 ++
>  lib/efi_loader/efi_bootmgr.c |   4 ++
>  4 files changed, 260 insertions(+), 5 deletions(-)
> 
> diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
> index 704d36debe..04df41a0cb 100644
> --- a/cmd/bootmenu.c
> +++ b/cmd/bootmenu.c
> @@ -220,7 +220,93 @@ static int prepare_bootmenu_entry(struct bootmenu_data 
> *menu,
>   return 1;
>  }
>  
> -#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR))
> +#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) && 
> (CONFIG_IS_ENABLED(CMD_EFICONFIG))
> +/**
> + * generate_media_device_boot_option() - generate the media device boot 
> option
> + *
> + * This function enumerates all devices supporting 
> EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
> + * and generate the bootmenu entries.
> + * This function also provide the BOOT variable maintenance for
> + * the media device entries.
> + *   - Automatically create the BOOT variable for the newly detected 
> device,
> + * this BOOT variable is distinguished by the special GUID
> + * stored in the EFI_LOAD_OPTION.optional_data
> + *   - If the device is not attached to the system, the associated BOOT 
> variable
> + * is automatically deleted.
> + *
> + * Return:   status code
> + */
> +static efi_status_t generate_media_device_boot_option(void)
> +{
> + u32 i;
> + efi_status_t ret;
> + efi_uintn_t count;
> + efi_handle_t *volume_handles = NULL;
> + struct eficonfig_media_boot_option *opt = NULL;
> +
> + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, 
> _simple_file_system_protocol_guid,
> +NULL, , (efi_handle_t 
> **)_handles);
> + if (ret != EFI_SUCCESS)
> + return ret;
> +
> + opt = calloc(count, sizeof(struct eficonfig_media_boot_option));
> + if (!opt)
> + goto out;
> +
> + /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */
> + ret = eficonfig_enumerate_boot_option(opt, volume_handles, count);
> + if (ret != EFI_SUCCESS)
> + go

Re: [PATCH v10 00/10] enable menu-driven UEFI variable maintenance

2022-07-26 Thread Takahiro Akashi
On Wed, Jul 27, 2022 at 10:08:00AM +0900, Takahiro Akashi wrote:
> On Fri, Jul 22, 2022 at 11:45:49AM +0300, Ilias Apalodimas wrote:
> > Hi Kojima-san,
> > 
> > On Fri, 22 Jul 2022 at 05:36, Masahisa Kojima
> >  wrote:
> > >
> > > This series adds the menu-driven UEFI boot variable maintenance
> > > through the "eficonfig" new command.
> > > This series also adds the removable media support in bootmenu.
> > >
> > > Initrd file selection and python based unit test are added in v10.
> > >
> > > Source code can be cloned with:
> > > $ git clone https://git.linaro.org/people/masahisa.kojima/u-boot.git -b 
> > > eficonfig_upstream_v10
> > >
> > > [Major Changes]
> > > - rebased v2022.07
> > > - add initrd file selection
> > 
> > I tried to load an initrd, which on typical distros is not part of the
> > ESP.  While
> > => ls virtio 0:2
> > 
> > reads the filesystem contents fine, whenI try to navigate to that
> > virtio (and ext4 filesystem) device through the menu I am getting:
> > "Reading volume failed!"
> > 
> > Any ideas?
> 
> eficonfig_select_file()
>   efi_file_open_int()
> file_open()
>   exists = fs_exists(fh->path);
>   ...
> 
> It seems that fat and ext4 work in a different way against a *directory* here.
> For instance, try this both on fat and ext4
> ("test -e" internally uses fs_exists().)
> => test -e virtio X:Y /
> => echo $?
> 
> I think eficonfig_select_file() can be rewritten with 
> fs_opendir()/fs_readdir().

Correction:
Not all file systems support fs_opendir/fs_readdir interfaces, so this is not
a viable solution in general.
(Please note that UEFI spec says nothing about file systems other than fat, 
though.)

-Takahiro Akashi

> (Or much more preferably, efi_open(), and essentially fs_exists(), should be 
> fixed.)
> 
> -Takahiro Akashi
> 
> > Regards
> > /Ilias
> > > - add python based unit test
> > > - there is detailed changelog in each commit
> > >
> > > Masahisa Kojima (10):
> > >   efi_loader: move udevice pointer into struct efi_object
> > >   eficonfig: menu-driven addition of UEFI boot option
> > >   eficonfig: add "Edit Boot Option" menu entry
> > >   menu: add KEY_PLUS and KEY_MINUS handling
> > >   eficonfig: add "Change Boot Order" menu entry
> > >   eficonfig: add "Delete Boot Option" menu entry
> > >   bootmenu: add removable media entries
> > >   doc:bootmenu: add description for UEFI boot support
> > >   doc:eficonfig: add documentation for eficonfig command
> > >   test: unit test for eficonfig
> > >
> > >  cmd/Kconfig   |7 +
> > >  cmd/Makefile  |1 +
> > >  cmd/bootmenu.c|  106 +-
> > >  cmd/eficonfig.c   | 2103 +
> > >  common/menu.c |6 +
> > >  configs/sandbox_defconfig |1 +
> > >  doc/usage/cmd/bootmenu.rst|   74 +
> > >  doc/usage/cmd/eficonfig.rst   |   63 +
> > >  doc/usage/index.rst   |1 +
> > >  include/efi_config.h  |   91 +
> > >  include/efi_loader.h  |   67 +
> > >  include/menu.h|2 +
> > >  lib/efi_driver/efi_block_device.c |3 +-
> > >  lib/efi_loader/efi_bootmgr.c  |7 +
> > >  lib/efi_loader/efi_boottime.c |   52 +-
> > >  lib/efi_loader/efi_console.c  |   70 +
> > >  lib/efi_loader/efi_disk.c |   65 +-
> > >  lib/efi_loader/efi_file.c |   75 +-
> > >  lib/efi_loader/efi_helper.c   |   13 +
> > >  test/py/tests/test_eficonfig/conftest.py  |   40 +
> > >  .../py/tests/test_eficonfig/test_eficonfig.py |  325 +++
> > >  21 files changed, 3109 insertions(+), 63 deletions(-)
> > >  create mode 100644 cmd/eficonfig.c
> > >  create mode 100644 doc/usage/cmd/eficonfig.rst
> > >  create mode 100644 include/efi_config.h
> > >  create mode 100644 test/py/tests/test_eficonfig/conftest.py
> > >  create mode 100644 test/py/tests/test_eficonfig/test_eficonfig.py
> > >
> > > --
> > > 2.17.1
> > >


Re: [PATCH v10 00/10] enable menu-driven UEFI variable maintenance

2022-07-26 Thread Takahiro Akashi
On Fri, Jul 22, 2022 at 11:45:49AM +0300, Ilias Apalodimas wrote:
> Hi Kojima-san,
> 
> On Fri, 22 Jul 2022 at 05:36, Masahisa Kojima
>  wrote:
> >
> > This series adds the menu-driven UEFI boot variable maintenance
> > through the "eficonfig" new command.
> > This series also adds the removable media support in bootmenu.
> >
> > Initrd file selection and python based unit test are added in v10.
> >
> > Source code can be cloned with:
> > $ git clone https://git.linaro.org/people/masahisa.kojima/u-boot.git -b 
> > eficonfig_upstream_v10
> >
> > [Major Changes]
> > - rebased v2022.07
> > - add initrd file selection
> 
> I tried to load an initrd, which on typical distros is not part of the
> ESP.  While
> => ls virtio 0:2
> 
> reads the filesystem contents fine, whenI try to navigate to that
> virtio (and ext4 filesystem) device through the menu I am getting:
> "Reading volume failed!"
> 
> Any ideas?

eficonfig_select_file()
  efi_file_open_int()
file_open()
  exists = fs_exists(fh->path);
  ...

It seems that fat and ext4 work in a different way against a *directory* here.
For instance, try this both on fat and ext4
("test -e" internally uses fs_exists().)
=> test -e virtio X:Y /
=> echo $?

I think eficonfig_select_file() can be rewritten with fs_opendir()/fs_readdir().
(Or much more preferably, efi_open(), and essentially fs_exists(), should be 
fixed.)

-Takahiro Akashi

> Regards
> /Ilias
> > - add python based unit test
> > - there is detailed changelog in each commit
> >
> > Masahisa Kojima (10):
> >   efi_loader: move udevice pointer into struct efi_object
> >   eficonfig: menu-driven addition of UEFI boot option
> >   eficonfig: add "Edit Boot Option" menu entry
> >   menu: add KEY_PLUS and KEY_MINUS handling
> >   eficonfig: add "Change Boot Order" menu entry
> >   eficonfig: add "Delete Boot Option" menu entry
> >   bootmenu: add removable media entries
> >   doc:bootmenu: add description for UEFI boot support
> >   doc:eficonfig: add documentation for eficonfig command
> >   test: unit test for eficonfig
> >
> >  cmd/Kconfig   |7 +
> >  cmd/Makefile  |1 +
> >  cmd/bootmenu.c|  106 +-
> >  cmd/eficonfig.c   | 2103 +
> >  common/menu.c |6 +
> >  configs/sandbox_defconfig |1 +
> >  doc/usage/cmd/bootmenu.rst|   74 +
> >  doc/usage/cmd/eficonfig.rst   |   63 +
> >  doc/usage/index.rst   |1 +
> >  include/efi_config.h  |   91 +
> >  include/efi_loader.h  |   67 +
> >  include/menu.h|2 +
> >  lib/efi_driver/efi_block_device.c |3 +-
> >  lib/efi_loader/efi_bootmgr.c  |7 +
> >  lib/efi_loader/efi_boottime.c |   52 +-
> >  lib/efi_loader/efi_console.c  |   70 +
> >  lib/efi_loader/efi_disk.c |   65 +-
> >  lib/efi_loader/efi_file.c |   75 +-
> >  lib/efi_loader/efi_helper.c   |   13 +
> >  test/py/tests/test_eficonfig/conftest.py  |   40 +
> >  .../py/tests/test_eficonfig/test_eficonfig.py |  325 +++
> >  21 files changed, 3109 insertions(+), 63 deletions(-)
> >  create mode 100644 cmd/eficonfig.c
> >  create mode 100644 doc/usage/cmd/eficonfig.rst
> >  create mode 100644 include/efi_config.h
> >  create mode 100644 test/py/tests/test_eficonfig/conftest.py
> >  create mode 100644 test/py/tests/test_eficonfig/test_eficonfig.py
> >
> > --
> > 2.17.1
> >


Re: [RESEND v9 1/9] efi_loader: move udevice pointer into struct efi_object

2022-07-21 Thread Takahiro Akashi
On Wed, Jul 20, 2022 at 09:44:43AM +0200, Heinrich Schuchardt wrote:
> On 7/20/22 01:56, Takahiro Akashi wrote:
> > On Sun, Jul 17, 2022 at 10:09:42AM +0200, Heinrich Schuchardt wrote:
> > > On 7/15/22 16:47, Masahisa Kojima wrote:
> > > > This is a preparation patch to provide the unified method
> > > > to access udevice pointer associated with the block io device.
> > > > The EFI handles of both EFI block io driver implemented in
> > > > lib/efi_loader/efi_disk.c and EFI block io driver implemented
> > > > as EFI payload can posess the udevice pointer in the struct efi_object.
> > > > 
> > > > We can use this udevice pointer to get the U-Boot friendly
> > > > block device name(e.g. mmc 0:1, nvme 0:1) through efi_handle_t.
> > > > 
> > > > Signed-off-by: Masahisa Kojima 
> > > > ---
> > > > Newly created in v9
> > > > 
> > > >include/efi_loader.h  |  8 
> > > >lib/efi_loader/efi_disk.c | 20 +---
> > > >2 files changed, 21 insertions(+), 7 deletions(-)
> > > > 
> > > > diff --git a/include/efi_loader.h b/include/efi_loader.h
> > > > index 3a63a1f75f..bba5ffd482 100644
> > > > --- a/include/efi_loader.h
> > > > +++ b/include/efi_loader.h
> > > > @@ -226,6 +226,12 @@ const char *__efi_nesting_dec(void);
> > > >#define EFI_CACHELINE_SIZE 128
> > > >#endif
> > > > 
> > > > +/**
> > > > + * efi_handle_to_udev - accessor to the DM device associated to the 
> > > > EFI handle
> > > > + * @handle:pointer to the EFI handle
> > > > + */
> > > > +#define efi_handle_to_udev(handle) (((struct efi_object *)handle)->dev)
> > > 
> > > This conversion will hide errors if handle is not of type efi_handle_t.
> > > We should avoid the conversion and see build time errors instead.
> > > Please, remove the macro.
> > 
> > I don't think we should remove the macro itself, but only the type casting.
> > 
> > I think it is a good practice to hide an implementation how the relationship
> > between udev and efi_object is maintained *behind* accessor macros.
> > 
> > > For every handle of type efi_handle_t you can access the field
> > > handle->dev directly.
> > > 
> > > For struct efi_disk_obj we can use disk->header.dev.
> > 
> > This is a good example for hiding the implementation from the rest of code.
> 
> Such a macro is pure code obfuscation.

I don't think so. It will help make it easier to read the code.

If I follow your logic, why did you introduce/accept guidcpy/guidcmp()?

-Takahiro Akashi

> I won't take such a patch.
> 
> Best regards
> 
> Heinrich
> 
> > 
> > > > +
> > > >/* Key identifying current memory map */
> > > >extern efi_uintn_t efi_memory_map_key;
> > > > 
> > > > @@ -375,6 +381,7 @@ enum efi_object_type {
> > > > * @protocols:   linked list with the protocol interfaces 
> > > > installed on this
> > > > *   handle
> > > > * @type:image type if the handle relates to an image
> > > > + * @dev:   pointer to the DM device which is associated with this 
> > > > EFI handle
> > > > *
> > > > * UEFI offers a flexible and expandable object model. The objects 
> > > > in the UEFI
> > > > * API are devices, drivers, and loaded images. struct efi_object is 
> > > > our storage
> > > > @@ -392,6 +399,7 @@ struct efi_object {
> > > > /* The list of protocols */
> > > > struct list_head protocols;
> > > > enum efi_object_type type;
> > > > +   struct udevice *dev;
> > > >};
> > > > 
> > > >enum efi_image_auth_status {
> > > > diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
> > > > index 1d700b2a6b..a8e8521e3e 100644
> > > > --- a/lib/efi_loader/efi_disk.c
> > > > +++ b/lib/efi_loader/efi_disk.c
> > > > @@ -46,7 +46,6 @@ struct efi_disk_obj {
> > > > struct efi_device_path *dp;
> > > > unsigned int part;
> > > > struct efi_simple_file_system_protocol *volume;
> > > > -   struct udevice *dev; /* TODO: move it to efi_object */
> > > 
> > > ok
> > > 
> > > >};
> > &

Re: [RESEND v9 1/9] efi_loader: move udevice pointer into struct efi_object

2022-07-19 Thread Takahiro Akashi
> 
> > >   } else {
> > >   /* dev is a block device (UCLASS_BLK) */
> > >   struct blk_desc *desc;
> > > 
> > > -    desc = dev_get_uclass_plat(diskobj->dev);
> > > +    desc = dev_get_uclass_plat(efi_handle_to_udev(diskobj));
> > 
> > dev_get_uclass(diskobj->header.hdev)
> > 
> > 
> > >   if (direction == EFI_DISK_READ)
> > >   n = blk_dread(desc, lba, blocks, buffer);
> > >   else
> > > @@ -552,7 +551,7 @@ static int efi_disk_create_raw(struct udevice *dev)
> > > 
> > >   return -1;
> > >   }
> > > -    disk->dev = dev;
> > > +    efi_handle_to_udev(disk) = dev;
> > >   if (dev_tag_set_ptr(dev, DM_TAG_EFI, >header)) {
> > >   efi_free_pool(disk->dp);
> > >   efi_delete_handle(>header);
> > > @@ -609,7 +608,7 @@ static int efi_disk_create_part(struct udevice *dev)
> > >   log_err("Adding partition for %s failed\n", dev->name);
> > >   return -1;
> > >   }
> > > -    disk->dev = dev;
> > > +    efi_handle_to_udev(disk) = dev;
> > 
> > disk->header.dev = dev;
> > 
> > >   if (dev_tag_set_ptr(dev, DM_TAG_EFI, >header)) {
> > >   efi_free_pool(disk->dp);
> > >   efi_delete_handle(>header);
> > > @@ -656,6 +655,13 @@ static int efi_disk_probe(void *ctx, struct event
> > > *event)
> > >   ret = efi_disk_create_raw(dev);
> > >   if (ret)
> > >   return -1;
> > > +    } else {
> > > +    efi_handle_t handle;
> > > +
> > > +    if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)))
> 
> Setting handle->dev can be done more easily in efi_bl_bind():

I don't think so.
"dev" field should be maintained in *one* place, i.e. efi_disk_probe(),
which is uniquely called from probe event (even for efi_block_dev case).

To make this clear, we'd better put the code in efi_disk_create_raw():
  efi_disk_create_raw()
  if (desc->if_type == IF_TYPE_EFI_LOADER) { 
  /* handle should exist now */
  dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)));
  efi_set_udev(handle, dev);
  return 0;
  }

  /* normal block devices */
  ...
  efi_set_udev(>header, dev);
  ...


-Takahiro Akashi

> handle->dev = bdev;
> 
> We can further remove the field handle from struct blk_create_device as
> it is now available in handle->dev.
> 
> Best regards
> 
> Heinrich
> 
> > > +    return -1;
> > > +
> > > +    efi_handle_to_udev(handle) = dev;
> > 
> > handle->dev = dev;
> > 
> > Best regards
> > 
> > Heinrich
> > 
> > >   }
> > > 
> > >   device_foreach_child(child, dev) {
> > 
> 


Re: [PATCH v5 20/23] FWU: synquacer: Generate dfu_alt_info from devicetree partition

2022-07-19 Thread Takahiro Akashi
On Mon, Jul 18, 2022 at 09:49:56AM -0500, Jassi Brar wrote:
> On Fri, 17 Jun 2022 at 09:02, Michal Simek  wrote:
> > On 6/9/22 14:30, Sughosh Ganu wrote:
> > > From: Masami Hiramatsu 
> .
> 
> > >
> > > @@ -188,6 +178,9 @@ int board_late_init(void)
> > >   {
> > >   int ret;
> > >
> > > + /* Make mmc available for EFI */
> > > + run_command("mmc dev 0", 0);
> > > +
> >
> > What is this for?
> >
> > And I can't see any single note about in commit message.
> >
> For some reason, we get "No EFI system partition" during bootup and
> the mmc does not show up in 'efidebug devices' unless we manually run
> this (or mmc part) command.

As far as UEFI is concerned, any U-Boot block device will be
recognized as a UEFI disk(block_io) object *only* after device_probe()
is called.

-Takahiro Akashi


> Though not elegant, I found similar being done by some other
> platforms  grep run_command -rw board/*
> I am happy to learn the proper way of doing it.
> 
> Thanks.


Re: [RESEND v9 1/9] efi_loader: move udevice pointer into struct efi_object

2022-07-19 Thread Takahiro Akashi
= dev_get_uclass_plat(efi_handle_to_udev(diskobj));
> 
> dev_get_uclass(diskobj->header.hdev)
> 
> 
> > if (direction == EFI_DISK_READ)
> > n = blk_dread(desc, lba, blocks, buffer);
> > else
> > @@ -552,7 +551,7 @@ static int efi_disk_create_raw(struct udevice *dev)
> > 
> > return -1;
> > }
> > -   disk->dev = dev;
> > +   efi_handle_to_udev(disk) = dev;
> > if (dev_tag_set_ptr(dev, DM_TAG_EFI, >header)) {
> > efi_free_pool(disk->dp);
> > efi_delete_handle(>header);
> > @@ -609,7 +608,7 @@ static int efi_disk_create_part(struct udevice *dev)
> > log_err("Adding partition for %s failed\n", dev->name);
> > return -1;
> > }
> > -   disk->dev = dev;
> > +   efi_handle_to_udev(disk) = dev;
> 
> disk->header.dev = dev;

It's my preference, but I would suggest another accessor:
   efi_set_udev(handle, dev);
to hide an implementation.

-Takahiro Akashi

> 
> > if (dev_tag_set_ptr(dev, DM_TAG_EFI, >header)) {
> > efi_free_pool(disk->dp);
> > efi_delete_handle(>header);
> > @@ -656,6 +655,13 @@ static int efi_disk_probe(void *ctx, struct event 
> > *event)
> > ret = efi_disk_create_raw(dev);
> > if (ret)
> > return -1;
> > +   } else {
> > +   efi_handle_t handle;
> > +
> > +   if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)))
> > +   return -1;
> > +
> > +   efi_handle_to_udev(handle) = dev;
> 
> handle->dev = dev;
> 
> Best regards
> 
> Heinrich
> 
> > }
> > 
> > device_foreach_child(child, dev) {
> 


Re: [PATCH v8 2/9] eficonfig: menu-driven addition of UEFI boot option

2022-07-13 Thread Takahiro Akashi
Heinrich,

On Sun, Jul 10, 2022 at 11:03:43AM +0200, Heinrich Schuchardt wrote:
> On 6/19/22 06:56, Masahisa Kojima wrote:
> > This commit add the "eficonfig" command.
> > The "eficonfig" command implements the menu-driven UEFI boot option
> > maintenance feature. This commit implements the addition of
> > new boot option. User can select the block device volume having
> > efi_simple_file_system_protocol and select the file corresponding
> > to the Boot variable. User can also enter the description and
> > optional_data of the BOOT variable in utf8.
> > 
> > This commit adds "include/efi_config.h", it contains the common
> > definition to be used from other menus such as UEFI Secure Boot
> > key management.
> > 
> > Signed-off-by: Masahisa Kojima 
> > ---
> > Changes in v8:
> > - command name is change from "efimenu" to "eficonfig"
> > - function and struct prefixes is changed to "eficonfig"
> > - fix menu header string
> > 
> > Changes in v7:
> > - add "efimenu" command and uefi variable maintenance code
> >moved into cmd/efimenu.c
> > - create include/efimenu.h to define the common definition for
> >the other menu such as UEFI Secure Boot key management
> > - update boot option edit UI, user can select description, file,
> >and optional_data to edit in the same menu like following.
> > 
> >** Edit Boot Option **
> > 
> >   Description: debian
> >   File: virtio 0:1/EFI\debian\grubaa64.efi
> >   Optional Data: test
> >   Save
> >   Quit
> > 
> > - remove exit parameter from efimenu_process_common()
> > - menu title type is changed from u16 to char
> > - efimenu_process_common() add menu title string
> > - reduce printf/puts function call for displaying the menu
> > - efi_console_get_u16_string() accept 0 length to allow
> >optional_data is empty
> > - efi_console_get_u16_string() the "size" parameter name is changes to 
> > "count"
> > - efimenu is now designed to maintain the UEFI variables, remove autoboot 
> > related code
> > - remove one empty line before "Quit" entry
> > - efimenu_init() processes only the first time
> > 
> > Changes in v6:
> > - fix typos
> > - modify volume name to match U-Boot syntax
> > - compile in CONFIG_EFI_LOADER=n and CONFIG_CMD_BOOTEFI_BOOTMGR=n
> > - simplify u16_strncmp() usage
> > - support "a\b.efi" file path, use link list to handle filepath
> > - modify length check condition
> > - UEFI related menu items only appears with CONFIG_AUTOBOOT_MENU_SHOW=y
> > 
> > Changes in v5:
> > - remove forward declarations
> > - add const qualifier for menu items
> > - fix the possible unaligned access for directory info access
> > - split into three commit 1)add boot option 2) delete boot option 3)change 
> > boot order
> >This commit is 1)add boot option.
> > - fix file name buffer allocation size, it should be 
> > EFI_BOOTMENU_FILE_PATH_MAX * sizeof(u16)
> > - fix wrong size checking for file selection
> > 
> > Chanes in v4:
> > - UEFI boot option maintenance menu is integrated into bootmenu
> > - display the simplified volume name(e.g. usb0:1, nvme1:2) for the
> >volume selection
> > - instead of extending lib/efi_loader/efi_bootmgr.c, newly create
> >lib/efi_loader/efi_bootmenu_maintenance.c and implement boot
> >variable maintenance into it.
> > 
> > Changes in RFC v3:
> >   not included in v3 series
> > 
> > Changes in RFC v2:
> > - enable utf8 user input for boot option name
> > - create lib/efi_loader/efi_console.c::efi_console_get_u16_string() for
> >utf8 user input handling
> > - use u16_strlcat instead of u16_strcat
> > - remove the EFI_CALLs, and newly create or expose the following
> >xxx_int() functions.
> >  efi_locate_handle_buffer_int(), efi_open_volume_int(),
> >  efi_file_open_int(), efi_file_close_int(), efi_file_read_int() and
> >  efi_file_setpos_int().
> >Note that EFI_CALLs still exist for EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
> >and EFI_SIMPLE_TEXT_INPUT/OUTPUT_PROTOCOL
> > - use efi_search_protocol() instead of calling locate_protocol() to get
> >the device_path_to_text_protocol interface.
> > - remove unnecessary puts(ANSI_CLEAR_LINE), this patch is still depends on
> >puts(ANSI_CLEAR_CONSOLE)
> > - skip SetVariable() if the bootorder is not changed
> > 
> >   cmd/Kconfig   |7 +
> >   cmd/Makefile  |1 +
> >   cmd/eficonfig.c   | 1270 +
> >   include/efi_config.h  |   91 +++
> >   include/efi_loader.h  |   40 ++
> >   lib/efi_loader/efi_boottime.c |   52 +-
> >   lib/efi_loader/efi_console.c  |   78 ++
> >   lib/efi_loader/efi_disk.c |   11 +
> >   lib/efi_loader/efi_file.c |   75 +-
> >   9 files changed, 1578 insertions(+), 47 deletions(-)
> >   create mode 100644 cmd/eficonfig.c
> >   create mode 100644 include/efi_config.h
> > 
> > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > index 09193b61b9..bb7f1d0463 100644
> > --- a/cmd/Kconfig
> > +++ 

Re: [PATCH v8 2/9] eficonfig: menu-driven addition of UEFI boot option

2022-07-11 Thread Takahiro Akashi
fi_locate_handle_buffer_int(BY_PROTOCOL, 
> > _simple_file_system_protocol_guid,
> > +  NULL, , (efi_handle_t 
> > **)_handles);
> > +   if (ret != EFI_SUCCESS) {
> > +   eficonfig_print_msg("No block device found!");
> > +   return ret;
> > +   }
> > +
> > +   menu_item = calloc(count + 1, sizeof(struct eficonfig_item));
> > +   if (!menu_item) {
> > +   efi_free_pool(volume_handles);
> > +   return EFI_OUT_OF_RESOURCES;
> > +   }
> > +
> > +   iter = menu_item;
> > +   for (i = 0; i < count; i++) {
> > +   char *devname;
> > +   struct efi_block_io *block_io;
> > +   struct eficonfig_volume_entry_data *info;
> > +
> > +   ret = efi_search_protocol(volume_handles[i],
> > + 
> > _simple_file_system_protocol_guid, );
> > +   if (ret != EFI_SUCCESS)
> > +   continue;
> > +   ret = efi_protocol_open(handler, (void **), efi_root, NULL,
> > +   EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> > +   if (ret != EFI_SUCCESS)
> > +   continue;
> > +
> > +   ret = efi_search_protocol(volume_handles[i], 
> > _guid_device_path, );
> > +   if (ret != EFI_SUCCESS)
> > +   continue;
> > +   ret = efi_protocol_open(handler, (void **)_path,
> > +       efi_root, NULL, 
> > EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> > +   if (ret != EFI_SUCCESS)
> > +   continue;
> > +
> > +   ret = efi_search_protocol(volume_handles[i], 
> > _block_io_guid, );
> > +   if (ret != EFI_SUCCESS)
> > +   continue;
> > +   ret = efi_protocol_open(handler, (void **)_io,
> > +   efi_root, NULL, 
> > EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> > +   if (ret != EFI_SUCCESS)
> > +   continue;
> > +
> > +   info = calloc(1, sizeof(struct eficonfig_volume_entry_data));
> > +   if (!info) {
> > +   ret = EFI_OUT_OF_RESOURCES;
> > +   goto out;
> > +   }
> > +
> > +   devname = calloc(1, BOOTMENU_DEVICE_NAME_MAX);
> > +   if (!devname) {
> > +   free(info);
> > +   ret = EFI_OUT_OF_RESOURCES;
> > +   goto out;
> > +   }
> > +   efi_disk_get_device_name(block_io, devname, 
> > BOOTMENU_DEVICE_NAME_MAX);
> > +
> > +   info->v = v;
> > +   info->dp = device_path;
> > +   info->file_info = file_info;
> > +   iter->title = devname;
> > +   iter->func = eficonfig_volume_selected;
> > +   iter->data = info;
> > +   iter++;
> > +   }
> > +
> > +   iter->title = strdup("Quit");
> > +   iter->func = eficonfig_process_quit;
> > +   iter->data = NULL;
> > +   count += 1;
> > +
> > +   ret = eficonfig_process_common(menu_item, count, "  ** Select Volume 
> > **");
> > +
> > +out:
> > +   iter = menu_item;
> > +   for (i = 0; i < count; i++, iter++) {
> > +   free(iter->data);
> > +   free(iter->title);
> > +   }
> > +
> > +   free(menu_item);
> > +
> > +   efi_free_pool(volume_handles);
> > +
> > +   return ret;
> > +}
> > +
> > +static efi_status_t eficonfig_select_file(struct 
> > eficonfig_select_file_info *file_info,
> > + struct efi_file_handle *root)
> > +{
> > +   u32 i;
> > +   u32 count = 0;
> > +   efi_uintn_t len;
> > +   efi_status_t ret;
> > +   struct efi_file_handle *f;
> > +   struct efi_file_info *buf;
> > +   struct eficonfig_item *menu_item, *iter;
> > +
> > +   buf = calloc(1, sizeof(struct efi_file_info) + 
> > EFICONFIG_FILE_PATH_BUF_SIZE);
> > +   if (!buf)
> > +   return EFI_OUT_OF_RESOURCES;
> > +
> > +   while (!file_info->file_selected) {
> > +   count = 0;
> > +
> > +   ret = efi_file_open_int(root, , file_info->current_path, 
> > EFI_FILE_MODE_READ, 0);
> > +   if (ret != EFI_SUCCESS) {
> > +   /* TODO: need to fileter out non-FAT partition? */
> 
> %s/fileter/filter/
> 
> > +   eficonfig_print_m

Re: [RFC PATCH 3/3] eficonfig: add "Delete Key" menu entry

2022-07-11 Thread Takahiro Akashi
   /* only delete the single signature data */
> > +   sg->esl->signature_list_size -= 
> > sg->esl->signature_size;
> > +   size -= sg->esl->signature_size;
> > +   dest = (u8 *)sg->esd;
> > +   start = (u8 *)sg->esd + sg->esl->signature_size;
> > +   } else {
> > +   /* delete entire signature list */
> > +   dest = (u8 *)sg->esl;
> > +   start = (u8 *)sg->esl + 
> > sg->esl->signature_list_size;
> > +   size -= sg->esl->signature_list_size;
> > +   }
> > +   memmove(dest, start, (end - start));
> > +   }
> > +   }
> > +
> > +   *db_size = size;
> > +}
> > +
> > +static efi_status_t create_time_based_payload(void *db, void **new_db, 
> > efi_uintn_t *size)
> > +{
> > +   efi_status_t ret;
> > +   struct efi_time time;
> > +   efi_uintn_t total_size;
> > +   struct efi_variable_authentication_2 *auth;
> > +
> > +   *new_db = NULL;
> > +
> > +   /*
> > +* SetVariable() call with 
> > EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
> > +* attribute requires EFI_VARIABLE_AUTHENTICATED_2 descriptor, prepare 
> > it
> > +* without certificate data in it.
> > +*/
> > +   total_size = sizeof(struct efi_variable_authentication_2) + *size;
> > +
> > +   auth = calloc(1, total_size);
> > +   if (!auth)
> > +   return EFI_OUT_OF_RESOURCES;
> > +
> > +   ret = EFI_CALL((*efi_runtime_services.get_time)(, NULL));
> > +   if (ret != EFI_SUCCESS) {
> > +   free(auth);
> > +   return EFI_OUT_OF_RESOURCES;
> > +   }
> > +   time.pad1 = 0;
> > +   time.nanosecond = 0;
> > +   time.timezone = 0;
> > +   time.daylight = 0;
> > +   time.pad2 = 0;
> > +   memcpy(>time_stamp, , sizeof(time));
> > +   auth->auth_info.hdr.dwLength = sizeof(struct win_certificate_uefi_guid);
> > +   auth->auth_info.hdr.wRevision = 0x0200;
> > +   auth->auth_info.hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;
> > +   guidcpy(>auth_info.cert_type, _guid_cert_type_pkcs7);
> > +   if (db)
> > +   memcpy((u8 *)auth + sizeof(struct 
> > efi_variable_authentication_2), db, *size);
> > +
> > +   *new_db = auth;
> > +   *size = total_size;
> > +
> > +   return EFI_SUCCESS;
> > +}
> > +
> >   static efi_status_t prepare_signature_db_list(struct eficonfig_item 
> > **output, void *varname,
> >   void *db, efi_uintn_t db_size,
> >   eficonfig_entry_func func,
> > @@ -378,6 +510,68 @@ out:
> > return ret;
> >   }
> > 
> > +static efi_status_t process_delete_key(void *varname)
> > +{
> > +   u32 attr, i, count = 0;
> > +   efi_status_t ret;
> > +   struct eficonfig_item *menu_item = NULL, *iter;
> > +   void *db = NULL, *new_db = NULL;
> > +   efi_uintn_t db_size;
> > +   struct list_head siglist_list;
> > +   struct eficonfig_sig_data *selected;
> > +
> > +   db = efi_get_var(varname, efi_auth_var_get_guid(varname), _size);
> > +   if (!db) {
> > +   eficonfig_print_msg("There is no entry in the signature 
> > database.");
> 
> Please, use the terms of the UEFI specification.
> %s/signature database/signature store/

Signature database is also a common term throughout the specification.
See "section 32.4.1 Signature Database", for example.

-Takahiro Akashi


> > +   return EFI_NOT_FOUND;
> > +   }
> > +
> > +   ret = prepare_signature_db_list(_item, varname, db, db_size,
> > +   eficonfig_process_sigdata_delete, 
> > ,
> > +   _list, );
> > +   if (ret != EFI_SUCCESS)
> > +   goto out;
> > +
> > +   ret = eficonfig_process_common(menu_item, count, " ** Delete Key **");
> > +
> > +   if (ret == EFI_SUCCESS) {
> > +   delete_selected_signature_data(db, _size, selected, 
> > _list);
> > +
> > +   ret = create_time_based_payload(db, _db, _size);
> > +   if (ret != EFI_SUCCESS)
> > +   goto out;
> > +
> > +   attr = EFI_VARIABLE_NON_VOLATILE |
> > +  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> >

Re: [PATCH v6 00/13] FWU: Add FWU Multi Bank Update feature support

2022-07-04 Thread Takahiro Akashi
On Mon, Jul 04, 2022 at 10:46:45AM +0530, Sughosh Ganu wrote:
> 
> The patchset adds support for the FWU Multi Bank Update[1]
> feature. Certain aspects of the Dependable Boot[2] specification have
> also been implemented.
> 
> The FWU multi bank update feature is used for supporting multiple
> sets(also called banks) of firmware image(s), allowing the platform to
> boot from a different bank, in case it fails to boot from the active
> bank. This functionality is supported by keeping the relevant
> information in a structure called metadata, which provides information
> on the images. Among other parameters, the metadata structure contains
> information on the currect active bank that is being used to boot
> image(s).
> 
> Functionality is being added to work with the UEFI capsule driver in
> u-boot. The metadata is read to gather information on the update bank,
> which is the bank to which the firmware images would be flashed to. On
> a successful completion of the update of all components, the active
> bank field in the metadata is updated, to reflect the bank from which
> the platform will boot on the subsequent boots.
> 
> Currently, the feature is being enabled on the STM32MP157C-DK2 and
> Synquacer boards. The DK2 board boots a FIP image from a uSD card
> partitioned with the GPT partioning scheme, while the Synquacer board
> boots a FIP image from a MTD partitioned SPI NOR flash device.
> 
> This feature also requires changes in a previous stage of
> bootloader, which parses the metadata and selects the bank to boot the
> image(s) from. Support has being added in tf-a(BL2 stage) for the
> STM32MP157C-DK2 board to boot the active bank images. These changes 
> have been merged to the upstream tf-a repository.
> 
> The earlier patchset contained patches for both the DK2 and the
> Synquacer platforms. The handling of review comments for the Synquacer
> platform is to be taken up by a different engineer, and has not been
> done yet. After discussion with Tom Rini and Heinrich, it was decided
> to send the patches for the DK2 platform separately for review. The
> patch for adding a python test for the feature has been developed, and
> was sent in the version 5 of the patches[3]. However, the test script
> depends on adding support for the feature on MTD SPI NOR devices, and
> that is being done as part of the Synquacer patches. Hence these set
> of patches do not have the test script for the feature. That will be
> added through the patches for adding support for the feauture on
> Synquacer platform.
> 
> [1] - https://developer.arm.com/documentation/den0118/a
> [2] - 
> https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
> [3] - https://lists.denx.de/pipermail/u-boot/2022-June/485992.html
> 
> Changes since V5:
> * Changed to yaml file from txt as per review comment
> * Change the parameter to the function fwu_plat_get_alt_num to pass
>   the FWU udevice pointer instead of passing the metadata device
>   directly.
> * Changed the logic to store the GPT partitioned block device through
>   a priv structure as suggested by Patrick
> * Used dev_read_prop() to get the phandle_p instead of
>   ofnode_get_property() used earlier as suggested by Patrick
> * Made relevant functions static as suggested by Etienne
> * Change the mechanism to get the block device descriptor in
>   fwu_plat_get_alt_num() due to introduction of struct
>   fwu_mdata_gpt_blk_priv in the earlier patch.
> * Shuffled the location of the TAMP_FWU_* macros as suggested by
>   Patrick
> * Use u"TrialStateCtr" for the EFI variable name as suggested by
>   Patrick
> * Dropped the call to uclass_get_device() in fwu_boottime_checks() as
>   suggested by Patrick
> * Pass NULL instead of a pointer to trial_state_ctr variable when
>   deleting the variable as suggested by Etienne
> * Use u"TrialStateCtr" as suggested by Patrick
> * Do a metadata validity check by calling fwu_mdata_check() before
>   printing the FWU metadata as suggested by Michal
> * Use ret and res variables in do_fwu_mdata_read() as suggested by
>   Patrick
> * Change 'default y if FWU_MULTI_BANK_UPDATE' to default y as
>   suggested by Patrick
> * Use capsule_type instead of capsule variable that was created
>   earlier to check for the type of capsule
> * Remove use of payload variable in create_empty_capsule() as
>   suggested by Etienne
> * Initialise the struct efi_capsule_header as suggested by Etienne
> * Add some description about the reasoning for accept capsule needing
>   image GUID as suggested by Takahiro

Thanks, but I don't still understand why we need GUID here
as I said in
https://lists.denx.de/pipermail/u-boot/2022-June/486733.h

Re: [PATCH v8 0/9] enable menu-driven UEFI variable maintenance

2022-06-19 Thread Takahiro Akashi
On Sun, Jun 19, 2022 at 01:55:58PM +0900, Masahisa Kojima wrote:
> This series add the menu-driven UEFI boot variable maintenance
> and removable media support in bootmenu.
> 
> Different from previous version, thie series adds a new U-Boot
> command "efimenu" to invoke the UEFI boot-related variable
> maintenance menu.
> 
> Note that menu-driven UEFI Secure Boot key management patch series
> will follow.
> 
> Source code can be cloned with:
> $ git clone https://git.linaro.org/people/masahisa.kojima/u-boot.git -b 
> kojima/efi_menu_upstream_v8_0618
> 
> [Major Changes]
> - command name is changed from "efimenu" to "eficonfig"
> - there is detailed chang

At first glance, the behavior looks good.

Thanks,
-Takahiro Akashi



> Masahisa Kojima (9):
>   efi_loader: expose END device path node
>   eficonfig: menu-driven addition of UEFI boot option
>   eficonfig: add "Edit Boot Option" menu entry
>   menu: add KEY_PLUS and KEY_MINUS handling
>   eficonfig: add "Change Boot Order" menu entry
>   eficonfig: add "Delete Boot Option" menu entry
>   bootmenu: add removable media entries
>   doc:bootmenu: add description for UEFI boot support
>   doc:eficonfig: add documentation for eficonfig command
> 
>  cmd/Kconfig  |7 +
>  cmd/Makefile |1 +
>  cmd/bootmenu.c   |   99 +-
>  cmd/eficonfig.c  | 1872 ++
>  common/menu.c|6 +
>  doc/usage/cmd/bootmenu.rst   |   74 ++
>  doc/usage/cmd/eficonfig.rst  |   50 +
>  doc/usage/index.rst  |1 +
>  include/efi_config.h |   91 ++
>  include/efi_loader.h |   63 +
>  include/menu.h   |2 +
>  lib/efi_loader/efi_bootmgr.c |4 +
>  lib/efi_loader/efi_boottime.c|   52 +-
>  lib/efi_loader/efi_console.c |   78 ++
>  lib/efi_loader/efi_device_path.c |2 +-
>  lib/efi_loader/efi_disk.c|   11 +
>  lib/efi_loader/efi_file.c|   75 +-
>  17 files changed, 2437 insertions(+), 51 deletions(-)
>  create mode 100644 cmd/eficonfig.c
>  create mode 100644 doc/usage/cmd/eficonfig.rst
>  create mode 100644 include/efi_config.h
> 
> -- 
> 2.17.1
> 


Re: [PATCH v5 23/23] sandbox: fwu: Add support for testing FWU feature on sandbox

2022-06-16 Thread Takahiro Akashi
Sughosh,

On Wed, Jun 15, 2022 at 05:40:12PM +0530, Sughosh Ganu wrote:
> On Wed, 15 Jun 2022 at 11:07, Takahiro Akashi
>  wrote:
> >
> > On Thu, Jun 09, 2022 at 06:00:10PM +0530, Sughosh Ganu wrote:
> > > Add a python test script for testing the FWU Multi Bank Update
> > > functionality on the sandbox platform. The script has test cases for
> > > updation of the u-boot binary and the u-boot environment image to the
> > > non active bank.
> > >
> > > The FWU metadata is being stored on the SPI NOR flash, along with the
> > > updatable images, and the FWU metadata driver for MTD devices is being
> > > used for accessing the metadata. Certain FWU boottime checks are
> > > bypassed due to the unavailability of the EFI variable access very
> > > early in the boot on the sandbox platform -- the variable access is
> > > only available once the block disk image has been bound through the
> > > host interface.
> > >
> > > The FWU Multi Bank feature being enabled on the sandbox64 platform is
> > > enabling the RAW Firmware Management Protocol(FMP) instance, therefore
> > > the FIT FMP instance is being removed -- the FIT FMP is already being
> > > tested on the sandbox flattree variant.
> >
> > IMO,
> > Thinking of the importance of this feature, FIT FMP should also be
> > tested *with FWU*.
> 
> How will the FWU update feature work for FIT images? As I understand

So are you deliberately designing and proposing a solution that is
incompatible with (or not applicable to) an existing interface (FIT FMP)?

> FIT, it is a way of packaging different firmware images into a single
> package. At the time of writing the images, the FIT image parser would
> check the image configuration, and write the images to their
> respective locations. As you are aware, for the FWU feature, the
> information about the images, and the update bank is obtained from the
> structure called metadata. How does the FIT update mechanism map with
> the FWU metadata which is used to identify which bank needs to be
> updated. The bank to which the image is to be written translates into
> the DFU alt_num value for that image, and this gets computed at
> runtime. In the case of the FIT image, as per my understanding, the
> alt_num value is irrelevant. So my question is, how do we map the
> information obtained from the FWU metadata to tell the FIT image
> writing function(fit_update) which locations do the images need to be
> written to. I think this needs some more thought.
> 
> >
> > > Signed-off-by: Sughosh Ganu 
> > > ---
> > >  arch/sandbox/Kconfig  |   6 +
> > >  arch/sandbox/dts/test.dts |  45 ++-
> > >  board/sandbox/sandbox.c   |  49 +++
> > >  configs/sandbox64_defconfig   |  12 +-
> > >  include/fwu.h |   2 +
> > >  lib/fwu_updates/Kconfig   |   2 +-
> > >  lib/fwu_updates/fwu.c |  18 +-
> > >  lib/fwu_updates/fwu_mtd.c |  10 +-
> > >  .../test_capsule_firmware_fit.py  |   1 -
> > >  .../py/tests/test_fwu_updates/capsule_defs.py |  10 +
> > >  test/py/tests/test_fwu_updates/conftest.py|  78 
> > >  .../test_fwu_updates/test_fwu_updates.py  | 367 ++
> > >  12 files changed, 587 insertions(+), 13 deletions(-)
> > >  create mode 100644 test/py/tests/test_fwu_updates/capsule_defs.py
> > >  create mode 100644 test/py/tests/test_fwu_updates/conftest.py
> > >  create mode 100644 test/py/tests/test_fwu_updates/test_fwu_updates.py
> > >
> 
> 
> 
> > > diff --git a/test/py/tests/test_fwu_updates/conftest.py 
> > > b/test/py/tests/test_fwu_updates/conftest.py
> > > new file mode 100644
> > > index 00..cdf824c3be
> > > --- /dev/null
> > > +++ b/test/py/tests/test_fwu_updates/conftest.py
> > > @@ -0,0 +1,78 @@
> > > +# SPDX-License-Identifier:  GPL-2.0+
> > > +# Copyright (c) 2020, Linaro Limited
> > > +# Author: AKASHI Takahiro 
> >
> > If this file is exactly same as test_efi_capsule/conftest.py,
> > why not move all the tests (test_fwu_updates.py) to test_efi_capsule?
> 
> The files are not exactly the same. There is use of the mkfwumdata
> utility used for FWU tests, along with the capsule files that are
> being generated. I had tried putting the code under the
> test_efi_capsule directory, but the result was getting cluttered.

Okay, but from my curiosity, how cluttered was it

Re: [PATCH v5 11/23] mkeficapsule: Add support for generating empty capsules

2022-06-16 Thread Takahiro Akashi
Sughosh,

On Thu, Jun 16, 2022 at 12:42:08PM +0530, Sughosh Ganu wrote:
> hi Takahiro,
> 
> On Thu, 16 Jun 2022 at 06:31, Takahiro Akashi
>  wrote:
> >
> > Sughosh,
> >
> > On Wed, Jun 15, 2022 at 04:19:56PM +0530, Sughosh Ganu wrote:
> > > On Wed, 15 Jun 2022 at 10:41, Takahiro Akashi
> > >  wrote:
> > > >
> > > > On Thu, Jun 09, 2022 at 05:59:58PM +0530, Sughosh Ganu wrote:
> > > > > The Dependable Boot specification[1] describes the structure of the
> > > > > firmware accept and revert capsules. These are empty capsules which
> > > > > are used for signalling the acceptance or rejection of the updated
> > > > > firmware by the OS. Add support for generating these empty capsules.
> > > > >
> > > > > [1] - 
> > > > > https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
> > > > >
> > > > > Signed-off-by: Sughosh Ganu 
> > > > > ---
> > > > >  doc/mkeficapsule.1   |  29 ++---
> > > > >  tools/eficapsule.h   |   8 +++
> > > > >  tools/mkeficapsule.c | 139 
> > > > > +--
> > > > >  3 files changed, 151 insertions(+), 25 deletions(-)
> > > > >
> > > > > diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
> > > > > index 09bdc24295..77ca061efd 100644
> > > > > --- a/doc/mkeficapsule.1
> > > > > +++ b/doc/mkeficapsule.1
> > > > > @@ -8,7 +8,7 @@ mkeficapsule \- Generate EFI capsule file for U-Boot
> > > > >
> > > > >  .SH SYNOPSIS
> > > > >  .B mkeficapsule
> > > > > -.RI [ options "] " image-blob " " capsule-file
> > > > > +.RI [ options ] " " [ image-blob ] " " capsule-file
> > > > >
> > > > >  .SH "DESCRIPTION"
> > > > >  .B mkeficapsule
> > > > > @@ -23,8 +23,13 @@ Optionally, a capsule file can be signed with a 
> > > > > given private key.
> > > > >  In this case, the update will be authenticated by verifying the 
> > > > > signature
> > > > >  before applying.
> > > > >
> > > > > +Additionally, an empty capsule file can be generated for acceptance 
> > > > > or
> > > > > +rejection of firmware images by a governing component like an 
> > > > > Operating
> > > > > +System. The empty capsules do not require an image-blob input file.
> > > > > +
> > > > > +
> > > > >  .B mkeficapsule
> > > > > -takes any type of image files, including:
> > > > > +takes any type of image files when generating non empty capsules, 
> > > > > including:
> > > > >  .TP
> > > > >  .I raw image
> > > > >  format is a single binary blob of any type of firmware.
> > > > > @@ -36,18 +41,16 @@ multiple binary blobs in a single capsule file.
> > > > >  This type of image file can be generated by
> > > > >  .BR mkimage .
> > > > >
> > > > > -.PP
> > > > > -If you want to use other types than above two, you should explicitly
> > > > > -specify a guid for the FMP driver.
> > > > > -
> > > > >  .SH "OPTIONS"
> > > > > +
> > > > >  .TP
> > > > >  .BI "-g\fR,\fB --guid " guid-string
> > > > >  Specify guid for image blob type. The format is:
> > > > >  ----
> > > > >
> > > > >  The first three elements are in little endian, while the rest
> > > > > -is in big endian.
> > > > > +is in big endian. The option must be specified for all non empty and
> > > > > +image acceptance capsules
> > > >
> > > > "image acceptance" -> "firmware acceptance"
> > >
> > > Okay
> > >
> > > >
> > > > I don't still understand why we need a guid for acceptance
> > > > while revert doesn't require it.
> > > > I believe that firmware update is "all or nothing", isn't it?
> > >
> > > I believe this gives more flexibility in that different components
> > > might be required to accept the various firmware images. So, one
> > > co

Re: [PATCH v5 11/23] mkeficapsule: Add support for generating empty capsules

2022-06-15 Thread Takahiro Akashi
Sughosh,

On Wed, Jun 15, 2022 at 04:19:56PM +0530, Sughosh Ganu wrote:
> On Wed, 15 Jun 2022 at 10:41, Takahiro Akashi
>  wrote:
> >
> > On Thu, Jun 09, 2022 at 05:59:58PM +0530, Sughosh Ganu wrote:
> > > The Dependable Boot specification[1] describes the structure of the
> > > firmware accept and revert capsules. These are empty capsules which
> > > are used for signalling the acceptance or rejection of the updated
> > > firmware by the OS. Add support for generating these empty capsules.
> > >
> > > [1] - 
> > > https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
> > >
> > > Signed-off-by: Sughosh Ganu 
> > > ---
> > >  doc/mkeficapsule.1   |  29 ++---
> > >  tools/eficapsule.h   |   8 +++
> > >  tools/mkeficapsule.c | 139 +--
> > >  3 files changed, 151 insertions(+), 25 deletions(-)
> > >
> > > diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1
> > > index 09bdc24295..77ca061efd 100644
> > > --- a/doc/mkeficapsule.1
> > > +++ b/doc/mkeficapsule.1
> > > @@ -8,7 +8,7 @@ mkeficapsule \- Generate EFI capsule file for U-Boot
> > >
> > >  .SH SYNOPSIS
> > >  .B mkeficapsule
> > > -.RI [ options "] " image-blob " " capsule-file
> > > +.RI [ options ] " " [ image-blob ] " " capsule-file
> > >
> > >  .SH "DESCRIPTION"
> > >  .B mkeficapsule
> > > @@ -23,8 +23,13 @@ Optionally, a capsule file can be signed with a given 
> > > private key.
> > >  In this case, the update will be authenticated by verifying the signature
> > >  before applying.
> > >
> > > +Additionally, an empty capsule file can be generated for acceptance or
> > > +rejection of firmware images by a governing component like an Operating
> > > +System. The empty capsules do not require an image-blob input file.
> > > +
> > > +
> > >  .B mkeficapsule
> > > -takes any type of image files, including:
> > > +takes any type of image files when generating non empty capsules, 
> > > including:
> > >  .TP
> > >  .I raw image
> > >  format is a single binary blob of any type of firmware.
> > > @@ -36,18 +41,16 @@ multiple binary blobs in a single capsule file.
> > >  This type of image file can be generated by
> > >  .BR mkimage .
> > >
> > > -.PP
> > > -If you want to use other types than above two, you should explicitly
> > > -specify a guid for the FMP driver.
> > > -
> > >  .SH "OPTIONS"
> > > +
> > >  .TP
> > >  .BI "-g\fR,\fB --guid " guid-string
> > >  Specify guid for image blob type. The format is:
> > >  ----
> > >
> > >  The first three elements are in little endian, while the rest
> > > -is in big endian.
> > > +is in big endian. The option must be specified for all non empty and
> > > +image acceptance capsules
> >
> > "image acceptance" -> "firmware acceptance"
> 
> Okay
> 
> >
> > I don't still understand why we need a guid for acceptance
> > while revert doesn't require it.
> > I believe that firmware update is "all or nothing", isn't it?
> 
> I believe this gives more flexibility in that different components
> might be required to accept the various firmware images. So, one
> component might accept the optee_os, while another might be
> responsible for accepting u-boot. In any case, we do check that all
> the components have their accepted bit set, and only if so, does the
> bank boot in the regular state.

Probably I don't understand the behavior.
Let's assume that we have firmware A and firmware B and then
update both.
When the firmware A is accepted and B is not (not yet issuing
acceptance capsule) and I try to reboot the system, what happens?
>From which bank does the system boot, old one or new one?

> In case of a firmware revert, it would
> not matter which firmware component is being reverted -- the platform
> would simply need to boot from the other bank. Do you see any issue
> with the current method that we have?
> 
> >
> > If there is a good reason, please describe a possible/expected
> > scenario.
> 
> Where do you want me to explain this, in the feature documentation? Or
> do you think this can be elaborated in greater detail in the spec.

I prefer some explanation in U-Boot doc.

> >
> 

Re: [PATCH v5 08/23] FWU: Add boot time checks as highlighted by the FWU specification

2022-06-15 Thread Takahiro Akashi
_size, _state_ctr,
> > + NULL);
> > +   if (status != EFI_SUCCESS) {
> > +   log_err("Unable to read TrialStateCtr variable\n");
> > +   ret = -1;
> > +   goto out;
> > +   }
> > +
> > +   ++trial_state_ctr;
> > +   if (trial_state_ctr > CONFIG_FWU_TRIAL_STATE_CNT) {
> > +   log_info("Trial State count exceeded. Revert back to 
> > previous_active_index\n");
> > +   active_idx = mdata->active_index;
> > +   ret = fwu_revert_boot_index();
> > +   if (ret) {
> > +   log_err("Unable to revert active_index\n");
> > +   goto out;
> > +   }
> > +
> > +   trial_state_ctr = 0;
> > +   status = efi_set_variable_int(L"TrialStateCtr",
> > + _global_variable_guid,
> > + var_attributes,
> > + 0,
> > + _state_ctr, false);
> > +   if (status != EFI_SUCCESS) {
> > +   log_err("Unable to clear TrialStateCtr 
> > variable\n");
> > +   ret = -1;
> > +   goto out;
> > +   }
> > +   } else {
> > +   status = efi_set_variable_int(L"TrialStateCtr",
> > + _global_variable_guid,
> > + var_attributes,
> > + var_size,
> > + _state_ctr, false);
> > +   if (status != EFI_SUCCESS) {
> > +   log_err("Unable to increment TrialStateCtr 
> > variable\n");
> > +   ret = -1;
> > +   goto out;
> > +   }
> > +   }
> > +   } else {
> > +   trial_state_ctr = 0;
> > +   status = efi_set_variable_int(L"TrialStateCtr",
> > + _global_variable_guid,
> > + 0,
> > + 0, _state_ctr,
> > + NULL);
> > +   }
> > +
> > +out:
> > +   free(mdata);
> > +   return ret;
> > +}
> > +
> > +u8 fwu_update_checks_pass(void)
> > +{
> > +   return !trial_state && boottime_check;
> > +}
> > +
> > +int fwu_boottime_checks(void)
> > +{
> > +   int ret;
> > +   struct udevice *dev;
> > +   u32 boot_idx, active_idx;
> > +
> > +   if (uclass_get_device(UCLASS_FWU_MDATA, 0, ) || !dev) {
> > +   log_err("FWU Metadata device not found\n");
> > +   return 0;
> > +   }
> > +
> > +   ret = fwu_mdata_check();
> > +   if (ret) {
> > +   return 0;
> > +   }
> > +
> > +   /*
> > +* Get the Boot Index, i.e. the bank from
> > +* which the platform has booted. This value
> > +* gets passed from the ealier stage bootloader
> > +* which booted u-boot, e.g. tf-a. If the
> > +* boot index is not the same as the
> > +* active_index read from the FWU metadata,
> > +* update the active_index.
> > +*/
> > +   fwu_plat_get_bootidx(_idx);
> > +   if (boot_idx >= CONFIG_FWU_NUM_BANKS) {
> > +   log_err("Received incorrect value of boot_index\n");
> > +   return 0;
> > +   }
> > +
> > +   ret = fwu_get_active_index(_idx);
> > +   if (ret) {
> > +   log_err("Unable to read active_index\n");
> > +   return 0;
> > +   }
> > +
> > +   if (boot_idx != active_idx) {
> > +   log_info("Boot idx %u is not matching active idx %u, changing 
> > active_idx\n",
> > +boot_idx, active_idx);
> > +   ret = fwu_update_active_index(boot_idx);
> > +   if (!ret)
> > +   boottime_check = 1;
> > +
> > +   return 0;
> > +   }
> > +
> > +   if (efi_init_obj_list() != EFI_SUCCESS)
> 
> efi_init_obj_list() slows down the boot process. Why do want to invoke
> it if no EFI binary is launched?

Because fwu_boottime_checks() must access UEFI variables.

-Takahiro Akashi

> See also Takahiro's hint in
> https://lore.kernel.org/all/20220615061616.GD58082@laputa/
> 
> Best regards
> 
> Heinrich
> 
> > +   return 0;
> > +
> > +   ret = fwu_trial_state_check();
> > +   if (!ret)
> > +   boottime_check = 1;
> > +
> > +   return 0;
> > +}
> 


Re: [PATCH v5 23/23] sandbox: fwu: Add support for testing FWU feature on sandbox

2022-06-15 Thread Takahiro Akashi
On Thu, Jun 09, 2022 at 06:00:10PM +0530, Sughosh Ganu wrote:
> Add a python test script for testing the FWU Multi Bank Update
> functionality on the sandbox platform. The script has test cases for
> updation of the u-boot binary and the u-boot environment image to the
> non active bank.

IIUC, your test doesn't not exercise neither accept-capsule nor
revert capsule.
I think those tests are crucial for verifying the code.

-Takahiro Akashi

> The FWU metadata is being stored on the SPI NOR flash, along with the
> updatable images, and the FWU metadata driver for MTD devices is being
> used for accessing the metadata. Certain FWU boottime checks are
> bypassed due to the unavailability of the EFI variable access very
> early in the boot on the sandbox platform -- the variable access is
> only available once the block disk image has been bound through the
> host interface.
> 
> The FWU Multi Bank feature being enabled on the sandbox64 platform is
> enabling the RAW Firmware Management Protocol(FMP) instance, therefore
> the FIT FMP instance is being removed -- the FIT FMP is already being
> tested on the sandbox flattree variant.
> 
> Signed-off-by: Sughosh Ganu 
> ---
>  arch/sandbox/Kconfig  |   6 +
>  arch/sandbox/dts/test.dts |  45 ++-
>  board/sandbox/sandbox.c   |  49 +++
>  configs/sandbox64_defconfig   |  12 +-
>  include/fwu.h |   2 +
>  lib/fwu_updates/Kconfig   |   2 +-
>  lib/fwu_updates/fwu.c |  18 +-
>  lib/fwu_updates/fwu_mtd.c |  10 +-
>  .../test_capsule_firmware_fit.py  |   1 -
>  .../py/tests/test_fwu_updates/capsule_defs.py |  10 +
>  test/py/tests/test_fwu_updates/conftest.py|  78 
>  .../test_fwu_updates/test_fwu_updates.py  | 367 ++
>  12 files changed, 587 insertions(+), 13 deletions(-)
>  create mode 100644 test/py/tests/test_fwu_updates/capsule_defs.py
>  create mode 100644 test/py/tests/test_fwu_updates/conftest.py
>  create mode 100644 test/py/tests/test_fwu_updates/test_fwu_updates.py
> 
> diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
> index 5f55c7f28e..2985572083 100644
> --- a/arch/sandbox/Kconfig
> +++ b/arch/sandbox/Kconfig
> @@ -84,3 +84,9 @@ config SYS_FDT_LOAD_ADDR
> See `doc/arch/sandbox.rst` for more information.
>  
>  endmenu
> +
> +config FWU_NUM_BANKS
> +   default 2
> +
> +config FWU_NUM_IMAGES_PER_BANK
> + default 2
> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
> index 8f93775ff4..f11fa8733f 100644
> --- a/arch/sandbox/dts/test.dts
> +++ b/arch/sandbox/dts/test.dts
> @@ -1145,11 +1145,48 @@
>   pinctrl-names = "default";
>   pinctrl-0 = <_spi0_pins>;
>  
> - spi.bin@0 {
> + spi0: spi.bin@0 {
>   reg = <0>;
>   compatible = "spansion,m25p16", "jedec,spi-nor";
>   spi-max-frequency = <4000>;
>   sandbox,filename = "spi.bin";
> +
> + partitions {
> + compatible = "fixed-partitions";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + uuid = "af9e8c96-bec5-48be-9dab-3491c04b1366";
> +
> + partition@0 {
> + label = "Metadata";
> + reg = <0x0 0x2>;
> + };
> +
> + /* FWU Multi bank update partitions */
> + partition@10 {
> + label = "U-Boot-Bank0";
> + reg = <0x10 0x1>;
> + uuid = 
> "a8f61787-5d68-4c9d-9e4a-37bb0df99da7";
> + };
> +
> + partition@12 {
> + label = "U-Boot-ENV-Bank0";
> + reg = <0x12 0x1>;
> + uuid = 
> "ea9d59af-e0e8-4ef5-9b16-4c80ff67524c";
> + };
> +
> + partition@14 {
> + label = "U-Boot-Bank1";
> + reg = <0x14 0x1>;
> + uuid = 
>

Re: [PATCH v5 23/23] sandbox: fwu: Add support for testing FWU feature on sandbox

2022-06-14 Thread Takahiro Akashi
ib/fwu_updates/fwu.c
> @@ -185,12 +185,22 @@ int fwu_boottime_checks(void)
>   return 0;
>   }
>  
> - if (efi_init_obj_list() != EFI_SUCCESS)
> - return 0;
> + /*
> +  * On the sandbox platform, the EFI variable
> +  * access is available only after binding the
> +  * disk image with the host interface. Skip
> +  * the Trial State check on sandbox.
> +  */
> + if (!IS_ENABLED(CONFIG_SANDBOX)) {
> + if (efi_init_obj_list() != EFI_SUCCESS)
> + return 0;
>  
> - ret = fwu_trial_state_check();
> - if (!ret)
> + ret = fwu_trial_state_check();
> + if (!ret)
> + boottime_check = 1;
> + } else {
>   boottime_check = 1;
> + }
>  
>   return 0;
>  }
> diff --git a/lib/fwu_updates/fwu_mtd.c b/lib/fwu_updates/fwu_mtd.c
> index 3137f8635c..3a9ad70203 100644
> --- a/lib/fwu_updates/fwu_mtd.c
> +++ b/lib/fwu_updates/fwu_mtd.c
> @@ -84,11 +84,11 @@ int fwu_get_mtd_alt_num(efi_guid_t *image_id, int 
> *alt_num,
>  int gen_image_alt_info(char *buf, size_t len, int sidx,
>  struct fwu_image_entry *img, struct mtd_info *mtd)
>  {
> - char *p = buf, *end = buf + len;
> - char uuidbuf[UUID_STR_LEN + 1];
> - ofnode node, parts_node;
> - const char *suuid;
>   int i;
> + const char *suuid;
> + ofnode node, parts_node;
> + char uuidbuf[UUID_STR_LEN + 1];
> + char *p = buf, *end = buf + len;
>  
>   /* Find partition node under given MTD device. */
>   parts_node = ofnode_by_compatible(mtd_get_ofnode(mtd),
> @@ -145,7 +145,7 @@ int gen_image_alt_info(char *buf, size_t len, int sidx,
>  
>  int fwu_gen_alt_info_from_mtd(char *buf, size_t len, struct mtd_info *mtd)
>  {
> - struct fwu_mdata *mdata;
> + struct fwu_mdata *mdata = NULL;
>   int i, l, ret;
>  
>   ret = fwu_get_mdata();
> diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py 
> b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py
> index 5bef84958b..93bc5ed44b 100644
> --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py
> +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py
> @@ -13,7 +13,6 @@ import pytest
>  from capsule_defs import *
>  
>  
> -@pytest.mark.boardspec('sandbox64')
>  @pytest.mark.boardspec('sandbox_flattree')
>  @pytest.mark.buildconfigspec('efi_capsule_firmware_fit')
>  @pytest.mark.buildconfigspec('efi_capsule_on_disk')
> diff --git a/test/py/tests/test_fwu_updates/capsule_defs.py 
> b/test/py/tests/test_fwu_updates/capsule_defs.py
> new file mode 100644
> index 00..59b40f11bd
> --- /dev/null
> +++ b/test/py/tests/test_fwu_updates/capsule_defs.py
> @@ -0,0 +1,10 @@
> +# SPDX-License-Identifier:  GPL-2.0+
> +
> +# Directories
> +CAPSULE_DATA_DIR = '/EFI/CapsuleTestData'
> +CAPSULE_INSTALL_DIR = '/EFI/UpdateCapsule'
> +
> +# v1.5.1 or earlier of efitools has a bug in sha256 calculation, and
> +# you need build a newer version on your own.
> +# The path must terminate with '/' if it is not null.
> +EFITOOLS_PATH = ''
> diff --git a/test/py/tests/test_fwu_updates/conftest.py 
> b/test/py/tests/test_fwu_updates/conftest.py
> new file mode 100644
> index 00..cdf824c3be
> --- /dev/null
> +++ b/test/py/tests/test_fwu_updates/conftest.py
> @@ -0,0 +1,78 @@
> +# SPDX-License-Identifier:  GPL-2.0+
> +# Copyright (c) 2020, Linaro Limited
> +# Author: AKASHI Takahiro 

If this file is exactly same as test_efi_capsule/conftest.py,
why not move all the tests (test_fwu_updates.py) to test_efi_capsule?

The basic scenario of updating firmware, u-boot.bin and u-boot.env,
is also the same, isn't it? The only difference is whether FWU_MULTI_BANK_UPDATE
is enabled or not.

-Takahiro Akashi

> +
> +import os
> +import os.path
> +import re
> +from subprocess import call, check_call, check_output, CalledProcessError
> +import pytest
> +from capsule_defs import *
> +
> +#
> +# Fixture for UEFI capsule test
> +#
> +
> +@pytest.fixture(scope='session')
> +def efi_capsule_data(request, u_boot_config):
> +"""Set up a file system to be used in UEFI capsule and
> +   authentication test.
> +
> +Args:
> +request: Pytest request object.
> +u_boot_config: U-boot configuration.
> +
> +Return:
> +A path to disk image to be used for testing
> +"""
> +global CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR
> +
> +mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule'
> +data_dir = mnt_point + CAPSULE_DATA_DIR
&

Re: [PATCH v5 11/23] mkeficapsule: Add support for generating empty capsules

2022-06-14 Thread Takahiro Akashi
le_file(f, , sizeof(payload),
> +"FW Accept Capsule Payload"))
> + goto err;
> + }
> +
> + ret = 0;
> +
> +err:
> + if (f)
> + fclose(f);
> +
> + return ret;
> +}
> +
>  /**
>   * main - main entry function of mkeficapsule
>   * @argc:Number of arguments
> @@ -639,22 +715,49 @@ int main(int argc, char **argv)
>   case 'd':
>   dump_sig = 1;
>   break;
> + case 'A':
> + capsule |= CAPSULE_ACCEPT;
> + break;
> + case 'R':
> + capsule |= CAPSULE_REVERT;
> + break;
>   case 'h':
>   print_usage();
>   exit(EXIT_SUCCESS);
>   }
>   }
>  
> + if (capsule == (CAPSULE_ACCEPT | CAPSULE_REVERT)) {
> + fprintf(stderr,
> + "Select either of Accept or Revert capsule 
> generation\n");
> + exit(EXIT_FAILURE);
> + }
> +
> + empty_capsule = (capsule == CAPSULE_ACCEPT ||
> +  capsule == CAPSULE_REVERT);
> +

So empty_capsule is redundant as empty_capsule is equivalent with
"capsule == CAPSULE_NORMAL_BLOB".
I think that a single variable, say capsule_type, is enough.

>   /* check necessary parameters */
> - if ((argc != optind + 2) || !guid ||
> - ((privkey_file && !cert_file) ||
> -  (!privkey_file && cert_file))) {
> + if ((!empty_capsule &&
> + ((argc != optind + 2) || !guid ||
> +  ((privkey_file && !cert_file) ||
> +   (!privkey_file && cert_file ||
> + (empty_capsule &&
> + ((argc != optind + 1) ||
> +  ((capsule == CAPSULE_ACCEPT) && !guid) ||
> +  ((capsule == CAPSULE_REVERT) && guid {
>   print_usage();
>   exit(EXIT_FAILURE);
>   }
>  
> - if (create_fwbin(argv[argc - 1], argv[argc - 2], guid, index, instance,
> -  mcount, privkey_file, cert_file) < 0) {
> + if (empty_capsule) {
> + if (create_empty_capsule(argv[argc - 1], guid,
> +  capsule == CAPSULE_ACCEPT) < 0) {

if (capsule_type != CAPSULE_NORMAL_BLOB)
create_empty_capsule(..., capsule_type == CAPSULE_ACCEPT);

Simple is the best :)

-Takahiro Akashi
> + fprintf(stderr, "Creating empty capsule failed\n");
> + exit(EXIT_FAILURE);
> + }
> + } else  if (create_fwbin(argv[argc - 1], argv[argc - 2], guid,
> +  index, instance, mcount, privkey_file,
> +  cert_file) < 0) {
>   fprintf(stderr, "Creating firmware capsule failed\n");
>   exit(EXIT_FAILURE);
>   }
> -- 
> 2.25.1
> 


Re: [PATCH v7 0/9] enable menu-driven UEFI variable maintenance

2022-06-14 Thread Takahiro Akashi
On Mon, Jun 13, 2022 at 06:38:44PM +0900, Masahisa Kojima wrote:
> This series add the menu-driven UEFI boot variable maintenance
> and removable media support in bootmenu.
> 
> Different from previous version, thie series adds a new U-Boot
> command "efimenu" to invoke the UEFI boot-related variable
> maintenance menu.

Thanks.
I'd like to give this command a more *specific* name rather than
just "menu" :)
For example, eficontrol or eficonfig.

The followings are my comments mostly from user's perspective (or
user-friendliness). So you may take them as improvements.

* make menuconfig, "provide menu-driven uefi variables maintenance feature"
  Please add the command name, so "efimenu - ..."
* the command can lead to a segmentation fault. I see it on sandbox.
  efi_init_obj_list() must always be called at the beginning.
* If no boot option is defined yet, "Edit/Order/Delete" menu's simply
  return to the top menu. I expect some (error) message here.
* This may happen even at "Add" if there is no block device.
* Boot options without file paths (mostly for removable disks)
  appear in "Change Order" only if "bootmenu" is executed beforehand.
  This looks weird.
* Some menu's have "Quit", others not.
  In some menu's, "Quit" means "quit without change" which is equivalent
  to "Esc". It looks a bit inconsistent.
* Some menu's have "Save", others not.
  For instance, "Change Order" should have explicit "Save" so that user may
  cancel the change.
* "Add"
  - The header line is "Edit Boot Option". -> Add Boot Option
  - Users may want to add an additional device path, especially for initrd.
* "Edit"
  - The header line is "Select Boot Order". -> Select Boot Option
  - If "Description" is selected, I expect the current value is
shown at editing screen.
  - If "File" is selected, I expect I can start with the last component
(i.e. a file path). This might be arguable, though.
  - Users may want to have a short-form path.
  - Users may want to have a file path without a device media path.
Now those variants for device path are acceptable in U-Boot implementation.
* "Change Boot Order"
  - Users may want to remove a boot option (for a removable disk) which
is automatically inserted by "bootmenu" from BootOrder.
(The given boot option may still exist as a variable.)
  - As I said above, "Save" and "Quit" should be shown.
* "Delete"
  - The header line is "Select Boot Order". -> Delete Boot Option

-Takahiro Akashi


> Note that menu-driven UEFI Secure Boot key management patch series
> will follow.
> 
> [Major Changes]
> - rebased to v2022.07-rc4
> - there is detailed changelog in each commit
> 
> Masahisa Kojima (9):
>   efi_loader: expose END device path node
>   efimenu: menu-driven addition of UEFI boot option
>   efimenu: add "Edit Boot Option" menu entry
>   menu: add KEY_PLUS and KEY_MINUS handling
>   efimenu: add "Change Boot Order" menu entry
>   efimenu: add "Delete Boot Option" menu entry
>   bootmenu: add removable media entries
>   doc:bootmenu: add description for UEFI boot support
>   doc:efimenu: add documentation for efimenu command
> 
>  cmd/Kconfig  |7 +
>  cmd/Makefile |1 +
>  cmd/bootmenu.c   |   99 +-
>  cmd/efimenu.c| 1824 ++
>  common/menu.c|6 +
>  doc/usage/cmd/bootmenu.rst   |   74 ++
>  doc/usage/cmd/efimenu.rst|   50 +
>  doc/usage/index.rst  |1 +
>  include/efi_loader.h |   63 ++
>  include/efi_menu.h   |   91 ++
>  include/menu.h   |2 +
>  lib/efi_loader/efi_boottime.c|   52 +-
>  lib/efi_loader/efi_console.c |   78 ++
>  lib/efi_loader/efi_device_path.c |2 +-
>  lib/efi_loader/efi_disk.c|   11 +
>  lib/efi_loader/efi_file.c|   75 +-
>  16 files changed, 2385 insertions(+), 51 deletions(-)
>  create mode 100644 cmd/efimenu.c
>  create mode 100644 doc/usage/cmd/efimenu.rst
>  create mode 100644 include/efi_menu.h
> 
> -- 
> 2.17.1
> 


Re: [PATCH v6 1/6] efi_loader: menu-driven addition of UEFI boot option

2022-05-24 Thread Takahiro Akashi
On Mon, May 16, 2022 at 08:00:37PM +0900, Masahisa Kojima wrote:
> This commit supports the menu-driven UEFI boot option addition.
> User can select the block device volume having
> efi_simple_file_system_protocol and select the file corresponding
> to the Boot variable. Then user enter the label of the BOOT
> variable in utf8.
> 
> Signed-off-by: Masahisa Kojima 
> ---
> Changes in v6:
> - fix typos
> - modify volume name to match U-Boot syntax
> - compile in CONFIG_EFI_LOADER=n and CONFIG_CMD_BOOTEFI_BOOTMGR=n

Is this correct?

> - simplify u16_strncmp() usage
> - support "a\b.efi" file path, use link list to handle filepath
> - modify length check condition
> - UEFI related menu items only appears with CONFIG_AUTOBOOT_MENU_SHOW=y

Why?
I think that the feature is useful even without AUTOBOOT.
As you know, efidebug is seen as a debugging tool and is not expected
to be enabled in production systems.

So the feature you're adding is the only available UI for boot manager.
What I recommend is
- to create a boot manager maintenance as a standalone U-Boot command,
- to add an bootmenu entry for invoking the command

> Changes in v5:
> - remove forward declarations
> - add const qualifier for menu items
> - fix the possible unaligned access for directory info access
> - split into three commit 1)add boot option 2) delete boot option 3)change 
> boot order
>   This commit is 1)add boot option.
> - fix file name buffer allocation size, it should be 
> EFI_BOOTMENU_FILE_PATH_MAX * sizeof(u16)
> - fix wrong size checking for file selection
> 
> Chanes in v4:
> - UEFI boot option maintenance menu is integrated into bootmenu
> - display the simplified volume name(e.g. usb0:1, nvme1:2) for the
>   volume selection
> - instead of extending lib/efi_loader/efi_bootmgr.c, newly create
>   lib/efi_loader/efi_bootmenu_maintenance.c and implement boot
>   variable maintenance into it.
> 
> Changes in RFC v3:
>  not included in v3 series
> 
> Changes in RFC v2:
> - enable utf8 user input for boot option name
> - create lib/efi_loader/efi_console.c::efi_console_get_u16_string() for
>   utf8 user input handling
> - use u16_strlcat instead of u16_strcat
> - remove the EFI_CALLs, and newly create or expose the following
>   xxx_int() functions.
> efi_locate_handle_buffer_int(), efi_open_volume_int(),
> efi_file_open_int(), efi_file_close_int(), efi_file_read_int() and
> efi_file_setpos_int().
>   Note that EFI_CALLs still exist for EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
>   and EFI_SIMPLE_TEXT_INPUT/OUTPUT_PROTOCOL
> - use efi_search_protocol() instead of calling locate_protocol() to get
>   the device_path_to_text_protocol interface.
> - remove unnecessary puts(ANSI_CLEAR_LINE), this patch is still depends on
>   puts(ANSI_CLEAR_CONSOLE)
> - skip SetVariable() if the bootorder is not changed
> 
>  cmd/bootmenu.c|  73 +-
>  include/efi_loader.h  |  37 +
>  lib/efi_loader/Makefile   |   3 +
>  lib/efi_loader/efi_bootmenu_maintenance.c | 906 ++

I would say that this file should be moved under /cmd as the code does not
implement any UEFI specification semantics, but simply provides helper
functions for bootmenu command.

Or I recommend that the boot manager be implemented as a standalone command
(as I insisted serveral times before) and the related maintenance feature
be invoked as follows:
   => efibootmanager -i (i for interactive)

>  lib/efi_loader/efi_boottime.c |  52 +-
>  lib/efi_loader/efi_console.c  |  81 ++
>  lib/efi_loader/efi_disk.c |  11 +
>  lib/efi_loader/efi_file.c |  75 +-
>  8 files changed, 1184 insertions(+), 54 deletions(-)
>  create mode 100644 lib/efi_loader/efi_bootmenu_maintenance.c
> 
> diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
> index 8859eebea5..4b846332b0 100644
> --- a/cmd/bootmenu.c
> +++ b/cmd/bootmenu.c
> @@ -19,6 +19,12 @@
>  
>  /* maximum bootmenu entries */
>  #define MAX_COUNT99
> +#if defined(CONFIG_CMD_BOOTEFI_BOOTMGR) && defined(CONFIG_AUTOBOOT_MENU_SHOW)
> +#define STATIC_ENTRY 2
> +#else
> +#define STATIC_ENTRY 1
> +#endif
> +#define MAX_DYNAMIC_ENTRY (MAX_COUNT - STATIC_ENTRY)
>  
>  /* maximal size of bootmenu env
>   *  9 = strlen("bootmenu_")
> @@ -38,10 +44,11 @@ enum boot_type {
>   BOOTMENU_TYPE_NONE = 0,
>   BOOTMENU_TYPE_BOOTMENU,
>   BOOTMENU_TYPE_UEFI_BOOT_OPTION,
> + BOOTMENU_TYPE_UEFI_MAINTENANCE,
>  };
>  
>  struct bootmenu_entry {
> - unsigned short int num; /* unique number 0 .. MAX_COUNT */
> + unsigned short int num; /* unique number 0 .. (MAX_COUNT - 1) */
>   char key[3];/* key identifier of number */
>   u16 *title; /* title of entry */
>   char *command;  /* hush command of entry */
> @@ -55,7 +62,7 @@ static char *bootmenu_getoption(unsigned short int n)
>  {
>   char name[MAX_ENV_SIZE];
>  
> 

Re: [PATCH v6 5/6] doc:bootmenu: add description for UEFI boot support

2022-05-17 Thread Takahiro Akashi
Kojima-san,

On Mon, May 16, 2022 at 08:00:41PM +0900, Masahisa Kojima wrote:
> The bootmenu enumerates the UEFI boot options
> for boot device selection.
> 
> This commit adds the description how the UEFI boot work
> in bootmenu. This commit also adds "Synopsis", "Description"
> and "Configuration" sections to follow the U-Boot command
> documentation format.
> 
> Signed-off-by: Masahisa Kojima 
> ---
> Changes in v6:
> - remove distro boot related contents because the distro boot
> support in bootmenu is dropped

? I rejected it in my comment.
I don't think we have enough consensus yet.

> - update uefi entry example
> - add [delay] argument of bootmenu command
> - add description to enable uefi boot entry
> 
> Changes in v5:
> - follow the cmd documentation format same as other command, add "Synopsis",
>   "Description" add "Configuration" sections
> 
> Newly created in v4
> 
>  doc/usage/cmd/bootmenu.rst | 55 ++
>  1 file changed, 55 insertions(+)
> 
> diff --git a/doc/usage/cmd/bootmenu.rst b/doc/usage/cmd/bootmenu.rst
> index 9430f8c9aa..6b154d9655 100644
> --- a/doc/usage/cmd/bootmenu.rst
> +++ b/doc/usage/cmd/bootmenu.rst
> @@ -4,6 +4,16 @@
>  bootmenu command
>  
>  
> +Synopsis
> +
> +
> +::
> +
> +bootmenu [delay]
> +
> +Description
> +---
> +
>  The "bootmenu" command uses U-Boot menu interfaces and provides
>  a simple mechanism for creating menus with different boot items.
>  The cursor keys "Up" and "Down" are used for navigation through
> @@ -79,6 +89,35 @@ The above example will be rendered as below::
>  The selected menu entry will be highlighted - it will have inverted
>  background and text colors.
>  
> +UEFI boot variable enumeration
> +''
> +
> +The bootmenu automatically generates the UEFI boot variable("BOOT")
> +in order of "BootOrder".

To be strict, the bootmenu command *does not* create UEFI boot variables
(except ones for removable media).
So, I would suggest you to modify the text like:

If enabled, the bootmenu command will automatically generate and add
UEFI-related boot menu entries for
* possible bootable media with default file names
* user-defined UEFI boot options

Then,

> +The bootmenu automatically enumerates the possible bootable
> +media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.
> +This auto generated entry is named as " :" format.
> +(e.g. "usb 0:1")
> +

> When the user selects the UEFI boot
> +variable entry, bootmenu sets the selected boot variable index
> +to "BootNext", then call the uefi boot manager with the command
> +"bootefi bootmgr".
> +
> +Example bootmenu is as below::
> +
> +*** U-Boot Boot Menu ***
> +
> +   mmc 0:1
> +   mmc 0:2
> +   debian
> +   nvme 0:1
> +   ubuntu
> +   nvme 0:2
> +   usb 0:2

If I understand your patch correctly, menus are initially sorted out
in the order of
* user-defined bootmenu_xxx variables
* removable bootable media
* user-defined UEFI boot options

The example above looks odd.

That said, it would be worth mentioning that users can changes the order
among UEFI-related menus. (Right?)

In addition, please describe the default action if users do not select
anything.

-Takahiro Akashi


> +
> +Configuration
> +-
> +
>  The "bootmenu" command is enabled by::
>  
>  CONFIG_CMD_BOOTMENU=y
> @@ -88,3 +127,19 @@ To run the bootmenu at startup add these additional 
> settings::
>  CONFIG_AUTOBOOT_KEYED=y
>  CONFIG_BOOTDELAY=30
>  CONFIG_AUTOBOOT_MENU_SHOW=y
> +
> +UEFI boot variable enumeration is enabled by::
> +
> +CONFIG_AUTOBOOT_MENU_SHOW=y
> +
> +To improve the product security, entering U-Boot console from bootmenu
> +can be disabled by::
> +
> +CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE=n
> +
> +To scan the discoverable devices connected to the buses such as
> +USB and PCIe prior to bootmenu showing up, CONFIG_PREBOOT can be
> +used to run the command before showing the bootmenu, i.e.::
> +
> +CONFIG_USE_PREBOOT=y
> +CONFIG_PREBOOT="pci enum; usb start; scsi scan; nvme scan; virtio scan"
> -- 
> 2.17.1
> 


Re: [PATCH v5 10/17] bootmenu: add distro boot entry

2022-05-12 Thread Takahiro Akashi
On Sun, May 01, 2022 at 11:48:40PM +0200, Heinrich Schuchardt wrote:
> On 4/28/22 10:09, Masahisa Kojima wrote:
> > This commit adds the distro_boot entries into the bootmenu.
> > The bootmenu read the "boot_targets" U-Boot environment variable
> > and enumerate it.
> > User can select the distro boot entry, then bootmenu executes
> > "run bootcmd_xxx" command.
> > 
> > The bootmenu also checks the existing block devices and network
> > option("dhcp" and "pxe") availability, then filter out
> > the "boot_targets" appeared in bootmenu.
> > 
> > The bootmenu example is as follows, distro boot entry has the
> > "distro_boot" prefix.
> > 
> >*** U-Boot Boot Menu ***
> > 
> >   distro_boot   : usb0
> >   distro_boot   : scsi0
> >   distro_boot   : virtio0
> >   distro_boot   : dhcp
> 
> You will be creating UEFI boot options for all block devices anyway.
> We should avoid duplicate entries. Please, drop this patch.

Nak
A distro entry should work, searching not only for a default UEFI file
but also sysboot (extlinux.conf) and boot scripts.

> Best regards
> 
> heinrich
> 
> > 
> > Signed-off-by: Masahisa Kojima 
> > ---
> > Changes in v5:
> > - split into the separate patch
> > - add function description comment
> > - handle the case boot_targets variable is empty
> > - filter out the non-exist device entry
> > 
> >   cmd/bootmenu.c | 177 +
> >   1 file changed, 177 insertions(+)
> > 
> > diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
> > index da688e6213..afe42b8041 100644
> > --- a/cmd/bootmenu.c
> > +++ b/cmd/bootmenu.c
> > @@ -7,6 +7,7 @@
> >   #include 
> >   #include 
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> >   #include 
> > @@ -14,6 +15,7 @@
> >   #include 
> >   #include 
> >   #include 
> > +#include 
> >   #include 
> >   #include 
> > 
> > @@ -31,6 +33,7 @@ enum boot_type {
> > BOOTMENU_TYPE_NONE = 0,
> > BOOTMENU_TYPE_BOOTMENU,
> > BOOTMENU_TYPE_UEFI_BOOT_OPTION,
> > +   BOOTMENU_TYPE_DISTRO_BOOT,
> >   };
> > 
> >   struct bootmenu_entry {
> > @@ -90,6 +93,8 @@ static void bootmenu_print_entry(void *data)
> > printf("bootmenu_%02d   : %ls", entry->bootorder, entry->title);
> > else if (entry->type == BOOTMENU_TYPE_UEFI_BOOT_OPTION)
> > printf("UEFI BOOT%04X : %ls", entry->bootorder, entry->title);
> > +   else if (entry->type == BOOTMENU_TYPE_DISTRO_BOOT)
> > +   printf("distro_boot   : %ls", entry->title);
> > else
> > printf("%ls", entry->title);
> > 
> > @@ -465,6 +470,172 @@ static int prepare_uefi_bootorder_entry(struct 
> > bootmenu_data *menu,
> > return 1;
> >   }
> > 
> > +static int is_blk_device_available(char *token)
> > +{
> > +   struct driver *d = ll_entry_start(struct driver, driver);
> > +   const int n_ents = ll_entry_count(struct driver, driver);
> > +   struct driver *entry;
> > +   struct udevice *udev;
> > +   struct uclass *uc;
> > +   struct blk_desc *desc;
> > +   int ret, i;
> > +   const char *if_type_name;
> > +
> > +   ret = uclass_get(UCLASS_BLK, );
> > +   if (ret)
> > +   return -ENODEV;
> > +
> > +   for (entry = d; entry < d + n_ents; entry++) {
> > +   if (entry->id != UCLASS_BLK)
> > +   continue;
> > +   i = 0;
> > +   uclass_foreach_dev(udev, uc) {
> > +   if (udev->driver != entry)
> > +   continue;
> > +   desc = dev_get_uclass_plat(udev);
> > +   if_type_name = blk_get_if_type_name(desc->if_type);
> > +   if (strncmp(token, if_type_name, strlen(if_type_name)) 
> > == 0) {
> > +   char *p;
> > +   int j, len;
> > +   int devnum = 0;
> > +
> > +   p = token + strlen(if_type_name);
> > +   len = strlen(p);
> > +   if (!len)
> > +   continue; /* no device number */
> > +
> > +   for (j = 0; j < len; j++) {
> > +   if (!isdigit(*p)) {
> > +   /* invalid device number */
> > +   devnum = INT_MAX;
> > +   break;
> > +   }
> > +   devnum = (devnum * 10) + (*p++ - '0');
> > +   }
> > +
> > +   if (devnum == INT_MAX)
> > +   continue;
> > +
> > +   if (devnum == desc->devnum)
> > +   return 1;
> > +   }
> > +   }
> > +   }
> > +
> > +   if (strncmp(token, "dhcp", strlen("dhcp")) == 0) {
> > +   if (IS_ENABLED(CONFIG_CMD_DHCP))
> > +   return 1;
> > +   }
> > +
> > +   if (strncmp(token, 

Re: [PATCH v4 00/11] enable menu-driven boot device selection

2022-03-24 Thread Takahiro Akashi
Kojima-san,

On Thu, Mar 24, 2022 at 10:54:32PM +0900, Masahisa Kojima wrote:
> This patch series adds the menu-driven boot device selection,
> by extending the existing "bootmenu" to include UEFI and distro_boot
> related entries, and supports menu-driven UEFI boot variable
> maintenance.
> 
> This patch series also includes the removable media support
> that UEFI specification requires to support.
> 
> The menu example is as follows.

Good job done, Kojima-san. I like it.
Before reviewing each commit, I would suggest a couple of
improvements on the menu itself.
They are more or less my opinion and other people may have
their own preference, though.

1) Top menu (U-Boot Boot Menu)
 - In general, it's a bit difficult to understand from where
   each menu item comes and what it means.
   For instance,
>  UEFI BOOT : debian
   is a user-defined boot option, while
>  UEFI BOOT0002 : mmc0:1
   is an option for removable media. Correct?

 - I'd prefer to categorize items into sub-menus, particularly,
   UEFI items.

   bootmenu_...
   distro_boot ...
   UEFI Boot
   UEFI Boot Manager Maintenance

   and "UEFI Boot" sub-menu shows
>  UEFI BOOT : debian
>  UEFI BOOT0001 : ubuntu
   in an order of "BootOrder",

   and
/* not selectable */
>  UEFI BOOT0002 : mmc0:1
>  UEFI BOOT0003 : mmc0:2
   
 - For UEFI items, I want to do "e" (edit/modify) directly here
   to change the option.

 - When "U-Boot console" is selected, the prompt ("=>") is displayed
   like
   UEFI Boot Manager Maintenance
U-Boot console=>
   It should be output at the beginning of the next line or
   the screen be cleaned up before showing the prompt.

 - What not have "Quit" here?

2) UEFI Boot Manager Maintenance
 - The title should be "UEFI Boot Manager Maintenance".
 - I want to have "Edit(Modify) Boot Option"
 - "Add Boot Option"
   - The menu titles should be "Select a device" and "Select a file".
   - Some devices are shown, some are not. Why?
 Do we have to run, say, "scsi rescan" beforehand?
   - How can we specify "removable media" without a file path?
   - At "file selection" menu, "Esc" should let us go back to
 the "device selection" menu rather than the top, "Add Boot Option".
   - We should be able to specify initrd path, i.e. the second device path
 in a boot option.
   - We should be able to specify "optional data" in a boot option.
 - "Change Boot Order"
   - I like a more intuitive operation here. Say,
 select an item with "Enter" and then use "Up" and "Down" to move it
 around.
 - Probably, it would be better to have the final confirmation, like
   "Do you want to save the change?"

Thanks,
-Takahiro Akashi

>   *** U-Boot Boot Menu ***
> 
>  bootmenu_00   : Boot 1. kernel
>  bootmenu_01   : Boot 2. kernel
>  bootmenu_02   : Reset board
>  UEFI BOOT : debian
>  UEFI BOOT0001 : ubuntu
>  UEFI BOOT0002 : mmc0:1
>  UEFI BOOT0003 : mmc0:2
>  UEFI BOOT0004 : nvme0:1
>  UEFI BOOT0005 : nvme0:2
>  UEFI BOOT0006 : usb0:2
>  UEFI BOOT0007 : usb1:1
>  UEFI BOOT0008 : usb1:2
>  distro_boot   : usb0
>  distro_boot   : scsi0
>  distro_boot   : virtio0
>  distro_boot   : dhcp
> 
>   Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit
> 
> [Major changes from RFC v3]
> - add Kconfig option to disable U-Boot console
> - add UEFI boot variable maintenance feature
> - support removable media support and user selection
> - app bootmenu enhancement documentation
> 
> [How to run on QEMU(arm64)]
> 1) clone source code
>  $ git clone https://git.linaro.org/people/masahisa.kojima/u-boot.git \
> -b kojima/bootmenu_v4_upstream_0324 --depth 1
> 
> 2) prepare U-Boot .config
>  $ make qemu_arm64_menuconfig
>   then, enable CONFIG_CMD_BOOTMENU and CONFIG_AUTOBOOT_MENU_SHOW
> 
> 3) run on QEMU(arm64) example
>  $ qemu-system-aarch64 -machine virt,gic-version=3 -cpu cortex-a57 -m 4G 
> -nographic \
>-no-acpi -bios ./u-boot.bin -hda xxx.img
> 
> 
> AKASHI Takahiro (2):
>   efi_loader: export efi_locate_device_handle()
>   efi_loader: bootmgr: add booting from removable media
> 
> Masahisa Kojima (9):
>   bootmenu: fix menu API error handling
>   lib/charset: add u16_strlcat() function
>   test: unit test for u16_strlcat()
>   menu: always show the menu regardless of the number or entry
>   bootmenu: add UEFI and disto_boot entries
>   bootmenu: factor out the user input handling
>   efi_loader: add menu-driven UEFI Boot Variable mai

Re: [RFC PATCH v3 2/2] bootmenu: add UEFI and disto_boot entries

2022-03-09 Thread Takahiro Akashi
On Thu, Mar 10, 2022 at 10:50:57AM +0900, Takahiro Akashi wrote:
> On Wed, Mar 09, 2022 at 04:34:42PM +0200, Ilias Apalodimas wrote:
> > Hi Kojima-san
> > 
> > On Tue, Mar 08, 2022 at 11:07:45PM +0900, Masahisa Kojima wrote:
> > > This commit adds the UEFI related menu entries and
> > > distro_boot entries into the bootmenu.
> > > 
> > > For UEFI, user can select which UEFI "Boot" option
> > > to execute, call UEFI bootmgr and UEFI boot variable
> > > maintenance menu. UEFI bootmgr entry is required to
> > > correctly handle "BootNext" variable.
> > 
> > Hmm why? (some more info further down)
> > 
> > > 
> > > For distro_boot, user can select the boot device
> > > included in "boot_targets" u-boot environment variable.
> > > 
> > > The menu example is as follows.
> > > 
> > >   *** U-Boot Boot Menu ***
> > > 
> > >  Boot 1. kernel (bootmenu_0)
> > >  Boot 2. kernel (bootmenu_1)
> > >  Reset board (bootmenu_2)
> > >  debian (BOOT)
> > >  ubuntu (BOOT0001)
> > >  UEFI Boot Manager
> > >  usb0
> > >  scsi0
> > >  virtio0
> > >  dhcp
> > >  UEFI Boot Manager Maintenance
> > >  U-Boot console
> > > 
> > >   Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit
> > > 
> > > Signed-off-by: Masahisa Kojima 
> > > ---
> > > Changes in v3:
> > > - newly created
> > > 
> > >  cmd/bootmenu.c | 268 +++--
> > >  1 file changed, 259 insertions(+), 9 deletions(-)
> > > 
> > > diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
> > > index 409ef9a848..a8dc50dcaa 100644
> > > --- a/cmd/bootmenu.c
> > > +++ b/cmd/bootmenu.c
> > > @@ -3,9 +3,12 @@
> > >   * (C) Copyright 2011-2013 Pali Rohár 
> > >   */
> > >  
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > @@ -24,11 +27,20 @@
> > >   */
> > >  #define MAX_ENV_SIZE (9 + 2 + 1)
> > >  
> > > +enum boot_type {
> > > + BOOT_TYPE_NONE = 0,
> > > + BOOT_TYPE_BOOTMENU,
> > > + BOOT_TYPE_UEFI,
> > > + BOOT_TYPE_DISTRO_BOOT,
> > > +};
> > > +
> > >  struct bootmenu_entry {
> > >   unsigned short int num; /* unique number 0 .. MAX_COUNT */
> > >   char key[3];/* key identifier of number */
> > > - char *title;/* title of entry */
> > > + u16 *title; /* title of entry */
> > >   char *command;  /* hush command of entry */
> > > + enum boot_type type;
> > > + u16 bootorder;
> > >   struct bootmenu_data *menu; /* this bootmenu */
> > >   struct bootmenu_entry *next;/* next menu entry (num+1) */
> > >  };
> > > @@ -75,7 +87,12 @@ static void bootmenu_print_entry(void *data)
> > >   if (reverse)
> > >   puts(ANSI_COLOR_REVERSE);
> > >  
> > > - puts(entry->title);
> > > + if (entry->type == BOOT_TYPE_BOOTMENU)
> > > + printf("%ls (bootmenu_%d)", entry->title, entry->bootorder);
> > > + else if (entry->type == BOOT_TYPE_UEFI)
> > > + printf("%ls (BOOT%04X)", entry->title, entry->bootorder);
> > > + else
> > > + printf("%ls", entry->title);
> > >  
> > >   if (reverse)
> > >   puts(ANSI_COLOR_RESET);
> > > @@ -87,6 +104,10 @@ static void bootmenu_autoboot_loop(struct 
> > > bootmenu_data *menu,
> > >   int i, c;
> > >  
> > >   if (menu->delay > 0) {
> > > + /* flush input */
> > > + while (tstc())
> > > + getchar();
> > > +
> > >   printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
> > >   printf("  Hit any key to stop autoboot: %2d ", menu->delay);
> > >   }
> > > @@ -300,6 +321,8 @@ static struct bootmenu_data *bootmenu_create(int 
> > > delay)
> > >   menu->active = (int)simple_strtol(default_str, NULL, 10);
> > >  
> > >   while ((option = bootmenu_getoption(i))) {
> > > + u1

Re: [RFC PATCH v3 2/2] bootmenu: add UEFI and disto_boot entries

2022-03-09 Thread Takahiro Akashi
gt; Why do we need an entire menu entry if the bootorder is not defined?
> Currently there's no logic in the efibootmgr to look for the standard
> filenames in the ESP (eg bootarm.efi, bootaa64.efi etc) if no boot option
> is defined.  Instead this is implement in distro_bootcmd.

To be clear, "if no boot option is defined" is wrong.
What the specification requires is that, if a file name is missing
in a device path defined in a boot option, a default path/name must be
appended to the path before trying to load an image from that media.

> I was thinking of something along the lines of:
> 1. bootmenu comes up
> 2. We read all the Boot variables that are defined and add them on the
>menu 
> 2a. If the user doesn't explicitly choose a boot option we run 'bootefi 
> bootmgr'
> 2b. If the user does select a different option we set BootNext and still
> run 'bootefi bootmgr'
> 3. If there's not Boot option defined,  we should in the future add the
>functionality of searching for bootaa64.efi etc in ESP and still just 
>launch the efi bootmgr
> 
> > +   /* Add UEFI Boot Manager entry if available */
> > +   if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
> > +   if (i <= MAX_COUNT - 1) {
> > +   entry = malloc(sizeof(struct bootmenu_entry));
> > +   if (!entry)
> > +   goto cleanup;
> > +
> > +   entry->title = u16_strdup(u"UEFI Boot Manager");
> > +   if (!entry->title) {
> > +   free(entry);
> > +   goto cleanup;
> > +   }
> > +
> > +   entry->command = strdup("bootefi bootmgr");
> > +   if (!entry->command) {
> > +   free(entry->title);
> > +   free(entry);
> > +   goto cleanup;
> > +   }
> > +
> > +   sprintf(entry->key, "%d", i);
> > +
> > +   entry->num = i;
> > +   entry->menu = menu;
> > +   entry->type = BOOT_TYPE_NONE;
> > +   entry->next = NULL;
> > +
> > +   if (!iter)
> > +   menu->first = entry;
> > +   else
> > +   iter->next = entry;
> > +
> > +   iter = entry;
> > +   ++i;
> > +   }
> > +   }
> > +
> > +{
> > +   char *p;
> > +   char *token;
> > +   char *boot_targets;
> > +   int len;
> > +
> > +   /* list the distro boot "boot_targets" */
> > +   boot_targets = env_get("boot_targets");
> > +   if (!boot_targets)
> > +   goto exit_boot_targets;
> > +
> > +   len = strlen(boot_targets);
> > +   p = calloc(1, len + 1);
> > +   strncpy(p, boot_targets, len);
> > +
> > +   token = strtok(p, " ");
> > +
> > +   do {
> > +   u16 *buf;
> > +   char *command;
> > +   int command_size;
> > +
> > +   entry = malloc(sizeof(struct bootmenu_entry));
> > +   if (!entry)
> > +   goto cleanup;
> > +
> > +   len = strlen(token);
> > +   buf = calloc(1, (len + 1) * sizeof(u16));
> > +   entry->title = buf;
> > +   if (!entry->title) {
> > +   free(entry);
> > +   goto cleanup;
> > +   }
> > +   utf8_utf16_strncpy(, token,len);
> > +   sprintf(entry->key, "%d", i);
> > +   entry->num = i;
> > +   entry->menu = menu;
> > +
> > +   command_size = strlen("run bootcmd_") + len + 1;
> 
> I think we are better of here with a sizeof() instead of strlen since the
> 'run bootcmd_' string is not expected to change
> 
> > +   command = calloc(1, command_size);
> > +   if (!command) {
> > +   free(entry->title);
> > +   free(entry);
> > +   goto cleanup;
> > +   }
> > +   snprintf(command, command_size, "run bootcmd_%s", token);
> > +   entry->command = command;
> > +   entry->type = BOOT_TYPE_DISTRO_BOOT;
> > entry->next = NULL;
> >  
> > if (!iter)
> > @@ -345,6 +552,48 @@ static struct bootmenu_data *bootmenu_create(int delay)

Re: [RFC PATCH v3 1/2] efi_loader: introduce "bootefi bootindex" command

2022-03-08 Thread Takahiro Akashi
On Wed, Mar 09, 2022 at 09:47:25AM +0900, Masahisa Kojima wrote:
> On Tue, 8 Mar 2022 at 23:17, Takahiro Akashi  
> wrote:
> >
> > On Tue, Mar 08, 2022 at 11:07:44PM +0900, Masahisa Kojima wrote:
> > > This commit introduces the new command "bootefi bootindex".
> > > With this command, user can select which "Boot" option
> > > to load and execute.
> >
> > You can do the same thing with:
> > $ efidebug boot next 1 (for BOOT0001)
> > $ bootefi bootmgr
> 
> Thank you for the information, it is good to know.
> My only concern is that user needs to enable "efidebug" command
> for this case, since efidebug implies that it is for debug purpose.

Yeah, that is the point where I and ex-maintainer have never agreed.
So we have no standard UI for UEFI subsystem on U-Boot until now.

Just FYI, we can do the same thing in yet another way :)
  => env set -e -nv -bs -rt BootNext =0x0001

Similarly, BootOrder as well.

-Takahiro Akashi

> Thanks,
> Masahisa Kojima
> 
> >
> > -Takahiro Akashi
> >
> >
> > > Signed-off-by: Masahisa Kojima 
> > > ---
> > > Changes in v3:
> > > - newly created
> > >
> > >  cmd/bootefi.c| 42 
> > >  include/efi_loader.h |  1 +
> > >  lib/efi_loader/efi_bootmgr.c |  7 +++---
> > >  3 files changed, 46 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> > > index 46eebd5ee2..df86438fec 100644
> > > --- a/cmd/bootefi.c
> > > +++ b/cmd/bootefi.c
> > > @@ -416,6 +416,30 @@ static int do_efibootmgr(void)
> > >   return CMD_RET_SUCCESS;
> > >  }
> > >
> > > +/**
> > > + * do_efibootindex() - load and execute the specified Boot option
> > > + *
> > > + * Return:   status code
> > > + */
> > > +static int do_efibootindex(u16 boot_index)
> > > +{
> > > + efi_handle_t handle;
> > > + efi_status_t ret;
> > > + void *load_options;
> > > +
> > > + ret = efi_try_load_entry(boot_index, , _options);
> > > + if (ret != EFI_SUCCESS) {
> > > + log_notice("EFI boot manager: failed to load Boot%04X\n", 
> > > boot_index);
> > > + return CMD_RET_FAILURE;
> > > + }
> > > +
> > > + ret = do_bootefi_exec(handle, load_options);
> > > +
> > > + if (ret != EFI_SUCCESS)
> > > + return CMD_RET_FAILURE;
> > > +
> > > + return CMD_RET_SUCCESS;
> > > +}
> > >  /**
> > >   * do_bootefi_image() - execute EFI binary
> > >   *
> > > @@ -654,6 +678,22 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int 
> > > flag, int argc,
> > >   return CMD_RET_FAILURE;
> > >   }
> > >
> > > + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
> > > + if (!strcmp(argv[1], "bootindex")) {
> > > + char *endp;
> > > + int boot_index;
> > > +
> > > + if (argc < 3)
> > > + return CMD_RET_USAGE;
> > > +
> > > + boot_index = (int)hextoul(argv[2], );
> > > + if (*endp != '\0' || boot_index > 0x)
> > > + return CMD_RET_USAGE;
> > > +
> > > + return do_efibootindex((u16)boot_index);
> > > + }
> > > + }
> > > +
> > >   if (argc > 2) {
> > >   uintptr_t fdt_addr;
> > >
> > > @@ -702,6 +742,8 @@ static char bootefi_help_text[] =
> > >   "\n"
> > >   "If specified, the device tree located at  gets\n"
> > >   "exposed as EFI configuration table.\n"
> > > + "bootefi bootindex \n"
> > > + "  - load and boot EFI payload based on the specified Boot 
> > > variable.\n"
> > >  #endif
> > >   ;
> > >  #endif
> > > diff --git a/include/efi_loader.h b/include/efi_loader.h
> > > index 80a5f1ec01..e5972f5fee 100644
> > > --- a/include/efi_loader.h
> > > +++ b/include/efi_loader.h
> > > @@ -861,6 +861,7 @@ efi_status_t efi_set_load_options(efi_handle_t handle,
> > > efi_uintn_t load_options_size,
> > >

Re: [RFC PATCH v3 1/2] efi_loader: introduce "bootefi bootindex" command

2022-03-08 Thread Takahiro Akashi
On Tue, Mar 08, 2022 at 11:07:44PM +0900, Masahisa Kojima wrote:
> This commit introduces the new command "bootefi bootindex".
> With this command, user can select which "Boot" option
> to load and execute.

You can do the same thing with:
$ efidebug boot next 1 (for BOOT0001)
$ bootefi bootmgr

-Takahiro Akashi


> Signed-off-by: Masahisa Kojima 
> ---
> Changes in v3:
> - newly created
> 
>  cmd/bootefi.c| 42 
>  include/efi_loader.h |  1 +
>  lib/efi_loader/efi_bootmgr.c |  7 +++---
>  3 files changed, 46 insertions(+), 4 deletions(-)
> 
> diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> index 46eebd5ee2..df86438fec 100644
> --- a/cmd/bootefi.c
> +++ b/cmd/bootefi.c
> @@ -416,6 +416,30 @@ static int do_efibootmgr(void)
>   return CMD_RET_SUCCESS;
>  }
>  
> +/**
> + * do_efibootindex() - load and execute the specified Boot option
> + *
> + * Return:   status code
> + */
> +static int do_efibootindex(u16 boot_index)
> +{
> + efi_handle_t handle;
> + efi_status_t ret;
> + void *load_options;
> +
> + ret = efi_try_load_entry(boot_index, , _options);
> + if (ret != EFI_SUCCESS) {
> + log_notice("EFI boot manager: failed to load Boot%04X\n", 
> boot_index);
> + return CMD_RET_FAILURE;
> + }
> +
> + ret = do_bootefi_exec(handle, load_options);
> +
> + if (ret != EFI_SUCCESS)
> + return CMD_RET_FAILURE;
> +
> + return CMD_RET_SUCCESS;
> +}
>  /**
>   * do_bootefi_image() - execute EFI binary
>   *
> @@ -654,6 +678,22 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
> int argc,
>   return CMD_RET_FAILURE;
>   }
>  
> + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
> + if (!strcmp(argv[1], "bootindex")) {
> + char *endp;
> + int boot_index;
> +
> + if (argc < 3)
> + return CMD_RET_USAGE;
> +
> + boot_index = (int)hextoul(argv[2], );
> + if (*endp != '\0' || boot_index > 0x)
> + return CMD_RET_USAGE;
> +
> + return do_efibootindex((u16)boot_index);
> + }
> + }
> +
>   if (argc > 2) {
>   uintptr_t fdt_addr;
>  
> @@ -702,6 +742,8 @@ static char bootefi_help_text[] =
>   "\n"
>   "If specified, the device tree located at  gets\n"
>   "exposed as EFI configuration table.\n"
> + "bootefi bootindex \n"
> + "  - load and boot EFI payload based on the specified Boot 
> variable.\n"
>  #endif
>   ;
>  #endif
> diff --git a/include/efi_loader.h b/include/efi_loader.h
> index 80a5f1ec01..e5972f5fee 100644
> --- a/include/efi_loader.h
> +++ b/include/efi_loader.h
> @@ -861,6 +861,7 @@ efi_status_t efi_set_load_options(efi_handle_t handle,
> efi_uintn_t load_options_size,
> void *load_options);
>  efi_status_t efi_bootmgr_load(efi_handle_t *handle, void **load_options);
> +efi_status_t efi_try_load_entry(u16 n, efi_handle_t *handle, void 
> **load_options);
>  
>  /**
>   * struct efi_image_regions - A list of memory regions
> diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
> index 8c04ecbdc8..a3060b5c62 100644
> --- a/lib/efi_loader/efi_bootmgr.c
> +++ b/lib/efi_loader/efi_bootmgr.c
> @@ -42,8 +42,7 @@ static const struct efi_runtime_services *rs;
>   * @load_options:load options set on the loaded image protocol
>   * Return:   status code
>   */
> -static efi_status_t try_load_entry(u16 n, efi_handle_t *handle,
> -void **load_options)
> +efi_status_t efi_try_load_entry(u16 n, efi_handle_t *handle, void 
> **load_options)
>  {
>   struct efi_load_option lo;
>   u16 varname[] = u"Boot";
> @@ -165,7 +164,7 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle, void 
> **load_options)
>   /* load BootNext */
>   if (ret == EFI_SUCCESS) {
>   if (size == sizeof(u16)) {
> - ret = try_load_entry(bootnext, handle,
> + ret = efi_try_load_entry(bootnext, handle,
>load_options);
>   if (ret == EFI_SUCCESS)
>   return ret;
> @@ -189,7 +188,7 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle, void 
> **load_options)
>   for (i = 0; i < num; i++) {
>   log_debug("%s trying to load Boot%04X\n", __func__,
> bootorder[i]);
> - ret = try_load_entry(bootorder[i], handle, load_options);
> + ret = efi_try_load_entry(bootorder[i], handle, load_options);
>   if (ret == EFI_SUCCESS)
>   break;
>   }
> -- 
> 2.17.1
> 


Re: [PATCH 2/3] mkeficapsule: Remove dtb related options

2021-07-16 Thread Takahiro Akashi
On Fri, Jul 16, 2021 at 02:57:54PM +0900, Masami Hiramatsu wrote:
> 2021年7月16日(金) 2:00 Ilias Apalodimas :
> >
> > commit 322c813f4bec ("mkeficapsule: Add support for embedding public key in 
> > a dtb")
> > added a bunch of options enabling the addition of the capsule public key
> > in a dtb.  Since now we embeded the key in U-Boot's .rodata we don't this
> > this functionality anymore
> 
> This looks good to me.
> 
> Reviewed-by: Masami Hiramatsu 
> 
> Thanks,
> 
> >
> > Signed-off-by: Ilias Apalodimas 
> > ---
> >  tools/mkeficapsule.c | 226 ++-
> >  1 file changed, 7 insertions(+), 219 deletions(-)
> >
> > diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
> > index de0a62898886..214dc38e46e3 100644
> > --- a/tools/mkeficapsule.c
> > +++ b/tools/mkeficapsule.c
> > @@ -4,14 +4,12 @@
> >   * Author: AKASHI Takahiro
> >   */
> >
> > -#include 
> >  #include 
> >  #include 
> >  #include 
> >  #include 
> >  #include 
> >  #include 
> > -#include 
> >  #include 
> >
> >  #include 

I didn't try the compilation, but I don't think
we need neither  nor "fdt_host.h".

-Takahiro Akashi

> > @@ -29,9 +27,6 @@ typedef __s32 s32;
> >
> >  #define aligned_u64 __aligned_u64
> >
> > -#define SIGNATURE_NODENAME "signature"
> > -#define OVERLAY_NODENAME   "__overlay__"
> > -
> >  #ifndef __packed
> >  #define __packed __attribute__((packed))
> >  #endif
> > @@ -52,9 +47,6 @@ static struct option options[] = {
> > {"raw", required_argument, NULL, 'r'},
> > {"index", required_argument, NULL, 'i'},
> > {"instance", required_argument, NULL, 'I'},
> > -   {"dtb", required_argument, NULL, 'D'},
> > -   {"public key", required_argument, NULL, 'K'},
> > -   {"overlay", no_argument, NULL, 'O'},
> > {"help", no_argument, NULL, 'h'},
> > {NULL, 0, NULL, 0},
> >  };
> > @@ -68,187 +60,10 @@ static void print_usage(void)
> >"\t-r, --rawnew raw image file\n"
> >"\t-i, --index  update image index\n"
> >"\t-I, --instanceupdate hardware instance\n"
> > -  "\t-K, --public-key  public key esl file\n"
> > -  "\t-D, --dtb dtb file\n"
> > -  "\t-O, --overlay   the dtb file is an overlay\n"
> >"\t-h, --help  print a help message\n",
> >tool_name);
> >  }
> >
> > -static int fdt_add_pub_key_data(void *sptr, void *dptr, size_t key_size,
> > -   bool overlay)
> > -{
> > -   int parent;
> > -   int ov_node;
> > -   int frag_node;
> > -   int ret = 0;
> > -
> > -   if (overlay) {
> > -   /*
> > -* The signature would be stored in the
> > -* first fragment node of the overlay
> > -*/
> > -   frag_node = fdt_first_subnode(dptr, 0);
> > -   if (frag_node == -FDT_ERR_NOTFOUND) {
> > -   fprintf(stderr,
> > -   "Couldn't find the fragment node: %s\n",
> > -   fdt_strerror(frag_node));
> > -   goto done;
> > -   }
> > -
> > -   ov_node = fdt_subnode_offset(dptr, frag_node, 
> > OVERLAY_NODENAME);
> > -   if (ov_node == -FDT_ERR_NOTFOUND) {
> > -   fprintf(stderr,
> > -   "Couldn't find the __overlay__ node: %s\n",
> > -   fdt_strerror(ov_node));
> > -   goto done;
> > -   }
> > -   } else {
> > -   ov_node = 0;
> > -   }
> > -
> > -   parent = fdt_subnode_offset(dptr, ov_node, SIGNATURE_NODENAME);
> > -   if (parent == -FDT_ERR_NOTFOUND) {
> > -   parent = fdt_add_subnode(dptr, ov_node, SIGNATURE_NODENAME);
> > -   if (parent < 0) {
> > -   ret = parent;
> > -   if (ret != -FDT_ERR_NOSPACE) {
> > -   fprintf(stderr,
> > -  

Re: [PATCH 1/3] efi_capsule: Move signature from DTB to .rodata

2021-07-16 Thread Takahiro Akashi
 +extern char __efi_capsule_sig_begin[];
> > +extern char __efi_capsule_sig_end[];
> >
> >  /* Private data used by of-platdata devices/uclasses */
> >  extern char __priv_data_start[], __priv_data_end[];
> > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> > index 156b39152112..42f1292fa04b 100644
> > --- a/lib/efi_loader/Kconfig
> > +++ b/lib/efi_loader/Kconfig
> > @@ -213,6 +213,12 @@ config EFI_CAPSULE_AUTHENTICATE
> >   Select this option if you want to enable capsule
> >   authentication
> >
> > +config EFI_CAPSULE_KEY_PATH
> > +   string "Path to .esl file for capsule authentication"
> > +   depends on EFI_CAPSULE_AUTHENTICATE
> > +   help
> > + Provide the .esl file used for capsule authentication

We might be friendly if we add what "esl" means here.
More importantly, we are able to contain more than one signatures
if we want.

> > +
> >  config EFI_DEVICE_PATH_TO_TEXT
> > bool "Device path to text protocol"
> > default y
> > diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
> > index fd344cea29b0..9b369430e258 100644
> > --- a/lib/efi_loader/Makefile
> > +++ b/lib/efi_loader/Makefile
> > @@ -20,11 +20,19 @@ always += helloworld.efi
> >  targets += helloworld.o
> >  endif
> >
> > +ifeq ($(CONFIG_EFI_CAPSULE_AUTHENTICATE),y)
> > +EFI_CAPSULE_KEY_PATH := $(subst $\",,$(CONFIG_EFI_CAPSULE_KEY_PATH))
> > +ifeq ("$(wildcard $(EFI_CAPSULE_KEY_PATH))","")
> > +$(error .esl cerificate not found. Configure your 
> > CONFIG_EFI_CAPSULE_KEY_PATH)
> > +endif
> > +endif
> > +
> >  obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
> >  obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += efi_bootmgr.o
> >  obj-y += efi_boottime.o
> >  obj-y += efi_helper.o
> >  obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o
> > +obj-$(CONFIG_EFI_CAPSULE_AUTHENTICATE) += efi_capsule_key.o

We should give users another choice here to allow them to add their
own solution for key storage.
Or only enable this line if "CONFIG_EFI_CAPSULE_KEY_PATH" != null?

> >  obj-$(CONFIG_EFI_CAPSULE_FIRMWARE) += efi_firmware.o
> >  obj-y += efi_console.o
> >  obj-y += efi_device_path.o
> > diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
> > index b878e71438b8..50e93cad4ee5 100644
> > --- a/lib/efi_loader/efi_capsule.c
> > +++ b/lib/efi_loader/efi_capsule.c
> > @@ -16,6 +16,7 @@
> >  #include 
> >  #include 
> >
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -222,12 +223,23 @@ skip:
> >  const efi_guid_t efi_guid_capsule_root_cert_guid =
> > EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
> >
> > +int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len)

static?

> > +{
> > +   const void *blob = __efi_capsule_sig_begin;
> > +   const int len = __efi_capsule_sig_end - __efi_capsule_sig_begin;

It seems that the length can be calculated at compile time.

> > +   *pkey = (void *)blob;
> > +   *pkey_len = len;
> > +
> > +   return 0;
> > +}
> > +
> >  efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t 
> > capsule_size,
> >   void **image, efi_uintn_t *image_size)
> >  {
> > u8 *buf;
> > int ret;
> > -   void *fdt_pkey, *pkey;
> > +   void *stored_pkey, *pkey;
> > efi_uintn_t pkey_len;
> > uint64_t monotonic_count;
> > struct efi_signature_store *truststore;
> > @@ -286,7 +298,7 @@ efi_status_t efi_capsule_authenticate(const void 
> > *capsule, efi_uintn_t capsule_s
> > goto out;
> > }
> >
> > -   ret = efi_get_public_key_data(_pkey, _len);
> > +   ret = efi_get_public_key_data(_pkey, _len);
> > if (ret < 0)
> > goto out;
> >
> > @@ -294,7 +306,7 @@ efi_status_t efi_capsule_authenticate(const void 
> > *capsule, efi_uintn_t capsule_s
> > if (!pkey)
> > goto out;
> >
> > -   memcpy(pkey, fdt_pkey, pkey_len);
> > +   memcpy(pkey, stored_pkey, pkey_len);
> > truststore = efi_build_signature_store(pkey, pkey_len);
> > if (!truststore)
> > goto out;
> > diff --git a/lib/efi_loader/efi_capsule_key.S 
> > b/lib/efi_loader/efi_capsule_key.S
> > new file mode 100644
> > index ..f7047a42e39d
> > --- /dev/null
> > +++ b/lib/efi_loader/efi_capsule_key.S
> > @@ -0,0 +1,8 @@

Should we have "#include " here?
Otherwise it looks good.

-Takahiro Akashi

> > +.section .rodata.capsule_key.init,"a"
> > +.balign 16
> > +.global __efi_capsule_sig_begin
> > +__efi_capsule_sig_begin:
> > +.incbin CONFIG_EFI_CAPSULE_KEY_PATH
> > +__efi_capsule_sig_end:
> > +.global __efi_capsule_sig_end
> > +.balign 16
> > --
> > 2.32.0.rc0
> >
> 
> 
> --
> Masami Hiramatsu


Re: [PATCH v6 1/3] lib: fix build error for secure boot and capsule authentication

2021-05-13 Thread Takahiro Akashi
On Thu, May 13, 2021 at 04:18:29PM +0900, Masahisa Kojima wrote:
> Build error occurs when CONFIG_EFI_SECURE_BOOT or
> CONFIG_EFI_CAPSULE_AUTHENTICATE is enabled,
> because hash-checksum.c is not compiled.
> 
> This commit adds hash-checksum.c as a compilation target
> if CONFIG_EFI_SECURE_BOOT or CONFIG_EFI_CAPSULE_AUTHENTICATE
> is enabled.
> 
> Signed-off-by: Masahisa Kojima 
> ---
> 
> Changes in v6:
> - update lib/Makefile to compile hash-checksum.c, instead of
>   selecting FIT_SIGNATURE in secure boot and capsule authentication.
> 
> Changes in v5:
> - Missing option for EFI_TCG2_PROTOROL already added in different commit.
>   This commit adds FIT_SIGNATURE only.
> 
> Changes in v4:
> - newly added in this patch series, due to rebasing
>   the base code.
> 
>  lib/Makefile | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/Makefile b/lib/Makefile
> index 6825671955..bd022dd5d3 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -61,7 +61,10 @@ endif
>  obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi/
>  obj-$(CONFIG_$(SPL_)MD5) += md5.o
>  obj-$(CONFIG_$(SPL_)RSA) += rsa/
> -obj-$(CONFIG_FIT_SIGNATURE) += hash-checksum.o
> +ifneq (,$(filter y,$(CONFIG_FIT_SIGNATURE)$(CONFIG_EFI_SECURE_BOOT)\
> +$(CONFIG_EFI_CAPSULE_AUTHENTICATE)))
> +obj-y += hash-checksum.o
> +endif

Why not create a new kconfig option here?
There is a good reason to do so if there are more than one users.

Otherwise, every new user of hash_calculate() needs
to modify generic Makefile.


-Takahiro Akashi


>  obj-$(CONFIG_SHA1) += sha1.o
>  obj-$(CONFIG_SHA256) += sha256.o
>  obj-$(CONFIG_SHA512_ALGO) += sha512.o
> -- 
> 2.17.1
> 


Re: [PATCH v3 1/2] efi_loader: expose efi_image_parse() even if UEFI Secure Boot is disabled

2021-05-09 Thread Takahiro Akashi
On Mon, May 10, 2021 at 09:49:03AM +0900, Masahisa Kojima wrote:
> Hi Heinrich,
> 
> Sorry for the late reply.
> 
> On Sat, 8 May 2021 at 23:08, Heinrich Schuchardt  wrote:
> >
> > On 4/28/21 3:16 PM, Heinrich Schuchardt wrote:
> > > On 28.04.21 14:19, Masahisa Kojima wrote:
> > 
> > >>   /**
> > >>* cmp_pe_section() - compare virtual addresses of two PE image 
> > >> sections
> > >>* @arg1:  pointer to pointer to first section header
> > >> @@ -504,6 +565,9 @@ static bool efi_image_authenticate(void *efi, size_t 
> > >> efi_size)
> > >>
> > >>  EFI_PRINT("%s: Enter, %d\n", __func__, ret);
> > >>
> > >> +if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> > >> +return true;
> > >> +
> > >
> > > Why is this needed? Doesn't efi_secure_boot_enabled() return false in
> > > this case?
> 
> The original code is as follows.

Heinrich's concern was, I guess, that

> > >> +if (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
> > >> +return true;

and the succeeding check,

if (!efi_secure_boot_enabled())
return true;

are somehow redundant.
But in the latter case, I'm afraid that a compiler cannot optimize out
the rest of the logic in efi_image_authenticate().

-Takahiro Akashi


> #ifdef CONFIG_EFI_SECURE_BOOT
> static bool efi_image_authenticate(void *efi, size_t efi_size) {
> 
>   < snip >
> 
>  }
> #else
> static bool efi_image_authenticate(void *efi, size_t efi_size)
> {
>return true;
> }
> #endif /* CONFIG_EFI_SECURE_BOOT */
> 
> The purpose of this commit is removing #if compilation switch,
> so I keep the original implementation, always return true
> if CONFIG_EFI_SECURE_BOOT is disabled.
> 
> Thanks,
> Masahisa
> 
> >
> > Hello Masahisa,
> >
> > I did not see any reply yet. Was a mail lost?
> >
> > Best regards
> >
> > Heinrich


Re: [PATCH v2 12/13] doc: qemu: arm64: Fix the documentation of capsule update

2021-04-20 Thread Takahiro Akashi
Heinrich, Sughosh,

On Mon, Apr 19, 2021 at 04:35:15AM +0200, Heinrich Schuchardt wrote:
> Am 19. April 2021 04:24:37 MESZ schrieb Masami Hiramatsu 
> :
> >Hi,
> >
> >2021年4月19日(月) 9:37 Takahiro Akashi :
> >>
> >> Sughosh,
> >>
> >> On Sun, Apr 18, 2021 at 01:37:58PM +0530, Sughosh Ganu wrote:
> >> > On Sat, 17 Apr 2021 at 23:51, Heinrich Schuchardt
> >
> >> > wrote:
> >> >
> >> > > On 4/17/21 1:39 AM, Masami Hiramatsu wrote:
> >> > > > Since the EDK2 GenerateCapsule script is out of date and it
> >> > > > doesn't generate the supported version capsule file, the
> >document
> >> > > > should refer the mkeficapsule in tools.
> >> > > >
> >> > > > Signed-off-by: Masami Hiramatsu 
> >> > > > ---
> >> > > >   doc/board/emulation/qemu_capsule_update.rst |   11
> >++-
> >> > > >   1 file changed, 2 insertions(+), 9 deletions(-)
> >> > > >
> >> > > > diff --git a/doc/board/emulation/qemu_capsule_update.rst
> >> > > b/doc/board/emulation/qemu_capsule_update.rst
> >> > > > index 9fec75f8f1..e2a9f0db71 100644
> >> > > > --- a/c
> >> > > > +++ b/doc/board/emulation/qemu_capsule_update.rst
> >> > > > @@ -39,16 +39,9 @@ In addition, the following config needs to
> >be
> >> > > disabled(QEMU ARM specific)::
> >> > > >
> >> > > >   CONFIG_TFABOOT
> >> > > >
> >> > > > -The capsule file can be generated by using the
> >GenerateCapsule.py
> >> > > > -script in EDKII::
> >> > > > -
> >> > > > -$ ./BaseTools/BinWrappers/PosixLike/GenerateCapsule -e -o
> >\
> >> > > > - --fw-version  --lsv  --guid
> >\
> >> > > > -e2bb9c06-70e9-4b14-97a3-5a7913176e3f --verbose
> >--update-image-index
> >> > > \
> >> > > > - --verbose 
> >> > > > +The capsule file can be generated by using the
> >tools/mkeficapsule::
> >> > > >
> >> > > > -The above is a wrapper script(GenerateCapsule) which
> >eventually calls
> >> > > > -the actual GenerateCapsule.py script.
> >> > > > +$ mkeficapsule --raw  --index 1
> >
> >> > >
> >> > > Thanks for the change.
> >> > >
> >> > > Could you, please, adjust the same in chapter "Enabling Capsule
> >> > > Authentication" below.
> >
> >So as Sughosh said, since currently mkeficapsule doesn't support
> >authentication,
> >I only changed it for the normal capsule update. Without this change,
> >the capsule
> >update just failed.
> >
> >
> >> > Currently, we do not have support for adding authentication header
> >to the
> >> > capsule. This is because I have been using the GenerateCapsule
> >script in
> >> > edk2 for generation of a capsule with authentication header. I
> >think adding
> >> > the signature to the capsule is easier when done through a python
> >script
> >> > rather than C code.
> >>
> >> Why do you think so?
> >> At a quick glance at the script, it internally uses openssl command
> >like:
> >> openssl smime -sign -binary -outform DER -md sha256 \
> >> -signer <...> -certfile <...>
> >> (See PayloadDescriptor.Encode in the script.)
> >>
> >> The output from the standard output is exactly what you want
> >> to use to build a capsule file, that is "AuthInfo".
> >> Then you can naturally extend mkeficapsule to insert this signature
> >> between the header and the image itself in a capsule file.
> >
> >Hmm, if it can be done by just calling openssl, I think it is easier
> >for me
> >to run the tools/mkeficapsule, because I don't need to build EDK2
> >for U-Boot.
> >
> >If GenerateCapsule becomes a standard implementation and
> >independent from the EDK2 project, from the interoperability point
> >of view, it is better to use that. But it is a part of EDK2 and the
> >GenerateCapsule seems out-of-date and not maintained well
> >(why doesn't it support the latest version yet??)
> 
> Sughosh told me that EDK II cannot create a signed capsule that is usable 
> with U-Boot due to an outdated header version used 

Re: [PATCH v2 12/13] doc: qemu: arm64: Fix the documentation of capsule update

2021-04-18 Thread Takahiro Akashi
Sughosh,

On Sun, Apr 18, 2021 at 01:37:58PM +0530, Sughosh Ganu wrote:
> On Sat, 17 Apr 2021 at 23:51, Heinrich Schuchardt 
> wrote:
> 
> > On 4/17/21 1:39 AM, Masami Hiramatsu wrote:
> > > Since the EDK2 GenerateCapsule script is out of date and it
> > > doesn't generate the supported version capsule file, the document
> > > should refer the mkeficapsule in tools.
> > >
> > > Signed-off-by: Masami Hiramatsu 
> > > ---
> > >   doc/board/emulation/qemu_capsule_update.rst |   11 ++-
> > >   1 file changed, 2 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/doc/board/emulation/qemu_capsule_update.rst
> > b/doc/board/emulation/qemu_capsule_update.rst
> > > index 9fec75f8f1..e2a9f0db71 100644
> > > --- a/c
> > > +++ b/doc/board/emulation/qemu_capsule_update.rst
> > > @@ -39,16 +39,9 @@ In addition, the following config needs to be
> > disabled(QEMU ARM specific)::
> > >
> > >   CONFIG_TFABOOT
> > >
> > > -The capsule file can be generated by using the GenerateCapsule.py
> > > -script in EDKII::
> > > -
> > > -$ ./BaseTools/BinWrappers/PosixLike/GenerateCapsule -e -o \
> > > - --fw-version  --lsv  --guid \
> > > -e2bb9c06-70e9-4b14-97a3-5a7913176e3f --verbose --update-image-index
> > \
> > > - --verbose 
> > > +The capsule file can be generated by using the tools/mkeficapsule::
> > >
> > > -The above is a wrapper script(GenerateCapsule) which eventually calls
> > > -the actual GenerateCapsule.py script.
> > > +$ mkeficapsule --raw  --index 1 
> >
> > Thanks for the change.
> >
> > Could you, please, adjust the same in chapter "Enabling Capsule
> > Authentication" below.
> >
> 
> Currently, we do not have support for adding authentication header to the
> capsule. This is because I have been using the GenerateCapsule script in
> edk2 for generation of a capsule with authentication header. I think adding
> the signature to the capsule is easier when done through a python script
> rather than C code.

Why do you think so?
At a quick glance at the script, it internally uses openssl command like:
openssl smime -sign -binary -outform DER -md sha256 \
-signer <...> -certfile <...>
(See PayloadDescriptor.Encode in the script.)

The output from the standard output is exactly what you want
to use to build a capsule file, that is "AuthInfo".
Then you can naturally extend mkeficapsule to insert this signature
between the header and the image itself in a capsule file.

Furthermore, I believe, it is fairly straightforward to add a native
'signing' feature to mkeficapsule if you use openssl library.

-Takahiro Akashi


> I am working on adding support for the latest version
> of the EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER in the GenerateCapsule
> script in edk2. Meanwhile, would it be possible to have support for the
> version 2 of this header in the capsule driver -- it is a minor change and
> I already have a patch for it. If you are fine, I can submit a patch for
> the same.
> 
> -sughosh
> 
> 
> >
> > Best regards
> >
> > Heinrich
> >
> > >
> > >   As per the UEFI specification, the capsule file needs to be placed on
> > >   the EFI System Partition, under the \EFI\UpdateCapsule directory. The
> > >
> >
> >


Re: [PATCH 11/13] board: synquacer: Add DeveloperBox 96boards EE support

2021-04-14 Thread Takahiro Akashi
On Wed, Apr 14, 2021 at 03:29:23PM +0900, Masami Hiramatsu wrote:
> Hi Takahiro,
> 
> 2021年4月14日(水) 13:48 Takahiro Akashi :
> >
> > > > So why not define UEFI load options (BOOT) and use UEFI boot manager
> > > > ("bootefi bootmgr")?
> > > > That is the way how UEFI (at least boot manager) boots the kernel.
> > >
> > > Good point! Actually, I'm not sure how to define the BOOT in
> > > config.h (I only
> > > know how to include efivars file when build). Could you tell me how to do 
> > > it?
> > > I would like to rewrite the default boot commands.
> >
> > For example,
> > => efidebug boot add 1 USBBOOT usb 0:1 /EFI/BOOT/bootaa64.efi 
> > => efidebug boot add 2 MMCBOOT mmc 0:1 /EFI/BOOT/bootaa64.efi 
> > => efidebug boot order 1 2
> > => bootefi bootmgr
> 
> Hmm, but this can not be embedded in the build process, can this?

Probably there are a couple of ways;
You may put them in "pre_boot_environment_command" if you don't mind :)

But it would be best to run them as part of OS installation process.
Or you may want to provide a default efivars file(?).

> >
> > Since "BOOTxxx" are non-volatile variables, we don't have to
> > set them again once those commands are run.
> 
> What is the default behavior of "bootefi bootmgr" if there is no
> BOOT is set?

Nothing will happen.

> If it just do nothing and exit, I think I can add it to the top of
> CONFIG_BOOTCOMMAND
> so that U-Boot can try it first.
> (BOOT will be set by user after boot)
> 
> > But distro_bootcmd can also detect and try to boot "bootaa64.efi" anyway.
> > (I'm not sure about the order of devices to detect though.)
> 
> Hmm, interesting. OK, I'll try to enable distro_bootcmd.

I'm pretty sure it will work.

-Takahiro Akashi

> Thank you,
> 
> >
> > -Takahiro Akashi
> >
> > > Thank you,
> > >
> > > --
> > > Masami Hiramatsu
> 
> 
> 
> -- 
> Masami Hiramatsu


Re: [PATCH 11/13] board: synquacer: Add DeveloperBox 96boards EE support

2021-04-13 Thread Takahiro Akashi
On Wed, Apr 14, 2021 at 11:06:36AM +0900, Masami Hiramatsu wrote:
> Hi Takahiro,
> 
> 2021年4月14日(水) 10:27 Takahiro Akashi :
> >
> > On Wed, Apr 14, 2021 at 10:12:42AM +0900, Masami Hiramatsu wrote:
> > > Hello Tom,
> > >
> > > 2021年4月14日(水) 2:47 Tom Rini :
> > > >
> > > > On Wed, Apr 14, 2021 at 12:31:21AM +0900, Masami Hiramatsu wrote:
> > > >
> > > > > Add the DeveloperBox 96boards EE support. This board is also
> > > > > known as Socionext SynQuacer E-Series. It contians one "SC2A11"
> > > > > SoC, which has 24-cores of arm Cortex-A53, and 4 DDR3 slots,
> > > > > 3 PCIe slots (1 4x port and 2 1x ports which are expanded via
> > > > > PCIe bridge chip), 2 USB 3.0 ports and 2 USB 2.0 ports, 2 SATA
> > > > > ports and 1 GbE, 64MB NOR flash and 8GB eMMC on standard
> > > > > MicroATX Form Factor.
> > > > >
> > > > > For more information, see this page;
> > > > >   https://www.96boards.org/product/developerbox/
> > > > >
> > > > > Signed-off-by: Masami Hiramatsu 
> > > > [snip]
> > > > > diff --git a/arch/arm/include/asm/arch-sc2a11/gpio.h 
> > > > > b/arch/arm/include/asm/arch-sc2a11/gpio.h
> > > > > new file mode 100644
> > > > > index 00..6779803080
> > > > > --- /dev/null
> > > > > +++ b/arch/arm/include/asm/arch-sc2a11/gpio.h
> > > > > @@ -0,0 +1,9 @@
> > > > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > > > +/*
> > > > > + * Copyright 2021 (C) Linaro Ltd.
> > > > > + */
> > > > > +
> > > > > +#ifndef __ASM_ARCH_SC2A11_GPIO_H
> > > > > +#define __ASM_ARCH_SC2A11_GPIO_H
> > > > > +
> > > > > +#endif
> > > >
> > > > Please update the list in arch/arm/include/asm/gpio.h to not look for
> > > > asm/arch/gpio.h on this SoC, thanks.
> > >
> > > Ah, I missed that. OK, I'll change arch/arm/include/asm/gpio.h.
> > >
> > > BTW, isn't it better to introduce CONFIG_ARCH_GENERIC_GPIO
> > > instead of updating the header?
> > >
> > > > > diff --git a/board/socionext/developerbox/README 
> > > > > b/board/socionext/developerbox/README
> > > > > new file mode 100644
> > > > > index 00..bb121002dd
> > > > > --- /dev/null
> > > > > +++ b/board/socionext/developerbox/README
> > > >
> > > > This needs to be in rST form and under doc/board/ now.
> > > >
> > > > [snip]
> > > > > +/*
> > > > > + * arguments for booti command
> > > > > + */
> > > > > +#define LINUX_BASIC_BOOTARGS "basic_bootargs='"  
> > > > > \
> > > > > + "console=ttyAMA0," 
> > > > > __stringify(CONFIG_BAUDRATE) " " \
> > > > > + "rootwait verbose'\0"
> > > > > +
> > > > > +/* kernel:mmcblk0p1(ext2), rootfs:mmcblk0p1(ext2), 
> > > > > devtree:mmcblk0p1(ext2) */
> > > > > +#define  LINUX_MMCBOOTCOMMAND1   
> > > > > \
> > > > > + "mmcboot1=echo 'Boot from MMC (ext2 single rootfs)' ; " 
> > > > > \
> > > > > + "mmc dev 0 &&"  
> > > > > \
> > > > > + "ext2load mmc 0:1 ${kernel_addr} /boot/Image && "   
> > > > > \
> > > > > + "ext2load mmc 0:1 ${fdt_addr_base} 
> > > > > /boot/DeveloperBox.dtb && "  \
> > > > > + "setenv fdt_addr ${fdt_addr_base} &&"   
> > > > > \
> > > > > + "setenv fdt_size ${filesize} &&"
> > > > > \
> > > > > + "setenv bootargs ${mmc_bootargs1} && "  
> > > > > \
> > > > > + "booti ${kernel_addr} - ${fdt_addr}\0"  
> > > > > \
> > > > > + "mmc_bootar

Re: [PATCH 11/13] board: synquacer: Add DeveloperBox 96boards EE support

2021-04-13 Thread Takahiro Akashi
On Wed, Apr 14, 2021 at 10:12:42AM +0900, Masami Hiramatsu wrote:
> Hello Tom,
> 
> 2021年4月14日(水) 2:47 Tom Rini :
> >
> > On Wed, Apr 14, 2021 at 12:31:21AM +0900, Masami Hiramatsu wrote:
> >
> > > Add the DeveloperBox 96boards EE support. This board is also
> > > known as Socionext SynQuacer E-Series. It contians one "SC2A11"
> > > SoC, which has 24-cores of arm Cortex-A53, and 4 DDR3 slots,
> > > 3 PCIe slots (1 4x port and 2 1x ports which are expanded via
> > > PCIe bridge chip), 2 USB 3.0 ports and 2 USB 2.0 ports, 2 SATA
> > > ports and 1 GbE, 64MB NOR flash and 8GB eMMC on standard
> > > MicroATX Form Factor.
> > >
> > > For more information, see this page;
> > >   https://www.96boards.org/product/developerbox/
> > >
> > > Signed-off-by: Masami Hiramatsu 
> > [snip]
> > > diff --git a/arch/arm/include/asm/arch-sc2a11/gpio.h 
> > > b/arch/arm/include/asm/arch-sc2a11/gpio.h
> > > new file mode 100644
> > > index 00..6779803080
> > > --- /dev/null
> > > +++ b/arch/arm/include/asm/arch-sc2a11/gpio.h
> > > @@ -0,0 +1,9 @@
> > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > +/*
> > > + * Copyright 2021 (C) Linaro Ltd.
> > > + */
> > > +
> > > +#ifndef __ASM_ARCH_SC2A11_GPIO_H
> > > +#define __ASM_ARCH_SC2A11_GPIO_H
> > > +
> > > +#endif
> >
> > Please update the list in arch/arm/include/asm/gpio.h to not look for
> > asm/arch/gpio.h on this SoC, thanks.
> 
> Ah, I missed that. OK, I'll change arch/arm/include/asm/gpio.h.
> 
> BTW, isn't it better to introduce CONFIG_ARCH_GENERIC_GPIO
> instead of updating the header?
> 
> > > diff --git a/board/socionext/developerbox/README 
> > > b/board/socionext/developerbox/README
> > > new file mode 100644
> > > index 00..bb121002dd
> > > --- /dev/null
> > > +++ b/board/socionext/developerbox/README
> >
> > This needs to be in rST form and under doc/board/ now.
> >
> > [snip]
> > > +/*
> > > + * arguments for booti command
> > > + */
> > > +#define LINUX_BASIC_BOOTARGS "basic_bootargs='"  
> > > \
> > > + "console=ttyAMA0," 
> > > __stringify(CONFIG_BAUDRATE) " " \
> > > + "rootwait verbose'\0"
> > > +
> > > +/* kernel:mmcblk0p1(ext2), rootfs:mmcblk0p1(ext2), 
> > > devtree:mmcblk0p1(ext2) */
> > > +#define  LINUX_MMCBOOTCOMMAND1   
> > > \
> > > + "mmcboot1=echo 'Boot from MMC (ext2 single rootfs)' ; " 
> > > \
> > > + "mmc dev 0 &&"  
> > > \
> > > + "ext2load mmc 0:1 ${kernel_addr} /boot/Image && "   
> > > \
> > > + "ext2load mmc 0:1 ${fdt_addr_base} /boot/DeveloperBox.dtb 
> > > && "  \
> > > + "setenv fdt_addr ${fdt_addr_base} &&"   
> > > \
> > > + "setenv fdt_size ${filesize} &&"
> > > \
> > > + "setenv bootargs ${mmc_bootargs1} && "  
> > >     \
> > > + "booti ${kernel_addr} - ${fdt_addr}\0"  
> > > \
> > > + "mmc_bootargs1="
> > > \
> > > + "root=/dev/mmcblk0p1 rw dtb=0x${fdt_addr},0x${fdt_size} "   
> > > \
> > > + "${basic_bootargs} \0"
> >
> > You are strongly encouraged to use the generic distro boot features
> > instead.  This may require a little work to handle the device tree.
> 
> OK, anyway I can just drop it, because this platform is expected to use
> UEFI boot (the DeveloperBox is shipped with EDK2).
> I left this just for reference.

So why not define UEFI load options (BOOT) and use UEFI boot manager
("bootefi bootmgr")?
That is the way how UEFI (at least boot manager) boots the kernel.

-Takahiro Akashi

> Thank you,
> 
> -- 
> Masami Hiramatsu


Re: [PATCH v3 7/8] efi_loader: signature: rework for intermediate

2020-07-16 Thread Takahiro Akashi
On Thu, Jul 16, 2020 at 11:39:36AM +, REITHER Robert - Contractor wrote:
> Hi,
> 
> I think I have found a bug in
> lib/efi_loader/efi_signature.c
> 
> efi_verify_certificate()
> 
> + cert = 
> x509_cert_parse(sig_data->data, sig_data->size);
> + if (!cert) {
> +
> EFI_PRINT("Cannot parse x509 certificate\n");
> +continue;
> + }
> 
> 
> x509_cert_parse() not only returns a pointer, but also embed a linux 
> error_code, so if an error happens there, the (!cert) check will fail!
> 
> I suggest using:
> 
> -  if (!cert) {
> +if (IS_ERR(cert)) {

That's correct.
Can you post a fix patch, please?

# There was the same problem with pkcs7_parse_message(),
# and I have fixed it before.

Thanks,
-Takahiro Akashi

> 
> Regards
> Robert


Re: [RFC PATCH 4/4] qemu: arm64: Add support for efi firmware management protocol routines

2020-03-30 Thread Takahiro Akashi
Sughosh,

On Mon, Mar 23, 2020 at 12:42:01PM +0530, Sughosh Ganu wrote:
> Add support for the get_image_info and set_image routines, which are
> part of the efi firmware management protocol.
> 
> The current implementation uses the set_image routine for updating the
> u-boot binary image for the qemu arm64 platform. This is supported
> using the capsule-on-disk feature of the uefi specification, wherein
> the firmware image to be updated is placed on the efi system partition
> as a efi capsule under EFI/UpdateCapsule/ directory.
> 
> Signed-off-by: Sughosh Ganu 
> ---
>  board/emulation/qemu-arm/Kconfig|  12 ++
>  board/emulation/qemu-arm/Makefile   |   1 +
>  board/emulation/qemu-arm/qemu_efi_fmp.c | 173 
>  3 files changed, 186 insertions(+)
>  create mode 100644 board/emulation/qemu-arm/qemu_efi_fmp.c
> 
> diff --git a/board/emulation/qemu-arm/Kconfig 
> b/board/emulation/qemu-arm/Kconfig
> index 02ae4d9884..1ef2a27539 100644
> --- a/board/emulation/qemu-arm/Kconfig
> +++ b/board/emulation/qemu-arm/Kconfig
> @@ -11,3 +11,15 @@ config BOARD_SPECIFIC_OPTIONS # dummy
>   imply VIRTIO_BLK
>  
>  endif
> +
> +if TARGET_QEMU_ARM_64BIT
> +
> +config EFI_FIRMWARE_MANAGEMENT_PROTOCOL

I think that we should give it a qemu-specific configuration name
as there can co-exist multiple drivers of FMP at the same time.

> + bool "EFI Firmware Management protocol for Qemu arm64 platform"
> + depends on EFI_CAPSULE_UPDATE && EFI_CAPSULE_UPDATE_FIRMWARE

Please add a dependency on SEMIHOSTING with some description.

> + default n
> + help
> +   Select this option for enabling firmware management protocol
> +   for qemu arm64 platform
> +
> +endif
> diff --git a/board/emulation/qemu-arm/Makefile 
> b/board/emulation/qemu-arm/Makefile
> index a22d1237ff..c95ac6d233 100644
> --- a/board/emulation/qemu-arm/Makefile
> +++ b/board/emulation/qemu-arm/Makefile
> @@ -1,3 +1,4 @@
>  # SPDX-License-Identifier: GPL-2.0+
>  
>  obj-y+= qemu-arm.o
> +obj-$(CONFIG_EFI_FIRMWARE_MANAGEMENT_PROTOCOL) += qemu_efi_fmp.o
> diff --git a/board/emulation/qemu-arm/qemu_efi_fmp.c 
> b/board/emulation/qemu-arm/qemu_efi_fmp.c
> new file mode 100644
> index 00..17caa59786
> --- /dev/null
> +++ b/board/emulation/qemu-arm/qemu_efi_fmp.c
> @@ -0,0 +1,173 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2020, Linaro Limited
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define QEMU_UBOOT_IMAGE_INDEX   0x1
> +#define QEMU_UBOOT_IMAGE 0x1
> +
> +#define UBOOT_FILE   "bl33.bin"

It would be better to parameterize this file name as
a configuration option so as to make this solution more generic
for TFA-based and non-TFA-based system.

-Takahiro Akashi

> +static efi_status_t EFIAPI qemu_arm64_fmp_get_image_info(
> + struct efi_firmware_management_protocol *this,
> + efi_uintn_t *image_info_size,
> + struct efi_firmware_image_descriptor *image_info,
> + u32 *desc_version, u8 *desc_count,
> + efi_uintn_t *desc_size, u32 *package_version,
> + u16 **package_version_name)
> +{
> + efi_status_t status = EFI_SUCCESS;
> + u16 *image_id_name;
> + const char *image_name = "Qemu Aarch64 U-Boot";
> + const efi_guid_t image_guid = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
> +
> + EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this, image_info_size,
> +   image_info, desc_version, desc_count, desc_size,
> +   package_version, package_version_name);
> +
> + /* Sanity checks */
> + if (*image_info_size && !image_info) {
> + status = EFI_INVALID_PARAMETER;
> + goto back;
> + }
> +
> + if (*image_info_size &&
> + (!desc_version || !desc_count || !desc_size)) {
> + status = EFI_INVALID_PARAMETER;
> + goto back;
> + }
> +
> + if (*image_info_size && (!package_version || !package_version_name)) {
> + status = EFI_INVALID_PARAMETER;
> + goto back;
> + }
> +
> + if (*image_info_size < sizeof(*image_info)) {
> + *image_info_size = sizeof(*image_info);
> + status = EFI_BUFFER_TOO_SMALL;
> + goto back;
> + }
> +
> + if (desc_version)
> + *desc_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
> +
> + *desc_count = 0x1;
> + *desc_size = sizeof(*image_info);
> +
> + if (package_version)
> + *package_version = 0x;
> +
> + if (pa

Re: [RFC PATCH 1/4] efidebug: capsule: Add a command to update capsule on disk

2020-03-30 Thread Takahiro Akashi
On Tue, Mar 24, 2020 at 09:19:55AM +0530, Sughosh Ganu wrote:
> On Mon, 23 Mar 2020 at 17:20, Heinrich Schuchardt 
> wrote:
> 
> > On 3/23/20 8:11 AM, Sughosh Ganu wrote:
> > > Add a efidebug subcommand to initiate a firmware update using the efi
> > > firmware management protocol(fmp) set_image routine.
> > >
> > > The firmware update can be initiated through
> > >
> > > 'efidebug capsule disk-update'
> > >
> > > This would locate the efi capsule file on the efi system partition,
> > > and call the platform's set_image fmp routine to initiate the firmware
> > > update.
> >
> > Hello Sughosh,
> >
> > why do we need this command? Shouldn't a simple reset do the job?
> >
> > See chapter 8.5.5 "Delivery of Capsules via file on Mass Storage device"
> > of UEFI spec 2.8.
> >
> 
> Like i have mentioned in the cover letter, we need to invoke
> capsule-on-disk update during the platform boot -- that is on the Todo
> list. The spec requires setting the
> EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED flag in the
> OsIndications variable. But we would not be supporting that, at least for
> now, since we do not have support of runtime variables on our platforms.
> The idea is to invoke a capsule-on-disk update during the platform boot. I
> think Takahiro will be working on this.

To be strict,
under my current implementation, all the capsule files under
\EFI\UpdateCapsule will be applied only at the first time when
any of UEFI-related commands is invoked.
This is the way how the UEFI subsystem is initialized on U-Boot.

I mentioned this in my cover letter, and how we should comply
with UEFI specification and meet users' expectation is a point
of discussion as RFC. 

UpdateCapsule API is provided, but it is more or less an internal
function in the current form so as to directly initiate capsule
handling. It currently ignores CAPSULE_FLAGS_PERSIST_ACROSS_RESET
and CAPSULE_FLAGS_INITIATE_RESET in a capsule.
(I mentioned this in TODO list.)

> 
> >
> > What might be of interest is a command to start a capsule from a memory
> > location. This would allow to load capsules from other locations than
> > directory \EFI\UpdateCapsule.
> >
> 
> Takahiro has indeed added this command which updates a capsule which has
> been loaded into the memory. I thought it might be easier to invoke a
> command where the user is not required to load the capsule into memory
> first, but that is taken care of directly by the capsule update logic. That
> said, I can drop the patch if you prefer just having the version which
> updates the capsule from memory.

"efidebug capsule" command, like other subcommands of efidebug,
is a tool mainly for test/debug purpose.
Keep the functionality in the command won't bother anyone
in that sense.

-Takahiro Akashi


> -sughosh
> 
> 
> >
> > Best regards
> >
> > Heinrich
> >
> > >
> > > Signed-off-by: Sughosh Ganu 
> > > ---
> > >  cmd/efidebug.c | 14 ++
> > >  1 file changed, 14 insertions(+)
> > >
> > > diff --git a/cmd/efidebug.c b/cmd/efidebug.c
> > > index 4a7661d0ac..fd8366dc90 100644
> > > --- a/cmd/efidebug.c
> > > +++ b/cmd/efidebug.c
> > > @@ -77,6 +77,16 @@ static int do_efi_capsule_update(cmd_tbl_t *cmdtp,
> > int flag,
> > >   return CMD_RET_SUCCESS;
> > >  }
> > >
> > > +static int do_efi_capsule_on_disk_update(cmd_tbl_t *cmdtp, int flag,
> > > +  int argc, char * const argv[])
> > > +{
> > > + efi_status_t ret;
> > > +
> > > + ret = efi_launch_capsules();
> > > +
> > > + return ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
> > > +}
> > > +
> > >  /**
> > >   * do_efi_capsule_show() - show capsule information
> > >   *
> > > @@ -205,6 +215,8 @@ static cmd_tbl_t cmd_efidebug_capsule_sub[] = {
> > >"", ""),
> > >   U_BOOT_CMD_MKENT(show, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_show,
> > >"", ""),
> > > + U_BOOT_CMD_MKENT(disk-update, 0, 0, do_efi_capsule_on_disk_update,
> > > +  "", ""),
> > >   U_BOOT_CMD_MKENT(result, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_res,
> > >"", ""),
> > >  };
> > > @@ -1387,6 +1399,8 @@ static char efidebug_help_text[] =
> > >  #ifdef CONFIG_EFI_CAPSULE_UPDATE
> > >   "efidebug capsule update [-v] \n"
> > >   "  - process a capsule\n"
> > > + "efidebug capsule disk-update\n"
> > > + "  - update a capsule from disk\n"
> > >   "efidebug capsule show \n"
> > >   "  - show capsule information\n"
> > >   "efidebug capsule result []\n"
> > >
> >
> >


Re: [U-Boot] [PATCH v4 1/1] efi_loader: add RuntimeServicesSupported variable

2019-06-16 Thread Takahiro Akashi
On Fri, Jun 14, 2019 at 06:30:38PM +0200, Heinrich Schuchardt wrote:
> From: AKASHI Takahiro 
> 
> This variable is defined in UEFI specification 2.8, section 8.1.
> Its value should be updated whenever we add any usable runtime services
> function.
> 
> Currently we only support SetVirtualAddress() for all systems and
> ResetSystem() for some.
> 
> Signed-off-by: AKASHI Takahiro 
> Reviewed-by: Heinrich Schuchardt 

Please make clear who changed what.

> ---
> v4
>   CONFIG_IS_ENABLED() wants Kconfig variables without CONFIG_ prefix.

This macro is intended for CONFIG_SPL_XXX as well.
For UEFI, however, we won't support UEFI in SPL.

-Takahiro Akashi

> v3
>   Ensure that efi_runtime_services_supported is initialized.
> v2
>   Currently we only support SetVirtualAddress() for all systems and
>   ResetSystem() for some.
> ---
>  include/efi_api.h| 15 +++
>  include/efi_loader.h |  3 +++
>  lib/efi_loader/efi_runtime.c | 24 
>  lib/efi_loader/efi_setup.c   |  5 +
>  4 files changed, 47 insertions(+)
> 
> diff --git a/include/efi_api.h b/include/efi_api.h
> index 65584dd2d8..d7d95edd4d 100644
> --- a/include/efi_api.h
> +++ b/include/efi_api.h
> @@ -213,6 +213,21 @@ struct efi_capsule_header {
>   u32 capsule_image_size;
>  };
> 
> +#define EFI_RT_SUPPORTED_GET_TIME0x0001
> +#define EFI_RT_SUPPORTED_SET_TIME0x0002
> +#define EFI_RT_SUPPORTED_GET_WAKEUP_TIME 0x0004
> +#define EFI_RT_SUPPORTED_SET_WAKEUP_TIME 0x0008
> +#define EFI_RT_SUPPORTED_GET_VARIABLE0x0010
> +#define EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME  0x0020
> +#define EFI_RT_SUPPORTED_SET_VARIABLE0x0040
> +#define EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP 0x0080
> +#define EFI_RT_SUPPORTED_CONVERT_POINTER 0x0100
> +#define EFI_RT_SUPPORTED_GET_NEXT_HIGH_MONOTONIC_COUNT   0x0200
> +#define EFI_RT_SUPPORTED_RESET_SYSTEM0x0400
> +#define EFI_RT_SUPPORTED_UPDATE_CAPSULE  0x0800
> +#define EFI_RT_SUPPORTED_QUERY_CAPSULE_CAPABILITIES  0x1000
> +#define EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO 0x2000
> +
>  struct efi_runtime_services {
>   struct efi_table_hdr hdr;
>   efi_status_t (EFIAPI *get_time)(struct efi_time *time,
> diff --git a/include/efi_loader.h b/include/efi_loader.h
> index f0e1313f93..b07155cecb 100644
> --- a/include/efi_loader.h
> +++ b/include/efi_loader.h
> @@ -573,6 +573,9 @@ static inline int guidcmp(const efi_guid_t *g1, const 
> efi_guid_t *g2)
>  #define __efi_runtime_data __attribute__ ((section (".data.efi_runtime")))
>  #define __efi_runtime __attribute__ ((section (".text.efi_runtime")))
> 
> +/* Indicate supported runtime services */
> +efi_status_t efi_init_runtime_supported(void);
> +
>  /* Update CRC32 in table header */
>  void __efi_runtime efi_update_table_header_crc32(struct efi_table_hdr 
> *table);
> 
> diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
> index 432551d0c8..0c57d0abd7 100644
> --- a/lib/efi_loader/efi_runtime.c
> +++ b/lib/efi_loader/efi_runtime.c
> @@ -89,6 +89,30 @@ struct elf_rela {
>   * handle a good number of runtime callbacks
>   */
> 
> +efi_status_t efi_init_runtime_supported(void)
> +{
> + u16 efi_runtime_services_supported = 0;
> +
> + /*
> +  * This value must be synced with efi_runtime_detach_list
> +  * as well as efi_runtime_services.
> +  */
> +#if CONFIG_IS_ENABLED(ARCH_BCM283X) || \
> +CONFIG_IS_ENABLED(FSL_LAYERSCAPE) || \
> +CONFIG_IS_ENABLED(SYSRESET_X86) || \
> +CONFIG_IS_ENABLED(PSCI_RESET)
> + efi_runtime_services_supported |= EFI_RT_SUPPORTED_RESET_SYSTEM;
> +#endif
> + efi_runtime_services_supported |=
> + EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP;
> + return EFI_CALL(efi_set_variable(L"RuntimeServicesSupported",
> +  _global_variable_guid,
> +  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +  EFI_VARIABLE_RUNTIME_ACCESS,
> +  sizeof(efi_runtime_services_supported),
> +  _runtime_services_supported));
> +}
> +
>  /**
>   * efi_update_table_header_crc32() - Update crc32 in table header
>   *
> diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
> index 8691d686d2..bfb57836fa 100644
> --- a/lib/efi_loader/efi_setup.c
> +++ b/lib/efi_loader/efi_setup.c
> @@ -117,6 +117,11 @

Re: [U-Boot] [PATCH v2 1/1] efi_loader: unload applications upon Exit()

2019-05-07 Thread Takahiro Akashi
On Wed, May 08, 2019 at 02:59:08AM +0200, Heinrich Schuchardt wrote:
> On 5/8/19 1:59 AM, Takahiro Akashi wrote:
> >On Tue, May 07, 2019 at 09:13:24PM +0200, Heinrich Schuchardt wrote:
> >>Implement unloading of images in the Exit() boot services:
> >>
> >>* unload images that are not yet started,
> >>* unload started applications,
> >>* unload drivers returning an error.
> >>
> >>Signed-off-by: Heinrich Schuchardt 
> >>---
> >>v2
> >>Images that are no yet started can be unloaded by calling Exit().
> >>In this case they are not the current image. Move the test for
> >>current down in the code.
> >>
> >>A started driver that called Exit() should still be considered a
> >>started image. Exit cannot be called by another image afterwards,
> >>cf. UEFI SCT 2.6 (2017), 3.5.1 Exit(), 5.1.4.5.8 - 5.1.4.5.10.
> >>---
> >>  include/efi_loader.h  |  1 +
> >>  lib/efi_loader/efi_boottime.c | 36 +--
> >>  lib/efi_loader/efi_image_loader.c |  2 ++
> >>  3 files changed, 33 insertions(+), 6 deletions(-)
> >>
> >>diff --git a/include/efi_loader.h b/include/efi_loader.h
> >>index 3b50cd28ef..4e4cffa799 100644
> >>--- a/include/efi_loader.h
> >>+++ b/include/efi_loader.h
> >>@@ -234,6 +234,7 @@ struct efi_loaded_image_obj {
> >>struct jmp_buf_data exit_jmp;
> >>EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
> >> struct efi_system_table *st);
> >>+   u16 image_type;
> >>  };
> >>
> >>  /**
> >>diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> >>index 0385883ded..1ea96dab6c 100644
> >>--- a/lib/efi_loader/efi_boottime.c
> >>+++ b/lib/efi_loader/efi_boottime.c
> >>@@ -13,6 +13,7 @@
> >>  #include 
> >>  #include 
> >>  #include 
> >>+#include 
> >>  #include 
> >>
> >>  DECLARE_GLOBAL_DATA_PTR;
> >>@@ -2798,7 +2799,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> >>image_handle,
> >> *   image protocol.
> >> */
> >>efi_status_t ret;
> >>-   void *info;
> >>+   struct efi_loaded_image *loaded_image_protocol;
> >>struct efi_loaded_image_obj *image_obj =
> >>(struct efi_loaded_image_obj *)image_handle;
> >>
> >>@@ -2806,13 +2807,33 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> >>image_handle,
> >>  exit_data_size, exit_data);
> >>
> >>/* Check parameters */
> >>-   if (image_handle != current_image)
> >>-   goto out;
> >>ret = EFI_CALL(efi_open_protocol(image_handle, _guid_loaded_image,
> >>-, NULL, NULL,
> >>+(void **)_image_protocol,
> >>+NULL, NULL,
> >> EFI_OPEN_PROTOCOL_GET_PROTOCOL));
> >>-   if (ret != EFI_SUCCESS)
> >>+   if (ret != EFI_SUCCESS) {
> >>+   ret = EFI_INVALID_PARAMETER;
> >>goto out;
> >>+   }
> >>+
> >>+   /* Unloading of unstarted images */
> >>+   switch (image_obj->header.type) {
> >>+   case EFI_OBJECT_TYPE_STARTED_IMAGE:
> >>+   break;
> >>+   case EFI_OBJECT_TYPE_LOADED_IMAGE:
> >>+   efi_delete_image(image_obj, loaded_image_protocol);
> >>+   ret = EFI_SUCCESS;
> >>+   goto out;
> >>+   default:
> >>+   /* Handle does not refer to loaded image */
> >>+   ret = EFI_INVALID_PARAMETER;
> >>+   goto out;
> >>+   }
> >>+   /* A started image can only be unloaded it is the last one started. */
> >>+   if (image_handle != current_image) {
> >>+   ret = EFI_INVALID_PARAMETER;
> >>+   goto out;
> >>+   }
> >>
> >>/* Exit data is only foreseen in case of failure. */
> >>if (exit_status != EFI_SUCCESS) {
> >>@@ -2822,6 +2843,9 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> >>image_handle,
> >>if (ret != EFI_SUCCESS)
> >>EFI_PRINT("%s: out of memory\n", __func__);
> >>}
> >>+   if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION ||
> >>+   exit_status != EFI_SUCCESS)
> >>+   efi_delete_image(image_obj, loaded_image_protocol);
> >
> >No change around efi_delete_image() and "goto" above?
> >
> 
> Do you see a bug?
> 
> A diff would help me to understand what you would like to change.

You said:
>> For me, your code is much unreadable.
>> Moreover, I remember that you have said, in a review of my patch, that
>> we should use "goto" only in error cases.
>
>Good point. So the check must be after handling
>EFI_OBJECT_TYPE_LOADED_IMAGE.
>
>I will revise the patch.

-Takahiro Akashi

> Best regards
> 
> Heinrich
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2 1/1] efi_loader: unload applications upon Exit()

2019-05-07 Thread Takahiro Akashi
On Tue, May 07, 2019 at 09:13:24PM +0200, Heinrich Schuchardt wrote:
> Implement unloading of images in the Exit() boot services:
> 
> * unload images that are not yet started,
> * unload started applications,
> * unload drivers returning an error.
> 
> Signed-off-by: Heinrich Schuchardt 
> ---
> v2
>   Images that are no yet started can be unloaded by calling Exit().
>   In this case they are not the current image. Move the test for
>   current down in the code.
> 
>   A started driver that called Exit() should still be considered a
>   started image. Exit cannot be called by another image afterwards,
>   cf. UEFI SCT 2.6 (2017), 3.5.1 Exit(), 5.1.4.5.8 - 5.1.4.5.10.
> ---
>  include/efi_loader.h  |  1 +
>  lib/efi_loader/efi_boottime.c | 36 +--
>  lib/efi_loader/efi_image_loader.c |  2 ++
>  3 files changed, 33 insertions(+), 6 deletions(-)
> 
> diff --git a/include/efi_loader.h b/include/efi_loader.h
> index 3b50cd28ef..4e4cffa799 100644
> --- a/include/efi_loader.h
> +++ b/include/efi_loader.h
> @@ -234,6 +234,7 @@ struct efi_loaded_image_obj {
>   struct jmp_buf_data exit_jmp;
>   EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
>struct efi_system_table *st);
> + u16 image_type;
>  };
> 
>  /**
> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> index 0385883ded..1ea96dab6c 100644
> --- a/lib/efi_loader/efi_boottime.c
> +++ b/lib/efi_loader/efi_boottime.c
> @@ -13,6 +13,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
> 
>  DECLARE_GLOBAL_DATA_PTR;
> @@ -2798,7 +2799,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
>*   image protocol.
>*/
>   efi_status_t ret;
> - void *info;
> + struct efi_loaded_image *loaded_image_protocol;
>   struct efi_loaded_image_obj *image_obj =
>   (struct efi_loaded_image_obj *)image_handle;
> 
> @@ -2806,13 +2807,33 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
> exit_data_size, exit_data);
> 
>   /* Check parameters */
> - if (image_handle != current_image)
> - goto out;
>   ret = EFI_CALL(efi_open_protocol(image_handle, _guid_loaded_image,
> -  , NULL, NULL,
> +  (void **)_image_protocol,
> +  NULL, NULL,
>EFI_OPEN_PROTOCOL_GET_PROTOCOL));
> - if (ret != EFI_SUCCESS)
> + if (ret != EFI_SUCCESS) {
> + ret = EFI_INVALID_PARAMETER;
>   goto out;
> + }
> +
> + /* Unloading of unstarted images */
> + switch (image_obj->header.type) {
> + case EFI_OBJECT_TYPE_STARTED_IMAGE:
> + break;
> + case EFI_OBJECT_TYPE_LOADED_IMAGE:
> + efi_delete_image(image_obj, loaded_image_protocol);
> + ret = EFI_SUCCESS;
> + goto out;
> + default:
> + /* Handle does not refer to loaded image */
> + ret = EFI_INVALID_PARAMETER;
> + goto out;
> + }
> + /* A started image can only be unloaded it is the last one started. */
> + if (image_handle != current_image) {
> + ret = EFI_INVALID_PARAMETER;
> + goto out;
> + }
> 
>   /* Exit data is only foreseen in case of failure. */
>   if (exit_status != EFI_SUCCESS) {
> @@ -2822,6 +2843,9 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
>   if (ret != EFI_SUCCESS)
>   EFI_PRINT("%s: out of memory\n", __func__);
>   }
> + if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION ||
> + exit_status != EFI_SUCCESS)
> + efi_delete_image(image_obj, loaded_image_protocol);

No change around efi_delete_image() and "goto" above?

-Takahiro Akashi

>   /* Make sure entry/exit counts for EFI world cross-overs match */
>   EFI_EXIT(exit_status);
> @@ -2837,7 +2861,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
> 
>   panic("EFI application exited");
>  out:
> - return EFI_EXIT(EFI_INVALID_PARAMETER);
> + return EFI_EXIT(ret);
>  }
> 
>  /**
> diff --git a/lib/efi_loader/efi_image_loader.c 
> b/lib/efi_loader/efi_image_loader.c
> index f8092b6202..13541cfa7a 100644
> --- a/lib/efi_loader/efi_image_loader.c
> +++ b/lib/efi_loader/efi_image_loader.c
> @@ -273,6 +273,7 @@ efi_status_t efi_load_pe(struct efi_loa

Re: [U-Boot] [PATCH v2 1/1] efi_loader: optional data in load options are binary

2019-05-07 Thread Takahiro Akashi
On Tue, May 07, 2019 at 06:54:45PM +0200, Heinrich Schuchardt wrote:
> On 5/7/19 9:30 AM, Takahiro Akashi wrote:
> >On Tue, May 07, 2019 at 09:12:56AM +0200, Heinrich Schuchardt wrote:
> >>On 5/7/19 8:16 AM, Takahiro Akashi wrote:
> >>>On Tue, May 07, 2019 at 08:04:26AM +0200, Heinrich Schuchardt wrote:
> >>>>On 5/7/19 7:16 AM, Heinrich Schuchardt wrote:
> >>>>>On 5/7/19 3:53 AM, Takahiro Akashi wrote:
> >>>>>>On Tue, Apr 30, 2019 at 08:11:15AM +0200, Heinrich Schuchardt wrote:
> >>>>>>>The field boot OptionalData in structure _EFI_LOAD_OPTIONS is for 
> >>>>>>>binary
> >>>>>>>data.
> >>>>>>>
> >>>>>>>When we use `efidebug boot add` we should convert the 5th argument from
> >>>>>>>UTF-8 to UTF-16 before putting it into the Boot variable.
> >>>>>>
> >>>>>>While optional_data holds u8 string in calling
> >>>>>>efi_serialize_load_option(),
> >>>>>>it holds u16 string in leaving from efi_deserialize_load_option().
> >>>>>>We should handle it in a consistent way if you want to keep 
> >>>>>>optional_data
> >>>>>>as "const u8."
> >>>>
> >>>>When communicating with Linux optional data may contain a u16 string.
> >>>>But I cannot see were our coding is inconsistent.
> >>>
> >>>I don't get your point.
> >>>Do you want to allow 'u8 *' variable to hold u16 string?#
> >>
> >>Yes, optional data may contain anything, in the case of Linux the
> >>command line parameters as an u16 string.
> >>
> >>Other operating systems may use the field in other ways, e.g. store an
> >>ASCII string.
> >
> >The problem is that with your patch optional_data is *always* converted
> >to utf-16 as far as we use efidebug.
> >My efidebug is not for linux only.
> 
> optional_data treated is not treated as u16 in efidebug:

With your patch,
efi_serialize_load_option() always convert a given argument to
utf-16 and then the resulting variable contains u16 string as
optional_data. On the other hand, efi_deserialize_load_option()
does *not* convert an encoded optional_data in a variable to utf-8.

See what I mean?

-Takahiro Akashi


> include/hexdump.h:
> void print_hex_dump(const char *prefix_str, int prefix_type,
>   int rowsize, int groupsize, const void *buf,
>   size_t len, bool ascii);
> 
> include/efi_loader:
> struct efi_load_option {
> u32 attributes;
> u16 file_path_length;
> u16 *label;
> struct efi_device_path *file_path;
> const u8 *optional_data;
> };
> 
> cmd/efidebug.c
>   print_hex_dump("", DUMP_PREFIX_OFFSET, 16, 1,
>   lo.optional_data, size + (u8 *)data -
>   (u8 *)lo.optional_data, true);
> 
> Best regards
> 
> Heinrich
> 
> >
> >-Takahiro Akashi
> >
> >
> >>Regards
> >>
> >>Heinrich
> >>
> >>>
> >>>-Takahiro Akashi
> >>>
> >>>>Regards
> >>>>
> >>>>Heinrich
> >>>>
> >>>>>
> >>>>>The patch is already merged so I will have to create a follow up patch.
> >>>>>
> >>>>>The UEFI spec has EFI_LOAD_OPTION.OptionalData as UINT8. So an odd
> >>>>>number of bytes is a possibility.
> >>>>>
> >>>>>Best regards
> >>>>>
> >>>>>Heinrich
> >>>>>
> >>>>>>
> >>>>>>Thanks,
> >>>>>>-Takahiro Akashi
> >>>>>>
> >>>>>>>When printing boot variables with `efidebug boot dump` we should 
> >>>>>>>support
> >>>>>>>the OptionalData being arbitrary binary data. So let's dump the data as
> >>>>>>>hexadecimal values.
> >>>>>>>
> >>>>>>>Here is an example session protocol:
> >>>>>>>
> >>>>>>>=> efidebug boot add 00a1 label1 scsi 0:1 doit1 'my option'
> >>>>>>>=> efidebug boot add 00a2 label2 scsi 0:1 doit2
> >>>>>>>=> efidebug boot dump
> >>>>>>>Boot00A0:
> >>>>>>>    attributes: A-- (0x0001)
> >>>>>>

Re: [U-Boot] [PATCH v2 1/1] efi_loader: optional data in load options are binary

2019-05-07 Thread Takahiro Akashi
On Tue, May 07, 2019 at 09:12:56AM +0200, Heinrich Schuchardt wrote:
> On 5/7/19 8:16 AM, Takahiro Akashi wrote:
> > On Tue, May 07, 2019 at 08:04:26AM +0200, Heinrich Schuchardt wrote:
> >> On 5/7/19 7:16 AM, Heinrich Schuchardt wrote:
> >>> On 5/7/19 3:53 AM, Takahiro Akashi wrote:
> >>>> On Tue, Apr 30, 2019 at 08:11:15AM +0200, Heinrich Schuchardt wrote:
> >>>>> The field boot OptionalData in structure _EFI_LOAD_OPTIONS is for binary
> >>>>> data.
> >>>>>
> >>>>> When we use `efidebug boot add` we should convert the 5th argument from
> >>>>> UTF-8 to UTF-16 before putting it into the Boot variable.
> >>>>
> >>>> While optional_data holds u8 string in calling
> >>>> efi_serialize_load_option(),
> >>>> it holds u16 string in leaving from efi_deserialize_load_option().
> >>>> We should handle it in a consistent way if you want to keep optional_data
> >>>> as "const u8."
> >>
> >> When communicating with Linux optional data may contain a u16 string.
> >> But I cannot see were our coding is inconsistent.
> >
> > I don't get your point.
> > Do you want to allow 'u8 *' variable to hold u16 string?#
> 
> Yes, optional data may contain anything, in the case of Linux the
> command line parameters as an u16 string.
> 
> Other operating systems may use the field in other ways, e.g. store an
> ASCII string.

The problem is that with your patch optional_data is *always* converted
to utf-16 as far as we use efidebug.
My efidebug is not for linux only.

-Takahiro Akashi


> Regards
> 
> Heinrich
> 
> >
> > -Takahiro Akashi
> >
> >> Regards
> >>
> >> Heinrich
> >>
> >>>
> >>> The patch is already merged so I will have to create a follow up patch.
> >>>
> >>> The UEFI spec has EFI_LOAD_OPTION.OptionalData as UINT8. So an odd
> >>> number of bytes is a possibility.
> >>>
> >>> Best regards
> >>>
> >>> Heinrich
> >>>
> >>>>
> >>>> Thanks,
> >>>> -Takahiro Akashi
> >>>>
> >>>>> When printing boot variables with `efidebug boot dump` we should support
> >>>>> the OptionalData being arbitrary binary data. So let's dump the data as
> >>>>> hexadecimal values.
> >>>>>
> >>>>> Here is an example session protocol:
> >>>>>
> >>>>> => efidebug boot add 00a1 label1 scsi 0:1 doit1 'my option'
> >>>>> => efidebug boot add 00a2 label2 scsi 0:1 doit2
> >>>>> => efidebug boot dump
> >>>>> Boot00A0:
> >>>>>    attributes: A-- (0x0001)
> >>>>>    label: label1
> >>>>>    file_path: .../HD(1,MBR,0xeac4e18b,0x800,0x3fffe)/doit1
> >>>>>    data:
> >>>>>  : 6d 00 79 00 20 00 6f 00 70 00 74 00 69 00 6f 00  m.y.
> >>>>> .o.p.t.i.o.
> >>>>>  0010: 6e 00 00 00  n...
> >>>>> Boot00A1:
> >>>>>    attributes: A-- (0x0001)
> >>>>>    label: label2
> >>>>>    file_path: .../HD(1,MBR,0xeac4e18b,0x800,0x3fffe)/doit2
> >>>>>    data:
> >>>>>
> >>>>> Signed-off-by: Heinrich Schuchardt 
> >>>>> ---
> >>>>> v2:
> >>>>> remove statement without effect in efi_serialize_load_option()
> >>>>> ---
> >>>>>   cmd/efidebug.c   | 27 +--
> >>>>>   include/efi_loader.h |  2 +-
> >>>>>   lib/efi_loader/efi_bootmgr.c | 15 ---
> >>>>>   3 files changed, 26 insertions(+), 18 deletions(-)
> >>>>>
> >>>>> diff --git a/cmd/efidebug.c b/cmd/efidebug.c
> >>>>> index efe4ea873e..c4ac9dd634 100644
> >>>>> --- a/cmd/efidebug.c
> >>>>> +++ b/cmd/efidebug.c
> >>>>> @@ -11,6 +11,7 @@
> >>>>>   #include 
> >>>>>   #include 
> >>>>>   #include 
> >>>>> +#include 
> >>>>>   #include 
> >>>>>   #include 
> >>>>>   #include 
> >>>>> @@ -545,7 +546,10 @@ static int do_efi_boot_add(cmd_tbl_t *cmdtp, int
> &

Re: [U-Boot] [PATCH 4/4] efi_loader: unload applications upon Exit()

2019-05-07 Thread Takahiro Akashi
On Tue, May 07, 2019 at 07:50:48AM +0200, Heinrich Schuchardt wrote:
> On 5/7/19 6:39 AM, Takahiro Akashi wrote:
> >On Sat, May 04, 2019 at 10:36:36AM +0200, Heinrich Schuchardt wrote:
> >>Implement unloading of images in the Exit() boot services:
> >>
> >>* unload images that are not yet started,
> >>* unload started applications,
> >>* unload drivers returning an error.
> >>
> >>Signed-off-by: Heinrich Schuchardt 
> >>---
> >>  include/efi_loader.h  |  1 +
> >>  lib/efi_loader/efi_boottime.c | 34 ++-
> >>  lib/efi_loader/efi_image_loader.c |  2 ++
> >>  3 files changed, 32 insertions(+), 5 deletions(-)
> >>
> >>diff --git a/include/efi_loader.h b/include/efi_loader.h
> >>index c2a449e5b6..d73c89ac26 100644
> >>--- a/include/efi_loader.h
> >>+++ b/include/efi_loader.h
> >>@@ -237,6 +237,7 @@ struct efi_loaded_image_obj {
> >>struct jmp_buf_data exit_jmp;
> >>EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
> >> struct efi_system_table *st);
> >>+   u16 image_type;
> >>  };
> >>
> >>  /**
> >>diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> >>index bbcd66caa6..51e0bb2fd5 100644
> >>--- a/lib/efi_loader/efi_boottime.c
> >>+++ b/lib/efi_loader/efi_boottime.c
> >>@@ -13,6 +13,7 @@
> >>  #include 
> >>  #include 
> >>  #include 
> >>+#include 
> >>  #include 
> >>
> >>  DECLARE_GLOBAL_DATA_PTR;
> >>@@ -2798,7 +2799,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> >>image_handle,
> >> *   image protocol.
> >> */
> >>efi_status_t ret;
> >>-   void *info;
> >>+   struct efi_loaded_image *loaded_image_protocol;
> >>struct efi_loaded_image_obj *image_obj =
> >>(struct efi_loaded_image_obj *)image_handle;
> >>
> >>@@ -2806,13 +2807,33 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> >>image_handle,
> >>  exit_data_size, exit_data);
> >>
> >>/* Check parameters */
> >>-   if (image_handle != current_image)
> >>+   if (image_handle != current_image) {
> >
> >Does this check make sense even for a driver?
> 
> The check is prescribed in the UEFI specification. See the heading
> "Status Codes Returned".
> 
> Multiple binaries may be in status started. If a child image (which may
> be a driver) calls Exit() with the parent image handle this might cause
> fancy problems.
> 
> The lifetime of a driver is LoadImage(), StartImage(), Exit(),
> UnloadImage(). Typically between StartImage() and Exit() it will install
> its protocols and between Exit() and UnloadImage() wait for other
> binaries to call the protocols.

If this is true, that will be fine for a driver.
But what about 'not started' application? In "Status Codes Returned" of
Exit(), it says
  EFI_SUCCESS
  The image specified by ImageHandle was unloaded. This condition only
  occurs for images that have been loaded with LoadImage() but have not
  been started with StartImage().
In this case, the caller of Exit() is not an application.

> >
> >>+   ret = EFI_INVALID_PARAMETER;
> >>goto out;
> >>+   }
> >>ret = EFI_CALL(efi_open_protocol(image_handle, _guid_loaded_image,
> >>-, NULL, NULL,
> >>+(void **)_image_protocol,
> >>+NULL, NULL,
> >> EFI_OPEN_PROTOCOL_GET_PROTOCOL));
> >>-   if (ret != EFI_SUCCESS)
> >>+   if (ret != EFI_SUCCESS) {
> >
> >Is this check necessary even when 'header.type' is introduced?
> 
> I am passing the loaded image protocol to efi_delete_handle().

I don't think that it can be a critical reason.

> In
> principal a binary might have uninstalled its own loaded image protocol
> so this call may fail.

If we admit this possibility, there will be bunch of fragile code elsewhere.

> >
> >>+   ret = EFI_INVALID_PARAMETER;
> >>goto out;
> >>+   }
> >>+
> >>+   /* Unloading of unstarted images */
> >
> >'Unload' sounds odd when we call efi_delete_image(), doesn't it?
> >
> >>+   switch (image_obj->header.type) {
> >>+   case EFI_OBJECT_TYPE_STARTED_IMAGE:
> >>+   break;
> >>+   case EFI_OBJECT_TYPE_

Re: [U-Boot] [PATCH v2 1/1] efi_loader: optional data in load options are binary

2019-05-07 Thread Takahiro Akashi
On Tue, May 07, 2019 at 08:04:26AM +0200, Heinrich Schuchardt wrote:
> On 5/7/19 7:16 AM, Heinrich Schuchardt wrote:
> >On 5/7/19 3:53 AM, Takahiro Akashi wrote:
> >>On Tue, Apr 30, 2019 at 08:11:15AM +0200, Heinrich Schuchardt wrote:
> >>>The field boot OptionalData in structure _EFI_LOAD_OPTIONS is for binary
> >>>data.
> >>>
> >>>When we use `efidebug boot add` we should convert the 5th argument from
> >>>UTF-8 to UTF-16 before putting it into the Boot variable.
> >>
> >>While optional_data holds u8 string in calling
> >>efi_serialize_load_option(),
> >>it holds u16 string in leaving from efi_deserialize_load_option().
> >>We should handle it in a consistent way if you want to keep optional_data
> >>as "const u8."
> 
> When communicating with Linux optional data may contain a u16 string.
> But I cannot see were our coding is inconsistent.

I don't get your point.
Do you want to allow 'u8 *' variable to hold u16 string?

-Takahiro Akashi

> Regards
> 
> Heinrich
> 
> >
> >The patch is already merged so I will have to create a follow up patch.
> >
> >The UEFI spec has EFI_LOAD_OPTION.OptionalData as UINT8. So an odd
> >number of bytes is a possibility.
> >
> >Best regards
> >
> >Heinrich
> >
> >>
> >>Thanks,
> >>-Takahiro Akashi
> >>
> >>>When printing boot variables with `efidebug boot dump` we should support
> >>>the OptionalData being arbitrary binary data. So let's dump the data as
> >>>hexadecimal values.
> >>>
> >>>Here is an example session protocol:
> >>>
> >>>=> efidebug boot add 00a1 label1 scsi 0:1 doit1 'my option'
> >>>=> efidebug boot add 00a2 label2 scsi 0:1 doit2
> >>>=> efidebug boot dump
> >>>Boot00A0:
> >>>   attributes: A-- (0x0001)
> >>>   label: label1
> >>>   file_path: .../HD(1,MBR,0xeac4e18b,0x800,0x3fffe)/doit1
> >>>   data:
> >>> : 6d 00 79 00 20 00 6f 00 70 00 74 00 69 00 6f 00  m.y.
> >>>.o.p.t.i.o.
> >>> 0010: 6e 00 00 00  n...
> >>>Boot00A1:
> >>>   attributes: A-- (0x0001)
> >>>   label: label2
> >>>   file_path: .../HD(1,MBR,0xeac4e18b,0x800,0x3fffe)/doit2
> >>>   data:
> >>>
> >>>Signed-off-by: Heinrich Schuchardt 
> >>>---
> >>>v2:
> >>>remove statement without effect in efi_serialize_load_option()
> >>>---
> >>>  cmd/efidebug.c   | 27 +--
> >>>  include/efi_loader.h |  2 +-
> >>>  lib/efi_loader/efi_bootmgr.c | 15 ---
> >>>  3 files changed, 26 insertions(+), 18 deletions(-)
> >>>
> >>>diff --git a/cmd/efidebug.c b/cmd/efidebug.c
> >>>index efe4ea873e..c4ac9dd634 100644
> >>>--- a/cmd/efidebug.c
> >>>+++ b/cmd/efidebug.c
> >>>@@ -11,6 +11,7 @@
> >>>  #include 
> >>>  #include 
> >>>  #include 
> >>>+#include 
> >>>  #include 
> >>>  #include 
> >>>  #include 
> >>>@@ -545,7 +546,10 @@ static int do_efi_boot_add(cmd_tbl_t *cmdtp, int
> >>>flag,
> >>>  + sizeof(struct efi_device_path); /* for END */
> >>>
> >>>  /* optional data */
> >>>-    lo.optional_data = (u8 *)(argc == 6 ? "" : argv[6]);
> >>>+    if (argc < 6)
> >>>+    lo.optional_data = NULL;
> >>>+    else
> >>>+    lo.optional_data = (const u8 *)argv[6];
> >>>
> >>>  size = efi_serialize_load_option(, (u8 **));
> >>>  if (!size) {
> >>>@@ -615,12 +619,13 @@ static int do_efi_boot_rm(cmd_tbl_t *cmdtp, int
> >>>flag,
> >>>  /**
> >>>   * show_efi_boot_opt_data() - dump UEFI load option
> >>>   *
> >>>- * @id:    Load option number
> >>>- * @data:    Value of UEFI load option variable
> >>>+ * @id:    load option number
> >>>+ * @data:    value of UEFI load option variable
> >>>+ * @size:    size of the boot option
> >>>   *
> >>>   * Decode the value of UEFI load option variable and print
> >>>information.
> >>>   */
> >>>-static void show_efi_boot_opt_data(int id, void *data)
> >>>+stat

Re: [U-Boot] [PATCH 1/4] efi_loader: mark started images

2019-05-07 Thread Takahiro Akashi
On Tue, May 07, 2019 at 08:05:48AM +0200, Heinrich Schuchardt wrote:
> On 5/7/19 7:58 AM, Takahiro Akashi wrote:
> >On Tue, May 07, 2019 at 07:53:41AM +0200, Heinrich Schuchardt wrote:
> >>On 5/7/19 7:44 AM, Takahiro Akashi wrote:
> >>>On Tue, May 07, 2019 at 07:26:46AM +0200, Heinrich Schuchardt wrote:
> >>>>On 5/7/19 5:02 AM, Takahiro Akashi wrote:
> >>>>>On Sat, May 04, 2019 at 10:36:33AM +0200, Heinrich Schuchardt wrote:
> >>>>>>In UnloadImage() we need to know if an image is already started.
> >>>>>>
> >>>>>>Add a field to the handle structure identifying loaded and started 
> >>>>>>images.
> >>>>>>
> >>>>>>Signed-off-by: Heinrich Schuchardt 
> >>>>>>---
> >>>>>>  include/efi_loader.h  | 13 +
> >>>>>>  lib/efi_loader/efi_boottime.c |  2 ++
> >>>>>>  2 files changed, 15 insertions(+)
> >>>>>>
> >>>>>>diff --git a/include/efi_loader.h b/include/efi_loader.h
> >>>>>>index 3fd9901d66..c2a449e5b6 100644
> >>>>>>--- a/include/efi_loader.h
> >>>>>>+++ b/include/efi_loader.h
> >>>>>>@@ -182,6 +182,18 @@ struct efi_handler {
> >>>>>>struct list_head open_infos;
> >>>>>>  };
> >>>>>>
> >>>>>>+/**
> >>>>>>+ * enum efi_object_type - type of EFI object
> >>>>>>+ *
> >>>>>>+ * In UnloadImage we must be able to identify if the handle relates to 
> >>>>>>a
> >>>>>>+ * started image.
> >>>>>>+ */
> >>>>>>+enum efi_object_type {
> >>>>>>+   EFI_OBJECT_TYPE_UNDEFINED = 0,
> >>>>>>+   EFI_OBJECT_TYPE_LOADED_IMAGE,
> >>>>>>+   EFI_OBJECT_TYPE_STARTED_IMAGE,
> >>>>>>+};
> >>>>>
> >>>>>It sounds *status*, not *type*.
> >>>>>In a separate patch, you added U_BOOT_FIRMWARE.
> >>>>>We should distinguish status and type for future enhancement and
> >>>>>to avoid any confusion.
> >>>>
> >>>>Having both information in the same field makes the evaluation easier.
> >>>>
> >>>>Currently I see not necessity for more handle types to be
> >>>>differentiated. Let's change it when the need arises.
> >>>
> >>>I don't think we need U_BOOT_FIRMWARE if we use STARTED_IMAGE
> >>>for root node. Then we can rename efi_object_type to efi_image_status.
> >>
> >>This would allow calling UnloadImage() for the root node.
> >
> >Who knows the address of root node?
> 
> Just enumerated handles with a loaded image protocol.

Remove it when enumerating handles if necessary.


> >For safe guard, you can add
> > if (handle == root_node)
> > return EFI_INVALID_PARAMETER;
> >at the beginning of unload_image.
> 
> This would not decrease complexity.

I believe that it's much better and more understandable than
confusing use of status and type.

-Takahiro Akashi


> Regards
> 
> Heinrich
> 
> >
> >-Takahiro Akashi
> >
> >
> >>Best regards
> >>
> >>Heinrich
> >>
> >>>
> >>>-Takahiro Akashi
> >>>
> >>>
> >>>>Best regards
> >>>>
> >>>>Heinrich
> >>>>
> >>>>>
> >>>>>Thanks,
> >>>>>-Takahiro Akashi
> >>>>>
> >>>>>
> >>>>>>  /**
> >>>>>>   * struct efi_object - dereferenced EFI handle
> >>>>>>   *
> >>>>>>@@ -204,6 +216,7 @@ struct efi_object {
> >>>>>>struct list_head link;
> >>>>>>/* The list of protocols */
> >>>>>>struct list_head protocols;
> >>>>>>+   enum efi_object_type type;
> >>>>>>  };
> >>>>>>
> >>>>>>  /**
> >>>>>>diff --git a/lib/efi_loader/efi_boottime.c 
> >>>>>>b/lib/efi_loader/efi_boottime.c
> >>>>>>index 3ed08e7c37..dc444fccf6 100644
> >>>>>>--- a/lib/efi_loader/efi_boottime.c
> >>>>>>+++ b/lib/efi_loader/efi_boottime.c
> >>>>>>@@ -1554,6 +1554,7 @@ efi_status_t efi_setup_loaded_image(struct 
> >>>>>>efi_device_path *device_path,
> >>>>>>free(info);
> >>>>>>return EFI_OUT_OF_RESOURCES;
> >>>>>>}
> >>>>>>+   obj->header.type = EFI_OBJECT_TYPE_LOADED_IMAGE;
> >>>>>>
> >>>>>>/* Add internal object to object list */
> >>>>>>efi_add_handle(>header);
> >>>>>>@@ -2678,6 +2679,7 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t 
> >>>>>>image_handle,
> >>>>>>}
> >>>>>>
> >>>>>>current_image = image_handle;
> >>>>>>+   image_obj->header.type = EFI_OBJECT_TYPE_STARTED_IMAGE;
> >>>>>>EFI_PRINT("Jumping into 0x%p\n", image_obj->entry);
> >>>>>>ret = EFI_CALL(image_obj->entry(image_handle, ));
> >>>>>>
> >>>>>>--
> >>>>>>2.20.1
> >>>>>>
> >>>>>
> >>>>
> >>>
> >>
> >
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 1/4] efi_loader: mark started images

2019-05-06 Thread Takahiro Akashi
On Tue, May 07, 2019 at 07:53:41AM +0200, Heinrich Schuchardt wrote:
> On 5/7/19 7:44 AM, Takahiro Akashi wrote:
> >On Tue, May 07, 2019 at 07:26:46AM +0200, Heinrich Schuchardt wrote:
> >>On 5/7/19 5:02 AM, Takahiro Akashi wrote:
> >>>On Sat, May 04, 2019 at 10:36:33AM +0200, Heinrich Schuchardt wrote:
> >>>>In UnloadImage() we need to know if an image is already started.
> >>>>
> >>>>Add a field to the handle structure identifying loaded and started images.
> >>>>
> >>>>Signed-off-by: Heinrich Schuchardt 
> >>>>---
> >>>>  include/efi_loader.h  | 13 +
> >>>>  lib/efi_loader/efi_boottime.c |  2 ++
> >>>>  2 files changed, 15 insertions(+)
> >>>>
> >>>>diff --git a/include/efi_loader.h b/include/efi_loader.h
> >>>>index 3fd9901d66..c2a449e5b6 100644
> >>>>--- a/include/efi_loader.h
> >>>>+++ b/include/efi_loader.h
> >>>>@@ -182,6 +182,18 @@ struct efi_handler {
> >>>>  struct list_head open_infos;
> >>>>  };
> >>>>
> >>>>+/**
> >>>>+ * enum efi_object_type - type of EFI object
> >>>>+ *
> >>>>+ * In UnloadImage we must be able to identify if the handle relates to a
> >>>>+ * started image.
> >>>>+ */
> >>>>+enum efi_object_type {
> >>>>+ EFI_OBJECT_TYPE_UNDEFINED = 0,
> >>>>+ EFI_OBJECT_TYPE_LOADED_IMAGE,
> >>>>+ EFI_OBJECT_TYPE_STARTED_IMAGE,
> >>>>+};
> >>>
> >>>It sounds *status*, not *type*.
> >>>In a separate patch, you added U_BOOT_FIRMWARE.
> >>>We should distinguish status and type for future enhancement and
> >>>to avoid any confusion.
> >>
> >>Having both information in the same field makes the evaluation easier.
> >>
> >>Currently I see not necessity for more handle types to be
> >>differentiated. Let's change it when the need arises.
> >
> >I don't think we need U_BOOT_FIRMWARE if we use STARTED_IMAGE
> >for root node. Then we can rename efi_object_type to efi_image_status.
> 
> This would allow calling UnloadImage() for the root node.

Who knows the address of root node?
For safe guard, you can add
if (handle == root_node)
return EFI_INVALID_PARAMETER;
at the beginning of unload_image.

-Takahiro Akashi


> Best regards
> 
> Heinrich
> 
> >
> >-Takahiro Akashi
> >
> >
> >>Best regards
> >>
> >>Heinrich
> >>
> >>>
> >>>Thanks,
> >>>-Takahiro Akashi
> >>>
> >>>
> >>>>  /**
> >>>>   * struct efi_object - dereferenced EFI handle
> >>>>   *
> >>>>@@ -204,6 +216,7 @@ struct efi_object {
> >>>>  struct list_head link;
> >>>>  /* The list of protocols */
> >>>>  struct list_head protocols;
> >>>>+ enum efi_object_type type;
> >>>>  };
> >>>>
> >>>>  /**
> >>>>diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> >>>>index 3ed08e7c37..dc444fccf6 100644
> >>>>--- a/lib/efi_loader/efi_boottime.c
> >>>>+++ b/lib/efi_loader/efi_boottime.c
> >>>>@@ -1554,6 +1554,7 @@ efi_status_t efi_setup_loaded_image(struct 
> >>>>efi_device_path *device_path,
> >>>>  free(info);
> >>>>  return EFI_OUT_OF_RESOURCES;
> >>>>  }
> >>>>+ obj->header.type = EFI_OBJECT_TYPE_LOADED_IMAGE;
> >>>>
> >>>>  /* Add internal object to object list */
> >>>>  efi_add_handle(>header);
> >>>>@@ -2678,6 +2679,7 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t 
> >>>>image_handle,
> >>>>  }
> >>>>
> >>>>  current_image = image_handle;
> >>>>+ image_obj->header.type = EFI_OBJECT_TYPE_STARTED_IMAGE;
> >>>>  EFI_PRINT("Jumping into 0x%p\n", image_obj->entry);
> >>>>  ret = EFI_CALL(image_obj->entry(image_handle, ));
> >>>>
> >>>>--
> >>>>2.20.1
> >>>>
> >>>
> >>
> >
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 1/4] efi_loader: mark started images

2019-05-06 Thread Takahiro Akashi
On Tue, May 07, 2019 at 07:26:46AM +0200, Heinrich Schuchardt wrote:
> On 5/7/19 5:02 AM, Takahiro Akashi wrote:
> >On Sat, May 04, 2019 at 10:36:33AM +0200, Heinrich Schuchardt wrote:
> >>In UnloadImage() we need to know if an image is already started.
> >>
> >>Add a field to the handle structure identifying loaded and started images.
> >>
> >>Signed-off-by: Heinrich Schuchardt 
> >>---
> >>  include/efi_loader.h  | 13 +
> >>  lib/efi_loader/efi_boottime.c |  2 ++
> >>  2 files changed, 15 insertions(+)
> >>
> >>diff --git a/include/efi_loader.h b/include/efi_loader.h
> >>index 3fd9901d66..c2a449e5b6 100644
> >>--- a/include/efi_loader.h
> >>+++ b/include/efi_loader.h
> >>@@ -182,6 +182,18 @@ struct efi_handler {
> >>struct list_head open_infos;
> >>  };
> >>
> >>+/**
> >>+ * enum efi_object_type - type of EFI object
> >>+ *
> >>+ * In UnloadImage we must be able to identify if the handle relates to a
> >>+ * started image.
> >>+ */
> >>+enum efi_object_type {
> >>+   EFI_OBJECT_TYPE_UNDEFINED = 0,
> >>+   EFI_OBJECT_TYPE_LOADED_IMAGE,
> >>+   EFI_OBJECT_TYPE_STARTED_IMAGE,
> >>+};
> >
> >It sounds *status*, not *type*.
> >In a separate patch, you added U_BOOT_FIRMWARE.
> >We should distinguish status and type for future enhancement and
> >to avoid any confusion.
> 
> Having both information in the same field makes the evaluation easier.
> 
> Currently I see not necessity for more handle types to be
> differentiated. Let's change it when the need arises.

I don't think we need U_BOOT_FIRMWARE if we use STARTED_IMAGE
for root node. Then we can rename efi_object_type to efi_image_status.

-Takahiro Akashi


> Best regards
> 
> Heinrich
> 
> >
> >Thanks,
> >-Takahiro Akashi
> >
> >
> >>  /**
> >>   * struct efi_object - dereferenced EFI handle
> >>   *
> >>@@ -204,6 +216,7 @@ struct efi_object {
> >>struct list_head link;
> >>/* The list of protocols */
> >>struct list_head protocols;
> >>+   enum efi_object_type type;
> >>  };
> >>
> >>  /**
> >>diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> >>index 3ed08e7c37..dc444fccf6 100644
> >>--- a/lib/efi_loader/efi_boottime.c
> >>+++ b/lib/efi_loader/efi_boottime.c
> >>@@ -1554,6 +1554,7 @@ efi_status_t efi_setup_loaded_image(struct 
> >>efi_device_path *device_path,
> >>free(info);
> >>return EFI_OUT_OF_RESOURCES;
> >>}
> >>+   obj->header.type = EFI_OBJECT_TYPE_LOADED_IMAGE;
> >>
> >>/* Add internal object to object list */
> >>efi_add_handle(>header);
> >>@@ -2678,6 +2679,7 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t 
> >>image_handle,
> >>}
> >>
> >>current_image = image_handle;
> >>+   image_obj->header.type = EFI_OBJECT_TYPE_STARTED_IMAGE;
> >>EFI_PRINT("Jumping into 0x%p\n", image_obj->entry);
> >>ret = EFI_CALL(image_obj->entry(image_handle, ));
> >>
> >>--
> >>2.20.1
> >>
> >
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 4/4] efi_loader: unload applications upon Exit()

2019-05-06 Thread Takahiro Akashi
On Sat, May 04, 2019 at 10:36:36AM +0200, Heinrich Schuchardt wrote:
> Implement unloading of images in the Exit() boot services:
> 
> * unload images that are not yet started,
> * unload started applications,
> * unload drivers returning an error.
>
> Signed-off-by: Heinrich Schuchardt 
> ---
>  include/efi_loader.h  |  1 +
>  lib/efi_loader/efi_boottime.c | 34 ++-
>  lib/efi_loader/efi_image_loader.c |  2 ++
>  3 files changed, 32 insertions(+), 5 deletions(-)
> 
> diff --git a/include/efi_loader.h b/include/efi_loader.h
> index c2a449e5b6..d73c89ac26 100644
> --- a/include/efi_loader.h
> +++ b/include/efi_loader.h
> @@ -237,6 +237,7 @@ struct efi_loaded_image_obj {
>   struct jmp_buf_data exit_jmp;
>   EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
>struct efi_system_table *st);
> + u16 image_type;
>  };
> 
>  /**
> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> index bbcd66caa6..51e0bb2fd5 100644
> --- a/lib/efi_loader/efi_boottime.c
> +++ b/lib/efi_loader/efi_boottime.c
> @@ -13,6 +13,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
> 
>  DECLARE_GLOBAL_DATA_PTR;
> @@ -2798,7 +2799,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
>*   image protocol.
>*/
>   efi_status_t ret;
> - void *info;
> + struct efi_loaded_image *loaded_image_protocol;
>   struct efi_loaded_image_obj *image_obj =
>   (struct efi_loaded_image_obj *)image_handle;
> 
> @@ -2806,13 +2807,33 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
> exit_data_size, exit_data);
> 
>   /* Check parameters */
> - if (image_handle != current_image)
> + if (image_handle != current_image) {

Does this check make sense even for a driver?

> + ret = EFI_INVALID_PARAMETER;
>   goto out;
> + }
>   ret = EFI_CALL(efi_open_protocol(image_handle, _guid_loaded_image,
> -  , NULL, NULL,
> +  (void **)_image_protocol,
> +  NULL, NULL,
>EFI_OPEN_PROTOCOL_GET_PROTOCOL));
> - if (ret != EFI_SUCCESS)
> + if (ret != EFI_SUCCESS) {

Is this check necessary even when 'header.type' is introduced?

> + ret = EFI_INVALID_PARAMETER;
>   goto out;
> + }
> +
> + /* Unloading of unstarted images */

'Unload' sounds odd when we call efi_delete_image(), doesn't it?

> + switch (image_obj->header.type) {
> + case EFI_OBJECT_TYPE_STARTED_IMAGE:
> + break;
> + case EFI_OBJECT_TYPE_LOADED_IMAGE:
> + efi_delete_image(image_obj, loaded_image_protocol);
> + ret = EFI_SUCCESS;
> + goto out;
> + default:
> + /* Handle does not refer to loaded image */
> + ret = EFI_INVALID_PARAMETER;
> + goto out;
> + }
> + image_obj->header.type = EFI_OBJECT_TYPE_LOADED_IMAGE;
> 
>   /* Exit data is only foreseen in case of failure. */
>   if (exit_status != EFI_SUCCESS) {
> @@ -2822,6 +2843,9 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
>   if (ret != EFI_SUCCESS)
>   EFI_PRINT("%s: out of memory\n", __func__);
>   }
> + if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION ||
> + exit_status != EFI_SUCCESS)
> + efi_delete_image(image_obj, loaded_image_protocol);

Why not merge those two efi_delete_image()?

-Takahiro Akashi


>   /* Make sure entry/exit counts for EFI world cross-overs match */
>   EFI_EXIT(exit_status);
> @@ -2837,7 +2861,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
> 
>   panic("EFI application exited");
>  out:
> - return EFI_EXIT(EFI_INVALID_PARAMETER);
> + return EFI_EXIT(ret);
>  }
> 
>  /**
> diff --git a/lib/efi_loader/efi_image_loader.c 
> b/lib/efi_loader/efi_image_loader.c
> index f8092b6202..13541cfa7a 100644
> --- a/lib/efi_loader/efi_image_loader.c
> +++ b/lib/efi_loader/efi_image_loader.c
> @@ -273,6 +273,7 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj 
> *handle, void *efi,
>   IMAGE_OPTIONAL_HEADER64 *opt = >OptionalHeader;
>   image_base = opt->ImageBase;
>   efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
> + handle->image_type = opt->Subsystem;
>   

Re: [U-Boot] [PATCH 1/4] efi_loader: mark started images

2019-05-06 Thread Takahiro Akashi
On Sat, May 04, 2019 at 10:36:33AM +0200, Heinrich Schuchardt wrote:
> In UnloadImage() we need to know if an image is already started.
> 
> Add a field to the handle structure identifying loaded and started images.
> 
> Signed-off-by: Heinrich Schuchardt 
> ---
>  include/efi_loader.h  | 13 +
>  lib/efi_loader/efi_boottime.c |  2 ++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/include/efi_loader.h b/include/efi_loader.h
> index 3fd9901d66..c2a449e5b6 100644
> --- a/include/efi_loader.h
> +++ b/include/efi_loader.h
> @@ -182,6 +182,18 @@ struct efi_handler {
>   struct list_head open_infos;
>  };
> 
> +/**
> + * enum efi_object_type - type of EFI object
> + *
> + * In UnloadImage we must be able to identify if the handle relates to a
> + * started image.
> + */
> +enum efi_object_type {
> + EFI_OBJECT_TYPE_UNDEFINED = 0,
> + EFI_OBJECT_TYPE_LOADED_IMAGE,
> + EFI_OBJECT_TYPE_STARTED_IMAGE,
> +};

It sounds *status*, not *type*.
In a separate patch, you added U_BOOT_FIRMWARE.
We should distinguish status and type for future enhancement and
to avoid any confusion.

Thanks,
-Takahiro Akashi


>  /**
>   * struct efi_object - dereferenced EFI handle
>   *
> @@ -204,6 +216,7 @@ struct efi_object {
>   struct list_head link;
>   /* The list of protocols */
>   struct list_head protocols;
> + enum efi_object_type type;
>  };
> 
>  /**
> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> index 3ed08e7c37..dc444fccf6 100644
> --- a/lib/efi_loader/efi_boottime.c
> +++ b/lib/efi_loader/efi_boottime.c
> @@ -1554,6 +1554,7 @@ efi_status_t efi_setup_loaded_image(struct 
> efi_device_path *device_path,
>   free(info);
>   return EFI_OUT_OF_RESOURCES;
>   }
> + obj->header.type = EFI_OBJECT_TYPE_LOADED_IMAGE;
> 
>   /* Add internal object to object list */
>   efi_add_handle(>header);
> @@ -2678,6 +2679,7 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t 
> image_handle,
>   }
> 
>   current_image = image_handle;
> + image_obj->header.type = EFI_OBJECT_TYPE_STARTED_IMAGE;
>   EFI_PRINT("Jumping into 0x%p\n", image_obj->entry);
>   ret = EFI_CALL(image_obj->entry(image_handle, ));
> 
> --
> 2.20.1
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2 1/1] efi_loader: optional data in load options are binary

2019-05-06 Thread Takahiro Akashi
On Tue, Apr 30, 2019 at 08:11:15AM +0200, Heinrich Schuchardt wrote:
> The field boot OptionalData in structure _EFI_LOAD_OPTIONS is for binary
> data.
> 
> When we use `efidebug boot add` we should convert the 5th argument from
> UTF-8 to UTF-16 before putting it into the Boot variable.

While optional_data holds u8 string in calling efi_serialize_load_option(),
it holds u16 string in leaving from efi_deserialize_load_option().
We should handle it in a consistent way if you want to keep optional_data
as "const u8."

Thanks,
-Takahiro Akashi

> When printing boot variables with `efidebug boot dump` we should support
> the OptionalData being arbitrary binary data. So let's dump the data as
> hexadecimal values.
> 
> Here is an example session protocol:
> 
> => efidebug boot add 00a1 label1 scsi 0:1 doit1 'my option'
> => efidebug boot add 00a2 label2 scsi 0:1 doit2
> => efidebug boot dump
> Boot00A0:
>   attributes: A-- (0x0001)
>   label: label1
>   file_path: .../HD(1,MBR,0xeac4e18b,0x800,0x3fffe)/doit1
>   data:
> : 6d 00 79 00 20 00 6f 00 70 00 74 00 69 00 6f 00  m.y. 
> .o.p.t.i.o.
> 0010: 6e 00 00 00  n...
> Boot00A1:
>   attributes: A-- (0x0001)
>   label: label2
>   file_path: .../HD(1,MBR,0xeac4e18b,0x800,0x3fffe)/doit2
>   data:
> 
> Signed-off-by: Heinrich Schuchardt 
> ---
> v2:
>   remove statement without effect in efi_serialize_load_option()
> ---
>  cmd/efidebug.c   | 27 +--
>  include/efi_loader.h |  2 +-
>  lib/efi_loader/efi_bootmgr.c | 15 ---
>  3 files changed, 26 insertions(+), 18 deletions(-)
> 
> diff --git a/cmd/efidebug.c b/cmd/efidebug.c
> index efe4ea873e..c4ac9dd634 100644
> --- a/cmd/efidebug.c
> +++ b/cmd/efidebug.c
> @@ -11,6 +11,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -545,7 +546,10 @@ static int do_efi_boot_add(cmd_tbl_t *cmdtp, int flag,
>   + sizeof(struct efi_device_path); /* for END */
> 
>   /* optional data */
> - lo.optional_data = (u8 *)(argc == 6 ? "" : argv[6]);
> + if (argc < 6)
> + lo.optional_data = NULL;
> + else
> + lo.optional_data = (const u8 *)argv[6];
> 
>   size = efi_serialize_load_option(, (u8 **));
>   if (!size) {
> @@ -615,12 +619,13 @@ static int do_efi_boot_rm(cmd_tbl_t *cmdtp, int flag,
>  /**
>   * show_efi_boot_opt_data() - dump UEFI load option
>   *
> - * @id:  Load option number
> - * @data:Value of UEFI load option variable
> + * @id:  load option number
> + * @data:value of UEFI load option variable
> + * @size:size of the boot option
>   *
>   * Decode the value of UEFI load option variable and print information.
>   */
> -static void show_efi_boot_opt_data(int id, void *data)
> +static void show_efi_boot_opt_data(int id, void *data, size_t size)
>  {
>   struct efi_load_option lo;
>   char *label, *p;
> @@ -638,7 +643,7 @@ static void show_efi_boot_opt_data(int id, void *data)
>   utf16_utf8_strncpy(, lo.label, label_len16);
> 
>   printf("Boot%04X:\n", id);
> - printf("\tattributes: %c%c%c (0x%08x)\n",
> + printf("  attributes: %c%c%c (0x%08x)\n",
>  /* ACTIVE */
>  lo.attributes & LOAD_OPTION_ACTIVE ? 'A' : '-',
>  /* FORCE RECONNECT */
> @@ -646,14 +651,16 @@ static void show_efi_boot_opt_data(int id, void *data)
>  /* HIDDEN */
>  lo.attributes & LOAD_OPTION_HIDDEN ? 'H' : '-',
>  lo.attributes);
> - printf("\tlabel: %s\n", label);
> + printf("  label: %s\n", label);
> 
>   dp_str = efi_dp_str(lo.file_path);
> - printf("\tfile_path: %ls\n", dp_str);
> + printf("  file_path: %ls\n", dp_str);
>   efi_free_pool(dp_str);
> 
> - printf("\tdata: %s\n", lo.optional_data);
> -
> + printf("  data:\n");
> + print_hex_dump("", DUMP_PREFIX_OFFSET, 16, 1,
> +lo.optional_data, size + (u8 *)data -
> +(u8 *)lo.optional_data, true);
>   free(label);
>  }
> 
> @@ -686,7 +693,7 @@ static void show_efi_boot_opt(int id)
>   data));
>   }
>   if (ret == EFI_SUCCESS)
> - show_efi_boot_opt_data(id, data);
> + show_efi_boot_opt_data(id, data, size);
>   else if (ret == EFI_NOT_FOUND)
>   printf("Boot

Re: [U-Boot] [PATCH v2 2/2] efi_loader: parameter checks in StartImage and Exit()

2019-04-10 Thread Takahiro Akashi
On Fri, Apr 05, 2019 at 03:52:58AM +0200, Heinrich Schuchardt wrote:
> Add parameter checks in the StartImage() and Exit() boottime services:
> - check that the image handle is valid and has the loaded image protocol
>   installed
> - in StartImage() record the current image
> - in Exit() check that the image is the current image

Does this check logic work for a case of nested calls of StartImage() at all?

-Takahiro Akashi

> Signed-off-by: Heinrich Schuchardt 
> ---
> v2
>   avoid `parent_image` may be used uninitialized
> ---
>  lib/efi_loader/efi_boottime.c | 27 +++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> index 6aac8391c5..970c01614e 100644
> --- a/lib/efi_loader/efi_boottime.c
> +++ b/lib/efi_loader/efi_boottime.c
> @@ -26,6 +26,9 @@ LIST_HEAD(efi_obj_list);
>  /* List of all events */
>  LIST_HEAD(efi_events);
> 
> +/* Handle of the currently executing image */
> +static efi_handle_t current_image;
> +
>  /*
>   * If we're running on nasty systems (32bit ARM booting into non-EFI Linux)
>   * we need to do trickery with caches. Since we don't want to break the EFI
> @@ -2631,9 +2634,18 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t 
> image_handle,
>   struct efi_loaded_image_obj *image_obj =
>   (struct efi_loaded_image_obj *)image_handle;
>   efi_status_t ret;
> + void *info;
> + efi_handle_t parent_image = current_image;
> 
>   EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
> 
> + /* Check parameters */
> + ret = EFI_CALL(efi_open_protocol(image_handle, _guid_loaded_image,
> +  , NULL, NULL,
> +  EFI_OPEN_PROTOCOL_GET_PROTOCOL));
> + if (ret != EFI_SUCCESS)
> + return EFI_EXIT(EFI_INVALID_PARAMETER);
> +
>   efi_is_direct_boot = false;
> 
>   /* call the image! */
> @@ -2662,9 +2674,11 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t 
> image_handle,
> __efi_nesting_dec(),
> (unsigned long)((uintptr_t)image_obj->exit_status &
> ~EFI_ERROR_MASK));
> + current_image = parent_image;
>   return EFI_EXIT(image_obj->exit_status);
>   }
> 
> + current_image = image_handle;
>   ret = EFI_CALL(image_obj->entry(image_handle, ));
> 
>   /*
> @@ -2699,12 +2713,23 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
>* TODO: We should call the unload procedure of the loaded
>*   image protocol.
>*/
> + efi_status_t ret;
> + void *info;
>   struct efi_loaded_image_obj *image_obj =
>   (struct efi_loaded_image_obj *)image_handle;
> 
>   EFI_ENTRY("%p, %ld, %zu, %p", image_handle, exit_status,
> exit_data_size, exit_data);
> 
> + /* Check parameters */
> + if (image_handle != current_image)
> + goto out;
> + ret = EFI_CALL(efi_open_protocol(image_handle, _guid_loaded_image,
> +  , NULL, NULL,
> +  EFI_OPEN_PROTOCOL_GET_PROTOCOL));
> + if (ret != EFI_SUCCESS)
> + goto out;
> +
>   /* Make sure entry/exit counts for EFI world cross-overs match */
>   EFI_EXIT(exit_status);
> 
> @@ -2718,6 +2743,8 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
>   longjmp(_obj->exit_jmp, 1);
> 
>   panic("EFI application exited");
> +out:
> + return EFI_EXIT(EFI_INVALID_PARAMETER);
>  }
> 
>  /**
> --
> 2.20.1
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [U-Boot, RESEND, v5, 3/7] test: fs: Add filesystem integrity checks

2019-04-09 Thread Takahiro Akashi
On Wed, Apr 10, 2019 at 11:51:20AM +0900, Takahiro Akashi wrote:
> On Tue, Apr 09, 2019 at 10:25:14PM -0400, Tom Rini wrote:
> > On Wed, Apr 10, 2019 at 10:37:42AM +0900, Takahiro Akashi wrote:
> > > On Tue, Apr 09, 2019 at 08:19:40PM -0400, Tom Rini wrote:
> > > > On Wed, Apr 10, 2019 at 02:10:12AM +0200, Heinrich Schuchardt wrote:
> > > > > On 4/9/19 10:03 PM, Tom Rini wrote:
> > > > > > On Wed, Feb 13, 2019 at 12:15:23PM +0100, Jean-Jacques Hiblot wrote:
> > > > > >
> > > > > >> We need to make sure that file writes,file creation, etc. are 
> > > > > >> properly
> > > > > >> performed and do not corrupt the filesystem.
> > > > > >> To help with this, introduce the assert_fs_integrity() function 
> > > > > >> that
> > > > > >> executes the appropriate fsck tool. It should be called at the end 
> > > > > >> of any
> > > > > >> test that modify the content/organization of the filesystem.
> > > > > >> Currently only supports FATs and EXT4.
> > > > > >>
> > > > > >> Signed-off-by: Jean-Jacques Hiblot 
> > > > > >> Reviewed-by: Tom Rini 
> > > > > >
> > > > > > OK, I'm adding in a bunch of people to CC here.  The issue with this
> > > > > > patch is that by adding fsck to our tests we see 34 FAT16/FAT32
> > > > > > failures:
> > > > > > TestFsBasic.test_fs13[fat16]
> > > > > > TestFsBasic.test_fs11[fat32]
> > > > > > TestFsBasic.test_fs12[fat32]
> > > > > > TestFsBasic.test_fs13[fat32]
> > > > > > TestFsExt.test_fs_ext1[fat32]
> > > > > > TestFsExt.test_fs_ext2[fat32]
> > > > > > TestFsExt.test_fs_ext3[fat32]
> > > > > > TestFsExt.test_fs_ext4[fat32]
> > > > > > TestFsExt.test_fs_ext5[fat32]
> > > > > > TestFsExt.test_fs_ext6[fat32]
> > > > > > TestFsExt.test_fs_ext7[fat32]
> > > > > > TestFsExt.test_fs_ext8[fat32]
> > > > > > TestFsExt.test_fs_ext9[fat32]
> > > > > > TestMkdir.test_mkdir6[fat16]
> > > > > > TestMkdir.test_mkdir1[fat32]
> > > > > > TestMkdir.test_mkdir2[fat32]
> > > > > > TestMkdir.test_mkdir3[fat32]
> > > > > > TestMkdir.test_mkdir4[fat32]
> > > > > > TestMkdir.test_mkdir5[fat32]
> > > > > > TestMkdir.test_mkdir6[fat32]
> > > > > > TestUnlink.test_unlink1[fat16]
> > > > > > TestUnlink.test_unlink2[fat16]
> > > > > > TestUnlink.test_unlink3[fat16]
> > > > > > TestUnlink.test_unlink4[fat16]
> > > > > > TestUnlink.test_unlink5[fat16]
> > > > > > TestUnlink.test_unlink6[fat16]
> > > > > > TestUnlink.test_unlink7[fat16]
> > > > > > TestUnlink.test_unlink1[fat32]
> > > > > > TestUnlink.test_unlink2[fat32]
> > > > > > TestUnlink.test_unlink3[fat32]
> > > > > > TestUnlink.test_unlink4[fat32]
> > > > > > TestUnlink.test_unlink5[fat32]
> > > > > > TestUnlink.test_unlink6[fat32]
> > > > > > TestUnlink.test_unlink7[fat32]
> > > > > 
> > > > > I appreciate that we get tests for file system functions.
> > > > > 
> > > > > Unfortunately the test output is rudimentary. Can we have something 
> > > > > more
> > > > > expressive than unlink1 - unlink7?
> > > > > 
> > > > > CCing Takahiro as he was contributing recently to FAT.
> > > > 
> > > > Sorry, yes, kind of?  I pasted that in for brevity, but it's basically
> > > > that for example all of test/py/tests/test_fs/test_unlink.py fails if
> > > > you fsck the image in question after each test.  If you apply
> > > > https://patchwork.ozlabs.org/patch/1041186/ (to avoid spurious ext4
> > > > failures) and then https://patchwork.ozlabs.org/patch/1041181/ and run
> > > > 'make tests' you'll see the full output.
> > > 
> > > I have no time to dig into this issue right now,
> > > but if you give me a log from fsck, particularly
> > > why fsck failed here, it would help me to understand
> > > the problem.
> > 
> > The raw log can be seen here:
> > https://gist.github.com/trini/b68799ed9880a31a3289e9bea033831d
> 
> Thanks. I can find error messages like:
> Free cluster summary wrong (144636 vs. really 144380)
> 
> So there seems to be a leak in reclaiming freed clusters.

A count of free clusters, along with other info, is kept in an "info sector"
on a file system (only for fat32), but in U-Boot fat, none of information
in that sector is currently maintained. So this error would be inevitable.
I don't know any fsck option to suppress this kind of check.

-Takahiro Akashi

> > > # like the case of ext4, we might have to turn off
> > > # some option at fsck?
> > 
> > Note that for ext4 we're turning off the metadata csum feature of the
> > filesystem as we do not support it.
> 
> I'm afraid that this is not the case.
> 
> -Takahiro Akashi
> 
> > -- 
> > Tom
> 
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [U-Boot, RESEND, v5, 3/7] test: fs: Add filesystem integrity checks

2019-04-09 Thread Takahiro Akashi
On Tue, Apr 09, 2019 at 10:25:14PM -0400, Tom Rini wrote:
> On Wed, Apr 10, 2019 at 10:37:42AM +0900, Takahiro Akashi wrote:
> > On Tue, Apr 09, 2019 at 08:19:40PM -0400, Tom Rini wrote:
> > > On Wed, Apr 10, 2019 at 02:10:12AM +0200, Heinrich Schuchardt wrote:
> > > > On 4/9/19 10:03 PM, Tom Rini wrote:
> > > > > On Wed, Feb 13, 2019 at 12:15:23PM +0100, Jean-Jacques Hiblot wrote:
> > > > >
> > > > >> We need to make sure that file writes,file creation, etc. are 
> > > > >> properly
> > > > >> performed and do not corrupt the filesystem.
> > > > >> To help with this, introduce the assert_fs_integrity() function that
> > > > >> executes the appropriate fsck tool. It should be called at the end 
> > > > >> of any
> > > > >> test that modify the content/organization of the filesystem.
> > > > >> Currently only supports FATs and EXT4.
> > > > >>
> > > > >> Signed-off-by: Jean-Jacques Hiblot 
> > > > >> Reviewed-by: Tom Rini 
> > > > >
> > > > > OK, I'm adding in a bunch of people to CC here.  The issue with this
> > > > > patch is that by adding fsck to our tests we see 34 FAT16/FAT32
> > > > > failures:
> > > > > TestFsBasic.test_fs13[fat16]
> > > > > TestFsBasic.test_fs11[fat32]
> > > > > TestFsBasic.test_fs12[fat32]
> > > > > TestFsBasic.test_fs13[fat32]
> > > > > TestFsExt.test_fs_ext1[fat32]
> > > > > TestFsExt.test_fs_ext2[fat32]
> > > > > TestFsExt.test_fs_ext3[fat32]
> > > > > TestFsExt.test_fs_ext4[fat32]
> > > > > TestFsExt.test_fs_ext5[fat32]
> > > > > TestFsExt.test_fs_ext6[fat32]
> > > > > TestFsExt.test_fs_ext7[fat32]
> > > > > TestFsExt.test_fs_ext8[fat32]
> > > > > TestFsExt.test_fs_ext9[fat32]
> > > > > TestMkdir.test_mkdir6[fat16]
> > > > > TestMkdir.test_mkdir1[fat32]
> > > > > TestMkdir.test_mkdir2[fat32]
> > > > > TestMkdir.test_mkdir3[fat32]
> > > > > TestMkdir.test_mkdir4[fat32]
> > > > > TestMkdir.test_mkdir5[fat32]
> > > > > TestMkdir.test_mkdir6[fat32]
> > > > > TestUnlink.test_unlink1[fat16]
> > > > > TestUnlink.test_unlink2[fat16]
> > > > > TestUnlink.test_unlink3[fat16]
> > > > > TestUnlink.test_unlink4[fat16]
> > > > > TestUnlink.test_unlink5[fat16]
> > > > > TestUnlink.test_unlink6[fat16]
> > > > > TestUnlink.test_unlink7[fat16]
> > > > > TestUnlink.test_unlink1[fat32]
> > > > > TestUnlink.test_unlink2[fat32]
> > > > > TestUnlink.test_unlink3[fat32]
> > > > > TestUnlink.test_unlink4[fat32]
> > > > > TestUnlink.test_unlink5[fat32]
> > > > > TestUnlink.test_unlink6[fat32]
> > > > > TestUnlink.test_unlink7[fat32]
> > > > 
> > > > I appreciate that we get tests for file system functions.
> > > > 
> > > > Unfortunately the test output is rudimentary. Can we have something more
> > > > expressive than unlink1 - unlink7?
> > > > 
> > > > CCing Takahiro as he was contributing recently to FAT.
> > > 
> > > Sorry, yes, kind of?  I pasted that in for brevity, but it's basically
> > > that for example all of test/py/tests/test_fs/test_unlink.py fails if
> > > you fsck the image in question after each test.  If you apply
> > > https://patchwork.ozlabs.org/patch/1041186/ (to avoid spurious ext4
> > > failures) and then https://patchwork.ozlabs.org/patch/1041181/ and run
> > > 'make tests' you'll see the full output.
> > 
> > I have no time to dig into this issue right now,
> > but if you give me a log from fsck, particularly
> > why fsck failed here, it would help me to understand
> > the problem.
> 
> The raw log can be seen here:
> https://gist.github.com/trini/b68799ed9880a31a3289e9bea033831d

Thanks. I can find error messages like:
Free cluster summary wrong (144636 vs. really 144380)

So there seems to be a leak in reclaiming freed clusters.

> > # like the case of ext4, we might have to turn off
> > # some option at fsck?
> 
> Note that for ext4 we're turning off the metadata csum feature of the
> filesystem as we do not support it.

I'm afraid that this is not the case.

-Takahiro Akashi

> -- 
> Tom


___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [U-Boot, RESEND, v5, 3/7] test: fs: Add filesystem integrity checks

2019-04-09 Thread Takahiro Akashi
On Tue, Apr 09, 2019 at 08:19:40PM -0400, Tom Rini wrote:
> On Wed, Apr 10, 2019 at 02:10:12AM +0200, Heinrich Schuchardt wrote:
> > On 4/9/19 10:03 PM, Tom Rini wrote:
> > > On Wed, Feb 13, 2019 at 12:15:23PM +0100, Jean-Jacques Hiblot wrote:
> > >
> > >> We need to make sure that file writes,file creation, etc. are properly
> > >> performed and do not corrupt the filesystem.
> > >> To help with this, introduce the assert_fs_integrity() function that
> > >> executes the appropriate fsck tool. It should be called at the end of any
> > >> test that modify the content/organization of the filesystem.
> > >> Currently only supports FATs and EXT4.
> > >>
> > >> Signed-off-by: Jean-Jacques Hiblot 
> > >> Reviewed-by: Tom Rini 
> > >
> > > OK, I'm adding in a bunch of people to CC here.  The issue with this
> > > patch is that by adding fsck to our tests we see 34 FAT16/FAT32
> > > failures:
> > > TestFsBasic.test_fs13[fat16]
> > > TestFsBasic.test_fs11[fat32]
> > > TestFsBasic.test_fs12[fat32]
> > > TestFsBasic.test_fs13[fat32]
> > > TestFsExt.test_fs_ext1[fat32]
> > > TestFsExt.test_fs_ext2[fat32]
> > > TestFsExt.test_fs_ext3[fat32]
> > > TestFsExt.test_fs_ext4[fat32]
> > > TestFsExt.test_fs_ext5[fat32]
> > > TestFsExt.test_fs_ext6[fat32]
> > > TestFsExt.test_fs_ext7[fat32]
> > > TestFsExt.test_fs_ext8[fat32]
> > > TestFsExt.test_fs_ext9[fat32]
> > > TestMkdir.test_mkdir6[fat16]
> > > TestMkdir.test_mkdir1[fat32]
> > > TestMkdir.test_mkdir2[fat32]
> > > TestMkdir.test_mkdir3[fat32]
> > > TestMkdir.test_mkdir4[fat32]
> > > TestMkdir.test_mkdir5[fat32]
> > > TestMkdir.test_mkdir6[fat32]
> > > TestUnlink.test_unlink1[fat16]
> > > TestUnlink.test_unlink2[fat16]
> > > TestUnlink.test_unlink3[fat16]
> > > TestUnlink.test_unlink4[fat16]
> > > TestUnlink.test_unlink5[fat16]
> > > TestUnlink.test_unlink6[fat16]
> > > TestUnlink.test_unlink7[fat16]
> > > TestUnlink.test_unlink1[fat32]
> > > TestUnlink.test_unlink2[fat32]
> > > TestUnlink.test_unlink3[fat32]
> > > TestUnlink.test_unlink4[fat32]
> > > TestUnlink.test_unlink5[fat32]
> > > TestUnlink.test_unlink6[fat32]
> > > TestUnlink.test_unlink7[fat32]
> > 
> > I appreciate that we get tests for file system functions.
> > 
> > Unfortunately the test output is rudimentary. Can we have something more
> > expressive than unlink1 - unlink7?
> > 
> > CCing Takahiro as he was contributing recently to FAT.
> 
> Sorry, yes, kind of?  I pasted that in for brevity, but it's basically
> that for example all of test/py/tests/test_fs/test_unlink.py fails if
> you fsck the image in question after each test.  If you apply
> https://patchwork.ozlabs.org/patch/1041186/ (to avoid spurious ext4
> failures) and then https://patchwork.ozlabs.org/patch/1041181/ and run
> 'make tests' you'll see the full output.

I have no time to dig into this issue right now,
but if you give me a log from fsck, particularly
why fsck failed here, it would help me to understand
the problem.

# like the case of ext4, we might have to turn off
# some option at fsck?

Thanks,
-Takahiro Akashi

> -- 
> Tom


___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2 2/2] efi_loader: parameter checks in StartImage and Exit()

2019-04-08 Thread Takahiro Akashi
On Fri, Apr 05, 2019 at 03:52:58AM +0200, Heinrich Schuchardt wrote:
> Add parameter checks in the StartImage() and Exit() boottime services:
> - check that the image handle is valid and has the loaded image protocol
>   installed
> - in StartImage() record the current image
> - in Exit() check that the image is the current image
> 
> Signed-off-by: Heinrich Schuchardt 
> ---
> v2
>   avoid `parent_image` may be used uninitialized
> ---
>  lib/efi_loader/efi_boottime.c | 27 +++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> index 6aac8391c5..970c01614e 100644
> --- a/lib/efi_loader/efi_boottime.c
> +++ b/lib/efi_loader/efi_boottime.c
> @@ -26,6 +26,9 @@ LIST_HEAD(efi_obj_list);
>  /* List of all events */
>  LIST_HEAD(efi_events);
> 
> +/* Handle of the currently executing image */
> +static efi_handle_t current_image;
> +
>  /*
>   * If we're running on nasty systems (32bit ARM booting into non-EFI Linux)
>   * we need to do trickery with caches. Since we don't want to break the EFI
> @@ -2631,9 +2634,18 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t 
> image_handle,
>   struct efi_loaded_image_obj *image_obj =
>   (struct efi_loaded_image_obj *)image_handle;
>   efi_status_t ret;
> + void *info;
> + efi_handle_t parent_image = current_image;
> 
>   EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
> 
> + /* Check parameters */
> + ret = EFI_CALL(efi_open_protocol(image_handle, _guid_loaded_image,
> +  , NULL, NULL,
> +  EFI_OPEN_PROTOCOL_GET_PROTOCOL));
> + if (ret != EFI_SUCCESS)
> + return EFI_EXIT(EFI_INVALID_PARAMETER);
> +
>   efi_is_direct_boot = false;
> 
>   /* call the image! */
> @@ -2662,9 +2674,11 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t 
> image_handle,
> __efi_nesting_dec(),
> (unsigned long)((uintptr_t)image_obj->exit_status &
> ~EFI_ERROR_MASK));
> + current_image = parent_image;
>   return EFI_EXIT(image_obj->exit_status);
>   }
> 
> + current_image = image_handle;
>   ret = EFI_CALL(image_obj->entry(image_handle, ));
> 
>   /*
> @@ -2699,12 +2713,23 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
>* TODO: We should call the unload procedure of the loaded
>*   image protocol.
>*/
> + efi_status_t ret;
> + void *info;
>   struct efi_loaded_image_obj *image_obj =
>   (struct efi_loaded_image_obj *)image_handle;
> 
>   EFI_ENTRY("%p, %ld, %zu, %p", image_handle, exit_status,
> exit_data_size, exit_data);
> 
> + /* Check parameters */
> + if (image_handle != current_image)
> + goto out;
> + ret = EFI_CALL(efi_open_protocol(image_handle, _guid_loaded_image,
> +  , NULL, NULL,
> +  EFI_OPEN_PROTOCOL_GET_PROTOCOL));

Why do we need this protocol check again?

-Takahiro Akashi

> + if (ret != EFI_SUCCESS)
> + goto out;
> +
>   /* Make sure entry/exit counts for EFI world cross-overs match */
>   EFI_EXIT(exit_status);
> 
> @@ -2718,6 +2743,8 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t 
> image_handle,
>   longjmp(_obj->exit_jmp, 1);
> 
>   panic("EFI application exited");
> +out:
> + return EFI_EXIT(EFI_INVALID_PARAMETER);
>  }
> 
>  /**
> --
> 2.20.1
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 1/1] efi_loader: correct parameter size in efi_allocate_pool

2019-03-19 Thread Takahiro Akashi
On Tue, Mar 19, 2019 at 07:59:37AM +0100, Heinrich Schuchardt wrote:
> On 3/19/19 1:19 AM, Takahiro Akashi wrote:
> > On Mon, Mar 18, 2019 at 08:32:23PM +0100, Heinrich Schuchardt wrote:
> >> efi_allocate_pages() expects a (uint64_t *) pointer to pass the address of
> >> the assigned memory. If we pass the address of a pointer here, an illegal
> >> memory access occurs on 32bit systems.
> >>
> >> Fixes: 282a06cbcae8 ("efi_loader: Expose U-Boot addresses in memory map
> >> for sandbox")
> >> Signed-off-by: Heinrich Schuchardt 
> >> ---
> >>  lib/efi_loader/efi_memory.c | 5 +++--
> >>  1 file changed, 3 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
> >> index ebd2b36c03..55622d2fb4 100644
> >> --- a/lib/efi_loader/efi_memory.c
> >> +++ b/lib/efi_loader/efi_memory.c
> >> @@ -440,6 +440,7 @@ efi_status_t efi_free_pages(uint64_t memory, 
> >> efi_uintn_t pages)
> >>  efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void 
> >> **buffer)
> >>  {
> >>efi_status_t r;
> >> +  u64 addr;
> >>struct efi_pool_allocation *alloc;
> >>u64 num_pages = efi_size_in_pages(size +
> >>  sizeof(struct efi_pool_allocation));
> >> @@ -453,9 +454,9 @@ efi_status_t efi_allocate_pool(int pool_type, 
> >> efi_uintn_t size, void **buffer)
> >>}
> >>  
> >>r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, pool_type, num_pages,
> >> - (uint64_t *));
> > 
> > I wonder why efi_allocate_pages() doesn't expect (void **) for the fourth
> > argument.
> 
> efi_allocate_pages implements the AllocatePages() boot time service. The
> UEFI spec mandates that the parameter is of type EFI_PHYSICAL_ADDRESS *
> i.e. u64 *.

But allocate_pool() takes "void **" for the third argument. Why?

> > If this is because the type of the argument is a pointer to "physical 
> > address,"
> > 
> >> -
> >> + );
> >>if (r == EFI_SUCCESS) {
> >> +  alloc = (struct efi_pool_allocation *)(uintptr_t)addr;
> > 
> > we should use map_sysmem() here.
> 
> This would create a bug on the sandbox.
> 
> map_sysmem() converts an address from the sandbox virtual address space
> to the address space that can be used by EFI binaries.
> 
> AllocatePool() and AllocatePages() both refer to the same address space.
> 
> Cf. commit 49759743bf09 ("efi_loader: eliminate sandbox addresses")

I don't know the case of sandbox, but What I have in mind is
LPAE, that is, the system have >32-bit physical address space,
but cpu can only access it via 32-bit pointer.

Thanks,
-Takahiro Akashi

> Best regards
> 
> Heinrich
> 
> > 
> > Thanks,
> > -Takahiro Akashi
> > 
> >>alloc->num_pages = num_pages;
> >>*buffer = alloc->data;
> >>}
> >> -- 
> >> 2.20.1
> >>
> > 
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 1/1] efi_loader: correct parameter size in efi_allocate_pool

2019-03-18 Thread Takahiro Akashi
On Mon, Mar 18, 2019 at 08:32:23PM +0100, Heinrich Schuchardt wrote:
> efi_allocate_pages() expects a (uint64_t *) pointer to pass the address of
> the assigned memory. If we pass the address of a pointer here, an illegal
> memory access occurs on 32bit systems.
> 
> Fixes: 282a06cbcae8 ("efi_loader: Expose U-Boot addresses in memory map
> for sandbox")
> Signed-off-by: Heinrich Schuchardt 
> ---
>  lib/efi_loader/efi_memory.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
> index ebd2b36c03..55622d2fb4 100644
> --- a/lib/efi_loader/efi_memory.c
> +++ b/lib/efi_loader/efi_memory.c
> @@ -440,6 +440,7 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t 
> pages)
>  efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void 
> **buffer)
>  {
>   efi_status_t r;
> + u64 addr;
>   struct efi_pool_allocation *alloc;
>   u64 num_pages = efi_size_in_pages(size +
> sizeof(struct efi_pool_allocation));
> @@ -453,9 +454,9 @@ efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t 
> size, void **buffer)
>   }
>  
>   r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, pool_type, num_pages,
> -(uint64_t *));

I wonder why efi_allocate_pages() doesn't expect (void **) for the fourth
argument.
If this is because the type of the argument is a pointer to "physical address,"

> -
> +);
>   if (r == EFI_SUCCESS) {
> +     alloc = (struct efi_pool_allocation *)(uintptr_t)addr;

we should use map_sysmem() here.

Thanks,
-Takahiro Akashi

>   alloc->num_pages = num_pages;
>   *buffer = alloc->data;
>   }
> -- 
> 2.20.1
> 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH] qemu-arm: Add persistent environment support

2018-12-14 Thread Takahiro Akashi
On Thu, Dec 13, 2018 at 02:43:58AM +0200, Tuomas Tynkkynen wrote:
> Hi Sumit, Takahiro,
> 
> On Wed, 12 Dec 2018 10:42:56 +0900
> Takahiro Akashi  wrote:
> 
> > On Tue, Dec 11, 2018 at 06:04:05PM +0530, Sumit Garg wrote:
> > > On Mon, 26 Nov 2018 at 16:51, Sumit Garg 
> > > wrote:  
> > > >
> > > > Currently on qemu-arm platforms environment is kept in RAM.
> > > > Instead use pflash device 1 to provide persistent environment
> > > > support across device reset.
> > > >
> > > > Also (optionally) provide support for persistent environment
> > > > across qemu machine OFF/ON using following instructions:
> > > >
> > > > - Create envstore.img using qemu-img:
> > > > qemu-img create -f raw envstore.img 64M
> > > > - Add a pflash drive parameter to the command line:
> > > > -drive if=pflash,format=raw,index=1,file=envstore.img
> > > >
> > > > Signed-off-by: Sumit Garg 
> > > > ---
> > > >  configs/qemu_arm64_defconfig | 7 +++
> > > >  configs/qemu_arm_defconfig   | 7 +++
> > > >  doc/README.qemu-arm  | 6 ++
> > > >  include/configs/qemu-arm.h   | 8 +++-
> > > >  4 files changed, 27 insertions(+), 1 deletion(-)
> > > >  
> > > 
> > > Gentle reminder. Please let me know if you have any further
> > > comments.  
> 
> I'm not too familiar with the UEFI/ATF related aspects here, but I
> think that the read-only parts (aka u-boot.bin) and read-write parts
> (the U-Boot environment) should belong to different files (which is
> what this patch series does). Basically, IMO as a normal user I should
> be able to run QEMU on a distro-provided U-Boot binary with something
> like:

So probably I'm not a normal user.
Tom has already applied this patch, and I would change qemu-arm.h
in my local repo if necessary. That's fine.

> qemu-system-arm -bios /usr/share/u-boot/qemu_arm.bin

# As u-boot is quite board-specific, I don't think distro's default
u-boot, if any, won't work on qemu.

> and not have it fail due to not having write permission to /usr/.
> 
> > Another use case is atf + u-boot (although I don't know people are
> > interested in it). Put bl1.bin in flash0(0x0-0x400) and put
> > fip.bin in flash1(0x400-0x800). Please note that, with
> > secure=on, flash0 is in secure and flash1 is in non-secure.
> > While I admit that your patch is workable, my point is that there are
> > different use cases and it may not be a good idea to put one
> > configuration in qemu-arm.h.

> Can EDK2 in QEMU boot with ATF and if so, how does it lay out things?

Do you mean UEFI? EDK2 is an implementation, UEFI is the specification/
interface.
Just FYI, as I said, I experimentally succeeded to run atf + u-boot
as BL33, only modifying CONFIG_SYS_TEXT_BASE and CONFIG_SYS_FLASH_BASE
(and CONFIG_ENV_* if needed).

> Would it be possible to build U-Boot in such a way that u-boot.bin
> could be substituted in existing build scripts or instructions in place
> of the EDK2 binary so that things still work the same?
> 
> Or in other words, if EDK2 has already has a working
> implementation of something (such as the flash layout), IMO we should
> prefer to use that instead of reimplementing it in a different
> way.

It is up to the implementation how efi variables are stored
in storage while efi variables on u-boot are mapped to corresponding
u-boot environment variables. So there's no compatibility in flash layout
between EDK2 and u-boot/UEFI.

Thanks,
-Takahiro Akashi


> - Tuomas
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH] qemu-arm: Add persistent environment support

2018-12-11 Thread Takahiro Akashi
On Wed, Dec 12, 2018 at 12:14:27PM +0530, Sumit Garg wrote:
> On Wed, 12 Dec 2018 at 07:09, Takahiro Akashi
>  wrote:
> >
> > On Tue, Dec 11, 2018 at 06:04:05PM +0530, Sumit Garg wrote:
> > > On Mon, 26 Nov 2018 at 16:51, Sumit Garg  wrote:
> > > >
> > > > Currently on qemu-arm platforms environment is kept in RAM. Instead
> > > > use pflash device 1 to provide persistent environment support across
> > > > device reset.
> > > >
> > > > Also (optionally) provide support for persistent environment across
> > > > qemu machine OFF/ON using following instructions:
> > > >
> > > > - Create envstore.img using qemu-img:
> > > > qemu-img create -f raw envstore.img 64M
> > > > - Add a pflash drive parameter to the command line:
> > > > -drive if=pflash,format=raw,index=1,file=envstore.img
> > > >
> > > > Signed-off-by: Sumit Garg 
> > > > ---
> > > >  configs/qemu_arm64_defconfig | 7 +++
> > > >  configs/qemu_arm_defconfig   | 7 +++
> > > >  doc/README.qemu-arm  | 6 ++
> > > >  include/configs/qemu-arm.h   | 8 +++-
> > > >  4 files changed, 27 insertions(+), 1 deletion(-)
> > > >
> > >
> > > Gentle reminder. Please let me know if you have any further comments.
> >
> > Another use case is atf + u-boot (although I don't know people are
> > interested in it). Put bl1.bin in flash0(0x0-0x400) and put
> > fip.bin in flash1(0x400-0x800). Please note that, with secure=on,
> > flash0 is in secure and flash1 is in non-secure.
> 
> I don't think current u-boot with "CONFIG_SYS_TEXT_BASE=0x"
> (flash0 address) could work in atf + u-boot configuration with bl33
> address as NS_IMAGE_OFFSET=0x6000 [1] (RAM address). Alternatively
> we could use PRELOADED_BL33_BASE to specify flash address but that
> certainly won't be flash0 start address.

I was able to run atf + u-boot with some tweaks on some CONFIG_*
and even successfully ran linux kernel with bootefi.
But I don't want to go into details now.

> Also from TF-A doc for qemu [2] it seems to support UEFI/edk2 boot.
> 
> IMHO, there should be separate u-boot ram defconfig to work with atf +
> u-boot configuration. Also we may choose a different flash address for
> environment for this target.

My point is, again,


> [1] 
> https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/qemu/include/platform_def.h#L168
> [2] 
> https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/plat/qemu.rst
> 
> -Sumit
> 
> > While I admit that your patch is workable, my point is that there are
> > different use cases and it may not be a good idea to put one configuration
> > in qemu-arm.h.

here.
It's time that we need get opinions from maintainers or anybody else.

Thanks,
-Takahiro Akashi

> > Thanks,
> > -Takahiro Akashi
> >
> >
> > > -Sumit
> > >
> > > > diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig
> > > > index f4502c9..0f13716 100644
> > > > --- a/configs/qemu_arm64_defconfig
> > > > +++ b/configs/qemu_arm64_defconfig
> > > > @@ -29,3 +29,10 @@ CONFIG_USB=y
> > > >  CONFIG_DM_USB=y
> > > >  CONFIG_USB_EHCI_HCD=y
> > > >  CONFIG_USB_EHCI_PCI=y
> > > > +CONFIG_ENV_IS_IN_FLASH=y
> > > > +CONFIG_MTD=y
> > > > +CONFIG_MTD_NOR_FLASH=y
> > > > +CONFIG_FLASH_CFI_DRIVER=y
> > > > +CONFIG_CFI_FLASH=y
> > > > +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
> > > > +CONFIG_SYS_FLASH_CFI=y
> > > > diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig
> > > > index acebdc5..b75363e 100644
> > > > --- a/configs/qemu_arm_defconfig
> > > > +++ b/configs/qemu_arm_defconfig
> > > > @@ -29,3 +29,10 @@ CONFIG_USB=y
> > > >  CONFIG_DM_USB=y
> > > >  CONFIG_USB_EHCI_HCD=y
> > > >  CONFIG_USB_EHCI_PCI=y
> > > > +CONFIG_ENV_IS_IN_FLASH=y
> > > > +CONFIG_MTD=y
> > > > +CONFIG_MTD_NOR_FLASH=y
> > > > +CONFIG_FLASH_CFI_DRIVER=y
> > > > +CONFIG_CFI_FLASH=y
> > > > +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
> > > > +CONFIG_SYS_FLASH_CFI=y
> > > > diff --git a/doc/README.qemu-arm b/doc/README.qemu-arm
> > > > index 2601656..e67bc13 100644
> > > > --- a/doc/README.qemu-arm
> > > > +++ b/doc/README.qemu-arm
> > > > @@ -47,6 +47,12 @@ The minimal QEMU comman

Re: [U-Boot] [PATCH] qemu-arm: Add persistent environment support

2018-12-11 Thread Takahiro Akashi
On Tue, Dec 11, 2018 at 06:04:05PM +0530, Sumit Garg wrote:
> On Mon, 26 Nov 2018 at 16:51, Sumit Garg  wrote:
> >
> > Currently on qemu-arm platforms environment is kept in RAM. Instead
> > use pflash device 1 to provide persistent environment support across
> > device reset.
> >
> > Also (optionally) provide support for persistent environment across
> > qemu machine OFF/ON using following instructions:
> >
> > - Create envstore.img using qemu-img:
> > qemu-img create -f raw envstore.img 64M
> > - Add a pflash drive parameter to the command line:
> > -drive if=pflash,format=raw,index=1,file=envstore.img
> >
> > Signed-off-by: Sumit Garg 
> > ---
> >  configs/qemu_arm64_defconfig | 7 +++
> >  configs/qemu_arm_defconfig   | 7 +++
> >  doc/README.qemu-arm  | 6 ++
> >  include/configs/qemu-arm.h   | 8 +++-
> >  4 files changed, 27 insertions(+), 1 deletion(-)
> >
> 
> Gentle reminder. Please let me know if you have any further comments.

Another use case is atf + u-boot (although I don't know people are
interested in it). Put bl1.bin in flash0(0x0-0x400) and put
fip.bin in flash1(0x400-0x800). Please note that, with secure=on,
flash0 is in secure and flash1 is in non-secure.
While I admit that your patch is workable, my point is that there are
different use cases and it may not be a good idea to put one configuration
in qemu-arm.h.

Thanks,
-Takahiro Akashi


> -Sumit
> 
> > diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig
> > index f4502c9..0f13716 100644
> > --- a/configs/qemu_arm64_defconfig
> > +++ b/configs/qemu_arm64_defconfig
> > @@ -29,3 +29,10 @@ CONFIG_USB=y
> >  CONFIG_DM_USB=y
> >  CONFIG_USB_EHCI_HCD=y
> >  CONFIG_USB_EHCI_PCI=y
> > +CONFIG_ENV_IS_IN_FLASH=y
> > +CONFIG_MTD=y
> > +CONFIG_MTD_NOR_FLASH=y
> > +CONFIG_FLASH_CFI_DRIVER=y
> > +CONFIG_CFI_FLASH=y
> > +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
> > +CONFIG_SYS_FLASH_CFI=y
> > diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig
> > index acebdc5..b75363e 100644
> > --- a/configs/qemu_arm_defconfig
> > +++ b/configs/qemu_arm_defconfig
> > @@ -29,3 +29,10 @@ CONFIG_USB=y
> >  CONFIG_DM_USB=y
> >  CONFIG_USB_EHCI_HCD=y
> >  CONFIG_USB_EHCI_PCI=y
> > +CONFIG_ENV_IS_IN_FLASH=y
> > +CONFIG_MTD=y
> > +CONFIG_MTD_NOR_FLASH=y
> > +CONFIG_FLASH_CFI_DRIVER=y
> > +CONFIG_CFI_FLASH=y
> > +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
> > +CONFIG_SYS_FLASH_CFI=y
> > diff --git a/doc/README.qemu-arm b/doc/README.qemu-arm
> > index 2601656..e67bc13 100644
> > --- a/doc/README.qemu-arm
> > +++ b/doc/README.qemu-arm
> > @@ -47,6 +47,12 @@ The minimal QEMU command line to get U-Boot up and 
> > running is:
> >  Note that for some odd reason qemu-system-aarch64 needs to be explicitly
> >  told to use a 64-bit CPU or it will boot in 32-bit mode.
> >
> > +Additional persistent U-boot environment support can be added as follows:
> > +- Create envstore.img using qemu-img:
> > +qemu-img create -f raw envstore.img 64M
> > +- Add a pflash drive parameter to the command line:
> > +-drive if=pflash,format=raw,index=1,file=envstore.img
> > +
> >  Additional peripherals that have been tested to work in both U-Boot and 
> > Linux
> >  can be enabled with the following command line parameters:
> >
> > diff --git a/include/configs/qemu-arm.h b/include/configs/qemu-arm.h
> > index fedc466..83a930b 100644
> > --- a/include/configs/qemu-arm.h
> > +++ b/include/configs/qemu-arm.h
> > @@ -21,7 +21,8 @@
> >  #define CONFIG_SYS_HZ   1000
> >
> >  /* Environment options */
> > -#define CONFIG_ENV_SIZESZ_64K
> > +#define CONFIG_ENV_ADDR0x400
> > +#define CONFIG_ENV_SIZESZ_256K
> >
> >  #define BOOT_TARGET_DEVICES(func) \
> > func(SCSI, scsi, 0) \
> > @@ -42,4 +43,9 @@
> >
> >  #define CONFIG_SYS_CBSIZE 512
> >
> > +#define CONFIG_SYS_MONITOR_BASECONFIG_SYS_TEXT_BASE
> > +#define CONFIG_SYS_FLASH_BASE  0x0
> > +#define CONFIG_SYS_MAX_FLASH_BANKS 2
> > +#define CONFIG_SYS_MAX_FLASH_SECT  256 /* Sector: 256K, Bank: 64M */
> > +
> >  #endif /* __CONFIG_H */
> > --
> > 2.7.4
> >
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH 0/4] efi_loader: non-volatile variables support

2018-12-06 Thread Takahiro Akashi
# My patch is more or less a RFC to raise attention.

On Wed, Dec 05, 2018 at 11:53:42AM +0530, Sumit Garg wrote:
> Hi Akashi,
> 
> On Wed, 28 Nov 2018 at 11:28, AKASHI Takahiro
>  wrote:
> >
> > As the subject suggested, this patch set allows any efi variable to be
> > volatile or non-volatile as UEFI specification describes.
> >
> > With my efishell patch[1] with patch #2, you can try as follows:
> >   => efi setvar PlatformLang en
> >   => efi setvar -nv BootNext =H0200
> >   => env save
> >
> 
> How do you expect usage of "EFI_VARIABLE_NON_VOLATILE" attribute to
> work during boot-time services as we don't have "env save" command
> option as a boot-time service?
> 
> Take example scenario with EDK2 shell launched from u-boot and tries
> to set non-volatile efi variable.

I know the issue, but

> IMHO, support should be added to "efi_set_variable" to save variable
> with "EFI_VARIABLE_NON_VOLATILE" attribute to non volatile storage.

I also hesitate to implement such a behavior to efi_set_variable
as it ends up writing to flash every time. Please note that data on
storage is a sorted list in plain text and so updating it can be painful.

-Takahiro Akashi


> -Sumit
> 
> > BootNext will be preserved across reboot, while PlatformLang not.
> >
> > Please note that, currently, setvar command does not automatically
> > append NON_VOLATILE attribute, while UEFI specification expects that
> > PlatformLang be non-volatile, you'd better also specify -nv for
> > this variable here.
> >
> > Patch #2/#3 depend on my efishell patch[1].
> > Patch #4 depends on my BootNext patch[2].
> >
> > Patch[1] and [2] have not been merged yet, so patch#1 can be applied
> > on its own.
> >
> > [1] https://lists.denx.de/pipermail/u-boot/2018-November/346450.html
> > [2] https://lists.denx.de/pipermail/u-boot/2018-November/349281.html
> >
> > AKASHI Takahiro (4):
> >   efi_loader: support non-volatile variable behavior
> >   cmd: efishell: support -nv option to setvar sub-command
> >   cmd: efishell: make Boot/BootOrder variable non-volatile
> >   efi_loader: bootmgr: make BootNext non-volatile
> >
> >  cmd/efishell.c| 20 ---
> >  env/env.c |  4 +++
> >  include/efi_loader.h  |  1 +
> >  lib/efi_loader/efi_bootmgr.c  |  3 +-
> >  lib/efi_loader/efi_variable.c | 64 +--
> >  5 files changed, 84 insertions(+), 8 deletions(-)
> >
> > --
> > 2.19.1
> >
> > ___
> > U-Boot mailing list
> > U-Boot@lists.denx.de
> > https://lists.denx.de/listinfo/u-boot
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


  1   2   >