diff options
Diffstat (limited to 'arch/x86/idt')
| -rw-r--r-- | arch/x86/idt/Idt.cpp | 130 | ||||
| -rw-r--r-- | arch/x86/idt/Idt.h | 63 |
2 files changed, 193 insertions, 0 deletions
diff --git a/arch/x86/idt/Idt.cpp b/arch/x86/idt/Idt.cpp new file mode 100644 index 0000000..d489f0e --- /dev/null +++ b/arch/x86/idt/Idt.cpp @@ -0,0 +1,130 @@ +#include "Idt.h" + + +uint64 MngIdt::idt[MngIdt::size]; +bool MngIdt::isInitialize = false; +bool MngIdt::idtLoaded = false; +MngIdt mngIdt; + +DescInterrupt32::DescInterrupt32(uint32 offset, uint16 selector, uint8 attr) +{ + uint8 gateType = attr & 0x0f; + + if((gateType == TSK_GATE and offset != 0) + or gateType < TSK_GATE + or (gateType > TRAP_GATE_16 and gateType < INT_GATE_32) + or gateType > TRAP_GATE_32 + or !(attr & PRESENT_BIT)) + { + offsetLow = 0; + offsetHight = 0; + segmentSelector = 0; + attributes = 0; + } + else + { + offsetLow = offset & 0xffff; + offsetHight = (offset & 0xffff0000) >> 16; + segmentSelector = selector; + attributes = attr; + } +}; + +uint64 DescInterrupt32::getDescriptor() +{ + uint64 desc = 0; + + desc |= offsetLow; + desc |= (uint32)segmentSelector << 16; + desc |= (uint64)attributes << 40; + desc |= (uint64)offsetHight << 48; + + return desc; +}; + +DescInterrupt32 DescInterrupt32::InterruptKernelLong(uint32 offset, uint16 selector) +{ + return DescInterrupt32( + offset, + selector, + PRESENT_BIT | RING_KERN | INT_GATE_32 + ); +}; + +DescInterrupt32 DescInterrupt32::TrapKernelLong(uint32 offset, uint16 selector) +{ + return DescInterrupt32( + offset, + selector, + PRESENT_BIT | RING_KERN | TRAP_GATE_32 + ); +}; + +DescInterrupt32 DescInterrupt32::TaskKernel(uint16 selector) +{ + return DescInterrupt32( + NULL, + selector, + PRESENT_BIT | RING_KERN | TSK_GATE + ); +}; + +MngIdt::MngIdt() +{ + if(!isInitialize) + { + MemoryOperations::set(idt, 0, sizeof(uint64) * size); + currIdx = NULL; + idtLoaded = false; + isInitialize = true; + } +}; + +bool MngIdt::canDescriptorWrite(uint8 idx) +{ + if(idt[idx] or idtLoaded) return false; + else return true; +}; + +bool MngIdt::addDescriptor(DescInterrupt32 desc) +{ + if(!canDescriptorWrite(currIdx)) return false; + + idt[currIdx++] = desc.getDescriptor(); + return true; +}; + +bool MngIdt::setDescriptor(DescInterrupt32 desc, uint8 idx) +{ + if(!canDescriptorWrite(idx)) return false; + + idt[idx] = desc.getDescriptor(); + return true; +}; + +bool MngIdt::loadIdt() +{ + if(idtLoaded) return false; + + //Set descriptor + uint64 descriptor = 0; + uint16 size = sizeof(uint64) * size - 1; + uint32 offset = (uint32)(&idt); + + descriptor |= offset; + descriptor <<= 16; + descriptor |= size; + + // Load descriptor in LDTR + asm ("lidt %0" :: "m"(descriptor)); + + idtLoaded = true; + return true; +}; + +// Get static instance of MngIdt initialized once +MngIdt &MngIdt::getInstance() +{ + if(!isInitialize) mngIdt = MngIdt(); + return mngIdt; +}; diff --git a/arch/x86/idt/Idt.h b/arch/x86/idt/Idt.h new file mode 100644 index 0000000..c90b674 --- /dev/null +++ b/arch/x86/idt/Idt.h @@ -0,0 +1,63 @@ +#ifndef IDT_H +#define IDT_H + + +#include "../gdt/Gdt.h" +#include <MemoryOperations.h> + +// Defines + +// Attributes +#define TSK_GATE 0x5 +#define INT_GATE_16 0x6 +#define TRAP_GATE_16 0x7 +#define INT_GATE_32 0xe +#define TRAP_GATE_32 0xf +#define PRESENT_BIT 0x80 +#define RING_KERN 0 +#define RING_DRIVERSH 0x20 +#define RING_DRIVERSL 0x40 +#define RING_APP 0x60 + +//-------- + +class DescInterrupt32 +{ + private: + uint16 offsetLow; + uint16 segmentSelector; + uint8 attributes; + uint16 offsetHight; + public: + DescInterrupt32() = default; + DescInterrupt32(const DescInterrupt32 &) = default; + DescInterrupt32(uint32 offset, uint16 selector, uint8 attr); + uint64 getDescriptor(); + static DescInterrupt32 InterruptKernelLong(uint32 offset, + uint16 selector); + static DescInterrupt32 TrapKernelLong(uint32 offset, + uint16 selector); + static DescInterrupt32 TaskKernel(uint16 selector); +}; + +class MngIdt +{ + private: + const static uint8 size = 255; + static uint64 idt[size]; + static bool isInitialize; + static bool idtLoaded; + uint8 currIdx; + public: + MngIdt(); + MngIdt(const MngIdt &) = delete; + bool addDescriptor(DescInterrupt32 desc); + bool setDescriptor(DescInterrupt32 desc, uint8 idx); + bool canDescriptorWrite(uint8 idx); + bool loadIdt(); + static MngIdt &getInstance(); +}; + +extern MngIdt mngIdt; + +#endif |
