diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..13cbe59 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "pic.h": "c" + } +} \ No newline at end of file diff --git a/src/kernel/arch_i386/idt.s b/src/kernel/arch_i386/idt.s index bba542c..017869e 100644 --- a/src/kernel/arch_i386/idt.s +++ b/src/kernel/arch_i386/idt.s @@ -32,7 +32,7 @@ global _isr30 global _isr31 global load_idt - +section .text load_idt: push ebp mov ebp, esp @@ -249,98 +249,93 @@ global _irq15 global _syscall _irq0: cli - push 0 - push 32 + ; jmp $ + push dword 0 + push dword 32 jmp _irq_common_stub _irq1: cli - push 0 - push 33 + push dword 0 + push dword 33 jmp _irq_common_stub _irq2: cli - push 0 - push 34 + push dword 0 + push dword 34 jmp _irq_common_stub _irq3: cli - push 0 - push 35 + push dword 0 + push dword 35 jmp _irq_common_stub _irq4: cli - push 0 - push 36 + push dword 0 + push dword 36 jmp _irq_common_stub _irq5: cli - push 0 - push 37 + push dword 0 + push dword 37 jmp _irq_common_stub _irq6: cli - push 0 - push 38 + push dword 0 + push dword 38 jmp _irq_common_stub _irq7: cli - push 0 - push 39 + push dword 0 + push dword 39 jmp _irq_common_stub _irq8: cli - push 0 - push 40 + push dword 0 + push dword 40 jmp _irq_common_stub _irq9: cli - push 0 - push 41 + push dword 0 + push dword 41 jmp _irq_common_stub _irq10: cli - push 0 - push 42 + push dword 0 + push dword 42 jmp _irq_common_stub _irq11: cli - push 0 - push 43 + push dword 0 + push dword 43 jmp _irq_common_stub _irq12: cli - push 0 - push 44 + push dword 0 + push dword 44 jmp _irq_common_stub _irq13: cli - push 0 - push 45 + push dword 0 + push dword 45 jmp _irq_common_stub _irq14: cli - push 0 - push 46 + push dword 0 + push dword 46 jmp _irq_common_stub _irq15: cli - push 0 - push 47 + push dword 0 + push dword 47 jmp _irq_common_stub _syscall: cli - push 0 - push 0x80 + push dword 0 + push dword 0x80 _irq_common_stub: - push eax - push ebx - push ecx - push edx - push ebp - push esi - push edi + pushad push ds push es push fs @@ -354,12 +349,6 @@ _irq_common_stub: pop fs pop es pop ds - pop edi - pop esi - pop ebp - pop edx - pop ecx - pop ebx - pop eax + popad add esp, 8 iret \ No newline at end of file diff --git a/src/kernel/arch_i386/interrupts.c b/src/kernel/arch_i386/interrupts.c index fc917cf..9dd7ea9 100644 --- a/src/kernel/arch_i386/interrupts.c +++ b/src/kernel/arch_i386/interrupts.c @@ -1,5 +1,6 @@ #include "../shared/interrupts.h" #include "../drivers/serial.h" +#include "../drivers/cpuio.h" #include extern void _isr0(); @@ -8,16 +9,31 @@ extern void _isr1(); extern void _irq0(); extern void _irq1(); extern void _syscall(); +extern void load_idt(void*); +typedef struct idt_entry{ + uint16_t offset_low; + uint16_t code_seg; + uint8_t reserved; + uint8_t flags; + uint16_t offset_high; +}__attribute__((packed)) idt_entry_t; +cpu_registers_t *(*interrupt_handlers[16])(cpu_registers_t *regs) = {0}; idt_t idt_desc; -uint64_t idt_table[256]; + +idt_entry_t idt_table[256]; inline void set_idt_entry(uint32_t index, void *ptr, uint8_t flags, uint16_t segment){ uint32_t offset = (uint32_t) ptr; - idt_table[index] = ((uint64_t)(offset >> 16) << 48) | ((uint64_t)(flags | 0x80) << 40) | (segment << 16) | (offset & 0xffff); + idt_table[index].offset_high = offset >> 16; + idt_table[index].offset_low = offset & 0xffff; + idt_table[index].code_seg = segment; + idt_table[index].flags = flags | 0x80; + // idt_table[index] = (segment << 16) | (offset & 0xffff); + // idt_table[index+1] = (offset >> 16) | ((flags | 0x80) << 8); + // idt_table[index] = ((uint64_t)(offset >> 16) << 48) | ((uint64_t)(flags | 0x80) << 40) | (segment << 16) | (offset & 0xffff); } -cpu_registers_t *(*interrupt_handlers[16])(cpu_registers_t *regs) = {0}; void _irq_handler(cpu_registers_t *regs){ if(regs->int_no == 0x80){ @@ -25,11 +41,20 @@ void _irq_handler(cpu_registers_t *regs){ } else if(interrupt_handlers[regs->int_no - 32]) { + if(regs->int_no == 32){ + // printf("Tick\n"); + // printf("%x\n", regs->int_no); + } regs = interrupt_handlers[regs->int_no - 32](regs); + // printf("eip: %x", regs->eip); + outb(0x20, 0x20); + if(regs->int_no >= 0x28){ + outb(0xa0, 0x20); + } } } void _isr_handler(cpu_registers_t *regs){ - printf("Error!!\n"); + printf("Error!! %x\n", regs->eip); for(;;); } @@ -39,13 +64,34 @@ cpu_registers_t *syscall(cpu_registers_t *regs){ void init_idt(){ for(uint32_t i = 0; i < 32; i++){ - set_idt_entry(i, (_isr0 + (_isr1 - _isr0) * i), IDT_GATE_TRAP, 0x10); + set_idt_entry(i, (_isr0 + ((_isr1 - _isr0) * i)), IDT_GATE_INT, 0x10); + // printf("int %d: address: %x\n", i, _isr0 + (_isr1 - _isr0) * i); } + // printf("last ") for(uint32_t i = 0; i < 16; i++){ - set_idt_entry(i + 32, (_irq0 + (_irq1 - _irq0) * i), IDT_GATE_INT, 0x10); + set_idt_entry(i + 32, (_irq0 + ((_irq1 - _irq0) * i)), IDT_GATE_INT, 0x10); + printf("int %d: address: %x\n", i + 32, _irq0 + (_irq1 - _irq0) * i); } - idt_desc.pointer = (uint32_t)idt_table; - idt_desc.size = sizeof(idt_table); - asm volatile("lidt (%0)" : : "m"(idt_desc)); + idt_desc.pointer = (uint32_t)&idt_table; + idt_desc.size = sizeof(idt_entry_t) * 256 - 1; + for(int i = 0; i < 16; i++){ + interrupt_handlers[i] = 0; + } + // asm volatile("lidt (%0)" : : "m"(&idt_desc)); + // outb(0x20, 0x11 ); + // outb(0xa0, 0x11); + // outb(0x21, 0x20); + // outb(0xa1, 0x28); + // outb(0x21, 4); + // outb(0xa1, 2); + // outb(0x21, 1); + // outb(0xa1, 1); + // outb(0x21, 0); + // outb(0xa1, 0); + + //set pic masks + // outb(0x21, 0); + // outb(0xa1, 0); + load_idt(&idt_desc); } diff --git a/src/kernel/drivers/pic.c b/src/kernel/drivers/pic.c index dab6526..f959c79 100644 --- a/src/kernel/drivers/pic.c +++ b/src/kernel/drivers/pic.c @@ -1,5 +1,34 @@ #include "pic.h" +#include "cpuio.h" void init_pic(uint8_t idt_index){ + uint8_t a1 = inb(PIC1_DATA); + uint8_t a2 = inb(PIC2_DATA); + outb(PIC1_COMMAND, PIC_ICW1_INIT | PIC_ICW1_ICW4); + outb(PIC2_COMMAND, PIC_ICW1_INIT | PIC_ICW1_ICW4); + + outb(PIC1_DATA, 32); + outb(PIC2_DATA, 40); + + outb(PIC1_DATA, 4); + outb(PIC2_DATA, 2); + + outb(PIC1_DATA, PIC_ICW4_8086); + outb(PIC2_DATA, PIC_ICW4_8086); + + outb(PIC1_DATA, a1); + outb(PIC2_DATA, a2); +} +void pic_disable(){ + outb(PIC1_DATA, 0xff); + outb(PIC2_DATA, 0xff); +} +void pic_setmask(uint8_t mask, uint16_t pic){ + // if(pic != PIC1_DATA || pic != PIC2_DATA) return; + outb(pic, mask); +} +uint8_t pic_getmask(uint16_t pic){ + // if(pic != PIC1_DATA || pic != PIC2_DATA) return 0; + return inb(pic); } \ No newline at end of file diff --git a/src/kernel/drivers/pic.h b/src/kernel/drivers/pic.h index 62675bc..655b8f8 100644 --- a/src/kernel/drivers/pic.h +++ b/src/kernel/drivers/pic.h @@ -15,4 +15,12 @@ #define PIC_ICW1_INIT 0x10 #define PIC_ICW4_8086 0x01 -#define P +#define PIC_ICW4_AUTO 0x02 +#define PIC_ICW4_BUF_S 0x08 +#define PIC_ICW4_BUF_M 0x0c +#define PIC_ICW4_SFNM 0x10 + +void init_pic(uint8_t idt_index); +void pic_disable(); +void pic_setmask(uint8_t mask, uint16_t pic); +uint8_t pic_getmask(uint16_t pic); diff --git a/src/kernel/entry.s b/src/kernel/entry.s index b1ee487..1b26f34 100644 --- a/src/kernel/entry.s +++ b/src/kernel/entry.s @@ -4,6 +4,7 @@ extern kmain section .text global _start _start: + cld mov esp, stack_top mov ebp, stack_top push esi diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index bf98bae..d60c9f7 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -3,10 +3,17 @@ #include "shared/kstdlib.h" #include "shared/interrupts.h" #include "drivers/serial.h" +#include "drivers/pic.h" extern void kmain(kernel_info_t *kernel_info){ init_serial(); pm_init(kernel_info); init_idt(); + init_pic(32); + pic_disable(); + pic_setmask(0xfe, PIC1_DATA); + enable_interrupts(); + printf("done\n"); + for(;;); return; } \ No newline at end of file diff --git a/src/kernel/system/string.c b/src/kernel/system/string.c index 22d64f7..326a0cd 100644 --- a/src/kernel/system/string.c +++ b/src/kernel/system/string.c @@ -5,6 +5,11 @@ void itoa(int64_t data, char *res, uint8_t base){ char carr[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char negative = 0; if(res == 0) return; + if(data == 0){ + res[0] = '0'; + res[1] = 0; + return; + } if(data < 0 && base == 10){ data *= -1; negative = 1;