Log(" SS:RSP = 0x%04x:%016x", Regs->SS, Regs->RSP);
Log(" RFLAGS = 0x%016x", Regs->RFlags);
- Log(" EAX %016x ECX %016x EDX %016x EBX %016x",
+ Log(" RAX %016x RCX %016x RDX %016x RBX %016x",
Regs->RAX, Regs->RCX, Regs->RDX, Regs->RBX);
- Log(" ESP %016x EBP %016x ESI %016x EDI %016x",
+ Log(" RSP %016x RBP %016x RSI %016x RDI %016x",
Regs->RSP, Regs->RBP, Regs->RSP, Regs->RDI);
Log(" R8 %016x R9 %016x R10 %016x R11 %016x",
Regs->R8, Regs->R9, Regs->R10, Regs->R11);
+ Log(" R12 %016x R13 %016x R14 %016x R15 %016x",
+ Regs->R12, Regs->R13, Regs->R14, Regs->R15);
Log(" FS %04x GS %04x", Regs->FS, Regs->GS);
Uint64 giPhysRangeFirst[NUM_MM_PHYS_RANGES]; // First free page in each range
Uint64 giPhysRangeLast[NUM_MM_PHYS_RANGES]; // Last free page in each range
Uint64 giMaxPhysPage = 0; // Maximum Physical page
+// Only used in init, allows the init code to provide pages for use by
+// the allocator before the bitmaps exist.
+// 3 entries because the are three calls to MM_AllocPhys in MM_Map
+#define NUM_STATIC_ALLOC 3
+tPAddr gaiStaticAllocPages[NUM_STATIC_ALLOC] = {0};
// === CODE ===
/**
int i;
Uint64 base, size;
tVAddr vaddr;
- tPAddr paddr;
+ tPAddr paddr, firstFreePage;
Log("MM_InitPhys_Multiboot: (MBoot=%p)", MBoot);
numPages, superPages);
if(maxAddr == 0)
{
- int todo = numPages;
+ int todo = numPages*2 + superPages;
// Ok, naieve allocation, just put it after the kernel
// - Allocated Bitmap
vaddr = MM_PAGE_BITMAP;
paddr = (tPAddr)&gKernelEnd - KERNEL_BASE;
- while(todo --)
+ while(todo )
{
+ // Allocate statics
+ for( i = 0; i < NUM_STATIC_ALLOC; i++) {
+ if(gaiStaticAllocPages[i] != 0) continue;
+ gaiStaticAllocPages[i] = paddr;
+ paddr += 0x1000;
+ }
+
MM_Map(vaddr, paddr);
vaddr += 0x1000;
paddr += 0x1000;
- }
- // - Multi-Alloc Bitmap
- vaddr = MM_PAGE_DBLBMP;
- todo = numPages;
- while(todo --) {
- MM_Map(vaddr, paddr);
- vaddr += 0x1000;
- paddr += 0x1000;
- }
- // - Super Bitmap
- vaddr = MM_PAGE_SUPBMP;
- todo = superPages;
- while(todo --) {
- MM_Map(vaddr, paddr);
- vaddr += 0x1000;
- paddr += 0x1000;
+
+ todo --;
+
+ if( todo == numPages + superPages )
+ vaddr = MM_PAGE_DBLBMP;
+ if( todo == superPages )
+ vaddr = MM_PAGE_SUPBMP;
}
}
// Scan for a nice range
else
{
int todo = numPages*2 + superPages;
- tPAddr paddr = 0;
- tVAddr vaddr = MM_PAGE_BITMAP;
+ paddr = 0;
+ vaddr = MM_PAGE_BITMAP;
// Scan!
for(
ent = mmapStart;
)
{
int avail;
- int i, max;
// RAM only please
if( ent->Type != 1 )
Log(" MM_InitPhys_Multiboot: paddr=0x%x, avail=%i", paddr, avail);
// Map
- max = todo < avail ? todo : avail;
- for( i = 0; i < max; i ++ )
+ while( todo && avail --)
{
+ // Static Allocations
+ for( i = 0; i < NUM_STATIC_ALLOC && avail; i++) {
+ if(gaiStaticAllocPages[i] != 0) continue;
+ gaiStaticAllocPages[i] = paddr;
+ paddr += 0x1000;
+ avail --;
+ }
+ if(!avail) break;
+
+ // Map
MM_Map(vaddr, paddr);
todo --;
vaddr += 0x1000;
paddr += 0x1000;
+
// Alter the destination address when needed
if(todo == superPages+numPages)
vaddr = MM_PAGE_DBLBMP;
if( !todo ) break;
}
}
+ // Save the current value of paddr to simplify the allocation later
+ firstFreePage = paddr;
- Log(" MM_InitPhys_Multiboot: Cearing multi bitmap");
+ Log(" MM_InitPhys_Multiboot: Clearing multi bitmap");
// Fill the bitmaps
memset(gaMultiBitmap, 0, numPages<<12);
// - initialise to one, then clear the avaliable areas
}
// Reference the used pages
- // - Kernel
- Log(" MM_InitPhys_Multiboot: Setting kernel area");
base = (tPAddr)&gKernelBase >> 12;
- size = ((tPAddr)&gKernelEnd - KERNEL_BASE - base) >> 12;
+ size = firstFreePage >> 12;
memset( &gaMainBitmap[base / 64], -1, size/8 );
if( size & 7 ) {
Uint64 val = -1 << (size & 7);
val <<= (size/8)&7;
gaMainBitmap[base / 64] |= val;
}
- // - Bitmaps
- Log(" MM_InitPhys_Multiboot: Setting bitmaps' memory");
- vaddr = MM_PAGE_BITMAP;
- for( i = 0; i < numPages; i++, vaddr ++ )
- {
- paddr = MM_GetPhysAddr(vaddr) >> 12;
- gaMainBitmap[paddr >> 6] |= 1 << (paddr&63);
- }
- vaddr = MM_PAGE_DBLBMP;
- for( i = 0; i < numPages; i++, vaddr += 0x1000 )
- {
- paddr = MM_GetPhysAddr(vaddr) >> 12;
- gaMainBitmap[paddr >> 6] |= 1 << (paddr&63);
- }
- vaddr = MM_PAGE_SUPBMP;
- for( i = 0; i < superPages; i++, vaddr += 0x1000 )
- {
- paddr = MM_GetPhysAddr(vaddr) >> 12;
- gaMainBitmap[paddr >> 6] |= 1 << (paddr&63);
+ // Free the unused static allocs
+ for( i = 0; i < NUM_STATIC_ALLOC; i++) {
+ if(gaiStaticAllocPages[i] != 0)
+ continue;
+ gaMainBitmap[ gaiStaticAllocPages[i] >> (12+6) ]
+ &= ~(1 << ((gaiStaticAllocPages[i]>>12)&63));
}
// Fill the super bitmap
*/
tPAddr MM_AllocPhys(void)
{
+ int i;
+
+ // Hack to allow allocation during setup
+ for(i = 0; i < NUM_STATIC_ALLOC; i++) {
+ if( gaiStaticAllocPages[i] ) {
+ tPAddr ret = gaiStaticAllocPages[i];
+ gaiStaticAllocPages[i] = 0;
+ return ret;
+ }
+ }
+
return MM_AllocPhysRange(1, -1);
}
#define PTAB_SHIFT 12
#define PADDR_MASK 0x7FFFFFFF##FFFFF000
+#define PAGE_MASK (((Uint)1 << 36)-1)
+#define TABLE_MASK (((Uint)1 << 27)-1)
+#define PDP_MASK (((Uint)1 << 18)-1)
+#define PML4_MASK (((Uint)1 << 9)-1)
#define PF_PRESENT 0x1
#define PF_WRITE 0x2
#define PF_NX 0x80000000##00000000
// === MACROS ===
-#define PAGETABLE(idx) (*((tPAddr*)MM_FRACTAL_BASE+(idx)))
-#define PAGEDIR(idx) PAGETABLE((MM_FRACTAL_BASE>>12)+((idx)&0x7FFFFFF))
-#define PAGEDIRPTR(idx) PAGEDIR((MM_FRACTAL_BASE>>21)+((idx)&0x3FFFF))
-#define PAGEMAPLVL4(idx) PAGEDIRPTR((MM_FRACTAL_BASE>>30)+((idx)&0x1FF))
+#define PAGETABLE(idx) (*((tPAddr*)MM_FRACTAL_BASE+((idx)&PAGE_MASK)))
+#define PAGEDIR(idx) PAGETABLE((MM_FRACTAL_BASE>>12)+((idx)&TABLE_MASK))
+#define PAGEDIRPTR(idx) PAGEDIR((MM_FRACTAL_BASE>>21)+((idx)&PDP_MASK))
+#define PAGEMAPLVL4(idx) PAGEDIRPTR((MM_FRACTAL_BASE>>30)+((idx)&PML4_MASK))
// === GLOBALS ===
Log("MM_Map: (VAddr=0x%x, PAddr=0x%x)", VAddr, PAddr);
// Check PML4
+ Log(" MM_Map: &PAGEMAPLVL4(%x) = %x", VAddr >> 39, &PAGEMAPLVL4(VAddr >> 39));
+ Log(" MM_Map: &PAGEDIRPTR(%x) = %x", VAddr >> 30, &PAGEDIRPTR(VAddr >> 30));
+ Log(" MM_Map: &PAGEDIR(%x) = %x", VAddr >> 21, &PAGEDIR(VAddr >> 21));
+ Log(" MM_Map: &PAGETABLE(%x) = %x", VAddr >> 12, &PAGETABLE(VAddr >> 12));
+ Log(" MM_Map: &PAGETABLE(0) = %x", &PAGETABLE(0));
if( !(PAGEMAPLVL4(VAddr >> 39) & 1) )
{
tmp = MM_AllocPhys();
}
// Check if this virtual address is already mapped
- if( PAGETABLE(VAddr >> 12) & 1 )
+ if( PAGETABLE(VAddr >> PTAB_SHIFT) & 1 )
return 0;
- PAGETABLE(VAddr >> 12) = PAddr | 3;
+ PAGETABLE(VAddr >> PTAB_SHIFT) = PAddr | 3;
return 1;
}
// Check Page Dir
if( !(PAGEDIR(VAddr >> 21) & 1) ) return ;
- PAGETABLE(VAddr >> 12) = 0;
+ PAGETABLE(VAddr >> PTAB_SHIFT) = 0;
}
/**
if( !(PAGEDIR(Addr >> 21) & 1) )
return 0;
Log(" MM_GetPhysAddr: PT Valid");
- if( !(PAGETABLE(Addr >> 12) & 1) )
+ if( !(PAGETABLE(Addr >> PTAB_SHIFT) & 1) )
return 0;
Log(" MM_GetPhysAddr: Page Valid");
- return (PAGETABLE(Addr >> 12) & ~0xFFF) | (Addr & 0xFFF);
+ return (PAGETABLE(Addr >> PTAB_SHIFT) & ~0xFFF) | (Addr & 0xFFF);
}
/**