xref: /DragonOS/kernel/src/arch/riscv64/mm/init.rs (revision 453452cc02e2766a28d87dd47bdee37caddc4c44)
1*453452ccSLoGin use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
2*453452ccSLoGin 
3*453452ccSLoGin use system_error::SystemError;
4*453452ccSLoGin 
57a29d4fcSLoGin use crate::{
6*453452ccSLoGin     arch::{
7*453452ccSLoGin         mm::{
8*453452ccSLoGin             kernel_page_flags, INNER_ALLOCATOR, KERNEL_BEGIN_PA, KERNEL_BEGIN_VA, KERNEL_END_PA,
9*453452ccSLoGin             KERNEL_END_VA,
10*453452ccSLoGin         },
11*453452ccSLoGin         MMArch,
12*453452ccSLoGin     },
13*453452ccSLoGin     driver::firmware::efi::efi_manager,
14*453452ccSLoGin     kdebug, kinfo,
15*453452ccSLoGin     libs::lib_ui::screen_manager::scm_disable_put_to_window,
16*453452ccSLoGin     mm::{
17*453452ccSLoGin         allocator::{buddy::BuddyAllocator, bump::BumpAllocator, page_frame::FrameAllocator},
18*453452ccSLoGin         kernel_mapper::KernelMapper,
19*453452ccSLoGin         memblock::mem_block_manager,
20*453452ccSLoGin         page::PageEntry,
21*453452ccSLoGin         MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
22*453452ccSLoGin     },
237a29d4fcSLoGin };
247a29d4fcSLoGin 
25*453452ccSLoGin use super::RiscV64MMArch;
26*453452ccSLoGin 
27*453452ccSLoGin pub(super) static mut INITIAL_PGTABLE_VALUE: PhysAddr = PhysAddr::new(0);
28*453452ccSLoGin 
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 }
67*453452ccSLoGin 
68*453452ccSLoGin pub(super) unsafe fn riscv_mm_init() -> Result<(), SystemError> {
69*453452ccSLoGin     mem_block_manager()
70*453452ccSLoGin         .reserve_block(KERNEL_BEGIN_PA, KERNEL_END_PA - KERNEL_BEGIN_PA)
71*453452ccSLoGin         .expect("Failed to reserve kernel memory");
72*453452ccSLoGin 
73*453452ccSLoGin     let mut bump_allocator = BumpAllocator::<RiscV64MMArch>::new(0);
74*453452ccSLoGin     let _old_page_table = MMArch::table(PageTableKind::Kernel);
75*453452ccSLoGin     let new_page_table: PhysAddr;
76*453452ccSLoGin 
77*453452ccSLoGin     // 使用bump分配器,把所有的内存页都映射到页表
78*453452ccSLoGin     {
79*453452ccSLoGin         kdebug!("to create new page table");
80*453452ccSLoGin         // 用bump allocator创建新的页表
81*453452ccSLoGin         let mut mapper: crate::mm::page::PageMapper<MMArch, &mut BumpAllocator<MMArch>> =
82*453452ccSLoGin             crate::mm::page::PageMapper::<MMArch, _>::create(
83*453452ccSLoGin                 PageTableKind::Kernel,
84*453452ccSLoGin                 &mut bump_allocator,
85*453452ccSLoGin             )
86*453452ccSLoGin             .expect("Failed to create page mapper");
87*453452ccSLoGin         new_page_table = mapper.table().phys();
88*453452ccSLoGin         kdebug!("PageMapper created");
89*453452ccSLoGin 
90*453452ccSLoGin         // 取消最开始时候,在head.S中指定的映射(暂时不刷新TLB)
91*453452ccSLoGin         {
92*453452ccSLoGin             let table = mapper.table();
93*453452ccSLoGin             let empty_entry = PageEntry::<MMArch>::from_usize(0);
94*453452ccSLoGin             for i in 0..MMArch::PAGE_ENTRY_NUM {
95*453452ccSLoGin                 table
96*453452ccSLoGin                     .set_entry(i, empty_entry)
97*453452ccSLoGin                     .expect("Failed to empty page table entry");
98*453452ccSLoGin             }
99*453452ccSLoGin         }
100*453452ccSLoGin         kdebug!("Successfully emptied page table");
101*453452ccSLoGin 
102*453452ccSLoGin         let total_num = mem_block_manager().total_initial_memory_regions();
103*453452ccSLoGin         for i in 0..total_num {
104*453452ccSLoGin             let area = mem_block_manager().get_initial_memory_region(i).unwrap();
105*453452ccSLoGin             // kdebug!("area: base={:?}, size={:#x}, end={:?}", area.base, area.size, area.base + area.size);
106*453452ccSLoGin             for i in 0..((area.size + MMArch::PAGE_SIZE - 1) / MMArch::PAGE_SIZE) {
107*453452ccSLoGin                 let paddr = area.base.add(i * MMArch::PAGE_SIZE);
108*453452ccSLoGin                 let vaddr = unsafe { MMArch::phys_2_virt(paddr) }.unwrap();
109*453452ccSLoGin                 let flags = kernel_page_flags::<MMArch>(vaddr).set_execute(true);
110*453452ccSLoGin 
111*453452ccSLoGin                 let flusher = mapper
112*453452ccSLoGin                     .map_phys(vaddr, paddr, flags)
113*453452ccSLoGin                     .expect("Failed to map frame");
114*453452ccSLoGin                 // 暂时不刷新TLB
115*453452ccSLoGin                 flusher.ignore();
116*453452ccSLoGin             }
117*453452ccSLoGin         }
118*453452ccSLoGin 
119*453452ccSLoGin         // 添加低地址的映射(在smp完成初始化之前,需要使用低地址的映射.初始化之后需要取消这一段映射)
120*453452ccSLoGin         LowAddressRemapping::remap_at_low_address(&mut mapper);
121*453452ccSLoGin     }
122*453452ccSLoGin 
123*453452ccSLoGin     unsafe {
124*453452ccSLoGin         INITIAL_PGTABLE_VALUE = new_page_table;
125*453452ccSLoGin     }
126*453452ccSLoGin     kdebug!(
127*453452ccSLoGin         "After mapping all physical memory, DragonOS used: {} KB",
128*453452ccSLoGin         bump_allocator.usage().used().bytes() / 1024
129*453452ccSLoGin     );
130*453452ccSLoGin 
131*453452ccSLoGin     // 初始化buddy_allocator
132*453452ccSLoGin     let buddy_allocator = unsafe { BuddyAllocator::<MMArch>::new(bump_allocator).unwrap() };
133*453452ccSLoGin     // 设置全局的页帧分配器
134*453452ccSLoGin     unsafe { set_inner_allocator(buddy_allocator) };
135*453452ccSLoGin     kinfo!("Successfully initialized buddy allocator");
136*453452ccSLoGin     // 关闭显示输出
137*453452ccSLoGin     scm_disable_put_to_window();
138*453452ccSLoGin 
139*453452ccSLoGin     // make the new page table current
140*453452ccSLoGin     {
141*453452ccSLoGin         let mut binding = INNER_ALLOCATOR.lock();
142*453452ccSLoGin         let mut allocator_guard = binding.as_mut().unwrap();
143*453452ccSLoGin         kdebug!("To enable new page table.");
144*453452ccSLoGin         compiler_fence(Ordering::SeqCst);
145*453452ccSLoGin         let mapper = crate::mm::page::PageMapper::<MMArch, _>::new(
146*453452ccSLoGin             PageTableKind::Kernel,
147*453452ccSLoGin             new_page_table,
148*453452ccSLoGin             &mut allocator_guard,
149*453452ccSLoGin         );
150*453452ccSLoGin         compiler_fence(Ordering::SeqCst);
151*453452ccSLoGin         mapper.make_current();
152*453452ccSLoGin         compiler_fence(Ordering::SeqCst);
153*453452ccSLoGin         // kdebug!("New page table enabled");
154*453452ccSLoGin     }
155*453452ccSLoGin     kdebug!("Successfully enabled new page table");
156*453452ccSLoGin     kinfo!("riscv mm init done");
157*453452ccSLoGin 
158*453452ccSLoGin     return Ok(());
159*453452ccSLoGin }
160*453452ccSLoGin 
161*453452ccSLoGin unsafe fn set_inner_allocator(allocator: BuddyAllocator<MMArch>) {
162*453452ccSLoGin     static FLAG: AtomicBool = AtomicBool::new(false);
163*453452ccSLoGin     if FLAG
164*453452ccSLoGin         .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
165*453452ccSLoGin         .is_err()
166*453452ccSLoGin     {
167*453452ccSLoGin         panic!("Cannot set inner allocator twice!");
168*453452ccSLoGin     }
169*453452ccSLoGin     *INNER_ALLOCATOR.lock() = Some(allocator);
170*453452ccSLoGin }
171*453452ccSLoGin 
172*453452ccSLoGin /// 低地址重映射的管理器
173*453452ccSLoGin ///
174*453452ccSLoGin /// 低地址重映射的管理器,在smp初始化完成之前,需要使用低地址的映射,因此需要在smp初始化完成之后,取消这一段映射
175*453452ccSLoGin pub struct LowAddressRemapping;
176*453452ccSLoGin 
177*453452ccSLoGin impl LowAddressRemapping {
178*453452ccSLoGin     pub unsafe fn remap_at_low_address(
179*453452ccSLoGin         mapper: &mut crate::mm::page::PageMapper<MMArch, &mut BumpAllocator<MMArch>>,
180*453452ccSLoGin     ) {
181*453452ccSLoGin         let info = efi_manager().kernel_load_info().unwrap();
182*453452ccSLoGin         let base = PhysAddr::new(info.paddr as usize);
183*453452ccSLoGin         let size = info.size as usize;
184*453452ccSLoGin 
185*453452ccSLoGin         for i in 0..(size / MMArch::PAGE_SIZE) {
186*453452ccSLoGin             let paddr = PhysAddr::new(base.data() + i * MMArch::PAGE_SIZE);
187*453452ccSLoGin             let vaddr = VirtAddr::new(base.data() + i * MMArch::PAGE_SIZE);
188*453452ccSLoGin             let flags = kernel_page_flags::<MMArch>(vaddr).set_execute(true);
189*453452ccSLoGin 
190*453452ccSLoGin             let flusher = mapper
191*453452ccSLoGin                 .map_phys(vaddr, paddr, flags)
192*453452ccSLoGin                 .expect("Failed to map frame");
193*453452ccSLoGin             // 暂时不刷新TLB
194*453452ccSLoGin             flusher.ignore();
195*453452ccSLoGin         }
196*453452ccSLoGin     }
197*453452ccSLoGin 
198*453452ccSLoGin     /// 取消低地址的映射
199*453452ccSLoGin     pub unsafe fn unmap_at_low_address(flush: bool) {
200*453452ccSLoGin         let mut mapper = KernelMapper::lock();
201*453452ccSLoGin         assert!(mapper.as_mut().is_some());
202*453452ccSLoGin 
203*453452ccSLoGin         let info = efi_manager().kernel_load_info().unwrap();
204*453452ccSLoGin         let base = PhysAddr::new(info.paddr as usize);
205*453452ccSLoGin         let size = info.size as usize;
206*453452ccSLoGin 
207*453452ccSLoGin         for i in 0..(size / MMArch::PAGE_SIZE) {
208*453452ccSLoGin             let vaddr = VirtAddr::new(base.data() + i * MMArch::PAGE_SIZE);
209*453452ccSLoGin             let (_, _, flusher) = mapper
210*453452ccSLoGin                 .as_mut()
211*453452ccSLoGin                 .unwrap()
212*453452ccSLoGin                 .unmap_phys(vaddr, true)
213*453452ccSLoGin                 .expect("Failed to unmap frame");
214*453452ccSLoGin             if flush == false {
215*453452ccSLoGin                 flusher.ignore();
216*453452ccSLoGin             }
217*453452ccSLoGin         }
218*453452ccSLoGin     }
219*453452ccSLoGin }
220