Skip to content
This repository was archived by the owner on Nov 7, 2022. It is now read-only.

Define EL1 cache management registers #41

Merged
merged 5 commits into from
Jun 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/registers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#[macro_use]
mod macros;

mod ccsidr_el1;
mod clidr_el1;
mod cntfrq_el0;
mod cnthctl_el2;
mod cntp_ctl_el0;
Expand All @@ -16,6 +18,7 @@ mod cntv_cval_el0;
mod cntv_tval_el0;
mod cntvct_el0;
mod cntvoff_el2;
mod csselr_el1;
mod currentel;
mod daif;
mod elr_el1;
Expand All @@ -29,6 +32,7 @@ mod fp;
mod hcr_el2;
mod id_aa64mmfr0_el1;
mod id_aa64isar0_el1;
mod id_aa64mmfr2_el1;
mod lr;
mod mair_el1;
mod mair_el2;
Expand Down Expand Up @@ -57,6 +61,8 @@ mod ttbr1_el1;
mod vbar_el1;
mod vbar_el2;

pub use ccsidr_el1::CCSIDR_EL1;
pub use clidr_el1::CLIDR_EL1;
pub use cntfrq_el0::CNTFRQ_EL0;
pub use cnthctl_el2::CNTHCTL_EL2;
pub use cntp_ctl_el0::CNTP_CTL_EL0;
Expand All @@ -67,6 +73,7 @@ pub use cntv_cval_el0::CNTV_CVAL_EL0;
pub use cntv_tval_el0::CNTV_TVAL_EL0;
pub use cntvct_el0::CNTVCT_EL0;
pub use cntvoff_el2::CNTVOFF_EL2;
pub use csselr_el1::CSSELR_EL1;
pub use currentel::CurrentEL;
pub use daif::DAIF;
pub use elr_el1::ELR_EL1;
Expand All @@ -80,6 +87,7 @@ pub use fp::FP;
pub use hcr_el2::HCR_EL2;
pub use id_aa64mmfr0_el1::ID_AA64MMFR0_EL1;
pub use id_aa64isar0_el1::ID_AA64ISAR0_EL1;
pub use id_aa64mmfr2_el1::ID_AA64MMFR2_EL1;
pub use lr::LR;
pub use mair_el1::MAIR_EL1;
pub use mair_el2::MAIR_EL2;
Expand Down
119 changes: 119 additions & 0 deletions src/registers/ccsidr_el1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Copyright (c) 2018-2022 by the author(s)
//
// Author(s):
// - Valentin B. <valentin.be@protonmail.com>

//! Current Cache Size ID Register - EL1
//!
//! Provides information about the architecture of the currently selected cache.

use tock_registers::{
interfaces::{Readable, Writeable},
register_bitfields,
};

register_bitfields! {u64,
pub CCSIDR_EL1 [
/// Number of sets in cache.
///
/// A value of 0 indicates 1 set in the cache. The number does not
/// necessarily have to be a power of 2.
NumSetsWithCCIDX OFFSET(32) NUMBITS(24) [],

/// Number of sets in cache.
///
/// A value of 0 indicates 1 set in the cache. The number does not
/// necessarily have to be a power of 2.
NumSetsWithoutCCIDX OFFSET(13) NUMBITS(15) [],

/// Associativity of cache.
///
/// A value of 0 indicates an associativity of 1. The value does not
/// necessarily have to be a power of 2.
AssociativityWithCCIDX OFFSET(3) NUMBITS(21) [],

/// Associativity of cache.
///
/// A value of 0 indicates an associativity of 1. The value does not
/// necessarily have to be a power of 2.
AssociativityWithoutCCIDX OFFSET(3) NUMBITS(10) [],

/// Log2(Number of bytes in cache lline) - 4.
///
/// **Examples:**
///
/// - For a line length of 16 bytes: Log2(16) - 4 = 0. This is the minimum line length.
///
/// - For a line length of 32 bytes: Log2(32) - 4 = 1.
LineSize OFFSET(0) NUMBITS(3) []
]
}

#[inline(always)]
fn has_feature_ccidx() -> bool {
use crate::registers::ID_AA64MMFR2_EL1;

ID_AA64MMFR2_EL1.read(ID_AA64MMFR2_EL1::CCIDX) != 0
}

pub struct Reg;

impl Reg {
/// Reads the [`CCSIDR_EL1`] `NumSets` field, selecting the correct
/// bit field by checking if the running CPU supports `CCIDX`.
#[inline(always)]
pub fn get_num_sets(&self) -> u64 {
match has_feature_ccidx() {
true => self.read(CCSIDR_EL1::NumSetsWithCCIDX),
false => self.read(CCSIDR_EL1::NumSetsWithoutCCIDX),
}
}

/// Sets the [`CCSIDR_EL1`] `NumSets` field, selecting the correct
/// bit field by checking if the running CPU supports `CCIDX`.
#[inline(always)]
pub fn set_num_sets(&self, value: u64) {
match has_feature_ccidx() {
true => self.write(CCSIDR_EL1::NumSetsWithCCIDX.val(value)),
false => self.write(CCSIDR_EL1::NumSetsWithoutCCIDX.val(value)),
}
}

/// Reads the [`CCSIDR_EL1`] `Associativity` field, selecting the correct
/// bit field by checking if the running CPU supports `CCIDX`.
#[inline(always)]
pub fn get_associativity(&self) -> u64 {
match has_feature_ccidx() {
true => self.read(CCSIDR_EL1::AssociativityWithCCIDX),
false => self.read(CCSIDR_EL1::AssociativityWithoutCCIDX),
}
}

/// Sets the [`CCSIDR_EL1`] `Associativity` field, selecting the correct
/// bit field by checking if the running CPU supports `CCIDX`.
#[inline(always)]
pub fn set_associativity(&self, value: u64) {
match has_feature_ccidx() {
true => self.write(CCSIDR_EL1::AssociativityWithCCIDX.val(value)),
false => self.write(CCSIDR_EL1::AssociativityWithoutCCIDX.val(value)),
}
}
}

impl Readable for Reg {
type T = u64;
type R = CCSIDR_EL1::Register;

sys_coproc_read_raw!(u64, "CCSIDR_EL1", "x");
}

impl Writeable for Reg {
type T = u64;
type R = CCSIDR_EL1::Register;

sys_coproc_write_raw!(u64, "CCSIDR_EL1", "x");
}

pub const CCSIDR_EL1: Reg = Reg;
Loading