From 5410540f02866e7488be81c7a6d8c82adceca056 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Fri, 14 Sep 2018 19:59:46 +0100 Subject: [PATCH 1/3] remove obsolete patches --- AW64-add-spl-atf-support.patch | 194 --------------------------------- fdt-fixes.patch | 171 ----------------------------- 2 files changed, 365 deletions(-) delete mode 100644 AW64-add-spl-atf-support.patch delete mode 100644 fdt-fixes.patch diff --git a/AW64-add-spl-atf-support.patch b/AW64-add-spl-atf-support.patch deleted file mode 100644 index 8a5cbc6..0000000 --- a/AW64-add-spl-atf-support.patch +++ /dev/null @@ -1,194 +0,0 @@ -From patchwork Fri Mar 31 22:31:26 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,14/19] sunxi: 64-bit SoCs: introduce FIT generator script -From: Andre Przywara -X-Patchwork-Id: 745831 -X-Patchwork-Delegate: jagannadh.teki@gmail.com -Message-Id: <1490999491-14899-15-git-send-email-andre.przywara@arm.com> -To: Maxime Ripard , - Jagan Teki , Simon Glass , - Tom Rini -Cc: Philipp Tomsich , - Michal Simek , u-boot@lists.denx.de, - Icenowy Zheng -Date: Fri, 31 Mar 2017 23:31:26 +0100 - -Now that the Makefile can call a generator script to build a more -advanced FIT image, let's use this feature to address the needs of -Allwinner boards with 64-bit SoCs (A64 and H5). -The (DTB stripped) U-Boot binary and the ATF are static, but we allow -an arbitrary number of supported device trees to be passed. -The script enters both a DT entry in the /images node and the respective -subnode in /configurations to support all listed DTBs. - -This requires to copy the ARM Trusted Firmware build (bl31.bin) into -the U-Boot source directory (or to create a symlink to it). - -Signed-off-by: Andre Przywara -Reviewed-by: Simon Glass -Acked-by: Maxime Ripard ---- - board/sunxi/mksunxi_fit_atf.sh | 73 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 73 insertions(+) - create mode 100755 board/sunxi/mksunxi_fit_atf.sh - -diff --git a/board/sunxi/mksunxi_fit_atf.sh b/board/sunxi/mksunxi_fit_atf.sh -new file mode 100755 -index 0000000..afa22e8 ---- /dev/null -+++ b/board/sunxi/mksunxi_fit_atf.sh -@@ -0,0 +1,73 @@ -+#!/bin/sh -+# -+# script to generate FIT image source for 64-bit sunxi boards with -+# ARM Trusted Firmware and multiple device trees (given on the command line) -+# -+# usage: $0 [ [; -+ -+ images { -+ uboot@1 { -+ description = "U-Boot (64-bit)"; -+ data = /incbin/("u-boot-nodtb.bin"); -+ type = "standalone"; -+ arch = "arm64"; -+ compression = "none"; -+ load = <0x4a000000>; -+ }; -+ atf@1 { -+ description = "ARM Trusted Firmware"; -+ data = /incbin/("bl31.bin"); -+ type = "firmware"; -+ arch = "arm64"; -+ compression = "none"; -+ load = <0x44000>; -+ entry = <0x44000>; -+ }; -+__HEADER_EOF -+ -+cnt=1 -+for dtname in $* -+do -+ cat << __FDT_IMAGE_EOF -+ fdt@$cnt { -+ description = "$(basename $dtname .dtb)"; -+ data = /incbin/("$dtname"); -+ type = "flat_dt"; -+ compression = "none"; -+ }; -+__FDT_IMAGE_EOF -+ cnt=$((cnt+1)) -+done -+ -+cat << __CONF_HEADER_EOF -+ }; -+ configurations { -+ default = "config@1"; -+ -+__CONF_HEADER_EOF -+ -+cnt=1 -+for dtname in $* -+do -+ cat << __CONF_SECTION_EOF -+ config@$cnt { -+ description = "$(basename $dtname .dtb)"; -+ firmware = "uboot@1"; -+ loadables = "atf@1"; -+ fdt = "fdt@$cnt"; -+ }; -+__CONF_SECTION_EOF -+ cnt=$((cnt+1)) -+done -+ -+cat << __ITS_EOF -+ }; -+}; -+__ITS_EOF -From patchwork Fri Mar 31 22:31:28 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,16/19] sunxi: enable automatic FIT build for 64-bit SoCs -From: Andre Przywara -X-Patchwork-Id: 745840 -X-Patchwork-Delegate: jagannadh.teki@gmail.com -Message-Id: <1490999491-14899-17-git-send-email-andre.przywara@arm.com> -To: Maxime Ripard , - Jagan Teki , Simon Glass , - Tom Rini -Cc: Philipp Tomsich , - Michal Simek , u-boot@lists.denx.de, - Icenowy Zheng -Date: Fri, 31 Mar 2017 23:31:28 +0100 - -The Allwinner SoCs with 64-bit cores use an ARM Trusted Firmware binary, -which needs to be loaded alongside U-Boot proper. -Set the respective Kconfig options to let them select this feature and -also automatically build the FIT image. - -Signed-off-by: Andre Przywara -Acked-by: Maxime Ripard ---- - Kconfig | 1 + - board/sunxi/Kconfig | 4 ++++ - include/configs/sunxi-common.h | 4 ++++ - 3 files changed, 9 insertions(+) - -diff --git a/Kconfig b/Kconfig -index 5c82788..ffea4c3 100644 ---- a/Kconfig -+++ b/Kconfig -@@ -252,6 +252,7 @@ config SPL_FIT_SOURCE - config SPL_FIT_GENERATOR - string ".its file generator script for U-Boot FIT image" - depends on SPL_FIT -+ default "board/sunxi/mksunxi_fit_atf.sh" if SPL_LOAD_FIT && ARCH_SUNXI - help - Specifies a (platform specific) script file to generate the FIT - source file used to build the U-Boot FIT image file. This gets -diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig -index 3e0e262..b629f3b 100644 ---- a/board/sunxi/Kconfig -+++ b/board/sunxi/Kconfig -@@ -145,12 +145,16 @@ config MACH_SUN50I - select SUNXI_GEN_SUN6I - select SUNXI_HIGH_SRAM - select SUPPORT_SPL -+ select FIT -+ select SPL_LOAD_FIT - - config MACH_SUN50I_H5 - bool "sun50i (Allwinner H5)" - select ARM64 - select MACH_SUNXI_H3_H5 - select SUNXI_HIGH_SRAM -+ select FIT -+ select SPL_LOAD_FIT - - endchoice - -diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h -index b7eb95e..1982063 100644 ---- a/include/configs/sunxi-common.h -+++ b/include/configs/sunxi-common.h -@@ -32,6 +32,10 @@ - # define CONFIG_MACH_TYPE_COMPAT_REV 1 - #endif - -+#ifdef CONFIG_ARM64 -+#define CONFIG_BUILD_TARGET "u-boot.itb" -+#endif -+ - /* Serial & console */ - #define CONFIG_SYS_NS16550_SERIAL - /* ns16550 reg in the low bits of cpu reg */ - diff --git a/fdt-fixes.patch b/fdt-fixes.patch deleted file mode 100644 index 8db6d27..0000000 --- a/fdt-fixes.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 6a09f5e80038570b15f81fdb1e5bde897e01868a Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Fri, 23 Jun 2017 15:36:33 -0400 -Subject: [PATCH] dm: core: also parse chosen node - -This is the node that would contain, for example, the framebuffer setup -by an earlier stage. - -Signed-off-by: Rob Clark ---- - arch/sandbox/dts/test.dts | 7 +++++++ - drivers/core/root.c | 12 ++++++++++++ - test/dm/bus.c | 2 +- - test/dm/test-fdt.c | 2 +- - 4 files changed, 21 insertions(+), 2 deletions(-) - -diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts -index e67d428eb2..3f9e788e6c 100644 ---- a/arch/sandbox/dts/test.dts -+++ b/arch/sandbox/dts/test.dts -@@ -478,6 +478,13 @@ - wdt0: wdt@0 { - compatible = "sandbox,wdt"; - }; -+ -+ chosen { -+ chosen-test { -+ compatible = "denx,u-boot-fdt-test"; -+ reg = <9 1>; -+ }; -+ }; - }; - - #include "sandbox_pmic.dtsi" -diff --git a/drivers/core/root.c b/drivers/core/root.c -index 976e2c4fdd..5a1c5994f6 100644 ---- a/drivers/core/root.c -+++ b/drivers/core/root.c -@@ -266,6 +266,18 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob, - for (offset = fdt_first_subnode(blob, offset); - offset > 0; - offset = fdt_next_subnode(blob, offset)) { -+ -+ /* "chosen" node isn't a device itself but may contain some: */ -+ if (!strcmp(fdt_get_name(blob, offset, NULL), "chosen")) { -+ pr_debug("parsing subnodes of \"chosen\"\n"); -+ -+ err = dm_scan_fdt_node(parent, blob, offset, -+ pre_reloc_only); -+ if (err && !ret) -+ ret = err; -+ continue; -+ } -+ - if (pre_reloc_only && - !dm_fdt_pre_reloc(blob, offset)) - continue; -diff --git a/test/dm/bus.c b/test/dm/bus.c -index 7006d4163d..1da398ae3a 100644 ---- a/test/dm/bus.c -+++ b/test/dm/bus.c -@@ -105,7 +105,7 @@ UCLASS_DRIVER(testbus) = { - /* Test that we can probe for children */ - static int dm_test_bus_children(struct unit_test_state *uts) - { -- int num_devices = 6; -+ int num_devices = 7; - struct udevice *bus; - struct uclass *uc; - -diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c -index dcc2ef8b65..920ccbf016 100644 ---- a/test/dm/test-fdt.c -+++ b/test/dm/test-fdt.c -@@ -167,7 +167,7 @@ int dm_check_devices(struct unit_test_state *uts, int num_devices) - /* Test that FDT-based binding works correctly */ - static int dm_test_fdt(struct unit_test_state *uts) - { -- const int num_devices = 6; -+ const int num_devices = 7; - struct udevice *dev; - struct uclass *uc; - int ret; - -From 310feda7f7f40afbb26a158183e16c2c46eea28a Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Thu, 3 Aug 2017 09:52:14 -0400 -Subject: [PATCH] fdtdec: allow board to provide fdt for CONFIG_OF_SEPARATE - -Similar to CONFIG_OF_BOARD, but in this case the fdt is still built by -u-boot build. This allows the board to patch the fdt, etc. - -In the specific case of dragonboard 410c, we pass the u-boot generated -fdt to the previous stage of bootloader (by embedding it in the -u-boot.img that is loaded by lk/aboot), which patches the fdt and passes -it back to u-boot. - -Signed-off-by: Rob Clark ---- - include/fdtdec.h | 3 ++- - lib/fdtdec.c | 35 +++++++++++++++++++++++------------ - 2 files changed, 25 insertions(+), 13 deletions(-) - -diff --git a/include/fdtdec.h b/include/fdtdec.h -index 1ba02be8e1..c5acb8dae1 100644 ---- a/include/fdtdec.h -+++ b/include/fdtdec.h -@@ -988,7 +988,8 @@ int fdtdec_setup(void); - - /** - * Board-specific FDT initialization. Returns the address to a device tree blob. -- * Called when CONFIG_OF_BOARD is defined. -+ * Called when CONFIG_OF_BOARD is defined, or if CONFIG_OF_SEPARATE is defined -+ * and the board implements it. - */ - void *board_fdt_blob_setup(void); - -diff --git a/lib/fdtdec.c b/lib/fdtdec.c -index 45f3fe7baf..15bd9b2572 100644 ---- a/lib/fdtdec.c -+++ b/lib/fdtdec.c -@@ -1258,6 +1258,28 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) - # endif - #endif - -+#ifdef CONFIG_OF_SEPARATE -+/* -+ * For CONFIG_OF_SEPARATE, the board may optionally implement this to -+ * provide and/or fixup the fdt. -+ */ -+__weak void *board_fdt_blob_setup(void) -+{ -+ void *fdt_blob = NULL; -+#ifdef CONFIG_SPL_BUILD -+ /* FDT is at end of BSS unless it is in a different memory region */ -+ if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) -+ fdt_blob = (ulong *)&_image_binary_end; -+ else -+ fdt_blob = (ulong *)&__bss_end; -+#else -+ /* FDT is at end of image */ -+ fdt_blob = (ulong *)&_end; -+#endif -+ return fdt_blob; -+} -+#endif -+ - int fdtdec_setup(void) - { - #if CONFIG_IS_ENABLED(OF_CONTROL) -@@ -1267,18 +1289,7 @@ int fdtdec_setup(void) - # ifdef CONFIG_OF_EMBED - /* Get a pointer to the FDT */ - gd->fdt_blob = __dtb_dt_begin; --# elif defined CONFIG_OF_SEPARATE --# ifdef CONFIG_SPL_BUILD -- /* FDT is at end of BSS unless it is in a different memory region */ -- if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) -- gd->fdt_blob = (ulong *)&_image_binary_end; -- else -- gd->fdt_blob = (ulong *)&__bss_end; --# else -- /* FDT is at end of image */ -- gd->fdt_blob = (ulong *)&_end; --# endif --# elif defined(CONFIG_OF_BOARD) -+# elif defined(CONFIG_OF_SEPARATE) || defined(CONFIG_OF_BOARD) - /* Allow the board to override the fdt address. */ - gd->fdt_blob = board_fdt_blob_setup(); - # elif defined(CONFIG_OF_HOSTFILE) - From 24e3b803388f4c1f40f95f952b047efb1cb125fe Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 27 Jan 2019 12:36:59 +0000 Subject: [PATCH 2/3] Raspberry Pi 3A+ --- rpi-add-3Aplus.patch | 32 ++++++++++++++++++++++++++++++++ uboot-tools.spec | 8 ++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 rpi-add-3Aplus.patch diff --git a/rpi-add-3Aplus.patch b/rpi-add-3Aplus.patch new file mode 100644 index 0000000..8f2ae2e --- /dev/null +++ b/rpi-add-3Aplus.patch @@ -0,0 +1,32 @@ +From d61cf138bce890b0b79745e48a908062bc36b99f Mon Sep 17 00:00:00 2001 +From: Jonathan Gray +Date: Fri, 16 Nov 2018 23:07:39 +1100 +Subject: [PATCH] rpi: add 3 Model A+ + +Add Raspberry Pi 3 Model A+ to list of models, the revision code is 0xE +according to the list on raspberrypi.org. + +Signed-off-by: Jonathan Gray +Signed-off-by: Alexander Graf +--- + board/raspberrypi/rpi/rpi.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c +index 5062486..153a1fd 100644 +--- a/board/raspberrypi/rpi/rpi.c ++++ b/board/raspberrypi/rpi/rpi.c +@@ -138,6 +138,11 @@ static const struct rpi_model rpi_models_new_scheme[] = { + DTB_DIR "bcm2837-rpi-3-b-plus.dtb", + true, + }, ++ [0xE] = { ++ "3 Model A+", ++ DTB_DIR "bcm2837-rpi-3-a-plus.dtb", ++ false, ++ }, + }; + + static const struct rpi_model rpi_models_old_scheme[] = { +-- +2.7.4 diff --git a/uboot-tools.spec b/uboot-tools.spec index 2ec81a8..770331a 100644 --- a/uboot-tools.spec +++ b/uboot-tools.spec @@ -2,7 +2,7 @@ Name: uboot-tools Version: 2018.09 -Release: 1%{?candidate:.%{candidate}}%{?dist} +Release: 2%{?candidate:.%{candidate}}%{?dist} Summary: U-Boot utilities License: GPLv2+ BSD LGPL-2.1+ LGPL-2.0+ URL: http://www.denx.de/wiki/U-Boot @@ -32,9 +32,10 @@ Patch16: tegra-efi_loader-simplify-ifdefs.patch Patch17: tegra-TXx-Add-CONFIG_EFI_LOADER_BOUNCE_BUFFER.patch Patch18: tegra-fix-tx1.patch Patch19: sunxi-DT-A64-add-Pine64-LTS-support.patch +Patch20: rpi-add-3Aplus.patch # Upstream UEFI fixes -Patch20: uefi-fixes.patch +Patch21: uefi-fixes.patch BuildRequires: bc BuildRequires: dtc @@ -321,6 +322,9 @@ cp -p board/warp7/README builds/docs/README.warp7 %endif %changelog +* Sun Jan 27 2019 Peter Robinson 2018.09-2 +- Add support for Raspberry Pi 3A+ + * Sun Sep 30 2018 Pablo Greco - Added conditional to enable devtoolset-7-gcc for .el7 build (Arrfab) - Added conditional BR, python2-pyelftools is python-pyelftools in .el7 (Arrfab) From 7ea80dbc67d8a4788399befcb785a04f5003e05b Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 17 Mar 2019 13:49:12 +0000 Subject: [PATCH 3/3] Drop problematic UEFI patch --- uboot-tools.spec | 8 +- uefi-fixes.patch | 1017 ---------------------------------------------- 2 files changed, 4 insertions(+), 1021 deletions(-) delete mode 100644 uefi-fixes.patch diff --git a/uboot-tools.spec b/uboot-tools.spec index 770331a..6b26397 100644 --- a/uboot-tools.spec +++ b/uboot-tools.spec @@ -2,7 +2,7 @@ Name: uboot-tools Version: 2018.09 -Release: 2%{?candidate:.%{candidate}}%{?dist} +Release: 3%{?candidate:.%{candidate}}%{?dist} Summary: U-Boot utilities License: GPLv2+ BSD LGPL-2.1+ LGPL-2.0+ URL: http://www.denx.de/wiki/U-Boot @@ -34,9 +34,6 @@ Patch18: tegra-fix-tx1.patch Patch19: sunxi-DT-A64-add-Pine64-LTS-support.patch Patch20: rpi-add-3Aplus.patch -# Upstream UEFI fixes -Patch21: uefi-fixes.patch - BuildRequires: bc BuildRequires: dtc BuildRequires: make @@ -322,6 +319,9 @@ cp -p board/warp7/README builds/docs/README.warp7 %endif %changelog +* Sun Mar 17 2019 Peter Robinson 2018.09-3 +- Drop problematic UEFI patch + * Sun Jan 27 2019 Peter Robinson 2018.09-2 - Add support for Raspberry Pi 3A+ diff --git a/uefi-fixes.patch b/uefi-fixes.patch deleted file mode 100644 index 8b53dc6..0000000 --- a/uefi-fixes.patch +++ /dev/null @@ -1,1017 +0,0 @@ -From 6aef5da1b5b6a649e64b00e3209a580359db9179 Mon Sep 17 00:00:00 2001 -From: Alexander Graf -Date: Mon, 17 Sep 2018 13:54:33 +0200 -Subject: [PATCH 1/5] efi_loader: Align runtime section to 64kb - -The UEFI spec mandates that runtime sections are 64kb aligned to enable -support for 64kb page size OSs. - -This patch ensures that we extend the runtime section to 64kb to be spec -compliant. - -Signed-off-by: Alexander Graf ---- - lib/efi_loader/efi_memory.c | 20 +++++++++++++++++--- - 1 file changed, 17 insertions(+), 3 deletions(-) - -diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c -index e2b40aa85b5..50c3515f5e6 100644 ---- a/lib/efi_loader/efi_memory.c -+++ b/lib/efi_loader/efi_memory.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - - DECLARE_GLOBAL_DATA_PTR; - -@@ -519,6 +520,7 @@ __weak void efi_add_known_memory(void) - static void add_u_boot_and_runtime(void) - { - unsigned long runtime_start, runtime_end, runtime_pages; -+ unsigned long runtime_mask = EFI_PAGE_MASK; - unsigned long uboot_start, uboot_pages; - unsigned long uboot_stack_size = 16 * 1024 * 1024; - -@@ -527,10 +529,22 @@ static void add_u_boot_and_runtime(void) - uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT; - efi_add_memory_map(uboot_start, uboot_pages, EFI_LOADER_DATA, false); - -- /* Add Runtime Services */ -- runtime_start = (ulong)&__efi_runtime_start & ~EFI_PAGE_MASK; -+#if defined(__aarch64__) -+ /* -+ * Runtime Services must be 64KiB aligned according to the -+ * "AArch64 Platforms" section in the UEFI spec (2.7+). -+ */ -+ -+ runtime_mask = SZ_64K - 1; -+#endif -+ -+ /* -+ * Add Runtime Services. We mark surrounding boottime code as runtime as -+ * well to fulfill the runtime alignment constraints but avoid padding. -+ */ -+ runtime_start = (ulong)&__efi_runtime_start & ~runtime_mask; - runtime_end = (ulong)&__efi_runtime_stop; -- runtime_end = (runtime_end + EFI_PAGE_MASK) & ~EFI_PAGE_MASK; -+ runtime_end = (runtime_end + runtime_mask) & ~runtime_mask; - runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT; - efi_add_memory_map(runtime_start, runtime_pages, - EFI_RUNTIME_SERVICES_CODE, false); --- -2.19.0 - -From af3ef8121fbfff175e963e03b3eedf13df5ce548 Mon Sep 17 00:00:00 2001 -From: Alexander Graf -Date: Mon, 17 Sep 2018 04:35:10 +0200 -Subject: [PATCH 2/5] efi_loader: Merge memory map entries - -We currently do not combine memory entries that are adjacent and have -the same attributes. The problem with that is that our memory map can -easily grow multiple hundreds of entries in a simple UEFI Shell -environment. - -So let's make sure we always combine all entries to make the memory -map as small as possible. That way every other piece of code that -loops through it should also gain some nice speed ups. - -Signed-off-by: Alexander Graf ---- - lib/efi_loader/efi_memory.c | 45 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 45 insertions(+) - -diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c -index 50c3515f5e6..3fe014d9e72 100644 ---- a/lib/efi_loader/efi_memory.c -+++ b/lib/efi_loader/efi_memory.c -@@ -67,9 +67,54 @@ static int efi_mem_cmp(void *priv, struct list_head *a, struct list_head *b) - return -1; - } - -+static uint64_t desc_get_end(struct efi_mem_desc *desc) -+{ -+ return desc->physical_start + (desc->num_pages << EFI_PAGE_SHIFT); -+} -+ - static void efi_mem_sort(void) - { -+ struct list_head *lhandle; -+ struct efi_mem_list *prevmem = NULL; -+ bool merge_again = true; -+ - list_sort(NULL, &efi_mem, efi_mem_cmp); -+ -+ /* Now merge entries that can be merged */ -+ while (merge_again) { -+ merge_again = false; -+ list_for_each(lhandle, &efi_mem) { -+ struct efi_mem_list *lmem; -+ struct efi_mem_desc *prev = &prevmem->desc; -+ struct efi_mem_desc *cur; -+ uint64_t pages; -+ -+ lmem = list_entry(lhandle, struct efi_mem_list, link); -+ if (!prevmem) { -+ prevmem = lmem; -+ continue; -+ } -+ -+ cur = &lmem->desc; -+ -+ if ((desc_get_end(cur) == prev->physical_start) && -+ (prev->type == cur->type) && -+ (prev->attribute == cur->attribute)) { -+ /* There is an existing map before, reuse it */ -+ pages = cur->num_pages; -+ prev->num_pages += pages; -+ prev->physical_start -= pages << EFI_PAGE_SHIFT; -+ prev->virtual_start -= pages << EFI_PAGE_SHIFT; -+ list_del(&lmem->link); -+ free(lmem); -+ -+ merge_again = true; -+ break; -+ } -+ -+ prevmem = lmem; -+ } -+ } - } - - /** efi_mem_carve_out - unmap memory region --- -2.19.0 - -From 2b72b771cc760ca85f47a561c4055817e8bc8f25 Mon Sep 17 00:00:00 2001 -From: Alexander Graf -Date: Sun, 23 Sep 2018 16:26:58 +0200 -Subject: [PATCH 3/5] efi_loader: Fix loaded_image handle passing from EL3 - -When running in EL3 mode on AArch64, we have to first drop to EL2 -to execute a UEFI payload. When dropping down, the arguments to -the entry point have to stay identical to the ones for normal entry -though. - -In commit ea54ad59286 ("efi_loader: pass handle of loaded image") -we incorrectly changed that logic and had the el3 entry path diverge. -Fix it up by syncing it back to what it's supposed to be. - -Fixes: ea54ad59286 ("efi_loader: pass handle of loaded image") -Signed-off-by: Alexander Graf ---- - cmd/bootefi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/cmd/bootefi.c b/cmd/bootefi.c -index b60c151fb4a..f2939da3e1a 100644 ---- a/cmd/bootefi.c -+++ b/cmd/bootefi.c -@@ -373,7 +373,7 @@ static efi_status_t do_bootefi_exec(void *efi, - - /* Move into EL2 and keep running there */ - armv8_switch_to_el2((ulong)entry, -- (ulong)&loaded_image_info_obj.handle, -+ (ulong)loaded_image_info_obj.handle, - (ulong)&systab, 0, (ulong)efi_run_in_el2, - ES_TO_AARCH64); - --- -2.19.0 - -From fdbf589100f6b1f9e4e12a53a0d370d88de5f7e3 Mon Sep 17 00:00:00 2001 -From: Stephen Warren -Date: Tue, 31 Jul 2018 13:44:12 -0600 -Subject: [PATCH 4/5] efi_loader: don't allocate unusable RAM - -Some boards define a maximum usable RAM top that's more restrictive than -the ranges defined by U-Boot's memory bank definitions[1]. In this case, -the unusable RAM isn't mapped in the page tables, and so the EFI code must -not attempt to allocate RAM from outside the usable regions. Fix -efi_find_free_memory() to detect when max_addr is unconstrained or out of -range, and substitue a valid value. - -[1] For example, when some peripherals can't access RAM above 4GiB, it's -simplest to force U-Boot's ram_top to a smaller value to avoid dealing -with this issue more explicitly. However, the RAM bank definitions still -describe the unusable RAM so that the booted OS has access to it, since -the OS can typically deal with such restrictions in a more complex -manner. - -Fixes: aa909462d018 "efi_loader: efi_allocate_pages is too restrictive" -Cc: Heinrich Schuchardt -Cc: Alexander Graf -Signed-off-by: Stephen Warren ---- - lib/efi_loader/efi_memory.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c -index 3fe014d9e72..bf9d6963cbe 100644 ---- a/lib/efi_loader/efi_memory.c -+++ b/lib/efi_loader/efi_memory.c -@@ -296,6 +296,9 @@ static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr) - { - struct list_head *lhandle; - -+ if ((max_addr == -1ULL) || (max_addr > gd->ram_top)) -+ max_addr = gd->ram_top; -+ - list_for_each(lhandle, &efi_mem) { - struct efi_mem_list *lmem = list_entry(lhandle, - struct efi_mem_list, link); --- -2.19.0 - -From df3831a3833c2f477ef779a207cf973dd74ef0ee Mon Sep 17 00:00:00 2001 -From: Peter Robinson -Date: Fri, 28 Sep 2018 15:56:25 +0100 -Subject: [PATCH 5/5] efi_loader: remove efi_exit_caches() - -Since GRUB patch d0c070179d4d ("arm/efi: Switch to arm64 linux loader", -2018-07-09) we do not need a workaround for GRUB on 32bit ARM anymore. - -So let's eliminate function efi_exit_caches(). - -This will require Linux distributions to update grub-efi-arm to the GRUB -git HEAD (a tag containing the aforementioned GRUB patch is not available -yet). - -Signed-off-by: Heinrich Schuchardt -Signed-off-by: Peter Robinson ---- - lib/efi_loader/efi_boottime.c | 28 ---------------------------- - 1 file changed, 28 deletions(-) - -diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c -index 3935e4f1ce9..56557205d00 100644 ---- a/lib/efi_loader/efi_boottime.c -+++ b/lib/efi_loader/efi_boottime.c -@@ -27,14 +27,6 @@ LIST_HEAD(efi_obj_list); - /* List of all events */ - LIST_HEAD(efi_events); - --/* -- * If we're running on nasty systems (32bit ARM booting into non-EFI Linux) -- * we need to do trickery with caches. Since we don't want to break the EFI -- * aware boot path, only apply hacks when loading exiting directly (breaking -- * direct Linux EFI booting along the way - oh well). -- */ --static bool efi_is_direct_boot = true; -- - #ifdef CONFIG_ARM - /* - * The "gd" pointer lives in a register on ARM and AArch64 that we declare -@@ -1696,8 +1688,6 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, - EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data); - entry = info->reserved; - -- efi_is_direct_boot = false; -- - /* call the image! */ - if (setjmp(&info->exit_jmp)) { - /* -@@ -1811,21 +1801,6 @@ static efi_status_t EFIAPI efi_unload_image(efi_handle_t image_handle) - return EFI_EXIT(EFI_SUCCESS); - } - --/** -- * efi_exit_caches() - fix up caches for EFI payloads if necessary -- */ --static void efi_exit_caches(void) --{ --#if defined(CONFIG_ARM) && !defined(CONFIG_ARM64) -- /* -- * Grub on 32bit ARM needs to have caches disabled before jumping into -- * a zImage, but does not know of all cache layers. Give it a hand. -- */ -- if (efi_is_direct_boot) -- cleanup_before_linux(); --#endif --} -- - /** - * efi_exit_boot_services() - stop all boot services - * @image_handle: handle of the loaded image -@@ -1879,9 +1854,6 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle, - - board_quiesce_devices(); - -- /* Fix up caches for EFI payloads if necessary */ -- efi_exit_caches(); -- - /* This stops all lingering devices */ - bootm_disable_interrupts(); - --- -2.19.0 -From 05e6d0b69f30c6b902ab9a343f4c4080a837ebd2 Mon Sep 17 00:00:00 2001 -From: Peter Robinson -Date: Thu, 4 Oct 2018 10:37:24 +0100 -Subject: [PATCH] efi_loader: fix simple network protocol - -We should not call eth_rx() before the network interface is initialized. -The services of the simple network protocol should check the state of -the network adapter. - -Provide a correctly aligned transmit buffer not depending on -CONFIG_EFI_LOADER_BOUNCE_BUFFER. - -Correct the unit test. - -Add and correct comments. - -Without this patch i.mx6 system Wandboard Quad rev B1 fails to execute -bootefi selftest. - -Signed-off-by: Heinrich Schuchardt -Signed-off-by: Peter Robinson ---- - lib/efi_loader/efi_net.c | 419 +++++++++++++++++++++++----- - lib/efi_selftest/efi_selftest_snp.c | 16 +- - 2 files changed, 359 insertions(+), 76 deletions(-) - -diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c -index 5a3d7be86cf..871c4c98228 100644 ---- a/lib/efi_loader/efi_net.c -+++ b/lib/efi_loader/efi_net.c -@@ -16,6 +16,8 @@ static const efi_guid_t efi_pxe_guid = EFI_PXE_GUID; - static struct efi_pxe_packet *dhcp_ack; - static bool new_rx_packet; - static void *new_tx_packet; -+static void *transmit_buffer; -+ - /* - * The notification function of this event is called in every timer cycle - * to check if a new network packet has been received. -@@ -37,22 +39,68 @@ struct efi_net_obj { - struct efi_pxe_mode pxe_mode; - }; - -+/* -+ * efi_net_start() - start the network interface -+ * -+ * This function implements the Start service of the -+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface -+ * (UEFI) specification for details. -+ * -+ * @this: pointer to the protocol instance -+ * Return: status code -+ */ - static efi_status_t EFIAPI efi_net_start(struct efi_simple_network *this) - { -+ efi_status_t ret = EFI_SUCCESS; -+ - EFI_ENTRY("%p", this); - -- return EFI_EXIT(EFI_SUCCESS); -+ /* Check parameters */ -+ if (!this) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } -+ -+ if (this->mode->state != EFI_NETWORK_STOPPED) -+ ret = EFI_ALREADY_STARTED; -+ else -+ this->mode->state = EFI_NETWORK_STARTED; -+out: -+ return EFI_EXIT(ret); - } - -+/* -+ * efi_net_stop() - stop the network interface -+ * -+ * This function implements the Stop service of the -+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface -+ * (UEFI) specification for details. -+ * -+ * @this: pointer to the protocol instance -+ * Return: status code -+ */ - static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this) - { -+ efi_status_t ret = EFI_SUCCESS; -+ - EFI_ENTRY("%p", this); - -- return EFI_EXIT(EFI_SUCCESS); -+ /* Check parameters */ -+ if (!this) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } -+ -+ if (this->mode->state == EFI_NETWORK_STOPPED) -+ ret = EFI_NOT_STARTED; -+ else -+ this->mode->state = EFI_NETWORK_STOPPED; -+out: -+ return EFI_EXIT(ret); - } - - /* -- * Initialize network adapter and allocate transmit and receive buffers. -+ * efi_net_initialize() - initialize the network interface - * - * This function implements the Initialize service of the - * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface -@@ -61,7 +109,7 @@ static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this) - * @this: pointer to the protocol instance - * @extra_rx: extra receive buffer to be allocated - * @extra_tx: extra transmit buffer to be allocated -- * @return: status code -+ * Return: status code - */ - static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this, - ulong extra_rx, ulong extra_tx) -@@ -71,9 +119,10 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this, - - EFI_ENTRY("%p, %lx, %lx", this, extra_rx, extra_tx); - -+ /* Check parameters */ - if (!this) { - r = EFI_INVALID_PARAMETER; -- goto error; -+ goto out; - } - - /* Setup packet buffers */ -@@ -86,32 +135,83 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this, - ret = eth_init(); - if (ret < 0) { - eth_halt(); -+ this->mode->state = EFI_NETWORK_STOPPED; - r = EFI_DEVICE_ERROR; -+ goto out; -+ } else { -+ this->mode->state = EFI_NETWORK_INITIALIZED; - } -- --error: -+out: - return EFI_EXIT(r); - } - -+/* -+ * efi_net_reset() - reinitialize the network interface -+ * -+ * This function implements the Reset service of the -+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface -+ * (UEFI) specification for details. -+ * -+ * @this: pointer to the protocol instance -+ * @extended_verification: execute exhaustive verification -+ * Return: status code -+ */ - static efi_status_t EFIAPI efi_net_reset(struct efi_simple_network *this, - int extended_verification) - { - EFI_ENTRY("%p, %x", this, extended_verification); - -- return EFI_EXIT(EFI_SUCCESS); -+ return EFI_EXIT(EFI_CALL(efi_net_initialize(this, 0, 0))); - } - -+/* -+ * efi_net_shutdown() - shut down the network interface -+ * -+ * This function implements the Shutdown service of the -+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface -+ * (UEFI) specification for details. -+ * -+ * @this: pointer to the protocol instance -+ * Return: status code -+ */ - static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this) - { -+ efi_status_t ret = EFI_SUCCESS; -+ - EFI_ENTRY("%p", this); - -- return EFI_EXIT(EFI_SUCCESS); -+ /* Check parameters */ -+ if (!this) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } -+ -+ eth_halt(); -+ this->mode->state = EFI_NETWORK_STOPPED; -+ -+out: -+ return EFI_EXIT(ret); - } - --static efi_status_t EFIAPI efi_net_receive_filters( -- struct efi_simple_network *this, u32 enable, u32 disable, -- int reset_mcast_filter, ulong mcast_filter_count, -- struct efi_mac_address *mcast_filter) -+/* -+ * efi_net_receive_filters() - mange multicast receive filters -+ * -+ * This function implements the ReceiveFilters service of the -+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface -+ * (UEFI) specification for details. -+ * -+ * @this: pointer to the protocol instance -+ * @enable: bit mask of receive filters to enable -+ * @disable: bit mask of receive filters to disable -+ * @reset_mcast_filter: true resets contents of the filters -+ * @mcast_filter_count: number of hardware MAC addresses in the new filters list -+ * @mcast_filter: list of new filters -+ * Return: status code -+ */ -+static efi_status_t EFIAPI efi_net_receive_filters -+ (struct efi_simple_network *this, u32 enable, u32 disable, -+ int reset_mcast_filter, ulong mcast_filter_count, -+ struct efi_mac_address *mcast_filter) - { - EFI_ENTRY("%p, %x, %x, %x, %lx, %p", this, enable, disable, - reset_mcast_filter, mcast_filter_count, mcast_filter); -@@ -119,15 +219,40 @@ static efi_status_t EFIAPI efi_net_receive_filters( - return EFI_EXIT(EFI_UNSUPPORTED); - } - --static efi_status_t EFIAPI efi_net_station_address( -- struct efi_simple_network *this, int reset, -- struct efi_mac_address *new_mac) -+/* -+ * efi_net_station_address() - set the hardware MAC address -+ * -+ * This function implements the StationAddress service of the -+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface -+ * (UEFI) specification for details. -+ * -+ * @this: pointer to the protocol instance -+ * @reset: if true reset the address to default -+ * @new_mac: new MAC address -+ * Return: status code -+ */ -+static efi_status_t EFIAPI efi_net_station_address -+ (struct efi_simple_network *this, int reset, -+ struct efi_mac_address *new_mac) - { - EFI_ENTRY("%p, %x, %p", this, reset, new_mac); - - return EFI_EXIT(EFI_UNSUPPORTED); - } - -+/* -+ * efi_net_statistics() - reset or collect statistics of the network interface -+ * -+ * This function implements the Statistics service of the -+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface -+ * (UEFI) specification for details. -+ * -+ * @this: pointer to the protocol instance -+ * @reset: if true, the statistics are reset -+ * @stat_size: size of the statistics table -+ * @stat_table: table to receive the statistics -+ * Return: status code -+ */ - static efi_status_t EFIAPI efi_net_statistics(struct efi_simple_network *this, - int reset, ulong *stat_size, - void *stat_table) -@@ -137,6 +262,19 @@ static efi_status_t EFIAPI efi_net_statistics(struct efi_simple_network *this, - return EFI_EXIT(EFI_UNSUPPORTED); - } - -+/* -+ * efi_net_mcastiptomac() - translate multicast IP address to MAC address -+ * -+ * This function implements the Statistics service of the -+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface -+ * (UEFI) specification for details. -+ * -+ * @this: pointer to the protocol instance -+ * @ipv6: true if the IP address is an IPv6 address -+ * @ip: IP address -+ * @mac: MAC address -+ * Return: status code -+ */ - static efi_status_t EFIAPI efi_net_mcastiptomac(struct efi_simple_network *this, - int ipv6, - struct efi_ip_address *ip, -@@ -147,6 +285,19 @@ static efi_status_t EFIAPI efi_net_mcastiptomac(struct efi_simple_network *this, - return EFI_EXIT(EFI_INVALID_PARAMETER); - } - -+/** -+ * efi_net_nvdata() - read or write NVRAM -+ * -+ * This function implements the GetStatus service of the Simple Network -+ * Protocol. See the UEFI spec for details. -+ * -+ * @this: the instance of the Simple Network Protocol -+ * @readwrite: true for read, false for write -+ * @offset: offset in NVRAM -+ * @buffer_size: size of buffer -+ * @buffer: buffer -+ * Return: status code -+ */ - static efi_status_t EFIAPI efi_net_nvdata(struct efi_simple_network *this, - int read_write, ulong offset, - ulong buffer_size, char *buffer) -@@ -157,13 +308,42 @@ static efi_status_t EFIAPI efi_net_nvdata(struct efi_simple_network *this, - return EFI_EXIT(EFI_UNSUPPORTED); - } - -+/** -+ * efi_net_get_status() - get interrupt status -+ * -+ * This function implements the GetStatus service of the Simple Network -+ * Protocol. See the UEFI spec for details. -+ * -+ * @this: the instance of the Simple Network Protocol -+ * @int_status: interface status -+ * @txbuf: transmission buffer -+ */ - static efi_status_t EFIAPI efi_net_get_status(struct efi_simple_network *this, - u32 *int_status, void **txbuf) - { -+ efi_status_t ret = EFI_SUCCESS; -+ - EFI_ENTRY("%p, %p, %p", this, int_status, txbuf); - - efi_timer_check(); - -+ /* Check parameters */ -+ if (!this) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } -+ -+ switch (this->mode->state) { -+ case EFI_NETWORK_STOPPED: -+ ret = EFI_NOT_STARTED; -+ goto out; -+ case EFI_NETWORK_STARTED: -+ ret = EFI_DEVICE_ERROR; -+ goto out; -+ default: -+ break; -+ } -+ - if (int_status) { - /* We send packets synchronously, so nothing is outstanding */ - *int_status = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT; -@@ -174,65 +354,103 @@ static efi_status_t EFIAPI efi_net_get_status(struct efi_simple_network *this, - *txbuf = new_tx_packet; - - new_tx_packet = NULL; -- -- return EFI_EXIT(EFI_SUCCESS); -+out: -+ return EFI_EXIT(ret); - } - --static efi_status_t EFIAPI efi_net_transmit(struct efi_simple_network *this, -- size_t header_size, size_t buffer_size, void *buffer, -- struct efi_mac_address *src_addr, -- struct efi_mac_address *dest_addr, u16 *protocol) -+/** -+ * efi_net_transmit() - transmit a packet -+ * -+ * This function implements the Transmit service of the Simple Network Protocol. -+ * See the UEFI spec for details. -+ * -+ * @this: the instance of the Simple Network Protocol -+ * @header_size: size of the media header -+ * @buffer_size: size of the buffer to receive the packet -+ * @buffer: buffer to receive the packet -+ * @src_addr: source hardware MAC address -+ * @dest_addr: destination hardware MAC address -+ * @protocol: type of header to build -+ * Return: status code -+ */ -+static efi_status_t EFIAPI efi_net_transmit -+ (struct efi_simple_network *this, size_t header_size, -+ size_t buffer_size, void *buffer, -+ struct efi_mac_address *src_addr, -+ struct efi_mac_address *dest_addr, u16 *protocol) - { -+ efi_status_t ret = EFI_SUCCESS; -+ - EFI_ENTRY("%p, %lu, %lu, %p, %p, %p, %p", this, - (unsigned long)header_size, (unsigned long)buffer_size, - buffer, src_addr, dest_addr, protocol); - - efi_timer_check(); - -+ /* Check parameters */ -+ if (!this) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } -+ -+ /* We do not support jumbo packets */ -+ if (buffer_size > PKTSIZE_ALIGN) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } -+ - if (header_size) { -- /* We would need to create the header if header_size != 0 */ -- return EFI_EXIT(EFI_INVALID_PARAMETER); -+ /* -+ * TODO: We would need to create the header -+ * if header_size != 0 -+ */ -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } -+ -+ switch (this->mode->state) { -+ case EFI_NETWORK_STOPPED: -+ ret = EFI_NOT_STARTED; -+ goto out; -+ case EFI_NETWORK_STARTED: -+ ret = EFI_DEVICE_ERROR; -+ goto out; -+ default: -+ break; - } - --#ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER - /* Ethernet packets always fit, just bounce */ -- memcpy(efi_bounce_buffer, buffer, buffer_size); -- net_send_packet(efi_bounce_buffer, buffer_size); --#else -- net_send_packet(buffer, buffer_size); --#endif -+ memcpy(transmit_buffer, buffer, buffer_size); -+ net_send_packet(transmit_buffer, buffer_size); - - new_tx_packet = buffer; - -- return EFI_EXIT(EFI_SUCCESS); -+out: -+ return EFI_EXIT(ret); - } - --static void efi_net_push(void *pkt, int len) --{ -- new_rx_packet = true; -- wait_for_packet->is_signaled = true; --} -- --/* -- * Receive a packet from a network interface. -+/** -+ * efi_net_receive() - receive a packet from a network interface - * - * This function implements the Receive service of the Simple Network Protocol. - * See the UEFI spec for details. - * -- * @this the instance of the Simple Network Protocol -- * @header_size size of the media header -- * @buffer_size size of the buffer to receive the packet -- * @buffer buffer to receive the packet -- * @src_addr source MAC address -- * @dest_addr destination MAC address -- * @protocol protocol -- * @return status code -+ * @this: the instance of the Simple Network Protocol -+ * @header_size: size of the media header -+ * @buffer_size: size of the buffer to receive the packet -+ * @buffer: buffer to receive the packet -+ * @src_addr: source MAC address -+ * @dest_addr: destination MAC address -+ * @protocol: protocol -+ * Return: status code - */ --static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this, -- size_t *header_size, size_t *buffer_size, void *buffer, -- struct efi_mac_address *src_addr, -- struct efi_mac_address *dest_addr, u16 *protocol) -+static efi_status_t EFIAPI efi_net_receive -+ (struct efi_simple_network *this, size_t *header_size, -+ size_t *buffer_size, void *buffer, -+ struct efi_mac_address *src_addr, -+ struct efi_mac_address *dest_addr, u16 *protocol) - { -+ efi_status_t ret = EFI_SUCCESS; - struct ethernet_hdr *eth_hdr; - size_t hdr_size = sizeof(struct ethernet_hdr); - u16 protlen; -@@ -240,14 +458,35 @@ static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this, - EFI_ENTRY("%p, %p, %p, %p, %p, %p, %p", this, header_size, - buffer_size, buffer, src_addr, dest_addr, protocol); - -+ /* Execute events */ - efi_timer_check(); - -- if (!new_rx_packet) -- return EFI_EXIT(EFI_NOT_READY); -+ /* Check parameters */ -+ if (!this) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } -+ -+ switch (this->mode->state) { -+ case EFI_NETWORK_STOPPED: -+ ret = EFI_NOT_STARTED; -+ goto out; -+ case EFI_NETWORK_STARTED: -+ ret = EFI_DEVICE_ERROR; -+ goto out; -+ default: -+ break; -+ } -+ -+ if (!new_rx_packet) { -+ ret = EFI_NOT_READY; -+ goto out; -+ } - /* Check that we at least received an Ethernet header */ - if (net_rx_packet_len < sizeof(struct ethernet_hdr)) { - new_rx_packet = false; -- return EFI_EXIT(EFI_NOT_READY); -+ ret = EFI_NOT_READY; -+ goto out; - } - /* Fill export parameters */ - eth_hdr = (struct ethernet_hdr *)net_rx_packet; -@@ -265,18 +504,24 @@ static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this, - if (protocol) - *protocol = protlen; - if (*buffer_size < net_rx_packet_len) { -- /* Packet doesn't fit, try again with bigger buf */ -+ /* Packet doesn't fit, try again with bigger buffer */ - *buffer_size = net_rx_packet_len; -- return EFI_EXIT(EFI_BUFFER_TOO_SMALL); -+ ret = EFI_BUFFER_TOO_SMALL; -+ goto out; - } - /* Copy packet */ - memcpy(buffer, net_rx_packet, net_rx_packet_len); - *buffer_size = net_rx_packet_len; - new_rx_packet = false; -- -- return EFI_EXIT(EFI_SUCCESS); -+out: -+ return EFI_EXIT(ret); - } - -+/** -+ * efi_net_set_dhcp_ack() - take note of a selected DHCP IP address -+ * -+ * This function is called by dhcp_handler(). -+ */ - void efi_net_set_dhcp_ack(void *pkt, int len) - { - int maxsize = sizeof(*dhcp_ack); -@@ -287,8 +532,22 @@ void efi_net_set_dhcp_ack(void *pkt, int len) - memcpy(dhcp_ack, pkt, min(len, maxsize)); - } - --/* -- * Check if a new network packet has been received. -+/** -+ * efi_net_push() - callback for received network packet -+ * -+ * This function is called when a network packet is received by eth_rx(). -+ * -+ * @pkt: network packet -+ * @len: length -+ */ -+static void efi_net_push(void *pkt, int len) -+{ -+ new_rx_packet = true; -+ wait_for_packet->is_signaled = true; -+} -+ -+/** -+ * efi_network_timer_notify() - check if a new network packet has been received - * - * This notification function is called in every timer cycle. - * -@@ -298,20 +557,34 @@ void efi_net_set_dhcp_ack(void *pkt, int len) - static void EFIAPI efi_network_timer_notify(struct efi_event *event, - void *context) - { -+ struct efi_simple_network *this = (struct efi_simple_network *)context; -+ - EFI_ENTRY("%p, %p", event, context); - -+ /* -+ * Some network drivers do not support calling eth_rx() before -+ * initialization. -+ */ -+ if (!this || this->mode->state != EFI_NETWORK_INITIALIZED) -+ goto out; -+ - if (!new_rx_packet) { - push_packet = efi_net_push; - eth_rx(); - push_packet = NULL; - } -+out: - EFI_EXIT(EFI_SUCCESS); - } - --/* This gets called from do_bootefi_exec(). */ -+/** -+ * efi_net_register() - register the simple network protocol -+ * -+ * This gets called from do_bootefi_exec(). -+ */ - efi_status_t efi_net_register(void) - { -- struct efi_net_obj *netobj; -+ struct efi_net_obj *netobj = NULL; - efi_status_t r; - - if (!eth_get_dev()) { -@@ -321,10 +594,15 @@ efi_status_t efi_net_register(void) - - /* We only expose the "active" eth device, so one is enough */ - netobj = calloc(1, sizeof(*netobj)); -- if (!netobj) { -- printf("ERROR: Out of memory\n"); -- return EFI_OUT_OF_RESOURCES; -- } -+ if (!netobj) -+ goto out_of_resources; -+ -+ /* Allocate an aligned transmit buffer */ -+ transmit_buffer = calloc(1, PKTSIZE_ALIGN + ARCH_DMA_MINALIGN); -+ if (!transmit_buffer) -+ goto out_of_resources; -+ transmit_buffer = (void *)ALIGN((uintptr_t)transmit_buffer, -+ ARCH_DMA_MINALIGN); - - /* Hook net up to the device list */ - efi_add_handle(&netobj->parent); -@@ -387,13 +665,13 @@ efi_status_t efi_net_register(void) - * iPXE is running at TPL_CALLBACK most of the time. Use a higher TPL. - */ - r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY, -- efi_network_timer_notify, NULL, NULL, -+ efi_network_timer_notify, &netobj->net, NULL, - &network_timer_event); - if (r != EFI_SUCCESS) { - printf("ERROR: Failed to register network event\n"); - return r; - } -- /* Network is time critical, create event in every timer cyle */ -+ /* Network is time critical, create event in every timer cycle */ - r = efi_set_timer(network_timer_event, EFI_TIMER_PERIODIC, 0); - if (r != EFI_SUCCESS) { - printf("ERROR: Failed to set network timer\n"); -@@ -404,4 +682,9 @@ efi_status_t efi_net_register(void) - failure_to_add_protocol: - printf("ERROR: Failure to add protocol\n"); - return r; -+out_of_resources: -+ free(netobj); -+ /* free(transmit_buffer) not needed yet */ -+ printf("ERROR: Out of memory\n"); -+ return EFI_OUT_OF_RESOURCES; - } -diff --git a/lib/efi_selftest/efi_selftest_snp.c b/lib/efi_selftest/efi_selftest_snp.c -index 09bd53da82d..e10a34ba645 100644 ---- a/lib/efi_selftest/efi_selftest_snp.c -+++ b/lib/efi_selftest/efi_selftest_snp.c -@@ -103,7 +103,7 @@ static efi_status_t send_dhcp_discover(void) - struct dhcp p = {}; - - /* -- * Fill ethernet header -+ * Fill Ethernet header - */ - boottime->copy_mem(p.eth_hdr.et_dest, (void *)BROADCAST_MAC, ARP_HLEN); - boottime->copy_mem(p.eth_hdr.et_src, &net->mode->current_address, -@@ -229,19 +229,19 @@ static int setup(const efi_handle_t handle, - return EFI_ST_FAILURE; - } - /* -- * Initialize network adapter. -+ * Start network adapter. - */ -- ret = net->initialize(net, 0, 0); -- if (ret != EFI_SUCCESS) { -- efi_st_error("Failed to initialize network adapter\n"); -+ ret = net->start(net); -+ if (ret != EFI_SUCCESS && ret != EFI_ALREADY_STARTED) { -+ efi_st_error("Failed to start network adapter\n"); - return EFI_ST_FAILURE; - } - /* -- * Start network adapter. -+ * Initialize network adapter. - */ -- ret = net->start(net); -+ ret = net->initialize(net, 0, 0); - if (ret != EFI_SUCCESS) { -- efi_st_error("Failed to start network adapter\n"); -+ efi_st_error("Failed to initialize network adapter\n"); - return EFI_ST_FAILURE; - } - return EFI_ST_SUCCESS; --- -2.19.0 -