162306a36Sopenharmony_ci#! /bin/bash 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci# Copyright (C) 2015 Frank Rowand 562306a36Sopenharmony_ci# 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci 862306a36Sopenharmony_ciusage() { 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci # use spaces instead of tabs in the usage message 1162306a36Sopenharmony_ci cat >&2 <<eod 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ciUsage: 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci `basename $0` DTx 1662306a36Sopenharmony_ci decompile DTx 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci `basename $0` DTx_1 DTx_2 1962306a36Sopenharmony_ci diff DTx_1 and DTx_2 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci --annotate synonym for -T 2362306a36Sopenharmony_ci --color synonym for -c (requires diff with --color support) 2462306a36Sopenharmony_ci -c enable colored output 2562306a36Sopenharmony_ci -f print full dts in diff (--unified=99999) 2662306a36Sopenharmony_ci -h synonym for --help 2762306a36Sopenharmony_ci -help synonym for --help 2862306a36Sopenharmony_ci --help print this message and exit 2962306a36Sopenharmony_ci -s SRCTREE linux kernel source tree is at path SRCTREE 3062306a36Sopenharmony_ci (default is current directory) 3162306a36Sopenharmony_ci -S linux kernel source tree is at root of current git repo 3262306a36Sopenharmony_ci -T annotate output .dts with input source file and line 3362306a36Sopenharmony_ci (-T -T for more details) 3462306a36Sopenharmony_ci -u unsorted, do not sort DTx 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ciEach DTx is processed by the dtc compiler to produce a sorted dts source 3862306a36Sopenharmony_cifile. If DTx is a dts source file then it is pre-processed in the same 3962306a36Sopenharmony_cimanner as done for the compile of the dts source file in the Linux kernel 4062306a36Sopenharmony_cibuild system ('#include' and '/include/' directives are processed). 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ciIf two DTx are provided, the resulting dts source files are diffed. 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ciIf DTx is a directory, it is treated as a DT subtree, such as 4562306a36Sopenharmony_ci /proc/device-tree. 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ciIf DTx contains the binary blob magic value in the first four bytes, 4862306a36Sopenharmony_ci it is treated as a binary blob (aka .dtb or FDT). 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ciOtherwise DTx is treated as a dts source file (aka .dts). 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci If this script is not run from the root of the linux source tree, 5362306a36Sopenharmony_ci and DTx utilizes '#include' or '/include/' then the path of the 5462306a36Sopenharmony_ci linux source tree can be provided by '-s SRCTREE' or '-S' so that 5562306a36Sopenharmony_ci include paths will be set properly. 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci The shell variable \${ARCH} must provide the architecture containing 5862306a36Sopenharmony_ci the dts source file for include paths to be set properly for '#include' 5962306a36Sopenharmony_ci or '/include/' to be processed. 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci If DTx_1 and DTx_2 are in different architectures, then this script 6262306a36Sopenharmony_ci may not work since \${ARCH} is part of the include path. The following 6362306a36Sopenharmony_ci workaround can be used: 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci `basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts 6662306a36Sopenharmony_ci `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts 6762306a36Sopenharmony_ci `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts 6862306a36Sopenharmony_ci rm tmp_dtx_1.dts tmp_dtx_2.dts 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci If DTx_1 and DTx_2 are in different directories, then this script will 7162306a36Sopenharmony_ci add the path of DTx_1 and DTx_2 to the include paths. If DTx_2 includes 7262306a36Sopenharmony_ci a local file that exists in both the path of DTx_1 and DTx_2 then the 7362306a36Sopenharmony_ci file in the path of DTx_1 will incorrectly be included. Possible 7462306a36Sopenharmony_ci workaround: 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci `basename $0` DTx_1 >tmp_dtx_1.dts 7762306a36Sopenharmony_ci `basename $0` DTx_2 >tmp_dtx_2.dts 7862306a36Sopenharmony_ci `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts 7962306a36Sopenharmony_ci rm tmp_dtx_1.dts tmp_dtx_2.dts 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cieod 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cicompile_to_dts() { 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci dtx="$1" 8862306a36Sopenharmony_ci dtc_include="$2" 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci if [ -d "${dtx}" ] ; then 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci # ----- input is file tree 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci if ( ! ${DTC} -I fs ${dtx} ) ; then 9562306a36Sopenharmony_ci exit 3 9662306a36Sopenharmony_ci fi 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci elif [ -f "${dtx}" ] && [ -r "${dtx}" ] ; then 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci magic=`hexdump -n 4 -e '/1 "%02x"' ${dtx}` 10162306a36Sopenharmony_ci if [ "${magic}" = "d00dfeed" ] ; then 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci # ----- input is FDT (binary blob) 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci if ( ! ${DTC} -I dtb ${dtx} ) ; then 10662306a36Sopenharmony_ci exit 3 10762306a36Sopenharmony_ci fi 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci return 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci fi 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci # ----- input is DTS (source) 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \ 11662306a36Sopenharmony_ci | ${DTC} ${dtc_include} -I dts ) ; then 11762306a36Sopenharmony_ci return 11862306a36Sopenharmony_ci fi 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci echo "" >&2 12162306a36Sopenharmony_ci echo "Possible hints to resolve the above error:" >&2 12262306a36Sopenharmony_ci echo " (hints might not fix the problem)" >&2 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci hint_given=0 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci if [ "${ARCH}" = "" ] ; then 12762306a36Sopenharmony_ci hint_given=1 12862306a36Sopenharmony_ci echo "" >&2 12962306a36Sopenharmony_ci echo " shell variable \$ARCH not set" >&2 13062306a36Sopenharmony_ci fi 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci dtx_arch=`echo "/${dtx}" | sed -e 's|.*/arch/||' -e 's|/.*||'` 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci if [ "${dtx_arch}" != "" -a "${dtx_arch}" != "${ARCH}" ] ; then 13562306a36Sopenharmony_ci hint_given=1 13662306a36Sopenharmony_ci echo "" >&2 13762306a36Sopenharmony_ci echo " architecture ${dtx_arch} is in file path," >&2 13862306a36Sopenharmony_ci echo " but does not match shell variable \$ARCH" >&2 13962306a36Sopenharmony_ci echo " >>\$ARCH<< is: >>${ARCH}<<" >&2 14062306a36Sopenharmony_ci fi 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci if [ ! -d ${srctree}/arch/${ARCH} ] ; then 14362306a36Sopenharmony_ci hint_given=1 14462306a36Sopenharmony_ci echo "" >&2 14562306a36Sopenharmony_ci echo " ${srctree}/arch/${ARCH}/ does not exist" >&2 14662306a36Sopenharmony_ci echo " Is \$ARCH='${ARCH}' correct?" >&2 14762306a36Sopenharmony_ci echo " Possible fix: use '-s' option" >&2 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci git_root=`git rev-parse --show-toplevel 2>/dev/null` 15062306a36Sopenharmony_ci if [ -d ${git_root}/arch/ ] ; then 15162306a36Sopenharmony_ci echo " Possible fix: use '-S' option" >&2 15262306a36Sopenharmony_ci fi 15362306a36Sopenharmony_ci fi 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci if [ $hint_given = 0 ] ; then 15662306a36Sopenharmony_ci echo "" >&2 15762306a36Sopenharmony_ci echo " No hints available." >&2 15862306a36Sopenharmony_ci fi 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci echo "" >&2 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci exit 3 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci else 16562306a36Sopenharmony_ci echo "" >&2 16662306a36Sopenharmony_ci echo "ERROR: ${dtx} does not exist or is not readable" >&2 16762306a36Sopenharmony_ci echo "" >&2 16862306a36Sopenharmony_ci exit 2 16962306a36Sopenharmony_ci fi 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci# ----- start of script 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ciannotate="" 17762306a36Sopenharmony_cicmd_diff=0 17862306a36Sopenharmony_cidiff_flags="-u" 17962306a36Sopenharmony_cidiff_color="" 18062306a36Sopenharmony_cidtx_file_1="" 18162306a36Sopenharmony_cidtx_file_2="" 18262306a36Sopenharmony_cidtc_sort="-s" 18362306a36Sopenharmony_cihelp=0 18462306a36Sopenharmony_cisrctree="" 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ciwhile [ $# -gt 0 ] ; do 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci case $1 in 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci -c | --color ) 19262306a36Sopenharmony_ci if diff --color /dev/null /dev/null 2>/dev/null ; then 19362306a36Sopenharmony_ci diff_color="--color=always" 19462306a36Sopenharmony_ci fi 19562306a36Sopenharmony_ci shift 19662306a36Sopenharmony_ci ;; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci -f ) 19962306a36Sopenharmony_ci diff_flags="--unified=999999" 20062306a36Sopenharmony_ci shift 20162306a36Sopenharmony_ci ;; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci -h | -help | --help ) 20462306a36Sopenharmony_ci help=1 20562306a36Sopenharmony_ci shift 20662306a36Sopenharmony_ci ;; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci -s ) 20962306a36Sopenharmony_ci srctree="$2" 21062306a36Sopenharmony_ci shift 2 21162306a36Sopenharmony_ci ;; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci -S ) 21462306a36Sopenharmony_ci git_root=`git rev-parse --show-toplevel 2>/dev/null` 21562306a36Sopenharmony_ci srctree="${git_root}" 21662306a36Sopenharmony_ci shift 21762306a36Sopenharmony_ci ;; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci -T | --annotate ) 22062306a36Sopenharmony_ci if [ "${annotate}" = "" ] ; then 22162306a36Sopenharmony_ci annotate="-T" 22262306a36Sopenharmony_ci elif [ "${annotate}" = "-T" ] ; then 22362306a36Sopenharmony_ci annotate="-T -T" 22462306a36Sopenharmony_ci fi 22562306a36Sopenharmony_ci shift 22662306a36Sopenharmony_ci ;; 22762306a36Sopenharmony_ci -u ) 22862306a36Sopenharmony_ci dtc_sort="" 22962306a36Sopenharmony_ci shift 23062306a36Sopenharmony_ci ;; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci *) 23362306a36Sopenharmony_ci if [ "${dtx_file_1}" = "" ] ; then 23462306a36Sopenharmony_ci dtx_file_1="$1" 23562306a36Sopenharmony_ci elif [ "${dtx_file_2}" = "" ] ; then 23662306a36Sopenharmony_ci dtx_file_2="$1" 23762306a36Sopenharmony_ci else 23862306a36Sopenharmony_ci echo "" >&2 23962306a36Sopenharmony_ci echo "ERROR: Unexpected parameter: $1" >&2 24062306a36Sopenharmony_ci echo "" >&2 24162306a36Sopenharmony_ci exit 2 24262306a36Sopenharmony_ci fi 24362306a36Sopenharmony_ci shift 24462306a36Sopenharmony_ci ;; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci esac 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_cidone 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ciif [ "${srctree}" = "" ] ; then 25162306a36Sopenharmony_ci srctree="." 25262306a36Sopenharmony_cifi 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ciif [ "${dtx_file_2}" != "" ]; then 25562306a36Sopenharmony_ci cmd_diff=1 25662306a36Sopenharmony_cifi 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ciif (( ${help} )) ; then 25962306a36Sopenharmony_ci usage 26062306a36Sopenharmony_ci exit 1 26162306a36Sopenharmony_cifi 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci# this must follow check for ${help} 26462306a36Sopenharmony_ciif [ "${dtx_file_1}" = "" ]; then 26562306a36Sopenharmony_ci echo "" >&2 26662306a36Sopenharmony_ci echo "ERROR: parameter DTx required" >&2 26762306a36Sopenharmony_ci echo "" >&2 26862306a36Sopenharmony_ci exit 2 26962306a36Sopenharmony_cifi 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci# ----- prefer dtc from linux kernel, allow fallback to dtc in $PATH 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ciif [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then 27562306a36Sopenharmony_ci __KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}" 27662306a36Sopenharmony_cielif [ "${KBUILD_OUTPUT}" = "" ] ; then 27762306a36Sopenharmony_ci __KBUILD_OUTPUT="." 27862306a36Sopenharmony_cielse 27962306a36Sopenharmony_ci __KBUILD_OUTPUT="${KBUILD_OUTPUT}" 28062306a36Sopenharmony_cifi 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ciDTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc" 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ciif [ ! -x ${DTC} ] ; then 28562306a36Sopenharmony_ci __DTC="dtc" 28662306a36Sopenharmony_ci if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config 2>/dev/null; then 28762306a36Sopenharmony_ci make_command=' 28862306a36Sopenharmony_ci make scripts' 28962306a36Sopenharmony_ci else 29062306a36Sopenharmony_ci make_command=' 29162306a36Sopenharmony_ci Enable CONFIG_DTC in the kernel configuration 29262306a36Sopenharmony_ci make scripts' 29362306a36Sopenharmony_ci fi 29462306a36Sopenharmony_ci if ( ! which ${__DTC} >/dev/null ) ; then 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci # use spaces instead of tabs in the error message 29762306a36Sopenharmony_ci cat >&2 <<eod 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ciERROR: unable to find a 'dtc' program 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci Preferred 'dtc' (built from Linux kernel source tree) was not found or 30262306a36Sopenharmony_ci is not executable. 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci 'dtc' is: ${DTC} 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci If it does not exist, create it from the root of the Linux source tree: 30762306a36Sopenharmony_ci${make_command} 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci If not at the root of the Linux kernel source tree -s SRCTREE or -S 31062306a36Sopenharmony_ci may need to be specified to find 'dtc'. 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci If 'O=\${dir}' is specified in your Linux builds, this script requires 31362306a36Sopenharmony_ci 'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH 31462306a36Sopenharmony_ci before running. 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run 31762306a36Sopenharmony_ci this script from the root of the Linux kernel source tree is required. 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci Fallback '${__DTC}' was also not in \${PATH} or is not executable. 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_cieod 32262306a36Sopenharmony_ci exit 2 32362306a36Sopenharmony_ci fi 32462306a36Sopenharmony_ci DTC=${__DTC} 32562306a36Sopenharmony_cifi 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci# ----- cpp and dtc flags same as for linux source tree build of .dtb files, 32962306a36Sopenharmony_ci# plus directories of the dtx file(s) 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_cidtx_path_1_dtc_include="-i `dirname ${dtx_file_1}`" 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_cidtx_path_2_dtc_include="" 33462306a36Sopenharmony_ciif (( ${cmd_diff} )) ; then 33562306a36Sopenharmony_ci dtx_path_2_dtc_include="-i `dirname ${dtx_file_2}`" 33662306a36Sopenharmony_cifi 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_cicpp_flags="\ 33962306a36Sopenharmony_ci -nostdinc \ 34062306a36Sopenharmony_ci -I${srctree}/scripts/dtc/include-prefixes \ 34162306a36Sopenharmony_ci -undef -D__DTS__" 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ciDTC="\ 34462306a36Sopenharmony_ci ${DTC} \ 34562306a36Sopenharmony_ci -i ${srctree}/scripts/dtc/include-prefixes \ 34662306a36Sopenharmony_ci -O dts -qq -f ${dtc_sort} ${annotate} -o -" 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci# ----- do the diff or decompile 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ciif (( ${cmd_diff} )) ; then 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci diff ${diff_flags} ${diff_color} --label "${dtx_file_1}" --label "${dtx_file_2}" \ 35462306a36Sopenharmony_ci <(compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}") \ 35562306a36Sopenharmony_ci <(compile_to_dts "${dtx_file_2}" "${dtx_path_2_dtc_include}") 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_cielse 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}" 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_cifi 362