mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-20 11:55:03 +00:00
Merge patch series "bloblist: refactor xferlist and bloblist"
Tom Rini <trini@konsulko.com> says: This small series separates "bloblist" and "standard passage" to allow for these similar concepts to explore solutions to problems without introduces breaking changes to the other. Link: https://lore.kernel.org/r/20250220000223.1044376-1-raymond.mao@linaro.org
This commit is contained in:
commit
c33ccc8725
7 changed files with 87 additions and 65 deletions
|
@ -8,18 +8,16 @@
|
||||||
#include <bloblist.h>
|
#include <bloblist.h>
|
||||||
#include "xferlist.h"
|
#include "xferlist.h"
|
||||||
|
|
||||||
int xferlist_from_boot_arg(ulong addr, ulong size)
|
int xferlist_from_boot_arg(ulong *addr)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = bloblist_check(saved_args[3], size);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = bloblist_check_reg_conv(saved_args[0], saved_args[2],
|
ret = bloblist_check_reg_conv(saved_args[0], saved_args[2],
|
||||||
saved_args[1]);
|
saved_args[1], saved_args[3]);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return bloblist_reloc((void *)addr, size);
|
*addr = bloblist_get_base();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1066,11 +1066,15 @@ config BLOBLIST_ALLOC
|
||||||
specify a fixed address on systems where this is unknown or can
|
specify a fixed address on systems where this is unknown or can
|
||||||
change at runtime.
|
change at runtime.
|
||||||
|
|
||||||
config BLOBLIST_PASSAGE
|
config BLOBLIST_PASSAGE_MANDATORY
|
||||||
bool "Use bloblist in-place"
|
bool "Use bloblist in-place mandatorily"
|
||||||
help
|
help
|
||||||
Use a bloblist in the incoming standard passage. The size is detected
|
By default U-Boot will use a bloblist in the incoming standard passage.
|
||||||
automatically so CONFIG_BLOBLIST_SIZE can be 0.
|
This option controls whether U-Boot tries to load a static bloblist or
|
||||||
|
allocate one if a valid incoming bloblist does not exist.
|
||||||
|
Select this option to mark incoming standard passage as mandatory and
|
||||||
|
U-Boot will report an error when a valid incoming bloblist does not
|
||||||
|
exist.
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
@ -1086,7 +1090,7 @@ config BLOBLIST_ADDR
|
||||||
|
|
||||||
config BLOBLIST_SIZE
|
config BLOBLIST_SIZE
|
||||||
hex "Size of bloblist"
|
hex "Size of bloblist"
|
||||||
default 0x0 if BLOBLIST_PASSAGE
|
default 0x0 if BLOBLIST_PASSAGE_MANDATORY
|
||||||
default 0x400
|
default 0x400
|
||||||
help
|
help
|
||||||
Sets the size of the bloblist in bytes. This must include all
|
Sets the size of the bloblist in bytes. This must include all
|
||||||
|
|
|
@ -505,8 +505,7 @@ int bloblist_reloc(void *to, uint to_size)
|
||||||
/*
|
/*
|
||||||
* Weak default function for getting bloblist from boot args.
|
* Weak default function for getting bloblist from boot args.
|
||||||
*/
|
*/
|
||||||
int __weak xferlist_from_boot_arg(ulong __always_unused addr,
|
int __weak xferlist_from_boot_arg(ulong __always_unused *addr)
|
||||||
ulong __always_unused size)
|
|
||||||
{
|
{
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
@ -514,29 +513,37 @@ int __weak xferlist_from_boot_arg(ulong __always_unused addr,
|
||||||
int bloblist_init(void)
|
int bloblist_init(void)
|
||||||
{
|
{
|
||||||
bool fixed = IS_ENABLED(CONFIG_BLOBLIST_FIXED);
|
bool fixed = IS_ENABLED(CONFIG_BLOBLIST_FIXED);
|
||||||
int ret = -ENOENT;
|
int ret = 0;
|
||||||
ulong addr = 0, size;
|
ulong addr = 0, size;
|
||||||
|
|
||||||
|
/* Check if a valid transfer list passed in */
|
||||||
|
if (!xferlist_from_boot_arg(&addr)) {
|
||||||
|
size = bloblist_get_total_size();
|
||||||
|
} else {
|
||||||
/*
|
/*
|
||||||
* If U-Boot is not in the first phase, an existing bloblist must be
|
* If U-Boot is not in the first phase, an existing bloblist must
|
||||||
* at a fixed address.
|
* be at a fixed address.
|
||||||
*/
|
*/
|
||||||
bool from_addr = fixed && !xpl_is_first_phase();
|
bool from_addr = fixed && !xpl_is_first_phase();
|
||||||
if (xpl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST))
|
|
||||||
|
/*
|
||||||
|
* If Firmware Handoff is mandatory but no transfer list is
|
||||||
|
* observed, report it as an error.
|
||||||
|
*/
|
||||||
|
if (IS_ENABLED(CONFIG_BLOBLIST_PASSAGE_MANDATORY))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
ret = -ENOENT;
|
||||||
|
|
||||||
|
if (xpl_prev_phase() == PHASE_TPL &&
|
||||||
|
!IS_ENABLED(CONFIG_TPL_BLOBLIST))
|
||||||
from_addr = false;
|
from_addr = false;
|
||||||
if (fixed)
|
if (fixed)
|
||||||
addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED,
|
addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED,
|
||||||
CONFIG_BLOBLIST_ADDR);
|
CONFIG_BLOBLIST_ADDR);
|
||||||
size = CONFIG_BLOBLIST_SIZE;
|
size = CONFIG_BLOBLIST_SIZE;
|
||||||
|
|
||||||
|
if (from_addr)
|
||||||
/*
|
|
||||||
* If the current boot stage is the first phase of U-Boot, then an
|
|
||||||
* architecture-specific routine should be used to handle the bloblist
|
|
||||||
* passed from the previous boot loader
|
|
||||||
*/
|
|
||||||
if (xpl_is_first_phase() && !IS_ENABLED(CONFIG_BLOBLIST_ALLOC))
|
|
||||||
ret = xferlist_from_boot_arg(addr, size);
|
|
||||||
else if (from_addr)
|
|
||||||
ret = bloblist_check(addr, size);
|
ret = bloblist_check(addr, size);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -545,6 +552,7 @@ int bloblist_init(void)
|
||||||
else
|
else
|
||||||
/* Get the real size */
|
/* Get the real size */
|
||||||
size = gd->bloblist->total_size;
|
size = gd->bloblist->total_size;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/*
|
/*
|
||||||
|
@ -569,6 +577,7 @@ int bloblist_init(void)
|
||||||
log_debug("Found existing bloblist size %lx at %lx\n", size,
|
log_debug("Found existing bloblist size %lx at %lx\n", size,
|
||||||
addr);
|
addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return log_msg_ret("ini", ret);
|
return log_msg_ret("ini", ret);
|
||||||
gd->flags |= GD_FLG_BLOBLIST_READY;
|
gd->flags |= GD_FLG_BLOBLIST_READY;
|
||||||
|
@ -589,10 +598,11 @@ int bloblist_maybe_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig)
|
int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig, ulong xlist)
|
||||||
{
|
{
|
||||||
u64 version = BLOBLIST_REGCONV_VER;
|
u64 version = BLOBLIST_REGCONV_VER;
|
||||||
ulong sigval;
|
ulong sigval;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if ((IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_SPL_BUILD)) ||
|
if ((IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_SPL_BUILD)) ||
|
||||||
(IS_ENABLED(CONFIG_SPL_64BIT) && IS_ENABLED(CONFIG_SPL_BUILD))) {
|
(IS_ENABLED(CONFIG_SPL_64BIT) && IS_ENABLED(CONFIG_SPL_BUILD))) {
|
||||||
|
@ -603,8 +613,14 @@ int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig)
|
||||||
((version & BLOBLIST_REGCONV_MASK) << BLOBLIST_REGCONV_SHIFT_32));
|
((version & BLOBLIST_REGCONV_MASK) << BLOBLIST_REGCONV_SHIFT_32));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rzero || rsig != sigval ||
|
if (rzero || rsig != sigval)
|
||||||
rfdt != (ulong)bloblist_find(BLOBLISTT_CONTROL_FDT, 0)) {
|
return -EIO;
|
||||||
|
|
||||||
|
ret = bloblist_check(xlist, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (rfdt != (ulong)bloblist_find(BLOBLISTT_CONTROL_FDT, 0)) {
|
||||||
gd->bloblist = NULL; /* Reset the gd bloblist pointer */
|
gd->bloblist = NULL; /* Reset the gd bloblist pointer */
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
|
@ -624,11 +624,14 @@ static int reserve_stacks(void)
|
||||||
static int reserve_bloblist(void)
|
static int reserve_bloblist(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BLOBLIST
|
#ifdef CONFIG_BLOBLIST
|
||||||
|
ulong size = bloblist_get_total_size();
|
||||||
|
|
||||||
|
if (size < CONFIG_BLOBLIST_SIZE_RELOC)
|
||||||
|
size = CONFIG_BLOBLIST_SIZE_RELOC;
|
||||||
|
|
||||||
/* Align to a 4KB boundary for easier reading of addresses */
|
/* Align to a 4KB boundary for easier reading of addresses */
|
||||||
gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp -
|
gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp - size, 0x1000);
|
||||||
CONFIG_BLOBLIST_SIZE_RELOC, 0x1000);
|
gd->boardf->new_bloblist = map_sysmem(gd->start_addr_sp, size);
|
||||||
gd->boardf->new_bloblist = map_sysmem(gd->start_addr_sp,
|
|
||||||
CONFIG_BLOBLIST_SIZE_RELOC);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -698,11 +701,14 @@ static int reloc_bloblist(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (gd->boardf->new_bloblist) {
|
if (gd->boardf->new_bloblist) {
|
||||||
debug("Copying bloblist from %p to %p, size %x\n",
|
ulong size = bloblist_get_total_size();
|
||||||
gd->bloblist, gd->boardf->new_bloblist,
|
|
||||||
gd->bloblist->total_size);
|
if (size < CONFIG_BLOBLIST_SIZE_RELOC)
|
||||||
return bloblist_reloc(gd->boardf->new_bloblist,
|
size = CONFIG_BLOBLIST_SIZE_RELOC;
|
||||||
CONFIG_BLOBLIST_SIZE_RELOC);
|
|
||||||
|
debug("Copying bloblist from %p to %p, size %lx\n",
|
||||||
|
gd->bloblist, gd->boardf->new_bloblist, size);
|
||||||
|
return bloblist_reloc(gd->boardf->new_bloblist, size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <configs/vexpress_fvp_defconfig>
|
#include <configs/vexpress_fvp_defconfig>
|
||||||
|
|
||||||
CONFIG_BLOBLIST=y
|
CONFIG_BLOBLIST=y
|
||||||
CONFIG_BLOBLIST_PASSAGE=y
|
CONFIG_BLOBLIST_PASSAGE_MANDATORY=y
|
||||||
CONFIG_BLOBLIST_SIZE_RELOC=0x10000
|
CONFIG_BLOBLIST_SIZE_RELOC=0x10000
|
||||||
|
|
|
@ -53,8 +53,8 @@ predefined bloblist at a specified address, dynamically allocating memory for a
|
||||||
bloblist, or utilizing a standard passage-provided bloblist with automatic size
|
bloblist, or utilizing a standard passage-provided bloblist with automatic size
|
||||||
detection.
|
detection.
|
||||||
|
|
||||||
By default, ``vexpress_fvp_bloblist_defconfig`` uses the standard passage method
|
By default, ``vexpress_fvp_bloblist_defconfig`` uses the standard passage method mandatorily
|
||||||
(CONFIG_BLOBLIST_PASSAGE) because TF-A provides a Transfer List in non-secure
|
(CONFIG_BLOBLIST_PASSAGE_MANDATORY) because TF-A provides a Transfer List in non-secure
|
||||||
memory that U-Boot can utilise. This Bloblist, which is referred to as a Transfer List in
|
memory that U-Boot can utilise. This Bloblist, which is referred to as a Transfer List in
|
||||||
TF-A, contains all necessary data for the handoff process, including DT and ACPI
|
TF-A, contains all necessary data for the handoff process, including DT and ACPI
|
||||||
tables.
|
tables.
|
||||||
|
|
|
@ -467,9 +467,8 @@ int bloblist_reloc(void *to, uint to_size);
|
||||||
* If CONFIG_BLOBLIST_ALLOC is selected, it allocates memory for a bloblist of
|
* If CONFIG_BLOBLIST_ALLOC is selected, it allocates memory for a bloblist of
|
||||||
* size CONFIG_BLOBLIST_SIZE.
|
* size CONFIG_BLOBLIST_SIZE.
|
||||||
*
|
*
|
||||||
* If CONFIG_BLOBLIST_PASSAGE is selected, it uses the bloblist in the incoming
|
* If CONFIG_BLOBLIST_PASSAGE_MANDATORY is selected, bloblist in the incoming
|
||||||
* standard passage. The size is detected automatically so CONFIG_BLOBLIST_SIZE
|
* standard passage is mandatorily required.
|
||||||
* can be 0.
|
|
||||||
*
|
*
|
||||||
* Sets GD_FLG_BLOBLIST_READY in global_data flags on success
|
* Sets GD_FLG_BLOBLIST_READY in global_data flags on success
|
||||||
*
|
*
|
||||||
|
@ -501,19 +500,18 @@ static inline int bloblist_maybe_init(void)
|
||||||
* @rfdt: Register that holds the FDT base address.
|
* @rfdt: Register that holds the FDT base address.
|
||||||
* @rzero: Register that must be zero.
|
* @rzero: Register that must be zero.
|
||||||
* @rsig: Register that holds signature and register conventions version.
|
* @rsig: Register that holds signature and register conventions version.
|
||||||
|
* @xlist: Register that holds the transfer list.
|
||||||
* Return: 0 if OK, -EIO if the bloblist is not compliant to the register
|
* Return: 0 if OK, -EIO if the bloblist is not compliant to the register
|
||||||
* conventions.
|
* conventions.
|
||||||
*/
|
*/
|
||||||
int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig);
|
int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig, ulong xlist);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xferlist_from_boot_arg() - Get bloblist from the boot args and relocate it
|
* xferlist_from_boot_arg() - Get bloblist from the boot args.
|
||||||
* to the specified address.
|
|
||||||
*
|
*
|
||||||
* @addr: Address for the bloblist
|
* @addr: Address of the bloblist
|
||||||
* @size: Size of space reserved for the bloblist
|
|
||||||
* Return: 0 if OK, else on error
|
* Return: 0 if OK, else on error
|
||||||
*/
|
*/
|
||||||
int xferlist_from_boot_arg(ulong addr, ulong size);
|
int xferlist_from_boot_arg(ulong *addr);
|
||||||
|
|
||||||
#endif /* __BLOBLIST_H */
|
#endif /* __BLOBLIST_H */
|
||||||
|
|
Loading…
Add table
Reference in a new issue