/** @file | |
Initialize GDT for Linux. | |
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> | |
This program and the accompanying materials | |
are licensed and made available under the terms and conditions of the BSD License | |
which accompanies this distribution. The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
**/ | |
#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); | |
} | |