Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 72 → Rev 73

/SPARTAN/trunk/include/fpu_context.h
10,7 → 10,7
extern void fpu_context_restore(fpu_context_t *);
extern void fpu_lazy_context_save(fpu_context_t *);
extern void fpu_lazy_context_restore(fpu_context_t *);
extern void fpu_init(void);
 
 
 
#endif /*fpu_context_h*/
/SPARTAN/trunk/include/proc/thread.h
74,6 → 74,9
context_t saved_context;
context_t sleep_timeout_context;
fpu_context_t saved_fpu_context;
int fpu_context_exists;
int fpu_context_engaged; /* Defined only if thread doesn't run. It means that fpu context is in CPU
that last time executes this thread. This disables migration */
waitq_t *sleep_queue;
/SPARTAN/trunk/doc/TODO
11,6 → 11,7
 
+ save/restore floating point context on context switch
+ [ia32] lazy context switch using TS flag
+ [ia32] MMX,SSE1-.. initialization
+ [ia32] review privilege separation
+ zero IOPL in EFLAGS
+ before IRET (from SYSCALL), zero NT in EFLAGS
18,3 → 19,5
+ [ia32] zero the alignment exception bit in EFLAGS
+ make emulated architectures also work on real hardware
+ bring in support for other architectures (e.g. PowerPC)
 
 
/SPARTAN/trunk/src/proc/scheduler.c
267,6 → 267,11
spinlock_lock(&threads_lock);
list_remove(&THREAD->threads_link);
spinlock_unlock(&threads_lock);
 
spinlock_lock(&THREAD->cpu->lock);
if(THREAD->cpu->arch.fpu_owner==THREAD) THREAD->cpu->arch.fpu_owner=NULL;
spinlock_unlock(&THREAD->cpu->lock);
 
free(THREAD);
427,9 → 432,10
/*
* We don't want to steal CPU-wired threads neither threads already stolen.
* The latter prevents threads from migrating between CPU's without ever being run.
*/
* We don't want to steal threads whose FPU context is still in CPU
*/
spinlock_lock(&t->lock);
if (!(t->flags & (X_WIRED | X_STOLEN))) {
if ( (!(t->flags & (X_WIRED | X_STOLEN))) && (!(t->fpu_context_engaged)) ) {
/*
* Remove t from r.
*/
/SPARTAN/trunk/src/proc/thread.c
189,6 → 189,9
t->task = task;
t->fpu_context_exists=0;
t->fpu_context_engaged=0;
/*
* Register this thread in the system-wide list.
*/
/SPARTAN/trunk/arch/ia32/include/interrupt.h
76,6 → 76,7
 
extern void null_interrupt(__u8 n, __u32 stack[]);
extern void gp_fault(__u8 n, __u32 stack[]);
extern void nm_fault(__u8 n, __u32 stack[]);
extern void page_fault(__u8 n, __u32 stack[]);
extern void syscall(__u8 n, __u32 stack[]);
extern void tlb_shootdown_ipi(__u8 n, __u32 stack[]);
/SPARTAN/trunk/arch/ia32/src/fpu_context.c
40,29 → 40,39
 
void fpu_context_restore(fpu_context_t *fctx)
{
if(THREAD==CPU->arch.fpu_owner) reset_TS_flag();
else set_TS_flag();
if(THREAD==CPU->arch.fpu_owner) {reset_TS_flag(); }
else {set_TS_flag(); ((CPU->arch).fpu_owner)->fpu_context_engaged=1;}
}
 
 
void fpu_lazy_context_save(fpu_context_t *fctx)
{
/*
pushl %eax
mov 8(%esp),%eax
fxsave (%eax)
popl %eax
ret
*/
asm(
"mov %0,%%eax;"
"fxsave (%%eax);"
"ret;"
:"=m"(fctx)
:
:"%eax"
);
}
 
void fpu_lazy_context_restore(fpu_context_t *fctx)
{
/*
pushl %eax
mov 8(%esp),%eax
fxrstor (%eax)
popl %eax
ret
*/
asm(
"mov %0,%%eax;"
"fxrstor (%%eax);"
"ret;"
:"=m"(fctx)
:
:"%eax"
);
}
 
void fpu_init(void)
{
asm(
"fninit;"
);
}
 
/SPARTAN/trunk/arch/ia32/src/pm.c
120,6 → 120,7
trap_register(i, null_interrupt);
}
trap_register(13, gp_fault);
trap_register( 7, nm_fault);
}
 
 
/SPARTAN/trunk/arch/ia32/src/interrupt.c
85,6 → 85,27
panic("general protection fault\n");
}
 
void nm_fault(__u8 n, __u32 stack[])
{
 
if (((CPU->arch).fpu_owner)!=NULL)
{
fpu_lazy_context_save(&(((CPU->arch).fpu_owner)->saved_fpu_context));
((CPU->arch).fpu_owner)->fpu_context_engaged=0; /* Enables migration */
}
if(THREAD->fpu_context_exists) fpu_lazy_context_restore(&(THREAD->saved_fpu_context));
else {fpu_init();THREAD->fpu_context_exists=1;}
 
(CPU->arch).fpu_owner=THREAD;
 
reset_TS_flag();
// panic("#NM fault\n");
}
 
 
 
void page_fault(__u8 n, __u32 stack[])
{
printf("page fault address: %X\n", cpu_read_cr2());