Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1020 → Rev 1021

/kernel/trunk/tools/amd64/gencontext.c
37,28 → 37,6
fprintf(f,"#define OFFSET_R15 0x%x\n", ((int) &pctx->r15) - (int) pctx);
fprintf(f,"#define OFFSET_IPL 0x%x\n", ((int) &pctx->ipl) - (int) pctx);
 
fprintf(f, "\n");
 
#define ifpr(big, nm) fprintf(f, "#define IOFFSET_" #big " 0x%x\n", ((int) &ipctx->nm) - (int) ipctx)
ifpr(RAX, rax);
ifpr(RBX, rbx);
ifpr(RCX, rcx);
ifpr(RDX, rdx);
ifpr(RSI, rsi);
ifpr(RDI, rdi);
ifpr(R8, r8);
ifpr(R9, r9);
ifpr(R10, r10);
ifpr(R11, r11);
ifpr(R12, r12);
ifpr(R13, r13);
ifpr(R14, r14);
ifpr(R15, r15);
ifpr(RBP, rbp);
 
fprintf(f, "#define IREGISTER_SPACE %d\n", sizeof(ictx));
 
fclose(f);
 
return 0;
/kernel/trunk/arch/amd64/include/context_offset.h
8,20 → 8,3
#define OFFSET_R14 0x30
#define OFFSET_R15 0x38
#define OFFSET_IPL 0x40
 
#define IOFFSET_RAX 0x0
#define IOFFSET_RBX 0x8
#define IOFFSET_RCX 0x10
#define IOFFSET_RDX 0x18
#define IOFFSET_RSI 0x20
#define IOFFSET_RDI 0x28
#define IOFFSET_R8 0x30
#define IOFFSET_R9 0x38
#define IOFFSET_R10 0x40
#define IOFFSET_R11 0x48
#define IOFFSET_R12 0x50
#define IOFFSET_R13 0x58
#define IOFFSET_R14 0x60
#define IOFFSET_R15 0x68
#define IOFFSET_RBP 0x70
#define IREGISTER_SPACE 120
/kernel/trunk/arch/amd64/include/interrupt.h
76,10 → 76,13
__u64 r13;
__u64 r14;
__u64 r15;
/* These 2 items MUST be last parts of the structure */
__u64 rbp;
__u64 stack[0]; /* Additional data on stack */
} __attribute__ ((packed));
__u64 error_word;
__u64 rip;
__u64 cs;
__u64 rflags;
__u64 stack[]; /* Additional data on stack */
};
 
extern void (* disable_irqs_function)(__u16 irqmask);
extern void (* enable_irqs_function)(__u16 irqmask);
/kernel/trunk/arch/amd64/src/asm_utils.S
26,15 → 26,29
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
#define IREGISTER_SPACE 120
 
#define IOFFSET_RAX 0x0
#define IOFFSET_RBX 0x8
#define IOFFSET_RCX 0x10
#define IOFFSET_RDX 0x18
#define IOFFSET_RSI 0x20
#define IOFFSET_RDI 0x28
#define IOFFSET_R8 0x30
#define IOFFSET_R9 0x38
#define IOFFSET_R10 0x40
#define IOFFSET_R11 0x48
#define IOFFSET_R12 0x50
#define IOFFSET_R13 0x58
#define IOFFSET_R14 0x60
#define IOFFSET_R15 0x68
#define IOFFSET_RBP 0x70
 
# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
# and 1 means interrupt with error word
 
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
 
#include <arch/pm.h>
#include <arch/context_offset.h>
#include <arch/mm/page.h>
.text
141,46 → 155,58
movq IOFFSET_R14(%rsp), %r14
movq IOFFSET_R15(%rsp), %r15
.endm
 
## Declare interrupt handlers
#
# Declare interrupt handlers for n interrupt
# vectors starting at vector i.
#
# The handlers setup data segment registers
# and call exc_dispatch().
# The handlers call exc_dispatch().
#
.macro handler i n
subq $IREGISTER_SPACE, %rsp
save_all_gpr
 
movq $(\i),%rdi # %rdi - first parameter
movq %rsp, %rsi # %rsi - pointer to interrupt_context
call exc_dispatch # exc_dispatch(i, stack)
/*
* Choose between version with error code and version without error code.
* Both versions have to be of the same size. amd64 assembly is, however,
* a little bit tricky. For instance, subq $0x80, %rsp and subq $0x78, %rsp
* can result in two instructions with different op-code lengths.
* Therefore, pay special attention to the extra NOP's that serve as
* a necessary fill.
*/
 
# 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;
.iflt \i-32
.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
/*
* Version with error word.
*/
subq $IREGISTER_SPACE, %rsp
nop
nop
nop
.else
/*
* Version without error word,
*/
subq $(IREGISTER_SPACE+8), %rsp
.endif
.else
/*
* Version without error word,
*/
subq $(IREGISTER_SPACE+8), %rsp
.endif
 
save_all_gpr
 
# Return with error word
movq $(\i), %rdi # %rdi - first parameter
movq %rsp, %rsi # %rsi - pointer to istate
call exc_dispatch # exc_dispatch(i, istate)
restore_all_gpr
# $8 = Skip error word
addq $IREGISTER_SPACE + 0x8, %rsp
addq $(IREGISTER_SPACE+8), %rsp
iretq
 
0:
# Return with no error word
restore_all_gpr
addq $IREGISTER_SPACE, %rsp
iretq
 
.if (\n-\i)-1
handler "(\i+1)",\n
.endif
/kernel/trunk/arch/amd64/src/interrupt.c
47,14 → 47,13
char *symbol;
__u64 *x = &istate->stack[0];
 
if (!(symbol=get_symtab_entry(x[1])))
if (!(symbol=get_symtab_entry(istate->rip)))
symbol = "";
 
printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n",n,__FUNCTION__);
printf("%%rip: %Q (%s)\n",istate->stack[1],symbol);
printf("ERROR_WORD=%Q\n", istate->stack[0]);
printf("%%rcs=%Q,flags=%Q, %%cr0=%Q\n", istate->stack[2],
istate->stack[3],read_cr0());
printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n",n, __FUNCTION__);
printf("%%rip: %Q (%s)\n",istate->rip, symbol);
printf("ERROR_WORD=%Q\n", istate->error_word);
printf("%%rcs=%Q, flags=%Q, %%cr0=%Q\n", istate->cs, istate->rflags,read_cr0());
printf("%%rax=%Q, %%rbx=%Q, %%rcx=%Q\n",istate->rax,istate->rbx,istate->rcx);
printf("%%rdx=%Q, %%rsi=%Q, %%rdi=%Q\n",istate->rdx,istate->rsi,istate->rdi);
printf("%%r8 =%Q, %%r9 =%Q, %%r10=%Q\n",istate->r8,istate->r9,istate->r10);
77,9 → 76,7
 
void null_interrupt(int n, istate_t *istate)
{
printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n",n,__FUNCTION__); \
printf("stack: %X, %X, %X, %X\n", istate->stack[0], istate->stack[1],
istate->stack[2], istate->stack[3]);
print_info_errcode(n, istate);
panic("unserviced interrupt\n");
}
 
/kernel/trunk/arch/ia32/src/asm.S
78,36 → 78,36
# and call exc_dispatch().
#
.macro handler i n
push %eax
 
/*
* Test if this is interrupt with error word or not.
* Be careful about width of the shift.
* This macro distinguishes between two versions of ia32 exceptions.
* One version has error word and the other does not have it.
* 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
movl $(1<<\i), %eax
.else
movl $0, %eax
.endif
andl $ERROR_WORD_INTERRUPT_LIST, %eax
movl (%esp), %eax
.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
/*
* Version with error word.
* Just take space equal to subl $4, %esp.
*/
nop
nop
nop
.else
/*
* Version without error word,
*/
subl $4, %esp
.endif
.else
/*
* Version without error word,
*/
subl $4, %esp
.endif
 
/*
* 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 istate structure. In that case
* we merely leave the EAX on the stack.
*/
jz 0f
 
/*
* This exception stores error word.
* Remove EAX from the stack.
*/
addl $4, %esp
 
0:
pusha
movl %esp, %ebp
push %ds
138,7 → 138,7
popfl
popa
addl $4,%esp # Skip error word, whether real or fake.
addl $4,%esp # Skip error word, no matter whether real or fake.
iret
 
.if (\n-\i)-1