/** @file Initialize GDT for Linux. Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "LoadLinuxLib.h" // // Local structure definitions // #pragma pack (1) // // Global Descriptor Entry structures // typedef struct _GDT_ENTRY { UINT16 Limit15_0; UINT16 Base15_0; UINT8 Base23_16; UINT8 Type; UINT8 Limit19_16_and_flags; UINT8 Base31_24; } GDT_ENTRY; typedef struct _GDT_ENTRIES { GDT_ENTRY Null; GDT_ENTRY Null2; GDT_ENTRY Linear; GDT_ENTRY LinearCode; GDT_ENTRY TaskSegment; GDT_ENTRY Spare4; GDT_ENTRY Spare5; } GDT_ENTRIES; #pragma pack () STATIC GDT_ENTRIES *mGdt = NULL; // // Global descriptor table (GDT) Template // STATIC GDT_ENTRIES GdtTemplate = { // // Null // { 0x0, // limit 15:0 0x0, // base 15:0 0x0, // base 23:16 0x0, // type 0x0, // limit 19:16, flags 0x0, // base 31:24 }, // // Null2 // { 0x0, // limit 15:0 0x0, // base 15:0 0x0, // base 23:16 0x0, // type 0x0, // limit 19:16, flags 0x0, // base 31:24 }, // // Linear // { 0x0FFFF, // limit 0xFFFFF 0x0, // base 0 0x0, 0x09A, // present, ring 0, data, expand-up, writable 0x0CF, // page-granular, 32-bit 0x0, }, // // LinearCode // { 0x0FFFF, // limit 0xFFFFF 0x0, // base 0 0x0, 0x092, // present, ring 0, data, expand-up, writable 0x0CF, // page-granular, 32-bit 0x0, }, // // TaskSegment // { 0x0, // limit 0 0x0, // base 0 0x0, 0x089, // ? 0x080, // ? 0x0, }, // // Spare4 // { 0x0, // limit 0 0x0, // base 0 0x0, 0x0, // present, ring 0, data, expand-up, writable 0x0, // page-granular, 32-bit 0x0, }, // // Spare5 // { 0x0, // limit 0 0x0, // base 0 0x0, 0x0, // present, ring 0, data, expand-up, writable 0x0, // page-granular, 32-bit 0x0, }, }; /** Initialize Global Descriptor Table. **/ VOID InitLinuxDescriptorTables ( VOID ) { // // Allocate Runtime Data for the GDT // mGdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8); ASSERT (mGdt != NULL); mGdt = ALIGN_POINTER (mGdt, 8); // // Initialize all GDT entries // CopyMem (mGdt, &GdtTemplate, sizeof (GdtTemplate)); } /** Initialize Global Descriptor Table. **/ VOID SetLinuxDescriptorTables ( VOID ) { IA32_DESCRIPTOR GdtPtr; IA32_DESCRIPTOR IdtPtr; // // Write GDT register // GdtPtr.Base = (UINT32)(UINTN)(VOID*) mGdt; GdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1); AsmWriteGdtr (&GdtPtr); IdtPtr.Base = (UINT32) 0; IdtPtr.Limit = (UINT16) 0; AsmWriteIdtr (&IdtPtr); }