blob: bbec7a854122fb259f543271eb39f8c80532fa95 [file] [log] [blame]
Pierre-Clément Tosida4440a2022-08-22 18:06:32 +01001// Copyright 2022, 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//! Miscellaneous helper functions.
16
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000017use core::arch::asm;
Srivatsa Vaddagiric25d68e2023-04-19 22:56:33 -070018use core::ops::Range;
Alice Wangeacb7382023-06-05 12:53:54 +000019use vmbase::memory::SIZE_4KB;
Alice Wang81399f52023-05-26 14:23:43 +000020use vmbase::read_sysreg;
Alice Wangeacb7382023-06-05 12:53:54 +000021use vmbase::util::unchecked_align_down;
Pierre-Clément Tosi8383c542022-11-01 14:07:29 +000022use zeroize::Zeroize;
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000023
Pierre-Clément Tosi4f4f5eb2022-12-08 14:31:42 +000024pub const GUEST_PAGE_SIZE: usize = SIZE_4KB;
Pierre-Clément Tosi23aba522023-04-21 17:03:50 +010025pub const PVMFW_PAGE_SIZE: usize = SIZE_4KB;
Pierre-Clément Tosi4f4f5eb2022-12-08 14:31:42 +000026
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000027#[inline]
Pierre-Clément Tosi97f52492023-04-04 15:52:17 +010028/// Read the number of words in the smallest cache line of all the data caches and unified caches.
29pub fn min_dcache_line_size() -> usize {
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000030 const DMINLINE_SHIFT: usize = 16;
31 const DMINLINE_MASK: usize = 0xf;
Jakob Vukalovicc9afb512023-03-30 16:04:32 +000032 let ctr_el0 = read_sysreg!("ctr_el0");
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000033
34 // DminLine: log2 of the number of words in the smallest cache line of all the data caches.
35 let dminline = (ctr_el0 >> DMINLINE_SHIFT) & DMINLINE_MASK;
36
37 1 << dminline
38}
39
Pierre-Clément Tosi2ca2e312022-11-29 11:24:52 +000040/// Flush `size` bytes of data cache by virtual address.
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000041#[inline]
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000042pub fn flush_region(start: usize, size: usize) {
43 let line_size = min_dcache_line_size();
44 let end = start + size;
45 let start = unchecked_align_down(start, line_size);
46
47 for line in (start..end).step_by(line_size) {
48 // SAFETY - Clearing cache lines shouldn't have Rust-visible side effects.
Pierre-Clément Tosi7d6944f2023-03-30 19:14:11 +010049 unsafe {
50 asm!(
51 "dc cvau, {x}",
52 x = in(reg) line,
53 options(nomem, nostack, preserves_flags),
54 )
55 }
Pierre-Clément Tosia0934c12022-11-25 20:54:11 +000056 }
57}
Pierre-Clément Tosi8383c542022-11-01 14:07:29 +000058
59#[inline]
Pierre-Clément Tosidb74cb12022-12-08 13:56:25 +000060/// Flushes the slice to the point of unification.
61pub fn flush(reg: &[u8]) {
62 flush_region(reg.as_ptr() as usize, reg.len())
63}
64
65#[inline]
Pierre-Clément Tosi8383c542022-11-01 14:07:29 +000066/// Overwrites the slice with zeroes, to the point of unification.
67pub fn flushed_zeroize(reg: &mut [u8]) {
68 reg.zeroize();
Pierre-Clément Tosidb74cb12022-12-08 13:56:25 +000069 flush(reg)
Pierre-Clément Tosi8383c542022-11-01 14:07:29 +000070}
Jiyong Parkb87f3302023-03-21 10:03:11 +090071
Srivatsa Vaddagiric25d68e2023-04-19 22:56:33 -070072/// Trait to check containment of one range within another.
73pub(crate) trait RangeExt {
74 /// Returns true if `self` is contained within the `other` range.
75 fn is_within(&self, other: &Self) -> bool;
76}
77
78impl<T: PartialOrd> RangeExt for Range<T> {
79 fn is_within(&self, other: &Self) -> bool {
80 self.start >= other.start && self.end <= other.end
81 }
82}
83
Jiyong Parkb87f3302023-03-21 10:03:11 +090084/// Create &CStr out of &str literal
85#[macro_export]
86macro_rules! cstr {
87 ($str:literal) => {{
Pierre-Clément Tosi7c5df042023-05-12 12:06:44 +000088 core::ffi::CStr::from_bytes_with_nul(concat!($str, "\0").as_bytes()).unwrap()
Jiyong Parkb87f3302023-03-21 10:03:11 +090089 }};
90}