blob: 3a52c2d7c1de5ca68476bb7a62876b26b8ec7b4f [file] [log] [blame]
Alice Wang4dd20932023-05-26 13:47:16 +00001// 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//! Hardware management of the access flag and dirty state.
16
17use crate::{isb, read_sysreg, write_sysreg};
18
19/// Sets whether the hardware management of access and dirty state is enabled with
20/// the given boolean.
21pub fn set_dbm_enabled(enabled: bool) {
22 if !dbm_available() {
23 return;
24 }
25 // TCR_EL1.{HA,HD} bits controlling hardware management of access and dirty state
26 const TCR_EL1_HA_HD_BITS: usize = 3 << 39;
27
28 let mut tcr = read_sysreg!("tcr_el1");
29 if enabled {
30 tcr |= TCR_EL1_HA_HD_BITS
31 } else {
32 tcr &= !TCR_EL1_HA_HD_BITS
33 };
34 // Safe because it writes to a system register and does not affect Rust.
35 unsafe { write_sysreg!("tcr_el1", tcr) }
36 isb!();
37}
38
39/// Returns `true` if hardware dirty state management is available.
40fn dbm_available() -> bool {
41 if !cfg!(feature = "cpu_feat_hafdbs") {
42 return false;
43 }
44 // Hardware dirty bit management available flag (ID_AA64MMFR1_EL1.HAFDBS[1])
45 const DBM_AVAILABLE: usize = 1 << 1;
46 read_sysreg!("id_aa64mmfr1_el1") & DBM_AVAILABLE != 0
47}