diff options
Diffstat (limited to 'src/registers')
50 files changed, 4533 insertions, 0 deletions
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 {}; |