1 // Copyright 2023, The Android Open Source Project
2 //
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 // http://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
15 //! Wrappers of assembly calls.
16
17 pub mod dbm;
18 pub mod exceptions;
19 pub mod hvc;
20 pub mod layout;
21 pub mod linker;
22 pub mod page_table;
23 pub mod platform;
24 pub mod rand;
25 pub mod uart;
26
27 /// Reads a value from a system register.
28 #[macro_export]
29 macro_rules! read_sysreg {
30 ($sysreg:literal) => {{
31 let mut r: usize;
32 #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
33 // SAFETY: Reading a system register does not affect memory.
34 unsafe {
35 core::arch::asm!(
36 concat!("mrs {}, ", $sysreg),
37 out(reg) r,
38 options(nomem, nostack, preserves_flags),
39 )
40 }
41 r
42 }};
43 }
44
45 /// Writes a value to a system register.
46 ///
47 /// # Safety
48 ///
49 /// Callers must ensure that side effects of updating the system register are properly handled.
50 #[macro_export]
51 macro_rules! write_sysreg {
52 ($sysreg:literal, $val:expr) => {{
53 let value: usize = $val;
54 core::arch::asm!(
55 concat!("msr ", $sysreg, ", {}"),
56 in(reg) value,
57 options(nomem, nostack, preserves_flags),
58 )
59 }};
60 }
61
62 /// Executes an instruction synchronization barrier.
63 #[macro_export]
64 macro_rules! isb {
65 () => {{
66 #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
67 // SAFETY: memory barriers do not affect Rust's memory model.
68 unsafe {
69 core::arch::asm!("isb", options(nomem, nostack, preserves_flags));
70 }
71 }};
72 }
73
74 /// Executes a data synchronization barrier.
75 #[macro_export]
76 macro_rules! dsb {
77 ($option:literal) => {{
78 #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
79 // SAFETY: memory barriers do not affect Rust's memory model.
80 unsafe {
81 core::arch::asm!(concat!("dsb ", $option), options(nomem, nostack, preserves_flags));
82 }
83 }};
84 }
85
86 /// Executes a data cache operation.
87 #[macro_export]
88 macro_rules! dc {
89 ($option:literal, $addr:expr) => {{
90 let addr: usize = $addr;
91 #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
92 // SAFETY: Clearing cache lines shouldn't have Rust-visible side effects.
93 unsafe {
94 core::arch::asm!(
95 concat!("dc ", $option, ", {x}"),
96 x = in(reg) addr,
97 options(nomem, nostack, preserves_flags),
98 );
99 }
100 }};
101 }
102
103 /// Invalidates cached leaf PTE entries by virtual address.
104 #[macro_export]
105 macro_rules! tlbi {
106 ($option:literal, $asid:expr, $addr:expr) => {{
107 let asid: usize = $asid;
108 let addr: usize = $addr;
109 #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
110 // SAFETY: Invalidating the TLB doesn't affect Rust. When the address matches a
111 // block entry larger than the page size, all translations for the block are invalidated.
112 unsafe {
113 core::arch::asm!(
114 concat!("tlbi ", $option, ", {x}"),
115 x = in(reg) (asid << 48) | (addr >> 12),
116 options(nomem, nostack, preserves_flags)
117 );
118 }
119 }};
120 }
121
122 /// Reads the number of words in the smallest cache line of all the data caches and unified caches.
123 #[inline]
min_dcache_line_size() -> usize124 pub fn min_dcache_line_size() -> usize {
125 const DMINLINE_SHIFT: usize = 16;
126 const DMINLINE_MASK: usize = 0xf;
127 let ctr_el0 = read_sysreg!("ctr_el0");
128
129 // DminLine: log2 of the number of words in the smallest cache line of all the data caches.
130 let dminline = (ctr_el0 >> DMINLINE_SHIFT) & DMINLINE_MASK;
131
132 1 << dminline
133 }
134