Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1099 → Rev 1100

/kernel/trunk/arch/ia32/include/interrupt.h
63,14 → 63,19
#define VECTOR_DEBUG_IPI (IVT_FREEBASE+2)
 
struct istate {
__u32 eax;
__u32 ecx;
__u32 edx;
__u32 esi;
__u32 edi;
__u32 esi;
__u32 ebp;
__u32 esp;
__u32 ebx;
__u32 edx;
__u32 ecx;
__u32 eax;
 
__u32 gs;
__u32 fs;
__u32 es;
__u32 ds;
 
__u32 error_word;
__u32 eip;
__u32 cs;
/kernel/trunk/arch/ia32/include/atomic.h
30,6 → 30,8
#define __ia32_ATOMIC_H__
 
#include <arch/types.h>
#include <arch/barrier.h>
#include <preemption.h>
 
typedef struct { volatile __u32 count; } atomic_t;
 
100,7 → 102,31
return v;
}
 
/** Ia32 specific fast spinlock */
static inline void atomic_lock_arch(atomic_t *val)
{
__u32 tmp;
 
extern void spinlock_arch(volatile int *val);
preemption_disable();
__asm__ volatile (
"0:;"
#ifdef CONFIG_HT
"pause;" /* Pentium 4's HT love this instruction */
#endif
"mov %0, %1;"
"testl %1, %1;"
"jnz 0b;" /* Leightweight looping on locked spinlock */
"incl %1;" /* now use the atomic operation */
"xchgl %0, %1;"
"testl %1, %1;"
"jnz 0b;"
: "=m"(val->count),"=r"(tmp)
);
/*
* Prevent critical section code from bleeding out this way up.
*/
CS_ENTER_BARRIER();
}
 
#endif
/kernel/trunk/arch/ia32/src/asm.S
68,6 → 68,15
pop %eax
ret
 
# Clear nested flag
# overwrites %ecx
.macro CLEAR_NT_FLAG
pushfl
pop %ecx
and $0xffffbfff,%ecx
push %ecx
popfl
.endm
 
## Declare interrupt handlers
#
77,8 → 86,40
# The handlers setup data segment registers
# and call exc_dispatch().
#
#define INTERRUPT_ALIGN 64
.macro handler i n
 
.ifeq \i-0x30 # Syscall handler
push %ds
push %es
push %fs
push %gs
 
# Push arguments on stack
push %edi
push %esi
push %edx
push %ecx
push %eax
# we must fill the data segment registers
movw $16,%ax
movw %ax,%ds
movw %ax,%es
sti
call syscall_handler # syscall_handler(ax,cx,dx,si,di)
cli
addl $20, %esp # clean-up of parameters
pop %gs
pop %fs
pop %es
pop %ds
CLEAR_NT_FLAG
iret
.else
/*
* This macro distinguishes between two versions of ia32 exceptions.
* One version has error word and the other does not have it.
85,16 → 126,11
* The latter version fakes the error word on the stack so that the
* handlers and istate_t can be the same for both types.
*/
 
.iflt \i-32
.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
/*
* Version with error word.
* Just take space equal to subl $4, %esp.
/*
* With error word, do nothing
*/
nop
nop
nop
.else
/*
* Version without error word,
106,41 → 142,59
* Version without error word,
*/
subl $4, %esp
.endif
 
pusha
movl %esp, %ebp
.endif
push %ds
push %es
push %fs
push %gs
 
#ifdef CONFIG_DEBUG_ALLREGS
push %ebx
push %ebp
push %edi
push %esi
#else
sub $16, %esp
#endif
push %edx
push %ecx
push %eax
# we must fill the data segment registers
movw $16,%ax
movw %ax,%ds
movw %ax,%es
 
pushl %ebp
pushl $(\i)
call exc_dispatch
addl $8,%esp
pushl %esp # *istate
pushl $(\i) # intnum
call exc_dispatch # excdispatch(intnum, *istate)
addl $8,%esp # Clear arguments from stack
 
CLEAR_NT_FLAG # Modifies %ecx
pop %eax
pop %ecx
pop %edx
#ifdef CONFIG_DEBUG_ALLREGS
pop %esi
pop %edi
pop %ebp
pop %ebx
#else
add $16, %esp
#endif
pop %gs
pop %fs
pop %es
pop %ds
 
# Clear Nested Task flag.
pushfl
pop %eax
and $0xffffbfff,%eax
push %eax
popfl
popa
addl $4,%esp # Skip error word, no matter whether real or fake.
iret
.endif
 
.align INTERRUPT_ALIGN
.if (\n-\i)-1
handler "(\i+1)",\n
.endif
148,12 → 202,10
 
# keep in sync with pm.h !!!
IDT_ITEMS=64
.align INTERRUPT_ALIGN
interrupt_handlers:
h_start:
handler 0 64
# handler 64 128
# handler 128 192
# handler 192 256
handler 0 IDT_ITEMS
h_end:
 
.data
/kernel/trunk/arch/ia32/src/interrupt.c
64,8 → 64,10
printf("%%eip: %X (%s)\n",istate->eip,symbol);
printf("ERROR_WORD=%X\n", istate->error_word);
printf("%%cs=%X,flags=%X\n", istate->cs, istate->eflags);
printf("%%eax=%X, %%ebx=%X, %%ecx=%X, %%edx=%X\n", istate->eax,istate->ebx,istate->ecx,istate->edx);
printf("%%esi=%X, %%edi=%X, %%ebp=%X, %%esp=%X\n", istate->esi,istate->edi,istate->ebp,istate->esp);
printf("%%eax=%X, %%ecx=%X, %%edx=%X, %%esp=%X\n", istate->eax,istate->ecx,istate->edx,&istate->stack[0]);
#ifdef CONFIG_DEBUG_ALLREGS
printf("%%esi=%X, %%edi=%X, %%ebp=%X, %%ebx=%X\n", istate->esi,istate->edi,istate->ebp,istate->ebx);
#endif
printf("stack: %X, %X, %X, %X\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]);
printf(" %X, %X, %X, %X\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]);
}
125,12 → 127,7
 
void syscall(int n, istate_t *istate)
{
interrupts_enable();
if (istate->esi < SYSCALL_END)
istate->eax = syscall_table[istate->esi](istate->eax, istate->ebx, istate->ecx, istate->edx);
else
panic("Undefined syscall %d", istate->esi);
interrupts_disable();
panic("Obsolete syscall handler.");
}
 
void tlb_shootdown_ipi(int n, istate_t *istate)