/** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory * FILE: xtoskrnl/ar/amd64/archsup.S * DESCRIPTION: Provides AMD64 architecture features not implementable in C * DEVELOPERS: Rafal Kupiec */ #include .altmacro .text /** * This macro creates a trap handler for the specified vector. * * @param Vector * Supplies a trap vector number. * * @return This macro does not return any value. * * @since XT 1.0 */ .macro ArpCreateTrapHandler Vector .global ArpTrap\Vector ArpTrap\Vector: /* Push fake error code for non-error vectors */ .if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30 push $0 .endif /* Push vector number */ push $\Vector /* Push General Purpose Registers */ push %rbp push %rdi push %rsi push %r15 push %r14 push %r13 push %r12 push %r11 push %r10 push %r9 push %r8 push %rdx push %rcx push %rbx push %rax /* Reserve space for other registers and point RBP to the trap frame */ sub $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %rsp lea (%rsp), %rbp /* Store segment selectors */ mov %gs, TrapSegGs(%rbp) mov %fs, TrapSegFs(%rbp) mov %es, TrapSegEs(%rbp) mov %ds, TrapSegDs(%rbp) /* Store debug registers */ mov %dr7, %rax mov %rax, TrapDr7(%rbp) mov %dr6, %rax mov %rax, TrapDr6(%rbp) mov %dr3, %rax mov %rax, TrapDr3(%rbp) mov %dr2, %rax mov %rax, TrapDr2(%rbp) mov %dr1, %rax mov %rax, TrapDr1(%rbp) mov %dr0, %rax mov %rax, TrapDr0(%rbp) /* Store CR2 and CR3 */ mov %cr3, %rax mov %rax, TrapCr3(%rbp) mov %cr2, %rax mov %rax, TrapCr2(%rbp) /* Store MxCsr register */ stmxcsr TrapMxCsr(%rbp) /* Store XMM registers */ movdqa %xmm15, TrapXmm15(%rbp) movdqa %xmm14, TrapXmm14(%rbp) movdqa %xmm13, TrapXmm13(%rbp) movdqa %xmm12, TrapXmm12(%rbp) movdqa %xmm11, TrapXmm11(%rbp) movdqa %xmm10, TrapXmm10(%rbp) movdqa %xmm9, TrapXmm9(%rbp) movdqa %xmm8, TrapXmm8(%rbp) movdqa %xmm7, TrapXmm7(%rbp) movdqa %xmm6, TrapXmm6(%rbp) movdqa %xmm5, TrapXmm5(%rbp) movdqa %xmm4, TrapXmm4(%rbp) movdqa %xmm3, TrapXmm3(%rbp) movdqa %xmm2, TrapXmm2(%rbp) movdqa %xmm1, TrapXmm1(%rbp) movdqa %xmm0, TrapXmm0(%rbp) /* Test previous mode and swap GS if needed */ movl $0, TrapPreviousMode(%rbp) mov %cs, %ax and $1, %al mov %al, TrapPreviousMode(%rbp) jz KernelMode$\Vector swapgs KernelMode$\Vector: /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ mov %rsp, %rcx cld call ArpDispatchTrap /* Test previous mode and swapgs if needed */ testb $1, TrapPreviousMode(%rbp) jz KernelModeReturn$\Vector cli swapgs KernelModeReturn$\Vector: /* Restore XMM registers */ movdqa TrapXmm0(%rbp), %xmm0 movdqa TrapXmm1(%rbp), %xmm1 movdqa TrapXmm2(%rbp), %xmm2 movdqa TrapXmm3(%rbp), %xmm3 movdqa TrapXmm4(%rbp), %xmm4 movdqa TrapXmm5(%rbp), %xmm5 movdqa TrapXmm6(%rbp), %xmm6 movdqa TrapXmm7(%rbp), %xmm7 movdqa TrapXmm8(%rbp), %xmm8 movdqa TrapXmm9(%rbp), %xmm9 movdqa TrapXmm10(%rbp), %xmm10 movdqa TrapXmm11(%rbp), %xmm11 movdqa TrapXmm12(%rbp), %xmm12 movdqa TrapXmm13(%rbp), %xmm13 movdqa TrapXmm14(%rbp), %xmm14 movdqa TrapXmm15(%rbp), %xmm15 /* Load MxCsr register */ ldmxcsr TrapMxCsr(%rbp) /* Restore segment selectors */ mov TrapSegDs(%rbp), %ds mov TrapSegEs(%rbp), %es mov TrapSegFs(%rbp), %fs /* Free stack space */ add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %rsp /* Pop General Purpose Registers */ pop %rax pop %rbx pop %rcx pop %rdx pop %r8 pop %r9 pop %r10 pop %r11 pop %r12 pop %r13 pop %r14 pop %r15 pop %rsi pop %rdi pop %rbp /* Skip error code and vector number, then return */ add $(2 * 8), %rsp iretq .endm /* Populate common trap handlers */ .irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F ArpCreateTrapHandler 0x\i\j .endr .endr