Skip to content

Commit 170b56c

Browse files
author
Ioan-Cristian CÎRSTEA
committed
Use const operand for ARM syscall implementation
`asm_const` feature has been stabilized in Rust 1.82. Using const operands for inline assembly eliminates a lot of the duplicated code in the ARM syscall implementation. This commit has been tested by running a simple application that periodically blinks and writes a message on Raspberry Pi Pico.
1 parent f0fe519 commit 170b56c

File tree

3 files changed

+29
-65
lines changed

3 files changed

+29
-65
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ version = "0.1.0"
1313
[workspace.package]
1414
# This must be kept in sync with rust-toolchain.toml; please see that file for
1515
# more information.
16-
rust-version = "1.77"
16+
rust-version = "1.82"
1717

1818
[features]
1919
rust_embedded = [

runtime/src/syscalls_impl_arm.rs

+27-63
Original file line numberDiff line numberDiff line change
@@ -43,92 +43,56 @@ unsafe impl RawSyscalls for crate::TockSyscalls {
4343
}
4444
}
4545

46-
unsafe fn syscall1<const CLASS: usize>([Register(mut r0)]: [Register; 1]) -> [Register; 2] {
46+
unsafe fn syscall1<const SYSCALL_CLASS_NUMBER: usize>(
47+
[Register(mut r0)]: [Register; 1],
48+
) -> [Register; 2] {
4749
let r1;
4850
// Safety: This matches the invariants required by the documentation on
4951
// RawSyscalls::syscall1
5052
unsafe {
51-
// Syscall class 5 is Memop, the only syscall class that syscall1
52-
// supports.
53-
asm!("svc 5",
54-
inlateout("r0") r0,
55-
lateout("r1") r1,
56-
options(preserves_flags, nostack, nomem),
53+
asm!(
54+
"svc {SYSCALL_CLASS_NUMBER}",
55+
inlateout("r0") r0,
56+
lateout("r1") r1,
57+
options(preserves_flags, nostack, nomem),
58+
SYSCALL_CLASS_NUMBER = const SYSCALL_CLASS_NUMBER,
5759
);
5860
}
5961
[Register(r0), Register(r1)]
6062
}
6163

62-
unsafe fn syscall2<const CLASS: usize>(
64+
unsafe fn syscall2<const SYSCALL_CLASS_NUMBER: usize>(
6365
[Register(mut r0), Register(mut r1)]: [Register; 2],
6466
) -> [Register; 2] {
6567
// Safety: This matches the invariants required by the documentation on
6668
// RawSyscalls::syscall2
6769
unsafe {
68-
// TODO: Replace this match statement with a `const` operand when
69-
// asm_const [1] is stabilized, or redesign RawSyscalls to not need
70-
// this match statement.
71-
//
72-
// [1] https://github.com/rust-lang/rust/issues/93332
73-
match CLASS {
74-
syscall_class::MEMOP => asm!("svc 5",
75-
inlateout("r0") r0,
76-
inlateout("r1") r1,
77-
options(preserves_flags, nostack, nomem)
78-
),
79-
syscall_class::EXIT => asm!("svc 6",
80-
inlateout("r0") r0,
81-
inlateout("r1") r1,
82-
options(preserves_flags, nostack, nomem)
83-
),
84-
_ => unreachable!(),
85-
}
70+
asm!(
71+
"svc {SYSCALL_CLASS_NUMBER}",
72+
inlateout("r0") r0,
73+
inlateout("r1") r1,
74+
options(preserves_flags, nostack, nomem),
75+
SYSCALL_CLASS_NUMBER = const SYSCALL_CLASS_NUMBER,
76+
);
8677
}
8778
[Register(r0), Register(r1)]
8879
}
8980

90-
unsafe fn syscall4<const CLASS: usize>(
81+
unsafe fn syscall4<const SYSCALL_CLASS_NUMBER: usize>(
9182
[Register(mut r0), Register(mut r1), Register(mut r2), Register(mut r3)]: [Register; 4],
9283
) -> [Register; 4] {
9384
// Safety: This matches the invariants required by the documentation on
9485
// RawSyscalls::syscall4
9586
unsafe {
96-
// TODO: Replace this match statement with a `const` operand when
97-
// asm_const [1] is stabilized, or redesign RawSyscalls to not need
98-
// this match statement.
99-
//
100-
// [1] https://github.com/rust-lang/rust/issues/93332
101-
match CLASS {
102-
syscall_class::SUBSCRIBE => asm!("svc 1",
103-
inlateout("r0") r0,
104-
inlateout("r1") r1,
105-
inlateout("r2") r2,
106-
inlateout("r3") r3,
107-
options(preserves_flags, nostack),
108-
),
109-
syscall_class::COMMAND => asm!("svc 2",
110-
inlateout("r0") r0,
111-
inlateout("r1") r1,
112-
inlateout("r2") r2,
113-
inlateout("r3") r3,
114-
options(preserves_flags, nostack),
115-
),
116-
syscall_class::ALLOW_RW => asm!("svc 3",
117-
inlateout("r0") r0,
118-
inlateout("r1") r1,
119-
inlateout("r2") r2,
120-
inlateout("r3") r3,
121-
options(preserves_flags, nostack),
122-
),
123-
syscall_class::ALLOW_RO => asm!("svc 4",
124-
inlateout("r0") r0,
125-
inlateout("r1") r1,
126-
inlateout("r2") r2,
127-
inlateout("r3") r3,
128-
options(preserves_flags, nostack),
129-
),
130-
_ => unreachable!(),
131-
}
87+
asm!(
88+
"svc {SYSCALL_CLASS_NUMBER}",
89+
inlateout("r0") r0,
90+
inlateout("r1") r1,
91+
inlateout("r2") r2,
92+
inlateout("r3") r3,
93+
options(preserves_flags, nostack),
94+
SYSCALL_CLASS_NUMBER = const SYSCALL_CLASS_NUMBER,
95+
);
13296
}
13397
[Register(r0), Register(r1), Register(r2), Register(r3)]
13498
}

rust-toolchain.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# you'd like to use. When you do so, update this to the first Rust version that
66
# includes that feature. Whenever this value is updated, the rust-version field
77
# in Cargo.toml must be updated as well.
8-
channel = "1.77"
8+
channel = "1.82"
99
components = ["clippy", "rustfmt"]
1010
targets = [
1111
"thumbv6m-none-eabi",

0 commit comments

Comments
 (0)