xref: /OK3568_Linux_fs/kernel/scripts/dtc/dtx_diff (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#! /bin/bash
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun# Copyright (C) 2015 Frank Rowand
5*4882a593Smuzhiyun#
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun
8*4882a593Smuzhiyunusage() {
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun	# use spaces instead of tabs in the usage message
11*4882a593Smuzhiyun	cat >&2 <<eod
12*4882a593Smuzhiyun
13*4882a593SmuzhiyunUsage:
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun   `basename $0` DTx
16*4882a593Smuzhiyun        decompile DTx
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun   `basename $0` DTx_1 DTx_2
19*4882a593Smuzhiyun        diff DTx_1 and DTx_2
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun      --annotate    synonym for -T
23*4882a593Smuzhiyun      --color       synonym for -c (requires diff with --color support)
24*4882a593Smuzhiyun       -c           enable colored output
25*4882a593Smuzhiyun       -f           print full dts in diff (--unified=99999)
26*4882a593Smuzhiyun       -h           synonym for --help
27*4882a593Smuzhiyun       -help        synonym for --help
28*4882a593Smuzhiyun      --help        print this message and exit
29*4882a593Smuzhiyun       -s SRCTREE   linux kernel source tree is at path SRCTREE
30*4882a593Smuzhiyun                        (default is current directory)
31*4882a593Smuzhiyun       -S           linux kernel source tree is at root of current git repo
32*4882a593Smuzhiyun       -T           annotate output .dts with input source file and line
33*4882a593Smuzhiyun                        (-T -T for more details)
34*4882a593Smuzhiyun       -u           unsorted, do not sort DTx
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun
37*4882a593SmuzhiyunEach DTx is processed by the dtc compiler to produce a sorted dts source
38*4882a593Smuzhiyunfile.  If DTx is a dts source file then it is pre-processed in the same
39*4882a593Smuzhiyunmanner as done for the compile of the dts source file in the Linux kernel
40*4882a593Smuzhiyunbuild system ('#include' and '/include/' directives are processed).
41*4882a593Smuzhiyun
42*4882a593SmuzhiyunIf two DTx are provided, the resulting dts source files are diffed.
43*4882a593Smuzhiyun
44*4882a593SmuzhiyunIf DTx is a directory, it is treated as a DT subtree, such as
45*4882a593Smuzhiyun  /proc/device-tree.
46*4882a593Smuzhiyun
47*4882a593SmuzhiyunIf DTx contains the binary blob magic value in the first four bytes,
48*4882a593Smuzhiyun  it is treated as a binary blob (aka .dtb or FDT).
49*4882a593Smuzhiyun
50*4882a593SmuzhiyunOtherwise DTx is treated as a dts source file (aka .dts).
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun   If this script is not run from the root of the linux source tree,
53*4882a593Smuzhiyun   and DTx utilizes '#include' or '/include/' then the path of the
54*4882a593Smuzhiyun   linux source tree can be provided by '-s SRCTREE' or '-S' so that
55*4882a593Smuzhiyun   include paths will be set properly.
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun   The shell variable \${ARCH} must provide the architecture containing
58*4882a593Smuzhiyun   the dts source file for include paths to be set properly for '#include'
59*4882a593Smuzhiyun   or '/include/' to be processed.
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun   If DTx_1 and DTx_2 are in different architectures, then this script
62*4882a593Smuzhiyun   may not work since \${ARCH} is part of the include path.  The following
63*4882a593Smuzhiyun   workaround can be used:
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun      `basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts
66*4882a593Smuzhiyun      `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts
67*4882a593Smuzhiyun      `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts
68*4882a593Smuzhiyun      rm tmp_dtx_1.dts tmp_dtx_2.dts
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun   If DTx_1 and DTx_2 are in different directories, then this script will
71*4882a593Smuzhiyun   add the path of DTx_1 and DTx_2 to the include paths.  If DTx_2 includes
72*4882a593Smuzhiyun   a local file that exists in both the path of DTx_1 and DTx_2 then the
73*4882a593Smuzhiyun   file in the path of DTx_1 will incorrectly be included.  Possible
74*4882a593Smuzhiyun   workaround:
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun      `basename $0` DTx_1 >tmp_dtx_1.dts
77*4882a593Smuzhiyun      `basename $0` DTx_2 >tmp_dtx_2.dts
78*4882a593Smuzhiyun      `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts
79*4882a593Smuzhiyun      rm tmp_dtx_1.dts tmp_dtx_2.dts
80*4882a593Smuzhiyun
81*4882a593Smuzhiyuneod
82*4882a593Smuzhiyun}
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun
85*4882a593Smuzhiyuncompile_to_dts() {
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun	dtx="$1"
88*4882a593Smuzhiyun	dtc_include="$2"
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun	if [ -d "${dtx}" ] ; then
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun		# -----  input is file tree
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun		if ( ! ${DTC} -I fs ${dtx} ) ; then
95*4882a593Smuzhiyun			exit 3
96*4882a593Smuzhiyun		fi
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun	elif [ -f "${dtx}" ] && [ -r "${dtx}" ] ; then
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun		magic=`hexdump -n 4 -e '/1 "%02x"' ${dtx}`
101*4882a593Smuzhiyun		if [ "${magic}" = "d00dfeed" ] ; then
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun			# -----  input is FDT (binary blob)
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun			if ( ! ${DTC} -I dtb ${dtx} ) ; then
106*4882a593Smuzhiyun				exit 3
107*4882a593Smuzhiyun			fi
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun			return
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun		fi
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun		# -----  input is DTS (source)
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun		if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \
116*4882a593Smuzhiyun			| ${DTC} ${dtc_include} -I dts ) ; then
117*4882a593Smuzhiyun			return
118*4882a593Smuzhiyun		fi
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun		echo ""                                                      >&2
121*4882a593Smuzhiyun		echo "Possible hints to resolve the above error:"            >&2
122*4882a593Smuzhiyun		echo "  (hints might not fix the problem)"                   >&2
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun		hint_given=0
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun		if [ "${ARCH}" = "" ] ; then
127*4882a593Smuzhiyun			hint_given=1
128*4882a593Smuzhiyun			echo ""                                              >&2
129*4882a593Smuzhiyun			echo "  shell variable \$ARCH not set"               >&2
130*4882a593Smuzhiyun		fi
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun		dtx_arch=`echo "/${dtx}" | sed -e 's|.*/arch/||' -e 's|/.*||'`
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun		if [ "${dtx_arch}" != ""  -a "${dtx_arch}" != "${ARCH}" ] ; then
135*4882a593Smuzhiyun			hint_given=1
136*4882a593Smuzhiyun			echo ""                                              >&2
137*4882a593Smuzhiyun			echo "  architecture ${dtx_arch} is in file path,"   >&2
138*4882a593Smuzhiyun			echo "  but does not match shell variable \$ARCH"    >&2
139*4882a593Smuzhiyun			echo "  >>\$ARCH<< is: >>${ARCH}<<"                  >&2
140*4882a593Smuzhiyun		fi
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun		if [ ! -d ${srctree}/arch/${ARCH} ] ; then
143*4882a593Smuzhiyun			hint_given=1
144*4882a593Smuzhiyun			echo ""                                              >&2
145*4882a593Smuzhiyun			echo "  ${srctree}/arch/${ARCH}/ does not exist"     >&2
146*4882a593Smuzhiyun			echo "  Is \$ARCH='${ARCH}' correct?"                >&2
147*4882a593Smuzhiyun			echo "  Possible fix: use '-s' option"               >&2
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun			git_root=`git rev-parse --show-toplevel 2>/dev/null`
150*4882a593Smuzhiyun			if [ -d ${git_root}/arch/ ] ; then
151*4882a593Smuzhiyun				echo "  Possible fix: use '-S' option"       >&2
152*4882a593Smuzhiyun			fi
153*4882a593Smuzhiyun		fi
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun		if [ $hint_given = 0 ] ; then
156*4882a593Smuzhiyun			echo ""                                              >&2
157*4882a593Smuzhiyun			echo "  No hints available."                         >&2
158*4882a593Smuzhiyun		fi
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun		echo ""                                                      >&2
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun		exit 3
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun	else
165*4882a593Smuzhiyun		echo ""                                                     >&2
166*4882a593Smuzhiyun		echo "ERROR: ${dtx} does not exist or is not readable"      >&2
167*4882a593Smuzhiyun		echo ""                                                     >&2
168*4882a593Smuzhiyun		exit 2
169*4882a593Smuzhiyun	fi
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun}
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun# -----  start of script
175*4882a593Smuzhiyun
176*4882a593Smuzhiyunannotate=""
177*4882a593Smuzhiyuncmd_diff=0
178*4882a593Smuzhiyundiff_flags="-u"
179*4882a593Smuzhiyundiff_color=""
180*4882a593Smuzhiyundtx_file_1=""
181*4882a593Smuzhiyundtx_file_2=""
182*4882a593Smuzhiyundtc_sort="-s"
183*4882a593Smuzhiyunhelp=0
184*4882a593Smuzhiyunsrctree=""
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun
187*4882a593Smuzhiyunwhile [ $# -gt 0 ] ; do
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun	case $1 in
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun	-c | --color )
192*4882a593Smuzhiyun		if diff --color /dev/null /dev/null 2>/dev/null ; then
193*4882a593Smuzhiyun			diff_color="--color=always"
194*4882a593Smuzhiyun		fi
195*4882a593Smuzhiyun		shift
196*4882a593Smuzhiyun		;;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun	-f )
199*4882a593Smuzhiyun		diff_flags="--unified=999999"
200*4882a593Smuzhiyun		shift
201*4882a593Smuzhiyun		;;
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun	-h | -help | --help )
204*4882a593Smuzhiyun		help=1
205*4882a593Smuzhiyun		shift
206*4882a593Smuzhiyun		;;
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun	-s )
209*4882a593Smuzhiyun		srctree="$2"
210*4882a593Smuzhiyun		shift 2
211*4882a593Smuzhiyun		;;
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun	-S )
214*4882a593Smuzhiyun		git_root=`git rev-parse --show-toplevel 2>/dev/null`
215*4882a593Smuzhiyun		srctree="${git_root}"
216*4882a593Smuzhiyun		shift
217*4882a593Smuzhiyun		;;
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun	-T | --annotate )
220*4882a593Smuzhiyun		if [ "${annotate}"  = "" ] ; then
221*4882a593Smuzhiyun			annotate="-T"
222*4882a593Smuzhiyun		elif [ "${annotate}"  = "-T" ] ; then
223*4882a593Smuzhiyun			annotate="-T -T"
224*4882a593Smuzhiyun		fi
225*4882a593Smuzhiyun		shift
226*4882a593Smuzhiyun		;;
227*4882a593Smuzhiyun	-u )
228*4882a593Smuzhiyun		dtc_sort=""
229*4882a593Smuzhiyun		shift
230*4882a593Smuzhiyun		;;
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun	*)
233*4882a593Smuzhiyun		if [ "${dtx_file_1}"  = "" ] ; then
234*4882a593Smuzhiyun			dtx_file_1="$1"
235*4882a593Smuzhiyun		elif [ "${dtx_file_2}" = "" ] ; then
236*4882a593Smuzhiyun			dtx_file_2="$1"
237*4882a593Smuzhiyun		else
238*4882a593Smuzhiyun			echo ""                                             >&2
239*4882a593Smuzhiyun			echo "ERROR: Unexpected parameter: $1"              >&2
240*4882a593Smuzhiyun			echo ""                                             >&2
241*4882a593Smuzhiyun			exit 2
242*4882a593Smuzhiyun		fi
243*4882a593Smuzhiyun		shift
244*4882a593Smuzhiyun		;;
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun	esac
247*4882a593Smuzhiyun
248*4882a593Smuzhiyundone
249*4882a593Smuzhiyun
250*4882a593Smuzhiyunif [ "${srctree}" = "" ] ; then
251*4882a593Smuzhiyun	srctree="."
252*4882a593Smuzhiyunfi
253*4882a593Smuzhiyun
254*4882a593Smuzhiyunif [ "${dtx_file_2}" != "" ]; then
255*4882a593Smuzhiyun	cmd_diff=1
256*4882a593Smuzhiyunfi
257*4882a593Smuzhiyun
258*4882a593Smuzhiyunif (( ${help} )) ; then
259*4882a593Smuzhiyun	usage
260*4882a593Smuzhiyun	exit 1
261*4882a593Smuzhiyunfi
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun# this must follow check for ${help}
264*4882a593Smuzhiyunif [ "${dtx_file_1}" = "" ]; then
265*4882a593Smuzhiyun	echo ""                                                             >&2
266*4882a593Smuzhiyun	echo "ERROR: parameter DTx required"                                >&2
267*4882a593Smuzhiyun	echo ""                                                             >&2
268*4882a593Smuzhiyun	exit 2
269*4882a593Smuzhiyunfi
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun# -----  prefer dtc from linux kernel, allow fallback to dtc in $PATH
273*4882a593Smuzhiyun
274*4882a593Smuzhiyunif [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then
275*4882a593Smuzhiyun	__KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}"
276*4882a593Smuzhiyunelif [ "${KBUILD_OUTPUT}" = "" ] ; then
277*4882a593Smuzhiyun	__KBUILD_OUTPUT="."
278*4882a593Smuzhiyunelse
279*4882a593Smuzhiyun	__KBUILD_OUTPUT="${KBUILD_OUTPUT}"
280*4882a593Smuzhiyunfi
281*4882a593Smuzhiyun
282*4882a593SmuzhiyunDTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc"
283*4882a593Smuzhiyun
284*4882a593Smuzhiyunif [ ! -x ${DTC} ] ; then
285*4882a593Smuzhiyun	__DTC="dtc"
286*4882a593Smuzhiyun	if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config 2>/dev/null; then
287*4882a593Smuzhiyun		make_command='
288*4882a593Smuzhiyun         make scripts'
289*4882a593Smuzhiyun	else
290*4882a593Smuzhiyun		make_command='
291*4882a593Smuzhiyun         Enable CONFIG_DTC in the kernel configuration
292*4882a593Smuzhiyun         make scripts'
293*4882a593Smuzhiyun	fi
294*4882a593Smuzhiyun	if ( ! which ${__DTC} >/dev/null ) ; then
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun		# use spaces instead of tabs in the error message
297*4882a593Smuzhiyun		cat >&2 <<eod
298*4882a593Smuzhiyun
299*4882a593SmuzhiyunERROR: unable to find a 'dtc' program
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun   Preferred 'dtc' (built from Linux kernel source tree) was not found or
302*4882a593Smuzhiyun   is not executable.
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun      'dtc' is: ${DTC}
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun      If it does not exist, create it from the root of the Linux source tree:
307*4882a593Smuzhiyun${make_command}
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun      If not at the root of the Linux kernel source tree -s SRCTREE or -S
310*4882a593Smuzhiyun      may need to be specified to find 'dtc'.
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun      If 'O=\${dir}' is specified in your Linux builds, this script requires
313*4882a593Smuzhiyun      'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH
314*4882a593Smuzhiyun      before running.
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun      If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run
317*4882a593Smuzhiyun      this script from the root of the Linux kernel source tree is required.
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun   Fallback '${__DTC}' was also not in \${PATH} or is not executable.
320*4882a593Smuzhiyun
321*4882a593Smuzhiyuneod
322*4882a593Smuzhiyun		exit 2
323*4882a593Smuzhiyun	fi
324*4882a593Smuzhiyun	DTC=${__DTC}
325*4882a593Smuzhiyunfi
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun# -----  cpp and dtc flags same as for linux source tree build of .dtb files,
329*4882a593Smuzhiyun#        plus directories of the dtx file(s)
330*4882a593Smuzhiyun
331*4882a593Smuzhiyundtx_path_1_dtc_include="-i `dirname ${dtx_file_1}`"
332*4882a593Smuzhiyun
333*4882a593Smuzhiyundtx_path_2_dtc_include=""
334*4882a593Smuzhiyunif (( ${cmd_diff} )) ; then
335*4882a593Smuzhiyun	dtx_path_2_dtc_include="-i `dirname ${dtx_file_2}`"
336*4882a593Smuzhiyunfi
337*4882a593Smuzhiyun
338*4882a593Smuzhiyuncpp_flags="\
339*4882a593Smuzhiyun	-nostdinc                                  \
340*4882a593Smuzhiyun	-I${srctree}/scripts/dtc/include-prefixes  \
341*4882a593Smuzhiyun	-undef -D__DTS__"
342*4882a593Smuzhiyun
343*4882a593SmuzhiyunDTC="\
344*4882a593Smuzhiyun	${DTC}                                     \
345*4882a593Smuzhiyun	-i ${srctree}/scripts/dtc/include-prefixes \
346*4882a593Smuzhiyun	-O dts -qq -f ${dtc_sort} ${annotate} -o -"
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun# -----  do the diff or decompile
350*4882a593Smuzhiyun
351*4882a593Smuzhiyunif (( ${cmd_diff} )) ; then
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun	diff ${diff_flags} ${diff_color} --label "${dtx_file_1}" --label "${dtx_file_2}" \
354*4882a593Smuzhiyun		<(compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}") \
355*4882a593Smuzhiyun		<(compile_to_dts "${dtx_file_2}" "${dtx_path_2_dtc_include}")
356*4882a593Smuzhiyun
357*4882a593Smuzhiyunelse
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun	compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}"
360*4882a593Smuzhiyun
361*4882a593Smuzhiyunfi
362