Files
exectos/xtoskrnl/ar/amd64/archsup.S
Aiken Harris 87a91bfeb1
Some checks failed
Builds / ExectOS (amd64, release) (push) Successful in 34s
Builds / ExectOS (amd64, debug) (push) Successful in 41s
Builds / ExectOS (i686, debug) (push) Successful in 39s
Builds / ExectOS (i686, release) (push) Failing after 30s
Make XTDK headers assembly-safe
2026-04-01 16:05:34 +02:00

240 lines
5.7 KiB
ArmAsm

/**
* 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 <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include <xtkmapi.h>
#include <ar/amd64/asmsup.h>
.altmacro
.text
/**
* Creates a trap or interrupt handler for the specified vector.
*
* @param Vector
* Supplies a trap/interrupt vector number.
*
* @param Type
* Specifies whether the handler is designed to handle an interrupt or a trap.
*
* @return This macro does not return any value.
*
* @since XT 1.0
*/
.macro ArCreateHandler Vector Type
.global Ar\Type\Vector
Ar\Type\Vector:
/* Check handler type */
.ifc \Type,Trap
/* Push fake error code for non-error vector traps */
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
push $0
.endif
.else
/* Push fake error code for interrupts */
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 TrapSegCs(%rbp), %ax
and $3, %al
mov %al, TrapPreviousMode(%rbp)
/* Skip swapgs as the interrupt originated from kernel mode */
jz UserMode\Type\Vector
swapgs
UserMode\Type\Vector:
/* Set up trap frame pointer for the dispatcher and clear the direction flag */
mov %rsp, %rcx
cld
/* Preserve the original stack pointer */
mov %rsp, %rbx
/* Force stack alignment */
and $-16, %rsp
/* Allocate 32 bytes of shadow space */
sub $32, %rsp
.ifc \Type,Trap
/* Pass to the trap dispatcher */
call ArDispatchTrap
.else
/* Pass to the interrupt dispatcher */
call ArDispatchTrap
.endif
/* Restore the original trap frame stack pointer */
mov %rbx, %rsp
/* Test previous mode and swapgs if needed */
testb $1, TrapPreviousMode(%rbp)
jz KernelModeReturn\Type\Vector
cli
swapgs
KernelModeReturn\Type\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)
/* 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 interrupt and 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
ArCreateHandler 0x\i\j Interrupt
ArCreateHandler 0x\i\j Trap
.endr
.endr
/* Define array of pointers to the interrupt handlers */
.global ArInterruptEntry
ArInterruptEntry:
.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
.quad ArInterrupt0x\i\j
.endr
.endr
/* Define array of pointers to the trap handlers */
.global ArTrapEntry
ArTrapEntry:
.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
.quad ArTrap0x\i\j
.endr
.endr
/**
* Handles a spurious interrupt allowing it to end up.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
.global ArHandleSpuriousInterrupt
ArHandleSpuriousInterrupt:
iretq