2 AcessOS Microkernel Version
9 #define REFERENCE_BASE 0xE0400000
12 extern void gKernelEnd;
15 Uint32 MM_AllocPhys();
16 void MM_RefPhys(Uint32 Addr);
17 void MM_DerefPhys(Uint32 Addr);
22 Uint32 gaSuperBitmap[1024]; // Blocks of 1024 Pages
23 Uint32 gaPageBitmap[1024*1024/32]; // Individual pages
24 Uint32 *gaPageReferences;
27 void MM_Install(tMBoot_Info *MBoot)
29 Uint kernelPages, num;
34 giPageCount = (MBoot->HighMem >> 2) + 256; // HighMem is a kByte value
35 Log("giPageCount = %i", giPageCount);
37 // Get used page count
38 kernelPages = (Uint)&gKernelEnd - KERNEL_BASE;
39 kernelPages += 0xFFF; // Page Align
44 memsetd(gaPageBitmap, -1, num);
45 gaPageBitmap[ num ] = (1 << (kernelPages & 31)) - 1;
47 // Fill Superpage bitmap
48 num = kernelPages/(32*32);
49 memsetd(gaSuperBitmap, -1, num);
50 gaSuperBitmap[ num ] = (1 << ((kernelPages / 32) & 31)) - 1;
52 // Mark Multiboot's pages as taken
54 MM_RefPhys( (Uint)MBoot - KERNEL_BASE );
56 for(i = (MBoot->ModuleCount*sizeof(tMBoot_Module)+0xFFF)>12; i--; )
57 MM_RefPhys( MBoot->Modules + (i << 12) );
59 mods = (void*)(MBoot->Modules + KERNEL_BASE);
60 for(i = 0; i < MBoot->ModuleCount; i++)
62 num = (mods[i].End - mods[i].Start + 0xFFF) >> 12;
64 MM_RefPhys( (mods[i].Start & ~0xFFF) + (num<<12) );
67 // Allocate References
68 Log("Reference Pages %i", (giPageCount*4+0xFFF)>>12);
69 for(num = 0; num < (giPageCount*4+0xFFF)>>12; num++)
71 MM_Allocate( REFERENCE_BASE + (num<<12) );
75 gaPageReferences = (void*)REFERENCE_BASE;
76 memsetd(gaPageReferences, 1, kernelPages);
77 for( num = kernelPages; num < giPageCount; num++ )
79 //if(gaPageBitmap[ num2 / 32 ] == 0) {
80 // memsetd(&gaPageReferences[num2], 0, 31-(num2&31));
81 // num2 = (num2 + 32) & ~31;
83 gaPageReferences[num] = (gaPageBitmap[ num / 32 ] >> (num&31)) & 1;
88 * \fn Uint32 MM_AllocPhys()
89 * \brief Allocates a physical page
93 int num = giPageCount / 32 / 32;
100 for(a=0;gaSuperBitmap[a]==-1&&a<num;a++);
102 RELEASE( &giPhysAlloc );
105 for(b=0;gaSuperBitmap[a]&(1<<b);b++);
106 for(c=0;gaPageBitmap[a*32+b]&(1<<c);c++);
107 //for(c=0;gaPageReferences[a*32*32+b*32+c]>0;c++);
111 gaPageReferences[a*32*32+b*32+c] = 1;
112 gaPageBitmap[ a*32+b ] |= 1 << c;
115 ret = (a << 22) + (b << 17) + (c << 12);
118 if(gaPageBitmap[ a*32+b ] == -1) gaSuperBitmap[a] |= 1 << b;
121 RELEASE( &giPhysAlloc );
122 //LOG("ret = %x", ret);
127 * \fn void MM_RefPhys(tPAddr Addr)
129 void MM_RefPhys(tPAddr Addr)
134 // We don't care about non-ram pages
135 if(Addr >= giPageCount) return;
138 LOCK( &giPhysAlloc );
140 // Reference the page
142 gaPageReferences[ Addr ] ++;
145 gaPageBitmap[ Addr / 32 ] |= 1 << (Addr&31);
148 if(gaPageBitmap[ Addr / 32 ] == -1) gaSuperBitmap[Addr/1024] |= 1 << ((Addr/32)&31);
151 RELEASE( &giPhysAlloc );
155 * \fn void MM_DerefPhys(Uint32 Addr)
157 void MM_DerefPhys(Uint32 Addr)
162 // We don't care about non-ram pages
163 if(Addr >= giPageCount) return;
165 // Check if it is freed
166 if(gaPageReferences[ Addr ] == 0) {
167 Warning("MM_DerefPhys - Non-referenced memory dereferenced");
172 LOCK( &giPhysAlloc );
175 gaPageReferences[ Addr ] --;
177 // Mark as free in bitmaps
178 if( gaPageReferences[ Addr ] == 0 )
180 gaPageBitmap[ Addr / 32 ] &= ~(1 << (Addr&31));
181 if(gaPageReferences[ Addr ] == 0)
182 gaSuperBitmap[ Addr >> 10 ] &= ~(1 << ((Addr >> 5)&31));
186 RELEASE( &giPhysAlloc );