/*
- AcessOS Microkernel Version
- mm_phys.c
-*/
+ * Acess2
+ * - Physical memory manager
+ */
#define DEBUG 1
#include <common.h>
#include <mboot.h>
extern void gKernelEnd;
// === PROTOTYPES ===
-Uint32 MM_AllocPhys();
-void MM_RefPhys(Uint32 Addr);
-void MM_DerefPhys(Uint32 Addr);
+tPAddr MM_AllocPhys();
+tPAddr MM_AllocPhysRange(int Pages);
+void MM_RefPhys(tPAddr Addr);
+void MM_DerefPhys(tPAddr Addr);
// === GLOBALS ===
int giPhysAlloc = 0;
// Initialise globals
giPageCount = (MBoot->HighMem >> 2) + 256; // HighMem is a kByte value
- LOG("giPageCount = %i", giPageCount);
+ //LOG("giPageCount = %i", giPageCount);
// Get used page count
kernelPages = (Uint)&gKernelEnd - KERNEL_BASE;
}
// Allocate References
- LOG("Reference Pages %i", (giPageCount*4+0xFFF)>>12);
+ //LOG("Reference Pages %i", (giPageCount*4+0xFFF)>>12);
for(num = 0; num < (giPageCount*4+0xFFF)>>12; num++)
{
MM_Allocate( REFERENCE_BASE + (num<<12) );
}
+ //LOG("Filling");
// Fill references
gaPageReferences = (void*)REFERENCE_BASE;
memsetd(gaPageReferences, 1, kernelPages);
{
int num = giPageCount / 32 / 32;
int a, b, c;
- Uint32 ret;
+ tPAddr ret;
LOCK( &giPhysAlloc );
}
for(b=0;gaSuperBitmap[a]&(1<<b);b++);
for(c=0;gaPageBitmap[a*32+b]&(1<<c);c++);
- //for(c=0;gaPageReferences[a*32*32+b*32+c]>0;c++);
// Mark page used
if(gaPageReferences)
// Release Spinlock
RELEASE( &giPhysAlloc );
- //LOG("Allocated 0x%x\n", ret);
- //LOG("ret = %x", ret);
+
+ return ret;
+}
+
+/**
+ * \fn tPAddr MM_AllocPhysRange(int Pages)
+ * \brief Allocate a range of physical pages
+ * \param Pages Number of pages to allocate
+ */
+tPAddr MM_AllocPhysRange(int Pages)
+{
+ int num = giPageCount / 32 / 32;
+ int a, b, c;
+ tPAddr ret;
+
+ LOCK( &giPhysAlloc );
+
+ // Find free page
+ for(a=0;gaSuperBitmap[a]==-1&&a<num;a++);
+ if(a == num) {
+ RELEASE( &giPhysAlloc );
+ Warning("MM_AllocPhys - OUT OF MEMORY (Called by %p)", __builtin_return_address(0));
+ return 0;
+ }
+ for(b=0;gaSuperBitmap[a]&(1<<b);b++);
+ for(c=0;gaPageBitmap[a*32+b]&(1<<c);c++);
+
+ // Mark page used
+ if(gaPageReferences)
+ gaPageReferences[a*32*32+b*32+c] = 1;
+ gaPageBitmap[ a*32+b ] |= 1 << c;
+
+ // Get address
+ ret = (a << 22) + (b << 17) + (c << 12);
+
+ // Mark used block
+ if(gaPageBitmap[ a*32+b ] == -1) gaSuperBitmap[a] |= 1 << b;
+
+ // Release Spinlock
+ RELEASE( &giPhysAlloc );
+
return ret;
}