171 lines
2.6 KiB
NASM
171 lines
2.6 KiB
NASM
; Calcite, src/kernel/interrupts.asm
|
|
; Copyright 2025-2026 Benji Dial
|
|
;
|
|
; This program 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.
|
|
;
|
|
; This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
bits 64
|
|
default rel
|
|
|
|
;both defined in interrupts.c
|
|
extern isr_exception_c
|
|
extern isr_irq_c
|
|
|
|
section .rodata
|
|
|
|
;referenced in interrupts.c
|
|
global isrs
|
|
isrs:
|
|
%assign n 0
|
|
%rep 48
|
|
dq isr_ %+ n
|
|
%assign n n + 1
|
|
%endrep
|
|
|
|
section .text
|
|
|
|
%assign n 0
|
|
|
|
%rep 32
|
|
isr_ %+ n:
|
|
%if n <= 0x07 || n = 0x09 || (n >= 0x0f && n <= 0x1c && n <> 0x11 && n <> 0x15) || n = 0x1f
|
|
push qword 0
|
|
%endif
|
|
push qword n
|
|
jmp isr_exception_common
|
|
%assign n n + 1
|
|
%endrep
|
|
|
|
%rep 16
|
|
isr_ %+ n:
|
|
push rdi
|
|
mov rdi, n - 32
|
|
jmp isr_irq_common
|
|
%assign n n + 1
|
|
%endrep
|
|
|
|
isr_exception_common:
|
|
push rax
|
|
push rbx
|
|
push rcx
|
|
push rdx
|
|
push rdi
|
|
push rsi
|
|
push rbp
|
|
push r8
|
|
push r9
|
|
push r10
|
|
push r11
|
|
push r12
|
|
push r13
|
|
push r14
|
|
push r15
|
|
mov rax, cr2
|
|
push rax
|
|
mov rax, cr3
|
|
push rax
|
|
mov rdi, rsp
|
|
|
|
call isr_exception_c
|
|
|
|
add rsp, 48
|
|
pop r11
|
|
pop r10
|
|
pop r9
|
|
pop r8
|
|
add rsp, 8
|
|
pop rsi
|
|
pop rdi
|
|
pop rdx
|
|
pop rcx
|
|
add rsp, 8
|
|
pop rax
|
|
add rsp, 16
|
|
iretq
|
|
|
|
isr_irq_common:
|
|
push rax
|
|
push rcx
|
|
push rdx
|
|
push rsi
|
|
push r8
|
|
push r9
|
|
push r10
|
|
push r11
|
|
|
|
test dil, 0x08
|
|
jnz .high
|
|
|
|
call isr_irq_c
|
|
mov al, 0x20
|
|
out 0x20, al
|
|
jmp .common_end
|
|
|
|
.high:
|
|
call isr_irq_c
|
|
mov al, 0x20
|
|
out 0xa0, al
|
|
out 0x20, al
|
|
|
|
.common_end:
|
|
pop r11
|
|
pop r10
|
|
pop r9
|
|
pop r8
|
|
pop rsi
|
|
pop rdx
|
|
pop rcx
|
|
pop rax
|
|
pop rdi
|
|
|
|
iretq
|
|
|
|
;referenced in interrupts.c
|
|
;rdi is pointer to gdt descriptor
|
|
;rsi is pointer to idt descriptor
|
|
;dx is offset of tss into gdt
|
|
global init_interrupts_asm
|
|
init_interrupts_asm:
|
|
|
|
;load tables
|
|
|
|
lgdt [rdi]
|
|
ltr dx
|
|
lidt [rsi]
|
|
|
|
;initialize interrupt controllers
|
|
|
|
mov al, 0x11
|
|
out 0x20, al
|
|
mov al, 0x20
|
|
out 0x21, al
|
|
mov al, 0x04
|
|
out 0x21, al
|
|
mov al, 0x01
|
|
out 0x21, al
|
|
mov al, 0x00
|
|
out 0x21, al
|
|
|
|
mov al, 0x11
|
|
out 0xa0, al
|
|
mov al, 0x28
|
|
out 0xa1, al
|
|
mov al, 0x02
|
|
out 0xa1, al
|
|
mov al, 0x01
|
|
out 0xa1, al
|
|
mov al, 0x00
|
|
out 0xa1, al
|
|
|
|
ret
|