mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Update GDT & IDT structures
This commit is contained in:
parent
05610c7e7a
commit
622214003f
@ -25,117 +25,84 @@
|
|||||||
namespace GlobalDescriptorTable
|
namespace GlobalDescriptorTable
|
||||||
{
|
{
|
||||||
static GlobalDescriptorTableEntries GDTEntriesTemplate = {
|
static GlobalDescriptorTableEntries GDTEntriesTemplate = {
|
||||||
.Null = {
|
.Null = 0,
|
||||||
.Limit0 = 0x0,
|
|
||||||
.BaseLow = 0x0,
|
|
||||||
.BaseMiddle = 0x0,
|
|
||||||
.Access = {.Raw = 0x0},
|
|
||||||
// .Limit1 = 0x0,
|
|
||||||
.Flags = {.Raw = 0x0},
|
|
||||||
.BaseHigh = 0x0,
|
|
||||||
},
|
|
||||||
|
|
||||||
.Code = {
|
.Code = {
|
||||||
.Limit0 = 0xFFFF,
|
.SegmentLimitLow = 0xFFFF,
|
||||||
.BaseLow = 0x0,
|
.BaseAddressLow = 0x0,
|
||||||
.BaseMiddle = 0x0,
|
.BaseAddressHigh = 0x0,
|
||||||
.Access = {
|
.Accessed = 0,
|
||||||
.A = 0,
|
.Readable = 1,
|
||||||
.RW = 1,
|
.Conforming = 0,
|
||||||
.DC = 0,
|
.Executable = 1,
|
||||||
.E = 1,
|
.Type = 1,
|
||||||
.S = 1,
|
.DescriptorPrivilegeLevel = 0,
|
||||||
.DPL = 0,
|
.Present = 1,
|
||||||
.P = 1,
|
.SegmentLimitHigh = 0xF,
|
||||||
},
|
.Available = 0,
|
||||||
// .Limit1 = 0xF,
|
.Long = 1,
|
||||||
.Flags = {
|
.Default = 0,
|
||||||
.Reserved = 0xF, /* Workaround for Limit1 */
|
.Granularity = 1,
|
||||||
|
.BaseAddressHigher = 0x0,
|
||||||
.AVL = 0,
|
|
||||||
.L = 1,
|
|
||||||
.DB = 0,
|
|
||||||
.G = 1,
|
|
||||||
},
|
|
||||||
.BaseHigh = 0x0,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.Data = {
|
.Data = {
|
||||||
.Limit0 = 0xFFFF,
|
.SegmentLimitLow = 0xFFFF,
|
||||||
.BaseLow = 0x0,
|
.BaseAddressLow = 0x0,
|
||||||
.BaseMiddle = 0x0,
|
.BaseAddressHigh = 0x0,
|
||||||
.Access = {
|
.Accessed = 0,
|
||||||
.A = 0,
|
.Writable = 1,
|
||||||
.RW = 1,
|
.ExpandDown = 0,
|
||||||
.DC = 0,
|
.Executable = 0,
|
||||||
.E = 0,
|
.Type = 1,
|
||||||
.S = 1,
|
.DescriptorPrivilegeLevel = 0,
|
||||||
.DPL = 0,
|
.Present = 1,
|
||||||
.P = 1,
|
.SegmentLimitHigh = 0xF,
|
||||||
},
|
.Available = 0,
|
||||||
// .Limit1 = 0xF,
|
.Reserved = 0,
|
||||||
.Flags = {
|
.Default = 0,
|
||||||
.Reserved = 0xF, /* Workaround for Limit1 */
|
.Granularity = 1,
|
||||||
|
.BaseAddressHigher = 0x0,
|
||||||
.AVL = 0,
|
|
||||||
.L = 0,
|
|
||||||
.DB = 1,
|
|
||||||
.G = 1,
|
|
||||||
},
|
|
||||||
.BaseHigh = 0x0,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.UserData = {
|
.UserData = {
|
||||||
.Limit0 = 0xFFFF,
|
.SegmentLimitLow = 0xFFFF,
|
||||||
.BaseLow = 0x0,
|
.BaseAddressLow = 0x0,
|
||||||
.BaseMiddle = 0x0,
|
.BaseAddressHigh = 0x0,
|
||||||
.Access = {
|
.Accessed = 0,
|
||||||
.A = 0,
|
.Writable = 1,
|
||||||
.RW = 1,
|
.ExpandDown = 1,
|
||||||
.DC = 0,
|
.Executable = 0,
|
||||||
.E = 0,
|
.Type = 1,
|
||||||
.S = 1,
|
.DescriptorPrivilegeLevel = 3,
|
||||||
.DPL = 3,
|
.Present = 1,
|
||||||
.P = 1,
|
.SegmentLimitHigh = 0xF,
|
||||||
},
|
.Available = 0,
|
||||||
// .Limit1 = 0xF,
|
.Reserved = 0,
|
||||||
.Flags = {
|
.Default = 0,
|
||||||
.Reserved = 0xF, /* Workaround for Limit1 */
|
.Granularity = 1,
|
||||||
|
.BaseAddressHigher = 0x0,
|
||||||
.AVL = 0,
|
|
||||||
.L = 0,
|
|
||||||
.DB = 1,
|
|
||||||
.G = 1,
|
|
||||||
},
|
|
||||||
.BaseHigh = 0x0,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.UserCode = {
|
.UserCode = {
|
||||||
.Limit0 = 0xFFFF,
|
.SegmentLimitLow = 0xFFFF,
|
||||||
.BaseLow = 0x0,
|
.BaseAddressLow = 0x0,
|
||||||
.BaseMiddle = 0x0,
|
.BaseAddressHigh = 0x0,
|
||||||
.Access = {
|
.Accessed = 0,
|
||||||
.A = 0,
|
.Readable = 1,
|
||||||
.RW = 1,
|
.Conforming = 0,
|
||||||
.DC = 0,
|
.Executable = 1,
|
||||||
.E = 1,
|
.Type = 1,
|
||||||
.S = 1,
|
.DescriptorPrivilegeLevel = 3,
|
||||||
.DPL = 3,
|
.Present = 1,
|
||||||
.P = 1,
|
.SegmentLimitHigh = 0xF,
|
||||||
},
|
.Available = 0,
|
||||||
// .Limit1 = 0xF,
|
.Long = 1,
|
||||||
.Flags = {
|
.Default = 0,
|
||||||
.Reserved = 0xF, /* Workaround for Limit1 */
|
.Granularity = 1,
|
||||||
|
.BaseAddressHigher = 0x0,
|
||||||
.AVL = 0,
|
|
||||||
.L = 1,
|
|
||||||
.DB = 0,
|
|
||||||
.G = 1,
|
|
||||||
},
|
|
||||||
.BaseHigh = 0x0,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.TaskStateSegment = {},
|
.TaskStateSegment{},
|
||||||
};
|
};
|
||||||
|
|
||||||
GlobalDescriptorTableEntries GDTEntries[MAX_CPU] __aligned(16);
|
GlobalDescriptorTableEntries GDTEntries[MAX_CPU] __aligned(16);
|
||||||
@ -156,48 +123,18 @@ namespace GlobalDescriptorTable
|
|||||||
SafeFunction void Init(int Core)
|
SafeFunction void Init(int Core)
|
||||||
{
|
{
|
||||||
memcpy(&GDTEntries[Core], &GDTEntriesTemplate, sizeof(GlobalDescriptorTableEntries));
|
memcpy(&GDTEntries[Core], &GDTEntriesTemplate, sizeof(GlobalDescriptorTableEntries));
|
||||||
gdt[Core] = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries[Core]};
|
gdt[Core] =
|
||||||
|
{
|
||||||
|
.Limit = sizeof(GlobalDescriptorTableEntries) - 1,
|
||||||
|
.BaseAddress = &GDTEntries[Core],
|
||||||
|
};
|
||||||
|
|
||||||
debug("GDT: %#lx", &gdt[Core]);
|
debug("GDT: %#lx", &gdt[Core]);
|
||||||
debug("GDT KERNEL: CODE %#lx: Limit0: 0x%X, BaseLow: 0x%X, BaseMiddle: 0x%X, Access: 0x%X, Limit1: 0x%X, Flags: 0x%X, BaseHigh: 0x%X",
|
debug("GDT KERNEL CODE %#lx", GDT_KERNEL_CODE);
|
||||||
GDT_KERNEL_CODE,
|
debug("GDT KERNEL DATA %#lx", GDT_KERNEL_DATA);
|
||||||
GDTEntries[Core].Code.Limit0,
|
debug("GDT USER CODE %#lx", GDT_USER_CODE);
|
||||||
GDTEntries[Core].Code.BaseLow,
|
debug("GDT USER DATA %#lx", GDT_USER_DATA);
|
||||||
GDTEntries[Core].Code.BaseMiddle,
|
debug("GDT TSS %#lx", GDT_TSS);
|
||||||
GDTEntries[Core].Code.Access.Raw,
|
|
||||||
GDTEntries[Core].Code.Flags.Reserved,
|
|
||||||
GDTEntries[Core].Code.Flags.Raw & ~0xF,
|
|
||||||
GDTEntries[Core].Code.BaseHigh);
|
|
||||||
|
|
||||||
debug("GDT KERNEL: DATA %#lx: Limit0: 0x%X, BaseLow: 0x%X, BaseMiddle: 0x%X, Access: 0x%X, Limit1: 0x%X, Flags: 0x%X, BaseHigh: 0x%X",
|
|
||||||
GDT_KERNEL_DATA,
|
|
||||||
GDTEntries[Core].Data.Limit0,
|
|
||||||
GDTEntries[Core].Data.BaseLow,
|
|
||||||
GDTEntries[Core].Data.BaseMiddle,
|
|
||||||
GDTEntries[Core].Data.Access.Raw,
|
|
||||||
GDTEntries[Core].Data.Flags.Reserved,
|
|
||||||
GDTEntries[Core].Data.Flags.Raw & ~0xF,
|
|
||||||
GDTEntries[Core].Data.BaseHigh);
|
|
||||||
|
|
||||||
debug("GDT USER: CODE %#lx: Limit0: 0x%X, BaseLow: 0x%X, BaseMiddle: 0x%X, Access: 0x%X, Limit1: 0x%X, Flags: 0x%X, BaseHigh: 0x%X",
|
|
||||||
GDT_USER_CODE,
|
|
||||||
GDTEntries[Core].UserCode.Limit0,
|
|
||||||
GDTEntries[Core].UserCode.BaseLow,
|
|
||||||
GDTEntries[Core].UserCode.BaseMiddle,
|
|
||||||
GDTEntries[Core].UserCode.Access.Raw,
|
|
||||||
GDTEntries[Core].UserCode.Flags.Reserved,
|
|
||||||
GDTEntries[Core].UserCode.Flags.Raw & ~0xF,
|
|
||||||
GDTEntries[Core].UserCode.BaseHigh);
|
|
||||||
|
|
||||||
debug("GDT USER: DATA %#lx: Limit0: 0x%X, BaseLow: 0x%X, BaseMiddle: 0x%X, Access: 0x%X, Limit1: 0x%X, Flags: 0x%X, BaseHigh: 0x%X",
|
|
||||||
GDT_USER_DATA,
|
|
||||||
GDTEntries[Core].UserData.Limit0,
|
|
||||||
GDTEntries[Core].UserData.BaseLow,
|
|
||||||
GDTEntries[Core].UserData.BaseMiddle,
|
|
||||||
GDTEntries[Core].UserData.Access.Raw,
|
|
||||||
GDTEntries[Core].UserData.Flags.Reserved,
|
|
||||||
GDTEntries[Core].UserData.Flags.Raw & ~0xF,
|
|
||||||
GDTEntries[Core].UserData.BaseHigh);
|
|
||||||
|
|
||||||
CPU::x64::lgdt(&gdt[Core]);
|
CPU::x64::lgdt(&gdt[Core]);
|
||||||
|
|
||||||
@ -222,13 +159,22 @@ namespace GlobalDescriptorTable
|
|||||||
|
|
||||||
uintptr_t Base = (uintptr_t)&tss[Core];
|
uintptr_t Base = (uintptr_t)&tss[Core];
|
||||||
size_t Limit = Base + sizeof(TaskStateSegment);
|
size_t Limit = Base + sizeof(TaskStateSegment);
|
||||||
gdt[Core].Entries->TaskStateSegment.Limit = Limit & 0xFFFF;
|
SystemSegmentDescriptor *tssDesc = &gdt[Core].BaseAddress->TaskStateSegment;
|
||||||
gdt[Core].Entries->TaskStateSegment.BaseLow = Base & 0xFFFF;
|
tssDesc->SegmentLimitLow = Limit & 0xFFFF;
|
||||||
gdt[Core].Entries->TaskStateSegment.BaseMiddle = (Base >> 16) & 0xFF;
|
tssDesc->BaseAddressLow = Base & 0xFFFF;
|
||||||
gdt[Core].Entries->TaskStateSegment.BaseHigh = (Base >> 24) & 0xFF;
|
tssDesc->BaseAddressMiddle = (Base >> 16) & 0xFF;
|
||||||
gdt[Core].Entries->TaskStateSegment.BaseUpper = s_cst(uint32_t, (Base >> 32) & 0xFFFFFFFF);
|
tssDesc->Type = AVAILABLE_64BIT_TSS;
|
||||||
gdt[Core].Entries->TaskStateSegment.Access = {.A = 1, .RW = 0, .DC = 0, .E = 1, .S = 0, .DPL = 0, .P = 1};
|
tssDesc->Zero0 = 0;
|
||||||
gdt[Core].Entries->TaskStateSegment.Granularity = (0 << 4) | ((Limit >> 16) & 0xF);
|
tssDesc->DescriptorPrivilegeLevel = 0;
|
||||||
|
tssDesc->Present = 1;
|
||||||
|
tssDesc->Available = 0;
|
||||||
|
tssDesc->Reserved0 = 0;
|
||||||
|
tssDesc->Granularity = 0;
|
||||||
|
tssDesc->BaseAddressHigh = (Base >> 24) & 0xFF;
|
||||||
|
tssDesc->BaseAddressHigher = s_cst(uint32_t, (Base >> 32) & 0xFFFFFFFF);
|
||||||
|
tssDesc->Reserved1 = 0;
|
||||||
|
tssDesc->Zero1 = 0;
|
||||||
|
tssDesc->Reserved2 = 0;
|
||||||
|
|
||||||
tss[Core].IOMapBaseAddressOffset = sizeof(TaskStateSegment);
|
tss[Core].IOMapBaseAddressOffset = sizeof(TaskStateSegment);
|
||||||
tss[Core].StackPointer[0] = (uint64_t)CPUStackPointer[Core] + STACK_SIZE;
|
tss[Core].StackPointer[0] = (uint64_t)CPUStackPointer[Core] + STACK_SIZE;
|
||||||
|
@ -19,100 +19,10 @@
|
|||||||
#define __FENNIX_KERNEL_GDT_H__
|
#define __FENNIX_KERNEL_GDT_H__
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
#include <cpu/x86/x64/SegmentDescriptors.hpp>
|
||||||
|
|
||||||
namespace GlobalDescriptorTable
|
namespace GlobalDescriptorTable
|
||||||
{
|
{
|
||||||
struct TaskStateSegmentEntry
|
|
||||||
{
|
|
||||||
/* LOW */
|
|
||||||
uint16_t Limit;
|
|
||||||
uint16_t BaseLow;
|
|
||||||
uint8_t BaseMiddle;
|
|
||||||
union GlobalDescriptorTableAccess
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Access bit.
|
|
||||||
*
|
|
||||||
* @note The CPU sets this bit to 1 when the segment
|
|
||||||
* is accessed.
|
|
||||||
*/
|
|
||||||
uint8_t A : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Readable bit for code segments, writable bit for data
|
|
||||||
* segments.
|
|
||||||
*
|
|
||||||
* Code Segment:
|
|
||||||
* This bit must be 1 for the segment to be readable.
|
|
||||||
*
|
|
||||||
* Data Segment:
|
|
||||||
* This bit must be 1 for the segment to be writable.
|
|
||||||
*/
|
|
||||||
uint8_t RW : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Direction bit for data segments, conforming bit for
|
|
||||||
* code segments.
|
|
||||||
*
|
|
||||||
* Code Segment:
|
|
||||||
* This bit must be 1 for code in the segment to be
|
|
||||||
* able to be executed from an equal or lower privilege
|
|
||||||
* level.
|
|
||||||
*
|
|
||||||
* Data Segment:
|
|
||||||
* This bit must be 1 for the segment to grow up (higher
|
|
||||||
* addresses).
|
|
||||||
*/
|
|
||||||
uint8_t DC : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executable bit.
|
|
||||||
*
|
|
||||||
* This bit must be 1 for code-segment descriptors.
|
|
||||||
*
|
|
||||||
* This bit must be 0 for data-segment and system
|
|
||||||
* descriptors.
|
|
||||||
*/
|
|
||||||
uint8_t E : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Descriptor type.
|
|
||||||
*
|
|
||||||
* This bit must be 0 for system descriptors.
|
|
||||||
*
|
|
||||||
* This bit must be 1 for code or data segment
|
|
||||||
* descriptor.
|
|
||||||
*/
|
|
||||||
uint8_t S : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Descriptor privilege level.
|
|
||||||
*
|
|
||||||
* This field determines the privilege level of the
|
|
||||||
* segment.
|
|
||||||
*
|
|
||||||
* 0 = kernel mode
|
|
||||||
* 3 = user mode
|
|
||||||
*/
|
|
||||||
uint8_t DPL : 2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Present bit.
|
|
||||||
*
|
|
||||||
* This bit must be 1 for all valid descriptors.
|
|
||||||
*/
|
|
||||||
uint8_t P : 1;
|
|
||||||
} __packed;
|
|
||||||
uint8_t Raw : 8;
|
|
||||||
} Access;
|
|
||||||
uint8_t Granularity;
|
|
||||||
uint8_t BaseHigh;
|
|
||||||
/* HIGH */
|
|
||||||
uint32_t BaseUpper;
|
|
||||||
uint32_t Reserved;
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct TaskStateSegment
|
struct TaskStateSegment
|
||||||
{
|
{
|
||||||
@ -125,189 +35,20 @@ namespace GlobalDescriptorTable
|
|||||||
uint16_t IOMapBaseAddressOffset;
|
uint16_t IOMapBaseAddressOffset;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct GlobalDescriptorTableEntry
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Limit 0:15
|
|
||||||
*/
|
|
||||||
uint16_t Limit0 : 16;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Low Base 0:15
|
|
||||||
*/
|
|
||||||
uint16_t BaseLow : 16;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Middle Base 16:23
|
|
||||||
*/
|
|
||||||
uint8_t BaseMiddle : 8;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Access
|
|
||||||
*/
|
|
||||||
union GlobalDescriptorTableAccess
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Access bit.
|
|
||||||
*
|
|
||||||
* @note The CPU sets this bit to 1 when the segment
|
|
||||||
* is accessed.
|
|
||||||
*/
|
|
||||||
uint8_t A : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Readable bit for code segments, writable bit for
|
|
||||||
* data segments.
|
|
||||||
*
|
|
||||||
* Code Segment:
|
|
||||||
* This bit must be 1 for the segment to be readable.
|
|
||||||
*
|
|
||||||
* Data Segment:
|
|
||||||
* This bit must be 1 for the segment to be writable.
|
|
||||||
*/
|
|
||||||
uint8_t RW : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Direction bit for data segments, conforming bit for
|
|
||||||
* code segments.
|
|
||||||
*
|
|
||||||
* Code Segment:
|
|
||||||
* This bit must be 1 for code in the segment to be able
|
|
||||||
* to be executed from an equal or lower privilege level.
|
|
||||||
*
|
|
||||||
* Data Segment:
|
|
||||||
* This bit must be 1 for the segment to grow up (higher
|
|
||||||
* addresses).
|
|
||||||
*/
|
|
||||||
uint8_t DC : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executable bit.
|
|
||||||
*
|
|
||||||
* This bit must be 1 for code-segment descriptors.
|
|
||||||
*
|
|
||||||
* This bit must be 0 for data-segment and
|
|
||||||
* system descriptors.
|
|
||||||
*/
|
|
||||||
uint8_t E : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Descriptor type.
|
|
||||||
*
|
|
||||||
* This bit must be 0 for system descriptors.
|
|
||||||
*
|
|
||||||
* This bit must be 1 for code or data segment
|
|
||||||
* descriptor.
|
|
||||||
*/
|
|
||||||
uint8_t S : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Descriptor privilege level.
|
|
||||||
*
|
|
||||||
* This field determines the privilege level of the
|
|
||||||
* segment.
|
|
||||||
*
|
|
||||||
* 0 = kernel mode
|
|
||||||
* 3 = user mode
|
|
||||||
*/
|
|
||||||
uint8_t DPL : 2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Present bit.
|
|
||||||
*
|
|
||||||
* This bit must be 1 for all valid descriptors.
|
|
||||||
*/
|
|
||||||
uint8_t P : 1;
|
|
||||||
} __packed;
|
|
||||||
uint8_t Raw : 8;
|
|
||||||
} Access;
|
|
||||||
|
|
||||||
// /** Limit 16:19 */
|
|
||||||
|
|
||||||
// uint16_t Limit1 : 4;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flags
|
|
||||||
*/
|
|
||||||
union GlobalDescriptorTableFlags
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
/* FIXME: Without this, the kernel crashes. */
|
|
||||||
uint8_t Reserved : 4;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Available bit.
|
|
||||||
*
|
|
||||||
* This bit is available for use by system software.
|
|
||||||
*/
|
|
||||||
uint8_t AVL : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Long mode.
|
|
||||||
*
|
|
||||||
* If the long mode bit is clear, the segment is in
|
|
||||||
* 32-bit protected mode.
|
|
||||||
*
|
|
||||||
* If the long mode bit is set, the segment is in
|
|
||||||
* 64-bit long mode.
|
|
||||||
*/
|
|
||||||
uint8_t L : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Size flag.
|
|
||||||
*
|
|
||||||
* If the size bit is clear, the segment is in
|
|
||||||
* 16-bit protected mode.
|
|
||||||
*
|
|
||||||
* If the size bit is set, the segment is in
|
|
||||||
* 32-bit protected mode.
|
|
||||||
*/
|
|
||||||
uint8_t DB : 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Granularity bit.
|
|
||||||
*
|
|
||||||
* If the granularity bit is clear, the segment limit
|
|
||||||
* is in 1 B blocks.
|
|
||||||
*
|
|
||||||
* If the granularity bit is set, the segment limit is
|
|
||||||
* in 4 KiB blocks.
|
|
||||||
*/
|
|
||||||
uint8_t G : 1;
|
|
||||||
} __packed;
|
|
||||||
uint8_t Raw : 8;
|
|
||||||
} Flags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* High Base 24:31
|
|
||||||
*/
|
|
||||||
uint8_t BaseHigh : 8;
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct GlobalDescriptorTableEntries
|
struct GlobalDescriptorTableEntries
|
||||||
{
|
{
|
||||||
GlobalDescriptorTableEntry Null;
|
uint64_t Null;
|
||||||
GlobalDescriptorTableEntry Code;
|
CodeSegmentDescriptor Code;
|
||||||
GlobalDescriptorTableEntry Data;
|
DataSegmentDescriptor Data;
|
||||||
GlobalDescriptorTableEntry UserData;
|
DataSegmentDescriptor UserData;
|
||||||
GlobalDescriptorTableEntry UserCode;
|
CodeSegmentDescriptor UserCode;
|
||||||
TaskStateSegmentEntry TaskStateSegment;
|
SystemSegmentDescriptor TaskStateSegment;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct GlobalDescriptorTableDescriptor
|
struct GlobalDescriptorTableDescriptor
|
||||||
{
|
{
|
||||||
/**
|
uint16_t Limit;
|
||||||
* GDT entries length
|
GlobalDescriptorTableEntries *BaseAddress;
|
||||||
*/
|
|
||||||
uint16_t Length;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GDT entries address
|
|
||||||
*/
|
|
||||||
GlobalDescriptorTableEntries *Entries;
|
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
extern void *CPUStackPointer[];
|
extern void *CPUStackPointer[];
|
||||||
|
@ -19,109 +19,10 @@
|
|||||||
#define __FENNIX_KERNEL_IDT_H__
|
#define __FENNIX_KERNEL_IDT_H__
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
#include <cpu/x86/x64/SegmentDescriptors.hpp>
|
||||||
|
|
||||||
namespace InterruptDescriptorTable
|
namespace InterruptDescriptorTable
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Manual: AMD Architecture Programmer's Manual Volume 2: System Programming
|
|
||||||
* Subsection: 4.8.3 System Descriptors
|
|
||||||
* Table: 4-6
|
|
||||||
*
|
|
||||||
* @note Reserved values are not listed in the table.
|
|
||||||
*/
|
|
||||||
enum GateType
|
|
||||||
{
|
|
||||||
LDT_64BIT = 0b0010,
|
|
||||||
AVAILABLE_64BIT_TSS = 0b1001,
|
|
||||||
BUSY_64BIT_TSS = 0b1011,
|
|
||||||
CALL_GATE_64BIT = 0b1100,
|
|
||||||
INTERRUPT_GATE_64BIT = 0b1110,
|
|
||||||
TRAP_GATE_64BIT = 0b1111,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum PrivilegeLevelType
|
|
||||||
{
|
|
||||||
RING0 = 0b0,
|
|
||||||
RING1 = 0b1,
|
|
||||||
RING2 = 0b10,
|
|
||||||
RING3 = 0b11,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum InterruptStackTableType
|
|
||||||
{
|
|
||||||
IST0 = 0b0,
|
|
||||||
IST1 = 0b1,
|
|
||||||
IST2 = 0b10,
|
|
||||||
IST3 = 0b11,
|
|
||||||
IST4 = 0b100,
|
|
||||||
IST5 = 0b101,
|
|
||||||
IST6 = 0b110,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InterruptGate
|
|
||||||
{
|
|
||||||
/* +0 */
|
|
||||||
uint64_t TargetOffsetLow : 16;
|
|
||||||
uint64_t TargetSelector : 16;
|
|
||||||
/* +4 */
|
|
||||||
uint64_t InterruptStackTable : 3;
|
|
||||||
uint64_t Reserved0 : 5;
|
|
||||||
uint64_t Type : 4;
|
|
||||||
uint64_t Zero : 1;
|
|
||||||
uint64_t DescriptorPrivilegeLevel : 2;
|
|
||||||
uint64_t Present : 1;
|
|
||||||
uint64_t TargetOffsetMiddle : 16;
|
|
||||||
/* +8 */
|
|
||||||
uint64_t TargetOffsetHigh : 32;
|
|
||||||
/* +12 */
|
|
||||||
uint64_t Reserved1 : 32;
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
typedef InterruptGate TrapGate;
|
|
||||||
|
|
||||||
struct CallGate
|
|
||||||
{
|
|
||||||
/* +0 */
|
|
||||||
uint64_t TargetOffsetLow : 16;
|
|
||||||
uint64_t TargetSelector : 16;
|
|
||||||
/* +4 */
|
|
||||||
uint64_t Reserved0 : 8;
|
|
||||||
uint64_t Type : 4;
|
|
||||||
uint64_t Zero0 : 1;
|
|
||||||
uint64_t DescriptorPrivilegeLevel : 2;
|
|
||||||
uint64_t Present : 1;
|
|
||||||
uint64_t TargetOffsetMiddle : 16;
|
|
||||||
/* +8 */
|
|
||||||
uint64_t TargetOffsetHigh : 32;
|
|
||||||
/* +12 */
|
|
||||||
uint64_t Reserved1 : 8;
|
|
||||||
uint64_t Zero1 : 5;
|
|
||||||
uint64_t Reserved2 : 19;
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
struct SystemSegmentDescriptor
|
|
||||||
{
|
|
||||||
/* +0 */
|
|
||||||
uint64_t SegmentLimitLow : 16;
|
|
||||||
uint64_t BaseAddressLow : 16;
|
|
||||||
/* +4 */
|
|
||||||
uint64_t BaseAddressMiddle : 8;
|
|
||||||
uint64_t Type : 4;
|
|
||||||
uint64_t Zero0 : 1;
|
|
||||||
uint64_t DescriptorPrivilegeLevel : 2;
|
|
||||||
uint64_t Present : 1;
|
|
||||||
uint64_t SegmentLimitMiddle : 4;
|
|
||||||
uint64_t Available : 1;
|
|
||||||
uint64_t Reserved0 : 2;
|
|
||||||
uint64_t Granularity : 1;
|
|
||||||
uint64_t BaseAddressHigh : 8;
|
|
||||||
/* +8 */
|
|
||||||
uint64_t BaseAddressHigher : 32;
|
|
||||||
/* +12 */
|
|
||||||
uint64_t Reserved1 : 8;
|
|
||||||
uint64_t Zero1 : 5;
|
|
||||||
uint64_t Reserved2 : 19;
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
union IDTGateDescriptor
|
union IDTGateDescriptor
|
||||||
{
|
{
|
||||||
|
168
include/cpu/x86/x64/SegmentDescriptors.hpp
Normal file
168
include/cpu/x86/x64/SegmentDescriptors.hpp
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Fennix Kernel.
|
||||||
|
|
||||||
|
Fennix Kernel is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
Fennix Kernel is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FENNIX_KERNEL_SEGMENT_DESCRIPTORS_H__
|
||||||
|
#define __FENNIX_KERNEL_SEGMENT_DESCRIPTORS_H__
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manual: AMD Architecture Programmer's Manual Volume 2: System Programming
|
||||||
|
* Subsection: 4.8.3 System Descriptors
|
||||||
|
* Table: 4-6
|
||||||
|
*
|
||||||
|
* @note Reserved values are not listed in the table.
|
||||||
|
*/
|
||||||
|
enum GateType
|
||||||
|
{
|
||||||
|
LDT_64BIT = 0b0010,
|
||||||
|
AVAILABLE_64BIT_TSS = 0b1001,
|
||||||
|
BUSY_64BIT_TSS = 0b1011,
|
||||||
|
CALL_GATE_64BIT = 0b1100,
|
||||||
|
INTERRUPT_GATE_64BIT = 0b1110,
|
||||||
|
TRAP_GATE_64BIT = 0b1111,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PrivilegeLevelType
|
||||||
|
{
|
||||||
|
RING0 = 0b0,
|
||||||
|
RING1 = 0b1,
|
||||||
|
RING2 = 0b10,
|
||||||
|
RING3 = 0b11,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum InterruptStackTableType
|
||||||
|
{
|
||||||
|
IST0 = 0b0,
|
||||||
|
IST1 = 0b1,
|
||||||
|
IST2 = 0b10,
|
||||||
|
IST3 = 0b11,
|
||||||
|
IST4 = 0b100,
|
||||||
|
IST5 = 0b101,
|
||||||
|
IST6 = 0b110,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InterruptGate
|
||||||
|
{
|
||||||
|
/* +0 */
|
||||||
|
uint64_t TargetOffsetLow : 16;
|
||||||
|
uint64_t TargetSelector : 16;
|
||||||
|
/* +4 */
|
||||||
|
uint64_t InterruptStackTable : 3;
|
||||||
|
uint64_t Reserved0 : 5;
|
||||||
|
uint64_t Type : 4;
|
||||||
|
uint64_t Zero : 1;
|
||||||
|
uint64_t DescriptorPrivilegeLevel : 2;
|
||||||
|
uint64_t Present : 1;
|
||||||
|
uint64_t TargetOffsetMiddle : 16;
|
||||||
|
/* +8 */
|
||||||
|
uint64_t TargetOffsetHigh : 32;
|
||||||
|
/* +12 */
|
||||||
|
uint64_t Reserved1 : 32;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
typedef InterruptGate TrapGate;
|
||||||
|
|
||||||
|
struct CallGate
|
||||||
|
{
|
||||||
|
/* +0 */
|
||||||
|
uint64_t TargetOffsetLow : 16;
|
||||||
|
uint64_t TargetSelector : 16;
|
||||||
|
/* +4 */
|
||||||
|
uint64_t Reserved0 : 8;
|
||||||
|
uint64_t Type : 4;
|
||||||
|
uint64_t Zero0 : 1;
|
||||||
|
uint64_t DescriptorPrivilegeLevel : 2;
|
||||||
|
uint64_t Present : 1;
|
||||||
|
uint64_t TargetOffsetMiddle : 16;
|
||||||
|
/* +8 */
|
||||||
|
uint64_t TargetOffsetHigh : 32;
|
||||||
|
/* +12 */
|
||||||
|
uint64_t Reserved1 : 8;
|
||||||
|
uint64_t Zero1 : 5;
|
||||||
|
uint64_t Reserved2 : 19;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct SystemSegmentDescriptor
|
||||||
|
{
|
||||||
|
/* +0 */
|
||||||
|
uint64_t SegmentLimitLow : 16;
|
||||||
|
uint64_t BaseAddressLow : 16;
|
||||||
|
/* +4 */
|
||||||
|
uint64_t BaseAddressMiddle : 8;
|
||||||
|
uint64_t Type : 4;
|
||||||
|
uint64_t Zero0 : 1;
|
||||||
|
uint64_t DescriptorPrivilegeLevel : 2;
|
||||||
|
uint64_t Present : 1;
|
||||||
|
uint64_t SegmentLimitMiddle : 4;
|
||||||
|
uint64_t Available : 1;
|
||||||
|
uint64_t Reserved0 : 2;
|
||||||
|
uint64_t Granularity : 1;
|
||||||
|
uint64_t BaseAddressHigh : 8;
|
||||||
|
/* +8 */
|
||||||
|
uint64_t BaseAddressHigher : 32;
|
||||||
|
/* +12 */
|
||||||
|
uint64_t Reserved1 : 8;
|
||||||
|
uint64_t Zero1 : 5;
|
||||||
|
uint64_t Reserved2 : 19;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct CodeSegmentDescriptor
|
||||||
|
{
|
||||||
|
/* +0 */
|
||||||
|
uint64_t SegmentLimitLow : 16;
|
||||||
|
uint64_t BaseAddressLow : 16;
|
||||||
|
/* +4 */
|
||||||
|
uint64_t BaseAddressHigh : 8;
|
||||||
|
uint64_t Accessed : 1;
|
||||||
|
uint64_t Readable : 1;
|
||||||
|
uint64_t Conforming : 1;
|
||||||
|
uint64_t Executable : 1;
|
||||||
|
uint64_t Type : 1;
|
||||||
|
uint64_t DescriptorPrivilegeLevel : 2;
|
||||||
|
uint64_t Present : 1;
|
||||||
|
uint64_t SegmentLimitHigh : 4;
|
||||||
|
uint64_t Available : 1;
|
||||||
|
uint64_t Long : 1;
|
||||||
|
uint64_t Default : 1;
|
||||||
|
uint64_t Granularity : 1;
|
||||||
|
uint64_t BaseAddressHigher : 8;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct DataSegmentDescriptor
|
||||||
|
{
|
||||||
|
/* +0 */
|
||||||
|
uint64_t SegmentLimitLow : 16;
|
||||||
|
uint64_t BaseAddressLow : 16;
|
||||||
|
/* +4 */
|
||||||
|
uint64_t BaseAddressHigh : 8;
|
||||||
|
uint64_t Accessed : 1;
|
||||||
|
uint64_t Writable : 1;
|
||||||
|
uint64_t ExpandDown : 1;
|
||||||
|
uint64_t Executable : 1;
|
||||||
|
uint64_t Type : 1;
|
||||||
|
uint64_t DescriptorPrivilegeLevel : 2;
|
||||||
|
uint64_t Present : 1;
|
||||||
|
uint64_t SegmentLimitHigh : 4;
|
||||||
|
uint64_t Available : 1;
|
||||||
|
uint64_t Reserved : 1;
|
||||||
|
uint64_t Default : 1;
|
||||||
|
uint64_t Granularity : 1;
|
||||||
|
uint64_t BaseAddressHigher : 8;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
#endif // !__FENNIX_KERNEL_SEGMENT_DESCRIPTORS_H__
|
Loading…
x
Reference in New Issue
Block a user