# satp.rs - source
Source of the Rust file `/home/runner/.cargo/git/checkouts/riscv-ab2abd16c438337b/11d43cf/src/register/satp.rs`.
Keywords: rust, rustlang, rust-lang

    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
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119

    //! satp register

    #[cfg(riscv)]
    use addr::Frame;
    #[cfg(riscv)]
    use bit_field::BitField;

    /// satp register
    #[derive(Clone, Copy, Debug)]
    pub struct Satp {
        bits: usize,
    }

    impl Satp {
        /// Returns the contents of the register as raw bits
        #[inline]
        pub fn bits(&self) -> usize {
            self.bits
        }

        /// Current address-translation scheme
        #[inline]
        #[cfg(riscv32)]
        pub fn mode(&self) -> Mode {
            match self.bits.get_bit(31) {
                false => Mode::Bare,
                true => Mode::Sv32,
            }
        }

        /// Current address-translation scheme
        #[inline]
        #[cfg(riscv64)]
        pub fn mode(&self) -> Mode {
            match self.bits.get_bits(60..64) {
                0 => Mode::Bare,
                8 => Mode::Sv39,
                9 => Mode::Sv48,
                10 => Mode::Sv57,
                11 => Mode::Sv64,
                _ => unreachable!(),
            }
        }

        /// Address space identifier
        #[inline]
        #[cfg(riscv32)]
        pub fn asid(&self) -> usize {
            self.bits.get_bits(22..31)
        }

        /// Address space identifier
        #[inline]
        #[cfg(riscv64)]
        pub fn asid(&self) -> usize {
            self.bits.get_bits(44..60)
        }

        /// Physical page number
        #[inline]
        #[cfg(riscv32)]
        pub fn ppn(&self) -> usize {
            self.bits.get_bits(0..22)
        }

        /// Physical page number
        #[inline]
        #[cfg(riscv64)]
        pub fn ppn(&self) -> usize {
            self.bits.get_bits(0..44)
        }

        /// Physical frame
        #[inline]
        #[cfg(riscv)]
        pub fn frame(&self) -> Frame {
            Frame::of_ppn(self.ppn())
        }
    }

    #[cfg(riscv32)]
    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
    pub enum Mode {
        Bare = 0,
        Sv32 = 1,
    }

    #[cfg(riscv64)]
    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
    pub enum Mode {
        Bare = 0,
        Sv39 = 8,
        Sv48 = 9,
        Sv57 = 10,
        Sv64 = 11,
    }

    read_csr_as!(Satp, 0x180, __read_satp);
    write_csr_as_usize!(0x180, __write_satp);

    #[inline]
    #[cfg(riscv32)]
    pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) {
        let mut bits = 0usize;
        bits.set_bits(31..32, mode as usize);
        bits.set_bits(22..31, asid);
        bits.set_bits(0..22, ppn);
        _write(bits);
    }

    #[inline]
    #[cfg(riscv64)]
    pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) {
        let mut bits = 0usize;
        bits.set_bits(60..64, mode as usize);
        bits.set_bits(44..60, asid);
        bits.set_bits(0..44, ppn);
        _write(bits);
    }