From: Alexander Graf <agraf@suse.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 09/14] efi_loader: Implement memory allocation and map
Date: Tue, 2 Feb 2016 01:59:58 +0100 [thread overview]
Message-ID: <56AFFF8E.4010501@suse.de> (raw)
In-Reply-To: <CAPnjgZ0YN10PD4o=WbAF-aCjJyHAZfMigGk=47ofg9-JnOyodQ@mail.gmail.com>
On 01/31/2016 04:23 PM, Simon Glass wrote:
> Hi Alexander,
>
> On 14 January 2016 at 22:06, Alexander Graf <agraf@suse.de> wrote:
>> Due to popular request, this is a separate patch implementing all of the memory
>> allocation and memory mapping bits.
>>
>> We assume we always have a linear RAM map. At TOM U-Boot resides. Inside of
>> U-Boot there is the runtime region that we need to explicitly expose via the
>> EFI memory map. Below U-Boot, we reserve 128MB of RAM for LOADER_DATA.
>>
>> Signed-off-by: Alexander Graf <agraf@suse.de>
>> ---
>> lib/efi_loader/efi_boottime.c | 99 ++++++++++++++++++++++++++++++++++++++-
>> lib/efi_loader/efi_image_loader.c | 28 ++++++++++-
>> 2 files changed, 123 insertions(+), 4 deletions(-)
>>
>> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
>> index 45217ef..ff3f969 100644
>> --- a/lib/efi_loader/efi_boottime.c
>> +++ b/lib/efi_loader/efi_boottime.c
>> @@ -98,6 +98,8 @@ static void efi_restore_tpl(unsigned long old_tpl)
>> static void *efi_alloc(uint64_t len, int memory_type)
>> {
>> switch (memory_type) {
>> + case EFI_LOADER_DATA:
>> + return efi_loader_alloc(len);
>> default:
>> return malloc(len);
>> }
>> @@ -143,16 +145,109 @@ static efi_status_t efi_free_pages(uint64_t memory, unsigned long pages)
>> return EFI_EXIT(EFI_SUCCESS);
>> }
>>
>> -/* Will be implemented in a later patch */
>> +/*
>> + * Returns the EFI memory map. In our case, this looks pretty simple:
>> + *
>> + * ____________________________ TOM
>> + * | |
>> + * | Second half of U-Boot |
> What does 'second half' mean?
It means that there's one big chunk of "U-Boot" with the RTS sitting in
the middle, dividing it into 2 halves :).
I hope my new memory allocation code makes this more obvious.
>
>> + * |____________________________| &__efi_runtime_stop
>> + * | |
>> + * | EFI Runtime Services |
>> + * |____________________________| &__efi_runtime_start
>> + * | |
>> + * | First half of U-Boot |
>> + * |____________________________| start of EFI loader allocation space
>> + * | |
>> + * | Free RAM |
>> + * |____________________________| CONFIG_SYS_SDRAM_BASE
>> + *
>> + * All pointers are extended to live on a 4k boundary. After exiting the boot
>> + * services, only the EFI Runtime Services chunk of memory stays alive.
>> + */
>> static efi_status_t efi_get_memory_map(unsigned long *memory_map_size,
>> struct efi_mem_desc *memory_map,
>> unsigned long *map_key,
>> unsigned long *descriptor_size,
>> uint32_t *descriptor_version)
>> {
>> + struct efi_mem_desc efi_memory_map[] = {
>> + {
>> + /* RAM before U-Boot */
>> + .type = EFI_CONVENTIONAL_MEMORY,
>> + .attribute = 1 << EFI_MEMORY_WB_SHIFT,
>> + },
>> + {
>> + /* First half of U-Boot */
>> + .type = EFI_LOADER_DATA,
>> + .attribute = 1 << EFI_MEMORY_WB_SHIFT,
>> + },
>> + {
>> + /* EFI Runtime Services */
>> + .type = EFI_RUNTIME_SERVICES_CODE,
>> + .attribute = (1 << EFI_MEMORY_WB_SHIFT) |
>> + (1ULL << EFI_MEMORY_RUNTIME_SHIFT),
>> + },
>> + {
>> + /* Second half of U-Boot */
>> + .type = EFI_LOADER_DATA,
>> + .attribute = 1 << EFI_MEMORY_WB_SHIFT,
>> + },
>> + };
>> + ulong runtime_start, runtime_end, runtime_len_pages, runtime_len;
>> +
>> EFI_ENTRY("%p, %p, %p, %p, %p", memory_map_size, memory_map, map_key,
>> descriptor_size, descriptor_version);
>> - return EFI_EXIT(EFI_UNSUPPORTED);
>> +
>> + 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's top of stack) */
>> + efi_memory_map[0].num_pages = gd->start_addr_sp >> 12;
>> +#ifdef CONFIG_SYS_SDRAM_BASE
> If not defined, what happens?
The new code uses gd->bd->bi_dram.
>
>> + 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;
>> +#endif
>> +
>> + /* Give us some space for the stack */
>> + efi_memory_map[0].num_pages -= (16 * 1024 * 1024) >> 12;
>> +
>> + /* Reserve the EFI loader pool */
>> + efi_memory_map[0].num_pages -= EFI_LOADER_POOL_SIZE >> 12;
>> +
>> + /* Cut out the runtime services */
>> + efi_memory_map[2].physical_start = runtime_start;
>> + efi_memory_map[2].virtual_start = efi_memory_map[2].physical_start;
>> + efi_memory_map[2].num_pages = runtime_len_pages;
>> +
>> + /* Allocate the rest to U-Boot */
>> + efi_memory_map[1].physical_start = efi_memory_map[0].physical_start +
>> + (efi_memory_map[0].num_pages << 12);
>> + efi_memory_map[1].virtual_start = efi_memory_map[1].physical_start;
>> + efi_memory_map[1].num_pages = (runtime_start -
>> + efi_memory_map[1].physical_start) >> 12;
>> +
>> + efi_memory_map[3].physical_start = runtime_start + runtime_len;
>> + efi_memory_map[3].virtual_start = efi_memory_map[3].physical_start;
>> + efi_memory_map[3].num_pages = (gd->ram_top -
>> + efi_memory_map[3].physical_start) >> 12;
>> +
>> + *memory_map_size = sizeof(efi_memory_map);
>> +
>> + if (descriptor_size)
>> + *descriptor_size = sizeof(struct efi_mem_desc);
>> +
>> + if (*memory_map_size < sizeof(efi_memory_map)) {
>> + return EFI_EXIT(EFI_BUFFER_TOO_SMALL);
>> + }
>> +
>> + if (memory_map)
>> + memcpy(memory_map, efi_memory_map, sizeof(efi_memory_map));
>> +
>> + return EFI_EXIT(EFI_SUCCESS);
>> }
>>
>> static efi_status_t efi_allocate_pool(int pool_type, unsigned long size, void **buffer)
>> diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
>> index a7788bf..67c4b06 100644
>> --- a/lib/efi_loader/efi_image_loader.c
>> +++ b/lib/efi_loader/efi_image_loader.c
>> @@ -29,10 +29,34 @@ efi_status_t efi_return_handle(void *handle, efi_guid_t *protocol,
>> return EFI_SUCCESS;
>> }
>>
>> -/* Will be implemented in a later patch */
>> +/*
>> + * EFI payloads potentially want to load pretty big images into memory,
>> + * so our small malloc region isn't enough for them. However, they usually
>> + * don't need a smart allocator either.
>> + *
>> + * So instead give them a really dumb one. We just reserve EFI_LOADER_POOL_SIZE
>> + * bytes from 16MB below the stack start to give the stack some space.
>> + * Then every allocation gets a 4k aligned chunk from it. We never free.
>> + */
>> void *efi_loader_alloc(uint64_t len)
>> {
>> - return NULL;
>> + static unsigned long loader_pool;
>> + void *r;
>> +
>> + if (!loader_pool) {
>> + loader_pool = ((gd->start_addr_sp >> 12) << 12) -
>> + (16 * MB) - EFI_LOADER_POOL_SIZE;
> I think it would be better to reserve this in board_f() with a
> reserve...() function. Perhaps store the address in global_data.
The new code doesn't reserve anything anymore :)
Alex
>
>> + }
>> +
>> + len = ROUND_UP(len, 4096);
>> + /* Out of memory */
>> + if ((loader_pool + len) >= (gd->relocaddr - TOTAL_MALLOC_LEN))
> debug() here?
>
>> + return NULL;
>> +
>> + r = (void *)loader_pool;
>> + loader_pool += len;
>> +
>> + return r;
>> }
>>
>> /*
>> --
>> 2.1.4
> Regards,
> Simon
next prev parent reply other threads:[~2016-02-02 0:59 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-15 5:06 [U-Boot] [PATCH 00/14] EFI payload / application support v2 Alexander Graf
2016-01-15 5:06 ` [U-Boot] [PATCH 01/14] disk/part.c: Expose list of available block drivers Alexander Graf
2016-01-15 5:06 ` [U-Boot] [PATCH 02/14] include/efi_api.h: Add more detailed API definitions Alexander Graf
2016-01-31 15:17 ` Simon Glass
2016-02-01 22:46 ` Alexander Graf
2016-01-15 5:06 ` [U-Boot] [PATCH 03/14] efi_loader: Add PE image loader Alexander Graf
2016-01-31 15:18 ` Simon Glass
2016-02-01 22:58 ` Alexander Graf
2016-01-15 5:06 ` [U-Boot] [PATCH 04/14] efi_loader: Add boot time services Alexander Graf
2016-01-20 0:16 ` Leif Lindholm
2016-02-02 1:52 ` Alexander Graf
2016-01-31 15:19 ` Simon Glass
2016-02-01 23:45 ` Alexander Graf
2016-02-01 23:54 ` Simon Glass
2016-02-02 0:02 ` Alexander Graf
2016-01-15 5:06 ` [U-Boot] [PATCH 05/14] efi_loader: Add console interface Alexander Graf
2016-01-31 15:19 ` Simon Glass
2016-01-15 5:06 ` [U-Boot] [PATCH 06/14] efi_loader: Add runtime services Alexander Graf
2016-01-21 17:20 ` Leif Lindholm
2016-01-31 15:20 ` Simon Glass
2016-02-01 23:57 ` Alexander Graf
2016-01-15 5:06 ` [U-Boot] [PATCH 07/14] efi_loader: Add disk interfaces Alexander Graf
2016-01-31 15:23 ` Simon Glass
2016-02-02 0:32 ` Alexander Graf
2016-01-15 5:06 ` [U-Boot] [PATCH 08/14] efi_loader: Add "bootefi" command Alexander Graf
2016-01-31 15:23 ` Simon Glass
2016-01-15 5:06 ` [U-Boot] [PATCH 09/14] efi_loader: Implement memory allocation and map Alexander Graf
2016-01-31 15:23 ` Simon Glass
2016-02-02 0:59 ` Alexander Graf [this message]
2016-01-15 5:06 ` [U-Boot] [PATCH 10/14] arm64: Allow exceptions to return Alexander Graf
2016-01-15 5:06 ` [U-Boot] [PATCH 11/14] arm64: Allow EFI payload code to take exceptions Alexander Graf
2016-01-15 5:06 ` [U-Boot] [PATCH 12/14] efi_loader: Add DCACHE_OFF support for arm64 Alexander Graf
2016-01-15 5:06 ` [U-Boot] [PATCH 13/14] efi_loader: hook up in build environment Alexander Graf
2016-01-31 15:24 ` Simon Glass
2016-01-15 5:06 ` [U-Boot] [PATCH 14/14] efi_loader: Add distro boot script for removable media Alexander Graf
2016-01-31 15:24 ` Simon Glass
2016-02-02 1:05 ` Alexander Graf
2016-01-31 15:17 ` [U-Boot] [PATCH 00/14] EFI payload / application support v2 Simon Glass
2016-01-31 21:43 ` Alexander Graf
2016-02-01 2:52 ` Simon Glass
2016-02-01 3:25 ` Simon Glass
2016-02-01 21:38 ` Alexander Graf
2016-02-02 0:02 ` Simon Glass
2016-02-02 0:16 ` Alexander Graf
2016-02-02 0:28 ` Simon Glass
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56AFFF8E.4010501@suse.de \
--to=agraf@suse.de \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox