/kernel/trunk/arch/ia32/include/interrupt.h |
---|
60,17 → 60,33 |
#define VECTOR_SYSCALL (IVT_FREEBASE+0) |
#define VECTOR_TLB_SHOOTDOWN_IPI (IVT_FREEBASE+1) |
struct istate { |
__u32 edi; |
__u32 esi; |
__u32 ebp; |
__u32 esp; |
__u32 ebx; |
__u32 edx; |
__u32 ecx; |
__u32 eax; |
__u32 error_word; |
__u32 eip; |
__u32 cs; |
__u32 eflags; |
__u32 stack[]; |
}; |
extern void (* disable_irqs_function)(__u16 irqmask); |
extern void (* enable_irqs_function)(__u16 irqmask); |
extern void (* eoi_function)(void); |
extern void null_interrupt(int n, void *stack); |
extern void gp_fault(int n, void *stack); |
extern void nm_fault(int n, void *stack); |
extern void ss_fault(int n, void *stack); |
extern void page_fault(int n, void *stack); |
extern void syscall(int n, void *stack); |
extern void tlb_shootdown_ipi(int n, void *stack); |
extern void null_interrupt(int n, istate_t *istate); |
extern void gp_fault(int n, istate_t *istate); |
extern void nm_fault(int n, istate_t *istate); |
extern void ss_fault(int n, istate_t *istate); |
extern void page_fault(int n, istate_t *istate); |
extern void syscall(int n, istate_t *istate); |
extern void tlb_shootdown_ipi(int n, istate_t *istate); |
extern void trap_virtual_enable_irqs(__u16 irqmask); |
extern void trap_virtual_disable_irqs(__u16 irqmask); |
/kernel/trunk/arch/ia32/include/types.h |
---|
47,7 → 47,7 |
typedef __u32 ipl_t; |
typedef __u32 __native; |
typedef __s32 __native; |
typedef __s32 __snative; |
typedef struct page_specifier pte_t; |
/kernel/trunk/arch/ia32/src/ia32.c |
---|
60,11 → 60,11 |
i8259_init(); /* PIC */ |
i8254_init(); /* hard clock */ |
exc_register(VECTOR_SYSCALL, "syscall", syscall); |
exc_register(VECTOR_SYSCALL, "syscall", (iroutine) syscall); |
#ifdef CONFIG_SMP |
exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", |
tlb_shootdown_ipi); |
(iroutine) tlb_shootdown_ipi); |
#endif /* CONFIG_SMP */ |
} |
} |
/kernel/trunk/arch/ia32/src/asm.S |
---|
78,10 → 78,37 |
# and call exc_dispatch(). |
# |
.macro handler i n |
push %ebp |
movl %esp,%ebp |
push %eax |
# Test if this is interrupt with error word or not |
movl $(1<<\i), %eax |
andl $ERROR_WORD_INTERRUPT_LIST,%eax |
/* |
* If this interrupt/exception stores error word, |
* we need to pop EAX. |
* If this interrupt doesn't store error word, we emulate it |
* for the sake of consistent pstate structure. In that case |
* we merely leave the EAX on the stack. |
*/ |
jz 0f |
/* |
* This exception stores error word. |
*/ |
pop %eax |
jmp 1f |
0: |
/* |
* This interrupt doesn't store error word. |
* Just restore EAX without doing POP. |
*/ |
movl (%esp), %eax |
1: |
pusha |
movl %esp, %ebp |
push %ds |
push %es |
92,7 → 119,6 |
movl $(\i),%edi |
pushl %ebp |
addl $4,(%esp) |
pushl %edi |
call exc_dispatch |
addl $8,%esp |
100,8 → 126,7 |
pop %es |
pop %ds |
# CLNT |
# Clear Nested Task flag. |
pushfl |
pop %eax |
and $0xFFFFBFFF,%eax |
108,31 → 133,10 |
push %eax |
popfl |
# Test if this is interrupt with error word or not |
mov $\i,%cl |
movl $1,%eax |
test $0xe0,%cl |
jnz 0f |
and $0x1f,%cl |
shl %cl,%eax |
and $ERROR_WORD_INTERRUPT_LIST,%eax |
jz 0f |
# Return with error word |
popa |
pop %ebp |
add $4,%esp # Skip error word |
add $4,%esp # Skip error word, whether real or fake. |
iret |
0: |
# Return with no error word |
popa |
pop %ebp |
iret |
.if (\n-\i)-1 |
handler "(\i+1)",\n |
.endif |
/kernel/trunk/arch/ia32/src/pm.c |
---|
125,11 → 125,11 |
} |
idt_setoffset(d, ((__address) interrupt_handlers) + i*interrupt_handler_size); |
exc_register(i, "undef", null_interrupt); |
exc_register(i, "undef", (iroutine) null_interrupt); |
} |
exc_register(13, "gp_fault", gp_fault); |
exc_register( 7, "nm_fault", nm_fault); |
exc_register(12, "ss_fault", ss_fault); |
exc_register(13, "gp_fault", (iroutine) gp_fault); |
exc_register( 7, "nm_fault", (iroutine) nm_fault); |
exc_register(12, "ss_fault", (iroutine) ss_fault); |
} |
/kernel/trunk/arch/ia32/src/smp/apic.c |
---|
112,8 → 112,8 |
#endif /* LAPIC_VERBOSE */ |
static void apic_spurious(int n, void *stack); |
static void l_apic_timer_interrupt(int n, void *stack); |
static void apic_spurious(int n, istate_t *istate); |
static void l_apic_timer_interrupt(int n, istate_t *istate); |
/** Initialize APIC on BSP. */ |
void apic_init(void) |
121,7 → 121,7 |
io_apic_id_t idreg; |
int i; |
exc_register(VECTOR_APIC_SPUR, "apic_spurious", apic_spurious); |
exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious); |
enable_irqs_function = io_apic_enable_irqs; |
disable_irqs_function = io_apic_disable_irqs; |
133,7 → 133,7 |
* Other interrupts will be forwarded to the lowest priority CPU. |
*/ |
io_apic_disable_irqs(0xffff); |
exc_register(VECTOR_CLK, "l_apic_timer", l_apic_timer_interrupt); |
exc_register(VECTOR_CLK, "l_apic_timer", (iroutine) l_apic_timer_interrupt); |
for (i = 0; i < IRQ_COUNT; i++) { |
int pin; |
169,7 → 169,7 |
* @param n Interrupt vector. |
* @param stack Interrupted stack. |
*/ |
void apic_spurious(int n, void *stack) |
void apic_spurious(int n, istate_t *istate) |
{ |
printf("cpu%d: APIC spurious interrupt\n", CPU->id); |
} |
427,7 → 427,7 |
* @param n Interrupt vector number. |
* @param stack Interrupted stack. |
*/ |
void l_apic_timer_interrupt(int n, void *stack) |
void l_apic_timer_interrupt(int n, istate_t *istate) |
{ |
l_apic_eoi(); |
clock(); |
/kernel/trunk/arch/ia32/src/mm/page.c |
---|
60,7 → 60,7 |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
exc_register(14, "page_fault", page_fault); |
exc_register(14, "page_fault", (iroutine) page_fault); |
write_cr3((__address) AS_KERNEL->page_table); |
} |
else { |
/kernel/trunk/arch/ia32/src/interrupt.c |
---|
49,46 → 49,41 |
void (* enable_irqs_function)(__u16 irqmask) = NULL; |
void (* eoi_function)(void) = NULL; |
#define PRINT_INFO_ERRCODE(st) { \ |
__native *x = (__native *) st; \ |
char *symbol = get_symtab_entry(x[1]); \ |
#define PRINT_INFO_ERRCODE(istate) do { \ |
char *symbol = get_symtab_entry(istate->eip); \ |
if (!symbol) \ |
symbol = ""; \ |
printf("----------------EXCEPTION OCCURED----------------\n"); \ |
printf("%%eip: %X (%s)\n",x[1],symbol); \ |
printf("ERROR_WORD=%X\n", x[0]); \ |
printf("%%cs=%X,flags=%X\n", x[2], x[3]); \ |
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",\ |
x[-2],x[-5],x[-3],x[-4]); \ |
istate->eax,istate->ebx,istate->ecx,istate->edx); \ |
printf("%%esi=%X, %%edi=%X, %%ebp=%X, %%esp=%X\n",\ |
x[-8],x[-9],x[-1],x); \ |
printf("stack: %X, %X, %X, %X\n", x[4], x[5], x[6], x[7]); \ |
printf(" %X, %X, %X, %X\n", x[8], x[9], x[10], x[11]); \ |
} |
istate->esi,istate->edi,istate->ebp,istate->esp); \ |
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]); \ |
} while(0) |
void null_interrupt(int n, void *st) |
void null_interrupt(int n, istate_t *istate) |
{ |
__native *stack = (__native *) st; |
printf("int %d: null_interrupt\n", n); |
printf("stack: %L, %L, %L, %L\n", stack[0], stack[1], stack[2], stack[3]); |
panic("unserviced interrupt\n"); |
PRINT_INFO_ERRCODE(istate); |
panic("unserviced interrupt: %d\n", n); |
} |
void gp_fault(int n, void *stack) |
void gp_fault(int n, istate_t *istate) |
{ |
PRINT_INFO_ERRCODE(stack); |
PRINT_INFO_ERRCODE(istate); |
panic("general protection fault\n"); |
} |
void ss_fault(int n, void *stack) |
void ss_fault(int n, istate_t *istate) |
{ |
PRINT_INFO_ERRCODE(stack); |
PRINT_INFO_ERRCODE(istate); |
panic("stack fault\n"); |
} |
void nm_fault(int n, void *stack) |
void nm_fault(int n, istate_t *istate) |
{ |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
97,33 → 92,29 |
#endif |
} |
void page_fault(int n, void *stack) |
void page_fault(int n, istate_t *istate) |
{ |
__address page; |
page = read_cr2(); |
if (!as_page_fault(page)) { |
PRINT_INFO_ERRCODE(stack); |
PRINT_INFO_ERRCODE(istate); |
printf("page fault address: %X\n", page); |
panic("page fault\n"); |
} |
} |
void syscall(int n, void *st) |
void syscall(int n, istate_t *istate) |
{ |
__native *stack = (__native *) st; |
interrupts_enable(); |
if (stack[-2] < SYSCALL_END) |
stack[-2] = syscall_table[stack[-2]](stack[-5], stack[-3], stack[-4]); |
if (istate->edx < SYSCALL_END) |
istate->eax = syscall_table[istate->edx](istate->eax, istate->ebx, istate->ecx); |
else |
panic("Undefined syscall %d", stack[-2]); |
panic("Undefined syscall %d", istate->edx); |
interrupts_disable(); |
} |
void tlb_shootdown_ipi(int n, void *stack) |
void tlb_shootdown_ipi(int n, istate_t *istate) |
{ |
trap_virtual_eoi(); |
tlb_shootdown_ipi_recv(); |
/kernel/trunk/arch/ia32/src/drivers/i8259.c |
---|
39,7 → 39,7 |
* Programmable Interrupt Controller for UP systems. |
*/ |
static void pic_spurious(int n, void *stack); |
static void pic_spurious(int n, istate_t *istate); |
void i8259_init(void) |
{ |
70,7 → 70,7 |
/* |
* Register interrupt handler for the PIC spurious interrupt. |
*/ |
exc_register(VECTOR_PIC_SPUR, "pic_spurious", pic_spurious); |
exc_register(VECTOR_PIC_SPUR, "pic_spurious", (iroutine) pic_spurious); |
/* |
* Set the enable/disable IRQs handlers. |
118,7 → 118,7 |
outb(0xa0,0x20); |
} |
void pic_spurious(int n, void *stack) |
void pic_spurious(int n, istate_t *istate) |
{ |
printf("cpu%d: PIC spurious interrupt\n", CPU->id); |
} |
/kernel/trunk/arch/ia32/src/drivers/i8254.c |
---|
53,7 → 53,7 |
#define CLK_CONST 1193180 |
#define MAGIC_NUMBER 1194 |
static void i8254_interrupt(int n, void *stack); |
static void i8254_interrupt(int n, istate_t *istate); |
void i8254_init(void) |
{ |
67,7 → 67,7 |
outb(CLK_PORT1, (CLK_CONST/HZ) & 0xf); |
outb(CLK_PORT1, (CLK_CONST/HZ) >> 8); |
pic_enable_irqs(1<<IRQ_CLK); |
exc_register(VECTOR_CLK, "i8254_clock", i8254_interrupt); |
exc_register(VECTOR_CLK, "i8254_clock", (iroutine) i8254_interrupt); |
} |
#define LOOPS 150000 |
125,7 → 125,7 |
return; |
} |
void i8254_interrupt(int n, void *stack) |
void i8254_interrupt(int n, istate_t *istate) |
{ |
trap_virtual_eoi(); |
clock(); |