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;