// SPDX-FileCopyrightText: Copyright 2023-2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
// SPDX-License-Identifier: MIT OR Apache-2.0

#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![cfg_attr(not(test), no_std)]

extern crate alloc;

use core::arch::asm;
use core::iter::zip;
use core::ops::Range;
use core::{fmt, panic};

use alloc::boxed::Box;
use alloc::format;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use log::debug;

use bitflags::bitflags;
use packed_struct::prelude::*;

use self::descriptor::DescriptorType;

use self::descriptor::{Attributes, DataAccessPermissions, Descriptor, Shareability};
use self::kernel_space::KernelSpace;
use self::page_pool::{Page, PagePool, Pages};
use self::region::{PhysicalRegion, VirtualRegion};
use self::region_pool::{Region, RegionPool, RegionPoolError};

mod descriptor;
pub mod kernel_space;
pub mod page_pool;
mod region;
mod region_pool;

/// The first level of memory descriptors table which
#[repr(C, align(512))]
pub struct BaseTable {
    pub descriptors: [Descriptor; 64],
}

impl BaseTable {
    pub fn new() -> Self {
        BaseTable {
            descriptors: core::array::from_fn(|_| Descriptor::default()),
        }
    }
}

/// Translation table error type
#[derive(Debug)]
pub enum XlatError {
    InvalidParameterError(String),
    AllocationError(String),
    AlignmentError(String),
    Overflow,
    InvalidOperation(String),
    Overlap,
    NotFound,
    RegionPoolError(RegionPoolError),
}

/// Memory attributes
///
/// MAIR_EL1 should be configured in the same way in startup.s
#[derive(PrimitiveEnum_u8, Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum MemoryAttributesIndex {
    #[default]
    Device_nGnRnE = 0x00,
    Normal_IWBWA_OWBWA = 0x01,
}

bitflags! {
    #[derive(Debug, Clone, Copy)]
    pub struct MemoryAccessRights : u32 {
        const R  = 0b00000001;
        const W  = 0b00000010;
        const X  = 0b00000100;
        const NS = 0b00001000;

        const RW = Self::R.bits() | Self::W.bits();
        const RX = Self::R.bits() | Self::X.bits();
        const RWX = Self::R.bits() | Self::W.bits() | Self::X.bits();

        const USER = 0b00010000;
        const DEVICE = 0b00100000;
        const GLOBAL = 0b01000000;
    }
}

impl From<MemoryAccessRights> for Attributes {
    fn from(access_rights: MemoryAccessRights) -> Self {
        let data_access_permissions = match (
            access_rights.contains(MemoryAccessRights::USER),
            access_rights.contains(MemoryAccessRights::W),
        ) {
            (false, false) => DataAccessPermissions::ReadOnly_None,
            (false, true) => DataAccessPermissions::ReadWrite_None,
            (true, false) => DataAccessPermissions::ReadOnly_ReadOnly,
            (true, true) => DataAccessPermissions::ReadWrite_ReadWrite,
        };

        let mem_attr_index = if access_rights.contains(MemoryAccessRights::DEVICE) {
            MemoryAttributesIndex::Device_nGnRnE
        } else {
            MemoryAttributesIndex::Normal_IWBWA_OWBWA
        };

        Attributes {
            uxn: !access_rights.contains(MemoryAccessRights::X)
                || !access_rights.contains(MemoryAccessRights::USER),
            pxn: !access_rights.contains(MemoryAccessRights::X)
                || access_rights.contains(MemoryAccessRights::USER),
            contiguous: false,
            not_global: !access_rights.contains(MemoryAccessRights::GLOBAL),
            access_flag: true,
            shareability: Shareability::NonShareable,
            data_access_permissions,
            non_secure: access_rights.contains(MemoryAccessRights::NS),
            mem_attr_index,
        }
    }
}

#[derive(PartialEq)]
struct Block {
    pa: usize,
    va: usize,
    granule: usize,
}

impl Block {
    fn new(pa: usize, va: usize, granule: usize) -> Self {
        assert!(Xlat::GRANULE_SIZES.contains(&granule));
        Self { pa, va, granule }
    }
}

impl fmt::Debug for Block {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Block")
            .field("pa", &format_args!("{:#010x}", self.pa))
            .field("va", &format_args!("{:#010x}", self.va))
            .field("granule", &format_args!("{:#010x}", self.granule))
            .finish()
    }
}

/// Enum for selecting TTBR0_EL1 or TTBR1_EL1
#[allow(clippy::upper_case_acronyms)]
pub enum TTBR {
    TTBR0_EL1,
    TTBR1_EL1,
}

pub struct Xlat {
    base_table: Box<BaseTable>,
    page_pool: PagePool,
    regions: RegionPool<VirtualRegion>,
}

/// Memory translation table handling
/// # High level interface
/// * allocate and map zero initialized region (with or without VA)
/// * allocate and map memory region and load contents (with or without VA)
/// * map memory region by PA (with or without VA)
/// * unmap memory region by PA
/// * query PA by VA
/// * set access rights of mapped memory areas
/// * active mapping
///
/// # Debug features
/// * print translation table details
///
/// # Region level interface
/// * map regions
/// * unmap region
/// * find a mapped region which contains
/// * find empty area for region
/// * set access rights for a region
/// * create blocks by region
///
/// # Block level interface
/// * map block
/// * unmap block
/// * set access rights of block
impl Xlat {
    pub const GRANULE_SIZES: [usize; 4] = [0, 0x4000_0000, 0x0020_0000, 0x0000_1000];

    pub fn new(page_pool: PagePool, va_range: Range<usize>) -> Self {
        let mut regions = RegionPool::new();
        regions
            .add(VirtualRegion::new(va_range.start, va_range.len()))
            .unwrap();
        Self {
            base_table: Box::new(BaseTable::new()),
            page_pool,
            regions,
        }
    }

    /// Allocate memory pages from the page pool, maps it to the given VA and fills it with the
    /// initial data
    /// # Arguments
    /// * va: Virtual address of the memory area
    /// * data: Data to be loaded to the memory area
    /// * access_rights: Memory access rights of the area
    /// # Return value
    /// * Virtual address of the mapped memory
    pub fn allocate_initalized_range(
        &mut self,
        va: Option<usize>,
        data: &[u8],
        access_rights: MemoryAccessRights,
    ) -> Result<usize, XlatError> {
        let mut pages = self.page_pool.allocate_pages(data.len()).map_err(|e| {
            XlatError::AllocationError(format!(
                "Cannot allocate pages for {} bytes ({:?})",
                data.len(),
                e
            ))
        })?;

        pages.copy_data_to_page(data);

        let pages_length = pages.length();
        let physical_region = PhysicalRegion::Allocated(self.page_pool.clone(), pages);
        let region = if let Some(required_va) = va {
            self.regions
                .acquire(required_va, pages_length, physical_region)
        } else {
            self.regions.allocate(pages_length, physical_region)
        }
        .map_err(XlatError::RegionPoolError)?;

        self.map_region(region, access_rights.into())
    }

    /// Allocate memory pages from the page pool, maps it to the given VA and fills it with zeros
    /// # Arguments
    /// * va: Virtual address of the memory area
    /// * length: Length of the memory area in bytes
    /// * access_rights: Memory access rights of the area
    /// # Return value
    /// * Virtual address of the mapped memory
    pub fn allocate_zero_init_range(
        &mut self,
        va: Option<usize>,
        length: usize,
        access_rights: MemoryAccessRights,
    ) -> Result<usize, XlatError> {
        let mut pages = self.page_pool.allocate_pages(length).map_err(|e| {
            XlatError::AllocationError(format!("Cannot allocate pages for {length} bytes ({e:?})"))
        })?;

        pages.zero_init();

        let pages_length = pages.length();
        let physical_region = PhysicalRegion::Allocated(self.page_pool.clone(), pages);
        let region = if let Some(required_va) = va {
            self.regions
                .acquire(required_va, pages_length, physical_region)
        } else {
            self.regions.allocate(pages_length, physical_region)
        }
        .map_err(XlatError::RegionPoolError)?;

        self.map_region(region, access_rights.into())
    }

    /// Map memory area by physical address
    /// # Arguments
    /// * va: Virtual address of the memory area
    /// * pa: Physical address of the memory area
    /// * length: Length of the memory area in bytes
    /// * access_rights: Memory access rights of the area
    /// # Return value
    /// * Virtual address of the mapped memory
    pub fn map_physical_address_range(
        &mut self,
        va: Option<usize>,
        pa: usize,
        length: usize,
        access_rights: MemoryAccessRights,
    ) -> Result<usize, XlatError> {
        let resource = PhysicalRegion::PhysicalAddress(pa);
        let region = if let Some(required_va) = va {
            self.regions.acquire(required_va, length, resource)
        } else {
            self.regions.allocate(length, resource)
        }
        .map_err(XlatError::RegionPoolError)?;

        self.map_region(region, access_rights.into())
    }

    /// Unmap memory area by virtual address
    /// # Arguments
    /// * va: Virtual address
    /// * length: Length of the memory area in bytes
    pub fn unmap_virtual_address_range(
        &mut self,
        va: usize,
        length: usize,
    ) -> Result<(), XlatError> {
        let pa = self.get_pa_by_va(va, length)?;

        let region_to_release = VirtualRegion::new_with_pa(pa, va, length);

        self.unmap_region(&region_to_release)?;

        self.regions
            .release(region_to_release)
            .map_err(XlatError::RegionPoolError)
    }

    /// Query physical address by virtual address range. Only returns a value if the memory area
    /// mapped as continuous area.
    /// # Arguments
    /// * va: Virtual address of the memory area
    /// * length: Length of the memory area in bytes
    /// # Return value
    /// * Physical address of the mapped memory
    pub fn get_pa_by_va(&self, va: usize, length: usize) -> Result<usize, XlatError> {
        let containing_region = self
            .find_containing_region(va, length)
            .ok_or(XlatError::NotFound)?;

        if !containing_region.used() {
            return Err(XlatError::NotFound);
        }

        Ok(containing_region.get_pa_for_va(va))
    }

    /// Sets the memory access right of memory area
    /// # Arguments
    /// * va: Virtual address of the memory area
    /// * length: Length of the memory area in bytes
    /// * access_rights: New memory access rights of the area
    pub fn set_access_rights(
        &mut self,
        va: usize,
        length: usize,
        access_rights: MemoryAccessRights,
    ) -> Result<(), XlatError> {
        let containing_region = self
            .find_containing_region(va, length)
            .ok_or(XlatError::NotFound)?;

        if !containing_region.used() {
            return Err(XlatError::NotFound);
        }

        let region = VirtualRegion::new_with_pa(containing_region.get_pa_for_va(va), va, length);
        self.map_region(region, access_rights.into())?;

        Ok(())
    }

    /// Activate memory mapping represented by the object
    /// # Arguments
    /// * asid: ASID of the table base address
    /// * ttbr: Selects TTBR0_EL1/TTBR1_EL1
    pub fn activate(&self, asid: u8, ttbr: TTBR) {
        let base_table_pa = KernelSpace::kernel_to_pa(self.base_table.descriptors.as_ptr() as u64);
        let ttbr_value = ((asid as u64) << 48) | base_table_pa;
        #[cfg(target_arch = "aarch64")]
        match ttbr {
            TTBR::TTBR0_EL1 => unsafe {
                asm!(
                    "msr ttbr0_el1, {0}
                     isb",
                    in(reg) ttbr_value)
            },
            TTBR::TTBR1_EL1 => unsafe {
                asm!(
                    "msr ttbr1_el1, {0}
                    isb

                    tlbi	vmalle1
                    dsb	sy
                    isb",
                    in(reg) ttbr_value)
            },
        }
    }

    /// Prints the translation tables to debug console recursively
    pub fn print(&self) {
        debug!(
            "Xlat table -> {:#010x}",
            self.base_table.descriptors.as_ptr() as u64
        );
        Self::print_table(1, 0, &self.base_table.descriptors);
    }

    /// Prints a single translation table to the debug console
    /// # Arguments
    /// * level: Level of the translation table
    /// * va: Base virtual address of the table
    /// * table: Table entries
    pub fn print_table(level: usize, va: usize, table: &[Descriptor]) {
        let level_prefix = match level {
            0 | 1 => "|-",
            2 => "|  |-",
            _ => "|  |  |-",
        };

        for (descriptor, va) in zip(table, (va..).step_by(Self::GRANULE_SIZES[level])) {
            match descriptor.get_descriptor_type(level) {
                DescriptorType::Block => debug!(
                    "{} {:#010x} Block -> {:#010x}",
                    level_prefix,
                    va,
                    descriptor.get_block_output_address(level)
                ),
                DescriptorType::Table => {
                    let next_level_table = unsafe { descriptor.get_next_level_table(level) };
                    debug!(
                        "{} {:#010x} Table -> {:#010x}",
                        level_prefix,
                        va,
                        next_level_table.as_ptr() as usize
                    );
                    Self::print_table(level + 1, va, next_level_table);
                }
                _ => {}
            }
        }
    }

    /// Adds memory region from the translation table. The function splits the region to blocks and
    /// uses the block level functions to do the mapping.
    /// # Arguments
    /// * region: Memory region object
    /// # Return value
    /// * Virtual address of the mapped memory
    fn map_region(
        &mut self,
        region: VirtualRegion,
        attributes: Attributes,
    ) -> Result<usize, XlatError> {
        let blocks = Self::split_region_to_blocks(region.get_pa(), region.base(), region.length())?;
        for block in blocks {
            self.map_block(block, attributes.clone());
        }

        Ok(region.base())
    }

    /// Remove memory region from the translation table. The function splits the region to blocks
    /// and uses the block level functions to do the unmapping.
    /// # Arguments
    /// * region: Memory region object
    fn unmap_region(&mut self, region: &VirtualRegion) -> Result<(), XlatError> {
        let blocks = Self::split_region_to_blocks(region.get_pa(), region.base(), region.length())?;
        for block in blocks {
            self.unmap_block(block);
        }

        Ok(())
    }

    /// Find mapped region that contains the whole region
    /// # Arguments
    /// * region: Virtual address to look for
    /// # Return value
    /// * Reference to virtual region if found
    fn find_containing_region(&self, va: usize, length: usize) -> Option<&VirtualRegion> {
        self.regions.find_containing_region(va, length).ok()
    }

    /// Splits memory region to blocks that matches the granule size of the translation table.
    /// # Arguments
    /// * pa: Physical address
    /// * va: Virtual address
    /// * length: Region size in bytes
    /// # Return value
    /// * Vector of granule sized blocks
    fn split_region_to_blocks(
        mut pa: usize,
        mut va: usize,
        mut length: usize,
    ) -> Result<Vec<Block>, XlatError> {
        let min_granule_mask = Self::GRANULE_SIZES.last().unwrap() - 1;

        if length == 0 {
            return Err(XlatError::InvalidParameterError(
                "Length cannot be 0".to_string(),
            ));
        }

        if pa & min_granule_mask != 0
            || va & min_granule_mask != 0
            || length & min_granule_mask != 0
        {
            return Err(XlatError::InvalidParameterError(format!(
                "Addresses and length must be aligned {pa:#010x} {va:#010x} {length:#x}"
            )));
        }

        let mut pages = Vec::new();

        while length > 0 {
            for granule in &Self::GRANULE_SIZES {
                if (pa | va) & (*granule - 1) == 0 && length >= *granule {
                    pages.push(Block::new(pa, va, *granule));
                    pa += *granule;
                    va = va.checked_add(*granule).ok_or(XlatError::Overflow)?;

                    length -= *granule;
                    break;
                }
            }
        }

        Ok(pages)
    }

    /// Add block to memory mapping
    /// # Arguments
    /// * block: Memory block that can be represented by a single translation table entry
    /// * attributes: Memory block's permissions, flags
    fn map_block(&mut self, block: Block, attributes: Attributes) {
        Self::set_block_descriptor_recursively(
            attributes,
            block.pa,
            block.va,
            block.granule,
            1,
            self.base_table.descriptors.as_mut_slice(),
            &self.page_pool,
        );
    }

    /// Adds the block descriptor to the translation table along all the intermediate tables the
    /// reach the required granule.
    /// # Arguments
    /// * attributes: Memory block's permssions, flags
    /// * pa: Physical address
    /// * va: Virtual address
    /// * granule: Translation granule in bytes
    /// * level: Translation table level
    /// * table: Translation table on the given level
    /// * page_pool: Page pool where the function can allocate pages for the translation tables
    fn set_block_descriptor_recursively(
        attributes: Attributes,
        pa: usize,
        va: usize,
        granule: usize,
        level: usize,
        table: &mut [Descriptor],
        page_pool: &PagePool,
    ) {
        // Get descriptor of the current level
        let descriptor = &mut table[va / Self::GRANULE_SIZES[level]];

        // We reached the required granule level
        if Self::GRANULE_SIZES[level] == granule {
            descriptor.set_block_descriptor(level, pa, attributes);
            return;
        }

        // Need to iterate forward
        match descriptor.get_descriptor_type(level) {
            DescriptorType::Invalid => {
                let mut page = page_pool.allocate_pages(Page::SIZE).unwrap();
                unsafe {
                    let next_table = page.get_as_slice();
                    descriptor.set_table_descriptor(level, next_table, None);
                }
                Self::set_block_descriptor_recursively(
                    attributes,
                    pa,
                    va & (Self::GRANULE_SIZES[level] - 1),
                    granule,
                    level + 1,
                    unsafe { descriptor.get_next_level_table_mut(level) },
                    page_pool,
                )
            }
            DescriptorType::Block => {
                // Saving current descriptor details
                let current_va = va & !(Self::GRANULE_SIZES[level] - 1);
                let current_pa = descriptor.get_block_output_address(level);
                let current_attributes = descriptor.get_block_attributes(level);

                // Replace block descriptor by table descriptor
                let mut page = page_pool.allocate_pages(Page::SIZE).unwrap();
                unsafe {
                    let next_table = page.get_as_slice();
                    descriptor.set_table_descriptor(level, next_table, None);
                }

                // Explode block descriptor to table entries
                for exploded_va in (current_va..(current_va + Self::GRANULE_SIZES[level]))
                    .step_by(Self::GRANULE_SIZES[level + 1])
                {
                    let offset = exploded_va - current_va;
                    Self::set_block_descriptor_recursively(
                        current_attributes.clone(),
                        current_pa + offset,
                        exploded_va & (Self::GRANULE_SIZES[level] - 1),
                        Self::GRANULE_SIZES[level + 1],
                        level + 1,
                        unsafe { descriptor.get_next_level_table_mut(level) },
                        page_pool,
                    )
                }

                // Invoke self to continue recursion on the newly created level
                Self::set_block_descriptor_recursively(
                    attributes, pa, va, granule, level, table, page_pool,
                );
            }
            DescriptorType::Table => Self::set_block_descriptor_recursively(
                attributes,
                pa,
                va & (Self::GRANULE_SIZES[level] - 1),
                granule,
                level + 1,
                unsafe { descriptor.get_next_level_table_mut(level) },
                page_pool,
            ),
        }
    }

    /// Remove block from memory mapping
    /// # Arguments
    /// * block: memory block that can be represented by a single translation entry
    fn unmap_block(&mut self, block: Block) {
        Self::remove_block_descriptor_recursively(
            block.va,
            block.granule,
            1,
            self.base_table.descriptors.as_mut_slice(),
            &self.page_pool,
        );
    }

    /// Removes block descriptor from the translation table along all the intermediate tables which
    /// become empty during the removal process.
    /// # Arguments
    /// * va: Virtual address
    /// * granule: Translation granule in bytes
    /// * level: Translation table level
    /// * table: Translation table on the given level
    /// * page_pool: Page pool where the function can release the pages of empty tables
    fn remove_block_descriptor_recursively(
        va: usize,
        granule: usize,
        level: usize,
        table: &mut [Descriptor],
        page_pool: &PagePool,
    ) {
        // Get descriptor of the current level
        let descriptor = &mut table[va / Self::GRANULE_SIZES[level]];

        // We reached the required granule level
        if Self::GRANULE_SIZES[level] == granule {
            descriptor.set_block_descriptor_to_invalid(level);
            return;
        }

        // Need to iterate forward
        match descriptor.get_descriptor_type(level) {
            DescriptorType::Invalid => {
                panic!("Cannot remove block from non-existing table");
            }
            DescriptorType::Block => {
                panic!("Cannot remove block with different granule");
            }
            DescriptorType::Table => {
                let next_level_table = unsafe { descriptor.get_next_level_table_mut(level) };
                Self::remove_block_descriptor_recursively(
                    va & (Self::GRANULE_SIZES[level] - 1),
                    granule,
                    level + 1,
                    next_level_table,
                    page_pool,
                );

                if next_level_table.iter().all(|d| !d.is_valid()) {
                    // Empty table
                    let mut page = unsafe {
                        Pages::from_slice(descriptor.set_table_descriptor_to_invalid(level))
                    };
                    page.zero_init();
                    page_pool.release_pages(page).unwrap();
                }
            }
        }
    }

    fn get_descriptor(&mut self, va: usize, granule: usize) -> &mut Descriptor {
        Self::walk_descriptors(va, granule, 0, &mut self.base_table.descriptors)
    }

    fn walk_descriptors(
        va: usize,
        granule: usize,
        level: usize,
        table: &mut [Descriptor],
    ) -> &mut Descriptor {
        // Get descriptor of the current level
        let descriptor = &mut table[va / Self::GRANULE_SIZES[level]];

        if Self::GRANULE_SIZES[level] == granule {
            return descriptor;
        }

        // Need to iterate forward
        match descriptor.get_descriptor_type(level) {
            DescriptorType::Invalid => {
                panic!("Invalid descriptor");
            }
            DescriptorType::Block => {
                panic!("Cannot split existing block descriptor to table");
            }
            DescriptorType::Table => Self::walk_descriptors(
                va & (Self::GRANULE_SIZES[level] - 1),
                granule,
                level + 1,
                unsafe { descriptor.get_next_level_table_mut(level) },
            ),
        }
    }
}

#[test]
fn test_split_to_pages() {
    let pages = Xlat::split_region_to_blocks(0x3fff_c000, 0x3fff_c000, 0x4020_5000).unwrap();
    assert_eq!(Block::new(0x3fff_c000, 0x3fff_c000, 0x1000), pages[0]);
    assert_eq!(Block::new(0x3fff_d000, 0x3fff_d000, 0x1000), pages[1]);
    assert_eq!(Block::new(0x3fff_e000, 0x3fff_e000, 0x1000), pages[2]);
    assert_eq!(Block::new(0x3fff_f000, 0x3fff_f000, 0x1000), pages[3]);
    assert_eq!(Block::new(0x4000_0000, 0x4000_0000, 0x4000_0000), pages[4]);
    assert_eq!(Block::new(0x8000_0000, 0x8000_0000, 0x0020_0000), pages[5]);
    assert_eq!(Block::new(0x8020_0000, 0x8020_0000, 0x1000), pages[6]);
}

#[test]
fn test_split_to_pages_unaligned() {
    let pages = Xlat::split_region_to_blocks(0x3fff_c000, 0x3f20_0000, 0x200000).unwrap();
    for (i, block) in pages.iter().enumerate().take(512) {
        assert_eq!(
            Block::new(0x3fff_c000 + (i << 12), 0x3f20_0000 + (i << 12), 0x1000),
            *block
        );
    }
}
