summaryrefslogtreecommitdiff
path: root/irq.asm
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2016-09-30 16:02:16 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2016-09-30 16:02:16 -0400
commit543b5096164a704aa7167fe0b9b23494237a297d (patch)
tree63fb43f100a61c6f874ba81412b09343a12055d9 /irq.asm
downloadkernel-fun-543b5096164a704aa7167fe0b9b23494237a297d.tar.gz
Initial commit
Diffstat (limited to 'irq.asm')
-rw-r--r--irq.asm248
1 files changed, 248 insertions, 0 deletions
diff --git a/irq.asm b/irq.asm
new file mode 100644
index 0000000..40ac990
--- /dev/null
+++ b/irq.asm
@@ -0,0 +1,248 @@
+section .text
+global idt_entry
+global PIC_sendEOI
+global idt_init
+extern interrupt_handler
+
+extern pio_read
+extern pio_write
+
+struc idt_entry
+ .base_low: resw 1
+ .selector: resw 1
+ .zero: resb 1
+ .flags: resb 1
+ .base_high: resw 1
+endstruc
+
+%macro no_error_code_interrupt_handler 1
+global interrupt_handler_%1:
+interrupt_handler_%1:
+ push dword 0
+ push dword %1
+ jmp common_interrupt_handler
+%endmacro
+
+%macro error_code_interrupt_handler 1
+global interrupt_handler_%1
+interrupt_handler_%1:
+ push dword %1
+ jmp common_interrupt_handler
+%endmacro
+
+%macro idt_set_gate 2
+ ; Assign values to IDT entry at interrupt (ecx)
+ ; with the offset of the interrupt handler (edx)
+ mov edx, %2
+ mov [idt + %1 * 8 + idt_entry.base_low], dx
+ mov word [idt + %1 * 8 + idt_entry.selector], 0x8
+ mov byte [idt + %1 * 8 + idt_entry.zero], 0x0
+ mov byte [idt + %1 * 8 + idt_entry.flags], 0x8e
+ shr edx, 16
+ mov word [idt + %1 * 8 + idt_entry.base_high], dx
+%endmacro
+
+common_interrupt_handler:
+ pushad
+ call interrupt_handler
+ popad
+ add esp, 8
+ iret
+
+no_error_code_interrupt_handler 0
+no_error_code_interrupt_handler 1
+no_error_code_interrupt_handler 2
+no_error_code_interrupt_handler 3
+no_error_code_interrupt_handler 4
+no_error_code_interrupt_handler 5
+no_error_code_interrupt_handler 6
+no_error_code_interrupt_handler 7
+error_code_interrupt_handler 8
+no_error_code_interrupt_handler 9
+error_code_interrupt_handler 10
+error_code_interrupt_handler 11
+error_code_interrupt_handler 12
+error_code_interrupt_handler 13
+error_code_interrupt_handler 14
+no_error_code_interrupt_handler 15
+no_error_code_interrupt_handler 16
+no_error_code_interrupt_handler 17
+no_error_code_interrupt_handler 18
+no_error_code_interrupt_handler 19
+no_error_code_interrupt_handler 20
+no_error_code_interrupt_handler 21
+no_error_code_interrupt_handler 22
+no_error_code_interrupt_handler 23
+no_error_code_interrupt_handler 24
+no_error_code_interrupt_handler 25
+no_error_code_interrupt_handler 26
+no_error_code_interrupt_handler 27
+no_error_code_interrupt_handler 28
+no_error_code_interrupt_handler 29
+no_error_code_interrupt_handler 30
+no_error_code_interrupt_handler 31
+; 32 unused
+no_error_code_interrupt_handler 33
+
+
+;interrupt_handler:
+; cmp byte [esp + 4], 0x21
+; je .int21
+;
+; jmp .end
+;
+;.int21:
+; mov dword [0xB8000], ': ) '
+; push m
+; call kprint
+;
+;.end:
+; ret
+
+PIC_sendEOI:
+ ret
+
+PIC_remap:
+ ;arguments:
+ ;offset1 - vector offset for master PIC
+ ; vectors on the master become offset1..offset1+7
+ ;offset2 - same for slave PIC: offset2..offset2+7
+
+ push ebp
+ mov ebp, esp
+
+ sub ebp, 8
+
+ push PIC1_DATA
+ call pio_read
+ mov [ebp - 4], al ; save PIC1 mask
+
+ push PIC2_DATA
+ call pio_read
+ mov [ebp - 8], al ; save PIC2 mask
+
+ push PIC1_COMMAND
+ push ICW1_INIT+ICW1_ICW4 ; initialization sequence (cascade)
+ call pio_write
+
+ push PIC2_COMMAND
+ push ICW1_INIT+ICW1_ICW4 ; initialization sequence (cascade)
+ call pio_write
+
+ push PIC1_DATA
+ push word [ebp + 8] ; ICW2: Master PIC vector offset
+ call pio_write
+
+ push PIC2_DATA
+ push word [ebp + 12] ; ICW2: Save PIC vector offset
+ call pio_write
+
+ push PIC1_DATA
+ push 0x4 ; ICW3: tell Master PIC there is a slave PIC at IRQ2 (0000 0100)
+ call pio_write
+
+ push PIC2_DATA
+ push 2 ; ICW3: tell Slave PIC its cacade identity (0000 0010)
+ call pio_write
+
+ push PIC1_DATA
+ push ICW4_8086
+ call pio_write
+
+ push PIC2_DATA
+ push ICW4_8086
+ call pio_write
+
+
+ ;; ICW3
+ ;push PIC1_DATA
+ ;push 0x20
+ ;call pio_write
+
+ ;push PIC2_DATA
+ ;push 0x28
+ ;call pio_write
+
+ ;; ICW4
+ ;push PIC1_DATA
+ ;push 0x00
+ ;call pio_write
+
+ ;push PIC2_DATA
+ ;push 0x01
+ ;call pio_write
+
+ ;; mask interrupts
+ ;push PIC1_DATA
+ ;push 0xff
+ ;call pio_write
+
+ ;push PIC2_DATA
+ ;push 0xff
+ ;call pio_write
+
+ push PIC1_DATA
+ push word [ebp - 4]
+ call pio_write
+
+ push PIC2_DATA
+ push word [ebp - 8]
+ call pio_write
+
+ add ebp, 8
+ leave
+ ret
+
+
+idt_init:
+ push ebp
+ mov ebp, esp
+
+ mov al, 0x0 ; idt's initial value
+ mov ecx, idt_entry_size * 256 - 1 ; Size of: idt
+ mov edi, idt ; pointer to: idt
+ cld ; clear direction flag
+ rep stosb ; fill array with zeros
+
+
+ idt_set_gate 33, interrupt_handler_33 ; implement INT 21
+
+ mov ebx, idt_entry_size * 256 - 1 ; size of: idt - 1
+ mov eax, idt ; pointer to: idt
+
+ mov [idt_ptr], ebx ; describe ITDR limit
+ mov [idt_ptr + 2], eax ; describe ITDR offset
+
+ push idt_ptr
+ call idt_load ; load IDTR register
+
+ leave
+ ret
+
+
+
+idt_load:
+ push ebp
+ mov ebp, esp
+
+ mov edx, [esp + 8]
+ lidt [edx]
+
+ leave
+ ret
+
+
+section .data
+%include 'constants.asm'
+
+section .bss
+align 4
+
+idt_ptr:
+ resw 1
+ resd 1
+
+idt:
+ resb idt_entry_size * 256
+
+