110eadc25SFrank Rowand#! /bin/bash 2b886d83cSThomas Gleixner# SPDX-License-Identifier: GPL-2.0-only 310eadc25SFrank Rowand 410eadc25SFrank Rowand# Copyright (C) 2015 Frank Rowand 510eadc25SFrank Rowand# 610eadc25SFrank Rowand 710eadc25SFrank Rowand 810eadc25SFrank Rowandusage() { 910eadc25SFrank Rowand 1010eadc25SFrank Rowand # use spaces instead of tabs in the usage message 1110eadc25SFrank Rowand cat >&2 <<eod 1210eadc25SFrank Rowand 1310eadc25SFrank RowandUsage: 1410eadc25SFrank Rowand 1510eadc25SFrank Rowand `basename $0` DTx 1610eadc25SFrank Rowand decompile DTx 1710eadc25SFrank Rowand 1810eadc25SFrank Rowand `basename $0` DTx_1 DTx_2 1910eadc25SFrank Rowand diff DTx_1 and DTx_2 2010eadc25SFrank Rowand 2110eadc25SFrank Rowand 2287143fceSFrank Rowand --annotate synonym for -T 231ee1ffe1SGeert Uytterhoeven --color synonym for -c (requires diff with --color support) 241ee1ffe1SGeert Uytterhoeven -c enable colored output 2510eadc25SFrank Rowand -f print full dts in diff (--unified=99999) 2610eadc25SFrank Rowand -h synonym for --help 2710eadc25SFrank Rowand -help synonym for --help 2810eadc25SFrank Rowand --help print this message and exit 2910eadc25SFrank Rowand -s SRCTREE linux kernel source tree is at path SRCTREE 3010eadc25SFrank Rowand (default is current directory) 3110eadc25SFrank Rowand -S linux kernel source tree is at root of current git repo 324036707cSGeert Uytterhoeven -T annotate output .dts with input source file and line 334036707cSGeert Uytterhoeven (-T -T for more details) 3410eadc25SFrank Rowand -u unsorted, do not sort DTx 3510eadc25SFrank Rowand 3610eadc25SFrank Rowand 3710eadc25SFrank RowandEach DTx is processed by the dtc compiler to produce a sorted dts source 3810eadc25SFrank Rowandfile. If DTx is a dts source file then it is pre-processed in the same 3910eadc25SFrank Rowandmanner as done for the compile of the dts source file in the Linux kernel 4010eadc25SFrank Rowandbuild system ('#include' and '/include/' directives are processed). 4110eadc25SFrank Rowand 4210eadc25SFrank RowandIf two DTx are provided, the resulting dts source files are diffed. 4310eadc25SFrank Rowand 4410eadc25SFrank RowandIf DTx is a directory, it is treated as a DT subtree, such as 4510eadc25SFrank Rowand /proc/device-tree. 4610eadc25SFrank Rowand 4710eadc25SFrank RowandIf DTx contains the binary blob magic value in the first four bytes, 4810eadc25SFrank Rowand it is treated as a binary blob (aka .dtb or FDT). 4910eadc25SFrank Rowand 5010eadc25SFrank RowandOtherwise DTx is treated as a dts source file (aka .dts). 5110eadc25SFrank Rowand 5210eadc25SFrank Rowand If this script is not run from the root of the linux source tree, 5310eadc25SFrank Rowand and DTx utilizes '#include' or '/include/' then the path of the 5410eadc25SFrank Rowand linux source tree can be provided by '-s SRCTREE' or '-S' so that 5510eadc25SFrank Rowand include paths will be set properly. 5610eadc25SFrank Rowand 5710eadc25SFrank Rowand The shell variable \${ARCH} must provide the architecture containing 5810eadc25SFrank Rowand the dts source file for include paths to be set properly for '#include' 5910eadc25SFrank Rowand or '/include/' to be processed. 6010eadc25SFrank Rowand 6110eadc25SFrank Rowand If DTx_1 and DTx_2 are in different architectures, then this script 62*d8adf5b9SMatthias Schiffer may not work since \${ARCH} is part of the include path. The following 63*d8adf5b9SMatthias Schiffer workaround can be used: 6410eadc25SFrank Rowand 6510eadc25SFrank Rowand `basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts 6610eadc25SFrank Rowand `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts 6710eadc25SFrank Rowand `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts 6810eadc25SFrank Rowand rm tmp_dtx_1.dts tmp_dtx_2.dts 6910eadc25SFrank Rowand 7010eadc25SFrank Rowand If DTx_1 and DTx_2 are in different directories, then this script will 7110eadc25SFrank Rowand add the path of DTx_1 and DTx_2 to the include paths. If DTx_2 includes 7210eadc25SFrank Rowand a local file that exists in both the path of DTx_1 and DTx_2 then the 7310eadc25SFrank Rowand file in the path of DTx_1 will incorrectly be included. Possible 7410eadc25SFrank Rowand workaround: 7510eadc25SFrank Rowand 7610eadc25SFrank Rowand `basename $0` DTx_1 >tmp_dtx_1.dts 7710eadc25SFrank Rowand `basename $0` DTx_2 >tmp_dtx_2.dts 7810eadc25SFrank Rowand `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts 7910eadc25SFrank Rowand rm tmp_dtx_1.dts tmp_dtx_2.dts 8010eadc25SFrank Rowand 8110eadc25SFrank Rowandeod 8210eadc25SFrank Rowand} 8310eadc25SFrank Rowand 8410eadc25SFrank Rowand 8510eadc25SFrank Rowandcompile_to_dts() { 8610eadc25SFrank Rowand 8710eadc25SFrank Rowand dtx="$1" 8835f3c984SFrank Rowand dtc_include="$2" 8910eadc25SFrank Rowand 9010eadc25SFrank Rowand if [ -d "${dtx}" ] ; then 9110eadc25SFrank Rowand 9210eadc25SFrank Rowand # ----- input is file tree 9310eadc25SFrank Rowand 9410eadc25SFrank Rowand if ( ! ${DTC} -I fs ${dtx} ) ; then 9510eadc25SFrank Rowand exit 3 9610eadc25SFrank Rowand fi 9710eadc25SFrank Rowand 9810eadc25SFrank Rowand elif [ -f "${dtx}" ] && [ -r "${dtx}" ] ; then 9910eadc25SFrank Rowand 10010eadc25SFrank Rowand magic=`hexdump -n 4 -e '/1 "%02x"' ${dtx}` 10110eadc25SFrank Rowand if [ "${magic}" = "d00dfeed" ] ; then 10210eadc25SFrank Rowand 10310eadc25SFrank Rowand # ----- input is FDT (binary blob) 10410eadc25SFrank Rowand 10510eadc25SFrank Rowand if ( ! ${DTC} -I dtb ${dtx} ) ; then 10610eadc25SFrank Rowand exit 3 10710eadc25SFrank Rowand fi 10810eadc25SFrank Rowand 10910eadc25SFrank Rowand return 11010eadc25SFrank Rowand 11110eadc25SFrank Rowand fi 11210eadc25SFrank Rowand 11310eadc25SFrank Rowand # ----- input is DTS (source) 11410eadc25SFrank Rowand 11510eadc25SFrank Rowand if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \ 11635f3c984SFrank Rowand | ${DTC} ${dtc_include} -I dts ) ; then 11710eadc25SFrank Rowand return 11810eadc25SFrank Rowand fi 11910eadc25SFrank Rowand 12010eadc25SFrank Rowand echo "" >&2 12110eadc25SFrank Rowand echo "Possible hints to resolve the above error:" >&2 12210eadc25SFrank Rowand echo " (hints might not fix the problem)" >&2 12310eadc25SFrank Rowand 12410eadc25SFrank Rowand hint_given=0 12510eadc25SFrank Rowand 12610eadc25SFrank Rowand if [ "${ARCH}" = "" ] ; then 12710eadc25SFrank Rowand hint_given=1 12810eadc25SFrank Rowand echo "" >&2 12910eadc25SFrank Rowand echo " shell variable \$ARCH not set" >&2 13010eadc25SFrank Rowand fi 13110eadc25SFrank Rowand 13210eadc25SFrank Rowand dtx_arch=`echo "/${dtx}" | sed -e 's|.*/arch/||' -e 's|/.*||'` 13310eadc25SFrank Rowand 13410eadc25SFrank Rowand if [ "${dtx_arch}" != "" -a "${dtx_arch}" != "${ARCH}" ] ; then 13510eadc25SFrank Rowand hint_given=1 13610eadc25SFrank Rowand echo "" >&2 13710eadc25SFrank Rowand echo " architecture ${dtx_arch} is in file path," >&2 13810eadc25SFrank Rowand echo " but does not match shell variable \$ARCH" >&2 13960c7f4cbSFrank Rowand echo " >>\$ARCH<< is: >>${ARCH}<<" >&2 14010eadc25SFrank Rowand fi 14110eadc25SFrank Rowand 14210eadc25SFrank Rowand if [ ! -d ${srctree}/arch/${ARCH} ] ; then 14310eadc25SFrank Rowand hint_given=1 14410eadc25SFrank Rowand echo "" >&2 14510eadc25SFrank Rowand echo " ${srctree}/arch/${ARCH}/ does not exist" >&2 14610eadc25SFrank Rowand echo " Is \$ARCH='${ARCH}' correct?" >&2 14710eadc25SFrank Rowand echo " Possible fix: use '-s' option" >&2 14810eadc25SFrank Rowand 14910eadc25SFrank Rowand git_root=`git rev-parse --show-toplevel 2>/dev/null` 15010eadc25SFrank Rowand if [ -d ${git_root}/arch/ ] ; then 15110eadc25SFrank Rowand echo " Possible fix: use '-S' option" >&2 15210eadc25SFrank Rowand fi 15310eadc25SFrank Rowand fi 15410eadc25SFrank Rowand 15510eadc25SFrank Rowand if [ $hint_given = 0 ] ; then 15610eadc25SFrank Rowand echo "" >&2 15710eadc25SFrank Rowand echo " No hints available." >&2 15810eadc25SFrank Rowand fi 15910eadc25SFrank Rowand 16010eadc25SFrank Rowand echo "" >&2 16110eadc25SFrank Rowand 16210eadc25SFrank Rowand exit 3 16310eadc25SFrank Rowand 16410eadc25SFrank Rowand else 16510eadc25SFrank Rowand echo "" >&2 16610eadc25SFrank Rowand echo "ERROR: ${dtx} does not exist or is not readable" >&2 16710eadc25SFrank Rowand echo "" >&2 16810eadc25SFrank Rowand exit 2 16910eadc25SFrank Rowand fi 17010eadc25SFrank Rowand 17110eadc25SFrank Rowand} 17210eadc25SFrank Rowand 17310eadc25SFrank Rowand 17410eadc25SFrank Rowand# ----- start of script 17510eadc25SFrank Rowand 17687143fceSFrank Rowandannotate="" 17710eadc25SFrank Rowandcmd_diff=0 17810eadc25SFrank Rowanddiff_flags="-u" 1791ee1ffe1SGeert Uytterhoevendiff_color="" 18010eadc25SFrank Rowanddtx_file_1="" 18110eadc25SFrank Rowanddtx_file_2="" 18210eadc25SFrank Rowanddtc_sort="-s" 18310eadc25SFrank Rowandhelp=0 18410eadc25SFrank Rowandsrctree="" 18510eadc25SFrank Rowand 18610eadc25SFrank Rowand 18710eadc25SFrank Rowandwhile [ $# -gt 0 ] ; do 18810eadc25SFrank Rowand 18910eadc25SFrank Rowand case $1 in 19010eadc25SFrank Rowand 1911ee1ffe1SGeert Uytterhoeven -c | --color ) 1921ee1ffe1SGeert Uytterhoeven if diff --color /dev/null /dev/null 2>/dev/null ; then 1931ee1ffe1SGeert Uytterhoeven diff_color="--color=always" 1941ee1ffe1SGeert Uytterhoeven fi 1951ee1ffe1SGeert Uytterhoeven shift 1961ee1ffe1SGeert Uytterhoeven ;; 1971ee1ffe1SGeert Uytterhoeven 19810eadc25SFrank Rowand -f ) 19910eadc25SFrank Rowand diff_flags="--unified=999999" 20010eadc25SFrank Rowand shift 20110eadc25SFrank Rowand ;; 20210eadc25SFrank Rowand 20310eadc25SFrank Rowand -h | -help | --help ) 20410eadc25SFrank Rowand help=1 20510eadc25SFrank Rowand shift 20610eadc25SFrank Rowand ;; 20710eadc25SFrank Rowand 20810eadc25SFrank Rowand -s ) 20910eadc25SFrank Rowand srctree="$2" 21010eadc25SFrank Rowand shift 2 21110eadc25SFrank Rowand ;; 21210eadc25SFrank Rowand 21310eadc25SFrank Rowand -S ) 21410eadc25SFrank Rowand git_root=`git rev-parse --show-toplevel 2>/dev/null` 21510eadc25SFrank Rowand srctree="${git_root}" 21610eadc25SFrank Rowand shift 21710eadc25SFrank Rowand ;; 21810eadc25SFrank Rowand 21987143fceSFrank Rowand -T | --annotate ) 22087143fceSFrank Rowand if [ "${annotate}" = "" ] ; then 22187143fceSFrank Rowand annotate="-T" 22287143fceSFrank Rowand elif [ "${annotate}" = "-T" ] ; then 22387143fceSFrank Rowand annotate="-T -T" 22487143fceSFrank Rowand fi 22587143fceSFrank Rowand shift 22687143fceSFrank Rowand ;; 22710eadc25SFrank Rowand -u ) 22810eadc25SFrank Rowand dtc_sort="" 22910eadc25SFrank Rowand shift 23010eadc25SFrank Rowand ;; 23110eadc25SFrank Rowand 23210eadc25SFrank Rowand *) 23310eadc25SFrank Rowand if [ "${dtx_file_1}" = "" ] ; then 23410eadc25SFrank Rowand dtx_file_1="$1" 23510eadc25SFrank Rowand elif [ "${dtx_file_2}" = "" ] ; then 23610eadc25SFrank Rowand dtx_file_2="$1" 23710eadc25SFrank Rowand else 23810eadc25SFrank Rowand echo "" >&2 23910eadc25SFrank Rowand echo "ERROR: Unexpected parameter: $1" >&2 24010eadc25SFrank Rowand echo "" >&2 24110eadc25SFrank Rowand exit 2 24210eadc25SFrank Rowand fi 24310eadc25SFrank Rowand shift 24410eadc25SFrank Rowand ;; 24510eadc25SFrank Rowand 24610eadc25SFrank Rowand esac 24710eadc25SFrank Rowand 24810eadc25SFrank Rowanddone 24910eadc25SFrank Rowand 25010eadc25SFrank Rowandif [ "${srctree}" = "" ] ; then 25110eadc25SFrank Rowand srctree="." 25210eadc25SFrank Rowandfi 25310eadc25SFrank Rowand 25410eadc25SFrank Rowandif [ "${dtx_file_2}" != "" ]; then 25510eadc25SFrank Rowand cmd_diff=1 25610eadc25SFrank Rowandfi 25710eadc25SFrank Rowand 25810eadc25SFrank Rowandif (( ${help} )) ; then 25910eadc25SFrank Rowand usage 26010eadc25SFrank Rowand exit 1 26110eadc25SFrank Rowandfi 26210eadc25SFrank Rowand 26310eadc25SFrank Rowand# this must follow check for ${help} 26410eadc25SFrank Rowandif [ "${dtx_file_1}" = "" ]; then 26510eadc25SFrank Rowand echo "" >&2 26610eadc25SFrank Rowand echo "ERROR: parameter DTx required" >&2 26710eadc25SFrank Rowand echo "" >&2 26810eadc25SFrank Rowand exit 2 26910eadc25SFrank Rowandfi 27010eadc25SFrank Rowand 27110eadc25SFrank Rowand 27210eadc25SFrank Rowand# ----- prefer dtc from linux kernel, allow fallback to dtc in $PATH 27310eadc25SFrank Rowand 27410eadc25SFrank Rowandif [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then 27510eadc25SFrank Rowand __KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}" 27610eadc25SFrank Rowandelif [ "${KBUILD_OUTPUT}" = "" ] ; then 27710eadc25SFrank Rowand __KBUILD_OUTPUT="." 27810eadc25SFrank Rowandelse 27910eadc25SFrank Rowand __KBUILD_OUTPUT="${KBUILD_OUTPUT}" 28010eadc25SFrank Rowandfi 28110eadc25SFrank Rowand 28210eadc25SFrank RowandDTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc" 28310eadc25SFrank Rowand 28410eadc25SFrank Rowandif [ ! -x ${DTC} ] ; then 28510eadc25SFrank Rowand __DTC="dtc" 286ca0cd118SGaurav Minocha if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config 2>/dev/null; then 28760c7f4cbSFrank Rowand make_command=' 28860c7f4cbSFrank Rowand make scripts' 28960c7f4cbSFrank Rowand else 29060c7f4cbSFrank Rowand make_command=' 29160c7f4cbSFrank Rowand Enable CONFIG_DTC in the kernel configuration 29260c7f4cbSFrank Rowand make scripts' 29360c7f4cbSFrank Rowand fi 29410eadc25SFrank Rowand if ( ! which ${__DTC} >/dev/null ) ; then 29510eadc25SFrank Rowand 29610eadc25SFrank Rowand # use spaces instead of tabs in the error message 29710eadc25SFrank Rowand cat >&2 <<eod 29810eadc25SFrank Rowand 29910eadc25SFrank RowandERROR: unable to find a 'dtc' program 30010eadc25SFrank Rowand 30110eadc25SFrank Rowand Preferred 'dtc' (built from Linux kernel source tree) was not found or 30210eadc25SFrank Rowand is not executable. 30310eadc25SFrank Rowand 30410eadc25SFrank Rowand 'dtc' is: ${DTC} 30510eadc25SFrank Rowand 30610eadc25SFrank Rowand If it does not exist, create it from the root of the Linux source tree: 30760c7f4cbSFrank Rowand${make_command} 30810eadc25SFrank Rowand 30910eadc25SFrank Rowand If not at the root of the Linux kernel source tree -s SRCTREE or -S 31010eadc25SFrank Rowand may need to be specified to find 'dtc'. 31110eadc25SFrank Rowand 31210eadc25SFrank Rowand If 'O=\${dir}' is specified in your Linux builds, this script requires 31310eadc25SFrank Rowand 'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH 31410eadc25SFrank Rowand before running. 31510eadc25SFrank Rowand 31610eadc25SFrank Rowand If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run 31710eadc25SFrank Rowand this script from the root of the Linux kernel source tree is required. 31810eadc25SFrank Rowand 31910eadc25SFrank Rowand Fallback '${__DTC}' was also not in \${PATH} or is not executable. 32010eadc25SFrank Rowand 32110eadc25SFrank Rowandeod 32210eadc25SFrank Rowand exit 2 32310eadc25SFrank Rowand fi 32410eadc25SFrank Rowand DTC=${__DTC} 32510eadc25SFrank Rowandfi 32610eadc25SFrank Rowand 32710eadc25SFrank Rowand 32810eadc25SFrank Rowand# ----- cpp and dtc flags same as for linux source tree build of .dtb files, 32910eadc25SFrank Rowand# plus directories of the dtx file(s) 33010eadc25SFrank Rowand 33110eadc25SFrank Rowanddtx_path_1_dtc_include="-i `dirname ${dtx_file_1}`" 33210eadc25SFrank Rowand 33310eadc25SFrank Rowanddtx_path_2_dtc_include="" 33410eadc25SFrank Rowandif (( ${cmd_diff} )) ; then 33510eadc25SFrank Rowand dtx_path_2_dtc_include="-i `dirname ${dtx_file_2}`" 33610eadc25SFrank Rowandfi 33710eadc25SFrank Rowand 33810eadc25SFrank Rowandcpp_flags="\ 33910eadc25SFrank Rowand -nostdinc \ 340b4b201d8SFrank Rowand -I${srctree}/scripts/dtc/include-prefixes \ 34110eadc25SFrank Rowand -undef -D__DTS__" 34210eadc25SFrank Rowand 34335f3c984SFrank RowandDTC="\ 34435f3c984SFrank Rowand ${DTC} \ 34535f3c984SFrank Rowand -i ${srctree}/scripts/dtc/include-prefixes \ 34687143fceSFrank Rowand -O dts -qq -f ${dtc_sort} ${annotate} -o -" 34710eadc25SFrank Rowand 34810eadc25SFrank Rowand 34910eadc25SFrank Rowand# ----- do the diff or decompile 35010eadc25SFrank Rowand 35110eadc25SFrank Rowandif (( ${cmd_diff} )) ; then 35210eadc25SFrank Rowand 3531ee1ffe1SGeert Uytterhoeven diff ${diff_flags} ${diff_color} --label "${dtx_file_1}" --label "${dtx_file_2}" \ 35435f3c984SFrank Rowand <(compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}") \ 35535f3c984SFrank Rowand <(compile_to_dts "${dtx_file_2}" "${dtx_path_2_dtc_include}") 35610eadc25SFrank Rowand 35710eadc25SFrank Rowandelse 35810eadc25SFrank Rowand 35935f3c984SFrank Rowand compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}" 36010eadc25SFrank Rowand 36110eadc25SFrank Rowandfi 362