[U-Boot] [PATCH V2 1/2] ARM: tegra: reserve unmapped RAM so EFI doesn't use it

Stephen Warren swarren at wwwdotorg.org
Thu Aug 30 15:45:58 UTC 2018


On 08/30/2018 12:43 AM, Alexander Graf wrote:
> 
> 
> On 29.08.18 23:52, Heinrich Schuchardt wrote:
>> On 08/29/2018 11:34 PM, Stephen Warren wrote:
>>> From: Stephen Warren <swarren at nvidia.com>
>>>
>>> Tegra U-Boot ensures that board_get_usable_ram_top() never returns a value
>>> over 4GB, since some peripherals can't access such addresses. However, on
>>> systems with more than 2GB of RAM, RAM bank 1 does describe this extra
>>> RAM, so that Linux (or whatever OS) can use it, subject to DMA
>>> limitations. Since board_get_usable_ram_top() points at the top of RAM
>>> bank 0, the memory locations describes by RAM bank 1 are not mapped by
>>> U-Boot's MMU configuration, and so cannot be used for anything.
>>>
>>> For some completely inexplicable reason, U-Boot's EFI support ignores the
>>> value returned by board_get_usable_ram_top(), and EFI memory allocation
>>> routines will return values above U-Boot's RAM top. This causes U-Boot to
>>> crash when it accesses that RAM, since it isn't mapped by the MMU. One
>>> use-case where this happens is TFTP download of a file on Jetson TX1
>>> (p2371-2180).
>>>
>>> This change explicitly tells the EFI code that this extra RAM should not
>>> be used, thus avoiding the crash.
>>>
>>> A previous attempt to make EFI honor board_get_usable_ram_top() was
>>> rejected. So, this patch will need to be replicated for any board that
>>> implements board_get_usable_ram_top().
>>>
>>> Fixes: aa909462d018 ("efi_loader: efi_allocate_pages is too restrictive")
>>> Signed-off-by: Stephen Warren <swarren at nvidia.com>
>>> ---
>>> v2:
>>> - Don't hard-code EFI page size.
>>> - Register RAM as a boot services data rather than reserved.
>>> ---
>>>   arch/arm/mach-tegra/board2.c | 14 ++++++++++++++
>>>   1 file changed, 14 insertions(+)
>>>
>>> diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c
>>> index 421a71b3014d..f893966140a1 100644
>>> --- a/arch/arm/mach-tegra/board2.c
>>> +++ b/arch/arm/mach-tegra/board2.c
>>> @@ -6,6 +6,7 @@
>>>   
>>>   #include <common.h>
>>>   #include <dm.h>
>>> +#include <efi_loader.h>
>>>   #include <errno.h>
>>>   #include <ns16550.h>
>>>   #include <usb.h>
>>> @@ -210,6 +211,19 @@ int board_early_init_f(void)
>>>   
>>>   int board_late_init(void)
>>>   {
>>> +#ifdef CONFIG_EFI_LOADER
>>> +	if (gd->bd->bi_dram[1].start) {
>>> +		/*
>>> +		 * Only bank 0 is below board_get_usable_ram_top(), so all of
>>> +		 * bank 1 is not mapped by the U-Boot MMU configuration, and so
>>> +		 * we must prevent EFI from using it.
>>> +		 */
>>> +		efi_add_memory_map(gd->bd->bi_dram[1].start,
>>> +				   gd->bd->bi_dram[1].size / EFI_PAGE_SIZE,
>>
>> Are you sure all boards do the division without library function?
>> This is why I prefer >> EFI_PAGE_SHIFT.
>>
>> Compiling SPL fails for harmony_defconfig.
>>
>>    LD      spl/common/spl/built-in.o
>> arch/arm/mach-tegra/board2.c: In function ‘board_late_init’:
>> arch/arm/mach-tegra/board2.c:221:3: warning: implicit declaration of
>> function ‘efi_add_memory_map’; did you mean ‘fdt_add_mem_rsv’?
>> [-Wimplicit-function-declaration]
>>     efi_add_memory_map(gd->bd->bi_dram[1].start,
>>     ^~~~~~~~~~~~~~~~~~
>>     fdt_add_mem_rsv

Oh, I figured that warning were errors and only checked that Jenkins 
passed, not for warnings in the logs.

> I think that means you want #if CONFIG_IS_ENABLED(EFI_LOADER) because
> the file is also compiled for SPL.

That does work, but include/efi_loader.h uses the following, so I think 
it makes sense to use the exact same ifdef in the source code:

#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)

Or, should I update the header to use CONFIG_IS_ENABLED too (and hope 
that won't break any other boards).


More information about the U-Boot mailing list