u-boot.lists.denx.de archive mirror
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: U-Boot Mailing List <u-boot@lists.denx.de>
Cc: Heinrich Schuchardt <xypron.glpk@gmx.de>,
	Bin Meng <bmeng.cn@gmail.com>,
	Christian Melki <christian.melki@t2data.com>,
	Tom Rini <trini@konsulko.com>,
	Ilias Apalodimas <ilias.apalodimas@linaro.org>,
	Simon Glass <sjg@chromium.org>, Alexander Graf <agraf@csgraf.de>
Subject: [PATCH v2 33/39] efi: Move exit_boot_services into a function
Date: Fri, 24 Sep 2021 18:30:49 -0600	[thread overview]
Message-ID: <20210925003055.759305-18-sjg@chromium.org> (raw)
In-Reply-To: <20210925003055.759305-1-sjg@chromium.org>

At present this code is inline in the app and stub. But they do the same
thing. The difference is that the stub does it immediately and the app
doesn't want to do it until the end (when it boots a kernel) or not at
all, if returning to UEFI.

Move it into a function so it can be called as needed.

Also store the memory map so that it can be accessed within the app if
needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2:
- Add a sentence about what the patch does

 include/efi.h      | 32 ++++++++++++++++++++++
 lib/efi/efi.c      | 68 ++++++++++++++++++++++++++++++++++++++++++++++
 lib/efi/efi_app.c  |  3 ++
 lib/efi/efi_stub.c | 66 ++++++++------------------------------------
 4 files changed, 114 insertions(+), 55 deletions(-)

diff --git a/include/efi.h b/include/efi.h
index 6d0eae67479..e04ef942161 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -407,6 +407,12 @@ static inline struct efi_mem_desc *efi_get_next_mem_desc(
  * @sys_table: Pointer to system table
  * @boot: Pointer to boot-services table
  * @run: Pointer to runtime-services table
+ * @memmap_key: Key returned from get_memory_map()
+ * @memmap_desc: List of memory-map records
+ * @memmap_alloc: Amount of memory allocated for memory map list
+ * @memmap_size Size of memory-map list in bytes
+ * @memmap_desc_size: Size of an individual memory-map record, in bytes
+ * @memmap_version: Memory-map version
  *
  * Used by app only:
  * @use_pool_for_malloc: true if all allocation should go through the EFI 'pool'
@@ -426,6 +432,12 @@ struct efi_priv {
 	struct efi_system_table *sys_table;
 	struct efi_boot_services *boot;
 	struct efi_runtime_services *run;
+	efi_uintn_t memmap_key;
+	struct efi_mem_desc *memmap_desc;
+	efi_uintn_t memmap_alloc;
+	efi_uintn_t memmap_size;
+	efi_uintn_t memmap_desc_size;
+	u32 memmap_version;
 
 	/* app: */
 	bool use_pool_for_malloc;
@@ -576,4 +588,24 @@ void efi_putc(struct efi_priv *priv, const char ch);
  */
 int efi_info_get(enum efi_entry_t type, void **datap, int *sizep);
 
+/**
+ * efi_store_memory_map() - Collect the memory-map info from EFI
+ *
+ * Collect the memory info and store it for later use, e.g. in calling
+ * exit_boot_services()
+ *
+ * @priv:	Pointer to private EFI structure
+ * @return 0 if OK, non-zero on error
+ */
+int efi_store_memory_map(struct efi_priv *priv);
+
+/**
+ * efi_call_exit_boot_services() - Handlet eh exit-boot-service procedure
+ *
+ * Tell EFI we don't want their boot services anymore
+ *
+ * @return 0 if OK, non-zero on error
+ */
+int efi_call_exit_boot_services(void);
+
 #endif /* _LINUX_EFI_H */
diff --git a/lib/efi/efi.c b/lib/efi/efi.c
index cd6bf47b180..20da88c9151 100644
--- a/lib/efi/efi.c
+++ b/lib/efi/efi.c
@@ -135,3 +135,71 @@ void efi_free(struct efi_priv *priv, void *ptr)
 
 	boot->free_pool(ptr);
 }
+
+int efi_store_memory_map(struct efi_priv *priv)
+{
+	struct efi_boot_services *boot = priv->sys_table->boottime;
+	efi_uintn_t size, desc_size;
+	efi_status_t ret;
+
+	/* Get the memory map so we can switch off EFI */
+	size = 0;
+	ret = boot->get_memory_map(&size, NULL, &priv->memmap_key,
+				   &priv->memmap_desc_size,
+				   &priv->memmap_version);
+	if (ret != EFI_BUFFER_TOO_SMALL) {
+		printhex2(EFI_BITS_PER_LONG);
+		putc(' ');
+		printhex2(ret);
+		puts(" No memory map\n");
+		return ret;
+	}
+	/*
+	 * Since doing a malloc() may change the memory map and also we want to
+	 * be able to read the memory map in efi_call_exit_boot_services()
+	 * below, after more changes have happened
+	 */
+	priv->memmap_alloc = size + 1024;
+	priv->memmap_size = priv->memmap_alloc;
+	priv->memmap_desc = efi_malloc(priv, size, &ret);
+	if (!priv->memmap_desc) {
+		printhex2(ret);
+		puts(" No memory for memory descriptor\n");
+		return ret;
+	}
+
+	ret = boot->get_memory_map(&priv->memmap_size, priv->memmap_desc,
+				   &priv->memmap_key, &desc_size,
+				   &priv->memmap_version);
+	if (ret) {
+		printhex2(ret);
+		puts(" Can't get memory map\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+int efi_call_exit_boot_services(void)
+{
+	struct efi_priv *priv = efi_get_priv();
+	const struct efi_boot_services *boot = priv->boot;
+	efi_uintn_t size;
+	u32 version;
+	efi_status_t ret;
+
+	size = priv->memmap_alloc;
+	ret = boot->get_memory_map(&size, priv->memmap_desc,
+				   &priv->memmap_key,
+				   &priv->memmap_desc_size, &version);
+	if (ret) {
+		printhex2(ret);
+		puts(" Can't get memory map\n");
+		return ret;
+	}
+	ret = boot->exit_boot_services(priv->parent_image, priv->memmap_key);
+	if (ret)
+		return ret;
+
+	return 0;
+}
diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c
index a0ae2a531ee..23a65c46fd4 100644
--- a/lib/efi/efi_app.c
+++ b/lib/efi/efi_app.c
@@ -341,6 +341,9 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
 		printf("Failed to set up memory: ret=%lx\n", ret);
 		return ret;
 	}
+	ret = efi_store_memory_map(priv);
+	if (ret)
+		return ret;
 
 	printf("starting\n");
 
diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
index bc4c3a48720..5b08c1c40c7 100644
--- a/lib/efi/efi_stub.c
+++ b/lib/efi/efi_stub.c
@@ -297,15 +297,12 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
 {
 	struct efi_priv local_priv, *priv = &local_priv;
 	struct efi_boot_services *boot = sys_table->boottime;
-	struct efi_mem_desc *desc;
 	struct efi_entry_memmap map;
 	struct efi_gop *gop;
 	struct efi_entry_gopmode mode;
 	struct efi_entry_systable table;
 	efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
-	efi_uintn_t key, desc_size, size;
 	efi_status_t ret;
-	u32 version;
 	int cs32;
 
 	ret = efi_init(priv, "Payload", image, sys_table);
@@ -320,24 +317,11 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
 	if (cs32 < 0)
 		return EFI_UNSUPPORTED;
 
-	/* Get the memory map so we can switch off EFI */
-	size = 0;
-	ret = boot->get_memory_map(&size, NULL, &key, &desc_size, &version);
-	if (ret != EFI_BUFFER_TOO_SMALL) {
-		printhex2(EFI_BITS_PER_LONG);
-		putc(' ');
-		printhex2(ret);
-		puts(" No memory map\n");
-		return ret;
-	}
-	size += 1024;	/* Since doing a malloc() may change the memory map! */
-	desc = efi_malloc(priv, size, &ret);
-	if (!desc) {
-		printhex2(ret);
-		puts(" No memory for memory descriptor\n");
+	ret = efi_store_memory_map(priv);
+	if (ret)
 		return ret;
-	}
-	ret = setup_info_table(priv, size + 128);
+
+	ret = setup_info_table(priv, priv->memmap_size + 128);
 	if (ret)
 		return ret;
 
@@ -353,48 +337,20 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
 			       sizeof(struct efi_gop_mode_info));
 	}
 
-	ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version);
-	if (ret) {
-		printhex2(ret);
-		puts(" Can't get memory map\n");
-		return ret;
-	}
-
 	table.sys_table = (ulong)sys_table;
 	add_entry_addr(priv, EFIET_SYS_TABLE, &table, sizeof(table), NULL, 0);
 
-	ret = boot->exit_boot_services(image, key);
-	if (ret) {
-		/*
-		 * Unfortunately it happens that we cannot exit boot services
-		 * the first time. But the second time it work. I don't know
-		 * why but this seems to be a repeatable problem. To get
-		 * around it, just try again.
-		 */
-		printhex2(ret);
-		puts(" Can't exit boot services\n");
-		size = sizeof(desc);
-		ret = boot->get_memory_map(&size, desc, &key, &desc_size,
-					   &version);
-		if (ret) {
-			printhex2(ret);
-			puts(" Can't get memory map\n");
-			return ret;
-		}
-		ret = boot->exit_boot_services(image, key);
-		if (ret) {
-			printhex2(ret);
-			puts(" Can't exit boot services 2\n");
-			return ret;
-		}
-	}
+	ret = efi_call_exit_boot_services();
+	if (ret)
+		return ret;
 
 	/* The EFI UART won't work now, switch to a debug one */
 	use_uart = true;
 
-	map.version = version;
-	map.desc_size = desc_size;
-	add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map), desc, size);
+	map.version = priv->memmap_version;
+	map.desc_size = priv->memmap_desc_size;
+	add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map),
+		       priv->memmap_desc, priv->memmap_size);
 	add_entry_addr(priv, EFIET_END, NULL, 0, 0, 0);
 
 	memcpy((void *)CONFIG_SYS_TEXT_BASE, _binary_u_boot_bin_start,
-- 
2.33.0.685.g46640cef36-goog


  parent reply	other threads:[~2021-09-25  0:44 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-25  0:30 [PATCH v2 00/39] efi: Improvements to U-Boot running on top of UEFI Simon Glass
2021-09-25  0:30 ` [PATCH v2 01/39] RFC: efi: Drop code that doesn't work with driver model Simon Glass
2021-10-20 23:34   ` Heinrich Schuchardt
2022-10-14 11:51     ` Jan Kiszka
2022-10-14 13:13       ` Tom Rini
2022-10-14 15:33         ` Simon Glass
2022-10-14 15:34           ` Jan Kiszka
2022-10-14 15:36             ` Simon Glass
2022-10-14 15:39               ` Tom Rini
2022-10-14 15:47                 ` Jan Kiszka
2022-10-14 15:58                   ` Tom Rini
2022-10-14 15:10       ` Heinrich Schuchardt
2022-10-14 15:20         ` Tom Rini
2022-10-14 15:27           ` Jan Kiszka
2022-10-14 15:34             ` Tom Rini
2022-10-14 15:35               ` Jan Kiszka
2022-10-14 15:38                 ` Tom Rini
2022-10-14 15:25         ` Jan Kiszka
2021-09-25  0:30 ` [PATCH v2 02/39] efi: Add a separate maintainer entry for the app Simon Glass
2021-10-18 16:36   ` Heinrich Schuchardt
2021-09-25  0:30 ` [PATCH v2 03/39] x86: Keep symbol information in u-boot ELF file Simon Glass
2021-09-25  0:30 ` [PATCH v2 04/39] x86: Create a new header for EFI Simon Glass
2021-10-18 17:00   ` Heinrich Schuchardt
2021-09-25  0:30 ` [PATCH v2 05/39] x86: Show some EFI info with the bdinfo command Simon Glass
2021-10-18 17:10   ` Heinrich Schuchardt
2021-10-26  3:29     ` Simon Glass
2021-09-25  0:30 ` [PATCH v2 06/39] x86: Tidy up global_data pointer for 64-bit Simon Glass
2021-10-18 17:15   ` Heinrich Schuchardt
2021-10-26  3:29     ` Simon Glass
2021-09-25  0:30 ` [PATCH v2 07/39] efi: Add a script for building and testing U-Boot on UEFI Simon Glass
2021-10-18 17:30   ` Heinrich Schuchardt
2021-10-18 18:12     ` Simon Glass
2021-10-25 19:35   ` Heinrich Schuchardt
2021-10-26  3:29     ` Simon Glass
2021-09-25  0:30 ` [PATCH v2 08/39] efi: Enable DM_ETH for the app Simon Glass
2021-09-25  0:30 ` [PATCH v2 09/39] efi: Drop the OF_EMBED warning for EFI Simon Glass
2021-10-23 11:37   ` Heinrich Schuchardt
2021-10-26  3:29     ` Simon Glass
2021-09-25  0:30 ` [PATCH v2 10/39] x86: Create a 32/64-bit selection for the app Simon Glass
2021-10-23 11:41   ` Heinrich Schuchardt
2021-09-25  0:30 ` [PATCH v2 11/39] efi: Create a 64-bit app Simon Glass
2021-09-25  0:30 ` [PATCH v2 12/39] x86: Don't duplicate global_ptr in 64-bit EFI app Simon Glass
2021-09-25  0:30 ` [PATCH v2 13/39] efi: Add a way to obtain boot services in the app Simon Glass
2021-09-25  0:30 ` [PATCH v2 14/39] efi: Add video support to " Simon Glass
2021-09-25  0:30 ` [PATCH v2 15/39] efi: Add EFI uclass for media Simon Glass
2021-10-23 12:26   ` Heinrich Schuchardt
2021-10-26  3:29     ` Simon Glass
2021-09-25  0:30 ` [PATCH v2 16/39] efi: Add a media/block driver for EFI block devices Simon Glass
2021-09-25  0:30 ` [PATCH v2 17/39] efi: Locate all block devices in the app Simon Glass
2021-09-25  0:30 ` [PATCH v2 18/39] patman: Use a ValueError exception if tools.Run() fails Simon Glass
2021-09-25  0:30 ` [PATCH v2 19/39] binman: Report an error if test files fail to compile Simon Glass
2021-09-25  0:30 ` [PATCH v2 20/39] binman: Support reading the offset of an ELF-file symbol Simon Glass
2021-09-25  0:30 ` [PATCH v2 21/39] binman: Allow timeout to occur in the image or its section Simon Glass
2021-09-25  0:30 ` [PATCH v2 22/39] binman: Tidy up comments on _DoTestFile() Simon Glass
2021-09-25  0:30 ` [PATCH v2 23/39] binman: Support updating the dtb in an ELF file Simon Glass
2021-09-25  0:30 ` [PATCH v2 24/39] efi: serial: Support arrow keys Simon Glass
2021-10-18 16:55   ` Heinrich Schuchardt
2021-10-26  3:29     ` Simon Glass
2021-09-25  0:30 ` [PATCH v2 25/39] bloblist: Support allocating the bloblist Simon Glass
2021-09-25  0:30 ` [PATCH v2 26/39] x86: Allow booting a kernel from the EFI app Simon Glass
2021-09-25  0:30 ` [PATCH v2 27/39] x86: Don't process the kernel command line unless enabled Simon Glass
2021-09-25  0:30 ` [PATCH v2 28/39] x86: efi: Add room for the binman definition in the dtb Simon Glass
2021-09-25  0:30 ` [PATCH v2 29/39] efi: Add comments to struct efi_priv Simon Glass
2021-10-23 11:28   ` Heinrich Schuchardt
2021-09-25  0:30 ` [PATCH v2 30/39] efi: Fix ll_boot_init() operation with the app Simon Glass
2021-09-25  0:30 ` [PATCH v2 32/39] efi: Share struct efi_priv between the app and stub code Simon Glass
2021-09-25  0:30 ` Simon Glass [this message]
2021-09-25  0:30 ` [PATCH v2 34/39] efi: Check for failure when initing the app Simon Glass
2021-09-25  0:30 ` [PATCH v2 35/39] efi: Mention that efi_info_get() is only used in the stub Simon Glass
2021-09-25  0:30 ` [PATCH v2 36/39] efi: Show when allocated pages are used Simon Glass
2021-09-25  0:30 ` [PATCH v2 37/39] efi: Allow easy selection of serial-only operation Simon Glass
2021-09-25  0:30 ` [PATCH v2 38/39] efi: Update efi_get_next_mem_desc() to avoid needing a map Simon Glass
2021-09-25  0:30 ` [PATCH v2 39/39] efi: Support the efi command in the app Simon Glass
2021-10-18 15:25 ` [PATCH v2 00/39] efi: Improvements to U-Boot running on top of UEFI Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210925003055.759305-18-sjg@chromium.org \
    --to=sjg@chromium.org \
    --cc=agraf@csgraf.de \
    --cc=bmeng.cn@gmail.com \
    --cc=christian.melki@t2data.com \
    --cc=ilias.apalodimas@linaro.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).