Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1020 → Rev 1021

/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