1453452ccSLoGin use core::sync::atomic::{compiler_fence, AtomicBool, Ordering}; 2453452ccSLoGin 3453452ccSLoGin use system_error::SystemError; 4453452ccSLoGin 57a29d4fcSLoGin use crate::{ 6453452ccSLoGin arch::{ 7453452ccSLoGin mm::{ 8453452ccSLoGin kernel_page_flags, INNER_ALLOCATOR, KERNEL_BEGIN_PA, KERNEL_BEGIN_VA, KERNEL_END_PA, 9453452ccSLoGin KERNEL_END_VA, 10453452ccSLoGin }, 11453452ccSLoGin MMArch, 12453452ccSLoGin }, 13453452ccSLoGin driver::firmware::efi::efi_manager, 14453452ccSLoGin kdebug, kinfo, 15453452ccSLoGin libs::lib_ui::screen_manager::scm_disable_put_to_window, 16453452ccSLoGin mm::{ 17453452ccSLoGin allocator::{buddy::BuddyAllocator, bump::BumpAllocator, page_frame::FrameAllocator}, 18453452ccSLoGin kernel_mapper::KernelMapper, 19453452ccSLoGin memblock::mem_block_manager, 20453452ccSLoGin page::PageEntry, 21453452ccSLoGin MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr, 22453452ccSLoGin }, 237a29d4fcSLoGin }; 247a29d4fcSLoGin 25453452ccSLoGin use super::RiscV64MMArch; 26453452ccSLoGin 27453452ccSLoGin pub(super) static mut INITIAL_PGTABLE_VALUE: PhysAddr = PhysAddr::new(0); 28453452ccSLoGin 297a29d4fcSLoGin #[inline(never)] 307a29d4fcSLoGin pub fn mm_early_init() { 317a29d4fcSLoGin unsafe { init_kernel_addr() }; 327a29d4fcSLoGin } 337a29d4fcSLoGin 347a29d4fcSLoGin unsafe fn init_kernel_addr() { 357a29d4fcSLoGin extern "C" { 367a29d4fcSLoGin /// 内核起始label 377a29d4fcSLoGin fn boot_text_start_pa(); 387a29d4fcSLoGin /// 内核结束位置的label 397a29d4fcSLoGin fn _end(); 407a29d4fcSLoGin 417a29d4fcSLoGin fn _start(); 427a29d4fcSLoGin 437a29d4fcSLoGin /// 内核start标签被加载到的物理地址 447a29d4fcSLoGin fn __initial_start_load_paddr(); 457a29d4fcSLoGin } 467a29d4fcSLoGin let initial_start_load_pa = *(__initial_start_load_paddr as usize as *const usize); 477a29d4fcSLoGin let offset = _start as usize - boot_text_start_pa as usize; 487a29d4fcSLoGin let start_pa = initial_start_load_pa - offset; 497a29d4fcSLoGin 507a29d4fcSLoGin let offset2 = _end as usize - boot_text_start_pa as usize; 517a29d4fcSLoGin let end_pa = start_pa + offset2; 527a29d4fcSLoGin 537a29d4fcSLoGin KERNEL_BEGIN_PA = PhysAddr::new(start_pa); 547a29d4fcSLoGin KERNEL_END_PA = PhysAddr::new(end_pa); 557a29d4fcSLoGin 567a29d4fcSLoGin KERNEL_BEGIN_VA = VirtAddr::new(boot_text_start_pa as usize); 577a29d4fcSLoGin KERNEL_END_VA = VirtAddr::new(_end as usize); 587a29d4fcSLoGin 597a29d4fcSLoGin kdebug!( 607a29d4fcSLoGin "init_kernel_addr: \n\tKERNEL_BEGIN_PA: {KERNEL_BEGIN_PA:?} 617a29d4fcSLoGin \tKERNEL_END_PA: {KERNEL_END_PA:?} 627a29d4fcSLoGin \tKERNEL_BEGIN_VA: {KERNEL_BEGIN_VA:?} 637a29d4fcSLoGin \tKERNEL_END_VA: {KERNEL_END_VA:?} 647a29d4fcSLoGin " 657a29d4fcSLoGin ); 667a29d4fcSLoGin } 67453452ccSLoGin 68453452ccSLoGin pub(super) unsafe fn riscv_mm_init() -> Result<(), SystemError> { 69453452ccSLoGin mem_block_manager() 70453452ccSLoGin .reserve_block(KERNEL_BEGIN_PA, KERNEL_END_PA - KERNEL_BEGIN_PA) 71453452ccSLoGin .expect("Failed to reserve kernel memory"); 72*471d65cfSLoGin // 开启S-mode User Memory Access,允许内核访问用户空间 73*471d65cfSLoGin riscv::register::sstatus::set_sum(); 74453452ccSLoGin 75453452ccSLoGin let mut bump_allocator = BumpAllocator::<RiscV64MMArch>::new(0); 76453452ccSLoGin let _old_page_table = MMArch::table(PageTableKind::Kernel); 77453452ccSLoGin let new_page_table: PhysAddr; 78453452ccSLoGin 79453452ccSLoGin // 使用bump分配器,把所有的内存页都映射到页表 80453452ccSLoGin { 81*471d65cfSLoGin // kdebug!("to create new page table"); 82453452ccSLoGin // 用bump allocator创建新的页表 83453452ccSLoGin let mut mapper: crate::mm::page::PageMapper<MMArch, &mut BumpAllocator<MMArch>> = 84453452ccSLoGin crate::mm::page::PageMapper::<MMArch, _>::create( 85453452ccSLoGin PageTableKind::Kernel, 86453452ccSLoGin &mut bump_allocator, 87453452ccSLoGin ) 88453452ccSLoGin .expect("Failed to create page mapper"); 89453452ccSLoGin new_page_table = mapper.table().phys(); 90*471d65cfSLoGin // kdebug!("PageMapper created"); 91453452ccSLoGin 92453452ccSLoGin // 取消最开始时候,在head.S中指定的映射(暂时不刷新TLB) 93453452ccSLoGin { 94453452ccSLoGin let table = mapper.table(); 95453452ccSLoGin let empty_entry = PageEntry::<MMArch>::from_usize(0); 96453452ccSLoGin for i in 0..MMArch::PAGE_ENTRY_NUM { 97453452ccSLoGin table 98453452ccSLoGin .set_entry(i, empty_entry) 99453452ccSLoGin .expect("Failed to empty page table entry"); 100453452ccSLoGin } 101453452ccSLoGin } 102453452ccSLoGin kdebug!("Successfully emptied page table"); 103453452ccSLoGin 104453452ccSLoGin let total_num = mem_block_manager().total_initial_memory_regions(); 105453452ccSLoGin for i in 0..total_num { 106453452ccSLoGin let area = mem_block_manager().get_initial_memory_region(i).unwrap(); 107453452ccSLoGin // kdebug!("area: base={:?}, size={:#x}, end={:?}", area.base, area.size, area.base + area.size); 108453452ccSLoGin for i in 0..((area.size + MMArch::PAGE_SIZE - 1) / MMArch::PAGE_SIZE) { 109453452ccSLoGin let paddr = area.base.add(i * MMArch::PAGE_SIZE); 110453452ccSLoGin let vaddr = unsafe { MMArch::phys_2_virt(paddr) }.unwrap(); 111453452ccSLoGin let flags = kernel_page_flags::<MMArch>(vaddr).set_execute(true); 112453452ccSLoGin 113453452ccSLoGin let flusher = mapper 114453452ccSLoGin .map_phys(vaddr, paddr, flags) 115453452ccSLoGin .expect("Failed to map frame"); 116453452ccSLoGin // 暂时不刷新TLB 117453452ccSLoGin flusher.ignore(); 118453452ccSLoGin } 119453452ccSLoGin } 120453452ccSLoGin 121453452ccSLoGin // 添加低地址的映射(在smp完成初始化之前,需要使用低地址的映射.初始化之后需要取消这一段映射) 122453452ccSLoGin LowAddressRemapping::remap_at_low_address(&mut mapper); 123453452ccSLoGin } 124453452ccSLoGin 125453452ccSLoGin unsafe { 126453452ccSLoGin INITIAL_PGTABLE_VALUE = new_page_table; 127453452ccSLoGin } 128453452ccSLoGin kdebug!( 129453452ccSLoGin "After mapping all physical memory, DragonOS used: {} KB", 130453452ccSLoGin bump_allocator.usage().used().bytes() / 1024 131453452ccSLoGin ); 132453452ccSLoGin 133453452ccSLoGin // 初始化buddy_allocator 134453452ccSLoGin let buddy_allocator = unsafe { BuddyAllocator::<MMArch>::new(bump_allocator).unwrap() }; 135453452ccSLoGin // 设置全局的页帧分配器 136453452ccSLoGin unsafe { set_inner_allocator(buddy_allocator) }; 137453452ccSLoGin kinfo!("Successfully initialized buddy allocator"); 138453452ccSLoGin // 关闭显示输出 139453452ccSLoGin scm_disable_put_to_window(); 140453452ccSLoGin 141453452ccSLoGin // make the new page table current 142453452ccSLoGin { 143453452ccSLoGin let mut binding = INNER_ALLOCATOR.lock(); 144453452ccSLoGin let mut allocator_guard = binding.as_mut().unwrap(); 145453452ccSLoGin kdebug!("To enable new page table."); 146453452ccSLoGin compiler_fence(Ordering::SeqCst); 147453452ccSLoGin let mapper = crate::mm::page::PageMapper::<MMArch, _>::new( 148453452ccSLoGin PageTableKind::Kernel, 149453452ccSLoGin new_page_table, 150453452ccSLoGin &mut allocator_guard, 151453452ccSLoGin ); 152453452ccSLoGin compiler_fence(Ordering::SeqCst); 153453452ccSLoGin mapper.make_current(); 154453452ccSLoGin compiler_fence(Ordering::SeqCst); 155453452ccSLoGin // kdebug!("New page table enabled"); 156453452ccSLoGin } 157453452ccSLoGin kdebug!("Successfully enabled new page table"); 158453452ccSLoGin kinfo!("riscv mm init done"); 159453452ccSLoGin 160453452ccSLoGin return Ok(()); 161453452ccSLoGin } 162453452ccSLoGin 163453452ccSLoGin unsafe fn set_inner_allocator(allocator: BuddyAllocator<MMArch>) { 164453452ccSLoGin static FLAG: AtomicBool = AtomicBool::new(false); 165453452ccSLoGin if FLAG 166453452ccSLoGin .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) 167453452ccSLoGin .is_err() 168453452ccSLoGin { 169453452ccSLoGin panic!("Cannot set inner allocator twice!"); 170453452ccSLoGin } 171453452ccSLoGin *INNER_ALLOCATOR.lock() = Some(allocator); 172453452ccSLoGin } 173453452ccSLoGin 174453452ccSLoGin /// 低地址重映射的管理器 175453452ccSLoGin /// 176453452ccSLoGin /// 低地址重映射的管理器,在smp初始化完成之前,需要使用低地址的映射,因此需要在smp初始化完成之后,取消这一段映射 177453452ccSLoGin pub struct LowAddressRemapping; 178453452ccSLoGin 179453452ccSLoGin impl LowAddressRemapping { 180453452ccSLoGin pub unsafe fn remap_at_low_address( 181453452ccSLoGin mapper: &mut crate::mm::page::PageMapper<MMArch, &mut BumpAllocator<MMArch>>, 182453452ccSLoGin ) { 183453452ccSLoGin let info = efi_manager().kernel_load_info().unwrap(); 184453452ccSLoGin let base = PhysAddr::new(info.paddr as usize); 185453452ccSLoGin let size = info.size as usize; 186453452ccSLoGin 187453452ccSLoGin for i in 0..(size / MMArch::PAGE_SIZE) { 188453452ccSLoGin let paddr = PhysAddr::new(base.data() + i * MMArch::PAGE_SIZE); 189453452ccSLoGin let vaddr = VirtAddr::new(base.data() + i * MMArch::PAGE_SIZE); 190453452ccSLoGin let flags = kernel_page_flags::<MMArch>(vaddr).set_execute(true); 191453452ccSLoGin 192453452ccSLoGin let flusher = mapper 193453452ccSLoGin .map_phys(vaddr, paddr, flags) 194453452ccSLoGin .expect("Failed to map frame"); 195453452ccSLoGin // 暂时不刷新TLB 196453452ccSLoGin flusher.ignore(); 197453452ccSLoGin } 198453452ccSLoGin } 199453452ccSLoGin 200453452ccSLoGin /// 取消低地址的映射 201453452ccSLoGin pub unsafe fn unmap_at_low_address(flush: bool) { 202453452ccSLoGin let mut mapper = KernelMapper::lock(); 203453452ccSLoGin assert!(mapper.as_mut().is_some()); 204453452ccSLoGin 205453452ccSLoGin let info = efi_manager().kernel_load_info().unwrap(); 206453452ccSLoGin let base = PhysAddr::new(info.paddr as usize); 207453452ccSLoGin let size = info.size as usize; 208453452ccSLoGin 209453452ccSLoGin for i in 0..(size / MMArch::PAGE_SIZE) { 210453452ccSLoGin let vaddr = VirtAddr::new(base.data() + i * MMArch::PAGE_SIZE); 211453452ccSLoGin let (_, _, flusher) = mapper 212453452ccSLoGin .as_mut() 213453452ccSLoGin .unwrap() 214453452ccSLoGin .unmap_phys(vaddr, true) 215453452ccSLoGin .expect("Failed to unmap frame"); 216453452ccSLoGin if flush == false { 217453452ccSLoGin flusher.ignore(); 218453452ccSLoGin } 219453452ccSLoGin } 220453452ccSLoGin } 221453452ccSLoGin } 222