[PATCH v5 4/4] fs: remove explicit efi configuration dependency

2024-01-16 Thread AKASHI Takahiro
Now it is clear that the feature actually depends on efi interfaces,
not "bootefi" command. efi_set_bootdev() will automatically be nullified
if necessary efi component is disabled.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
---
 fs/fs.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index f1a0b70d1d57..acf465bdd807 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -791,10 +791,9 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[],
return 1;
}
 
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
-   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
-   (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
-   len_read);
+   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
+   (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
+   len_read);
 
printf("%llu bytes read in %lu ms", len_read, time);
if (time > 0) {
-- 
2.34.1



[PATCH v5 3/4] net: tftp: remove explicit efi configuration dependency

2024-01-16 Thread AKASHI Takahiro
Now it is clear that the feature actually depends on efi interfaces,
not "bootefi" command. efi_set_bootdev() will automatically be nullified
if necessary efi component is disabled.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Ramon Fried 
Reviewed-by: Tom Rini 
---
 net/tftp.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/net/tftp.c b/net/tftp.c
index 88e71e67de35..2e335413492b 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -302,12 +302,10 @@ static void tftp_complete(void)
time_start * 1000, "/s");
}
puts("\ndone\n");
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) {
-   if (!tftp_put_active)
-   efi_set_bootdev("Net", "", tftp_filename,
-   map_sysmem(tftp_load_addr, 0),
-   net_boot_file_size);
-   }
+   if (!tftp_put_active)
+   efi_set_bootdev("Net", "", tftp_filename,
+   map_sysmem(tftp_load_addr, 0),
+   net_boot_file_size);
net_set_state(NETLOOP_SUCCESS);
 }
 
-- 
2.34.1



[PATCH v5 2/4] efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR

2024-01-16 Thread AKASHI Takahiro
At this point, EFI boot manager interfaces is fully independent from
bootefi command. So just rename the configuration parameter.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
---
 boot/Makefile   | 2 +-
 cmd/Kconfig | 4 ++--
 cmd/efidebug.c  | 4 ++--
 lib/efi_loader/Kconfig  | 2 +-
 lib/efi_loader/Makefile | 2 +-
 test/boot/bootflow.c| 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/boot/Makefile b/boot/Makefile
index a47e00274622..f0a279cde161 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -35,7 +35,7 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SANDBOX) += 
bootmeth_sandbox.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SCRIPT) += bootmeth_script.o
 obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o
 ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL
-obj-$(CONFIG_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
+obj-$(CONFIG_EFI_BOOTMGR) += bootmeth_efi_mgr.o
 obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o
 endif
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 150fa37a50a7..62d2ae3d3f1b 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -395,7 +395,7 @@ config CMD_BOOTEFI_BINARY
 
 config CMD_BOOTEFI_BOOTMGR
bool "UEFI Boot Manager command"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BOOTMGR
default y
help
  Select this option to enable the 'bootmgr' subcommand of 'bootefi'.
@@ -2153,7 +2153,7 @@ config CMD_EFIDEBUG
 config CMD_EFICONFIG
bool "eficonfig - provide menu-driven uefi variables maintenance 
interface"
default y if !HAS_BOARD_SIZE_LIMIT
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BOOTMGR
select MENU
help
  Enable the 'eficonfig' command which provides the menu-driven UEFI
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index aa8523797efb..a3a7556ea4a5 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -1414,7 +1414,7 @@ static __maybe_unused int do_efi_test_bootmgr(struct 
cmd_tbl *cmdtp, int flag,
 }
 
 static struct cmd_tbl cmd_efidebug_test_sub[] = {
-#ifdef CONFIG_BOOTEFI_BOOTMGR
+#ifdef CONFIG_EFI_BOOTMGR
U_BOOT_CMD_MKENT(bootmgr, CONFIG_SYS_MAXARGS, 1, do_efi_test_bootmgr,
 "", ""),
 #endif
@@ -1608,7 +1608,7 @@ U_BOOT_LONGHELP(efidebug,
"  - show UEFI memory map\n"
"efidebug tables\n"
"  - show UEFI configuration tables\n"
-#ifdef CONFIG_BOOTEFI_BOOTMGR
+#ifdef CONFIG_EFI_BOOTMGR
"efidebug test bootmgr\n"
"  - run simple bootmgr for test\n"
 #endif
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 64f2f1cdd161..db5571de1d95 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -41,7 +41,7 @@ config EFI_BINARY_EXEC
  You may enable CMD_BOOTEFI_BINARY so that you can use bootefi
  command to do that.
 
-config BOOTEFI_BOOTMGR
+config EFI_BOOTMGR
bool "UEFI Boot Manager"
default y
select BOOTMETH_GLOBAL if BOOTSTD
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index f0a31b4ad509..fcb0af7e7d6d 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -49,7 +49,7 @@ targets += initrddump.o
 endif
 
 obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
-obj-$(CONFIG_BOOTEFI_BOOTMGR) += efi_bootmgr.o
+obj-$(CONFIG_EFI_BOOTMGR) += efi_bootmgr.o
 obj-$(CONFIG_EFI_BINARY_EXEC) += efi_bootbin.o
 obj-y += efi_boottime.o
 obj-y += efi_helper.o
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 104f49deef2a..fa54dde661c8 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -374,7 +374,7 @@ static int bootflow_system(struct unit_test_state *uts)
 {
struct udevice *bootstd, *dev;
 
-   if (!IS_ENABLED(CONFIG_BOOTEFI_BOOTMGR))
+   if (!IS_ENABLED(CONFIG_EFI_BOOTMGR))
return -EAGAIN;
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, ));
ut_assertok(device_bind(bootstd, DM_DRIVER_GET(bootmeth_efi_mgr),
-- 
2.34.1



[PATCH v5 1/4] efi_loader: split unrelated code from efi_bootmgr.c

2024-01-16 Thread AKASHI Takahiro
Some code moved from cmd/bootefi.c is actually necessary only for "bootefi
" command (starting an image manually loaded by a user using U-Boot
load commands or other methods (like JTAG debugger).

The code will never been opted out as unused code by a compiler which
doesn't know how EFI boot manager is implemented. So introduce a new
configuration, CONFIG_EFI_BINARY_EXEC, to enforce them opted out
explicitly.

Signed-off-by: AKASHI Takahiro 
---
 boot/Kconfig |   4 +-
 cmd/Kconfig  |   6 +-
 include/efi_loader.h |  28 +-
 lib/efi_loader/Kconfig   |   9 +
 lib/efi_loader/Makefile  |   1 +
 lib/efi_loader/efi_bootbin.c | 211 +
 lib/efi_loader/efi_bootmgr.c | 488 ---
 lib/efi_loader/efi_device_path.c |   3 +-
 lib/efi_loader/efi_helper.c  | 286 ++
 9 files changed, 531 insertions(+), 505 deletions(-)
 create mode 100644 lib/efi_loader/efi_bootbin.c

diff --git a/boot/Kconfig b/boot/Kconfig
index 0894ecf4df1f..70ff24808b0b 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -523,7 +523,7 @@ config BOOTMETH_EXTLINUX_PXE
 
 config BOOTMETH_EFILOADER
bool "Bootdev support for EFI boot"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BINARY_EXEC
default y
help
  Enables support for EFI boot using bootdevs. This makes the
@@ -558,7 +558,7 @@ config BOOTMETH_DISTRO
select BOOTMETH_SCRIPT if CMDLINE # E.g. Armbian uses scripts
select BOOTMETH_EXTLINUX  # E.g. Debian uses these
select BOOTMETH_EXTLINUX_PXE if CMD_PXE && CMD_NET && DM_ETH
-   select BOOTMETH_EFILOADER if BOOTEFI_BOOTMGR # E.g. Ubuntu uses this
+   select BOOTMETH_EFILOADER if EFI_BINARY_EXEC # E.g. Ubuntu uses this
 
 config SPL_BOOTMETH_VBE
bool "Bootdev support for Verified Boot for Embedded (SPL)"
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 26ad03b6..150fa37a50a7 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -294,7 +294,7 @@ config CMD_BOOTMETH
 
 config BOOTM_EFI
bool "Support booting UEFI FIT images"
-   depends on BOOTEFI_BOOTMGR && CMD_BOOTM && FIT
+   depends on EFI_BINARY_EXEC && CMD_BOOTM && FIT
default y
help
  Support booting UEFI FIT images via the bootm command.
@@ -386,7 +386,7 @@ config CMD_BOOTEFI
 if CMD_BOOTEFI
 config CMD_BOOTEFI_BINARY
bool "Allow booting an EFI binary directly"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BINARY_EXEC
default y
help
  Select this option to enable direct execution of binary at 'bootefi'.
@@ -416,7 +416,7 @@ config CMD_BOOTEFI_HELLO_COMPILE
 
 config CMD_BOOTEFI_HELLO
bool "Allow booting a standard EFI hello world for testing"
-   depends on CMD_BOOTEFI_HELLO_COMPILE
+   depends on CMD_BOOTEFI_BINARY && CMD_BOOTEFI_HELLO_COMPILE
default y if CMD_BOOTEFI_SELFTEST
help
  This adds a standard EFI hello world application to U-Boot so that
diff --git a/include/efi_loader.h b/include/efi_loader.h
index d3725041b20d..d5fca2fa5efc 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -90,11 +90,7 @@ efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len);
  * back to u-boot world
  */
 void efi_restore_gd(void);
-/* Call this to unset the current device name */
-void efi_clear_bootdev(void);
-/* Call this to set the current device name */
-void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
-void *buffer, size_t buffer_size);
+
 /* Called by networking code to memorize the dhcp ack package */
 void efi_net_set_dhcp_ack(void *pkt, int len);
 /* Print information about all loaded images */
@@ -116,10 +112,6 @@ static inline efi_status_t efi_add_runtime_mmio(void 
*mmio_ptr, u64 len)
 
 /* No loader configured, stub out EFI_ENTRY */
 static inline void efi_restore_gd(void) { }
-static inline void efi_clear_bootdev(void) { }
-static inline void efi_set_bootdev(const char *dev, const char *devnr,
-  const char *path, void *buffer,
-  size_t buffer_size) { }
 static inline void efi_net_set_dhcp_ack(void *pkt, int len) { }
 static inline void efi_print_image_infos(void *pc) { }
 static inline efi_status_t efi_launch_capsules(void)
@@ -129,6 +121,20 @@ static inline efi_status_t efi_launch_capsules(void)
 
 #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */
 
+#if CONFIG_IS_ENABLED(EFI_BINARY_EXEC)
+/* Call this to unset the current device name */
+void efi_clear_bootdev(void);
+/* Call this to set the current device name */
+void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
+void *buffer, size_t buffer_size);
+#else
+static inline void efi_clear_bootdev(void) { }
+
+static inline void e

[PATCH v5 0/4] cmd: bootefi: refactor the code for bootmgr

2024-01-16 Thread AKASHI Takahiro
This patch set is motivated by the discussion[1] regarding
CONFIG_BOOTEFI_BOOTMGR option.

# This version (v5) contains only the remaining commits.

At the end, bootefi.c will be decomposed into two parts, one for
providing the command itself and one for implementing helper functions.
EFI_LOADER will now be available without CONFIG_CMDLINE or specifically
CONFIG_CMD_BOOTEFI if invoked via bootmeth/bootstd.

Then, EFI_LOADER library side will be further split into two options
for fine-grain control:
CONFIG_EFI_BINARY_EXEC: execute UEFI binaries which are to be explicitly
loaded by U-Boot's load commands/functions or other methods
(like a jtag debugger?)
It supports bootmeth_efi as well as "bootefi |hello"(/"bootm"?).

CONFIG_EFI_BOOTMGR: provide EFI boot manger functionality
It supports bootmeth_efi_mgr as well as "bootefi bootmgr".

As such, We will no longer need CONFIG_EFI_BINARY_EXEC if we want to only
make use of the UEFI boot manger for booting a next stage OS.

Prerequisite

This patch set is based on top of the latest "master" branch.

Tests
=
* ran and passed py/efi_selftest on sandbox locally
* ran and passed py/test_efi_bootmgr on sandbox locally
* passed CI check (github pull request[2])

Changes
===
v4 (Jan 17, 2024)
* rebased onto the latest master branch again

v4 (Jan 10, 2024)
* rebased onto the latest master branch
* moved binary execution portion of code (EFI_BINARY_EXEC) to
  a new file, efi_bootbin.c, instead of efi_helper.c (patch#1)

v3 (Dec 18, 2023)
* rebased onto Tom's latest next branch
* remove already-merged commits

v2 (Nov 21, 2023)
* rebased onto Tom's next branch
* remove already merged commits
* revise commit messages
* add patch #5 which was split from ex-patch#5
RFC (Oct 26, 2023)

[1] https://lists.denx.de/pipermail/u-boot/2023-October/534598.html
[2] https://dev.azure.com/u-boot/u-boot/_build/results?buildId=7760=results

AKASHI Takahiro (4):
  efi_loader: split unrelated code from efi_bootmgr.c
  efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR
  net: tftp: remove explicit efi configuration dependency
  fs: remove explicit efi configuration dependency

 boot/Kconfig |   4 +-
 boot/Makefile|   2 +-
 cmd/Kconfig  |  10 +-
 cmd/efidebug.c   |   4 +-
 fs/fs.c  |   7 +-
 include/efi_loader.h |  28 +-
 lib/efi_loader/Kconfig   |  11 +-
 lib/efi_loader/Makefile  |   3 +-
 lib/efi_loader/efi_bootbin.c | 211 +
 lib/efi_loader/efi_bootmgr.c | 488 ---
 lib/efi_loader/efi_device_path.c |   3 +-
 lib/efi_loader/efi_helper.c  | 286 ++
 net/tftp.c   |  10 +-
 test/boot/bootflow.c |   2 +-
 14 files changed, 546 insertions(+), 523 deletions(-)
 create mode 100644 lib/efi_loader/efi_bootbin.c

-- 
2.34.1



Re: [PATCH v4 2/4] efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR

2024-01-16 Thread AKASHI Takahiro
On Tue, Jan 16, 2024 at 07:44:22PM +0100, Heinrich Schuchardt wrote:
> On 1/16/24 02:43, AKASHI Takahiro wrote:
> > On Mon, Jan 15, 2024 at 03:16:22PM +0100, Heinrich Schuchardt wrote:
> > > On 15.01.24 11:12, AKASHI Takahiro wrote:
> > > > On Mon, Jan 15, 2024 at 09:34:51AM +0100, Heinrich Schuchardt wrote:
> > > > > On 1/15/24 01:58, AKASHI Takahiro wrote:
> > > > > > On Sun, Jan 14, 2024 at 01:46:45PM +0100, Heinrich Schuchardt wrote:
> > > > > > > On 1/10/24 02:16, AKASHI Takahiro wrote:
> > > > > > > > At this point, EFI boot manager interfaces is fully independent 
> > > > > > > > from
> > > > > > > > bootefi command. So just rename the configuration parameter.
> > > > > > > > 
> > > > > > > > Signed-off-by: AKASHI Takahiro 
> > > > > > > > Reviewed-by: Simon Glass 
> > > > > > > 
> > > > > > > This patch breaks the 'bootefi hello' command in
> > > > > > > qemu-riscv64_smode_defconfig and other QEMU defconfigs.
> > > > > > 
> > > > > > What happened? Please elaborate details so that I can trace your 
> > > > > > issue.
> > > > > > 
> > > > > > On my side, I didn't see any problem with "bootefi hello" on 
> > > > > > qemu-arm64
> > > > > > and moreover CI check (github pull request) didn't complain 
> > > > > > anything.
> > > > > 
> > > > > The failures are logged in
> > > > > https://source.denx.de/u-boot/custodians/u-boot-efi/-/pipelines/19302
> > > > 
> > > > In the logs for qemu-arm64, qemu-risc64 and maybe others as well,
> > > > I see the same error:
> > > > --- ---
> > > > __ test_efi_grub_net 
> > > > ___
> > > > test/py/tests/test_efi_loader.py:188: in test_efi_grub_net
> > > >   addr = fetch_tftp_file(u_boot_console, 
> > > > 'env__efi_loader_grub_file')
> > > > test/py/tests/test_efi_loader.py:136: in fetch_tftp_file
> > > >   assert expected_text in output
> > > > E   assert 'Bytes transferred = 520192' in "*** ERROR: `serverip' not 
> > > > set"
> > > > --- ---
> > > > 
> > > > This seems to be the root cause and my commit will have nothing to do
> > > > with the problem.
> > > > Please check the test environment.
> > > 
> > > You are looking at test_efi_grub_net. I referred to 'bootefi hello',
> > > i.e. test_efi_helloworld_builtin:
> > > 
> > > 
> > > - Captured stdout call
> > > -
> > > => bootefi hello
> > > 
> > > =>
> > > 
> > > 
> > > The command does not provide any output.
> > 
> > Ah, yeah, but
> > 
> > > > 
> > > > -Takahiro Akashi
> > > > 
> > > > > I have pushed the tag failed_20240114 to
> > > > > https://source.denx.de/u-boot/custodians/u-boot-efi.git for analysis.
> > 
> > While I compiled this code and tried to run "bootefi hello",
> > I could not reproduce this issue, always seeing the right output
> > either on qemu-arm64 or sandbox64.
> > (I also invoked test_efi_loader/efi_helloworld_builtin locally,
> > but the test passed.)
> > So no clue.
> 
> Please, rebase your patch set upon origin/master and retry the tests.

After rebasing my commits to the latest master (please note that my v4 has
already been rebased on the master at my submission time), I tried the test
again but anyhow the test passed as before on my side.
I'm not able to reproduce your issue.

The only conflicting commit was f19171c919e0 ("efi_loader: Clean up
efi_dp_append and efi_dp_concat"). I don't think that it would make
any difference.

-Takahiro Akashi


> Best regards
> 
> Heinrich
> 


Re: [PATCH v4 2/4] efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR

2024-01-15 Thread AKASHI Takahiro
On Mon, Jan 15, 2024 at 03:16:22PM +0100, Heinrich Schuchardt wrote:
> On 15.01.24 11:12, AKASHI Takahiro wrote:
> > On Mon, Jan 15, 2024 at 09:34:51AM +0100, Heinrich Schuchardt wrote:
> > > On 1/15/24 01:58, AKASHI Takahiro wrote:
> > > > On Sun, Jan 14, 2024 at 01:46:45PM +0100, Heinrich Schuchardt wrote:
> > > > > On 1/10/24 02:16, AKASHI Takahiro wrote:
> > > > > > At this point, EFI boot manager interfaces is fully independent from
> > > > > > bootefi command. So just rename the configuration parameter.
> > > > > > 
> > > > > > Signed-off-by: AKASHI Takahiro 
> > > > > > Reviewed-by: Simon Glass 
> > > > > 
> > > > > This patch breaks the 'bootefi hello' command in
> > > > > qemu-riscv64_smode_defconfig and other QEMU defconfigs.
> > > > 
> > > > What happened? Please elaborate details so that I can trace your issue.
> > > > 
> > > > On my side, I didn't see any problem with "bootefi hello" on qemu-arm64
> > > > and moreover CI check (github pull request) didn't complain anything.
> > > 
> > > The failures are logged in
> > > https://source.denx.de/u-boot/custodians/u-boot-efi/-/pipelines/19302
> > 
> > In the logs for qemu-arm64, qemu-risc64 and maybe others as well,
> > I see the same error:
> > --- ---
> > __ test_efi_grub_net 
> > ___
> > test/py/tests/test_efi_loader.py:188: in test_efi_grub_net
> >  addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file')
> > test/py/tests/test_efi_loader.py:136: in fetch_tftp_file
> >  assert expected_text in output
> > E   assert 'Bytes transferred = 520192' in "*** ERROR: `serverip' not set"
> > --- ---
> > 
> > This seems to be the root cause and my commit will have nothing to do
> > with the problem.
> > Please check the test environment.
> 
> You are looking at test_efi_grub_net. I referred to 'bootefi hello',
> i.e. test_efi_helloworld_builtin:
> 
> 
> - Captured stdout call
> -
> => bootefi hello
> 
> =>
> 
> 
> The command does not provide any output.

Ah, yeah, but

> Best regards
> 
> Heinrich
> 
> 
> > 
> > -Takahiro Akashi
> > 
> > > I have pushed the tag failed_20240114 to
> > > https://source.denx.de/u-boot/custodians/u-boot-efi.git for analysis.

While I compiled this code and tried to run "bootefi hello",
I could not reproduce this issue, always seeing the right output
either on qemu-arm64 or sandbox64.
(I also invoked test_efi_loader/efi_helloworld_builtin locally,
but the test passed.)
So no clue.

-Takahiro Akashi


> > > Best regards
> > > 
> > > Heinrich
> 


Re: [PATCH v4 2/4] efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR

2024-01-15 Thread AKASHI Takahiro
On Mon, Jan 15, 2024 at 09:34:51AM +0100, Heinrich Schuchardt wrote:
> On 1/15/24 01:58, AKASHI Takahiro wrote:
> > On Sun, Jan 14, 2024 at 01:46:45PM +0100, Heinrich Schuchardt wrote:
> > > On 1/10/24 02:16, AKASHI Takahiro wrote:
> > > > At this point, EFI boot manager interfaces is fully independent from
> > > > bootefi command. So just rename the configuration parameter.
> > > > 
> > > > Signed-off-by: AKASHI Takahiro 
> > > > Reviewed-by: Simon Glass 
> > > 
> > > This patch breaks the 'bootefi hello' command in
> > > qemu-riscv64_smode_defconfig and other QEMU defconfigs.
> > 
> > What happened? Please elaborate details so that I can trace your issue.
> > 
> > On my side, I didn't see any problem with "bootefi hello" on qemu-arm64
> > and moreover CI check (github pull request) didn't complain anything.
> 
> The failures are logged in
> https://source.denx.de/u-boot/custodians/u-boot-efi/-/pipelines/19302

In the logs for qemu-arm64, qemu-risc64 and maybe others as well,
I see the same error:
--- ---
__ test_efi_grub_net ___
test/py/tests/test_efi_loader.py:188: in test_efi_grub_net
addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file')
test/py/tests/test_efi_loader.py:136: in fetch_tftp_file
assert expected_text in output
E   assert 'Bytes transferred = 520192' in "*** ERROR: `serverip' not set"
--- ---

This seems to be the root cause and my commit will have nothing to do
with the problem.
Please check the test environment.

-Takahiro Akashi

> I have pushed the tag failed_20240114 to
> https://source.denx.de/u-boot/custodians/u-boot-efi.git for analysis.
> 
> Best regards
> 
> Heinrich


Re: [PATCH v4 2/4] efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR

2024-01-14 Thread AKASHI Takahiro
On Sun, Jan 14, 2024 at 01:46:45PM +0100, Heinrich Schuchardt wrote:
> On 1/10/24 02:16, AKASHI Takahiro wrote:
> > At this point, EFI boot manager interfaces is fully independent from
> > bootefi command. So just rename the configuration parameter.
> > 
> > Signed-off-by: AKASHI Takahiro 
> > Reviewed-by: Simon Glass 
> 
> This patch breaks the 'bootefi hello' command in
> qemu-riscv64_smode_defconfig and other QEMU defconfigs.

What happened? Please elaborate details so that I can trace your issue.

On my side, I didn't see any problem with "bootefi hello" on qemu-arm64
and moreover CI check (github pull request) didn't complain anything.

-Takahiro Akashi


> Best regards
> 
> Heinrich


[PATCH v4 4/4] fs: remove explicit efi configuration dependency

2024-01-09 Thread AKASHI Takahiro
Now it is clear that the feature actually depends on efi interfaces,
not "bootefi" command. efi_set_bootdev() will automatically be nullified
if necessary efi component is disabled.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
---
 fs/fs.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index f1a0b70d1d57..acf465bdd807 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -791,10 +791,9 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[],
return 1;
}
 
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
-   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
-   (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
-   len_read);
+   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
+   (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
+   len_read);
 
printf("%llu bytes read in %lu ms", len_read, time);
if (time > 0) {
-- 
2.34.1



[PATCH v4 3/4] net: tftp: remove explicit efi configuration dependency

2024-01-09 Thread AKASHI Takahiro
Now it is clear that the feature actually depends on efi interfaces,
not "bootefi" command. efi_set_bootdev() will automatically be nullified
if necessary efi component is disabled.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Ramon Fried 
Reviewed-by: Tom Rini 
---
 net/tftp.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/net/tftp.c b/net/tftp.c
index 88e71e67de35..2e335413492b 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -302,12 +302,10 @@ static void tftp_complete(void)
time_start * 1000, "/s");
}
puts("\ndone\n");
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) {
-   if (!tftp_put_active)
-   efi_set_bootdev("Net", "", tftp_filename,
-   map_sysmem(tftp_load_addr, 0),
-   net_boot_file_size);
-   }
+   if (!tftp_put_active)
+   efi_set_bootdev("Net", "", tftp_filename,
+   map_sysmem(tftp_load_addr, 0),
+   net_boot_file_size);
net_set_state(NETLOOP_SUCCESS);
 }
 
-- 
2.34.1



[PATCH v4 2/4] efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR

2024-01-09 Thread AKASHI Takahiro
At this point, EFI boot manager interfaces is fully independent from
bootefi command. So just rename the configuration parameter.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
---
 boot/Makefile   | 2 +-
 cmd/Kconfig | 4 ++--
 cmd/efidebug.c  | 4 ++--
 lib/efi_loader/Kconfig  | 2 +-
 lib/efi_loader/Makefile | 2 +-
 test/boot/bootflow.c| 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/boot/Makefile b/boot/Makefile
index a90ebea5a867..bcd01cfc890c 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -34,7 +34,7 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_CROS) += bootm.o bootm_os.o 
bootmeth_cros.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SCRIPT) += bootmeth_script.o
 ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL
-obj-$(CONFIG_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
+obj-$(CONFIG_EFI_BOOTMGR) += bootmeth_efi_mgr.o
 obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 150fa37a50a7..62d2ae3d3f1b 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -395,7 +395,7 @@ config CMD_BOOTEFI_BINARY
 
 config CMD_BOOTEFI_BOOTMGR
bool "UEFI Boot Manager command"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BOOTMGR
default y
help
  Select this option to enable the 'bootmgr' subcommand of 'bootefi'.
@@ -2153,7 +2153,7 @@ config CMD_EFIDEBUG
 config CMD_EFICONFIG
bool "eficonfig - provide menu-driven uefi variables maintenance 
interface"
default y if !HAS_BOARD_SIZE_LIMIT
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BOOTMGR
select MENU
help
  Enable the 'eficonfig' command which provides the menu-driven UEFI
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index e10fbf891a42..b4954258eeba 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -1410,7 +1410,7 @@ static __maybe_unused int do_efi_test_bootmgr(struct 
cmd_tbl *cmdtp, int flag,
 }
 
 static struct cmd_tbl cmd_efidebug_test_sub[] = {
-#ifdef CONFIG_BOOTEFI_BOOTMGR
+#ifdef CONFIG_EFI_BOOTMGR
U_BOOT_CMD_MKENT(bootmgr, CONFIG_SYS_MAXARGS, 1, do_efi_test_bootmgr,
 "", ""),
 #endif
@@ -1604,7 +1604,7 @@ U_BOOT_LONGHELP(efidebug,
"  - show UEFI memory map\n"
"efidebug tables\n"
"  - show UEFI configuration tables\n"
-#ifdef CONFIG_BOOTEFI_BOOTMGR
+#ifdef CONFIG_EFI_BOOTMGR
"efidebug test bootmgr\n"
"  - run simple bootmgr for test\n"
 #endif
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 64f2f1cdd161..db5571de1d95 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -41,7 +41,7 @@ config EFI_BINARY_EXEC
  You may enable CMD_BOOTEFI_BINARY so that you can use bootefi
  command to do that.
 
-config BOOTEFI_BOOTMGR
+config EFI_BOOTMGR
bool "UEFI Boot Manager"
default y
select BOOTMETH_GLOBAL if BOOTSTD
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index f85d26d9724c..56e5ce220a3e 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -42,7 +42,7 @@ targets += initrddump.o
 endif
 
 obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
-obj-$(CONFIG_BOOTEFI_BOOTMGR) += efi_bootmgr.o
+obj-$(CONFIG_EFI_BOOTMGR) += efi_bootmgr.o
 obj-$(CONFIG_EFI_BINARY_EXEC) += efi_bootbin.o
 obj-y += efi_boottime.o
 obj-y += efi_helper.o
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 104f49deef2a..fa54dde661c8 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -374,7 +374,7 @@ static int bootflow_system(struct unit_test_state *uts)
 {
struct udevice *bootstd, *dev;
 
-   if (!IS_ENABLED(CONFIG_BOOTEFI_BOOTMGR))
+   if (!IS_ENABLED(CONFIG_EFI_BOOTMGR))
return -EAGAIN;
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, ));
ut_assertok(device_bind(bootstd, DM_DRIVER_GET(bootmeth_efi_mgr),
-- 
2.34.1



[PATCH v4 1/4] efi_loader: split unrelated code from efi_bootmgr.c

2024-01-09 Thread AKASHI Takahiro
Some code moved from cmd/bootefi.c is actually necessary only for "bootefi
" command (starting an image manually loaded by a user using U-Boot
load commands or other methods (like JTAG debugger).

The code will never been opted out as unused code by a compiler which
doesn't know how EFI boot manager is implemented. So introduce a new
configuration, CONFIG_EFI_BINARY_EXEC, to enforce them opted out
explicitly.

Signed-off-by: AKASHI Takahiro 
---
v4
* moved binary execution portion of code (EFI_BINARY_EXEC) to
  a new file, efi_bootbin.c
---
 boot/Kconfig |   4 +-
 cmd/Kconfig  |   6 +-
 include/efi_loader.h |  28 +-
 lib/efi_loader/Kconfig   |   9 +
 lib/efi_loader/Makefile  |   1 +
 lib/efi_loader/efi_bootbin.c | 211 +
 lib/efi_loader/efi_bootmgr.c | 488 ---
 lib/efi_loader/efi_device_path.c |   3 +-
 lib/efi_loader/efi_helper.c  | 286 ++
 9 files changed, 531 insertions(+), 505 deletions(-)
 create mode 100644 lib/efi_loader/efi_bootbin.c

diff --git a/boot/Kconfig b/boot/Kconfig
index 9f5b8a0cb2c8..347f8cca7d0b 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -523,7 +523,7 @@ config BOOTMETH_EXTLINUX_PXE
 
 config BOOTMETH_EFILOADER
bool "Bootdev support for EFI boot"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BINARY_EXEC
default y
help
  Enables support for EFI boot using bootdevs. This makes the
@@ -558,7 +558,7 @@ config BOOTMETH_DISTRO
select BOOTMETH_SCRIPT if CMDLINE # E.g. Armbian uses scripts
select BOOTMETH_EXTLINUX  # E.g. Debian uses these
select BOOTMETH_EXTLINUX_PXE if CMD_PXE && CMD_NET && DM_ETH
-   select BOOTMETH_EFILOADER if BOOTEFI_BOOTMGR # E.g. Ubuntu uses this
+   select BOOTMETH_EFILOADER if EFI_BINARY_EXEC # E.g. Ubuntu uses this
 
 config SPL_BOOTMETH_VBE
bool "Bootdev support for Verified Boot for Embedded (SPL)"
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 26ad03b6..150fa37a50a7 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -294,7 +294,7 @@ config CMD_BOOTMETH
 
 config BOOTM_EFI
bool "Support booting UEFI FIT images"
-   depends on BOOTEFI_BOOTMGR && CMD_BOOTM && FIT
+   depends on EFI_BINARY_EXEC && CMD_BOOTM && FIT
default y
help
  Support booting UEFI FIT images via the bootm command.
@@ -386,7 +386,7 @@ config CMD_BOOTEFI
 if CMD_BOOTEFI
 config CMD_BOOTEFI_BINARY
bool "Allow booting an EFI binary directly"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BINARY_EXEC
default y
help
  Select this option to enable direct execution of binary at 'bootefi'.
@@ -416,7 +416,7 @@ config CMD_BOOTEFI_HELLO_COMPILE
 
 config CMD_BOOTEFI_HELLO
bool "Allow booting a standard EFI hello world for testing"
-   depends on CMD_BOOTEFI_HELLO_COMPILE
+   depends on CMD_BOOTEFI_BINARY && CMD_BOOTEFI_HELLO_COMPILE
default y if CMD_BOOTEFI_SELFTEST
help
  This adds a standard EFI hello world application to U-Boot so that
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 34e7fbbf1840..484c9fad239f 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -90,11 +90,7 @@ efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len);
  * back to u-boot world
  */
 void efi_restore_gd(void);
-/* Call this to unset the current device name */
-void efi_clear_bootdev(void);
-/* Call this to set the current device name */
-void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
-void *buffer, size_t buffer_size);
+
 /* Called by networking code to memorize the dhcp ack package */
 void efi_net_set_dhcp_ack(void *pkt, int len);
 /* Print information about all loaded images */
@@ -116,10 +112,6 @@ static inline efi_status_t efi_add_runtime_mmio(void 
*mmio_ptr, u64 len)
 
 /* No loader configured, stub out EFI_ENTRY */
 static inline void efi_restore_gd(void) { }
-static inline void efi_clear_bootdev(void) { }
-static inline void efi_set_bootdev(const char *dev, const char *devnr,
-  const char *path, void *buffer,
-  size_t buffer_size) { }
 static inline void efi_net_set_dhcp_ack(void *pkt, int len) { }
 static inline void efi_print_image_infos(void *pc) { }
 static inline efi_status_t efi_launch_capsules(void)
@@ -129,6 +121,20 @@ static inline efi_status_t efi_launch_capsules(void)
 
 #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */
 
+#if CONFIG_IS_ENABLED(EFI_BINARY_EXEC)
+/* Call this to unset the current device name */
+void efi_clear_bootdev(void);
+/* Call this to set the current device name */
+void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
+void *buffer, size_t buffer_size);
+#el

[PATCH v4 0/4] cmd: bootefi: refactor the code for bootmgr

2024-01-09 Thread AKASHI Takahiro
This patch set is motivated by the discussion[1] regarding
CONFIG_BOOTEFI_BOOTMGR option.

# This version (v4) contains only the remaining commits.

At the end, bootefi.c will be decomposed into two parts, one for
providing the command itself and one for implementing helper functions.
EFI_LOADER will now be available without CONFIG_CMDLINE or specifically
CONFIG_CMD_BOOTEFI if invoked via bootmeth/bootstd.

Then, EFI_LOADER library side will be further split into two options
for fine-grain control:
CONFIG_EFI_BINARY_EXEC: execute UEFI binaries which are to be explicitly
loaded by U-Boot's load commands/functions or other methods
(like a jtag debugger?)
It supports bootmeth_efi as well as "bootefi |hello"(/"bootm"?).

CONFIG_EFI_BOOTMGR: provide EFI boot manger functionality
It supports bootmeth_efi_mgr as well as "bootefi bootmgr".

As such, We will no longer need CONFIG_EFI_BINARY_EXEC if we want to only
make use of the UEFI boot manger for booting a next stage OS.

Prerequisite

This patch set is based on top of the latest "master" branch.

Tests
=
* ran and passed py/efi_selftest on sandbox locally
  (I saw an error in tcg2 though)
* ran and passed py/test_efi_bootmgr on sandbox locally
* passed CI check (github pull request)

Changes
===
v4 (Jan 10, 2024)
* rebased onto the latest master branch
* moved binary execution portion of code (EFI_BINARY_EXEC) to
  a new file, efi_bootbin.c, instead of efi_helper.c (patch#1)

v3 (Dec 18, 2023)
* rebased onto Tom's latest next branch
* remove already-merged commits

v2 (Nov 21, 2023)
* rebased onto Tom's next branch
* remove already merged commits
* revise commit messages
* add patch #5 which was split from ex-patch#5
RFC (Oct 26, 2023)

[1] https://lists.denx.de/pipermail/u-boot/2023-October/534598.html

AKASHI Takahiro (4):
  efi_loader: split unrelated code from efi_bootmgr.c
  efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR
  net: tftp: remove explicit efi configuration dependency
  fs: remove explicit efi configuration dependency

 boot/Kconfig |   4 +-
 boot/Makefile|   2 +-
 cmd/Kconfig  |  10 +-
 cmd/efidebug.c   |   4 +-
 fs/fs.c  |   7 +-
 include/efi_loader.h |  28 +-
 lib/efi_loader/Kconfig   |  11 +-
 lib/efi_loader/Makefile  |   3 +-
 lib/efi_loader/efi_bootbin.c | 211 +
 lib/efi_loader/efi_bootmgr.c | 488 ---
 lib/efi_loader/efi_device_path.c |   3 +-
 lib/efi_loader/efi_helper.c  | 286 ++
 net/tftp.c   |  10 +-
 test/boot/bootflow.c |   2 +-
 14 files changed, 546 insertions(+), 523 deletions(-)
 create mode 100644 lib/efi_loader/efi_bootbin.c

-- 
2.34.1



Re: [PATCH v3 3/4] net: tftp: remove explicit efi configuration dependency

2023-12-26 Thread AKASHI Takahiro
Hi Simon,

On Tue, Dec 26, 2023 at 09:47:03AM +, Simon Glass wrote:
> Hi Heinrich,
> 
> On Wed, Dec 20, 2023 at 9:17???AM Heinrich Schuchardt  
> wrote:
> >
> >
> >
> > Am 20. Dezember 2023 05:46:16 MEZ schrieb Simon Glass :
> > >Hi,
> > >
> > >On Mon, 18 Dec 2023 at 17:17, AKASHI Takahiro
> > > wrote:
> > >>
> > >> Hi Simon,
> > >>
> > >> On Mon, Dec 18, 2023 at 08:01:46AM -0700, Simon Glass wrote:
> > >> > Hi AKASHI,
> > >> >
> > >> > On Sun, 17 Dec 2023 at 19:39, AKASHI Takahiro
> > >> >  wrote:
> > >> > >
> > >> > > Now it is clear that the feature actually depends on efi interfaces,
> > >> > > not "bootefi" command. efi_set_bootdev() will automatically be 
> > >> > > nullified
> > >> > > if necessary efi component is disabled.
> > >> > >
> > >> > > Signed-off-by: AKASHI Takahiro 
> > >> > > ---
> > >> > >  net/tftp.c | 10 --
> > >> > >  1 file changed, 4 insertions(+), 6 deletions(-)
> > >> > >
> > >> >
> > >> > I have the same comment here as the 'fs' patch.
> > >> >
> > >> > > diff --git a/net/tftp.c b/net/tftp.c
> > >> > > index 88e71e67de35..2e335413492b 100644
> > >> > > --- a/net/tftp.c
> > >> > > +++ b/net/tftp.c
> > >> > > @@ -302,12 +302,10 @@ static void tftp_complete(void)
> > >> > > time_start * 1000, "/s");
> > >> > > }
> > >> > > puts("\ndone\n");
> > >> > > -   if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) {
> > >> >
> > >> > Shouldn't this depend on your new CONFIG? What happens if EFI_LOADER
> > >> > is not enabled?
> > >>
> > >> The trick is in efi_loader.h.
> > >> If EFI_LOADER (more specifically CONFIG_EFI_BINARY_EXEC) is not defined,
> > >> this function gets voided.  See patch#1 in this version.
> > >>
> > >> I took this approach in order not to make users much worried about
> > >> what config be used as they are not familiar with UEFI implementation.
> > >
> > >OK, but we really need to delete this function, so what is the plan
> > >for that? The info that EFI needs should be passed to the bootefi()
> > >function, not set in a global.
> >
> > Hello Simon,
> >
> > Bootstd is not the only way to boot. Please, do not forget the shell.
> >
> > The user loads a file with tftpboot. At some later moment the user executes 
> > bootefi.
> >
> > We need a place where we store the device from which the image was loaded.
> 
> Yes, agreed. See my other reply on that.
> 
> >
> > In future we might have a register of loaded files. But that is beyond the 
> > scope of this patch series.
> 
> I believe we could just record the device and partition number (which
> is itself a device these days, I suppose). Then for EFI can do the
> translation at the start of the bootm cmd if not using bootstd.

Then, what is the difference between "record the device and partition
number (strictly it's not accurate because we also support tftp and others.)
and "call efi_set_bootdev()"?

The latter does the translation on the fly and saves the info
in bootefi_image_path and bootefi_device_path local variables.

I believe that both are essentially the same.

> Reviewed-by: Simon Glass 

Always thank you for your review.

-Takahiro Akashi

> 
> >
> > Best regards
> >
> > Heinrich
> >
> > >
> > >
> > >>
> > >> -Takahiro Akashi
> > >>
> > >> > > -   if (!tftp_put_active)
> > >> > > -   efi_set_bootdev("Net", "", tftp_filename,
> > >> > > -   map_sysmem(tftp_load_addr, 
> > >> > > 0),
> > >> > > -   net_boot_file_size);
> > >> > > -   }
> > >> > > +   if (!tftp_put_active)
> > >> > > +   efi_set_bootdev("Net", "", tftp_filename,
> > >> > > +   map_sysmem(tftp_load_addr, 0),
> > >> > > +   net_boot_file_size);
> > >> > > net_set_state(NETLOOP_SUCCESS);
> > >> > >  }
> > >> > >
> > >> > > --
> > >> > > 2.34.1
> > >
> > >Regards,
> 
> Regards,
> Simon


Re: [PATCH v3 1/4] efi_loader: split unrelated code from efi_bootmgr.c

2023-12-26 Thread AKASHI Takahiro
On Mon, Dec 25, 2023 at 10:17:06AM +0100, Heinrich Schuchardt wrote:
> On 12/18/23 03:38, AKASHI Takahiro wrote:
> > Some code moved from cmd/bootefi.c is actually necessary only for "bootefi
> > " command (starting an image manually loaded by a user using U-Boot
> > load commands or other methods (like JTAG debugger).
> > 
> > The code will never been opted out as unused code by a compiler which
> > doesn't know how EFI boot manager is implemented. So introduce a new
> > configuration, CONFIG_EFI_BINARY_EXEC, to enforce theem opted out
> > explicitly.
> 
> We build with -ffunction-sections. The linker removes unreferenced
> functions.

Yes, I know but I also think it would be better in terms of readability
and maintainability to add a new config option and separate EFI_BINARY_EXEC
portion from BOOTEFI_BOOTMGR as these two functions share almost nothing
(except efi_install_fdt()).

> > 
> > Signed-off-by: AKASHI Takahiro 
> > ---
> >   boot/Kconfig |   4 +-
> >   cmd/Kconfig  |   6 +-
> >   include/efi_loader.h |  28 +-
> >   lib/efi_loader/Kconfig   |   9 +
> >   lib/efi_loader/efi_bootmgr.c | 493 --
> >   lib/efi_loader/efi_device_path.c |   3 +-
> >   lib/efi_loader/efi_helper.c  | 499 ++-
> 
> We expect that after each patch we can compile the code. This requires
> that the Makefile change is in the same patch as the creation of
> efi_helper.c.

Please remember that efi_helper.c is not a new file.
If you like, as Simon suggested, I will move "499" lines of code
into a new file, efi_boot.c and then add:
   obj-$(CONFIG_EFI_BINARY_EXEC) := efi_boot.o

> >   7 files changed, 529 insertions(+), 513 deletions(-)
> > 
> > diff --git a/boot/Kconfig b/boot/Kconfig
> > index 987ca7314117..8ab7e6f63d34 100644
> > --- a/boot/Kconfig
> > +++ b/boot/Kconfig
> > @@ -523,7 +523,7 @@ config BOOTMETH_EXTLINUX_PXE
> > 
> >   config BOOTMETH_EFILOADER
> > bool "Bootdev support for EFI boot"
> > -   depends on BOOTEFI_BOOTMGR
> > +   depends on EFI_BINARY_EXEC
> 
> Why do we need a symbol CONFIG_EFI_BINARY_EXEC? CONFIG_EFI_LOADER=y
> without the ability to execute an EFI binary makes no sense to me.

It's up to users. It allows them to configure U-Boot with EFI_LOADER and
EFI_BOOTMGR only.

Thanks,
-Takahiro Akashi


> Best regards
> 
> Heinrich
> 
> > default y
> > help
> >   Enables support for EFI boot using bootdevs. This makes the
> > @@ -558,7 +558,7 @@ config BOOTMETH_DISTRO
> > select BOOTMETH_SCRIPT if CMDLINE # E.g. Armbian uses scripts
> > select BOOTMETH_EXTLINUX  # E.g. Debian uses these
> > select BOOTMETH_EXTLINUX_PXE if CMD_PXE && CMD_NET && DM_ETH
> > -   select BOOTMETH_EFILOADER if BOOTEFI_BOOTMGR # E.g. Ubuntu uses this
> > +   select BOOTMETH_EFILOADER if EFI_BINARY_EXEC # E.g. Ubuntu uses this
> > 
> >   config SPL_BOOTMETH_VBE
> > bool "Bootdev support for Verified Boot for Embedded (SPL)"
> > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > index 24bfbe505722..2c993496b70e 100644
> > --- a/cmd/Kconfig
> > +++ b/cmd/Kconfig
> > @@ -273,7 +273,7 @@ config CMD_BOOTMETH
> > 
> >   config BOOTM_EFI
> > bool "Support booting UEFI FIT images"
> > -   depends on BOOTEFI_BOOTMGR && CMD_BOOTM && FIT
> > +   depends on EFI_BINARY_EXEC && CMD_BOOTM && FIT
> > default y
> > help
> >   Support booting UEFI FIT images via the bootm command.
> > @@ -365,7 +365,7 @@ config CMD_BOOTEFI
> >   if CMD_BOOTEFI
> >   config CMD_BOOTEFI_BINARY
> > bool "Allow booting an EFI binary directly"
> > -   depends on BOOTEFI_BOOTMGR
> > +   depends on EFI_BINARY_EXEC
> > default y
> > help
> >   Select this option to enable direct execution of binary at 'bootefi'.
> > @@ -395,7 +395,7 @@ config CMD_BOOTEFI_HELLO_COMPILE
> > 
> >   config CMD_BOOTEFI_HELLO
> > bool "Allow booting a standard EFI hello world for testing"
> > -   depends on CMD_BOOTEFI_HELLO_COMPILE
> > +   depends on CMD_BOOTEFI_BINARY && CMD_BOOTEFI_HELLO_COMPILE
> > default y if CMD_BOOTEFI_SELFTEST
> > help
> >   This adds a standard EFI hello world application to U-Boot so that
> > diff --git a/include/efi_loader.h b/include/efi_loader.h
> > index 34e7fbbf1840..484c9fad239f 100644
> > --- a/include/efi_loader.h
> > +++ b/include/efi_loader.h
>

Re: [PATCH v3 1/4] efi_loader: split unrelated code from efi_bootmgr.c

2023-12-18 Thread AKASHI Takahiro
On Mon, Dec 18, 2023 at 08:01:51AM -0700, Simon Glass wrote:
> Hi AKASHI,
> 
> On Sun, 17 Dec 2023 at 19:39, AKASHI Takahiro
>  wrote:
> >
> > Some code moved from cmd/bootefi.c is actually necessary only for "bootefi
> > " command (starting an image manually loaded by a user using U-Boot
> > load commands or other methods (like JTAG debugger).
> >
> > The code will never been opted out as unused code by a compiler which
> > doesn't know how EFI boot manager is implemented. So introduce a new
> > configuration, CONFIG_EFI_BINARY_EXEC, to enforce theem opted out
> > explicitly.
> >
> > Signed-off-by: AKASHI Takahiro 
> > ---
> >  boot/Kconfig |   4 +-
> >  cmd/Kconfig  |   6 +-
> >  include/efi_loader.h |  28 +-
> >  lib/efi_loader/Kconfig   |   9 +
> >  lib/efi_loader/efi_bootmgr.c | 493 --
> >  lib/efi_loader/efi_device_path.c |   3 +-
> >  lib/efi_loader/efi_helper.c  | 499 ++-
> >  7 files changed, 529 insertions(+), 513 deletions(-)
> 
> 'helper' seems a bit vague to me. How about efi_boot.c ?

Although I hesitated to add one more new file as we already have
efi_boottime.c and efi_bootmgr.c, then efi_boot.c?, okay I will do that.

-Takahiro Akashi


> REgards,
> Simon


Re: [PATCH v3 3/4] net: tftp: remove explicit efi configuration dependency

2023-12-18 Thread AKASHI Takahiro
Hi Simon,

On Mon, Dec 18, 2023 at 08:01:46AM -0700, Simon Glass wrote:
> Hi AKASHI,
> 
> On Sun, 17 Dec 2023 at 19:39, AKASHI Takahiro
>  wrote:
> >
> > Now it is clear that the feature actually depends on efi interfaces,
> > not "bootefi" command. efi_set_bootdev() will automatically be nullified
> > if necessary efi component is disabled.
> >
> > Signed-off-by: AKASHI Takahiro 
> > ---
> >  net/tftp.c | 10 --
> >  1 file changed, 4 insertions(+), 6 deletions(-)
> >
> 
> I have the same comment here as the 'fs' patch.
> 
> > diff --git a/net/tftp.c b/net/tftp.c
> > index 88e71e67de35..2e335413492b 100644
> > --- a/net/tftp.c
> > +++ b/net/tftp.c
> > @@ -302,12 +302,10 @@ static void tftp_complete(void)
> > time_start * 1000, "/s");
> > }
> > puts("\ndone\n");
> > -   if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) {
> 
> Shouldn't this depend on your new CONFIG? What happens if EFI_LOADER
> is not enabled?

The trick is in efi_loader.h.
If EFI_LOADER (more specifically CONFIG_EFI_BINARY_EXEC) is not defined,
this function gets voided.  See patch#1 in this version.

I took this approach in order not to make users much worried about
what config be used as they are not familiar with UEFI implementation.

-Takahiro Akashi

> > -   if (!tftp_put_active)
> > -   efi_set_bootdev("Net", "", tftp_filename,
> > -   map_sysmem(tftp_load_addr, 0),
> > -   net_boot_file_size);
> > -   }
> > +   if (!tftp_put_active)
> > +   efi_set_bootdev("Net", "", tftp_filename,
> > +   map_sysmem(tftp_load_addr, 0),
> > +   net_boot_file_size);
> > net_set_state(NETLOOP_SUCCESS);
> >  }
> >
> > --
> > 2.34.1
> >
> 
> Regards,
> Simon


[PATCH v3 4/4] fs: remove explicit efi configuration dependency

2023-12-17 Thread AKASHI Takahiro
Now it is clear that the feature actually depends on efi interfaces,
not "bootefi" command. efi_set_bootdev() will automatically be nullified
if necessary efi component is disabled.

Signed-off-by: AKASHI Takahiro 
---
 fs/fs.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index f33b85f92b61..82ee03b160e9 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -791,10 +791,9 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[],
return 1;
}
 
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
-   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
-   (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
-   len_read);
+   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
+   (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
+   len_read);
 
printf("%llu bytes read in %lu ms", len_read, time);
if (time > 0) {
-- 
2.34.1



[PATCH v3 3/4] net: tftp: remove explicit efi configuration dependency

2023-12-17 Thread AKASHI Takahiro
Now it is clear that the feature actually depends on efi interfaces,
not "bootefi" command. efi_set_bootdev() will automatically be nullified
if necessary efi component is disabled.

Signed-off-by: AKASHI Takahiro 
---
 net/tftp.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/net/tftp.c b/net/tftp.c
index 88e71e67de35..2e335413492b 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -302,12 +302,10 @@ static void tftp_complete(void)
time_start * 1000, "/s");
}
puts("\ndone\n");
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) {
-   if (!tftp_put_active)
-   efi_set_bootdev("Net", "", tftp_filename,
-   map_sysmem(tftp_load_addr, 0),
-   net_boot_file_size);
-   }
+   if (!tftp_put_active)
+   efi_set_bootdev("Net", "", tftp_filename,
+   map_sysmem(tftp_load_addr, 0),
+   net_boot_file_size);
net_set_state(NETLOOP_SUCCESS);
 }
 
-- 
2.34.1



[PATCH v3 1/4] efi_loader: split unrelated code from efi_bootmgr.c

2023-12-17 Thread AKASHI Takahiro
Some code moved from cmd/bootefi.c is actually necessary only for "bootefi
" command (starting an image manually loaded by a user using U-Boot
load commands or other methods (like JTAG debugger).

The code will never been opted out as unused code by a compiler which
doesn't know how EFI boot manager is implemented. So introduce a new
configuration, CONFIG_EFI_BINARY_EXEC, to enforce theem opted out
explicitly.

Signed-off-by: AKASHI Takahiro 
---
 boot/Kconfig |   4 +-
 cmd/Kconfig  |   6 +-
 include/efi_loader.h |  28 +-
 lib/efi_loader/Kconfig   |   9 +
 lib/efi_loader/efi_bootmgr.c | 493 --
 lib/efi_loader/efi_device_path.c |   3 +-
 lib/efi_loader/efi_helper.c  | 499 ++-
 7 files changed, 529 insertions(+), 513 deletions(-)

diff --git a/boot/Kconfig b/boot/Kconfig
index 987ca7314117..8ab7e6f63d34 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -523,7 +523,7 @@ config BOOTMETH_EXTLINUX_PXE
 
 config BOOTMETH_EFILOADER
bool "Bootdev support for EFI boot"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BINARY_EXEC
default y
help
  Enables support for EFI boot using bootdevs. This makes the
@@ -558,7 +558,7 @@ config BOOTMETH_DISTRO
select BOOTMETH_SCRIPT if CMDLINE # E.g. Armbian uses scripts
select BOOTMETH_EXTLINUX  # E.g. Debian uses these
select BOOTMETH_EXTLINUX_PXE if CMD_PXE && CMD_NET && DM_ETH
-   select BOOTMETH_EFILOADER if BOOTEFI_BOOTMGR # E.g. Ubuntu uses this
+   select BOOTMETH_EFILOADER if EFI_BINARY_EXEC # E.g. Ubuntu uses this
 
 config SPL_BOOTMETH_VBE
bool "Bootdev support for Verified Boot for Embedded (SPL)"
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 24bfbe505722..2c993496b70e 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -273,7 +273,7 @@ config CMD_BOOTMETH
 
 config BOOTM_EFI
bool "Support booting UEFI FIT images"
-   depends on BOOTEFI_BOOTMGR && CMD_BOOTM && FIT
+   depends on EFI_BINARY_EXEC && CMD_BOOTM && FIT
default y
help
  Support booting UEFI FIT images via the bootm command.
@@ -365,7 +365,7 @@ config CMD_BOOTEFI
 if CMD_BOOTEFI
 config CMD_BOOTEFI_BINARY
bool "Allow booting an EFI binary directly"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BINARY_EXEC
default y
help
  Select this option to enable direct execution of binary at 'bootefi'.
@@ -395,7 +395,7 @@ config CMD_BOOTEFI_HELLO_COMPILE
 
 config CMD_BOOTEFI_HELLO
bool "Allow booting a standard EFI hello world for testing"
-   depends on CMD_BOOTEFI_HELLO_COMPILE
+   depends on CMD_BOOTEFI_BINARY && CMD_BOOTEFI_HELLO_COMPILE
default y if CMD_BOOTEFI_SELFTEST
help
  This adds a standard EFI hello world application to U-Boot so that
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 34e7fbbf1840..484c9fad239f 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -90,11 +90,7 @@ efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len);
  * back to u-boot world
  */
 void efi_restore_gd(void);
-/* Call this to unset the current device name */
-void efi_clear_bootdev(void);
-/* Call this to set the current device name */
-void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
-void *buffer, size_t buffer_size);
+
 /* Called by networking code to memorize the dhcp ack package */
 void efi_net_set_dhcp_ack(void *pkt, int len);
 /* Print information about all loaded images */
@@ -116,10 +112,6 @@ static inline efi_status_t efi_add_runtime_mmio(void 
*mmio_ptr, u64 len)
 
 /* No loader configured, stub out EFI_ENTRY */
 static inline void efi_restore_gd(void) { }
-static inline void efi_clear_bootdev(void) { }
-static inline void efi_set_bootdev(const char *dev, const char *devnr,
-  const char *path, void *buffer,
-  size_t buffer_size) { }
 static inline void efi_net_set_dhcp_ack(void *pkt, int len) { }
 static inline void efi_print_image_infos(void *pc) { }
 static inline efi_status_t efi_launch_capsules(void)
@@ -129,6 +121,20 @@ static inline efi_status_t efi_launch_capsules(void)
 
 #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */
 
+#if CONFIG_IS_ENABLED(EFI_BINARY_EXEC)
+/* Call this to unset the current device name */
+void efi_clear_bootdev(void);
+/* Call this to set the current device name */
+void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
+void *buffer, size_t buffer_size);
+#else
+static inline void efi_clear_bootdev(void) { }
+
+static inline void efi_set_bootdev(const char *dev, const char *devnr,
+  const char *path, void *buffer,
+  s

[PATCH v3 2/4] efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR

2023-12-17 Thread AKASHI Takahiro
At this point, EFI boot manager interfaces is fully independent from
bootefi command. So just rename the configuration parameter.

Signed-off-by: AKASHI Takahiro 
---
 boot/Makefile   | 2 +-
 cmd/Kconfig | 4 ++--
 cmd/efidebug.c  | 4 ++--
 lib/efi_loader/Kconfig  | 2 +-
 lib/efi_loader/Makefile | 2 +-
 test/boot/bootflow.c| 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/boot/Makefile b/boot/Makefile
index a90ebea5a867..bcd01cfc890c 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -34,7 +34,7 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_CROS) += bootm.o bootm_os.o 
bootmeth_cros.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SCRIPT) += bootmeth_script.o
 ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL
-obj-$(CONFIG_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
+obj-$(CONFIG_EFI_BOOTMGR) += bootmeth_efi_mgr.o
 obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 2c993496b70e..856ff9f5395d 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -374,7 +374,7 @@ config CMD_BOOTEFI_BINARY
 
 config CMD_BOOTEFI_BOOTMGR
bool "UEFI Boot Manager command"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BOOTMGR
default y
help
  Select this option to enable the 'bootmgr' subcommand of 'bootefi'.
@@ -2122,7 +2122,7 @@ config CMD_EFIDEBUG
 config CMD_EFICONFIG
bool "eficonfig - provide menu-driven uefi variables maintenance 
interface"
default y if !HAS_BOARD_SIZE_LIMIT
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BOOTMGR
select MENU
help
  Enable the 'eficonfig' command which provides the menu-driven UEFI
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index e10fbf891a42..b4954258eeba 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -1410,7 +1410,7 @@ static __maybe_unused int do_efi_test_bootmgr(struct 
cmd_tbl *cmdtp, int flag,
 }
 
 static struct cmd_tbl cmd_efidebug_test_sub[] = {
-#ifdef CONFIG_BOOTEFI_BOOTMGR
+#ifdef CONFIG_EFI_BOOTMGR
U_BOOT_CMD_MKENT(bootmgr, CONFIG_SYS_MAXARGS, 1, do_efi_test_bootmgr,
 "", ""),
 #endif
@@ -1604,7 +1604,7 @@ U_BOOT_LONGHELP(efidebug,
"  - show UEFI memory map\n"
"efidebug tables\n"
"  - show UEFI configuration tables\n"
-#ifdef CONFIG_BOOTEFI_BOOTMGR
+#ifdef CONFIG_EFI_BOOTMGR
"efidebug test bootmgr\n"
"  - run simple bootmgr for test\n"
 #endif
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 64f2f1cdd161..db5571de1d95 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -41,7 +41,7 @@ config EFI_BINARY_EXEC
  You may enable CMD_BOOTEFI_BINARY so that you can use bootefi
  command to do that.
 
-config BOOTEFI_BOOTMGR
+config EFI_BOOTMGR
bool "UEFI Boot Manager"
default y
select BOOTMETH_GLOBAL if BOOTSTD
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index 0a2cb6e3c476..f882474bba6f 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -42,7 +42,7 @@ targets += initrddump.o
 endif
 
 obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
-obj-$(CONFIG_BOOTEFI_BOOTMGR) += efi_bootmgr.o
+obj-$(CONFIG_EFI_BOOTMGR) += efi_bootmgr.o
 obj-y += efi_boottime.o
 obj-y += efi_helper.o
 obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index f3e5a839da47..57e48fe62694 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -374,7 +374,7 @@ static int bootflow_system(struct unit_test_state *uts)
 {
struct udevice *bootstd, *dev;
 
-   if (!IS_ENABLED(CONFIG_BOOTEFI_BOOTMGR))
+   if (!IS_ENABLED(CONFIG_EFI_BOOTMGR))
return -EAGAIN;
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, ));
ut_assertok(device_bind(bootstd, DM_DRIVER_GET(bootmeth_efi_mgr),
-- 
2.34.1



[PATCH v3 0/4] cmd: bootefi: refactor the code for bootmgr

2023-12-17 Thread AKASHI Takahiro
This patch set is motivated by the discussion[1] regarding
CONFIG_BOOTEFI_BOOTMGR option.

# It has been partially merged in -next branch. So this version (v3)
# contains only the remaining commits.

At the end, bootefi.c will be decomposed into two parts, one for
providing the command itself and one for implementing helper functions.
EFI_LOADER will now be available without CONFIG_CMDLINE or specifically
CONFIG_CMD_BOOTEFI if invoked via bootmeth/bootstd.

Then, EFI_LOADER library side will be further split into two options
for fine-grain control:
CONFIG_EFI_BINARY_EXEC: execute UEFI binaries which are to be explicitly
loaded by U-Boot's load commands/functions or other methods
(like a jtag debugger?)
It supports bootmeth_efi as well as "bootefi |hello"(/"bootm"?).

CONFIG_EFI_BOOTMGR: provide EFI boot manger functionality
It supports bootmeth_efi_mgr as well as "bootefi bootmgr".

As such, We will no longer need CONFIG_EFI_BINARY_EXEC if we want to only
make use of the UEFI boot manger for booting a next stage OS.

Prerequisite

This patch set is based on top of Tom's latest "next" branch.

Tests
=
* run UT efi_selftest on sandbox locally
* run test_efi_bootmgr on sandbox locally

Unfortunately, I could not submit a pull request for CI test.

Changes
===
v3 (Dec 18, 2023)
* rebased onto Tom's latest next branch
* remove already-merged commits

v2 (Nov 21, 2023)
* rebased onto Tom's next branch
* remove already merged commits
* revise commit messages
* add patch #5 which was split from ex-patch#5
RFC (Oct 26, 2023)

[1] https://lists.denx.de/pipermail/u-boot/2023-October/534598.html

AKASHI Takahiro (4):
  efi_loader: split unrelated code from efi_bootmgr.c
  efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR
  net: tftp: remove explicit efi configuration dependency
  fs: remove explicit efi configuration dependency

 boot/Kconfig |   4 +-
 boot/Makefile|   2 +-
 cmd/Kconfig  |  10 +-
 cmd/efidebug.c   |   4 +-
 fs/fs.c  |   7 +-
 include/efi_loader.h |  28 +-
 lib/efi_loader/Kconfig   |  11 +-
 lib/efi_loader/Makefile  |   2 +-
 lib/efi_loader/efi_bootmgr.c | 493 --
 lib/efi_loader/efi_device_path.c |   3 +-
 lib/efi_loader/efi_helper.c  | 499 ++-
 net/tftp.c   |  10 +-
 test/boot/bootflow.c |   2 +-
 13 files changed, 544 insertions(+), 531 deletions(-)

-- 
2.34.1



Re: [PATCH] efi_loader: eliminate efi_disk_obj structure

2023-12-13 Thread AKASHI Takahiro
Hi Kojima-san,

On Wed, Dec 13, 2023 at 05:57:37PM +0900, Masahisa Kojima wrote:
> Current code uses struct efi_disk_obj to keep information
> about block devices and partitions. As the efi handle already
> has a field with the udevice, we should eliminate
> struct efi_disk_obj and use an pointer to struct efi_object
> for the handle.

I don't still understand what is an advantage of your approach.

> efi_link_dev() call is moved inside of efi_disk_add_dev() function
> to simplify the cleanup process in case of error.
> 
> Signed-off-by: Masahisa Kojima 
> ---
>  lib/efi_loader/efi_disk.c | 209 +-
>  1 file changed, 116 insertions(+), 93 deletions(-)
> 
> diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
> index f0d76113b0..cfb7ace551 100644
> --- a/lib/efi_loader/efi_disk.c
> +++ b/lib/efi_loader/efi_disk.c
> @@ -27,27 +27,24 @@ struct efi_system_partition efi_system_partition = {
>  const efi_guid_t efi_block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
>  const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
>  
> -/**
> - * struct efi_disk_obj - EFI disk object
> - *
> - * @header:  EFI object header
> - * @ops: EFI disk I/O protocol interface
> - * @dev_index:   device index of block device
> - * @media:   block I/O media information
> - * @dp:  device path to the block device
> - * @part:partition
> - * @volume:  simple file system protocol of the partition
> - * @dev: associated DM device
> - */
> -struct efi_disk_obj {
> - struct efi_object header;

This is a handy way of making it ease to dereference from an internal
structure to an external reference as Heinrich mentioned.

> - struct efi_block_io ops;

Along with "header" and "media", this allows us to congregate
a couple of "malloc" calls, instead of your change, into one.

> - int dev_index;
> - struct efi_device_path *dp;
> - unsigned int part;
> - struct efi_simple_file_system_protocol *volume;

If we carefully look into the base code, we will no longer have to
have those fields in this structure because they are mostly used in
a single internal function (if I'm correct).
So we can simply replace them with local variables (with some extra
changes).

-Takahiro Akashi

> -};
> +static efi_handle_t efi_blkio_find_obj(struct efi_block_io *blkio)
> +{
> + efi_handle_t handle;
> +
> + list_for_each_entry(handle, _obj_list, link) {
> + efi_status_t ret;
> + struct efi_handler *handler;
> +
> + ret = efi_search_protocol(handle, _block_io_guid, );
> + if (ret != EFI_SUCCESS)
> + continue;
> +
> + if (blkio == handler->protocol_interface)
> + return handle;
> + }
> +
> + return NULL;
> +}
>  
>  /**
>   * efi_disk_reset() - reset block device
> @@ -107,13 +104,16 @@ static efi_status_t efi_disk_rw_blocks(struct 
> efi_block_io *this,
>   u32 media_id, u64 lba, unsigned long buffer_size,
>   void *buffer, enum efi_disk_direction direction)
>  {
> - struct efi_disk_obj *diskobj;
> + efi_handle_t handle;
>   int blksz;
>   int blocks;
>   unsigned long n;
>  
> - diskobj = container_of(this, struct efi_disk_obj, ops);
> - blksz = diskobj->media.block_size;
> + handle = efi_blkio_find_obj(this);
> + if (!handle)
> + return EFI_INVALID_PARAMETER;
> +
> + blksz = this->media->block_size;
>   blocks = buffer_size / blksz;
>  
>   EFI_PRINT("blocks=%x lba=%llx blksz=%x dir=%d\n",
> @@ -124,18 +124,16 @@ static efi_status_t efi_disk_rw_blocks(struct 
> efi_block_io *this,
>   return EFI_BAD_BUFFER_SIZE;
>  
>   if (CONFIG_IS_ENABLED(PARTITIONS) &&
> - device_get_uclass_id(diskobj->header.dev) == UCLASS_PARTITION) {
> + device_get_uclass_id(handle->dev) == UCLASS_PARTITION) {
>   if (direction == EFI_DISK_READ)
> - n = disk_blk_read(diskobj->header.dev, lba, blocks,
> -   buffer);
> + n = disk_blk_read(handle->dev, lba, blocks, buffer);
>   else
> - n = disk_blk_write(diskobj->header.dev, lba, blocks,
> -buffer);
> + n = disk_blk_write(handle->dev, lba, blocks, buffer);
>   } else {
>   /* dev is a block device (UCLASS_BLK) */
>   struct blk_desc *desc;
>  
> - desc = dev_get_uclass_plat(diskobj->header.dev);
> + desc = dev_get_uclass_plat(handle->dev);
>   if (direction == EFI_DISK_READ)
>   n = blk_dread(desc, lba, blocks, buffer);
>   else
> @@ -388,6 +386,7 @@ static int efi_fs_exists(struct blk_desc *desc, int part)
>   * @part:partition
>   * @disk:pointer to receive the created handle
>   * @agent_handle:  

Re: [PATCH v2 02/12] cmd: bootefi: re-organize do_bootefi()

2023-12-07 Thread AKASHI Takahiro
Hi Ilias,

On Fri, Dec 08, 2023 at 08:33:11AM +0200, Ilias Apalodimas wrote:
> Akashi-san,
> 
> [...]
> 
> > > > > > help
> > > > > >   This compiles a standard EFI hello world application with 
> > > > > > U-Boot so
> > > > > > @@ -395,6 +405,7 @@ config CMD_BOOTEFI_HELLO
> > > > > >   up EFI support on a new architecture.
> > > > > >
> > > > > >   source lib/efi_selftest/Kconfig
> > > > > > +endif
> > > > > >
> > > > > >   config CMD_BOOTMENU
> > > > > > bool "bootmenu"
> > > > > > diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> > > > > > index 190ccba260e0..e9e5ab67a1f5 100644
> > > > > > --- a/cmd/bootefi.c
> > > > > > +++ b/cmd/bootefi.c
> > > > > > @@ -503,7 +503,6 @@ out:
> > > > > > return (ret != EFI_SUCCESS) ? ret : ret2;
> > > > > >   }
> > > > > >
> > > > > > -#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
> > > > > >   static efi_status_t bootefi_run_prepare(const char 
> > > > > > *load_options_path,
> > > > > > struct efi_device_path *device_path,
> > > > > > struct efi_device_path *image_path,
> > > > > > @@ -593,7 +592,6 @@ static int do_efi_selftest(void)
> > > > > >
> > > > > > return ret != EFI_SUCCESS;
> > > > > >   }
> > > > > > -#endif /* CONFIG_CMD_BOOTEFI_SELFTEST */
> > > > > >
> > > > > >   /**
> > > > > >* do_bootefi() - execute `bootefi` command
> > > > > > @@ -615,14 +613,6 @@ static int do_bootefi(struct cmd_tbl *cmdtp, 
> > > > > > int flag, int argc,
> > > > > > if (argc < 2)
> > > > > > return CMD_RET_USAGE;
> > > > > >
> > > > > > -   /* Initialize EFI drivers */
> > > > > > -   ret = efi_init_obj_list();
> > > > > > -   if (ret != EFI_SUCCESS) {
> > > > > > -   log_err("Error: Cannot initialize UEFI sub-system, r = 
> > > > > > %lu\n",
> > > > > > -   ret & ~EFI_ERROR_MASK);
> > > > > > -   return CMD_RET_FAILURE;
> > > > > > -   }
> > > > > > -
> > > > > > if (argc > 2) {
> > > > > > uintptr_t fdt_addr;
> > > > > >
> > > > > > @@ -631,29 +621,54 @@ static int do_bootefi(struct cmd_tbl *cmdtp, 
> > > > > > int flag, int argc,
> > > > > > } else {
> > > > > > fdt = EFI_FDT_USE_INTERNAL;
> > > > > > }
> > > > > > -   ret = efi_install_fdt(fdt);
> > > > > > -   if (ret == EFI_INVALID_PARAMETER)
> > > > > > -   return CMD_RET_USAGE;
> > > > > > -   else if (ret != EFI_SUCCESS)
> > > > > > -   return CMD_RET_FAILURE;
> > > > > >
> > > > > > -   if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
> > > > > > -   if (!strcmp(argv[1], "bootmgr"))
> > > > > > -   return do_efibootmgr();
> > > > > > +   if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR) &&
> > > > > > +   !strcmp(argv[1], "bootmgr")) {
> > > > >
> > > > >
> > > > > https://docs.u-boot.org/en/latest/develop/commands.html
> > > > > suggests to use U_BOOT_CMD_MKENT() to define sub-commands.
> > > >
> > > > As you know, these "if (!strcmp(argv[1], ...)" code exist since
> > > > the early days when efi_selftest and bootmgr sub-commands were
> > > > introduced in bootefi.
> > > >
> > > > In my personal preference, I would move bootmgr to a new independent
> > > > command, efi_selftest to efidebug, leaving only binary-execution
> > > > syntax in bootefi.
> > > > (So no sub-command.)
> > >
> > > And that's a good idea, does anything prevent us from doing that ? The
> > > code works reliably as-is so if we are thinking about refactoring it,
> > > take a deeper dive and let's do all of it.
> > >
> > > An idea would be to start with patches that move 'bootefi hello' and
> > > 'bootefi selftest' to the efidebug command?
> > >
> > > >
> > > > >
> > > > > > +   /* Initialize EFI drivers */
> > > > > > +   ret = efi_init_obj_list();
> > > > >
> > > > > We should not duplicate this call for each sub-command.
> > > >
> > > > Please also take a look at the succeeding commits.
> > > > A call to efi_init_obj_list() will be included in independent
> > > > library functions, either efi_bootmgr_run(), efi_binary_run()
> > > > or do_bootefi() (for efi_selftest) so that a caller of these
> > > > functions doesn't have to know/care much about detailed APIs.
> > >
> > > I am with Heinrich on this. Despite the further refactoring in
> > > subsequent patches, we could just initialize the EFI subsystem at the
> > > beginning. It will eventually be done by some part of u-boot and we
> >
> > Yes if you want to always call efi_init_obj_list() in, say, board_init_r().
> > But we didn't take this approach by design because we wanted to initialize
> > the subsystem only if needed.
> 
> Not in board_init_r(). Perhaps we can have that as a Kconfig option

Then where do you want to call the function?

> >
> > > don't clean up the initialization on any failure, so why not move it
> > > on top of the function right after the argument parsing?
> >
> > I'm not sure what you mean here, but please remember that either
> > efi_binary_run() or efi_bootmgr_run() is more or less a utility
> > 

Re: [PATCH v2 02/12] cmd: bootefi: re-organize do_bootefi()

2023-12-05 Thread AKASHI Takahiro
On Tue, Dec 05, 2023 at 10:54:23AM +0200, Ilias Apalodimas wrote:
> Hello Akashi-san,
> Thanks for taking a shot at the cleanup
> 
> On Tue, 21 Nov 2023 at 06:53, AKASHI Takahiro
>  wrote:
> >
> > Hi Heinrich,
> >
> > On Tue, Nov 21, 2023 at 04:31:40AM +0100, Heinrich Schuchardt wrote:
> > > On 11/21/23 02:29, AKASHI Takahiro wrote:
> > > > Replicate some code and re-organize do_bootefi() into three cases, which
> > > > will be carved out as independent functions in the next two commits.
> > > >
> > > > Signed-off-by: AKASHI Takahiro 
> > > > ---
> > > >   cmd/Kconfig  | 15 ++--
> > > >   cmd/bootefi.c| 82 ++--
> > > >   include/efi_loader.h |  2 --
> > > >   3 files changed, 69 insertions(+), 30 deletions(-)
> > > >
> > > > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > > > index 6f636155e5b6..4cf9a210c4a1 100644
> > > > --- a/cmd/Kconfig
> > > > +++ b/cmd/Kconfig
> > > > @@ -362,9 +362,19 @@ config CMD_BOOTEFI
> > > > help
> > > >   Boot an EFI image from memory.
> > > >
> > > > +if CMD_BOOTEFI
> > > > +config CMD_BOOTEFI_BINARY
> > > > +   bool "Allow booting an EFI binary directly"
> > > > +   depends on BOOTEFI_BOOTMGR
> > >
> > > Why should booting a known binary depend on the boot manager?
> >
> > Because I tried to maintain the meaning of CONFIG_BOOTEFI_BOOTMGR
> > at this point of refactoring.
> > This configuration will eventually be changed to
> > config CMD_BOOTEFI_BINARY
> > bool "Allow booting an EFI binary directly"
> > depends on EFI_BINARY_EXEC
> > default y
> > in patch#9.
> >
> > > > +   default y
> > > > +   help
> > > > + Select this option to enable direct execution of binary at 
> > > > 'bootefi'.
> > > > + This subcommand will allow you to load the UEFI binary using
> > > > + other U-Boot commands or external methods and then run it.
> > > > +
> > > >   config CMD_BOOTEFI_BOOTMGR
> > > > bool "UEFI Boot Manager command"
> > > > -   depends on BOOTEFI_BOOTMGR && CMD_BOOTEFI
> > > > +   depends on BOOTEFI_BOOTMGR
> > > > default y
> > > > help
> > > >   Select this option to enable the 'bootmgr' subcommand of 
> > > > 'bootefi'.
> > > > @@ -373,7 +383,7 @@ config CMD_BOOTEFI_BOOTMGR
> > > >
> > > >   config CMD_BOOTEFI_HELLO_COMPILE
> > > > bool "Compile a standard EFI hello world binary for testing"
> > > > -   depends on CMD_BOOTEFI && !CPU_V7M
> > > > +   depends on !CPU_V7M
> > >
> > > Why do we have this dependency?
> >
> > CPU_V7M?
> > It was introduced in your commit:
> > ---
> > commit 0ea8741ff65e
> > Author: Heinrich Schuchardt 
> > Date:   Sun Dec 30 10:11:14 2018 +0100
> >
> > efi_loader: CMD_BOOTEFI_HELLO_COMPILE in configs
> > ---
> >
> > > EFI_LOADER cannot be selected for SYS_CPU=armv7m.
> >
> > If not needed, you can delete it, but it is out of scope
> > of this patch series.
> >
> > > > default y
> > > > help
> > > >   This compiles a standard EFI hello world application with U-Boot 
> > > > so
> > > > @@ -395,6 +405,7 @@ config CMD_BOOTEFI_HELLO
> > > >   up EFI support on a new architecture.
> > > >
> > > >   source lib/efi_selftest/Kconfig
> > > > +endif
> > > >
> > > >   config CMD_BOOTMENU
> > > > bool "bootmenu"
> > > > diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> > > > index 190ccba260e0..e9e5ab67a1f5 100644
> > > > --- a/cmd/bootefi.c
> > > > +++ b/cmd/bootefi.c
> > > > @@ -503,7 +503,6 @@ out:
> > > > return (ret != EFI_SUCCESS) ? ret : ret2;
> > > >   }
> > > >
> > > > -#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
> > > >   static efi_status_t bootefi_run_prepare(const char *load_options_path,
> > > > struct efi_device_path *device_path,
> > > > struct efi_device_path *image_path,
> > > > @@ -593,7 +592,6 @@ static int do_efi_selftest(void)
> > > >
> > > >

Re: [PATCH v2 00/12] cmd: bootefi: refactor the code for bootmgr

2023-12-03 Thread AKASHI Takahiro
Hi Heinrich, Ilias

On Tue, Nov 21, 2023 at 10:29:38AM +0900, AKASHI Takahiro wrote:
> This patch set is motivated by the discussion[1] regarding
> CONFIG_BOOTEFI_BOOTMGR option.
> 
> At the end, bootefi.c will be decomposed into two parts, one for
> providing the command itself and one for implementing helper functions.
> EFI_LOADER will now be available without CONFIG_CMDLINE or specifically
> CONFIG_CMD_BOOTEFI if invoked via bootmeth/bootstd.
> 
> Then, EFI_LOADER library side will be further split into two options
> for fine-grain control:
> CONFIG_EFI_BINARY_EXEC: execute UEFI binaries which are to be explicitly
> loaded by U-Boot's load commands/functions or other methods
> (like a jtag debugger?)
> It supports bootmeth_efi as well as "bootefi |hello"(/"bootm"?).
> 
> CONFIG_EFI_BOOTMGR: provide EFI boot manger functionality
> It supports bootmeth_efi_mgr as well as "bootefi bootmgr".
> 
> As such, We will no longer need CONFIG_EFI_BINARY_EXEC if we want to only
> make use of the UEFI boot manger for booting a next stage OS.

Any other comments?
I think the changes are no doubt trivial.

-Takahiro Akashi


> Prerequisite
> 
> This patch set is based on top of Tom's "next" branch.
> 
> Patches
> ===
> Patch#1-#12: I hope that those commits show step-by-step refactoring
> without introducing degradation.
> 
> Tests
> =
> * run UT efi_selftest on sandbox locally
> * run test_efi_bootmgr on sandbox locally
> 
> Unfortunately, I could not submit a pull request for CI test.
> 
> Changes
> ===
> v2 (Nov 21, 2023)
> * rebased onto Tom's next branch
> * remove already merged commits
> * revise commit messages
> * add patch #5 which was split from ex-patch#5
> RFC (Oct 26, 2023)
> 
> [1] https://lists.denx.de/pipermail/u-boot/2023-October/534598.html
> 
> AKASHI Takahiro (12):
>   cmd: bootefi: unfold do_bootefi_image()
>   cmd: bootefi: re-organize do_bootefi()
>   cmd: bootefi: carve out EFI boot manager interface
>   cmd: bootefi: carve out binary execution interface
>   cmd: bootefi: localize global device paths for efi_selftest
>   cmd: bootefi: move library interfaces under lib/efi_loader
>   cmd: efidebug: ease efi configuration dependency
>   bootmeth: use efi_loader interfaces instead of bootefi command
>   efi_loader: split unrelated code from efi_bootmgr.c
>   efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR
>   net: tftp: remove explicit efi configuration dependency
>   fs: remove explicit efi configuration dependency
> 
>  boot/Kconfig |   4 +-
>  boot/Makefile|   2 +-
>  boot/bootm_os.c  |  31 +-
>  boot/bootmeth_efi.c  |   8 +-
>  boot/bootmeth_efi_mgr.c  |   2 +-
>  cmd/Kconfig  |  21 +-
>  cmd/bootefi.c| 670 +--
>  cmd/efidebug.c   |   4 +-
>  fs/fs.c  |   7 +-
>  include/efi_loader.h |  34 +-
>  lib/efi_loader/Kconfig   |  11 +-
>  lib/efi_loader/Makefile  |   2 +-
>  lib/efi_loader/efi_bootmgr.c |  37 ++
>  lib/efi_loader/efi_device_path.c |   3 +-
>  lib/efi_loader/efi_helper.c  | 498 ++-
>  net/tftp.c   |  10 +-
>  test/boot/bootflow.c |   2 +-
>  17 files changed, 700 insertions(+), 646 deletions(-)
> 
> -- 
> 2.34.1
> 


Re: [PATCH v1 2/3] efi_vars: Implement SPI Flash store

2023-11-21 Thread AKASHI Takahiro
On Tue, Nov 21, 2023 at 11:57:12PM +, Shantur Rathore wrote:
> Currently U-boot uses ESP as storage for EFI variables.
> Devices with SPI Flash are used for storing environment with this
> commit we allow EFI variables to be stored on SPI Flash.
> 
> Signed-off-by: Shantur Rathore 
> ---
> 
>  include/efi_variable.h| 25 ++
>  lib/efi_loader/Kconfig| 18 +++
>  lib/efi_loader/Makefile   |  1 +
>  lib/efi_loader/efi_var_sf.c   | 91 +++
>  lib/efi_loader/efi_variable.c |  4 ++
>  5 files changed, 139 insertions(+)
>  create mode 100644 lib/efi_loader/efi_var_sf.c
> 
> diff --git a/include/efi_variable.h b/include/efi_variable.h
> index ca7e19d514..766dd109f5 100644
> --- a/include/efi_variable.h
> +++ b/include/efi_variable.h
> @@ -188,6 +188,31 @@ efi_status_t efi_var_from_file(void);
>  
>  #endif // CONFIG_EFI_VARIABLE_FILE_STORE
>  
> +#ifdef CONFIG_EFI_VARIABLE_SF_STORE

Not needed as I said.

> +
> +/**
> + * efi_var_from_sf() - read variables from SPI Flash
> + *
> + * EFI variable buffer is read from SPI Flash at offset defined with
> + * CONFIG_EFI_VARIABLE_SF_OFFSET of length CONFIG_EFI_VAR_BUF_SIZE
> + *
> + *
> + * Return:   status code
> + */
> +efi_status_t efi_var_from_sf(void);
> +
> +/**
> + * efi_var_to_sf() - save non-volatile variables to SPI Flash
> + *
> + * EFI variable buffer is saved to SPI Flash at offset defined with
> + * CONFIG_EFI_VARIABLE_SF_OFFSET of length CONFIG_EFI_VAR_BUF_SIZE.
> + *
> + * Return:   status code
> + */
> +efi_status_t efi_var_to_sf(void);
> +
> +#endif // CONFIG_EFI_VARIABLE_SF_STORE
> +
>  /**
>   * efi_var_mem_init() - set-up variable list
>   *
> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> index 4ccd26f94a..1fcc6fabb4 100644
> --- a/lib/efi_loader/Kconfig
> +++ b/lib/efi_loader/Kconfig
> @@ -54,6 +54,17 @@ config EFI_VARIABLE_FILE_STORE
> Select this option if you want non-volatile UEFI variables to be
> stored as file /ubootefi.var on the EFI system partition.
>  
> +config EFI_VARIABLE_SF_STORE
> + bool "Store non-volatile UEFI variables in SPI Flash"
> + depends on SPI_FLASH
> + help
> +   Select this option if you want non-volatile UEFI variables to be
> +   stored in SPI Flash.
> +   Define CONFIG_EFI_VARIABLE_SF_OFFSET as offset in SPI Flash to use as
> +   the storage for variables. CONFIG_EFI_VAR_BUF_SIZE defines the space
> +   needed.
> +
> +
>  config EFI_MM_COMM_TEE
>   bool "UEFI variables storage service via the trusted world"
>   depends on OPTEE
> @@ -108,6 +119,13 @@ config EFI_VARIABLE_NO_STORE
>  
>  endchoice
>  
> +config EFI_VARIABLE_SF_OFFSET
> + hex "EFI variables in SPI flash offset"
> + depends on EFI_VARIABLE_SF_STORE
> + default 0x7D

The default value is definitely board-specific.
Please add "if TARGET_ROCKPRO64_RK3399(?)".

> + help
> +   Offset from the start of the SPI Flash where EFI variables will be 
> stored.
> +
>  config EFI_VARIABLES_PRESEED
>   bool "Initial values for UEFI variables"
>   depends on !EFI_MM_COMM_TEE
> diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
> index 8d31fc61c6..b9b715b1ff 100644
> --- a/lib/efi_loader/Makefile
> +++ b/lib/efi_loader/Makefile
> @@ -67,6 +67,7 @@ obj-$(CONFIG_EFI_UNICODE_COLLATION_PROTOCOL2) += 
> efi_unicode_collation.o
>  obj-y += efi_var_common.o
>  obj-y += efi_var_mem.o
>  obj-y += efi_var_file.o
> +obj-$(CONFIG_EFI_VARIABLE_SF_STORE) += efi_var_sf.o
>  ifeq ($(CONFIG_EFI_MM_COMM_TEE),y)
>  obj-y += efi_variable_tee.o
>  else
> diff --git a/lib/efi_loader/efi_var_sf.c b/lib/efi_loader/efi_var_sf.c
> new file mode 100644
> index 00..e604a2225c
> --- /dev/null
> +++ b/lib/efi_loader/efi_var_sf.c
> @@ -0,0 +1,91 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * File interface for UEFI variables

For Spi Flash?

> + *
> + * Copyright (c) 2023, Shantur Rtahore
> + */
> +
> +#define LOG_CATEGORY LOGC_EFI
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +efi_status_t efi_var_to_sf(void)
> +{
> + efi_status_t ret;
> + struct efi_var_file *buf;
> + loff_t len;
> + struct udevice *sfdev;
> +
> + ret = efi_var_collect(, , EFI_VARIABLE_NON_VOLATILE);
> + if (len > EFI_VAR_BUF_SIZE) {
> + log_err("EFI var buffer length more than target SF size");
> + ret = EFI_BAD_BUFFER_SIZE;
> + goto error;
> + }
> +
> + debug("%s - Got buffer to write buf->len : %d\n", __func__, 
> buf->length);

log_debug()?

> +
> + if (ret != EFI_SUCCESS)
> + goto error;
> +
> + ret = uclass_get_device(UCLASS_SPI_FLASH, 0, );
> + if (ret)
> + goto error;
> +
> + ret = spi_flash_erase_dm(sfdev, CONFIG_EFI_VARIABLE_SF_OFFSET, 
> EFI_VAR_BUF_SIZE);
> + debug("%s - Erased SPI Flash offset %lx\n", __func__, 
> CONFIG_EFI_VARIABLE_SF_OFFSET);
> + if (ret)
> + goto error;
> +
> +

Re: [PATCH v1 1/3] efi: filestore: don't compile when config disabled

2023-11-21 Thread AKASHI Takahiro
On Tue, Nov 21, 2023 at 11:57:11PM +, Shantur Rathore wrote:
> Compile out filestore functions when config isn't enabled.
> 
> Signed-off-by: Shantur Rathore 
> ---
> 
>  include/efi_variable.h| 21 -
>  lib/efi_loader/efi_var_file.c | 13 +++--
>  lib/efi_loader/efi_variable.c | 10 +-
>  3 files changed, 28 insertions(+), 16 deletions(-)
> 
> diff --git a/include/efi_variable.h b/include/efi_variable.h
> index 805e6c5f1e..ca7e19d514 100644
> --- a/include/efi_variable.h
> +++ b/include/efi_variable.h
> @@ -136,15 +136,6 @@ struct efi_var_file {
>   struct efi_var_entry var[];
>  };
>  
> -/**
> - * efi_var_to_file() - save non-volatile variables as file
> - *
> - * File ubootefi.var is created on the EFI system partion.
> - *
> - * Return:   status code
> - */
> -efi_status_t efi_var_to_file(void);
> -
>  /**
>   * efi_var_collect() - collect variables in buffer
>   *
> @@ -172,6 +163,16 @@ efi_status_t __maybe_unused efi_var_collect(struct 
> efi_var_file **bufp, loff_t *
>   */
>  efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe);
>  
> +#ifdef CONFIG_EFI_VARIABLE_FILE_STORE

I don't think we need this guard because any function declaration
in a header is harmless even if that function implementation is opted out.

> +/**
> + * efi_var_to_file() - save non-volatile variables as file
> + *
> + * File ubootefi.var is created on the EFI system parition.
> + *
> + * Return:   status code
> + */
> +efi_status_t efi_var_to_file(void);
> +
>  /**
>   * efi_var_from_file() - read variables from file
>   *
> @@ -185,6 +186,8 @@ efi_status_t efi_var_restore(struct efi_var_file *buf, 
> bool safe);
>   */
>  efi_status_t efi_var_from_file(void);
>  
> +#endif // CONFIG_EFI_VARIABLE_FILE_STORE
> +
>  /**
>   * efi_var_mem_init() - set-up variable list
>   *
> diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c
> index 62e071bd83..7ceb7e3cf7 100644
> --- a/lib/efi_loader/efi_var_file.c
> +++ b/lib/efi_loader/efi_var_file.c
> @@ -117,6 +117,8 @@ efi_status_t __maybe_unused efi_var_collect(struct 
> efi_var_file **bufp, loff_t *
>   return EFI_SUCCESS;
>  }
>  
> +#ifdef CONFIG_EFI_VARIABLE_FILE_STORE

Can you refactor the code further to purge all "#ifdef" stuffs from this file?

I mean:
1) move efi_var_collect/restor() to a always-compiled file, say,
   efi_var_common.c/efi_variable.c
2) modify call sites of the other functions, for example, as follows:
 if (CONFIG_IS_ENABLED(EFI_VARIABLE_STORE))
 efi_var_to_file();
   # I'm not sure why the return code is ignored everywhere.
3) modify Makefile to compile efi_var_file.c only if EFI_VARIABLE_FILE_STORE
   is enabled
4) remove "#ifdef CONFIG_EFI_VARIABLE_FILE_STORE" from efi_var_file.c

-Takahiro Akashi

> +
>  /**
>   * efi_var_to_file() - save non-volatile variables as file
>   *
> @@ -126,7 +128,6 @@ efi_status_t __maybe_unused efi_var_collect(struct 
> efi_var_file **bufp, loff_t *
>   */
>  efi_status_t efi_var_to_file(void)
>  {
> -#ifdef CONFIG_EFI_VARIABLE_FILE_STORE
>   efi_status_t ret;
>   struct efi_var_file *buf;
>   loff_t len;
> @@ -150,11 +151,10 @@ error:
>   log_err("Failed to persist EFI variables\n");
>   free(buf);
>   return ret;
> -#else
> - return EFI_SUCCESS;
> -#endif
>  }
>  
> +#endif // CONFIG_EFI_VARIABLE_FILE_STORE
> +
>  efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe)
>  {
>   struct efi_var_entry *var, *last_var;
> @@ -198,6 +198,7 @@ efi_status_t efi_var_restore(struct efi_var_file *buf, 
> bool safe)
>   return EFI_SUCCESS;
>  }
>  
> +#ifdef CONFIG_EFI_VARIABLE_FILE_STORE
>  /**
>   * efi_var_from_file() - read variables from file
>   *
> @@ -211,7 +212,6 @@ efi_status_t efi_var_restore(struct efi_var_file *buf, 
> bool safe)
>   */
>  efi_status_t efi_var_from_file(void)
>  {
> -#ifdef CONFIG_EFI_VARIABLE_FILE_STORE
>   struct efi_var_file *buf;
>   loff_t len;
>   efi_status_t ret;
> @@ -236,6 +236,7 @@ efi_status_t efi_var_from_file(void)
>   log_err("Invalid EFI variables file\n");
>  error:
>   free(buf);
> -#endif
>   return EFI_SUCCESS;
>  }
> +
> +#endif // CONFIG_EFI_VARIABLE_FILE_STORE
> diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
> index be95ed44e6..7fa51d 100644
> --- a/lib/efi_loader/efi_variable.c
> +++ b/lib/efi_loader/efi_variable.c
> @@ -357,8 +357,11 @@ efi_status_t efi_set_variable_int(const u16 
> *variable_name,
>* Write non-volatile EFI variables to file
>* TODO: check if a value change has occured to avoid superfluous writes
>*/
> - if (attributes & EFI_VARIABLE_NON_VOLATILE)
> + if (attributes & EFI_VARIABLE_NON_VOLATILE) {
> +#ifdef CONFIG_EFI_VARIABLE_FILE_STORE
>   efi_var_to_file();
> +#endif
> + }
>  
>   return EFI_SUCCESS;
>  }
> @@ -466,7 +469,12 @@ efi_status_t efi_init_variables(void)
>   if (ret != EFI_SUCCESS)
> 

Re: [PATCH v2 03/12] cmd: bootefi: carve out EFI boot manager interface

2023-11-20 Thread AKASHI Takahiro
On Tue, Nov 21, 2023 at 04:38:12AM +0100, Heinrich Schuchardt wrote:
> On 11/21/23 02:29, AKASHI Takahiro wrote:
> > Carve EFI boot manager related code out of do_bootefi_image() in order
> > to move boot manager specific code into library directory in the later
> > commit.
> > 
> > Signed-off-by: AKASHI Takahiro 
> > ---
> >   cmd/bootefi.c | 43 ---
> >   1 file changed, 24 insertions(+), 19 deletions(-)
> > 
> > diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> > index e9e5ab67a1f5..87910c42333a 100644
> > --- a/cmd/bootefi.c
> > +++ b/cmd/bootefi.c
> > @@ -413,28 +413,40 @@ out:
> >   }
> > 
> >   /**
> > - * do_efibootmgr() - execute EFI boot manager
> > + * efi_bootmgr_run() - execute EFI boot manager
> > + * fdt:Flat device tree
> > + *
> > + * Invoke EFI boot manager and execute a binary depending on
> > + * boot options. If @fdt is not NULL, it will be passed to
> > + * the executed binary.
> 
> How about the fallback to the control device-tree?

efi_install_fdt() will take care of that if fdt == EFI_FDT_INTERNAL_USE.
I didn't change any semantics.
I will add some description here to clarify it.

> How about booting with ACPI?

Not sure what is your concern, but
I didn't change any semantics in bootmgr use-case.

-Takahiro Akashi

> 
> Best regards
> 
> Heinrich
> 
> >*
> >* Return:status code
> >*/
> > -static int do_efibootmgr(void)
> > +static efi_status_t efi_bootmgr_run(void *fdt)
> >   {
> > efi_handle_t handle;
> > -   efi_status_t ret;
> > void *load_options;
> > +   efi_status_t ret;
> > 
> > -   ret = efi_bootmgr_load(, _options);
> > +   /* Initialize EFI drivers */
> > +   ret = efi_init_obj_list();
> > if (ret != EFI_SUCCESS) {
> > -   log_notice("EFI boot manager: Cannot load any image\n");
> > +   log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
> > +   ret & ~EFI_ERROR_MASK);
> > return CMD_RET_FAILURE;
> > }
> > 
> > -   ret = do_bootefi_exec(handle, load_options);
> > -
> > +   ret = efi_install_fdt(fdt);
> > if (ret != EFI_SUCCESS)
> > -   return CMD_RET_FAILURE;
> > +   return ret;
> > 
> > -   return CMD_RET_SUCCESS;
> > +   ret = efi_bootmgr_load(, _options);
> > +   if (ret != EFI_SUCCESS) {
> > +   log_notice("EFI boot manager: Cannot load any image\n");
> > +   return ret;
> > +   }
> > +
> > +   return do_bootefi_exec(handle, load_options);
> >   }
> > 
> >   /**
> > @@ -624,21 +636,14 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int 
> > flag, int argc,
> > 
> > if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR) &&
> > !strcmp(argv[1], "bootmgr")) {
> > -   /* Initialize EFI drivers */
> > -   ret = efi_init_obj_list();
> > -   if (ret != EFI_SUCCESS) {
> > -   log_err("Error: Cannot initialize UEFI sub-system, r = 
> > %lu\n",
> > -   ret & ~EFI_ERROR_MASK);
> > -   return CMD_RET_FAILURE;
> > -   }
> > +   ret = efi_bootmgr_run(fdt);
> > 
> > -   ret = efi_install_fdt(fdt);
> > if (ret == EFI_INVALID_PARAMETER)
> > return CMD_RET_USAGE;
> > -   else if (ret != EFI_SUCCESS)
> > +   else if (ret)
> > return CMD_RET_FAILURE;
> > 
> > -   return do_efibootmgr();
> > +   return CMD_RET_SUCCESS;
> > }
> > 
> > if (IS_ENABLED(CONFIG_CMD_BOOTEFI_SELFTEST) &&
> 


Re: [PATCH v2 02/12] cmd: bootefi: re-organize do_bootefi()

2023-11-20 Thread AKASHI Takahiro
Hi Heinrich,

On Tue, Nov 21, 2023 at 04:31:40AM +0100, Heinrich Schuchardt wrote:
> On 11/21/23 02:29, AKASHI Takahiro wrote:
> > Replicate some code and re-organize do_bootefi() into three cases, which
> > will be carved out as independent functions in the next two commits.
> > 
> > Signed-off-by: AKASHI Takahiro 
> > ---
> >   cmd/Kconfig  | 15 ++--
> >   cmd/bootefi.c| 82 ++--
> >   include/efi_loader.h |  2 --
> >   3 files changed, 69 insertions(+), 30 deletions(-)
> > 
> > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > index 6f636155e5b6..4cf9a210c4a1 100644
> > --- a/cmd/Kconfig
> > +++ b/cmd/Kconfig
> > @@ -362,9 +362,19 @@ config CMD_BOOTEFI
> > help
> >   Boot an EFI image from memory.
> > 
> > +if CMD_BOOTEFI
> > +config CMD_BOOTEFI_BINARY
> > +   bool "Allow booting an EFI binary directly"
> > +   depends on BOOTEFI_BOOTMGR
> 
> Why should booting a known binary depend on the boot manager?

Because I tried to maintain the meaning of CONFIG_BOOTEFI_BOOTMGR
at this point of refactoring.
This configuration will eventually be changed to
config CMD_BOOTEFI_BINARY
bool "Allow booting an EFI binary directly"
depends on EFI_BINARY_EXEC
default y
in patch#9.

> > +   default y
> > +   help
> > + Select this option to enable direct execution of binary at 'bootefi'.
> > + This subcommand will allow you to load the UEFI binary using
> > + other U-Boot commands or external methods and then run it.
> > +
> >   config CMD_BOOTEFI_BOOTMGR
> > bool "UEFI Boot Manager command"
> > -   depends on BOOTEFI_BOOTMGR && CMD_BOOTEFI
> > +   depends on BOOTEFI_BOOTMGR
> > default y
> > help
> >   Select this option to enable the 'bootmgr' subcommand of 'bootefi'.
> > @@ -373,7 +383,7 @@ config CMD_BOOTEFI_BOOTMGR
> > 
> >   config CMD_BOOTEFI_HELLO_COMPILE
> > bool "Compile a standard EFI hello world binary for testing"
> > -   depends on CMD_BOOTEFI && !CPU_V7M
> > +   depends on !CPU_V7M
> 
> Why do we have this dependency?

CPU_V7M?
It was introduced in your commit:
---
commit 0ea8741ff65e
Author: Heinrich Schuchardt 
Date:   Sun Dec 30 10:11:14 2018 +0100

efi_loader: CMD_BOOTEFI_HELLO_COMPILE in configs
---

> EFI_LOADER cannot be selected for SYS_CPU=armv7m.

If not needed, you can delete it, but it is out of scope
of this patch series.

> > default y
> > help
> >   This compiles a standard EFI hello world application with U-Boot so
> > @@ -395,6 +405,7 @@ config CMD_BOOTEFI_HELLO
> >   up EFI support on a new architecture.
> > 
> >   source lib/efi_selftest/Kconfig
> > +endif
> > 
> >   config CMD_BOOTMENU
> > bool "bootmenu"
> > diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> > index 190ccba260e0..e9e5ab67a1f5 100644
> > --- a/cmd/bootefi.c
> > +++ b/cmd/bootefi.c
> > @@ -503,7 +503,6 @@ out:
> > return (ret != EFI_SUCCESS) ? ret : ret2;
> >   }
> > 
> > -#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
> >   static efi_status_t bootefi_run_prepare(const char *load_options_path,
> > struct efi_device_path *device_path,
> > struct efi_device_path *image_path,
> > @@ -593,7 +592,6 @@ static int do_efi_selftest(void)
> > 
> > return ret != EFI_SUCCESS;
> >   }
> > -#endif /* CONFIG_CMD_BOOTEFI_SELFTEST */
> > 
> >   /**
> >* do_bootefi() - execute `bootefi` command
> > @@ -615,14 +613,6 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
> > int argc,
> > if (argc < 2)
> > return CMD_RET_USAGE;
> > 
> > -   /* Initialize EFI drivers */
> > -   ret = efi_init_obj_list();
> > -   if (ret != EFI_SUCCESS) {
> > -   log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
> > -   ret & ~EFI_ERROR_MASK);
> > -   return CMD_RET_FAILURE;
> > -   }
> > -
> > if (argc > 2) {
> > uintptr_t fdt_addr;
> > 
> > @@ -631,29 +621,54 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int 
> > flag, int argc,
> > } else {
> > fdt = EFI_FDT_USE_INTERNAL;
> > }
> > -   ret = efi_install_fdt(fdt);
> > -   if (ret == EFI_INVALID_PARAMETER)
> > -   return CMD_RET_USAGE;
> > -   else if (ret != EFI_SUCCESS)
> > -   return CMD_RET_FAILURE;
> > 
> > -   if (IS_ENABLED(CONFIG_CM

[PATCH v2 09/12] efi_loader: split unrelated code from efi_bootmgr.c

2023-11-20 Thread AKASHI Takahiro
Some code moved from cmd/bootefi.c is actually necessary only for "bootefi
" command (starting an image manually loaded by a user using U-Boot
load commands or other methods (like JTAG debugger).

The code will never been opted out as unused code by a compiler which
doesn't know how EFI boot manager is implemented. So introduce a new
configuration, CONFIG_EFI_BINARY_EXEC, to enforce theem opted out
explicitly.

Signed-off-by: AKASHI Takahiro 
---
 boot/Kconfig |   4 +-
 cmd/Kconfig  |   6 +-
 include/efi_loader.h |  28 +-
 lib/efi_loader/Kconfig   |   9 +
 lib/efi_loader/efi_bootmgr.c | 492 --
 lib/efi_loader/efi_device_path.c |   3 +-
 lib/efi_loader/efi_helper.c  | 498 ++-
 7 files changed, 528 insertions(+), 512 deletions(-)

diff --git a/boot/Kconfig b/boot/Kconfig
index e879c63b84e3..dddc53766bb9 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -511,7 +511,7 @@ config BOOTMETH_EXTLINUX_PXE
 
 config BOOTMETH_EFILOADER
bool "Bootdev support for EFI boot"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BINARY_EXEC
default y
help
  Enables support for EFI boot using bootdevs. This makes the
@@ -546,7 +546,7 @@ config BOOTMETH_DISTRO
select BOOTMETH_SCRIPT if CMDLINE # E.g. Armbian uses scripts
select BOOTMETH_EXTLINUX  # E.g. Debian uses these
select BOOTMETH_EXTLINUX_PXE if CMD_PXE && CMD_NET && DM_ETH
-   select BOOTMETH_EFILOADER if BOOTEFI_BOOTMGR # E.g. Ubuntu uses this
+   select BOOTMETH_EFILOADER if EFI_BINARY_EXEC # E.g. Ubuntu uses this
 
 config SPL_BOOTMETH_VBE
bool "Bootdev support for Verified Boot for Embedded (SPL)"
diff --git a/cmd/Kconfig b/cmd/Kconfig
index dc4ea48f78bc..189ea6003293 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -273,7 +273,7 @@ config CMD_BOOTMETH
 
 config BOOTM_EFI
bool "Support booting UEFI FIT images"
-   depends on BOOTEFI_BOOTMGR && CMD_BOOTM && FIT
+   depends on EFI_BINARY_EXEC && CMD_BOOTM && FIT
default y
help
  Support booting UEFI FIT images via the bootm command.
@@ -365,7 +365,7 @@ config CMD_BOOTEFI
 if CMD_BOOTEFI
 config CMD_BOOTEFI_BINARY
bool "Allow booting an EFI binary directly"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BINARY_EXEC
default y
help
  Select this option to enable direct execution of binary at 'bootefi'.
@@ -396,7 +396,7 @@ config CMD_BOOTEFI_HELLO_COMPILE
 
 config CMD_BOOTEFI_HELLO
bool "Allow booting a standard EFI hello world for testing"
-   depends on CMD_BOOTEFI_HELLO_COMPILE
+   depends on CMD_BOOTEFI_BINARY && CMD_BOOTEFI_HELLO_COMPILE
default y if CMD_BOOTEFI_SELFTEST
help
  This adds a standard EFI hello world application to U-Boot so that
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 34e7fbbf1840..484c9fad239f 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -90,11 +90,7 @@ efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len);
  * back to u-boot world
  */
 void efi_restore_gd(void);
-/* Call this to unset the current device name */
-void efi_clear_bootdev(void);
-/* Call this to set the current device name */
-void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
-void *buffer, size_t buffer_size);
+
 /* Called by networking code to memorize the dhcp ack package */
 void efi_net_set_dhcp_ack(void *pkt, int len);
 /* Print information about all loaded images */
@@ -116,10 +112,6 @@ static inline efi_status_t efi_add_runtime_mmio(void 
*mmio_ptr, u64 len)
 
 /* No loader configured, stub out EFI_ENTRY */
 static inline void efi_restore_gd(void) { }
-static inline void efi_clear_bootdev(void) { }
-static inline void efi_set_bootdev(const char *dev, const char *devnr,
-  const char *path, void *buffer,
-  size_t buffer_size) { }
 static inline void efi_net_set_dhcp_ack(void *pkt, int len) { }
 static inline void efi_print_image_infos(void *pc) { }
 static inline efi_status_t efi_launch_capsules(void)
@@ -129,6 +121,20 @@ static inline efi_status_t efi_launch_capsules(void)
 
 #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */
 
+#if CONFIG_IS_ENABLED(EFI_BINARY_EXEC)
+/* Call this to unset the current device name */
+void efi_clear_bootdev(void);
+/* Call this to set the current device name */
+void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
+void *buffer, size_t buffer_size);
+#else
+static inline void efi_clear_bootdev(void) { }
+
+static inline void efi_set_bootdev(const char *dev, const char *devnr,
+  const char *path, void *buffer,
+  s

[PATCH v2 11/12] net: tftp: remove explicit efi configuration dependency

2023-11-20 Thread AKASHI Takahiro
Now it is clear that the feature actually depends on efi interfaces,
not "bootefi" command. efi_set_bootdev() will automatically be nullified
if necessary efi component is disabled.

Signed-off-by: AKASHI Takahiro 
---
 net/tftp.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/net/tftp.c b/net/tftp.c
index 88e71e67de35..2e335413492b 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -302,12 +302,10 @@ static void tftp_complete(void)
time_start * 1000, "/s");
}
puts("\ndone\n");
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) {
-   if (!tftp_put_active)
-   efi_set_bootdev("Net", "", tftp_filename,
-   map_sysmem(tftp_load_addr, 0),
-   net_boot_file_size);
-   }
+   if (!tftp_put_active)
+   efi_set_bootdev("Net", "", tftp_filename,
+   map_sysmem(tftp_load_addr, 0),
+   net_boot_file_size);
net_set_state(NETLOOP_SUCCESS);
 }
 
-- 
2.34.1



[PATCH v2 10/12] efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR

2023-11-20 Thread AKASHI Takahiro
At this point, EFI boot manager interfaces is fully independent from
bootefi command. So just rename the configuration parameter.

Signed-off-by: AKASHI Takahiro 
---
 boot/Makefile   | 2 +-
 cmd/Kconfig | 4 ++--
 cmd/efidebug.c  | 4 ++--
 lib/efi_loader/Kconfig  | 2 +-
 lib/efi_loader/Makefile | 2 +-
 test/boot/bootflow.c| 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/boot/Makefile b/boot/Makefile
index 4eaa5eab4b77..48d74c67d680 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -32,7 +32,7 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_CROS) += bootm.o bootm_os.o 
bootmeth_cros.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SCRIPT) += bootmeth_script.o
 ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL
-obj-$(CONFIG_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
+obj-$(CONFIG_EFI_BOOTMGR) += bootmeth_efi_mgr.o
 obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 189ea6003293..897e99ae68de 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -374,7 +374,7 @@ config CMD_BOOTEFI_BINARY
 
 config CMD_BOOTEFI_BOOTMGR
bool "UEFI Boot Manager command"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BOOTMGR
default y
help
  Select this option to enable the 'bootmgr' subcommand of 'bootefi'.
@@ -2124,7 +2124,7 @@ config CMD_EFIDEBUG
 config CMD_EFICONFIG
bool "eficonfig - provide menu-driven uefi variables maintenance 
interface"
default y if !HAS_BOARD_SIZE_LIMIT
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BOOTMGR
select MENU
help
  Enable the 'eficonfig' command which provides the menu-driven UEFI
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index e10fbf891a42..b4954258eeba 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -1410,7 +1410,7 @@ static __maybe_unused int do_efi_test_bootmgr(struct 
cmd_tbl *cmdtp, int flag,
 }
 
 static struct cmd_tbl cmd_efidebug_test_sub[] = {
-#ifdef CONFIG_BOOTEFI_BOOTMGR
+#ifdef CONFIG_EFI_BOOTMGR
U_BOOT_CMD_MKENT(bootmgr, CONFIG_SYS_MAXARGS, 1, do_efi_test_bootmgr,
 "", ""),
 #endif
@@ -1604,7 +1604,7 @@ U_BOOT_LONGHELP(efidebug,
"  - show UEFI memory map\n"
"efidebug tables\n"
"  - show UEFI configuration tables\n"
-#ifdef CONFIG_BOOTEFI_BOOTMGR
+#ifdef CONFIG_EFI_BOOTMGR
"efidebug test bootmgr\n"
"  - run simple bootmgr for test\n"
 #endif
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index ddb1a012a761..61e056dedb5b 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -41,7 +41,7 @@ config EFI_BINARY_EXEC
  You may enable CMD_BOOTEFI_BINARY so that you can use bootefi
  command to do that.
 
-config BOOTEFI_BOOTMGR
+config EFI_BOOTMGR
bool "UEFI Boot Manager"
default y
select BOOTMETH_GLOBAL if BOOTSTD
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index 0a2cb6e3c476..f882474bba6f 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -42,7 +42,7 @@ targets += initrddump.o
 endif
 
 obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
-obj-$(CONFIG_BOOTEFI_BOOTMGR) += efi_bootmgr.o
+obj-$(CONFIG_EFI_BOOTMGR) += efi_bootmgr.o
 obj-y += efi_boottime.o
 obj-y += efi_helper.o
 obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index fa1bebdd02da..b670dfd5e5b5 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -374,7 +374,7 @@ static int bootflow_system(struct unit_test_state *uts)
 {
struct udevice *bootstd, *dev;
 
-   if (!IS_ENABLED(CONFIG_BOOTEFI_BOOTMGR))
+   if (!IS_ENABLED(CONFIG_EFI_BOOTMGR))
return -EAGAIN;
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, ));
ut_assertok(device_bind(bootstd, DM_DRIVER_GET(bootmeth_efi_mgr),
-- 
2.34.1



[PATCH v2 12/12] fs: remove explicit efi configuration dependency

2023-11-20 Thread AKASHI Takahiro
Now it is clear that the feature actually depends on efi interfaces,
not "bootefi" command. efi_set_bootdev() will automatically be nullified
if necessary efi component is disabled.

Signed-off-by: AKASHI Takahiro 
---
 fs/fs.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index 4cb4310c9cc2..70cdb594c4c8 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -791,10 +791,9 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[],
return 1;
}
 
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
-   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
-   (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
-   len_read);
+   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
+   (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
+   len_read);
 
printf("%llu bytes read in %lu ms", len_read, time);
if (time > 0) {
-- 
2.34.1



[PATCH v2 08/12] bootmeth: use efi_loader interfaces instead of bootefi command

2023-11-20 Thread AKASHI Takahiro
Now that efi_loader subsystem provides interfaces that are equivalent
with bootefi command, we can replace command invocations with APIs.

Signed-off-by: AKASHI Takahiro 
---
 boot/Kconfig|  4 ++--
 boot/Makefile   |  2 +-
 boot/bootm_os.c | 31 +++
 boot/bootmeth_efi.c |  8 +---
 boot/bootmeth_efi_mgr.c |  2 +-
 cmd/Kconfig |  2 +-
 test/boot/bootflow.c|  2 +-
 7 files changed, 14 insertions(+), 37 deletions(-)

diff --git a/boot/Kconfig b/boot/Kconfig
index ef71883a5026..e879c63b84e3 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -511,7 +511,7 @@ config BOOTMETH_EXTLINUX_PXE
 
 config BOOTMETH_EFILOADER
bool "Bootdev support for EFI boot"
-   depends on CMD_BOOTEFI
+   depends on BOOTEFI_BOOTMGR
default y
help
  Enables support for EFI boot using bootdevs. This makes the
@@ -546,7 +546,7 @@ config BOOTMETH_DISTRO
select BOOTMETH_SCRIPT if CMDLINE # E.g. Armbian uses scripts
select BOOTMETH_EXTLINUX  # E.g. Debian uses these
select BOOTMETH_EXTLINUX_PXE if CMD_PXE && CMD_NET && DM_ETH
-   select BOOTMETH_EFILOADER if CMD_BOOTEFI # E.g. Ubuntu uses this
+   select BOOTMETH_EFILOADER if BOOTEFI_BOOTMGR # E.g. Ubuntu uses this
 
 config SPL_BOOTMETH_VBE
bool "Bootdev support for Verified Boot for Embedded (SPL)"
diff --git a/boot/Makefile b/boot/Makefile
index 3fd048bb41ab..4eaa5eab4b77 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -32,7 +32,7 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_CROS) += bootm.o bootm_os.o 
bootmeth_cros.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SCRIPT) += bootmeth_script.o
 ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL
-obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
+obj-$(CONFIG_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
 obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o
diff --git a/boot/bootm_os.c b/boot/bootm_os.c
index 30296eb27d7d..c2f39cdf3f36 100644
--- a/boot/bootm_os.c
+++ b/boot/bootm_os.c
@@ -487,7 +487,6 @@ static int do_bootm_efi(int flag, int argc, char *const 
argv[],
struct bootm_headers *images)
 {
int ret;
-   efi_status_t efi_ret;
void *image_buf;
 
if (flag != BOOTM_STATE_OS_GO)
@@ -498,37 +497,21 @@ static int do_bootm_efi(int flag, int argc, char *const 
argv[],
if (ret)
return ret;
 
-   /* Initialize EFI drivers */
-   efi_ret = efi_init_obj_list();
-   if (efi_ret != EFI_SUCCESS) {
-   printf("## Failed to initialize UEFI sub-system: r = %lu\n",
-  efi_ret & ~EFI_ERROR_MASK);
-   return 1;
-   }
+   /* We expect to return */
+   images->os.type = IH_TYPE_STANDALONE;
 
-   /* Install device tree */
-   efi_ret = efi_install_fdt(images->ft_len
- ? images->ft_addr : EFI_FDT_USE_INTERNAL);
-   if (efi_ret != EFI_SUCCESS) {
-   printf("## Failed to install device tree: r = %lu\n",
-  efi_ret & ~EFI_ERROR_MASK);
-   return 1;
-   }
+   image_buf = map_sysmem(images->ep, images->os.image_len);
 
/* Run EFI image */
printf("## Transferring control to EFI (at address %08lx) ...\n",
   images->ep);
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
 
-   /* We expect to return */
-   images->os.type = IH_TYPE_STANDALONE;
-
-   image_buf = map_sysmem(images->ep, images->os.image_len);
+   ret = efi_binary_run(image_buf, images->os.image_len,
+images->ft_len
+? images->ft_addr : EFI_FDT_USE_INTERNAL);
 
-   efi_ret = efi_run_image(image_buf, images->os.image_len);
-   if (efi_ret != EFI_SUCCESS)
-   return 1;
-   return 0;
+   return ret;
 }
 #endif
 
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index ae936c8daa18..2a9f29f9db5a 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -412,7 +412,6 @@ static int distro_efi_read_bootflow(struct udevice *dev, 
struct bootflow *bflow)
 static int distro_efi_boot(struct udevice *dev, struct bootflow *bflow)
 {
ulong kernel, fdt;
-   char cmd[50];
int ret;
 
kernel = env_get_hex("kernel_addr_r", 0);
@@ -441,12 +440,7 @@ static int distro_efi_boot(struct udevice *dev, struct 
bootflow *bflow)
fdt = env_get_hex("fdt_addr_r", 0);
}
 
-   /*
-* At some point we can add a real interface to bootefi so we can call
-* this directly. For now, go through the CLI, like distro boot.
-*/
-   snprintf(cmd, sizeof(cmd), "bootefi %lx %lx", 

[PATCH v2 04/12] cmd: bootefi: carve out binary execution interface

2023-11-20 Thread AKASHI Takahiro
Carve binary execution code out of do_bootefi_image() in order to move
binary-execution specific code into library directory in the later
commit.

Signed-off-by: AKASHI Takahiro 
---
 cmd/bootefi.c | 46 --
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 87910c42333a..957e2618aca2 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -515,6 +515,36 @@ out:
return (ret != EFI_SUCCESS) ? ret : ret2;
 }
 
+/**
+ * efi_binary_run() - run loaded UEFI image
+ *
+ * @image: memory address of the UEFI image
+ * @size:  size of the UEFI image
+ *
+ * Execute an EFI binary image loaded at @image.
+ * @size may be zero if the binary is loaded with U-Boot load command.
+ *
+ * Return: status code
+ */
+static efi_status_t efi_binary_run(void *image, size_t size, void *fdt)
+{
+   efi_status_t ret;
+
+   /* Initialize EFI drivers */
+   ret = efi_init_obj_list();
+   if (ret != EFI_SUCCESS) {
+   log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
+   ret & ~EFI_ERROR_MASK);
+   return ret;
+   }
+
+   ret = efi_install_fdt(fdt);
+   if (ret != EFI_SUCCESS)
+   return ret;
+
+   return efi_run_image(image, size);
+}
+
 static efi_status_t bootefi_run_prepare(const char *load_options_path,
struct efi_device_path *device_path,
struct efi_device_path *image_path,
@@ -696,23 +726,11 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
int argc,
}
}
 
-   /* Initialize EFI drivers */
-   ret = efi_init_obj_list();
-   if (ret != EFI_SUCCESS) {
-   log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
-   ret & ~EFI_ERROR_MASK);
-   return CMD_RET_FAILURE;
-   }
+   ret = efi_binary_run(image_buf, size, fdt);
 
-   ret = efi_install_fdt(fdt);
if (ret == EFI_INVALID_PARAMETER)
return CMD_RET_USAGE;
-   else if (ret != EFI_SUCCESS)
-   return CMD_RET_FAILURE;
-
-   ret = efi_run_image(image_buf, size);
-
-   if (ret != EFI_SUCCESS)
+   else if (ret)
return CMD_RET_FAILURE;
 
return CMD_RET_SUCCESS;
-- 
2.34.1



[PATCH v2 07/12] cmd: efidebug: ease efi configuration dependency

2023-11-20 Thread AKASHI Takahiro
Now it is clear that the command actually depends on interfaces,
not "bootefi bootmgr" command.

Signed-off-by: AKASHI Takahiro 
---
 cmd/efidebug.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 78ef16f4cb5c..e10fbf891a42 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -1410,7 +1410,7 @@ static __maybe_unused int do_efi_test_bootmgr(struct 
cmd_tbl *cmdtp, int flag,
 }
 
 static struct cmd_tbl cmd_efidebug_test_sub[] = {
-#ifdef CONFIG_CMD_BOOTEFI_BOOTMGR
+#ifdef CONFIG_BOOTEFI_BOOTMGR
U_BOOT_CMD_MKENT(bootmgr, CONFIG_SYS_MAXARGS, 1, do_efi_test_bootmgr,
 "", ""),
 #endif
@@ -1604,7 +1604,7 @@ U_BOOT_LONGHELP(efidebug,
"  - show UEFI memory map\n"
"efidebug tables\n"
"  - show UEFI configuration tables\n"
-#ifdef CONFIG_CMD_BOOTEFI_BOOTMGR
+#ifdef CONFIG_BOOTEFI_BOOTMGR
"efidebug test bootmgr\n"
"  - run simple bootmgr for test\n"
 #endif
-- 
2.34.1



[PATCH v2 06/12] cmd: bootefi: move library interfaces under lib/efi_loader

2023-11-20 Thread AKASHI Takahiro
In the prior commits, interfaces for executing EFI binary and boot manager
were carved out. Move them under efi_loader directory so that they can
be called from other places without depending on bootefi command.

Only efi_selftest-related code will be left in bootefi.c.

Signed-off-by: AKASHI Takahiro 
---
 cmd/bootefi.c| 539 +--
 include/efi_loader.h |  10 +
 lib/efi_loader/efi_bootmgr.c | 529 ++
 3 files changed, 550 insertions(+), 528 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 7930c99def44..9cf9027bf409 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -7,545 +7,22 @@
 
 #define LOG_CATEGORY LOGC_EFI
 
-#include 
-#include 
-#include 
 #include 
-#include 
+#include 
 #include 
-#include 
-#include 
-#include 
-#include 
+#include 
 #include 
 #include 
-#include 
-#include 
-#include 
 #include 
-#include 
+#include 
 #include 
-#include 
+#include 
+#include 
 
 DECLARE_GLOBAL_DATA_PTR;
 
 static struct efi_device_path *test_image_path;
 static struct efi_device_path *test_device_path;
-static struct efi_device_path *bootefi_image_path;
-static struct efi_device_path *bootefi_device_path;
-static void *image_addr;
-static size_t image_size;
-
-/**
- * efi_get_image_parameters() - return image parameters
- *
- * @img_addr:  address of loaded image in memory
- * @img_size:  size of loaded image
- */
-void efi_get_image_parameters(void **img_addr, size_t *img_size)
-{
-   *img_addr = image_addr;
-   *img_size = image_size;
-}
-
-/**
- * efi_clear_bootdev() - clear boot device
- */
-static void efi_clear_bootdev(void)
-{
-   efi_free_pool(bootefi_device_path);
-   efi_free_pool(bootefi_image_path);
-   bootefi_device_path = NULL;
-   bootefi_image_path = NULL;
-   image_addr = NULL;
-   image_size = 0;
-}
-
-/**
- * efi_set_bootdev() - set boot device
- *
- * This function is called when a file is loaded, e.g. via the 'load' command.
- * We use the path to this file to inform the UEFI binary about the boot 
device.
- *
- * @dev:   device, e.g. "MMC"
- * @devnr: number of the device, e.g. "1:2"
- * @path:  path to file loaded
- * @buffer:buffer with file loaded
- * @buffer_size:   size of file loaded
- */
-void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
-void *buffer, size_t buffer_size)
-{
-   struct efi_device_path *device, *image;
-   efi_status_t ret;
-
-   log_debug("dev=%s, devnr=%s, path=%s, buffer=%p, size=%zx\n", dev,
- devnr, path, buffer, buffer_size);
-
-   /* Forget overwritten image */
-   if (buffer + buffer_size >= image_addr &&
-   image_addr + image_size >= buffer)
-   efi_clear_bootdev();
-
-   /* Remember only PE-COFF and FIT images */
-   if (efi_check_pe(buffer, buffer_size, NULL) != EFI_SUCCESS) {
-   if (IS_ENABLED(CONFIG_FIT) &&
-   !fit_check_format(buffer, IMAGE_SIZE_INVAL)) {
-   /*
-* FIT images of type EFI_OS are started via command
-* bootm. We should not use their boot device with the
-* bootefi command.
-*/
-   buffer = 0;
-   buffer_size = 0;
-   } else {
-   log_debug("- not remembering image\n");
-   return;
-   }
-   }
-
-   /* efi_set_bootdev() is typically called repeatedly, recover memory */
-   efi_clear_bootdev();
-
-   image_addr = buffer;
-   image_size = buffer_size;
-
-   ret = efi_dp_from_name(dev, devnr, path, , );
-   if (ret == EFI_SUCCESS) {
-   bootefi_device_path = device;
-   if (image) {
-   /* FIXME: image should not contain device */
-   struct efi_device_path *image_tmp = image;
-
-   efi_dp_split_file_path(image, , );
-   efi_free_pool(image_tmp);
-   }
-   bootefi_image_path = image;
-   log_debug("- boot device %pD\n", device);
-   if (image)
-   log_debug("- image %pD\n", image);
-   } else {
-   log_debug("- efi_dp_from_name() failed, err=%lx\n", ret);
-   efi_clear_bootdev();
-   }
-}
-
-/**
- * efi_env_set_load_options() - set load options from environment variable
- *
- * @handle:the image handle
- * @env_var:   name of the environment variable
- * @load_options:  pointer to load options (output)
- * Return: status code
- */
-static efi_status_t efi_env_set_load_options(efi_handle_t handle,
-

[PATCH v2 05/12] cmd: bootefi: localize global device paths for efi_selftest

2023-11-20 Thread AKASHI Takahiro
Device paths allocated in bootefi_test_prepare() will be immediately
consumed by do_efi_selftest() and there is no need to keep them for later
use. Introduce test-specific varialbles to make it easier to move other
bootmgr functions into library directory in the next commit.

Signed-off-by: AKASHI Takahiro 
---
 cmd/bootefi.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 957e2618aca2..7930c99def44 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -29,6 +29,8 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static struct efi_device_path *test_image_path;
+static struct efi_device_path *test_device_path;
 static struct efi_device_path *bootefi_image_path;
 static struct efi_device_path *bootefi_device_path;
 static void *image_addr;
@@ -586,23 +588,26 @@ static efi_status_t bootefi_test_prepare
efi_status_t ret;
 
/* Construct a dummy device path */
-   bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, 0, 0);
-   if (!bootefi_device_path)
+   test_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, 0, 0);
+   if (!test_device_path)
return EFI_OUT_OF_RESOURCES;
 
-   bootefi_image_path = efi_dp_from_file(NULL, path);
-   if (!bootefi_image_path) {
+   test_image_path = efi_dp_from_file(NULL, path);
+   if (!test_image_path) {
ret = EFI_OUT_OF_RESOURCES;
goto failure;
}
 
-   ret = bootefi_run_prepare(load_options_path, bootefi_device_path,
- bootefi_image_path, image_objp,
+   ret = bootefi_run_prepare(load_options_path, test_device_path,
+ test_image_path, image_objp,
  loaded_image_infop);
if (ret == EFI_SUCCESS)
return ret;
 
 failure:
+   efi_free_pool(test_device_path);
+   efi_free_pool(test_image_path);
+   /* TODO: not sure calling clear function is necessary */
efi_clear_bootdev();
return ret;
 }
@@ -627,6 +632,8 @@ static int do_efi_selftest(void)
ret = EFI_CALL(efi_selftest(_obj->header, ));
efi_restore_gd();
free(loaded_image_info->load_options);
+   efi_free_pool(test_device_path);
+   efi_free_pool(test_image_path);
if (ret != EFI_SUCCESS)
efi_delete_handle(_obj->header);
else
-- 
2.34.1



[PATCH v2 03/12] cmd: bootefi: carve out EFI boot manager interface

2023-11-20 Thread AKASHI Takahiro
Carve EFI boot manager related code out of do_bootefi_image() in order
to move boot manager specific code into library directory in the later
commit.

Signed-off-by: AKASHI Takahiro 
---
 cmd/bootefi.c | 43 ---
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index e9e5ab67a1f5..87910c42333a 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -413,28 +413,40 @@ out:
 }
 
 /**
- * do_efibootmgr() - execute EFI boot manager
+ * efi_bootmgr_run() - execute EFI boot manager
+ * fdt:Flat device tree
+ *
+ * Invoke EFI boot manager and execute a binary depending on
+ * boot options. If @fdt is not NULL, it will be passed to
+ * the executed binary.
  *
  * Return: status code
  */
-static int do_efibootmgr(void)
+static efi_status_t efi_bootmgr_run(void *fdt)
 {
efi_handle_t handle;
-   efi_status_t ret;
void *load_options;
+   efi_status_t ret;
 
-   ret = efi_bootmgr_load(, _options);
+   /* Initialize EFI drivers */
+   ret = efi_init_obj_list();
if (ret != EFI_SUCCESS) {
-   log_notice("EFI boot manager: Cannot load any image\n");
+   log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
+   ret & ~EFI_ERROR_MASK);
return CMD_RET_FAILURE;
}
 
-   ret = do_bootefi_exec(handle, load_options);
-
+   ret = efi_install_fdt(fdt);
if (ret != EFI_SUCCESS)
-   return CMD_RET_FAILURE;
+   return ret;
 
-   return CMD_RET_SUCCESS;
+   ret = efi_bootmgr_load(, _options);
+   if (ret != EFI_SUCCESS) {
+   log_notice("EFI boot manager: Cannot load any image\n");
+   return ret;
+   }
+
+   return do_bootefi_exec(handle, load_options);
 }
 
 /**
@@ -624,21 +636,14 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
int argc,
 
if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR) &&
!strcmp(argv[1], "bootmgr")) {
-   /* Initialize EFI drivers */
-   ret = efi_init_obj_list();
-   if (ret != EFI_SUCCESS) {
-   log_err("Error: Cannot initialize UEFI sub-system, r = 
%lu\n",
-   ret & ~EFI_ERROR_MASK);
-   return CMD_RET_FAILURE;
-   }
+   ret = efi_bootmgr_run(fdt);
 
-   ret = efi_install_fdt(fdt);
if (ret == EFI_INVALID_PARAMETER)
return CMD_RET_USAGE;
-   else if (ret != EFI_SUCCESS)
+   else if (ret)
return CMD_RET_FAILURE;
 
-   return do_efibootmgr();
+   return CMD_RET_SUCCESS;
}
 
if (IS_ENABLED(CONFIG_CMD_BOOTEFI_SELFTEST) &&
-- 
2.34.1



[PATCH v2 02/12] cmd: bootefi: re-organize do_bootefi()

2023-11-20 Thread AKASHI Takahiro
Replicate some code and re-organize do_bootefi() into three cases, which
will be carved out as independent functions in the next two commits.

Signed-off-by: AKASHI Takahiro 
---
 cmd/Kconfig  | 15 ++--
 cmd/bootefi.c| 82 ++--
 include/efi_loader.h |  2 --
 3 files changed, 69 insertions(+), 30 deletions(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 6f636155e5b6..4cf9a210c4a1 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -362,9 +362,19 @@ config CMD_BOOTEFI
help
  Boot an EFI image from memory.
 
+if CMD_BOOTEFI
+config CMD_BOOTEFI_BINARY
+   bool "Allow booting an EFI binary directly"
+   depends on BOOTEFI_BOOTMGR
+   default y
+   help
+ Select this option to enable direct execution of binary at 'bootefi'.
+ This subcommand will allow you to load the UEFI binary using
+ other U-Boot commands or external methods and then run it.
+
 config CMD_BOOTEFI_BOOTMGR
bool "UEFI Boot Manager command"
-   depends on BOOTEFI_BOOTMGR && CMD_BOOTEFI
+   depends on BOOTEFI_BOOTMGR
default y
help
  Select this option to enable the 'bootmgr' subcommand of 'bootefi'.
@@ -373,7 +383,7 @@ config CMD_BOOTEFI_BOOTMGR
 
 config CMD_BOOTEFI_HELLO_COMPILE
bool "Compile a standard EFI hello world binary for testing"
-   depends on CMD_BOOTEFI && !CPU_V7M
+   depends on !CPU_V7M
default y
help
  This compiles a standard EFI hello world application with U-Boot so
@@ -395,6 +405,7 @@ config CMD_BOOTEFI_HELLO
  up EFI support on a new architecture.
 
 source lib/efi_selftest/Kconfig
+endif
 
 config CMD_BOOTMENU
bool "bootmenu"
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 190ccba260e0..e9e5ab67a1f5 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -503,7 +503,6 @@ out:
return (ret != EFI_SUCCESS) ? ret : ret2;
 }
 
-#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
 static efi_status_t bootefi_run_prepare(const char *load_options_path,
struct efi_device_path *device_path,
struct efi_device_path *image_path,
@@ -593,7 +592,6 @@ static int do_efi_selftest(void)
 
return ret != EFI_SUCCESS;
 }
-#endif /* CONFIG_CMD_BOOTEFI_SELFTEST */
 
 /**
  * do_bootefi() - execute `bootefi` command
@@ -615,14 +613,6 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int 
argc,
if (argc < 2)
return CMD_RET_USAGE;
 
-   /* Initialize EFI drivers */
-   ret = efi_init_obj_list();
-   if (ret != EFI_SUCCESS) {
-   log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
-   ret & ~EFI_ERROR_MASK);
-   return CMD_RET_FAILURE;
-   }
-
if (argc > 2) {
uintptr_t fdt_addr;
 
@@ -631,29 +621,54 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
int argc,
} else {
fdt = EFI_FDT_USE_INTERNAL;
}
-   ret = efi_install_fdt(fdt);
-   if (ret == EFI_INVALID_PARAMETER)
-   return CMD_RET_USAGE;
-   else if (ret != EFI_SUCCESS)
-   return CMD_RET_FAILURE;
 
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
-   if (!strcmp(argv[1], "bootmgr"))
-   return do_efibootmgr();
+   if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR) &&
+   !strcmp(argv[1], "bootmgr")) {
+   /* Initialize EFI drivers */
+   ret = efi_init_obj_list();
+   if (ret != EFI_SUCCESS) {
+   log_err("Error: Cannot initialize UEFI sub-system, r = 
%lu\n",
+   ret & ~EFI_ERROR_MASK);
+   return CMD_RET_FAILURE;
+   }
+
+   ret = efi_install_fdt(fdt);
+   if (ret == EFI_INVALID_PARAMETER)
+   return CMD_RET_USAGE;
+   else if (ret != EFI_SUCCESS)
+   return CMD_RET_FAILURE;
+
+   return do_efibootmgr();
}
-#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
-   if (!strcmp(argv[1], "selftest"))
+
+   if (IS_ENABLED(CONFIG_CMD_BOOTEFI_SELFTEST) &&
+   !strcmp(argv[1], "selftest")) {
+   /* Initialize EFI drivers */
+   ret = efi_init_obj_list();
+   if (ret != EFI_SUCCESS) {
+   log_err("Error: Cannot initialize UEFI sub-system, r = 
%lu\n",
+   ret & ~EFI_ERROR_MASK);
+   return CMD_RET_FAILURE;
+   }
+
+   ret = efi_install_fdt(fdt);
+   if (ret == EFI_INVALID_PARAMETER)
+   return CMD_RET_USAGE;
+   else if (ret != EFI_SUCCESS)
+   return CMD_RET_FAILURE;
+

[PATCH v2 01/12] cmd: bootefi: unfold do_bootefi_image()

2023-11-20 Thread AKASHI Takahiro
Unfold do_bootefi_image() into do_bootefi() in order to make it easier
to re-organize do_bootefi() in the next commit.

Signed-off-by: AKASHI Takahiro 
---
 cmd/bootefi.c | 101 ++
 1 file changed, 37 insertions(+), 64 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 4d74969ad621..190ccba260e0 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -437,58 +437,6 @@ static int do_efibootmgr(void)
return CMD_RET_SUCCESS;
 }
 
-/**
- * do_bootefi_image() - execute EFI binary
- *
- * Set up memory image for the binary to be loaded, prepare device path, and
- * then call do_bootefi_exec() to execute it.
- *
- * @image_opt: string with image start address
- * @size_opt:  string with image size or NULL
- * Return: status code
- */
-static int do_bootefi_image(const char *image_opt, const char *size_opt)
-{
-   void *image_buf;
-   unsigned long addr, size;
-   efi_status_t ret;
-
-#ifdef CONFIG_CMD_BOOTEFI_HELLO
-   if (!strcmp(image_opt, "hello")) {
-   image_buf = __efi_helloworld_begin;
-   size = __efi_helloworld_end - __efi_helloworld_begin;
-   efi_clear_bootdev();
-   } else
-#endif
-   {
-   addr = strtoul(image_opt, NULL, 16);
-   /* Check that a numeric value was passed */
-   if (!addr)
-   return CMD_RET_USAGE;
-   image_buf = map_sysmem(addr, 0);
-
-   if (size_opt) {
-   size = strtoul(size_opt, NULL, 16);
-   if (!size)
-   return CMD_RET_USAGE;
-   efi_clear_bootdev();
-   } else {
-   if (image_buf != image_addr) {
-   log_err("No UEFI binary known at %s\n",
-   image_opt);
-   return CMD_RET_FAILURE;
-   }
-   size = image_size;
-   }
-   }
-   ret = efi_run_image(image_buf, size);
-
-   if (ret != EFI_SUCCESS)
-   return CMD_RET_FAILURE;
-
-   return CMD_RET_SUCCESS;
-}
-
 /**
  * efi_run_image() - run loaded UEFI image
  *
@@ -660,8 +608,9 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int 
argc,
  char *const argv[])
 {
efi_status_t ret;
-   char *img_addr, *img_size, *str_copy, *pos;
-   void *fdt;
+   char *p;
+   void *fdt, *image_buf;
+   unsigned long addr, size;
 
if (argc < 2)
return CMD_RET_USAGE;
@@ -696,18 +645,42 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
int argc,
if (!strcmp(argv[1], "selftest"))
return do_efi_selftest();
 #endif
-   str_copy = strdup(argv[1]);
-   if (!str_copy) {
-   log_err("Out of memory\n");
-   return CMD_RET_FAILURE;
+
+#ifdef CONFIG_CMD_BOOTEFI_HELLO
+   if (!strcmp(argv[1], "hello")) {
+   image_buf = __efi_helloworld_begin;
+   size = __efi_helloworld_end - __efi_helloworld_begin;
+   efi_clear_bootdev();
+   } else
+#endif
+   {
+   addr = strtoul(argv[1], NULL, 16);
+   /* Check that a numeric value was passed */
+   if (!addr)
+   return CMD_RET_USAGE;
+   image_buf = map_sysmem(addr, 0);
+
+   p  = strchr(argv[1], ':');
+   if (p) {
+   size = strtoul(++p, NULL, 16);
+   if (!size)
+   return CMD_RET_USAGE;
+   efi_clear_bootdev();
+   } else {
+   if (image_buf != image_addr) {
+   log_err("No UEFI binary known at %s\n",
+   argv[1]);
+   return CMD_RET_FAILURE;
+   }
+   size = image_size;
+   }
}
-   pos = str_copy;
-   img_addr = strsep(, ":");
-   img_size = strsep(, ":");
-   ret = do_bootefi_image(img_addr, img_size);
-   free(str_copy);
+   ret = efi_run_image(image_buf, size);
 
-   return ret;
+   if (ret != EFI_SUCCESS)
+   return CMD_RET_FAILURE;
+
+   return CMD_RET_SUCCESS;
 }
 
 U_BOOT_LONGHELP(bootefi,
-- 
2.34.1



[PATCH v2 00/12] cmd: bootefi: refactor the code for bootmgr

2023-11-20 Thread AKASHI Takahiro
This patch set is motivated by the discussion[1] regarding
CONFIG_BOOTEFI_BOOTMGR option.

At the end, bootefi.c will be decomposed into two parts, one for
providing the command itself and one for implementing helper functions.
EFI_LOADER will now be available without CONFIG_CMDLINE or specifically
CONFIG_CMD_BOOTEFI if invoked via bootmeth/bootstd.

Then, EFI_LOADER library side will be further split into two options
for fine-grain control:
CONFIG_EFI_BINARY_EXEC: execute UEFI binaries which are to be explicitly
loaded by U-Boot's load commands/functions or other methods
(like a jtag debugger?)
It supports bootmeth_efi as well as "bootefi |hello"(/"bootm"?).

CONFIG_EFI_BOOTMGR: provide EFI boot manger functionality
It supports bootmeth_efi_mgr as well as "bootefi bootmgr".

As such, We will no longer need CONFIG_EFI_BINARY_EXEC if we want to only
make use of the UEFI boot manger for booting a next stage OS.

Prerequisite

This patch set is based on top of Tom's "next" branch.

Patches
===
Patch#1-#12: I hope that those commits show step-by-step refactoring
without introducing degradation.

Tests
=
* run UT efi_selftest on sandbox locally
* run test_efi_bootmgr on sandbox locally

Unfortunately, I could not submit a pull request for CI test.

Changes
===
v2 (Nov 21, 2023)
* rebased onto Tom's next branch
* remove already merged commits
* revise commit messages
* add patch #5 which was split from ex-patch#5
RFC (Oct 26, 2023)

[1] https://lists.denx.de/pipermail/u-boot/2023-October/534598.html

AKASHI Takahiro (12):
  cmd: bootefi: unfold do_bootefi_image()
  cmd: bootefi: re-organize do_bootefi()
  cmd: bootefi: carve out EFI boot manager interface
  cmd: bootefi: carve out binary execution interface
  cmd: bootefi: localize global device paths for efi_selftest
  cmd: bootefi: move library interfaces under lib/efi_loader
  cmd: efidebug: ease efi configuration dependency
  bootmeth: use efi_loader interfaces instead of bootefi command
  efi_loader: split unrelated code from efi_bootmgr.c
  efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR
  net: tftp: remove explicit efi configuration dependency
  fs: remove explicit efi configuration dependency

 boot/Kconfig |   4 +-
 boot/Makefile|   2 +-
 boot/bootm_os.c  |  31 +-
 boot/bootmeth_efi.c  |   8 +-
 boot/bootmeth_efi_mgr.c  |   2 +-
 cmd/Kconfig  |  21 +-
 cmd/bootefi.c| 670 +--
 cmd/efidebug.c   |   4 +-
 fs/fs.c  |   7 +-
 include/efi_loader.h |  34 +-
 lib/efi_loader/Kconfig   |  11 +-
 lib/efi_loader/Makefile  |   2 +-
 lib/efi_loader/efi_bootmgr.c |  37 ++
 lib/efi_loader/efi_device_path.c |   3 +-
 lib/efi_loader/efi_helper.c  | 498 ++-
 net/tftp.c   |  10 +-
 test/boot/bootflow.c |   2 +-
 17 files changed, 700 insertions(+), 646 deletions(-)

-- 
2.34.1



[PATCH] xen: pvblock: fix the maximum io size in one operation

2023-11-14 Thread AKASHI Takahiro
The current implementation may cause BUG_ON() in blkfront_aio()
BUG_ON(n > BLKIF_MAX_SEGMENTS_PER_REQUEST);

In pvblock_iop(), a read/write operation will be split into smaller
chunks of data so that the size in one access (aio_nbytes) is limited
to, at the maximum,
BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE

But this works only if when the *buffer* passed in to pvblock_io()
is page-aligned. If not, the given data region may stand across
(BLKIF_MAX_SEGMENTS_PER_REQUEST + 1) pages. See the logic in
blkfront_aio():
start = (uintptr_t)aiocbp->aio_buf & PAGE_MASK;
end = ((uintptr_t)aiocbp->aio_buf + aiocbp->aio_nbytes +
   PAGE_SIZE - 1) & PAGE_MASK;
Then this will lead to BUG_ON() above.

This can be fixed by decreasing the maximum size of aio_nbytes.

Signed-off-by: AKASHI Takahiro 
Fixes: commit 3a739cc6c948 ("xen: pvblock: Implement front-back protocol and do 
IO")
---
 drivers/xen/pvblock.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/xen/pvblock.c b/drivers/xen/pvblock.c
index 4ad548d599d5..1df04e239ad0 100644
--- a/drivers/xen/pvblock.c
+++ b/drivers/xen/pvblock.c
@@ -632,7 +632,8 @@ static ulong pvblock_iop(struct udevice *udev, lbaint_t 
blknr,
memcpy(blk_dev->bounce_buffer, buffer, desc->blksz);
 
aiocb.aio_nbytes = unaligned ? desc->blksz :
-   min((size_t)(BLKIF_MAX_SEGMENTS_PER_REQUEST * 
PAGE_SIZE),
+   min((size_t)((BLKIF_MAX_SEGMENTS_PER_REQUEST - 1)
+   * PAGE_SIZE),
(size_t)(blocks_todo * desc->blksz));
 
blkfront_io(, write);
-- 
2.34.1



[PATCH v3 5/5] test: dm: add scmi command test

2023-11-13 Thread AKASHI Takahiro
In this test, "scmi" command is tested against different sub-commands.
Please note that scmi command is for debug purpose and is not intended
in production system.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
Reviewed-by: Etienne Carriere 
---
v9
* return -EAGAIN if we want to skip a test
* use CONFIG_IS_ENABLED() rather than IS_ENABLED()
v7
* make test assertions more flexible depending on the number of provided
  protocols
v4
* move 'base'-related changes to the prior commit
* add CONFIG_CMD_SCMI to sandbox_defconfig
v3
* change char to u8 in vendor/agent names
v2
* use helper functions, removing direct uses of ops
---
 configs/sandbox_defconfig |  1 +
 test/dm/scmi.c| 81 +++
 2 files changed, 82 insertions(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index bc5bcb2a6237..c550af93b0ca 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -121,6 +121,7 @@ CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_AES=y
 CONFIG_CMD_TPM=y
 CONFIG_CMD_TPM_TEST=y
+CONFIG_CMD_SCMI=y
 CONFIG_CMD_BTRFS=y
 CONFIG_CMD_CBFS=y
 CONFIG_CMD_CRAMFS=y
diff --git a/test/dm/scmi.c b/test/dm/scmi.c
index 582485471fff..e80667ef72a3 100644
--- a/test/dm/scmi.c
+++ b/test/dm/scmi.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -206,6 +207,86 @@ static int dm_test_scmi_base(struct unit_test_state *uts)
 
 DM_TEST(dm_test_scmi_base, UT_TESTF_SCAN_FDT);
 
+static int dm_test_scmi_cmd(struct unit_test_state *uts)
+{
+   struct udevice *agent_dev;
+   int num_proto = 0;
+   char cmd_out[30];
+
+   if (!CONFIG_IS_ENABLED(CMD_SCMI))
+   return -EAGAIN;
+
+   /* preparation */
+   ut_assertok(uclass_get_device_by_name(UCLASS_SCMI_AGENT, "scmi",
+ _dev));
+   ut_assertnonnull(agent_dev);
+
+   /*
+* Estimate the number of provided protocols.
+* This estimation is correct as far as a corresponding
+* protocol support is added to sandbox fake serer.
+*/
+   if (CONFIG_IS_ENABLED(POWER_DOMAIN))
+   num_proto++;
+   if (CONFIG_IS_ENABLED(CLK_SCMI))
+   num_proto++;
+   if (CONFIG_IS_ENABLED(RESET_SCMI))
+   num_proto++;
+   if (CONFIG_IS_ENABLED(DM_REGULATOR_SCMI))
+   num_proto++;
+
+   /* scmi info */
+   ut_assertok(run_command("scmi info", 0));
+
+   ut_assert_nextline("SCMI device: scmi");
+   snprintf(cmd_out, 30, "  protocol version: 0x%x",
+SCMI_BASE_PROTOCOL_VERSION);
+   ut_assert_nextline(cmd_out);
+   ut_assert_nextline("  # of agents: 2");
+   ut_assert_nextline("  0: platform");
+   ut_assert_nextline("> 1: OSPM");
+   snprintf(cmd_out, 30, "  # of protocols: %d", num_proto);
+   ut_assert_nextline(cmd_out);
+   if (CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN))
+   ut_assert_nextline("  Power domain management");
+   if (CONFIG_IS_ENABLED(CLK_SCMI))
+   ut_assert_nextline("  Clock management");
+   if (CONFIG_IS_ENABLED(RESET_SCMI))
+   ut_assert_nextline("  Reset domain management");
+   if (CONFIG_IS_ENABLED(DM_REGULATOR_SCMI))
+   ut_assert_nextline("  Voltage domain management");
+   ut_assert_nextline("  vendor: U-Boot");
+   ut_assert_nextline("  sub vendor: Sandbox");
+   ut_assert_nextline("  impl version: 0x1");
+
+   ut_assert_console_end();
+
+   /* scmi perm_dev */
+   ut_assertok(run_command("scmi perm_dev 1 0 1", 0));
+   ut_assert_console_end();
+
+   ut_assert(run_command("scmi perm_dev 1 0 0", 0));
+   ut_assert_nextline("Denying access to device:0 failed (-13)");
+   ut_assert_console_end();
+
+   /* scmi perm_proto */
+   ut_assertok(run_command("scmi perm_proto 1 0 14 1", 0));
+   ut_assert_console_end();
+
+   ut_assert(run_command("scmi perm_proto 1 0 14 0", 0));
+   ut_assert_nextline("Denying access to protocol:0x14 on device:0 failed 
(-13)");
+   ut_assert_console_end();
+
+   /* scmi reset */
+   ut_assert(run_command("scmi reset 1 1", 0));
+   ut_assert_nextline("Reset failed (-13)");
+   ut_assert_console_end();
+
+   return 0;
+}
+
+DM_TEST(dm_test_scmi_cmd, UT_TESTF_SCAN_FDT);
+
 static int dm_test_scmi_power_domains(struct unit_test_state *uts)
 {
struct sandbox_scmi_agent *agent;
-- 
2.34.1



[PATCH v3 4/5] doc: cmd: add documentation for scmi

2023-11-13 Thread AKASHI Takahiro
This is a help text for scmi command.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
Reviewed-by: Etienne Carriere 
---
v6
* add the manual to doc/usage/index.rst
v4
* s/tranport/transport/
v2
* add more descriptions about SCMI
---
 doc/usage/cmd/scmi.rst | 126 +
 doc/usage/index.rst|   1 +
 2 files changed, 127 insertions(+)
 create mode 100644 doc/usage/cmd/scmi.rst

diff --git a/doc/usage/cmd/scmi.rst b/doc/usage/cmd/scmi.rst
new file mode 100644
index ..9ea7e0e41dad
--- /dev/null
+++ b/doc/usage/cmd/scmi.rst
@@ -0,0 +1,126 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+scmi command
+
+
+Synopsis
+
+
+::
+
+scmi info
+scmi perm_dev   
+scmi perm_proto
+scmi reset  
+
+Description
+---
+
+Arm System Control and Management Interface (SCMI hereafter) is a set of
+standardised interfaces to manage system resources, like clocks, power
+domains, pin controls, reset and so on, in a system-wide manner.
+
+An entity which provides those services is called a SCMI firmware (or
+SCMI server if you like) may be placed/implemented by EL3 software or
+by a dedicated system control processor (SCP) or else.
+
+A user of SCMI interfaces, including U-Boot, is called a SCMI agent and
+may issues commands, which are defined in each protocol for specific system
+resources, to SCMI server via a communication channel, called a transport.
+Those interfaces are independent from the server's implementation thanks to
+a transport layer.
+
+For more details, see the `SCMI specification`_.
+
+While most of system resources managed under SCMI protocols are implemented
+and handled as standard U-Boot devices, for example clk_scmi, scmi command
+provides additional management functionality against SCMI server.
+
+scmi info
+~
+Show base information about SCMI server and supported protocols
+
+scmi perm_dev
+~
+Allow or deny access permission to the device
+
+scmi perm_proto
+~~~
+Allow or deny access to the protocol on the device
+
+scmi reset
+~~
+Reset the already-configured permissions against the device
+
+Parameters are used as follows:
+
+
+SCMI Agent ID, hex value
+
+
+SCMI Device ID, hex value
+
+Please note that what a device means is not defined
+in the specification.
+
+
+SCMI Protocol ID, hex value
+
+It must not be 0x10 (base protocol)
+
+
+Flags to control the action, hex value
+
+0 to deny, 1 to allow. The other values are reserved and allowed
+values may depend on the implemented version of SCMI server in
+the future. See SCMI specification for more details.
+
+Example
+---
+
+Obtain basic information about SCMI server:
+
+::
+
+=> scmi info
+SCMI device: scmi
+  protocol version: 0x2
+  # of agents: 3
+  0: platform
+> 1: OSPM
+  2: PSCI
+  # of protocols: 4
+  Power domain management
+  Performance domain management
+  Clock management
+  Sensor management
+  vendor: Linaro
+  sub vendor: PMWG
+  impl version: 0x20b
+
+Ask for access permission to device#0:
+
+::
+
+=> scmi perm_dev 1 0 1
+
+Reset configurations with all access permission settings retained:
+
+::
+
+=> scmi reset 1 0
+
+Configuration
+-
+
+The scmi command is only available if CONFIG_CMD_SCMI=y.
+Default n because this command is mainly for debug purpose.
+
+Return value
+
+
+The return value ($?) is set to 0 if the operation succeeded,
+1 if the operation failed or -1 if the operation failed due to
+a syntax error.
+
+.. _`SCMI specification`: 
https://developer.arm.com/documentation/den0056/e/?lang=en
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index d8e23fcacffb..1a626c03c237 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -94,6 +94,7 @@ Shell commands
cmd/rng
cmd/saves
cmd/sbi
+   cmd/scmi
cmd/scp03
cmd/seama
cmd/setexpr
-- 
2.34.1



[PATCH v3 3/5] cmd: add scmi command for SCMI firmware

2023-11-13 Thread AKASHI Takahiro
This command, "scmi", may provide a command line interface to various SCMI
protocols. It supports at least initially SCMI base protocol and is
intended mainly for debug purpose.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
Reviewed-by: Etienne Carriere 
---
v8 (actually v2 as SCMI cmd)
* localize global variables to avoid pytest errors
v3
* describe that arguments are in hex at a help message
* modify the code for dynamically allocated agent names
v2
* remove sub command category, 'scmi base', for simplicity
---
 cmd/Kconfig  |   9 ++
 cmd/Makefile |   1 +
 cmd/scmi.c   | 384 +++
 3 files changed, 394 insertions(+)
 create mode 100644 cmd/scmi.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index df6d71c103f9..ca9f742dcf78 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2559,6 +2559,15 @@ config CMD_CROS_EC
  a number of sub-commands for performing EC tasks such as
  updating its flash, accessing a small saved context area
  and talking to the I2C bus behind the EC (if there is one).
+
+config CMD_SCMI
+   bool "Enable scmi command"
+   depends on SCMI_FIRMWARE
+   default n
+   help
+ This command provides user interfaces to several SCMI (System
+ Control and Management Interface) protocols available on Arm
+ platforms to manage system resources.
 endmenu
 
 menu "Filesystem commands"
diff --git a/cmd/Makefile b/cmd/Makefile
index 9a6790cc1708..320f0b5266eb 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -159,6 +159,7 @@ obj-$(CONFIG_CMD_SATA) += sata.o
 obj-$(CONFIG_CMD_NVME) += nvme.o
 obj-$(CONFIG_SANDBOX) += sb.o
 obj-$(CONFIG_CMD_SF) += sf.o
+obj-$(CONFIG_CMD_SCMI) += scmi.o
 obj-$(CONFIG_CMD_SCSI) += scsi.o disk.o
 obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
 obj-$(CONFIG_CMD_SEAMA) += seama.o
diff --git a/cmd/scmi.c b/cmd/scmi.c
new file mode 100644
index ..664062c4eff5
--- /dev/null
+++ b/cmd/scmi.c
@@ -0,0 +1,384 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  SCMI (System Control and Management Interface) utility command
+ *
+ *  Copyright (c) 2023 Linaro Limited
+ *     Author: AKASHI Takahiro
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include  /* uclass_get_device */
+#include 
+#include 
+
+struct {
+   enum scmi_std_protocol id;
+   const char *name;
+} protocol_name[] = {
+   {SCMI_PROTOCOL_ID_BASE, "Base"},
+   {SCMI_PROTOCOL_ID_POWER_DOMAIN, "Power domain management"},
+   {SCMI_PROTOCOL_ID_SYSTEM, "System power management"},
+   {SCMI_PROTOCOL_ID_PERF, "Performance domain management"},
+   {SCMI_PROTOCOL_ID_CLOCK, "Clock management"},
+   {SCMI_PROTOCOL_ID_SENSOR, "Sensor management"},
+   {SCMI_PROTOCOL_ID_RESET_DOMAIN, "Reset domain management"},
+   {SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN, "Voltage domain management"},
+};
+
+/**
+ * get_agent() - get SCMI agent device
+ *
+ * Return: Pointer to SCMI agent device on success, NULL on failure
+ */
+static struct udevice *get_agent(void)
+{
+   struct udevice *agent;
+
+   if (uclass_get_device(UCLASS_SCMI_AGENT, 0, )) {
+   printf("Cannot find any SCMI agent\n");
+   return NULL;
+   }
+
+   return agent;
+}
+
+/**
+ * get_base_proto() - get SCMI base protocol device
+ * @agent: SCMI agent device
+ *
+ * Return: Pointer to SCMI base protocol device on success,
+ * NULL on failure
+ */
+static struct udevice *get_base_proto(struct udevice *agent)
+{
+   struct udevice *base_proto;
+
+   if (!agent) {
+   agent = get_agent();
+   if (!agent)
+   return NULL;
+   }
+
+   base_proto = scmi_get_protocol(agent, SCMI_PROTOCOL_ID_BASE);
+   if (!base_proto) {
+   printf("SCMI base protocol not found\n");
+   return NULL;
+   }
+
+   return base_proto;
+}
+
+/**
+ * get_proto_name() - get the name of SCMI protocol
+ *
+ * @id:SCMI Protocol ID
+ *
+ * Get the printable name of the protocol, @id
+ *
+ * Return: Name string on success, NULL on failure
+ */
+static const char *get_proto_name(enum scmi_std_protocol id)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(protocol_name); i++)
+   if (id == protocol_name[i].id)
+   return protocol_name[i].name;
+
+   return NULL;
+}
+
+/**
+ * do_scmi_info() - get the information of SCMI services
+ *
+ * @cmdtp: Command table
+ * @flag:  Command flag
+ * @argc:  Number of arguments
+ * @argv:  Argument array
+ *
+ * Get the information of SCMI services using various interfaces
+ * provided by the Base protocol.
+ *
+ * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
+ */
+static int do_scmi_info(struct cmd_tb

[PATCH v3 2/5] firmware: scmi: support protocols on sandbox only if enabled

2023-11-13 Thread AKASHI Takahiro
This change will be useful when we manually test SCMI on sandbox
by enabling/disabling a specific SCMI protocol.

Signed-off-by: AKASHI Takahiro 
---
v9
* use CONFIG_IS_ENABLED() rather than IS_ENABLED()
* remove goto by introducing a not_supported() function
---
 drivers/firmware/scmi/sandbox-scmi_agent.c   | 30 ++--
 drivers/firmware/scmi/sandbox-scmi_devices.c | 78 
 2 files changed, 71 insertions(+), 37 deletions(-)

diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c 
b/drivers/firmware/scmi/sandbox-scmi_agent.c
index d13180962662..cc9011c7312f 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -66,10 +66,10 @@ struct scmi_channel {
 };
 
 static u8 protocols[] = {
-   SCMI_PROTOCOL_ID_POWER_DOMAIN,
-   SCMI_PROTOCOL_ID_CLOCK,
-   SCMI_PROTOCOL_ID_RESET_DOMAIN,
-   SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,
+   CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN, (SCMI_PROTOCOL_ID_POWER_DOMAIN,))
+   CONFIG_IS_ENABLED(CLK_SCMI, (SCMI_PROTOCOL_ID_CLOCK,))
+   CONFIG_IS_ENABLED(RESET_SCMI, (SCMI_PROTOCOL_ID_RESET_DOMAIN,))
+   CONFIG_IS_ENABLED(DM_REGULATOR_SCMI, (SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,))
 };
 
 #define NUM_PROTOCOLS ARRAY_SIZE(protocols)
@@ -1124,6 +1124,13 @@ unsigned int sandbox_scmi_channel_id(struct udevice *dev)
return chan->channel_id;
 }
 
+static int sandbox_proto_not_supported(struct scmi_msg *msg)
+{
+   *(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
+
+   return 0;
+}
+
 static int sandbox_scmi_test_process_msg(struct udevice *dev,
 struct scmi_channel *channel,
 struct scmi_msg *msg)
@@ -1160,6 +1167,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_POWER_DOMAIN:
+   if (!CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN))
+   return sandbox_proto_not_supported(msg);
+
switch (msg->message_id) {
case SCMI_PROTOCOL_VERSION:
return sandbox_scmi_pwd_protocol_version(dev, msg);
@@ -1180,6 +1190,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_CLOCK:
+   if (!CONFIG_IS_ENABLED(CLK_SCMI))
+   return sandbox_proto_not_supported(msg);
+
switch (msg->message_id) {
case SCMI_PROTOCOL_ATTRIBUTES:
return sandbox_scmi_clock_protocol_attribs(dev, msg);
@@ -1196,6 +1209,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_RESET_DOMAIN:
+   if (!CONFIG_IS_ENABLED(RESET_SCMI))
+   return sandbox_proto_not_supported(msg);
+
switch (msg->message_id) {
case SCMI_RESET_DOMAIN_ATTRIBUTES:
return sandbox_scmi_rd_attribs(dev, msg);
@@ -1206,6 +1222,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
+   if (!CONFIG_IS_ENABLED(DM_REGULATOR_SCMI))
+   return sandbox_proto_not_supported(msg);
+
switch (msg->message_id) {
case SCMI_VOLTAGE_DOMAIN_ATTRIBUTES:
return sandbox_scmi_voltd_attribs(dev, msg);
@@ -1224,8 +1243,7 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
case SCMI_PROTOCOL_ID_SYSTEM:
case SCMI_PROTOCOL_ID_PERF:
case SCMI_PROTOCOL_ID_SENSOR:
-   *(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
-   return 0;
+   return sandbox_proto_not_supported(msg);
default:
break;
}
diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c 
b/drivers/firmware/scmi/sandbox-scmi_devices.c
index facb5b06ffb5..603e2bb40aff 100644
--- a/drivers/firmware/scmi/sandbox-scmi_devices.c
+++ b/drivers/firmware/scmi/sandbox-scmi_devices.c
@@ -62,12 +62,13 @@ static int sandbox_scmi_devices_remove(struct udevice *dev)
if (!devices)
return 0;
 
-   for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) {
-   int ret2 = reset_free(devices->reset + n);
+   if (CONFIG_IS_ENABLED(RESET_SCMI))
+   for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) {
+   int ret2 = reset_free(devices->reset + n);
 
-   if (ret2 && !ret)
-   ret = ret2;
-   }
+   if (ret2 && !ret)
+   ret = ret2;
+   }
 
return ret;
 }
@@ -89,39 +90,53 @@ static int sandbox_scmi_devices_probe(struct udevice *dev)
.regul_count = SCMI_T

[PATCH v3 1/5] test: dm: skip scmi tests against disabled protocols

2023-11-13 Thread AKASHI Takahiro
This is a precautionary change to make scmi tests workable whether or not
a specific protocol be enabled. If a given protocol is not configured,
we skip the test by returning -EAGAIN.

Signed-off-by: AKASHI Takahiro 
---
v9
* return -EAGAIN if we want to skip a test
* use CONFIG_IS_ENABLED() rather than IS_ENABLED()
---
 test/dm/scmi.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/test/dm/scmi.c b/test/dm/scmi.c
index da45314f2e4c..582485471fff 100644
--- a/test/dm/scmi.c
+++ b/test/dm/scmi.c
@@ -217,6 +217,9 @@ static int dm_test_scmi_power_domains(struct 
unit_test_state *uts)
u8 *name;
int ret;
 
+   if (!CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN))
+   return -EAGAIN;
+
/* preparation */
ut_assertok(load_sandbox_scmi_test_devices(uts, , ));
ut_assertnonnull(agent);
@@ -317,6 +320,9 @@ static int dm_test_scmi_clocks(struct unit_test_state *uts)
int ret_dev;
int ret;
 
+   if (!CONFIG_IS_ENABLED(CLK_SCMI))
+   return -EAGAIN;
+
ret = load_sandbox_scmi_test_devices(uts, , );
if (ret)
return ret;
@@ -382,6 +388,9 @@ static int dm_test_scmi_resets(struct unit_test_state *uts)
struct udevice *agent_dev, *reset_dev, *dev = NULL;
int ret;
 
+   if (!CONFIG_IS_ENABLED(RESET_SCMI))
+   return -EAGAIN;
+
ret = load_sandbox_scmi_test_devices(uts, , );
if (ret)
return ret;
@@ -418,6 +427,9 @@ static int dm_test_scmi_voltage_domains(struct 
unit_test_state *uts)
struct udevice *dev;
struct udevice *regul0_dev;
 
+   if (!CONFIG_IS_ENABLED(DM_REGULATOR_SCMI))
+   return -EAGAIN;
+
ut_assertok(load_sandbox_scmi_test_devices(uts, , ));
 
scmi_devices = sandbox_scmi_devices_ctx(dev);
-- 
2.34.1



[PATCH v3 0/5] cmd: add scmi command

2023-11-13 Thread AKASHI Takahiro
"Scmi" command will be re-introduced per Michal's request.
The functionality is the same as I put it in my patch set of adding
SCMI base protocol support, but made some tweak to make UT, "ut dm
scmi_cmd," more flexible and tolerable when enabling/disabling a specific
SCMI protocol for test purpose.

Each commit may have some change history inherited from the preceding
patch series.

Test

The patch series was tested on the following platforms:
* sandbox

Prerequisite:
=
* This patch series is based on the latest master.

Changes:

v3(Nov 14, 2023)
* return -EAGAIN if we want to skip a test.
* use CONFIG_IS_ENABLED() rather than IS_ENABLED().
* remove goto by introducing a function in sandbox implementation.
v2(Nov 13, 2023)
* localize global variables to avoid pytest errors.

AKASHI Takahiro (5):
  test: dm: skip scmi tests against disabled protocols
  firmware: scmi: support protocols on sandbox only if enabled
  cmd: add scmi command for SCMI firmware
  doc: cmd: add documentation for scmi
  test: dm: add scmi command test

 cmd/Kconfig  |   9 +
 cmd/Makefile |   1 +
 cmd/scmi.c   | 384 +++
 configs/sandbox_defconfig|   1 +
 doc/usage/cmd/scmi.rst   | 126 ++
 doc/usage/index.rst  |   1 +
 drivers/firmware/scmi/sandbox-scmi_agent.c   |  30 +-
 drivers/firmware/scmi/sandbox-scmi_devices.c |  78 ++--
 test/dm/scmi.c   |  93 +
 9 files changed, 686 insertions(+), 37 deletions(-)
 create mode 100644 cmd/scmi.c
 create mode 100644 doc/usage/cmd/scmi.rst

-- 
2.34.1



Re: [PATCH v2 2/5] firmware: scmi: support protocols on sandbox only if enabled

2023-11-13 Thread AKASHI Takahiro
On Mon, Nov 13, 2023 at 11:01:20AM -0700, Simon Glass wrote:
> Hi AKASHI,
> 
> On Sun, 12 Nov 2023 at 18:49, AKASHI Takahiro
>  wrote:
> >
> > This change will be useful when we manually test SCMI on sandbox
> > by enabling/disabling a specific SCMI protocol.
> >
> > Signed-off-by: AKASHI Takahiro 
> > ---
> >  drivers/firmware/scmi/sandbox-scmi_agent.c   | 27 ++-
> >  drivers/firmware/scmi/sandbox-scmi_devices.c | 78 
> >  2 files changed, 72 insertions(+), 33 deletions(-)
> >
> > diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c 
> > b/drivers/firmware/scmi/sandbox-scmi_agent.c
> > index d13180962662..1fc9a0f4ea7e 100644
> > --- a/drivers/firmware/scmi/sandbox-scmi_agent.c
> > +++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
> > @@ -66,10 +66,18 @@ struct scmi_channel {
> >  };
> >
> >  static u8 protocols[] = {
> > +#if IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN)
> > SCMI_PROTOCOL_ID_POWER_DOMAIN,
> 
> Is this better? Perhaps not!
> 
> CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN, (SCMI_PROTOCOL_ID_POWER_DOMAIN,))

Ah, good notation.

> > +#endif
> > +#if IS_ENABLED(CONFIG_CLK_SCMI)
> > SCMI_PROTOCOL_ID_CLOCK,
> > +#endif
> > +#if IS_ENABLED(CONFIG_RESET_SCMI)
> > SCMI_PROTOCOL_ID_RESET_DOMAIN,
> > +#endif
> > +#if IS_ENABLED(CONFIG_DM_REGULATOR_SCMI)
> > SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,
> > +#endif
> >  };
> >
> >  #define NUM_PROTOCOLS ARRAY_SIZE(protocols)
> > @@ -1160,6 +1168,9 @@ static int sandbox_scmi_test_process_msg(struct 
> > udevice *dev,
> > }
> > break;
> > case SCMI_PROTOCOL_ID_POWER_DOMAIN:
> > +   if (!IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN))
> > +   goto not_supported;
> > +
> > switch (msg->message_id) {
> > case SCMI_PROTOCOL_VERSION:
> > return sandbox_scmi_pwd_protocol_version(dev, msg);
> > @@ -1180,6 +1191,9 @@ static int sandbox_scmi_test_process_msg(struct 
> > udevice *dev,
> > }
> > break;
> > case SCMI_PROTOCOL_ID_CLOCK:
> > +   if (!IS_ENABLED(CONFIG_CLK_SCMI))
> > +   goto not_supported;
> 
> How about putting this all in a function and avoiding the goto?

Okay, will do.

Thanks,
-Takahiro Akashi

> > +
> > switch (msg->message_id) {
> > case SCMI_PROTOCOL_ATTRIBUTES:
> > return sandbox_scmi_clock_protocol_attribs(dev, 
> > msg);
> > @@ -1196,6 +1210,9 @@ static int sandbox_scmi_test_process_msg(struct 
> > udevice *dev,
> > }
> > break;
> > case SCMI_PROTOCOL_ID_RESET_DOMAIN:
> > +   if (!IS_ENABLED(CONFIG_RESET_SCMI))
> > +   goto not_supported;
> > +
> > switch (msg->message_id) {
> > case SCMI_RESET_DOMAIN_ATTRIBUTES:
> > return sandbox_scmi_rd_attribs(dev, msg);
> > @@ -1206,6 +1223,9 @@ static int sandbox_scmi_test_process_msg(struct 
> > udevice *dev,
> > }
> > break;
> > case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
> > +   if (!IS_ENABLED(CONFIG_DM_REGULATOR_SCMI))
> > +   goto not_supported;
> > +
> > switch (msg->message_id) {
> > case SCMI_VOLTAGE_DOMAIN_ATTRIBUTES:
> > return sandbox_scmi_voltd_attribs(dev, msg);
> > @@ -1224,8 +1244,7 @@ static int sandbox_scmi_test_process_msg(struct 
> > udevice *dev,
> > case SCMI_PROTOCOL_ID_SYSTEM:
> > case SCMI_PROTOCOL_ID_PERF:
> > case SCMI_PROTOCOL_ID_SENSOR:
> > -   *(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
> > -   return 0;
> > +   goto not_supported;
> > default:
> > break;
> > }
> > @@ -1239,6 +1258,10 @@ static int sandbox_scmi_test_process_msg(struct 
> > udevice *dev,
> > /* Intentionnaly report unhandled IDs through the SCMI return code 
> > */
> > *(u32 *)msg->out_msg = SCMI_PROTOCOL_ERROR;
> > return 0;
> > +
> > +not_supported:
> > +   *(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
> > +   return 0;
> >  }
> >
> >  static int sandbox_scmi_test_remove(struct udevice *dev)
> > diff --git a/

Re: [PATCH v2 1/5] test: dm: skip scmi tests against disabled protocols

2023-11-13 Thread AKASHI Takahiro
On Mon, Nov 13, 2023 at 11:01:18AM -0700, Simon Glass wrote:
> Hi AKASHI,
> 
> On Sun, 12 Nov 2023 at 18:49, AKASHI Takahiro
>  wrote:
> >
> > This is a precautionary change to make scmi tests workable whether or not
> > a specific protocol be enabled.
> >
> > Signed-off-by: AKASHI Takahiro 
> > ---
> >  test/dm/scmi.c | 12 
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/test/dm/scmi.c b/test/dm/scmi.c
> > index da45314f2e4c..2f63f2da16fb 100644
> > --- a/test/dm/scmi.c
> > +++ b/test/dm/scmi.c
> > @@ -217,6 +217,9 @@ static int dm_test_scmi_power_domains(struct 
> > unit_test_state *uts)
> > u8 *name;
> > int ret;
> >
> > +   if (!IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN))
> > +   return 0;
> 
> -EAGAIN to skip a test

Ah, I didn't notice such a common practice as it is rarely seen
under ut. Will fix.

-Takahiro Akashi

> Please update a comment if this needs to be documented better
> 
> > +
> > /* preparation */
> > ut_assertok(load_sandbox_scmi_test_devices(uts, , ));
> > ut_assertnonnull(agent);
> > @@ -317,6 +320,9 @@ static int dm_test_scmi_clocks(struct unit_test_state 
> > *uts)
> > int ret_dev;
> > int ret;
> >
> > +   if (!IS_ENABLED(CONFIG_CLK_SCMI))
> > +   return 0;
> > +
> > ret = load_sandbox_scmi_test_devices(uts, , );
> > if (ret)
> > return ret;
> > @@ -382,6 +388,9 @@ static int dm_test_scmi_resets(struct unit_test_state 
> > *uts)
> > struct udevice *agent_dev, *reset_dev, *dev = NULL;
> > int ret;
> >
> > +   if (!IS_ENABLED(CONFIG_RESET_SCMI))
> > +   return 0;
> > +
> > ret = load_sandbox_scmi_test_devices(uts, , );
> > if (ret)
> > return ret;
> > @@ -418,6 +427,9 @@ static int dm_test_scmi_voltage_domains(struct 
> > unit_test_state *uts)
> > struct udevice *dev;
> > struct udevice *regul0_dev;
> >
> > +   if (!IS_ENABLED(CONFIG_DM_REGULATOR_SCMI))
> > +   return 0;
> > +
> > ut_assertok(load_sandbox_scmi_test_devices(uts, , ));
> >
> > scmi_devices = sandbox_scmi_devices_ctx(dev);
> > --
> > 2.34.1
> >
> 
> Regards,
> Simon


Re: [PATCH 5/5] test: dm: add scmi command test

2023-11-13 Thread AKASHI Takahiro
On Mon, Nov 13, 2023 at 11:01:17AM -0700, Simon Glass wrote:
> Hi,
> 
> On Sun, 12 Nov 2023 at 18:46, AKASHI Takahiro
>  wrote:
> >
> > Hi Tom,
> >
> > On Fri, Nov 10, 2023 at 01:21:37PM -0500, Tom Rini wrote:
> > > On Wed, Oct 25, 2023 at 02:14:27PM +0900, AKASHI Takahiro wrote:
> > >
> > > > In this test, "scmi" command is tested against different sub-commands.
> > > > Please note that scmi command is for debug purpose and is not intended
> > > > in production system.
> > > >
> > > > Signed-off-by: AKASHI Takahiro 
> > > > Reviewed-by: Simon Glass 
> > > > Reviewed-by: Etienne Carriere 
> > >
> > > The test part of this still fails:
> > > https://source.denx.de/u-boot/u-boot/-/jobs/732077
> > >
> > > I don't know why more output wasn't captured, when I run it locally
> > > instead I get:
> > > == FAILURES 
> > > ===
> > > ___ test_ut[ut_dm_dm_test_scmi_cmd] 
> > > ___
> > > test/py/u_boot_spawn.py:195: in expect
> > > c = os.read(self.fd, 1024).decode(errors='replace')
> > > E   OSError: [Errno 5] Input/output error
> > >
> > > During handling of the above exception, another exception occurred:
> > > test/py/tests/test_ut.py:502: in test_ut
> > > output = u_boot_console.run_command('ut ' + ut_subtest)
> > > test/py/u_boot_console_base.py:266: in run_command
> > > m = self.p.expect([self.prompt_compiled] + self.bad_patterns)
> > > test/py/u_boot_spawn.py:204: in expect
> > > raise ValueError('U-Boot exited with %s' % info)
> > > E   ValueError: U-Boot exited with signal 11 (SIGSEGV)
> >
> >
> > The command uses global variables which hold pointers to 'struct udevice'
> > which are to be shared between the main and the sub-commands.
> > Since pytest framework executes ut tests twice, once with a (normal?) device
> > tree and once with a flat tree,  udevices will be *voided* between
> > two executions.
> 
> Are you able to put the var in the uclass-priv data instead? The state
> should be cleared before running each DM test.

Well, I don't think we need such a trick.
As you can see, we may simply fetch/find necessary udevices
every time the command is called.
It is enough given that the command is mainly for debug purpose.

-Takahiro Akashi


> Regards,
> Simon
> 
> 
> >
> > I will fix it in v2.
> >
> > Thanks,
> > -Takahiro Akashi
> >
> >
> > >  Captured stdout call 
> > > -
> > > => ut dm dm_test_scmi_cmd
> > > Test: dm_test_scmi_cmd: scmi.c
> > > SCMI device: scmi
> > >   protocol version: 0x2
> > >   # of agents: 2
> > >   0: platform
> > > > 1: OSPM
> > >   # of protocols: 4
> > >   Power domain management
> > >   Clock management
> > >   Reset domain management
> > >   Voltage domain management
> > >   vendor: U-Boot
> > >   sub vendor: Sandbox
> > >   impl version: 0x1
> > > Denying access to device:0 failed (-13)
> > > Denying access to protocol:0x14 on device:0 failed (-13)
> > > Reset failed (-13)
> > > Test: dm_test_scmi_cmd: scmi.c (flat tree)
> > > SCMI device: Q
> > > === short test summary info 
> > > ===
> > > FAILED test/py/tests/test_ut.py::test_ut[ut_dm_dm_test_scmi_cmd] - 
> > > ValueError: U-Boot exited...
> > >
> > > --
> > > Tom
> >
> >


[PATCH v2 5/5] test: dm: add scmi command test

2023-11-12 Thread AKASHI Takahiro
In this test, "scmi" command is tested against different sub-commands.
Please note that scmi command is for debug purpose and is not intended
in production system.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
Reviewed-by: Etienne Carriere 
---
v7
* make test assertions more flexible depending on the number of provided
  protocols
v4
* move 'base'-related changes to the prior commit
* add CONFIG_CMD_SCMI to sandbox_defconfig
v3
* change char to u8 in vendor/agent names
v2
* use helper functions, removing direct uses of ops
---
 configs/sandbox_defconfig |  1 +
 test/dm/scmi.c| 81 +++
 2 files changed, 82 insertions(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index bc5bcb2a6237..c550af93b0ca 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -121,6 +121,7 @@ CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_AES=y
 CONFIG_CMD_TPM=y
 CONFIG_CMD_TPM_TEST=y
+CONFIG_CMD_SCMI=y
 CONFIG_CMD_BTRFS=y
 CONFIG_CMD_CBFS=y
 CONFIG_CMD_CRAMFS=y
diff --git a/test/dm/scmi.c b/test/dm/scmi.c
index 2f63f2da16fb..2bcf7ac6fcc3 100644
--- a/test/dm/scmi.c
+++ b/test/dm/scmi.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -206,6 +207,86 @@ static int dm_test_scmi_base(struct unit_test_state *uts)
 
 DM_TEST(dm_test_scmi_base, UT_TESTF_SCAN_FDT);
 
+static int dm_test_scmi_cmd(struct unit_test_state *uts)
+{
+   struct udevice *agent_dev;
+   int num_proto = 0;
+   char cmd_out[30];
+
+   if (!IS_ENABLED(CONFIG_CMD_SCMI))
+   return 0;
+
+   /* preparation */
+   ut_assertok(uclass_get_device_by_name(UCLASS_SCMI_AGENT, "scmi",
+ _dev));
+   ut_assertnonnull(agent_dev);
+
+   /*
+* Estimate the number of provided protocols.
+* This estimation is correct as far as a corresponding
+* protocol support is added to sandbox fake serer.
+*/
+   if (IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN))
+   num_proto++;
+   if (IS_ENABLED(CONFIG_CLK_SCMI))
+   num_proto++;
+   if (IS_ENABLED(CONFIG_RESET_SCMI))
+   num_proto++;
+   if (IS_ENABLED(CONFIG_DM_REGULATOR_SCMI))
+   num_proto++;
+
+   /* scmi info */
+   ut_assertok(run_command("scmi info", 0));
+
+   ut_assert_nextline("SCMI device: scmi");
+   snprintf(cmd_out, 30, "  protocol version: 0x%x",
+SCMI_BASE_PROTOCOL_VERSION);
+   ut_assert_nextline(cmd_out);
+   ut_assert_nextline("  # of agents: 2");
+   ut_assert_nextline("  0: platform");
+   ut_assert_nextline("> 1: OSPM");
+   snprintf(cmd_out, 30, "  # of protocols: %d", num_proto);
+   ut_assert_nextline(cmd_out);
+   if (IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN))
+   ut_assert_nextline("  Power domain management");
+   if (IS_ENABLED(CONFIG_CLK_SCMI))
+   ut_assert_nextline("  Clock management");
+   if (IS_ENABLED(CONFIG_RESET_SCMI))
+   ut_assert_nextline("  Reset domain management");
+   if (IS_ENABLED(CONFIG_DM_REGULATOR_SCMI))
+   ut_assert_nextline("  Voltage domain management");
+   ut_assert_nextline("  vendor: U-Boot");
+   ut_assert_nextline("  sub vendor: Sandbox");
+   ut_assert_nextline("  impl version: 0x1");
+
+   ut_assert_console_end();
+
+   /* scmi perm_dev */
+   ut_assertok(run_command("scmi perm_dev 1 0 1", 0));
+   ut_assert_console_end();
+
+   ut_assert(run_command("scmi perm_dev 1 0 0", 0));
+   ut_assert_nextline("Denying access to device:0 failed (-13)");
+   ut_assert_console_end();
+
+   /* scmi perm_proto */
+   ut_assertok(run_command("scmi perm_proto 1 0 14 1", 0));
+   ut_assert_console_end();
+
+   ut_assert(run_command("scmi perm_proto 1 0 14 0", 0));
+   ut_assert_nextline("Denying access to protocol:0x14 on device:0 failed 
(-13)");
+   ut_assert_console_end();
+
+   /* scmi reset */
+   ut_assert(run_command("scmi reset 1 1", 0));
+   ut_assert_nextline("Reset failed (-13)");
+   ut_assert_console_end();
+
+   return 0;
+}
+
+DM_TEST(dm_test_scmi_cmd, UT_TESTF_SCAN_FDT);
+
 static int dm_test_scmi_power_domains(struct unit_test_state *uts)
 {
struct sandbox_scmi_agent *agent;
-- 
2.34.1



[PATCH v2 4/5] doc: cmd: add documentation for scmi

2023-11-12 Thread AKASHI Takahiro
This is a help text for scmi command.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
Reviewed-by: Etienne Carriere 
---
v6
* add the manual to doc/usage/index.rst
v4
* s/tranport/transport/
v2
* add more descriptions about SCMI
---
 doc/usage/cmd/scmi.rst | 126 +
 doc/usage/index.rst|   1 +
 2 files changed, 127 insertions(+)
 create mode 100644 doc/usage/cmd/scmi.rst

diff --git a/doc/usage/cmd/scmi.rst b/doc/usage/cmd/scmi.rst
new file mode 100644
index ..9ea7e0e41dad
--- /dev/null
+++ b/doc/usage/cmd/scmi.rst
@@ -0,0 +1,126 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+scmi command
+
+
+Synopsis
+
+
+::
+
+scmi info
+scmi perm_dev   
+scmi perm_proto
+scmi reset  
+
+Description
+---
+
+Arm System Control and Management Interface (SCMI hereafter) is a set of
+standardised interfaces to manage system resources, like clocks, power
+domains, pin controls, reset and so on, in a system-wide manner.
+
+An entity which provides those services is called a SCMI firmware (or
+SCMI server if you like) may be placed/implemented by EL3 software or
+by a dedicated system control processor (SCP) or else.
+
+A user of SCMI interfaces, including U-Boot, is called a SCMI agent and
+may issues commands, which are defined in each protocol for specific system
+resources, to SCMI server via a communication channel, called a transport.
+Those interfaces are independent from the server's implementation thanks to
+a transport layer.
+
+For more details, see the `SCMI specification`_.
+
+While most of system resources managed under SCMI protocols are implemented
+and handled as standard U-Boot devices, for example clk_scmi, scmi command
+provides additional management functionality against SCMI server.
+
+scmi info
+~
+Show base information about SCMI server and supported protocols
+
+scmi perm_dev
+~
+Allow or deny access permission to the device
+
+scmi perm_proto
+~~~
+Allow or deny access to the protocol on the device
+
+scmi reset
+~~
+Reset the already-configured permissions against the device
+
+Parameters are used as follows:
+
+
+SCMI Agent ID, hex value
+
+
+SCMI Device ID, hex value
+
+Please note that what a device means is not defined
+in the specification.
+
+
+SCMI Protocol ID, hex value
+
+It must not be 0x10 (base protocol)
+
+
+Flags to control the action, hex value
+
+0 to deny, 1 to allow. The other values are reserved and allowed
+values may depend on the implemented version of SCMI server in
+the future. See SCMI specification for more details.
+
+Example
+---
+
+Obtain basic information about SCMI server:
+
+::
+
+=> scmi info
+SCMI device: scmi
+  protocol version: 0x2
+  # of agents: 3
+  0: platform
+> 1: OSPM
+  2: PSCI
+  # of protocols: 4
+  Power domain management
+  Performance domain management
+  Clock management
+  Sensor management
+  vendor: Linaro
+  sub vendor: PMWG
+  impl version: 0x20b
+
+Ask for access permission to device#0:
+
+::
+
+=> scmi perm_dev 1 0 1
+
+Reset configurations with all access permission settings retained:
+
+::
+
+=> scmi reset 1 0
+
+Configuration
+-
+
+The scmi command is only available if CONFIG_CMD_SCMI=y.
+Default n because this command is mainly for debug purpose.
+
+Return value
+
+
+The return value ($?) is set to 0 if the operation succeeded,
+1 if the operation failed or -1 if the operation failed due to
+a syntax error.
+
+.. _`SCMI specification`: 
https://developer.arm.com/documentation/den0056/e/?lang=en
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index d8e23fcacffb..1a626c03c237 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -94,6 +94,7 @@ Shell commands
cmd/rng
cmd/saves
cmd/sbi
+   cmd/scmi
cmd/scp03
cmd/seama
cmd/setexpr
-- 
2.34.1



[PATCH v2 3/5] cmd: add scmi command for SCMI firmware

2023-11-12 Thread AKASHI Takahiro
This command, "scmi", may provide a command line interface to various SCMI
protocols. It supports at least initially SCMI base protocol and is
intended mainly for debug purpose.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
Reviewed-by: Etienne Carriere 
---
v8 (actually v2 as SCMI cmd)
* localize global variables to avoid pytest errors
v3
* describe that arguments are in hex at a help message
* modify the code for dynamically allocated agent names
v2
* remove sub command category, 'scmi base', for simplicity
---
 cmd/Kconfig  |   9 ++
 cmd/Makefile |   1 +
 cmd/scmi.c   | 384 +++
 3 files changed, 394 insertions(+)
 create mode 100644 cmd/scmi.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index df6d71c103f9..ca9f742dcf78 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2559,6 +2559,15 @@ config CMD_CROS_EC
  a number of sub-commands for performing EC tasks such as
  updating its flash, accessing a small saved context area
  and talking to the I2C bus behind the EC (if there is one).
+
+config CMD_SCMI
+   bool "Enable scmi command"
+   depends on SCMI_FIRMWARE
+   default n
+   help
+ This command provides user interfaces to several SCMI (System
+ Control and Management Interface) protocols available on Arm
+ platforms to manage system resources.
 endmenu
 
 menu "Filesystem commands"
diff --git a/cmd/Makefile b/cmd/Makefile
index 9a6790cc1708..320f0b5266eb 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -159,6 +159,7 @@ obj-$(CONFIG_CMD_SATA) += sata.o
 obj-$(CONFIG_CMD_NVME) += nvme.o
 obj-$(CONFIG_SANDBOX) += sb.o
 obj-$(CONFIG_CMD_SF) += sf.o
+obj-$(CONFIG_CMD_SCMI) += scmi.o
 obj-$(CONFIG_CMD_SCSI) += scsi.o disk.o
 obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
 obj-$(CONFIG_CMD_SEAMA) += seama.o
diff --git a/cmd/scmi.c b/cmd/scmi.c
new file mode 100644
index ..664062c4eff5
--- /dev/null
+++ b/cmd/scmi.c
@@ -0,0 +1,384 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  SCMI (System Control and Management Interface) utility command
+ *
+ *  Copyright (c) 2023 Linaro Limited
+ *     Author: AKASHI Takahiro
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include  /* uclass_get_device */
+#include 
+#include 
+
+struct {
+   enum scmi_std_protocol id;
+   const char *name;
+} protocol_name[] = {
+   {SCMI_PROTOCOL_ID_BASE, "Base"},
+   {SCMI_PROTOCOL_ID_POWER_DOMAIN, "Power domain management"},
+   {SCMI_PROTOCOL_ID_SYSTEM, "System power management"},
+   {SCMI_PROTOCOL_ID_PERF, "Performance domain management"},
+   {SCMI_PROTOCOL_ID_CLOCK, "Clock management"},
+   {SCMI_PROTOCOL_ID_SENSOR, "Sensor management"},
+   {SCMI_PROTOCOL_ID_RESET_DOMAIN, "Reset domain management"},
+   {SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN, "Voltage domain management"},
+};
+
+/**
+ * get_agent() - get SCMI agent device
+ *
+ * Return: Pointer to SCMI agent device on success, NULL on failure
+ */
+static struct udevice *get_agent(void)
+{
+   struct udevice *agent;
+
+   if (uclass_get_device(UCLASS_SCMI_AGENT, 0, )) {
+   printf("Cannot find any SCMI agent\n");
+   return NULL;
+   }
+
+   return agent;
+}
+
+/**
+ * get_base_proto() - get SCMI base protocol device
+ * @agent: SCMI agent device
+ *
+ * Return: Pointer to SCMI base protocol device on success,
+ * NULL on failure
+ */
+static struct udevice *get_base_proto(struct udevice *agent)
+{
+   struct udevice *base_proto;
+
+   if (!agent) {
+   agent = get_agent();
+   if (!agent)
+   return NULL;
+   }
+
+   base_proto = scmi_get_protocol(agent, SCMI_PROTOCOL_ID_BASE);
+   if (!base_proto) {
+   printf("SCMI base protocol not found\n");
+   return NULL;
+   }
+
+   return base_proto;
+}
+
+/**
+ * get_proto_name() - get the name of SCMI protocol
+ *
+ * @id:SCMI Protocol ID
+ *
+ * Get the printable name of the protocol, @id
+ *
+ * Return: Name string on success, NULL on failure
+ */
+static const char *get_proto_name(enum scmi_std_protocol id)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(protocol_name); i++)
+   if (id == protocol_name[i].id)
+   return protocol_name[i].name;
+
+   return NULL;
+}
+
+/**
+ * do_scmi_info() - get the information of SCMI services
+ *
+ * @cmdtp: Command table
+ * @flag:  Command flag
+ * @argc:  Number of arguments
+ * @argv:  Argument array
+ *
+ * Get the information of SCMI services using various interfaces
+ * provided by the Base protocol.
+ *
+ * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
+ */
+static int do_scmi_info(struct cmd_tb

[PATCH v2 2/5] firmware: scmi: support protocols on sandbox only if enabled

2023-11-12 Thread AKASHI Takahiro
This change will be useful when we manually test SCMI on sandbox
by enabling/disabling a specific SCMI protocol.

Signed-off-by: AKASHI Takahiro 
---
 drivers/firmware/scmi/sandbox-scmi_agent.c   | 27 ++-
 drivers/firmware/scmi/sandbox-scmi_devices.c | 78 
 2 files changed, 72 insertions(+), 33 deletions(-)

diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c 
b/drivers/firmware/scmi/sandbox-scmi_agent.c
index d13180962662..1fc9a0f4ea7e 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -66,10 +66,18 @@ struct scmi_channel {
 };
 
 static u8 protocols[] = {
+#if IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN)
SCMI_PROTOCOL_ID_POWER_DOMAIN,
+#endif
+#if IS_ENABLED(CONFIG_CLK_SCMI)
SCMI_PROTOCOL_ID_CLOCK,
+#endif
+#if IS_ENABLED(CONFIG_RESET_SCMI)
SCMI_PROTOCOL_ID_RESET_DOMAIN,
+#endif
+#if IS_ENABLED(CONFIG_DM_REGULATOR_SCMI)
SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,
+#endif
 };
 
 #define NUM_PROTOCOLS ARRAY_SIZE(protocols)
@@ -1160,6 +1168,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_POWER_DOMAIN:
+   if (!IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN))
+   goto not_supported;
+
switch (msg->message_id) {
case SCMI_PROTOCOL_VERSION:
return sandbox_scmi_pwd_protocol_version(dev, msg);
@@ -1180,6 +1191,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_CLOCK:
+   if (!IS_ENABLED(CONFIG_CLK_SCMI))
+   goto not_supported;
+
switch (msg->message_id) {
case SCMI_PROTOCOL_ATTRIBUTES:
return sandbox_scmi_clock_protocol_attribs(dev, msg);
@@ -1196,6 +1210,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_RESET_DOMAIN:
+   if (!IS_ENABLED(CONFIG_RESET_SCMI))
+   goto not_supported;
+
switch (msg->message_id) {
case SCMI_RESET_DOMAIN_ATTRIBUTES:
return sandbox_scmi_rd_attribs(dev, msg);
@@ -1206,6 +1223,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
+   if (!IS_ENABLED(CONFIG_DM_REGULATOR_SCMI))
+   goto not_supported;
+
switch (msg->message_id) {
case SCMI_VOLTAGE_DOMAIN_ATTRIBUTES:
return sandbox_scmi_voltd_attribs(dev, msg);
@@ -1224,8 +1244,7 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
case SCMI_PROTOCOL_ID_SYSTEM:
case SCMI_PROTOCOL_ID_PERF:
case SCMI_PROTOCOL_ID_SENSOR:
-   *(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
-   return 0;
+   goto not_supported;
default:
break;
}
@@ -1239,6 +1258,10 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
/* Intentionnaly report unhandled IDs through the SCMI return code */
*(u32 *)msg->out_msg = SCMI_PROTOCOL_ERROR;
return 0;
+
+not_supported:
+   *(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
+   return 0;
 }
 
 static int sandbox_scmi_test_remove(struct udevice *dev)
diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c 
b/drivers/firmware/scmi/sandbox-scmi_devices.c
index facb5b06ffb5..0519cf889aa9 100644
--- a/drivers/firmware/scmi/sandbox-scmi_devices.c
+++ b/drivers/firmware/scmi/sandbox-scmi_devices.c
@@ -62,12 +62,13 @@ static int sandbox_scmi_devices_remove(struct udevice *dev)
if (!devices)
return 0;
 
-   for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) {
-   int ret2 = reset_free(devices->reset + n);
+   if (IS_ENABLED(CONFIG_RESET_SCMI))
+   for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) {
+   int ret2 = reset_free(devices->reset + n);
 
-   if (ret2 && !ret)
-   ret = ret2;
-   }
+   if (ret2 && !ret)
+   ret = ret2;
+   }
 
return ret;
 }
@@ -89,39 +90,53 @@ static int sandbox_scmi_devices_probe(struct udevice *dev)
.regul_count = SCMI_TEST_DEVICES_VOLTD_COUNT,
};
 
-   ret = power_domain_get_by_index(dev, priv->devices.pwdom, 0);
-   if (ret) {
-   dev_err(dev, "%s: Failed on power domain\n", __func__);
-   return ret;
-   }
-
-   for (n = 0; n < SCMI_TEST_DEVICES_CLK_COUNT; n++) {
-   ret = clk_get_by_index(dev, n, priv->devices.clk + n);
+   if (IS_ENABLED(CONFIG_SCMI_

[PATCH v2 1/5] test: dm: skip scmi tests against disabled protocols

2023-11-12 Thread AKASHI Takahiro
This is a precautionary change to make scmi tests workable whether or not
a specific protocol be enabled.

Signed-off-by: AKASHI Takahiro 
---
 test/dm/scmi.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/test/dm/scmi.c b/test/dm/scmi.c
index da45314f2e4c..2f63f2da16fb 100644
--- a/test/dm/scmi.c
+++ b/test/dm/scmi.c
@@ -217,6 +217,9 @@ static int dm_test_scmi_power_domains(struct 
unit_test_state *uts)
u8 *name;
int ret;
 
+   if (!IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN))
+   return 0;
+
/* preparation */
ut_assertok(load_sandbox_scmi_test_devices(uts, , ));
ut_assertnonnull(agent);
@@ -317,6 +320,9 @@ static int dm_test_scmi_clocks(struct unit_test_state *uts)
int ret_dev;
int ret;
 
+   if (!IS_ENABLED(CONFIG_CLK_SCMI))
+   return 0;
+
ret = load_sandbox_scmi_test_devices(uts, , );
if (ret)
return ret;
@@ -382,6 +388,9 @@ static int dm_test_scmi_resets(struct unit_test_state *uts)
struct udevice *agent_dev, *reset_dev, *dev = NULL;
int ret;
 
+   if (!IS_ENABLED(CONFIG_RESET_SCMI))
+   return 0;
+
ret = load_sandbox_scmi_test_devices(uts, , );
if (ret)
return ret;
@@ -418,6 +427,9 @@ static int dm_test_scmi_voltage_domains(struct 
unit_test_state *uts)
struct udevice *dev;
struct udevice *regul0_dev;
 
+   if (!IS_ENABLED(CONFIG_DM_REGULATOR_SCMI))
+   return 0;
+
ut_assertok(load_sandbox_scmi_test_devices(uts, , ));
 
scmi_devices = sandbox_scmi_devices_ctx(dev);
-- 
2.34.1



[PATCH v2 0/5] cmd: add scmi command

2023-11-12 Thread AKASHI Takahiro
"Scmi" command will be re-introduced per Michal's request.
The functionality is the same as I put it in my patch set of adding
SCMI base protocol support, but made some tweak to make UT, "ut dm
scmi_cmd," more flexible and tolerable when enabling/disabling a specific
SCMI protocol for test purpose.

Each commit may have some change history inherited from the preceding
patch series.

Test

The patch series was tested on the following platforms:
* sandbox

Prerequisite:
=
* This patch series is based on the latest master.

Changes:

v2(Nov 13, 2023)
* localize global variables to avoid pytest errors.

AKASHI Takahiro (5):
  test: dm: skip scmi tests against disabled protocols
  firmware: scmi: support protocols on sandbox only if enabled
  cmd: add scmi command for SCMI firmware
  doc: cmd: add documentation for scmi
  test: dm: add scmi command test

 cmd/Kconfig  |   9 +
 cmd/Makefile |   1 +
 cmd/scmi.c   | 384 +++
 configs/sandbox_defconfig|   1 +
 doc/usage/cmd/scmi.rst   | 126 ++
 doc/usage/index.rst  |   1 +
 drivers/firmware/scmi/sandbox-scmi_agent.c   |  27 +-
 drivers/firmware/scmi/sandbox-scmi_devices.c |  78 ++--
 test/dm/scmi.c   |  93 +
 9 files changed, 687 insertions(+), 33 deletions(-)
 create mode 100644 cmd/scmi.c
 create mode 100644 doc/usage/cmd/scmi.rst

-- 
2.34.1



Re: [PATCH 5/5] test: dm: add scmi command test

2023-11-12 Thread AKASHI Takahiro
Hi Tom,

On Fri, Nov 10, 2023 at 01:21:37PM -0500, Tom Rini wrote:
> On Wed, Oct 25, 2023 at 02:14:27PM +0900, AKASHI Takahiro wrote:
> 
> > In this test, "scmi" command is tested against different sub-commands.
> > Please note that scmi command is for debug purpose and is not intended
> > in production system.
> > 
> > Signed-off-by: AKASHI Takahiro 
> > Reviewed-by: Simon Glass 
> > Reviewed-by: Etienne Carriere 
> 
> The test part of this still fails:
> https://source.denx.de/u-boot/u-boot/-/jobs/732077
> 
> I don't know why more output wasn't captured, when I run it locally
> instead I get:
> == FAILURES 
> ===
> ___ test_ut[ut_dm_dm_test_scmi_cmd] 
> ___
> test/py/u_boot_spawn.py:195: in expect
> c = os.read(self.fd, 1024).decode(errors='replace')
> E   OSError: [Errno 5] Input/output error
> 
> During handling of the above exception, another exception occurred:
> test/py/tests/test_ut.py:502: in test_ut
> output = u_boot_console.run_command('ut ' + ut_subtest)
> test/py/u_boot_console_base.py:266: in run_command
> m = self.p.expect([self.prompt_compiled] + self.bad_patterns)
> test/py/u_boot_spawn.py:204: in expect
> raise ValueError('U-Boot exited with %s' % info)
> E   ValueError: U-Boot exited with signal 11 (SIGSEGV)


The command uses global variables which hold pointers to 'struct udevice'
which are to be shared between the main and the sub-commands.
Since pytest framework executes ut tests twice, once with a (normal?) device
tree and once with a flat tree,  udevices will be *voided* between
two executions.

I will fix it in v2.

Thanks,
-Takahiro Akashi


>  Captured stdout call 
> -
> => ut dm dm_test_scmi_cmd
> Test: dm_test_scmi_cmd: scmi.c
> SCMI device: scmi
>   protocol version: 0x2
>   # of agents: 2
>   0: platform
> > 1: OSPM
>   # of protocols: 4
>   Power domain management
>   Clock management
>   Reset domain management
>   Voltage domain management
>   vendor: U-Boot
>   sub vendor: Sandbox
>   impl version: 0x1
> Denying access to device:0 failed (-13)
> Denying access to protocol:0x14 on device:0 failed (-13)
> Reset failed (-13)
> Test: dm_test_scmi_cmd: scmi.c (flat tree)
> SCMI device: Q
> === short test summary info 
> ===
> FAILED test/py/tests/test_ut.py::test_ut[ut_dm_dm_test_scmi_cmd] - 
> ValueError: U-Boot exited...
> 
> -- 
> Tom




signature.asc
Description: PGP signature


[PATCH] firmware: scmi: correct a validity check against power domain id

2023-11-06 Thread AKASHI Takahiro
A power domain id on sandbox should be in the range from zero to
ARRAY_SIZE(scmi_pwdom) - 1. Correct the validity check logic.

Signed-off-by: AKASHI Takahiro 
Fixes: CID 467401
Fixes: CID 467405
---
 drivers/firmware/scmi/sandbox-scmi_agent.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c 
b/drivers/firmware/scmi/sandbox-scmi_agent.c
index 9f5f497e0a6c..d13180962662 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -576,7 +576,7 @@ static int sandbox_scmi_pwd_attribs(struct udevice *dev, 
struct scmi_msg *msg)
domain_id = *(u32 *)msg->in_msg;
out = (struct scmi_pwd_attrs_out *)msg->out_msg;
 
-   if (domain_id > ARRAY_SIZE(scmi_pwdom)) {
+   if (domain_id >= ARRAY_SIZE(scmi_pwdom)) {
out->status = SCMI_NOT_FOUND;
 
return 0;
@@ -613,7 +613,7 @@ static int sandbox_scmi_pwd_state_set(struct udevice *dev, 
struct scmi_msg *msg)
in = (struct scmi_pwd_state_set_in *)msg->in_msg;
status = (s32 *)msg->out_msg;
 
-   if (in->domain_id > ARRAY_SIZE(scmi_pwdom)) {
+   if (in->domain_id >= ARRAY_SIZE(scmi_pwdom)) {
*status = SCMI_NOT_FOUND;
 
return 0;
@@ -653,7 +653,7 @@ static int sandbox_scmi_pwd_state_get(struct udevice *dev, 
struct scmi_msg *msg)
domain_id = *(u32 *)msg->in_msg;
out = (struct scmi_pwd_state_get_out *)msg->out_msg;
 
-   if (domain_id > ARRAY_SIZE(scmi_pwdom)) {
+   if (domain_id >= ARRAY_SIZE(scmi_pwdom)) {
out->status = SCMI_NOT_FOUND;
 
return 0;
@@ -686,7 +686,7 @@ static int sandbox_scmi_pwd_name_get(struct udevice *dev, 
struct scmi_msg *msg)
domain_id = *(u32 *)msg->in_msg;
out = (struct scmi_pwd_name_get_out *)msg->out_msg;
 
-   if (domain_id > ARRAY_SIZE(scmi_pwdom)) {
+   if (domain_id >= ARRAY_SIZE(scmi_pwdom)) {
out->status = SCMI_NOT_FOUND;
 
return 0;
-- 
2.34.1



Re: [RFC 01/13] cmd: bootefi: unfold do_bootefi_image()

2023-10-29 Thread AKASHI Takahiro
Hi Ilias,

On Fri, Oct 27, 2023 at 03:23:07PM +0300, Ilias Apalodimas wrote:
> Akashi-san
> 
> On Fri, 27 Oct 2023 at 04:00, Tom Rini  wrote:
> >
> > On Fri, Oct 27, 2023 at 09:25:44AM +0900, AKASHI Takahiro wrote:
> > > On Thu, Oct 26, 2023 at 01:01:52PM +0200, Heinrich Schuchardt wrote:
> > > > On 10/26/23 07:30, AKASHI Takahiro wrote:
> > > > > Unfold do_bootefi_image() into do_bootefi() for the sake of the 
> > > > > succeeding
> > > > > refactor work.
> > > > >
> 
> I don't disagree with the patchset, but what the patch does is pretty
> obvious.

Yeah, that is what I tried to do in this patch series, i.e. each step
be as trivial as possible to ensure that the semantics is unchanged
while the code is being morphed.

> It would help a lot to briefly describe how the unfolding
> process helps the refactoring.

Not sure, but will add a few more words.

Thanks,
-Takahiro Akashi


> Thanks
> /Ilias
> > > > > Signed-off-by: AKASHI Takahiro 
> > > > > ---
> > > > >   cmd/bootefi.c | 101 
> > > > > ++
> > > > >   1 file changed, 37 insertions(+), 64 deletions(-)
> > > > >
> > > > > diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> > > > > index 20e5c94a33a4..1b28bf5a318d 100644
> > > > > --- a/cmd/bootefi.c
> > > > > +++ b/cmd/bootefi.c
> > > > > @@ -425,58 +425,6 @@ static int do_efibootmgr(void)
> > > > >   return CMD_RET_SUCCESS;
> > > > >   }
> > > > >
> > > > > -/**
> > > > > - * do_bootefi_image() - execute EFI binary
> > > > > - *
> > > > > - * Set up memory image for the binary to be loaded, prepare device 
> > > > > path, and
> > > > > - * then call do_bootefi_exec() to execute it.
> > > > > - *
> > > > > - * @image_opt:   string with image start address
> > > > > - * @size_opt:string with image size or NULL
> > > > > - * Return:   status code
> > > > > - */
> > > > > -static int do_bootefi_image(const char *image_opt, const char 
> > > > > *size_opt)
> > > > > -{
> > > > > - void *image_buf;
> > > > > - unsigned long addr, size;
> > > > > - efi_status_t ret;
> > > > > -
> > > > > -#ifdef CONFIG_CMD_BOOTEFI_HELLO
> > > > > - if (!strcmp(image_opt, "hello")) {
> > > > > - image_buf = __efi_helloworld_begin;
> > > > > - size = __efi_helloworld_end - __efi_helloworld_begin;
> > > > > - efi_clear_bootdev();
> > > > > - } else
> > > > > -#endif
> > > > > - {
> > > > > - addr = strtoul(image_opt, NULL, 16);
> > > > > - /* Check that a numeric value was passed */
> > > > > - if (!addr)
> > > > > - return CMD_RET_USAGE;
> > > > > - image_buf = map_sysmem(addr, 0);
> > > > > -
> > > > > - if (size_opt) {
> > > > > - size = strtoul(size_opt, NULL, 16);
> > > > > - if (!size)
> > > > > - return CMD_RET_USAGE;
> > > > > - efi_clear_bootdev();
> > > > > - } else {
> > > > > - if (image_buf != image_addr) {
> > > > > - log_err("No UEFI binary known at %s\n",
> > > > > - image_opt);
> > > > > - return CMD_RET_FAILURE;
> > > > > - }
> > > > > - size = image_size;
> > > > > - }
> > > > > - }
> > > > > - ret = efi_run_image(image_buf, size);
> > > > > -
> > > > > - if (ret != EFI_SUCCESS)
> > > > > - return CMD_RET_FAILURE;
> > > > > -
> > > > > - return CMD_RET_SUCCESS;
> > > > > -}
> > > > > -
> > > > >   /**
> > > > >* efi_run_image() - run loaded UEFI image
> > > > >*
> > > > > @@ -648,8 +596,9 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int 
> > > > > flag, int argc,
> > > > > char *const argv[])
> > > > >   {
> > > > >   efi_status_t ret;
> > > > > - char *img_addr, *img_size, *str_copy, *pos;
> > > > > - void *fdt;
> > > > > + char *p;
> > > > > + void *fdt, *image_buf;
> > > > > + unsigned long addr, size;
> > > > >
> > > > >   if (argc < 2)
> > > > >   return CMD_RET_USAGE;
> > > > > @@ -684,18 +633,42 @@ static int do_bootefi(struct cmd_tbl *cmdtp, 
> > > > > int flag, int argc,
> > > > >   if (!strcmp(argv[1], "selftest"))
> > > > >   return do_efi_selftest();
> > > > >   #endif
> > > > > - str_copy = strdup(argv[1]);
> > > > > - if (!str_copy) {
> > > > > - log_err("Out of memory\n");
> > > > > - return CMD_RET_FAILURE;
> > > > > +
> > > > > +#ifdef CONFIG_CMD_BOOTEFI_HELLO
> > > >
> > > > I would prefer a normal if and let the linker sort it out.
> > >
> > > Here I focused on simply unfolding("moving") the function, keeping the 
> > > code
> > > as same as possible. Any how the code is in a tentative form
> > > at this point and will be reshaped in later patches, using IS_ENABLED().
> > > Please look at the final code after applying the whole series.
> >
> > I also agree with this approach.
> >
> > --
> > Tom


Re: [RFC 11/13] fs: remove explicit efi configuration dependency

2023-10-26 Thread AKASHI Takahiro
On Thu, Oct 26, 2023 at 08:47:52AM -0400, Tom Rini wrote:
> On Thu, Oct 26, 2023 at 05:48:30PM +0900, AKASHI Takahiro wrote:
> > On Thu, Oct 26, 2023 at 09:58:53AM +0200, Heinrich Schuchardt wrote:
> > > 
> > > 
> > > Am 26. Oktober 2023 07:30:50 MESZ schrieb AKASHI Takahiro 
> > > :
> > > >Now it is clear that the feature actually depends on efi interfaces,
> > > >not "bootefi" command. efi_set_bootdev() will automatically be nullified
> > > >if necessary efi component is disabled.
> > > >
> > > >Signed-off-by: AKASHI Takahiro 
> > > >---
> > > > fs/fs.c | 7 +++
> > > > 1 file changed, 3 insertions(+), 4 deletions(-)
> > > >
> > > >diff --git a/fs/fs.c b/fs/fs.c
> > > >index 4cb4310c9cc2..70cdb594c4c8 100644
> > > >--- a/fs/fs.c
> > > >+++ b/fs/fs.c
> > > >@@ -791,10 +791,9 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int 
> > > >argc, char *const argv[],
> > > > return 1;
> > > > }
> > > > 
> > > >-if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
> > > >-efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
> > > >-(argc > 4) ? argv[4] : "", 
> > > >map_sysmem(addr, 0),
> > > >-len_read);
> > > >+efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
> > > 
> > > This function should not exist for CONFIG_EFI_LOADER=n. There are other 
> > > places where the function is invoked. Please, review all of them.
> > 
> > Please go through the whole patch set, especially patch#8
> > "efi_loader: split unrelated code from efi_bootmgr.c".
> > 
> > efi_[set|clear]_bootdev() will be nullified if not necessary.
> 
> In this case I think what we have here today is more readable / clearer.
> We don't need empty functions as we can either do like this section of
> the code does today or the linker will discard things correctly as it's
> a case of funcB() calls funcA() and nothing calls funcB() so it will be
> discarded. I don't know without digging through the series more what the
> correct IS_ENABLED() guard should be here (and then also in patch #10).

If I correctly understand your question, it is my point in this commit.

I believe that a caller should not be bothered by thinking of what efi CONFIG
be used for the guard. All that should be done is to just put a right hook
(efi_set_bootdev() in this case) at a right place as a caller (do_load()
in this case) is apparently irrelevant to UEFI subsystem.
Hereafter, whatever rework may be done on UEFI side (like my refactoring
here), other code won't need to be modified.

If you want to rely on an intelligent linker behavior, I would suggest
another approach, modifying efi_set_bootdev() as follows;

efi_set_bootdev(...)
{
if (!IS_ENABLED(EFI_BINARY_EXEC))
return;
...
}

I hope it would also work.

-Takahiro Akashi

> 
> -- 
> Tom




signature.asc
Description: PGP signature


Re: [RFC 02/13] cmd: bootefi: re-organize do_bootefi_image()

2023-10-26 Thread AKASHI Takahiro
On Thu, Oct 26, 2023 at 12:44:00PM +0200, Heinrich Schuchardt wrote:
> On 10/26/23 07:30, AKASHI Takahiro wrote:
> > Decompose and re-organize do_bootefi_image() into three parts for
> > the succeeding refactor work.
> > 
> > Signed-off-by: AKASHI Takahiro 
> > ---
> >   cmd/Kconfig  | 15 ++--
> >   cmd/bootefi.c| 82 ++--
> >   include/efi_loader.h |  2 --
> >   3 files changed, 69 insertions(+), 30 deletions(-)
> > 
> > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > index 0eb739203ade..825a41d68aad 100644
> > --- a/cmd/Kconfig
> > +++ b/cmd/Kconfig
> > @@ -363,9 +363,19 @@ config CMD_BOOTEFI
> > help
> >   Boot an EFI image from memory.
> > 
> > +if CMD_BOOTEFI
> > +config CMD_BOOTEFI_BINARY
> > +   bool "Allow booting an EFI binary directly"
> > +   depends on BOOTEFI_BOOTMGR
> > +   default y
> > +   help
> > + Select this option to enable direct execution of binary at 'bootefi'.
> > + This subcommand will allow you to load the UEFI binary using
> > + other U-Boot commands or external methods and then run isince 2021. t.
> > +
> >   config CMD_BOOTEFI_BOOTMGR
> 
> This symbol is in lib/efi_loader/Kconfig:
> lib/efi_loader/Kconfig:35:config CMD_BOOTEFI_BOOTMGR

In the cover letter, I mentioned that the RFC was based on Tom's branch.
> 
> Please, rebase your series on origin/master.

If you agree to my idea in this whole series, I will re-post a new version,
rebasing it on Tom's "-next" branch with CONFIG_CMDLINE tweaks.
So please review other commits as well.

Thanks,
-Takahiro Akashi

> Best regards
> 
> Heinrich
> 
> > bool "UEFI Boot Manager command"
> > -   depends on BOOTEFI_BOOTMGR && CMD_BOOTEFI
> > +   depends on BOOTEFI_BOOTMGR
> > default y
> > help
> >   Select this option to enable the 'bootmgr' subcommand of 'bootefi'.
> > @@ -374,7 +384,7 @@ config CMD_BOOTEFI_BOOTMGR
> > 
> >   config CMD_BOOTEFI_HELLO_COMPILE
> > bool "Compile a standard EFI hello world binary for testing"
> > -   depends on CMD_BOOTEFI && !CPU_V7M
> > +   depends on !CPU_V7M
> > default y
> > help
> >   This compiles a standard EFI hello world application with U-Boot so
> > @@ -396,6 +406,7 @@ config CMD_BOOTEFI_HELLO
> >   up EFI support on a new architecture.
> > 
> >   source lib/efi_selftest/Kconfig
> > +endif
> > 
> >   config CMD_BOOTMENU
> > bool "bootmenu"
> > diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> > index 1b28bf5a318d..ae00bba3b4f0 100644
> > --- a/cmd/bootefi.c
> > +++ b/cmd/bootefi.c
> > @@ -491,7 +491,6 @@ out:
> > return (ret != EFI_SUCCESS) ? ret : ret2;
> >   }
> > 
> > -#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
> >   static efi_status_t bootefi_run_prepare(const char *load_options_path,
> > struct efi_device_path *device_path,
> > struct efi_device_path *image_path,
> > @@ -581,7 +580,6 @@ static int do_efi_selftest(void)
> > 
> > return ret != EFI_SUCCESS;
> >   }
> > -#endif /* CONFIG_CMD_BOOTEFI_SELFTEST */
> > 
> >   /**
> >* do_bootefi() - execute `bootefi` command
> > @@ -603,14 +601,6 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
> > int argc,
> > if (argc < 2)
> > return CMD_RET_USAGE;
> > 
> > -   /* Initialize EFI drivers */
> > -   ret = efi_init_obj_list();
> > -   if (ret != EFI_SUCCESS) {
> > -   log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
> > -   ret & ~EFI_ERROR_MASK);
> > -   return CMD_RET_FAILURE;
> > -   }
> > -
> > if (argc > 2) {
> > uintptr_t fdt_addr;
> > 
> > @@ -619,29 +609,54 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int 
> > flag, int argc,
> > } else {
> > fdt = EFI_FDT_USE_INTERNAL;
> > }
> > -   ret = efi_install_fdt(fdt);
> > -   if (ret == EFI_INVALID_PARAMETER)
> > -   return CMD_RET_USAGE;
> > -   else if (ret != EFI_SUCCESS)
> > -   return CMD_RET_FAILURE;
> > 
> > -   if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
> > -   if (!strcmp(argv[1], "bootmgr"))
> > -   return do_efibootmgr();
> > +   if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR) &&
> > +   !strcmp(argv[1], "bootmgr")) {
> >

Re: [RFC 01/13] cmd: bootefi: unfold do_bootefi_image()

2023-10-26 Thread AKASHI Takahiro
On Thu, Oct 26, 2023 at 01:01:52PM +0200, Heinrich Schuchardt wrote:
> On 10/26/23 07:30, AKASHI Takahiro wrote:
> > Unfold do_bootefi_image() into do_bootefi() for the sake of the succeeding
> > refactor work.
> > 
> > Signed-off-by: AKASHI Takahiro 
> > ---
> >   cmd/bootefi.c | 101 ++
> >   1 file changed, 37 insertions(+), 64 deletions(-)
> > 
> > diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> > index 20e5c94a33a4..1b28bf5a318d 100644
> > --- a/cmd/bootefi.c
> > +++ b/cmd/bootefi.c
> > @@ -425,58 +425,6 @@ static int do_efibootmgr(void)
> > return CMD_RET_SUCCESS;
> >   }
> > 
> > -/**
> > - * do_bootefi_image() - execute EFI binary
> > - *
> > - * Set up memory image for the binary to be loaded, prepare device path, 
> > and
> > - * then call do_bootefi_exec() to execute it.
> > - *
> > - * @image_opt: string with image start address
> > - * @size_opt:  string with image size or NULL
> > - * Return: status code
> > - */
> > -static int do_bootefi_image(const char *image_opt, const char *size_opt)
> > -{
> > -   void *image_buf;
> > -   unsigned long addr, size;
> > -   efi_status_t ret;
> > -
> > -#ifdef CONFIG_CMD_BOOTEFI_HELLO
> > -   if (!strcmp(image_opt, "hello")) {
> > -   image_buf = __efi_helloworld_begin;
> > -   size = __efi_helloworld_end - __efi_helloworld_begin;
> > -   efi_clear_bootdev();
> > -   } else
> > -#endif
> > -   {
> > -   addr = strtoul(image_opt, NULL, 16);
> > -   /* Check that a numeric value was passed */
> > -   if (!addr)
> > -   return CMD_RET_USAGE;
> > -   image_buf = map_sysmem(addr, 0);
> > -
> > -   if (size_opt) {
> > -   size = strtoul(size_opt, NULL, 16);
> > -   if (!size)
> > -   return CMD_RET_USAGE;
> > -   efi_clear_bootdev();
> > -   } else {
> > -   if (image_buf != image_addr) {
> > -   log_err("No UEFI binary known at %s\n",
> > -   image_opt);
> > -   return CMD_RET_FAILURE;
> > -   }
> > -   size = image_size;
> > -   }
> > -   }
> > -   ret = efi_run_image(image_buf, size);
> > -
> > -   if (ret != EFI_SUCCESS)
> > -   return CMD_RET_FAILURE;
> > -
> > -   return CMD_RET_SUCCESS;
> > -}
> > -
> >   /**
> >* efi_run_image() - run loaded UEFI image
> >*
> > @@ -648,8 +596,9 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
> > int argc,
> >   char *const argv[])
> >   {
> > efi_status_t ret;
> > -   char *img_addr, *img_size, *str_copy, *pos;
> > -   void *fdt;
> > +   char *p;
> > +   void *fdt, *image_buf;
> > +   unsigned long addr, size;
> > 
> > if (argc < 2)
> > return CMD_RET_USAGE;
> > @@ -684,18 +633,42 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int 
> > flag, int argc,
> > if (!strcmp(argv[1], "selftest"))
> > return do_efi_selftest();
> >   #endif
> > -   str_copy = strdup(argv[1]);
> > -   if (!str_copy) {
> > -   log_err("Out of memory\n");
> > -   return CMD_RET_FAILURE;
> > +
> > +#ifdef CONFIG_CMD_BOOTEFI_HELLO
> 
> I would prefer a normal if and let the linker sort it out.

Here I focused on simply unfolding("moving") the function, keeping the code
as same as possible. Any how the code is in a tentative form 
at this point and will be reshaped in later patches, using IS_ENABLED().
Please look at the final code after applying the whole series.

-Takahiro Akashi


> Otherwise looks good to me.
> 
> Best regards
> 
> Heinrich
> 
> > +   if (!strcmp(argv[1], "hello")) {
> > +   image_buf = __efi_helloworld_begin;
> > +   size = __efi_helloworld_end - __efi_helloworld_begin;
> > +   efi_clear_bootdev();
> > +   } else
> > +#endif
> > +   {
> > +   addr = strtoul(argv[1], NULL, 16);
> > +   /* Check that a numeric value was passed */
> > +   if (!addr)
> > +   return CMD_RET_USAGE;
> > +   image_buf = map_sysmem(addr, 0);
> > +
> > +   p  = strchr(argv[1], ':');
> > +   

Re: [RFC 11/13] fs: remove explicit efi configuration dependency

2023-10-26 Thread AKASHI Takahiro
On Thu, Oct 26, 2023 at 09:58:53AM +0200, Heinrich Schuchardt wrote:
> 
> 
> Am 26. Oktober 2023 07:30:50 MESZ schrieb AKASHI Takahiro 
> :
> >Now it is clear that the feature actually depends on efi interfaces,
> >not "bootefi" command. efi_set_bootdev() will automatically be nullified
> >if necessary efi component is disabled.
> >
> >Signed-off-by: AKASHI Takahiro 
> >---
> > fs/fs.c | 7 +++
> > 1 file changed, 3 insertions(+), 4 deletions(-)
> >
> >diff --git a/fs/fs.c b/fs/fs.c
> >index 4cb4310c9cc2..70cdb594c4c8 100644
> >--- a/fs/fs.c
> >+++ b/fs/fs.c
> >@@ -791,10 +791,9 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, 
> >char *const argv[],
> > return 1;
> > }
> > 
> >-if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
> >-efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
> >-(argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
> >-len_read);
> >+efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
> 
> This function should not exist for CONFIG_EFI_LOADER=n. There are other 
> places where the function is invoked. Please, review all of them.

Please go through the whole patch set, especially patch#8
"efi_loader: split unrelated code from efi_bootmgr.c".

efi_[set|clear]_bootdev() will be nullified if not necessary.

-Takahiro Akashi

> Best regards
> 
> Heinrich
> 
> 
> >+(argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
> >+len_read);
> > 
> > printf("%llu bytes read in %lu ms", len_read, time);
> > if (time > 0) {


[RFC 13/13] block: rkmtd: select CONFIG_RANDOM_UUID explicitly

2023-10-25 Thread AKASHI Takahiro
This option is necessary to compile any way.

Signed-off-by: AKASHI Takahiro 
---
 drivers/block/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 048a6caef00f..5cda21551043 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -265,6 +265,7 @@ config SYS_64BIT_LBA
 
 config RKMTD
bool "Rockchip rkmtd virtual block device"
+   imply RANDOM_UUID
help
  Enable "rkmtd" class and driver to create a virtual block device
  to transfer Rockchip boot block data to and from NAND with block
-- 
2.34.1



[RFC 12/13] lib: uuid: move CONFIG_RANDOM_UUID

2023-10-25 Thread AKASHI Takahiro
This option is independent from any commands and should be managed
under lib. For instance, drivers/block/rkmtd.c is a user.

It would be better to remove this configuration.

Signed-off-by: AKASHI Takahiro 
---
 cmd/Kconfig | 7 ---
 lib/Kconfig | 7 +++
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 3a8483f7d042..c42745d06b39 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1143,13 +1143,6 @@ config CMD_GPT
  Enable the 'gpt' command to ready and write GPT style partition
  tables.
 
-config RANDOM_UUID
-   bool "GPT Random UUID generation"
-   select LIB_UUID
-   help
- Enable the generation of partitions with random UUIDs if none
- are provided.
-
 config CMD_GPT_RENAME
bool "GPT partition renaming commands"
depends on CMD_GPT
diff --git a/lib/Kconfig b/lib/Kconfig
index f6ca559897e7..b6d580c30615 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -74,6 +74,13 @@ config HAVE_PRIVATE_LIBGCC
 config LIB_UUID
bool
 
+config RANDOM_UUID
+   bool "GPT Random UUID generation"
+   select LIB_UUID
+   help
+ Enable the generation of partitions with random UUIDs if none
+ are provided.
+
 config SPL_LIB_UUID
depends on SPL
bool
-- 
2.34.1



[RFC 11/13] fs: remove explicit efi configuration dependency

2023-10-25 Thread AKASHI Takahiro
Now it is clear that the feature actually depends on efi interfaces,
not "bootefi" command. efi_set_bootdev() will automatically be nullified
if necessary efi component is disabled.

Signed-off-by: AKASHI Takahiro 
---
 fs/fs.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index 4cb4310c9cc2..70cdb594c4c8 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -791,10 +791,9 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[],
return 1;
}
 
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
-   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
-   (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
-   len_read);
+   efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "",
+   (argc > 4) ? argv[4] : "", map_sysmem(addr, 0),
+   len_read);
 
printf("%llu bytes read in %lu ms", len_read, time);
if (time > 0) {
-- 
2.34.1



[RFC 10/13] net: tftp: remove explicit efi configuration dependency

2023-10-25 Thread AKASHI Takahiro
Now it is clear that the feature actually depends on efi interfaces,
not "bootefi" command. efi_set_bootdev() will automatically be nullified
if necessary efi component is disabled.

Signed-off-by: AKASHI Takahiro 
---
 net/tftp.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/net/tftp.c b/net/tftp.c
index 88e71e67de35..2e335413492b 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -302,12 +302,10 @@ static void tftp_complete(void)
time_start * 1000, "/s");
}
puts("\ndone\n");
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) {
-   if (!tftp_put_active)
-   efi_set_bootdev("Net", "", tftp_filename,
-   map_sysmem(tftp_load_addr, 0),
-   net_boot_file_size);
-   }
+   if (!tftp_put_active)
+   efi_set_bootdev("Net", "", tftp_filename,
+   map_sysmem(tftp_load_addr, 0),
+   net_boot_file_size);
net_set_state(NETLOOP_SUCCESS);
 }
 
-- 
2.34.1



[RFC 09/13] efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR

2023-10-25 Thread AKASHI Takahiro
At this point, EFI boot manager interfaces is fully independent from
bootefi command. So just rename the configuration parameter.

Signed-off-by: AKASHI Takahiro 
---
 boot/Makefile   | 2 +-
 cmd/Kconfig | 4 ++--
 cmd/efidebug.c  | 4 ++--
 lib/efi_loader/Kconfig  | 2 +-
 lib/efi_loader/Makefile | 2 +-
 test/boot/bootflow.c| 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/boot/Makefile b/boot/Makefile
index 4eaa5eab4b77..48d74c67d680 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -32,7 +32,7 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_CROS) += bootm.o bootm_os.o 
bootmeth_cros.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SCRIPT) += bootmeth_script.o
 ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL
-obj-$(CONFIG_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
+obj-$(CONFIG_EFI_BOOTMGR) += bootmeth_efi_mgr.o
 obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o
diff --git a/cmd/Kconfig b/cmd/Kconfig
index bf16fad04d37..3a8483f7d042 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -375,7 +375,7 @@ config CMD_BOOTEFI_BINARY
 
 config CMD_BOOTEFI_BOOTMGR
bool "UEFI Boot Manager command"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BOOTMGR
default y
help
  Select this option to enable the 'bootmgr' subcommand of 'bootefi'.
@@ -2122,7 +2122,7 @@ config CMD_EFIDEBUG
 config CMD_EFICONFIG
bool "eficonfig - provide menu-driven uefi variables maintenance 
interface"
default y if !HAS_BOARD_SIZE_LIMIT
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BOOTMGR
select MENU
help
  Enable the 'eficonfig' command which provides the menu-driven UEFI
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index c2b2b074e094..7ba2331ad19f 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -1335,7 +1335,7 @@ static __maybe_unused int do_efi_test_bootmgr(struct 
cmd_tbl *cmdtp, int flag,
 }
 
 static struct cmd_tbl cmd_efidebug_test_sub[] = {
-#ifdef CONFIG_BOOTEFI_BOOTMGR
+#ifdef CONFIG_EFI_BOOTMGR
U_BOOT_CMD_MKENT(bootmgr, CONFIG_SYS_MAXARGS, 1, do_efi_test_bootmgr,
 "", ""),
 #endif
@@ -1526,7 +1526,7 @@ U_BOOT_LONGHELP(efidebug,
"  - show UEFI memory map\n"
"efidebug tables\n"
"  - show UEFI configuration tables\n"
-#ifdef CONFIG_BOOTEFI_BOOTMGR
+#ifdef CONFIG_EFI_BOOTMGR
"efidebug test bootmgr\n"
"  - run simple bootmgr for test\n"
 #endif
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 987a990509f3..27d3f52897a9 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -41,7 +41,7 @@ config EFI_BINARY_EXEC
  You may enable CMD_BOOTEFI_BINARY so that you can use bootefi
  command to do that.
 
-config BOOTEFI_BOOTMGR
+config EFI_BOOTMGR
bool "UEFI Boot Manager"
default y
select BOOTMETH_GLOBAL if BOOTSTD
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index 0a2cb6e3c476..f882474bba6f 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -42,7 +42,7 @@ targets += initrddump.o
 endif
 
 obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
-obj-$(CONFIG_BOOTEFI_BOOTMGR) += efi_bootmgr.o
+obj-$(CONFIG_EFI_BOOTMGR) += efi_bootmgr.o
 obj-y += efi_boottime.o
 obj-y += efi_helper.o
 obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 47c552a94165..7eafdc79de3b 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -374,7 +374,7 @@ static int bootflow_system(struct unit_test_state *uts)
 {
struct udevice *bootstd, *dev;
 
-   if (!IS_ENABLED(CONFIG_BOOTEFI_BOOTMGR))
+   if (!IS_ENABLED(CONFIG_EFI_BOOTMGR))
return -EAGAIN;
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, ));
ut_assertok(device_bind(bootstd, DM_DRIVER_GET(bootmeth_efi_mgr),
-- 
2.34.1



[RFC 08/13] efi_loader: split unrelated code from efi_bootmgr.c

2023-10-25 Thread AKASHI Takahiro
Some code moved from cmd/bootefi.c is actually necessary only for "bootefi
" command (starting an image manually loaded by a user using U-Boot
load commands or other methods (like JTAG debugger).

The code will never been opted out as unused code by a compiler which
doesn't know how EFI boot manager is implemented. So introduce a new
configuration, CONFIG_EFI_BINARY_EXEC, to enforce theem opted out
explicitly.

Signed-off-by: AKASHI Takahiro 
---
 boot/Kconfig |   4 +-
 cmd/Kconfig  |   6 +-
 include/efi_loader.h |  28 +-
 lib/efi_loader/Kconfig   |   9 +
 lib/efi_loader/efi_bootmgr.c | 480 --
 lib/efi_loader/efi_device_path.c |   3 +-
 lib/efi_loader/efi_helper.c  | 486 ++-
 7 files changed, 516 insertions(+), 500 deletions(-)

diff --git a/boot/Kconfig b/boot/Kconfig
index a441fac8ade1..d371d0a25962 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -511,7 +511,7 @@ config BOOTMETH_EXTLINUX_PXE
 
 config BOOTMETH_EFILOADER
bool "Bootdev support for EFI boot"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BINARY_EXEC
default y
help
  Enables support for EFI boot using bootdevs. This makes the
@@ -546,7 +546,7 @@ config BOOTMETH_DISTRO
select BOOTMETH_SCRIPT if CMDLINE # E.g. Armbian uses scripts
select BOOTMETH_EXTLINUX  # E.g. Debian uses these
select BOOTMETH_EXTLINUX_PXE if CMD_PXE && CMD_NET && DM_ETH
-   select BOOTMETH_EFILOADER if BOOTEFI_BOOTMGR # E.g. Ubuntu uses this
+   select BOOTMETH_EFILOADER if EFI_BINARY_EXEC # E.g. Ubuntu uses this
 
 config SPL_BOOTMETH_VBE
bool "Bootdev support for Verified Boot for Embedded (SPL)"
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 81e959c96207..bf16fad04d37 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -274,7 +274,7 @@ config CMD_BOOTMETH
 
 config BOOTM_EFI
bool "Support booting UEFI FIT images"
-   depends on BOOTEFI_BOOTMGR && CMD_BOOTM && FIT
+   depends on EFI_BINARY_EXEC && CMD_BOOTM && FIT
default y
help
  Support booting UEFI FIT images via the bootm command.
@@ -366,7 +366,7 @@ config CMD_BOOTEFI
 if CMD_BOOTEFI
 config CMD_BOOTEFI_BINARY
bool "Allow booting an EFI binary directly"
-   depends on BOOTEFI_BOOTMGR
+   depends on EFI_BINARY_EXEC
default y
help
  Select this option to enable direct execution of binary at 'bootefi'.
@@ -397,7 +397,7 @@ config CMD_BOOTEFI_HELLO_COMPILE
 
 config CMD_BOOTEFI_HELLO
bool "Allow booting a standard EFI hello world for testing"
-   depends on CMD_BOOTEFI_HELLO_COMPILE
+   depends on CMD_BOOTEFI_BINARY && CMD_BOOTEFI_HELLO_COMPILE
default y if CMD_BOOTEFI_SELFTEST
help
  This adds a standard EFI hello world application to U-Boot so that
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 031a8f76846a..e9bc2f540cc8 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -91,11 +91,7 @@ efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len);
  * back to u-boot world
  */
 void efi_restore_gd(void);
-/* Call this to unset the current device name */
-void efi_clear_bootdev(void);
-/* Call this to set the current device name */
-void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
-void *buffer, size_t buffer_size);
+
 /* Called by networking code to memorize the dhcp ack package */
 void efi_net_set_dhcp_ack(void *pkt, int len);
 /* Print information about all loaded images */
@@ -117,10 +113,6 @@ static inline efi_status_t efi_add_runtime_mmio(void 
*mmio_ptr, u64 len)
 
 /* No loader configured, stub out EFI_ENTRY */
 static inline void efi_restore_gd(void) { }
-static inline void efi_clear_bootdev(void) { }
-static inline void efi_set_bootdev(const char *dev, const char *devnr,
-  const char *path, void *buffer,
-  size_t buffer_size) { }
 static inline void efi_net_set_dhcp_ack(void *pkt, int len) { }
 static inline void efi_print_image_infos(void *pc) { }
 static inline efi_status_t efi_launch_capsules(void)
@@ -130,6 +122,20 @@ static inline efi_status_t efi_launch_capsules(void)
 
 #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */
 
+#if CONFIG_IS_ENABLED(EFI_BINARY_EXEC)
+/* Call this to unset the current device name */
+void efi_clear_bootdev(void);
+/* Call this to set the current device name */
+void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
+void *buffer, size_t buffer_size);
+#else
+static inline void efi_clear_bootdev(void) { }
+
+static inline void efi_set_bootdev(const char *dev, const char *devnr,
+  const char *path, void *buffer,
+  s

[RFC 05/13] cmd: bootefi: move library interfaces under lib/efi_loader

2023-10-25 Thread AKASHI Takahiro
In the prior commits, interfaces for executing EFI binary or boot manager
were carved out. Move them under efi_loader directory so that they can
be called from other places without depending on bootefi command.

Signed-off-by: AKASHI Takahiro 
---
 cmd/bootefi.c| 546 ++-
 include/efi_loader.h |  10 +
 lib/efi_loader/efi_bootmgr.c | 517 +
 3 files changed, 551 insertions(+), 522 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 8b0bd07f1ff8..9cf9027bf409 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -7,531 +7,22 @@
 
 #define LOG_CATEGORY LOGC_EFI
 
-#include 
-#include 
-#include 
 #include 
-#include 
+#include 
 #include 
-#include 
-#include 
-#include 
-#include 
+#include 
 #include 
 #include 
-#include 
-#include 
-#include 
 #include 
-#include 
+#include 
 #include 
-#include 
+#include 
+#include 
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static struct efi_device_path *bootefi_image_path;
-static struct efi_device_path *bootefi_device_path;
-static void *image_addr;
-static size_t image_size;
-
-/**
- * efi_get_image_parameters() - return image parameters
- *
- * @img_addr:  address of loaded image in memory
- * @img_size:  size of loaded image
- */
-void efi_get_image_parameters(void **img_addr, size_t *img_size)
-{
-   *img_addr = image_addr;
-   *img_size = image_size;
-}
-
-/**
- * efi_clear_bootdev() - clear boot device
- */
-static void efi_clear_bootdev(void)
-{
-   efi_free_pool(bootefi_device_path);
-   efi_free_pool(bootefi_image_path);
-   bootefi_device_path = NULL;
-   bootefi_image_path = NULL;
-   image_addr = NULL;
-   image_size = 0;
-}
-
-/**
- * efi_set_bootdev() - set boot device
- *
- * This function is called when a file is loaded, e.g. via the 'load' command.
- * We use the path to this file to inform the UEFI binary about the boot 
device.
- *
- * @dev:   device, e.g. "MMC"
- * @devnr: number of the device, e.g. "1:2"
- * @path:  path to file loaded
- * @buffer:buffer with file loaded
- * @buffer_size:   size of file loaded
- */
-void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
-void *buffer, size_t buffer_size)
-{
-   struct efi_device_path *device, *image;
-   efi_status_t ret;
-
-   log_debug("dev=%s, devnr=%s, path=%s, buffer=%p, size=%zx\n", dev,
- devnr, path, buffer, buffer_size);
-
-   /* Forget overwritten image */
-   if (buffer + buffer_size >= image_addr &&
-   image_addr + image_size >= buffer)
-   efi_clear_bootdev();
-
-   /* Remember only PE-COFF and FIT images */
-   if (efi_check_pe(buffer, buffer_size, NULL) != EFI_SUCCESS) {
-   if (IS_ENABLED(CONFIG_FIT) &&
-   !fit_check_format(buffer, IMAGE_SIZE_INVAL)) {
-   /*
-* FIT images of type EFI_OS are started via command
-* bootm. We should not use their boot device with the
-* bootefi command.
-*/
-   buffer = 0;
-   buffer_size = 0;
-   } else {
-   log_debug("- not remembering image\n");
-   return;
-   }
-   }
-
-   /* efi_set_bootdev() is typically called repeatedly, recover memory */
-   efi_clear_bootdev();
-
-   image_addr = buffer;
-   image_size = buffer_size;
-
-   ret = efi_dp_from_name(dev, devnr, path, , );
-   if (ret == EFI_SUCCESS) {
-   bootefi_device_path = device;
-   if (image) {
-   /* FIXME: image should not contain device */
-   struct efi_device_path *image_tmp = image;
-
-   efi_dp_split_file_path(image, , );
-   efi_free_pool(image_tmp);
-   }
-   bootefi_image_path = image;
-   log_debug("- boot device %pD\n", device);
-   if (image)
-   log_debug("- image %pD\n", image);
-   } else {
-   log_debug("- efi_dp_from_name() failed, err=%lx\n", ret);
-   efi_clear_bootdev();
-   }
-}
-
-/**
- * efi_env_set_load_options() - set load options from environment variable
- *
- * @handle:the image handle
- * @env_var:   name of the environment variable
- * @load_options:  pointer to load options (output)
- * Return: status code
- */
-static efi_status_t efi_env_set_load_options(efi_handle_t handle,
-const char *env_var,
-u16 **load_options)
-{
-   const char *env = env_get(env_var);
-   size_t size;

[RFC 07/13] bootmeth: use efi_loader interfaces instead of bootefi command

2023-10-25 Thread AKASHI Takahiro
Now that efi_loader subsystem provides interfaces that are equivalent
with bootefi command, we can replace command invocations with APIs.

Signed-off-by: AKASHI Takahiro 
---
 boot/Kconfig|  4 ++--
 boot/Makefile   |  2 +-
 boot/bootm_os.c | 31 +++
 boot/bootmeth_efi.c |  8 +---
 boot/bootmeth_efi_mgr.c |  3 ++-
 cmd/Kconfig |  2 +-
 test/boot/bootflow.c|  2 +-
 7 files changed, 15 insertions(+), 37 deletions(-)

diff --git a/boot/Kconfig b/boot/Kconfig
index fabf6fec2195..a441fac8ade1 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -511,7 +511,7 @@ config BOOTMETH_EXTLINUX_PXE
 
 config BOOTMETH_EFILOADER
bool "Bootdev support for EFI boot"
-   depends on CMD_BOOTEFI
+   depends on BOOTEFI_BOOTMGR
default y
help
  Enables support for EFI boot using bootdevs. This makes the
@@ -546,7 +546,7 @@ config BOOTMETH_DISTRO
select BOOTMETH_SCRIPT if CMDLINE # E.g. Armbian uses scripts
select BOOTMETH_EXTLINUX  # E.g. Debian uses these
select BOOTMETH_EXTLINUX_PXE if CMD_PXE && CMD_NET && DM_ETH
-   select BOOTMETH_EFILOADER if CMD_BOOTEFI # E.g. Ubuntu uses this
+   select BOOTMETH_EFILOADER if BOOTEFI_BOOTMGR # E.g. Ubuntu uses this
 
 config SPL_BOOTMETH_VBE
bool "Bootdev support for Verified Boot for Embedded (SPL)"
diff --git a/boot/Makefile b/boot/Makefile
index 3fd048bb41ab..4eaa5eab4b77 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -32,7 +32,7 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_CROS) += bootm.o bootm_os.o 
bootmeth_cros.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SCRIPT) += bootmeth_script.o
 ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL
-obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
+obj-$(CONFIG_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
 obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o
 obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o
diff --git a/boot/bootm_os.c b/boot/bootm_os.c
index 9c035b5be886..029baac478ae 100644
--- a/boot/bootm_os.c
+++ b/boot/bootm_os.c
@@ -494,7 +494,6 @@ static int do_bootm_efi(int flag, int argc, char *const 
argv[],
struct bootm_headers *images)
 {
int ret;
-   efi_status_t efi_ret;
void *image_buf;
 
if (flag != BOOTM_STATE_OS_GO)
@@ -505,37 +504,21 @@ static int do_bootm_efi(int flag, int argc, char *const 
argv[],
if (ret)
return ret;
 
-   /* Initialize EFI drivers */
-   efi_ret = efi_init_obj_list();
-   if (efi_ret != EFI_SUCCESS) {
-   printf("## Failed to initialize UEFI sub-system: r = %lu\n",
-  efi_ret & ~EFI_ERROR_MASK);
-   return 1;
-   }
+   /* We expect to return */
+   images->os.type = IH_TYPE_STANDALONE;
 
-   /* Install device tree */
-   efi_ret = efi_install_fdt(images->ft_len
- ? images->ft_addr : EFI_FDT_USE_INTERNAL);
-   if (efi_ret != EFI_SUCCESS) {
-   printf("## Failed to install device tree: r = %lu\n",
-  efi_ret & ~EFI_ERROR_MASK);
-   return 1;
-   }
+   image_buf = map_sysmem(images->ep, images->os.image_len);
 
/* Run EFI image */
printf("## Transferring control to EFI (at address %08lx) ...\n",
   images->ep);
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
 
-   /* We expect to return */
-   images->os.type = IH_TYPE_STANDALONE;
-
-   image_buf = map_sysmem(images->ep, images->os.image_len);
+   ret = efi_binary_run(image_buf, images->os.image_len,
+images->ft_len
+? images->ft_addr : EFI_FDT_USE_INTERNAL);
 
-   efi_ret = efi_run_image(image_buf, images->os.image_len);
-   if (efi_ret != EFI_SUCCESS)
-   return 1;
-   return 0;
+   return ret;
 }
 #endif
 
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index ae936c8daa18..2a9f29f9db5a 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -412,7 +412,6 @@ static int distro_efi_read_bootflow(struct udevice *dev, 
struct bootflow *bflow)
 static int distro_efi_boot(struct udevice *dev, struct bootflow *bflow)
 {
ulong kernel, fdt;
-   char cmd[50];
int ret;
 
kernel = env_get_hex("kernel_addr_r", 0);
@@ -441,12 +440,7 @@ static int distro_efi_boot(struct udevice *dev, struct 
bootflow *bflow)
fdt = env_get_hex("fdt_addr_r", 0);
}
 
-   /*
-* At some point we can add a real interface to bootefi so we can call
-* this directly. For now, go through the CLI, like distro boot.
-*/
-   snprintf(cmd, sizeof(cmd), "bootefi %lx %lx", 

[RFC 06/13] cmd: efidebug: ease efi configuration dependency

2023-10-25 Thread AKASHI Takahiro
Now it is clear that the command actually depends on interfaces,
not "bootefi bootmgr" command.

Signed-off-by: AKASHI Takahiro 
---
 cmd/efidebug.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 201531ac19fc..c2b2b074e094 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -1335,7 +1335,7 @@ static __maybe_unused int do_efi_test_bootmgr(struct 
cmd_tbl *cmdtp, int flag,
 }
 
 static struct cmd_tbl cmd_efidebug_test_sub[] = {
-#ifdef CONFIG_CMD_BOOTEFI_BOOTMGR
+#ifdef CONFIG_BOOTEFI_BOOTMGR
U_BOOT_CMD_MKENT(bootmgr, CONFIG_SYS_MAXARGS, 1, do_efi_test_bootmgr,
 "", ""),
 #endif
@@ -1526,7 +1526,7 @@ U_BOOT_LONGHELP(efidebug,
"  - show UEFI memory map\n"
"efidebug tables\n"
"  - show UEFI configuration tables\n"
-#ifdef CONFIG_CMD_BOOTEFI_BOOTMGR
+#ifdef CONFIG_BOOTEFI_BOOTMGR
"efidebug test bootmgr\n"
"  - run simple bootmgr for test\n"
 #endif
-- 
2.34.1



[RFC 04/13] cmd: bootefi: carve out binary execution interface

2023-10-25 Thread AKASHI Takahiro
Carve binary execution code out of do_bootefi_image().

Signed-off-by: AKASHI Takahiro 
---
 cmd/bootefi.c | 46 --
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 899ed90f6817..8b0bd07f1ff8 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -503,6 +503,36 @@ out:
return (ret != EFI_SUCCESS) ? ret : ret2;
 }
 
+/**
+ * efi_binary_run() - run loaded UEFI image
+ *
+ * @image: memory address of the UEFI image
+ * @size:  size of the UEFI image
+ *
+ * Execute an EFI binary image loaded at @image.
+ * @size may be zero if the binary is loaded with U-Boot load command.
+ *
+ * Return: status code
+ */
+static efi_status_t efi_binary_run(void *image, size_t size, void *fdt)
+{
+   efi_status_t ret;
+
+   /* Initialize EFI drivers */
+   ret = efi_init_obj_list();
+   if (ret != EFI_SUCCESS) {
+   log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
+   ret & ~EFI_ERROR_MASK);
+   return ret;
+   }
+
+   ret = efi_install_fdt(fdt);
+   if (ret != EFI_SUCCESS)
+   return ret;
+
+   return efi_run_image(image, size);
+}
+
 static efi_status_t bootefi_run_prepare(const char *load_options_path,
struct efi_device_path *device_path,
struct efi_device_path *image_path,
@@ -684,23 +714,11 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
int argc,
}
}
 
-   /* Initialize EFI drivers */
-   ret = efi_init_obj_list();
-   if (ret != EFI_SUCCESS) {
-   log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
-   ret & ~EFI_ERROR_MASK);
-   return CMD_RET_FAILURE;
-   }
+   ret = efi_binary_run(image_buf, size, fdt);
 
-   ret = efi_install_fdt(fdt);
if (ret == EFI_INVALID_PARAMETER)
return CMD_RET_USAGE;
-   else if (ret != EFI_SUCCESS)
-   return CMD_RET_FAILURE;
-
-   ret = efi_run_image(image_buf, size);
-
-   if (ret != EFI_SUCCESS)
+   else if (ret)
return CMD_RET_FAILURE;
 
return CMD_RET_SUCCESS;
-- 
2.34.1



[RFC 03/13] cmd: bootefi: carve out EFI boot manager interface

2023-10-25 Thread AKASHI Takahiro
Carve EFI boot manager related code out of do_bootefi_image().

Signed-off-by: AKASHI Takahiro 
---
 cmd/bootefi.c | 43 ---
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index ae00bba3b4f0..899ed90f6817 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -401,28 +401,40 @@ out:
 }
 
 /**
- * do_efibootmgr() - execute EFI boot manager
+ * efi_bootmgr_run() - execute EFI boot manager
+ * fdt:Flat device tree
+ *
+ * Invoke EFI boot manager and execute a binary depending on
+ * boot options. If @fdt is not NULL, it will be passed to
+ * the executed binary.
  *
  * Return: status code
  */
-static int do_efibootmgr(void)
+static efi_status_t efi_bootmgr_run(void *fdt)
 {
efi_handle_t handle;
-   efi_status_t ret;
void *load_options;
+   efi_status_t ret;
 
-   ret = efi_bootmgr_load(, _options);
+   /* Initialize EFI drivers */
+   ret = efi_init_obj_list();
if (ret != EFI_SUCCESS) {
-   log_notice("EFI boot manager: Cannot load any image\n");
+   log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
+   ret & ~EFI_ERROR_MASK);
return CMD_RET_FAILURE;
}
 
-   ret = do_bootefi_exec(handle, load_options);
-
+   ret = efi_install_fdt(fdt);
if (ret != EFI_SUCCESS)
-   return CMD_RET_FAILURE;
+   return ret;
 
-   return CMD_RET_SUCCESS;
+   ret = efi_bootmgr_load(, _options);
+   if (ret != EFI_SUCCESS) {
+   log_notice("EFI boot manager: Cannot load any image\n");
+   return ret;
+   }
+
+   return do_bootefi_exec(handle, load_options);
 }
 
 /**
@@ -612,21 +624,14 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
int argc,
 
if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR) &&
!strcmp(argv[1], "bootmgr")) {
-   /* Initialize EFI drivers */
-   ret = efi_init_obj_list();
-   if (ret != EFI_SUCCESS) {
-   log_err("Error: Cannot initialize UEFI sub-system, r = 
%lu\n",
-   ret & ~EFI_ERROR_MASK);
-   return CMD_RET_FAILURE;
-   }
+   ret = efi_bootmgr_run(fdt);
 
-   ret = efi_install_fdt(fdt);
if (ret == EFI_INVALID_PARAMETER)
return CMD_RET_USAGE;
-   else if (ret != EFI_SUCCESS)
+   else if (ret)
return CMD_RET_FAILURE;
 
-   return do_efibootmgr();
+   return CMD_RET_SUCCESS;
}
 
if (IS_ENABLED(CONFIG_CMD_BOOTEFI_SELFTEST) &&
-- 
2.34.1



[RFC 02/13] cmd: bootefi: re-organize do_bootefi_image()

2023-10-25 Thread AKASHI Takahiro
Decompose and re-organize do_bootefi_image() into three parts for
the succeeding refactor work.

Signed-off-by: AKASHI Takahiro 
---
 cmd/Kconfig  | 15 ++--
 cmd/bootefi.c| 82 ++--
 include/efi_loader.h |  2 --
 3 files changed, 69 insertions(+), 30 deletions(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 0eb739203ade..825a41d68aad 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -363,9 +363,19 @@ config CMD_BOOTEFI
help
  Boot an EFI image from memory.
 
+if CMD_BOOTEFI
+config CMD_BOOTEFI_BINARY
+   bool "Allow booting an EFI binary directly"
+   depends on BOOTEFI_BOOTMGR
+   default y
+   help
+ Select this option to enable direct execution of binary at 'bootefi'.
+ This subcommand will allow you to load the UEFI binary using
+ other U-Boot commands or external methods and then run it.
+
 config CMD_BOOTEFI_BOOTMGR
bool "UEFI Boot Manager command"
-   depends on BOOTEFI_BOOTMGR && CMD_BOOTEFI
+   depends on BOOTEFI_BOOTMGR
default y
help
  Select this option to enable the 'bootmgr' subcommand of 'bootefi'.
@@ -374,7 +384,7 @@ config CMD_BOOTEFI_BOOTMGR
 
 config CMD_BOOTEFI_HELLO_COMPILE
bool "Compile a standard EFI hello world binary for testing"
-   depends on CMD_BOOTEFI && !CPU_V7M
+   depends on !CPU_V7M
default y
help
  This compiles a standard EFI hello world application with U-Boot so
@@ -396,6 +406,7 @@ config CMD_BOOTEFI_HELLO
  up EFI support on a new architecture.
 
 source lib/efi_selftest/Kconfig
+endif
 
 config CMD_BOOTMENU
bool "bootmenu"
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 1b28bf5a318d..ae00bba3b4f0 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -491,7 +491,6 @@ out:
return (ret != EFI_SUCCESS) ? ret : ret2;
 }
 
-#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
 static efi_status_t bootefi_run_prepare(const char *load_options_path,
struct efi_device_path *device_path,
struct efi_device_path *image_path,
@@ -581,7 +580,6 @@ static int do_efi_selftest(void)
 
return ret != EFI_SUCCESS;
 }
-#endif /* CONFIG_CMD_BOOTEFI_SELFTEST */
 
 /**
  * do_bootefi() - execute `bootefi` command
@@ -603,14 +601,6 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int 
argc,
if (argc < 2)
return CMD_RET_USAGE;
 
-   /* Initialize EFI drivers */
-   ret = efi_init_obj_list();
-   if (ret != EFI_SUCCESS) {
-   log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
-   ret & ~EFI_ERROR_MASK);
-   return CMD_RET_FAILURE;
-   }
-
if (argc > 2) {
uintptr_t fdt_addr;
 
@@ -619,29 +609,54 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
int argc,
} else {
fdt = EFI_FDT_USE_INTERNAL;
}
-   ret = efi_install_fdt(fdt);
-   if (ret == EFI_INVALID_PARAMETER)
-   return CMD_RET_USAGE;
-   else if (ret != EFI_SUCCESS)
-   return CMD_RET_FAILURE;
 
-   if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
-   if (!strcmp(argv[1], "bootmgr"))
-   return do_efibootmgr();
+   if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR) &&
+   !strcmp(argv[1], "bootmgr")) {
+   /* Initialize EFI drivers */
+   ret = efi_init_obj_list();
+   if (ret != EFI_SUCCESS) {
+   log_err("Error: Cannot initialize UEFI sub-system, r = 
%lu\n",
+   ret & ~EFI_ERROR_MASK);
+   return CMD_RET_FAILURE;
+   }
+
+   ret = efi_install_fdt(fdt);
+   if (ret == EFI_INVALID_PARAMETER)
+   return CMD_RET_USAGE;
+   else if (ret != EFI_SUCCESS)
+   return CMD_RET_FAILURE;
+
+   return do_efibootmgr();
}
-#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
-   if (!strcmp(argv[1], "selftest"))
+
+   if (IS_ENABLED(CONFIG_CMD_BOOTEFI_SELFTEST) &&
+   !strcmp(argv[1], "selftest")) {
+   /* Initialize EFI drivers */
+   ret = efi_init_obj_list();
+   if (ret != EFI_SUCCESS) {
+   log_err("Error: Cannot initialize UEFI sub-system, r = 
%lu\n",
+   ret & ~EFI_ERROR_MASK);
+   return CMD_RET_FAILURE;
+   }
+
+   ret = efi_install_fdt(fdt);
+   if (ret == EFI_INVALID_PARAMETER)
+   return CMD_RET_USAGE;
+   else if (ret != EFI_SUCCESS)
+   return CMD_RET_FAILURE;
+
return do_efi_selftest();
-#endif

[RFC 01/13] cmd: bootefi: unfold do_bootefi_image()

2023-10-25 Thread AKASHI Takahiro
Unfold do_bootefi_image() into do_bootefi() for the sake of the succeeding
refactor work.

Signed-off-by: AKASHI Takahiro 
---
 cmd/bootefi.c | 101 ++
 1 file changed, 37 insertions(+), 64 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 20e5c94a33a4..1b28bf5a318d 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -425,58 +425,6 @@ static int do_efibootmgr(void)
return CMD_RET_SUCCESS;
 }
 
-/**
- * do_bootefi_image() - execute EFI binary
- *
- * Set up memory image for the binary to be loaded, prepare device path, and
- * then call do_bootefi_exec() to execute it.
- *
- * @image_opt: string with image start address
- * @size_opt:  string with image size or NULL
- * Return: status code
- */
-static int do_bootefi_image(const char *image_opt, const char *size_opt)
-{
-   void *image_buf;
-   unsigned long addr, size;
-   efi_status_t ret;
-
-#ifdef CONFIG_CMD_BOOTEFI_HELLO
-   if (!strcmp(image_opt, "hello")) {
-   image_buf = __efi_helloworld_begin;
-   size = __efi_helloworld_end - __efi_helloworld_begin;
-   efi_clear_bootdev();
-   } else
-#endif
-   {
-   addr = strtoul(image_opt, NULL, 16);
-   /* Check that a numeric value was passed */
-   if (!addr)
-   return CMD_RET_USAGE;
-   image_buf = map_sysmem(addr, 0);
-
-   if (size_opt) {
-   size = strtoul(size_opt, NULL, 16);
-   if (!size)
-   return CMD_RET_USAGE;
-   efi_clear_bootdev();
-   } else {
-   if (image_buf != image_addr) {
-   log_err("No UEFI binary known at %s\n",
-   image_opt);
-   return CMD_RET_FAILURE;
-   }
-   size = image_size;
-   }
-   }
-   ret = efi_run_image(image_buf, size);
-
-   if (ret != EFI_SUCCESS)
-   return CMD_RET_FAILURE;
-
-   return CMD_RET_SUCCESS;
-}
-
 /**
  * efi_run_image() - run loaded UEFI image
  *
@@ -648,8 +596,9 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int 
argc,
  char *const argv[])
 {
efi_status_t ret;
-   char *img_addr, *img_size, *str_copy, *pos;
-   void *fdt;
+   char *p;
+   void *fdt, *image_buf;
+   unsigned long addr, size;
 
if (argc < 2)
return CMD_RET_USAGE;
@@ -684,18 +633,42 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, 
int argc,
if (!strcmp(argv[1], "selftest"))
return do_efi_selftest();
 #endif
-   str_copy = strdup(argv[1]);
-   if (!str_copy) {
-   log_err("Out of memory\n");
-   return CMD_RET_FAILURE;
+
+#ifdef CONFIG_CMD_BOOTEFI_HELLO
+   if (!strcmp(argv[1], "hello")) {
+   image_buf = __efi_helloworld_begin;
+   size = __efi_helloworld_end - __efi_helloworld_begin;
+   efi_clear_bootdev();
+   } else
+#endif
+   {
+   addr = strtoul(argv[1], NULL, 16);
+   /* Check that a numeric value was passed */
+   if (!addr)
+   return CMD_RET_USAGE;
+   image_buf = map_sysmem(addr, 0);
+
+   p  = strchr(argv[1], ':');
+   if (p) {
+   size = strtoul(++p, NULL, 16);
+   if (!size)
+   return CMD_RET_USAGE;
+   efi_clear_bootdev();
+   } else {
+   if (image_buf != image_addr) {
+   log_err("No UEFI binary known at %s\n",
+   argv[1]);
+   return CMD_RET_FAILURE;
+   }
+   size = image_size;
+   }
}
-   pos = str_copy;
-   img_addr = strsep(, ":");
-   img_size = strsep(, ":");
-   ret = do_bootefi_image(img_addr, img_size);
-   free(str_copy);
+   ret = efi_run_image(image_buf, size);
 
-   return ret;
+   if (ret != EFI_SUCCESS)
+   return CMD_RET_FAILURE;
+
+   return CMD_RET_SUCCESS;
 }
 
 U_BOOT_LONGHELP(bootefi,
-- 
2.34.1



[RFC 00/13] cmd: bootefi: refactor the code for bootmgr

2023-10-25 Thread AKASHI Takahiro
This patch set is motivated by the discussion[1] regarding
CONFIG_BOOTEFI_BOOTMGR option.

At the end, bootefi.c will be decomposed into two parts, one for
providing the command itself and one for implementing helper functions.
EFI_LOADER will now be available without CONFIG_CMDLINE or specifically
CONFIG_CMD_BOOTEFI if invoked via bootmeth/bootstd.

Then, EFI_LOADER library side will be further split into two options
for fine-grain control:
CONFIG_EFI_BINARY_EXEC: execute UEFI binaries which are to be explicitly
loaded by U-Boot's load commands/functions or other methods
(like a jtag debugger?)
It supports bootmeth_efi as well as "bootefi |hello"(/"bootm"?).

CONFIG_EFI_BOOTMGR: provide EFI boot manger functionality
It supports bootmeth_efi_mgr as well as "bootefi bootmgr".

As such, We will no longer need CONFIG_BINARY_EXEC if we want to only
make use of the boot manger for booting a next stage OS.

Prerequisite

This patch set is based on top of Simon/Tom's [2].

Patches
===
Patch#1-#11: I hope that those commits show step-by-step refactoring
without introducing degradation.
Patch#12-#13: Those are not directly related to the patch's aim, but
they are necessary to compile U-Boot on sandbox (sandbox_defconfig)
without CONFIG_CMDLINE.

[1] https://lists.denx.de/pipermail/u-boot/2023-October/534598.html
[2] origin/TEST/v4.1-tidy-up-use-of-CONFIG_CMDLINE

AKASHI Takahiro (13):
  cmd: bootefi: unfold do_bootefi_image()
  cmd: bootefi: re-organize do_bootefi_image()
  cmd: bootefi: carve out EFI boot manager interface
  cmd: bootefi: carve out binary execution interface
  cmd: bootefi: move library interfaces under lib/efi_loader
  cmd: efidebug: ease efi configuration dependency
  bootmeth: use efi_loader interfaces instead of bootefi command
  efi_loader: split unrelated code from efi_bootmgr.c
  efi_loader: rename BOOTEFI_BOOTMGR to EFI_BOOTMGR
  net: tftp: remove explicit efi configuration dependency
  fs: remove explicit efi configuration dependency
  lib: uuid: move CONFIG_RANDOM_UUID
  block: rkmtd: select CONFIG_RANDOM_UUID explicitly

 boot/Kconfig |   4 +-
 boot/Makefile|   2 +-
 boot/bootm_os.c  |  31 +-
 boot/bootmeth_efi.c  |   8 +-
 boot/bootmeth_efi_mgr.c  |   3 +-
 cmd/Kconfig  |  28 +-
 cmd/bootefi.c| 658 +--
 cmd/efidebug.c   |   4 +-
 drivers/block/Kconfig|   1 +
 fs/fs.c  |   7 +-
 include/efi_loader.h |  34 +-
 lib/Kconfig  |   7 +
 lib/efi_loader/Kconfig   |  11 +-
 lib/efi_loader/Makefile  |   2 +-
 lib/efi_loader/efi_bootmgr.c |  37 ++
 lib/efi_loader/efi_device_path.c |   3 +-
 lib/efi_loader/efi_helper.c  | 486 ++-
 net/tftp.c   |  10 +-
 test/boot/bootflow.c |   2 +-
 19 files changed, 697 insertions(+), 641 deletions(-)

-- 
2.34.1



Re: [PATCH 3/5] cmd: add scmi command for SCMI firmware

2023-10-25 Thread AKASHI Takahiro
Hi Michal,

On Wed, Oct 25, 2023 at 09:29:04AM +0200, Michal Simek wrote:
> 
> 
> On 10/25/23 07:14, AKASHI Takahiro wrote:
> > This command, "scmi", may provide a command line interface to various SCMI
> > protocols. It supports at least initially SCMI base protocol and is
> > intended mainly for debug purpose.
> > 
> > Signed-off-by: AKASHI Takahiro 
> > Reviewed-by: Simon Glass 
> > Reviewed-by: Etienne Carriere 
> > ---
> > v3
> > * describe that arguments are in hex at a help message
> > * modify the code for dynamically allocated agent names
> > v2
> > * remove sub command category, 'scmi base', for simplicity
> > ---
> >   cmd/Kconfig  |   9 ++
> >   cmd/Makefile |   1 +
> >   cmd/scmi.c   | 335 +++
> >   3 files changed, 345 insertions(+)
> >   create mode 100644 cmd/scmi.c
> > 
> > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > index 205df2f1fb65..c940051eba91 100644
> > --- a/cmd/Kconfig
> > +++ b/cmd/Kconfig
> > @@ -2550,6 +2550,15 @@ config CMD_CROS_EC
> >   a number of sub-commands for performing EC tasks such as
> >   updating its flash, accessing a small saved context area
> >   and talking to the I2C bus behind the EC (if there is one).
> > +
> > +config CMD_SCMI
> > +   bool "Enable scmi command"
> > +   depends on SCMI_FIRMWARE
> > +   default n
> 
> As I said in previous email. default n should be removed.
> It is default option.

I see.
I hope that Tom will take care of that when merging if there is no
other comment.

-Takahiro Akashi

> You can take a look at least on this commit.
> 
> commit b4c2c151b14b59a2403675526adf666710cade67
> Author: Michal Simek 
> AuthorDate: Fri Aug 27 08:48:10 2021 +0200
> Commit: Tom Rini 
> CommitDate: Tue Aug 31 17:47:49 2021 -0400
> 
> Kconfig: Remove all default n/no options
> 
> default n/no doesn't need to be specified. It is default option anyway.
> 
> Signed-off-by: Michal Simek 
> [trini: Rework FSP_USE_UPD portion]
> Signed-off-by: Tom Rini 
> 
> I have also sent one more resync patch and CC you there too.
> 
> Thanks,
> Michal
> 
> 
> 
> 


[PATCH 5/5] test: dm: add scmi command test

2023-10-24 Thread AKASHI Takahiro
In this test, "scmi" command is tested against different sub-commands.
Please note that scmi command is for debug purpose and is not intended
in production system.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
Reviewed-by: Etienne Carriere 
---
v7
* make test assertions more flexible depending on the number of provided
  protocols
v4
* move 'base'-related changes to the prior commit
* add CONFIG_CMD_SCMI to sandbox_defconfig
v3
* change char to u8 in vendor/agent names
v2
* use helper functions, removing direct uses of ops
---
 configs/sandbox_defconfig |  1 +
 test/dm/scmi.c| 81 +++
 2 files changed, 82 insertions(+)

diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index e3a2f9eb1708..34e3cc281d7f 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -120,6 +120,7 @@ CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_AES=y
 CONFIG_CMD_TPM=y
 CONFIG_CMD_TPM_TEST=y
+CONFIG_CMD_SCMI=y
 CONFIG_CMD_BTRFS=y
 CONFIG_CMD_CBFS=y
 CONFIG_CMD_CRAMFS=y
diff --git a/test/dm/scmi.c b/test/dm/scmi.c
index 2f63f2da16fb..2bcf7ac6fcc3 100644
--- a/test/dm/scmi.c
+++ b/test/dm/scmi.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -206,6 +207,86 @@ static int dm_test_scmi_base(struct unit_test_state *uts)
 
 DM_TEST(dm_test_scmi_base, UT_TESTF_SCAN_FDT);
 
+static int dm_test_scmi_cmd(struct unit_test_state *uts)
+{
+   struct udevice *agent_dev;
+   int num_proto = 0;
+   char cmd_out[30];
+
+   if (!IS_ENABLED(CONFIG_CMD_SCMI))
+   return 0;
+
+   /* preparation */
+   ut_assertok(uclass_get_device_by_name(UCLASS_SCMI_AGENT, "scmi",
+ _dev));
+   ut_assertnonnull(agent_dev);
+
+   /*
+* Estimate the number of provided protocols.
+* This estimation is correct as far as a corresponding
+* protocol support is added to sandbox fake serer.
+*/
+   if (IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN))
+   num_proto++;
+   if (IS_ENABLED(CONFIG_CLK_SCMI))
+   num_proto++;
+   if (IS_ENABLED(CONFIG_RESET_SCMI))
+   num_proto++;
+   if (IS_ENABLED(CONFIG_DM_REGULATOR_SCMI))
+   num_proto++;
+
+   /* scmi info */
+   ut_assertok(run_command("scmi info", 0));
+
+   ut_assert_nextline("SCMI device: scmi");
+   snprintf(cmd_out, 30, "  protocol version: 0x%x",
+SCMI_BASE_PROTOCOL_VERSION);
+   ut_assert_nextline(cmd_out);
+   ut_assert_nextline("  # of agents: 2");
+   ut_assert_nextline("  0: platform");
+   ut_assert_nextline("> 1: OSPM");
+   snprintf(cmd_out, 30, "  # of protocols: %d", num_proto);
+   ut_assert_nextline(cmd_out);
+   if (IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN))
+   ut_assert_nextline("  Power domain management");
+   if (IS_ENABLED(CONFIG_CLK_SCMI))
+   ut_assert_nextline("  Clock management");
+   if (IS_ENABLED(CONFIG_RESET_SCMI))
+   ut_assert_nextline("  Reset domain management");
+   if (IS_ENABLED(CONFIG_DM_REGULATOR_SCMI))
+   ut_assert_nextline("  Voltage domain management");
+   ut_assert_nextline("  vendor: U-Boot");
+   ut_assert_nextline("  sub vendor: Sandbox");
+   ut_assert_nextline("  impl version: 0x1");
+
+   ut_assert_console_end();
+
+   /* scmi perm_dev */
+   ut_assertok(run_command("scmi perm_dev 1 0 1", 0));
+   ut_assert_console_end();
+
+   ut_assert(run_command("scmi perm_dev 1 0 0", 0));
+   ut_assert_nextline("Denying access to device:0 failed (-13)");
+   ut_assert_console_end();
+
+   /* scmi perm_proto */
+   ut_assertok(run_command("scmi perm_proto 1 0 14 1", 0));
+   ut_assert_console_end();
+
+   ut_assert(run_command("scmi perm_proto 1 0 14 0", 0));
+   ut_assert_nextline("Denying access to protocol:0x14 on device:0 failed 
(-13)");
+   ut_assert_console_end();
+
+   /* scmi reset */
+   ut_assert(run_command("scmi reset 1 1", 0));
+   ut_assert_nextline("Reset failed (-13)");
+   ut_assert_console_end();
+
+   return 0;
+}
+
+DM_TEST(dm_test_scmi_cmd, UT_TESTF_SCAN_FDT);
+
 static int dm_test_scmi_power_domains(struct unit_test_state *uts)
 {
struct sandbox_scmi_agent *agent;
-- 
2.34.1



[PATCH 4/5] doc: cmd: add documentation for scmi

2023-10-24 Thread AKASHI Takahiro
This is a help text for scmi command.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
Reviewed-by: Etienne Carriere 
---
v6
* add the manual to doc/usage/index.rst
v4
* s/tranport/transport/
v2
* add more descriptions about SCMI
---
 doc/usage/cmd/scmi.rst | 126 +
 doc/usage/index.rst|   1 +
 2 files changed, 127 insertions(+)
 create mode 100644 doc/usage/cmd/scmi.rst

diff --git a/doc/usage/cmd/scmi.rst b/doc/usage/cmd/scmi.rst
new file mode 100644
index ..9ea7e0e41dad
--- /dev/null
+++ b/doc/usage/cmd/scmi.rst
@@ -0,0 +1,126 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+scmi command
+
+
+Synopsis
+
+
+::
+
+scmi info
+scmi perm_dev   
+scmi perm_proto
+scmi reset  
+
+Description
+---
+
+Arm System Control and Management Interface (SCMI hereafter) is a set of
+standardised interfaces to manage system resources, like clocks, power
+domains, pin controls, reset and so on, in a system-wide manner.
+
+An entity which provides those services is called a SCMI firmware (or
+SCMI server if you like) may be placed/implemented by EL3 software or
+by a dedicated system control processor (SCP) or else.
+
+A user of SCMI interfaces, including U-Boot, is called a SCMI agent and
+may issues commands, which are defined in each protocol for specific system
+resources, to SCMI server via a communication channel, called a transport.
+Those interfaces are independent from the server's implementation thanks to
+a transport layer.
+
+For more details, see the `SCMI specification`_.
+
+While most of system resources managed under SCMI protocols are implemented
+and handled as standard U-Boot devices, for example clk_scmi, scmi command
+provides additional management functionality against SCMI server.
+
+scmi info
+~
+Show base information about SCMI server and supported protocols
+
+scmi perm_dev
+~
+Allow or deny access permission to the device
+
+scmi perm_proto
+~~~
+Allow or deny access to the protocol on the device
+
+scmi reset
+~~
+Reset the already-configured permissions against the device
+
+Parameters are used as follows:
+
+
+SCMI Agent ID, hex value
+
+
+SCMI Device ID, hex value
+
+Please note that what a device means is not defined
+in the specification.
+
+
+SCMI Protocol ID, hex value
+
+It must not be 0x10 (base protocol)
+
+
+Flags to control the action, hex value
+
+0 to deny, 1 to allow. The other values are reserved and allowed
+values may depend on the implemented version of SCMI server in
+the future. See SCMI specification for more details.
+
+Example
+---
+
+Obtain basic information about SCMI server:
+
+::
+
+=> scmi info
+SCMI device: scmi
+  protocol version: 0x2
+  # of agents: 3
+  0: platform
+> 1: OSPM
+  2: PSCI
+  # of protocols: 4
+  Power domain management
+  Performance domain management
+  Clock management
+  Sensor management
+  vendor: Linaro
+  sub vendor: PMWG
+  impl version: 0x20b
+
+Ask for access permission to device#0:
+
+::
+
+=> scmi perm_dev 1 0 1
+
+Reset configurations with all access permission settings retained:
+
+::
+
+=> scmi reset 1 0
+
+Configuration
+-
+
+The scmi command is only available if CONFIG_CMD_SCMI=y.
+Default n because this command is mainly for debug purpose.
+
+Return value
+
+
+The return value ($?) is set to 0 if the operation succeeded,
+1 if the operation failed or -1 if the operation failed due to
+a syntax error.
+
+.. _`SCMI specification`: 
https://developer.arm.com/documentation/den0056/e/?lang=en
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 98b4719c4088..9a65b50aeed7 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -94,6 +94,7 @@ Shell commands
cmd/saves
cmd/sbi
cmd/sf
+   cmd/scmi
cmd/scp03
cmd/seama
cmd/setexpr
-- 
2.34.1



[PATCH 3/5] cmd: add scmi command for SCMI firmware

2023-10-24 Thread AKASHI Takahiro
This command, "scmi", may provide a command line interface to various SCMI
protocols. It supports at least initially SCMI base protocol and is
intended mainly for debug purpose.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
Reviewed-by: Etienne Carriere 
---
v3
* describe that arguments are in hex at a help message
* modify the code for dynamically allocated agent names
v2
* remove sub command category, 'scmi base', for simplicity
---
 cmd/Kconfig  |   9 ++
 cmd/Makefile |   1 +
 cmd/scmi.c   | 335 +++
 3 files changed, 345 insertions(+)
 create mode 100644 cmd/scmi.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 205df2f1fb65..c940051eba91 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2550,6 +2550,15 @@ config CMD_CROS_EC
  a number of sub-commands for performing EC tasks such as
  updating its flash, accessing a small saved context area
  and talking to the I2C bus behind the EC (if there is one).
+
+config CMD_SCMI
+   bool "Enable scmi command"
+   depends on SCMI_FIRMWARE
+   default n
+   help
+ This command provides user interfaces to several SCMI (System
+ Control and Management Interface) protocols available on Arm
+ platforms to manage system resources.
 endmenu
 
 menu "Filesystem commands"
diff --git a/cmd/Makefile b/cmd/Makefile
index 9a6790cc1708..320f0b5266eb 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -159,6 +159,7 @@ obj-$(CONFIG_CMD_SATA) += sata.o
 obj-$(CONFIG_CMD_NVME) += nvme.o
 obj-$(CONFIG_SANDBOX) += sb.o
 obj-$(CONFIG_CMD_SF) += sf.o
+obj-$(CONFIG_CMD_SCMI) += scmi.o
 obj-$(CONFIG_CMD_SCSI) += scsi.o disk.o
 obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
 obj-$(CONFIG_CMD_SEAMA) += seama.o
diff --git a/cmd/scmi.c b/cmd/scmi.c
new file mode 100644
index ..f8f54f84cff8
--- /dev/null
+++ b/cmd/scmi.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  SCMI (System Control and Management Interface) utility command
+ *
+ *  Copyright (c) 2023 Linaro Limited
+ *     Author: AKASHI Takahiro
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include  /* uclass_get_device */
+#include 
+#include 
+
+static struct udevice *agent;
+static struct udevice *base_proto;
+
+struct {
+   enum scmi_std_protocol id;
+   const char *name;
+} protocol_name[] = {
+   {SCMI_PROTOCOL_ID_BASE, "Base"},
+   {SCMI_PROTOCOL_ID_POWER_DOMAIN, "Power domain management"},
+   {SCMI_PROTOCOL_ID_SYSTEM, "System power management"},
+   {SCMI_PROTOCOL_ID_PERF, "Performance domain management"},
+   {SCMI_PROTOCOL_ID_CLOCK, "Clock management"},
+   {SCMI_PROTOCOL_ID_SENSOR, "Sensor management"},
+   {SCMI_PROTOCOL_ID_RESET_DOMAIN, "Reset domain management"},
+   {SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN, "Voltage domain management"},
+};
+
+/**
+ * get_proto_name() - get the name of SCMI protocol
+ *
+ * @id:SCMI Protocol ID
+ *
+ * Get the printable name of the protocol, @id
+ *
+ * Return: Name string on success, NULL on failure
+ */
+static const char *get_proto_name(enum scmi_std_protocol id)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(protocol_name); i++)
+   if (id == protocol_name[i].id)
+   return protocol_name[i].name;
+
+   return NULL;
+}
+
+/**
+ * do_scmi_info() - get the information of SCMI services
+ *
+ * @cmdtp: Command table
+ * @flag:  Command flag
+ * @argc:  Number of arguments
+ * @argv:  Argument array
+ *
+ * Get the information of SCMI services using various interfaces
+ * provided by the Base protocol.
+ *
+ * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
+ */
+static int do_scmi_info(struct cmd_tbl *cmdtp, int flag, int argc,
+   char * const argv[])
+{
+   u32 agent_id, num_protocols;
+   u8 *agent_name, *protocols;
+   int i, ret;
+
+   if (argc != 1)
+   return CMD_RET_USAGE;
+
+   printf("SCMI device: %s\n", agent->name);
+   printf("  protocol version: 0x%x\n", scmi_version(agent));
+   printf("  # of agents: %d\n", scmi_num_agents(agent));
+   for (i = 0; i < scmi_num_agents(agent); i++) {
+   ret = scmi_base_discover_agent(base_proto, i, _id,
+  _name);
+   if (ret) {
+   if (ret != -EOPNOTSUPP)
+   printf("base_discover_agent() failed for id: %d 
(%d)\n",
+  i, ret);
+   break;
+   }
+   printf("%c%2d: %s\n", i == scmi_agent_id(agent) ? '>' : ' ',
+  i, agent_name);
+   free(agent_name)

[PATCH 2/5] firmware: scmi: support protocols on sandbox only if enabled

2023-10-24 Thread AKASHI Takahiro
This change will be useful when we manually test SCMI on sandbox
by enabling/disabling a specific SCMI protocol.

Signed-off-by: AKASHI Takahiro 
---
 drivers/firmware/scmi/sandbox-scmi_agent.c   | 27 ++-
 drivers/firmware/scmi/sandbox-scmi_devices.c | 78 
 2 files changed, 72 insertions(+), 33 deletions(-)

diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c 
b/drivers/firmware/scmi/sandbox-scmi_agent.c
index 9f5f497e0a6c..e1b9b5f5f2d8 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -66,10 +66,18 @@ struct scmi_channel {
 };
 
 static u8 protocols[] = {
+#if IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN)
SCMI_PROTOCOL_ID_POWER_DOMAIN,
+#endif
+#if IS_ENABLED(CONFIG_CLK_SCMI)
SCMI_PROTOCOL_ID_CLOCK,
+#endif
+#if IS_ENABLED(CONFIG_RESET_SCMI)
SCMI_PROTOCOL_ID_RESET_DOMAIN,
+#endif
+#if IS_ENABLED(CONFIG_DM_REGULATOR_SCMI)
SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,
+#endif
 };
 
 #define NUM_PROTOCOLS ARRAY_SIZE(protocols)
@@ -1160,6 +1168,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_POWER_DOMAIN:
+   if (!IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN))
+   goto not_supported;
+
switch (msg->message_id) {
case SCMI_PROTOCOL_VERSION:
return sandbox_scmi_pwd_protocol_version(dev, msg);
@@ -1180,6 +1191,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_CLOCK:
+   if (!IS_ENABLED(CONFIG_CLK_SCMI))
+   goto not_supported;
+
switch (msg->message_id) {
case SCMI_PROTOCOL_ATTRIBUTES:
return sandbox_scmi_clock_protocol_attribs(dev, msg);
@@ -1196,6 +1210,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_RESET_DOMAIN:
+   if (!IS_ENABLED(CONFIG_RESET_SCMI))
+   goto not_supported;
+
switch (msg->message_id) {
case SCMI_RESET_DOMAIN_ATTRIBUTES:
return sandbox_scmi_rd_attribs(dev, msg);
@@ -1206,6 +1223,9 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
}
break;
case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
+   if (!IS_ENABLED(CONFIG_DM_REGULATOR_SCMI))
+   goto not_supported;
+
switch (msg->message_id) {
case SCMI_VOLTAGE_DOMAIN_ATTRIBUTES:
return sandbox_scmi_voltd_attribs(dev, msg);
@@ -1224,8 +1244,7 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
case SCMI_PROTOCOL_ID_SYSTEM:
case SCMI_PROTOCOL_ID_PERF:
case SCMI_PROTOCOL_ID_SENSOR:
-   *(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
-   return 0;
+   goto not_supported;
default:
break;
}
@@ -1239,6 +1258,10 @@ static int sandbox_scmi_test_process_msg(struct udevice 
*dev,
/* Intentionnaly report unhandled IDs through the SCMI return code */
*(u32 *)msg->out_msg = SCMI_PROTOCOL_ERROR;
return 0;
+
+not_supported:
+   *(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
+   return 0;
 }
 
 static int sandbox_scmi_test_remove(struct udevice *dev)
diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c 
b/drivers/firmware/scmi/sandbox-scmi_devices.c
index facb5b06ffb5..0519cf889aa9 100644
--- a/drivers/firmware/scmi/sandbox-scmi_devices.c
+++ b/drivers/firmware/scmi/sandbox-scmi_devices.c
@@ -62,12 +62,13 @@ static int sandbox_scmi_devices_remove(struct udevice *dev)
if (!devices)
return 0;
 
-   for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) {
-   int ret2 = reset_free(devices->reset + n);
+   if (IS_ENABLED(CONFIG_RESET_SCMI))
+   for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) {
+   int ret2 = reset_free(devices->reset + n);
 
-   if (ret2 && !ret)
-   ret = ret2;
-   }
+   if (ret2 && !ret)
+   ret = ret2;
+   }
 
return ret;
 }
@@ -89,39 +90,53 @@ static int sandbox_scmi_devices_probe(struct udevice *dev)
.regul_count = SCMI_TEST_DEVICES_VOLTD_COUNT,
};
 
-   ret = power_domain_get_by_index(dev, priv->devices.pwdom, 0);
-   if (ret) {
-   dev_err(dev, "%s: Failed on power domain\n", __func__);
-   return ret;
-   }
-
-   for (n = 0; n < SCMI_TEST_DEVICES_CLK_COUNT; n++) {
-   ret = clk_get_by_index(dev, n, priv->devices.clk + n);
+   if (IS_ENABLED(CONFIG_SCMI_

[PATCH 1/5] test: dm: skip scmi tests against disabled protocols

2023-10-24 Thread AKASHI Takahiro
This is a precautious change to make scmi tests workable whether or not
a specific protocol be enabled.

Signed-off-by: AKASHI Takahiro 
---
 test/dm/scmi.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/test/dm/scmi.c b/test/dm/scmi.c
index da45314f2e4c..2f63f2da16fb 100644
--- a/test/dm/scmi.c
+++ b/test/dm/scmi.c
@@ -217,6 +217,9 @@ static int dm_test_scmi_power_domains(struct 
unit_test_state *uts)
u8 *name;
int ret;
 
+   if (!IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN))
+   return 0;
+
/* preparation */
ut_assertok(load_sandbox_scmi_test_devices(uts, , ));
ut_assertnonnull(agent);
@@ -317,6 +320,9 @@ static int dm_test_scmi_clocks(struct unit_test_state *uts)
int ret_dev;
int ret;
 
+   if (!IS_ENABLED(CONFIG_CLK_SCMI))
+   return 0;
+
ret = load_sandbox_scmi_test_devices(uts, , );
if (ret)
return ret;
@@ -382,6 +388,9 @@ static int dm_test_scmi_resets(struct unit_test_state *uts)
struct udevice *agent_dev, *reset_dev, *dev = NULL;
int ret;
 
+   if (!IS_ENABLED(CONFIG_RESET_SCMI))
+   return 0;
+
ret = load_sandbox_scmi_test_devices(uts, , );
if (ret)
return ret;
@@ -418,6 +427,9 @@ static int dm_test_scmi_voltage_domains(struct 
unit_test_state *uts)
struct udevice *dev;
struct udevice *regul0_dev;
 
+   if (!IS_ENABLED(CONFIG_DM_REGULATOR_SCMI))
+   return 0;
+
ut_assertok(load_sandbox_scmi_test_devices(uts, , ));
 
scmi_devices = sandbox_scmi_devices_ctx(dev);
-- 
2.34.1



[PATCH 0/5] cmd: add scmi command

2023-10-24 Thread AKASHI Takahiro
"Scmi" command will be re-introduced per Michal's request.
The functionality is the same as I put it in my patch set of adding
SCMI base protocol support, but made some tweak to make UT, "ut dm
scmi_cmd," more flexible and tolerable when enabling/disabling a specific
SCMI protocol for test purpose.

Each commit may have some change history inherited from the preceding
patch series.

Test

The patch series was tested on the following platforms:
* sandbox


Prerequisite:
=
* This patch series is based on the latest master.

AKASHI Takahiro (5):
  test: dm: skip scmi tests against disabled protocols
  firmware: scmi: support protocols on sandbox only if enabled
  cmd: add scmi command for SCMI firmware
  doc: cmd: add documentation for scmi
  test: dm: add scmi command test

 cmd/Kconfig  |   9 +
 cmd/Makefile |   1 +
 cmd/scmi.c   | 335 +++
 configs/sandbox_defconfig|   1 +
 doc/usage/cmd/scmi.rst   | 126 +++
 doc/usage/index.rst  |   1 +
 drivers/firmware/scmi/sandbox-scmi_agent.c   |  27 +-
 drivers/firmware/scmi/sandbox-scmi_devices.c |  78 +++--
 test/dm/scmi.c   |  93 +
 9 files changed, 638 insertions(+), 33 deletions(-)
 create mode 100644 cmd/scmi.c
 create mode 100644 doc/usage/cmd/scmi.rst

-- 
2.34.1



Re: [PATCH v5 14/16] cmd: add scmi command for SCMI firmware

2023-10-24 Thread AKASHI Takahiro
Hi Tom, Michal,

On Tue, Oct 24, 2023 at 06:24:07PM -0400, Tom Rini wrote:
> On Tue, Oct 24, 2023 at 10:27:44AM +0200, Michal Simek wrote:
> > Hi Takahiro,
> > 
> > ?t 26. 9. 2023 v 9:00 odes?latel AKASHI Takahiro
> >  napsal:
> > >
> > > This command, "scmi", may provide a command line interface to various SCMI
> > > protocols. It supports at least initially SCMI base protocol and is
> > > intended mainly for debug purpose.
> > >
> > > Signed-off-by: AKASHI Takahiro 
> > > Reviewed-by: Simon Glass 
> > > Reviewed-by: Etienne Carriere 
> > > ---
> > > v3
> > > * describe that arguments are in hex at a help message
> > > * modify the code for dynamically allocated agent names
> > > v2
> > > * remove sub command category, 'scmi base', for simplicity
> > > ---
> > >  cmd/Kconfig  |   9 ++
> > >  cmd/Makefile |   1 +
> > >  cmd/scmi.c   | 337 +++
> > >  3 files changed, 347 insertions(+)
> > >  create mode 100644 cmd/scmi.c
> > >
> > > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > > index 43ca10f69ccf..f46152ace7d8 100644
> > > --- a/cmd/Kconfig
> > > +++ b/cmd/Kconfig
> > > @@ -2533,6 +2533,15 @@ config CMD_CROS_EC
> > >   a number of sub-commands for performing EC tasks such as
> > >   updating its flash, accessing a small saved context area
> > >   and talking to the I2C bus behind the EC (if there is one).
> > > +
> > > +config CMD_SCMI
> > > +   bool "Enable scmi command"
> > > +   depends on SCMI_FIRMWARE
> > > +   default n
> > 
> > This line above is wrong and this was removed from v6 with

@Michal, do you mean the default should be 'y'?

> > "drop scmi command which was intended to be used for debugging".
> > It is fine that it shouldn't be used on production system but it
> > doesn't mean that
> > it should be actually removed.
> > It is useful for bring ups. Can we get this patch merged? It was
> > already reviewed
> > anyway.
> 
> There was then also some conflict with the follow-up series here. I
> would be fine with the command being introduced again after I merge that
> second series, which I am testing now.

I don't mind neither.
My concern, however, was a test, "ut dm scmi_cmd".
The output from "scmi info" command varies depending on what SCMI protocols
are provided by SCMI firmware (sandbox fake server in this case).

I will try to keep it updated.

-Takahiro Akashi

> 
> -- 
> Tom




signature.asc
Description: PGP signature


Re: [v4 11/24] efi: Rearrange the Kconfig for CMD_BOOTEFI_BOOTMGR

2023-10-20 Thread AKASHI Takahiro
On Thu, Oct 19, 2023 at 11:19:33AM -0400, Tom Rini wrote:
> On Thu, Oct 19, 2023 at 05:16:28PM +0200, Heinrich Schuchardt wrote:
> > On 19.10.23 17:00, Tom Rini wrote:
> > > From: Simon Glass 
> > > 
> > > The command should not be used to enable library functionality. Add a
> > > new BOOTEFI_BOOTMGR Kconfig for that. Adjust the conditions so that the
> > > same code is built.
> > > 
> > > Signed-off-by: Simon Glass 
> > > Suggested-by: AKASHI Takahiro 
> > > ---
> > > Cc: Heinrich Schuchardt 
> > > Cc: Ilias Apalodimas 
> > > Changes in v4:
> > > - Integrate AKASHI Takahiro's feedback from v3
> > > - Reword the help text on CMD_BOOTEFI_BOOTMGR slightly
> > > ---
> > >   cmd/Kconfig | 11 ++-
> > >   lib/efi_loader/Kconfig  |  6 +++---
> > >   lib/efi_loader/Makefile |  2 +-
> > >   3 files changed, 14 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > > index 16e5cb8f0633..872cb49150cc 100644
> > > --- a/cmd/Kconfig
> > > +++ b/cmd/Kconfig
> > > @@ -379,6 +379,15 @@ config CMD_BOOTEFI
> > >   help
> > > Boot an EFI image from memory.
> > > +config CMD_BOOTEFI_BOOTMGR
> > > + bool "UEFI Boot Manager command"
> > > + depends on BOOTEFI_BOOTMGR && CMD_BOOTEFI
> > > + default y
> > > + help
> > > +   Select this option to enable the 'bootmgr' subcommand of 'bootefi'.
> > > +   This subcommand will allow you to select the UEFI binary to be booted
> > > +   via UEFI variables Boot, BootOrder, and BootNext.
> > > +
> > >   config CMD_BOOTEFI_HELLO_COMPILE
> > >   bool "Compile a standard EFI hello world binary for testing"
> > >   depends on CMD_BOOTEFI && !CPU_V7M
> > > @@ -2110,7 +2119,7 @@ config CMD_EFIDEBUG
> > >   config CMD_EFICONFIG
> > >   bool "eficonfig - provide menu-driven uefi variables 
> > > maintenance interface"
> > >   default y if !HAS_BOARD_SIZE_LIMIT
> > > - depends on CMD_BOOTEFI_BOOTMGR
> > > + depends on BOOTEFI_BOOTMGR
> > >   select MENU
> > >   help
> > > Enable the 'eficonfig' command which provides the menu-driven 
> > > UEFI
> > > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> > > index d20aaab6dba4..13cad6342c36 100644
> > > --- a/lib/efi_loader/Kconfig
> > > +++ b/lib/efi_loader/Kconfig
> > > @@ -32,14 +32,14 @@ config EFI_LOADER
> > >   if EFI_LOADER
> > > -config CMD_BOOTEFI_BOOTMGR
> > > +config BOOTEFI_BOOTMGR
> > >   bool "UEFI Boot Manager"
> > >   default y
> > >   select BOOTMETH_GLOBAL if BOOTSTD
> > >   help
> > > Select this option if you want to select the UEFI binary to 
> > > be booted
> > > -   via UEFI variables Boot, BootOrder, and BootNext. This enables the
> > > -   'bootefi bootmgr' command.
> > > +   via UEFI variables Boot, BootOrder, and BootNext. You should also
> > > +   normally enable CMD_BOOTEFI_BOOTMGR so that the command is available.
> > >   choice
> > >   prompt "Store for non-volatile UEFI variables"
> > > diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
> > > index 8d31fc61c601..0a2cb6e3c476 100644
> > > --- a/lib/efi_loader/Makefile
> > > +++ b/lib/efi_loader/Makefile
> > > @@ -42,7 +42,7 @@ targets += initrddump.o
> > >   endif
> > >   obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
> > > -obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += efi_bootmgr.o
> > > +obj-$(CONFIG_BOOTEFI_BOOTMGR) += efi_bootmgr.o
> > >   obj-y += efi_boottime.o
> > >   obj-y += efi_helper.o
> > >   obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o
> > 
> > This patch looks wrong.
> > 
> > Symbol CONFIG_CMD_BOOTEFI_BOOTMGR is used in a lot of places where it is not
> > related to the 'bootefi bootmgr' subcommand.
> > 
> > I see no benefit in two separate symbols. If you want to rename the symbol,
> > please, replace *all* occurrences:
> > 
> > %s/CONFIG_CMD_BOOTEFI_BOOTMGR/CONFIG_BOOTEFI_BOOTMGR/
> 
> Yes, there's work on the EFI_LOADER side of things to support the use
> case of "boot to menu" (or, "boot to efi bootmgr") of which this is the
> starting point. The follow-up work that I'm hoping you or someone else
> with more EFI_LOADER experience will pick up is splitting cmd/bootefi.c
> such that we can call in to starting an EFI payload (or bootmgr) without
> the command line.

I will be able to take care unless Heinrich wants to do by himself.
# Test would be another issue now that "bootefi" may handle various
  boot scenarios.

-Takahiro Akashi

> 
> -- 
> Tom




signature.asc
Description: PGP signature


Re: [PATCH v3 22/32] efi: Update EFI_LOADER to depend on DM_ETH

2023-10-19 Thread AKASHI Takahiro
On Thu, Oct 19, 2023 at 08:01:11AM -0600, Simon Glass wrote:
> Hi Heinrich,
> 
> On Wed, 18 Oct 2023 at 06:55, Heinrich Schuchardt  wrote:
> >
> > On 10/17/23 16:09, Tom Rini wrote:
> > > On Mon, Oct 16, 2023 at 04:28:13PM -0600, Simon Glass wrote:
> > >
> > >> Since efi_device_path.c calls eth_get_dev() and assumes that Ethernet is
> > >> available, add it as an explicit dependency.
> > >>
> > >> Signed-off-by: Simon Glass 
> > >> ---
> > >>
> > >> (no changes since v2)
> > >>
> > >> Changes in v2:
> > >> - Add new patch to update EFI_LOADER to depend on DM_ETH
> > >>
> > >>   lib/efi_loader/Kconfig | 1 +
> > >>   1 file changed, 1 insertion(+)
> > >>
> > >> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> > >> index 13cad6342c36..fca4b3eef270 100644
> > >> --- a/lib/efi_loader/Kconfig
> > >> +++ b/lib/efi_loader/Kconfig
> > >> @@ -11,6 +11,7 @@ config EFI_LOADER
> > >>  # We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB
> > >>  depends on !EFI_STUB || !X86 || X86_64 || EFI_STUB_32BIT
> > >>  depends on BLK
> > >> +depends on DM_ETH
> > >>  depends on !EFI_APP
> > >>  default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8
> > >>  select CHARSET
> > >
> > > Does this work for you Heinrich, or do you want to clarify the
> > > dependencies (and re-organize the code as needed) around networking?
> > >
> >
> > We should be able to boot via EFI on devices without U-Boot network support.
> >
> > We already use IS_ENABLED(CONFIG_NETDEVICES) to avoid invoking
> > eth_get_dev() if there is no network. CONFIG_NETDEVICES=y selects
> > CONFIG_DM_ETH.
> >
> > Why is this not sufficient?
> > Is there a configuration that does not build?
> 
> The point of this series is to disable CMDLINE and fix up what breaks.
> 
> In this case we have some sort of breakage...perhaps Tom has already
> found it, but otherwise could you take a look?
> 
> We should be able to disable NET and LTO in sandbox and still build.
> But this fails at present[1]. You can try it on -master

Obviously, it would be necessary to enclose efi_dp_from_eth()
with "if defined(CONFIG_NETDEVICES)" (or DM_ETH).
Then, we could drop "depends on DM_ETH".

Another possible place for completeness is "case UCLASS_ETH" clause
in dp_size(), but it seems to be harmless.

-Takahiro Akashi


> Regards,
> Simon
> 
> [1] sjg@sjg1:~/u$ crosfw sandbox -L
> cmd: make -j4 'CROSS_COMPILE=' --no-print-directory 'HOSTSTRIP=true'
> 'QEMU_ARCH=' 'KCONFIG_NOSILENTUPDATE=1' 'O=/tmp/b/sandbox' 'NO_LTO=1'
> -s 'BUILD_ROM=1' all
> /usr/bin/ld: lib/efi_loader/efi_device_path.o: in function `efi_dp_from_eth':
> /home/sjg/c/src/third_party/u-boot/files/lib/efi_loader/efi_device_path.c:985:(.text+0xca4):
> undefined reference to `eth_get_dev'
> /usr/bin/ld: 
> /home/sjg/c/src/third_party/u-boot/files/lib/efi_loader/efi_device_path.c:987:(.text+0xca9):
> undefined reference to `eth_get_dev'
> /usr/bin/ld: 
> /home/sjg/c/src/third_party/u-boot/files/lib/efi_loader/efi_device_path.c:993:(.text+0xcc9):
> undefined reference to `eth_get_dev'
> collect2: error: ld returned 1 exit status
> make[1]: *** [/home/sjg/c/src/third_party/u-boot/files/Makefile:1765:
> u-boot] Error 1
> make: *** [Makefile:177: sub-make] Error 2
> 
> sjg@sjg1:~/u$ crosfw sandbox
> sjg@sjg1:~/u$ (passes)
> 
> 'crosfw xx' is just 'buildman --bo xxx'
> 
> diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
> index a92bb896c63e..4e9996a92342 100644
> --- a/boot/pxe_utils.c
> +++ b/boot/pxe_utils.c
> @@ -48,7 +48,7 @@ int pxe_get_file_size(ulong *sizep)
> 
>   return 0;
>  }
> -
> +#if 0
>  /**
>   * format_mac_pxe() - obtain a MAC address in the PXE format
>   *
> @@ -82,7 +82,7 @@ int format_mac_pxe(char *outbuf, size_t outbuf_len)
> 
>   return 1;
>  }
> -
> +#endif
>  /**
>   * get_relfile() - read a file relative to the PXE file
>   *
> diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
> index 47417cb0391d..57bb6202dbb5 100644
> --- a/configs/sandbox_defconfig
> +++ b/configs/sandbox_defconfig
> @@ -349,3 +349,4 @@ CONFIG_TEST_FDTDEC=y
>  CONFIG_UNIT_TEST=y
>  CONFIG_UT_TIME=y
>  CONFIG_UT_DM=y
> +# CONFIG_NET is not set
> 
> Regards,
> Simon


Re: [PATCH v3 21/32] efi: Rearrange the Kconfig for CMD_BOOTEFI_BOOTMGR

2023-10-16 Thread AKASHI Takahiro
Hi Simon,

Thank you for taking my idea here.

On Mon, Oct 16, 2023 at 04:28:12PM -0600, Simon Glass wrote:
> The command should not be used to enable library functionality. Add a
> new BOOTEFI_BOOTMGR Kconfig for that. Adjust the conditions so that the
> same code is built.
> 
> Signed-off-by: Simon Glass 
> Suggested-by: AKASHI Takahiro 
> ---
> 
> Changes in v3:
> - Add new patch to rearrange the Kconfig for CMD_BOOTEFI_BOOTMGR
> 
>  cmd/Kconfig | 9 +
>  lib/efi_loader/Kconfig  | 7 +++
>  lib/efi_loader/Makefile | 2 +-
>  3 files changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index 46e484fc08b6..3b4112d9f319 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -306,6 +306,15 @@ config CMD_BOOTI
>   help
> Boot an AArch64 Linux Kernel image from memory.
>  
> +config CMD_BOOTEFI_BOOTMGR
> + bool "UEFI Boot Manager command"
> + depends on BOOTEFI_BOOTMGR && CMD_BOOTEFI
> + default y
> + help
> +   Select this option if you want to select the UEFI binary to be booted
> +   via UEFI variables Boot, BootOrder, and BootNext. This enables the
> +   'bootefi bootmgr' command.
> +
>  config BOOTM_LINUX

Do you have any intention to put this configuration here?
Otherwise, it should be placed just after CMD_BOOTEFI.

In addition, CMD_EFICONFIG should have a dependency on BOOTEFI_BOOTMGR
rather than CMD_BOOTEFI_BOOTMGR as it is a separate command.

Thanks,
-Takahiro Akashi

>   bool "Support booting Linux OS images"
>   depends on CMD_BOOTM || CMD_BOOTZ || CMD_BOOTI
> diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> index 621ed5e5b0fb..13cad6342c36 100644
> --- a/lib/efi_loader/Kconfig
> +++ b/lib/efi_loader/Kconfig
> @@ -32,15 +32,14 @@ config EFI_LOADER
>  
>  if EFI_LOADER
>  
> -config CMD_BOOTEFI_BOOTMGR
> +config BOOTEFI_BOOTMGR
>   bool "UEFI Boot Manager"
> - depends on CMDLINE
>   default y
>   select BOOTMETH_GLOBAL if BOOTSTD
>   help
> Select this option if you want to select the UEFI binary to be booted
> -   via UEFI variables Boot, BootOrder, and BootNext. This enables the
> -   'bootefi bootmgr' command.
> +   via UEFI variables Boot, BootOrder, and BootNext. You should also
> +   normally enable CMD_BOOTEFI_BOOTMGR so that the command is available.
>  
>  choice
>   prompt "Store for non-volatile UEFI variables"
> diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
> index 8d31fc61c601..0a2cb6e3c476 100644
> --- a/lib/efi_loader/Makefile
> +++ b/lib/efi_loader/Makefile
> @@ -42,7 +42,7 @@ targets += initrddump.o
>  endif
>  
>  obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
> -obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += efi_bootmgr.o
> +obj-$(CONFIG_BOOTEFI_BOOTMGR) += efi_bootmgr.o
>  obj-y += efi_boottime.o
>  obj-y += efi_helper.o
>  obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o
> -- 
> 2.42.0.655.g421f12c284-goog
> 


[PATCH v2 1/4] firmware: scmi: add power domain protocol support

2023-10-15 Thread AKASHI Takahiro
In this patch, added are helper functions to directly manipulate
SCMI power domain management protocol. DM compliant power domain
driver will be implemented on top of those interfaces in a succeeding
patch.

Signed-off-by: AKASHI Takahiro 
---
 drivers/firmware/scmi/Makefile |   1 +
 drivers/firmware/scmi/pwdom.c  | 189 +
 include/scmi_protocols.h   | 178 +++
 3 files changed, 368 insertions(+)
 create mode 100644 drivers/firmware/scmi/pwdom.c

diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile
index 1a23d4981709..dae42863589a 100644
--- a/drivers/firmware/scmi/Makefile
+++ b/drivers/firmware/scmi/Makefile
@@ -4,4 +4,5 @@ obj-y   += smt.o
 obj-$(CONFIG_SCMI_AGENT_SMCCC) += smccc_agent.o
 obj-$(CONFIG_SCMI_AGENT_MAILBOX)   += mailbox_agent.o
 obj-$(CONFIG_SCMI_AGENT_OPTEE) += optee_agent.o
+obj-$(CONFIG_SCMI_POWER_DOMAIN)+= pwdom.o
 obj-$(CONFIG_SANDBOX)  += sandbox-scmi_agent.o sandbox-scmi_devices.o
diff --git a/drivers/firmware/scmi/pwdom.c b/drivers/firmware/scmi/pwdom.c
new file mode 100644
index ..61b4338663de
--- /dev/null
+++ b/drivers/firmware/scmi/pwdom.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * SCMI Power domain management protocol
+ *
+ * Copyright (C) 2023 Linaro Limited
+ * author: AKASHI Takahiro 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int scmi_pwd_protocol_attrs(struct udevice *dev, int *num_pwdoms,
+   u64 *stats_addr, size_t *stats_len)
+{
+   struct scmi_pwd_protocol_attrs_out out;
+   struct scmi_msg msg = {
+   .protocol_id = SCMI_PROTOCOL_ID_POWER_DOMAIN,
+   .message_id = SCMI_PROTOCOL_ATTRIBUTES,
+   .out_msg = (u8 *),
+   .out_msg_sz = sizeof(out),
+   };
+   int ret;
+
+   if (!dev || !num_pwdoms || !stats_addr || !stats_len)
+   return -EINVAL;
+
+   ret = devm_scmi_process_msg(dev, );
+   if (ret)
+   return ret;
+   if (out.status)
+   return scmi_to_linux_errno(out.status);
+
+   *num_pwdoms = SCMI_PWD_PROTO_ATTRS_NUM_PWD(out.attributes);
+   *stats_addr = ((u64)out.stats_addr_high << 32) + out.stats_addr_low;
+   *stats_len = out.stats_len;
+
+   return 0;
+}
+
+int scmi_pwd_protocol_message_attrs(struct udevice *dev, s32 message_id,
+   u32 *attributes)
+{
+   struct scmi_pwd_protocol_msg_attrs_out out;
+   struct scmi_msg msg = {
+   .protocol_id = SCMI_PROTOCOL_ID_POWER_DOMAIN,
+   .message_id = SCMI_PROTOCOL_MESSAGE_ATTRIBUTES,
+   .in_msg = (u8 *)_id,
+   .in_msg_sz = sizeof(message_id),
+   .out_msg = (u8 *),
+   .out_msg_sz = sizeof(out),
+   };
+   int ret;
+
+   if (!dev || !attributes)
+   return -EINVAL;
+
+   ret = devm_scmi_process_msg(dev, );
+   if (ret)
+   return ret;
+   if (out.status)
+   return scmi_to_linux_errno(out.status);
+
+   *attributes = out.attributes;
+
+   return 0;
+}
+
+int scmi_pwd_attrs(struct udevice *dev, u32 domain_id, u32 *attributes,
+  u8 **name)
+{
+   struct scmi_pwd_attrs_out out;
+   struct scmi_msg msg = {
+   .protocol_id = SCMI_PROTOCOL_ID_POWER_DOMAIN,
+   .message_id = SCMI_PWD_ATTRIBUTES,
+   .in_msg = (u8 *)_id,
+   .in_msg_sz = sizeof(domain_id),
+   .out_msg = (u8 *),
+   .out_msg_sz = sizeof(out),
+   };
+   int ret;
+
+   if (!dev || !attributes || !name)
+   return -EINVAL;
+
+   ret = devm_scmi_process_msg(dev, );
+   if (ret)
+   return ret;
+   if (out.status)
+   return scmi_to_linux_errno(out.status);
+
+   *name = strdup(out.name);
+   if (!*name)
+   return -ENOMEM;
+
+   *attributes = out.attributes;
+
+   return 0;
+}
+
+int scmi_pwd_state_set(struct udevice *dev, u32 flags, u32 domain_id,
+  u32 pstate)
+{
+   struct scmi_pwd_state_set_in in;
+   s32 status;
+   struct scmi_msg msg = {
+   .protocol_id = SCMI_PROTOCOL_ID_POWER_DOMAIN,
+   .message_id = SCMI_PWD_STATE_SET,
+   .in_msg = (u8 *),
+   .in_msg_sz = sizeof(in),
+   .out_msg = (u8 *),
+   .out_msg_sz = sizeof(status),
+   };
+   int ret;
+
+   if (!dev)
+   return -EINVAL;
+
+   in.flags = flags;
+   in.domain_id = domain_id;
+   in.pstate = pstate;
+   ret = devm_scmi_process_msg(dev, );
+   if (ret)
+   return ret;
+   if (status)
+   return scmi_to_linux_errno(status);
+
+   return 0;
+}
+
+int scmi_pwd_state_get(struct udevice *de

[PATCH v2 4/4] test: dm: add SCMI power domain protocol test

2023-10-15 Thread AKASHI Takahiro
This ut has tests for the SCMI power domain protocol as well as DM
interfaces for power domain devices.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
---
v2
* remove a change at "test_scmi_cmd" because "scmi" command is no longer
  provided
---
 test/dm/scmi.c | 103 +
 1 file changed, 103 insertions(+)

diff --git a/test/dm/scmi.c b/test/dm/scmi.c
index d4ff60e00069..da45314f2e4c 100644
--- a/test/dm/scmi.c
+++ b/test/dm/scmi.c
@@ -206,6 +206,109 @@ static int dm_test_scmi_base(struct unit_test_state *uts)
 
 DM_TEST(dm_test_scmi_base, UT_TESTF_SCAN_FDT);
 
+static int dm_test_scmi_power_domains(struct unit_test_state *uts)
+{
+   struct sandbox_scmi_agent *agent;
+   struct sandbox_scmi_devices *scmi_devices;
+   struct udevice *agent_dev, *pwd, *dev;
+   u32 version, count, attributes, pstate;
+   u64 stats_addr;
+   size_t stats_len;
+   u8 *name;
+   int ret;
+
+   /* preparation */
+   ut_assertok(load_sandbox_scmi_test_devices(uts, , ));
+   ut_assertnonnull(agent);
+   scmi_devices = sandbox_scmi_devices_ctx(dev);
+   ut_assertnonnull(scmi_devices);
+   ut_asserteq(2, scmi_devices->pwdom->id); /* in test.dts */
+
+   ut_assertok(uclass_get_device_by_name(UCLASS_SCMI_AGENT, "scmi",
+ _dev));
+   ut_assertnonnull(agent_dev);
+   pwd = scmi_get_protocol(agent_dev, SCMI_PROTOCOL_ID_POWER_DOMAIN);
+   ut_assertnonnull(pwd);
+
+   /*
+* SCMI Power domain management protocol interfaces
+*/
+   /* version */
+   ret = scmi_generic_protocol_version(pwd, SCMI_PROTOCOL_ID_POWER_DOMAIN,
+   );
+   ut_assertok(ret);
+   ut_asserteq(agent->pwdom_version, version);
+
+   /* protocol attributes */
+   ret = scmi_pwd_protocol_attrs(pwd, , _addr, _len);
+   ut_assertok(ret);
+   ut_asserteq(agent->pwdom_count, count);
+   ut_asserteq(0, stats_len);
+
+   /* protocol message attributes */
+   ret = scmi_pwd_protocol_message_attrs(pwd, SCMI_PWD_STATE_SET,
+ );
+   ut_assertok(ret);
+   ret = scmi_pwd_protocol_message_attrs(pwd, SCMI_PWD_STATE_NOTIFY,
+ );
+   ut_asserteq(-ENOENT, ret); /* the protocol not supported */
+
+   /* power domain attributes */
+   ret = scmi_pwd_attrs(pwd, 0, , );
+   ut_assertok(ret);
+   ut_asserteq_str("power-domain--0", name);
+   free(name);
+
+   ret = scmi_pwd_attrs(pwd, 10, , );
+   ut_asserteq(-ENOENT, ret); /* domain-10 doesn't exist */
+
+   /* power domain state set/get */
+   ret = scmi_pwd_state_set(pwd, 0, 0, 0);
+   ut_assertok(ret);
+   ret = scmi_pwd_state_get(pwd, 0, );
+   ut_assertok(ret);
+   ut_asserteq(0, pstate); /* ON */
+
+   ret = scmi_pwd_state_set(pwd, 0, 0, SCMI_PWD_PSTATE_TYPE_LOST);
+   ut_assertok(ret);
+   ret = scmi_pwd_state_get(pwd, 0, );
+   ut_assertok(ret);
+   ut_asserteq(SCMI_PWD_PSTATE_TYPE_LOST, pstate); /* OFF */
+
+   ret = scmi_pwd_state_set(pwd, 0, 10, 0);
+   ut_asserteq(-ENOENT, ret);
+
+   /* power domain name get */
+   ret = scmi_pwd_name_get(pwd, 0, );
+   ut_assertok(ret);
+   ut_asserteq_str("power-domain--0-extended", name);
+   free(name);
+
+   ret = scmi_pwd_name_get(pwd, 10, );
+   ut_asserteq(-ENOENT, ret); /* domain-10 doesn't exist */
+
+   /*
+* U-Boot driver model interfaces
+*/
+   /* power_domain_on */
+   ret = power_domain_on(scmi_devices->pwdom);
+   ut_assertok(ret);
+   ret = scmi_pwd_state_get(pwd, scmi_devices->pwdom->id, );
+   ut_assertok(ret);
+   ut_asserteq(0, pstate); /* ON */
+
+   /* power_domain_off */
+   ret = power_domain_off(scmi_devices->pwdom);
+   ut_assertok(ret);
+   ret = scmi_pwd_state_get(pwd, scmi_devices->pwdom->id, );
+   ut_assertok(ret);
+   ut_asserteq(SCMI_PWD_PSTATE_TYPE_LOST, pstate); /* OFF */
+
+   return release_sandbox_scmi_test_devices(uts, dev);
+}
+
+DM_TEST(dm_test_scmi_power_domains, UT_TESTF_SCAN_FDT);
+
 static int dm_test_scmi_clocks(struct unit_test_state *uts)
 {
struct sandbox_scmi_agent *agent;
-- 
2.34.1



[PATCH v2 3/4] sandbox: add SCMI power domain protocol support for testing

2023-10-15 Thread AKASHI Takahiro
SCMI power domain management protocol is supported on sandbox
for test purpose. Add fake agent interfaces and associated
power domain devices.

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Simon Glass 
---
v2
* add a comment for a member, pstate, of struct sandbox_scmi_pwd
---
 arch/sandbox/dts/test.dts|   6 +
 arch/sandbox/include/asm/scmi_test.h |  21 ++
 configs/sandbox_defconfig|   1 +
 drivers/firmware/scmi/sandbox-scmi_agent.c   | 265 ++-
 drivers/firmware/scmi/sandbox-scmi_devices.c |  10 +
 5 files changed, 302 insertions(+), 1 deletion(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index c0ed2d83f3d2..309127a91004 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -732,6 +732,11 @@
#address-cells = <1>;
#size-cells = <0>;
 
+   pwrdom_scmi: protocol@11 {
+   reg = <0x11>;
+   #power-domain-cells = <1>;
+   };
+
clk_scmi: protocol@14 {
reg = <0x14>;
#clock-cells = <1>;
@@ -1635,6 +1640,7 @@
 
sandbox_scmi {
compatible = "sandbox,scmi-devices";
+   power-domains = <_scmi 2>;
clocks = <_scmi 2>, <_scmi 0>;
resets = <_scmi 3>;
regul0-supply = <_scmi>;
diff --git a/arch/sandbox/include/asm/scmi_test.h 
b/arch/sandbox/include/asm/scmi_test.h
index ccb0df6c148f..619f8f5098cd 100644
--- a/arch/sandbox/include/asm/scmi_test.h
+++ b/arch/sandbox/include/asm/scmi_test.h
@@ -6,10 +6,22 @@
 #ifndef __SANDBOX_SCMI_TEST_H
 #define __SANDBOX_SCMI_TEST_H
 
+#include 
+
 struct udevice;
 struct sandbox_scmi_agent;
 struct sandbox_scmi_service;
 
+/**
+ * struct sandbox_scmi_pwd
+ * @id:Identifier of the power domain used in the SCMI protocol
+ * @pstate::   Power state of the domain
+ */
+struct sandbox_scmi_pwd {
+   uint id;
+   u32 pstate;
+};
+
 /**
  * struct sandbox_scmi_clk - Simulated clock exposed by SCMI
  * @id:Identifier of the clock used in the SCMI protocol
@@ -45,6 +57,8 @@ struct sandbox_scmi_voltd {
 
 /**
  * struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent
+ * @pwdom_version: Implemented power domain protocol version
+ * @pwdom_count:   Simulated power domains array size
  * @clk:   Simulated clocks
  * @clk_count: Simulated clocks array size
  * @reset: Simulated reset domains
@@ -53,6 +67,9 @@ struct sandbox_scmi_voltd {
  * @voltd_count: Simulated voltage domains array size
  */
 struct sandbox_scmi_agent {
+   int pwdom_version;
+   struct sandbox_scmi_pwd *pwdom;
+   size_t pwdom_count;
struct sandbox_scmi_clk *clk;
size_t clk_count;
struct sandbox_scmi_reset *reset;
@@ -71,6 +88,8 @@ struct sandbox_scmi_service {
 
 /**
  * struct sandbox_scmi_devices - Reference to devices probed through SCMI
+ * @pwdom: Array of power domains
+ * @pwdom_count:   Number of power domains probed
  * @clk:   Array the clock devices
  * @clk_count: Number of clock devices probed
  * @reset: Array the reset controller devices
@@ -79,6 +98,8 @@ struct sandbox_scmi_service {
  * @regul_count:   Number of regulator devices probed
  */
 struct sandbox_scmi_devices {
+   struct power_domain *pwdom;
+   size_t pwdom_count;
struct clk *clk;
size_t clk_count;
struct reset_ctl *reset;
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 01830c7bd255..dbee9eb7f571 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -241,6 +241,7 @@ CONFIG_PINCTRL_SANDBOX=y
 CONFIG_PINCTRL_SINGLE=y
 CONFIG_POWER_DOMAIN=y
 CONFIG_SANDBOX_POWER_DOMAIN=y
+CONFIG_SCMI_POWER_DOMAIN=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_ACT8846=y
 CONFIG_DM_PMIC_PFUZE100=y
diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c 
b/drivers/firmware/scmi/sandbox-scmi_agent.c
index eb567dd900d7..9f5f497e0a6c 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -43,6 +43,8 @@
 #define SANDBOX_SCMI_AGENT_NAME "OSPM"
 #define SANDBOX_SCMI_PLATFORM_NAME "platform"
 
+#define SANDBOX_SCMI_PWD_PROTOCOL_VERSION SCMI_PWD_PROTOCOL_VERSION
+
 /**
  * struct sandbox_channel - Description of sandbox transport
  * @channel_id:Channel identifier
@@ -64,6 +66,7 @@ struct scmi_channel {
 };
 
 static u8 protocols[] = {
+   SCMI_PROTOCOL_ID_POWER_DOMAIN,
SCMI_PROTOCOL_ID_CLOCK,
SCMI_PROTOCOL_ID_RESET_DOMAIN,
SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,
@@ -71,6 +74,12 @@ static u8 protocols[] = {
 
 #define NUM_PROTOCOLS ARRAY_SIZE(protocols)
 
+static stru

[PATCH v2 2/4] power: domain: add SCMI driver

2023-10-15 Thread AKASHI Takahiro
Add power domain driver based on SCMI power domain management protocol.

Signed-off-by: AKASHI Takahiro 
---
v2
* remove tentative code which was enclosed by "#if 0"
* free allocated memory at the failure of probe function
---
 drivers/firmware/scmi/scmi_agent-uclass.c |  11 ++
 drivers/power/domain/Kconfig  |   7 +
 drivers/power/domain/Makefile |   1 +
 drivers/power/domain/scmi-power-domain.c  | 193 ++
 include/scmi_agent-uclass.h   |   2 +
 5 files changed, 214 insertions(+)
 create mode 100644 drivers/power/domain/scmi-power-domain.c

diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c 
b/drivers/firmware/scmi/scmi_agent-uclass.c
index 6f585b96f740..0f1003e167e6 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -86,6 +86,9 @@ struct udevice *scmi_get_protocol(struct udevice *dev,
case SCMI_PROTOCOL_ID_BASE:
proto = priv->base_dev;
break;
+   case SCMI_PROTOCOL_ID_POWER_DOMAIN:
+   proto = priv->pwdom_dev;
+   break;
case SCMI_PROTOCOL_ID_CLOCK:
proto = priv->clock_dev;
break;
@@ -133,6 +136,9 @@ static int scmi_add_protocol(struct udevice *dev,
case SCMI_PROTOCOL_ID_BASE:
priv->base_dev = proto;
break;
+   case SCMI_PROTOCOL_ID_POWER_DOMAIN:
+   priv->pwdom_dev = proto;
+   break;
case SCMI_PROTOCOL_ID_CLOCK:
priv->clock_dev = proto;
break;
@@ -405,6 +411,11 @@ static int scmi_bind_protocols(struct udevice *dev)
drv = NULL;
name = ofnode_get_name(node);
switch (protocol_id) {
+   case SCMI_PROTOCOL_ID_POWER_DOMAIN:
+   if (CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN) &&
+   scmi_protocol_is_supported(dev, protocol_id))
+   drv = DM_DRIVER_GET(scmi_power_domain);
+   break;
case SCMI_PROTOCOL_ID_CLOCK:
if (CONFIG_IS_ENABLED(CLK_SCMI) &&
scmi_protocol_is_supported(dev, protocol_id))
diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig
index 411c210756a3..bd82d2f7044b 100644
--- a/drivers/power/domain/Kconfig
+++ b/drivers/power/domain/Kconfig
@@ -83,6 +83,13 @@ config SANDBOX_POWER_DOMAIN
  simply accepts requests to power on/off various HW modules without
  actually doing anything beyond a little error checking.
 
+config SCMI_POWER_DOMAIN
+   bool "Enable SCMI power domain driver"
+   depends on POWER_DOMAIN && SCMI_FIRMWARE
+   help
+ Enable power domain implementation based on SCMI power domain
+ management protocol.
+
 config TEGRA186_POWER_DOMAIN
bool "Enable Tegra186 BPMP-based power domain driver"
depends on TEGRA186_BPMP
diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile
index aa5a4ba57cd8..2daab73eb758 100644
--- a/drivers/power/domain/Makefile
+++ b/drivers/power/domain/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_MESON_EE_POWER_DOMAIN) += meson-ee-pwrc.o
 obj-$(CONFIG_MESON_SECURE_POWER_DOMAIN) += meson-secure-pwrc.o
 obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o
 obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o
+obj-$(CONFIG_SCMI_POWER_DOMAIN) += scmi-power-domain.o
 obj-$(CONFIG_TEGRA186_POWER_DOMAIN) += tegra186-power-domain.o
 obj-$(CONFIG_TI_SCI_POWER_DOMAIN) += ti-sci-power-domain.o
 obj-$(CONFIG_TI_POWER_DOMAIN) += ti-power-domain.o
diff --git a/drivers/power/domain/scmi-power-domain.c 
b/drivers/power/domain/scmi-power-domain.c
new file mode 100644
index ..2b85efc08914
--- /dev/null
+++ b/drivers/power/domain/scmi-power-domain.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * SCMI Power domain driver
+ *
+ * Copyright (C) 2023 Linaro Limited
+ *  author: AKASHI Takahiro 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct scmi_pwd_properties
+ * @attributes:Power domain attributes
+ * @name:  Name of the domain
+ */
+struct scmi_pwd_properties {
+   u32 attributes;
+   u8 *name; /* not used now */
+};
+
+/**
+ * struct scmi_power_domain_priv
+ * @num_pwdoms:Number of power domains
+ * @prop:  Pointer to domain's properties
+ * @stats_addr:Address of statistics memory region
+ * @stats_len: Length of statistics memory region
+ */
+struct scmi_power_domain_priv {
+   int num_pwdoms;
+   struct scmi_pwd_properties *prop;
+   u64 stats_addr;
+   size_t stats_len;
+};
+
+/**
+ * async_is_supported - check asynchronous transition
+ * @attributes:Power domain attributes
+ *
+ * Determine 

[PATCH v2 0/4] firmware: scmi: add SCMI power domain protocol support

2023-10-15 Thread AKASHI Takahiro
This patch series allows users to access SCMI power domain protocol
provided by SCMI server (platform). See SCMI specification document
v3.2 beta 2[1] for more details about SCMI power domain protocol.

The implementation consists of two layers:
- basic helper functions for SCMI power domain protocol
  in drivers/firmware/scmi/pwdom.c (patch#1)
- DM-compliant power domain driver, which utilizes the helper functions,
  in drivers/power/domain/scmi-power-domain.c (patch#2)

[1] https://developer.arm.com/documentation/den0056/e/?lang=en

DT bindings
===
Standard bindings are applied, i.e.

scmi {
...
pwrdom_scmi: protocol@11 {
regs = <0x11>;
#power-domain-cells = <1>;
}
...
}

som-device {
...
power-domains = <_scmi 2>;
}

Test

The patch series was tested on the following platform:
* sandbox ("ut dm scmi_power_domains")


Prerequisite:
=
* This patch series is based on the master which now includes my "Base
  protocol support" patches v6[2]

[2] https://lists.denx.de/pipermail/u-boot/2023-September/531623.html

Patches:

Patch#1: Add SCMI power domain protocol helpers
Patch#2: Add power domain driver
Patch#3-#4: Test related


Change history:
===
v2 (Oct 16, 2023)
* remove a change on "test_scmi_cmd" because "scmi" command is no longer
  provided with base protocol v6
* some cleanup
v1 (Sep 26, 2023)
* initial release

AKASHI Takahiro (4):
  firmware: scmi: add power domain protocol support
  power: domain: add SCMI driver
  sandbox: add SCMI power domain protocol support for testing
  test: dm: add SCMI power domain protocol test

 arch/sandbox/dts/test.dts|   6 +
 arch/sandbox/include/asm/scmi_test.h |  21 ++
 configs/sandbox_defconfig|   1 +
 drivers/firmware/scmi/Makefile   |   1 +
 drivers/firmware/scmi/pwdom.c| 189 +
 drivers/firmware/scmi/sandbox-scmi_agent.c   | 265 ++-
 drivers/firmware/scmi/sandbox-scmi_devices.c |  10 +
 drivers/firmware/scmi/scmi_agent-uclass.c|  11 +
 drivers/power/domain/Kconfig |   7 +
 drivers/power/domain/Makefile|   1 +
 drivers/power/domain/scmi-power-domain.c | 193 ++
 include/scmi_agent-uclass.h  |   2 +
 include/scmi_protocols.h | 178 +
 test/dm/scmi.c   | 103 +++
 14 files changed, 987 insertions(+), 1 deletion(-)
 create mode 100644 drivers/firmware/scmi/pwdom.c
 create mode 100644 drivers/power/domain/scmi-power-domain.c

-- 
2.34.1



Re: [PATCH 4/4] test: dm: add SCMI power domain protocol test

2023-10-15 Thread AKASHI Takahiro
Hi Tom,

On Fri, Oct 13, 2023 at 09:20:48PM -0400, Tom Rini wrote:
> On Tue, Sep 26, 2023 at 04:00:43PM +0900, AKASHI Takahiro wrote:
> 
> > This ut has tests for the SCMI power domain protocol as well as DM
> > interfaces for power domain devices.
> > 
> > Signed-off-by: AKASHI Takahiro 
> > Reviewed-by: Simon Glass 
> > ---
> >  test/dm/scmi.c | 107 -
> >  1 file changed, 106 insertions(+), 1 deletion(-)
> 
> With v6 of the required series there is no scmi command, so, how do we
> test this support now?

Well, "ut dm scmi_power_domains" does test the code at function level
(both for SCMI protocol APIs and DM's power_domain_*() interfaces).

That said, prior to v6, we needed to adjust the output from "smci info"
command and hence "ut dm scmi_cmd" test because it, more specifically base
protocol's DISCOVER_LIST_PROTOCOLS, tries to enumerate available protocols
including power domain protocol.

With v6, we can simply remove the first hunk in this commit.
I will submit a new version with this change.

Thanks,
-Takahiro Akashi

> 
> -- 
> Tom




signature.asc
Description: PGP signature


Re: [PATCH v6 08/14] firmware: scmi: add a version check against base protocol

2023-10-11 Thread AKASHI Takahiro
Hi Etienne,

Thank you again for your review.

On Wed, Oct 11, 2023 at 03:44:36PM +, Etienne CARRIERE - foss wrote:
> > From: U-Boot  on behalf of AKASHI Takahiro 
> > 
> > Sent: Wednesday, October 11, 2023 12:07 PM
> > 
> > In SCMI base protocol version 2 (0x2), new interfaces,
> > BASE_SET_DEVICE_PERMISSIONS/BASE_SET_PROTOCOL_PERMISSIONS/
> > BASE_RESET_AGENT_CONFIGURATION, were added. Moreover, the api of
> > BASE_DISCOVER_AGENT was changed to support self-agent discovery.
> > 
> > So the driver expects SCMI firmware support version 2 of base protocol.
> > 
> > Signed-off-by: AKASHI Takahiro 
> > ---
> > v6
> > * new commit
> > ---
> >  drivers/firmware/scmi/base.c | 8 
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/drivers/firmware/scmi/base.c b/drivers/firmware/scmi/base.c
> > index ee84e261945a..1d41a8a98fc6 100644
> > --- a/drivers/firmware/scmi/base.c
> > +++ b/drivers/firmware/scmi/base.c
> > @@ -481,6 +481,7 @@ static int 
> > scmi_base_reset_agent_configuration_int(struct udevice *dev,
> >   */
> >  static int scmi_base_probe(struct udevice *dev)
> >  {
> > +   u32 version;
> > int ret;
> > 
> > ret = devm_scmi_of_get_channel(dev);
> > @@ -488,6 +489,13 @@ static int scmi_base_probe(struct udevice *dev)
> > dev_err(dev, "get_channel failed\n");
> > return ret;
> > }
> > +   ret = scmi_base_protocol_version_int(dev, );
> > +   if (ret) {
> > +   dev_err(dev, "getting protocol version failed\n");
> > +   return ret;
> > +   }
> > +   if (version < SCMI_BASE_PROTOCOL_VERSION)
> > +   return -EINVAL;
> 
> LGTM. The open source SCMI server implementations I'm aware of (scp-firmware, 
> tf-a and optee-os) all report SCMI Base protocol version v2.0.

Yeah, I also confirmed this.

> Reviewed-by: Etienne Carriere 
> 
> That said, maybe a more flexible implementation would support both version 
> v1.0 (0x1) and v2.0

SCMI v2.0 (not the base protocol, but the specification itself)
introduced base protocol v2.0 and the spec was published in 2019.
Along with the status of the existing SCMI server implementation (as you
mentioned above), I doubt any chance that there comes up any new SCMI with
the base protocol v1.0 in the future.

> but disable permission commands for v1.0 compliant servers. Maybe in a later 
> change, if there is a need for.

Yes, we can make a tweak later. But anyhow "permission" commands are
categorized as optional even in v2.0 (i.e. the firmware may still return
SCMI_NOT_SUPPORTED) and U-Boot has no framework to utilize them for now.

BTW, I will not add a version check against all the existing protocols
(you implemented) as they utilize only the interfaces defined in each one's 
v1.0.

Thanks,
-Takahiro Akashi

> I fear using such strict minima protocol version values for other SCMI 
> procotols make U-Boot client too restrictive.
> 
> BR,
> Etienne
> 
> > 
> > return ret;
> >  }
> > --
> > 2.34.1
> > 
> > 


[PATCH v6 14/14] firmware: scmi: add a check against availability of protocols

2023-10-11 Thread AKASHI Takahiro
Now that we have Base protocol support, we will be able to check if a given
protocol is really supported by the SCMI server (firmware).

Signed-off-by: AKASHI Takahiro 
Reviewed-by: Etienne Carriere 
Reviewed-by: Simon Glass 
---
v3
* new; import this patch from my followup patch set
---
 drivers/firmware/scmi/scmi_agent-uclass.c | 41 +--
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c 
b/drivers/firmware/scmi/scmi_agent-uclass.c
index b1a9c36310c1..6f585b96f740 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -38,6 +38,38 @@ static const struct error_code scmi_linux_errmap[] = {
{ .scmi = SCMI_PROTOCOL_ERROR, .errno = -EPROTO, },
 };
 
+/**
+ * scmi_protocol_is_supported - check availability of protocol
+ * @dev:   SCMI agent device
+ * @proto_id:  Identifier of protocol
+ *
+ * check if the protocol, @proto_id, is provided by the SCMI agent,
+ * @dev.
+ *
+ * Return: 0 on success, error code otherwise
+ */
+static bool scmi_protocol_is_supported(struct udevice *dev,
+  enum scmi_std_protocol proto_id)
+{
+   struct scmi_agent_priv *priv;
+   int i;
+
+   if (proto_id == SCMI_PROTOCOL_ID_BASE)
+   return true;
+
+   priv = dev_get_uclass_plat(dev);
+   if (!priv) {
+   dev_err(dev, "No priv data found\n");
+   return false;
+   }
+
+   for (i = 0; i < priv->num_protocols; i++)
+   if (priv->protocols[i] == proto_id)
+   return true;
+
+   return false;
+}
+
 struct udevice *scmi_get_protocol(struct udevice *dev,
  enum scmi_std_protocol id)
 {
@@ -374,15 +406,18 @@ static int scmi_bind_protocols(struct udevice *dev)
name = ofnode_get_name(node);
switch (protocol_id) {
case SCMI_PROTOCOL_ID_CLOCK:
-   if (CONFIG_IS_ENABLED(CLK_SCMI))
+   if (CONFIG_IS_ENABLED(CLK_SCMI) &&
+   scmi_protocol_is_supported(dev, protocol_id))
drv = DM_DRIVER_GET(scmi_clock);
break;
case SCMI_PROTOCOL_ID_RESET_DOMAIN:
-   if (IS_ENABLED(CONFIG_RESET_SCMI))
+   if (IS_ENABLED(CONFIG_RESET_SCMI) &&
+   scmi_protocol_is_supported(dev, protocol_id))
drv = DM_DRIVER_GET(scmi_reset_domain);
break;
case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
-   if (IS_ENABLED(CONFIG_DM_REGULATOR_SCMI)) {
+   if (IS_ENABLED(CONFIG_DM_REGULATOR_SCMI) &&
+   scmi_protocol_is_supported(dev, protocol_id)) {
node = ofnode_find_subnode(node, "regulators");
if (!ofnode_valid(node)) {
dev_err(dev, "no regulators node\n");
-- 
2.34.1



  1   2   3   4   5   6   7   8   9   10   >