4 * Virtual Memory Manager
15 #define PF_PRESENT 0x1
18 #define PF_NX 0x80000000##00000000
20 #define PF_PAGED 0x400
23 #define PAGETABLE(idx) (*((tPAddr*)MM_FRACTAL_BASE+(idx)))
24 #define PAGEDIR(idx) PAGETABLE((MM_FRACTAL_BASE>>12)+((idx)&0x7FFFFFF))
25 #define PAGEDIRPTR(idx) PAGETABLE((MM_FRACTAL_BASE>>21)+((idx)&0x3FFFF))
26 #define PAGEMAPLVL4(idx) PAGETABLE((MM_FRACTAL_BASE>>30)+((idx)&0x1FF))
31 void MM_InitVirt(void)
37 * \brief Map a physical page to a virtual one
39 int MM_Map(tVAddr VAddr, tPAddr PAddr)
44 if( !(PAGEMAPLVL4(VAddr >> 39) & 1) )
48 PAGEMAPLVL4(VAddr >> 39) = tmp | 3;
49 memset( &PAGEDIRPTR( (VAddr>>39)<<9 ), 0, 4096 );
53 if( !(PAGEDIRPTR(VAddr >> 30) & 1) )
57 PAGEDIRPTR(VAddr >> 30) = tmp | 3;
58 memset( &PAGEDIR( (VAddr>>30)<<9 ), 0, 4096 );
62 if( !(PAGEDIR(VAddr >> 21) & 1) )
66 PAGEDIR(VAddr >> 21) = tmp | 3;
67 memset( &PAGETABLE( (VAddr>>21)<<9 ), 0, 4096 );
70 // Check if this virtual address is already mapped
71 if( PAGETABLE(VAddr >> 12) & 1 )
74 PAGETABLE(VAddr >> 12) = PAddr | 3;
79 void MM_Unmap(tVAddr VAddr)
82 if( !(PAGEMAPLVL4(VAddr >> 39) & 1) ) return ;
84 if( !(PAGEDIRPTR(VAddr >> 30) & 1) ) return ;
86 if( !(PAGEDIR(VAddr >> 21) & 1) ) return ;
88 PAGETABLE(VAddr >> 12) = 0;
92 * \brief Allocate a block of memory at the specified virtual address
94 tPAddr MM_Allocate(tVAddr VAddr)
101 if( !MM_Map(VAddr, ret) )
110 void MM_Deallocate(tVAddr VAddr)
114 phys = MM_GetPhysAddr(VAddr);
123 * \brief Get the physical address of a virtual location
125 tPAddr MM_GetPhysAddr(tVAddr Addr)
127 if( !(PAGEMAPLVL4(Addr >> 39) & 1) )
129 if( !(PAGEDIRPTR(Addr >> 30) & 1) )
131 if( !(PAGEDIR(Addr >> 21) & 1) )
133 if( !(PAGETABLE(Addr >> 12) & 1) )
136 return (PAGETABLE(Addr >> 12) & ~0xFFF) | (Addr & 0xFFF);
140 * \brief Sets the flags on a page
142 void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask)
147 if( !(PAGEMAPLVL4(VAddr >> 39) & 1) )
149 if( !(PAGEDIRPTR(VAddr >> 30) & 1) )
151 if( !(PAGEDIR(VAddr >> 21) & 1) )
153 if( !(PAGETABLE(VAddr >> 12) & 1) )
157 ent = &PAGETABLE(VAddr >> 12);
160 if( Mask & MM_PFLAG_RO )
162 if( Flags & MM_PFLAG_RO ) {
171 if( Mask & MM_PFLAG_KERNEL )
173 if( Flags & MM_PFLAG_KERNEL ) {
182 if( Mask & MM_PFLAG_COW )
184 if( Flags & MM_PFLAG_COW ) {
195 if( Mask & MM_PFLAG_EXEC )
197 if( Flags & MM_PFLAG_EXEC ) {
207 * \brief Get the flags applied to a page
209 Uint MM_GetFlags(tVAddr VAddr)
215 if( !(PAGEMAPLVL4(VAddr >> 39) & 1) )
217 if( !(PAGEDIRPTR(VAddr >> 30) & 1) )
219 if( !(PAGEDIR(VAddr >> 21) & 1) )
221 if( !(PAGETABLE(VAddr >> 12) & 1) )
225 ent = &PAGETABLE(VAddr >> 12);
228 if( !(*ent & PF_WRITE) ) ret |= MM_PFLAG_RO;
230 if( !(*ent & PF_USER) ) ret |= MM_PFLAG_KERNEL;
232 if( *ent & PF_COW ) ret |= MM_PFLAG_COW;
234 if( !(*ent & PF_NX) ) ret |= MM_PFLAG_EXEC;
239 // --- Hardware Mappings ---
241 * \brief Map a range of hardware pages
243 tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number)
245 Log_KernelPanic("MM", "TODO: Implement MM_MapHWPages");
250 * \brief Free a range of hardware pages
252 void MM_UnmapHWPages(tVAddr VAddr, Uint Number)
254 Log_KernelPanic("MM", "TODO: Implement MM_UnmapHWPages");
257 // --- Tempory Mappings ---
258 tVAddr MM_MapTemp(tPAddr PAddr)
260 Log_KernelPanic("MM", "TODO: Implement MM_MapTemp");
264 void MM_FreeTemp(tVAddr VAddr)
266 Log_KernelPanic("MM", "TODO: Implement MM_FreeTemp");