aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Walbran <qwandor@google.com>2022-03-22 16:15:17 +0000
committerAndrew Walbran <qwandor@google.com>2022-04-07 16:40:02 +0000
commit4cb517a02631b05917ac900cdf3632918ba1e292 (patch)
tree4f7be03a78a4aaed66b1f8b4e85d316e71ccbe4c
parent412d44a5e74026c6489ca0789396cb2cd2a7ab17 (diff)
downloadcortex-a-main.tar.gz
Initial import.HEADmastermain
Bug: 223166344 Change-Id: I0b181158a5316e6122627d4a51301b908581656a
-rw-r--r--.cargo_vcs_info.json6
-rw-r--r--Cargo.toml27
-rw-r--r--Cargo.toml.orig23
l---------LICENSE1
-rw-r--r--LICENSE-APACHE201
-rw-r--r--LICENSE-MIT21
-rw-r--r--METADATA20
-rw-r--r--MODULE_LICENSE_APACHE20
-rw-r--r--OWNERS1
-rw-r--r--README.md93
-rw-r--r--rust-toolchain.toml3
-rw-r--r--src/asm.rs113
-rw-r--r--src/asm/barrier.rs111
-rw-r--r--src/lib.rs87
-rw-r--r--src/registers.rs107
-rw-r--r--src/registers/cntfrq_el0.rs25
-rw-r--r--src/registers/cnthctl_el2.rs73
-rw-r--r--src/registers/cntp_ctl_el0.rs63
-rw-r--r--src/registers/cntp_tval_el0.rs30
-rw-r--r--src/registers/cntpct_el0.rs23
-rw-r--r--src/registers/cntv_ctl_el0.rs69
-rw-r--r--src/registers/cntv_cval_el0.rs49
-rw-r--r--src/registers/cntv_tval_el0.rs31
-rw-r--r--src/registers/cntvct_el0.rs25
-rw-r--r--src/registers/cntvoff_el2.rs31
-rw-r--r--src/registers/currentel.rs46
-rw-r--r--src/registers/daif.rs87
-rw-r--r--src/registers/elr_el1.rs30
-rw-r--r--src/registers/elr_el2.rs30
-rw-r--r--src/registers/elr_el3.rs31
-rw-r--r--src/registers/esr_el1.rs82
-rw-r--r--src/registers/esr_el2.rs94
-rw-r--r--src/registers/far_el1.rs31
-rw-r--r--src/registers/far_el2.rs31
-rw-r--r--src/registers/fp.rs28
-rw-r--r--src/registers/hcr_el2.rs281
-rw-r--r--src/registers/id_aa64mmfr0_el1.rs96
-rw-r--r--src/registers/lr.rs29
-rw-r--r--src/registers/macros.rs76
-rw-r--r--src/registers/mair_el1.rs447
-rw-r--r--src/registers/mair_el2.rs448
-rw-r--r--src/registers/midr_el1.rs96
-rw-r--r--src/registers/mpidr_el1.rs24
-rw-r--r--src/registers/oslar_el1.rs48
-rw-r--r--src/registers/par_el1.rs63
-rw-r--r--src/registers/scr_el3.rs95
-rw-r--r--src/registers/sctlr_el1.rs320
-rw-r--r--src/registers/sctlr_el2.rs148
-rw-r--r--src/registers/sp.rs28
-rw-r--r--src/registers/sp_el0.rs31
-rw-r--r--src/registers/sp_el1.rs36
-rw-r--r--src/registers/spsel.rs49
-rw-r--r--src/registers/spsr_el1.rs145
-rw-r--r--src/registers/spsr_el2.rs149
-rw-r--r--src/registers/spsr_el3.rs150
-rw-r--r--src/registers/tcr_el1.rs347
-rw-r--r--src/registers/tcr_el2.rs176
-rw-r--r--src/registers/tpidr_el0.rs31
-rw-r--r--src/registers/tpidr_el1.rs31
-rw-r--r--src/registers/tpidrro_el0.rs31
-rw-r--r--src/registers/ttbr0_el1.rs64
-rw-r--r--src/registers/ttbr0_el2.rs60
-rw-r--r--src/registers/ttbr1_el1.rs64
-rw-r--r--src/registers/vbar_el1.rs30
-rw-r--r--src/registers/vbar_el2.rs31
65 files changed, 5347 insertions, 0 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..36ee32b
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,6 @@
+{
+ "git": {
+ "sha1": "5c942a99d9e534f3d0973c23d408384c7aefce05"
+ },
+ "path_in_vcs": ""
+} \ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..d6d0295
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,27 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "cortex-a"
+version = "7.2.0"
+authors = ["Andre Richter <andre.o.richter@gmail.com>"]
+exclude = [".github", ".gitignore", ".rustfmt.toml", ".vscode", ".editorconfig", "Makefile"]
+description = "Low level access to Cortex-A processors"
+homepage = "https://github.com/rust-embedded/cortex-a"
+readme = "README.md"
+keywords = ["arm", "aarch64", "cortex-a", "register"]
+categories = ["embedded", "hardware-support", "no-std"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/rust-embedded/cortex-a"
+[dependencies.tock-registers]
+version = "0.7.x"
+default-features = false
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644
index 0000000..22d5fac
--- /dev/null
+++ b/Cargo.toml.orig
@@ -0,0 +1,23 @@
+[package]
+name = "cortex-a"
+version = "7.2.0"
+authors = ["Andre Richter <andre.o.richter@gmail.com>"]
+description = "Low level access to Cortex-A processors"
+homepage = "https://github.com/rust-embedded/cortex-a"
+repository = "https://github.com/rust-embedded/cortex-a"
+readme = "README.md"
+keywords = ["arm", "aarch64", "cortex-a", "register"]
+categories = ["embedded", "hardware-support", "no-std"]
+license = "MIT/Apache-2.0"
+edition = "2018"
+exclude = [
+ ".github",
+ ".gitignore",
+ ".rustfmt.toml",
+ ".vscode",
+ ".editorconfig",
+ "Makefile"
+]
+
+[dependencies]
+tock-registers = { version = "0.7.x", default-features = false } # Use it as interface-only library.
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..6b579aa
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+LICENSE-APACHE \ No newline at end of file
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
new file mode 100644
index 0000000..16fe87b
--- /dev/null
+++ b/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..d36a7e1
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (C) 2018-2022 by the respective authors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..b1970eb
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,20 @@
+name: "cortex-a"
+description: "Low level access to Cortex-A processors"
+third_party {
+ url {
+ type: HOMEPAGE
+ value: "https://crates.io/crates/cortex-a"
+ }
+ url {
+ type: ARCHIVE
+ value: "https://static.crates.io/crates/cortex-a/cortex-a-7.2.0.crate"
+ }
+ version: "7.2.0"
+ # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same.
+ license_type: NOTICE
+ last_upgrade_date {
+ year: 2022
+ month: 3
+ day: 22
+ }
+}
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..45dc4dd
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1 @@
+include platform/prebuilts/rust:master:/OWNERS
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a7b547c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,93 @@
+[![crates.io](https://img.shields.io/crates/d/cortex-a.svg)](https://crates.io/crates/cortex-a)
+[![crates.io](https://img.shields.io/crates/v/cortex-a.svg)](https://crates.io/crates/cortex-a)
+
+# cortex-a
+
+Low level access to Cortex-A processors.
+
+## Currently Supported Execution States
+
+- [x] AArch64
+- [ ] AArch32
+
+## Minimum Supported Rust Version
+
+Requires a recent nightly of Rust.
+
+## Usage
+
+Please note that for using this crate's [register definitions](src/registers) (as provided by
+`cortex_a::registers::*`), you need to also include
+[`tock-registers`](https://crates.io/crates/tock-registers) in your project. This is because the
+`interface` traits provided by `tock-registers` are implemented by this crate. You should include
+the same version of `tock-registers` as is being used by this crate to ensure sane
+interoperatbility.
+
+For example, in the following snippet, `X.Y.Z` should be the same version of `tock-registers` that
+is mentioned in `cortex-a`'s [`Cargo.toml`](Cargo.toml).
+
+```toml
+[package]
+name = "Your embedded project"
+
+# Some parts omitted for brevity.
+
+[dependencies]
+tock-registers = "X.Y.Z"
+cortex-a = "A.B.C" # <-- Includes tock-registers itself.
+```
+
+### Example
+
+Check out https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials for usage examples. Listed
+below is a snippet of `rust-raspberrypi-OS-tutorials`'s early boot code.
+
+```rust
+use cortex_a::{asm, registers::*};
+use tock_registers::interfaces::Writeable; // <-- Trait needed to use `write()` and `set()`.
+
+// Some parts omitted for brevity.
+
+unsafe fn prepare_el2_to_el1_transition(
+ virt_boot_core_stack_end_exclusive_addr: u64,
+ virt_kernel_init_addr: u64,
+) {
+ // Enable timer counter registers for EL1.
+ CNTHCTL_EL2.write(CNTHCTL_EL2::EL1PCEN::SET + CNTHCTL_EL2::EL1PCTEN::SET);
+
+ // No offset for reading the counters.
+ CNTVOFF_EL2.set(0);
+
+ // Set EL1 execution state to AArch64.
+ HCR_EL2.write(HCR_EL2::RW::EL1IsAarch64);
+
+ // Set up a simulated exception return.
+ SPSR_EL2.write(
+ SPSR_EL2::D::Masked
+ + SPSR_EL2::A::Masked
+ + SPSR_EL2::I::Masked
+ + SPSR_EL2::F::Masked
+ + SPSR_EL2::M::EL1h,
+ );
+```
+
+## Disclaimer
+
+Descriptive comments in the source files are taken from the
+[ARM Architecture Reference Manual ARMv8, for ARMv8-A architecture profile](https://static.docs.arm.com/ddi0487/ca/DDI0487C_a_armv8_arm.pdf?_ga=2.266626254.1122218691.1534883460-1326731866.1530967873).
+
+## License
+
+Licensed under either of
+
+- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
+ http://www.apache.org/licenses/LICENSE-2.0)
+- MIT License ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the
+work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
+additional terms or conditions.
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
new file mode 100644
index 0000000..a500664
--- /dev/null
+++ b/rust-toolchain.toml
@@ -0,0 +1,3 @@
+[toolchain]
+channel = "nightly"
+targets = ["aarch64-unknown-none-softfloat"]
diff --git a/src/asm.rs b/src/asm.rs
new file mode 100644
index 0000000..0e4a942
--- /dev/null
+++ b/src/asm.rs
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Jorge Aparicio
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Wrappers around ARMv8-A instructions.
+
+pub mod barrier;
+
+/// The classic no-op
+#[inline(always)]
+pub fn nop() {
+ #[cfg(target_arch = "aarch64")]
+ unsafe {
+ core::arch::asm!("nop", options(nomem, nostack))
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ unimplemented!()
+}
+
+/// Wait For Interrupt
+///
+/// For more details on wfi, refer to [here](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0802a/CIHEGBBF.html).
+#[inline(always)]
+pub fn wfi() {
+ #[cfg(target_arch = "aarch64")]
+ unsafe {
+ core::arch::asm!("wfi", options(nomem, nostack))
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ unimplemented!()
+}
+
+/// Wait For Event
+///
+/// For more details of wfe - sev pair, refer to [here](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0802a/CIHEGBBF.html).
+#[inline(always)]
+pub fn wfe() {
+ #[cfg(target_arch = "aarch64")]
+ unsafe {
+ core::arch::asm!("wfe", options(nomem, nostack))
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ unimplemented!()
+}
+
+/// Send EVent.Locally
+///
+/// SEV causes an event to be signaled to the local core within a multiprocessor system.
+///
+/// For more details of wfe - sev/sevl pair, refer to [here](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0802a/CIHEGBBF.html).
+#[inline(always)]
+pub fn sevl() {
+ #[cfg(target_arch = "aarch64")]
+ unsafe {
+ core::arch::asm!("sevl", options(nomem, nostack))
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ unimplemented!()
+}
+
+/// Send EVent.
+///
+/// SEV causes an event to be signaled to all cores within a multiprocessor system.
+///
+/// For more details of wfe - sev pair, refer to [here](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0802a/CIHEGBBF.html).
+#[inline(always)]
+pub fn sev() {
+ #[cfg(target_arch = "aarch64")]
+ unsafe {
+ core::arch::asm!("sev", options(nomem, nostack))
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ unimplemented!()
+}
+
+/// Exception return
+///
+/// Will jump to wherever the corresponding link register points to, and therefore never return.
+#[inline(always)]
+pub fn eret() -> ! {
+ #[cfg(target_arch = "aarch64")]
+ unsafe {
+ core::arch::asm!("eret", options(nomem, nostack));
+ core::intrinsics::unreachable()
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ unimplemented!()
+}
+
+/// Function return
+///
+/// Will jump to wherever the corresponding link register points to, and therefore never return.
+#[inline(always)]
+pub fn ret() -> ! {
+ #[cfg(target_arch = "aarch64")]
+ unsafe {
+ core::arch::asm!("ret", options(nomem, nostack));
+ core::intrinsics::unreachable()
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ unimplemented!()
+}
diff --git a/src/asm/barrier.rs b/src/asm/barrier.rs
new file mode 100644
index 0000000..690c32f
--- /dev/null
+++ b/src/asm/barrier.rs
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Barrier functions.
+
+mod sealed {
+ pub trait Dmb {
+ unsafe fn __dmb(&self);
+ }
+
+ pub trait Dsb {
+ unsafe fn __dsb(&self);
+ }
+
+ pub trait Isb {
+ unsafe fn __isb(&self);
+ }
+}
+
+macro_rules! dmb_dsb {
+ ($A:ident) => {
+ impl sealed::Dmb for $A {
+ #[inline(always)]
+ unsafe fn __dmb(&self) {
+ match () {
+ #[cfg(target_arch = "aarch64")]
+ () => {
+ core::arch::asm!(concat!("DMB ", stringify!($A)), options(nostack))
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ () => unimplemented!(),
+ }
+ }
+ }
+ impl sealed::Dsb for $A {
+ #[inline(always)]
+ unsafe fn __dsb(&self) {
+ match () {
+ #[cfg(target_arch = "aarch64")]
+ () => {
+ core::arch::asm!(concat!("DSB ", stringify!($A)), options(nostack))
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ () => unimplemented!(),
+ }
+ }
+ }
+ };
+}
+
+pub struct SY;
+pub struct ISH;
+pub struct ISHST;
+
+dmb_dsb!(ISH);
+dmb_dsb!(ISHST);
+dmb_dsb!(SY);
+
+impl sealed::Isb for SY {
+ #[inline(always)]
+ unsafe fn __isb(&self) {
+ match () {
+ #[cfg(target_arch = "aarch64")]
+ () => {
+ core::arch::asm!("ISB SY", options(nostack))
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ () => unimplemented!(),
+ }
+ }
+}
+
+/// # Safety
+///
+/// In your own hands, this is hardware land!
+#[inline(always)]
+pub unsafe fn dmb<A>(arg: A)
+where
+ A: sealed::Dmb,
+{
+ arg.__dmb()
+}
+
+/// # Safety
+///
+/// In your own hands, this is hardware land!
+#[inline(always)]
+pub unsafe fn dsb<A>(arg: A)
+where
+ A: sealed::Dsb,
+{
+ arg.__dsb()
+}
+
+/// # Safety
+///
+/// In your own hands, this is hardware land!
+#[inline(always)]
+pub unsafe fn isb<A>(arg: A)
+where
+ A: sealed::Isb,
+{
+ arg.__isb()
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..36e13fd
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Low level access to Cortex-A processors.
+//!
+//! ## Currently Supported Execution States
+//!
+//! - [x] AArch64
+//! - [ ] AArch32
+//!
+//! ## Minimum Supported Rust Version
+//!
+//! Requires a recent nightly of Rust.
+//!
+//! ## Usage
+//!
+//! Please note that for using this crate's [register definitions](src/registers) (as provided by
+//! `cortex_a::registers::*`), you need to also include
+//! [`tock-registers`](https://crates.io/crates/tock-registers) in your project. This is because the
+//! `interface` traits provided by `tock-registers` are implemented by this crate. You should
+//! include the same version of `tock-registers` as is being used by this crate to ensure sane
+//! interoperatbility.
+//!
+//! For example, in the following snippet, `X.Y.Z` should be the same version of `tock-registers`
+//! that is mentioned in `cortex-a`'s [`Cargo.toml`](Cargo.toml).
+//!
+//! ```toml
+//! [package]
+//! name = "Your embedded project"
+//!
+//! # Some parts omitted for brevity.
+//!
+//! [dependencies]
+//! tock-registers = "X.Y.Z"
+//! cortex-a = "A.B.C" # <-- Includes tock-registers itself.
+//! ```
+//!
+//! ### Example
+//!
+//! Check out https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials for usage examples.
+//! Listed below is a snippet of `rust-raspberrypi-OS-tutorials`'s early boot code.
+//!
+//! ```rust
+//! use cortex_a::{asm, registers::*};
+//! use tock_registers::interfaces::Writeable; // <-- Trait needed to use `write()` and `set()`.
+//!
+//! // Some parts omitted for brevity.
+//!
+//! unsafe fn prepare_el2_to_el1_transition(
+//! virt_boot_core_stack_end_exclusive_addr: u64,
+//! virt_kernel_init_addr: u64,
+//! ) {
+//! // Enable timer counter registers for EL1.
+//! CNTHCTL_EL2.write(CNTHCTL_EL2::EL1PCEN::SET + CNTHCTL_EL2::EL1PCTEN::SET);
+//!
+//! // No offset for reading the counters.
+//! CNTVOFF_EL2.set(0);
+//!
+//! // Set EL1 execution state to AArch64.
+//! HCR_EL2.write(HCR_EL2::RW::EL1IsAarch64);
+//!
+//! // Set up a simulated exception return.
+//! SPSR_EL2.write(
+//! SPSR_EL2::D::Masked
+//! + SPSR_EL2::A::Masked
+//! + SPSR_EL2::I::Masked
+//! + SPSR_EL2::F::Masked
+//! + SPSR_EL2::M::EL1h,
+//! );
+//! ```
+//!
+//! ## Disclaimer
+//!
+//! Descriptive comments in the source files are taken from the [ARM Architecture Reference Manual
+//! ARMv8, for ARMv8-A architecture
+//! profile](https://static.docs.arm.com/ddi0487/ca/DDI0487C_a_armv8_arm.pdf?_ga=2.266626254.1122218691.1534883460-1326731866.1530967873).
+
+#![feature(core_intrinsics)]
+#![feature(custom_inner_attributes)]
+#![no_std]
+
+pub mod asm;
+pub mod registers;
diff --git a/src/registers.rs b/src/registers.rs
new file mode 100644
index 0000000..b805942
--- /dev/null
+++ b/src/registers.rs
@@ -0,0 +1,107 @@
+//! Processor core registers
+
+#![allow(unused_attributes)]
+#![rustfmt::skip]
+
+#[macro_use]
+mod macros;
+
+mod cntfrq_el0;
+mod cnthctl_el2;
+mod cntp_ctl_el0;
+mod cntp_tval_el0;
+mod cntpct_el0;
+mod cntv_ctl_el0;
+mod cntv_cval_el0;
+mod cntv_tval_el0;
+mod cntvct_el0;
+mod cntvoff_el2;
+mod currentel;
+mod daif;
+mod elr_el1;
+mod elr_el2;
+mod elr_el3;
+mod esr_el1;
+mod esr_el2;
+mod far_el1;
+mod far_el2;
+mod fp;
+mod hcr_el2;
+mod id_aa64mmfr0_el1;
+mod lr;
+mod mair_el1;
+mod mair_el2;
+mod midr_el1;
+mod mpidr_el1;
+mod oslar_el1;
+mod par_el1;
+mod scr_el3;
+mod sctlr_el1;
+mod sctlr_el2;
+mod sp;
+mod sp_el0;
+mod sp_el1;
+mod spsel;
+mod spsr_el1;
+mod spsr_el2;
+mod spsr_el3;
+mod tcr_el1;
+mod tcr_el2;
+mod tpidr_el0;
+mod tpidr_el1;
+mod tpidrro_el0;
+mod ttbr0_el1;
+mod ttbr0_el2;
+mod ttbr1_el1;
+mod vbar_el1;
+mod vbar_el2;
+
+pub use cntfrq_el0::CNTFRQ_EL0;
+pub use cnthctl_el2::CNTHCTL_EL2;
+pub use cntp_ctl_el0::CNTP_CTL_EL0;
+pub use cntp_tval_el0::CNTP_TVAL_EL0;
+pub use cntpct_el0::CNTPCT_EL0;
+pub use cntv_ctl_el0::CNTV_CTL_EL0;
+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 currentel::CurrentEL;
+pub use daif::DAIF;
+pub use elr_el1::ELR_EL1;
+pub use elr_el2::ELR_EL2;
+pub use elr_el3::ELR_EL3;
+pub use esr_el1::ESR_EL1;
+pub use esr_el2::ESR_EL2;
+pub use far_el1::FAR_EL1;
+pub use far_el2::FAR_EL2;
+pub use fp::FP;
+pub use hcr_el2::HCR_EL2;
+pub use id_aa64mmfr0_el1::ID_AA64MMFR0_EL1;
+pub use lr::LR;
+pub use mair_el1::MAIR_EL1;
+pub use mair_el2::MAIR_EL2;
+pub use midr_el1::MIDR_EL1;
+pub use mpidr_el1::MPIDR_EL1;
+pub use oslar_el1::OSLAR_EL1;
+pub use par_el1::PAR_EL1;
+pub use scr_el3::SCR_EL3;
+pub use sctlr_el1::SCTLR_EL1;
+pub use sctlr_el2::SCTLR_EL2;
+pub use sp::SP;
+pub use sp_el0::SP_EL0;
+pub use sp_el1::SP_EL1;
+pub use spsel::SPSel;
+pub use spsr_el1::SPSR_EL1;
+pub use spsr_el2::SPSR_EL2;
+pub use spsr_el3::SPSR_EL3;
+pub use tcr_el1::TCR_EL1;
+pub use tcr_el2::TCR_EL2;
+pub use tpidr_el0::TPIDR_EL0;
+pub use tpidr_el1::TPIDR_EL1;
+pub use tpidrro_el0::TPIDRRO_EL0;
+pub use ttbr0_el1::TTBR0_EL1;
+pub use ttbr0_el2::TTBR0_EL2;
+pub use ttbr1_el1::TTBR1_EL1;
+pub use vbar_el1::VBAR_EL1;
+pub use vbar_el2::VBAR_EL2;
diff --git a/src/registers/cntfrq_el0.rs b/src/registers/cntfrq_el0.rs
new file mode 100644
index 0000000..24c658d
--- /dev/null
+++ b/src/registers/cntfrq_el0.rs
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Counter-timer Frequency register - EL0
+//!
+//! This register is provided so that software can discover the frequency of the system counter. It
+//! must be programmed with this value as part of system initialization. The value of the register
+//! is not interpreted by hardware.
+
+use tock_registers::interfaces::Readable;
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "CNTFRQ_EL0", "x");
+}
+
+pub const CNTFRQ_EL0: Reg = Reg {};
diff --git a/src/registers/cnthctl_el2.rs b/src/registers/cnthctl_el2.rs
new file mode 100644
index 0000000..c591e3e
--- /dev/null
+++ b/src/registers/cnthctl_el2.rs
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Counter-timer Hypervisor Control register - EL2
+//!
+//! Controls the generation of an event stream from the physical counter, and
+//! access from Non-secure EL1 to the physical counter and the Non-secure EL1
+//! physical timer.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+// When HCR_EL2.E2H == 0:
+// TODO: Figure out how we can differentiate depending on HCR_EL2.E2H state
+//
+// For now, implement the HCR_EL2.E2H == 0 version
+register_bitfields! {u64,
+ pub CNTHCTL_EL2 [
+ /// Traps Non-secure EL0 and EL1 accesses to the physical timer registers to EL2.
+ ///
+ /// 0 From AArch64 state: Non-secure EL0 and EL1 accesses to the CNTP_CTL_EL0,
+ /// CNTP_CVAL_EL0, and CNTP_TVAL_EL0 are trapped to EL2, unless it is trapped by
+ /// CNTKCTL_EL1.EL0PTEN.
+ ///
+ /// From AArch32 state: Non-secure EL0 and EL1 accesses to the CNTP_CTL, CNTP_CVAL, and
+ /// CNTP_TVAL are trapped to EL2, unless it is trapped by CNTKCTL_EL1.EL0PTEN or
+ /// CNTKCTL.PL0PTEN.
+ ///
+ /// 1 This control does not cause any instructions to be trapped.
+ ///
+ /// If EL3 is implemented and EL2 is not implemented, behavior is as if this bit is 1 other
+ /// than for the purpose of a direct read.
+ EL1PCEN OFFSET(1) NUMBITS(1) [],
+
+ /// Traps Non-secure EL0 and EL1 accesses to the physical counter register to EL2.
+ ///
+ /// 0 From AArch64 state: Non-secure EL0 and EL1 accesses to the CNTPCT_EL0 are trapped to
+ /// EL2, unless it is trapped by CNTKCTL_EL1.EL0PCTEN.
+ ///
+ /// From AArch32 state: Non-secure EL0 and EL1 accesses to the CNTPCT are trapped to EL2,
+ /// unless it is trapped by CNTKCTL_EL1.EL0PCTEN or CNTKCTL.PL0PCTEN.
+ ///
+ /// 1 This control does not cause any instructions to be trapped.
+ ///
+ /// If EL3 is implemented and EL2 is not implemented, behavior is as if this bit is 1 other
+ /// than for the purpose of a direct read.
+ EL1PCTEN OFFSET(0) NUMBITS(1) []
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = CNTHCTL_EL2::Register;
+
+ sys_coproc_read_raw!(u64, "CNTHCTL_EL2", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = CNTHCTL_EL2::Register;
+
+ sys_coproc_write_raw!(u64, "CNTHCTL_EL2", "x");
+}
+
+pub const CNTHCTL_EL2: Reg = Reg {};
diff --git a/src/registers/cntp_ctl_el0.rs b/src/registers/cntp_ctl_el0.rs
new file mode 100644
index 0000000..50ee701
--- /dev/null
+++ b/src/registers/cntp_ctl_el0.rs
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Counter-timer Physical Timer Control register - EL0
+//!
+//! Control register for the EL1 physical timer.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub CNTP_CTL_EL0 [
+ /// The status of the timer. This bit indicates whether the timer condition is met:
+ ///
+ /// 0 Timer condition is not met.
+ /// 1 Timer condition is met.
+ ///
+ /// When the value of the ENABLE bit is 1, ISTATUS indicates whether the timer condition is
+ /// met. ISTATUS takes no account of the value of the IMASK bit. If the value of ISTATUS is
+ /// 1 and the value of IMASK is 0 then the timer interrupt is asserted.
+ ///
+ /// When the value of the ENABLE bit is 0, the ISTATUS field is UNKNOWN.
+ ///
+ /// This bit is read-only.
+ ISTATUS OFFSET(2) NUMBITS(1) [],
+
+ /// Timer interrupt mask bit. Permitted values are:
+ ///
+ /// 0 Timer interrupt is not masked by the IMASK bit.
+ /// 1 Timer interrupt is masked by the IMASK bit.
+ IMASK OFFSET(1) NUMBITS(1) [],
+
+ /// Enables the timer. Permitted values are:
+ ///
+ /// 0 Timer disabled.
+ /// 1 Timer enabled.
+ ENABLE OFFSET(0) NUMBITS(1) []
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = CNTP_CTL_EL0::Register;
+
+ sys_coproc_read_raw!(u64, "CNTP_CTL_EL0", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = CNTP_CTL_EL0::Register;
+
+ sys_coproc_write_raw!(u64, "CNTP_CTL_EL0", "x");
+}
+
+pub const CNTP_CTL_EL0: Reg = Reg {};
diff --git a/src/registers/cntp_tval_el0.rs b/src/registers/cntp_tval_el0.rs
new file mode 100644
index 0000000..e28a4a0
--- /dev/null
+++ b/src/registers/cntp_tval_el0.rs
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Counter-timer Physical Timer TimerValue register - EL0
+//!
+//! Holds the timer value for the EL1 physical timer.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "CNTP_TVAL_EL0", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "CNTP_TVAL_EL0", "x");
+}
+
+pub const CNTP_TVAL_EL0: Reg = Reg {};
diff --git a/src/registers/cntpct_el0.rs b/src/registers/cntpct_el0.rs
new file mode 100644
index 0000000..95e917b
--- /dev/null
+++ b/src/registers/cntpct_el0.rs
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Counter-timer Physical Count register - EL0
+//!
+//! Holds the 64-bit physical count value.
+
+use tock_registers::interfaces::Readable;
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "CNTPCT_EL0", "x");
+}
+
+pub const CNTPCT_EL0: Reg = Reg {};
diff --git a/src/registers/cntv_ctl_el0.rs b/src/registers/cntv_ctl_el0.rs
new file mode 100644
index 0000000..75f7c3e
--- /dev/null
+++ b/src/registers/cntv_ctl_el0.rs
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Gregor Reitzenstein <me@dequbed.space>
+
+//! Counter-timer Virtual Timer Control register - EL0
+//!
+//! Control register for the virtual timer
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub CNTV_CTL_EL0 [
+ /// The status of the timer. This bit indicates whether the timer condition is met:
+ ///
+ /// 0 Timer condition is not met.
+ /// 1 Timer condition is met.
+ ///
+ /// When the value of the ENABLE bit is 1, ISTATUS indicates whether the timer condition is
+ /// met. ISTATUS takes no account of the value of the IMASK bit. If the value of ISTATUS is
+ /// 1 and the value of IMASK is 0 then the timer interrupt is asserted.
+ ///
+ /// When the value of the ENABLE bit is 0, the ISTATUS field is UNKNOWN.
+ ///
+ /// This bit is read-only.
+ ISTATUS OFFSET(2) NUMBITS(1) [],
+
+ /// Timer interrupt mask bit. Permitted values are:
+ ///
+ /// 0 Timer interrupt is not masked by the IMASK bit.
+ /// 1 Timer interrupt is masked by the IMASK bit.
+ IMASK OFFSET(1) NUMBITS(1) [],
+
+ /// Enables the timer. Permitted values are:
+ ///
+ /// 0 Timer disabled.
+ /// 1 Timer enabled.
+ ///
+ /// Setting this bit to 0 disables the timer output signal but the timer value accessible
+ /// from `CNTV_TVAL_EL0` continues to count down.
+ ///
+ /// Disabling the output signal might be a power-saving option
+ ENABLE OFFSET(0) NUMBITS(1) []
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = CNTV_CTL_EL0::Register;
+
+ sys_coproc_read_raw!(u64, "CNTV_CTL_EL0", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = CNTV_CTL_EL0::Register;
+
+ sys_coproc_write_raw!(u64, "CNTV_CTL_EL0", "x");
+}
+
+pub const CNTV_CTL_EL0: Reg = Reg {};
diff --git a/src/registers/cntv_cval_el0.rs b/src/registers/cntv_cval_el0.rs
new file mode 100644
index 0000000..cb46074
--- /dev/null
+++ b/src/registers/cntv_cval_el0.rs
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Javier Alvarez <javier.alvarez@allthingsembedded.net>
+
+//! Counter-timer Virtual Timer CompareValue register - EL0
+//!
+//! Holds the compare value for the virtual timer.
+//!
+//! When CNTV_CTL_EL0.ENABLE is 1, the timer condition is met when (CNTVCT_EL0 - CompareValue) is
+//! greater than or equal to zero. This means that CompareValue acts like a 64-bit upcounter timer.
+//!
+//! When the timer condition is met:
+//! - CNTV_CTL_EL0.ISTATUS is set to 1.
+//! - If CNTV_CTL_EL0.IMASK is 0, an interrupt is generated.
+//!
+//! When CNTV_CTL_EL0.ENABLE is 0, the timer condition is not met, but CNTVCT_EL0 continues to
+//! count.
+//!
+//! If the Generic counter is implemented at a size less than 64 bits, then this field is permitted
+//! to be implemented at the same width as the counter, and the upper bits are RES0.
+//!
+//! The value of this field is treated as zero-extended in all counter calculations.
+//!
+//! The reset behaviour of this field is:
+//! - On a Warm reset, this field resets to an architecturally UNKNOWN value.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "CNTV_CVAL_EL0", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "CNTV_CVAL_EL0", "x");
+}
+
+pub const CNTV_CVAL_EL0: Reg = Reg {};
diff --git a/src/registers/cntv_tval_el0.rs b/src/registers/cntv_tval_el0.rs
new file mode 100644
index 0000000..e90e70b
--- /dev/null
+++ b/src/registers/cntv_tval_el0.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Gregor Reitzenstein <me@dequbed.space>
+
+//! Counter-timer Virtual Timer TimerValue register - EL0
+//!
+//! Holds the timer value for the EL1 virtual timer.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "CNTV_TVAL_EL0", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "CNTV_TVAL_EL0", "x");
+}
+
+pub const CNTV_TVAL_EL0: Reg = Reg {};
diff --git a/src/registers/cntvct_el0.rs b/src/registers/cntvct_el0.rs
new file mode 100644
index 0000000..c541aac
--- /dev/null
+++ b/src/registers/cntvct_el0.rs
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Gregor Reitzenstein <me@dequbed.space>
+
+//! Counter-timer Virtual Count register - EL0
+//!
+//! Holds the 64-bit virtual count value. The virtual count value is equal to the physical count
+//! value in `CNTPCT_EL0` minus the virtual offset visible in `CNTVOFF_EL2`
+
+use tock_registers::interfaces::Readable;
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "CNTVCT_EL0", "x");
+}
+
+pub const CNTVCT_EL0: Reg = Reg {};
diff --git a/src/registers/cntvoff_el2.rs b/src/registers/cntvoff_el2.rs
new file mode 100644
index 0000000..d944055
--- /dev/null
+++ b/src/registers/cntvoff_el2.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Counter-timer Virtual Offset register - EL2
+//!
+//! Holds the 64-bit virtual offset. This is the offset between the physical count value visible in
+//! CNTPCT_EL0 and the virtual count value visible in CNTVCT_EL0.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "CNTVOFF_EL2", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "CNTVOFF_EL2", "x");
+}
+
+pub const CNTVOFF_EL2: Reg = Reg {};
diff --git a/src/registers/currentel.rs b/src/registers/currentel.rs
new file mode 100644
index 0000000..cafee3e
--- /dev/null
+++ b/src/registers/currentel.rs
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Current Exception Level
+//!
+//! Holds the current Exception level.
+
+use tock_registers::{interfaces::Readable, register_bitfields};
+
+register_bitfields! {u64,
+ pub CurrentEL [
+ /// Current Exception level. Possible values of this field are:
+ ///
+ /// 00 EL0
+ /// 01 EL1
+ /// 10 EL2
+ /// 11 EL3
+ ///
+ /// When the HCR_EL2.NV bit is 1, Non-secure EL1 read accesses to the CurrentEL register
+ /// return the value of 0x2 in this field.
+ ///
+ /// This field resets to a value that is architecturally UNKNOWN.
+ EL OFFSET(2) NUMBITS(2) [
+ EL0 = 0,
+ EL1 = 1,
+ EL2 = 2,
+ EL3 = 3
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = CurrentEL::Register;
+
+ sys_coproc_read_raw!(u64, "CurrentEL", "x");
+}
+
+#[allow(non_upper_case_globals)]
+pub const CurrentEL: Reg = Reg {};
diff --git a/src/registers/daif.rs b/src/registers/daif.rs
new file mode 100644
index 0000000..2cabdaa
--- /dev/null
+++ b/src/registers/daif.rs
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Interrupt Mask Bits
+//!
+//! Allows access to the interrupt mask bits.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub DAIF [
+ /// Process state D mask. The possible values of this bit are:
+ ///
+ /// 0 Watchpoint, Breakpoint, and Software Step exceptions targeted at the current Exception
+ /// level are not masked.
+ ///
+ /// 1 Watchpoint, Breakpoint, and Software Step exceptions targeted at the current Exception
+ /// level are masked.
+ ///
+ /// When the target Exception level of the debug exception is higher than the current
+ /// Exception level, the exception is not masked by this bit.
+ ///
+ /// When this register has an architecturally-defined reset value, this field resets to 1.
+ D OFFSET(9) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// SError interrupt mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ ///
+ /// When this register has an architecturally-defined reset value, this field resets to 1.
+ A OFFSET(8) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// IRQ mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ ///
+ /// When this register has an architecturally-defined reset value, this field resets to 1.
+ I OFFSET(7) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// FIQ mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ ///
+ /// When this register has an architecturally-defined reset value, this field resets to 1.
+ F OFFSET(6) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = DAIF::Register;
+
+ sys_coproc_read_raw!(u64, "DAIF", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = DAIF::Register;
+
+ sys_coproc_write_raw!(u64, "DAIF", "x");
+}
+
+pub const DAIF: Reg = Reg {};
diff --git a/src/registers/elr_el1.rs b/src/registers/elr_el1.rs
new file mode 100644
index 0000000..9d094cb
--- /dev/null
+++ b/src/registers/elr_el1.rs
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Exception Link Register - EL1
+//!
+//! When taking an exception to EL1, holds the address to return to.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "ELR_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "ELR_EL1", "x");
+}
+
+pub const ELR_EL1: Reg = Reg {};
diff --git a/src/registers/elr_el2.rs b/src/registers/elr_el2.rs
new file mode 100644
index 0000000..062a513
--- /dev/null
+++ b/src/registers/elr_el2.rs
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Exception Link Register - EL2
+//!
+//! When taking an exception to EL2, holds the address to return to.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "ELR_EL2", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "ELR_EL2", "x");
+}
+
+pub const ELR_EL2: Reg = Reg {};
diff --git a/src/registers/elr_el3.rs b/src/registers/elr_el3.rs
new file mode 100644
index 0000000..911e9b2
--- /dev/null
+++ b/src/registers/elr_el3.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Berkus Decker <berkus+github@metta.systems>
+
+//! Exception Link Register - EL3
+//!
+//! When taking an exception to EL3, holds the address to return to.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "ELR_EL3", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "ELR_EL3", "x");
+}
+
+pub const ELR_EL3: Reg = Reg {};
diff --git a/src/registers/esr_el1.rs b/src/registers/esr_el1.rs
new file mode 100644
index 0000000..0cad468
--- /dev/null
+++ b/src/registers/esr_el1.rs
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Berkus Decker <berkus+github@metta.systems>
+
+//! Exception Syndrome Register - EL1
+//!
+//! Holds syndrome information for an exception taken to EL1.
+
+use tock_registers::{interfaces::Readable, register_bitfields};
+
+register_bitfields! {u64,
+ pub ESR_EL1 [
+ /// Exception Class. Indicates the reason for the exception that this register holds
+ /// information about.
+ ///
+ /// For each EC value, the table references a subsection that gives information about:
+ /// - The cause of the exception, for example the configuration required to enable the
+ /// trap.
+ /// - The encoding of the associated ISS.
+ ///
+ /// Incomplete listing - to be done.
+ EC OFFSET(26) NUMBITS(6) [
+ Unknown = 0b00_0000,
+ TrappedWFIorWFE = 0b00_0001,
+ TrappedMCRorMRC = 0b00_0011, // A32
+ TrappedMCRRorMRRC = 0b00_0100, // A32
+ TrappedMCRorMRC2 = 0b00_0101, // A32
+ TrappedLDCorSTC = 0b00_0110, // A32
+ TrappedFP = 0b00_0111,
+ TrappedMRRC = 0b00_1100, // A32
+ BranchTarget = 0b00_1101,
+ IllegalExecutionState = 0b00_1110,
+ SVC32 = 0b01_0001, // A32
+ SVC64 = 0b01_0101,
+ HVC64 = 0b01_0110,
+ SMC64 = 0b01_0111,
+ TrappedMsrMrs = 0b01_1000,
+ TrappedSve = 0b01_1001,
+ PointerAuth = 0b01_1100,
+ InstrAbortLowerEL = 0b10_0000,
+ InstrAbortCurrentEL = 0b10_0001,
+ PCAlignmentFault = 0b10_0010,
+ DataAbortLowerEL = 0b10_0100,
+ DataAbortCurrentEL = 0b10_0101,
+ SPAlignmentFault = 0b10_0110,
+ TrappedFP32 = 0b10_1000, // A32
+ TrappedFP64 = 0b10_1100,
+ SError = 0b10_1111,
+ BreakpointLowerEL = 0b11_0000,
+ BreakpointCurrentEL = 0b11_0001,
+ SoftwareStepLowerEL = 0b11_0010,
+ SoftwareStepCurrentEL = 0b11_0011,
+ WatchpointLowerEL = 0b11_0100,
+ WatchpointCurrentEL = 0b11_0101,
+ Bkpt32 = 0b11_1000, // A32 BKTP instruction
+ Brk64 = 0b11_1100 // A64 BRK instruction
+ ],
+
+ /// Instruction Length for synchronous exceptions.
+ IL OFFSET(25) NUMBITS(1) [],
+
+ /// Instruction Specific Syndrome. Architecturally, this field can be defined independently
+ /// for each defined Exception class. However, in practice, some ISS encodings are used for
+ /// more than one Exception class.
+ ISS OFFSET(0) NUMBITS(25) []
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ESR_EL1::Register;
+
+ sys_coproc_read_raw!(u64, "ESR_EL1", "x");
+}
+
+pub const ESR_EL1: Reg = Reg {};
diff --git a/src/registers/esr_el2.rs b/src/registers/esr_el2.rs
new file mode 100644
index 0000000..af9f27e
--- /dev/null
+++ b/src/registers/esr_el2.rs
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Berkus Decker <berkus+github@metta.systems>
+// - Bradley Landherr <landhb@users.noreply.github.com>
+
+//! Exception Syndrome Register - EL2
+//!
+//! Holds syndrome information for an exception taken to EL2.
+
+use tock_registers::{interfaces::Readable, register_bitfields};
+
+register_bitfields! {u64,
+ pub ESR_EL2 [
+
+ /// Reserved
+ RES0 OFFSET(37) NUMBITS(27) [],
+
+ /// Instruction Specific Syndrome 2. If a memory access generated by an ST64BV or ST64BV0
+ /// instruction generates a Data Abort for a Translation fault, Access flag fault, or
+ /// Permission fault, then this field holds register specifier, Xs.
+ ///
+ /// For any other Data Abort, this field is RES0.
+ ISS2 OFFSET(32) NUMBITS(5) [],
+
+ /// Exception Class. Indicates the reason for the exception that this register holds
+ /// information about.
+ ///
+ /// For each EC value, the table references a subsection that gives information about:
+ /// - The cause of the exception, for example the configuration required to enable the
+ /// trap.
+ /// - The encoding of the associated ISS.
+ ///
+ /// Incomplete listing - to be done.
+ EC OFFSET(26) NUMBITS(6) [
+ Unknown = 0b00_0000,
+ TrappedWFIorWFE = 0b00_0001,
+ TrappedMCRorMRC = 0b00_0011, // A32
+ TrappedMCRRorMRRC = 0b00_0100, // A32
+ TrappedMCRorMRC2 = 0b00_0101, // A32
+ TrappedLDCorSTC = 0b00_0110, // A32
+ TrappedFP = 0b00_0111,
+ TrappedMRRC = 0b00_1100, // A32
+ BranchTarget = 0b00_1101,
+ IllegalExecutionState = 0b00_1110,
+ SVC32 = 0b01_0001, // A32
+ SVC64 = 0b01_0101,
+ HVC64 = 0b01_0110,
+ SMC64 = 0b01_0111,
+ TrappedMsrMrs = 0b01_1000,
+ TrappedSve = 0b01_1001,
+ PointerAuth = 0b01_1100,
+ InstrAbortLowerEL = 0b10_0000,
+ InstrAbortCurrentEL = 0b10_0001,
+ PCAlignmentFault = 0b10_0010,
+ DataAbortLowerEL = 0b10_0100,
+ DataAbortCurrentEL = 0b10_0101,
+ SPAlignmentFault = 0b10_0110,
+ TrappedFP32 = 0b10_1000, // A32
+ TrappedFP64 = 0b10_1100,
+ SError = 0b10_1111,
+ BreakpointLowerEL = 0b11_0000,
+ BreakpointCurrentEL = 0b11_0001,
+ SoftwareStepLowerEL = 0b11_0010,
+ SoftwareStepCurrentEL = 0b11_0011,
+ WatchpointLowerEL = 0b11_0100,
+ WatchpointCurrentEL = 0b11_0101,
+ Bkpt32 = 0b11_1000, // A32 BKTP instruction
+ Brk64 = 0b11_1100 // A64 BRK instruction
+ ],
+
+ /// Instruction Length for synchronous exceptions.
+ IL OFFSET(25) NUMBITS(1) [],
+
+ /// Instruction Specific Syndrome. Architecturally, this field can be defined independently
+ /// for each defined Exception class. However, in practice, some ISS encodings are used for
+ /// more than one Exception class.
+ ISS OFFSET(0) NUMBITS(25) []
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ESR_EL2::Register;
+
+ sys_coproc_read_raw!(u64, "ESR_EL2", "x");
+}
+
+pub const ESR_EL2: Reg = Reg {};
diff --git a/src/registers/far_el1.rs b/src/registers/far_el1.rs
new file mode 100644
index 0000000..2bd77d1
--- /dev/null
+++ b/src/registers/far_el1.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Fault Address Register - EL1
+//!
+//! Holds the faulting Virtual Address for all synchronous Instruction or Data Abort, PC alignment
+//! fault and Watchpoint exceptions that are taken to EL1.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "FAR_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "FAR_EL1", "x");
+}
+
+pub const FAR_EL1: Reg = Reg {};
diff --git a/src/registers/far_el2.rs b/src/registers/far_el2.rs
new file mode 100644
index 0000000..0dcfa8a
--- /dev/null
+++ b/src/registers/far_el2.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Fault Address Register - EL2
+//!
+//! Holds the faulting Virtual Address for all synchronous Instruction or Data Abort, PC alignment
+//! fault and Watchpoint exceptions that are taken to EL2.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "FAR_EL2", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "FAR_EL2", "x");
+}
+
+pub const FAR_EL2: Reg = Reg {};
diff --git a/src/registers/fp.rs b/src/registers/fp.rs
new file mode 100644
index 0000000..76169ea
--- /dev/null
+++ b/src/registers/fp.rs
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! The frame pointer register
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ read_raw!(u64, "x29", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ write_raw!(u64, "x29", "x");
+}
+
+pub const FP: Reg = Reg {};
diff --git a/src/registers/hcr_el2.rs b/src/registers/hcr_el2.rs
new file mode 100644
index 0000000..877ee30
--- /dev/null
+++ b/src/registers/hcr_el2.rs
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Bradley Landherr <landhb@users.noreply.github.com>
+// - Javier Alvarez <javier.alvarez@allthingsembedded.com>
+
+//! Hypervisor Configuration Register - EL2
+//!
+//! Provides configuration controls for virtualization, including defining
+//! whether various Non-secure operations are trapped to EL2.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub HCR_EL2 [
+ /// Controls the use of instructions related to Pointer Authentication:
+ ///
+ /// - In EL0, when HCR_EL2.TGE==0 or HCR_EL2.E2H==0, and the associated SCTLR_EL1.En<N><M>==1.
+ /// - In EL1, the associated SCTLR_EL1.En<N><M>==1.
+ ///
+ /// Traps are reported using EC syndrome value 0x09. The Pointer Authentication instructions
+ /// trapped are:
+ ///
+ /// AUTDA, AUTDB, AUTDZA, AUTDZB, AUTIA, AUTIA1716, AUTIASP, AUTIAZ, AUTIB, AUTIB1716,
+ /// AUTIBSP, AUTIBZ, AUTIZA, AUTIZB, PACGA, PACDA, PACDB, PACDZA, PACDZB, PACIA,
+ /// PACIA1716, PACIASP, PACIAZ, PACIB, PACIB1716, PACIBSP, PACIBZ, PACIZA, PACIZB.
+ /// RETAA, RETAB, BRAA, BRAB, BLRAA, BLRAB, BRAAZ, BRABZ, BLRAAZ, BLRABZ.
+ /// ERETAA, ERETAB, LDRAA, and LDRAB.
+ API OFFSET(41) NUMBITS(1) [
+ EnableTrapPointerAuthInstToEl2 = 0,
+ DisableTrapPointerAuthInstToEl2 = 1
+ ],
+
+ /// Trap registers holding "key" values for Pointer Authentication. Traps accesses to the
+ /// following registers from EL1 to EL2, when EL2 is enabled in the current Security state,
+ /// reported using EC syndrome value 0x18:
+ ///
+ /// APIAKeyLo_EL1, APIAKeyHi_EL1, APIBKeyLo_EL1, APIBKeyHi_EL1, APDAKeyLo_EL1,
+ /// APDAKeyHi_EL1, APDBKeyLo_EL1, APDBKeyHi_EL1, APGAKeyLo_EL1, and APGAKeyHi_EL1.
+ APK OFFSET(40) NUMBITS(1) [
+ EnableTrapPointerAuthKeyRegsToEl2 = 0,
+ DisableTrapPointerAuthKeyRegsToEl2 = 1,
+ ],
+
+ /// Route synchronous External abort exceptions to EL2.
+ /// if 0: This control does not cause exceptions to be routed from EL0 and EL1 to EL2.
+ /// if 1: Route synchronous External abort exceptions from EL0 and EL1 to EL2, when EL2 is
+ /// enabled in the current Security state, if not routed to EL3.
+ TEA OFFSET(37) NUMBITS(1) [
+ DisableTrapSyncExtAbortsToEl2 = 0,
+ EnableTrapSyncExtAbortsToEl2 = 1,
+ ],
+
+ /// EL2 Host. Enables a configuration where a Host Operating System is running in EL2, and
+ /// the Host Operating System's applications are running in EL0.
+ E2H OFFSET(34) NUMBITS(1) [
+ DisableOsAtEl2 = 0,
+ EnableOsAtEl2 = 1
+ ],
+
+ /// Execution state control for lower Exception levels:
+ ///
+ /// 0 Lower levels are all AArch32.
+ /// 1 The Execution state for EL1 is AArch64. The Execution state for EL0 is determined by
+ /// the current value of PSTATE.nRW when executing at EL0.
+ ///
+ /// If all lower Exception levels cannot use AArch32 then this bit is RAO/WI.
+ ///
+ /// In an implementation that includes EL3, when SCR_EL3.NS==0, the PE behaves as if this
+ /// bit has the same value as the SCR_EL3.RW bit for all purposes other than a direct read
+ /// or write access of HCR_EL2.
+ ///
+ /// The RW bit is permitted to be cached in a TLB.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this
+ /// field behaves as 1 for all purposes other than a direct read of the value of this bit.
+ RW OFFSET(31) NUMBITS(1) [
+ AllLowerELsAreAarch32 = 0,
+ EL1IsAarch64 = 1
+ ],
+
+ /// Trap General Exceptions, from EL0.
+ ///
+ /// If enabled:
+ /// - When EL2 is not enabled in the current Security state, this control has no effect on
+ /// execution at EL0.
+ ///
+ /// - When EL2 is enabled in the current Security state, in all cases:
+ ///
+ /// - All exceptions that would be routed to EL1 are routed to EL2.
+ /// - If EL1 is using AArch64, the SCTLR_EL1.M field is treated as being 0 for all
+ /// purposes other than returning the result of a direct read of SCTLR_EL1.
+ /// - If EL1 is using AArch32, the SCTLR.M field is treated as being 0 for all
+ /// purposes other than returning the result of a direct read of SCTLR.
+ /// - All virtual interrupts are disabled.
+ /// - Any IMPLEMENTATION DEFINED mechanisms for signaling virtual interrupts are
+ /// disabled.
+ /// - An exception return to EL1 is treated as an illegal exception return.
+ /// - The MDCR_EL2.{TDRA, TDOSA, TDA, TDE} fields are treated as being 1 for all
+ /// purposes other than returning the result of a direct read of MDCR_EL2.
+ ///
+ /// - In addition, when EL2 is enabled in the current Security state, if:
+ ///
+ /// - HCR_EL2.E2H is 0, the Effective values of the HCR_EL2.{FMO, IMO, AMO} fields
+ /// are 1.
+ /// - HCR_EL2.E2H is 1, the Effective values of the HCR_EL2.{FMO, IMO, AMO} fields
+ /// are 0.
+ ///
+ /// - For further information on the behavior of this bit when E2H is 1, see 'Behavior of
+ /// HCR_EL2.E2H'.
+ TGE OFFSET(27) NUMBITS(1) [
+ DisableTrapGeneralExceptionsToEl2 = 0,
+ EnableTrapGeneralExceptionsToEl2 = 1,
+ ],
+
+ /// Default Cacheability.
+ ///
+ /// 0 This control has no effect on the Non-secure EL1&0 translation regime.
+ ///
+ /// 1 In Non-secure state:
+ /// - When EL1 is using AArch64, the PE behaves as if the value of the SCTLR_EL1.M field
+ /// is 0 for all purposes other than returning the value of a direct read of SCTLR_EL1.
+ ///
+ /// - When EL1 is using AArch32, the PE behaves as if the value of the SCTLR.M field is 0
+ /// for all purposes other than returning the value of a direct read of SCTLR.
+ ///
+ /// - The PE behaves as if the value of the HCR_EL2.VM field is 1 for all purposes other
+ /// than returning the value of a direct read of HCR_EL2.
+ ///
+ /// - The memory type produced by stage 1 of the EL1&0 translation regime is Normal
+ /// Non-Shareable, Inner Write-Back Read-Allocate Write-Allocate, Outer Write-Back
+ /// Read-Allocate Write-Allocate.
+ ///
+ /// This field has no effect on the EL2, EL2&0, and EL3 translation regimes.
+ ///
+ /// This field is permitted to be cached in a TLB.
+ ///
+ /// In an implementation that includes EL3, when the value of SCR_EL3.NS is 0 the PE behaves
+ /// as if this field is 0 for all purposes other than a direct read or write access of
+ /// HCR_EL2.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this
+ /// field behaves as 0 for all purposes other than a direct read of the value of this field.
+ DC OFFSET(12) NUMBITS(1) [],
+
+ /// Physical SError interrupt routing.
+ /// - If bit is 1 when executing at any Exception level, and EL2 is enabled in the current
+ /// Security state:
+ /// - Physical SError interrupts are taken to EL2, unless they are routed to EL3.
+ /// - When the value of HCR_EL2.TGE is 0, then virtual SError interrupts are enabled.
+ AMO OFFSET(5) NUMBITS(1) [],
+
+ /// Physical IRQ Routing.
+ ///
+ /// If this bit is 0:
+ /// - When executing at Exception levels below EL2, and EL2 is enabled in the current
+ /// Security state:
+ /// - When the value of HCR_EL2.TGE is 0, Physical IRQ interrupts are not taken to EL2.
+ /// - When the value of HCR_EL2.TGE is 1, Physical IRQ interrupts are taken to EL2
+ /// unless they are routed to EL3.
+ /// - Virtual IRQ interrupts are disabled.
+ ///
+ /// If this bit is 1:
+ /// - When executing at any Exception level, and EL2 is enabled in the current Security
+ /// state:
+ /// - Physical IRQ interrupts are taken to EL2, unless they are routed to EL3.
+ /// - When the value of HCR_EL2.TGE is 0, then Virtual IRQ interrupts are enabled.
+ ///
+ /// If EL2 is enabled in the current Security state, and the value of HCR_EL2.TGE is 1:
+ /// - Regardless of the value of the IMO bit, physical IRQ Interrupts target EL2 unless
+ /// they are routed to EL3.
+ /// - When FEAT_VHE is not implemented, or if HCR_EL2.E2H is 0, this field behaves as 1
+ /// for all purposes other than a direct read of the value of this bit.
+ /// - When FEAT_VHE is implemented and HCR_EL2.E2H is 1, this field behaves as 0 for all
+ /// purposes other than a direct read of the value of this bit.
+ ///
+ /// For more information, see 'Asynchronous exception routing'.
+ IMO OFFSET(4) NUMBITS(1) [
+ DisableVirtualIRQ = 0,
+ EnableVirtualIRQ = 1,
+ ],
+
+ /// Physical FIQ Routing.
+ /// If this bit is 0:
+ /// - When executing at Exception levels below EL2, and EL2 is enabled in the current
+ /// Security state:
+ /// - When the value of HCR_EL2.TGE is 0, Physical FIQ interrupts are not taken to EL2.
+ /// - When the value of HCR_EL2.TGE is 1, Physical FIQ interrupts are taken to EL2
+ /// unless they are routed to EL3.
+ /// - Virtual FIQ interrupts are disabled.
+ ///
+ /// If this bit is 1:
+ /// - When executing at any Exception level, and EL2 is enabled in the current Security
+ /// state:
+ /// - Physical FIQ interrupts are taken to EL2, unless they are routed to EL3.
+ /// - When HCR_EL2.TGE is 0, then Virtual FIQ interrupts are enabled.
+ ///
+ /// If EL2 is enabled in the current Security state and the value of HCR_EL2.TGE is 1:
+ /// - Regardless of the value of the FMO bit, physical FIQ Interrupts target EL2 unless
+ /// they are routed to EL3.
+ /// - When FEAT_VHE is not implemented, or if HCR_EL2.E2H is 0, this field behaves as 1
+ /// for all purposes other than a direct read of the value of this bit.
+ /// - When FEAT_VHE is implemented and HCR_EL2.E2H is 1, this field behaves as 0 for all
+ /// purposes other than a direct read of the value of this bit.
+ ///
+ /// For more information, see 'Asynchronous exception routing'.
+ FMO OFFSET(3) NUMBITS(1) [
+ DisableVirtualFIQ = 0,
+ EnableVirtualFIQ = 1,
+ ],
+
+ /// Set/Way Invalidation Override. Causes Non-secure EL1 execution of the data cache
+ /// invalidate by set/way instructions to perform a data cache clean and invalidate by
+ /// set/way:
+ ///
+ /// 0 This control has no effect on the operation of data cache invalidate by set/way
+ /// instructions.
+ ///
+ /// 1 Data cache invalidate by set/way instructions perform a data cache clean and
+ /// invalidate by set/way.
+ ///
+ /// When the value of this bit is 1:
+ ///
+ /// AArch32: DCISW performs the same invalidation as a DCCISW instruction.
+ ///
+ /// AArch64: DC ISW performs the same invalidation as a DC CISW instruction.
+ ///
+ /// This bit can be implemented as RES 1.
+ ///
+ /// In an implementation that includes EL3, when the value of SCR_EL3.NS is 0 the PE behaves
+ /// as if this field is 0 for all purposes other than a direct read or write access of
+ /// HCR_EL2.
+ ///
+ /// When HCR_EL2.TGE is 1, the PE ignores the value of this field for all purposes other
+ /// than a direct read of this field.
+ SWIO OFFSET(1) NUMBITS(1) [],
+
+ /// Virtualization enable. Enables stage 2 address translation for the EL1&0 translation regime,
+ /// when EL2 is enabled in the current Security state. The possible values are:
+ ///
+ /// 0 EL1&0 stage 2 address translation disabled.
+ /// 1 EL1&0 stage 2 address translation enabled.
+ ///
+ /// When the value of this bit is 1, data cache invalidate instructions executed at EL1 perform
+ /// a data cache clean and invalidate. For the invalidate by set/way instruction this behavior
+ /// applies regardless of the value of the HCR_EL2.SWIO bit.
+ ///
+ /// This bit is permitted to be cached in a TLB.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this
+ /// field behaves as 0 for all purposes other than a direct read of the value of this field.
+ VM OFFSET(0) NUMBITS(1) [
+ Disable = 0,
+ Enable = 1
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = HCR_EL2::Register;
+
+ sys_coproc_read_raw!(u64, "HCR_EL2", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = HCR_EL2::Register;
+
+ sys_coproc_write_raw!(u64, "HCR_EL2", "x");
+}
+
+pub const HCR_EL2: Reg = Reg {};
diff --git a/src/registers/id_aa64mmfr0_el1.rs b/src/registers/id_aa64mmfr0_el1.rs
new file mode 100644
index 0000000..933a6ec
--- /dev/null
+++ b/src/registers/id_aa64mmfr0_el1.rs
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! AArch64 Memory Model Feature Register 0 - 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_AA64MMFR0_EL1 [
+ /// Support for 4KiB memory translation granule size. Defined values are:
+ ///
+ /// 0000 4KiB granule supported.
+ /// 1111 4KiB granule not supported.
+ ///
+ /// All other values are reserved.
+ TGran4 OFFSET(28) NUMBITS(4) [
+ Supported = 0b0000,
+ NotSupported = 0b1111
+ ],
+
+ /// Support for 64KiB memory translation granule size. Defined values are:
+ ///
+ /// 0000 64KiB granule supported.
+ /// 1111 64KiB granule not supported.
+ ///
+ /// All other values are reserved.
+ TGran64 OFFSET(24) NUMBITS(4) [
+ Supported = 0b0000,
+ NotSupported = 0b1111
+ ],
+
+ /// Support for 16KiB memory translation granule size. Defined values are:
+ ///
+ /// 0001 16KiB granule supported.
+ /// 0000 16KiB granule not supported.
+ ///
+ /// All other values are reserved.
+ TGran16 OFFSET(20) NUMBITS(4) [
+ Supported = 0b0001,
+ NotSupported = 0b0000
+ ],
+
+ /// Number of bits supported in the ASID:
+ ///
+ /// 0000 ASIDs are 8 bits.
+ /// 0010 ASIDs are 16 bits.
+ ///
+ /// All other values are reserved.
+ ASIDBits OFFSET(4) NUMBITS(4) [
+ Bits_8 = 0b0000,
+ Bits_16 = 0b0010
+ ],
+
+ /// Physical Address range supported. Defined values are:
+ ///
+ /// 0000 32 bits, 4GiB.
+ /// 0001 36 bits, 64GiB.
+ /// 0010 40 bits, 1TiB.
+ /// 0011 42 bits, 4TiB.
+ /// 0100 44 bits, 16TiB.
+ /// 0101 48 bits, 256TiB.
+ /// 0110 52 bits, 4PiB.
+ ///
+ /// All other values are reserved.
+ ///
+ /// The value 0110 is permitted only if the implementation includes ARMv8.2-LPA, otherwise
+ /// it is reserved.
+ PARange OFFSET(0) NUMBITS(4) [
+ Bits_32 = 0b0000,
+ Bits_36 = 0b0001,
+ Bits_40 = 0b0010,
+ Bits_42 = 0b0011,
+ Bits_44 = 0b0100,
+ Bits_48 = 0b0101,
+ Bits_52 = 0b0110
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ID_AA64MMFR0_EL1::Register;
+
+ sys_coproc_read_raw!(u64, "ID_AA64MMFR0_EL1", "x");
+}
+
+pub const ID_AA64MMFR0_EL1: Reg = Reg {};
diff --git a/src/registers/lr.rs b/src/registers/lr.rs
new file mode 100644
index 0000000..78b8795
--- /dev/null
+++ b/src/registers/lr.rs
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Alban Seurat <alban.seurat@me.com>
+
+//! The link register
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ read_raw!(u64, "lr", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ write_raw!(u64, "lr", "x");
+}
+
+pub const LR: Reg = Reg {};
diff --git a/src/registers/macros.rs b/src/registers/macros.rs
new file mode 100644
index 0000000..536670d
--- /dev/null
+++ b/src/registers/macros.rs
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+macro_rules! __read_raw {
+ ($width:ty, $asm_instr:tt, $asm_reg_name:tt, $asm_width:tt) => {
+ /// Reads the raw bits of the CPU register.
+ #[inline]
+ fn get(&self) -> $width {
+ match () {
+ #[cfg(target_arch = "aarch64")]
+ () => {
+ let reg;
+ unsafe {
+ core::arch::asm!(concat!($asm_instr, " {reg:", $asm_width, "}, ", $asm_reg_name), reg = out(reg) reg, options(nomem, nostack));
+ }
+ reg
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ () => unimplemented!(),
+ }
+ }
+ };
+}
+
+macro_rules! __write_raw {
+ ($width:ty, $asm_instr:tt, $asm_reg_name:tt, $asm_width:tt) => {
+ /// Writes raw bits to the CPU register.
+ #[cfg_attr(not(target_arch = "aarch64"), allow(unused_variables))]
+ #[inline]
+ fn set(&self, value: $width) {
+ match () {
+ #[cfg(target_arch = "aarch64")]
+ () => {
+ unsafe {
+ core::arch::asm!(concat!($asm_instr, " ", $asm_reg_name, ", {reg:", $asm_width, "}"), reg = in(reg) value, options(nomem, nostack))
+ }
+ }
+
+ #[cfg(not(target_arch = "aarch64"))]
+ () => unimplemented!(),
+ }
+ }
+ };
+}
+
+/// Raw read from system coprocessor registers.
+macro_rules! sys_coproc_read_raw {
+ ($width:ty, $asm_reg_name:tt, $asm_width:tt) => {
+ __read_raw!($width, "mrs", $asm_reg_name, $asm_width);
+ };
+}
+
+/// Raw write to system coprocessor registers.
+macro_rules! sys_coproc_write_raw {
+ ($width:ty, $asm_reg_name:tt, $asm_width:tt) => {
+ __write_raw!($width, "msr", $asm_reg_name, $asm_width);
+ };
+}
+
+/// Raw read from (ordinary) registers.
+macro_rules! read_raw {
+ ($width:ty, $asm_reg_name:tt, $asm_width:tt) => {
+ __read_raw!($width, "mov", $asm_reg_name, $asm_width);
+ };
+}
+/// Raw write to (ordinary) registers.
+macro_rules! write_raw {
+ ($width:ty, $asm_reg_name:tt, $asm_width:tt) => {
+ __write_raw!($width, "mov", $asm_reg_name, $asm_width);
+ };
+}
diff --git a/src/registers/mair_el1.rs b/src/registers/mair_el1.rs
new file mode 100644
index 0000000..478a7c7
--- /dev/null
+++ b/src/registers/mair_el1.rs
@@ -0,0 +1,447 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Erik Verbruggen <erik.verbruggen@me.com>
+
+//! Memory Attribute Indirection Register - EL1
+//!
+//! Provides the memory attribute encodings corresponding to the possible AttrIndx values in a
+//! Long-descriptor format translation table entry for stage 1 translations at EL1.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub MAIR_EL1 [
+ /// Attribute 7
+ Attr7_Normal_Outer OFFSET(60) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr7_Device OFFSET(56) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr7_Normal_Inner OFFSET(56) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 6
+ Attr6_Normal_Outer OFFSET(52) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr6_Device OFFSET(48) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr6_Normal_Inner OFFSET(48) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 5
+ Attr5_Normal_Outer OFFSET(44) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr5_Device OFFSET(40) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr5_Normal_Inner OFFSET(40) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 4
+ Attr4_Normal_Outer OFFSET(36) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr4_Device OFFSET(32) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr4_Normal_Inner OFFSET(32) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 3
+ Attr3_Normal_Outer OFFSET(28) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr3_Device OFFSET(24) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr3_Normal_Inner OFFSET(24) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 2
+ Attr2_Normal_Outer OFFSET(20) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr2_Device OFFSET(16) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr2_Normal_Inner OFFSET(16) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 1
+ Attr1_Normal_Outer OFFSET(12) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr1_Device OFFSET(8) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr1_Normal_Inner OFFSET(8) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 0
+ Attr0_Normal_Outer OFFSET(4) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr0_Device OFFSET(0) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr0_Normal_Inner OFFSET(0) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = MAIR_EL1::Register;
+
+ sys_coproc_read_raw!(u64, "MAIR_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = MAIR_EL1::Register;
+
+ sys_coproc_write_raw!(u64, "MAIR_EL1", "x");
+}
+
+pub const MAIR_EL1: Reg = Reg {};
diff --git a/src/registers/mair_el2.rs b/src/registers/mair_el2.rs
new file mode 100644
index 0000000..859cada
--- /dev/null
+++ b/src/registers/mair_el2.rs
@@ -0,0 +1,448 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Erik Verbruggen <erik.verbruggen@me.com>
+// - Bradley Landherr <landhb@users.noreply.github.com>
+
+//! Memory Attribute Indirection Register - EL2
+//!
+//! Provides the memory attribute encodings corresponding to the possible AttrIndx values in a
+//! Long-descriptor format translation table entry for stage 1 translations at EL2.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub MAIR_EL2 [
+ /// Attribute 7
+ Attr7_Normal_Outer OFFSET(60) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr7_Device OFFSET(56) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr7_Normal_Inner OFFSET(56) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 6
+ Attr6_Normal_Outer OFFSET(52) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr6_Device OFFSET(48) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr6_Normal_Inner OFFSET(48) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 5
+ Attr5_Normal_Outer OFFSET(44) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr5_Device OFFSET(40) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr5_Normal_Inner OFFSET(40) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 4
+ Attr4_Normal_Outer OFFSET(36) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr4_Device OFFSET(32) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr4_Normal_Inner OFFSET(32) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 3
+ Attr3_Normal_Outer OFFSET(28) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr3_Device OFFSET(24) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr3_Normal_Inner OFFSET(24) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 2
+ Attr2_Normal_Outer OFFSET(20) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr2_Device OFFSET(16) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr2_Normal_Inner OFFSET(16) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 1
+ Attr1_Normal_Outer OFFSET(12) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr1_Device OFFSET(8) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr1_Normal_Inner OFFSET(8) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+
+ /// Attribute 0
+ Attr0_Normal_Outer OFFSET(4) NUMBITS(4) [
+ Device = 0b0000,
+
+ WriteThrough_Transient_WriteAlloc = 0b0001,
+ WriteThrough_Transient_ReadAlloc = 0b0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0b0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ],
+ Attr0_Device OFFSET(0) NUMBITS(8) [
+ nonGathering_nonReordering_noEarlyWriteAck = 0b0000_0000,
+ nonGathering_nonReordering_EarlyWriteAck = 0b0000_0100,
+ nonGathering_Reordering_EarlyWriteAck = 0b0000_1000,
+ Gathering_Reordering_EarlyWriteAck = 0b0000_1100
+ ],
+ Attr0_Normal_Inner OFFSET(0) NUMBITS(4) [
+ WriteThrough_Transient = 0x0000,
+ WriteThrough_Transient_WriteAlloc = 0x0001,
+ WriteThrough_Transient_ReadAlloc = 0x0010,
+ WriteThrough_Transient_ReadWriteAlloc = 0x0011,
+
+ NonCacheable = 0b0100,
+ WriteBack_Transient_WriteAlloc = 0b0101,
+ WriteBack_Transient_ReadAlloc = 0b0110,
+ WriteBack_Transient_ReadWriteAlloc = 0b0111,
+
+ WriteThrough_NonTransient = 0b1000,
+ WriteThrough_NonTransient_WriteAlloc = 0b1001,
+ WriteThrough_NonTransient_ReadAlloc = 0b1010,
+ WriteThrough_NonTransient_ReadWriteAlloc = 0b1011,
+
+ WriteBack_NonTransient = 0b1100,
+ WriteBack_NonTransient_WriteAlloc = 0b1101,
+ WriteBack_NonTransient_ReadAlloc = 0b1110,
+ WriteBack_NonTransient_ReadWriteAlloc = 0b1111
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = MAIR_EL2::Register;
+
+ sys_coproc_read_raw!(u64, "MAIR_EL2", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = MAIR_EL2::Register;
+
+ sys_coproc_write_raw!(u64, "MAIR_EL2", "x");
+}
+
+pub const MAIR_EL2: Reg = Reg {};
diff --git a/src/registers/midr_el1.rs b/src/registers/midr_el1.rs
new file mode 100644
index 0000000..10082e1
--- /dev/null
+++ b/src/registers/midr_el1.rs
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Main ID Register - EL1
+//!
+//! Provides identification information for the processor, including an implementer code for the
+//! device and a device ID number.
+
+use tock_registers::{interfaces::Readable, register_bitfields};
+
+register_bitfields! {u64,
+ pub MIDR_EL1 [
+ /// The Implementer code. This field must hold an implementer code that has been assigned by
+ /// Arm. Assigned codes include the following:
+ ///
+ /// Hex representation Implementer
+ /// 0x00 Reserved for software use
+ /// 0xC0 Ampere Computing
+ /// 0x41 Arm Limited
+ /// 0x42 Broadcom Corporation
+ /// 0x43 Cavium Inc.
+ /// 0x44 Digital Equipment Corporation
+ /// 0x46 Fujitsu Ltd.
+ /// 0x49 Infineon Technologies AG
+ /// 0x4D Motorola or Freescale Semiconductor Inc.
+ /// 0x4E NVIDIA Corporation
+ /// 0x50 Applied Micro Circuits Corporation
+ /// 0x51 Qualcomm Inc.
+ /// 0x56 Marvell International Ltd.
+ /// 0x69 Intel Corporation
+ ///
+ /// Arm can assign codes that are not published in this manual. All values not assigned by
+ /// Arm are reserved and must not be used.
+ Implementer OFFSET(24) NUMBITS(8) [
+ Reserved = 0x00,
+ Ampere = 0xC0,
+ Arm = 0x41,
+ Broadcom = 0x42,
+ Cavium = 0x43,
+ DigitalEquipment = 0x44,
+ Fujitsu = 0x46,
+ Infineon = 0x49,
+ MotorolaOrFreescale = 0x4D,
+ NVIDIA = 0x4E,
+ AppliedMicroCircuits = 0x50,
+ Qualcomm = 0x51,
+ Marvell = 0x56,
+ Intel = 0x69
+ ],
+
+ /// An IMPLEMENTATION DEFINED variant number. Typically, this field is used to distinguish
+ /// between different product variants, or major revisions of a product.
+ Variant OFFSET(20) NUMBITS(4) [],
+
+ /// The permitted values of this field are:
+ ///
+ /// 0001 Armv4.
+ /// 0010 Armv4T.
+ /// 0011 Armv5 (obsolete).
+ /// 0100 Armv5T.
+ /// 0101 Armv5TE.
+ /// 0110 Armv5TEJ.
+ /// 0111 Armv6.
+ /// 1111 Architectural features are individually identified in the ID_* registers, see ID
+ /// registers on page K14-8060.
+ ///
+ /// All other values are reserved.
+ Architecture OFFSET(16) NUMBITS(4) [
+ Individual = 0b1111
+ ],
+
+ /// An IMPLEMENTATION DEFINED primary part number for the device.
+ ///
+ /// On processors implemented by Arm, if the top four bits of the primary part number are
+ /// 0x0 or 0x7, the variant and architecture are encoded differently.
+ PartNum OFFSET(4) NUMBITS(12) [],
+
+ /// An IMPLEMENTATION DEFINED revision number for the device.
+ Revision OFFSET(0) NUMBITS(4) []
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = MIDR_EL1::Register;
+
+ sys_coproc_read_raw!(u64, "MIDR_EL1", "x");
+}
+
+pub const MIDR_EL1: Reg = Reg {};
diff --git a/src/registers/mpidr_el1.rs b/src/registers/mpidr_el1.rs
new file mode 100644
index 0000000..7db1eba
--- /dev/null
+++ b/src/registers/mpidr_el1.rs
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Multiprocessor Affinity Register - EL1
+//!
+//! In a multiprocessor system, provides an additional PE identification mechanism for scheduling
+//! purposes.
+
+use tock_registers::interfaces::Readable;
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "MPIDR_EL1", "x");
+}
+
+pub const MPIDR_EL1: Reg = Reg {};
diff --git a/src/registers/oslar_el1.rs b/src/registers/oslar_el1.rs
new file mode 100644
index 0000000..0acd317
--- /dev/null
+++ b/src/registers/oslar_el1.rs
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Javier Alvarez <javier.alvarez@allthingsembedded.net>
+
+//! OS Lock Access Register - EL1
+//!
+//! Used to lock or unlock the OS Lock.
+//!
+//! AArch64 System register OSLAR_EL1 bits [31:0] are architecturally mapped to External register
+//! OSLAR_EL1[31:0]. The OS Lock can also be locked or unlocked using DBGOSLAR.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub OSLAR_EL1 [
+ /// On writes to OSLAR_EL1, bit[0] is copied to the OS Lock.
+ /// Use OSLSR_EL1.OSLK to check the current status of the lock.
+ OSLK OFFSET(0) NUMBITS(1) [
+ Unlocked = 0,
+ Locked = 1
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = OSLAR_EL1::Register;
+
+ sys_coproc_read_raw!(u64, "OSLAR_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = OSLAR_EL1::Register;
+
+ sys_coproc_write_raw!(u64, "OSLAR_EL1", "x");
+}
+
+pub const OSLAR_EL1: Reg = Reg {};
diff --git a/src/registers/par_el1.rs b/src/registers/par_el1.rs
new file mode 100644
index 0000000..e0c76a3
--- /dev/null
+++ b/src/registers/par_el1.rs
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2021-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Physical Address Register - EL1
+//!
+//! Returns the output address (OA) from an Address translation instruction that executed
+//! successfully, or fault information if the instruction did not execute successfully.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub PAR_EL1 [
+ /// Output address. The output address (OA) corresponding to the supplied input address.
+ /// This field returns address bits[47:12].
+ ///
+ /// When ARMv8.2-LPA is implemented, and 52-bit addresses and a 64KB translation granule are
+ /// in use, the PA[51:48] bits form the upper part of the address value. Otherwise the
+ /// PA[51:48] bits are RES0.
+ ///
+ /// For implementations with fewer than 48 physical address bits, the corresponding upper
+ /// bits in this field are RES0.
+ ///
+ /// This field resets to an architecturally UNKNOWN value.
+ PA OFFSET(12) NUMBITS(36) [],
+
+ /// Indicates whether the instruction performed a successful address translation.
+ ///
+ /// 0 Address translation completed successfully.
+ ///
+ /// 1 Address translation aborted.
+ ///
+ /// This field resets to an architecturally UNKNOWN value.
+ F OFFSET(0) NUMBITS(1) [
+ TranslationSuccessfull = 0,
+ TranslationAborted = 1
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = PAR_EL1::Register;
+
+ sys_coproc_read_raw!(u64, "PAR_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = PAR_EL1::Register;
+
+ sys_coproc_write_raw!(u64, "PAR_EL1", "x");
+}
+
+pub const PAR_EL1: Reg = Reg {};
diff --git a/src/registers/scr_el3.rs b/src/registers/scr_el3.rs
new file mode 100644
index 0000000..537ff9d
--- /dev/null
+++ b/src/registers/scr_el3.rs
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2019-2022 by the author(s)
+//
+// Author(s):
+// - Berkus Decker <berkus+github@metta.systems>
+
+//! Secure Configuration Register - EL3, page D12.2.99 of armv8arm.
+//! Defines the configuration of the current Security state. It specifies:
+//! • The Security state of EL0, EL1, and EL2. The Security state is either Secure or Non-secure.
+//! • The Execution state at lower Exception levels.
+//! • Whether IRQ, FIQ, SError interrupts, and External abort exceptions are taken to EL3.
+//! • Whether various operations are trapped to EL3.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub SCR_EL3 [
+ /// Execution state control for lower Exception levels:
+ ///
+ /// 0 Lower levels are all AArch32.
+ /// 1 The next lower level is AArch64.
+ /// If EL2 is present:
+ /// The Execution state for EL2 is AArch64.
+ /// EL2 controls EL1 and EL0 behaviors.
+ /// If EL2 is not present:
+ /// The Execution state for EL1 is AArch64.
+ /// The Execution state for EL0 is determined by the current value of PSTATE.nRW when
+ /// executing at EL0.
+ ///
+ /// If all lower Exception levels cannot use AArch32 then this bit is RAO/WI.
+ ///
+ /// When SCR_EL3.{EEL2,NS}=={1,0}, this bit is treated as 1 for all purposes other than
+ /// reading or writing the register.
+ ///
+ /// The RW bit is permitted to be cached in a TLB.
+ RW OFFSET(10) NUMBITS(1) [
+ AllLowerELsAreAarch32 = 0,
+ NextELIsAarch64 = 1
+ ],
+
+ /// Hypervisor Call Enable
+ ///
+ /// 0 The HVC instruction is undefined at all exception levels.
+ /// 1 The HVC instruction is enabled at EL1, EL2, or EL3.
+ HCE OFFSET(8) NUMBITS(1) [
+ HvcDisabled = 0,
+ HvcEnabled = 1
+ ],
+
+ /// Secure Monitor call Disable
+ ///
+ /// 0 The SMC instruction is enabled at EL1, EL2, and EL3.
+ ///
+ /// 1 The SMC instruction is undefined at all exception levels. At EL1, in the Non-secure
+ /// state, the HCR_EL2.TSC bit has priority over this control.
+ SMD OFFSET(7) NUMBITS(1) [
+ SmcEnabled = 0,
+ SmcDisabled = 1
+ ],
+
+ /// Non-secure bit.
+ /// 0 Indicates that EL0 and EL1 are in Secure state.
+ ///
+ /// 1 Indicates that Exception levels lower than EL3 are in Non-secure state, and so memory
+ /// accesses from those Exception levels cannot access Secure memory.
+ ///
+ /// When SCR_EL3.{EEL2, NS} == {1, 0}, then EL2 is using AArch64 and in Secure state.
+ NS OFFSET(0) NUMBITS(1) [
+ Secure = 0,
+ NonSecure = 1
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = SCR_EL3::Register;
+
+ sys_coproc_read_raw!(u64, "SCR_EL3", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = SCR_EL3::Register;
+
+ sys_coproc_write_raw!(u64, "SCR_EL3", "x");
+}
+
+pub const SCR_EL3: Reg = Reg {};
diff --git a/src/registers/sctlr_el1.rs b/src/registers/sctlr_el1.rs
new file mode 100644
index 0000000..8ba4025
--- /dev/null
+++ b/src/registers/sctlr_el1.rs
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! System Control Register - EL1
+//!
+//! Provides top level control of the system, including its memory system, at EL1 and EL0.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub SCTLR_EL1 [
+ /// Traps EL0 execution of cache maintenance instructions to EL1, from AArch64 state only.
+ ///
+ /// 0 Any attempt to execute a DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU
+ /// instruction at EL0 using AArch64 is trapped to EL1.
+ /// 1 This control does not cause any instructions to be trapped.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on execution at EL0.
+ ///
+ /// If the Point of Coherency is before any level of data cache, it is IMPLEMENTATION DEFINED whether
+ /// the execution of any data or unified cache clean, or clean and invalidate instruction that operates by
+ /// VA to the point of coherency can be trapped when the value of this control is 1.
+ ///
+ /// If the Point of Unification is before any level of data cache, it is IMPLEMENTATION DEFINED whether
+ /// the execution of any data or unified cache clean by VA to the point of unification instruction can be
+ /// trapped when the value of this control is 1.
+ ///
+ /// If the Point of Unification is before any level of instruction cache, it is IMPLEMENTATION DEFINED
+ /// whether the execution of any instruction cache invalidate by VA to the point of unification
+ /// instruction can be trapped when the value of this control is 1.
+ UCI OFFSET(26) NUMBITS(1) [
+ Trap = 0,
+ DontTrap = 1,
+ ],
+
+ /// Endianness of data accesses at EL1, and stage 1 translation table walks in the EL1&0 translation regime.
+ ///
+ /// 0 Explicit data accesses at EL1, and stage 1 translation table walks in the EL1&0
+ /// translation regime are little-endian.
+ /// 1 Explicit data accesses at EL1, and stage 1 translation table walks in the EL1&0
+ /// translation regime are big-endian.
+ ///
+ /// If an implementation does not provide Big-endian support at Exception Levels higher than EL0, this
+ /// bit is RES 0.
+ ///
+ /// If an implementation does not provide Little-endian support at Exception Levels higher than EL0,
+ /// this bit is RES 1.
+ ///
+ /// The EE bit is permitted to be cached in a TLB.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on the PE.
+ EE OFFSET(25) NUMBITS(1) [
+ LittleEndian = 0,
+ BigEndian = 1,
+ ],
+
+ /// Endianness of data accesses at EL0.
+ ///
+ /// 0 Explicit data accesses at EL0 are little-endian.
+ ///
+ /// 1 Explicit data accesses at EL0 are big-endian.
+ ///
+ /// If an implementation only supports Little-endian accesses at EL0 then this bit is RES 0. This option
+ /// is not permitted when SCTLR_EL1.EE is RES 1.
+ ///
+ /// If an implementation only supports Big-endian accesses at EL0 then this bit is RES 1. This option is
+ /// not permitted when SCTLR_EL1.EE is RES 0.
+ ///
+ /// This bit has no effect on the endianness of LDTR , LDTRH , LDTRSH , LDTRSW , STTR , and STTRH instructions
+ /// executed at EL1.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on execution at EL0.
+ E0E OFFSET(24) NUMBITS(1) [
+ LittleEndian = 0,
+ BigEndian = 1,
+ ],
+
+ /// Write permission implies XN (Execute-never). For the EL1&0 translation regime, this bit can force
+ /// all memory regions that are writable to be treated as XN.
+ ///
+ /// 0 This control has no effect on memory access permissions.
+ ///
+ /// 1 Any region that is writable in the EL1&0 translation regime is forced to XN for accesses
+ /// from software executing at EL1 or EL0.
+ ///
+ /// The WXN bit is permitted to be cached in a TLB.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on the PE.
+ WXN OFFSET(19) NUMBITS(1) [
+ Disable = 0,
+ Enable = 1,
+ ],
+
+ /// Traps EL0 execution of WFE instructions to EL1, from both Execution states.
+ ///
+ /// 0 Any attempt to execute a WFE instruction at EL0 is trapped to EL1, if the instruction
+ /// would otherwise have caused the PE to enter a low-power state.
+ ///
+ /// 1 This control does not cause any instructions to be trapped.
+ ///
+ /// In AArch32 state, the attempted execution of a conditional WFE instruction is only trapped if the
+ /// instruction passes its condition code check.
+ ///
+ /// **Note:**
+ ///
+ /// Since a WFE or WFI can complete at any time, even without a Wakeup event, the traps on WFE of
+ /// WFI are not guaranteed to be taken, even if the WFE or WFI is executed when there is no Wakeup
+ /// event. The only guarantee is that if the instruction does not complete in finite time in the
+ /// absence of a Wakeup event, the trap will be taken.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on execution at EL0.
+ NTWE OFFSET(18) NUMBITS(1) [
+ Trap = 0,
+ DontTrap = 1,
+ ],
+
+ /// Traps EL0 executions of WFI instructions to EL1, from both execution states:
+ ///
+ /// 0 Any attempt to execute a WFI instruction at EL0 is trapped EL1, if the instruction would
+ /// otherwise have caused the PE to enter a low-power state.
+ ///
+ /// 1 This control does not cause any instructions to be trapped.
+ ///
+ /// In AArch32 state, the attempted execution of a conditional WFI instruction is only trapped if the
+ /// instruction passes its condition code check.
+ ///
+ /// **Note:**
+ ///
+ /// Since a WFE or WFI can complete at any time, even without a Wakeup event, the traps on WFE of
+ /// WFI are not guaranteed to be taken, even if the WFE or WFI is executed when there is no Wakeup
+ /// event. The only guarantee is that if the instruction does not complete in finite time in the
+ /// absence of a Wakeup event, the trap will be taken.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on execution at EL0.
+ NTWI OFFSET(16) NUMBITS(1) [
+ Trap = 0,
+ DontTrap = 1,
+ ],
+
+ /// Traps EL0 accesses to the CTR_EL0 to EL1, from AArch64 state only.
+ ///
+ /// 0 Accesses to the CTR_EL0 from EL0 using AArch64 are trapped to EL1.
+ ///
+ /// 1 This control does not cause any instructions to be trapped.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on execution at EL0.
+ UCT OFFSET(15) NUMBITS(1) [
+ Trap = 0,
+ DontTrap = 1,
+ ],
+
+ /// Traps EL0 execution of DC ZVA instructions to EL1, from AArch64 state only.
+ ///
+ /// 0 Any attempt to execute a DC ZVA instruction at EL0 using AArch64 is trapped to EL1.
+ /// Reading DCZID_EL0.DZP from EL0 returns 1, indicating that DC ZVA instructions
+ /// are not supported.
+ ///
+ /// 1 This control does not cause any instructions to be trapped.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on execution at EL0.
+ DZE OFFSET(14) NUMBITS(1) [
+ Trap = 0,
+ DontTrap = 1,
+ ],
+
+ /// Instruction access Cacheability control, for accesses at EL0 and
+ /// EL1:
+ ///
+ /// 0 All instruction access to Normal memory from EL0 and EL1 are Non-cacheable for all
+ /// levels of instruction and unified cache.
+ ///
+ /// If the value of SCTLR_EL1.M is 0, instruction accesses from stage 1 of the EL1&0
+ /// translation regime are to Normal, Outer Shareable, Inner Non-cacheable, Outer
+ /// Non-cacheable memory.
+ ///
+ /// 1 This control has no effect on the Cacheability of instruction access to Normal memory
+ /// from EL0 and EL1.
+ ///
+ /// If the value of SCTLR_EL1.M is 0, instruction accesses from stage 1 of the EL1&0
+ /// translation regime are to Normal, Outer Shareable, Inner Write-Through, Outer
+ /// Write-Through memory.
+ ///
+ /// When the value of the HCR_EL2.DC bit is 1, then instruction access to Normal memory from
+ /// EL0 and EL1 are Cacheable regardless of the value of the SCTLR_EL1.I bit.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on the PE.
+ ///
+ /// When this register has an architecturally-defined reset value, this field resets to 0.
+ I OFFSET(12) NUMBITS(1) [
+ NonCacheable = 0,
+ Cacheable = 1
+ ],
+
+ /// User Mask Access. Traps EL0 execution of MSR and MRS instructions that access the
+ /// PSTATE.{D, A, I, F} masks to EL1, from AArch64 state only.
+ ///
+ /// 0 Any attempt at EL0 using AArch64 to execute an MRS , MSR(register) , or MSR(immediate)
+ /// instruction that accesses the [`DAIF`](module@super::super::DAIF) is trapped to EL1.
+ ///
+ /// 1 This control does not cause any instructions to be trapped.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on execution at EL0.
+ UMA OFFSET(9) NUMBITS(1) [
+ Trap = 0,
+ DontTrap = 1,
+ ],
+
+ /// Non-aligned access. This bit controls generation of Alignment faults at EL1 and EL0 under certain conditions.
+ ///
+ /// LDAPR, LDAPRH, LDAPUR, LDAPURH, LDAPURSH, LDAPURSW, LDAR, LDARH, LDLAR, LDLARH,
+ /// STLLR, STLLRH, STLR, STLRH, STLUR, and STLURH will or will not generate an Alignment
+ /// fault if all bytes being accessed are not within a single 16-byte quantity,
+ /// aligned to 16 bytes for accesses.
+ NAA OFFSET(6) NUMBITS(1) [
+ Disable = 0,
+ Enable = 1
+ ],
+
+ /// SP Alignment check enable for EL0.
+ ///
+ /// When set to 1, if a load or store instruction executed at EL0 uses the SP
+ /// as the base address and the SP is not aligned to a 16-byte boundary,
+ /// then a SP alignment fault exception is generated.
+ SA0 OFFSET(4) NUMBITS(1) [
+ Disable = 0,
+ Enable = 1
+ ],
+
+ /// SP Alignment check enable.
+ ///
+ /// When set to 1, if a load or store instruction executed at EL1 uses the SP
+ /// as the base address and the SP is not aligned to a 16-byte boundary,
+ /// then a SP alignment fault exception is generated.
+ SA OFFSET(3) NUMBITS(1) [
+ Disable = 0,
+ Enable = 1
+ ],
+
+ /// Cacheability control, for data accesses.
+ ///
+ /// 0 All data access to Normal memory from EL0 and EL1, and all Normal memory accesses to
+ /// the EL1&0 stage 1 translation tables, are Non-cacheable for all levels of data and
+ /// unified cache.
+ ///
+ /// 1 This control has no effect on the Cacheability of:
+ /// - Data access to Normal memory from EL0 and EL1.
+ /// - Normal memory accesses to the EL1&0 stage 1 translation tables.
+ ///
+ /// When the value of the HCR_EL2.DC bit is 1, the PE ignores SCLTR.C. This means that
+ /// Non-secure EL0 and Non-secure EL1 data accesses to Normal memory are Cacheable.
+ ///
+ /// When ARMv8.1-VHE is implemented, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on the PE.
+ ///
+ /// When this register has an architecturally-defined reset value, this field resets to 0.
+ C OFFSET(2) NUMBITS(1) [
+ NonCacheable = 0,
+ Cacheable = 1
+ ],
+
+ /// Alignment check enable. This is the enable bit for Alignment fault checking at EL1 and EL0.
+ ///
+ /// Instructions that load or store one or more registers, other than load/store exclusive
+ /// and load-acquire/store-release, will or will not check that the address being accessed
+ /// is aligned to the size of the data element(s) being accessed depending on this flag.
+ ///
+ /// Load/store exclusive and load-acquire/store-release instructions have an alignment check
+ /// regardless of the value of the A bit.
+ A OFFSET(1) NUMBITS(1) [
+ Disable = 0,
+ Enable = 1
+ ],
+
+ /// MMU enable for EL1 and EL0 stage 1 address translation. Possible values of this bit are:
+ ///
+ /// 0 EL1 and EL0 stage 1 address translation disabled.
+ /// - See the SCTLR_EL1.I field for the behavior of instruction accesses to Normal memory.
+ ///
+ /// 1 EL1 and EL0 stage 1 address translation enabled.
+ M OFFSET(0) NUMBITS(1) [
+ Disable = 0,
+ Enable = 1
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = SCTLR_EL1::Register;
+
+ sys_coproc_read_raw!(u64, "SCTLR_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = SCTLR_EL1::Register;
+
+ sys_coproc_write_raw!(u64, "SCTLR_EL1", "x");
+}
+
+pub const SCTLR_EL1: Reg = Reg {};
diff --git a/src/registers/sctlr_el2.rs b/src/registers/sctlr_el2.rs
new file mode 100644
index 0000000..3e4a760
--- /dev/null
+++ b/src/registers/sctlr_el2.rs
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Bradley Landherr <landhb@users.noreply.github.com>
+
+//! System Control Register - EL2
+//!
+//! Provides top level control of the system, including its memory system, at EL2.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub SCTLR_EL2 [
+
+ /// Exception endianness. The possible values are:
+ ///
+ /// 0 Little endian.
+ /// 1 Big endian.
+ EE OFFSET(25) NUMBITS(1) [
+ Little = 0,
+ Big = 1
+ ],
+
+ /// Force treatment of all memory regions with write permissions as XN.
+ /// The possible values are:
+ ///
+ /// 0 Regions with write permissions are not forced XN. This is the reset value.
+ /// 1 Regions with write permissions are forced XN.
+ WXN OFFSET(19) NUMBITS(1) [
+ Disable = 0,
+ Enable = 1
+ ],
+
+ /// Instruction Cache Control, two possible values:
+ ///
+ /// 0 All instruction access to Normal memory from EL2 are Non-cacheable for all
+ /// levels of instruction and unified cache.
+ ///
+ /// If the value of SCTLR_EL2.M is 0, instruction accesses from stage 1 of the EL2 or EL2&0
+ /// translation regime are to Normal, Outer Shareable, Inner Non-cacheable, Outer
+ /// Non-cacheable memory.
+ ///
+ /// 1 This control has no effect on the Cacheability of instruction access to Normal memory
+ /// from EL2 and, when EL2 is enabled in the current Security state and
+ /// HCR_EL2.{E2H, TGE} == {1, 1}, instruction access to Normal memory from EL0.
+ ///
+ /// If the value of SCTLR_EL2.M is 0, instruction accesses from stage 1 of the EL2&0
+ /// translation regime are to Normal, Outer Shareable, Inner Write-Through, Outer
+ /// Write-Through memory.
+ ///
+ /// When EL2 is disabled, and the value of HCR_EL2.{E2H, TGE} is {1, 1}, this bit
+ /// has no effect on the PE.
+ ///
+ /// On a Warm reset, in a system where the PE resets into EL2, this field resets to 0.
+ I OFFSET(12) NUMBITS(1) [
+ NonCacheable = 0,
+ Cacheable = 1
+ ],
+
+ /// SP Alignment check enable.
+ ///
+ /// When set to 1, if a load or store instruction executed at EL2 uses the SP
+ /// as the base address and the SP is not aligned to a 16-byte boundary,
+ /// then a SP alignment fault exception is generated.
+ SA OFFSET(3) NUMBITS(1) [
+ Disable = 0,
+ Enable = 1
+ ],
+
+ /// Cacheability control, for data accesses.
+ ///
+ /// 0 The following are Non-cacheable for all levels of data and unified cache:
+ /// - Data accesses to Normal memory from EL2.
+ /// - When HCR_EL2.{E2H, TGE} != {1, 1}, Normal memory accesses to the EL2 translation tables.
+ /// - When EL2 is enabled in the current Security state and HCR_EL2.{E2H, TGE} == {1, 1}:
+ /// - Data accesses to Normal memory from EL0.
+ /// - Normal memory accesses to the EL2&0 translation tables.
+ ///
+ /// 1 This control has no effect on the Cacheability of:
+ /// - Data access to Normal memory from EL2.
+ /// - When HCR_EL2.{E2H, TGE} != {1, 1}, Normal memory accesses to the EL2 translation tables.
+ /// - When EL2 is enabled in the current Security state and HCR_EL2.{E2H, TGE} == {1, 1}:
+ /// - Data accesses to Normal memory from EL0.
+ /// - Normal memory accesses to the EL2&0 translation tables.
+ ///
+ /// When EL2 is disabled in the current Security state or HCR_EL2.{E2H, TGE} != {1, 1},
+ /// this bit has no effect on the EL1&0 translation regime.
+ ///
+ /// On a Warm reset, in a system where the PE resets into EL2, this field resets to 0.
+ C OFFSET(2) NUMBITS(1) [
+ NonCacheable = 0,
+ Cacheable = 1
+ ],
+
+ /// Alignment check enable. This is the enable bit for Alignment fault checking at EL2 and,
+ /// when EL2 is enabled in the current Security state and HCR_EL2.{E2H, TGE} == {1, 1}, EL0.
+ ///
+ /// Instructions that load or store one or more registers, other than load/store exclusive
+ /// and load-acquire/store-release, will or will not check that the address being accessed
+ /// is aligned to the size of the data element(s) being accessed depending on this flag.
+ ///
+ /// Load/store exclusive and load-acquire/store-release instructions have an alignment check
+ /// regardless of the value of the A bit.
+ A OFFSET(1) NUMBITS(1) [
+ Disable = 0,
+ Enable = 1
+ ],
+
+ /// MMU enable for EL2 or EL2&0 stage 1 address translation. Possible values of this bit are:
+ ///
+ /// 0 - When HCR_EL2.{E2H, TGE} != {1, 1}, EL2 stage 1 address translation disabled.
+ /// - When HCR_EL2.{E2H, TGE} == {1, 1}, EL2&0 stage 1 address translation disabled.
+ /// - See the SCTLR_EL2.I field for the behavior of instruction accesses to Normal memory.
+ ///
+ /// 1 - When HCR_EL2.{E2H, TGE} != {1, 1}, EL2 stage 1 address translation enabled.
+ /// - When HCR_EL2.{E2H, TGE} == {1, 1}, EL2&0 stage 1 address translation enabled.
+ ///
+ /// On a Warm reset, in a system where the PE resets into EL2, this field resets to 0.
+ M OFFSET(0) NUMBITS(1) [
+ Disable = 0,
+ Enable = 1
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = SCTLR_EL2::Register;
+
+ sys_coproc_read_raw!(u64, "SCTLR_EL2", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = SCTLR_EL2::Register;
+
+ sys_coproc_write_raw!(u64, "SCTLR_EL2", "x");
+}
+
+pub const SCTLR_EL2: Reg = Reg {};
diff --git a/src/registers/sp.rs b/src/registers/sp.rs
new file mode 100644
index 0000000..5065320
--- /dev/null
+++ b/src/registers/sp.rs
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! The stack pointer
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ read_raw!(u64, "sp", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ write_raw!(u64, "sp", "x");
+}
+
+pub const SP: Reg = Reg {};
diff --git a/src/registers/sp_el0.rs b/src/registers/sp_el0.rs
new file mode 100644
index 0000000..074120a
--- /dev/null
+++ b/src/registers/sp_el0.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! The stack pointer - EL0
+//!
+//! Holds the stack pointer associated with EL0. At higher Exception levels, this is used as the
+//! current stack pointer when the value of SPSel.SP is 0.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "SP_EL0", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "SP_EL0", "x");
+}
+
+pub const SP_EL0: Reg = Reg {};
diff --git a/src/registers/sp_el1.rs b/src/registers/sp_el1.rs
new file mode 100644
index 0000000..640b3aa
--- /dev/null
+++ b/src/registers/sp_el1.rs
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! The stack pointer - EL1
+//!
+//! Holds the stack pointer associated with EL1. When executing at EL1, the value of SPSel.SP
+//! determines the current stack pointer:
+//!
+//! SPSel.SP | current stack pointer
+//! --------------------------------
+//! 0 | SP_EL0
+//! 1 | SP_EL1
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "SP_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "SP_EL1", "x");
+}
+
+pub const SP_EL1: Reg = Reg {};
diff --git a/src/registers/spsel.rs b/src/registers/spsel.rs
new file mode 100644
index 0000000..f90b1f5
--- /dev/null
+++ b/src/registers/spsel.rs
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Stack Pointer Select
+//!
+//! Allows the Stack Pointer to be selected between SP_EL0 and SP_ELx.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub SPSel [
+ /// Stack pointer to use. Possible values of this bit are:
+ ///
+ /// 0 Use SP_EL0 at all Exception levels.
+ /// 1 Use SP_ELx for Exception level ELx.
+ ///
+ /// When this register has an architecturally-defined reset value, this field resets to 1.
+ SP OFFSET(0) NUMBITS(1) [
+ EL0 = 0,
+ ELx = 1
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = SPSel::Register;
+
+ sys_coproc_read_raw!(u64, "SPSEL", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = SPSel::Register;
+
+ sys_coproc_write_raw!(u64, "SPSEL", "x");
+}
+
+#[allow(non_upper_case_globals)]
+pub const SPSel: Reg = Reg {};
diff --git a/src/registers/spsr_el1.rs b/src/registers/spsr_el1.rs
new file mode 100644
index 0000000..958f19f
--- /dev/null
+++ b/src/registers/spsr_el1.rs
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Saved Program Status Register - EL1
+//!
+//! Holds the saved process state when an exception is taken to EL1.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub SPSR_EL1 [
+ /// Negative condition flag.
+ ///
+ /// Set to the value of the N condition flag on taking an exception to EL1, and copied to
+ /// the N condition flag on executing an exception return operation in EL1.
+ ///
+ /// Set to 1 if the result of the last flag-setting instruction was negative.
+ N OFFSET(31) NUMBITS(1) [],
+
+ /// Zero condition flag.
+ ///
+ /// Set to the value of the Z condition flag on taking an exception to EL1, and copied to
+ /// the Z condition flag on executing an exception return operation in EL1.
+ ///
+ /// Set to 1 if the result of the last flag-setting instruction was zero, and to 0
+ /// otherwise. A result of zero often indicates an equal result from a comparison.
+ Z OFFSET(30) NUMBITS(1) [],
+
+ /// Carry condition flag.
+ ///
+ /// Set to the value of the C condition flag on taking an exception to EL1, and copied to
+ /// the C condition flag on executing an exception return operation in EL1.
+ ///
+ /// Set to 1 if the last flag-setting instruction resulted in a carry condition, for example
+ /// an unsigned overflow on an addition.
+ C OFFSET(29) NUMBITS(1) [],
+
+ /// Overflow condition flag.
+ ///
+ /// Set to the value of the V condition flag on taking an exception to EL1, and copied to
+ /// the V condition flag on executing an exception return operation in EL1.
+ ///
+ /// Set to 1 if the last flag-setting instruction resulted in an overflow condition, for
+ /// example a signed overflow on an addition.
+ V OFFSET(28) NUMBITS(1) [],
+
+ /// Software step. Shows the value of PSTATE.SS immediately before the exception was taken.
+ SS OFFSET(21) NUMBITS(1) [],
+
+ /// Illegal Execution state bit. Shows the value of PSTATE.IL immediately before the
+ /// exception was taken.
+ IL OFFSET(20) NUMBITS(1) [],
+
+ /// Process state D mask. The possible values of this bit are:
+ ///
+ /// 0 Watchpoint, Breakpoint, and Software Step exceptions targeted at the current Exception
+ /// level are not masked.
+ ///
+ /// 1 Watchpoint, Breakpoint, and Software Step exceptions targeted at the current Exception
+ /// level are masked.
+ ///
+ /// When the target Exception level of the debug exception is higher than the current
+ /// Exception level, the exception is not masked by this bit.
+ D OFFSET(9) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// SError interrupt mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ A OFFSET(8) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// IRQ mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ I OFFSET(7) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// FIQ mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ F OFFSET(6) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// AArch64 state (Exception level and selected SP) that an exception was taken from. The
+ /// possible values are:
+ ///
+ /// M[3:0] | State
+ /// --------------
+ /// 0b0000 | EL0t
+ /// 0b0100 | EL1t
+ /// 0b0101 | EL1h
+ ///
+ /// Other values are reserved, and returning to an Exception level that is using AArch64
+ /// with a reserved value in this field is treated as an illegal exception return.
+ ///
+ /// The bits in this field are interpreted as follows:
+ /// - M[3:2] holds the Exception Level.
+ /// - M[1] is unused and is RES 0 for all non-reserved values.
+ /// - M[0] is used to select the SP:
+ /// - 0 means the SP is always SP0.
+ /// - 1 means the exception SP is determined by the EL.
+ M OFFSET(0) NUMBITS(4) [
+ EL0t = 0b0000,
+ EL1t = 0b0100,
+ EL1h = 0b0101
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = SPSR_EL1::Register;
+
+ sys_coproc_read_raw!(u64, "SPSR_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = SPSR_EL1::Register;
+
+ sys_coproc_write_raw!(u64, "SPSR_EL1", "x");
+}
+
+pub const SPSR_EL1: Reg = Reg {};
diff --git a/src/registers/spsr_el2.rs b/src/registers/spsr_el2.rs
new file mode 100644
index 0000000..9493c3e
--- /dev/null
+++ b/src/registers/spsr_el2.rs
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Saved Program Status Register - EL2
+//!
+//! Holds the saved process state when an exception is taken to EL2.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub SPSR_EL2 [
+ /// Negative condition flag.
+ ///
+ /// Set to the value of the N condition flag on taking an exception to EL2, and copied to
+ /// the N condition flag on executing an exception return operation in EL2.
+ ///
+ /// Set to 1 if the result of the last flag-setting instruction was negative.
+ N OFFSET(31) NUMBITS(1) [],
+
+ /// Zero condition flag.
+ ///
+ /// Set to the value of the Z condition flag on taking an exception to EL2, and copied to
+ /// the Z condition flag on executing an exception return operation in EL2.
+ ///
+ /// Set to 1 if the result of the last flag-setting instruction was zero, and to 0
+ /// otherwise. A result of zero often indicates an equal result from a comparison.
+ Z OFFSET(30) NUMBITS(1) [],
+
+ /// Carry condition flag.
+ ///
+ /// Set to the value of the C condition flag on taking an exception to EL2, and copied to
+ /// the C condition flag on executing an exception return operation in EL2.
+ ///
+ /// Set to 1 if the last flag-setting instruction resulted in a carry condition, for example
+ /// an unsigned overflow on an addition.
+ C OFFSET(29) NUMBITS(1) [],
+
+ /// Overflow condition flag.
+ ///
+ /// Set to the value of the V condition flag on taking an exception to EL2, and copied to
+ /// the V condition flag on executing an exception return operation in EL2.
+ ///
+ /// Set to 1 if the last flag-setting instruction resulted in an overflow condition, for
+ /// example a signed overflow on an addition.
+ V OFFSET(28) NUMBITS(1) [],
+
+ /// Software step. Shows the value of PSTATE.SS immediately before the exception was taken.
+ SS OFFSET(21) NUMBITS(1) [],
+
+ /// Illegal Execution state bit. Shows the value of PSTATE.IL immediately before the
+ /// exception was taken.
+ IL OFFSET(20) NUMBITS(1) [],
+
+ /// Process state D mask. The possible values of this bit are:
+ ///
+ /// 0 Watchpoint, Breakpoint, and Software Step exceptions targeted at the current Exception
+ /// level are not masked.
+ ///
+ /// 1 Watchpoint, Breakpoint, and Software Step exceptions targeted at the current Exception
+ /// level are masked.
+ ///
+ /// When the target Exception level of the debug exception is higher than the current
+ /// Exception level, the exception is not masked by this bit.
+ D OFFSET(9) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// SError interrupt mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ A OFFSET(8) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// IRQ mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ I OFFSET(7) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// FIQ mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ F OFFSET(6) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// AArch64 state (Exception level and selected SP) that an exception was taken from. The
+ /// possible values are:
+ ///
+ /// M[3:0] | State
+ /// --------------
+ /// 0b0000 | EL0t
+ /// 0b0100 | EL1t
+ /// 0b0101 | EL1h
+ /// 0b1000 | EL2t
+ /// 0b1001 | EL2h
+ ///
+ /// Other values are reserved, and returning to an Exception level that is using AArch64
+ /// with a reserved value in this field is treated as an illegal exception return.
+ ///
+ /// The bits in this field are interpreted as follows:
+ /// - M[3:2] holds the Exception Level.
+ /// - M[1] is unused and is RES 0 for all non-reserved values.
+ /// - M[0] is used to select the SP:
+ /// - 0 means the SP is always SP0.
+ /// - 1 means the exception SP is determined by the EL.
+ M OFFSET(0) NUMBITS(4) [
+ EL0t = 0b0000,
+ EL1t = 0b0100,
+ EL1h = 0b0101,
+ EL2t = 0b1000,
+ EL2h = 0b1001
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = SPSR_EL2::Register;
+
+ sys_coproc_read_raw!(u64, "SPSR_EL2", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = SPSR_EL2::Register;
+
+ sys_coproc_write_raw!(u64, "SPSR_EL2", "x");
+}
+
+pub const SPSR_EL2: Reg = Reg {};
diff --git a/src/registers/spsr_el3.rs b/src/registers/spsr_el3.rs
new file mode 100644
index 0000000..857d9c0
--- /dev/null
+++ b/src/registers/spsr_el3.rs
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Berkus Decker <berkus+github@metta.systems>
+
+//! Saved Program Status Register - EL3
+//!
+//! Holds the saved process state when an exception is taken to EL3.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub SPSR_EL3 [
+ /// Negative condition flag.
+ ///
+ /// Set to the value of the N condition flag on taking an exception to EL3, and copied to
+ /// the N condition flag on executing an exception return operation in EL3.
+ ///
+ /// Set to 1 if the result of the last flag-setting instruction was negative.
+ N OFFSET(31) NUMBITS(1) [],
+
+ /// Zero condition flag.
+ ///
+ /// Set to the value of the Z condition flag on taking an exception to EL3, and copied to
+ /// the Z condition flag on executing an exception return operation in EL3.
+ ///
+ /// Set to 1 if the result of the last flag-setting instruction was zero, and to 0
+ /// otherwise. A result of zero often indicates an equal result from a comparison.
+ Z OFFSET(30) NUMBITS(1) [],
+
+ /// Carry condition flag.
+ ///
+ /// Set to the value of the C condition flag on taking an exception to EL3, and copied to
+ /// the C condition flag on executing an exception return operation in EL3.
+ ///
+ /// Set to 1 if the last flag-setting instruction resulted in a carry condition, for example
+ /// an unsigned overflow on an addition.
+ C OFFSET(29) NUMBITS(1) [],
+
+ /// Overflow condition flag.
+ ///
+ /// Set to the value of the V condition flag on taking an exception to EL3, and copied to
+ /// the V condition flag on executing an exception return operation in EL3.
+ ///
+ /// Set to 1 if the last flag-setting instruction resulted in an overflow condition, for
+ /// example a signed overflow on an addition.
+ V OFFSET(28) NUMBITS(1) [],
+
+ /// Software step. Shows the value of PSTATE.SS immediately before the exception was taken.
+ SS OFFSET(21) NUMBITS(1) [],
+
+ /// Illegal Execution state bit. Shows the value of PSTATE.IL immediately before the
+ /// exception was taken.
+ IL OFFSET(20) NUMBITS(1) [],
+
+ /// Process state D mask. The possible values of this bit are:
+ ///
+ /// 0 Watchpoint, Breakpoint, and Software Step exceptions targeted at the current Exception
+ /// level are not masked.
+ ///
+ /// 1 Watchpoint, Breakpoint, and Software Step exceptions targeted at the current Exception
+ /// level are masked.
+ ///
+ /// When the target Exception level of the debug exception is higher than the current
+ /// Exception level, the exception is not masked by this bit.
+ D OFFSET(9) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// SError interrupt mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ A OFFSET(8) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// IRQ mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ I OFFSET(7) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// FIQ mask bit. The possible values of this bit are:
+ ///
+ /// 0 Exception not masked.
+ /// 1 Exception masked.
+ F OFFSET(6) NUMBITS(1) [
+ Unmasked = 0,
+ Masked = 1
+ ],
+
+ /// AArch64 state (Exception level and selected SP) that an exception was taken from. The
+ /// possible values are:
+ ///
+ /// M[3:0] | State
+ /// --------------
+ /// 0b0000 | EL0t
+ /// 0b0100 | EL1t
+ /// 0b0101 | EL1h
+ /// 0b1000 | EL2t
+ /// 0b1001 | EL2h
+ ///
+ /// Other values are reserved, and returning to an Exception level that is using AArch64
+ /// with a reserved value in this field is treated as an illegal exception return.
+ ///
+ /// The bits in this field are interpreted as follows:
+ /// - M[3:2] holds the Exception Level.
+ /// - M[1] is unused and is RES 0 for all non-reserved values.
+ /// - M[0] is used to select the SP:
+ /// - 0 means the SP is always SP0.
+ /// - 1 means the exception SP is determined by the EL.
+ M OFFSET(0) NUMBITS(4) [
+ EL0t = 0b0000,
+ EL1t = 0b0100,
+ EL1h = 0b0101,
+ EL2t = 0b1000,
+ EL2h = 0b1001
+ ]
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = SPSR_EL3::Register;
+
+ sys_coproc_read_raw!(u64, "SPSR_EL3", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = SPSR_EL3::Register;
+
+ sys_coproc_write_raw!(u64, "SPSR_EL3", "x");
+}
+
+pub const SPSR_EL3: Reg = Reg {};
diff --git a/src/registers/tcr_el1.rs b/src/registers/tcr_el1.rs
new file mode 100644
index 0000000..8ab1308
--- /dev/null
+++ b/src/registers/tcr_el1.rs
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Translation Control Register - EL1
+//!
+//! The control register for stage 1 of the EL1&0 translation regime.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub TCR_EL1 [
+ /// When ARMv8.3-PAuth is implemented:
+ /// Controls the use of the top byte of instruction addresses for address matching.
+ /// 0 TCR_EL1.TBI1 applies to Instruction and Data accesses.
+ /// 1 TCR_EL1.TBI1 applies to Data accesses only.
+ /// This affects addresses where the address would be translated by tables pointed
+ /// to by TTBR1_EL1. This field resets to an architecturally UNKNOWN value.
+ /// Otherwise:
+ /// Reserved, RES0.
+ TBID1 OFFSET(52) NUMBITS(1) [],
+
+ /// When ARMv8.3-PAuth is implemented:
+ /// Controls the use of the top byte of instruction addresses for address matching.
+ /// 0 TCR_EL1.TBI0 applies to Instruction and Data accesses.
+ /// 1 TCR_EL1.TBI0 applies to Data accesses only.
+ /// This affects addresses where the address would be translated by tables pointed
+ /// to by TTBR0_EL1. This field resets to an architecturally UNKNOWN value.
+ /// Otherwise:
+ /// Reserved, RES0.
+ TBID0 OFFSET(51) NUMBITS(1) [],
+
+ /// Top Byte ignored - indicates whether the top byte of an address is used for address
+ /// match for the TTBR1_EL1 region, or ignored and used for tagged addresses. Defined values
+ /// are:
+ ///
+ /// 0 Top Byte used in the address calculation.
+ ///
+ /// 1 Top Byte ignored in the address calculation.
+ ///
+ /// This affects addresses generated in EL0 and EL1 using AArch64 where the address would be
+ /// translated by tables pointed to by TTBR1_EL1. It has an effect whether the EL1&0
+ /// translation regime is enabled or not.
+ ///
+ /// If ARMv8.3-PAuth is implemented and TCR_EL1.TBID1 is 1, then this field only applies to
+ /// Data accesses.
+ /// Otherwise, if the value of TBI1 is 1 and bit [55] of the target address to be stored to
+ /// the PC is 0, then bits[63:56] of that target address are also set to 0 before the
+ /// address is stored in the PC, in the following cases:
+ ///
+ /// • A branch or procedure return within EL0 or EL1.
+ /// • An exception taken to EL1.
+ /// • An exception return to EL0 or EL1.
+ TBI1 OFFSET(38) NUMBITS(1) [
+ Used = 0,
+ Ignored = 1
+ ],
+
+ /// Top Byte ignored - indicates whether the top byte of an address is used for address
+ /// match for the TTBR0_EL1 region, or ignored and used for tagged addresses. Defined values
+ /// are:
+ ///
+ /// 0 Top Byte used in the address calculation.
+ ///
+ /// 1 Top Byte ignored in the address calculation.
+ ///
+ /// This affects addresses generated in EL0 and EL1 using AArch64 where the address would be
+ /// translated by tables pointed to by TTBR0_EL1. It has an effect whether the EL1&0
+ /// translation regime is enabled or not.
+ ///
+ /// If ARMv8.3-PAuth is implemented and TCR_EL1.TBID0 is 1, then this field only applies to
+ /// Data accesses.
+ /// Otherwise, if the value of TBI0 is 1 and bit [55] of the target address to be stored to
+ /// the PC is 0, then bits[63:56] of that target address are also set to 0 before the
+ /// address is stored in the PC, in the following cases:
+ ///
+ /// • A branch or procedure return within EL0 or EL1.
+ /// • An exception taken to EL1.
+ /// • An exception return to EL0 or EL1.
+ TBI0 OFFSET(37) NUMBITS(1) [
+ Used = 0,
+ Ignored = 1
+ ],
+
+ /// ASID Size. Defined values are:
+ ///
+ /// 0 8 bit - the upper 8 bits of TTBR0_EL1 and TTBR1_EL1 are ignored by hardware for every
+ /// purpose except reading back the register, and are treated as if they are all
+ /// zeros for when used for allocation and matching entries in the TLB.
+ ///
+ /// 1 16 bit - the upper 16 bits of TTBR0_EL1 and TTBR1_EL1 are used for allocation and
+ /// matching in the TLB.
+ ///
+ /// If the implementation has only 8 bits of ASID, this field is RES0.
+ AS OFFSET(36) NUMBITS(1) [
+ ASID8Bits = 0,
+ ASID16Bits = 1
+ ],
+
+ /// Intermediate Physical Address Size.
+ ///
+ /// 000 32 bits, 4GiB.
+ /// 001 36 bits, 64GiB.
+ /// 010 40 bits, 1TiB.
+ /// 011 42 bits, 4TiB.
+ /// 100 44 bits, 16TiB.
+ /// 101 48 bits, 256TiB.
+ /// 110 52 bits, 4PiB
+ ///
+ /// Other values are reserved.
+ ///
+ /// The reserved values behave in the same way as the 101 or 110 encoding, but software must
+ /// not rely on this property as the behavior of the reserved values might change in a
+ /// future revision of the architecture.
+ ///
+ /// The value 110 is permitted only if ARMv8.2-LPA is implemented and the translation
+ /// granule size is 64KiB.
+ ///
+ /// In an implementation that supports 52-bit PAs, if the value of this field is not 110 ,
+ /// then bits[51:48] of every translation table base address for the stage of translation
+ /// controlled by TCR_EL1 are 0000.
+ IPS OFFSET(32) NUMBITS(3) [
+ Bits_32 = 0b000,
+ Bits_36 = 0b001,
+ Bits_40 = 0b010,
+ Bits_42 = 0b011,
+ Bits_44 = 0b100,
+ Bits_48 = 0b101,
+ Bits_52 = 0b110
+ ],
+
+ /// Granule size for the TTBR1_EL1.
+ ///
+ /// 10 4KiB
+ /// 01 16KiB
+ /// 11 64KiB
+ ///
+ /// Other values are reserved.
+ ///
+ /// If the value is programmed to either a reserved value, or a size that has not been
+ /// implemented, then the hardware will treat the field as if it has been programmed to an
+ /// IMPLEMENTATION DEFINED choice of the sizes that has been implemented for all purposes
+ /// other than the value read back from this register.
+ ///
+ /// It is IMPLEMENTATION DEFINED whether the value read back is the value programmed or the
+ /// value that corresponds to the size chosen.
+ TG1 OFFSET(30) NUMBITS(2) [
+ KiB_4 = 0b10,
+ KiB_16 = 0b01,
+ KiB_64 = 0b11
+ ],
+
+ /// Shareability attribute for memory associated with translation table walks using
+ /// TTBR1_EL1.
+ ///
+ /// 00 Non-shareable
+ /// 10 Outer Shareable
+ /// 11 Inner Shareable
+ ///
+ /// Other values are reserved.
+ SH1 OFFSET(28) NUMBITS(2) [
+ None = 0b00,
+ Outer = 0b10,
+ Inner = 0b11
+ ],
+
+ /// Outer cacheability attribute for memory associated with translation table walks using
+ /// TTBR1_EL1.
+ ///
+ /// 00 Normal memory, Outer Non-cacheable
+ ///
+ /// 01 Normal memory, Outer Write-Back Read-Allocate Write-Allocate Cacheable
+ ///
+ /// 10 Normal memory, Outer Write-Through Read-Allocate No Write-Allocate Cacheable
+ ///
+ /// 11 Normal memory, Outer Write-Back Read-Allocate No Write-Allocate Cacheable
+ ORGN1 OFFSET(26) NUMBITS(2) [
+ NonCacheable = 0b00,
+ WriteBack_ReadAlloc_WriteAlloc_Cacheable = 0b01,
+ WriteThrough_ReadAlloc_NoWriteAlloc_Cacheable = 0b10,
+ WriteBack_ReadAlloc_NoWriteAlloc_Cacheable = 0b11
+ ],
+
+ /// Inner cacheability attribute for memory associated with translation
+ /// table walks using TTBR1_EL1.
+ ///
+ /// 00 Normal memory, Inner Non-cacheable
+ ///
+ /// 01 Normal memory, Inner Write-Back Read-Allocate Write-Allocate Cacheable
+ ///
+ /// 10 Normal memory, Inner Write-Through Read-Allocate No Write-Allocate Cacheable
+ ///
+ /// 11 Normal memory, Inner Write-Back Read-Allocate No Write-Allocate Cacheable
+ IRGN1 OFFSET(24) NUMBITS(2) [
+ NonCacheable = 0b00,
+ WriteBack_ReadAlloc_WriteAlloc_Cacheable = 0b01,
+ WriteThrough_ReadAlloc_NoWriteAlloc_Cacheable = 0b10,
+ WriteBack_ReadAlloc_NoWriteAlloc_Cacheable = 0b11
+ ],
+
+ /// Translation table walk disable for translations using TTBR1_EL1. This bit controls
+ /// whether a translation table walk is performed on a TLB miss, for an address that is
+ /// translated using TTBR1_EL1. The encoding of this bit is:
+ ///
+ /// 0 Perform translation table walks using TTBR1_EL1.
+ ///
+ /// 1 A TLB miss on an address that is translated using TTBR1_EL1 generates a Translation
+ /// fault. No translation table walk is performed.
+ EPD1 OFFSET(23) NUMBITS(1) [
+ EnableTTBR1Walks = 0,
+ DisableTTBR1Walks = 1
+ ],
+
+ /// Selects whether TTBR0_EL1 or TTBR1_EL1 defines the ASID. The encoding of this bit is:
+ ///
+ /// 0 TTBR0_EL1.ASID defines the ASID.
+ /// 1 TTBR1_EL1.ASID defines the ASID.
+ A1 OFFSET(22) NUMBITS(1) [
+ TTBR0 = 0,
+ TTBR1 = 1
+ ],
+
+ /// The size offset of the memory region addressed by TTBR1_EL1. The region size is
+ /// 2^(64-T1SZ) bytes.
+ ///
+ /// The maximum and minimum possible values for T1SZ depend on the level of translation
+ /// table and the memory translation granule size, as described in the AArch64 Virtual
+ /// Memory System Architecture chapter.
+ ///
+ /// This field resets to an architecturally UNKNOWN value.
+ T1SZ OFFSET(16) NUMBITS(6) [],
+
+ /// Granule size for the TTBR0_EL1.
+ ///
+ /// 00 4KiB
+ /// 01 64KiB
+ /// 10 16KiB
+ ///
+ /// Other values are reserved.
+ ///
+ /// If the value is programmed to either a reserved value, or a size that has not been
+ /// implemented, then the hardware will treat the field as if it has been programmed to an
+ /// IMPLEMENTATION DEFINED choice of the sizes that has been implemented for all purposes
+ /// other than the value read back from this register.
+ ///
+ /// It is IMPLEMENTATION DEFINED whether the value read back is the value programmed or the
+ /// value that corresponds to the size chosen.
+ TG0 OFFSET(14) NUMBITS(2) [
+ KiB_4 = 0b00,
+ KiB_16 = 0b10,
+ KiB_64 = 0b01
+ ],
+
+ /// Shareability attribute for memory associated with translation table walks using
+ /// TTBR0_EL1.
+ ///
+ /// 00 Non-shareable
+ /// 10 Outer Shareable
+ /// 11 Inner Shareable
+ ///
+ /// Other values are reserved.
+ SH0 OFFSET(12) NUMBITS(2) [
+ None = 0b00,
+ Outer = 0b10,
+ Inner = 0b11
+ ],
+
+ /// Outer cacheability attribute for memory associated with translation table walks using
+ /// TTBR0_EL1.
+ ///
+ /// 00 Normal memory, Outer Non-cacheable
+ ///
+ /// 01 Normal memory, Outer Write-Back Read-Allocate Write-Allocate Cacheable
+ ///
+ /// 10 Normal memory, Outer Write-Through Read-Allocate No Write-Allocate Cacheable
+ ///
+ /// 11 Normal memory, Outer Write-Back Read-Allocate No Write-Allocate Cacheable
+ ORGN0 OFFSET(10) NUMBITS(2) [
+ NonCacheable = 0b00,
+ WriteBack_ReadAlloc_WriteAlloc_Cacheable = 0b01,
+ WriteThrough_ReadAlloc_NoWriteAlloc_Cacheable = 0b10,
+ WriteBack_ReadAlloc_NoWriteAlloc_Cacheable = 0b11
+ ],
+
+ /// Inner cacheability attribute for memory associated with translation table walks using
+ /// TTBR0_EL1.
+ ///
+ /// 00 Normal memory, Inner Non-cacheable
+ ///
+ /// 01 Normal memory, Inner Write-Back Read-Allocate Write-Allocate Cacheable
+ ///
+ /// 10 Normal memory, Inner Write-Through Read-Allocate No Write-Allocate Cacheable
+ ///
+ /// 11 Normal memory, Inner Write-Back Read-Allocate No Write-Allocate Cacheable
+ IRGN0 OFFSET(8) NUMBITS(2) [
+ NonCacheable = 0b00,
+ WriteBack_ReadAlloc_WriteAlloc_Cacheable = 0b01,
+ WriteThrough_ReadAlloc_NoWriteAlloc_Cacheable = 0b10,
+ WriteBack_ReadAlloc_NoWriteAlloc_Cacheable = 0b11
+ ],
+
+ /// Translation table walk disable for translations using TTBR0_EL1. This bit controls
+ /// whether a translation table walk is performed on a TLB miss, for an address that is
+ /// translated using TTBR0_EL1. The encoding of this bit is:
+ ///
+ /// 0 Perform translation table walks using TTBR0_EL1.
+ ///
+ /// 1 A TLB miss on an address that is translated using TTBR0_EL1 generates a Translation
+ /// fault. No translation table walk is performed.
+ EPD0 OFFSET(7) NUMBITS(1) [
+ EnableTTBR0Walks = 0,
+ DisableTTBR0Walks = 1
+ ],
+
+ /// The size offset of the memory region addressed by TTBR0_EL1. The region size is
+ /// 2^(64-T0SZ) bytes.
+ ///
+ /// The maximum and minimum possible values for T0SZ depend on the level of translation
+ /// table and the memory translation granule size, as described in the AArch64 Virtual
+ /// Memory System Architecture chapter.
+ T0SZ OFFSET(0) NUMBITS(6) []
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = TCR_EL1::Register;
+
+ sys_coproc_read_raw!(u64, "TCR_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = TCR_EL1::Register;
+
+ sys_coproc_write_raw!(u64, "TCR_EL1", "x");
+}
+
+pub const TCR_EL1: Reg = Reg {};
diff --git a/src/registers/tcr_el2.rs b/src/registers/tcr_el2.rs
new file mode 100644
index 0000000..386ded0
--- /dev/null
+++ b/src/registers/tcr_el2.rs
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Bradley Landherr <landhb@users.noreply.github.com>
+
+//! Translation Control Register - EL2
+//!
+//! The control register for stage 1 of the EL2, or EL2&0 translation regime.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub TCR_EL2 [
+
+ /// Top Byte ignored - indicates whether the top byte of an address is used for address
+ /// match for the TTBR0_EL2 region, or ignored and used for tagged addresses. Defined values
+ /// are:
+ ///
+ /// 0 Top Byte used in the address calculation.
+ ///
+ /// 1 Top Byte ignored in the address calculation.
+ ///
+ /// This affects addresses generated in EL2 using AArch64 where the address would be
+ /// translated by tables pointed to by TTBR0_EL2. It has an effect whether the EL2,
+ /// or EL2&0, translation regime is enabled or not.
+ ///
+ /// If ARMv8.3-PAuth is implemented and TCR_EL2.TBID1 is 1, then this field only applies to
+ /// Data accesses.
+ ///
+ /// If the value of TBI is 1, then bits[63:56] of that target address are also set to 0
+ /// before the address is stored in the PC, in the following cases:
+ ///
+ /// • A branch or procedure return within EL2.
+ /// • An exception taken to EL2.
+ /// • An exception return to EL2.
+ TBI OFFSET(20) NUMBITS(1) [
+ Used = 0,
+ Ignored = 1
+ ],
+
+ /// Physical Address Size.
+ ///
+ /// 000 32 bits, 4GiB.
+ /// 001 36 bits, 64GiB.
+ /// 010 40 bits, 1TiB.
+ /// 011 42 bits, 4TiB.
+ /// 100 44 bits, 16TiB.
+ /// 101 48 bits, 256TiB.
+ /// 110 52 bits, 4PB
+ ///
+ /// Other values are reserved.
+ ///
+ /// The reserved values behave in the same way as the 101 or 110 encoding, but software must
+ /// not rely on this property as the behavior of the reserved values might change in a
+ /// future revision of the architecture.
+ ///
+ /// The value 110 is permitted only if ARMv8.2-LPA is implemented and the translation
+ /// granule size is 64KiB.
+ ///
+ /// In an implementation that supports 52-bit PAs, if the value of this field is not 110 ,
+ /// then bits[51:48] of every translation table base address for the stage of translation
+ /// controlled by TCR_EL2 are 0000.
+ PS OFFSET(16) NUMBITS(3) [
+ Bits_32 = 0b000,
+ Bits_36 = 0b001,
+ Bits_40 = 0b010,
+ Bits_42 = 0b011,
+ Bits_44 = 0b100,
+ Bits_48 = 0b101,
+ Bits_52 = 0b110
+ ],
+
+ /// Granule size for the TTBR0_EL2.
+ ///
+ /// 0b00 4KiB
+ /// 0b01 64KiB
+ /// 0b10 16KiB
+ ///
+ /// Other values are reserved.
+ ///
+ /// If the value is programmed to either a reserved value, or a size that has not been
+ /// implemented, then the hardware will treat the field as if it has been programmed to an
+ /// IMPLEMENTATION DEFINED choice of the sizes that has been implemented for all purposes
+ /// other than the value read back from this register.
+ ///
+ /// It is IMPLEMENTATION DEFINED whether the value read back is the value programmed or the
+ /// value that corresponds to the size chosen.
+ TG0 OFFSET(14) NUMBITS(2) [
+ KiB_4 = 0b00,
+ KiB_64 = 0b01,
+ KiB_16 = 0b10
+ ],
+
+ /// Shareability attribute for memory associated with translation table walks using
+ /// TTBR0_EL2.
+ ///
+ /// 00 Non-shareable
+ /// 01 Reserved
+ /// 10 Outer Shareable
+ /// 11 Inner Shareable
+ ///
+ /// Other values are reserved.
+ SH0 OFFSET(12) NUMBITS(2) [
+ None = 0b00,
+ Outer = 0b10,
+ Inner = 0b11
+ ],
+
+ /// Outer cacheability attribute for memory associated with translation table walks using
+ /// TTBR0_EL2.
+ ///
+ /// 00 Normal memory, Outer Non-cacheable
+ ///
+ /// 01 Normal memory, Outer Write-Back Read-Allocate Write-Allocate Cacheable
+ ///
+ /// 10 Normal memory, Outer Write-Through Read-Allocate No Write-Allocate Cacheable
+ ///
+ /// 11 Normal memory, Outer Write-Back Read-Allocate No Write-Allocate Cacheable
+ ORGN0 OFFSET(10) NUMBITS(2) [
+ NonCacheable = 0b00,
+ WriteBack_ReadAlloc_WriteAlloc_Cacheable = 0b01,
+ WriteThrough_ReadAlloc_NoWriteAlloc_Cacheable = 0b10,
+ WriteBack_ReadAlloc_NoWriteAlloc_Cacheable = 0b11
+ ],
+
+ /// Inner cacheability attribute for memory associated with translation table walks using
+ /// TTBR0_EL2.
+ ///
+ /// 00 Normal memory, Inner Non-cacheable
+ ///
+ /// 01 Normal memory, Inner Write-Back Read-Allocate Write-Allocate Cacheable
+ ///
+ /// 10 Normal memory, Inner Write-Through Read-Allocate No Write-Allocate Cacheable
+ ///
+ /// 11 Normal memory, Inner Write-Back Read-Allocate No Write-Allocate Cacheable
+ IRGN0 OFFSET(8) NUMBITS(2) [
+ NonCacheable = 0b00,
+ WriteBack_ReadAlloc_WriteAlloc_Cacheable = 0b01,
+ WriteThrough_ReadAlloc_NoWriteAlloc_Cacheable = 0b10,
+ WriteBack_ReadAlloc_NoWriteAlloc_Cacheable = 0b11
+ ],
+
+
+ /// The size offset of the memory region addressed by TTBR0_EL2. The region size is
+ /// 2^(64-T0SZ) bytes.
+ ///
+ /// The maximum and minimum possible values for T0SZ depend on the level of translation
+ /// table and the memory translation granule size, as described in the AArch64 Virtual
+ /// Memory System Architecture chapter.
+ T0SZ OFFSET(0) NUMBITS(6) []
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = TCR_EL2::Register;
+
+ sys_coproc_read_raw!(u64, "TCR_EL2", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = TCR_EL2::Register;
+
+ sys_coproc_write_raw!(u64, "TCR_EL2", "x");
+}
+
+pub const TCR_EL2: Reg = Reg {};
diff --git a/src/registers/tpidr_el0.rs b/src/registers/tpidr_el0.rs
new file mode 100644
index 0000000..458aaa5
--- /dev/null
+++ b/src/registers/tpidr_el0.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2020-2022 by the author(s)
+//
+// Author(s):
+// - Erik Verbruggen <erikjv@me.com>
+
+//! Read/Write Software Thread ID Register - EL0.
+//!
+//! Provides a location where software executing at EL0 can store thread identifying information,
+//! for OS management purposes.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "TPIDR_EL0", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "TPIDR_EL0", "x");
+}
+
+pub const TPIDR_EL0: Reg = Reg {};
diff --git a/src/registers/tpidr_el1.rs b/src/registers/tpidr_el1.rs
new file mode 100644
index 0000000..7819a4e
--- /dev/null
+++ b/src/registers/tpidr_el1.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2020-2022 by the author(s)
+//
+// Author(s):
+// - Erik Verbruggen <erikjv@me.com>
+
+//! Software Thread ID Register - EL1.
+//!
+//! Provides a location where software executing at EL1 can store thread identifying information,
+//! for OS management purposes.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "TPIDR_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "TPIDR_EL1", "x");
+}
+
+pub const TPIDR_EL1: Reg = Reg {};
diff --git a/src/registers/tpidrro_el0.rs b/src/registers/tpidrro_el0.rs
new file mode 100644
index 0000000..612e898
--- /dev/null
+++ b/src/registers/tpidrro_el0.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2020-2022 by the author(s)
+//
+// Author(s):
+// - Erik Verbruggen <erikjv@me.com>
+
+//! Read-Only Software Thread ID Register - EL0.
+//!
+//! Provides a location where software executing at EL1 or higher can store thread identifying
+//! information that is visible to software executing at EL0, for OS management purposes.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "TPIDRRO_EL0", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "TPIDRRO_EL0", "x");
+}
+
+pub const TPIDRRO_EL0: Reg = Reg {};
diff --git a/src/registers/ttbr0_el1.rs b/src/registers/ttbr0_el1.rs
new file mode 100644
index 0000000..1307ab2
--- /dev/null
+++ b/src/registers/ttbr0_el1.rs
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Translation Table Base Register 0 - EL1
+//!
+//! Holds the base address of the translation table for the initial lookup for stage 1 of the
+//! translation of an address from the lower VA range in the EL1&0 translation regime, and other
+//! information for this translation regime.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub TTBR0_EL1 [
+ /// An ASID for the translation table base address. The TCR_EL1.A1 field selects either
+ /// TTBR0_EL1.ASID or TTBR1_EL1.ASID.
+ ///
+ /// If the implementation has only 8 bits of ASID, then the upper 8 bits of this field are
+ /// RES 0.
+ ASID OFFSET(48) NUMBITS(16) [],
+
+ /// Translation table base address
+ BADDR OFFSET(1) NUMBITS(47) [],
+
+ /// Common not Private
+ CnP OFFSET(0) NUMBITS(1) []
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = TTBR0_EL1::Register;
+
+ sys_coproc_read_raw!(u64, "TTBR0_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = TTBR0_EL1::Register;
+
+ sys_coproc_write_raw!(u64, "TTBR0_EL1", "x");
+}
+
+impl Reg {
+ #[inline(always)]
+ pub fn get_baddr(&self) -> u64 {
+ self.read(TTBR0_EL1::BADDR) << 1
+ }
+
+ #[inline(always)]
+ pub fn set_baddr(&self, addr: u64) {
+ self.write(TTBR0_EL1::BADDR.val(addr >> 1));
+ }
+}
+
+pub const TTBR0_EL1: Reg = Reg {};
diff --git a/src/registers/ttbr0_el2.rs b/src/registers/ttbr0_el2.rs
new file mode 100644
index 0000000..737e470
--- /dev/null
+++ b/src/registers/ttbr0_el2.rs
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Bradley Landherr <landhb@users.noreply.github.com>
+
+//! Translation Table Base Register 0 - EL2
+//!
+//! Holds the base address of the translation table for the initial lookup for stage 1 of the
+//! translation of an address from the lower VA range for accesses from EL2.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub TTBR0_EL2 [
+ /// Reserved
+ RES0 OFFSET(48) NUMBITS(16) [],
+
+ /// Translation table base address
+ BADDR OFFSET(1) NUMBITS(48) [],
+
+ /// Common not Private
+ CnP OFFSET(0) NUMBITS(1) []
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = TTBR0_EL2::Register;
+
+ sys_coproc_read_raw!(u64, "TTBR0_EL2", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = TTBR0_EL2::Register;
+
+ sys_coproc_write_raw!(u64, "TTBR0_EL2", "x");
+}
+
+impl Reg {
+ #[inline(always)]
+ pub fn get_baddr(&self) -> u64 {
+ self.read(TTBR0_EL2::BADDR) << 1
+ }
+
+ #[inline(always)]
+ pub fn set_baddr(&self, addr: u64) {
+ self.write(TTBR0_EL2::BADDR.val(addr >> 1));
+ }
+}
+
+pub const TTBR0_EL2: Reg = Reg {};
diff --git a/src/registers/ttbr1_el1.rs b/src/registers/ttbr1_el1.rs
new file mode 100644
index 0000000..0626189
--- /dev/null
+++ b/src/registers/ttbr1_el1.rs
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Translation Table Base Register 1 - EL1
+//!
+//! Holds the base address of the translation table for the initial lookup for stage 1 of the
+//! translation of an address from the higher VA range in the EL1&0 translation regime, and other
+//! information for this translation regime.
+
+use tock_registers::{
+ interfaces::{Readable, Writeable},
+ register_bitfields,
+};
+
+register_bitfields! {u64,
+ pub TTBR1_EL1 [
+ /// An ASID for the translation table base address. The TCR_EL1.A1 field selects either
+ /// TTBR0_EL1.ASID or TTBR1_EL1.ASID.
+ ///
+ /// If the implementation has only 8 bits of ASID, then the upper 8 bits of this field are
+ /// RES 0.
+ ASID OFFSET(48) NUMBITS(16) [],
+
+ /// Translation table base address
+ BADDR OFFSET(1) NUMBITS(47) [],
+
+ /// Common not Private
+ CnP OFFSET(0) NUMBITS(1) []
+ ]
+}
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = TTBR1_EL1::Register;
+
+ sys_coproc_read_raw!(u64, "TTBR1_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = TTBR1_EL1::Register;
+
+ sys_coproc_write_raw!(u64, "TTBR1_EL1", "x");
+}
+
+impl Reg {
+ #[inline(always)]
+ pub fn get_baddr(&self) -> u64 {
+ self.read(TTBR1_EL1::BADDR) << 1
+ }
+
+ #[inline(always)]
+ pub fn set_baddr(&self, addr: u64) {
+ self.write(TTBR1_EL1::BADDR.val(addr >> 1));
+ }
+}
+
+pub const TTBR1_EL1: Reg = Reg {};
diff --git a/src/registers/vbar_el1.rs b/src/registers/vbar_el1.rs
new file mode 100644
index 0000000..cef722f
--- /dev/null
+++ b/src/registers/vbar_el1.rs
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+
+//! Vector Base Address Register - EL1
+//!
+//! Holds the vector base address for any exception that is taken to EL1.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "VBAR_EL1", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "VBAR_EL1", "x");
+}
+
+pub const VBAR_EL1: Reg = Reg {};
diff --git a/src/registers/vbar_el2.rs b/src/registers/vbar_el2.rs
new file mode 100644
index 0000000..f624e97
--- /dev/null
+++ b/src/registers/vbar_el2.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Copyright (c) 2018-2022 by the author(s)
+//
+// Author(s):
+// - Andre Richter <andre.o.richter@gmail.com>
+// - Javier Alvarez <javier.alvarez@allthingsembedded.net>
+
+//! Vector Base Address Register - EL2
+//!
+//! Holds the vector base address for any exception that is taken to EL2.
+
+use tock_registers::interfaces::{Readable, Writeable};
+
+pub struct Reg;
+
+impl Readable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_read_raw!(u64, "VBAR_EL2", "x");
+}
+
+impl Writeable for Reg {
+ type T = u64;
+ type R = ();
+
+ sys_coproc_write_raw!(u64, "VBAR_EL2", "x");
+}
+
+pub const VBAR_EL2: Reg = Reg {};