fn backup_and_disable_mmu(&self) -> Result<Option<[u32; 4 * 1024]>, Error> {
        // Below are some checks for the register values, which are known to be initialized in this
        // particular way by the existing BROM implementations. We don't strictly need them to
        // exactly match, but still have these safety guards in place in order to detect and review
        // any potential configuration changes in future SoC variants (if one of these checks fails,
        // then it is not a serious problem but more likely just an indication that one of these
        // check needs to be relaxed).

        // Basically, ignore M/Z/I/V/UNK bits and expect no TEX remap.
        // Check `SCTLR` register.
        let sctlr = self.get_sctlr().context("unable to read SCTLR register")?;
        if (sctlr & !((0x7 << 11) | (1 << 6) | 1)) != 0x00C5_0038 {
            bail!("unexpected SCTLR register ({:#010x})", sctlr);
        }
        if (sctlr & 0x0000_0001) == 0 {
            return Ok(None);
        }

        // Check `DACR` register.
        let dacr = self.get_dacr().context("unable to read DACR register")?;
        if dacr != 0x5555_5555 {
            bail!("unexpected DACR register ({:#010x})", dacr);
        }

        // Check `TTBRC` register.
        let ttbcr = self.get_ttbcr().context("unable to read TTBCR register")?;
        if ttbcr != 0x0000_0000 {
            bail!("unexpected TTBCR register ({:#010x})", ttbcr);
        }

        // Check `TTBR0` register
        let ttbr0 = self.get_ttbr0().context("unable to read TTBR0 register")?;
        if (ttbr0 & 0x0000_3FFF) != 0 {
            bail!("unexpected TTBR0 register ({:#010x})", ttbr0);
        }

        // Read MMU translation table.
        let mut tt = [0_u32; 4 * 1024];
        self.fel_read(ttbr0, u32_as_u8_mut(&mut tt)).context({
            format!(
                "could not read the MMU translation table from {:#010x}",
                ttbr0
            )
        })?;
        for (i, le_word) in tt.iter_mut().enumerate() {
            let word = u32::from_le(*le_word);

            // Sanity checks:
            if ((word >> 1) & 1) != 1 || ((word >> 18) & 1) != 0 {
                bail!("found a word in the translation table that was not a section descriptor");
            }
            if (word >> 20) != i as u32 {
                bail!("found a word in the translation table that was not a direct mapping");
            }
            *le_word = word;
        }

        // Disable I-cache, MMU and branch prediction
        let arm_code: [u32; 6] = [
            // mrc        15, 0, r0, cr1, cr0, {0}
            0x_ee_11_0f_10_u32.to_le(),
            // bic        r0, r0, #1
            0x_e3_c0_00_01_u32.to_le(),
            // bic        r0, r0, #4096
            0x_e3_c0_0a_01_u32.to_le(),
            // bic        r0, r0, #2048
            0x_e3_c0_0b_02_u32.to_le(),
            // mcr        15, 0, r0, cr1, cr0, {0}
            0x_ee_01_0f_10_u32.to_le(),
            // Return back to FEL
            // bx         lr
            0x_e1_2f_ff_1e_u32.to_le(),
        ];

        self.fel_write(self.soc_info.get_scratch_addr(), u32_as_u8(&arm_code))
            .context({
                "could not write ARM code to memory for disabling I-cache, MMU and branch \
                 prediction"
            })?;
        self.fel_execute(self.soc_info.get_scratch_addr())
            .context({
                "could not execute ARM code to memory to disable I-cache, MMU and branch prediction"
            })?;
        Ok(Some(tt))
    }
/// Backup *MMU* translation table and disable it.
Backup *MMU* translation table and disable it.
Backup * MMU * translation table and disable it .
fn backup_and_disable_mmu(&self) -> Result<Option<[u32; 4 * 1024]>, Error> {
        // Below are some checks for the register values, which are known to be initialized in this
        // particular way by the existing BROM implementations. We don't strictly need them to
        // exactly match, but still have these safety guards in place in order to detect and review
        // any potential configuration changes in future SoC variants (if one of these checks fails,
        // then it is not a serious problem but more likely just an indication that one of these
        // check needs to be relaxed).
        // Basically, ignore M/Z/I/V/UNK bits and expect no TEX remap.
        // Check `SCTLR` register.
        let sctlr = self.get_sctlr().context("unable to read SCTLR register")?;
        if (sctlr & !((0x7 << 11) | (1 << 6) | 1)) != 0x00C5_0038 {
            bail!("unexpected SCTLR register ({:#010x})", sctlr);
        }
        if (sctlr & 0x0000_0001) == 0 {
            return Ok(None);
        }
        // Check `DACR` register.
        let dacr = self.get_dacr().context("unable to read DACR register")?;
        if dacr != 0x5555_5555 {
            bail!("unexpected DACR register ({:#010x})", dacr);
        }
        // Check `TTBRC` register.
        let ttbcr = self.get_ttbcr().context("unable to read TTBCR register")?;
        if ttbcr != 0x0000_0000 {
            bail!("unexpected TTBCR register ({:#010x})", ttbcr);
        }
        // Check `TTBR0` register
        let ttbr0 = self.get_ttbr0().context("unable to read TTBR0 register")?;
        if (ttbr0 & 0x0000_3FFF) != 0 {
            bail!("unexpected TTBR0 register ({:#010x})", ttbr0);
        }
        // Read MMU translation table.
        let mut tt = [0_u32; 4 * 1024];
        self.fel_read(ttbr0, u32_as_u8_mut(&mut tt)).context({
            format!(
                "could not read the MMU translation table from {:#010x}",
                ttbr0
            )
        })?;
        for (i, le_word) in tt.iter_mut().enumerate() {
            let word = u32::from_le(*le_word);
            // Sanity checks:
            if ((word >> 1) & 1) != 1 || ((word >> 18) & 1) != 0 {
                bail!("found a word in the translation table that was not a section descriptor");
            }
            if (word >> 20) != i as u32 {
                bail!("found a word in the translation table that was not a direct mapping");
            }
            *le_word = word;
        }
        // Disable I-cache, MMU and branch prediction
        let arm_code: [u32; 6] = [
            // mrc        15, 0, r0, cr1, cr0, {0}
            0x_ee_11_0f_10_u32.to_le(),
            // bic        r0, r0, #1
            0x_e3_c0_00_01_u32.to_le(),
            // bic        r0, r0, #4096
            0x_e3_c0_0a_01_u32.to_le(),
            // bic        r0, r0, #2048
            0x_e3_c0_0b_02_u32.to_le(),
            // mcr        15, 0, r0, cr1, cr0, {0}
            0x_ee_01_0f_10_u32.to_le(),
            // Return back to FEL
            // bx         lr
            0x_e1_2f_ff_1e_u32.to_le(),
        ];
        self.fel_write(self.soc_info.get_scratch_addr(), u32_as_u8(&arm_code))
            .context({
                "could not write ARM code to memory for disabling I-cache, MMU and branch \
                 prediction"
            })?;
        self.fel_execute(self.soc_info.get_scratch_addr())
            .context({
                "could not execute ARM code to memory to disable I-cache, MMU and branch prediction"
            })?;
        Ok(Some(tt))
    }
fn backup_and_disable_mmu ( & self ) -> Result < Option < [ u32 ; 4 * 1024 ] > , Error > { // Below are some checks for the register values, which are known to be initialized in this // particular way by the existing BROM implementations. We don't strictly need them to // exactly match, but still have these safety guards in place in order to detect and review // any potential configuration changes in future SoC variants (if one of these checks fails, // then it is not a serious problem but more likely just an indication that one of these // check needs to be relaxed). // Basically, ignore M/Z/I/V/UNK bits and expect no TEX remap. // Check `SCTLR` register. let sctlr = self . get_sctlr ( ) . context ( " " ) ? ; if ( sctlr & ! ( ( 0x7 << 11 ) | ( 1 << 6 ) | 1 ) ) != 0x00C5_0038 { bail ! ( " " sctlr ) ; } if ( sctlr & 0x0000_0001 ) == 0 { return Ok ( None ) ; } // Check `DACR` register. let dacr = self . get_dacr ( ) . context ( " " ) ? ; if dacr != 0x5555_5555 { bail ! ( " " dacr ) ; } // Check `TTBRC` register. let ttbcr = self . get_ttbcr ( ) . context ( " " ) ? ; if ttbcr != 0x0000_0000 { bail ! ( " " ttbcr ) ; } // Check `TTBR0` register let ttbr0 = self . get_ttbr0 ( ) . context ( " " ) ? ; if ( ttbr0 & 0x0000_3FFF ) != 0 { bail ! ( " " ttbr0 ) ; } // Read MMU translation table. let mut tt = [ 0_u32 ; 4 * 1024 ] ; self . fel_read ( ttbr0 , u32_as_u8_mut ( & mut tt ) ) . context ( { format ! ( " " ttbr0 ) } ) ? ; for ( i , le_word ) in tt . iter_mut ( ) . enumerate ( ) { let word = u32 :: from_le ( * le_word ) ; // Sanity checks: if ( ( word >> 1 ) & 1 ) != 1 || ( ( word >> 18 ) & 1 ) != 0 { bail ! ( " " ) ; } if ( word >> 20 ) != i as u32 { bail ! ( " " ) ; } * le_word = word ; } // Disable I-cache, MMU and branch prediction let arm_code : [ u32 ; 6 ] = [ // mrc        15, 0, r0, cr1, cr0, {0} 0x_ee_11_0f_10_u32 . to_le ( ) , // bic        r0, r0, #1 0x_e3_c0_00_01_u32 . to_le ( ) , // bic        r0, r0, #4096 0x_e3_c0_0a_01_u32 . to_le ( ) , // bic        r0, r0, #2048 0x_e3_c0_0b_02_u32 . to_le ( ) , // mcr        15, 0, r0, cr1, cr0, {0} 0x_ee_01_0f_10_u32 . to_le ( ) , // Return back to FEL // bx         lr 0x_e1_2f_ff_1e_u32 . to_le ( ) , ] ; self . fel_write ( self . soc_info . get_scratch_addr ( ) , u32_as_u8 ( & arm_code ) ) . context ( { " \
 " } ) ? ; self . fel_execute ( self . soc_info . get_scratch_addr ( ) ) . context ( { " " } ) ? ; Ok ( Some ( tt ) ) }
Backup *MMU* translation table and disable it.
Backup * MMU * translation table and disable it .
&self
&self