From f6ba89ba93581eea2877276e864869724a4271d7 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 25 Sep 2011 09:41:57 +0800 Subject: [PATCH] Kernel/arm7 - Debugging - lib.c - Updated to use a composite divide/modulo function --- Kernel/arch/arm7/debug.c | 2 +- Kernel/arch/arm7/main.c | 6 ++ Kernel/arch/arm7/mm_phys.c | 4 +- Kernel/arch/arm7/mm_virt.c | 16 ++++- Kernel/arch/x86/proc.c | 2 +- Kernel/include/acess.h | 15 ++-- Kernel/include/tpl_mm_phys_bitmap.h | 104 +++++++++++++++------------- Kernel/lib.c | 7 +- Kernel/logging.c | 2 +- 9 files changed, 95 insertions(+), 63 deletions(-) diff --git a/Kernel/arch/arm7/debug.c b/Kernel/arch/arm7/debug.c index 6d0232f2..12794983 100644 --- a/Kernel/arch/arm7/debug.c +++ b/Kernel/arch/arm7/debug.c @@ -42,7 +42,7 @@ void KernelPanic_SetMode(void) void KernelPanic_PutChar(char ch) { - Debug_PutCharDebug(ch); +// Debug_PutCharDebug(ch); } void StartupPrint(const char *str) diff --git a/Kernel/arch/arm7/main.c b/Kernel/arch/arm7/main.c index 455fe839..e8bc3757 100644 --- a/Kernel/arch/arm7/main.c +++ b/Kernel/arch/arm7/main.c @@ -9,6 +9,8 @@ // === 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); @@ -21,6 +23,10 @@ int kmain(void) // Interrupts_Setup(); MM_SetupPhys(); + + Heap_Install(); + + Threads_Init(); //TODO: LogF("End of kmain(), for(;;);\n"); diff --git a/Kernel/arch/arm7/mm_phys.c b/Kernel/arch/arm7/mm_phys.c index cc16463e..0a7632ce 100644 --- a/Kernel/arch/arm7/mm_phys.c +++ b/Kernel/arch/arm7/mm_phys.c @@ -4,6 +4,8 @@ * ARM7 Physical Memory Manager * arch/arm7/mm_phys.c */ +#define DEBUG 0 + #include #include @@ -34,7 +36,7 @@ int MM_int_GetMapEntry( void *Data, int Index, tPAddr *Start, tPAddr *Length ) { case 0: *Start = ((tVAddr)&gKernelEnd - KERNEL_BASE + 0xFFF) & ~0xFFF; - *Length = 16*1024*1024; + *Length = 16*1024*1024 - *Start; return 1; default: return 0; diff --git a/Kernel/arch/arm7/mm_virt.c b/Kernel/arch/arm7/mm_virt.c index 6744bae2..d069248e 100644 --- a/Kernel/arch/arm7/mm_virt.c +++ b/Kernel/arch/arm7/mm_virt.c @@ -151,6 +151,8 @@ int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) 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; } else { @@ -159,7 +161,7 @@ int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) } break; case 20: // Section or unmapped - Log_Warning("MM", "TODO: Implement sections"); + Warning("TODO: Implement sections"); break; case 24: // Supersection // Error if not aligned @@ -184,6 +186,7 @@ int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) LEAVE('i', 0); return 0; } + // TODO: What here? LEAVE('i', 1); return 1; } @@ -192,6 +195,8 @@ int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) return 1; } +extern tShortSpinlock glDebug_Lock; + int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) { Uint32 *table0, *table1; @@ -200,11 +205,15 @@ int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) 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; + switch( (desc & 3) ) { // 0: Unmapped @@ -220,6 +229,7 @@ int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) 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 @@ -239,7 +249,7 @@ int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) pi->bExecutable = desc & 1; pi->bGlobal = !(desc >> 11); pi->bShared = (desc >> 10) & 1; - return 1; + return 0; } return 1; @@ -277,7 +287,7 @@ tPAddr MM_GetPhysAddr(tVAddr VAddr) tMM_PageInfo pi; if( MM_int_GetPageInfo(VAddr, &pi) ) return 0; - return pi.PhysAddr; + return pi.PhysAddr | (VAddr & ((1 << pi.Size)-1)); } Uint MM_GetFlags(tVAddr VAddr) diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index 8598fa65..b1b18a6a 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -640,7 +640,7 @@ int Proc_Clone(Uint Flags) * \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; diff --git a/Kernel/include/acess.h b/Kernel/include/acess.h index 6373cec5..d1e0b155 100644 --- a/Kernel/include/acess.h +++ b/Kernel/include/acess.h @@ -7,6 +7,7 @@ #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 )) @@ -33,6 +34,9 @@ typedef struct sShortSpinlock tShortSpinlock; #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)) /** * \} @@ -307,10 +311,10 @@ extern int MM_GetPageNode(tPAddr PAddr, void **Node); * \{ */ 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); /** * \} */ @@ -438,7 +442,7 @@ extern void Time_Delay(int Delay); * \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); @@ -457,6 +461,7 @@ extern int Threads_SetName(const char *NewName); // --- Simple Math --- extern int DivUp(int num, int dem); +extern Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem); #include #include diff --git a/Kernel/include/tpl_mm_phys_bitmap.h b/Kernel/include/tpl_mm_phys_bitmap.h index 89c942b0..b5c39ff1 100644 --- a/Kernel/include/tpl_mm_phys_bitmap.h +++ b/Kernel/include/tpl_mm_phys_bitmap.h @@ -4,8 +4,6 @@ * include/tpl_mm_phys_bitmap.h * Physical Memory Manager Template */ -#define DEBUG 0 - /* * Bitmap Edition * @@ -33,9 +31,9 @@ Uint32 *gaiPageReferences = (void*)MM_PAGE_REFCOUNTS; // Reference Counts 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 === /** @@ -52,27 +50,47 @@ void MM_Tpl_InitPhys(int MaxRAMPage, void *MemoryMap) 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 ) { @@ -86,6 +104,7 @@ void MM_Tpl_InitPhys(int MaxRAMPage, void *MemoryMap) gbPMM_Init = 1; + LOG("giPhysFirstFree = 0x%x, giPhysLastFree = 0x%x", giPhysFirstFree, giPhysLastFree); LEAVE('-'); } @@ -100,37 +119,21 @@ void MM_Tpl_InitPhys(int MaxRAMPage, void *MemoryMap) 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 @@ -138,17 +141,18 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) { 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 @@ -161,7 +165,7 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) } nFree ++; addr ++; - LOG("nFree(%i) == %i (0x%x)", nFree, Pages, addr); + LOG("nFree(%i) == %i (1x%x)", nFree, Pages, addr); if(nFree == Pages) break; } @@ -173,11 +177,13 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) 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 @@ -189,7 +195,7 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) 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; @@ -198,18 +204,19 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) // 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); @@ -329,6 +336,8 @@ void MM_DerefPhys(tPAddr PAddr) Uint64 page = PAddr >> 12; if( PAddr >> 12 > giMaxPhysPage ) return ; + + ENTER("PPAddr", PAddr); if( MM_GetPhysAddr( (tVAddr)&gaiPageReferences[page] ) ) { @@ -350,13 +359,11 @@ void MM_DerefPhys(tPAddr PAddr) // 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 @@ -365,6 +372,7 @@ void MM_DerefPhys(tPAddr PAddr) gaSuperBitmap[page / (32*32)] |= 1LL << ((page / 32) & 31); } #endif + LEAVE('-'); } int MM_SetPageNode(tPAddr PAddr, void *Node) diff --git a/Kernel/lib.c b/Kernel/lib.c index a30bdfce..28edc561 100644 --- a/Kernel/lib.c +++ b/Kernel/lib.c @@ -159,6 +159,7 @@ void itoa(char *buf, Uint64 num, int base, int minLength, char pad) { char tmpBuf[64+1]; int pos=0, i; + Uint64 rem; // Sanity check if(!buf) return; @@ -171,11 +172,11 @@ void itoa(char *buf, Uint64 num, int base, int minLength, char pad) // 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 ]; pos++; } - tmpBuf[pos++] = cUCDIGITS[ num % base ]; // Last digit of `num` + tmpBuf[pos++] = cUCDIGITS[ num ]; // Last digit of `num` // Put in reverse i = 0; diff --git a/Kernel/logging.c b/Kernel/logging.c index 0cfc3ded..b419be3d 100644 --- a/Kernel/logging.c +++ b/Kernel/logging.c @@ -178,7 +178,7 @@ void Log_KernelPanic(const char *Ident, const char *Message, ...) va_start(args, Message); Log_AddEvent(Ident, LOG_LEVEL_KPANIC, Message, args); va_end(args); - Panic("Log_KernelPanic"); + Panic("Log_KernelPanic - %s", Ident); } /** -- 2.20.1