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 24*87143fceSFrank Rowand --annotate synonym for -T 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 32*87143fceSFrank Rowand -T Annotate output .dts with input source file and line (-T -T for more details) 3310eadc25SFrank Rowand -u unsorted, do not sort DTx 3410eadc25SFrank Rowand 3510eadc25SFrank Rowand 3610eadc25SFrank RowandEach DTx is processed by the dtc compiler to produce a sorted dts source 3710eadc25SFrank Rowandfile. If DTx is a dts source file then it is pre-processed in the same 3810eadc25SFrank Rowandmanner as done for the compile of the dts source file in the Linux kernel 3910eadc25SFrank Rowandbuild system ('#include' and '/include/' directives are processed). 4010eadc25SFrank Rowand 4110eadc25SFrank RowandIf two DTx are provided, the resulting dts source files are diffed. 4210eadc25SFrank Rowand 4310eadc25SFrank RowandIf DTx is a directory, it is treated as a DT subtree, such as 4410eadc25SFrank Rowand /proc/device-tree. 4510eadc25SFrank Rowand 4610eadc25SFrank RowandIf DTx contains the binary blob magic value in the first four bytes, 4710eadc25SFrank Rowand it is treated as a binary blob (aka .dtb or FDT). 4810eadc25SFrank Rowand 4910eadc25SFrank RowandOtherwise DTx is treated as a dts source file (aka .dts). 5010eadc25SFrank Rowand 5110eadc25SFrank Rowand If this script is not run from the root of the linux source tree, 5210eadc25SFrank Rowand and DTx utilizes '#include' or '/include/' then the path of the 5310eadc25SFrank Rowand linux source tree can be provided by '-s SRCTREE' or '-S' so that 5410eadc25SFrank Rowand include paths will be set properly. 5510eadc25SFrank Rowand 5610eadc25SFrank Rowand The shell variable \${ARCH} must provide the architecture containing 5710eadc25SFrank Rowand the dts source file for include paths to be set properly for '#include' 5810eadc25SFrank Rowand or '/include/' to be processed. 5910eadc25SFrank Rowand 6010eadc25SFrank Rowand If DTx_1 and DTx_2 are in different architectures, then this script 6110eadc25SFrank Rowand may not work since \${ARCH} is part of the include path. Two possible 6210eadc25SFrank Rowand workarounds: 6310eadc25SFrank Rowand 6410eadc25SFrank Rowand `basename $0` \\ 6510eadc25SFrank Rowand <(ARCH=arch_of_dtx_1 `basename $0` DTx_1) \\ 6610eadc25SFrank Rowand <(ARCH=arch_of_dtx_2 `basename $0` DTx_2) 6710eadc25SFrank Rowand 6810eadc25SFrank Rowand `basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts 6910eadc25SFrank Rowand `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts 7010eadc25SFrank Rowand `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts 7110eadc25SFrank Rowand rm tmp_dtx_1.dts tmp_dtx_2.dts 7210eadc25SFrank Rowand 7310eadc25SFrank Rowand If DTx_1 and DTx_2 are in different directories, then this script will 7410eadc25SFrank Rowand add the path of DTx_1 and DTx_2 to the include paths. If DTx_2 includes 7510eadc25SFrank Rowand a local file that exists in both the path of DTx_1 and DTx_2 then the 7610eadc25SFrank Rowand file in the path of DTx_1 will incorrectly be included. Possible 7710eadc25SFrank Rowand workaround: 7810eadc25SFrank Rowand 7910eadc25SFrank Rowand `basename $0` DTx_1 >tmp_dtx_1.dts 8010eadc25SFrank Rowand `basename $0` DTx_2 >tmp_dtx_2.dts 8110eadc25SFrank Rowand `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts 8210eadc25SFrank Rowand rm tmp_dtx_1.dts tmp_dtx_2.dts 8310eadc25SFrank Rowand 8410eadc25SFrank Rowandeod 8510eadc25SFrank Rowand} 8610eadc25SFrank Rowand 8710eadc25SFrank Rowand 8810eadc25SFrank Rowandcompile_to_dts() { 8910eadc25SFrank Rowand 9010eadc25SFrank Rowand dtx="$1" 9135f3c984SFrank Rowand dtc_include="$2" 9210eadc25SFrank Rowand 9310eadc25SFrank Rowand if [ -d "${dtx}" ] ; then 9410eadc25SFrank Rowand 9510eadc25SFrank Rowand # ----- input is file tree 9610eadc25SFrank Rowand 9710eadc25SFrank Rowand if ( ! ${DTC} -I fs ${dtx} ) ; then 9810eadc25SFrank Rowand exit 3 9910eadc25SFrank Rowand fi 10010eadc25SFrank Rowand 10110eadc25SFrank Rowand elif [ -f "${dtx}" ] && [ -r "${dtx}" ] ; then 10210eadc25SFrank Rowand 10310eadc25SFrank Rowand magic=`hexdump -n 4 -e '/1 "%02x"' ${dtx}` 10410eadc25SFrank Rowand if [ "${magic}" = "d00dfeed" ] ; then 10510eadc25SFrank Rowand 10610eadc25SFrank Rowand # ----- input is FDT (binary blob) 10710eadc25SFrank Rowand 10810eadc25SFrank Rowand if ( ! ${DTC} -I dtb ${dtx} ) ; then 10910eadc25SFrank Rowand exit 3 11010eadc25SFrank Rowand fi 11110eadc25SFrank Rowand 11210eadc25SFrank Rowand return 11310eadc25SFrank Rowand 11410eadc25SFrank Rowand fi 11510eadc25SFrank Rowand 11610eadc25SFrank Rowand # ----- input is DTS (source) 11710eadc25SFrank Rowand 11810eadc25SFrank Rowand if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \ 11935f3c984SFrank Rowand | ${DTC} ${dtc_include} -I dts ) ; then 12010eadc25SFrank Rowand return 12110eadc25SFrank Rowand fi 12210eadc25SFrank Rowand 12310eadc25SFrank Rowand echo "" >&2 12410eadc25SFrank Rowand echo "Possible hints to resolve the above error:" >&2 12510eadc25SFrank Rowand echo " (hints might not fix the problem)" >&2 12610eadc25SFrank Rowand 12710eadc25SFrank Rowand hint_given=0 12810eadc25SFrank Rowand 12910eadc25SFrank Rowand if [ "${ARCH}" = "" ] ; then 13010eadc25SFrank Rowand hint_given=1 13110eadc25SFrank Rowand echo "" >&2 13210eadc25SFrank Rowand echo " shell variable \$ARCH not set" >&2 13310eadc25SFrank Rowand fi 13410eadc25SFrank Rowand 13510eadc25SFrank Rowand dtx_arch=`echo "/${dtx}" | sed -e 's|.*/arch/||' -e 's|/.*||'` 13610eadc25SFrank Rowand 13710eadc25SFrank Rowand if [ "${dtx_arch}" != "" -a "${dtx_arch}" != "${ARCH}" ] ; then 13810eadc25SFrank Rowand hint_given=1 13910eadc25SFrank Rowand echo "" >&2 14010eadc25SFrank Rowand echo " architecture ${dtx_arch} is in file path," >&2 14110eadc25SFrank Rowand echo " but does not match shell variable \$ARCH" >&2 14260c7f4cbSFrank Rowand echo " >>\$ARCH<< is: >>${ARCH}<<" >&2 14310eadc25SFrank Rowand fi 14410eadc25SFrank Rowand 14510eadc25SFrank Rowand if [ ! -d ${srctree}/arch/${ARCH} ] ; then 14610eadc25SFrank Rowand hint_given=1 14710eadc25SFrank Rowand echo "" >&2 14810eadc25SFrank Rowand echo " ${srctree}/arch/${ARCH}/ does not exist" >&2 14910eadc25SFrank Rowand echo " Is \$ARCH='${ARCH}' correct?" >&2 15010eadc25SFrank Rowand echo " Possible fix: use '-s' option" >&2 15110eadc25SFrank Rowand 15210eadc25SFrank Rowand git_root=`git rev-parse --show-toplevel 2>/dev/null` 15310eadc25SFrank Rowand if [ -d ${git_root}/arch/ ] ; then 15410eadc25SFrank Rowand echo " Possible fix: use '-S' option" >&2 15510eadc25SFrank Rowand fi 15610eadc25SFrank Rowand fi 15710eadc25SFrank Rowand 15810eadc25SFrank Rowand if [ $hint_given = 0 ] ; then 15910eadc25SFrank Rowand echo "" >&2 16010eadc25SFrank Rowand echo " No hints available." >&2 16110eadc25SFrank Rowand fi 16210eadc25SFrank Rowand 16310eadc25SFrank Rowand echo "" >&2 16410eadc25SFrank Rowand 16510eadc25SFrank Rowand exit 3 16610eadc25SFrank Rowand 16710eadc25SFrank Rowand else 16810eadc25SFrank Rowand echo "" >&2 16910eadc25SFrank Rowand echo "ERROR: ${dtx} does not exist or is not readable" >&2 17010eadc25SFrank Rowand echo "" >&2 17110eadc25SFrank Rowand exit 2 17210eadc25SFrank Rowand fi 17310eadc25SFrank Rowand 17410eadc25SFrank Rowand} 17510eadc25SFrank Rowand 17610eadc25SFrank Rowand 17710eadc25SFrank Rowand# ----- start of script 17810eadc25SFrank Rowand 179*87143fceSFrank Rowandannotate="" 18010eadc25SFrank Rowandcmd_diff=0 18110eadc25SFrank Rowanddiff_flags="-u" 18210eadc25SFrank Rowanddtx_file_1="" 18310eadc25SFrank Rowanddtx_file_2="" 18410eadc25SFrank Rowanddtc_sort="-s" 18510eadc25SFrank Rowandhelp=0 18610eadc25SFrank Rowandsrctree="" 18710eadc25SFrank Rowand 18810eadc25SFrank Rowand 18910eadc25SFrank Rowandwhile [ $# -gt 0 ] ; do 19010eadc25SFrank Rowand 19110eadc25SFrank Rowand case $1 in 19210eadc25SFrank Rowand 19310eadc25SFrank Rowand -f ) 19410eadc25SFrank Rowand diff_flags="--unified=999999" 19510eadc25SFrank Rowand shift 19610eadc25SFrank Rowand ;; 19710eadc25SFrank Rowand 19810eadc25SFrank Rowand -h | -help | --help ) 19910eadc25SFrank Rowand help=1 20010eadc25SFrank Rowand shift 20110eadc25SFrank Rowand ;; 20210eadc25SFrank Rowand 20310eadc25SFrank Rowand -s ) 20410eadc25SFrank Rowand srctree="$2" 20510eadc25SFrank Rowand shift 2 20610eadc25SFrank Rowand ;; 20710eadc25SFrank Rowand 20810eadc25SFrank Rowand -S ) 20910eadc25SFrank Rowand git_root=`git rev-parse --show-toplevel 2>/dev/null` 21010eadc25SFrank Rowand srctree="${git_root}" 21110eadc25SFrank Rowand shift 21210eadc25SFrank Rowand ;; 21310eadc25SFrank Rowand 214*87143fceSFrank Rowand -T | --annotate ) 215*87143fceSFrank Rowand if [ "${annotate}" = "" ] ; then 216*87143fceSFrank Rowand annotate="-T" 217*87143fceSFrank Rowand elif [ "${annotate}" = "-T" ] ; then 218*87143fceSFrank Rowand annotate="-T -T" 219*87143fceSFrank Rowand fi 220*87143fceSFrank Rowand shift 221*87143fceSFrank Rowand ;; 22210eadc25SFrank Rowand -u ) 22310eadc25SFrank Rowand dtc_sort="" 22410eadc25SFrank Rowand shift 22510eadc25SFrank Rowand ;; 22610eadc25SFrank Rowand 22710eadc25SFrank Rowand *) 22810eadc25SFrank Rowand if [ "${dtx_file_1}" = "" ] ; then 22910eadc25SFrank Rowand dtx_file_1="$1" 23010eadc25SFrank Rowand elif [ "${dtx_file_2}" = "" ] ; then 23110eadc25SFrank Rowand dtx_file_2="$1" 23210eadc25SFrank Rowand else 23310eadc25SFrank Rowand echo "" >&2 23410eadc25SFrank Rowand echo "ERROR: Unexpected parameter: $1" >&2 23510eadc25SFrank Rowand echo "" >&2 23610eadc25SFrank Rowand exit 2 23710eadc25SFrank Rowand fi 23810eadc25SFrank Rowand shift 23910eadc25SFrank Rowand ;; 24010eadc25SFrank Rowand 24110eadc25SFrank Rowand esac 24210eadc25SFrank Rowand 24310eadc25SFrank Rowanddone 24410eadc25SFrank Rowand 24510eadc25SFrank Rowandif [ "${srctree}" = "" ] ; then 24610eadc25SFrank Rowand srctree="." 24710eadc25SFrank Rowandfi 24810eadc25SFrank Rowand 24910eadc25SFrank Rowandif [ "${dtx_file_2}" != "" ]; then 25010eadc25SFrank Rowand cmd_diff=1 25110eadc25SFrank Rowandfi 25210eadc25SFrank Rowand 25310eadc25SFrank Rowandif (( ${help} )) ; then 25410eadc25SFrank Rowand usage 25510eadc25SFrank Rowand exit 1 25610eadc25SFrank Rowandfi 25710eadc25SFrank Rowand 25810eadc25SFrank Rowand# this must follow check for ${help} 25910eadc25SFrank Rowandif [ "${dtx_file_1}" = "" ]; then 26010eadc25SFrank Rowand echo "" >&2 26110eadc25SFrank Rowand echo "ERROR: parameter DTx required" >&2 26210eadc25SFrank Rowand echo "" >&2 26310eadc25SFrank Rowand exit 2 26410eadc25SFrank Rowandfi 26510eadc25SFrank Rowand 26610eadc25SFrank Rowand 26710eadc25SFrank Rowand# ----- prefer dtc from linux kernel, allow fallback to dtc in $PATH 26810eadc25SFrank Rowand 26910eadc25SFrank Rowandif [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then 27010eadc25SFrank Rowand __KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}" 27110eadc25SFrank Rowandelif [ "${KBUILD_OUTPUT}" = "" ] ; then 27210eadc25SFrank Rowand __KBUILD_OUTPUT="." 27310eadc25SFrank Rowandelse 27410eadc25SFrank Rowand __KBUILD_OUTPUT="${KBUILD_OUTPUT}" 27510eadc25SFrank Rowandfi 27610eadc25SFrank Rowand 27710eadc25SFrank RowandDTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc" 27810eadc25SFrank Rowand 27910eadc25SFrank Rowandif [ ! -x ${DTC} ] ; then 28010eadc25SFrank Rowand __DTC="dtc" 281ca0cd118SGaurav Minocha if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config 2>/dev/null; then 28260c7f4cbSFrank Rowand make_command=' 28360c7f4cbSFrank Rowand make scripts' 28460c7f4cbSFrank Rowand else 28560c7f4cbSFrank Rowand make_command=' 28660c7f4cbSFrank Rowand Enable CONFIG_DTC in the kernel configuration 28760c7f4cbSFrank Rowand make scripts' 28860c7f4cbSFrank Rowand fi 28910eadc25SFrank Rowand if ( ! which ${__DTC} >/dev/null ) ; then 29010eadc25SFrank Rowand 29110eadc25SFrank Rowand # use spaces instead of tabs in the error message 29210eadc25SFrank Rowand cat >&2 <<eod 29310eadc25SFrank Rowand 29410eadc25SFrank RowandERROR: unable to find a 'dtc' program 29510eadc25SFrank Rowand 29610eadc25SFrank Rowand Preferred 'dtc' (built from Linux kernel source tree) was not found or 29710eadc25SFrank Rowand is not executable. 29810eadc25SFrank Rowand 29910eadc25SFrank Rowand 'dtc' is: ${DTC} 30010eadc25SFrank Rowand 30110eadc25SFrank Rowand If it does not exist, create it from the root of the Linux source tree: 30260c7f4cbSFrank Rowand${make_command} 30310eadc25SFrank Rowand 30410eadc25SFrank Rowand If not at the root of the Linux kernel source tree -s SRCTREE or -S 30510eadc25SFrank Rowand may need to be specified to find 'dtc'. 30610eadc25SFrank Rowand 30710eadc25SFrank Rowand If 'O=\${dir}' is specified in your Linux builds, this script requires 30810eadc25SFrank Rowand 'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH 30910eadc25SFrank Rowand before running. 31010eadc25SFrank Rowand 31110eadc25SFrank Rowand If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run 31210eadc25SFrank Rowand this script from the root of the Linux kernel source tree is required. 31310eadc25SFrank Rowand 31410eadc25SFrank Rowand Fallback '${__DTC}' was also not in \${PATH} or is not executable. 31510eadc25SFrank Rowand 31610eadc25SFrank Rowandeod 31710eadc25SFrank Rowand exit 2 31810eadc25SFrank Rowand fi 31910eadc25SFrank Rowand DTC=${__DTC} 32010eadc25SFrank Rowandfi 32110eadc25SFrank Rowand 32210eadc25SFrank Rowand 32310eadc25SFrank Rowand# ----- cpp and dtc flags same as for linux source tree build of .dtb files, 32410eadc25SFrank Rowand# plus directories of the dtx file(s) 32510eadc25SFrank Rowand 32610eadc25SFrank Rowanddtx_path_1_dtc_include="-i `dirname ${dtx_file_1}`" 32710eadc25SFrank Rowand 32810eadc25SFrank Rowanddtx_path_2_dtc_include="" 32910eadc25SFrank Rowandif (( ${cmd_diff} )) ; then 33010eadc25SFrank Rowand dtx_path_2_dtc_include="-i `dirname ${dtx_file_2}`" 33110eadc25SFrank Rowandfi 33210eadc25SFrank Rowand 33310eadc25SFrank Rowandcpp_flags="\ 33410eadc25SFrank Rowand -nostdinc \ 335b4b201d8SFrank Rowand -I${srctree}/scripts/dtc/include-prefixes \ 33610eadc25SFrank Rowand -undef -D__DTS__" 33710eadc25SFrank Rowand 33835f3c984SFrank RowandDTC="\ 33935f3c984SFrank Rowand ${DTC} \ 34035f3c984SFrank Rowand -i ${srctree}/scripts/dtc/include-prefixes \ 341*87143fceSFrank Rowand -O dts -qq -f ${dtc_sort} ${annotate} -o -" 34210eadc25SFrank Rowand 34310eadc25SFrank Rowand 34410eadc25SFrank Rowand# ----- do the diff or decompile 34510eadc25SFrank Rowand 34610eadc25SFrank Rowandif (( ${cmd_diff} )) ; then 34710eadc25SFrank Rowand 3487782b144SGeert Uytterhoeven diff ${diff_flags} --label "${dtx_file_1}" --label "${dtx_file_2}" \ 34935f3c984SFrank Rowand <(compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}") \ 35035f3c984SFrank Rowand <(compile_to_dts "${dtx_file_2}" "${dtx_path_2_dtc_include}") 35110eadc25SFrank Rowand 35210eadc25SFrank Rowandelse 35310eadc25SFrank Rowand 35435f3c984SFrank Rowand compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}" 35510eadc25SFrank Rowand 35610eadc25SFrank Rowandfi 357