Ported x64 interrupt assembly to the GNU assembler.

This commit is contained in:
Jonas 'Sortie' Termansen 2012-04-13 17:34:17 +02:00
parent 8cbf9ff8f0
commit f59b53ddce
3 changed files with 444 additions and 172 deletions

View File

@ -1,6 +1,6 @@
/******************************************************************************
/*******************************************************************************
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
This file is part of Sortix.
@ -14,13 +14,13 @@
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along
with Sortix. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License along with
Sortix. If not, see <http://www.gnu.org/licenses/>.
x63/interrupt.s
x64/interrupt.s
Transfers control to interrupt handlers when interrupts happen.
******************************************************************************/
*******************************************************************************/
.section .text

View File

@ -1,166 +0,0 @@
;
; interrupt.s -- Contains interrupt service routine wrappers.
; Based on Bran's kernel development tutorials.
; Rewritten for JamesM's kernel development tutorials.
; This macro creates a stub for an ISR which does NOT pass it's own
; error code (adds a dummy errcode byte).
%macro ISR_NOERRCODE 1
global isr%1
isr%1:
cli ; Disable interrupts firstly.
push long 0 ; Push a dummy error code.
push long %1 ; Push the interrupt number.
jmp isr_common_stub ; Go to our common handler code.
%endmacro
; This macro creates a stub for an ISR which passes it's own
; error code.
%macro ISR_ERRCODE 1
global isr%1
isr%1:
cli ; Disable interrupts.
push long %1 ; Push the interrupt number
jmp isr_common_stub
%endmacro
; This macro creates a stub for an IRQ - the first parameter is
; the IRQ number, the second is the ISR number it is remapped to.
%macro IRQ 2
global irq%1
irq%1:
cli
push long 0
push long %2
jmp irq_common_stub
%endmacro
ISR_NOERRCODE 0
ISR_NOERRCODE 1
ISR_NOERRCODE 2
ISR_NOERRCODE 3
ISR_NOERRCODE 4
ISR_NOERRCODE 5
ISR_NOERRCODE 6
ISR_NOERRCODE 7
ISR_ERRCODE 8
ISR_NOERRCODE 9
ISR_ERRCODE 10
ISR_ERRCODE 11
ISR_ERRCODE 12
ISR_ERRCODE 13
ISR_ERRCODE 14
ISR_NOERRCODE 15
ISR_NOERRCODE 16
ISR_NOERRCODE 17
ISR_NOERRCODE 18
ISR_NOERRCODE 19
ISR_NOERRCODE 20
ISR_NOERRCODE 21
ISR_NOERRCODE 22
ISR_NOERRCODE 23
ISR_NOERRCODE 24
ISR_NOERRCODE 25
ISR_NOERRCODE 26
ISR_NOERRCODE 27
ISR_NOERRCODE 28
ISR_NOERRCODE 29
ISR_NOERRCODE 30
ISR_NOERRCODE 31
ISR_NOERRCODE 128
IRQ 0, 32
IRQ 1, 33
IRQ 2, 34
IRQ 3, 35
IRQ 4, 36
IRQ 5, 37
IRQ 6, 38
IRQ 7, 39
IRQ 8, 40
IRQ 9, 41
IRQ 10, 42
IRQ 11, 43
IRQ 12, 44
IRQ 13, 45
IRQ 14, 46
IRQ 15, 47
extern interrupt_handler
; This is our common ISR stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
; and finally restores the stack frame.
isr_common_stub:
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov eax, ds ; Lower 16-bits of eax = ds.
push eax ; save the data segment descriptor
mov eax, cr2
push eax
mov ax, 0x10 ; load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
push esp
call interrupt_handler
add esp, 8
pop ebx ; reload the original data segment descriptor
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
popa ; Pops edi,esi,ebp...
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
;sti
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
; This is our common IRQ stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
; and finally restores the stack frame.
irq_common_stub:
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov eax, ds ; Lower 16-bits of eax = ds.
push eax ; save the data segment descriptor
mov eax, cr2
push eax
mov ax, 0x10 ; load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
push esp
call interrupt_handler
add esp, 8
pop ebx ; reload the original data segment descriptor
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
popa ; Pops edi,esi,ebp...
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
;sti
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
global interrupt_handler_null
interrupt_handler_null:
iret
global asm_interrupts_are_enabled
asm_interrupts_are_enabled:
pushf
pop eax
and eax, 0x000200 ; FLAGS_INTERRUPT
ret

438
sortix/x86/interrupt.s Normal file
View File

@ -0,0 +1,438 @@
/*******************************************************************************
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012.
This file is part of Sortix.
Sortix is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
Sortix. If not, see <http://www.gnu.org/licenses/>.
x86/interrupt.s
Transfers control to interrupt handlers when interrupts happen.
*******************************************************************************/
.section .text
.global isr0
.type isr0, @function
isr0:
cli
pushl $0 # err_code
pushl $0 # int_no
jmp interrupt_handler_prepare
.global isr1
.type isr1, @function
isr1:
cli
pushl $0 # err_code
pushl $1 # int_no
jmp interrupt_handler_prepare
.global isr2
.type isr2, @function
isr2:
cli
pushl $0 # err_code
pushl $2 # int_no
jmp interrupt_handler_prepare
.global isr3
.type isr3, @function
isr3:
cli
pushl $0 # err_code
pushl $3 # int_no
jmp interrupt_handler_prepare
.global isr4
.type isr4, @function
isr4:
cli
pushl $0 # err_code
pushl $4 # int_no
jmp interrupt_handler_prepare
.global isr5
.type isr5, @function
isr5:
cli
pushl $0 # err_code
pushl $5 # int_no
jmp interrupt_handler_prepare
.global isr6
.type isr6, @function
isr6:
cli
pushl $0 # err_code
pushl $6 # int_no
jmp interrupt_handler_prepare
.global isr7
.type isr7, @function
isr7:
cli
pushl $0 # err_code
pushl $7 # int_no
jmp interrupt_handler_prepare
.global isr8
.type isr8, @function
isr8:
cli
# pushl $0 # err_code pushed by CPU
pushl $8 # int_no
jmp interrupt_handler_prepare
.global isr9
.type isr9, @function
isr9:
cli
pushl $0 # err_code
pushl $9 # int_no
jmp interrupt_handler_prepare
.global isr10
.type isr10, @function
isr10:
cli
# pushl $0 # err_code pushed by CPU
pushl $10 # int_no
jmp interrupt_handler_prepare
.global isr11
.type isr11, @function
isr11:
cli
# pushl $0 # err_code pushed by CPU
pushl $11 # int_no
jmp interrupt_handler_prepare
.global isr12
.type isr12, @function
isr12:
cli
# pushl $0 # err_code pushed by CPU
pushl $12 # int_no
jmp interrupt_handler_prepare
.global isr13
.type isr13, @function
isr13:
cli
# pushl $0 # err_code pushed by CPU
pushl $13 # int_no
jmp interrupt_handler_prepare
.global isr14
.type isr14, @function
isr14:
cli
# pushl $0 # err_code pushed by CPU
pushl $14 # int_no
jmp interrupt_handler_prepare
.global isr15
.type isr15, @function
isr15:
cli
pushl $0 # err_code
pushl $15 # int_no
jmp interrupt_handler_prepare
.global isr16
.type isr16, @function
isr16:
cli
pushl $0 # err_code
pushl $16 # int_no
jmp interrupt_handler_prepare
.global isr17
.type isr17, @function
isr17:
cli
pushl $0 # err_code
pushl $17 # int_no
jmp interrupt_handler_prepare
.global isr18
.type isr18, @function
isr18:
cli
pushl $0 # err_code
pushl $18 # int_no
jmp interrupt_handler_prepare
.global isr19
.type isr19, @function
isr19:
cli
pushl $0 # err_code
pushl $19 # int_no
jmp interrupt_handler_prepare
.global isr20
.type isr20, @function
isr20:
cli
pushl $0 # err_code
pushl $20 # int_no
jmp interrupt_handler_prepare
.global isr21
.type isr21, @function
isr21:
cli
pushl $0 # err_code
pushl $21 # int_no
jmp interrupt_handler_prepare
.global isr22
.type isr22, @function
isr22:
cli
pushl $0 # err_code
pushl $22 # int_no
jmp interrupt_handler_prepare
.global isr23
.type isr23, @function
isr23:
cli
pushl $0 # err_code
pushl $23 # int_no
jmp interrupt_handler_prepare
.global isr24
.type isr24, @function
isr24:
cli
pushl $0 # err_code
pushl $24 # int_no
jmp interrupt_handler_prepare
.global isr25
.type isr25, @function
isr25:
cli
pushl $0 # err_code
pushl $25 # int_no
jmp interrupt_handler_prepare
.global isr26
.type isr26, @function
isr26:
cli
pushl $0 # err_code
pushl $26 # int_no
jmp interrupt_handler_prepare
.global isr27
.type isr27, @function
isr27:
cli
pushl $0 # err_code
pushl $27 # int_no
jmp interrupt_handler_prepare
.global isr28
.type isr28, @function
isr28:
cli
pushl $0 # err_code
pushl $28 # int_no
jmp interrupt_handler_prepare
.global isr29
.type isr29, @function
isr29:
cli
pushl $0 # err_code
pushl $29 # int_no
jmp interrupt_handler_prepare
.global isr30
.type isr30, @function
isr30:
cli
pushl $0 # err_code
pushl $30 # int_no
jmp interrupt_handler_prepare
.global isr31
.type isr31, @function
isr31:
cli
pushl $0 # err_code
pushl $31 # int_no
jmp interrupt_handler_prepare
.global isr128
.type isr128, @function
isr128:
cli
pushl $0 # err_code
pushl $128 # int_no
jmp interrupt_handler_prepare
.global irq0
.type irq0, @function
irq0:
cli
pushl $0 # err_code
pushl $32 # int_no
jmp interrupt_handler_prepare
.global irq1
.type irq1, @function
irq1:
cli
pushl $0 # err_code
pushl $33 # int_no
jmp interrupt_handler_prepare
.global irq2
.type irq2, @function
irq2:
cli
pushl $0 # err_code
pushl $34 # int_no
jmp interrupt_handler_prepare
.global irq3
.type irq3, @function
irq3:
cli
pushl $0 # err_code
pushl $35 # int_no
jmp interrupt_handler_prepare
.global irq4
.type irq4, @function
irq4:
cli
pushl $0 # err_code
pushl $36 # int_no
jmp interrupt_handler_prepare
.global irq5
.type irq5, @function
irq5:
cli
pushl $0 # err_code
pushl $37 # int_no
jmp interrupt_handler_prepare
.global irq6
.type irq6, @function
irq6:
cli
pushl $0 # err_code
pushl $38 # int_no
jmp interrupt_handler_prepare
.global irq7
.type irq7, @function
irq7:
cli
pushl $0 # err_code
pushl $39 # int_no
jmp interrupt_handler_prepare
.global irq8
.type irq8, @function
irq8:
cli
pushl $0 # err_code
pushl $40 # int_no
jmp interrupt_handler_prepare
.global irq9
.type irq9, @function
irq9:
cli
pushl $0 # err_code
pushl $41 # int_no
jmp interrupt_handler_prepare
.global irq10
.type irq10, @function
irq10:
cli
pushl $0 # err_code
pushl $42 # int_no
jmp interrupt_handler_prepare
.global irq11
.type irq11, @function
irq11:
cli
pushl $0 # err_code
pushl $43 # int_no
jmp interrupt_handler_prepare
.global irq12
.type irq12, @function
irq12:
cli
pushl $0 # err_code
pushl $44 # int_no
jmp interrupt_handler_prepare
.global irq13
.type irq13, @function
irq13:
cli
pushl $0 # err_code
pushl $45 # int_no
jmp interrupt_handler_prepare
.global irq14
.type irq14, @function
irq14:
cli
pushl $0 # err_code
pushl $46 # int_no
jmp interrupt_handler_prepare
.global irq15
.type irq15, @function
irq15:
cli
pushl $0 # err_code
pushl $47 # int_no
jmp interrupt_handler_prepare
interrupt_handler_prepare:
pushl %eax
pushl %ecx
pushl %edx
pushl %ebx
pushl %esp
pushl %ebp
pushl %esi
pushl %edi
# Push the user-space data segment.
movl %ds, %ebp
pushl %ebp
# Load the kernel data segment.
movw $0x10, %bp
movl %ebp, %ds
movl %ebp, %es
movl %ebp, %fs
movl %ebp, %gs
# Push CR2 in case of page faults
movl %cr2, %ebp
pushl %ebp
# Now call the interrupt handler.
pushl %esp
call interrupt_handler
addl $4, %esp
# Remove CR2 from the stack.
addl $4, %esp
# Restore the user-space data segment.
popl %ebp
movl %ebp, %ds
movl %ebp, %es
movl %ebp, %fs
movl %ebp, %gs
popl %edi
popl %esi
popl %ebp
popl %esp
popl %ebx
popl %edx
popl %ecx
popl %eax
# Remove int_no and err_code
addl $8, %esp
# Return to where we came from.
iret
.global interrupt_handler_null
.type interrupt_handler_null, @function
interrupt_handler_null:
iret
.global asm_interrupts_are_enabled
.type asm_interrupts_are_enabled, @function
asm_interrupts_are_enabled:
pushfl
popl %eax
andl $0x000200, %eax # FLAGS_INTERRUPT
retl