kevin / gru: Remove task profiling to improve SHI interrupt latency
[cros-ec.git] / Makefile.rules
1 # -*- makefile -*-
2 # vim: set filetype=make :
3 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6 #
7 # Embedded Controller firmware build system - common targets
8 #
9
10 build-utils := $(foreach u,$(build-util-bin),$(out)/util/$(u))
11 host-utils := $(foreach u,$(host-util-bin),$(out)/util/$(u))
12 build-srcs := $(foreach u,$(build-util-bin),$(sort $($(u)-objs:%.o=util/%.c) util/$(u).c))
13 host-srcs := $(foreach u,$(host-util-bin),$(sort $($(u)-objs:%.o=util/%.c) util/$(u).c))
14
15 # Don't do a build test on the following boards:
16 skip_boards = OWNERS host it83xx_evb
17 # Skip building cr50 if private folder is not present
18 ifeq ("$(wildcard ./private-cr51)","")
19 skip_boards += cr50
20 endif
21 boards := $(filter-out $(skip_boards),$(notdir $(wildcard board/* private*/board/*)))
22
23 # Create output directories if necessary
24 _common_dir_create := $(foreach d,$(common_dirs),$(shell [ -d $(out)/$(d) ] || \
25             mkdir -p $(out)/$(d)))
26 _sharedlib_dir_create := $(foreach d,$(dirs),$(shell \
27         [ -d $(out)/$(SHOBJLIB)/$(d) ] || mkdir -p $(out)/$(SHOBJLIB)/$(d)))
28 _dir_create := $(foreach d,$(dirs),$(shell [ -d $(out)/$(BLD)/$(d) ] || \
29             mkdir -p $(out)/RO/$(d); mkdir -p $(out)/RW/$(d)))
30 _dir_y_create := $(foreach d,$(dirs-y),$(shell [ -d $(out)/$(BLD)/$(d) ] || \
31             mkdir -p $(out)/RO/$(d); mkdir -p $(out)/RW/$(d)))
32
33 # Decrease verbosity unless you pass V=1
34 quiet = $(if $(V),,@echo '  $(2)' $(subst $(out)/,,$@) ; )$(cmd_$(1))
35 silent = $(if $(V),,1>/dev/null)
36 silent_err = $(if $(V),,2>/dev/null)
37
38 # commands to build all targets
39 cmd_lds = $(CPP) -P -C -MMD -MF $@.d -MT $@ $(CPPFLAGS) $< -o $@
40 cmd_lds_b = $(cmd_lds) -DRW_B_LDS
41 # Allow obj_to_bin to be overridden by board or chip specific commands
42 cmd_obj_to_bin ?= $(OBJCOPY) --gap-fill=0xff -O binary $^ $(out)/$*.bin.tmp
43 cmd_flat_to_obj = $(CC) -T $(out)/firmware_image.lds -nostdlib $(CPPFLAGS) \
44                   -Wl,--build-id=none -o $@ $<
45 # Allow the .roshared section to overlap other sections (itself)
46 cmd_ec_elf_to_flat ?= $(OBJCOPY) --set-section-flags .roshared=share \
47                                 -O binary $< $@
48 cmd_elf_to_signed ?= sudo $(out)/util/signer --key=util/signer/$(3) \
49         --input=$< --format=bin --output=$@.signed $(SIG_EXTRA) \
50         && sudo chown $(shell whoami) $@.signed && mv $@.signed $@
51 cmd_elf_to_dis = $(OBJDUMP) -D $< > $@
52 cmd_elf_to_hex = $(OBJCOPY) -O ihex $< $@
53 cmd_bin_to_hex = $(OBJCOPY) -I binary -O ihex \
54         --change-addresses $(_program_memory_base) $^ $@
55 cmd_smap = $(NM) $< | sort > $@
56 cmd_elf = $(CC) $(objs) $(libsharedobjs_elf-y) $(LDFLAGS) \
57         -o $@ -Wl,-T,$< -Wl,-Map,$(patsubst %.elf,%.map,$@)
58 cmd_exe = $(CC) $(ro-objs) $(HOST_TEST_LDFLAGS) -o $@
59 cmd_c_to_o = $(CC) $(CFLAGS) -MMD -MF $@.d -c $< -o $(@D)/$(@F)
60 cmd_c_to_build = $(BUILDCC) $(BUILD_CFLAGS) \
61                  $(sort $(foreach c,$($(*F)-objs),util/$(c:%.o=%.c)) $*.c) \
62                  $(BUILD_LDFLAGS) \
63                  -MMD -MF $@.d -o $@
64 cmd_c_to_host = $(HOSTCC) $(HOST_CFLAGS) -MMD -MF $@.d  -o $@ \
65                  $(sort $(foreach c,$($(*F)-objs),util/$(c:%.o=%.c)) $*.c)
66 cmd_cxx_to_host = $(HOSTCXX) -std=c++0x $(COMMON_WARN) $(HOST_CXXFLAGS)\
67         -I ./$($(notdir $@)_ROOT) -o $@ $(filter %.cc,$^) $($(notdir $@)_LIBS)
68 cmd_host_test = ./util/run_host_test $* $(silent)
69 cmd_version = ./util/getversion.sh > $@
70 cmd_mv_from_tmp = mv $(out)/$*.bin.tmp $(out)/$*.bin
71 cmd_extractrw-y = dd if=$(out)/$(PROJECT).bin.tmp of=$(out)/$(PROJECT).RW.bin \
72                bs=1 count=$(_rw_size) skip=$(_rw_off) $(silent_err)
73 cmd_copyrw-y = cd $(out) && cp RW/$(PROJECT).RW.flat RW/$(PROJECT).RW.bin
74 cmd_sharedlib_elf = $(CC) $(libsharedobjs_deps) \
75         -Wl,-T,common/ec.$(SHOBJLIB).ld $(LDFLAGS) \
76         -o $(out)/$(SHOBJLIB)/$(SHOBJLIB).elf \
77         -Wl,-Map,$(out)/$(SHOBJLIB)/$(SHOBJLIB).map
78
79 # commands for RSA signature
80 cmd_rsasign = futility sign --type usbpd1 --pem $(PEM) $(out)/$*.bin.tmp
81
82 # commands to build optional xref files
83 cmd_deps_to_list = cat $(deps) | tr -d ':\\' | tr ' ' '\012' \
84         | egrep '\.[chS]$$' | sort | uniq > $@
85 cmd_etags = etags -o $@ $(shell cat $<)
86 cmd_ctags = ctags -o $@ $(shell cat $<)
87 targ_if_prog = $(if $(shell which $(1) 2>/dev/null),$(2),)
88
89 FAILED_BOARDS_DIR = .failedboards
90 # When building with -j, it's easy to miss errors. If you don't have your shell
91 # configured to warn you about nonzero exit, you may not even notice that "make
92 # buildall -j" failed. To make it more obvious, we'll do one level of recursion
93 # here.
94 .PHONY: try_buildall
95 try_buildall: $(foreach b, $(boards), proj-$(b))
96
97 .PHONY: buildall
98 buildall:
99         @rm -rf $(FAILED_BOARDS_DIR)
100         @mkdir $(FAILED_BOARDS_DIR)
101         @for b in $(boards); do echo 'starting' > $(FAILED_BOARDS_DIR)/$$b; done
102         $(MAKE) try_buildall
103         $(MAKE) build_cts
104         $(MAKE) runtests
105         @touch .tests-passed
106         @echo "$@ completed successfully!"
107
108 # Print any important notices at the end of the build.
109 .PHONY: notice
110 notice: $(config)
111 ifeq ($(CONFIG_EXPERIMENTAL_CONSOLE),y)
112 ifeq ($(TEST_BUILD),)
113         @echo "*** NOTE: The experimental console is ENABLED. ***"
114         @echo "You will need to run the EC-3PO interactive console in the util"
115         @echo "directory!  Otherwise, you won't be able to enter any commands."
116 endif # not a TEST_BUILD
117 endif # CONFIG_EXPERIMENTAL_CONSOLE=y
118
119 proj-%:
120         @echo 'building' > $(FAILED_BOARDS_DIR)/$*
121         @echo "======= building $*"
122         $(MAKE) --no-print-directory BOARD=$* V=$(V)
123         @rm $(FAILED_BOARDS_DIR)/$*
124
125 dis-y := $(out)/RW/$(PROJECT).RW.dis
126 dis-$(CONFIG_FW_INCLUDE_RO) += $(out)/RO/$(PROJECT).RO.dis
127 dis-$(CONFIG_SHAREDLIB) += $(out)/$(SHOBJLIB)/$(SHOBJLIB).dis
128 dis: $(dis-y)
129 .PHONY: dis
130
131 hex-y := $(out)/RO/$(PROJECT).RO.hex $(out)/RW/$(PROJECT).RW.hex $(out)/$(PROJECT).hex
132 hex: $(hex-y)
133 .PHONY: hex
134
135 .PHONY: utils-host
136 utils-host: $(host-utils)
137
138 .PHONY: utils-build
139 utils-build: $(build-utils)
140
141 .PHONY: utils
142 utils: utils-host utils-build
143
144 # On board test binaries
145 test-targets=$(foreach t,$(test-list-y),test-$(t))
146 .PHONY: $(test-targets)
147
148 ifeq "$(CONFIG_COMMON_RUNTIME)" "y"
149 $(test-targets): test-%:
150         @set -e ; \
151         echo "  BUILD   $(out)/$*" ; \
152         $(MAKE) --no-print-directory BOARD=$(BOARD) PROJECT=$* \
153                 V=$(V) out=$(out)/$* TEST_BUILD=y; \
154         cp $(out)/$*/$*.bin $(out)/test-$*.bin
155 endif
156
157 .PHONY: tests
158 tests: $(test-targets)
159
160 # Emulator test executables
161 host-test-targets=$(foreach t,$(test-list-host),host-$(t))
162 run-test-targets=$(foreach t,$(test-list-host),run-$(t))
163 .PHONY: $(host-test-targets) $(run-test-targets)
164
165 $(host-test-targets): host-%:
166         @set -e ; \
167         echo "  BUILD   host - build/host/$*" ; \
168         $(MAKE) --no-print-directory BOARD=host PROJECT=$* \
169                 V=$(V) out=build/host/$* TEST_BUILD=y EMU_BUILD=y $(TEST_FLAG) \
170                 CROSS_COMPILE= build/host/$*/$*.exe
171
172 $(run-test-targets): run-%: host-%
173         $(call quiet,host_test,TEST   )
174
175 .PHONY: hosttests runtests
176 hosttests: $(host-test-targets)
177 runtests: $(run-test-targets)
178
179 # Automatically enumerate all suites.
180 cts_excludes := common
181 cts_suites := $(filter-out $(cts_excludes), \
182         $(shell find cts -maxdepth 1 -mindepth 1 -type d -printf "%f "))
183
184 # Add boards below as CTS is expanded.
185 cts_boards := stm32l476g-eval nucleo-f072rb
186
187 .PHONY: build_cts
188
189 # Create CTS rule automatically for given suite and board
190 # $1: suite name
191 # $2: board name
192 # $3: suite name used in the previous loop
193 define make-cts =
194 ifneq ($$(filter $(1),$$(cts_suites)),)
195 ifneq ($$(filter $(3),$$(cts_suites)),)
196 # Serialize builds
197 cts-$(1)-$(2): cts-$(3)-$(2)
198 endif
199 build_cts: cts-$(1)-$(2)
200 cts-$(1)-$(2):
201         $$(MAKE) CTS_MODULE=$(1) BOARD=$(2)
202 endif
203 # Do not remove this blank line
204
205 endef
206
207 # Create rules for all cts-suite-board combinations. Additionally, we serialize
208 # targets per board: cts-x-board -> cts-y-board -> ...
209 # If we don't serialize targets, parallel make fails because all suites
210 # try to produce ec.bin in the same directory (e.g. build/stm32l476g-eval).
211 $(foreach b, $(cts_boards), \
212         $(foreach s, $(cts_suites) none, \
213                 $(eval $(call make-cts,$(s),$(b),$(prev)) prev:=$(s)) \
214         ) \
215 )
216
217 cov-test-targets=$(foreach t,$(test-list-host),build/host/$(t).info)
218 bldversion=$(shell (./util/getversion.sh ; echo VERSION) | $(CPP) -P)
219
220 # lcov fails when multiple instances run at the same time.
221 # We need to run them sequentially by using flock
222 cmd_lcov=flock /tmp/ec-lcov-lock -c "lcov -q -o $@ -c -d build/host/$*"
223 cmd_report_cov=genhtml -q -o build/host/coverage_rpt -t \
224                "EC Unittest "$(bldversion) $^
225
226 build/host/%.info: run-%
227         $(call quiet,lcov,COV    )
228
229 .PHONY: coverage
230 coverage: TEST_FLAG=TEST_COVERAGE=y
231 coverage: $(cov-test-targets)
232         $(call quiet,report_cov,REPORT )
233
234 $(out)/firmware_image.lds: common/firmware_image.lds.S
235         $(call quiet,lds,LDS    )
236 $(out)/%.lds: core/$(CORE)/ec.lds.S
237         $(call quiet,lds,LDS    )
238
239 $(out)/%_B.lds: core/$(CORE)/ec.lds.S
240         $(call quiet,lds_b,LDS_B  )
241
242 $(out)/%.bin: $(out)/%.obj
243         $(call quiet,obj_to_bin,OBJCOPY)
244         $(if $(wildcard $(PEM)),$(call quiet,rsasign,SIGN   ),)
245         $(if $(wildcard $(PEM)),$(call quiet,extractrw-y,EXTR_RW), \
246                         $(call quiet,copyrw-y,COPY_RW))
247         $(call quiet,mv_from_tmp,MV     )
248
249 flat-y := $(out)/RW/$(PROJECT).RW.flat
250 flat-$(CONFIG_FW_INCLUDE_RO) += $(out)/RO/$(PROJECT).RO.flat
251
252 deps += $(out)/firmware_image.lds.d $(flat-y:%.flat=%.lds.d)
253
254 flat-$(CONFIG_SHAREDLIB) += $(libsharedobjs-y)
255
256 $(out)/$(PROJECT).obj: common/firmware_image.S $(out)/firmware_image.lds \
257         $(flat-y)
258         $(call quiet,flat_to_obj,CAT    )
259
260 $(out)/%.dis: $(out)/%.elf
261         $(call quiet,elf_to_dis,OBJDUMP)
262
263 $(out)/RW/%.hex: $(out)/RW/%.elf $(out)/RW/%.smap
264         $(call quiet,elf_to_hex,OBJCOPY)
265
266 ifeq ($(SIGNED_IMAGES),)
267 $(out)/%.flat: $(out)/%.elf $(out)/%.smap utils-build
268         $(call quiet,ec_elf_to_flat,OBJCOPY)
269
270 $(out)/RO/%.hex: $(out)/RO/%.elf $(out)/RO/%.smap
271         $(call quiet,elf_to_hex,OBJCOPY)
272 else
273 $(out)/RO/%.flat: $(out)/RO/%.elf  $(out)/RO/%.smap
274         $(call quiet,elf_to_signed,RO_SIGN,$(CR50_RO_KEY))
275
276 $(out)/RW/%.flat: $(out)/RW/%.elf  $(out)/RW/%.smap
277         $(call quiet,elf_to_signed,RW_SIGN,loader-testkey-A.pem)
278
279 $(out)/RO/%.hex: $(out)/RO/%.flat
280         $(call quiet,bin_to_hex,OBJCOPY)
281 endif
282 $(out)/$(PROJECT).hex: $(out)/$(PROJECT).bin
283         $(call quiet,bin_to_hex,OBJCOPY)
284
285 $(out)/RW/%.elf: override BLD:=RW
286 $(out)/RW/%.elf: private objs := $(rw-objs)
287 $(out)/RW/%.elf: $(out)/RW/%.lds $(rw-objs) $(libsharedobjs_elf-y)
288         $(call quiet,elf,LD     )
289
290 $(out)/RO/%.elf: override BLD:=RO
291 $(out)/RO/%.elf: private objs := $(ro-objs)
292 $(out)/RO/%.elf: $(out)/RO/%.lds $(ro-objs) $(libsharedobjs_elf-y)
293         $(call quiet,elf,LD     )
294
295 $(out)/%.elf: $(out)/%.lds $(objs)
296         $(call quiet,elf,LD     )
297
298 $(out)/$(SHOBJLIB)/$(SHOBJLIB).elf: $(sharedlib-objs)
299         @mkdir -p $(out)/$(SHOBJLIB)
300         $(call quiet,sharedlib_elf,LD     )
301
302 $(out)/%.smap: $(out)/%.elf
303         $(call quiet,smap,NM     )
304
305 $(out)/$(PROJECT).exe: $(ro-objs)
306         $(call quiet,exe,EXE    )
307
308 $(out)/RO/%.o:%.c
309         $(call quiet,c_to_o,CC     )
310 $(out)/RW/%.o:%.c
311         $(call quiet,c_to_o,CC     )
312
313 $(out)/$(SHOBJLIB)/%.o: override LATE_CFLAGS_DEFINE:=-DSHAREDLIB_IMAGE
314 $(out)/$(SHOBJLIB)/%.o:%.c
315         $(call quiet,c_to_o,CC     )
316
317 $(out)/RO/%.o:%.S
318         $(call quiet,c_to_o,AS     )
319 $(out)/RW/%.o:%.S
320         $(call quiet,c_to_o,AS     )
321
322
323 # Conditionally force the rebuilding of ec_version.h only if it would be
324 # changed.
325 old_version_hash := $(shell cat $(out)/ec_version.h 2> /dev/null | md5sum -)
326 new_version_hash := $(shell BOARD=$(BOARD) ./util/getversion.sh | md5sum -)
327
328 ifneq ($(old_version_hash),$(new_version_hash))
329 .PHONY: $(out)/ec_version.h
330 endif
331
332 # All of the objects have an order only dependency on the ec_version header.
333 # This ensures that if ec_version.h needs to be built (because it was marked
334 # PHONY above) then it will be rebuilt before any objects.  This is important
335 # because some source files will include ec_version.h and fail to compile if
336 # it doesn't already exist.  This dependency shouldn't be a normal dependency
337 # because that would cause every object to be rebuilt when ec_version.h
338 # changes, instead of just the ones that actually depend on it.  The objects
339 # that truly depend on ec_version.h will have that information encoded in their
340 # .d file.
341 $(ro-objs): | $(out)/ec_version.h
342 $(rw-objs): | $(out)/ec_version.h
343 $(sharedlib-objs): | $(out)/ec_version.h
344
345 $(out)/ec_version.h:
346         $(call quiet,version,VERSION)
347
348 $(build-utils): $(out)/%:$(build-srcs)
349         $(call quiet,c_to_build,BUILDCC)
350
351 $(host-utils): $(out)/%:$(host-srcs)
352         $(call quiet,c_to_host,HOSTCC )
353
354 $(out)/cscope.files: $(out)/$(PROJECT).bin
355         $(call quiet,deps_to_list,SH     )
356
357 $(out)/TAGS: $(out)/cscope.files
358         $(call quiet,etags,ETAGS  )
359
360 $(out)/tags: $(out)/cscope.files
361         $(call quiet,ctags,CTAGS  )
362
363 # TODO: optional make rules for PROJECT_EXTRA
364 $(npcx-flash-fw-bin):
365         $(if $(V),,@echo '  EXTBIN ' $(subst $(out)/,,$@) ; )
366         -@ mkdir -p $(@D)
367         -@ $(CC) $(CFLAGS) -MMD -MF $(out)/$(npcx-lfw).d -c $(npcx-flash-fw).c \
368                 -o $(out)/$(npcx-flash-fw).o
369         -@ $(CC) $(out)/$(npcx-flash-fw).o $(LDFLAGS) \
370                 -o $(out)/$(npcx-flash-fw).elf -Wl,-T,$(npcx-flash-fw).ld \
371                 -Wl,-Map,$(out)/$(npcx-flash-fw).map
372         -@ $(OBJCOPY) -O binary $(out)/$(npcx-flash-fw).elf $@
373
374 .PHONY: xrefs
375 xrefs: $(call targ_if_prog,etags,$(out)/TAGS) \
376         $(call targ_if_prog,ctags,$(out)/tags)
377
378 .PHONY: flash
379 flash: $(out)/ec.bin
380         openocd -c "set BOARD $(BOARD)"\
381                 -c "set BUILD_DIR $(out)"\
382                 -f $(BDIR)/openocd-flash.cfg
383
384 .PHONY: flash_ec
385 flash_ec: $(out)/ec.bin
386         ./util/flash_ec --board $(BOARD) --image $(out)/ec.bin
387
388 .PHONY: flash_dfu
389 flash_dfu: $(out)/ec.bin
390         sudo ./$(BDIR)/dfu $(out)/ec.bin
391
392 .PHONY: clean
393 clean:
394         -rm -rf $(out)
395
396 .PHONY: clobber
397 clobber:
398         -rm -rf build TAGS cscope.files cscope.out
399
400 .SECONDARY:
401
402 -include $(deps)