use kernel_arch_interface::sync::IrqSafeSpinlock;
use libk_mm_interface::{address::PhysicalAddress, table::EntryLevel};

use crate::{
    mem::{
        auto_lower_address,
        table::{PageEntry, PageTable, L1},
        KERNEL_VIRT_OFFSET,
    },
    ArchitectureImpl,
};

pub const IDENTITY_SIZE_L1: usize = 64;

pub(super) static mut KERNEL_L1: PageTable<L1> = const {
    let mut table = PageTable::zeroed();

    let mut index = 0;
    while index < IDENTITY_SIZE_L1 {
        let entry = PageEntry::identity_block(PhysicalAddress::from_usize(index << L1::SHIFT));
        table.entries[index] = entry;
        table.entries[index + ((KERNEL_VIRT_OFFSET >> L1::SHIFT) & 0x1FF)] = entry;
        index += 1;
    }

    table
};
pub(super) static LOCK: IrqSafeSpinlock<ArchitectureImpl, ()> = IrqSafeSpinlock::new(());

pub fn table_physical_address() -> PhysicalAddress {
    PhysicalAddress::from_usize(auto_lower_address(&raw const KERNEL_L1))
}
