- lib.c - Updated to use a composite divide/modulo function
void KernelPanic_PutChar(char ch)
{
void KernelPanic_PutChar(char ch)
{
- Debug_PutCharDebug(ch);
+// Debug_PutCharDebug(ch);
}
void StartupPrint(const char *str)
}
void StartupPrint(const char *str)
// === IMPORTS ===
extern void Interrupts_Setup(void);
extern void Arch_LoadBootModules(void);
// === IMPORTS ===
extern void Interrupts_Setup(void);
extern void Arch_LoadBootModules(void);
+extern void Heap_Install(void);
+extern void Threads_Init(void);
// === PROTOTYPES ===
int kmain(void);
// === PROTOTYPES ===
int kmain(void);
// Interrupts_Setup();
MM_SetupPhys();
// Interrupts_Setup();
MM_SetupPhys();
+
+ Heap_Install();
+
+ Threads_Init();
//TODO:
LogF("End of kmain(), for(;;);\n");
//TODO:
LogF("End of kmain(), for(;;);\n");
* ARM7 Physical Memory Manager
* arch/arm7/mm_phys.c
*/
* ARM7 Physical Memory Manager
* arch/arm7/mm_phys.c
*/
#include <acess.h>
#include <mm_virt.h>
#include <acess.h>
#include <mm_virt.h>
{
case 0:
*Start = ((tVAddr)&gKernelEnd - KERNEL_BASE + 0xFFF) & ~0xFFF;
{
case 0:
*Start = ((tVAddr)&gKernelEnd - KERNEL_BASE + 0xFFF) & ~0xFFF;
- *Length = 16*1024*1024;
+ *Length = 16*1024*1024 - *Start;
return 1;
default:
return 0;
return 1;
default:
return 0;
if( pi->bShared) *desc |= 1 << 10; // S
*desc |= (pi->AP & 3) << 4; // AP
*desc |= ((pi->AP >> 2) & 1) << 9; // APX
if( pi->bShared) *desc |= 1 << 10; // S
*desc |= (pi->AP & 3) << 4; // AP
*desc |= ((pi->AP >> 2) & 1) << 9; // APX
+ LEAVE('i', 0);
+ return 0;
}
break;
case 20: // Section or unmapped
}
break;
case 20: // Section or unmapped
- Log_Warning("MM", "TODO: Implement sections");
+ Warning("TODO: Implement sections");
break;
case 24: // Supersection
// Error if not aligned
break;
case 24: // Supersection
// Error if not aligned
LEAVE('i', 0);
return 0;
}
LEAVE('i', 0);
return 0;
}
LEAVE('i', 1);
return 1;
}
LEAVE('i', 1);
return 1;
}
+extern tShortSpinlock glDebug_Lock;
+
int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
{
Uint32 *table0, *table1;
int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
{
Uint32 *table0, *table1;
MM_int_GetTables(VAddr, &table0, &table1);
desc = table0[ VAddr >> 20 ];
MM_int_GetTables(VAddr, &table0, &table1);
desc = table0[ VAddr >> 20 ];
+
+// if( VAddr > 0x90000000)
+// LOG("table0 desc(%p) = %x", &table0[ VAddr >> 20 ], desc);
pi->bExecutable = 1;
pi->bGlobal = 0;
pi->bShared = 0;
pi->bExecutable = 1;
pi->bGlobal = 0;
pi->bShared = 0;
switch( (desc & 3) )
{
// 0: Unmapped
switch( (desc & 3) )
{
// 0: Unmapped
pi->Domain = (desc >> 5) & 7;
// Get next level
desc = table1[ VAddr >> 12 ];
pi->Domain = (desc >> 5) & 7;
// Get next level
desc = table1[ VAddr >> 12 ];
+// LOG("table1 desc(%p) = %x", &table1[ VAddr >> 12 ], desc);
switch( desc & 3 )
{
// 0: Unmapped
switch( desc & 3 )
{
// 0: Unmapped
pi->bExecutable = desc & 1;
pi->bGlobal = !(desc >> 11);
pi->bShared = (desc >> 10) & 1;
pi->bExecutable = desc & 1;
pi->bGlobal = !(desc >> 11);
pi->bShared = (desc >> 10) & 1;
tMM_PageInfo pi;
if( MM_int_GetPageInfo(VAddr, &pi) )
return 0;
tMM_PageInfo pi;
if( MM_int_GetPageInfo(VAddr, &pi) )
return 0;
+ return pi.PhysAddr | (VAddr & ((1 << pi.Size)-1));
}
Uint MM_GetFlags(tVAddr VAddr)
}
Uint MM_GetFlags(tVAddr VAddr)
* \fn int Proc_SpawnWorker(void)
* \brief Spawns a new worker thread
*/
* \fn int Proc_SpawnWorker(void)
* \brief Spawns a new worker thread
*/
-int Proc_SpawnWorker(void)
+int Proc_SpawnWorker(void (*Fcn)(void*), void *Data);
{
tThread *new, *cur;
Uint eip, esp, ebp;
{
tThread *new, *cur;
Uint eip, esp, ebp;
#define NULL ((void*)0)
#define PACKED __attribute__((packed))
#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 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)
#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))
/**
* \}
#define VER2(major,minor) ((((major)&0xFF)<<8)|((minor)&0xFF))
/**
* \}
* \{
*/
extern int memcmp(const void *m1, const void *m2, size_t count);
* \{
*/
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
* \{
*/
* \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);
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);
// --- 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 <binary_ext.h>
#include <vfs_ext.h>
* include/tpl_mm_phys_bitmap.h
* Physical Memory Manager Template
*/
* include/tpl_mm_phys_bitmap.h
* Physical Memory Manager Template
*/
Uint32 *gaPageBitmaps = (void*)MM_PAGE_BITMAP; // Used bitmap (1 == avail)
Uint64 giMaxPhysPage = 0; // Maximum Physical page
int gbPMM_Init = 0;
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;
giMaxPhysPage = MaxRAMPage;
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;
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;
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 ) ) {
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 ;
}
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);
}
// 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 ) {
}
// Mark blocks of 32 as avail
for( ; rangeLen > 31; rangeStart += 32, rangeLen -= 32 ) {
+ LOG("giPhysFirstFree = 0x%x, giPhysLastFree = 0x%x", giPhysFirstFree, giPhysLastFree);
tPAddr MM_AllocPhysRange(int Pages, int MaxBits)
{
tPAddr addr, ret;
tPAddr MM_AllocPhysRange(int Pages, int MaxBits)
{
tPAddr addr, ret;
int nFree = 0, i;
ENTER("iPages iBits", Pages, MaxBits);
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);
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
// 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;
// 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
{
#if USE_SUPER_BITMAP
// Check the super bitmap
{
LOG("nFree = %i = 0 (super) (0x%x)", nFree, addr);
nFree = 0;
{
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
+ LOG("gaPageBitmaps[%i] = 0x%x", addr/32, gaPageBitmaps[addr/32]);
// Check page block (32 pages)
if( gaPageBitmaps[addr / 32] == 0) {
// 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);
- addr += 1LL << (6);
- addr &= ~0x3F;
+ addr += 32;
+ addr &= ~31;
continue;
}
// Check individual page
continue;
}
// Check individual page
- LOG("nFree(%i) == %i (0x%x)", nFree, Pages, addr);
+ LOG("nFree(%i) == %i (1x%x)", nFree, Pages, addr);
if(nFree == Pages)
break;
}
if(nFree == Pages)
break;
}
// Oops. ok, let's do an expensive check (scan down the list
// until a free range is found)
nFree = 1;
addr = gaiPhysRangeLastFree[ rangeID ];
// TODO
// Oops. ok, let's do an expensive check (scan down the list
// until a free range is found)
nFree = 1;
addr = gaiPhysRangeLastFree[ rangeID ];
// TODO
Mutex_Release(&glPhysicalPages);
// TODO: Page out
// ATM. Just Warning
Mutex_Release(&glPhysicalPages);
// TODO: Page out
// ATM. Just Warning
LEAVE('i', 0);
return 0;
}
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 pages as allocated
addr -= Pages;
// Mark as used
gaPageBitmaps[addr / 32] &= ~(1 << (addr & 31));
// Maintain first possible free
// 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
// 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;
}
}
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);
#if USE_SUPER_BITMAP
// Update super bitmap
Pages += addr & (32-1);
Uint64 page = PAddr >> 12;
if( PAddr >> 12 > giMaxPhysPage ) return ;
Uint64 page = PAddr >> 12;
if( PAddr >> 12 > giMaxPhysPage ) return ;
+
+ ENTER("PPAddr", PAddr);
if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[page] ) )
{
if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[page] ) )
{
// Update the free counts if the page was freed
if( gaPageBitmaps[ page / 32 ] & (1LL << (page&31)) )
{
// 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;
gaSuperBitmap[page / (32*32)] |= 1LL << ((page / 32) & 31);
}
#endif
gaSuperBitmap[page / (32*32)] |= 1LL << ((page / 32) & 31);
}
#endif
}
int MM_SetPageNode(tPAddr PAddr, void *Node)
}
int MM_SetPageNode(tPAddr PAddr, void *Node)
{
char tmpBuf[64+1];
int pos=0, i;
{
char tmpBuf[64+1];
int pos=0, i;
// Sanity check
if(!buf) return;
// Sanity check
if(!buf) return;
// Convert
while(num > base-1) {
// Convert
while(num > base-1) {
- tmpBuf[pos] = cUCDIGITS[ num % base ];
- num /= (Uint)base; // Shift `num` right 1 digit
+ num = DivMod64U(num, base, &rem); // Shift `num` and get remainder
+ tmpBuf[pos] = cUCDIGITS[ rem ];
- tmpBuf[pos++] = cUCDIGITS[ num % base ]; // Last digit of `num`
+ tmpBuf[pos++] = cUCDIGITS[ num ]; // Last digit of `num`
va_start(args, Message);
Log_AddEvent(Ident, LOG_LEVEL_KPANIC, Message, args);
va_end(args);
va_start(args, Message);
Log_AddEvent(Ident, LOG_LEVEL_KPANIC, Message, args);
va_end(args);
- Panic("Log_KernelPanic");
+ Panic("Log_KernelPanic - %s", Ident);