matos/arch/x86/irq_wrappers.S
Mathieu Maret 75dbbdb53b Wrap IRQ, Exception, cpu_context to be ready for user
Fix ASM where ebp was push 2 times.
One by pushw ebp
One by pushal later
2021-10-27 00:14:22 +02:00

113 lines
2.3 KiB
ArmAsm

#define ASM_SOURCE 1
#include "segment.h"
.file "irq_wrappers.S"
.text
.extern interrupt_handler_pic
.globl irq_handler_wrapper_array
/** Update the kernel TSS in case we are switching to a thread in user
mode in order to come back into the correct kernel stack */
.extern cpu_context_update_kernel_tss
/* The address of the function to call to set back the user thread's
MMU configuration upon return to user context */
.extern thread_prepare_irq_switch_back
.altmacro
.macro interrupt_pic irq
int_wrapper_\irq:
.type int_wrapper_\irq,@function
/* INTERRUPT FRAME START */
/* ALREADY PUSHED TO US BY THE PROCESSOR UPON ENTRY TO THIS INTERRUPT */
/* uint32_t ip */
/* uint32_t cs; */
/* uint32_t flags */
/* Pushes the other reg to save same and look like a struct cpu_state*/
/* Fake error code */
pushl $0
/* Backup the actual context */
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ecx
pushl %edx
pushl %ebx
pushl %esi
pushl %edi
subl $2,%esp
pushw %ss
pushw %ds
pushw %es
pushw %fs
pushw %gs
/* Set correct kernel segment descriptors' value */
movw $BUILD_SEGMENT_REG_VALUE(0, 0, SEG_KDATA), %di
pushw %di ; popw %ds
pushw %di ; popw %es
pushw %di ; popw %fs
pushw %di ; popw %gs
push %esp
pushl $\irq
call interrupt_handler_pic
addl $8, %esp
/* Reconfigure the MMU if needed */
pushl %esp /* cpu_ctxt */
call thread_prepare_irq_switch_back
addl $4, %esp /* Unallocate the stack */
/* Prepare kernel TSS in case we are switching to a
user thread: we make sure that we will come back
into the kernel at a correct stack location */
pushl %esp /* Pass the location of the context we are
restoring to the function */
call cpu_context_update_kernel_tss
addl $4, %esp
/* Restore the context */
popw %gs
popw %fs
popw %es
popw %ds
popw %ss
addl $2,%esp
popl %edi
popl %esi
popl %ebx
popl %edx
popl %ecx
popl %eax
popl %ebp
/* Remove fake error code */
addl $4, %esp
iret
.endm
.set i, 0
.rept 0x10
interrupt_pic %i
.set i, i+1
.endr
.macro ref_int_wrapper irq
.long int_wrapper_\irq
.endm
.section ".rodata"
.p2align 5, 0x0
irq_handler_wrapper_array:
.set i, 0x0
.rept 0x10
ref_int_wrapper %i
.set i, i+1
.endr