summaryrefslogtreecommitdiffstats
path: root/util/checklist/Makefile.inc
blob: 362498e35882d75f9131ba3afb9fe5b8151aa93e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
#
# This file is part of the coreboot project.
#
# Copyright (C) 2016 Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#

###########################################################################
# Instructions
###########################################################################
#
# Create new control files for checklist:
#
#     1. Remove any selection for CREATE_BOARD_CHECKLIST
#     2. Remove any selection for MAKE_CHECKLIST_PUBLIC
#     3. make
#     4. nm build/cbfs/fallback/<stage>.debug > <stage>_symbols.txt
#     6. sed 's/^...........//' <stage>_symbols.txt > <stage>_complete.dat
#     7. grep -F " W " <stage>_symbols.txt | sed 's/^...........//' \
#             > <stage>_optional.dat
#     8. Edit <stage>_complete.dat to remove any symbols that are not
#        desired in the report
#     9. Edit <stage>_optional.dat to remove any symbols that are
#        required to be implemented
#
# Create a board checklist:
#
#     1. select CREATE_BOARD_CHECKLIST
#     2. Optionally: select MAKE_CHECKLIST_PUBLIC
#     3. Specify CONFIG_CHECKLIST_DATA_FILE_LOCATION
#     4. make
#
# Build Errors:
#     * No checklist built - verify CREATE_BOARD_CHECKLIST is selected in
#           board Kconfig file.  Do a make clean
#     * <stage>_complete.dat not found - verify that
#           CONFIG_CHECKLIST_DATA_FILE_LOCATION points to the directory
#           containing the checklist data files.  Build the checklist
#           data files if necessary.
#     * Segmentation fault - most likely caused by $(NM_$(class)) not being
#           set.
#
###########################################################################
# Build the board implementation checklist
###########################################################################

# Only build the checklist for boards under development
ifeq ($(CONFIG_CREATE_BOARD_CHECKLIST),y)

#
# Extract the symbol table from the image
#
%.symbol_table: %.elf %.debug
	$(NM_$(class)) $(*D)/$(*F).debug > $@
	$(NM_$(class)) $< >> $@

#
# All symbols in the image
#
# 1. Remove the address and symbol type
# 2. Sort the table into alphabetical order
# 3. Remove any duplicates
#
%.symbols: %.symbol_table
	sed 's/^...........//' $< > $@.tmp
	sort $@.tmp > $@.tmp2
	uniq $@.tmp2 > $@
	rm $@.tmp $@.tmp2

#
# Weak symbols in the image
#
# 1. Find the weak symbols
# 2. Remove the address and symbol type
# 3. Sort the table into alphabetical order
# 4. Remove any duplicates
#
%.weak: %.symbol_table
	grep -F " W " $< | sed 's/^...........//' > $@.tmp
	sort $@.tmp > $@.tmp2
	uniq $@.tmp2 > $@
	rm $@.tmp $@.tmp2

#
# Expected symbols in the image
#
# 1. Get the complete list of expected symbols in the image
# 2. Sort the table into alphabetical order
# 3. Remove any duplicates
#
%.expected: %.symbol_table
	cp $(CONFIG_CHECKLIST_DATA_FILE_LOCATION)/$(basename $(*F))_complete.dat $@.tmp
	cat $(CONFIG_CHECKLIST_DATA_FILE_LOCATION)/$(basename $(*F))_optional.dat >> $@.tmp
	# If no separate verstage, combine verstage and romstage routines into a single list
	if [ "$(*F)" = "romstage" ]; then \
	  if [ ! -e $(*D)/verstage.elf ]; then \
	    if [ ! -e $(*D)/postcar.elf ]; then \
	      cat $(CONFIG_CHECKLIST_DATA_FILE_LOCATION)/verstage_complete.dat >> $@.tmp; \
	      cat $(CONFIG_CHECKLIST_DATA_FILE_LOCATION)/verstage_optional.dat >> $@.tmp; \
	    fi; \
	  fi; \
	fi
	sort $@.tmp > $@.tmp2
	uniq $@.tmp2 > $@
	rm $@.tmp $@.tmp2

#
# Optional symbols in the image
#
# 1. Get the list of optional symbols in the image
# 2. Sort the table into alphabetical order
# 3. Remove any duplicates
#
%.optional: %.symbol_table
	cp $(CONFIG_CHECKLIST_DATA_FILE_LOCATION)/$(basename $(*F))_optional.dat $@.tmp
	# If no separate verstage, combine verstage and romstage routines into a single list
	if [ "$(*F)" = "romstage" ]; then \
	  if [ ! -e $(*D)/verstage.elf ]; then \
	    if [ ! -e $(*D)/postcar.elf ]; then \
	      cat $(CONFIG_CHECKLIST_DATA_FILE_LOCATION)/verstage_optional.dat >> $@.tmp; \
	    fi; \
	  fi; \
	fi
	sort $@.tmp > $@.tmp2
	uniq $@.tmp2 > $@
	rm $@.tmp $@.tmp2

#
#   Expected Symbols Optional	Weak	Done	Type
#	no	yes	no	d/c	yes	Don't display
#	yes	no	no	no	no	Required - not implemented
#	yes	no	yes	no	no	Optional - not implemented
#	yes	yes	yes	yes	no	Optional - not implemented
#	yes	yes	no	no	yes	Required - implemented
#	yes	yes	yes	no	yes	Required - implemented
#
# Implemented routines are in the symbol table and are not weak
#
# 1. Remove expected symbols which are not in the image (not implemented yet)
# 2. Remove weak symbols from the list (not implemented yet)
#
%.done: %.symbols %.expected %.weak %.optional
	comm -12 $(*D)/$(*F).expected $(*D)/$(*F).symbols | sed "s/^[ \t]*//" > $@.tmp
	comm -23 $@.tmp $(*D)/$(*F).weak | sed "s/^[ \t]*//" > $@
	rm $@.tmp

#
# Remove any routines that are implemented
#
%.optional2: %.optional %.done
	comm -23 $^ | sed "s/^[ \t]*//" > $@

#
# Remove any implemented or optional routines
#
%.tbd: %.expected %.done %.optional2
	comm -23 $(*D)/$(*F).expected $(*D)/$(*F).done | sed "s/^[ \t]*//" > $@.tmp
	comm -23 $@.tmp $(*D)/$(*F).optional2 | sed "s/^[ \t]*//" > $@
	rm $@.tmp

#
# Build the implementation table for each stage
# 1. Color code the rows
#    *  Done table rows are in green
#    *  Optional table rows are in yellow
#    *  TBD table rows are in red
# 2. Add the row termination
# 3. Sort the rows into alphabetical order
#
%.table_rows: %.optional2 %.done %.expected %.tbd
	sed -e 's/^/<tr bgcolor=#c0ffc0><td>Required<\/td><td>/' $(*D)/$(basename $(*F)).done > $@.tmp
	sed -e 's/^/<tr bgcolor=#ffffc0><td>Optional<\/td><td>/' $(*D)/$(basename $(*F)).optional2 >> $@.tmp
	if [ -s $(*D)/$(basename $(*F)).tbd ]; then \
	  sed -e 's/^/<tr bgcolor=#ffc0c0><td>Required<\/td><td>/' $(*D)/$(basename $(*F)).tbd >> $@.tmp; \
	fi
	sed -e 's/$$/<\/td><\/tr>/' -i $@.tmp
	sort -t ">" -k4 $@.tmp > $@
	rm $@.tmp

#
# Count the lines in the done file
#
done_lines = $$(wc -l $(*D)/$(basename $(*F)).done | sed 's/ .*//')

#
# Count the lines in the optional file
#
optional_lines = $$(wc -l $(*D)/$(basename $(*F)).optional2 | sed 's/ .*//')

#
# Count the lines in the expected file
#
expected_lines = $$(wc -l $(*D)/$(basename $(*F)).expected | sed 's/ .*//')

# Compute the percentage done by routine count
percent_complete = $$(($(done_lines) * 100 / ($(expected_lines) - $(optional_lines))))

#
# Build the table
# 1. Add the table header
# 2. Add the table rows
# 3. Add the table trailer
#
%.html: %.table_rows
	echo "<table border=1>" > $@
	echo "<tr><th colspan=2>$(basename $(*F)): $(percent_complete)% Done</th></tr>" >> $@
	echo "<tr><th>Type</th><th>Routine</td></tr>" >> $@
	cat $< >> $@
	echo "</table>" >> $@

#
# Determine which HTML files to include into the webpage
#
ifeq ($(CONFIG_C_ENVIRONMENT_BOOTBLOCK),y)
html_table_files += $(objcbfs)/bootblock.html
endif
ifeq ($(CONFIG_SEPARATE_VERSTAGE),y)
html_table_files += $(objcbfs)/verstage.html
endif
html_table_files += $(objcbfs)/romstage.html
ifeq ($(CONFIG_POSTCAR_STAGE),y)
html_table_files += $(objcbfs)/postcar.html
endif
html_table_files += $(objcbfs)/ramstage.html

#
# Create a list with each file on a separate line
#
list_of_html_files = $(subst _NEWLINE_,${\n},${html_table_files})

#
# Get the date for the webpage
#
current_date_time = $$(date +"%Y/%m/%d %T %Z")

#
# Build the webpage from the implementation tables
# 1. Add the header to the webpage
# 2. Add the legend to the webpage
# 3. Use a table to place stage tables side-by-side
# 4. Add the stage tables to the webpage
# 5. Separate the stage tables
# 6. Terminate the outer table
# 7. Add the trailer to the webpage
#
$(obj)/$(CONFIG_MAINBOARD_PART_NUMBER)_checklist.html: $(html_table_files)
	echo "<html>" > $@
	echo "<head>" >> $@
	echo "<title>$(CONFIG_MAINBOARD_PART_NUMBER) Implementation Status</title>" >> $@
	echo "</title>" >> $@
	echo "<body>" >> $@
	echo "<h1>$(CONFIG_MAINBOARD_PART_NUMBER) Implementation Status<br>$(current_date_time)</h1>" >> $@
	echo "<table>" >> $@
	echo "  <tr><td colspan=2><b>Legend</b></td></tr>" >> $@
	echo "  <tr><td bgcolor=\"#ffc0c0\">Red</td><td>Required - To-be-implemented</td></tr>" >> $@
	echo "  <tr><td bgcolor=\"#ffffc0\">Yellow</td><td>Optional</td></tr>" >> $@
	echo "  <tr><td bgcolor=\"#c0ffc0\">Green</td><td>Implemented</td></tr>" >> $@
	echo "</table>" >> $@
	echo "<table>" >> $@
	echo "  <tr valign=\"top\">" >> $@
	for table in $(list_of_html_files); do \
	  echo "    <td>" >> $@; \
	  cat $$table >> $@; \
	  echo "    </td>" >> $@; \
	  echo "    <td width=5>&nbsp;</td>" >> $@; \
	done
	echo "  </tr>" >> $@
	echo "</table>" >> $@
	echo "</body>" >> $@
	echo "</html>" >> $@

#
# Copy the output file into the Documentation directory
#
Documentation/$(CONFIG_MAINBOARD_VENDOR)/Board/$(CONFIG_MAINBOARD_PART_NUMBER)_checklist.html: $(obj)/$(CONFIG_MAINBOARD_PART_NUMBER)_checklist.html
	if [ ! -d Documentation/$(CONFIG_MAINBOARD_VENDOR) ]; then \
	  mkdir Documentation/$(CONFIG_MAINBOARD_VENDOR); \
	fi
	if [ ! -d Documentation/$(CONFIG_MAINBOARD_VENDOR)/Board ]; then \
	  mkdir Documentation/$(CONFIG_MAINBOARD_VENDOR)/Board; \
	fi
	cp $< $@

#
# Determine where to place the output file
#
ifeq ($(CONFIG_MAKE_CHECKLIST_PUBLIC),y)
INTERMEDIATE+=Documentation/$(CONFIG_MAINBOARD_VENDOR)/Board/$(CONFIG_MAINBOARD_PART_NUMBER)_checklist.html
else
INTERMEDIATE+=$(obj)/$(CONFIG_MAINBOARD_PART_NUMBER)_checklist.html
endif

endif