summaryrefslogtreecommitdiff
path: root/cpu/idt.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/idt.c')
-rw-r--r--cpu/idt.c195
1 files changed, 0 insertions, 195 deletions
diff --git a/cpu/idt.c b/cpu/idt.c
deleted file mode 100644
index abcafad..0000000
--- a/cpu/idt.c
+++ /dev/null
@@ -1,195 +0,0 @@
-#include <cpu/idt.h>
-#include <sched/scheduler.h>
-#include <stdio.h>
-
-#define MASTER_PIC_COMMAND_PORT 0x20
-#define MASTER_PIC_DATA_PORT 0x21
-#define SLAVE_PIC_COMMAND_PORT 0xA0
-#define SLAVE_PIC_DATA_PORT 0xA1
-#define KEYBOARD_DATA_PORT 0x60
-#define KEYBOARD_STATUS_PORT 0x64
-#define KERNEL_CODE_SEGMENT_OFFSET GDT_ENTRY_SIZE *GDT_KERNEL_CODE_SEGMENT
-
-#define IDT_MAX_ENTRY 256
-
-struct IDT_Descriptor {
- uint16_t low_offset;
- uint16_t code_segment_selector;
- uint8_t zero; // Always should be zero
- uint8_t type_attribute;
- uint16_t high_offset;
-} __attribute__((packed)) __attribute__((aligned(4)));
-
-struct IDT_Pointer {
- uint16_t size;
- struct IDT_Descriptor **interrupt_table;
-} __attribute__((packed));
-
-struct IDT_Descriptor IDT_Entry[IDT_MAX_ENTRY];
-struct IDT_Pointer idtr;
-
-extern void load_idtr(void *idtr);
-
-void format_descriptor(uint32_t offset, uint16_t code_segment,
- uint8_t type_attribute,
- struct IDT_Descriptor *descriptor) {
- descriptor->low_offset = offset & 0xFFFF;
- descriptor->high_offset = offset >> 16;
- descriptor->type_attribute = type_attribute;
- descriptor->code_segment_selector = code_segment;
- descriptor->zero = 0;
-}
-
-void install_handler(void (*handler_function)(), uint16_t type_attribute,
- uint8_t entry) {
- format_descriptor((uint32_t)handler_function, KERNEL_CODE_SEGMENT_OFFSET,
- type_attribute, &IDT_Entry[entry]);
-}
-
-__attribute__((no_caller_saved_registers)) void EOI(uint8_t irq) {
- if (irq > 7)
- outb(SLAVE_PIC_COMMAND_PORT, 0x20);
-
- outb(MASTER_PIC_COMMAND_PORT, 0x20);
-}
-
-__attribute__((interrupt)) void general_protection_fault(registers_t *regs) {
- klog("General Protetion Fault", 0x1);
- kprintf(" Error Code: %x\n", regs->error_code);
- kprintf("Instruction Pointer: %x\n", regs->eip);
- dump_backtrace(12);
- asm("hlt");
- for (;;)
- ;
- EOI(0xD - 8);
-}
-
-__attribute__((interrupt)) void double_fault(registers_t *regs) {
- (void)regs;
- klog("DOUBLE FAULT", LOG_ERROR);
- asm("hlt");
- for (;;)
- ;
-}
-__attribute__((interrupt)) void page_fault(registers_t *regs) {
- if (0xFFFFDEAD == regs->eip) {
- asm("sti");
- for (;;)
- switch_task();
- }
- klog("Page Fault", LOG_ERROR);
- if (get_current_task()) {
- kprintf("PID: %x\n", get_current_task()->pid);
- kprintf("Name: %s\n", get_current_task()->program_name);
- }
- kprintf("Error Code: %x\n", regs->error_code);
- kprintf("Instruction Pointer: %x\n", regs->eip);
-
- if (regs->error_code & (1 << 0))
- kprintf("page-protection violation\n");
- else
- kprintf("non-present page\n");
-
- if (regs->error_code & (1 << 1))
- kprintf("write access\n");
- else
- kprintf("read access\n");
-
- if (regs->error_code & (1 << 2))
- kprintf("CPL = 3\n");
-
- if (regs->error_code & (1 << 4))
- kprintf("Attempted instruction fetch\n");
-
- dump_backtrace(5);
- asm("hlt");
- for (;;)
- ;
-}
-
-static inline void io_wait(void) { outb(0x80, 0); }
-
-#define ICW1_ICW4 0x01 /* ICW4 (not) needed */
-#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
-#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
-#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
-#define ICW1_INIT 0x10 /* Initialization - required! */
-
-#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
-#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
-#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
-#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
-#define ICW4_SFNM 0x10 /* Special fully nested (not) */
-
-void PIC_remap(int offset) {
- unsigned char a1, a2;
- a1 = inb(MASTER_PIC_DATA_PORT);
- a2 = inb(SLAVE_PIC_DATA_PORT);
-
- // Send ICW1 and tell the PIC that we will issue a ICW4
- // Since there is no ICW1_SINGLE sent to indicate it is cascaded
- // it means we will issue a ICW3.
- outb(MASTER_PIC_COMMAND_PORT, ICW1_INIT | ICW1_ICW4);
- io_wait();
- outb(SLAVE_PIC_COMMAND_PORT, ICW1_INIT | ICW1_ICW4);
- io_wait();
-
- // As a part of ICW2 this sends the offsets(the position to put IRQ0) of the
- // vector tables.
- outb(MASTER_PIC_DATA_PORT, offset);
- io_wait();
- outb(SLAVE_PIC_DATA_PORT, offset + 0x8);
- io_wait();
-
- // This tells the master on which lines it is having slaves
- outb(MASTER_PIC_DATA_PORT, 4);
- io_wait();
- // This tells the slave the cascading identity.
- outb(SLAVE_PIC_DATA_PORT, 2);
- io_wait();
-
- outb(MASTER_PIC_DATA_PORT, ICW4_8086);
- io_wait();
- outb(SLAVE_PIC_DATA_PORT, ICW4_8086);
- io_wait();
-
- outb(MASTER_PIC_DATA_PORT, a1);
- outb(SLAVE_PIC_DATA_PORT, a2);
-}
-
-void IRQ_set_mask(unsigned char IRQline) {
- uint16_t port;
- uint8_t value;
- port = (IRQline < 8) ? MASTER_PIC_DATA_PORT : SLAVE_PIC_DATA_PORT;
- if (IRQline >= 8)
- IRQline -= 8;
- value = inb(port) | (1 << IRQline);
- outb(port, value);
-}
-
-void IRQ_clear_mask(unsigned char IRQline) {
- uint16_t port;
- uint8_t value;
- port = (IRQline < 8) ? MASTER_PIC_DATA_PORT : SLAVE_PIC_DATA_PORT;
- if (IRQline >= 8) {
- IRQline -= 8;
- }
- value = inb(port) & ~(1 << IRQline);
- outb(port, value);
-}
-
-void idt_init(void) {
- install_handler(page_fault, INT_32_INTERRUPT_GATE(0x0), 0xE);
- install_handler(double_fault, INT_32_INTERRUPT_GATE(0x0), 0x8);
- install_handler(general_protection_fault, INT_32_INTERRUPT_GATE(0x0), 0xD);
-
- PIC_remap(0x20);
- IRQ_clear_mask(0xb);
- IRQ_set_mask(0xe);
- IRQ_set_mask(0xf);
- IRQ_clear_mask(2);
-
- idtr.interrupt_table = (struct IDT_Descriptor **)&IDT_Entry;
- idtr.size = (sizeof(struct IDT_Descriptor) * IDT_MAX_ENTRY) - 1;
- load_idtr(&idtr);
-}