audk/OvmfPkg/Library/LoadLinuxLib/LinuxGdt.c

176 lines
3.2 KiB
C

/** @file
Initialize GDT for Linux.
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
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);
}