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" 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} \ 11610eadc25SFrank Rowand | ${DTC} -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 139*60c7f4cbSFrank 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 17610eadc25SFrank Rowandcmd_diff=0 17710eadc25SFrank Rowanddiff_flags="-u" 17810eadc25SFrank Rowanddtx_file_1="" 17910eadc25SFrank Rowanddtx_file_2="" 18010eadc25SFrank Rowanddtc_sort="-s" 18110eadc25SFrank Rowandhelp=0 18210eadc25SFrank Rowandsrctree="" 18310eadc25SFrank Rowand 18410eadc25SFrank Rowand 18510eadc25SFrank Rowandwhile [ $# -gt 0 ] ; do 18610eadc25SFrank Rowand 18710eadc25SFrank Rowand case $1 in 18810eadc25SFrank Rowand 18910eadc25SFrank Rowand -f ) 19010eadc25SFrank Rowand diff_flags="--unified=999999" 19110eadc25SFrank Rowand shift 19210eadc25SFrank Rowand ;; 19310eadc25SFrank Rowand 19410eadc25SFrank Rowand -h | -help | --help ) 19510eadc25SFrank Rowand help=1 19610eadc25SFrank Rowand shift 19710eadc25SFrank Rowand ;; 19810eadc25SFrank Rowand 19910eadc25SFrank Rowand -s ) 20010eadc25SFrank Rowand srctree="$2" 20110eadc25SFrank Rowand shift 2 20210eadc25SFrank Rowand ;; 20310eadc25SFrank Rowand 20410eadc25SFrank Rowand -S ) 20510eadc25SFrank Rowand git_root=`git rev-parse --show-toplevel 2>/dev/null` 20610eadc25SFrank Rowand srctree="${git_root}" 20710eadc25SFrank Rowand shift 20810eadc25SFrank Rowand ;; 20910eadc25SFrank Rowand 21010eadc25SFrank Rowand -u ) 21110eadc25SFrank Rowand dtc_sort="" 21210eadc25SFrank Rowand shift 21310eadc25SFrank Rowand ;; 21410eadc25SFrank Rowand 21510eadc25SFrank Rowand *) 21610eadc25SFrank Rowand if [ "${dtx_file_1}" = "" ] ; then 21710eadc25SFrank Rowand dtx_file_1="$1" 21810eadc25SFrank Rowand elif [ "${dtx_file_2}" = "" ] ; then 21910eadc25SFrank Rowand dtx_file_2="$1" 22010eadc25SFrank Rowand else 22110eadc25SFrank Rowand echo "" >&2 22210eadc25SFrank Rowand echo "ERROR: Unexpected parameter: $1" >&2 22310eadc25SFrank Rowand echo "" >&2 22410eadc25SFrank Rowand exit 2 22510eadc25SFrank Rowand fi 22610eadc25SFrank Rowand shift 22710eadc25SFrank Rowand ;; 22810eadc25SFrank Rowand 22910eadc25SFrank Rowand esac 23010eadc25SFrank Rowand 23110eadc25SFrank Rowanddone 23210eadc25SFrank Rowand 23310eadc25SFrank Rowandif [ "${srctree}" = "" ] ; then 23410eadc25SFrank Rowand srctree="." 23510eadc25SFrank Rowandfi 23610eadc25SFrank Rowand 23710eadc25SFrank Rowandif [ "${dtx_file_2}" != "" ]; then 23810eadc25SFrank Rowand cmd_diff=1 23910eadc25SFrank Rowandfi 24010eadc25SFrank Rowand 24110eadc25SFrank Rowandif (( ${help} )) ; then 24210eadc25SFrank Rowand usage 24310eadc25SFrank Rowand exit 1 24410eadc25SFrank Rowandfi 24510eadc25SFrank Rowand 24610eadc25SFrank Rowand# this must follow check for ${help} 24710eadc25SFrank Rowandif [ "${dtx_file_1}" = "" ]; then 24810eadc25SFrank Rowand echo "" >&2 24910eadc25SFrank Rowand echo "ERROR: parameter DTx required" >&2 25010eadc25SFrank Rowand echo "" >&2 25110eadc25SFrank Rowand exit 2 25210eadc25SFrank Rowandfi 25310eadc25SFrank Rowand 25410eadc25SFrank Rowand 25510eadc25SFrank Rowand# ----- prefer dtc from linux kernel, allow fallback to dtc in $PATH 25610eadc25SFrank Rowand 25710eadc25SFrank Rowandif [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then 25810eadc25SFrank Rowand __KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}" 25910eadc25SFrank Rowandelif [ "${KBUILD_OUTPUT}" = "" ] ; then 26010eadc25SFrank Rowand __KBUILD_OUTPUT="." 26110eadc25SFrank Rowandelse 26210eadc25SFrank Rowand __KBUILD_OUTPUT="${KBUILD_OUTPUT}" 26310eadc25SFrank Rowandfi 26410eadc25SFrank Rowand 26510eadc25SFrank RowandDTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc" 26610eadc25SFrank Rowand 26710eadc25SFrank Rowandif [ ! -x ${DTC} ] ; then 26810eadc25SFrank Rowand __DTC="dtc" 269*60c7f4cbSFrank Rowand if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config ; then 270*60c7f4cbSFrank Rowand make_command=' 271*60c7f4cbSFrank Rowand make scripts' 272*60c7f4cbSFrank Rowand else 273*60c7f4cbSFrank Rowand make_command=' 274*60c7f4cbSFrank Rowand Enable CONFIG_DTC in the kernel configuration 275*60c7f4cbSFrank Rowand make scripts' 276*60c7f4cbSFrank Rowand fi 27710eadc25SFrank Rowand if ( ! which ${__DTC} >/dev/null ) ; then 27810eadc25SFrank Rowand 27910eadc25SFrank Rowand # use spaces instead of tabs in the error message 28010eadc25SFrank Rowand cat >&2 <<eod 28110eadc25SFrank Rowand 28210eadc25SFrank RowandERROR: unable to find a 'dtc' program 28310eadc25SFrank Rowand 28410eadc25SFrank Rowand Preferred 'dtc' (built from Linux kernel source tree) was not found or 28510eadc25SFrank Rowand is not executable. 28610eadc25SFrank Rowand 28710eadc25SFrank Rowand 'dtc' is: ${DTC} 28810eadc25SFrank Rowand 28910eadc25SFrank Rowand If it does not exist, create it from the root of the Linux source tree: 290*60c7f4cbSFrank Rowand${make_command} 29110eadc25SFrank Rowand 29210eadc25SFrank Rowand If not at the root of the Linux kernel source tree -s SRCTREE or -S 29310eadc25SFrank Rowand may need to be specified to find 'dtc'. 29410eadc25SFrank Rowand 29510eadc25SFrank Rowand If 'O=\${dir}' is specified in your Linux builds, this script requires 29610eadc25SFrank Rowand 'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH 29710eadc25SFrank Rowand before running. 29810eadc25SFrank Rowand 29910eadc25SFrank Rowand If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run 30010eadc25SFrank Rowand this script from the root of the Linux kernel source tree is required. 30110eadc25SFrank Rowand 30210eadc25SFrank Rowand Fallback '${__DTC}' was also not in \${PATH} or is not executable. 30310eadc25SFrank Rowand 30410eadc25SFrank Rowandeod 30510eadc25SFrank Rowand exit 2 30610eadc25SFrank Rowand fi 30710eadc25SFrank Rowand DTC=${__DTC} 30810eadc25SFrank Rowandfi 30910eadc25SFrank Rowand 31010eadc25SFrank Rowand 31110eadc25SFrank Rowand# ----- cpp and dtc flags same as for linux source tree build of .dtb files, 31210eadc25SFrank Rowand# plus directories of the dtx file(s) 31310eadc25SFrank Rowand 31410eadc25SFrank Rowanddtx_path_1_dtc_include="-i `dirname ${dtx_file_1}`" 31510eadc25SFrank Rowand 31610eadc25SFrank Rowanddtx_path_2_dtc_include="" 31710eadc25SFrank Rowandif (( ${cmd_diff} )) ; then 31810eadc25SFrank Rowand dtx_path_2_dtc_include="-i `dirname ${dtx_file_2}`" 31910eadc25SFrank Rowandfi 32010eadc25SFrank Rowand 32110eadc25SFrank Rowandcpp_flags="\ 32210eadc25SFrank Rowand -nostdinc \ 32310eadc25SFrank Rowand -I${srctree}/arch/${ARCH}/boot/dts \ 32410eadc25SFrank Rowand -I${srctree}/arch/${ARCH}/boot/dts/include \ 32510eadc25SFrank Rowand -I${srctree}/drivers/of/testcase-data \ 32610eadc25SFrank Rowand -undef -D__DTS__" 32710eadc25SFrank Rowand 32810eadc25SFrank Rowanddtc_flags="\ 32910eadc25SFrank Rowand -i ${srctree}/arch/${ARCH}/boot/dts/ \ 33010eadc25SFrank Rowand -i ${srctree}/kernel/dts \ 33110eadc25SFrank Rowand ${dtx_path_1_dtc_include} \ 33210eadc25SFrank Rowand ${dtx_path_2_dtc_include}" 33310eadc25SFrank Rowand 33410eadc25SFrank RowandDTC="${DTC} ${dtc_flags} -O dts -qq -f ${dtc_sort} -o -" 33510eadc25SFrank Rowand 33610eadc25SFrank Rowand 33710eadc25SFrank Rowand# ----- do the diff or decompile 33810eadc25SFrank Rowand 33910eadc25SFrank Rowandif (( ${cmd_diff} )) ; then 34010eadc25SFrank Rowand 34110eadc25SFrank Rowand diff ${diff_flags} \ 34210eadc25SFrank Rowand <(compile_to_dts "${dtx_file_1}") \ 34310eadc25SFrank Rowand <(compile_to_dts "${dtx_file_2}") 34410eadc25SFrank Rowand 34510eadc25SFrank Rowandelse 34610eadc25SFrank Rowand 34710eadc25SFrank Rowand compile_to_dts "${dtx_file_1}" 34810eadc25SFrank Rowand 34910eadc25SFrank Rowandfi 350