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:
|
||||
qemu-system-i386 -kernel kernel-base.ker
|
||||
qemu-system-i386 -kernel kernel-base.ker -m 64
|
||||
|
||||
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