[U-Boot] [PATCH 4/9] efi_loader: Add boot time services
Leif Lindholm
leif.lindholm at linaro.org
Fri Jan 15 14:02:01 CET 2016
On Fri, Jan 15, 2016 at 01:13:15AM +0100, Alexander Graf wrote:
> On 26.12.15 19:09, Leif Lindholm wrote:
> >> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> >> new file mode 100644
> >> index 0000000..ed95962
> >> --- /dev/null
> >> +++ b/lib/efi_loader/efi_boottime.c
> >> @@ -0,0 +1,838 @@
> >> +/*
> >> + * EFI application boot time services
> >> + *
...
> >> +
> >> +static unsigned long efi_raise_tpl(unsigned long new_tpl)
> >> +{
> >> + EFI_ENTRY("0x%lx", new_tpl);
> >> + return EFI_EXIT(efi_unsupported(__func__));
> >
> > "Unlike other UEFI interface functions, EFI_BOOT_SERVICES.RaiseTPL()
> > does not return a status code. Instead, it returns the previous task
> > priority level, which is to be restored later with a matching call to
> > RestoreTPL()."
>
> Since we don't do TPLs (or IRQs for that matter), I'll just return 0 here.
Sure.
> >> +}
> >> +
> >> +static void efi_restore_tpl(unsigned long old_tpl)
> >> +{
> >> + EFI_ENTRY("0x%lx", old_tpl);
> >> + EFI_EXIT(efi_unsupported(__func__));
> >
> > (void function, nothing to return)
>
> Yes, hence no return. EFI_EXIT deals with the gd swapping and
> efi_unsupported() gives me a nice debug message :).
Ah, ok.
> >> +static efi_status_t efi_allocate_pages(int type, int memory_type,
> >> + unsigned long pages, uint64_t *memory)
> >> +{
> >> + u64 len = pages << 12;
> >> + efi_status_t r = EFI_SUCCESS;
> >> +
> >> + EFI_ENTRY("%d, %d, 0x%lx, %p", type, memory_type, pages, memory);
> >> +
> >> + switch (type) {
> >> + case 0:
> >> + /* Any page means we can go to efi_alloc */
> >> + *memory = (unsigned long)efi_alloc(len, memory_type);
> >> + break;
> >> + case 1:
> >> + /* Max address */
> >> + if (gd->relocaddr < *memory) {
> >> + *memory = (unsigned long)efi_alloc(len, memory_type);
> >> + break;
> >> + }
> >> + r = EFI_UNSUPPORTED;
> >
> > EFI_OUT_OF_RESOURCES/EFI_NOT_FOUND?
> >
> >> + break;
> >> + case 2:
> >> + /* Exact address, grant it. The addr is already in *memory. */
> >
> > As far as I can tell, this is why GRUB works. Because it filters
> > through the memory map manually, requesting to allocate its heap at an
> > exact address in a region of free memory in the UEFI memory map.
>
> Yes.
>
> > The key is that EFI_LOADER_MEMORY will be used by applications loaded
> > as well as by U-Boot to load applications into. A simple example where
> > this could be problematic would be a large(ish) initrd loaded via initrd=
> > on kernel (stub loader) command line rather than via GRUB.
>
> Ah, so here the 128MB limit on the LOADER_DATA section might bite us?
Yeah, I think so.
> >> + runtime_start = (ulong)&__efi_runtime_start & ~0xfffULL;
> >> + runtime_end = ((ulong)&__efi_runtime_stop + 0xfff) & ~0xfffULL;
> >> + runtime_len_pages = (runtime_end - runtime_start) >> 12;
> >> + runtime_len = runtime_len_pages << 12;
> >> +
> >> + /* Fill in where normal RAM is (up to U-Boot) */
> >> + efi_memory_map[0].num_pages = gd->relocaddr >> 12;
> >
> > U-Boot question: is gd->relocaddr always the offset from start of RAM?
> > How does this work with gaps in memory map?
>
> U-Boot always relocates itself at TOM (or at least what we consider TOM
> here). gd->relocaddr is the physical address of the start of U-Boot
> which is right below TOM.
Still ... would need additional handling if memory has holes (like,
fitted with multiple DIMMs smaller than the individual memory window
reserved for them). Or even on something like Juno, which has 2GB of
RAM at 0x00_8000_0000, and a further 6GB at 0x08_8000_0000 (I think).
> >> +#ifdef CONFIG_SYS_SDRAM_BASE
> >> + efi_memory_map[0].physical_start = CONFIG_SYS_SDRAM_BASE;
> >> + efi_memory_map[0].virtual_start = CONFIG_SYS_SDRAM_BASE;
> >> + efi_memory_map[0].num_pages -= CONFIG_SYS_SDRAM_BASE >> 12;
> > #else
> > #error "..."
> > ?
>
> If it's not defined, it's 0 :).
Make it
#if CONFIG_SYS_SDRAM_BASE != 0
for clarity?
/
Leif
More information about the U-Boot
mailing list