summaryrefslogtreecommitdiffstats
path: root/arch/x86/idt
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/idt')
-rw-r--r--arch/x86/idt/Idt.cpp130
-rw-r--r--arch/x86/idt/Idt.h63
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