Initial import.

Bug: 223166344
Change-Id: I0b181158a5316e6122627d4a51301b908581656a
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 {};