From 673e42779651f24ba08c19eaff642e8d1bdff9d2 Mon Sep 17 00:00:00 2001 From: Valentin B Date: Wed, 15 Jun 2022 16:06:59 +0200 Subject: [PATCH 1/5] Define the CSSELR_EL1 register --- src/registers.rs | 2 + src/registers/csselr_el1.rs | 100 ++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 src/registers/csselr_el1.rs diff --git a/src/registers.rs b/src/registers.rs index 8ad25a1..59cf0dc 100644 --- a/src/registers.rs +++ b/src/registers.rs @@ -16,6 +16,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; @@ -67,6 +68,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; diff --git a/src/registers/csselr_el1.rs b/src/registers/csselr_el1.rs new file mode 100644 index 0000000..fc6250a --- /dev/null +++ b/src/registers/csselr_el1.rs @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// +// Copyright (c) 2018-2022 by the author(s) +// +// Author(s): +// - Valentin B. + +//! 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 CSSELR_EL1 [ + /// ** When `FEAT_MTE2` is implemented:** + /// + /// Allocation Tag not Data bit. + /// + /// When [`CSSELR_EL1::InD`] is set, this bit is considered reserved. + /// + /// When [`CSSELR_EL1::Level`] is programmed to a cache level that is + /// not implemented, this field's value will be undefined for reads. + /// + /// NOTE: On a Warm reset, this field resets to an architecturally + /// undefined value. + /// + /// **Otherwise:** + /// + /// Reserved. + TnD OFFSET(4) NUMBITS(1) [ + /// Data, Instruction or Unified cache. + Data = 0b0, + /// Separate Allocation Tag cache. + AllocationTag = 0b1 + ], + + /// Cache level of required cache. + /// + /// Any value other than the pre-defined ones are considered reserved + /// and shall not be written to this field. + /// + /// When [`CSSELR_EL1::Level`] is programmed to a cache level that is + /// not implemented, this field's value will be undefined for reads. + /// + /// NOTE: On a Warm reset, this field resets to an architecturally + /// undefined value. + Level OFFSET(1) NUMBITS(3) [ + /// Level 1 Cache. + L1 = 0b000, + /// Level 2 Cache. + L2 = 0b001, + /// Level 3 Cache. + L3 = 0b010, + /// Level 4 Cache. + L4 = 0b011, + /// Level 5 Cache. + L5 = 0b100, + /// Level 6 Cache. + L6 = 0b101, + /// Level 7 Cache. + L7 = 0b110 + ], + + /// Instruction not Data bit. + /// + /// When [`CSSELR_EL1::Level`] is programmed to a cache level that is + /// not implemented, this field's value will be undefined for reads. + /// + /// NOTE: On a Warm reset, this field resets to an architecturally + /// undefined value. + InD OFFSET(0) NUMBITS(1) [ + /// Data or Unified cache. + Data = 0b0, + /// Instruction cache. + Instruction = 0b1 + ] + ] +} + +pub struct Reg; + +impl Readable for Reg { + type T = u64; + type R = CSSELR_EL1::Register; + + sys_coproc_read_raw!(u64, "CSSELR_EL1", "x"); +} + +impl Writeable for Reg { + type T = u64; + type R = CSSELR_EL1::Register; + + sys_coproc_write_raw!(u64, "CSSELR_EL1", "x"); +} + +pub const CSSELR_EL1: Reg = Reg; From 678a7d8e6a69e349b1c94eb0ca28d2d12df48b5c Mon Sep 17 00:00:00 2001 From: Valentin B Date: Wed, 15 Jun 2022 16:47:29 +0200 Subject: [PATCH 2/5] Define the CLIDR_EL1 register --- src/registers.rs | 2 + src/registers/clidr_el1.rs | 414 ++++++++++++++++++++++++++++++++++++ src/registers/csselr_el1.rs | 2 +- 3 files changed, 417 insertions(+), 1 deletion(-) create mode 100644 src/registers/clidr_el1.rs diff --git a/src/registers.rs b/src/registers.rs index 59cf0dc..ea06ec0 100644 --- a/src/registers.rs +++ b/src/registers.rs @@ -6,6 +6,7 @@ #[macro_use] mod macros; +mod clidr_el1; mod cntfrq_el0; mod cnthctl_el2; mod cntp_ctl_el0; @@ -58,6 +59,7 @@ mod ttbr1_el1; mod vbar_el1; mod vbar_el2; +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; diff --git a/src/registers/clidr_el1.rs b/src/registers/clidr_el1.rs new file mode 100644 index 0000000..676d3cc --- /dev/null +++ b/src/registers/clidr_el1.rs @@ -0,0 +1,414 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// +// Copyright (c) 2018-2022 by the author(s) +// +// Author(s): +// - Valentin B. + +//! Cache Level ID Register - EL1 +//! +//! Identifies the type of cache, or caches, that are implemented at each level and can +//! be managed using the architected cache maintenance instructions that operate by set/way, +//! up to a maximum of seven levels. Also identifies the Level of Coherence (LoC) and Level +//! of Unification (LoU) for the cache hierarchy. + +use tock_registers::{ + interfaces::{Readable, Writeable}, + register_bitfields, +}; + +register_bitfields! {u64, + pub CLIDR_EL1 [ + /// **When FEAT_MTE2 is implemented:** + /// + /// Tag cache type 7. Indicates the type of cache that is implemented and can be + /// managed using the architected cache maintenance instructions that operate + /// by set/way at each level, from Level 1 up to a maximum of seven levels of + /// cache hierarchy. + /// + /// **Otherwise:** + /// + /// Reserved. + Ttype7 OFFSET(45) NUMBITS(2) [ + /// No Tag Cache. + NoTag = 0b00, + /// Separate Allocation Tag Cache. + SeparateAllocationTag = 0b01, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in unified lines. + UnifiedAllocationTagDataCombined = 0b10, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in separate lines. + UnifiedAllocationTagDataSeparated = 0b11 + ], + + /// **When FEAT_MTE2 is implemented:** + /// + /// Tag cache type 6. Indicates the type of cache that is implemented and can be + /// managed using the architected cache maintenance instructions that operate + /// by set/way at each level, from Level 1 up to a maximum of seven levels of + /// cache hierarchy. + /// + /// **Otherwise:** + /// + /// Reserved. + Ttype6 OFFSET(43) NUMBITS(2) [ + /// No Tag Cache. + NoTag = 0b00, + /// Separate Allocation Tag Cache. + SeparateAllocationTag = 0b01, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in unified lines. + UnifiedAllocationTagDataCombined = 0b10, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in separate lines. + UnifiedAllocationTagDataSeparated = 0b11 + ], + + /// **When FEAT_MTE2 is implemented:** + /// + /// Tag cache type 5. Indicates the type of cache that is implemented and can be + /// managed using the architected cache maintenance instructions that operate + /// by set/way at each level, from Level 1 up to a maximum of seven levels of + /// cache hierarchy. + /// + /// **Otherwise:** + /// + /// Reserved. + Ttype5 OFFSET(41) NUMBITS(2) [ + /// No Tag Cache. + NoTag = 0b00, + /// Separate Allocation Tag Cache. + SeparateAllocationTag = 0b01, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in unified lines. + UnifiedAllocationTagDataCombined = 0b10, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in separate lines. + UnifiedAllocationTagDataSeparated = 0b11 + ], + + /// **When FEAT_MTE2 is implemented:** + /// + /// Tag cache type 4. Indicates the type of cache that is implemented and can be + /// managed using the architected cache maintenance instructions that operate + /// by set/way at each level, from Level 1 up to a maximum of seven levels of + /// cache hierarchy. + /// + /// **Otherwise:** + /// + /// Reserved. + Ttype4 OFFSET(39) NUMBITS(2) [ + /// No Tag Cache. + NoTag = 0b00, + /// Separate Allocation Tag Cache. + SeparateAllocationTag = 0b01, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in unified lines. + UnifiedAllocationTagDataCombined = 0b10, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in separate lines. + UnifiedAllocationTagDataSeparated = 0b11 + ], + + /// **When FEAT_MTE2 is implemented:** + /// + /// Tag cache type 3. Indicates the type of cache that is implemented and can be + /// managed using the architected cache maintenance instructions that operate + /// by set/way at each level, from Level 1 up to a maximum of seven levels of + /// cache hierarchy. + /// + /// **Otherwise:** + /// + /// Reserved. + Ttype3 OFFSET(37) NUMBITS(2) [ + /// No Tag Cache. + NoTag = 0b00, + /// Separate Allocation Tag Cache. + SeparateAllocationTag = 0b01, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in unified lines. + UnifiedAllocationTagDataCombined = 0b10, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in separate lines. + UnifiedAllocationTagDataSeparated = 0b11 + ], + + /// **When FEAT_MTE2 is implemented:** + /// + /// Tag cache type 2. Indicates the type of cache that is implemented and can be + /// managed using the architected cache maintenance instructions that operate + /// by set/way at each level, from Level 1 up to a maximum of seven levels of + /// cache hierarchy. + /// + /// **Otherwise:** + /// + /// Reserved. + Ttype2 OFFSET(35) NUMBITS(2) [ + /// No Tag Cache. + NoTag = 0b00, + /// Separate Allocation Tag Cache. + SeparateAllocationTag = 0b01, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in unified lines. + UnifiedAllocationTagDataCombined = 0b10, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in separate lines. + UnifiedAllocationTagDataSeparated = 0b11 + ], + + /// **When FEAT_MTE2 is implemented:** + /// + /// Tag cache type 1. Indicates the type of cache that is implemented and can be + /// managed using the architected cache maintenance instructions that operate + /// by set/way at each level, from Level 1 up to a maximum of seven levels of + /// cache hierarchy. + /// + /// **Otherwise:** + /// + /// Reserved. + Ttype1 OFFSET(33) NUMBITS(2) [ + /// No Tag Cache. + NoTag = 0b00, + /// Separate Allocation Tag Cache. + SeparateAllocationTag = 0b01, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in unified lines. + UnifiedAllocationTagDataCombined = 0b10, + /// Unified Allocation Tag and Data cache, Allocation Tags and Data in separate lines. + UnifiedAllocationTagDataSeparated = 0b11 + ], + + /// Inner cache boundary. This field indicates the boundary for caching + /// Inner Cacheable memory regions. + ICB OFFSET(30) NUMBITS(3) [ + /// Not disclosed by this mechanism. + Undisclosed = 0b000, + /// L1 cache is the highest Inner Cacheable level. + HighestInnerCacheableL1 = 0b001, + /// L2 cache is the highest Inner Cacheable level. + HighestInnerCacheableL2 = 0b010, + /// L3 cache is the highest Inner Cacheable level. + HighestInnerCacheableL3 = 0b011, + /// L4 cache is the highest Inner Cacheable level. + HighestInnerCacheableL4 = 0b100, + /// L5 cache is the highest Inner Cacheable level. + HighestInnerCacheableL5 = 0b101, + /// L6 cache is the highest Inner Cacheable level. + HighestInnerCacheableL6 = 0b110, + /// L7 cache is the highest Inner Cacheable level. + HighestInnerCacheableL7 = 0b111 + ], + + /// Level of Unification Uniprocessor for the cache hierarchy. + /// + /// When FEAT_S2FWB is implemented, the architecture requires that this field + /// is zero so that no levels of data cache need to be cleaned in order to + /// manage coherency with instruction fetches. + LoUU OFFSET(27) NUMBITS(3) [], + + /// Levels of Coherence for the cache hierarchy. + LoC OFFSET(24) NUMBITS(3) [], + + /// Level of Unification Inner Shareable for the cache hierarchy. + /// + /// When FEAT_S2FWB is implemented, the architecture requires that this field + /// is zero so that no levels of data cache need to be cleaned in order to + /// manage coherency with instruction fetches. + LoUIS OFFSET(21) NUMBITS(3) [], + + /// Cache Type field 7. + /// + /// Indicates the type of cache that is implemented and can be managed using + /// the architected cache maintenance instructions that operate by set/way at + /// each level, from Level 1 up to a maximum of seven levels of cache hierarchy. + /// + /// All values other than the defined ones are considered reserved. + /// + /// If software reads the Cache Type fields from [`CLIDR_EL1::Ctype1`] upwards, + /// once it has seen a value of `000`, no caches that can be managed using the + /// architected cache maintenance instructions that operate by set/way exist at + /// further-out levels of the hierarchy. So, for example, if Ctype3 is the first + /// Cache Type field with a value of `000`, the values of `Ctype4` to `Ctype7` + /// must be ignored. + Ctype7 OFFSET(18) NUMBITS(3) [ + /// No cache. + NoCache = 0b000, + /// Instruction cache only. + InstructionCacheOnly = 0b001, + /// Data cache only. + DataCacheOnly = 0b010, + /// Separate instruction and data caches. + SeparateInstructionAndDataCaches = 0b011, + /// Unified cache. + UnifiedCache = 0b100 + ], + + /// Cache Type field 6. + /// + /// Indicates the type of cache that is implemented and can be managed using + /// the architected cache maintenance instructions that operate by set/way at + /// each level, from Level 1 up to a maximum of seven levels of cache hierarchy. + /// + /// All values other than the defined ones are considered reserved. + /// + /// If software reads the Cache Type fields from [`CLIDR_EL1::Ctype1`] upwards, + /// once it has seen a value of `000`, no caches that can be managed using the + /// architected cache maintenance instructions that operate by set/way exist at + /// further-out levels of the hierarchy. So, for example, if Ctype3 is the first + /// Cache Type field with a value of `000`, the values of `Ctype4` to `Ctype7` + /// must be ignored. + Ctype6 OFFSET(15) NUMBITS(3) [ + /// No cache. + NoCache = 0b000, + /// Instruction cache only. + InstructionCacheOnly = 0b001, + /// Data cache only. + DataCacheOnly = 0b010, + /// Separate instruction and data caches. + SeparateInstructionAndDataCaches = 0b011, + /// Unified cache. + UnifiedCache = 0b100 + ], + + /// Cache Type field 5. + /// + /// Indicates the type of cache that is implemented and can be managed using + /// the architected cache maintenance instructions that operate by set/way at + /// each level, from Level 1 up to a maximum of seven levels of cache hierarchy. + /// + /// All values other than the defined ones are considered reserved. + /// + /// If software reads the Cache Type fields from [`CLIDR_EL1::Ctype1`] upwards, + /// once it has seen a value of `000`, no caches that can be managed using the + /// architected cache maintenance instructions that operate by set/way exist at + /// further-out levels of the hierarchy. So, for example, if Ctype3 is the first + /// Cache Type field with a value of `000`, the values of `Ctype4` to `Ctype7` + /// must be ignored. + Ctype5 OFFSET(12) NUMBITS(3) [ + /// No cache. + NoCache = 0b000, + /// Instruction cache only. + InstructionCacheOnly = 0b001, + /// Data cache only. + DataCacheOnly = 0b010, + /// Separate instruction and data caches. + SeparateInstructionAndDataCaches = 0b011, + /// Unified cache. + UnifiedCache = 0b100 + ], + + /// Cache Type field 4. + /// + /// Indicates the type of cache that is implemented and can be managed using + /// the architected cache maintenance instructions that operate by set/way at + /// each level, from Level 1 up to a maximum of seven levels of cache hierarchy. + /// + /// All values other than the defined ones are considered reserved. + /// + /// If software reads the Cache Type fields from [`CLIDR_EL1::Ctype1`] upwards, + /// once it has seen a value of `000`, no caches that can be managed using the + /// architected cache maintenance instructions that operate by set/way exist at + /// further-out levels of the hierarchy. So, for example, if Ctype3 is the first + /// Cache Type field with a value of `000`, the values of `Ctype4` to `Ctype7` + /// must be ignored. + Ctype4 OFFSET(9) NUMBITS(3) [ + /// No cache. + NoCache = 0b000, + /// Instruction cache only. + InstructionCacheOnly = 0b001, + /// Data cache only. + DataCacheOnly = 0b010, + /// Separate instruction and data caches. + SeparateInstructionAndDataCaches = 0b011, + /// Unified cache. + UnifiedCache = 0b100 + ], + + /// Cache Type field 3. + /// + /// Indicates the type of cache that is implemented and can be managed using + /// the architected cache maintenance instructions that operate by set/way at + /// each level, from Level 1 up to a maximum of seven levels of cache hierarchy. + /// + /// All values other than the defined ones are considered reserved. + /// + /// If software reads the Cache Type fields from [`CLIDR_EL1::Ctype1`] upwards, + /// once it has seen a value of `000`, no caches that can be managed using the + /// architected cache maintenance instructions that operate by set/way exist at + /// further-out levels of the hierarchy. So, for example, if Ctype3 is the first + /// Cache Type field with a value of `000`, the values of `Ctype4` to `Ctype7` + /// must be ignored. + Ctype3 OFFSET(6) NUMBITS(3) [ + /// No cache. + NoCache = 0b000, + /// Instruction cache only. + InstructionCacheOnly = 0b001, + /// Data cache only. + DataCacheOnly = 0b010, + /// Separate instruction and data caches. + SeparateInstructionAndDataCaches = 0b011, + /// Unified cache. + UnifiedCache = 0b100 + ], + + /// Cache Type field 2. + /// + /// Indicates the type of cache that is implemented and can be managed using + /// the architected cache maintenance instructions that operate by set/way at + /// each level, from Level 1 up to a maximum of seven levels of cache hierarchy. + /// + /// All values other than the defined ones are considered reserved. + /// + /// If software reads the Cache Type fields from [`CLIDR_EL1::Ctype1`] upwards, + /// once it has seen a value of `000`, no caches that can be managed using the + /// architected cache maintenance instructions that operate by set/way exist at + /// further-out levels of the hierarchy. So, for example, if Ctype3 is the first + /// Cache Type field with a value of `000`, the values of `Ctype4` to `Ctype7` + /// must be ignored. + Ctype2 OFFSET(3) NUMBITS(3) [ + /// No cache. + NoCache = 0b000, + /// Instruction cache only. + InstructionCacheOnly = 0b001, + /// Data cache only. + DataCacheOnly = 0b010, + /// Separate instruction and data caches. + SeparateInstructionAndDataCaches = 0b011, + /// Unified cache. + UnifiedCache = 0b100 + ], + + /// Cache Type field 1. + /// + /// Indicates the type of cache that is implemented and can be managed using + /// the architected cache maintenance instructions that operate by set/way at + /// each level, from Level 1 up to a maximum of seven levels of cache hierarchy. + /// + /// All values other than the defined ones are considered reserved. + /// + /// If software reads the Cache Type fields from [`CLIDR_EL1::Ctype1`] upwards, + /// once it has seen a value of `000`, no caches that can be managed using the + /// architected cache maintenance instructions that operate by set/way exist at + /// further-out levels of the hierarchy. So, for example, if Ctype3 is the first + /// Cache Type field with a value of `000`, the values of `Ctype4` to `Ctype7` + /// must be ignored. + Ctype1 OFFSET(0) NUMBITS(3) [ + /// No cache. + NoCache = 0b000, + /// Instruction cache only. + InstructionCacheOnly = 0b001, + /// Data cache only. + DataCacheOnly = 0b010, + /// Separate instruction and data caches. + SeparateInstructionAndDataCaches = 0b011, + /// Unified cache. + UnifiedCache = 0b100 + ] + ] +} + +pub struct Reg; + +impl Readable for Reg { + type T = u64; + type R = CLIDR_EL1::Register; + + sys_coproc_read_raw!(u64, "CLIDR_EL1", "x"); +} + +impl Writeable for Reg { + type T = u64; + type R = CLIDR_EL1::Register; + + sys_coproc_write_raw!(u64, "CLIDR_EL1", "x"); +} + +pub const CLIDR_EL1: Reg = Reg; diff --git a/src/registers/csselr_el1.rs b/src/registers/csselr_el1.rs index fc6250a..91248fc 100644 --- a/src/registers/csselr_el1.rs +++ b/src/registers/csselr_el1.rs @@ -31,7 +31,7 @@ register_bitfields! {u64, /// **Otherwise:** /// /// Reserved. - TnD OFFSET(4) NUMBITS(1) [ + TnD OFFSET(4) NUMBITS(1) [ /// Data, Instruction or Unified cache. Data = 0b0, /// Separate Allocation Tag cache. From d07960450db18b9be4eb92aea2b4382ba9394069 Mon Sep 17 00:00:00 2001 From: Valentin B Date: Wed, 15 Jun 2022 17:04:30 +0200 Subject: [PATCH 3/5] Define the CCSIDR_EL1 register --- src/registers.rs | 2 + src/registers/ccsidr_el1.rs | 99 +++++++++++++++++++++++++++++++++++++ src/registers/csselr_el1.rs | 5 +- 3 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 src/registers/ccsidr_el1.rs diff --git a/src/registers.rs b/src/registers.rs index ea06ec0..b6cb9cf 100644 --- a/src/registers.rs +++ b/src/registers.rs @@ -6,6 +6,7 @@ #[macro_use] mod macros; +mod ccsidr_el1; mod clidr_el1; mod cntfrq_el0; mod cnthctl_el2; @@ -59,6 +60,7 @@ mod ttbr1_el1; mod vbar_el1; mod vbar_el2; +pub use ccsidr_el1::{CCSIDR_EL1, CSSIDR_EL1_WITH_FEAT_CCIDX}; pub use clidr_el1::CLIDR_EL1; pub use cntfrq_el0::CNTFRQ_EL0; pub use cnthctl_el2::CNTHCTL_EL2; diff --git a/src/registers/ccsidr_el1.rs b/src/registers/ccsidr_el1.rs new file mode 100644 index 0000000..156ce0c --- /dev/null +++ b/src/registers/ccsidr_el1.rs @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// +// Copyright (c) 2018-2022 by the author(s) +// +// Author(s): +// - Valentin B. + +//! 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, + /// The representation of `CCSIDR_EL1` when `FEAT_CCIDX` is implemented. + pub CCSIDR_EL1_WITH_FEAT_CCIDX [ + /// 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. + NumSets OFFSET(32) NUMBITS(24) [], + + /// Associativity of cache. + /// + /// A value of 0 indicates an associativity of 1. The value does not + /// necessarily have to be a power of 2. + Associativity OFFSET(3) NUMBITS(21) [], + + /// 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) [] + ], + + /// The representation of `CCSIDR_EL1` otherwise. + 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. + NumSets 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. + Associativity 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) [] + ] +} + +pub struct RegWithFeatCcidx; +pub struct Reg; + +impl Readable for RegWithFeatCcidx { + type T = u64; + type R = CCSIDR_EL1_WITH_FEAT_CCIDX::Register; + + sys_coproc_read_raw!(u64, "CCSIDR_EL1", "x"); +} + +impl Writeable for RegWithFeatCcidx { + type T = u64; + type R = CCSIDR_EL1_WITH_FEAT_CCIDX::Register; + + sys_coproc_write_raw!(u64, "CCSIDR_EL1", "x"); +} + +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_WITH_FEAT_CCIDX: RegWithFeatCcidx = RegWithFeatCcidx; +pub const CCSIDR_EL1: Reg = Reg; diff --git a/src/registers/csselr_el1.rs b/src/registers/csselr_el1.rs index 91248fc..ce6b39f 100644 --- a/src/registers/csselr_el1.rs +++ b/src/registers/csselr_el1.rs @@ -5,9 +5,10 @@ // Author(s): // - Valentin B. -//! Current Cache Size ID Register - EL1 +//! Cache Size Selection Register - EL1 //! -//! Provides information about the architecture of the currently selected cache. +//! Selects the current Cache Size ID Register, CCSIDR_EL1, by specifying the +//! required cache level and the cache type (either instruction or data cache). use tock_registers::{ interfaces::{Readable, Writeable}, From dd99e9e87fa9d4bffc30127430670efdbc6198c1 Mon Sep 17 00:00:00 2001 From: Valentin B Date: Wed, 15 Jun 2022 23:24:08 +0200 Subject: [PATCH 4/5] Define the ID_AA64MMFR2_EL1 register --- src/registers.rs | 4 +- src/registers/id_aa64mmfr2_el1.rs | 108 ++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 src/registers/id_aa64mmfr2_el1.rs diff --git a/src/registers.rs b/src/registers.rs index b6cb9cf..710436c 100644 --- a/src/registers.rs +++ b/src/registers.rs @@ -32,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; @@ -60,7 +61,7 @@ mod ttbr1_el1; mod vbar_el1; mod vbar_el2; -pub use ccsidr_el1::{CCSIDR_EL1, CSSIDR_EL1_WITH_FEAT_CCIDX}; +pub use ccsidr_el1::{CCSIDR_EL1, CCSIDR_EL1_WITH_FEAT_CCIDX}; pub use clidr_el1::CLIDR_EL1; pub use cntfrq_el0::CNTFRQ_EL0; pub use cnthctl_el2::CNTHCTL_EL2; @@ -86,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; diff --git a/src/registers/id_aa64mmfr2_el1.rs b/src/registers/id_aa64mmfr2_el1.rs new file mode 100644 index 0000000..e258146 --- /dev/null +++ b/src/registers/id_aa64mmfr2_el1.rs @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: Apache-2.0 OR MIT +// +// Copyright (c) 2018-2022 by the author(s) +// +// Author(s): +// - Valentin B. + +//! AArch64 Memory Model Feature Register 2 - EL1 +//! +//! Provides information about the implemented memory model and memory +//! management support in AArch64 state. + +use tock_registers::{interfaces::Readable, register_bitfields}; + +register_bitfields! {u64, + pub ID_AA64MMFR2_EL1 [ + /// Indicates support for the E0PD mechanism. + E0PD OFFSET(60) NUMBITS(4) [], + + /// Enhanced Virtualization Traps. + /// + /// If EL2 is implemented, indicates support for the + /// HCR_EL2.{TTLBOS, TTLBIS, TOCU, TICAB, TID4} traps. + EVT OFFSET(56) NUMBITS(4) [ + /// None of the aforementioned traps are supported. + Nothing = 0b0000, + /// All aforementioned traps but the HCR_EL2.{TTLBOS, TTLBBIS} + /// ones are supported. + NoTtl = 0b0001, + /// All the aforementioned HCR_EL2 traps are supported. + Everything = 0b0010 + ], + + /// Allows identification of the requirements of the hardware to have + /// break-before-make sequences when changing block size for a translation. + BBM OFFSET(52) NUMBITS(4) [ + /// Level 0 support for changing block size is supported. + Level0 = 0b0000, + /// Level 1 support for changing block size is supported. + Level1 = 0b0001, + /// Level 2 support for changing block size is supported. + Level2 = 0b0010 + ], + + /// Indicates support for TTL field in address operations. + TTL OFFSET(48) NUMBITS(4) [], + + /// Indicates support for HCR_EL2.FWB. + FWB OFFSET(40) NUMBITS(4) [], + + /// Indicates the value of ESR_ELx.EC that reports an exception generated by + /// a read access to the feature ID space. + /// + /// - When reading 0, only read access exceptions other than HCR_EL2.TIDx, + /// SCTLR_EL1.UCT, or SCTLR_EL2.UCT traps are reported by ESR_ELx.EC == 0. + /// + /// - When reading 1, all read access exceptions are reported by ESR_ELx.EC == 0x18. + IDS OFFSET(36) NUMBITS(4) [], + + /// Identifies support for unaligned single-copy atomicity and atomic functions. + AT OFFSET(32) NUMBITS(4) [], + + /// Identifies support for small translation tables. + ST OFFSET(28) NUMBITS(4) [], + + /// If EL2 is implemented, indicates support for the use of nested virtualization. + NV OFFSET(24) NUMBITS(4) [ + /// Nested virtualization is not supported. + Unsupported = 0b0000, + /// The HCR_EL2.{AT, NV1, NV} bits are implemented. + Partial = 0b001, + /// The VNCR_EL2 register and the HCR_EL2.{NV2, AT, NV1, NV} bits are implemented. + Full = 0b0010 + ], + + /// Support for the use of revised `CCSIDR_EL1` register format. + CCIDX OFFSET(20) NUMBITS(4) [], + + /// Indicates support for a larger virtual address. + /// + /// When this reads 1, 52-bit VAs when using the 64KB translation granule are + /// supported along with the standard 48-bit VAs. + VARange OFFSET(16) NUMBITS(4) [], + + /// Indicates support for the IESB bit in the SCTLR_ELx registers. + IESB OFFSET(12) NUMBITS(4) [], + + /// Indicates support for LSMAOE and nTLSMD bits in SCTLR_EL1 and SCTLR_EL2. + LSM OFFSET(8) NUMBITS(4) [], + + /// Indicates support for User Access Overrides. + UAO OFFSET(4) NUMBITS(4) [], + + /// Indicates support for Common not Private translations. + CnP OFFSET(0) NUMBITS(4) [] + ] +} + +pub struct Reg; + +impl Readable for Reg { + type T = u64; + type R = ID_AA64MMFR2_EL1::Register; + + sys_coproc_read_raw!(u64, "ID_AA64MMFR2_EL1", "x"); +} + +pub const ID_AA64MMFR2_EL1: Reg = Reg; From ff8127cbb4e7abd0844e6e5b5c2248f60f40f680 Mon Sep 17 00:00:00 2001 From: Valentin B Date: Wed, 15 Jun 2022 23:36:23 +0200 Subject: [PATCH 5/5] Add CCSIDR_EL1 getters/setters with respect to CCIDX availability --- src/registers.rs | 2 +- src/registers/ccsidr_el1.rs | 88 +++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/src/registers.rs b/src/registers.rs index 710436c..ba6c344 100644 --- a/src/registers.rs +++ b/src/registers.rs @@ -61,7 +61,7 @@ mod ttbr1_el1; mod vbar_el1; mod vbar_el2; -pub use ccsidr_el1::{CCSIDR_EL1, CCSIDR_EL1_WITH_FEAT_CCIDX}; +pub use ccsidr_el1::CCSIDR_EL1; pub use clidr_el1::CLIDR_EL1; pub use cntfrq_el0::CNTFRQ_EL0; pub use cnthctl_el2::CNTHCTL_EL2; diff --git a/src/registers/ccsidr_el1.rs b/src/registers/ccsidr_el1.rs index 156ce0c..4c16641 100644 --- a/src/registers/ccsidr_el1.rs +++ b/src/registers/ccsidr_el1.rs @@ -15,43 +15,30 @@ use tock_registers::{ }; register_bitfields! {u64, - /// The representation of `CCSIDR_EL1` when `FEAT_CCIDX` is implemented. - pub CCSIDR_EL1_WITH_FEAT_CCIDX [ + 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. - NumSets OFFSET(32) NUMBITS(24) [], + NumSetsWithCCIDX OFFSET(32) NUMBITS(24) [], - /// Associativity of cache. + /// Number of sets in cache. /// - /// A value of 0 indicates an associativity of 1. The value does not + /// A value of 0 indicates 1 set in the cache. The number does not /// necessarily have to be a power of 2. - Associativity OFFSET(3) NUMBITS(21) [], - - /// 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) [] - ], + NumSetsWithoutCCIDX OFFSET(13) NUMBITS(15) [], - /// The representation of `CCSIDR_EL1` otherwise. - pub CCSIDR_EL1 [ - /// Number of sets in cache. + /// Associativity of cache. /// - /// A value of 0 indicates 1 set in the cache. The number does not + /// A value of 0 indicates an associativity of 1. The value does not /// necessarily have to be a power of 2. - NumSets OFFSET(13) NUMBITS(15) [], + 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. - Associativity OFFSET(3) NUMBITS(10) [], + AssociativityWithoutCCIDX OFFSET(3) NUMBITS(10) [], /// Log2(Number of bytes in cache lline) - 4. /// @@ -64,21 +51,55 @@ register_bitfields! {u64, ] } -pub struct RegWithFeatCcidx; -pub struct Reg; +#[inline(always)] +fn has_feature_ccidx() -> bool { + use crate::registers::ID_AA64MMFR2_EL1; -impl Readable for RegWithFeatCcidx { - type T = u64; - type R = CCSIDR_EL1_WITH_FEAT_CCIDX::Register; - - sys_coproc_read_raw!(u64, "CCSIDR_EL1", "x"); + ID_AA64MMFR2_EL1.read(ID_AA64MMFR2_EL1::CCIDX) != 0 } -impl Writeable for RegWithFeatCcidx { - type T = u64; - type R = CCSIDR_EL1_WITH_FEAT_CCIDX::Register; +pub struct Reg; - sys_coproc_write_raw!(u64, "CCSIDR_EL1", "x"); +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 { @@ -95,5 +116,4 @@ impl Writeable for Reg { sys_coproc_write_raw!(u64, "CCSIDR_EL1", "x"); } -pub const CCSIDR_EL1_WITH_FEAT_CCIDX: RegWithFeatCcidx = RegWithFeatCcidx; pub const CCSIDR_EL1: Reg = Reg;