From: John Hodge Date: Fri, 14 Oct 2011 06:11:47 +0000 (+0800) Subject: Kernel/armv7 - Fixing bugs, Proc_Clone works now X-Git-Tag: rel0.13~72 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=e31829ecc2b8ae2338745f4ed393748704a81531;p=tpg%2Facess2.git Kernel/armv7 - Fixing bugs, Proc_Clone works now - Also fixed a few bugs in tpl_mm_phys_bitmap --- diff --git a/Kernel/arch/armv7/include/mm_virt.h b/Kernel/arch/armv7/include/mm_virt.h index 1228998f..dc1ed3cf 100644 --- a/Kernel/arch/armv7/include/mm_virt.h +++ b/Kernel/arch/armv7/include/mm_virt.h @@ -13,7 +13,7 @@ #define MM_KSTACK_END 0x7F000000 #define MM_PPD_HANDLES 0x7F800000 #define MM_TABLE1USER 0x7FC00000 // 2 GiB - 4 MiB -#define MM_TABLE0USER 0x7FDFC000 // 2 GiB - 2 MiB - 4 pages +#define MM_TABLE0USER 0x7FE00000 // 2 GiB - 2 MiB // Page Blocks are 12-bits wide (12 address bits used) // Hence, the table is 16KiB large (and must be so aligned) diff --git a/Kernel/arch/armv7/lib.c b/Kernel/arch/armv7/lib.c index 7e54afe4..a44489af 100644 --- a/Kernel/arch/armv7/lib.c +++ b/Kernel/arch/armv7/lib.c @@ -7,6 +7,7 @@ // === PROTOTYPES === Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem); +Uint32 __divmod32(Uint32 Num, Uint32 Den, Uint32 *Rem); Uint64 __udivdi3(Uint64 Num, Uint64 Den); Uint64 __umoddi3(Uint64 Num, Uint64 Den); Uint32 __udivsi3(Uint32 Num, Uint32 Den); @@ -113,35 +114,24 @@ void *memset(void *_dest, int _value, size_t _length) return _dest; } -Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem) -{ - Uint64 ret, add; - - ret = 0; - add = 1; +// Divide +// - Find what power of two times Den is > Num +// - Iterate down in bit significance +// > If the `N` value is greater than `D`, we can set this bit +#define DEF_DIVMOD(s) Uint##s __divmod##s(Uint##s N, Uint##s D, Uint##s*Rem){\ + Uint##s ret=0,add=1;\ + while(N>=D&&add) {D<<=1;add<<=1;}\ + while(add>1){\ + add>>=1;D>>=1;\ + if(N>=D){ret+=add;N-=D;}\ + }\ + if(Rem)*Rem = N;\ + return ret;\ +} - // Find what power of two times Den is > Num - while( Num >= Den ) - { - Den <<= 1; - add <<= 1; - } +DEF_DIVMOD(64) +DEF_DIVMOD(32) - // Search backwards - while( add > 1 ) - { - add >>= 1; - Den >>= 1; - // If the numerator is > Den, subtract and add to return value - if( Num >= Den ) - { - ret += add; - Num -= Den; - } - } - if(Rem) *Rem = Num; - return ret; -} Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem) { @@ -172,62 +162,14 @@ Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem) return Num >> 12; } - #if 0 - { - // http://www.tofla.iconbar.com/tofla/arm/arm02/index.htm - Uint64 tmp = 1; - __asm__ __volatile__( - "1:" - "cmpl %2,%1" - "movls %2,%2,lsl#1" - "movls %3,%3,lsl#1" - "bls 1b" - "2:" - "cmpl %" - while(Num > Den) { - Den <<= 1; - tmp <<= 1; - } - Den >>= 1; tmp >>= 1; - while( - } - if(Rem) *Rem = Num; - return ret; - #elif 0 - for( ret = 0; Num > Den; ret ++, Num -= Den) ; - if(Rem) *Rem = Num; - return ret; - #else ret = __divmod64(Num, Den, Rem); return ret; - #endif } // Unsigned Divide 64-bit Integer Uint64 __udivdi3(Uint64 Num, Uint64 Den) { return DivMod64U(Num, Den, NULL); - #if 0 -// if( Den == 0 ) return 5 / (Uint32)Den; // Force a #DIV0 - if( Den == 16 ) return Num >> 4; - if( Den == 256 ) return Num >> 8; - if( Den == 512 ) return Num >> 9; - if( Den == 1024 ) return Num >> 10; - if( Den == 2048 ) return Num >> 11; - if( Den == 4096 ) return Num >> 12; - if( Num < Den ) return 0; - if( Num <= 0xFFFFFFFF && Den <= 0xFFFFFFFF ) - return (Uint32)Num / (Uint32)Den; - - #if 0 - if( Den <= 0xFFFFFFFF ) { - (Uint32)(Num >> 32) / (Uint32)Den - } - #endif - Uint64 ret = 0; - for( ret = 0; Num > Den; ret ++, Num -= Den ); - return ret; - #endif } // Unsigned Modulus 64-bit Integer @@ -236,28 +178,6 @@ Uint64 __umoddi3(Uint64 Num, Uint64 Den) Uint64 ret = 0; DivMod64U(Num, Den, &ret); return ret; - #if 0 - if( Den == 0 ) return 5 / (Uint32)Den; // Force a #DIV0 - if( Num < Den ) return Num; - if( Den == 1 ) return 0; - if( Den == 2 ) return Num & 1; - if( Den == 16 ) return Num & 3; - if( Den == 256 ) return Num & 0xFF; - if( Den == 512 ) return Num & 0x1FF; - if( Den == 1024 ) return Num & 0x3FF; - if( Den == 2048 ) return Num & 0x7FF; - if( Den == 4096 ) return Num & 0xFFF; -// if( Num <= 0xFFFFFFFF && Den <= 0xFFFFFFFF ) -// return (Uint32)Num % (Uint32)Den; - - #if 0 - if( Den <= 0xFFFFFFFF ) { - (Uint32)(Num >> 32) / (Uint32)Den - } - #endif - for( ; Num > Den; Num -= Den ); - return Num; - #endif } #define _divide_s_32(Num, Den, rem) __asm__ __volatile__ ( \ @@ -274,33 +194,14 @@ Uint64 __umoddi3(Uint64 Num, Uint64 Den) ) Uint32 __udivsi3(Uint32 Num, Uint32 Den) { - register Uint32 ret; - Uint64 P, D; - int i; - - if( Num == 0 ) return 0; - if( Den == 0 ) return 0xFFFFFFFF; // TODO: Throw an error - if( Den == 1 ) return Num; - - D = ((Uint64)Den) << 32; - - for( i = 32; i --; ) - { - P = 2*P - D; - if( P >= 0 ) - ret |= 1; - else - P += D; - ret <<= 1; - } - -// _divide_s_32(Num, Den, rem); - return Num; + return __divmod32(Num, Den, NULL); } Uint32 __umodsi3(Uint32 Num, Uint32 Den) { - return Num - __udivsi3(Num, Den)*Den; + Uint32 rem; + __divmod32(Num, Den, &rem); + return rem; } Sint32 __divsi3(Sint32 Num, Sint32 Den) @@ -317,7 +218,12 @@ Sint32 __divsi3(Sint32 Num, Sint32 Den) Sint32 __modsi3(Sint32 Num, Sint32 Den) { - //register Sint32 rem; - //_divide_s_32(Num, Den, rem); - return Num - __divsi3(Num, Den) * Den; + if( (Num < 0) && (Den < 0) ) + return __umodsi3(-Num, -Den); + else if( Num < 0 ) + return __umodsi3(-Num, Den); + else if( Den < 0 ) + return __umodsi3(Den, -Den); + else + return __umodsi3(Den, Den); } diff --git a/Kernel/arch/armv7/mm_phys.c b/Kernel/arch/armv7/mm_phys.c index 0a7632ce..8a210aec 100644 --- a/Kernel/arch/armv7/mm_phys.c +++ b/Kernel/arch/armv7/mm_phys.c @@ -11,6 +11,7 @@ #define MM_NUM_RANGES 1 // Single range #define MM_RANGE_MAX 0 +#define TRACE_ALLOCS 0 #define NUM_STATIC_ALLOC 4 diff --git a/Kernel/arch/armv7/mm_virt.c b/Kernel/arch/armv7/mm_virt.c index a023c423..4a8a1fa3 100644 --- a/Kernel/arch/armv7/mm_virt.c +++ b/Kernel/arch/armv7/mm_virt.c @@ -34,6 +34,7 @@ typedef struct #define FRACTAL(table1, addr) ((table1)[ (0xFF8/4*1024) + ((addr)>>22)]) #define USRFRACTAL(table1, addr) ((table1)[ (0x7F8/4*1024) + ((addr)>>22)]) #define TLBIALL() __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0)) +#define TLBIMVA(addr) __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 1" : : "r" (addr)) // === PROTOTYPES === void MM_int_GetTables(tVAddr VAddr, Uint32 **Table0, Uint32 **Table1); @@ -124,7 +125,7 @@ int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) Uint32 *table0, *table1; Uint32 *desc; - ENTER("pVADdr ppi", VAddr, pi); + ENTER("pVAddr ppi", VAddr, pi); MM_int_GetTables(VAddr, &table0, &table1); @@ -158,6 +159,7 @@ 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 + TLBIMVA(VAddr & 0xFFFFF000); LEAVE('i', 0); return 0; } @@ -165,6 +167,7 @@ int MM_int_SetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) { // Large page // TODO: + Log_Warning("MMVirt", "TODO: Implement large pages in MM_int_SetPageInfo"); } break; case 20: // Section or unmapped @@ -250,8 +253,6 @@ int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi) pi->AP = ((desc >> 4) & 3) | (((desc >> 9) & 1) << 2); pi->bExecutable = !(desc & 0x8000); pi->bShared = (desc >> 10) & 1; -// LogF("Large page, VAddr = %p, table1[VAddr>>12] = %p, desc = %x\n", VAddr, &table1[ VAddr >> 12 ], desc); -// LogF("Par desc = %p %x\n", &table0[ VAddr >> 20 ], table0[ VAddr >> 20 ]); return 0; // 2/3: Small page case 2: @@ -344,6 +345,8 @@ void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask) int MM_Map(tVAddr VAddr, tPAddr PAddr) { tMM_PageInfo pi = {0}; +// Log("MM_Map %P=>%p", PAddr, VAddr); + pi.PhysAddr = PAddr; pi.Size = 12; pi.AP = AP_KRW_ONLY; // Kernel Read/Write @@ -402,11 +405,15 @@ tPAddr MM_AllocateRootTable(void) if( ret & 0x1000 ) { MM_DerefPhys(ret); ret += 0x1000; +// Log("MM_AllocateRootTable: Second try not aligned, %P", ret); } else { MM_DerefPhys(ret + 0x2000); +// Log("MM_AllocateRootTable: Second try aligned, %P", ret); } } +// else +// Log("MM_AllocateRootTable: Got it in one, %P", ret); return ret; } @@ -467,10 +474,8 @@ tPAddr MM_Clone(void) for( i = 1; i < 0x800-4; i ++ ) { // Log("i = %i", i); - if( i == 0x400 ) { + if( i == 0x400 ) tmp_map = &new_lvl1_2[-0x400]; - Log("tmp_map = %p", tmp_map); - } switch( cur[i] & 3 ) { case 0: tmp_map[i] = 0; break; @@ -493,25 +498,35 @@ tPAddr MM_Clone(void) Uint32 *table = (void*)MM_MapTemp(tmp); Uint32 sp; register Uint32 __SP asm("sp"); + Log("new_lvl1_2 = %p, &new_lvl1_2[0x3FC] = %p", new_lvl1_2, &new_lvl1_2[0x3FC]); // Map table to last 4MiB of user space - tmp_map[i+0] = tmp + 0*0x400 + 1; - tmp_map[i+1] = tmp + 1*0x400 + 1; - tmp_map[i+2] = tmp + 2*0x400 + 1; - tmp_map[i+3] = tmp + 3*0x400 + 1; - for( j = 0; j < 256; j ++ ) { - table[j] = new_lvl1_1[j*4] & PADDR_MASK_LVL1;// 0xFFFFFC00; - table[j] |= 0x10|3; // Kernel Only, Small table, XN - } - for( ; j < 512; j ++ ) { - table[j] = new_lvl1_2[(j-256)*4] & PADDR_MASK_LVL1;// 0xFFFFFC00; - table[j] |= 0x10|3; // Kernel Only, Small table, XN + new_lvl1_2[0x3FC] = tmp + 0*0x400 + 1; + new_lvl1_2[0x3FD] = tmp + 1*0x400 + 1; + new_lvl1_2[0x3FE] = tmp + 2*0x400 + 1; + new_lvl1_2[0x3FF] = tmp + 3*0x400 + 1; + + tmp_map = new_lvl1_1; + for( j = 0; j < 512; j ++ ) + { + if( j == 256 ) + tmp_map = &new_lvl1_2[-0x400]; + if( (tmp_map[j*4] & 3) == 1 ) + { + table[j] = tmp_map[j*4] & PADDR_MASK_LVL1;// 0xFFFFFC00; + table[j] |= 0x813; // nG, Kernel Only, Small page, XN + } + else + table[j] = 0; } + // Fractal + table[j++] = (ret + 0x0000) | 0x813; + table[j++] = (ret + 0x1000) | 0x813; + Log("table[%i] = %x, table[%i] = %x", j-2, table[j-2], j-1, table[j-1]); for( ; j < 1024; j ++ ) table[j] = 0; // Get kernel stack bottom - sp = __SP; - sp &= ~(MM_KSTACK_SIZE-1); + sp = __SP & ~(MM_KSTACK_SIZE-1); j = (sp / 0x1000) % 1024; num = MM_KSTACK_SIZE/0x1000; Log("sp = %p, j = %i", sp, j); @@ -519,22 +534,30 @@ tPAddr MM_Clone(void) // Copy stack pages for(; num--; j ++, sp += 0x1000) { - tVAddr page = MM_AllocPhys(); + tVAddr page; void *tmp_page; - table[j] = page | 0x13; + + page = MM_AllocPhys(); + table[j] = page | 0x813; + tmp_page = (void*)MM_MapTemp(page); memcpy(tmp_page, (void*)sp, 0x1000); - MM_FreeTemp( (tVAddr)tmp_page ); + MM_FreeTemp( (tVAddr) tmp_page ); } - + +// Debug_HexDump("MMVirt - last table", table, 0x1000); + MM_FreeTemp( (tVAddr)table ); } - tmp_map = &tmp_map[0x400]; - MM_FreeTemp( (tVAddr)tmp_map ); +// Debug_HexDump("MMVirt - Return page 1", new_lvl1_1, 0x1000); +// Debug_HexDump("MMVirt - Return page 2", new_lvl1_2, 0x1000); + + MM_FreeTemp( (tVAddr)new_lvl1_1 ); + MM_FreeTemp( (tVAddr)new_lvl1_2 ); - Log("Table dump"); - MM_DumpTables(0, -1); +// Log("Table dump"); +// MM_DumpTables(0, -1); return ret; } @@ -549,12 +572,14 @@ tVAddr MM_MapTemp(tPAddr PAddr) { tVAddr ret; tMM_PageInfo pi; - + for( ret = MM_TMPMAP_BASE; ret < MM_TMPMAP_END - PAGE_SIZE; ret += PAGE_SIZE ) { if( MM_int_GetPageInfo(ret, &pi) == 0 ) continue; - + +// Log("MapTemp %P at %p", PAddr, ret); + MM_RefPhys(PAddr); // Counter the MM_Deallocate in FreeTemp MM_Map(ret, PAddr); return ret; @@ -682,9 +707,11 @@ void MM_DumpTables(tVAddr Start, tVAddr End) pi_old.Size = 0; + Log("Page Table Dump:"); range_start = Start; for( addr = Start; i == 0 || (addr && addr < End); i = 1 ) { +// Log("addr = %p", addr); int rv = MM_int_GetPageInfo(addr, &pi); if( rv || pi.Size != pi_old.Size diff --git a/Kernel/arch/armv7/proc.S b/Kernel/arch/armv7/proc.S index e9273146..37f9650a 100644 --- a/Kernel/arch/armv7/proc.S +++ b/Kernel/arch/armv7/proc.S @@ -51,7 +51,7 @@ SwitchTask: str sp, [r1] @ Only update TTBR0 if the task has an explicit address space - ldr r1, [sp,#0x40] + ldr r1, [sp,#4*10] tst r1, r1 mcrne p15, 0, r1, c2, c0, 0 @ Set TTBR0 to r0 @@ -79,8 +79,20 @@ Proc_CloneInt: ldr r0, =Proc_CloneInt_new pop {r4-r12,pc} Proc_CloneInt_new: + cps #18 + mov r0, #0 mov r1, #0x80000000 bl MM_DumpTables + +@ ldr r0, =csProc_CloneInt_NewTaskMessage +@ bl Log + + cps #19 mov r0, #0 pop {r4-r12,pc} + + +.section .rodata +csProc_CloneInt_NewTaskMessage: + .asciz "New task" diff --git a/Kernel/arch/armv7/proc.c b/Kernel/arch/armv7/proc.c index c336fc3f..e3696489 100644 --- a/Kernel/arch/armv7/proc.c +++ b/Kernel/arch/armv7/proc.c @@ -167,8 +167,10 @@ void Proc_Reschedule(void) if(!next) next = gpIdleThread; if(!next || next == cur) return; - Log("Switching to %p (%i %s)", next, next->TID, next->ThreadName); - Log(" IP=%p SP=%p TTBR0=%p", next->SavedState.IP, next->SavedState.SP, next->MemState.Base); + Log("Switching to %p (%i %s) IP=%p SP=%p TTBR0=%p", + next, next->TID, next->ThreadName, + next->SavedState.IP, next->SavedState.SP, next->MemState.Base + ); Log("Requested by %p", __builtin_return_address(0)); gpCurrentThread = next; diff --git a/Kernel/arch/armv7/start.S b/Kernel/arch/armv7/start.S index faf10ea9..fb3ecd08 100644 --- a/Kernel/arch/armv7/start.S +++ b/Kernel/arch/armv7/start.S @@ -187,15 +187,14 @@ kernel_table0: @ User table1 data table (only the first half is needed) @ - Abused to provide kernel stacks in upper half user_table1_map: @ Size = 4KiB (only 2KiB used) - .rept 0x800/4-4 + .rept 0x800/4-1 .long 0 .endr - .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x10 + 3 @ ...1FC000 = 0x7FDDC000 - .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x10 + 3 @ ...1FD000 = 0x7FDDD000 - .long 0 .long user_table1_map - KERNEL_BASE + 0x10 + 3 @ ...1FF000 = 0x7FDFF000 @ Kernel stack zone - .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000) + .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x10 + 3 @ ...200000 = 0x7FE00000 + .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x10 + 3 @ ...201000 = 0x7FE01000 + .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000)-2 .long 0 .endr #if MM_KSTACK_SIZE != 0x2000 diff --git a/Kernel/include/tpl_mm_phys_bitmap.h b/Kernel/include/tpl_mm_phys_bitmap.h index b5c39ff1..0874ab62 100644 --- a/Kernel/include/tpl_mm_phys_bitmap.h +++ b/Kernel/include/tpl_mm_phys_bitmap.h @@ -14,6 +14,10 @@ #define MM_PAGE_NODES (MM_PMM_BASE+(MM_MAXPHYSPAGE*sizeof(Uint32))) #define MM_PAGE_BITMAP (MM_PAGE_NODES+(MM_MAXPHYSPAGE*sizeof(void*))) +#define PAGE_BITMAP_FREE(__pg) (gaPageBitmaps[(__pg)/32] & (1LL << ((__pg)&31))) +#define PAGE_BITMAP_SETFREE(__pg) do{gaPageBitmaps[(__pg)/32] |= (1LL << ((__pg)&31));}while(0) +#define PAGE_BITMAP_SETUSED(__pg) do{gaPageBitmaps[(__pg)/32] &= ~(1LL << ((__pg)&31));}while(0) + // === PROTOTYPES === //void MM_InitPhys_Multiboot(tMBoot_Info *MBoot); //tPAddr MM_AllocPhysRange(int Num, int Bits); @@ -202,7 +206,7 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) for( i = 0; i < Pages; i++, addr++ ) { // Mark as used - gaPageBitmaps[addr / 32] &= ~(1 << (addr & 31)); + PAGE_BITMAP_SETUSED(addr); // Maintain first possible free giPhysNumFree --; if(addr == giPhysFirstFree) @@ -217,6 +221,10 @@ tPAddr MM_AllocPhysRange(int Pages, int MaxBits) ret = addr - Pages; // Save the return address LOG("ret = %x", ret); + #if TRACE_ALLOCS + LogF("MM_AllocPhysRange: %P (%i pages)\n", ret, Pages); + #endif + #if USE_SUPER_BITMAP // Update super bitmap Pages += addr & (32-1); @@ -272,6 +280,9 @@ tPAddr MM_AllocPhys(void) Log_Error("PMM", "MM_AllocPhys failed duing init"); return 0; } + #if TRACE_ALLOCS + Log("AllocPhys by %p", __builtin_return_address(0)); + #endif return MM_AllocPhysRange(1, -1); } @@ -282,31 +293,41 @@ tPAddr MM_AllocPhys(void) void MM_RefPhys(tPAddr PAddr) { tPAddr page = PAddr / PAGE_SIZE; + tVAddr refpage = (tVAddr)&gaiPageReferences[page] & ~(PAGE_SIZE-1); if( page >= giMaxPhysPage ) return ; - - if( gaPageBitmaps[ page / 32 ] & (1LL << (page&31)) ) + + if( PAGE_BITMAP_FREE(page) ) { // Allocate - gaPageBitmaps[page / 32] &= ~(1LL << (page&31)); + PAGE_BITMAP_SETUSED(page); #if USE_SUPER_BITMAP if( gaPageBitmaps[page / 32] == 0 ) gaSuperBitmap[page / (32*32)] &= ~(1LL << ((page / 32) & 31)); #endif + if( MM_GetPhysAddr( refpage ) ) + gaiPageReferences[page] = 1; } else { - tVAddr refpage = (tVAddr)&gaiPageReferences[page] & ~(PAGE_SIZE-1); // Reference again if( !MM_GetPhysAddr( refpage ) ) { + int pages_per_page, basepage, i; if( MM_Allocate(refpage) == 0 ) { // Out of memory, can this be resolved? // TODO: Reclaim memory Log_Error("PMM", "Out of memory (MM_RefPhys)"); return ; } - memset((void*)refpage, 0, PAGE_SIZE); + pages_per_page = PAGE_SIZE/sizeof(*gaiPageReferences); + basepage = page & ~(pages_per_page-1); + for( i = 0; i < pages_per_page; i ++ ) { + if( PAGE_BITMAP_FREE(basepage+i) ) + gaiPageReferences[basepage+i] = 0; + else + gaiPageReferences[basepage+i] = 1; + } gaiPageReferences[page] = 2; } else diff --git a/Kernel/threads.c b/Kernel/threads.c index 57382a8c..78e53ac5 100644 --- a/Kernel/threads.c +++ b/Kernel/threads.c @@ -665,7 +665,7 @@ void Threads_Kill(tThread *Thread, int Status) */ void Threads_Yield(void) { - Log("Threads_Yield: by %p", __builtin_return_address(0)); +// Log("Threads_Yield: by %p", __builtin_return_address(0)); Proc_Reschedule(); }