Adds GDT SegmentDescriptors.
This commit is contained in:
parent
dc1166758e
commit
8e247ba638
3 changed files with 96 additions and 1 deletions
|
@ -45,7 +45,7 @@ kernel-base.ker: $(OBJS)
|
||||||
|
|
||||||
|
|
||||||
run:
|
run:
|
||||||
qemu-system-i386 -kernel kernel-base.ker
|
qemu-system-i386 -kernel kernel-base.ker -m 64
|
||||||
|
|
||||||
bnr: kernel-base.ker run
|
bnr: kernel-base.ker run
|
||||||
|
|
||||||
|
|
83
prototypes/base/include/gdt.hpp
Normal file
83
prototypes/base/include/gdt.hpp
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
enum class SegmentAccess : uint8_t
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Accessed = (1 << 0),
|
||||||
|
|
||||||
|
Readable = (1<<1),
|
||||||
|
Writable = (1<<1),
|
||||||
|
|
||||||
|
Direction = (1<<2),
|
||||||
|
Conforming = (1<<2),
|
||||||
|
|
||||||
|
Executable = (1 << 3),
|
||||||
|
Segment = (1 << 4),
|
||||||
|
|
||||||
|
Ring0 = 0,
|
||||||
|
Ring1 = (1<<5),
|
||||||
|
Ring2 = (1<<6),
|
||||||
|
Ring3 = (1<<5) | (1<<6),
|
||||||
|
|
||||||
|
Present = (1 << 7),
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline SegmentAccess operator | (SegmentAccess lhs, SegmentAccess rhs)
|
||||||
|
{
|
||||||
|
return static_cast<SegmentAccess>(static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline SegmentAccess operator & (SegmentAccess lhs, SegmentAccess rhs)
|
||||||
|
{
|
||||||
|
return static_cast<SegmentAccess>(static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SegmentDescriptor
|
||||||
|
{
|
||||||
|
uint16_t limit0;
|
||||||
|
uint16_t base0;
|
||||||
|
uint8_t base1;
|
||||||
|
SegmentAccess access;
|
||||||
|
uint8_t limit1 : 4;
|
||||||
|
uint8_t flags : 4;
|
||||||
|
uint8_t base2;
|
||||||
|
|
||||||
|
uint32_t limit()
|
||||||
|
{
|
||||||
|
return this->limit0 | (this->limit1 << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLimit(uint32_t value)
|
||||||
|
{
|
||||||
|
this->limit0 = (value & 0x0FFFF) >> 0;
|
||||||
|
this->limit1 = (value & 0xFFFFF) >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t base()
|
||||||
|
{
|
||||||
|
return this->base0 | (this->base1 << 16) | (this->base2 << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBase(uint32_t value)
|
||||||
|
{
|
||||||
|
this->base0 = (value & 0x0000FFFF) >> 0;
|
||||||
|
this->base1 = (value & 0x00FF0000) >> 16;
|
||||||
|
this->base2 = (value & 0xFF000000) >> 24;
|
||||||
|
}
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
static_assert(sizeof(SegmentDescriptor) == 8, "SegmentDescriptor must be 8 bytes large.");
|
||||||
|
|
||||||
|
class GDT
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const uint32_t length = 8;
|
||||||
|
private:
|
||||||
|
static SegmentDescriptor descriptors[length];
|
||||||
|
GDT() = delete;
|
||||||
|
public:
|
||||||
|
|
||||||
|
static SegmentDescriptor & descriptor(uint32_t index);
|
||||||
|
};
|
12
prototypes/base/src/gdt.cpp
Normal file
12
prototypes/base/src/gdt.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "gdt.hpp"
|
||||||
|
|
||||||
|
SegmentDescriptor GDT::descriptors[GDT::length];
|
||||||
|
|
||||||
|
SegmentDescriptor & GDT::descriptor(uint32_t index)
|
||||||
|
{
|
||||||
|
static SegmentDescriptor invalid;
|
||||||
|
if(index >= GDT::length) {
|
||||||
|
return invalid;
|
||||||
|
}
|
||||||
|
return GDT::descriptors[index];
|
||||||
|
}
|
Loading…
Reference in a new issue