xref: /DragonOS/kernel/src/arch/riscv64/mm/init.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
1453452ccSLoGin use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
2453452ccSLoGin 
3*2eab6dd7S曾俊 use log::{debug, info};
4453452ccSLoGin use system_error::SystemError;
5453452ccSLoGin 
67a29d4fcSLoGin use crate::{
7453452ccSLoGin     arch::{
8453452ccSLoGin         mm::{
9453452ccSLoGin             kernel_page_flags, INNER_ALLOCATOR, KERNEL_BEGIN_PA, KERNEL_BEGIN_VA, KERNEL_END_PA,
10453452ccSLoGin             KERNEL_END_VA,
11453452ccSLoGin         },
12453452ccSLoGin         MMArch,
13453452ccSLoGin     },
14453452ccSLoGin     driver::firmware::efi::efi_manager,
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)]
mm_early_init()307a29d4fcSLoGin pub fn mm_early_init() {
317a29d4fcSLoGin     unsafe { init_kernel_addr() };
327a29d4fcSLoGin }
337a29d4fcSLoGin 
init_kernel_addr()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 
59*2eab6dd7S曾俊     debug!(
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 
riscv_mm_init() -> Result<(), SystemError>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");
72471d65cfSLoGin     // 开启S-mode User Memory Access,允许内核访问用户空间
73471d65cfSLoGin     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*2eab6dd7S曾俊         // debug!("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*2eab6dd7S曾俊         // debug!("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         }
102*2eab6dd7S曾俊         debug!("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();
107*2eab6dd7S曾俊             // debug!("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     }
128*2eab6dd7S曾俊     debug!(
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) };
137*2eab6dd7S曾俊     info!("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();
145*2eab6dd7S曾俊         debug!("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);
155*2eab6dd7S曾俊         // debug!("New page table enabled");
156453452ccSLoGin     }
157*2eab6dd7S曾俊     debug!("Successfully enabled new page table");
158*2eab6dd7S曾俊     info!("riscv mm init done");
159453452ccSLoGin 
160453452ccSLoGin     return Ok(());
161453452ccSLoGin }
162453452ccSLoGin 
set_inner_allocator(allocator: BuddyAllocator<MMArch>)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 {
remap_at_low_address( mapper: &mut crate::mm::page::PageMapper<MMArch, &mut BumpAllocator<MMArch>>, )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     /// 取消低地址的映射
unmap_at_low_address(flush: bool)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