static inline unsigned long arm_mem_boarddata(unsigned long membase, unsigned long endmem, unsigned long size) { unsigned long mem; mem = arm_mem_barebox_image(membase, endmem, barebox_image_size); mem -= ALIGN(size, 64); return mem; }
__noreturn void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { unsigned long endmem = membase + memsize; unsigned long malloc_start, malloc_end; unsigned long barebox_size = barebox_image_size + MAX_BSS_SIZE; if (IS_ENABLED(CONFIG_RELOCATABLE)) { unsigned long barebox_base = arm_mem_barebox_image(membase, endmem, barebox_size); relocate_to_adr(barebox_base); } setup_c(); barrier(); pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize); arm_stack_top = endmem; arm_barebox_size = barebox_size; malloc_end = arm_mem_barebox_image(membase, endmem, arm_barebox_size); if (IS_ENABLED(CONFIG_MMU_EARLY)) { unsigned long ttb = arm_mem_ttb(membase, endmem); if (IS_ENABLED(CONFIG_PBL_IMAGE)) { arm_set_cache_functions(); } else { pr_debug("enabling MMU, ttb @ 0x%08lx\n", ttb); arm_early_mmu_cache_invalidate(); mmu_early_enable(membase, memsize, ttb); } } if (boarddata) { uint32_t totalsize = 0; const char *name; if (blob_is_fdt(boarddata)) { totalsize = get_unaligned_be32(boarddata + 4); name = "DTB"; } else if (blob_is_compressed_fdt(boarddata)) { struct barebox_arm_boarddata_compressed_dtb *bd = boarddata; totalsize = bd->datalen + sizeof(*bd); name = "Compressed DTB"; } else if (blob_is_arm_boarddata(boarddata)) { totalsize = sizeof(struct barebox_arm_boarddata); name = "machine type"; } if (totalsize) { unsigned long mem = arm_mem_boarddata(membase, endmem, totalsize); pr_debug("found %s in boarddata, copying to 0x%08lx\n", name, mem); barebox_boarddata = memcpy((void *)mem, boarddata, totalsize); barebox_boarddata_size = totalsize; malloc_end = mem; } } /* * Maximum malloc space is the Kconfig value if given * or 1GB. */ if (MALLOC_SIZE > 0) { malloc_start = malloc_end - MALLOC_SIZE; if (malloc_start < membase) malloc_start = membase; } else { malloc_start = malloc_end - (malloc_end - membase) / 2; if (malloc_end - malloc_start > SZ_1G) malloc_start = malloc_end - SZ_1G; } pr_debug("initializing malloc pool at 0x%08lx (size 0x%08lx)\n", malloc_start, malloc_end - malloc_start); mem_malloc_init((void *)malloc_start, (void *)malloc_end - 1); pr_debug("starting barebox...\n"); start_barebox(); }
void __noreturn barebox_multi_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { uint32_t pg_len; void __noreturn (*barebox)(unsigned long, unsigned long, void *); uint32_t endmem = membase + memsize; unsigned long barebox_base; uint32_t *image_end; void *pg_start; unsigned long pc = get_pc(); image_end = (void *)ld_var(__image_end) - get_runtime_offset(); if (IS_ENABLED(CONFIG_PBL_RELOCATABLE)) { /* * If we run from inside the memory just relocate the binary * to the current address. Otherwise it may be a readonly location. * Copy and relocate to the start of the memory in this case. */ if (pc > membase && pc - membase < memsize) relocate_to_current_adr(); else relocate_to_adr(membase); } /* * image_end is the first location after the executable. It contains * the size of the appended compressed binary followed by the binary. */ pg_start = image_end + 1; pg_len = *(image_end); if (IS_ENABLED(CONFIG_RELOCATABLE)) barebox_base = arm_mem_barebox_image(membase, endmem, pg_len); else barebox_base = TEXT_BASE; setup_c(); pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize); if (IS_ENABLED(CONFIG_MMU_EARLY)) { unsigned long ttb = arm_mem_ttb(membase, endmem); pr_debug("enabling MMU, ttb @ 0x%08lx\n", ttb); mmu_early_enable(membase, memsize, ttb); } free_mem_ptr = arm_mem_early_malloc(membase, endmem); free_mem_end_ptr = arm_mem_early_malloc_end(membase, endmem); pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx\n", pg_start, pg_len, barebox_base); pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len); arm_early_mmu_cache_flush(); flush_icache(); if (IS_ENABLED(CONFIG_THUMB2_BAREBOX)) barebox = (void *)(barebox_base + 1); else barebox = (void *)barebox_base; pr_debug("jumping to uncompressed image at 0x%p\n", barebox); barebox(membase, memsize, boarddata); }