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