xref: /linux/scripts/gfp-translate (revision 76c0f27d063079ce2c6e7fa971a185a38905d844)
1608e8e66SMel Gorman#!/bin/bash
24f19048fSThomas Gleixner# SPDX-License-Identifier: GPL-2.0-only
3608e8e66SMel Gorman# Translate the bits making up a GFP mask
4608e8e66SMel Gorman# (c) 2009, Mel Gorman <mel@csn.ul.ie>
5608e8e66SMel GormanSOURCE=
6608e8e66SMel GormanGFPMASK=none
7608e8e66SMel Gorman
8608e8e66SMel Gorman# Helper function to report failures and exit
9608e8e66SMel Gormandie() {
10608e8e66SMel Gorman	echo ERROR: $@
11608e8e66SMel Gorman	if [ "$TMPFILE" != "" ]; then
12608e8e66SMel Gorman		rm -f $TMPFILE
13608e8e66SMel Gorman	fi
14608e8e66SMel Gorman	exit -1
15608e8e66SMel Gorman}
16608e8e66SMel Gorman
17608e8e66SMel Gormanusage() {
18608e8e66SMel Gorman	echo "usage: gfp-translate [-h] [ --source DIRECTORY ] gfpmask"
19608e8e66SMel Gorman	exit 0
20608e8e66SMel Gorman}
21608e8e66SMel Gorman
223ad2f3fbSDaniel Mack# Parse command-line arguments
23608e8e66SMel Gormanwhile [ $# -gt 0 ]; do
24608e8e66SMel Gorman	case $1 in
25608e8e66SMel Gorman		--source)
26608e8e66SMel Gorman			SOURCE=$2
27608e8e66SMel Gorman			shift 2
28608e8e66SMel Gorman			;;
29608e8e66SMel Gorman		-h)
30608e8e66SMel Gorman			usage
31608e8e66SMel Gorman			;;
32608e8e66SMel Gorman		--help)
33608e8e66SMel Gorman			usage
34608e8e66SMel Gorman			;;
35608e8e66SMel Gorman		*)
36608e8e66SMel Gorman			GFPMASK=$1
37608e8e66SMel Gorman			shift
38608e8e66SMel Gorman			;;
39608e8e66SMel Gorman	esac
40608e8e66SMel Gormandone
41608e8e66SMel Gorman
42608e8e66SMel Gorman# Guess the kernel source directory if it's not set. Preference is in order of
43608e8e66SMel Gorman# o current directory
44608e8e66SMel Gorman# o /usr/src/linux
45608e8e66SMel Gormanif [ "$SOURCE" = "" ]; then
46608e8e66SMel Gorman	if [ -r "/usr/src/linux/Makefile" ]; then
47608e8e66SMel Gorman		SOURCE=/usr/src/linux
48608e8e66SMel Gorman	fi
49608e8e66SMel Gorman	if [ -r "`pwd`/Makefile" ]; then
50608e8e66SMel Gorman		SOURCE=`pwd`
51608e8e66SMel Gorman	fi
52608e8e66SMel Gormanfi
53608e8e66SMel Gorman
54608e8e66SMel Gorman# Confirm that a source directory exists
55608e8e66SMel Gormanif [ ! -r "$SOURCE/Makefile" ]; then
56608e8e66SMel Gorman	die "Could not locate kernel source directory or it is invalid"
57608e8e66SMel Gormanfi
58608e8e66SMel Gorman
59608e8e66SMel Gorman# Confirm that a GFP mask has been specified
60608e8e66SMel Gormanif [ "$GFPMASK" = "none" ]; then
61608e8e66SMel Gorman	usage
62608e8e66SMel Gormanfi
63608e8e66SMel Gorman
64608e8e66SMel Gorman# Extract GFP flags from the kernel source
65*a3f6a89cSMarc ZyngierTMPFILE=`mktemp -t gfptranslate-XXXXXX.c` || exit 1
66608e8e66SMel Gorman
67608e8e66SMel Gormanecho Source: $SOURCE
68608e8e66SMel Gormanecho Parsing: $GFPMASK
69*a3f6a89cSMarc Zyngier
70*a3f6a89cSMarc Zyngier(
71*a3f6a89cSMarc Zyngier    cat <<EOF
72*a3f6a89cSMarc Zyngier#include <stdint.h>
73*a3f6a89cSMarc Zyngier#include <stdio.h>
74*a3f6a89cSMarc Zyngier
75*a3f6a89cSMarc Zyngier// Try to fool compiler.h into not including extra stuff
76*a3f6a89cSMarc Zyngier#define __ASSEMBLY__	1
77*a3f6a89cSMarc Zyngier
78*a3f6a89cSMarc Zyngier#include <generated/autoconf.h>
79*a3f6a89cSMarc Zyngier#include <linux/gfp_types.h>
80*a3f6a89cSMarc Zyngier
81*a3f6a89cSMarc Zyngierstatic const char *masks[] = {
82*a3f6a89cSMarc ZyngierEOF
83*a3f6a89cSMarc Zyngier
84*a3f6a89cSMarc Zyngier    sed -nEe 's/^[[:space:]]+(___GFP_.*)_BIT,.*$/\1/p' $SOURCE/include/linux/gfp_types.h |
85*a3f6a89cSMarc Zyngier	while read b; do
86*a3f6a89cSMarc Zyngier	    cat <<EOF
87*a3f6a89cSMarc Zyngier#if defined($b) && ($b > 0)
88*a3f6a89cSMarc Zyngier	[${b}_BIT]	= "$b",
89*a3f6a89cSMarc Zyngier#endif
90*a3f6a89cSMarc ZyngierEOF
91608e8e66SMel Gorman	done
92608e8e66SMel Gorman
93*a3f6a89cSMarc Zyngier    cat <<EOF
94*a3f6a89cSMarc Zyngier};
95*a3f6a89cSMarc Zyngier
96*a3f6a89cSMarc Zyngierint main(int argc, char *argv[])
97*a3f6a89cSMarc Zyngier{
98*a3f6a89cSMarc Zyngier	unsigned long long mask = $GFPMASK;
99*a3f6a89cSMarc Zyngier
100*a3f6a89cSMarc Zyngier	for (int i = 0; i < sizeof(mask) * 8; i++) {
101*a3f6a89cSMarc Zyngier		unsigned long long bit = 1ULL << i;
102*a3f6a89cSMarc Zyngier		if (mask & bit)
103*a3f6a89cSMarc Zyngier			printf("\t%-25s0x%llx\n",
104*a3f6a89cSMarc Zyngier			       (i < ___GFP_LAST_BIT && masks[i]) ?
105*a3f6a89cSMarc Zyngier					masks[i] : "*** INVALID ***",
106*a3f6a89cSMarc Zyngier			       bit);
107*a3f6a89cSMarc Zyngier	}
108*a3f6a89cSMarc Zyngier
109*a3f6a89cSMarc Zyngier	return 0;
110*a3f6a89cSMarc Zyngier}
111*a3f6a89cSMarc ZyngierEOF
112*a3f6a89cSMarc Zyngier) > $TMPFILE
113*a3f6a89cSMarc Zyngier
114*a3f6a89cSMarc Zyngier${CC:-gcc} -Wall -o ${TMPFILE}.bin -I $SOURCE/include $TMPFILE && ${TMPFILE}.bin
115*a3f6a89cSMarc Zyngier
116*a3f6a89cSMarc Zyngierrm -f $TMPFILE ${TMPFILE}.bin
117*a3f6a89cSMarc Zyngier
118608e8e66SMel Gormanexit 0
119