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;
80 * \brief Allocate a block of memory at the specified virtual address
82 tPAddr MM_Allocate(tVAddr VAddr)
89 if( !MM_Map(VAddr, ret) )
99 * \brief Get the physical address of a virtual location
101 tPAddr MM_GetPhysAddr(tVAddr Addr)
103 if( !(PAGEMAPLVL4(Addr >> 39) & 1) )
105 if( !(PAGEDIRPTR(Addr >> 30) & 1) )
107 if( !(PAGEDIR(Addr >> 21) & 1) )
109 if( !(PAGETABLE(Addr >> 12) & 1) )
112 return (PAGETABLE(Addr >> 12) & ~0xFFF) | (Addr & 0xFFF);
116 * \brief Sets the flags on a page
118 void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask)
123 if( !(PAGEMAPLVL4(VAddr >> 39) & 1) )
125 if( !(PAGEDIRPTR(VAddr >> 30) & 1) )
127 if( !(PAGEDIR(VAddr >> 21) & 1) )
129 if( !(PAGETABLE(VAddr >> 12) & 1) )
133 ent = &PAGETABLE(VAddr >> 12);
136 if( Mask & MM_PFLAG_RO )
138 if( Flags & MM_PFLAG_RO ) {
147 if( Mask & MM_PFLAG_KERNEL )
149 if( Flags & MM_PFLAG_KERNEL ) {
158 if( Mask & MM_PFLAG_COW )
160 if( Flags & MM_PFLAG_COW ) {
171 if( Mask & MM_PFLAG_EXEC )
173 if( Flags & MM_PFLAG_EXEC ) {
182 Uint MM_GetFlags(tVAddr VAddr)
188 if( !(PAGEMAPLVL4(VAddr >> 39) & 1) )
190 if( !(PAGEDIRPTR(VAddr >> 30) & 1) )
192 if( !(PAGEDIR(VAddr >> 21) & 1) )
194 if( !(PAGETABLE(VAddr >> 12) & 1) )
198 ent = &PAGETABLE(VAddr >> 12);
201 if( !(*ent & PF_WRITE) ) ret |= MM_PFLAG_RO;
203 if( !(*ent & PF_USER) ) ret |= MM_PFLAG_KERNEL;
205 if( *ent & PF_COW ) ret |= MM_PFLAG_COW;
207 if( !(*ent & PF_NX) ) ret |= MM_PFLAG_EXEC;