Update kernel

This commit is contained in:
Alex
2023-08-06 04:53:14 +03:00
parent 3b65386399
commit 2c51e4432f
181 changed files with 21873 additions and 21475 deletions

View File

@@ -22,197 +22,299 @@
namespace GlobalDescriptorTable
{
struct TaskStateSegmentEntry
{
/* LOW */
uint16_t Limit;
uint16_t BaseLow;
uint8_t BaseMiddle;
union GlobalDescriptorTableAccess
{
struct
{
/** @brief Access bit.
* @note The CPU sets this bit to 1 when the segment is accessed.
*/
uint8_t A : 1;
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;
/** @brief Readable bit for code segments, writable bit for data segments.
* @details For code segments, this bit must be 1 for the segment to be readable.
* @details For data segments, this bit must be 1 for the segment to be writable.
*/
uint8_t RW : 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;
/** @brief Direction bit for data segments, conforming bit for code segments.
* @details For data segments, this bit must be 1 for the segment to grow up (higher addresses).
* @details For code segments, this bit must be 1 for code in the segment to be able to be executed from an equal or lower privilege level.
*/
uint8_t DC : 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;
/** @brief Executable bit.
* @details This bit must be 1 for code-segment descriptors.
* @details This bit must be 0 for data-segment and system descriptors.
*/
uint8_t E : 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;
/** @brief Descriptor type.
* @details This bit must be 0 for system descriptors.
* @details This bit must be 1 for code or data segment descriptor.
*/
uint8_t S : 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;
/** @brief Descriptor privilege level.
* @details This field determines the privilege level of the segment.
* @details 0 = kernel mode, 3 = user mode.
*/
uint8_t DPL : 2;
/**
* Descriptor privilege level.
*
* This field determines the privilege level of the
* segment.
*
* 0 = kernel mode
* 3 = user mode
*/
uint8_t DPL : 2;
/** @brief Present bit.
* @details 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;
/**
* 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
{
uint32_t Reserved0 __aligned(16);
uint64_t StackPointer[3];
uint64_t Reserved1;
uint64_t InterruptStackTable[7];
uint64_t Reserved2;
uint16_t Reserved3;
uint16_t IOMapBaseAddressOffset;
} __packed;
struct TaskStateSegment
{
uint32_t Reserved0 __aligned(16);
uint64_t StackPointer[3];
uint64_t Reserved1;
uint64_t InterruptStackTable[7];
uint64_t Reserved2;
uint16_t Reserved3;
uint16_t IOMapBaseAddressOffset;
} __packed;
struct GlobalDescriptorTableEntry
{
/** @brief Limit 0:15 */
uint16_t Limit0 : 16;
struct GlobalDescriptorTableEntry
{
/**
* Limit 0:15
*/
uint16_t Limit0 : 16;
/** @brief Low Base 0:15 */
uint16_t BaseLow : 16;
/**
* Low Base 0:15
*/
uint16_t BaseLow : 16;
/** @brief Middle Base 16:23 */
uint8_t BaseMiddle : 8;
/**
* Middle Base 16:23
*/
uint8_t BaseMiddle : 8;
/** @brief Access */
union GlobalDescriptorTableAccess
{
struct
{
/** @brief Access bit.
* @note The CPU sets this bit to 1 when the segment is accessed.
*/
uint8_t A : 1;
/**
* Access
*/
union GlobalDescriptorTableAccess
{
struct
{
/**
* Access bit.
*
* @note The CPU sets this bit to 1 when the segment
* is accessed.
*/
uint8_t A : 1;
/** @brief Readable bit for code segments, writable bit for data segments.
* @details For code segments, this bit must be 1 for the segment to be readable.
* @details For data segments, this bit must be 1 for the segment to be writable.
*/
uint8_t RW : 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;
/** @brief Direction bit for data segments, conforming bit for code segments.
* @details For data segments, this bit must be 1 for the segment to grow up (higher addresses).
* @details For code segments, this bit must be 1 for code in the segment to be able to be executed from an equal or lower privilege level.
*/
uint8_t DC : 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;
/** @brief Executable bit.
* @details This bit must be 1 for code-segment descriptors.
* @details This bit must be 0 for data-segment and system descriptors.
*/
uint8_t E : 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;
/** @brief Descriptor type.
* @details This bit must be 0 for system descriptors.
* @details This bit must be 1 for code or data segment descriptor.
*/
uint8_t S : 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;
/** @brief Descriptor privilege level.
* @details This field determines the privilege level of the segment.
* @details 0 = kernel mode, 3 = user mode.
*/
uint8_t DPL : 2;
/**
* Descriptor privilege level.
*
* This field determines the privilege level of the
* segment.
*
* 0 = kernel mode
* 3 = user mode
*/
uint8_t DPL : 2;
/** @brief Present bit.
* @details This bit must be 1 for all valid descriptors.
*/
uint8_t P : 1;
} __packed;
uint8_t Raw : 8;
} Access;
/**
* Present bit.
*
* This bit must be 1 for all valid descriptors.
*/
uint8_t P : 1;
} __packed;
uint8_t Raw : 8;
} Access;
// /** @brief Limit 16:19 */
// uint16_t Limit1 : 4;
// /** Limit 16:19 */
/** @brief Flags */
union GlobalDescriptorTableFlags
{
struct
{
uint8_t Reserved : 4; /* FIXME: Without this, the kernel crashes. */
/** @brief Available bit.
* @details This bit is available for use by system software.
*/
uint8_t AVL : 1;
// uint16_t Limit1 : 4;
/** @brief Long mode.
* @details If the long mode bit is clear, the segment is in 32-bit protected mode.
* @details If the long mode bit is set, the segment is in 64-bit long mode.
*/
uint8_t L : 1;
/**
* Flags
*/
union GlobalDescriptorTableFlags
{
struct
{
/* FIXME: Without this, the kernel crashes. */
uint8_t Reserved : 4;
/** @brief Size flag.
* @details If the size bit is clear, the segment is in 16-bit protected mode.
* @details If the size bit is set, the segment is in 32-bit protected mode.
*/
uint8_t DB : 1;
/**
* Available bit.
*
* This bit is available for use by system software.
*/
uint8_t AVL : 1;
/** @brief Granularity bit.
* @details If the granularity bit is clear, the segment limit is in 1 B blocks.
* @details If the granularity bit is set, the segment limit is in 4 KiB blocks.
*/
uint8_t G : 1;
} __packed;
uint8_t Raw : 8;
} Flags;
/**
* 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;
/** @brief High Base 24:31 */
uint8_t BaseHigh : 8;
} __packed;
/**
* 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;
struct GlobalDescriptorTableEntries
{
GlobalDescriptorTableEntry Null;
GlobalDescriptorTableEntry Code;
GlobalDescriptorTableEntry Data;
GlobalDescriptorTableEntry UserData;
GlobalDescriptorTableEntry UserCode;
TaskStateSegmentEntry TaskStateSegment;
} __packed;
/**
* 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;
struct GlobalDescriptorTableDescriptor
{
/** @brief GDT entries length */
uint16_t Length;
/** @brief GDT entries address */
GlobalDescriptorTableEntries *Entries;
} __packed;
/**
* High Base 24:31
*/
uint8_t BaseHigh : 8;
} __packed;
extern void *CPUStackPointer[];
extern TaskStateSegment tss[];
void Init(int Core);
void SetKernelStack(void *Stack);
void *GetKernelStack();
struct GlobalDescriptorTableEntries
{
GlobalDescriptorTableEntry Null;
GlobalDescriptorTableEntry Code;
GlobalDescriptorTableEntry Data;
GlobalDescriptorTableEntry UserData;
GlobalDescriptorTableEntry UserCode;
TaskStateSegmentEntry TaskStateSegment;
} __packed;
struct GlobalDescriptorTableDescriptor
{
/**
* GDT entries length
*/
uint16_t Length;
/**
* GDT entries address
*/
GlobalDescriptorTableEntries *Entries;
} __packed;
extern void *CPUStackPointer[];
extern TaskStateSegment tss[];
void Init(int Core);
void SetKernelStack(void *Stack);
void *GetKernelStack();
}
#define GDT_KERNEL_CODE offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Code)