cortex_a/registers/
ccsidr_el1.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2//
3// Copyright (c) 2018-2022 by the author(s)
4//
5// Author(s):
6//   - Valentin B. <valentin.be@protonmail.com>
7
8//! Current Cache Size ID Register - EL1
9//!
10//! Provides information about the architecture of the currently selected cache.
11
12use tock_registers::{
13    interfaces::{Readable, Writeable},
14    register_bitfields,
15};
16
17register_bitfields! {u64,
18    pub CCSIDR_EL1 [
19        /// Number of sets in cache.
20        ///
21        /// A value of 0 indicates 1 set in the cache. The number does not
22        /// necessarily have to be a power of 2.
23        NumSetsWithCCIDX OFFSET(32) NUMBITS(24) [],
24
25        /// Number of sets in cache.
26        ///
27        /// A value of 0 indicates 1 set in the cache. The number does not
28        /// necessarily have to be a power of 2.
29        NumSetsWithoutCCIDX OFFSET(13) NUMBITS(15) [],
30
31        /// Associativity of cache.
32        ///
33        /// A value of 0 indicates an associativity of 1. The value does not
34        /// necessarily have to be a power of 2.
35        AssociativityWithCCIDX OFFSET(3) NUMBITS(21) [],
36
37        /// Associativity of cache.
38        ///
39        /// A value of 0 indicates an associativity of 1. The value does not
40        /// necessarily have to be a power of 2.
41        AssociativityWithoutCCIDX OFFSET(3) NUMBITS(10) [],
42
43        /// Log2(Number of bytes in cache lline) - 4.
44        ///
45        /// **Examples:**
46        ///
47        /// - For a line length of 16 bytes: Log2(16) - 4 = 0. This is the minimum line length.
48        ///
49        /// - For a line length of 32 bytes: Log2(32) - 4 = 1.
50        LineSize OFFSET(0) NUMBITS(3) []
51    ]
52}
53
54#[inline(always)]
55fn has_feature_ccidx() -> bool {
56    use crate::registers::ID_AA64MMFR2_EL1;
57
58    ID_AA64MMFR2_EL1.read(ID_AA64MMFR2_EL1::CCIDX) != 0
59}
60
61pub struct Reg;
62
63impl Reg {
64    /// Reads the [`CCSIDR_EL1`] `NumSets` field, selecting the correct
65    /// bit field by checking if the running CPU supports `CCIDX`.
66    #[inline(always)]
67    pub fn get_num_sets(&self) -> u64 {
68        match has_feature_ccidx() {
69            true => self.read(CCSIDR_EL1::NumSetsWithCCIDX),
70            false => self.read(CCSIDR_EL1::NumSetsWithoutCCIDX),
71        }
72    }
73
74    /// Sets the [`CCSIDR_EL1`] `NumSets` field, selecting the correct
75    /// bit field by checking if the running CPU supports `CCIDX`.
76    #[inline(always)]
77    pub fn set_num_sets(&self, value: u64) {
78        match has_feature_ccidx() {
79            true => self.write(CCSIDR_EL1::NumSetsWithCCIDX.val(value)),
80            false => self.write(CCSIDR_EL1::NumSetsWithoutCCIDX.val(value)),
81        }
82    }
83
84    /// Reads the [`CCSIDR_EL1`] `Associativity` field, selecting the correct
85    /// bit field by checking if the running CPU supports `CCIDX`.
86    #[inline(always)]
87    pub fn get_associativity(&self) -> u64 {
88        match has_feature_ccidx() {
89            true => self.read(CCSIDR_EL1::AssociativityWithCCIDX),
90            false => self.read(CCSIDR_EL1::AssociativityWithoutCCIDX),
91        }
92    }
93
94    /// Sets the [`CCSIDR_EL1`] `Associativity` field, selecting the correct
95    /// bit field by checking if the running CPU supports `CCIDX`.
96    #[inline(always)]
97    pub fn set_associativity(&self, value: u64) {
98        match has_feature_ccidx() {
99            true => self.write(CCSIDR_EL1::AssociativityWithCCIDX.val(value)),
100            false => self.write(CCSIDR_EL1::AssociativityWithoutCCIDX.val(value)),
101        }
102    }
103}
104
105impl Readable for Reg {
106    type T = u64;
107    type R = CCSIDR_EL1::Register;
108
109    sys_coproc_read_raw!(u64, "CCSIDR_EL1", "x");
110}
111
112impl Writeable for Reg {
113    type T = u64;
114    type R = CCSIDR_EL1::Register;
115
116    sys_coproc_write_raw!(u64, "CCSIDR_EL1", "x");
117}
118
119pub const CCSIDR_EL1: Reg = Reg;