From: John Hodge Date: Tue, 27 Sep 2011 12:53:52 +0000 (+0800) Subject: Kernel/armv7 - Task switching now supported X-Git-Tag: rel0.11~44 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=f9c581641afeb556188e84428febd4011e61edc2;p=tpg%2Facess2.git Kernel/armv7 - Task switching now supported - Also fixed nested locks in threads.c --- diff --git a/Kernel/Makefile b/Kernel/Makefile index 9d92cbfd..f76540cb 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -10,6 +10,10 @@ -include Makefile.BuildNum.$(ARCH) +ifeq ($(BUILDNUM),) +BUILDNUM = 0 +endif + KERNEL_VERSION = 0.5 MAKEDEP = $(CC) -M diff --git a/Kernel/arch/armv7/include/mm_virt.h b/Kernel/arch/armv7/include/mm_virt.h index b57e45c3..ef3de83f 100644 --- a/Kernel/arch/armv7/include/mm_virt.h +++ b/Kernel/arch/armv7/include/mm_virt.h @@ -5,11 +5,15 @@ #ifndef _MM_VIRT_H_ #define _MM_VIRT_H_ +#define MM_KSTACK_SIZE 0x10000 + #define MM_USER_MIN 0x00001000 -#define USER_LIB_MAX 0x7F800000 +#define USER_LIB_MAX 0x70000000 +#define MM_KSTACK_BASE 0x70000000 +#define MM_KSTACK_END 0x7F000000 #define MM_PPD_HANDLES 0x7F800000 -#define MM_TABLE0USER 0x7F900000 // 2 GiB - 16 KiB #define MM_TABLE1USER 0x7FC00000 // 2 GiB - 4 MiB +#define MM_TABLE0USER 0x7FEFE000 // 2 GiB - 2 MiB - 2 pages // Page Blocks are 12-bits wide (12 address bits used) // Hence, the table is 16KiB large (and must be so aligned) @@ -24,7 +28,10 @@ #define MM_KHEAP_MAX 0xC0000000 // ~1GiB of kernel heap #define MM_MODULE_MIN 0xC0000000 // - 0xD0000000 -#define MM_MODULE_MAX 0xD0000000 +#define MM_MODULE_MAX 0xCF000000 + +#define MM_GLOBALSTACKS 0xCF000000 // Global stacks +#define MM_GLOBALSTACKS_END 0xD0000000 // PMM Data, giving it 256MiB is overkill, but it's unused atm #define MM_MAXPHYSPAGE (1024*1024) @@ -41,6 +48,6 @@ #define MM_KERNEL_VFS 0xFF000000 // #define MM_TABLE1KERN 0xFF800000 // - 0x???????? 4MiB -#define MM_TABLE0KERN 0xFFC00000 // - 0xFFE04000 16KiB +//#define MM_TABLE0KERN 0xFFC00000 // - 0xFFE04000 16KiB #endif diff --git a/Kernel/arch/armv7/main.c b/Kernel/arch/armv7/main.c index b6186bbe..37eda682 100644 --- a/Kernel/arch/armv7/main.c +++ b/Kernel/arch/armv7/main.c @@ -40,8 +40,9 @@ int kmain(void) LogF("Moving to arch-independent init\n"); System_Init(""); //TODO: - LogF("End of kmain(), for(;;);\n"); - for(;;); + LogF("End of kmain(), for(;;) Threads_Sleep();\n"); + for(;;) + Threads_Sleep(); } void Arch_LoadBootModules(void) diff --git a/Kernel/arch/armv7/mm_virt.c b/Kernel/arch/armv7/mm_virt.c index c191c683..0fc426d4 100644 --- a/Kernel/arch/armv7/mm_virt.c +++ b/Kernel/arch/armv7/mm_virt.c @@ -324,9 +324,6 @@ void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask) tMM_PageInfo pi; if( MM_int_GetPageInfo(VAddr, &pi) ) return; - - - } int MM_Map(tVAddr VAddr, tPAddr PAddr) @@ -395,11 +392,46 @@ void MM_FreeTemp(tVAddr VAddr) // TODO: Implement FreeTemp } -tVAddr MM_NewKStack(int bGlobal) +tVAddr MM_NewKStack(int bShared) { - // TODO: Implement NewKStack - // TODO: Should I support global stacks? if only for the idle thread - return 0; + tVAddr min_addr, max_addr; + tVAddr addr, ofs; + + if( bShared ) { + min_addr = MM_GLOBALSTACKS; + max_addr = MM_GLOBALSTACKS_END; + } + else { + min_addr = MM_KSTACK_BASE; + max_addr = MM_KSTACK_END; + } + + // Locate a free slot + for( addr = min_addr; addr < max_addr; addr += MM_KSTACK_SIZE ) + { + tMM_PageInfo pi; + if( MM_int_GetPageInfo(addr+MM_KSTACK_SIZE-PAGE_SIZE, &pi) ) break; + } + + // Check for an error + if(addr >= max_addr) { + return 0; + } + + // 1 guard page + for( ofs = PAGE_SIZE; ofs < MM_KSTACK_SIZE; ofs += PAGE_SIZE ) + { + if( MM_Allocate(addr + ofs) == 0 ) { + while(ofs) + { + ofs -= PAGE_SIZE; + MM_Deallocate(addr + ofs); + } + Log_Warning("MMVirt", "MM_NewKStack: Unable to allocate"); + return 0; + } + } + return addr + ofs; } void MM_DumpTables(tVAddr Start, tVAddr End) diff --git a/Kernel/arch/armv7/proc.c b/Kernel/arch/armv7/proc.c index f4025cca..7dfbb456 100644 --- a/Kernel/arch/armv7/proc.c +++ b/Kernel/arch/armv7/proc.c @@ -2,7 +2,7 @@ * Acess2 * - By John Hodge (thePowersGang) * - * arch/arm7/proc. + * arch/arm7/proc.c * - ARM7 Process Switching */ #include @@ -12,12 +12,12 @@ // === IMPORTS === extern tThread gThreadZero; extern void SwitchTask(Uint32 NewSP, Uint32 *OldSP, Uint32 NewIP, Uint32 *OldIP, Uint32 MemPtr); -extern void KernelThreadHeader(void); // Actually takes args +extern void KernelThreadHeader(void); // Actually takes args on stack extern tVAddr MM_NewKStack(int bGlobal); // TODO: Move out into a header // === PROTOTYPES === void Proc_IdleThread(void *unused); -tTID Proc_NewKThread( void (*Fnc)(void*), void *Ptr ); +tTID Proc_NewKThread(void (*Fnc)(void*), void *Ptr); // === GLOBALS === tThread *gpCurrentThread = &gThreadZero; @@ -30,8 +30,10 @@ void ArchThreads_Init(void) void Proc_IdleThread(void *unused) { - for(;;) + for(;;) { + __asm__ __volatile__ ("wfi"); Proc_Reschedule(); + } } void Proc_Start(void) @@ -74,9 +76,10 @@ tTID Proc_NewKThread( void (*Fnc)(void*), void *Ptr ) new = Threads_CloneTCB(NULL, 0); if(!new) return -1; - new->KernelStack = MM_NewKStack(0); + new->KernelStack = MM_NewKStack(1); if(!new->KernelStack) { // TODO: Delete thread + Log_Error("Proc", "Unable to allocate kernel stack"); return -1; } @@ -109,7 +112,12 @@ void Proc_Reschedule(void) next = Threads_GetNextToRun(0, cur); if(!next) next = gpIdleThread; if(!next || next == cur) return; + + Log("Switching to %p (%i) IP=%p SP=%p", next, next->TID, next->SavedState.IP, next->SavedState.SP); + gpCurrentThread = next; + // TODO: Change kernel stack? + SwitchTask( next->SavedState.SP, &cur->SavedState.SP, next->SavedState.IP, &cur->SavedState.IP, diff --git a/Kernel/arch/armv7/start.S b/Kernel/arch/armv7/start.S index 718131c0..e1bbe0c9 100644 --- a/Kernel/arch/armv7/start.S +++ b/Kernel/arch/armv7/start.S @@ -52,9 +52,14 @@ IRQHandler: kernel_table0: .long 0x00000002 @ Identity map the first 1 MiB - .rept 0x800 - 1 + .rept 0x7FC - 1 .long 0 .endr + .long user_table1_map + 0x000 - KERNEL_BASE + 1 + .long user_table1_map + 0x400 - KERNEL_BASE + 1 + .long 0 @ user_table1_map + 0x800 - KERNEL_BASE + 1 + .long 0 @ user_table1_map + 0xC00 - KERNEL_BASE + 1 + @ 0x80000000 - User/Kernel split .long 0x00000002 @ Map first 4 MiB to 2GiB .long 0x00100002 @ .long 0x00200002 @ @@ -102,6 +107,18 @@ kernel_table0: .long 0 .endr +@ PID0 user table +.globl user_table1_map +user_table1_map: @ Size = 4KiB + .rept 0x7F8/4 + .long 0 + .endr + .long kernel_table0 - KERNEL_BASE + (1 << 4) + 3 + .long user_table1_map - KERNEL_BASE + (1 << 4) + 3 + .rept 0x800/4 + .long 0 + .endr + .globl kernel_table1_map kernel_table1_map: @ Size = 4KiB .rept 0xF00/4 diff --git a/Kernel/threads.c b/Kernel/threads.c index f84ca7c2..aac66480 100644 --- a/Kernel/threads.c +++ b/Kernel/threads.c @@ -904,14 +904,17 @@ void Threads_AddActive(tThread *Thread) /** * \brief Removes the current thread from the active queue - * \warning This should ONLY be called with task switches disabled + * \warning This should ONLY be called with the lock held * \return Current thread pointer */ tThread *Threads_RemActive(void) { tThread *ret = Proc_GetCurThread(); - - SHORTLOCK( &glThreadListLock ); + + if( !IS_LOCKED(&glThreadListLock) ) { + Log_KernelPanic("Threads", "Threads_RemActive called without lock held"); + return NULL; + } // Delete from active queue #if SCHEDULER_TYPE == SCHED_RR_PRI @@ -938,8 +941,6 @@ tThread *Threads_RemActive(void) GetCPUNum(), ret, ret->TID, ret->ThreadName, giFreeTickets); #endif - SHORTREL( &glThreadListLock ); - return ret; } diff --git a/Makefile.arm7.cfg b/Makefile.arm7.cfg deleted file mode 100644 index 992a88c3..00000000 --- a/Makefile.arm7.cfg +++ /dev/null @@ -1,8 +0,0 @@ - -CC = arm-elf-gcc -AS = arm-elf-gcc -c -LD = arm-elf-ld -OBJDUMP = arm-elf-objdump -DISASM = $(OBJDUMP) -d -S -ARCHDIR = arm7 -STRIP = arm-elf-strip diff --git a/Makefile.armv7.cfg b/Makefile.armv7.cfg new file mode 100644 index 00000000..dc35ca71 --- /dev/null +++ b/Makefile.armv7.cfg @@ -0,0 +1,8 @@ + +CC = arm-elf-gcc +AS = arm-elf-gcc -c +LD = arm-elf-ld +OBJDUMP = arm-elf-objdump +DISASM = $(OBJDUMP) -d -S +ARCHDIR = armv7 +STRIP = arm-elf-strip diff --git a/Makefile.cfg b/Makefile.cfg index c980f42e..c349d5ae 100644 --- a/Makefile.cfg +++ b/Makefile.cfg @@ -21,16 +21,17 @@ MKDIR := mkdir -p RMDIR := rm -rf lCP := cp + # Load Architecture settings ifeq ($(ARCH),) ARCH := i386 endif --include $(ACESSDIR)/Makefile.$(ARCH).cfg +include $(ACESSDIR)/Makefile.$(ARCH).cfg ifeq ($(ARCHDIR),) ARCHDIR := x86 endif ifneq ($(ARCH),host) --include $(ACESSDIR)/Makefile.$(ARCHDIR).cfg +include $(ACESSDIR)/Makefile.$(ARCHDIR).cfg endif # Makefile.user.cfg is not part of the Acess git repo, diff --git a/RunQemuArm b/RunQemuArm index 23b874e7..c0e1239c 100755 --- a/RunQemuArm +++ b/RunQemuArm @@ -5,7 +5,7 @@ QEMU=qemu-system-arm USE_GDB= _SYSTEM=realview-pb-a8 -_KERNEL=Acess2.arm7.bin +_KERNEL=Acess2.armv7.bin QEMU_PARAMS="" _NETTYPE="user"