Pull request of efi-next
Documentation: * Add Sunxi board description UEFI: * Improvements to U-Boot running on top of UEFI -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAmHOp5gACgkQxIHbvCwF GsTonA//Y8wwlaXA1TD6B0fIEcQiZucDJQD0nbHugx+1xw/7w9wHX1qfM4Tskqc4 y4RA3QyoyUp7tvesP6/EA3mAUSEUp0nrtLPyCJjjXV1lrOaXhwvbdqrhOCqUQLen h6RNjhujVtbC90wBWYPal3Ip0hdIUROe3qp9Mk2p4zAru8jBEShn+PTRIeHvf6UV 9BZ8j9LCivC7hUAG3Cyv+KFhW1s47IN54WddedIREEWk4vIdrUMRLjW/kW8ZbDxx gi1Eec25Rte6+p5k/+TJkvCwA8GC1kW+MFMYWxcAARZlUd0yr/S6ru5yaW8km0KQ kKgcYGp878hVB41JFEhiGUf9CkwU2oo+3NZGIfNv/vG45J4UppyqNffm9c3ZudWC S6DqRVPSp1YQEs45SIVZGx+LK6s1iTBn3DJ/dX68NavuUIYX2nnveUBgtW5vdzGf ba0yh4a0EU36hcjd2o3y3sEAjiy+PF8SAZ+f2HQ7JaLjsCWF1zNFGsiAxaEStHp8 aVrUN0cWQPKnnI2A8DCqjmMaSBDKZDK59k6EeC1ZFdMmGivHEO61A0sDiUTz+IRW U7XLvjAA5IVKAtij6T/iab6qvhgwABJRL9lZI5DMiFxJRSl4uSYe9YviG7+EzUg0 XMIs5nK6jBB74HPKqhBouiSUiRa9UHY/rdyNhJACHQ8GODzCf04= =YdSB -----END PGP SIGNATURE----- Merge tag 'efi-next' of https://source.denx.de/u-boot/custodians/u-boot-efi into next Pull request of efi-next Documentation: * Add Sunxi board description UEFI: * Improvements to U-Boot running on top of UEFI
This commit is contained in:
commit
5fec3c853d
@ -7,6 +7,7 @@
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <efi.h>
|
||||
#include <efi_api.h>
|
||||
#include <errno.h>
|
||||
#include <init.h>
|
||||
#include <log.h>
|
||||
@ -296,8 +297,14 @@ void setup_efi_info(struct efi_info *efi_info)
|
||||
void efi_show_bdinfo(void)
|
||||
{
|
||||
struct efi_entry_systable *table = NULL;
|
||||
struct efi_system_table *sys_table;
|
||||
int size, ret;
|
||||
|
||||
ret = efi_info_get(EFIET_SYS_TABLE, (void **)&table, &size);
|
||||
bdinfo_print_num_l("efi_table", (ulong)table);
|
||||
if (!ret) {
|
||||
bdinfo_print_num_l("efi_table", table->sys_table);
|
||||
sys_table = (struct efi_system_table *)(uintptr_t)
|
||||
table->sys_table;
|
||||
bdinfo_print_num_l(" revision", sys_table->fw_revision);
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ dtb-y += bayleybay.dtb \
|
||||
|
||||
targets += $(dtb-y)
|
||||
|
||||
DTC_FLAGS += -R 4 -p 0x1000
|
||||
DTC_FLAGS += -R 4 -p $(if $(CONFIG_EFI_APP),0x8000,0x1000)
|
||||
|
||||
PHONY += dtbs
|
||||
dtbs: $(addprefix $(obj)/, $(dtb-y))
|
||||
|
@ -179,10 +179,14 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
|
||||
* U-Boot is setting them up that way for itself in
|
||||
* arch/i386/cpu/cpu.c.
|
||||
*
|
||||
* Note that we cannot currently boot a kernel while running as
|
||||
* an EFI application. Please use the payload option for that.
|
||||
* Note: this is incomplete for EFI kernels!
|
||||
*
|
||||
* This can boot a kernel while running as an EFI application,
|
||||
* but if the kernel requires EFI support then that support needs
|
||||
* to be enabled first (see EFI_LOADER). Also the EFI information
|
||||
* must enabled with setup_efi_info(). See setup_zimage() for
|
||||
* how this is done with the stub.
|
||||
*/
|
||||
#ifndef CONFIG_EFI_APP
|
||||
__asm__ __volatile__ (
|
||||
"movl $0, %%ebp\n"
|
||||
"cli\n"
|
||||
@ -191,7 +195,6 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
|
||||
[boot_params] "S"(setup_base),
|
||||
"b"(0), "D"(0)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* We can't get to here */
|
||||
|
@ -365,11 +365,14 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
|
||||
strcpy(cmd_line, (char *)cmdline_force);
|
||||
else
|
||||
build_command_line(cmd_line, auto_boot);
|
||||
ret = bootm_process_cmdline(cmd_line, max_size, BOOTM_CL_ALL);
|
||||
if (ret) {
|
||||
printf("Cmdline setup failed (max_size=%x, bootproto=%x, err=%d)\n",
|
||||
max_size, bootproto, ret);
|
||||
return ret;
|
||||
if (IS_ENABLED(CONFIG_CMD_BOOTM)) {
|
||||
ret = bootm_process_cmdline(cmd_line, max_size,
|
||||
BOOTM_CL_ALL);
|
||||
if (ret) {
|
||||
printf("Cmdline setup failed (max_size=%x, bootproto=%x, err=%d)\n",
|
||||
max_size, bootproto, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
printf("Kernel command line: \"");
|
||||
puts(cmd_line);
|
||||
|
@ -841,9 +841,8 @@ void board_init_r(gd_t *new_gd, ulong dest_addr)
|
||||
* TODO(sjg@chromium.org): Consider doing this for all archs, or
|
||||
* dropping the new_gd parameter.
|
||||
*/
|
||||
#if CONFIG_IS_ENABLED(X86_64)
|
||||
arch_setup_gd(new_gd);
|
||||
#endif
|
||||
if (CONFIG_IS_ENABLED(X86_64) && !IS_ENABLED(CONFIG_EFI_APP))
|
||||
arch_setup_gd(new_gd);
|
||||
|
||||
#ifdef CONFIG_NEEDS_MANUAL_RELOC
|
||||
int i;
|
||||
|
9
doc/board/allwinner/index.rst
Normal file
9
doc/board/allwinner/index.rst
Normal file
@ -0,0 +1,9 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
Allwinner (sunxi) boards
|
||||
========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
sunxi
|
319
doc/board/allwinner/sunxi.rst
Normal file
319
doc/board/allwinner/sunxi.rst
Normal file
@ -0,0 +1,319 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
.. Copyright (C) 2021 Arm Ltd.
|
||||
|
||||
Allwinner SoC based boards
|
||||
==========================
|
||||
For boards using an Allwinner ARM based SoC ("sunxi"), the U-Boot build
|
||||
system generates a single integrated image file: ``u-boot-sunxi-with-spl.bin.``
|
||||
This file can be used on SD cards, eMMC devices, SPI flash and for the
|
||||
USB-OTG based boot method (FEL). To build this file:
|
||||
|
||||
* For 64-bit SoCs, build Trusted Firmware (TF-A, formerly known as ATF) first,
|
||||
you will need its ``bl31.bin``. See below for more details.
|
||||
* Optionally on 64-bit SoCs, build the `crust`_ management processor firmware,
|
||||
you will need its ``scp.bin``. See below for more details.
|
||||
* Build U-Boot::
|
||||
|
||||
$ export BL31=/path/to/bl31.bin # required for 64-bit SoCs
|
||||
$ export SCP=/path/to/scp.bin # optional for some 64-bit SoCs
|
||||
$ make <yourboardname>_defconfig
|
||||
$ make
|
||||
* Transfer to an (micro)SD card (see below for more details)::
|
||||
|
||||
$ sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=8k seek=1
|
||||
* Boot and enjoy!
|
||||
|
||||
.. note::
|
||||
The traditional SD card location the Allwinner BootROM loads from is 8KB
|
||||
(sector 16). This works fine with the old MBR partitioning scheme, which most
|
||||
SD cards come formatted with. However this is in the middle of a potential
|
||||
GPT partition table, which will become invalid in this step. Newer SoCs
|
||||
(starting with the H3 from late 2014) also support booting from 128KB, which
|
||||
is beyond even a GPT and thus a safer location.
|
||||
|
||||
For more details, and alternative boot locations or installations, see below.
|
||||
|
||||
Building Arm Trusted Firmware (TF-A)
|
||||
------------------------------------
|
||||
Boards using a 64-bit Soc (A64, H5, H6, H616, R329) require the BL31 stage of
|
||||
the `Arm Trusted Firmware-A`_ firmware. This provides the reference
|
||||
implementation of secure software for Armv8-A, offering PSCI and SMCCC
|
||||
services. Allwinner support is fully mainlined. To build bl31.bin::
|
||||
|
||||
$ git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
|
||||
$ cd trusted-firmware-a
|
||||
$ make CROSS_COMPILE=aarch64-linux-gnu- PLAT=sun50i_a64 DEBUG=1
|
||||
$ export BL31=$(pwd)/build/sun50i_a64/debug/bl31.bin
|
||||
|
||||
The target platform (``PLAT=``) for A64 and H5 SoCs is sun50i_a64, for the H6
|
||||
sun50i_h6, for the H616 sun50i_h616, and for the R329 sun50i_r329. Use::
|
||||
|
||||
$ find plat/allwinner -name platform.mk
|
||||
|
||||
to find all supported platforms. TF-A's `docs/plat/allwinner.rst`_ contains
|
||||
more information and lists some build options.
|
||||
|
||||
Building the Crust management processor firmware
|
||||
------------------------------------------------
|
||||
For some SoCs and boards, the integrated OpenRISC management controller can
|
||||
be used to provide power management services, foremost suspend to RAM.
|
||||
There is a community supported Open Source implementation called `crust`_,
|
||||
which runs on most SoCs featuring a management controller.
|
||||
|
||||
This firmware part is optional, setting the SCP environment variable to
|
||||
/dev/null avoids the warning message when building without one.
|
||||
|
||||
To build crust's scp.bin, you need an OpenRISC (or1k) cross compiler, then::
|
||||
|
||||
$ git clone https://github.com/crust-firmware/crust.git
|
||||
$ cd crust
|
||||
$ make <yourboard>_defconfig
|
||||
$ make CROSS_COMPILE=or1k-none-elf- scp
|
||||
$ export SCP=$(pwd)/build/scp/scp.bin
|
||||
|
||||
Find a list of supported board configurations in the `configs/`_ directory.
|
||||
The `crust README`_ has more information about the building process, including
|
||||
information about where to get OpenRISC cross compilers.
|
||||
|
||||
Building the U-Boot image
|
||||
-------------------------
|
||||
Find the U-Boot defconfig file for your board first. Those files live in
|
||||
the ``configs/`` directory; you can grep for the stub name of the devicetree
|
||||
file, if you know that, or for the SoC name to find the right version::
|
||||
|
||||
$ git grep -l MACH_SUN8I_H3 configs
|
||||
$ git grep -l sun50i-h6-orangepi-3 configs
|
||||
|
||||
The `linux-sunxi`_ wiki also lists the name of the defconfig file in the
|
||||
respective board page. Then use this defconfig file to create the .config
|
||||
file, and build the image::
|
||||
|
||||
$ make <yourboard>_defconfig
|
||||
$ make
|
||||
|
||||
For 64-bit boards, this requires either the BL31 environment variable to be
|
||||
set (as shown above in the TF-A build example), or it to be supplied on the
|
||||
build command line::
|
||||
|
||||
$ make BL31=/src/tf-a.git/build/sun50i_h616/debug/bl31.bin
|
||||
|
||||
The same applies to the (optional) SCP firmware.
|
||||
|
||||
The file containing everything you need is called ``u-boot-sunxi-with-spl.bin``,
|
||||
you will find it in the root folder of your U-Boot (build) tree. Except for
|
||||
raw NAND flash devices this very same file can be used for any boot source.
|
||||
It will contain the SPL image, fitted with the proper signature recognised by
|
||||
the BROM, and the required checksum. Also it will contain at least U-Boot
|
||||
proper, either wrapped in the legacy U-Boot image format, or in a FIT image.
|
||||
The board's devicetree is also included, either appended to the U-Boot proper
|
||||
image, or contained in the FIT image. If required by the SoC, this FIT file will
|
||||
also include the other firmware images.
|
||||
|
||||
Installing U-Boot
|
||||
-----------------
|
||||
|
||||
Installing on a (micro-) SD card
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
All Allwinner SoCs will try to find a boot image at sector 16 (8KB) of
|
||||
an SD card, connected to the first MMC controller. To transfer the generated
|
||||
image to an SD card, from any Linux device (including the board itself) with
|
||||
an (micro-)SD card reader, type::
|
||||
|
||||
$ sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1k seek=8
|
||||
|
||||
``/dev/sdx`` needs to be replaced with the block device name of the SD card
|
||||
reader. On some machines this could be ``/dev/mmcblkX``.
|
||||
Newer SoCs (starting from the H3 from 2014, and including all ARM64 SoCs),
|
||||
also look at sector 256 (128KB) for the signature (after having checked the
|
||||
8KB location). Installing the firmware there has the advantage of not
|
||||
overlapping with a GPT partition table. Simply replace the "``seek=8``" above
|
||||
with "``seek=128``".
|
||||
|
||||
You can also use an existing (mainline) U-Boot to write to the SD card. Load
|
||||
the generated U-Boot image somewhere into DRAM (via ``ext4load``, ``fatload``,
|
||||
or ``tftpboot``), then write to MMC device 0::
|
||||
|
||||
=> fatload mmc 0:1 $kernel_addr_r u-boot-sunxi-with-spl.bin
|
||||
=> mmc dev 0
|
||||
=> mmc write $kernel_addr_r 0x10 0x7f0
|
||||
|
||||
To use the alternative boot location on newer SoCs::
|
||||
|
||||
=> mmc write $kernel_addr_r 0x100 0x700
|
||||
|
||||
Installing on eMMC (on-board flash memory)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Some boards have a soldered eMMC chip, some other boards have an eMMC socket
|
||||
to receive an optional eMMC module. U-Boot can be installed to those chips,
|
||||
to boot without an SD card inserted. The Boot-ROM can boot either from the
|
||||
regular user data partition, or from one of the separate eMMC boot partitions.
|
||||
U-Boot can be installed either from a running Linux instance on the device,
|
||||
from a running (mainline) U-Boot, or via an adapter for the (removable)
|
||||
eMMC module.
|
||||
|
||||
Installing on an eMMC user data partition from Linux
|
||||
````````````````````````````````````````````````````
|
||||
If you have a running Linux instance on the device, and have somehow copied
|
||||
over the image file to that device, you can write the image directly into the
|
||||
eMMC device from there.
|
||||
Find the name of the block device file first, it is one of the
|
||||
``/dev/mmcblk<X>`` devices. eMMC devices typically also list a
|
||||
``/dev/mmcblk<X>boot0`` partition (see below), this helps you to tell it apart
|
||||
from the SD card device.
|
||||
To install onto the user data partition::
|
||||
|
||||
$ sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/dev/mmcblkX bs=1k seek=8
|
||||
|
||||
Similar to SD cards, the BROM in newer SoCs (H3 and above) also checks
|
||||
sector 256 of an eMMC, so you can use "``seek=128``" as well. Having a GPT
|
||||
on an eMMC device is much more likely than on an SD card, so you should
|
||||
probably stick to the alternative location, or use one of the boot partitions.
|
||||
|
||||
Installing on an eMMC boot partition from Linux
|
||||
```````````````````````````````````````````````
|
||||
In the following examples, ``/dev/mmcblkX`` needs to be replaced with the block
|
||||
device name of the eMMC device. The eMMC device can be recognised by also
|
||||
listing the boot partitions (``/dev/mmcblkXboot0``) in ``/proc/partitions``.
|
||||
|
||||
To allow booting from one of the eMMC boot partitions, this one needs to be
|
||||
enabled first. This only needs to be done once, as this setting is
|
||||
persistent, even though the boot partition can be disabled or changed again
|
||||
any time later::
|
||||
|
||||
# apt-get install mmc-utils
|
||||
# mmc bootbus set single_hs x1 x4 /dev/mmcblkX
|
||||
# mmc bootpart enable 1 1 /dev/mmcblkX
|
||||
|
||||
The first "1" in the last command points to the boot partition number to be
|
||||
used, typically devices offer two boot partitions.
|
||||
|
||||
By default Linux disables write access to the boot partitions, to prevent
|
||||
accidental overwrites. You need to disable the write protection (until the
|
||||
next reboot), then can write the U-Boot image to the *first* sector of the
|
||||
selected boot partition::
|
||||
|
||||
# echo 0 > /sys/block/mmcblkXboot0/force_ro
|
||||
# dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblkXboot0 bs=1k
|
||||
|
||||
Installing on an eMMC user data partition from U-Boot
|
||||
`````````````````````````````````````````````````````
|
||||
You can also write the generated image file to an SD card, boot the device
|
||||
from there, and burn the very same image to the eMMC device from U-Boot.
|
||||
The following commands copy the image from the SD card to the eMMC device::
|
||||
|
||||
=> mmc dev 0
|
||||
=> mmc read $kernel_addr_r 0x10 0x7f0
|
||||
=> mmc dev 1
|
||||
=> mmc write $kernel_addr_r 0x10 0x7f0
|
||||
|
||||
You can also copy an image from the 8K offset of an SD card to the 128K
|
||||
offset of the eMMC (or any combination), just change the "``0x10 0x7f0``" above
|
||||
to "``0x100 0x700``", respectively. Of course the image file can be loaded via
|
||||
any other loading method, including ``fatload``, ``ext4load``, ``tftpboot``.
|
||||
|
||||
Installing on an eMMC boot partition from U-Boot
|
||||
````````````````````````````````````````````````
|
||||
The selected eMMC boot partition needs to be initially enabled first (same
|
||||
as in Linux above), you can do this from U-Boot with::
|
||||
|
||||
=> mmc dev 1
|
||||
=> mmc bootbus 1 1 0 0
|
||||
=> mmc partconf 1 1 1 1
|
||||
|
||||
The first "1" in both commands denotes the MMC device number. The second "1"
|
||||
in the partconf command sets the required ``BOOT_ACK`` option, the last two "1"s
|
||||
selects the active boot partition and the target for the next data access,
|
||||
respectively. So for the next "``mmc write``" command to address one of the boot
|
||||
partitions, the last number must either be "1" or "2", "0" would switch (back)
|
||||
to the normal user data partition.
|
||||
|
||||
Then load the ``u-boot-sunxi-with-spl.bin`` image file into DRAM, either by
|
||||
reading directly from an SD card or eMMC user data partition, or from a
|
||||
file system or TFTP (see above), and transfer it to the boot partition::
|
||||
|
||||
=> tftpboot $kernel_addr_r u-boot-sunxi-with-spl.bin
|
||||
=> mmc write $kernel_addr_r 0 0x7f0
|
||||
|
||||
After that the device should boot from the selected boot partition, which takes
|
||||
precedence over booting from the user data partition.
|
||||
|
||||
Installing on SPI flash
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Some devices have a SPI NOR flash chip soldered on the board. If it is
|
||||
connected to the SPI0 pins on PortC, the BROM can also boot from there.
|
||||
Typically the SPI flash has the lowest boot priority, so SD card and eMMC
|
||||
devices will be considered first.
|
||||
|
||||
Installing on SPI flash from Linux
|
||||
``````````````````````````````````
|
||||
If the devicetree enables and describes the SPI flash device, you can access
|
||||
the SPI flash content from Linux, using the `MTD utils`_::
|
||||
|
||||
# apt-get install mtd-utils
|
||||
# mtdinfo
|
||||
# mtd_debug erase /dev/mtdX 0 0xf0000
|
||||
# mtd_debug write /dev/mtdX 0 0xf0000 u-boot-sunxi-with-spl.bin
|
||||
|
||||
``/dev/mtdX`` needs to be replaced with the respective device name, as listed
|
||||
in the output of ``mtdinfo``.
|
||||
|
||||
Installing on SPI flash from U-Boot
|
||||
```````````````````````````````````
|
||||
If SPI flash driver and command support (``CONFIG_CMD_SF``) is enabled in the
|
||||
U-Boot configuration, the image file can be installed via U-Boot as well::
|
||||
|
||||
=> tftpboot $kernel_addr_r u-boot-sunxi-with-spl.bin
|
||||
=> sf probe
|
||||
=> sf erase 0 +0xf0000
|
||||
=> sf write $kernel_addr_r 0 $filesize
|
||||
|
||||
Installing on SPI flash via USB in FEL mode
|
||||
```````````````````````````````````````````
|
||||
If the device is in FEL mode (see below), the SPI flash can also be written to
|
||||
with the sunxi-fel utility, via an USB(-OTG) cable from any USB host machine::
|
||||
|
||||
$ sunxi-fel spiflash-write 0 u-boot-sunxi-with-spl.bin
|
||||
|
||||
Booting via the USB(-OTG) FEL mode
|
||||
----------------------------------
|
||||
If none of the boot locations checked by the BROM contains a medium or valid
|
||||
signature, the BROM will enter the so-called FEL mode, in which it will
|
||||
listen to commands from a host on the SoC's USB-OTG interface. Those commands
|
||||
allow to read from and write to arbitrary memory locations, also to start
|
||||
execution at any address, which allows to bootstrap a board solely via an
|
||||
USB cable. Some boards feature a "FEL" or "U-Boot" button, which forces
|
||||
FEL mode despite a valid boot location being present. The same can be achieved
|
||||
via a `magic binary`_ on an SD card, which allows to enter FEL mode on any
|
||||
board.
|
||||
|
||||
To use FEL booting, let the board enter FEL mode, via any of the mentioned
|
||||
methods (no boot media, FEL button, SD card with FEL binary), then connect
|
||||
a USB cable to the board's USB OTG port. Some boards (Pine64, TV boxes) don't
|
||||
have a separate OTG port. In this case mostly one of the USB-A ports is
|
||||
connected to USB0, and can be used via a non-standard USB-A to USB-A cable.
|
||||
|
||||
Typically there is no on-board indication of FEL mode, other than a new USB
|
||||
device appearing on the connected host computer. The USB vendor/device ID
|
||||
is 1f3a:efe8. Mostly this will identify as "sunxi SoC OTG connector in
|
||||
FEL/flashing mode", but older distributions might still report "Onda
|
||||
(unverified) V972 tablet in flashing mode".
|
||||
|
||||
The `sunxi_fel`_ tool implements the proprietary BROM protocol, and allows to
|
||||
bootstrap U-Boot by just providing our venerable u-boot-sunxi-with-spl.bin::
|
||||
|
||||
$ sudo apt-get install sunxi-tools
|
||||
$ sunxi-fel uboot u-boot-sunxi-with-spl.bin
|
||||
|
||||
Additional binaries like a kernel, an initial ramdisk or a boot script, can
|
||||
also be uploaded via FEL, check the Wiki's `FEL page`_ for more details.
|
||||
|
||||
.. _`Arm Trusted Firmware-A`: https://www.trustedfirmware.org/projects/tf-a/
|
||||
.. _`docs/plat/allwinner.rst`: https://trustedfirmware-a.readthedocs.io/en/latest/plat/allwinner.html
|
||||
.. _`crust`: https://github.com/crust-firmware/crust
|
||||
.. _`configs/`: https://github.com/crust-firmware/crust/tree/master/configs
|
||||
.. _`crust README`: https://github.com/crust-firmware/crust/blob/master/README.md#building-the-firmware
|
||||
.. _`linux-sunxi`: https://linux-sunxi.org
|
||||
.. _`MTD utils`: http://www.linux-mtd.infradead.org/
|
||||
.. _`magic binary`: https://github.com/linux-sunxi/sunxi-tools/raw/master/bin/fel-sdboot.sunxi
|
||||
.. _`sunxi_fel`: https://github.com/linux-sunxi/sunxi-tools
|
||||
.. _`FEL page`: https://linux-sunxi.org/FEL/USBBoot
|
@ -9,6 +9,7 @@ Board-specific doc
|
||||
actions/index
|
||||
advantech/index
|
||||
AndesTech/index
|
||||
allwinner/index
|
||||
amlogic/index
|
||||
apple/index
|
||||
atmel/index
|
||||
|
@ -265,13 +265,11 @@ This work could be extended in a number of ways:
|
||||
|
||||
- Figure out how to solve the interrupt problem
|
||||
|
||||
- Add more drivers to the application side (e.g. block devices, USB,
|
||||
environment access). This would mostly be an academic exercise as a strong
|
||||
use case is not readily apparent, but it might be fun.
|
||||
- Add more drivers to the application side (e.g.USB, environment access).
|
||||
|
||||
- Avoid turning off boot services in the stub. Instead allow U-Boot to make
|
||||
use of boot services in case it wants to. It is unclear what it might want
|
||||
though.
|
||||
though. It is better to use the app.
|
||||
|
||||
Where is the code?
|
||||
------------------
|
||||
|
@ -24,6 +24,9 @@ struct serial_efi_priv {
|
||||
bool have_key;
|
||||
};
|
||||
|
||||
/* Convert a lower-case character to its ctrl-char equivalent */
|
||||
#define CTL_CH(c) ((c) - 'a' + 1)
|
||||
|
||||
int serial_efi_setbrg(struct udevice *dev, int baudrate)
|
||||
{
|
||||
return 0;
|
||||
@ -49,6 +52,7 @@ static int serial_efi_get_key(struct serial_efi_priv *priv)
|
||||
static int serial_efi_getc(struct udevice *dev)
|
||||
{
|
||||
struct serial_efi_priv *priv = dev_get_priv(dev);
|
||||
char conv_scan[10] = {0, 'p', 'n', 'f', 'b', 'a', 'e', 0, 8};
|
||||
int ret, ch;
|
||||
|
||||
ret = serial_efi_get_key(priv);
|
||||
@ -63,8 +67,11 @@ static int serial_efi_getc(struct udevice *dev)
|
||||
* key scan code of 8. Handle this so that backspace works correctly
|
||||
* in the U-Boot command line.
|
||||
*/
|
||||
if (!ch && priv->key.scan_code == 8)
|
||||
ch = 8;
|
||||
if (!ch && priv->key.scan_code < sizeof(conv_scan)) {
|
||||
ch = conv_scan[priv->key.scan_code];
|
||||
if (ch >= 'a')
|
||||
ch -= 'a' - 1;
|
||||
}
|
||||
debug(" [%x %x %x] ", ch, priv->key.unicode_char, priv->key.scan_code);
|
||||
|
||||
return ch;
|
||||
|
@ -10,8 +10,33 @@
|
||||
|
||||
#undef CONFIG_TPM_TIS_BASE_ADDRESS
|
||||
|
||||
/*
|
||||
* Select the output device: Put an 'x' prefix before one of these to disable it
|
||||
*/
|
||||
|
||||
/*
|
||||
* Video output - can normally continue after exit_boot_services has been
|
||||
* called, since output to the display does not require EFI services at that
|
||||
* point. U-Boot sets up the console memory and does its own drawing.
|
||||
*/
|
||||
#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial\0" \
|
||||
"stdout=vidconsole\0" \
|
||||
"stderr=vidconsole\0"
|
||||
|
||||
/*
|
||||
* Serial output with no console. Run qemu with:
|
||||
*
|
||||
* -display none -serial mon:stdio
|
||||
*
|
||||
* This will hang or fail to output on the console after exit_boot_services is
|
||||
* called.
|
||||
*/
|
||||
#define xCONFIG_STD_DEVICES_SETTINGS "stdin=serial\0" \
|
||||
"stdout=serial\0" \
|
||||
"stderr=serial\0"
|
||||
|
||||
#undef CONFIG_BOOTCOMMAND
|
||||
|
||||
#define CONFIG_BOOTCOMMAND "part list efi 0; fatls efi 0:1"
|
||||
|
||||
#endif
|
||||
|
@ -321,7 +321,7 @@ struct efi_info_hdr {
|
||||
* struct efi_entry_hdr - Header for a table entry
|
||||
*
|
||||
* @type: enum eft_entry_t
|
||||
* @size size of entry bytes excluding header and padding
|
||||
* @size: size of entry bytes excluding header and padding
|
||||
* @addr: address of this entry (0 if it follows the header )
|
||||
* @link: size of entry including header and padding
|
||||
* @spare1: Spare space for expansion
|
||||
@ -400,15 +400,37 @@ static inline struct efi_mem_desc *efi_get_next_mem_desc(
|
||||
return (struct efi_mem_desc *)((ulong)desc + map->desc_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct efi_priv - Information about the environment provided by EFI
|
||||
*
|
||||
* @parent_image: image passed into the EFI app or stub
|
||||
* @sys_table: Pointer to system table
|
||||
* @boot: Pointer to boot-services table
|
||||
* @run: Pointer to runtime-services table
|
||||
*
|
||||
* @use_pool_for_malloc: true if all allocation should go through the EFI 'pool'
|
||||
* methods allocate_pool() and free_pool(); false to use 'pages' methods
|
||||
* allocate_pages() and free_pages()
|
||||
* @ram_base: Base address of RAM (size CONFIG_EFI_RAM_SIZE)
|
||||
* @image_data_type: Type of the loaded image (e.g. EFI_LOADER_CODE)
|
||||
*
|
||||
* @info: Header of the info list, holding info collected by the stub and passed
|
||||
* to U-Boot
|
||||
* @info_size: Size of the info list @info in bytes
|
||||
* @next_hdr: Pointer to where to put the next header when adding to the list
|
||||
*/
|
||||
struct efi_priv {
|
||||
efi_handle_t parent_image;
|
||||
struct efi_device_path *device_path;
|
||||
struct efi_system_table *sys_table;
|
||||
struct efi_boot_services *boot;
|
||||
struct efi_runtime_services *run;
|
||||
|
||||
/* app: */
|
||||
bool use_pool_for_malloc;
|
||||
unsigned long ram_base;
|
||||
unsigned int image_data_type;
|
||||
|
||||
/* stub: */
|
||||
struct efi_info_hdr *info;
|
||||
unsigned int info_size;
|
||||
void *next_hdr;
|
||||
@ -419,10 +441,12 @@ struct efi_priv {
|
||||
*
|
||||
* @handle: handle of the controller on which this driver is installed
|
||||
* @blkio: block io protocol proxied by this driver
|
||||
* @device_path: EFI path to the device
|
||||
*/
|
||||
struct efi_media_plat {
|
||||
efi_handle_t handle;
|
||||
struct efi_block_io *blkio;
|
||||
efi_handle_t handle;
|
||||
struct efi_block_io *blkio;
|
||||
struct efi_device_path *device_path;
|
||||
};
|
||||
|
||||
/* Base address of the EFI image */
|
||||
@ -450,6 +474,27 @@ extern char _binary_u_boot_bin_start[], _binary_u_boot_bin_end[];
|
||||
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \
|
||||
EFI_VARIABLE_APPEND_WRITE)
|
||||
|
||||
/**
|
||||
* efi_get_priv() - Get access to the EFI-private information
|
||||
*
|
||||
* This struct it used by both the stub and the app to record things about the
|
||||
* EFI environment. It is not available in U-Boot proper after the stub has
|
||||
* jumped there. Use efi_info_get() to obtain info in that case.
|
||||
*
|
||||
* Return: pointer to private info
|
||||
*/
|
||||
struct efi_priv *efi_get_priv(void);
|
||||
|
||||
/**
|
||||
* efi_set_priv() - Set up a pointer to the EFI-private information
|
||||
*
|
||||
* This is called in the stub and app to record the location of this
|
||||
* information.
|
||||
*
|
||||
* @priv: New location of private data
|
||||
*/
|
||||
void efi_set_priv(struct efi_priv *priv);
|
||||
|
||||
/**
|
||||
* efi_get_sys_table() - Get access to the main EFI system table
|
||||
*
|
||||
@ -521,6 +566,10 @@ void efi_putc(struct efi_priv *priv, const char ch);
|
||||
/**
|
||||
* efi_info_get() - get an entry from an EFI table
|
||||
*
|
||||
* This function is called from U-Boot proper to read information set up by the
|
||||
* EFI stub. It can only be used when running from the EFI stub, not when U-Boot
|
||||
* is running as an app.
|
||||
*
|
||||
* @type: Entry type to search for
|
||||
* @datap: Returns pointer to entry data
|
||||
* @sizep: Returns pointer to entry size
|
||||
|
@ -2035,4 +2035,19 @@ struct efi_firmware_management_protocol {
|
||||
const u16 *package_version_name);
|
||||
};
|
||||
|
||||
#define EFI_DISK_IO_PROTOCOL_GUID \
|
||||
EFI_GUID(0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, \
|
||||
0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
|
||||
|
||||
struct efi_disk {
|
||||
u64 revision;
|
||||
efi_status_t (EFIAPI *read_disk)(struct efi_disk *this, u32 media_id,
|
||||
u64 offset, efi_uintn_t buffer_size,
|
||||
void *buffer);
|
||||
|
||||
efi_status_t (EFIAPI *write_disk)(struct efi_disk *this, u32 media_id,
|
||||
u64 offset, efi_uintn_t buffer_size,
|
||||
void *buffer);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -14,8 +14,11 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Avoid using CONFIG_EFI_STUB directly as we may boot from other loaders */
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
/*
|
||||
* In case of the EFI app the UEFI firmware provides the low-level
|
||||
* initialisation.
|
||||
*/
|
||||
#ifdef CONFIG_EFI
|
||||
#define ll_boot_init() false
|
||||
#else
|
||||
#include <asm/global_data.h>
|
||||
|
@ -58,6 +58,7 @@
|
||||
#define TEE_SUCCESS 0x00000000
|
||||
#define TEE_ERROR_STORAGE_NOT_AVAILABLE 0xf0100003
|
||||
#define TEE_ERROR_GENERIC 0xffff0000
|
||||
#define TEE_ERROR_EXCESS_DATA 0xffff0004
|
||||
#define TEE_ERROR_BAD_PARAMETERS 0xffff0006
|
||||
#define TEE_ERROR_ITEM_NOT_FOUND 0xffff0008
|
||||
#define TEE_ERROR_NOT_IMPLEMENTED 0xffff0009
|
||||
|
@ -52,7 +52,7 @@ config CC_OPTIMIZE_LIBS_FOR_SPEED
|
||||
|
||||
config CHARSET
|
||||
bool
|
||||
default y if UT_UNICODE || EFI_LOADER || UFS
|
||||
default y if UT_UNICODE || EFI_LOADER || UFS || EFI_APP
|
||||
help
|
||||
Enables support for various conversions between different
|
||||
character sets, such as between unicode representations and
|
||||
|
@ -1,5 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Functions shared by the app and stub
|
||||
*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
*
|
||||
* EFI information obtained here:
|
||||
@ -17,6 +19,33 @@
|
||||
#include <efi.h>
|
||||
#include <efi_api.h>
|
||||
|
||||
static struct efi_priv *global_priv;
|
||||
|
||||
struct efi_priv *efi_get_priv(void)
|
||||
{
|
||||
return global_priv;
|
||||
}
|
||||
|
||||
void efi_set_priv(struct efi_priv *priv)
|
||||
{
|
||||
global_priv = priv;
|
||||
}
|
||||
|
||||
struct efi_system_table *efi_get_sys_table(void)
|
||||
{
|
||||
return global_priv->sys_table;
|
||||
}
|
||||
|
||||
struct efi_boot_services *efi_get_boot(void)
|
||||
{
|
||||
return global_priv->boot;
|
||||
}
|
||||
|
||||
unsigned long efi_get_ram_base(void)
|
||||
{
|
||||
return global_priv->ram_base;
|
||||
}
|
||||
|
||||
/*
|
||||
* Global declaration of gd.
|
||||
*
|
||||
|
@ -21,31 +21,60 @@
|
||||
#include <efi.h>
|
||||
#include <efi_api.h>
|
||||
#include <sysreset.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/root.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static struct efi_priv *global_priv;
|
||||
|
||||
struct efi_system_table *efi_get_sys_table(void)
|
||||
{
|
||||
return global_priv->sys_table;
|
||||
}
|
||||
|
||||
struct efi_boot_services *efi_get_boot(void)
|
||||
{
|
||||
return global_priv->boot;
|
||||
}
|
||||
|
||||
unsigned long efi_get_ram_base(void)
|
||||
{
|
||||
return global_priv->ram_base;
|
||||
}
|
||||
|
||||
int efi_info_get(enum efi_entry_t type, void **datap, int *sizep)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_bind_block() - bind a new block device to an EFI device
|
||||
*
|
||||
* Binds a new top-level EFI_MEDIA device as well as a child block device so
|
||||
* that the block device can be accessed in U-Boot.
|
||||
*
|
||||
* The device can then be accessed using 'part list efi 0', 'fat ls efi 0:1',
|
||||
* for example, just like any other interface type.
|
||||
*
|
||||
* @handle: handle of the controller on which this driver is installed
|
||||
* @blkio: block io protocol proxied by this driver
|
||||
* @device_path: EFI device path structure for this
|
||||
* @len: Length of @device_path in bytes
|
||||
* @devp: Returns the bound device
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int efi_bind_block(efi_handle_t handle, struct efi_block_io *blkio,
|
||||
struct efi_device_path *device_path, int len,
|
||||
struct udevice **devp)
|
||||
{
|
||||
struct efi_media_plat plat;
|
||||
struct udevice *dev;
|
||||
char name[18];
|
||||
int ret;
|
||||
|
||||
plat.handle = handle;
|
||||
plat.blkio = blkio;
|
||||
plat.device_path = malloc(device_path->length);
|
||||
if (!plat.device_path)
|
||||
return log_msg_ret("path", -ENOMEM);
|
||||
memcpy(plat.device_path, device_path, device_path->length);
|
||||
ret = device_bind(dm_root(), DM_DRIVER_GET(efi_media), "efi_media",
|
||||
&plat, ofnode_null(), &dev);
|
||||
if (ret)
|
||||
return log_msg_ret("bind", ret);
|
||||
|
||||
snprintf(name, sizeof(name), "efi_media_%x", dev_seq(dev));
|
||||
device_set_name(dev, name);
|
||||
*devp = dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static efi_status_t setup_memory(struct efi_priv *priv)
|
||||
{
|
||||
struct efi_boot_services *boot = priv->boot;
|
||||
@ -77,13 +106,14 @@ static efi_status_t setup_memory(struct efi_priv *priv)
|
||||
ret = boot->allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
|
||||
priv->image_data_type, pages, &addr);
|
||||
if (ret) {
|
||||
printf("(using pool %lx) ", ret);
|
||||
log_info("(using pool %lx) ", ret);
|
||||
priv->ram_base = (ulong)efi_malloc(priv, CONFIG_EFI_RAM_SIZE,
|
||||
&ret);
|
||||
if (!priv->ram_base)
|
||||
return ret;
|
||||
priv->use_pool_for_malloc = true;
|
||||
} else {
|
||||
log_info("(using allocated RAM address %lx) ", (ulong)addr);
|
||||
priv->ram_base = addr;
|
||||
}
|
||||
gd->ram_size = pages << 12;
|
||||
@ -91,6 +121,14 @@ static efi_status_t setup_memory(struct efi_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* free_memory() - Free memory used by the U-Boot app
|
||||
*
|
||||
* This frees memory allocated in setup_memory(), in preparation for returning
|
||||
* to UEFI. It also zeroes the global_data pointer.
|
||||
*
|
||||
* @priv: Private EFI data
|
||||
*/
|
||||
static void free_memory(struct efi_priv *priv)
|
||||
{
|
||||
struct efi_boot_services *boot = priv->boot;
|
||||
@ -105,6 +143,150 @@ static void free_memory(struct efi_priv *priv)
|
||||
global_data_ptr = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* devpath_is_partition() - Figure out if a device path is a partition
|
||||
*
|
||||
* Checks if a device path refers to a partition on some media device. This
|
||||
* works by checking for a valid partition number in a hard-driver media device
|
||||
* as the final component of the device path.
|
||||
*
|
||||
* @path: device path
|
||||
* Return: true if a partition, false if not
|
||||
* (e.g. it might be media which contains partitions)
|
||||
*/
|
||||
static bool devpath_is_partition(const struct efi_device_path *path)
|
||||
{
|
||||
const struct efi_device_path *p;
|
||||
bool was_part;
|
||||
|
||||
for (p = path; p->type != DEVICE_PATH_TYPE_END;
|
||||
p = (void *)p + p->length) {
|
||||
was_part = false;
|
||||
if (p->type == DEVICE_PATH_TYPE_MEDIA_DEVICE &&
|
||||
p->sub_type == DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH) {
|
||||
struct efi_device_path_hard_drive_path *hd =
|
||||
(void *)path;
|
||||
|
||||
if (hd->partition_number)
|
||||
was_part = true;
|
||||
}
|
||||
}
|
||||
|
||||
return was_part;
|
||||
}
|
||||
|
||||
/**
|
||||
* setup_block() - Find all block devices and setup EFI devices for them
|
||||
*
|
||||
* Partitions are ignored, since U-Boot has partition handling. Errors with
|
||||
* particular devices produce a warning but execution continues to try to
|
||||
* find others.
|
||||
*
|
||||
* Return: 0 if found, -ENOSYS if there is no boot-services table, -ENOTSUPP
|
||||
* if a required protocol is not supported
|
||||
*/
|
||||
static int setup_block(void)
|
||||
{
|
||||
efi_guid_t efi_blkio_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
|
||||
efi_guid_t efi_devpath_guid = EFI_DEVICE_PATH_PROTOCOL_GUID;
|
||||
efi_guid_t efi_pathutil_guid = EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID;
|
||||
efi_guid_t efi_pathtext_guid = EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
|
||||
struct efi_boot_services *boot = efi_get_boot();
|
||||
struct efi_device_path_utilities_protocol *util;
|
||||
struct efi_device_path_to_text_protocol *text;
|
||||
struct efi_device_path *path;
|
||||
struct efi_block_io *blkio;
|
||||
efi_uintn_t num_handles;
|
||||
efi_handle_t *handle;
|
||||
int ret, i;
|
||||
|
||||
if (!boot)
|
||||
return log_msg_ret("sys", -ENOSYS);
|
||||
|
||||
/* Find all devices which support the block I/O protocol */
|
||||
ret = boot->locate_handle_buffer(BY_PROTOCOL, &efi_blkio_guid, NULL,
|
||||
&num_handles, &handle);
|
||||
if (ret)
|
||||
return log_msg_ret("loc", -ENOTSUPP);
|
||||
log_debug("Found %d handles:\n", (int)num_handles);
|
||||
|
||||
/* We need to look up the path size and convert it to text */
|
||||
ret = boot->locate_protocol(&efi_pathutil_guid, NULL, (void **)&util);
|
||||
if (ret)
|
||||
return log_msg_ret("util", -ENOTSUPP);
|
||||
ret = boot->locate_protocol(&efi_pathtext_guid, NULL, (void **)&text);
|
||||
if (ret)
|
||||
return log_msg_ret("text", -ENOTSUPP);
|
||||
|
||||
for (i = 0; i < num_handles; i++) {
|
||||
struct udevice *dev;
|
||||
const u16 *name;
|
||||
bool is_part;
|
||||
int len;
|
||||
|
||||
ret = boot->handle_protocol(handle[i], &efi_devpath_guid,
|
||||
(void **)&path);
|
||||
if (ret) {
|
||||
log_warning("- devpath %d failed (ret=%d)\n", i, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = boot->handle_protocol(handle[i], &efi_blkio_guid,
|
||||
(void **)&blkio);
|
||||
if (ret) {
|
||||
log_warning("- blkio %d failed (ret=%d)\n", i, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
name = text->convert_device_path_to_text(path, true, false);
|
||||
is_part = devpath_is_partition(path);
|
||||
|
||||
if (!is_part) {
|
||||
len = util->get_device_path_size(path);
|
||||
ret = efi_bind_block(handle[i], blkio, path, len, &dev);
|
||||
if (ret) {
|
||||
log_warning("- blkio bind %d failed (ret=%d)\n",
|
||||
i, ret);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
dev = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Show the device name if we created one. Otherwise indicate
|
||||
* that it is a partition.
|
||||
*/
|
||||
printf("%2d: %-12s %ls\n", i, dev ? dev->name : "<partition>",
|
||||
name);
|
||||
}
|
||||
boot->free_pool(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_scan_other() - Scan for UEFI devices that should be available to U-Boot
|
||||
*
|
||||
* This sets up block devices within U-Boot for those found in UEFI. With this,
|
||||
* U-Boot can access those devices
|
||||
*
|
||||
* @pre_reloc_only: true to only bind pre-relocation devices (ignored)
|
||||
* Returns: 0 on success, -ve on error
|
||||
*/
|
||||
int dm_scan_other(bool pre_reloc_only)
|
||||
{
|
||||
if (gd->flags & GD_FLG_RELOC) {
|
||||
int ret;
|
||||
|
||||
ret = setup_block();
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_main() - Start an EFI image
|
||||
*
|
||||
@ -119,9 +301,12 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
|
||||
efi_status_t ret;
|
||||
|
||||
/* Set up access to EFI data structures */
|
||||
efi_init(priv, "App", image, sys_table);
|
||||
|
||||
global_priv = priv;
|
||||
ret = efi_init(priv, "App", image, sys_table);
|
||||
if (ret) {
|
||||
printf("Failed to set up U-Boot: err=%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
efi_set_priv(priv);
|
||||
|
||||
/*
|
||||
* Set up the EFI debug UART so that printf() works. This is
|
||||
@ -147,7 +332,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
|
||||
|
||||
static void efi_exit(void)
|
||||
{
|
||||
struct efi_priv *priv = global_priv;
|
||||
struct efi_priv *priv = efi_get_priv();
|
||||
|
||||
free_memory(priv);
|
||||
printf("U-Boot EFI exiting\n");
|
||||
|
@ -31,7 +31,6 @@
|
||||
#error "This file needs to be ported for use on architectures"
|
||||
#endif
|
||||
|
||||
static struct efi_priv *global_priv;
|
||||
static bool use_uart;
|
||||
|
||||
struct __packed desctab_info {
|
||||
@ -63,6 +62,8 @@ void _debug_uart_init(void)
|
||||
|
||||
void putc(const char ch)
|
||||
{
|
||||
struct efi_priv *priv = efi_get_priv();
|
||||
|
||||
if (ch == '\n')
|
||||
putc('\r');
|
||||
|
||||
@ -73,7 +74,7 @@ void putc(const char ch)
|
||||
;
|
||||
outb(ch, (ulong)&com_port->thr);
|
||||
} else {
|
||||
efi_putc(global_priv, ch);
|
||||
efi_putc(priv, ch);
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,6 +226,22 @@ static int get_codeseg32(void)
|
||||
return cs32;
|
||||
}
|
||||
|
||||
/**
|
||||
* setup_info_table() - sets up a table containing information from EFI
|
||||
*
|
||||
* We must call exit_boot_services() before jumping out of the stub into U-Boot
|
||||
* proper, so that U-Boot has full control of peripherals, memory, etc.
|
||||
*
|
||||
* Once we do this, we cannot call any boot-services functions so we must find
|
||||
* out everything we need to before doing that.
|
||||
*
|
||||
* Set up a struct efi_info_hdr table which can hold various records (e.g.
|
||||
* struct efi_entry_memmap) with information obtained from EFI.
|
||||
*
|
||||
* @priv: Pointer to our private information which contains the list
|
||||
* @size: Size of the table to allocate
|
||||
* Return: 0 if OK, non-zero on error
|
||||
*/
|
||||
static int setup_info_table(struct efi_priv *priv, int size)
|
||||
{
|
||||
struct efi_info_hdr *info;
|
||||
@ -248,6 +265,19 @@ static int setup_info_table(struct efi_priv *priv, int size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_entry_addr() - Add a new entry to the efi_info list
|
||||
*
|
||||
* This adds an entry, consisting of a tag and two lots of data. This avoids the
|
||||
* caller having to coalesce the data first
|
||||
*
|
||||
* @priv: Pointer to our private information which contains the list
|
||||
* @type: Type of the entry to add
|
||||
* @ptr1: Pointer to first data block to add
|
||||
* @size1: Size of first data block in bytes (can be 0)
|
||||
* @ptr2: Pointer to second data block to add
|
||||
* @size2: Size of second data block in bytes (can be 0)
|
||||
*/
|
||||
static void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type,
|
||||
void *ptr1, int size1, void *ptr2, int size2)
|
||||
{
|
||||
@ -291,7 +321,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
|
||||
puts(" efi_init() failed\n");
|
||||
return ret;
|
||||
}
|
||||
global_priv = priv;
|
||||
efi_set_priv(priv);
|
||||
|
||||
cs32 = get_codeseg32();
|
||||
if (cs32 < 0)
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <malloc.h>
|
||||
#include <mm_communication.h>
|
||||
|
||||
#define OPTEE_PAGE_SIZE BIT(12)
|
||||
extern struct efi_var_file __efi_runtime_data *efi_var_buf;
|
||||
static efi_uintn_t max_buffer_size; /* comm + var + func + data */
|
||||
static efi_uintn_t max_payload_size; /* func + data */
|
||||
@ -114,7 +113,11 @@ static efi_status_t optee_mm_communicate(void *comm_buf, ulong dsize)
|
||||
rc = tee_invoke_func(conn.tee, &arg, 2, param);
|
||||
tee_shm_free(shm);
|
||||
tee_close_session(conn.tee, conn.session);
|
||||
if (rc || arg.ret != TEE_SUCCESS)
|
||||
if (rc)
|
||||
return EFI_DEVICE_ERROR;
|
||||
if (arg.ret == TEE_ERROR_EXCESS_DATA)
|
||||
log_err("Variable payload too large\n");
|
||||
if (arg.ret != TEE_SUCCESS)
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
switch (param[1].u.value.a) {
|
||||
@ -255,15 +258,6 @@ efi_status_t EFIAPI get_max_payload(efi_uintn_t *size)
|
||||
goto out;
|
||||
}
|
||||
*size = var_payload->size;
|
||||
/*
|
||||
* Although the max payload is configurable on StMM, we only share a
|
||||
* single page from OP-TEE for the non-secure buffer used to communicate
|
||||
* with StMM. Since OP-TEE will reject to map anything bigger than that,
|
||||
* make sure we are in bounds.
|
||||
*/
|
||||
if (*size > OPTEE_PAGE_SIZE)
|
||||
*size = OPTEE_PAGE_SIZE - MM_COMMUNICATE_HEADER_SIZE -
|
||||
MM_VARIABLE_COMMUNICATE_SIZE;
|
||||
/*
|
||||
* There seems to be a bug in EDK2 miscalculating the boundaries and
|
||||
* size checks, so deduct 2 more bytes to fulfill this requirement. Fix
|
||||
|
@ -276,9 +276,8 @@ static char *string(char *buf, char *end, char *s, int field_width,
|
||||
}
|
||||
|
||||
/* U-Boot uses UTF-16 strings in the EFI context only. */
|
||||
#if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD)
|
||||
static char *string16(char *buf, char *end, u16 *s, int field_width,
|
||||
int precision, int flags)
|
||||
static __maybe_unused char *string16(char *buf, char *end, u16 *s,
|
||||
int field_width, int precision, int flags)
|
||||
{
|
||||
const u16 *str = s ? s : L"<NULL>";
|
||||
ssize_t i, len = utf16_strnlen(str, precision);
|
||||
@ -317,7 +316,6 @@ static char *device_path_string(char *buf, char *end, void *dp, int field_width,
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width,
|
||||
int precision, int flags)
|
||||
@ -616,7 +614,8 @@ repeat:
|
||||
|
||||
case 's':
|
||||
/* U-Boot uses UTF-16 strings in the EFI context only. */
|
||||
#if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD)
|
||||
#if (CONFIG_IS_ENABLED(EFI_LOADER) || CONFIG_IS_ENABLED(EFI_APP)) && \
|
||||
!defined(API_BUILD)
|
||||
if (qualifier == 'l') {
|
||||
str = string16(str, end, va_arg(args, u16 *),
|
||||
field_width, precision, flags);
|
||||
|
Loading…
Reference in New Issue
Block a user