Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

elfloader: factor out load_dtb() #161

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions elfloader-tool/include/elfloader_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ typedef uintptr_t vaddr_t;
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
#define NULL ((void *)0)


/*
* Information about a DTB we are loading.
*/
typedef struct {
paddr_t phys_base;
size_t size;
} dtb_info_t;

/*
* Information about an image we are loading.
*/
Expand Down Expand Up @@ -93,9 +102,7 @@ int load_images(
struct image_info *user_info,
unsigned int max_user_images,
unsigned int *num_images,
void const *bootloader_dtb,
void const **chosen_dtb,
size_t *chosen_dtb_size);
dtb_info_t *dtb_info);

/* Platform functions */
void platform_init(void);
Expand Down
10 changes: 7 additions & 3 deletions elfloader-tool/src/arch-arm/smp_boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ static volatile int non_boot_lock = 0;

void arm_disable_dcaches(void);

extern void const *dtb;
extern uint32_t dtb_size;
extern dtb_info_t dtb_info;

/* Entry point for all CPUs other than the initial. */
void non_boot_main(void)
Expand Down Expand Up @@ -58,10 +57,15 @@ void non_boot_main(void)
arm_enable_mmu();
}

/* Usually DTBs are much less than 4 GiB, so this cast should be fine. */
uint32_t dtb_size_u32 = (uint32_t)dtb_info.size;

/* Jump to the kernel. */
((init_arm_kernel_t)kernel_info.virt_entry)(user_info.phys_region_start,
user_info.phys_region_end, user_info.phys_virt_offset,
user_info.virt_entry, (paddr_t)dtb, dtb_size);
user_info.virt_entry,
(word_t)dtb_info.phys_base,
(word_t)dtb_size_u32);

printf("AP Kernel returned back to the elf-loader.\n");
abort();
Expand Down
37 changes: 25 additions & 12 deletions elfloader-tool/src/arch-arm/sys_boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ char core_stack_alloc[CONFIG_MAX_NUM_NODES][BIT(PAGE_BITS)];

struct image_info kernel_info;
struct image_info user_info;
void const *dtb;
size_t dtb_size;
dtb_info_t dtb_info;

extern void finish_relocation(int offset, void *_dynamic, unsigned int total_offset);
void continue_boot(int was_relocated);
Expand Down Expand Up @@ -101,8 +100,6 @@ void relocate_below_kernel(void)
*/
void main(UNUSED void *arg)
{
void *bootloader_dtb = NULL;

/* initialize platform to a state where we can print to a UART */
if (initialise_devices()) {
printf("ERROR: Did not successfully return from initialise_devices()\n");
Expand All @@ -116,13 +113,22 @@ void main(UNUSED void *arg)
print_cpuid();
printf(" paddr=[%p..%p]\n", _text, _end - 1);

/* Assume by default, that no DTB is provided from a previous
* bootloader stage. Since 0 is a valid physical address, the size
* field is used to indicate if the address is valid. The value -1
* is to be used if the actual size is not known.
*/
dtb_info.phys_base = 0;
dtb_info.size = 0;

#if defined(CONFIG_IMAGE_UIMAGE)

/* U-Boot passes a DTB. Ancient bootloaders may pass atags. When booting via
* bootelf argc is NULL.
*/
if (arg && (DTB_MAGIC == *(uint32_t *)arg)) {
bootloader_dtb = arg;
dtb_info.phys_base = (paddr_t)arg;
dtb_info.size = (size_t)(-1);
}

#elif defined(CONFIG_IMAGE_EFI)
Expand All @@ -132,20 +138,24 @@ void main(UNUSED void *arg)
abort();
}

bootloader_dtb = efi_get_fdt();
/* For EFI, the DTB address is not supposed to be 0. */
void *efi_dtb = efi_get_fdt();
if (efi_dtb) {
dtb_info.phys_base = (paddr_t)efi_dtb;
dtb_info.size = (size_t)(-1);
}

#endif

if (bootloader_dtb) {
printf(" dtb=%p\n", bootloader_dtb);
if (0 != dtb_info.size) {
printf(" dtb=%p\n", dtb_info.phys_base);
} else {
printf("No DTB passed in from boot loader.\n");
}

/* Unpack ELF images into memory. */
unsigned int num_apps = 0;
int ret = load_images(&kernel_info, &user_info, 1, &num_apps,
bootloader_dtb, &dtb, &dtb_size);
int ret = load_images(&kernel_info, &user_info, 1, &num_apps, &dtb_info);
if (0 != ret) {
printf("ERROR: image loading failed\n");
abort();
Expand Down Expand Up @@ -221,12 +231,15 @@ void continue_boot(int was_relocated)
printf("Jumping to kernel-image entry point...\n\n");
}

/* Usually DTBs are much less than 4 GiB, so this cast should be fine. */
uint32_t dtb_size_u32 = (uint32_t)dtb_info.size;

((init_arm_kernel_t)kernel_info.virt_entry)(user_info.phys_region_start,
user_info.phys_region_end,
user_info.phys_virt_offset,
user_info.virt_entry,
(word_t)dtb,
dtb_size);
(word_t)dtb_info.phys_base,
(word_t)dtb_size_u32);

/* We should never get here. */
printf("ERROR: Kernel returned back to the ELF Loader\n");
Expand Down
22 changes: 14 additions & 8 deletions elfloader-tool/src/arch-riscv/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ unsigned long l2pt_elf[PTES_PER_PT] __attribute__((aligned(4096)));
char elfloader_stack_alloc[BIT(CONFIG_KERNEL_STACK_BITS)];

/* first HART will initialise these */
void const *dtb = NULL;
size_t dtb_size = 0;
dtb_info_t dtb_info;

/*
* overwrite the default implementation for abort()
Expand Down Expand Up @@ -194,10 +193,12 @@ static int run_elfloader(UNUSED int hart_id, void *bootloader_dtb)
{
int ret;

dtb_info.phys_base = (paddr_t)bootloader_dtb;
dtb_info.size = (size_t)(-1);

/* Unpack ELF images into memory. */
unsigned int num_apps = 0;
ret = load_images(&kernel_info, &user_info, 1, &num_apps,
bootloader_dtb, &dtb, &dtb_size);
ret = load_images(&kernel_info, &user_info, 1, &num_apps, &dtb_info);
if (0 != ret) {
printf("ERROR: image loading failed, code %d\n", ret);
return -1;
Expand Down Expand Up @@ -238,13 +239,16 @@ static int run_elfloader(UNUSED int hart_id, void *bootloader_dtb)
printf("Enabling MMU and paging\n");
enable_virtual_memory();

/* Usually DTBs are much less than 4 GiB, so this cast should be fine. */
uint32_t dtb_size_u32 = (uint32_t)dtb_info.size;

printf("Jumping to kernel-image entry point...\n\n");
((init_riscv_kernel_t)kernel_info.virt_entry)(user_info.phys_region_start,
user_info.phys_region_end,
user_info.phys_virt_offset,
user_info.virt_entry,
(word_t)dtb,
dtb_size
(word_t)dtb_info.phys_base,
(word_t)dtb_size_u32
#if CONFIG_MAX_NUM_NODES > 1
,
hart_id,
Expand All @@ -271,15 +275,17 @@ void secondary_entry(int hart_id, int core_id)

enable_virtual_memory();

/* Usually DTBs are much less than 4 GiB, so this cast should be fine. */
uint32_t dtb_size_u32 = (uint32_t)dtb_info.size;

/* If adding or modifying these parameters you will need to update
the registers in head.S */
((init_riscv_kernel_t)kernel_info.virt_entry)(user_info.phys_region_start,
user_info.phys_region_end,
user_info.phys_virt_offset,
user_info.virt_entry,
(word_t)dtb,
dtb_size,
(word_t)dtb_info.phys_base,
(word_t)dtb_size_u32,
hart_id,
core_id
);
Expand Down
53 changes: 27 additions & 26 deletions elfloader-tool/src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,7 @@ int load_images(
struct image_info *user_info,
unsigned int max_user_images,
unsigned int *num_images,
void const *bootloader_dtb,
void const **chosen_dtb,
size_t *chosen_dtb_size)
dtb_info_t *dtb_info)
{
int ret;
uint64_t kernel_phys_start, kernel_phys_end;
Expand Down Expand Up @@ -434,31 +432,32 @@ int load_images(

#ifdef CONFIG_ELFLOADER_INCLUDE_DTB

if (chosen_dtb) {
printf("Looking for DTB in CPIO archive...");
/*
* Note the lack of newline in the above printf(). Normally one would
* have an fflush(stdout) here to ensure that the message shows up on a
* line-buffered stream (which is the POSIX default on terminal
* devices). But we are freestanding (on the "bare metal"), and using
* our own unbuffered printf() implementation.
*/
dtb = cpio_get_file(cpio, cpio_len, "kernel.dtb", NULL);
if (dtb == NULL) {
printf("not found.\n");
} else {
has_dtb_cpio = 1;
printf("found at %p.\n", dtb);
}
printf("Looking for DTB in CPIO archive...");
/*
* Note the lack of newline in the above printf(). Normally one would
* have an fflush(stdout) here to ensure that the message shows up on a
* line-buffered stream (which is the POSIX default on terminal
* devices). But we are freestanding (on the "bare metal"), and using
* our own unbuffered printf() implementation.
*/
dtb = cpio_get_file(cpio, cpio_len, "kernel.dtb", NULL);
if (dtb == NULL) {
printf("not found.\n");
} else {
has_dtb_cpio = 1;
printf("found at %p.\n", dtb);
}

#endif /* CONFIG_ELFLOADER_INCLUDE_DTB */

if (chosen_dtb && !dtb && bootloader_dtb) {
/* Use the bootloader's DTB if we are not using the DTB in the CPIO
* archive.
*/
dtb = bootloader_dtb;
/* If we don't have a DTB here, use the one a bootloader might have
* provided. Since 0 is a valid physical address, the size field is used to
* determin if the address is valid. A size of -1 indicates, that the actual
* size is not known - which is usually the case, because a bootloader often
* just passes an address.
*/
if (!dtb && (dtb_info->size > 0)) {
dtb = (void const *)dtb_info->phys_base;
}

/*
Expand Down Expand Up @@ -489,9 +488,11 @@ int load_images(

printf("Loaded DTB from %p.\n", dtb);
printf(" paddr=[%p..%p]\n", dtb_phys_start, dtb_phys_end - 1);
*chosen_dtb = (void *)dtb_phys_start;
*chosen_dtb_size = dtb_size;
dtb_info->phys_base = dtb_phys_start;
dtb_info->size = dtb_size;
} else {
dtb_info->phys_base = 0;
dtb_info->size = 0;
next_phys_addr = ROUND_UP(kernel_phys_end, PAGE_BITS);
}

Expand Down
Loading