/** @file\r
- C based implemention of IA32 interrupt handling only\r
+ C based implementation of IA32 interrupt handling only\r
requiring a minimal assembly interrupt entry point.\r
\r
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
//\r
// Global descriptor table (GDT) Template\r
//\r
-STATIC GDT_ENTRIES GdtTemplate = {\r
+STATIC GDT_ENTRIES mGdtTemplate = {\r
//\r
// NULL_SEL\r
//\r
// LINEAR_SEL\r
//\r
{\r
- 0x0FFFF, // limit 0xFFFFF\r
- 0x0, // base 0\r
- 0x0,\r
- 0x092, // present, ring 0, data, expand-up, writable\r
+ 0x0FFFF, // limit 15:0\r
+ 0x0, // base 15:0\r
+ 0x0, // base 23:16\r
+ 0x092, // present, ring 0, data, read/write\r
0x0CF, // page-granular, 32-bit\r
0x0,\r
},\r
// LINEAR_CODE_SEL\r
//\r
{\r
- 0x0FFFF, // limit 0xFFFFF\r
- 0x0, // base 0\r
- 0x0,\r
- 0x09A, // present, ring 0, data, expand-up, writable\r
+ 0x0FFFF, // limit 15:0\r
+ 0x0, // base 15:0\r
+ 0x0, // base 23:16\r
+ 0x09F, // present, ring 0, code, execute/read, conforming, accessed\r
0x0CF, // page-granular, 32-bit\r
0x0,\r
},\r
// SYS_DATA_SEL\r
//\r
{\r
- 0x0FFFF, // limit 0xFFFFF\r
- 0x0, // base 0\r
- 0x0,\r
- 0x092, // present, ring 0, data, expand-up, writable\r
+ 0x0FFFF, // limit 15:0\r
+ 0x0, // base 15:0\r
+ 0x0, // base 23:16\r
+ 0x093, // present, ring 0, data, read/write, accessed\r
0x0CF, // page-granular, 32-bit\r
0x0,\r
},\r
// SYS_CODE_SEL\r
//\r
{\r
- 0x0FFFF, // limit 0xFFFFF\r
- 0x0, // base 0\r
- 0x0,\r
- 0x09A, // present, ring 0, data, expand-up, writable\r
+ 0x0FFFF, // limit 15:0\r
+ 0x0, // base 15:0\r
+ 0x0, // base 23:16\r
+ 0x09A, // present, ring 0, code, execute/read\r
0x0CF, // page-granular, 32-bit\r
0x0,\r
},\r
//\r
- // LINEAR_CODE64_SEL\r
+ // SYS_CODE16_SEL\r
//\r
{\r
- 0x0FFFF, // limit 0xFFFFF\r
- 0x0, // base 0\r
- 0x0,\r
- 0x09B, // present, ring 0, code, expand-up, writable\r
- 0x0AF, // LimitHigh (CS.L=1, CS.D=0)\r
- 0x0, // base (high)\r
+ 0x0FFFF, // limit 15:0\r
+ 0x0, // base 15:0\r
+ 0x0, // base 23:16\r
+ 0x09A, // present, ring 0, code, execute/read\r
+ 0x08F, // page-granular, 16-bit\r
+ 0x0, // base 31:24\r
},\r
//\r
- // SPARE4_SEL\r
+ // LINEAR_DATA64_SEL\r
//\r
{\r
- 0x0, // limit 0\r
- 0x0, // base 0\r
- 0x0,\r
- 0x0, // present, ring 0, data, expand-up, writable\r
- 0x0, // page-granular, 32-bit\r
+ 0x0FFFF, // limit 15:0\r
+ 0x0, // base 15:0\r
+ 0x0, // base 23:16\r
+ 0x092, // present, ring 0, data, read/write\r
+ 0x0CF, // page-granular, 32-bit\r
0x0,\r
},\r
//\r
+ // LINEAR_CODE64_SEL\r
+ //\r
+ {\r
+ 0x0FFFF, // limit 15:0\r
+ 0x0, // base 15:0\r
+ 0x0, // base 23:16\r
+ 0x09A, // present, ring 0, code, execute/read\r
+ 0x0AF, // page-granular, 64-bit code\r
+ 0x0, // base (high)\r
+ },\r
+ //\r
// SPARE5_SEL\r
//\r
{\r
- 0x0, // limit 0\r
- 0x0, // base 0\r
- 0x0,\r
- 0x0, // present, ring 0, data, expand-up, writable\r
- 0x0, // page-granular, 32-bit\r
- 0x0,\r
+ 0x0, // limit 15:0\r
+ 0x0, // base 15:0\r
+ 0x0, // base 23:16\r
+ 0x0, // type\r
+ 0x0, // limit 19:16, flags\r
+ 0x0, // base 31:24\r
},\r
};\r
\r
VOID\r
)\r
{\r
- GDT_ENTRIES *gdt;\r
- IA32_DESCRIPTOR gdtPtr;\r
+ EFI_STATUS Status;\r
+ GDT_ENTRIES *Gdt;\r
+ IA32_DESCRIPTOR Gdtr;\r
+ EFI_PHYSICAL_ADDRESS Memory;\r
\r
//\r
- // Allocate Runtime Data for the GDT\r
- //\r
- gdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8);\r
- ASSERT (gdt != NULL);\r
- gdt = ALIGN_POINTER (gdt, 8);\r
+ // Allocate Runtime Data below 4GB for the GDT\r
+ // AP uses the same GDT when it's waken up from real mode so\r
+ // the GDT needs to be below 4GB.\r
+ //\r
+ Memory = SIZE_4GB - 1;\r
+ Status = gBS->AllocatePages (\r
+ AllocateMaxAddress,\r
+ EfiRuntimeServicesData,\r
+ EFI_SIZE_TO_PAGES (sizeof (mGdtTemplate)),\r
+ &Memory\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ ASSERT ((Memory != 0) && (Memory < SIZE_4GB));\r
+ Gdt = (GDT_ENTRIES *)(UINTN)Memory;\r
\r
//\r
// Initialize all GDT entries\r
//\r
- CopyMem (gdt, &GdtTemplate, sizeof (GdtTemplate));\r
+ CopyMem (Gdt, &mGdtTemplate, sizeof (mGdtTemplate));\r
\r
//\r
// Write GDT register\r
//\r
- gdtPtr.Base = (UINT32)(UINTN)(VOID*) gdt;\r
- gdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1);\r
- AsmWriteGdtr (&gdtPtr);\r
+ Gdtr.Base = (UINT32)(UINTN)Gdt;\r
+ Gdtr.Limit = (UINT16)(sizeof (mGdtTemplate) - 1);\r
+ AsmWriteGdtr (&Gdtr);\r
\r
//\r
// Update selector (segment) registers base on new GDT\r
SetCodeSelector ((UINT16)CPU_CODE_SEL);\r
SetDataSelectors ((UINT16)CPU_DATA_SEL);\r
}\r
-\r