/* * Copyright (C) 2017 Robin Krahl * * 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. */ #include #include #include #include #include #define IDT_GATE_COUNT 256 struct idt_gate { uint16_t handler_lo; uint16_t gdt_offset; uint8_t reserved; uint8_t access; uint16_t handler_hi; } __attribute__((packed)); struct idt_gate idt[IDT_GATE_COUNT]; struct idtp idtp = { .limit = IDT_GATE_COUNT * sizeof(*idt) - 1, .pointer = idt, }; static void idt_set(uint8_t no, uint16_t offset, uint32_t handler, uint8_t access, uint8_t flags); void idt_init(void) { uint32_t offset = gdt_get_code_offset(); uint32_t i; uint8_t *no = irqnos; uint32_t *addr = irqhdls; ker_dbg("Initializing IDT ..."); for (i = 0; i < IDT_GATE_COUNT; i++) idt_set(i, offset, (uint32_t) &irqign, 0, 0xE); for (; *no; no++, addr++) { if (!*addr) continue; ker_dbg("Registerung IRQ handler ..."); idt_set(*no, offset, *addr, 0, 0xE); } idtset(idtp); } void idt_activate(void) { idtact(); } static void idt_set(uint8_t no, uint16_t offset, uint32_t handler, uint8_t access, uint8_t flags) { idt[no].handler_lo = handler & 0xFFFF; idt[no].handler_hi = (handler >> 16) & 0xFFFF; idt[no].gdt_offset = offset; idt[no].reserved = 0; idt[no].access = 0x80 | flags | ((access & 0x3) << 5); }