From fed0a8f469f7b187d26c0c8cb109bfd6930efaee Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 13 May 2010 21:51:35 +0800 Subject: [PATCH] Fixed bugs caused by the segregation of timer code. - Also removed MM_IsUser from x86 and replaced it with MM_GetFlags - Added Kernel/time.c (I should have added this earlier) --- Kernel/Makefile.BuildNum | 2 +- Kernel/arch/x86/mm_virt.c | 40 +++++++++------ Kernel/arch/x86/proc.c | 4 +- Kernel/arch/x86/time.c | 1 + Kernel/time.c | 105 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 19 deletions(-) create mode 100644 Kernel/time.c diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index ae732f5f..efeefa47 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 2157 +BUILD_NUM = 2158 diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index cbf03fc6..aaec06ea 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -413,22 +413,6 @@ tPAddr MM_GetPhysAddr(tVAddr Addr) return (gaPageTable[Addr >> 12] & ~0xFFF) | (Addr & 0xFFF); } - -/** - * \fn int MM_IsUser(tVAddr VAddr) - * \brief Checks if a page is user accessable - */ -int MM_IsUser(tVAddr VAddr) -{ - if( !(gaPageDir[VAddr >> 22] & 1) ) - return 0; - if( !(gaPageTable[VAddr >> 12] & 1) ) - return 0; - if( !(gaPageTable[VAddr >> 12] & PF_USER) ) - return 0; - return 1; -} - /** * \fn void MM_SetCR3(Uint CR3) * \brief Sets the current process space @@ -827,6 +811,30 @@ void MM_SetFlags(tVAddr VAddr, Uint Flags, Uint Mask) // *ent, VAddr >> 22, gaPageDir[VAddr >> 22]); } +/** + * \brief Get the flags on a page + */ +Uint MM_GetFlags(tVAddr VAddr) +{ + tTabEnt *ent; + Uint ret = 0; + + // Validity Check + if( !(gaPageDir[VAddr >> 22] & 1) ) return 0; + if( !(gaPageTable[VAddr >> 12] & 1) ) return 0; + + ent = &gaPageTable[VAddr >> 12]; + + // Read-Only + if( !(*ent & PF_WRITE) ) ret |= MM_PFLAG_RO; + // Kernel + if( !(*ent & PF_USER) ) ret |= MM_PFLAG_KERNEL; + // Copy-On-Write + if( *ent & PF_COW ) ret |= MM_PFLAG_COW; + + return ret; +} + /** * \fn tPAddr MM_DuplicatePage(tVAddr VAddr) * \brief Duplicates a virtual page to a physical one diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index e9884161..2451cd0b 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -26,7 +26,7 @@ extern void APStartup(); // 16-bit AP startup code extern Uint GetEIP(); // start.asm extern Uint32 gaInitPageDir[1024]; // start.asm extern void Kernel_Stack_Top; -extern volatile int giThreadListLock; +extern tSpinlock glThreadListLock; extern int giNumCPUs; extern int giNextTID; extern int giTotalTickets; @@ -717,7 +717,7 @@ void Proc_Scheduler(int CPU) tThread *thread; // If the spinlock is set, let it complete - if(giThreadListLock) return; + if(IS_LOCKED(&glThreadListLock)) return; // Clear Delete Queue while(gDeleteThreads) diff --git a/Kernel/arch/x86/time.c b/Kernel/arch/x86/time.c index 4b2e0678..49d515e4 100644 --- a/Kernel/arch/x86/time.c +++ b/Kernel/arch/x86/time.c @@ -17,6 +17,7 @@ extern Sint64 giTimestamp; extern Uint64 giTicks; extern Uint64 giPartMiliseconds; +extern void Timer_CallTimers(void); // === PROTOTYPES === void Time_Interrupt(); diff --git a/Kernel/time.c b/Kernel/time.c new file mode 100644 index 00000000..e8206efa --- /dev/null +++ b/Kernel/time.c @@ -0,0 +1,105 @@ +/* + * Acess 2 + * - By John Hodge (thePowersGang) + * + * Timer Code + */ +#include + +// === CONSTANTS === +#define NUM_TIMERS 8 + +// === TYPEDEFS === +typedef struct sTimer { + int FiresAfter; + void (*Callback)(void*); + void *Argument; +} tTimer; + +// === PROTOTYPES === +void Timer_CallTimers(); + +// === GLOBALS === +Uint64 giTicks = 0; +Sint64 giTimestamp = 0; +Uint64 giPartMiliseconds = 0; +tTimer gTimers[NUM_TIMERS]; + +// === CODE === +/** + * \fn Sint64 now() + * \brief Return the current timestamp + */ +Sint64 now() +{ + return giTimestamp; +} + +/** + * \fn void Timer_CallTimers() + */ +void Timer_CallTimers() +{ + int i; + void (*callback)(void *); + + for(i = 0; + i < NUM_TIMERS; + i ++) + { + if(gTimers[i].Callback == NULL) continue; + if(giTimestamp < gTimers[i].FiresAfter) continue; + callback = gTimers[i].Callback; + gTimers[i].Callback = NULL; + callback(gTimers[i].Argument); + } +} + +/** + * \fn int Time_CreateTimer(int Delta, void *Callback, void *Argument) + */ +int Time_CreateTimer(int Delta, void *Callback, void *Argument) +{ + int ret; + + if(Callback == NULL) return -1; + + for(ret = 0; + ret < NUM_TIMERS; + ret++) + { + if(gTimers[ret].Callback != NULL) continue; + gTimers[ret].Callback = Callback; + gTimers[ret].FiresAfter = giTimestamp + Delta; + gTimers[ret].Argument = Argument; + //Log("Callback = %p", Callback); + //Log("Timer %i fires at %lli", ret, gTimers[ret].FiresAfter); + return ret; + } + return -1; +} + +/** + * \fn void Time_RemoveTimer(int ID) + */ +void Time_RemoveTimer(int ID) +{ + if(ID < 0 || ID >= NUM_TIMERS) return; + gTimers[ID].Callback = NULL; +} + +/** + * \fn void Time_Delay(int Delay) + * \brief Delay for a small ammount of time + */ +void Time_Delay(int Delay) +{ + Sint64 dest = giTimestamp + Delay; + while(dest < giTimestamp) Threads_Yield(); +} + +// === EXPORTS === +EXPORT(now); +EXPORT(Time_CreateTimer); +EXPORT(Time_RemoveTimer); +EXPORT(Time_Delay); -- 2.20.1