#define NULL ((void*)0)
#define PACKED __attribute__((packed))
+#define NORETURN __attribute__((noreturn))
#define UNUSED(x) UNUSED_##x __attribute__((unused))
#define offsetof(st, m) ((Uint)((char *)&((st *)(0))->m - (char *)0 ))
#define STR(x) #x
#define EXPAND_STR(x) STR(x)
+extern char __buildnum[];
+#define BUILD_NUM ((int)&__buildnum)
+
#define VER2(major,minor) ((((major)&0xFF)<<8)|((minor)&0xFF))
/**
* \}
* \{
*/
extern int memcmp(const void *m1, const void *m2, size_t count);
-extern void *memcpy(void *dest, const void *src, size_t count);
-extern void *memcpyd(void *dest, const void *src, size_t count);
-extern void *memset(void *dest, int val, size_t count);
-extern void *memsetd(void *dest, Uint32 val, size_t count);
+extern void *memcpy(void *dest, const void *src, size_t count);
+extern void *memcpyd(void *dest, const void *src, size_t count);
+extern void *memset(void *dest, int val, size_t count);
+extern void *memsetd(void *dest, Uint32 val, size_t count);
/**
* \}
*/
* \name Threads and Processes
* \{
*/
-extern int Proc_SpawnWorker(void);
+extern int Proc_SpawnWorker(void (*Fcn)(void*), void *Data);
extern int Proc_Spawn(const char *Path);
extern void Threads_Exit(int TID, int Status);
extern void Threads_Yield(void);
// --- Simple Math ---
extern int DivUp(int num, int dem);
+extern Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem);
#include <binary_ext.h>
#include <vfs_ext.h>
* include/tpl_mm_phys_bitmap.h
* Physical Memory Manager Template
*/
-#define DEBUG 0
-
/*
* Bitmap Edition
*
Uint32 *gaPageBitmaps = (void*)MM_PAGE_BITMAP; // Used bitmap (1 == avail)
Uint64 giMaxPhysPage = 0; // Maximum Physical page
int gbPMM_Init = 0;
- int gaiPhysRangeFirstFree[MM_NUM_RANGES];
- int gaiPhysRangeLastFree[MM_NUM_RANGES];
- int gaiPhysRangeNumFree[MM_NUM_RANGES];
+ int giPhysFirstFree;
+ int giPhysLastFree;
+ int giPhysNumFree;
// === CODE ===
/**
giMaxPhysPage = MaxRAMPage;
+// for( i = 0; i < MM_RANGE_MAX; i ++ )
+// gaiPhysRangeFirstFree[i] = -1;
+ giPhysFirstFree = -1;
+
while( MM_int_GetMapEntry(MemoryMap, mapIndex++, &rangeStart, &rangeLen) )
{
tVAddr bitmap_page;
+
+ LOG("Range %i, %P to %P", mapIndex-1, rangeStart, rangeLen);
rangeStart /= PAGE_SIZE;
rangeLen /= PAGE_SIZE;
+ giPhysNumFree += rangeLen;
+
+ LOG("rangeStart = 0x%x, rangeLen = 0x%x", rangeStart, rangeLen);
+
+ if( giPhysFirstFree == -1 || giPhysFirstFree > rangeStart )
+ giPhysFirstFree = rangeStart;
+
+ if( giPhysLastFree < rangeStart + rangeLen )
+ giPhysLastFree = rangeStart + rangeLen;
+
+ LOG("giPhysFirstFree = 0x%x, giPhysLastFree = 0x%x", giPhysFirstFree, giPhysLastFree);
+
bitmap_page = (tVAddr)&gaPageBitmaps[rangeStart/32];
bitmap_page &= ~(PAGE_SIZE-1);
// Only need to allocate bitmaps
if( !MM_GetPhysAddr( bitmap_page ) ) {
- if( MM_Allocate( bitmap_page ) ) {
+ if( !MM_Allocate( bitmap_page ) ) {
Log_KernelPanic("PMM", "Out of memory during init, this is bad");
return ;
}
- memset( (void*)bitmap_page, 0, rangeStart/8 & ~(PAGE_SIZE-1) );
+// memset( (void*)bitmap_page, 0, (rangeStart/8) & ~(PAGE_SIZE-1) );
+ memset( (void*)bitmap_page, 0, PAGE_SIZE );
}
// Align to 32 pages
for( ; (rangeStart & 31) && rangeLen > 0; rangeStart++, rangeLen-- ) {
gaPageBitmaps[rangeStart / 32] |= 1 << (rangeStart&31);
+ LOG("gaPageBitmaps[%i] = 0x%x", rangeStart/32, gaPageBitmaps[rangeStart/32]);
}
// Mark blocks of 32 as avail
for( ; rangeLen > 31; rangeStart += 32, rangeLen -= 32 ) {
gbPMM_Init = 1;
+ LOG("giPhysFirstFree = 0x%x, giPhysLastFree = 0x%x", giPhysFirstFree, giPhysLastFree);
LEAVE('-');
}
tPAddr MM_AllocPhysRange(int Pages, int MaxBits)
{
tPAddr addr, ret;
- int rangeID;
int nFree = 0, i;
ENTER("iPages iBits", Pages, MaxBits);
-
- // Get range ID
- if( MaxBits <= 0 || MaxBits >= 64 ) // Speedup for the common case
- rangeID = MM_RANGE_MAX;
- else
- rangeID = MM_int_GetRangeID( (1LL << MaxBits) - 1 );
Mutex_Acquire(&glPhysicalPages);
- // Check if the range actually has any free pages
- while(gaiPhysRangeNumFree[rangeID] == 0 && rangeID)
- rangeID --;
-
- LOG("rangeID = %i", rangeID);
-
// Check if there is enough in the range
- if(gaiPhysRangeNumFree[rangeID] >= Pages)
+ if(giPhysNumFree >= Pages)
{
- LOG("{%i,0x%x -> 0x%x}",
- giPhysRangeFree[rangeID],
- giPhysRangeFirst[rangeID], giPhysRangeLast[rangeID]
- );
+ LOG("{0x%x -> 0x%x}", giPhysFirstFree, giPhysLastFree);
// Do a cheap scan, scanning upwards from the first free page in
// the range
nFree = 0;
- addr = gaiPhysRangeFirstFree[ rangeID ];
- while( addr <= gaiPhysRangeLastFree[ rangeID ] )
+ addr = giPhysFirstFree;
+ while( addr <= giPhysLastFree )
{
#if USE_SUPER_BITMAP
// Check the super bitmap
{
LOG("nFree = %i = 0 (super) (0x%x)", nFree, addr);
nFree = 0;
- addr += 1LL << (6+6);
- addr &= ~0xFFF; // (1LL << 6+6) - 1
+ addr += (32*32);
+ addr &= ~(32*32-1); // (1LL << 6+6) - 1
continue;
}
#endif
+ LOG("gaPageBitmaps[%i] = 0x%x", addr/32, gaPageBitmaps[addr/32]);
// Check page block (32 pages)
if( gaPageBitmaps[addr / 32] == 0) {
- LOG("nFree = %i = 0 (main) (0x%x)", nFree, addr);
+ LOG("nFree = %i = 0 (block) (0x%x)", nFree, addr);
nFree = 0;
- addr += 1LL << (6);
- addr &= ~0x3F;
+ addr += 32;
+ addr &= ~31;
continue;
}
// Check individual page
}
nFree ++;
addr ++;
- LOG("nFree(%i) == %i (0x%x)", nFree, Pages, addr);
+ LOG("nFree(%i) == %i (1x%x)", nFree, Pages, addr);
if(nFree == Pages)
break;
}
if( !nFree )
{
+#if 0
// Oops. ok, let's do an expensive check (scan down the list
// until a free range is found)
nFree = 1;
addr = gaiPhysRangeLastFree[ rangeID ];
// TODO
+#endif
Mutex_Release(&glPhysicalPages);
// TODO: Page out
// ATM. Just Warning
LEAVE('i', 0);
return 0;
}
- LOG("nFree = %i, addr = 0x%08x", nFree, addr);
+ LOG("nFree = %i, addr = 0x%08x", nFree, (addr-Pages) << 12);
// Mark pages as allocated
addr -= Pages;
// Mark as used
gaPageBitmaps[addr / 32] &= ~(1 << (addr & 31));
// Maintain first possible free
- rangeID = MM_int_GetRangeID(addr * PAGE_SIZE);
- gaiPhysRangeNumFree[ rangeID ] --;
- if(addr == gaiPhysRangeFirstFree[ rangeID ])
- gaiPhysRangeFirstFree[ rangeID ] += 1;
+ giPhysNumFree --;
+ if(addr == giPhysFirstFree)
+ giPhysFirstFree += 1;
+ LOG("if( MM_GetPhysAddr( %p ) )", &gaiPageReferences[addr]);
// Mark as referenced if the reference count page is valid
- if(MM_GetPhysAddr( (tVAddr)&gaiPageReferences[addr] )) {
+ if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[addr] ) ) {
gaiPageReferences[addr] = 1;
}
}
- ret = addr; // Save the return address
-
+ ret = addr - Pages; // Save the return address
+ LOG("ret = %x", ret);
+
#if USE_SUPER_BITMAP
// Update super bitmap
Pages += addr & (32-1);
Uint64 page = PAddr >> 12;
if( PAddr >> 12 > giMaxPhysPage ) return ;
+
+ ENTER("PPAddr", PAddr);
if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[page] ) )
{
// Update the free counts if the page was freed
if( gaPageBitmaps[ page / 32 ] & (1LL << (page&31)) )
{
- int rangeID;
- rangeID = MM_int_GetRangeID( PAddr );
- gaiPhysRangeNumFree[ rangeID ] ++;
- if( gaiPhysRangeFirstFree[rangeID] > page )
- gaiPhysRangeFirstFree[rangeID] = page;
- if( gaiPhysRangeLastFree[rangeID] < page )
- gaiPhysRangeLastFree[rangeID] = page;
+ giPhysNumFree ++;
+ if( giPhysFirstFree == -1 || giPhysFirstFree > page )
+ giPhysFirstFree = page;
+ if( giPhysLastFree < page )
+ giPhysLastFree = page;
}
#if USE_SUPER_BITMAP
gaSuperBitmap[page / (32*32)] |= 1LL << ((page / 32) & 31);
}
#endif
+ LEAVE('-');
}
int MM_SetPageNode(tPAddr PAddr, void *Node)