summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAlexey Gavrilov <rebovas@yahoo.com>2024-03-31 14:39:51 +0700
committerAlexey Gavrilov <rebovas@yahoo.com>2024-03-31 14:39:51 +0700
commit49cfee4e370892df8404e56d53b04dde196f82f2 (patch)
treed309b630a161823c79dab9a48f67a41a40d76b24 /arch
parenta276644952ed018e77ca64181059434a6bc4ee62 (diff)
IDT + uintptr update
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/PrimaryInit.cpp17
-rw-r--r--arch/x86/PrimaryInit.h1
-rwxr-xr-xarch/x86/gdt/Gdt.cpp60
-rwxr-xr-xarch/x86/gdt/Gdt.h27
-rw-r--r--arch/x86/idt/Idt.cpp130
-rw-r--r--arch/x86/idt/Idt.h63
6 files changed, 259 insertions, 39 deletions
diff --git a/arch/x86/PrimaryInit.cpp b/arch/x86/PrimaryInit.cpp
index 7de690e..5359978 100644
--- a/arch/x86/PrimaryInit.cpp
+++ b/arch/x86/PrimaryInit.cpp
@@ -1,13 +1,28 @@
#include "PrimaryInit.h"
+#include "idt/Idt.h"
+// Function to test idt work. Should remove
+void isr()
+{
+ out::display << "The kernel has finished" << '\n';
+};
+
void PrimaryInitialization::processorInitialize()
{
- MngGdt mngGdt = MngGdt();
+ MngIdt &mngIdt = MngIdt::getInstance();
+ MngGdt &mngGdt = MngGdt::getInstance();
mngGdt.addDescriptor(DescSeg32::flatCodeKernel());
mngGdt.addDescriptor(DescSeg32::flatDataKernel());
mngGdt.loadGdt();
+
+ mngIdt.setDescriptor(
+ DescInterrupt32::InterruptKernelLong(
+ (uint32)isr,
+ mngGdt.getCodeSegmentKernel()),
+ 0x20);
+ mngIdt.loadIdt();
};
void PrimaryInitialization::devicesInitialize()
diff --git a/arch/x86/PrimaryInit.h b/arch/x86/PrimaryInit.h
index 243c731..540ad41 100644
--- a/arch/x86/PrimaryInit.h
+++ b/arch/x86/PrimaryInit.h
@@ -1,5 +1,6 @@
#include "gdt/Gdt.h"
#include "io/VGADisplay.h"
+#include "idt/Idt.h"
class PrimaryInitialization
diff --git a/arch/x86/gdt/Gdt.cpp b/arch/x86/gdt/Gdt.cpp
index 21941b4..70f30cd 100755
--- a/arch/x86/gdt/Gdt.cpp
+++ b/arch/x86/gdt/Gdt.cpp
@@ -2,6 +2,21 @@
uint64 MngGdt::gdt[MngGdt::size];
+bool MngGdt::isInitialize = false;
+bool MngGdt::gdtLoaded = false;
+MngGdt mngGdt;
+
+MngGdt::MngGdt()
+{
+ if(!isInitialize)
+ {
+ MemoryOperations::set(gdt, 0, sizeof(uint64) * size);
+ currIdx = 1;
+ gdtLoaded = false;
+ isInitialize = true;
+ codeSegmentKern = NULL;
+ }
+};
DescSeg32::DescSeg32(uint32 base, uint32 limit, uint8 access, uint8 flags)
{
@@ -57,59 +72,48 @@ uint64 DescSeg32::flatDataUser()
, PAGEGRAN | HIGHSIZE).getDescriptor();
};
-MngGdt::MngGdt()
-{
- gdt[0] = 0;
- currIdx = 1;
- isGdtLoaded = 0;
-};
-
bool MngGdt::addDescriptor(uint64 desc)
{
- if(currIdx >= size || currIdx == 0)
+ if(currIdx >= size or currIdx == 0 or gdtLoaded)
{
return false;
}
+ if(desc == DescSeg32::flatCodeKernel()) codeSegmentKern = currIdx * 8;
this->gdt[currIdx++] = desc;
return true;
};
bool MngGdt::loadGdt()
{
- if(isGdtLoaded)
+ if(gdtLoaded)
{
return false;
}
- uint64 pointer = 0;
+ // Set pointer
+ uint64 descriptor = 0;
uint16 size = sizeof(uint64) * this->size - 1;
- uint32 offset = (uint32)((void *)(&gdt));
+ uint32 offset = (uint32)(&gdt);
- pointer |= offset;
- pointer <<= 16;
- pointer |= size;
+ descriptor |= offset;
+ descriptor <<= 16;
+ descriptor |= size;
- SWITCHTOGDT(pointer);
+ SWITCHTOGDT(descriptor);
- isGdtLoaded = 1;
+ gdtLoaded = 1;
return true;
};
-bool MngGdt::getIsGdtLoaded()
+// Get static instance of MngGdt initialized once
+MngGdt &MngGdt::getInstance()
{
- return isGdtLoaded;
+ if(!isInitialize) mngGdt = MngGdt();
+ return mngGdt;
};
-void MngGdt::operator=(const MngGdt& src)
+uint16 MngGdt::getCodeSegmentKernel()
{
- if(this->isGdtLoaded == 1 || src.isGdtLoaded == 1)
- {
- return;
- }
-
- // Fix it. Write method to copy from ... to ...
- for(int i = 0; i < this->size; i++) this->gdt[i] = src.gdt[i];
- this->isGdtLoaded = src.isGdtLoaded;
- this->currIdx = src.currIdx;
+ return codeSegmentKern;
};
diff --git a/arch/x86/gdt/Gdt.h b/arch/x86/gdt/Gdt.h
index 6667d93..321d67c 100755
--- a/arch/x86/gdt/Gdt.h
+++ b/arch/x86/gdt/Gdt.h
@@ -2,6 +2,7 @@
#define GDT_H
#include <types.h>
+#include <MemoryOperations.h>
// Define access options
@@ -59,7 +60,7 @@ class DescSeg32 // Segment descriptor
#ifdef __cplusplus
extern "C" {
#endif
-extern void SWITCHTOGDT(uint64 pointer);
+extern void SWITCHTOGDT(uint64 descriptor);
#ifdef __cplusplus
};
#endif
@@ -67,17 +68,23 @@ extern void SWITCHTOGDT(uint64 pointer);
class MngGdt
{
private:
- const static uint8 size = 10;
- static uint64 gdt[size];
- uint8 currIdx;
- bool isGdtLoaded;
+ const static uint8 size = 10;
+ static uint64 gdt[size];
+ static bool isInitialize;
+ static bool gdtLoaded;
+ uint16 codeSegmentKern;
+ uint8 currIdx;
+ MngGdt &operator=(const MngGdt &) = default;
public:
- MngGdt();
- void operator=(const MngGdt& src);
- bool addDescriptor(uint64 desc); // 0 - not set descriptor, 1 - set
- bool loadGdt(); // 0 - if GDT is not loaded, 1 - loaded
- bool getIsGdtLoaded();
+ MngGdt();
+ MngGdt(const MngGdt &) = delete;
+ bool addDescriptor(uint64 desc); // 0 - not set descriptor, 1 - set
+ bool loadGdt(); // 0 - if GDT is not loaded, 1 - loaded
+ uint16 getCodeSegmentKernel();
+ static MngGdt &getInstance();
};
+extern MngGdt mngGdt;
+
#endif
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