From 7635ecacd362cdc43b122fc6f50307fd34ceba85 Mon Sep 17 00:00:00 2001 From: Karthick Shanmugham Date: Fri, 12 Jun 2020 18:25:56 +0530 Subject: [PATCH] ipq50xx: Added support for compressed dtb in u-boot Signed-off-by: Karthick Shanmugham Change-Id: If56b282b02cf621fa220d7f8cc6f2ddfe85bb212 --- Kconfig | 3 ++ Makefile | 57 +++++++++++++++++++++++++- arch/arm/dts/combined_dtb.lds | 40 +++++++++++++++++++ arch/arm/dts/compressed_dtb/Makefile | 13 ++++++ common/board_f.c | 5 ++- common/dlmalloc.c | 21 +++++++++- include/configs/ipq5018.h | 4 ++ include/malloc.h | 3 ++ lib/fdtdec.c | 60 ++++++++++++++++++++++++++++ 9 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 arch/arm/dts/combined_dtb.lds create mode 100644 arch/arm/dts/compressed_dtb/Makefile diff --git a/Kconfig b/Kconfig index 821b464db2..9551e5922a 100644 --- a/Kconfig +++ b/Kconfig @@ -104,6 +104,9 @@ menu "Boot images" config SUPPORT_SPL bool +config COMPRESSED_DTB_BASE + hex + config SUPPORT_TPL bool diff --git a/Makefile b/Makefile index 96faa4671a..61340e5dec 100644 --- a/Makefile +++ b/Makefile @@ -556,6 +556,12 @@ else include/config/auto.conf: ; endif # $(dot-config) +ifndef DTBLDSCRIPT + ifeq ($(wildcard $(DTBLDSCRIPT)),) + DTBLDSCRIPT := $(srctree)/arch/$(ARCH)/dts/combined_dtb.lds + endif +endif + ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS += -Os else @@ -700,6 +706,9 @@ libs-y := $(patsubst %/, %/built-in.o, $(libs-y)) u-boot-init := $(head-y) u-boot-main := $(libs-y) +ifneq ($(CONFIG_COMPRESSED_DTB_BASE),) +compressed_dtb-dirs := arch/$(ARCH)/dts/compressed_dtb +endif # Add GCC lib ifeq ($(CONFIG_USE_PRIVATE_LIBGCC),y) @@ -805,6 +814,17 @@ ifneq ($(CONFIG_SYS_TEXT_BASE),) LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE) endif + +ifneq ($(CONFIG_COMPRESSED_DTB_BASE),) +LDFLAGS_dtb_combine += $(LDFLAGS_FINAL) +COMPRESS_DTB_BASE = $(shell printf "0x%x" $$(( $(CONFIG_SYS_TEXT_BASE) - $(CONFIG_COMPRESSED_DTB_MAX_SIZE)))) +LDFLAGS_dtb_combine += -Ttext $(COMPRESS_DTB_BASE) + +# Normal objcopy without filter the sections +quiet_cmd_nobjcopy = OBJCOPY $@ +cmd_nobjcopy = $(OBJCOPY) --gap-fill=0xff -O binary $< $@ +endif + # Normally we fill empty space with 0xff quiet_cmd_objcopy = OBJCOPY $@ cmd_objcopy = $(OBJCOPY) --gap-fill=0xff $(OBJCOPYFLAGS) \ @@ -890,6 +910,11 @@ u-boot.bin: u-boot FORCE $(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE)) $(BOARD_SIZE_CHECK) +ifneq ($(CONFIG_COMPRESSED_DTB_BASE),) +dtb_combined.bin: dtb_combined FORCE + $(call if_changed,nobjcopy) +endif + quiet_cmd_mkheader = MKHEADER $@ cmd_mkheader = $(PYTHON) tools/mkheader.py $(CONFIG_SYS_TEXT_BASE) $(CONFIG_IPQ_APPSBL_IMG_TYPE) $< $@ @@ -1204,6 +1229,23 @@ quiet_cmd_u-boot__ ?= LD $@ --start-group $(u-boot-main) --end-group \ $(PLATFORM_LIBS) -Map u-boot.map +ifneq ($(CONFIG_COMPRESSED_DTB_BASE),) +# Rule to link combined_dtb.lds +quiet_cmd_dtb_combined__ ?= LD $@ + cmd_dtb_combined__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_dtb_combine) -o dtb_combined \ + -T combined_dtb.lds $(u-boot-init) \ + --start-group arch/$(ARCH)/dts/built-in.o --end-group \ + $(PLATFORM_LIBS) -Map dtb_combined.map + +combine_dtb_Linker: combined_dtb.lds + $(call if_changed,dtb_combined__) + +compress_dtb: combine_dtb_Linker dtb_combined.bin $(compressed_dtb-dirs) + cp arch/$(ARCH)/dts/compressed_dtb/dtbcombined.o arch/$(ARCH)/dts/built-in.o +else +compress_dtb: +endif + quiet_cmd_smap = GEN common/system_map.o cmd_smap = \ smap=`$(call SYSTEM_MAP,u-boot) | \ @@ -1211,7 +1253,7 @@ cmd_smap = \ $(CC) $(c_flags) -DSYSTEM_MAP="\"$${smap}\"" \ -c $(srctree)/common/system_map.c -o common/system_map.o -u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds +u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds compress_dtb $(call if_changed,u-boot__) ifeq ($(CONFIG_KALLSYMS),y) $(call cmd,smap) @@ -1228,10 +1270,16 @@ $(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ; # make menuconfig etc. # Error messages still appears in the original language + PHONY += $(u-boot-dirs) $(u-boot-dirs): prepare scripts $(Q)$(MAKE) $(build)=$@ +ifneq ($(CONFIG_COMPRESSED_DTB_BASE),) +$(compressed_dtb-dirs): prepare scripts + $(Q)$(MAKE) $(build)=$@ +endif + tools: prepare # The "tools" are needed early $(filter-out tools, $(u-boot-dirs)): tools @@ -1346,6 +1394,13 @@ cmd_cpp_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \ u-boot.lds: $(LDSCRIPT) prepare FORCE $(call if_changed_dep,cpp_lds) +quiet_cmd_cpp_dtb_lds = LDS $@ +cmd_cpp_dtb_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \ + -D__ASSEMBLY__ -x assembler-with-cpp -P -o $@ $< + +combined_dtb.lds: $(DTBLDSCRIPT) prepare FORCE + $(call if_changed_dep,cpp_dtb_lds) + spl/u-boot-spl.bin: spl/u-boot-spl @: spl/u-boot-spl: tools prepare $(if $(CONFIG_OF_SEPARATE),dts/dt.dtb) diff --git a/arch/arm/dts/combined_dtb.lds b/arch/arm/dts/combined_dtb.lds new file mode 100644 index 0000000000..0cb0e77788 --- /dev/null +++ b/arch/arm/dts/combined_dtb.lds @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SECTIONS +{ + + . = ALIGN(4); + .text : + { + *(.__image_copy_start) + *(.vectors) + CPUDIR/start.o (.text*) + *(.text*) + } + + +#ifdef CONFIG_OF_COMBINE + . = ALIGN(4); + .dtb : { + KEEP(*(.dtb.combine*)); + } +#endif + + . = ALIGN(4); + +} diff --git a/arch/arm/dts/compressed_dtb/Makefile b/arch/arm/dts/compressed_dtb/Makefile new file mode 100644 index 0000000000..6bbae065c1 --- /dev/null +++ b/arch/arm/dts/compressed_dtb/Makefile @@ -0,0 +1,13 @@ +$(obj)/dtbcombined.S: $(obj)/../../../../dtb_combined.bin + gzip -k --best $(obj)/../../../../dtb_combined.bin + echo ".section .dtb.combine_blob,\"a\"" > $(obj)/dtbcombined.S + echo '.balign 16' >> $(obj)/dtbcombined.S + echo ".global __dtb_blob_begin" >> $(obj)/dtbcombined.S + echo "__dtb_blob_begin:" >> $(obj)/dtbcombined.S + echo '.incbin "$(obj)/../../../../dtb_combined.bin.gz"' >> $(obj)/dtbcombined.S + echo '.balign 16' >> $(obj)/dtbcombined.S + echo ".global __dtb_blob_end" >> $(obj)/dtbcombined.S + echo "__dtb_blob_end:" >> $(obj)/dtbcombined.S + echo ".word 0" >> $(obj)/dtbcombined.S + +obj-y := dtbcombined.o diff --git a/common/board_f.c b/common/board_f.c index 9c2e1aaf7b..26b1e644eb 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -842,12 +842,15 @@ static init_fnc_t init_sequence_f[] = { #endif setup_mon_len, #ifdef CONFIG_OF_CONTROL +#ifdef CONFIG_COMPRESSED_DTB_BASE + initf_pre_malloc, +#endif fdtdec_setup, #endif + initf_malloc, #ifdef CONFIG_TRACE trace_early_init, #endif - initf_malloc, initf_console_record, #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) /* TODO: can this go into arch_cpu_init()? */ diff --git a/common/dlmalloc.c b/common/dlmalloc.c index b5bb05191c..5a77be4a48 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -3261,17 +3261,34 @@ int mALLOPt(param_number, value) int param_number; int value; } } +#ifdef CONFIG_COMPRESSED_DTB_BASE +unsigned long malloc_base; + +int initf_pre_malloc(void) +{ +#ifdef CONFIG_SYS_MALLOC_F_LEN + assert(gd->malloc_base); /* Set up by crt0.S */ + malloc_base = gd->malloc_base; + gd->malloc_limit = CONFIG_COMPRESSED_DTB_MAX_SIZE; + gd->malloc_base = CONFIG_COMPRESSED_DTB_BASE - CONFIG_COMPRESSED_DTB_MAX_SIZE; + gd->malloc_ptr = 0; +#endif + return 0; +} +#endif + int initf_malloc(void) { #ifdef CONFIG_SYS_MALLOC_F_LEN assert(gd->malloc_base); /* Set up by crt0.S */ gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; +#ifdef CONFIG_COMPRESSED_DTB_BASE + gd->malloc_base = malloc_base; +#endif gd->malloc_ptr = 0; #endif - return 0; } - /* History: diff --git a/include/configs/ipq5018.h b/include/configs/ipq5018.h index a0dcce7f26..0470205743 100644 --- a/include/configs/ipq5018.h +++ b/include/configs/ipq5018.h @@ -107,6 +107,9 @@ #define CONFIG_OF_COMBINE 1 +#define CONFIG_COMPRESSED_DTB_MAX_SIZE 0x40000 +#define CONFIG_COMPRESSED_DTB_BASE CONFIG_SYS_TEXT_BASE - CONFIG_COMPRESSED_DTB_MAX_SIZE + #define CONFIG_QCA_SMEM_BASE 0x4AB00000 #define CONFIG_IPQ_FDT_HIGH 0x4A400000 @@ -393,6 +396,7 @@ extern loff_t board_env_size; #ifdef CONFIG_ART_COMPRESSED #undef CONFIG_GZIP #undef CONFIG_ZLIB +#undef CONFIG_COMPRESSED_DTB_BASE /* * CONFIG_COMPRESSED_LOAD_ADDR loads the compressed data for uncompress action */ diff --git a/include/malloc.h b/include/malloc.h index f20e4d3d2a..e5c6561720 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -909,6 +909,9 @@ void *realloc_simple(void *ptr, size_t size); /* Set up pre-relocation malloc() ready for use */ int initf_malloc(void); +# ifdef CONFIG_COMPRESSED_DTB_BASE +int initf_pre_malloc(void); +# endif /* Public routines */ /* Simple versions which can be used when space is tight */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index fb703129e6..fc4dd017a1 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1216,19 +1216,58 @@ int fdtdec_decode_display_timing(const void *blob, int parent, int index, } #ifdef CONFIG_OF_COMBINE + +#ifdef CONFIG_COMPRESSED_DTB_BASE +extern unsigned long __dtb_blob_begin; +extern unsigned long __dtb_blob_end; + + +static uint32_t uncompress_gzipped_dtb(unsigned long dest_ddr_addr) +{ + uint32_t size; + unsigned long compressed_len; + unsigned long dtb_begin; + unsigned long dtb_end; + + dtb_begin = (unsigned long)&__dtb_blob_begin; + dtb_end = (unsigned long)&__dtb_blob_end; + + size = CONFIG_COMPRESSED_DTB_MAX_SIZE; + compressed_len = dtb_end - dtb_begin; + if (gunzip((void *)dest_ddr_addr, size, (unsigned char *)dtb_begin, &compressed_len) != 0 ) + hang(); + else + debug("Unzipping compressed DTB's success\n"); + return compressed_len; + +} + +# else extern unsigned long __dtb_table_start; + +#endif + struct dtb_combined_hdr { unsigned long machid; unsigned long dtbaddr; }; + static int parse_combined_fdt(unsigned long machid) { unsigned long *ptr = NULL; struct dtb_combined_hdr *fdt_table; unsigned long ndtbs = 0; +#ifdef CONFIG_COMPRESSED_DTB_BASE + uint32_t size, uncompressed_size; + unsigned long dtb_end, dtb_begin, dtb_base; + unsigned long pgtable_base; + uncompressed_size = uncompress_gzipped_dtb(CONFIG_COMPRESSED_DTB_BASE); + ptr = (void *)CONFIG_COMPRESSED_DTB_BASE; +# else ptr = &__dtb_table_start; +#endif ndtbs = *ptr; ptr++; @@ -1243,7 +1282,28 @@ static int parse_combined_fdt(unsigned long machid) if(ndtbs == 0) hang(); +#ifdef CONFIG_COMPRESSED_DTB_BASE + dtb_begin = fdt_table->dtbaddr; + + if (ndtbs == 1) { + size = CONFIG_COMPRESSED_DTB_BASE + uncompressed_size - dtb_begin; + } else { + fdt_table++; + dtb_end = fdt_table->dtbaddr; + size = dtb_end - dtb_begin; + } + + pgtable_base = CONFIG_SYS_TEXT_BASE + gd->mon_len; + pgtable_base += (0x10000 - 1); + pgtable_base &= ~(0x10000 - 1); + dtb_base = (unsigned long)(pgtable_base + PGTABLE_SIZE) + 0x4; // 0x4 breathing space for overcome overlap. + + memcpy((ulong *)dtb_base, (void *)dtb_begin, size); + + return dtb_base; +# else return fdt_table->dtbaddr; +#endif } #endif