110eadc25SFrank Rowand#! /bin/bash 210eadc25SFrank Rowand 310eadc25SFrank Rowand# Copyright (C) 2015 Frank Rowand 410eadc25SFrank Rowand# 510eadc25SFrank Rowand# This program is free software; you can redistribute it and/or modify 610eadc25SFrank Rowand# it under the terms of the GNU General Public License as published by 710eadc25SFrank Rowand# the Free Software Foundation; version 2 of the License. 810eadc25SFrank Rowand 910eadc25SFrank Rowand 1010eadc25SFrank Rowandusage() { 1110eadc25SFrank Rowand 1210eadc25SFrank Rowand # use spaces instead of tabs in the usage message 1310eadc25SFrank Rowand cat >&2 <<eod 1410eadc25SFrank Rowand 1510eadc25SFrank RowandUsage: 1610eadc25SFrank Rowand 1710eadc25SFrank Rowand `basename $0` DTx 1810eadc25SFrank Rowand decompile DTx 1910eadc25SFrank Rowand 2010eadc25SFrank Rowand `basename $0` DTx_1 DTx_2 2110eadc25SFrank Rowand diff DTx_1 and DTx_2 2210eadc25SFrank Rowand 2310eadc25SFrank Rowand 2410eadc25SFrank Rowand -f print full dts in diff (--unified=99999) 2510eadc25SFrank Rowand -h synonym for --help 2610eadc25SFrank Rowand -help synonym for --help 2710eadc25SFrank Rowand --help print this message and exit 2810eadc25SFrank Rowand -s SRCTREE linux kernel source tree is at path SRCTREE 2910eadc25SFrank Rowand (default is current directory) 3010eadc25SFrank Rowand -S linux kernel source tree is at root of current git repo 3110eadc25SFrank Rowand -u unsorted, do not sort DTx 3210eadc25SFrank Rowand 3310eadc25SFrank Rowand 3410eadc25SFrank RowandEach DTx is processed by the dtc compiler to produce a sorted dts source 3510eadc25SFrank Rowandfile. If DTx is a dts source file then it is pre-processed in the same 3610eadc25SFrank Rowandmanner as done for the compile of the dts source file in the Linux kernel 3710eadc25SFrank Rowandbuild system ('#include' and '/include/' directives are processed). 3810eadc25SFrank Rowand 3910eadc25SFrank RowandIf two DTx are provided, the resulting dts source files are diffed. 4010eadc25SFrank Rowand 4110eadc25SFrank RowandIf DTx is a directory, it is treated as a DT subtree, such as 4210eadc25SFrank Rowand /proc/device-tree. 4310eadc25SFrank Rowand 4410eadc25SFrank RowandIf DTx contains the binary blob magic value in the first four bytes, 4510eadc25SFrank Rowand it is treated as a binary blob (aka .dtb or FDT). 4610eadc25SFrank Rowand 4710eadc25SFrank RowandOtherwise DTx is treated as a dts source file (aka .dts). 4810eadc25SFrank Rowand 4910eadc25SFrank Rowand If this script is not run from the root of the linux source tree, 5010eadc25SFrank Rowand and DTx utilizes '#include' or '/include/' then the path of the 5110eadc25SFrank Rowand linux source tree can be provided by '-s SRCTREE' or '-S' so that 5210eadc25SFrank Rowand include paths will be set properly. 5310eadc25SFrank Rowand 5410eadc25SFrank Rowand The shell variable \${ARCH} must provide the architecture containing 5510eadc25SFrank Rowand the dts source file for include paths to be set properly for '#include' 5610eadc25SFrank Rowand or '/include/' to be processed. 5710eadc25SFrank Rowand 5810eadc25SFrank Rowand If DTx_1 and DTx_2 are in different architectures, then this script 5910eadc25SFrank Rowand may not work since \${ARCH} is part of the include path. Two possible 6010eadc25SFrank Rowand workarounds: 6110eadc25SFrank Rowand 6210eadc25SFrank Rowand `basename $0` \\ 6310eadc25SFrank Rowand <(ARCH=arch_of_dtx_1 `basename $0` DTx_1) \\ 6410eadc25SFrank Rowand <(ARCH=arch_of_dtx_2 `basename $0` DTx_2) 6510eadc25SFrank Rowand 6610eadc25SFrank Rowand `basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts 6710eadc25SFrank Rowand `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts 6810eadc25SFrank Rowand `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts 6910eadc25SFrank Rowand rm tmp_dtx_1.dts tmp_dtx_2.dts 7010eadc25SFrank Rowand 7110eadc25SFrank Rowand If DTx_1 and DTx_2 are in different directories, then this script will 7210eadc25SFrank Rowand add the path of DTx_1 and DTx_2 to the include paths. If DTx_2 includes 7310eadc25SFrank Rowand a local file that exists in both the path of DTx_1 and DTx_2 then the 7410eadc25SFrank Rowand file in the path of DTx_1 will incorrectly be included. Possible 7510eadc25SFrank Rowand workaround: 7610eadc25SFrank Rowand 7710eadc25SFrank Rowand `basename $0` DTx_1 >tmp_dtx_1.dts 7810eadc25SFrank Rowand `basename $0` DTx_2 >tmp_dtx_2.dts 7910eadc25SFrank Rowand `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts 8010eadc25SFrank Rowand rm tmp_dtx_1.dts tmp_dtx_2.dts 8110eadc25SFrank Rowand 8210eadc25SFrank Rowandeod 8310eadc25SFrank Rowand} 8410eadc25SFrank Rowand 8510eadc25SFrank Rowand 8610eadc25SFrank Rowandcompile_to_dts() { 8710eadc25SFrank Rowand 8810eadc25SFrank Rowand dtx="$1" 89*35f3c984SFrank Rowand dtc_include="$2" 9010eadc25SFrank Rowand 9110eadc25SFrank Rowand if [ -d "${dtx}" ] ; then 9210eadc25SFrank Rowand 9310eadc25SFrank Rowand # ----- input is file tree 9410eadc25SFrank Rowand 9510eadc25SFrank Rowand if ( ! ${DTC} -I fs ${dtx} ) ; then 9610eadc25SFrank Rowand exit 3 9710eadc25SFrank Rowand fi 9810eadc25SFrank Rowand 9910eadc25SFrank Rowand elif [ -f "${dtx}" ] && [ -r "${dtx}" ] ; then 10010eadc25SFrank Rowand 10110eadc25SFrank Rowand magic=`hexdump -n 4 -e '/1 "%02x"' ${dtx}` 10210eadc25SFrank Rowand if [ "${magic}" = "d00dfeed" ] ; then 10310eadc25SFrank Rowand 10410eadc25SFrank Rowand # ----- input is FDT (binary blob) 10510eadc25SFrank Rowand 10610eadc25SFrank Rowand if ( ! ${DTC} -I dtb ${dtx} ) ; then 10710eadc25SFrank Rowand exit 3 10810eadc25SFrank Rowand fi 10910eadc25SFrank Rowand 11010eadc25SFrank Rowand return 11110eadc25SFrank Rowand 11210eadc25SFrank Rowand fi 11310eadc25SFrank Rowand 11410eadc25SFrank Rowand # ----- input is DTS (source) 11510eadc25SFrank Rowand 11610eadc25SFrank Rowand if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \ 117*35f3c984SFrank Rowand | ${DTC} ${dtc_include} -I dts ) ; then 11810eadc25SFrank Rowand return 11910eadc25SFrank Rowand fi 12010eadc25SFrank Rowand 12110eadc25SFrank Rowand echo "" >&2 12210eadc25SFrank Rowand echo "Possible hints to resolve the above error:" >&2 12310eadc25SFrank Rowand echo " (hints might not fix the problem)" >&2 12410eadc25SFrank Rowand 12510eadc25SFrank Rowand hint_given=0 12610eadc25SFrank Rowand 12710eadc25SFrank Rowand if [ "${ARCH}" = "" ] ; then 12810eadc25SFrank Rowand hint_given=1 12910eadc25SFrank Rowand echo "" >&2 13010eadc25SFrank Rowand echo " shell variable \$ARCH not set" >&2 13110eadc25SFrank Rowand fi 13210eadc25SFrank Rowand 13310eadc25SFrank Rowand dtx_arch=`echo "/${dtx}" | sed -e 's|.*/arch/||' -e 's|/.*||'` 13410eadc25SFrank Rowand 13510eadc25SFrank Rowand if [ "${dtx_arch}" != "" -a "${dtx_arch}" != "${ARCH}" ] ; then 13610eadc25SFrank Rowand hint_given=1 13710eadc25SFrank Rowand echo "" >&2 13810eadc25SFrank Rowand echo " architecture ${dtx_arch} is in file path," >&2 13910eadc25SFrank Rowand echo " but does not match shell variable \$ARCH" >&2 14060c7f4cbSFrank Rowand echo " >>\$ARCH<< is: >>${ARCH}<<" >&2 14110eadc25SFrank Rowand fi 14210eadc25SFrank Rowand 14310eadc25SFrank Rowand if [ ! -d ${srctree}/arch/${ARCH} ] ; then 14410eadc25SFrank Rowand hint_given=1 14510eadc25SFrank Rowand echo "" >&2 14610eadc25SFrank Rowand echo " ${srctree}/arch/${ARCH}/ does not exist" >&2 14710eadc25SFrank Rowand echo " Is \$ARCH='${ARCH}' correct?" >&2 14810eadc25SFrank Rowand echo " Possible fix: use '-s' option" >&2 14910eadc25SFrank Rowand 15010eadc25SFrank Rowand git_root=`git rev-parse --show-toplevel 2>/dev/null` 15110eadc25SFrank Rowand if [ -d ${git_root}/arch/ ] ; then 15210eadc25SFrank Rowand echo " Possible fix: use '-S' option" >&2 15310eadc25SFrank Rowand fi 15410eadc25SFrank Rowand fi 15510eadc25SFrank Rowand 15610eadc25SFrank Rowand if [ $hint_given = 0 ] ; then 15710eadc25SFrank Rowand echo "" >&2 15810eadc25SFrank Rowand echo " No hints available." >&2 15910eadc25SFrank Rowand fi 16010eadc25SFrank Rowand 16110eadc25SFrank Rowand echo "" >&2 16210eadc25SFrank Rowand 16310eadc25SFrank Rowand exit 3 16410eadc25SFrank Rowand 16510eadc25SFrank Rowand else 16610eadc25SFrank Rowand echo "" >&2 16710eadc25SFrank Rowand echo "ERROR: ${dtx} does not exist or is not readable" >&2 16810eadc25SFrank Rowand echo "" >&2 16910eadc25SFrank Rowand exit 2 17010eadc25SFrank Rowand fi 17110eadc25SFrank Rowand 17210eadc25SFrank Rowand} 17310eadc25SFrank Rowand 17410eadc25SFrank Rowand 17510eadc25SFrank Rowand# ----- start of script 17610eadc25SFrank Rowand 17710eadc25SFrank Rowandcmd_diff=0 17810eadc25SFrank Rowanddiff_flags="-u" 17910eadc25SFrank Rowanddtx_file_1="" 18010eadc25SFrank Rowanddtx_file_2="" 18110eadc25SFrank Rowanddtc_sort="-s" 18210eadc25SFrank Rowandhelp=0 18310eadc25SFrank Rowandsrctree="" 18410eadc25SFrank Rowand 18510eadc25SFrank Rowand 18610eadc25SFrank Rowandwhile [ $# -gt 0 ] ; do 18710eadc25SFrank Rowand 18810eadc25SFrank Rowand case $1 in 18910eadc25SFrank Rowand 19010eadc25SFrank Rowand -f ) 19110eadc25SFrank Rowand diff_flags="--unified=999999" 19210eadc25SFrank Rowand shift 19310eadc25SFrank Rowand ;; 19410eadc25SFrank Rowand 19510eadc25SFrank Rowand -h | -help | --help ) 19610eadc25SFrank Rowand help=1 19710eadc25SFrank Rowand shift 19810eadc25SFrank Rowand ;; 19910eadc25SFrank Rowand 20010eadc25SFrank Rowand -s ) 20110eadc25SFrank Rowand srctree="$2" 20210eadc25SFrank Rowand shift 2 20310eadc25SFrank Rowand ;; 20410eadc25SFrank Rowand 20510eadc25SFrank Rowand -S ) 20610eadc25SFrank Rowand git_root=`git rev-parse --show-toplevel 2>/dev/null` 20710eadc25SFrank Rowand srctree="${git_root}" 20810eadc25SFrank Rowand shift 20910eadc25SFrank Rowand ;; 21010eadc25SFrank Rowand 21110eadc25SFrank Rowand -u ) 21210eadc25SFrank Rowand dtc_sort="" 21310eadc25SFrank Rowand shift 21410eadc25SFrank Rowand ;; 21510eadc25SFrank Rowand 21610eadc25SFrank Rowand *) 21710eadc25SFrank Rowand if [ "${dtx_file_1}" = "" ] ; then 21810eadc25SFrank Rowand dtx_file_1="$1" 21910eadc25SFrank Rowand elif [ "${dtx_file_2}" = "" ] ; then 22010eadc25SFrank Rowand dtx_file_2="$1" 22110eadc25SFrank Rowand else 22210eadc25SFrank Rowand echo "" >&2 22310eadc25SFrank Rowand echo "ERROR: Unexpected parameter: $1" >&2 22410eadc25SFrank Rowand echo "" >&2 22510eadc25SFrank Rowand exit 2 22610eadc25SFrank Rowand fi 22710eadc25SFrank Rowand shift 22810eadc25SFrank Rowand ;; 22910eadc25SFrank Rowand 23010eadc25SFrank Rowand esac 23110eadc25SFrank Rowand 23210eadc25SFrank Rowanddone 23310eadc25SFrank Rowand 23410eadc25SFrank Rowandif [ "${srctree}" = "" ] ; then 23510eadc25SFrank Rowand srctree="." 23610eadc25SFrank Rowandfi 23710eadc25SFrank Rowand 23810eadc25SFrank Rowandif [ "${dtx_file_2}" != "" ]; then 23910eadc25SFrank Rowand cmd_diff=1 24010eadc25SFrank Rowandfi 24110eadc25SFrank Rowand 24210eadc25SFrank Rowandif (( ${help} )) ; then 24310eadc25SFrank Rowand usage 24410eadc25SFrank Rowand exit 1 24510eadc25SFrank Rowandfi 24610eadc25SFrank Rowand 24710eadc25SFrank Rowand# this must follow check for ${help} 24810eadc25SFrank Rowandif [ "${dtx_file_1}" = "" ]; then 24910eadc25SFrank Rowand echo "" >&2 25010eadc25SFrank Rowand echo "ERROR: parameter DTx required" >&2 25110eadc25SFrank Rowand echo "" >&2 25210eadc25SFrank Rowand exit 2 25310eadc25SFrank Rowandfi 25410eadc25SFrank Rowand 25510eadc25SFrank Rowand 25610eadc25SFrank Rowand# ----- prefer dtc from linux kernel, allow fallback to dtc in $PATH 25710eadc25SFrank Rowand 25810eadc25SFrank Rowandif [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then 25910eadc25SFrank Rowand __KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}" 26010eadc25SFrank Rowandelif [ "${KBUILD_OUTPUT}" = "" ] ; then 26110eadc25SFrank Rowand __KBUILD_OUTPUT="." 26210eadc25SFrank Rowandelse 26310eadc25SFrank Rowand __KBUILD_OUTPUT="${KBUILD_OUTPUT}" 26410eadc25SFrank Rowandfi 26510eadc25SFrank Rowand 26610eadc25SFrank RowandDTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc" 26710eadc25SFrank Rowand 26810eadc25SFrank Rowandif [ ! -x ${DTC} ] ; then 26910eadc25SFrank Rowand __DTC="dtc" 270ca0cd118SGaurav Minocha if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config 2>/dev/null; then 27160c7f4cbSFrank Rowand make_command=' 27260c7f4cbSFrank Rowand make scripts' 27360c7f4cbSFrank Rowand else 27460c7f4cbSFrank Rowand make_command=' 27560c7f4cbSFrank Rowand Enable CONFIG_DTC in the kernel configuration 27660c7f4cbSFrank Rowand make scripts' 27760c7f4cbSFrank Rowand fi 27810eadc25SFrank Rowand if ( ! which ${__DTC} >/dev/null ) ; then 27910eadc25SFrank Rowand 28010eadc25SFrank Rowand # use spaces instead of tabs in the error message 28110eadc25SFrank Rowand cat >&2 <<eod 28210eadc25SFrank Rowand 28310eadc25SFrank RowandERROR: unable to find a 'dtc' program 28410eadc25SFrank Rowand 28510eadc25SFrank Rowand Preferred 'dtc' (built from Linux kernel source tree) was not found or 28610eadc25SFrank Rowand is not executable. 28710eadc25SFrank Rowand 28810eadc25SFrank Rowand 'dtc' is: ${DTC} 28910eadc25SFrank Rowand 29010eadc25SFrank Rowand If it does not exist, create it from the root of the Linux source tree: 29160c7f4cbSFrank Rowand${make_command} 29210eadc25SFrank Rowand 29310eadc25SFrank Rowand If not at the root of the Linux kernel source tree -s SRCTREE or -S 29410eadc25SFrank Rowand may need to be specified to find 'dtc'. 29510eadc25SFrank Rowand 29610eadc25SFrank Rowand If 'O=\${dir}' is specified in your Linux builds, this script requires 29710eadc25SFrank Rowand 'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH 29810eadc25SFrank Rowand before running. 29910eadc25SFrank Rowand 30010eadc25SFrank Rowand If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run 30110eadc25SFrank Rowand this script from the root of the Linux kernel source tree is required. 30210eadc25SFrank Rowand 30310eadc25SFrank Rowand Fallback '${__DTC}' was also not in \${PATH} or is not executable. 30410eadc25SFrank Rowand 30510eadc25SFrank Rowandeod 30610eadc25SFrank Rowand exit 2 30710eadc25SFrank Rowand fi 30810eadc25SFrank Rowand DTC=${__DTC} 30910eadc25SFrank Rowandfi 31010eadc25SFrank Rowand 31110eadc25SFrank Rowand 31210eadc25SFrank Rowand# ----- cpp and dtc flags same as for linux source tree build of .dtb files, 31310eadc25SFrank Rowand# plus directories of the dtx file(s) 31410eadc25SFrank Rowand 31510eadc25SFrank Rowanddtx_path_1_dtc_include="-i `dirname ${dtx_file_1}`" 31610eadc25SFrank Rowand 31710eadc25SFrank Rowanddtx_path_2_dtc_include="" 31810eadc25SFrank Rowandif (( ${cmd_diff} )) ; then 31910eadc25SFrank Rowand dtx_path_2_dtc_include="-i `dirname ${dtx_file_2}`" 32010eadc25SFrank Rowandfi 32110eadc25SFrank Rowand 32210eadc25SFrank Rowandcpp_flags="\ 32310eadc25SFrank Rowand -nostdinc \ 324b4b201d8SFrank Rowand -I${srctree}/scripts/dtc/include-prefixes \ 32510eadc25SFrank Rowand -undef -D__DTS__" 32610eadc25SFrank Rowand 327*35f3c984SFrank RowandDTC="\ 328*35f3c984SFrank Rowand ${DTC} \ 329*35f3c984SFrank Rowand -i ${srctree}/scripts/dtc/include-prefixes \ 330*35f3c984SFrank Rowand -O dts -qq -f ${dtc_sort} -o -" 33110eadc25SFrank Rowand 33210eadc25SFrank Rowand 33310eadc25SFrank Rowand# ----- do the diff or decompile 33410eadc25SFrank Rowand 33510eadc25SFrank Rowandif (( ${cmd_diff} )) ; then 33610eadc25SFrank Rowand 3377782b144SGeert Uytterhoeven diff ${diff_flags} --label "${dtx_file_1}" --label "${dtx_file_2}" \ 338*35f3c984SFrank Rowand <(compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}") \ 339*35f3c984SFrank Rowand <(compile_to_dts "${dtx_file_2}" "${dtx_path_2_dtc_include}") 34010eadc25SFrank Rowand 34110eadc25SFrank Rowandelse 34210eadc25SFrank Rowand 343*35f3c984SFrank Rowand compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}" 34410eadc25SFrank Rowand 34510eadc25SFrank Rowandfi 346