-
Notifications
You must be signed in to change notification settings - Fork 4
/
Makefile.toml
373 lines (316 loc) Β· 12.1 KB
/
Makefile.toml
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
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
#
# SPDX-License-Identifier: BlueOak-1.0.0
#
# Copyright (c) Berkus Decker <[email protected]>
#
# Global workspace configuration
#
[config]
min_version = "0.37.0"
default_to_workspace = true
skip_core_tasks = true
[env]
DEFAULT_TARGET = "aarch64-vesper-metta"
#
# === User-configurable ===
#
# Pass TARGET env var if it does not match the default target above.
TARGET = { value = "${DEFAULT_TARGET}", condition = { env_not_set = [
"TARGET",
] } }
# Name of the target board "rpi3" or "rpi4"
TARGET_BOARD = { value = "rpi4", condition = { env_not_set = [
"TARGET_BOARD",
] } }
# Name of the DTB file for target board configuration, use bcm2710-rpi-3-b-plus.dtb for RasPi3B+
TARGET_DTB = { value = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/targets/bcm2711-rpi-4-b.dtb", condition = { env_not_set = [
"TARGET_DTB",
] } }
# AArch64 QEMU binary
QEMU = { value = "qemu-system-aarch64", condition = { env_not_set = ["QEMU"] } }
# QEMU machine type, defaults to raspi3b but CI runners override it due to ancient QEMU versions they use.
# Supported as of qemu 9.0:
# raspi3ap Raspberry Pi 3A+ (revision 1.0)
# raspi3b Raspberry Pi 3B (revision 1.2)
# raspi4b Raspberry Pi 4B (revision 1.5)
QEMU_MACHINE = { value = "raspi3b", condition = { env_not_set = [
"QEMU_MACHINE",
] } }
# An aarch64-enabled GDB
GDB = { value = "/usr/local/opt/gdb/HEAD-a2c58332-aarch64/bin/aarch64-unknown-elf-gdb", condition = { env_not_set = [
"GDB",
] } }
# @todo: Replace it with probe-rs.. which can be installed by `cargo make`!
# OpenOCD with JLink support
# (RTT patch from http://openocd.zylin.com/#/c/4055/11 has already been merged into main line)
OPENOCD = { value = "/usr/local/opt/openocd/4d6519593-rtt/bin/openocd", condition = { env_not_set = [
"OPENOCD",
] } }
# Mounted sdcard partition path
VOLUME = { value = "/Volumes/BOOT", condition = { env_not_set = ["VOLUME"] } }
#
# === Automatic ===
#
# When running `cargo make` for modules which are part of a workspace, you can automatically
# have the member crates makefile (*even if doesn't exist*) extend the workspace level makefile.
# This allows you to maintain a single makefile for the entire workspace but
# have access to those custom tasks in every member crate.
# This is only relevant for workspace builds which are triggered in the workspace root.
# Flows that start directly in the member crate, must manually extend the workspace
# level makefile using the `extend` keyword.
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
# Build rust stdlib locally
RUST_STD = "-Zbuild-std=compiler_builtins,core,alloc -Zbuild-std-features=compiler-builtins-mem"
TARGET_JSON = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/targets/${TARGET}.json"
PLATFORM_TARGET = "--target=${TARGET_JSON}|--features=${TARGET_FEATURES}"
DEVICE_FEATURES = "noserial"
QEMU_FEATURES = "qemu,rpi3"
# Working objcopy from `brew install aarch64-elf-binutils`
#OBJCOPY = "/opt/homebrew/Cellar/aarch64-elf-binutils/2.40/bin/aarch64-elf-objcopy"
# LLVM's objcopy, usually full of bugs like https://github.com/llvm/llvm-project/issues/58407
OBJCOPY = "rust-objcopy" # Part of `cargo objcopy` in cargo-binutils
OBJCOPY_PARAMS = "--strip-all -O binary"
NM = "rust-nm" # Part of `cargo nm` in cargo-binutils
UTILS_CONTAINER = "andrerichter/raspi3-utils"
DOCKER_CMD = "docker run -it --rm -v ${PWD}:/work -w /work -p 5900:5900"
QEMU_CONTAINER_CMD = "qemu-system-aarch64"
#
# Could additionally use -nographic to disable GUI -- this shall be useful for automated tests.
#
# QEMU has renamed the RasPi machines since version 6.2.0, use just `raspi3` for previous versions.
QEMU_OPTS = "-M ${QEMU_MACHINE} -semihosting"
QEMU_ARM_TRACE_OPTS = "arm_gt_cntvoff_write,arm_gt_ctl_write,arm_gt_cval_write,arm_gt_imask_toggle,arm_gt_recalc,arm_gt_recalc_disabled,arm_gt_tval_write,armsse_cpu_pwrctrl_read,armsse_cpu_pwrctrl_write,armsse_cpuid_read,armsse_cpuid_write,armsse_mhu_read,armsse_mhu_write"
QEMU_BCM_TRACE_OPTS = "bcm2835_cprman_read,bcm2835_cprman_write,bcm2835_cprman_write_invalid_magic,bcm2835_ic_set_cpu_irq,bcm2835_ic_set_gpu_irq,bcm2835_mbox_irq,bcm2835_mbox_property,bcm2835_mbox_read,bcm2835_mbox_write,bcm2835_sdhost_edm_change,bcm2835_sdhost_read,bcm2835_sdhost_update_irq,bcm2835_sdhost_write,bcm2835_systmr_irq_ack,bcm2835_systmr_read,bcm2835_systmr_run,bcm2835_systmr_timer_expired,bcm2835_systmr_write"
QEMU_TRACE_OPTS = "trace:${QEMU_ARM_TRACE_OPTS},${QEMU_BCM_TRACE_OPTS}" # @todo trace: prefix for each opt
QEMU_DISASM_OPTS = "-d in_asm,unimp,int,mmu,cpu_reset,guest_errors,nochain,plugin"
QEMU_SERIAL_OPTS = "-serial stdio -serial pty"
QEMU_TESTS_OPTS = "-nographic"
# For gdb connection:
# - if this is set, MUST have gdb attached for SYS_WRITE0 to work, otherwise QEMU will crash.
# - port 5555 used to match JLink configuration, so we can reuse the same GDB command for both QEMU and JTAG.
QEMU_GDB_OPTS = "-gdb tcp::5555 -S"
GDB_CONNECT_FILE = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${TARGET}/gdb-connect"
KERNEL_ELF = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${TARGET}/release/nucleus"
KERNEL_BIN = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/nucleus.bin"
CHAINBOOT_SERIAL = "/dev/tty.SLAB_USBtoUART"
CHAINBOOT_BAUD = 115200
#
# === Base reusable commands ===
#
# By default, build everything.
[tasks.default]
alias = "all"
# All primary dependencies to build.
[tasks.all]
dependencies = ["kernel-binary", "chainboot", "chainofcommand"]
[tasks.xtool-modules]
workspace = false
command = "cargo"
args = ["modules", "tree"]
# Disable build in the root by default.
[tasks.build]
workspace = false
alias = "empty"
# Run a target build with current platform configuration.
[tasks.build-target]
workspace = false
command = "cargo"
env = { RUSTFLAGS = "-D warnings" }
args = [
"build",
"@@split(PLATFORM_TARGET,|)",
"@@split(RUST_STD, )",
"--release",
]
[tasks.build-device]
workspace = false
env = { "TARGET_FEATURES" = "${TARGET_BOARD}" }
run_task = "build-target"
[tasks.build-qemu]
workspace = false
env = { "TARGET_FEATURES" = "${QEMU_FEATURES}" }
run_task = "build-target"
[tasks.qemu-runner]
workspace = false
dependencies = ["build-qemu", "kernel-binary"]
env = { "TARGET_FEATURES" = "${QEMU_FEATURES}" }
script = [
"echo π Run QEMU ${QEMU_OPTS} ${QEMU_RUNNER_OPTS} with ${KERNEL_BIN}\n\n\n",
"rm -f qemu.log",
"${QEMU} ${QEMU_OPTS} ${QEMU_RUNNER_OPTS} -dtb ${TARGET_DTB} -kernel ${KERNEL_BIN} 2>&1 | tee qemu.log",
"echo \n\n",
]
[tasks.xtool-expand-target]
workspace = false
env = { "TARGET_FEATURES" = "" }
command = "cargo"
args = ["expand", "@@split(PLATFORM_TARGET,|)", "--release"]
[tasks.test]
env = { "TARGET_FEATURES" = "${QEMU_FEATURES}" }
command = "cargo"
args = ["test", "@@split(PLATFORM_TARGET,|)", "@@split(RUST_STD, )"]
[tasks.docs]
env = { "TARGET_FEATURES" = "" }
command = "cargo"
args = ["doc", "--open", "--no-deps", "@@split(PLATFORM_TARGET,|)"]
[tasks.xtool-clippy]
workspace = false
env = { "TARGET_FEATURES" = "rpi3", "CLIPPY_FEATURES" = { value = "--features=${CLIPPY_FEATURES}", condition = { env_set = [
"CLIPPY_FEATURES",
] } } }
command = "cargo"
args = [
"clippy",
"@@split(PLATFORM_TARGET,|)",
"@@split(RUST_STD, )",
"@@remove-empty(CLIPPY_FEATURES)",
"--",
"--deny",
"warnings",
"--allow",
"deprecated",
]
# These tasks are written in cargo-make's own script to make them portable across platforms (no `basename` on Windows)
## Copy and prepare a given ELF file. Convert to binary output format.
[tasks.build-custom-binary]
workspace = false
env = { "BINARY_FILE" = "${BINARY_FILE}" }
script_runner = "@duckscript"
script = [
'''
binaryFile = basename ${BINARY_FILE}
outElf = set ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.elf
outBin = set ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.bin
cp ${BINARY_FILE} ${outElf}
exec --fail-on-error ${OBJCOPY} %{OBJCOPY_PARAMS} ${BINARY_FILE} ${outBin}
elfSize = get_file_size ${outElf}
binSize = get_file_size ${outBin}
shortBinary = replace ${BINARY_FILE} "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/" ""
shortOutElf = replace ${outElf} "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/" ""
shortOutBin = replace ${outBin} "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/" ""
echo
echo π Processing ${shortBinary}:
echo π Copied ${binaryFile} to ${shortOutElf} (${elfSize} bytes)
echo π« Converted ${binaryFile} to ${shortOutBin} (${binSize} bytes)
echo
''',
]
install_crate = { crate_name = "cargo-binutils", binary = "rust-objcopy", test_arg = [
"--help",
] }
## Copy and prepare binary with tests.
[tasks.test-binary]
workspace = false
env = { "BINARY_FILE" = "${CARGO_MAKE_TASK_ARGS}" }
run_task = "build-custom-binary"
## Run binary with tests in QEMU.
[tasks.test-runner]
workspace = false
dependencies = ["test-binary"]
script_runner = "@duckscript"
script = [
'''
binaryFile = basename ${CARGO_MAKE_TASK_ARGS}
echo ποΈ Run QEMU %{QEMU_OPTS} %{QEMU_TESTS_OPTS} with target/${binaryFile}.bin
exec --fail-on-error ${QEMU} %{QEMU_OPTS} %{QEMU_TESTS_OPTS} -dtb ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/targets/bcm2710-rpi-3-b-plus.dtb -kernel ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.bin
''',
]
## Generate GDB startup configuration file.
[tasks.gdb-config]
workspace = false
script_runner = "@duckscript"
script = ['''
writefile ${GDB_CONNECT_FILE} "target extended-remote :5555\n"
appendfile ${GDB_CONNECT_FILE} "break *0x80000\n"
appendfile ${GDB_CONNECT_FILE} "break kernel_init\n"
appendfile ${GDB_CONNECT_FILE} "break kernel_main\n"
echo ποΈ Generated GDB config file
''']
#appendfile ${GDB_CONNECT_FILE} "continue\n"
## Generate zellij configuration file.
[tasks.zellij-config]
workspace = false
dependencies = ["build-qemu", "kernel-binary"]
script_runner = "@duckscript"
env = { "ZELLIJ_CONFIG_FILE" = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/emulation/zellij-config.sh" }
script = [
'''
writefile ${ZELLIJ_CONFIG_FILE} "QEMU=${QEMU}\n"
appendfile ${ZELLIJ_CONFIG_FILE} "QEMU_OPTS=\"${QEMU_OPTS}\"\n"
appendfile ${ZELLIJ_CONFIG_FILE} "QEMU_RUNNER_OPTS=${QEMU_RUNNER_OPTS}\n"
appendfile ${ZELLIJ_CONFIG_FILE} "CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}\n"
appendfile ${ZELLIJ_CONFIG_FILE} "TARGET_DTB=${TARGET_DTB}\n"
appendfile ${ZELLIJ_CONFIG_FILE} "KERNEL_BIN=${KERNEL_BIN}\n"
''',
]
install_crate = { crate_name = "zellij", binary = "zellij", test_arg = [
"--help",
] }
[tasks.openocd]
workspace = false
script = [
"${OPENOCD} -f interface/jlink.cfg -f ../ocd/${TARGET_BOARD}_target.cfg",
]
[tasks.sdeject]
workspace = false
dependencies = ["sdcard"]
script = ["diskutil ejectAll ${VOLUME}"]
[tasks.qemu]
workspace = false
alias = "empty"
[tasks.clean]
command = "cargo"
args = ["clean"]
#
# Per-workspace commands, disabled in the root by efault.
# TODO: defined only in sub-modules with workspace = false
#
# Tasks for nucleus
#[tasks.build-kernel-binary]
#alias = "empty"
# Tasks for chainboot
#[tasks.chainboot]
#alias = "empty"
# sdeject
#[tasks.cb-eject]
#alias = "empty"
# Tasks for chainofcommand
#[tasks.chainofcommand]
#alias = "empty"
# Tasks for ttt
#[tasks.ttt]
#alias = "empty"
# Other tasks
#[tasks.gdb]
#alias = "empty"
#[tasks.gdb-cb]
#alias = "empty"
#[tasks.sdcard]
#alias = "empty"
#[tasks.qemu-gdb]
#alias = "empty"
#[tasks.qemu-cb]
#alias = "empty"
#[tasks.qemu-cb-gdb]
#alias = "empty"
#[tasks.xtool-hopper]
#alias = "empty"
#
#[tasks.xtool-nm]
#alias = "empty"
#[tasks.zellij-cb]
#alias = "empty"
#[tasks.zellij-cb-gdb]
#alias = "empty"
#[tasks.zellij-nucleus]
#alias = "empty"
## Target dependencies:
#[tasks.kernel-binary]
#alias = "empty"
#[tasks.chainboot-binary]
#alias = "empty"
#
#[tasks.chainofcommand-binary]
#alias = "empty"
#[tasks.ttt-binary]
#alias = "empty"