aboutsummaryrefslogtreecommitdiff
path: root/src/int/pic.c
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2021-04-11 20:53:06 +0200
committerLoic Guegan <manzerbredes@mailbox.org>2021-04-11 20:53:06 +0200
commit6edeba8fe208fb019aec00fdc72b97407a8078d3 (patch)
tree965376727a7519fd20f73a946c01157151098ec6 /src/int/pic.c
parent3212145e94e0c68a5da96306545c116292dfbe85 (diff)
Enable paging
Diffstat (limited to 'src/int/pic.c')
-rw-r--r--src/int/pic.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/int/pic.c b/src/int/pic.c
new file mode 100644
index 0000000..472e50c
--- /dev/null
+++ b/src/int/pic.c
@@ -0,0 +1,115 @@
+#include "pic.h"
+#include "utils/asm.h"
+#include "utils/mem.h"
+#include "utils/syscall.h"
+
+struct IDT_REGISTER IDTR={
+ 200*8,
+ 0x0
+};
+
+/// Bridge between IDT and functions call
+asm (
+".macro SAVE_REGS \n\t"
+ "pushal \n\t"
+ "push %ds \n\t"
+ "push %es \n\t"
+ "push %fs \n\t"
+ "push %gs \n\t"
+ "push %ebx \n\t"
+ "mov $0x10,%bx \n\t"
+ "mov %bx,%ds \n\t"
+ "pop %ebx \n\t"
+".endm \n\t"
+".macro RESTORE_REGS \n\t"
+ "pop %gs \n\t"
+ "pop %fs \n\t"
+ "pop %es \n\t"
+ "pop %ds \n\t"
+ "popal \n\t"
+".endm \n\t"
+"PIC_IRQ_DEFAULT: \n\t"
+ "SAVE_REGS \n\t"
+ "movb $0x20, %al \n\t"
+ "outb %al, $0x20 \n\t"
+ "RESTORE_REGS \n\t"
+ "iret \n\t"
+"PIC_IRQ_PRINT: \n\t"
+ "SAVE_REGS \n\t"
+ "call _8042_keypress \n\t"
+ "movb $0x20, %al \n\t"
+ "outb %al, $0x20 \n\t"
+ "RESTORE_REGS \n\t"
+ "iret \n\t"
+"PIC_IRQ_CLOCK: \n\t"
+ "SAVE_REGS \n\t"
+ "call clock \n\t"
+ "movb $0x20, %al \n\t"
+ "outb %al, $0x20 \n\t"
+ "RESTORE_REGS \n\t"
+ "iret \n\t"
+"PIC_IRQ_SYSCALL: \n\t"
+ "SAVE_REGS \n\t"
+ "call syscall \n\t"
+ "movb $0x20, %al \n\t"
+ "outb %al, $0x20 \n\t"
+ "RESTORE_REGS \n\t"
+ "iret \n\t"
+"INT_PAGE_FAULT: \n\t"
+ "SAVE_REGS \n\t"
+ "call page_fault \n\t"
+ "hlt \n\t"
+ "movb $0x20, %al \n\t"
+ "outb %al, $0x20 \n\t"
+ "RESTORE_REGS \n\t"
+ "iret \n\t"
+);
+
+extern u32 PIC_IRQ_DEFAULT,PIC_IRQ_PRINT,PIC_IRQ_CLOCK, PIC_IRQ_SYSCALL,INT_PAGE_FAULT;
+
+void pic_enable_interrupt(){
+ // Map first default 32 entries
+ for(int i=0;i<200;i++){
+ pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_DEFAULT,IDT_INT_GATE},i);
+ if(i==14)
+ pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&INT_PAGE_FAULT,IDT_INT_GATE},i);
+ if(i==32)
+ pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_CLOCK,IDT_INT_GATE},i);
+ if(i==33)
+ pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_PRINT,IDT_INT_GATE},i);
+ if(i==48)
+ pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_SYSCALL,IDT_TRAP_GATE},i);
+ }
+
+ // Now configure 8952A
+
+ // ICW1: Initialisation
+ outbj(0x20,0x11); // Master
+ outbj(0xA0,0x11); // Slave
+
+ // ICW2: Map IRQ index to entry into the IDT
+ outbj(0x21,0x20); // Start interrupt at offset 0x20 in IDT (index 32)
+ outbj(0xA1,0x70); // Start interrupt at offset 0x50 in IDT (index 80)
+
+ // ICW3: Indicate the connection between master and slave
+ outbj(0x21,0x02); // Slave connected to pin 2
+ outbj(0xA1,0x01); // Indicate pin id to the slave (2-1)
+
+ // ICW4: Operating mode
+ outbj(0x21,0x01); // Default operating mode
+ outbj(0xA1,0x01); // Default operating mode
+
+ // OCW: Masking
+ outbj(0x21,0b11111100);
+
+
+ asm("lidtl (IDTR)");
+ asm("sti");
+}
+
+void pic_add_idt_entry(IDT_ENTRY entry, int id){
+ int descriptor[2];
+ descriptor[0]=entry.offset & 0xFFFF | entry.segment << 16;
+ descriptor[1]=entry.type & 0xFFFF | entry.offset & 0xFFFF0000;
+ memcpy((void*)descriptor, (void *)(IDTR.base+(id*8)),8);
+}