1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Copyright (c) 2018-2022 by the author(s)
//
// Author(s):
//   - Valentin B. <valentin.be@protonmail.com>

//! AArch64 Memory Model Feature Register 2 - EL1
//!
//! Provides information about the implemented memory model and memory
//! management support in AArch64 state.

use tock_registers::{interfaces::Readable, register_bitfields};

register_bitfields! {u64,
    pub ID_AA64MMFR2_EL1 [
        /// Indicates support for the E0PD mechanism.
        E0PD OFFSET(60) NUMBITS(4) [],

        /// Enhanced Virtualization Traps.
        ///
        /// If EL2 is implemented, indicates support for the
        /// HCR_EL2.{TTLBOS, TTLBIS, TOCU, TICAB, TID4} traps.
        EVT OFFSET(56) NUMBITS(4) [
            /// None of the aforementioned traps are supported.
            Nothing = 0b0000,
            /// All aforementioned traps but the HCR_EL2.{TTLBOS, TTLBBIS}
            /// ones are supported.
            NoTtl = 0b0001,
            /// All the aforementioned HCR_EL2 traps are supported.
            Everything = 0b0010
        ],

        /// Allows identification of the requirements of the hardware to have
        /// break-before-make sequences when changing block size for a translation.
        BBM OFFSET(52) NUMBITS(4) [
            /// Level 0 support for changing block size is supported.
            Level0 = 0b0000,
            /// Level 1 support for changing block size is supported.
            Level1 = 0b0001,
            /// Level 2 support for changing block size is supported.
            Level2 = 0b0010
        ],

        /// Indicates support for TTL field in address operations.
        TTL OFFSET(48) NUMBITS(4) [],

        /// Indicates support for HCR_EL2.FWB.
        FWB OFFSET(40) NUMBITS(4) [],

        /// Indicates the value of ESR_ELx.EC that reports an exception generated by
        /// a read access to the feature ID space.
        ///
        /// - When reading 0, only read access exceptions other than HCR_EL2.TIDx,
        /// SCTLR_EL1.UCT, or SCTLR_EL2.UCT traps are reported by ESR_ELx.EC == 0.
        ///
        /// - When reading 1, all read access exceptions are reported by ESR_ELx.EC == 0x18.
        IDS OFFSET(36) NUMBITS(4) [],

        /// Identifies support for unaligned single-copy atomicity and atomic functions.
        AT OFFSET(32) NUMBITS(4) [],

        /// Identifies support for small translation tables.
        ST OFFSET(28) NUMBITS(4) [],

        /// If EL2 is implemented, indicates support for the use of nested virtualization.
        NV OFFSET(24) NUMBITS(4) [
            /// Nested virtualization is not supported.
            Unsupported = 0b0000,
            /// The HCR_EL2.{AT, NV1, NV} bits are implemented.
            Partial = 0b001,
            /// The VNCR_EL2 register and the HCR_EL2.{NV2, AT, NV1, NV} bits are implemented.
            Full = 0b0010
        ],

        /// Support for the use of revised `CCSIDR_EL1` register format.
        CCIDX OFFSET(20) NUMBITS(4) [],

        /// Indicates support for a larger virtual address.
        ///
        /// When this reads 1, 52-bit VAs when using the 64KB translation granule are
        /// supported along with the standard 48-bit VAs.
        VARange OFFSET(16) NUMBITS(4) [],

        /// Indicates support for the IESB bit in the SCTLR_ELx registers.
        IESB OFFSET(12) NUMBITS(4) [],

        /// Indicates support for LSMAOE and nTLSMD bits in SCTLR_EL1 and SCTLR_EL2.
        LSM OFFSET(8) NUMBITS(4) [],

        /// Indicates support for User Access Overrides.
        UAO OFFSET(4) NUMBITS(4) [],

        /// Indicates support for Common not Private translations.
        CnP OFFSET(0) NUMBITS(4) []
    ]
}

pub struct Reg;

impl Readable for Reg {
    type T = u64;
    type R = ID_AA64MMFR2_EL1::Register;

    sys_coproc_read_raw!(u64, "ID_AA64MMFR2_EL1", "x");
}

pub const ID_AA64MMFR2_EL1: Reg = Reg;