blob: ddf17d92640dcb66d16c7119a7ebba000e5c0c48 [file] [log] [blame]
Andrew Walbran692b3252019-03-07 15:51:31 +00001# Copyright 2018 The Hafnium Authors.
Andrew Scull23e93a82018-10-26 14:56:04 +01002#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15declare_args() {
16 # Set by arch toolchain. Prefix for binutils tools.
17 tool_prefix = ""
Alfredo Mazzinghi8aa8c622019-01-18 17:40:58 +000018
19 # Enable link time optimizations
20 use_lto = true
Andrew Scull23e93a82018-10-26 14:56:04 +010021}
22
23# Template for embedded toolchains; there is no support for C++ or libraries.
24# Instead, use source_set to group source together.
25template("embedded_cc_toolchain") {
26 toolchain(target_name) {
27 assert(defined(invoker.cc), "\"cc\" must be defined for ${target_name}.")
28 assert(defined(invoker.ld), "\"ld\" must be defined for ${target_name}.")
29
30 # Collect extra flags from the toolchain.
31 extra_defines = ""
Alfredo Mazzinghi8aa8c622019-01-18 17:40:58 +000032 extra_cflags = "-ffunction-sections -fdata-sections"
33 if (use_lto) {
34 extra_cflags += " -flto"
35 }
36 extra_ldflags = "-pie --gc-sections"
37
Andrew Scull23e93a82018-10-26 14:56:04 +010038 if (defined(invoker.extra_defines)) {
39 extra_defines += " ${invoker.extra_defines}"
40 }
41 if (defined(invoker.extra_cflags)) {
42 extra_cflags += " ${invoker.extra_cflags}"
43 }
44 if (defined(invoker.extra_ldflags)) {
45 extra_ldflags += " ${invoker.extra_ldflags}"
46 }
47
48 # Define the tools.
49 tool("cc") {
50 depfile = "{{output}}.d"
51 command = "${invoker.cc} -MMD -MF $depfile ${extra_defines} {{defines}} {{include_dirs}} ${extra_cflags} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
52 depsformat = "gcc"
53 description = "CC {{output}}"
54 outputs = [
55 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
56 ]
57 }
58
59 tool("asm") {
60 depfile = "{{output}}.d"
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +000061 command = "${invoker.cc} -MMD -MF $depfile ${extra_defines} {{defines}} {{include_dirs}} ${extra_cflags} {{asmflags}} -c {{source}} -o {{output}}"
Andrew Scull23e93a82018-10-26 14:56:04 +010062 depsformat = "gcc"
63 description = "ASM {{output}}"
64 outputs = [
65 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
66 ]
67 }
68
69 tool("link") {
70 outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
71 rspfile = "$outfile.rsp"
72 command = "${invoker.ld} ${extra_ldflags} {{ldflags}} -o $outfile --start-group @$rspfile --end-group"
73 description = "LINK $outfile"
74 default_output_dir = "{{root_out_dir}}"
75 rspfile_content = "{{inputs}}"
76 outputs = [
77 outfile,
78 ]
79 }
80
81 tool("stamp") {
82 command = "touch {{output}}"
83 description = "STAMP {{output}}"
84 }
85
86 tool("copy") {
87 command = "cp -af {{source}} {{output}}"
88 description = "COPY {{source}} {{output}}"
89 }
90
91 toolchain_args = {
92 forward_variables_from(invoker.toolchain_args, "*")
93 }
94 }
95}
96
97# Specialize for clang.
98template("embedded_clang_toolchain") {
99 assert(defined(invoker.target),
100 "\"target\" must be defined for ${target_name}.")
101 assert(defined(invoker.tool_prefix),
102 "\"tool_prefix\" must be defined for ${target_name}.")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000103 assert(defined(invoker.extra_defines),
104 "\"extra_defines\" must be defined for ${target_name}")
105 assert(defined(invoker.extra_cflags),
106 "\"extra_cflags\" must be defined for ${target_name}")
107 assert(defined(invoker.extra_ldflags),
108 "\"extra_ldflags\" must be defined for ${target_name}")
Andrew Scull23e93a82018-10-26 14:56:04 +0100109
110 embedded_cc_toolchain(target_name) {
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000111 cc = "clang"
112 ld = "ld.lld"
Andrew Scull23e93a82018-10-26 14:56:04 +0100113
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000114 forward_variables_from(invoker,
115 [
116 "extra_defines",
117 "extra_cflags",
118 "extra_ldflags",
119 ])
Andrew Walbran883a4b22019-03-05 15:13:56 +0000120
121 # TODO: Remove //inc/system if we can stop using the version of stdatomic.h
122 # from the Android prebuilt Clang.
123 extra_cflags +=
124 " -target ${invoker.target} -fcolor-diagnostics -nostdinc -isystem" +
125 rebase_path("//prebuilts/linux-aarch64/musl/include") + " -isystem" +
126 rebase_path("//prebuilts/linux-x64/clang/lib64/clang/8.0.4/include") +
127 " -isystem" + rebase_path("//inc/system")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000128 extra_ldflags +=
129 " -O2 -lto-O2 --icf=all --fatal-warnings --color-diagnostics"
130
131 toolchain_args = {
132 tool_prefix = invoker.tool_prefix
133 if (defined(invoker.toolchain_args)) {
134 forward_variables_from(invoker.toolchain_args, "*")
135 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100136 }
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000137 }
138}
139
140# Specialize for mixed toolchain with clang and bfd linker.
141template("embedded_clang_bfd_toolchain") {
142 assert(defined(invoker.target),
143 "\"target\" must be defined for ${target_name}.")
144 assert(defined(invoker.tool_prefix),
145 "\"tool_prefix\" must be defined for ${target_name}.")
146 assert(defined(invoker.extra_defines),
147 "\"extra_defines\" must be defined for ${target_name}")
148 assert(defined(invoker.extra_cflags),
149 "\"extra_cflags\" must be defined for ${target_name}")
150 assert(defined(invoker.extra_ldflags),
151 "\"extra_ldflags\" must be defined for ${target_name}")
152
153 embedded_cc_toolchain(target_name) {
154 cc = "clang"
155 ld = "${invoker.tool_prefix}ld.bfd"
156
157 forward_variables_from(invoker,
158 [
159 "extra_defines",
160 "extra_cflags",
161 "extra_ldflags",
162 ])
163 extra_cflags += " -target ${invoker.target} -fcolor-diagnostics"
Alfredo Mazzinghi8aa8c622019-01-18 17:40:58 +0000164 extra_ldflags += " --fatal-warnings"
165 if (use_lto) {
166 extra_ldflags += " -O2 -lto-O2 --icf=all"
167 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100168
169 toolchain_args = {
170 tool_prefix = invoker.tool_prefix
171 if (defined(invoker.toolchain_args)) {
172 forward_variables_from(invoker.toolchain_args, "*")
173 }
174 }
175 }
176}
177
178# Specialize for gcc.
179template("embedded_gcc_toolchain") {
180 assert(defined(invoker.tool_prefix),
181 "\"tool_prefix\" must be defined for ${target_name}.")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000182 assert(defined(invoker.extra_defines),
183 "\"extra_defines\" must be defined for ${target_name}.")
184 assert(defined(invoker.extra_cflags),
185 "\"extra_cflags\" must be defined for ${target_name}.")
186 assert(defined(invoker.extra_ldflags),
187 "\"extra_ldflags\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100188
189 embedded_cc_toolchain(target_name) {
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000190 cc = "${invoker.tool_prefix}gcc"
Andrew Scull23e93a82018-10-26 14:56:04 +0100191 ld = "${invoker.tool_prefix}ld"
192
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000193 forward_variables_from(invoker,
194 [
195 "extra_defines",
196 "extra_cflags",
197 "extra_ldflags",
198 ])
199
200 extra_cflags += " -fdiagnostics-color=always"
Andrew Scull23e93a82018-10-26 14:56:04 +0100201
202 toolchain_args = {
203 tool_prefix = invoker.tool_prefix
204 if (defined(invoker.toolchain_args)) {
205 forward_variables_from(invoker.toolchain_args, "*")
206 }
207 }
208 }
209}
210
211# Expand to clang and gcc variants.
212template("embedded_platform_toolchain") {
213 assert(defined(invoker.arch), "\"arch\" must be defined for ${target_name}.")
214 assert(defined(invoker.target),
215 "\"target\" must be defined for ${target_name}.")
216 assert(defined(invoker.tool_prefix),
217 "\"tool_prefix\" must be defined for ${target_name}.")
218 assert(defined(invoker.origin_address),
219 "\"origin_address\" must be defined for ${target_name}.")
Andrew Walbrande33f082018-12-07 14:10:11 +0000220 assert(defined(invoker.heap_pages),
221 "\"heap_pages\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100222 assert(defined(invoker.max_cpus),
223 "\"max_cpus\" must be defined for ${target_name}.")
224 assert(defined(invoker.max_vms),
225 "\"max_vms\" must be defined for ${target_name}.")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000226 assert(defined(invoker.platform_name),
227 "\"platform_name\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100228
229 defines = ""
Andrew Sculla59f9bc2019-04-03 15:24:35 +0100230 cflags = "-fno-builtin -ffreestanding -fpic"
Andrew Scull23e93a82018-10-26 14:56:04 +0100231 ldflags = "--defsym=ORIGIN_ADDRESS=${invoker.origin_address}"
232 if (defined(invoker.extra_defines)) {
233 defines += " ${invoker.extra_defines}"
234 }
235 if (defined(invoker.extra_cflags)) {
236 cflags += " ${invoker.extra_cflags}"
237 }
238 if (defined(invoker.extra_ldflags)) {
239 ldflags += " ${invoker.extra_ldflags}"
240 }
241
242 embedded_clang_toolchain("${target_name}_clang") {
243 target = invoker.target
244 tool_prefix = invoker.tool_prefix
245 extra_defines = defines
246 extra_cflags = cflags
247 extra_ldflags = ldflags
248 toolchain_args = {
Andrew Scullb401ba32018-11-09 10:30:54 +0000249 use_platform = true
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000250 plat_name = invoker.platform_name
251 plat_arch = invoker.arch
252 plat_heap_pages = invoker.heap_pages
253 plat_max_cpus = invoker.max_cpus
254 plat_max_vms = invoker.max_vms
255 if (defined(invoker.toolchain_args)) {
256 forward_variables_from(invoker.toolchain_args, "*")
257 }
258 }
259 }
260
261 embedded_clang_bfd_toolchain("${target_name}_clang_bfd") {
262 target = invoker.target
263 tool_prefix = invoker.tool_prefix
264 extra_defines = defines
265 extra_cflags = cflags
266 extra_ldflags = ldflags
267 toolchain_args = {
268 use_platform = true
269 plat_name = invoker.platform_name
Andrew Scullb401ba32018-11-09 10:30:54 +0000270 plat_arch = invoker.arch
Andrew Walbrande33f082018-12-07 14:10:11 +0000271 plat_heap_pages = invoker.heap_pages
Andrew Scullb401ba32018-11-09 10:30:54 +0000272 plat_max_cpus = invoker.max_cpus
273 plat_max_vms = invoker.max_vms
Andrew Scull23e93a82018-10-26 14:56:04 +0100274 if (defined(invoker.toolchain_args)) {
275 forward_variables_from(invoker.toolchain_args, "*")
276 }
277 }
278 }
279
280 embedded_gcc_toolchain("${target_name}_gcc") {
281 tool_prefix = invoker.tool_prefix
282 extra_defines = defines
283 extra_cflags = cflags
284 extra_ldflags = ldflags
285 toolchain_args = {
Andrew Scullb401ba32018-11-09 10:30:54 +0000286 use_platform = true
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000287 plat_name = invoker.platform_name
Andrew Scullb401ba32018-11-09 10:30:54 +0000288 plat_arch = invoker.arch
Andrew Walbrande33f082018-12-07 14:10:11 +0000289 plat_heap_pages = invoker.heap_pages
Andrew Scullb401ba32018-11-09 10:30:54 +0000290 plat_max_cpus = invoker.max_cpus
291 plat_max_vms = invoker.max_vms
Andrew Scull23e93a82018-10-26 14:56:04 +0100292 if (defined(invoker.toolchain_args)) {
293 forward_variables_from(invoker.toolchain_args, "*")
294 }
295 }
296 }
297}
298
299# Specialize for different architectures.
300
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000301template("aarch64_common_toolchain") {
Andrew Scull23e93a82018-10-26 14:56:04 +0100302 assert(defined(invoker.cpu), "\"cpu\" must be defiend for ${target_name}.")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000303 assert(defined(invoker.target),
304 "\"target\" must be defined for ${target_name}")
305 assert(defined(invoker.tool_prefix),
306 "\"tool_prefix\" must be defined for ${target_name}")
Andrew Scull23e93a82018-10-26 14:56:04 +0100307 assert(defined(invoker.origin_address),
308 "\"origin_address\" must be defined for ${target_name}.")
309 assert(defined(invoker.use_pl011),
310 "\"use_pl011\" must be defined for ${target_name}.")
Andrew Walbrande33f082018-12-07 14:10:11 +0000311 assert(defined(invoker.heap_pages),
312 "\"heap_pages\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100313 assert(defined(invoker.max_cpus),
314 "\"max_cpus\" must be defined for ${target_name}.")
315 assert(defined(invoker.max_vms),
316 "\"max_vms\" must be defined for ${target_name}.")
Andrew Walbran53f38762018-12-07 15:21:29 +0000317 if (invoker.gic_version == 3 || invoker.gic_version == 4) {
318 assert(defined(invoker.gicd_base_address),
319 "\"gicd_base_address\" must be defined for ${target_name}.")
320 assert(defined(invoker.gicr_base_address),
321 "\"gicr_base_address\" must be defined for ${target_name}.")
322 }
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000323 assert(defined(invoker.platform_name),
324 "\"platform_name\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100325
326 embedded_platform_toolchain(target_name) {
327 forward_variables_from(invoker,
328 [
329 "origin_address",
Andrew Walbrande33f082018-12-07 14:10:11 +0000330 "heap_pages",
Andrew Scull23e93a82018-10-26 14:56:04 +0100331 "max_cpus",
332 "max_vms",
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000333 "platform_name",
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000334 "extra_ldflags",
Andrew Scull23e93a82018-10-26 14:56:04 +0100335 ])
336 arch = "aarch64"
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000337 target = invoker.target
338 tool_prefix = invoker.tool_prefix
Andrew Scull23e93a82018-10-26 14:56:04 +0100339 extra_cflags = "-mcpu=${invoker.cpu} -mstrict-align"
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000340 if (defined(invoker.extra_cflags)) {
341 extra_cflags += " ${invoker.extra_cflags}"
342 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100343
Andrew Walbran53f38762018-12-07 15:21:29 +0000344 extra_defines = ""
Alfredo Mazzinghi62e91562019-02-13 17:11:23 +0000345 if (defined(invoker.extra_defines)) {
346 extra_defines += " ${invoker.extra_defines}"
347 }
348
Andrew Scull23e93a82018-10-26 14:56:04 +0100349 if (invoker.use_pl011) {
350 assert(defined(invoker.pl011_base_address),
351 "\"pl011_base_address\" must be defined for ${target_name}.")
Andrew Walbran53f38762018-12-07 15:21:29 +0000352 extra_defines += " -DPL011_BASE=${invoker.pl011_base_address}"
353 }
354 if (invoker.gic_version > 0) {
355 extra_defines += " -DGIC_VERSION=${invoker.gic_version}"
356 }
357 if (invoker.gic_version == 3 || invoker.gic_version == 4) {
358 extra_defines += " -DGICD_BASE=${invoker.gicd_base_address} -DGICR_BASE=${invoker.gicr_base_address}"
Andrew Scull23e93a82018-10-26 14:56:04 +0100359 }
360
361 toolchain_args = {
362 arch_aarch64_use_pl011 = invoker.use_pl011
363 }
364 }
365}
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000366
367template("aarch64_toolchain") {
368 aarch64_common_toolchain("${target_name}") {
369 forward_variables_from(invoker, "*")
370 target = "aarch64-none-eabi"
371 tool_prefix = "aarch64-linux-gnu-" # TODO: this isn't right for bare metal but it works.
372 platform_name = target_name
373 }
374}