blob: 31f78944d9ec2d503329a4d8b687e31995dd18e8 [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
David Brazdil863b1502019-10-24 13:55:50 +010081 tool("alink") {
82 outfile = "{{target_out_dir}}/{{target_output_name}}.a"
83 command = "rm -f $outfile && ${invoker.ar} -rc $outfile {{inputs}}"
84 description = "ALINK $outfile"
85 outputs = [
86 outfile,
87 ]
88 }
89
Andrew Scull23e93a82018-10-26 14:56:04 +010090 tool("stamp") {
91 command = "touch {{output}}"
92 description = "STAMP {{output}}"
93 }
94
95 tool("copy") {
96 command = "cp -af {{source}} {{output}}"
97 description = "COPY {{source}} {{output}}"
98 }
99
100 toolchain_args = {
101 forward_variables_from(invoker.toolchain_args, "*")
102 }
103 }
104}
105
106# Specialize for clang.
107template("embedded_clang_toolchain") {
108 assert(defined(invoker.target),
109 "\"target\" must be defined for ${target_name}.")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000110 assert(defined(invoker.extra_defines),
111 "\"extra_defines\" must be defined for ${target_name}")
112 assert(defined(invoker.extra_cflags),
113 "\"extra_cflags\" must be defined for ${target_name}")
114 assert(defined(invoker.extra_ldflags),
115 "\"extra_ldflags\" must be defined for ${target_name}")
Andrew Scull23e93a82018-10-26 14:56:04 +0100116
117 embedded_cc_toolchain(target_name) {
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000118 cc = "clang"
119 ld = "ld.lld"
David Brazdil863b1502019-10-24 13:55:50 +0100120 ar = "llvm-ar"
Andrew Scull23e93a82018-10-26 14:56:04 +0100121
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000122 forward_variables_from(invoker,
123 [
124 "extra_defines",
125 "extra_cflags",
126 "extra_ldflags",
127 ])
Andrew Walbran883a4b22019-03-05 15:13:56 +0000128
129 # TODO: Remove //inc/system if we can stop using the version of stdatomic.h
130 # from the Android prebuilt Clang.
131 extra_cflags +=
132 " -target ${invoker.target} -fcolor-diagnostics -nostdinc -isystem" +
Andrew Walbran93704502019-10-22 14:19:24 +0100133 rebase_path("//prebuilts/linux-x64/clang/lib64/clang/9.0.3/include") +
Andrew Walbran883a4b22019-03-05 15:13:56 +0000134 " -isystem" + rebase_path("//inc/system")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000135 extra_ldflags +=
136 " -O2 -lto-O2 --icf=all --fatal-warnings --color-diagnostics"
137
138 toolchain_args = {
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000139 if (defined(invoker.toolchain_args)) {
140 forward_variables_from(invoker.toolchain_args, "*")
141 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100142 }
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000143 }
144}
145
146# Specialize for mixed toolchain with clang and bfd linker.
147template("embedded_clang_bfd_toolchain") {
148 assert(defined(invoker.target),
149 "\"target\" must be defined for ${target_name}.")
150 assert(defined(invoker.tool_prefix),
151 "\"tool_prefix\" must be defined for ${target_name}.")
152 assert(defined(invoker.extra_defines),
153 "\"extra_defines\" must be defined for ${target_name}")
154 assert(defined(invoker.extra_cflags),
155 "\"extra_cflags\" must be defined for ${target_name}")
156 assert(defined(invoker.extra_ldflags),
157 "\"extra_ldflags\" must be defined for ${target_name}")
158
159 embedded_cc_toolchain(target_name) {
160 cc = "clang"
161 ld = "${invoker.tool_prefix}ld.bfd"
David Brazdil863b1502019-10-24 13:55:50 +0100162 ar = "llvm-ar"
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000163
164 forward_variables_from(invoker,
165 [
166 "extra_defines",
167 "extra_cflags",
168 "extra_ldflags",
169 ])
170 extra_cflags += " -target ${invoker.target} -fcolor-diagnostics"
Alfredo Mazzinghi8aa8c622019-01-18 17:40:58 +0000171 extra_ldflags += " --fatal-warnings"
172 if (use_lto) {
173 extra_ldflags += " -O2 -lto-O2 --icf=all"
174 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100175
176 toolchain_args = {
Andrew Scull23e93a82018-10-26 14:56:04 +0100177 if (defined(invoker.toolchain_args)) {
178 forward_variables_from(invoker.toolchain_args, "*")
179 }
180 }
181 }
182}
183
Andrew Walbranff28f3b2019-10-21 13:00:00 +0100184# Expand to clang variants.
Andrew Scull23e93a82018-10-26 14:56:04 +0100185template("embedded_platform_toolchain") {
186 assert(defined(invoker.arch), "\"arch\" must be defined for ${target_name}.")
187 assert(defined(invoker.target),
188 "\"target\" must be defined for ${target_name}.")
189 assert(defined(invoker.tool_prefix),
190 "\"tool_prefix\" must be defined for ${target_name}.")
191 assert(defined(invoker.origin_address),
192 "\"origin_address\" must be defined for ${target_name}.")
Andrew Walbrande33f082018-12-07 14:10:11 +0000193 assert(defined(invoker.heap_pages),
194 "\"heap_pages\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100195 assert(defined(invoker.max_cpus),
196 "\"max_cpus\" must be defined for ${target_name}.")
197 assert(defined(invoker.max_vms),
198 "\"max_vms\" must be defined for ${target_name}.")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000199 assert(defined(invoker.platform_name),
200 "\"platform_name\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100201
Andrew Walbran8e946692019-05-21 11:22:00 +0100202 extra_defines = ""
203 extra_cflags = "-fno-builtin -ffreestanding -fpic"
204 extra_ldflags = "--defsym=ORIGIN_ADDRESS=${invoker.origin_address}"
Andrew Scull23e93a82018-10-26 14:56:04 +0100205 if (defined(invoker.extra_defines)) {
Andrew Walbran8e946692019-05-21 11:22:00 +0100206 extra_defines += " ${invoker.extra_defines}"
Andrew Scull23e93a82018-10-26 14:56:04 +0100207 }
208 if (defined(invoker.extra_cflags)) {
Andrew Walbran8e946692019-05-21 11:22:00 +0100209 extra_cflags += " ${invoker.extra_cflags}"
Andrew Scull23e93a82018-10-26 14:56:04 +0100210 }
211 if (defined(invoker.extra_ldflags)) {
Andrew Walbran8e946692019-05-21 11:22:00 +0100212 extra_ldflags += " ${invoker.extra_ldflags}"
Andrew Scull23e93a82018-10-26 14:56:04 +0100213 }
Andrew Walbran8e946692019-05-21 11:22:00 +0100214 toolchain_args = {
215 use_platform = true
216 plat_name = invoker.platform_name
217 plat_arch = invoker.arch
218 plat_heap_pages = invoker.heap_pages
219 plat_max_cpus = invoker.max_cpus
220 plat_max_vms = invoker.max_vms
221 if (defined(invoker.toolchain_args)) {
222 forward_variables_from(invoker.toolchain_args, "*")
223 }
224 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100225
226 embedded_clang_toolchain("${target_name}_clang") {
227 target = invoker.target
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000228 }
229
230 embedded_clang_bfd_toolchain("${target_name}_clang_bfd") {
231 target = invoker.target
Andrew Walbranff28f3b2019-10-21 13:00:00 +0100232 tool_prefix = invoker.tool_prefix
Andrew Scull23e93a82018-10-26 14:56:04 +0100233 }
234}
235
236# Specialize for different architectures.
237
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000238template("aarch64_common_toolchain") {
Andrew Walbran549a9f22019-05-09 17:29:00 +0100239 assert(defined(invoker.cpu), "\"cpu\" must be defined for ${target_name}.")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000240 assert(defined(invoker.target),
241 "\"target\" must be defined for ${target_name}")
242 assert(defined(invoker.tool_prefix),
243 "\"tool_prefix\" must be defined for ${target_name}")
Andrew Scull23e93a82018-10-26 14:56:04 +0100244 assert(defined(invoker.origin_address),
245 "\"origin_address\" must be defined for ${target_name}.")
Andrew Walbran48699362019-05-20 14:38:00 +0100246 assert(defined(invoker.console),
247 "\"console\" must be defined for ${target_name}.")
Andrew Walbrande33f082018-12-07 14:10:11 +0000248 assert(defined(invoker.heap_pages),
249 "\"heap_pages\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100250 assert(defined(invoker.max_cpus),
251 "\"max_cpus\" must be defined for ${target_name}.")
252 assert(defined(invoker.max_vms),
253 "\"max_vms\" must be defined for ${target_name}.")
Andrew Walbran53f38762018-12-07 15:21:29 +0000254 if (invoker.gic_version == 3 || invoker.gic_version == 4) {
255 assert(defined(invoker.gicd_base_address),
256 "\"gicd_base_address\" must be defined for ${target_name}.")
257 assert(defined(invoker.gicr_base_address),
258 "\"gicr_base_address\" must be defined for ${target_name}.")
259 }
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000260 assert(defined(invoker.platform_name),
261 "\"platform_name\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100262
263 embedded_platform_toolchain(target_name) {
264 forward_variables_from(invoker,
265 [
266 "origin_address",
Andrew Walbrande33f082018-12-07 14:10:11 +0000267 "heap_pages",
Andrew Scull23e93a82018-10-26 14:56:04 +0100268 "max_cpus",
269 "max_vms",
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000270 "platform_name",
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000271 "extra_ldflags",
Andrew Scull23e93a82018-10-26 14:56:04 +0100272 ])
273 arch = "aarch64"
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000274 target = invoker.target
275 tool_prefix = invoker.tool_prefix
Andrew Scull23e93a82018-10-26 14:56:04 +0100276 extra_cflags = "-mcpu=${invoker.cpu} -mstrict-align"
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000277 if (defined(invoker.extra_cflags)) {
278 extra_cflags += " ${invoker.extra_cflags}"
279 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100280
Andrew Walbran53f38762018-12-07 15:21:29 +0000281 extra_defines = ""
Alfredo Mazzinghi62e91562019-02-13 17:11:23 +0000282 if (defined(invoker.extra_defines)) {
283 extra_defines += " ${invoker.extra_defines}"
284 }
285
Andrew Walbran53f38762018-12-07 15:21:29 +0000286 if (invoker.gic_version > 0) {
287 extra_defines += " -DGIC_VERSION=${invoker.gic_version}"
288 }
289 if (invoker.gic_version == 3 || invoker.gic_version == 4) {
290 extra_defines += " -DGICD_BASE=${invoker.gicd_base_address} -DGICR_BASE=${invoker.gicr_base_address}"
Andrew Scull23e93a82018-10-26 14:56:04 +0100291 }
292
293 toolchain_args = {
David Brazdil0dbb41f2019-09-09 18:03:35 +0100294 plat_boot_flow = invoker.boot_flow
Andrew Walbran48699362019-05-20 14:38:00 +0100295 plat_console = invoker.console
296 forward_variables_from(invoker.toolchain_args, "*")
Andrew Scull23e93a82018-10-26 14:56:04 +0100297 }
298 }
299}
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000300
301template("aarch64_toolchain") {
302 aarch64_common_toolchain("${target_name}") {
303 forward_variables_from(invoker, "*")
304 target = "aarch64-none-eabi"
305 tool_prefix = "aarch64-linux-gnu-" # TODO: this isn't right for bare metal but it works.
306 platform_name = target_name
307 }
308}
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100309
310template("aarch64_toolchains") {
311 aarch64_toolchain("${target_name}") {
312 forward_variables_from(invoker,
313 [
314 "origin_address",
David Brazdil0dbb41f2019-09-09 18:03:35 +0100315 "boot_flow",
Andrew Walbran48699362019-05-20 14:38:00 +0100316 "console",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100317 "gic_version",
318 "gicd_base_address",
319 "gicr_base_address",
320 "heap_pages",
321 "max_cpus",
322 "max_vms",
Andrew Walbran48699362019-05-20 14:38:00 +0100323 "toolchain_args",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100324 ])
325 cpu = "${invoker.cpu}+nofp"
David Brazdil711fbe92019-08-06 13:39:58 +0100326
327 # Add a macro so files can tell whether they are not being built for a VM.
328 extra_defines = " -DVM_TOOLCHAIN=0"
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100329 }
330
331 # Toolchain for building test VMs which run under Hafnium.
332 aarch64_toolchain("${target_name}_vm") {
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100333 forward_variables_from(invoker,
334 [
335 "origin_address",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100336 "gic_version",
337 "gicd_base_address",
338 "gicr_base_address",
Andrew Walbranafabe852019-03-20 17:55:11 +0000339 "max_cpus",
Andrew Walbran48699362019-05-20 14:38:00 +0100340 "toolchain_args",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100341 ])
342 cpu = "${invoker.cpu}+fp"
David Brazdil0dbb41f2019-09-09 18:03:35 +0100343 boot_flow = "//src/arch/fake:boot_flow"
Andrew Walbran58954f92019-05-09 17:11:20 +0100344 console = "//src/arch/aarch64/hftest:console"
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100345
346 # Nonsense values because they are required but shouldn't be used.
347 heap_pages = 0
Andrew Walbran7f904bf2019-07-12 16:38:38 +0100348 max_vms = 0
David Brazdil711fbe92019-08-06 13:39:58 +0100349
350 # Add a macro so files can tell whether they are being built for a VM.
351 extra_defines = " -DVM_TOOLCHAIN=1"
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100352 }
353}