blob: 6b6ab54a6add8cf723854ca9aff7fc522a35574f [file] [log] [blame]
Andrew Walbran692b3252019-03-07 15:51:31 +00001# Copyright 2018 The Hafnium Authors.
Andrew Scull23e93a82018-10-26 14:56:04 +01002#
Andrew Walbrane959ec12020-06-17 15:01:09 +01003# Use of this source code is governed by a BSD-style
4# license that can be found in the LICENSE file or at
5# https://opensource.org/licenses/BSD-3-Clause.
Andrew Scull23e93a82018-10-26 14:56:04 +01006
7declare_args() {
8 # Set by arch toolchain. Prefix for binutils tools.
9 tool_prefix = ""
Alfredo Mazzinghi8aa8c622019-01-18 17:40:58 +000010
11 # Enable link time optimizations
12 use_lto = true
Andrew Scull23e93a82018-10-26 14:56:04 +010013}
14
15# Template for embedded toolchains; there is no support for C++ or libraries.
16# Instead, use source_set to group source together.
17template("embedded_cc_toolchain") {
18 toolchain(target_name) {
19 assert(defined(invoker.cc), "\"cc\" must be defined for ${target_name}.")
20 assert(defined(invoker.ld), "\"ld\" must be defined for ${target_name}.")
21
22 # Collect extra flags from the toolchain.
23 extra_defines = ""
Alfredo Mazzinghi8aa8c622019-01-18 17:40:58 +000024 extra_cflags = "-ffunction-sections -fdata-sections"
25 if (use_lto) {
26 extra_cflags += " -flto"
27 }
28 extra_ldflags = "-pie --gc-sections"
29
Andrew Scull23e93a82018-10-26 14:56:04 +010030 if (defined(invoker.extra_defines)) {
31 extra_defines += " ${invoker.extra_defines}"
32 }
33 if (defined(invoker.extra_cflags)) {
34 extra_cflags += " ${invoker.extra_cflags}"
35 }
36 if (defined(invoker.extra_ldflags)) {
37 extra_ldflags += " ${invoker.extra_ldflags}"
38 }
39
40 # Define the tools.
41 tool("cc") {
42 depfile = "{{output}}.d"
43 command = "${invoker.cc} -MMD -MF $depfile ${extra_defines} {{defines}} {{include_dirs}} ${extra_cflags} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
44 depsformat = "gcc"
45 description = "CC {{output}}"
Olivier Deprez306d7812023-02-02 09:51:10 +010046 outputs =
47 [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
Andrew Scull23e93a82018-10-26 14:56:04 +010048 }
49
50 tool("asm") {
51 depfile = "{{output}}.d"
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +000052 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 +010053 depsformat = "gcc"
54 description = "ASM {{output}}"
Olivier Deprez306d7812023-02-02 09:51:10 +010055 outputs =
56 [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
Andrew Scull23e93a82018-10-26 14:56:04 +010057 }
58
59 tool("link") {
60 outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
61 rspfile = "$outfile.rsp"
62 command = "${invoker.ld} ${extra_ldflags} {{ldflags}} -o $outfile --start-group @$rspfile --end-group"
63 description = "LINK $outfile"
64 default_output_dir = "{{root_out_dir}}"
65 rspfile_content = "{{inputs}}"
Olivier Deprez306d7812023-02-02 09:51:10 +010066 outputs = [ outfile ]
Andrew Scull23e93a82018-10-26 14:56:04 +010067 }
68
David Brazdil863b1502019-10-24 13:55:50 +010069 tool("alink") {
70 outfile = "{{target_out_dir}}/{{target_output_name}}.a"
71 command = "rm -f $outfile && ${invoker.ar} -rc $outfile {{inputs}}"
72 description = "ALINK $outfile"
Olivier Deprez306d7812023-02-02 09:51:10 +010073 outputs = [ outfile ]
David Brazdil863b1502019-10-24 13:55:50 +010074 }
75
Andrew Scull23e93a82018-10-26 14:56:04 +010076 tool("stamp") {
77 command = "touch {{output}}"
78 description = "STAMP {{output}}"
79 }
80
81 tool("copy") {
82 command = "cp -af {{source}} {{output}}"
83 description = "COPY {{source}} {{output}}"
84 }
85
86 toolchain_args = {
87 forward_variables_from(invoker.toolchain_args, "*")
88 }
89 }
90}
91
92# Specialize for clang.
93template("embedded_clang_toolchain") {
94 assert(defined(invoker.target),
95 "\"target\" must be defined for ${target_name}.")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +000096 assert(defined(invoker.extra_defines),
97 "\"extra_defines\" must be defined for ${target_name}")
98 assert(defined(invoker.extra_cflags),
99 "\"extra_cflags\" must be defined for ${target_name}")
100 assert(defined(invoker.extra_ldflags),
101 "\"extra_ldflags\" must be defined for ${target_name}")
Andrew Scull23e93a82018-10-26 14:56:04 +0100102
103 embedded_cc_toolchain(target_name) {
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000104 cc = "clang"
105 ld = "ld.lld"
David Brazdil863b1502019-10-24 13:55:50 +0100106 ar = "llvm-ar"
Andrew Scull23e93a82018-10-26 14:56:04 +0100107
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000108 forward_variables_from(invoker,
109 [
110 "extra_defines",
111 "extra_cflags",
112 "extra_ldflags",
113 ])
Andrew Walbran883a4b22019-03-05 15:13:56 +0000114
115 # TODO: Remove //inc/system if we can stop using the version of stdatomic.h
116 # from the Android prebuilt Clang.
Olivier Deprez9fa36962021-09-20 14:32:14 +0100117 extra_cflags += " -target ${invoker.target} -fcolor-diagnostics -nostdinc" +
118 " -isystem ${toolchain_lib}/include" + " -isystem " +
119 rebase_path("//inc/system")
Olivier Deprezb9bb6c292021-04-20 13:45:38 +0200120 extra_ldflags += " -O2 --icf=all --fatal-warnings --color-diagnostics"
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000121
122 toolchain_args = {
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000123 if (defined(invoker.toolchain_args)) {
124 forward_variables_from(invoker.toolchain_args, "*")
125 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100126 }
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000127 }
128}
129
130# Specialize for mixed toolchain with clang and bfd linker.
131template("embedded_clang_bfd_toolchain") {
132 assert(defined(invoker.target),
133 "\"target\" must be defined for ${target_name}.")
134 assert(defined(invoker.tool_prefix),
135 "\"tool_prefix\" must be defined for ${target_name}.")
136 assert(defined(invoker.extra_defines),
137 "\"extra_defines\" must be defined for ${target_name}")
138 assert(defined(invoker.extra_cflags),
139 "\"extra_cflags\" must be defined for ${target_name}")
140 assert(defined(invoker.extra_ldflags),
141 "\"extra_ldflags\" must be defined for ${target_name}")
142
143 embedded_cc_toolchain(target_name) {
144 cc = "clang"
145 ld = "${invoker.tool_prefix}ld.bfd"
David Brazdil863b1502019-10-24 13:55:50 +0100146 ar = "llvm-ar"
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000147
148 forward_variables_from(invoker,
149 [
150 "extra_defines",
151 "extra_cflags",
152 "extra_ldflags",
153 ])
154 extra_cflags += " -target ${invoker.target} -fcolor-diagnostics"
Alfredo Mazzinghi8aa8c622019-01-18 17:40:58 +0000155 extra_ldflags += " --fatal-warnings"
156 if (use_lto) {
Olivier Deprezb9bb6c292021-04-20 13:45:38 +0200157 extra_ldflags += " -O2 --icf=all"
Alfredo Mazzinghi8aa8c622019-01-18 17:40:58 +0000158 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100159
160 toolchain_args = {
Andrew Scull23e93a82018-10-26 14:56:04 +0100161 if (defined(invoker.toolchain_args)) {
162 forward_variables_from(invoker.toolchain_args, "*")
163 }
164 }
165 }
166}
167
Andrew Walbranff28f3b2019-10-21 13:00:00 +0100168# Expand to clang variants.
Andrew Scull23e93a82018-10-26 14:56:04 +0100169template("embedded_platform_toolchain") {
170 assert(defined(invoker.arch), "\"arch\" must be defined for ${target_name}.")
171 assert(defined(invoker.target),
172 "\"target\" must be defined for ${target_name}.")
173 assert(defined(invoker.tool_prefix),
174 "\"tool_prefix\" must be defined for ${target_name}.")
175 assert(defined(invoker.origin_address),
176 "\"origin_address\" must be defined for ${target_name}.")
Andrew Walbrande33f082018-12-07 14:10:11 +0000177 assert(defined(invoker.heap_pages),
178 "\"heap_pages\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100179 assert(defined(invoker.max_cpus),
180 "\"max_cpus\" must be defined for ${target_name}.")
181 assert(defined(invoker.max_vms),
182 "\"max_vms\" must be defined for ${target_name}.")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000183 assert(defined(invoker.platform_name),
184 "\"platform_name\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100185
Andrew Walbran8e946692019-05-21 11:22:00 +0100186 extra_defines = ""
187 extra_cflags = "-fno-builtin -ffreestanding -fpic"
188 extra_ldflags = "--defsym=ORIGIN_ADDRESS=${invoker.origin_address}"
Andrew Scull23e93a82018-10-26 14:56:04 +0100189 if (defined(invoker.extra_defines)) {
Andrew Walbran8e946692019-05-21 11:22:00 +0100190 extra_defines += " ${invoker.extra_defines}"
Andrew Scull23e93a82018-10-26 14:56:04 +0100191 }
192 if (defined(invoker.extra_cflags)) {
Andrew Walbran8e946692019-05-21 11:22:00 +0100193 extra_cflags += " ${invoker.extra_cflags}"
Andrew Scull23e93a82018-10-26 14:56:04 +0100194 }
195 if (defined(invoker.extra_ldflags)) {
Andrew Walbran8e946692019-05-21 11:22:00 +0100196 extra_ldflags += " ${invoker.extra_ldflags}"
Andrew Scull23e93a82018-10-26 14:56:04 +0100197 }
Andrew Walbran8e946692019-05-21 11:22:00 +0100198 toolchain_args = {
199 use_platform = true
200 plat_name = invoker.platform_name
201 plat_arch = invoker.arch
202 plat_heap_pages = invoker.heap_pages
203 plat_max_cpus = invoker.max_cpus
204 plat_max_vms = invoker.max_vms
205 if (defined(invoker.toolchain_args)) {
206 forward_variables_from(invoker.toolchain_args, "*")
207 }
208 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100209
210 embedded_clang_toolchain("${target_name}_clang") {
211 target = invoker.target
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000212 }
213
214 embedded_clang_bfd_toolchain("${target_name}_clang_bfd") {
215 target = invoker.target
Andrew Walbranff28f3b2019-10-21 13:00:00 +0100216 tool_prefix = invoker.tool_prefix
Andrew Scull23e93a82018-10-26 14:56:04 +0100217 }
218}
219
220# Specialize for different architectures.
221
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000222template("aarch64_common_toolchain") {
Andrew Walbran549a9f22019-05-09 17:29:00 +0100223 assert(defined(invoker.cpu), "\"cpu\" must be defined for ${target_name}.")
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000224 assert(defined(invoker.target),
225 "\"target\" must be defined for ${target_name}")
226 assert(defined(invoker.tool_prefix),
227 "\"tool_prefix\" must be defined for ${target_name}")
Andrew Scull23e93a82018-10-26 14:56:04 +0100228 assert(defined(invoker.origin_address),
229 "\"origin_address\" must be defined for ${target_name}.")
Andrew Walbran48699362019-05-20 14:38:00 +0100230 assert(defined(invoker.console),
231 "\"console\" must be defined for ${target_name}.")
Andrew Walbrande33f082018-12-07 14:10:11 +0000232 assert(defined(invoker.heap_pages),
233 "\"heap_pages\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100234 assert(defined(invoker.max_cpus),
235 "\"max_cpus\" must be defined for ${target_name}.")
236 assert(defined(invoker.max_vms),
237 "\"max_vms\" must be defined for ${target_name}.")
Andrew Walbran53f38762018-12-07 15:21:29 +0000238 if (invoker.gic_version == 3 || invoker.gic_version == 4) {
239 assert(defined(invoker.gicd_base_address),
240 "\"gicd_base_address\" must be defined for ${target_name}.")
241 assert(defined(invoker.gicr_base_address),
242 "\"gicr_base_address\" must be defined for ${target_name}.")
Bo Yanef642332022-02-10 10:05:11 -0800243 assert(defined(invoker.gicr_frames),
244 "\"gicr_frames\" must be defined for ${target_name}.")
Andrew Walbran53f38762018-12-07 15:21:29 +0000245 }
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000246 assert(defined(invoker.platform_name),
247 "\"platform_name\" must be defined for ${target_name}.")
Andrew Scull23e93a82018-10-26 14:56:04 +0100248
249 embedded_platform_toolchain(target_name) {
250 forward_variables_from(invoker,
251 [
252 "origin_address",
Andrew Walbrande33f082018-12-07 14:10:11 +0000253 "heap_pages",
Andrew Scull23e93a82018-10-26 14:56:04 +0100254 "max_cpus",
255 "max_vms",
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000256 "platform_name",
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000257 "extra_ldflags",
Andrew Scull23e93a82018-10-26 14:56:04 +0100258 ])
259 arch = "aarch64"
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000260 target = invoker.target
261 tool_prefix = invoker.tool_prefix
Andrew Scull23e93a82018-10-26 14:56:04 +0100262 extra_cflags = "-mcpu=${invoker.cpu} -mstrict-align"
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000263 if (defined(invoker.extra_cflags)) {
264 extra_cflags += " ${invoker.extra_cflags}"
265 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100266
Andrew Walbran53f38762018-12-07 15:21:29 +0000267 extra_defines = ""
Alfredo Mazzinghi62e91562019-02-13 17:11:23 +0000268 if (defined(invoker.extra_defines)) {
269 extra_defines += " ${invoker.extra_defines}"
270 }
271
Andrew Walbran53f38762018-12-07 15:21:29 +0000272 if (invoker.gic_version > 0) {
273 extra_defines += " -DGIC_VERSION=${invoker.gic_version}"
274 }
275 if (invoker.gic_version == 3 || invoker.gic_version == 4) {
Bo Yanef642332022-02-10 10:05:11 -0800276 extra_defines += " -DGICD_BASE=${invoker.gicd_base_address} -DGICR_BASE=${invoker.gicr_base_address} -DGICR_FRAMES=${invoker.gicr_frames}"
Andrew Scull23e93a82018-10-26 14:56:04 +0100277 }
Raghu Krishnamurthy94220fb2022-08-09 22:28:14 -0700278 if (defined(invoker.gic_enable_espi)) {
279 extra_defines += " -DGIC_EXT_INTID=${invoker.gic_enable_espi}"
280 }
Raghu Krishnamurthy75ebf8c2021-11-28 07:22:12 -0800281 if (defined(invoker.branch_protection)) {
282 extra_cflags += " -mbranch-protection=${invoker.branch_protection}"
283 extra_defines += " -DBRANCH_PROTECTION=1"
284 }
285
Andrew Scull23e93a82018-10-26 14:56:04 +0100286 toolchain_args = {
David Brazdil0dbb41f2019-09-09 18:03:35 +0100287 plat_boot_flow = invoker.boot_flow
Andrew Walbran48699362019-05-20 14:38:00 +0100288 plat_console = invoker.console
Andrew Scull3c257452019-11-26 13:32:50 +0000289 plat_iommu = invoker.iommu
J-Alvesdad60032023-11-08 13:16:41 +0000290 plat_memory_protect = invoker.memory_protect
David Brazdil52230432020-01-27 15:08:34 +0000291 if (defined(invoker.stdout)) {
292 stdout = invoker.stdout
293 }
David Brazdila2f45212020-01-20 13:19:31 +0000294 if (defined(invoker.max_image_size)) {
295 plat_max_image_size = invoker.max_image_size
296 }
Andrew Walbran48699362019-05-20 14:38:00 +0100297 forward_variables_from(invoker.toolchain_args, "*")
Andrew Scull23e93a82018-10-26 14:56:04 +0100298 }
Maksims Svecovs6a0ccc92022-03-04 15:16:55 +0000299
300 if (defined(toolchain_args.enable_mte)) {
301 extra_cflags += " -march=armv8.5-a+memtag"
302 extra_cflags += " -fsanitize=memtag"
303 extra_defines += " -DENABLE_MTE"
304 }
Andrew Scull23e93a82018-10-26 14:56:04 +0100305 }
306}
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000307
308template("aarch64_toolchain") {
309 aarch64_common_toolchain("${target_name}") {
310 forward_variables_from(invoker, "*")
311 target = "aarch64-none-eabi"
Olivier Deprez306d7812023-02-02 09:51:10 +0100312 tool_prefix = "aarch64-linux-gnu-" # TODO: this isn't right for bare metal
313 # but it works.
Alfredo Mazzinghi880f5b22019-02-07 15:42:41 +0000314 platform_name = target_name
315 }
316}
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100317
318template("aarch64_toolchains") {
319 aarch64_toolchain("${target_name}") {
320 forward_variables_from(invoker,
321 [
322 "origin_address",
David Brazdil0dbb41f2019-09-09 18:03:35 +0100323 "boot_flow",
Andrew Walbran48699362019-05-20 14:38:00 +0100324 "console",
Andrew Scull3c257452019-11-26 13:32:50 +0000325 "iommu",
J-Alvesdad60032023-11-08 13:16:41 +0000326 "memory_protect",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100327 "gic_version",
Raghu Krishnamurthy94220fb2022-08-09 22:28:14 -0700328 "gic_enable_espi",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100329 "gicd_base_address",
330 "gicr_base_address",
Bo Yanef642332022-02-10 10:05:11 -0800331 "gicr_frames",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100332 "heap_pages",
333 "max_cpus",
David Brazdila2f45212020-01-20 13:19:31 +0000334 "max_image_size",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100335 "max_vms",
Andrew Walbran48699362019-05-20 14:38:00 +0100336 "toolchain_args",
Raghu Krishnamurthy75ebf8c2021-11-28 07:22:12 -0800337 "branch_protection",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100338 ])
339 cpu = "${invoker.cpu}+nofp"
David Brazdil711fbe92019-08-06 13:39:58 +0100340
341 # Add a macro so files can tell whether they are not being built for a VM.
342 extra_defines = " -DVM_TOOLCHAIN=0"
Maksims Svecovs6a0ccc92022-03-04 15:16:55 +0000343 extra_cflags = " -mgeneral-regs-only"
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100344 }
345
346 # Toolchain for building test VMs which run under Hafnium.
347 aarch64_toolchain("${target_name}_vm") {
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100348 forward_variables_from(invoker,
349 [
350 "origin_address",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100351 "gic_version",
Raghu Krishnamurthy94220fb2022-08-09 22:28:14 -0700352 "gic_enable_espi",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100353 "gicd_base_address",
354 "gicr_base_address",
Bo Yanef642332022-02-10 10:05:11 -0800355 "gicr_frames",
Andrew Walbranafabe852019-03-20 17:55:11 +0000356 "max_cpus",
Andrew Walbran48699362019-05-20 14:38:00 +0100357 "toolchain_args",
David Brazdil52230432020-01-27 15:08:34 +0000358 "console",
Raghu Krishnamurthy75ebf8c2021-11-28 07:22:12 -0800359 "branch_protection",
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100360 ])
361 cpu = "${invoker.cpu}+fp"
David Brazdil0dbb41f2019-09-09 18:03:35 +0100362 boot_flow = "//src/arch/fake:boot_flow"
Andrew Scull3c257452019-11-26 13:32:50 +0000363 iommu = "//src/iommu:absent"
J-Alvesdad60032023-11-08 13:16:41 +0000364 memory_protect = "//src/memory_protect:absent"
David Brazdil52230432020-01-27 15:08:34 +0000365 stdout = "//src/arch/aarch64/hftest:stdout"
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100366
367 # Nonsense values because they are required but shouldn't be used.
368 heap_pages = 0
Andrew Walbran7f904bf2019-07-12 16:38:38 +0100369 max_vms = 0
David Brazdil711fbe92019-08-06 13:39:58 +0100370
371 # Add a macro so files can tell whether they are being built for a VM.
372 extra_defines = " -DVM_TOOLCHAIN=1"
Andrew Walbran7559fcf2019-05-09 17:11:20 +0100373 }
374}