Merge tag 'efi-2022-01-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi
Pull request for efi-2022-01-rc1 Documentation: Use Sphinx 3.43. Move system reset documentation to HTML UEFI: Fix linking EFI apps with LLVM Fix alignment of loaded image Correct simple network protocol test Code cleanup
This commit is contained in:
@@ -693,6 +693,13 @@ F: drivers/core/
|
||||
F: include/dm/
|
||||
F: test/dm/
|
||||
|
||||
EFI APP
|
||||
M: Simon Glass <sjg@chromium.org>
|
||||
M: Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
S: Maintained
|
||||
W: https://u-boot.readthedocs.io/en/latest/develop/uefi/u-boot_on_efi.html
|
||||
F: lib/efi/efi_app.c
|
||||
|
||||
EFI PAYLOAD
|
||||
M: Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
R: Alexander Graf <agraf@csgraf.de>
|
||||
|
||||
@@ -37,7 +37,7 @@ KBUILD_LDFLAGS += -m $(if $(IS_32BIT),elf_i386,elf_x86_64)
|
||||
LDFLAGS_EFI_PAYLOAD := -Bsymbolic -Bsymbolic-functions -shared --no-undefined -s
|
||||
|
||||
OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
|
||||
-j .rel -j .rela -j .reloc
|
||||
-j .rel -j .rela -j .reloc --strip-all
|
||||
|
||||
# Compiler flags to be added when building UEFI applications
|
||||
CFLAGS_EFI := -fpic -fshort-wchar
|
||||
@@ -65,7 +65,7 @@ CPPFLAGS_crt0-efi-$(EFIARCH).o += $(CFLAGS_EFI)
|
||||
ifeq ($(CONFIG_EFI_APP),y)
|
||||
|
||||
PLATFORM_CPPFLAGS += $(CFLAGS_EFI)
|
||||
LDFLAGS_FINAL += -znocombreloc -shared -s
|
||||
LDFLAGS_FINAL += -znocombreloc -shared
|
||||
LDSCRIPT := $(LDSCRIPT_EFI)
|
||||
|
||||
else
|
||||
|
||||
@@ -280,15 +280,24 @@ void setup_efi_info(struct efi_info *efi_info)
|
||||
}
|
||||
efi_info->efi_memdesc_size = map->desc_size;
|
||||
efi_info->efi_memdesc_version = map->version;
|
||||
efi_info->efi_memmap = (u32)(map->desc);
|
||||
efi_info->efi_memmap = (ulong)(map->desc);
|
||||
efi_info->efi_memmap_size = size - sizeof(struct efi_entry_memmap);
|
||||
|
||||
#ifdef CONFIG_EFI_STUB_64BIT
|
||||
efi_info->efi_systab_hi = table->sys_table >> 32;
|
||||
efi_info->efi_memmap_hi = (u64)(u32)(map->desc) >> 32;
|
||||
efi_info->efi_memmap_hi = (u64)(ulong)map->desc >> 32;
|
||||
signature = EFI64_LOADER_SIGNATURE;
|
||||
#else
|
||||
signature = EFI32_LOADER_SIGNATURE;
|
||||
#endif
|
||||
memcpy(&efi_info->efi_loader_signature, signature, 4);
|
||||
}
|
||||
|
||||
void efi_show_bdinfo(void)
|
||||
{
|
||||
struct efi_entry_systable *table = NULL;
|
||||
int size, ret;
|
||||
|
||||
ret = efi_info_get(EFIET_SYS_TABLE, (void **)&table, &size);
|
||||
bdinfo_print_num_l("efi_table", (ulong)table);
|
||||
}
|
||||
|
||||
39
arch/x86/include/asm/efi.h
Normal file
39
arch/x86/include/asm/efi.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright Google LLC
|
||||
*/
|
||||
|
||||
#ifndef _ASM_EFI_H_
|
||||
#define _ASM_EFI_H_
|
||||
|
||||
struct efi_info;
|
||||
struct screen_info;
|
||||
|
||||
/**
|
||||
* setup_video() - Set up the screen info in the x86 setup
|
||||
*
|
||||
* This is needed so Linux can use the display (when U-Boot is an EFI payload)
|
||||
*
|
||||
* @efi_info: Pointer to place to put the screen info in the x86 setup base
|
||||
*/
|
||||
void setup_video(struct screen_info *screen_info);
|
||||
|
||||
/**
|
||||
* setup_efi_info() - Set up the EFI info needed by Linux to boot
|
||||
*
|
||||
* This writes a suitable signature, table pointers, memory-map pointer, etc.
|
||||
* These are needed for Linux to boot from U-Boot (when U-Boot is an EFI
|
||||
* payload).
|
||||
*
|
||||
* @efi_info: Pointer to place to put the EFI info in the x86 setup base
|
||||
*/
|
||||
void setup_efi_info(struct efi_info *efi_info);
|
||||
|
||||
/**
|
||||
* efi_show_bdinfo() - Show information about EFI for the 'bdinfo' command
|
||||
*
|
||||
* This looks up the EFI table pointer and shows related info
|
||||
*/
|
||||
void efi_show_bdinfo(void);
|
||||
|
||||
#endif
|
||||
@@ -72,7 +72,4 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
|
||||
*/
|
||||
void zimage_dump(struct boot_params *base_ptr);
|
||||
|
||||
void setup_video(struct screen_info *screen_info);
|
||||
void setup_efi_info(struct efi_info *efi_info);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# (C) Copyright 2002-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
|
||||
obj-y += bdinfo.o
|
||||
ifndef CONFIG_X86_64
|
||||
ifndef CONFIG_TPL_BUILD
|
||||
obj-y += bios.o
|
||||
|
||||
22
arch/x86/lib/bdinfo.c
Normal file
22
arch/x86/lib/bdinfo.c
Normal file
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* x86-specific information for the 'bd' command
|
||||
*
|
||||
* Copyright 2021 Google LLC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <efi.h>
|
||||
#include <init.h>
|
||||
#include <asm/efi.h>
|
||||
#include <asm/global_data.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void arch_print_bdinfo(void)
|
||||
{
|
||||
bdinfo_print_num_l("prev table", gd->arch.table);
|
||||
|
||||
if (IS_ENABLED(CONFIG_EFI_STUB))
|
||||
efi_show_bdinfo();
|
||||
}
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/bootm.h>
|
||||
#include <asm/bootparam.h>
|
||||
#include <asm/efi.h>
|
||||
#include <asm/global_data.h>
|
||||
#ifdef CONFIG_SYS_COREBOOT
|
||||
#include <asm/arch/timestamp.h>
|
||||
|
||||
@@ -1143,10 +1143,7 @@ static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t *size)
|
||||
{
|
||||
struct efi_device_path *initrd_path = NULL;
|
||||
struct efi_load_option lo;
|
||||
u16 *dp_str;
|
||||
efi_status_t ret;
|
||||
efi_uintn_t initrd_dp_size;
|
||||
const efi_guid_t lf2_initrd_guid = EFI_INITRD_MEDIA_GUID;
|
||||
|
||||
ret = efi_deserialize_load_option(&lo, data, size);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
@@ -1165,15 +1162,11 @@ static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t *size)
|
||||
lo.attributes);
|
||||
printf(" label: %ls\n", lo.label);
|
||||
|
||||
dp_str = efi_dp_str(lo.file_path);
|
||||
printf(" file_path: %ls\n", dp_str);
|
||||
efi_free_pool(dp_str);
|
||||
printf(" file_path: %pD\n", lo.file_path);
|
||||
|
||||
initrd_path = efi_dp_from_lo(&lo, &initrd_dp_size, lf2_initrd_guid);
|
||||
initrd_path = efi_dp_from_lo(&lo, &efi_lf2_initrd_guid);
|
||||
if (initrd_path) {
|
||||
dp_str = efi_dp_str(initrd_path);
|
||||
printf(" initrd_path: %ls\n", dp_str);
|
||||
efi_free_pool(dp_str);
|
||||
printf(" initrd_path: %pD\n", initrd_path);
|
||||
efi_free_pool(initrd_path);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ CONFIG_ANDROID_BOOT_IMAGE=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_SIGNATURE=y
|
||||
CONFIG_MISC_INIT_F=y
|
||||
CONFIG_AVB_BUF_ADDR=0x0
|
||||
CONFIG_AVB_BUF_SIZE=0x8192
|
||||
# CONFIG_CMD_BOOTD is not set
|
||||
# CONFIG_CMD_BOOTM is not set
|
||||
# CONFIG_CMD_ELF is not set
|
||||
@@ -31,4 +33,7 @@ CONFIG_SYSRESET=y
|
||||
# CONFIG_VIRTIO_MMIO is not set
|
||||
# CONFIG_VIRTIO_PCI is not set
|
||||
# CONFIG_VIRTIO_SANDBOX is not set
|
||||
# CONFIG_EFI_LOADER is not set
|
||||
CONFIG_EFI_CAPSULE_ON_DISK=y
|
||||
CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y
|
||||
CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
|
||||
CONFIG_EFI_CAPSULE_AUTHENTICATE=y
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
AMCC suggested to set the PMU bit to 0 for best performace on the
|
||||
PPC440 DDR controller. The 440er common DDR setup files (sdram.c &
|
||||
spd_sdram.c) are changed accordingly. So all 440er boards using
|
||||
these setup routines will automatically receive this performance
|
||||
increase.
|
||||
|
||||
Please see below some benchmarks done by AMCC to demonstrate this
|
||||
performance changes:
|
||||
|
||||
|
||||
----------------------------------------
|
||||
SDRAM0_CFG0[PMU] = 1 (U-Boot default for Bamboo, Yosemite and Yellowstone)
|
||||
----------------------------------------
|
||||
Stream benchmark results
|
||||
-------------------------------------------------------------
|
||||
This system uses 8 bytes per DOUBLE PRECISION word.
|
||||
-------------------------------------------------------------
|
||||
Array size = 2000000, Offset = 0
|
||||
Total memory required = 45.8 MB.
|
||||
Each test is run 10 times, but only
|
||||
the *best* time for each is used.
|
||||
-------------------------------------------------------------
|
||||
Your clock granularity/precision appears to be 1 microseconds.
|
||||
Each test below will take on the order of 112345 microseconds.
|
||||
(= 112345 clock ticks)
|
||||
Increase the size of the arrays if this shows that you are not getting
|
||||
at least 20 clock ticks per test.
|
||||
-------------------------------------------------------------
|
||||
WARNING -- The above is only a rough guideline.
|
||||
For best results, please be sure you know the precision of your system
|
||||
timer.
|
||||
-------------------------------------------------------------
|
||||
Function Rate (MB/s) RMS time Min time Max time
|
||||
Copy: 256.7683 0.1248 0.1246 0.1250
|
||||
Scale: 246.0157 0.1302 0.1301 0.1302
|
||||
Add: 255.0316 0.1883 0.1882 0.1885
|
||||
Triad: 253.1245 0.1897 0.1896 0.1899
|
||||
|
||||
|
||||
TTCP Benchmark Results
|
||||
ttcp-t: socket
|
||||
ttcp-t: connect
|
||||
ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5000 tcp ->
|
||||
localhost
|
||||
ttcp-t: 16777216 bytes in 0.28 real seconds = 454.29 Mbit/sec +++
|
||||
ttcp-t: 2048 I/O calls, msec/call = 0.14, calls/sec = 7268.57
|
||||
ttcp-t: 0.0user 0.1sys 0:00real 60% 0i+0d 0maxrss 0+2pf 3+1506csw
|
||||
|
||||
----------------------------------------
|
||||
SDRAM0_CFG0[PMU] = 0 (Suggested modification)
|
||||
Setting PMU = 0 provides a noticeable performance improvement *2% to
|
||||
5% improvement in memory performance.
|
||||
*Improves the Mbit/sec for TTCP benchmark by almost 76%.
|
||||
----------------------------------------
|
||||
Stream benchmark results
|
||||
-------------------------------------------------------------
|
||||
This system uses 8 bytes per DOUBLE PRECISION word.
|
||||
-------------------------------------------------------------
|
||||
Array size = 2000000, Offset = 0
|
||||
Total memory required = 45.8 MB.
|
||||
Each test is run 10 times, but only
|
||||
the *best* time for each is used.
|
||||
-------------------------------------------------------------
|
||||
Your clock granularity/precision appears to be 1 microseconds.
|
||||
Each test below will take on the order of 120066 microseconds.
|
||||
(= 120066 clock ticks)
|
||||
Increase the size of the arrays if this shows that you are not getting
|
||||
at least 20 clock ticks per test.
|
||||
-------------------------------------------------------------
|
||||
WARNING -- The above is only a rough guideline.
|
||||
For best results, please be sure you know the precision of your system
|
||||
timer.
|
||||
-------------------------------------------------------------
|
||||
Function Rate (MB/s) RMS time Min time Max time
|
||||
Copy: 262.5167 0.1221 0.1219 0.1223
|
||||
Scale: 258.4856 0.1238 0.1238 0.1240
|
||||
Add: 262.5404 0.1829 0.1828 0.1831
|
||||
Triad: 266.8594 0.1800 0.1799 0.1802
|
||||
|
||||
TTCP Benchmark Results
|
||||
ttcp-t: socket
|
||||
ttcp-t: connect
|
||||
ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5000 tcp ->
|
||||
localhost
|
||||
ttcp-t: 16777216 bytes in 0.16 real seconds = 804.06 Mbit/sec +++
|
||||
ttcp-t: 2048 I/O calls, msec/call = 0.08, calls/sec = 12864.89
|
||||
ttcp-t: 0.0user 0.0sys 0:00real 46% 0i+0d 0maxrss 0+2pf 120+1csw
|
||||
|
||||
|
||||
2006-07-28, Stefan Roese <sr@denx.de>
|
||||
@@ -15,5 +15,6 @@ U-Boot API documentation
|
||||
rng
|
||||
sandbox
|
||||
serial
|
||||
sysreset
|
||||
timer
|
||||
unicode
|
||||
|
||||
7
doc/api/sysreset.rst
Normal file
7
doc/api/sysreset.rst
Normal file
@@ -0,0 +1,7 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
System reset
|
||||
============
|
||||
|
||||
.. kernel-doc:: include/sysreset.h
|
||||
:internal:
|
||||
6
doc/build/gcc.rst
vendored
6
doc/build/gcc.rst
vendored
@@ -27,9 +27,9 @@ Depending on the build targets further packages maybe needed
|
||||
device-tree-compiler dfu-util efitools flex gdisk graphviz imagemagick \
|
||||
liblz4-tool libguestfs-tools libncurses-dev libpython3-dev libsdl2-dev \
|
||||
libssl-dev lz4 lzma lzma-alone openssl pkg-config python3 \
|
||||
python3-coverage python3-pycryptodome python3-pyelftools python3-pytest \
|
||||
python3-sphinxcontrib.apidoc python3-sphinx-rtd-theme python3-virtualenv \
|
||||
swig
|
||||
python3-coverage python3-pkg-resources python3-pycryptodome \
|
||||
python3-pyelftools python3-pytest python3-sphinxcontrib.apidoc \
|
||||
python3-sphinx-rtd-theme python3-virtualenv swig
|
||||
|
||||
SUSE based
|
||||
~~~~~~~~~~
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
docutils==0.16
|
||||
Sphinx==2.4.4
|
||||
Sphinx==3.4.3
|
||||
sphinx_rtd_theme
|
||||
six
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define EFI_INITRD_MEDIA_GUID \
|
||||
EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, \
|
||||
0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
|
||||
extern const efi_guid_t efi_lf2_initrd_guid;
|
||||
|
||||
struct efi_initrd_dp {
|
||||
struct efi_device_path_vendor vendor;
|
||||
|
||||
@@ -675,6 +675,8 @@ struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t guid);
|
||||
#define efi_size_in_pages(size) (((size) + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT)
|
||||
/* Generic EFI memory allocator, call this to get memory */
|
||||
void *efi_alloc(uint64_t len, int memory_type);
|
||||
/* Allocate pages on the specified alignment */
|
||||
void *efi_alloc_aligned_pages(u64 len, int memory_type, size_t align);
|
||||
/* More specific EFI memory allocator, called by EFI payloads */
|
||||
efi_status_t efi_allocate_pages(enum efi_allocate_type type,
|
||||
enum efi_memory_type memory_type,
|
||||
@@ -840,7 +842,7 @@ struct efi_load_option {
|
||||
};
|
||||
|
||||
struct efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
|
||||
efi_uintn_t *size, efi_guid_t guid);
|
||||
const efi_guid_t *guid);
|
||||
struct efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
|
||||
const struct efi_device_path *dp2);
|
||||
efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data,
|
||||
|
||||
@@ -9,43 +9,55 @@
|
||||
|
||||
struct udevice;
|
||||
|
||||
/**
|
||||
* enum sysreset_t - system reset types
|
||||
*/
|
||||
enum sysreset_t {
|
||||
SYSRESET_WARM, /* Reset CPU, keep GPIOs active */
|
||||
SYSRESET_COLD, /* Reset CPU and GPIOs */
|
||||
SYSRESET_POWER, /* Reset PMIC (remove and restore power) */
|
||||
SYSRESET_POWER_OFF, /* Turn off power */
|
||||
|
||||
/** @SYSRESET_WARM: reset CPU, keep GPIOs active */
|
||||
SYSRESET_WARM,
|
||||
/** @SYSRESET_COLD: reset CPU and GPIOs */
|
||||
SYSRESET_COLD,
|
||||
/** @SYSRESET_POWER: reset PMIC (remove and restore power) */
|
||||
SYSRESET_POWER,
|
||||
/** @SYSRESET_POWER_OFF: turn off power */
|
||||
SYSRESET_POWER_OFF,
|
||||
/** @SYSRESET_COUNT: number of available reset types */
|
||||
SYSRESET_COUNT,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sysreset_ops - operations of system reset drivers
|
||||
*/
|
||||
struct sysreset_ops {
|
||||
/**
|
||||
* request() - request a sysreset of the given type
|
||||
* @request: request a sysreset of the given type
|
||||
*
|
||||
* Note that this function may return before the reset takes effect.
|
||||
*
|
||||
* @dev: Device to be used for system reset
|
||||
* @type: Reset type to request
|
||||
* @return -EINPROGRESS if the reset has been started and
|
||||
* will complete soon, -EPROTONOSUPPORT if not supported
|
||||
* by this device, 0 if the reset has already happened
|
||||
* (in which case this method will not actually return)
|
||||
* Return:
|
||||
* -EINPROGRESS if the reset has been started and
|
||||
* will complete soon, -EPROTONOSUPPORT if not supported
|
||||
* by this device, 0 if the reset has already happened
|
||||
* (in which case this method will not actually return)
|
||||
*/
|
||||
int (*request)(struct udevice *dev, enum sysreset_t type);
|
||||
/**
|
||||
* get_status() - get printable reset status information
|
||||
* @get_status: get printable reset status information
|
||||
*
|
||||
* @dev: Device to check
|
||||
* @buf: Buffer to receive the textual reset information
|
||||
* @size: Size of the passed buffer
|
||||
* @return 0 if OK, -ve on error
|
||||
* Return: 0 if OK, -ve on error
|
||||
*/
|
||||
int (*get_status)(struct udevice *dev, char *buf, int size);
|
||||
|
||||
/**
|
||||
* get_last() - get information on the last reset
|
||||
* @get_last: get information on the last reset
|
||||
*
|
||||
* @dev: Device to check
|
||||
* @return last reset state (enum sysreset_t) or -ve error
|
||||
* Return: last reset state (enum :enum:`sysreset_t`) or -ve error
|
||||
*/
|
||||
int (*get_last)(struct udevice *dev);
|
||||
};
|
||||
@@ -55,8 +67,9 @@ struct sysreset_ops {
|
||||
/**
|
||||
* sysreset_request() - request a sysreset
|
||||
*
|
||||
* @dev: Device to be used for system reset
|
||||
* @type: Reset type to request
|
||||
* @return 0 if OK, -EPROTONOSUPPORT if not supported by this device
|
||||
* Return: 0 if OK, -EPROTONOSUPPORT if not supported by this device
|
||||
*/
|
||||
int sysreset_request(struct udevice *dev, enum sysreset_t type);
|
||||
|
||||
@@ -66,7 +79,7 @@ int sysreset_request(struct udevice *dev, enum sysreset_t type);
|
||||
* @dev: Device to check
|
||||
* @buf: Buffer to receive the textual reset information
|
||||
* @size: Size of the passed buffer
|
||||
* @return 0 if OK, -ve on error
|
||||
* Return: 0 if OK, -ve on error
|
||||
*/
|
||||
int sysreset_get_status(struct udevice *dev, char *buf, int size);
|
||||
|
||||
@@ -74,7 +87,7 @@ int sysreset_get_status(struct udevice *dev, char *buf, int size);
|
||||
* sysreset_get_last() - get information on the last reset
|
||||
*
|
||||
* @dev: Device to check
|
||||
* @return last reset state (enum sysreset_t) or -ve error
|
||||
* Return: last reset state (enum sysreset_t) or -ve error
|
||||
*/
|
||||
int sysreset_get_last(struct udevice *dev);
|
||||
|
||||
@@ -88,7 +101,7 @@ int sysreset_get_last(struct udevice *dev);
|
||||
* If this function fails to reset, it will display a message and halt
|
||||
*
|
||||
* @type: Reset type to request
|
||||
* @return -EINPROGRESS if a reset is in progress, -ENOSYS if not available
|
||||
* Return: -EINPROGRESS if a reset is in progress, -ENOSYS if not available
|
||||
*/
|
||||
int sysreset_walk(enum sysreset_t type);
|
||||
|
||||
@@ -101,7 +114,7 @@ int sysreset_walk(enum sysreset_t type);
|
||||
*
|
||||
* If no device prives the information, this function returns -ENOENT
|
||||
*
|
||||
* @return last reset state (enum sysreset_t) or -ve error
|
||||
* Return: last reset state (enum sysreset_t) or -ve error
|
||||
*/
|
||||
int sysreset_get_last_walk(void);
|
||||
|
||||
@@ -110,6 +123,8 @@ int sysreset_get_last_walk(void);
|
||||
*
|
||||
* This calls sysreset_walk(). If it returns, indicating that reset is not
|
||||
* supported, it prints a message and halts.
|
||||
*
|
||||
* @type: Reset type to request
|
||||
*/
|
||||
void sysreset_walk_halt(enum sysreset_t type);
|
||||
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
# object inclusion implicitly depends on it
|
||||
|
||||
obj-y += efi_uclass.o
|
||||
ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy)
|
||||
ifeq ($(CONFIG_PARTITIONS),y)
|
||||
obj-y += efi_block_device.o
|
||||
endif
|
||||
|
||||
@@ -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 || !NET
|
||||
default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8
|
||||
select LIB_UUID
|
||||
select PARTITION_UUIDS
|
||||
|
||||
@@ -46,7 +46,7 @@ static const struct efi_device_path_vendor ROOT = {
|
||||
.guid = U_BOOT_GUID,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
|
||||
#if defined(CONFIG_MMC)
|
||||
/*
|
||||
* Determine if an MMC device is an SD card.
|
||||
*
|
||||
@@ -486,7 +486,6 @@ bool efi_dp_is_multi_instance(const struct efi_device_path *dp)
|
||||
return p->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM
|
||||
/* size of device-path not including END node for device and all parents
|
||||
* up to the root device.
|
||||
*/
|
||||
@@ -503,7 +502,6 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
|
||||
case UCLASS_ETH:
|
||||
return dp_size(dev->parent) +
|
||||
sizeof(struct efi_device_path_mac_addr);
|
||||
#ifdef CONFIG_BLK
|
||||
case UCLASS_BLK:
|
||||
switch (dev->parent->uclass->uc_drv->id) {
|
||||
#ifdef CONFIG_IDE
|
||||
@@ -511,12 +509,12 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
|
||||
return dp_size(dev->parent) +
|
||||
sizeof(struct efi_device_path_atapi);
|
||||
#endif
|
||||
#if defined(CONFIG_SCSI) && defined(CONFIG_DM_SCSI)
|
||||
#if defined(CONFIG_SCSI)
|
||||
case UCLASS_SCSI:
|
||||
return dp_size(dev->parent) +
|
||||
sizeof(struct efi_device_path_scsi);
|
||||
#endif
|
||||
#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
|
||||
#if defined(CONFIG_MMC)
|
||||
case UCLASS_MMC:
|
||||
return dp_size(dev->parent) +
|
||||
sizeof(struct efi_device_path_sd_mmc_path);
|
||||
@@ -554,8 +552,7 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
|
||||
default:
|
||||
return dp_size(dev->parent);
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
|
||||
#if defined(CONFIG_MMC)
|
||||
case UCLASS_MMC:
|
||||
return dp_size(dev->parent) +
|
||||
sizeof(struct efi_device_path_sd_mmc_path);
|
||||
@@ -590,7 +587,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
|
||||
*vdp = ROOT;
|
||||
return &vdp[1];
|
||||
}
|
||||
#ifdef CONFIG_DM_ETH
|
||||
#ifdef CONFIG_NET
|
||||
case UCLASS_ETH: {
|
||||
struct efi_device_path_mac_addr *dp =
|
||||
dp_fill(buf, dev->parent);
|
||||
@@ -607,7 +604,6 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
|
||||
return &dp[1];
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_BLK
|
||||
case UCLASS_BLK:
|
||||
switch (dev->parent->uclass->uc_drv->id) {
|
||||
#ifdef CONFIG_SANDBOX
|
||||
@@ -662,7 +658,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
|
||||
return &dp[1];
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_SCSI) && defined(CONFIG_DM_SCSI)
|
||||
#if defined(CONFIG_SCSI)
|
||||
case UCLASS_SCSI: {
|
||||
struct efi_device_path_scsi *dp =
|
||||
dp_fill(buf, dev->parent);
|
||||
@@ -676,7 +672,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
|
||||
return &dp[1];
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
|
||||
#if defined(CONFIG_MMC)
|
||||
case UCLASS_MMC: {
|
||||
struct efi_device_path_sd_mmc_path *sddp =
|
||||
dp_fill(buf, dev->parent);
|
||||
@@ -727,8 +723,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
|
||||
dev->name, dev->parent->uclass->uc_drv->id);
|
||||
return dp_fill(buf, dev->parent);
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
|
||||
#if defined(CONFIG_MMC)
|
||||
case UCLASS_MMC: {
|
||||
struct efi_device_path_sd_mmc_path *sddp =
|
||||
dp_fill(buf, dev->parent);
|
||||
@@ -770,24 +765,18 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
|
||||
return dp_fill(buf, dev->parent);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned dp_part_size(struct blk_desc *desc, int part)
|
||||
{
|
||||
unsigned dpsize;
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_BLK
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret = blk_find_device(desc->if_type, desc->devnum, &dev);
|
||||
ret = blk_find_device(desc->if_type, desc->devnum, &dev);
|
||||
|
||||
if (ret)
|
||||
dev = desc->bdev->parent;
|
||||
dpsize = dp_size(dev);
|
||||
}
|
||||
#else
|
||||
dpsize = sizeof(ROOT) + sizeof(struct efi_device_path_usb);
|
||||
#endif
|
||||
if (ret)
|
||||
dev = desc->bdev->parent;
|
||||
dpsize = dp_size(dev);
|
||||
|
||||
if (part == 0) /* the actual disk, not a partition */
|
||||
return dpsize;
|
||||
@@ -877,36 +866,14 @@ static void *dp_part_node(void *buf, struct blk_desc *desc, int part)
|
||||
*/
|
||||
static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
|
||||
{
|
||||
#ifdef CONFIG_BLK
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret = blk_find_device(desc->if_type, desc->devnum, &dev);
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
if (ret)
|
||||
dev = desc->bdev->parent;
|
||||
buf = dp_fill(buf, dev);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* We *could* make a more accurate path, by looking at if_type
|
||||
* and handling all the different cases like we do for non-
|
||||
* legacy (i.e. CONFIG_BLK=y) case. But most important thing
|
||||
* is just to have a unique device-path for if_type+devnum.
|
||||
* So map things to a fictitious USB device.
|
||||
*/
|
||||
struct efi_device_path_usb *udp;
|
||||
ret = blk_find_device(desc->if_type, desc->devnum, &dev);
|
||||
|
||||
memcpy(buf, &ROOT, sizeof(ROOT));
|
||||
buf += sizeof(ROOT);
|
||||
|
||||
udp = buf;
|
||||
udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
|
||||
udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB;
|
||||
udp->dp.length = sizeof(*udp);
|
||||
udp->parent_port_number = desc->if_type;
|
||||
udp->usb_interface = desc->devnum;
|
||||
buf = &udp[1];
|
||||
#endif
|
||||
if (ret)
|
||||
dev = desc->bdev->parent;
|
||||
buf = dp_fill(buf, dev);
|
||||
|
||||
if (part == 0) /* the actual disk, not a partition */
|
||||
return buf;
|
||||
@@ -1051,39 +1018,18 @@ struct efi_device_path *efi_dp_from_uart(void)
|
||||
#ifdef CONFIG_NET
|
||||
struct efi_device_path *efi_dp_from_eth(void)
|
||||
{
|
||||
#ifndef CONFIG_DM_ETH
|
||||
struct efi_device_path_mac_addr *ndp;
|
||||
#endif
|
||||
void *buf, *start;
|
||||
unsigned dpsize = 0;
|
||||
|
||||
assert(eth_get_dev());
|
||||
|
||||
#ifdef CONFIG_DM_ETH
|
||||
dpsize += dp_size(eth_get_dev());
|
||||
#else
|
||||
dpsize += sizeof(ROOT);
|
||||
dpsize += sizeof(*ndp);
|
||||
#endif
|
||||
|
||||
start = buf = dp_alloc(dpsize + sizeof(END));
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
#ifdef CONFIG_DM_ETH
|
||||
buf = dp_fill(buf, eth_get_dev());
|
||||
#else
|
||||
memcpy(buf, &ROOT, sizeof(ROOT));
|
||||
buf += sizeof(ROOT);
|
||||
|
||||
ndp = buf;
|
||||
ndp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
|
||||
ndp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR;
|
||||
ndp->dp.length = sizeof(*ndp);
|
||||
ndp->if_type = 1; /* Ethernet */
|
||||
memcpy(ndp->mac.addr, eth_get_ethaddr(), ARP_HLEN);
|
||||
buf = &ndp[1];
|
||||
#endif
|
||||
|
||||
*((struct efi_device_path *)buf) = END;
|
||||
|
||||
@@ -1263,7 +1209,6 @@ ssize_t efi_dp_check_length(const struct efi_device_path *dp,
|
||||
* initrd location
|
||||
*
|
||||
* @lo: EFI_LOAD_OPTION containing a valid device path
|
||||
* @size: size of the discovered device path
|
||||
* @guid: guid to search for
|
||||
*
|
||||
* Return:
|
||||
@@ -1272,7 +1217,7 @@ ssize_t efi_dp_check_length(const struct efi_device_path *dp,
|
||||
*/
|
||||
struct
|
||||
efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
|
||||
efi_uintn_t *size, efi_guid_t guid)
|
||||
const efi_guid_t *guid)
|
||||
{
|
||||
struct efi_device_path *fp = lo->file_path;
|
||||
struct efi_device_path_vendor *vendor;
|
||||
@@ -1287,8 +1232,8 @@ efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
|
||||
continue;
|
||||
|
||||
vendor = (struct efi_device_path_vendor *)fp;
|
||||
if (!guidcmp(&vendor->guid, &guid))
|
||||
return efi_dp_dup(fp);
|
||||
if (!guidcmp(&vendor->guid, guid))
|
||||
return efi_dp_dup(efi_dp_next(fp));
|
||||
}
|
||||
log_debug("VenMedia(%pUl) not found in %ls\n", &guid, lo->label);
|
||||
|
||||
|
||||
@@ -555,7 +555,6 @@ efi_status_t efi_disk_register(void)
|
||||
struct efi_disk_obj *disk;
|
||||
int disks = 0;
|
||||
efi_status_t ret;
|
||||
#ifdef CONFIG_BLK
|
||||
struct udevice *dev;
|
||||
|
||||
for (uclass_first_device_check(UCLASS_BLK, &dev); dev;
|
||||
@@ -583,54 +582,7 @@ efi_status_t efi_disk_register(void)
|
||||
&disk->header, desc, if_typename,
|
||||
desc->devnum, dev->name);
|
||||
}
|
||||
#else
|
||||
int i, if_type;
|
||||
|
||||
/* Search for all available disk devices */
|
||||
for (if_type = 0; if_type < IF_TYPE_COUNT; if_type++) {
|
||||
const struct blk_driver *cur_drvr;
|
||||
const char *if_typename;
|
||||
|
||||
cur_drvr = blk_driver_lookup_type(if_type);
|
||||
if (!cur_drvr)
|
||||
continue;
|
||||
|
||||
if_typename = cur_drvr->if_typename;
|
||||
log_info("Scanning disks on %s...\n", if_typename);
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct blk_desc *desc;
|
||||
char devname[32] = { 0 }; /* dp->str is u16[32] long */
|
||||
|
||||
desc = blk_get_devnum_by_type(if_type, i);
|
||||
if (!desc)
|
||||
continue;
|
||||
if (desc->type == DEV_TYPE_UNKNOWN)
|
||||
continue;
|
||||
|
||||
snprintf(devname, sizeof(devname), "%s%d",
|
||||
if_typename, i);
|
||||
|
||||
/* Add block device for the full device */
|
||||
ret = efi_disk_add_dev(NULL, NULL, if_typename, desc,
|
||||
i, NULL, 0, &disk);
|
||||
if (ret == EFI_NOT_READY) {
|
||||
log_notice("Disk %s not ready\n", devname);
|
||||
continue;
|
||||
}
|
||||
if (ret) {
|
||||
log_err("ERROR: failure to add disk device %s, r = %lu\n",
|
||||
devname, ret & ~EFI_ERROR_MASK);
|
||||
return ret;
|
||||
}
|
||||
disks++;
|
||||
|
||||
/* Partitions show up as block devices in EFI */
|
||||
disks += efi_disk_create_partitions
|
||||
(&disk->header, desc,
|
||||
if_typename, i, devname);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
log_info("Found %d disks\n", disks);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
#include <efi_loader.h>
|
||||
#include <efi_variable.h>
|
||||
|
||||
#if defined(CONFIG_CMD_EFIDEBUG) || defined(CONFIG_EFI_LOAD_FILE2_INITRD)
|
||||
/* GUID used by Linux to identify the LoadFile2 protocol with the initrd */
|
||||
const efi_guid_t efi_lf2_initrd_guid = EFI_INITRD_MEDIA_GUID;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* efi_create_current_boot_var() - Return Boot#### name were #### is replaced by
|
||||
* the value of BootCurrent
|
||||
@@ -63,10 +68,8 @@ out:
|
||||
*/
|
||||
struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t guid)
|
||||
{
|
||||
struct efi_device_path *file_path = NULL;
|
||||
struct efi_device_path *tmp = NULL;
|
||||
struct efi_load_option lo;
|
||||
void *var_value = NULL;
|
||||
void *var_value;
|
||||
efi_uintn_t size;
|
||||
efi_status_t ret;
|
||||
u16 var_name[16];
|
||||
@@ -81,18 +84,11 @@ struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t guid)
|
||||
|
||||
ret = efi_deserialize_load_option(&lo, var_value, &size);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
goto err;
|
||||
|
||||
tmp = efi_dp_from_lo(&lo, &size, guid);
|
||||
if (!tmp)
|
||||
goto out;
|
||||
return efi_dp_from_lo(&lo, &guid);
|
||||
|
||||
/* efi_dp_dup will just return NULL if efi_dp_next is NULL */
|
||||
file_path = efi_dp_dup(efi_dp_next(tmp));
|
||||
|
||||
out:
|
||||
efi_free_pool(tmp);
|
||||
err:
|
||||
free(var_value);
|
||||
|
||||
return file_path;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -898,9 +898,9 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
|
||||
image_base = opt->ImageBase;
|
||||
efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
|
||||
handle->image_type = opt->Subsystem;
|
||||
virt_size = ALIGN(virt_size, opt->SectionAlignment);
|
||||
efi_reloc = efi_alloc(virt_size,
|
||||
loaded_image_info->image_code_type);
|
||||
efi_reloc = efi_alloc_aligned_pages(virt_size,
|
||||
loaded_image_info->image_code_type,
|
||||
opt->SectionAlignment);
|
||||
if (!efi_reloc) {
|
||||
log_err("Out of memory\n");
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
@@ -914,9 +914,9 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
|
||||
image_base = opt->ImageBase;
|
||||
efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
|
||||
handle->image_type = opt->Subsystem;
|
||||
virt_size = ALIGN(virt_size, opt->SectionAlignment);
|
||||
efi_reloc = efi_alloc(virt_size,
|
||||
loaded_image_info->image_code_type);
|
||||
efi_reloc = efi_alloc_aligned_pages(virt_size,
|
||||
loaded_image_info->image_code_type,
|
||||
opt->SectionAlignment);
|
||||
if (!efi_reloc) {
|
||||
log_err("Out of memory\n");
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
|
||||
@@ -52,7 +52,6 @@ static efi_handle_t efi_initrd_handle;
|
||||
*/
|
||||
static efi_status_t get_initrd_fp(struct efi_device_path **initrd_fp)
|
||||
{
|
||||
const efi_guid_t lf2_initrd_guid = EFI_INITRD_MEDIA_GUID;
|
||||
struct efi_device_path *dp = NULL;
|
||||
|
||||
/*
|
||||
@@ -65,7 +64,7 @@ static efi_status_t get_initrd_fp(struct efi_device_path **initrd_fp)
|
||||
* We can then use this specific return value and not install the
|
||||
* protocol, while allowing the boot to continue
|
||||
*/
|
||||
dp = efi_get_dp_from_boot(lf2_initrd_guid);
|
||||
dp = efi_get_dp_from_boot(efi_lf2_initrd_guid);
|
||||
if (!dp)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
|
||||
@@ -549,6 +549,58 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_alloc_aligned_pages - allocate
|
||||
*
|
||||
* @len: len in bytes
|
||||
* @memory_type: usage type of the allocated memory
|
||||
* @align: alignment in bytes
|
||||
* Return: aligned memory or NULL
|
||||
*/
|
||||
void *efi_alloc_aligned_pages(u64 len, int memory_type, size_t align)
|
||||
{
|
||||
u64 req_pages = efi_size_in_pages(len);
|
||||
u64 true_pages = req_pages + efi_size_in_pages(align) - 1;
|
||||
u64 free_pages;
|
||||
u64 aligned_mem;
|
||||
efi_status_t r;
|
||||
u64 mem;
|
||||
|
||||
/* align must be zero or a power of two */
|
||||
if (align & (align - 1))
|
||||
return NULL;
|
||||
|
||||
/* Check for overflow */
|
||||
if (true_pages < req_pages)
|
||||
return NULL;
|
||||
|
||||
if (align < EFI_PAGE_SIZE) {
|
||||
r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, memory_type,
|
||||
req_pages, &mem);
|
||||
return (r == EFI_SUCCESS) ? (void *)(uintptr_t)mem : NULL;
|
||||
}
|
||||
|
||||
r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, memory_type,
|
||||
true_pages, &mem);
|
||||
if (r != EFI_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
aligned_mem = ALIGN(mem, align);
|
||||
/* Free pages before alignment */
|
||||
free_pages = efi_size_in_pages(aligned_mem - mem);
|
||||
if (free_pages)
|
||||
efi_free_pages(mem, free_pages);
|
||||
|
||||
/* Free trailing pages */
|
||||
free_pages = true_pages - (req_pages + free_pages);
|
||||
if (free_pages) {
|
||||
mem = aligned_mem + req_pages * EFI_PAGE_SIZE;
|
||||
efi_free_pages(mem, free_pages);
|
||||
}
|
||||
|
||||
return (void *)(uintptr_t)aligned_mem;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_allocate_pool - allocate memory from pool
|
||||
*
|
||||
|
||||
@@ -19,6 +19,13 @@
|
||||
|
||||
#define PART_STR_LEN 10
|
||||
|
||||
/* GUID used by Shim to store the MOK database */
|
||||
#define SHIM_LOCK_GUID \
|
||||
EFI_GUID(0x605dab50, 0xe046, 0x4300, \
|
||||
0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
|
||||
|
||||
static const efi_guid_t shim_lock_guid = SHIM_LOCK_GUID;
|
||||
|
||||
/**
|
||||
* efi_set_blk_dev_to_system_partition() - select EFI system partition
|
||||
*
|
||||
@@ -175,6 +182,7 @@ efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe)
|
||||
if (!safe &&
|
||||
(efi_auth_var_get_type(var->name, &var->guid) !=
|
||||
EFI_AUTH_VAR_NONE ||
|
||||
!guidcmp(&var->guid, &shim_lock_guid) ||
|
||||
!(var->attr & EFI_VARIABLE_NON_VOLATILE)))
|
||||
continue;
|
||||
if (!var->length)
|
||||
|
||||
@@ -309,6 +309,18 @@ static int execute(void)
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
|
||||
/* Check media connected */
|
||||
ret = net->get_status(net, NULL, NULL);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
efi_st_error("Failed to get status");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
if (net->mode && net->mode->media_present_supported &&
|
||||
!net->mode->media_present) {
|
||||
efi_st_error("Network media is not connected");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send DHCP discover message
|
||||
*/
|
||||
@@ -328,8 +340,6 @@ static int execute(void)
|
||||
events[0] = timer;
|
||||
events[1] = net->wait_for_packet;
|
||||
for (;;) {
|
||||
u32 int_status;
|
||||
|
||||
/*
|
||||
* Wait for packet to be received or timer event.
|
||||
*/
|
||||
@@ -352,48 +362,46 @@ static int execute(void)
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Receive packet
|
||||
* Receive packets until buffer is empty
|
||||
*/
|
||||
buffer_size = sizeof(buffer);
|
||||
ret = net->get_status(net, &int_status, NULL);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
efi_st_error("Failed to get status");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
if (!(int_status & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT)) {
|
||||
efi_st_error("RX interrupt not set");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
ret = net->receive(net, NULL, &buffer_size, &buffer,
|
||||
&srcaddr, &destaddr, NULL);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
efi_st_error("Failed to receive packet");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Check the packet is meant for this system.
|
||||
* Unfortunately QEMU ignores the broadcast flag.
|
||||
* So we have to check for broadcasts too.
|
||||
*/
|
||||
if (memcmp(&destaddr, &net->mode->current_address, ARP_HLEN) &&
|
||||
memcmp(&destaddr, BROADCAST_MAC, ARP_HLEN))
|
||||
continue;
|
||||
/*
|
||||
* Check this is a DHCP reply
|
||||
*/
|
||||
if (buffer.p.eth_hdr.et_protlen != ntohs(PROT_IP) ||
|
||||
buffer.p.ip_udp.ip_hl_v != 0x45 ||
|
||||
buffer.p.ip_udp.ip_p != IPPROTO_UDP ||
|
||||
buffer.p.ip_udp.udp_src != ntohs(67) ||
|
||||
buffer.p.ip_udp.udp_dst != ntohs(68) ||
|
||||
buffer.p.dhcp_hdr.op != BOOTREPLY)
|
||||
continue;
|
||||
/*
|
||||
* We successfully received a DHCP reply.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
for (;;) {
|
||||
buffer_size = sizeof(buffer);
|
||||
ret = net->receive(net, NULL, &buffer_size, &buffer,
|
||||
&srcaddr, &destaddr, NULL);
|
||||
if (ret == EFI_NOT_READY) {
|
||||
/* The received buffer is empty. */
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret != EFI_SUCCESS) {
|
||||
efi_st_error("Failed to receive packet");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Check the packet is meant for this system.
|
||||
* Unfortunately QEMU ignores the broadcast flag.
|
||||
* So we have to check for broadcasts too.
|
||||
*/
|
||||
if (memcmp(&destaddr, &net->mode->current_address, ARP_HLEN) &&
|
||||
memcmp(&destaddr, BROADCAST_MAC, ARP_HLEN))
|
||||
continue;
|
||||
/*
|
||||
* Check this is a DHCP reply
|
||||
*/
|
||||
if (buffer.p.eth_hdr.et_protlen != ntohs(PROT_IP) ||
|
||||
buffer.p.ip_udp.ip_hl_v != 0x45 ||
|
||||
buffer.p.ip_udp.ip_p != IPPROTO_UDP ||
|
||||
buffer.p.ip_udp.udp_src != ntohs(67) ||
|
||||
buffer.p.ip_udp.udp_dst != ntohs(68) ||
|
||||
buffer.p.dhcp_hdr.op != BOOTREPLY)
|
||||
continue;
|
||||
/*
|
||||
* We successfully received a DHCP reply.
|
||||
*/
|
||||
goto received;
|
||||
}
|
||||
}
|
||||
received:
|
||||
/*
|
||||
* Write a log message.
|
||||
*/
|
||||
|
||||
@@ -403,7 +403,7 @@ $(obj)/%.efi: $(obj)/%_efi.so
|
||||
|
||||
quiet_cmd_efi_ld = LD $@
|
||||
cmd_efi_ld = $(LD) -nostdlib -znocombreloc -T $(EFI_LDS_PATH) -shared \
|
||||
-Bsymbolic -s $^ -o $@
|
||||
-Bsymbolic -znorelro -s $^ -o $@
|
||||
|
||||
EFI_LDS_PATH = $(srctree)/arch/$(ARCH)/lib/$(EFI_LDS)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user