]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/CpuDxe/CpuGdt.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / CpuGdt.c
1 /** @file
2 C based implementation of IA32 interrupt handling only
3 requiring a minimal assembly interrupt entry point.
4
5 Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "CpuDxe.h"
11 #include "CpuGdt.h"
12
13 //
14 // Global descriptor table (GDT) Template
15 //
16 STATIC GDT_ENTRIES mGdtTemplate = {
17 //
18 // NULL_SEL
19 //
20 {
21 0x0, // limit 15:0
22 0x0, // base 15:0
23 0x0, // base 23:16
24 0x0, // type
25 0x0, // limit 19:16, flags
26 0x0, // base 31:24
27 },
28 //
29 // LINEAR_SEL
30 //
31 {
32 0x0FFFF, // limit 15:0
33 0x0, // base 15:0
34 0x0, // base 23:16
35 0x092, // present, ring 0, data, read/write
36 0x0CF, // page-granular, 32-bit
37 0x0,
38 },
39 //
40 // LINEAR_CODE_SEL
41 //
42 {
43 0x0FFFF, // limit 15:0
44 0x0, // base 15:0
45 0x0, // base 23:16
46 0x09F, // present, ring 0, code, execute/read, conforming, accessed
47 0x0CF, // page-granular, 32-bit
48 0x0,
49 },
50 //
51 // SYS_DATA_SEL
52 //
53 {
54 0x0FFFF, // limit 15:0
55 0x0, // base 15:0
56 0x0, // base 23:16
57 0x093, // present, ring 0, data, read/write, accessed
58 0x0CF, // page-granular, 32-bit
59 0x0,
60 },
61 //
62 // SYS_CODE_SEL
63 //
64 {
65 0x0FFFF, // limit 15:0
66 0x0, // base 15:0
67 0x0, // base 23:16
68 0x09A, // present, ring 0, code, execute/read
69 0x0CF, // page-granular, 32-bit
70 0x0,
71 },
72 //
73 // SYS_CODE16_SEL
74 //
75 {
76 0x0FFFF, // limit 15:0
77 0x0, // base 15:0
78 0x0, // base 23:16
79 0x09A, // present, ring 0, code, execute/read
80 0x08F, // page-granular, 16-bit
81 0x0, // base 31:24
82 },
83 //
84 // LINEAR_DATA64_SEL
85 //
86 {
87 0x0FFFF, // limit 15:0
88 0x0, // base 15:0
89 0x0, // base 23:16
90 0x092, // present, ring 0, data, read/write
91 0x0CF, // page-granular, 32-bit
92 0x0,
93 },
94 //
95 // LINEAR_CODE64_SEL
96 //
97 {
98 0x0FFFF, // limit 15:0
99 0x0, // base 15:0
100 0x0, // base 23:16
101 0x09A, // present, ring 0, code, execute/read
102 0x0AF, // page-granular, 64-bit code
103 0x0, // base (high)
104 },
105 //
106 // SPARE5_SEL
107 //
108 {
109 0x0, // limit 15:0
110 0x0, // base 15:0
111 0x0, // base 23:16
112 0x0, // type
113 0x0, // limit 19:16, flags
114 0x0, // base 31:24
115 },
116 };
117
118 /**
119 Initialize Global Descriptor Table.
120
121 **/
122 VOID
123 InitGlobalDescriptorTable (
124 VOID
125 )
126 {
127 EFI_STATUS Status;
128 GDT_ENTRIES *Gdt;
129 IA32_DESCRIPTOR Gdtr;
130 EFI_PHYSICAL_ADDRESS Memory;
131
132 //
133 // Allocate Runtime Data below 4GB for the GDT
134 // AP uses the same GDT when it's waken up from real mode so
135 // the GDT needs to be below 4GB.
136 //
137 Memory = SIZE_4GB - 1;
138 Status = gBS->AllocatePages (
139 AllocateMaxAddress,
140 EfiRuntimeServicesData,
141 EFI_SIZE_TO_PAGES (sizeof (mGdtTemplate)),
142 &Memory
143 );
144 ASSERT_EFI_ERROR (Status);
145 ASSERT ((Memory != 0) && (Memory < SIZE_4GB));
146 Gdt = (GDT_ENTRIES *)(UINTN)Memory;
147
148 //
149 // Initialize all GDT entries
150 //
151 CopyMem (Gdt, &mGdtTemplate, sizeof (mGdtTemplate));
152
153 //
154 // Write GDT register
155 //
156 Gdtr.Base = (UINT32)(UINTN)Gdt;
157 Gdtr.Limit = (UINT16)(sizeof (mGdtTemplate) - 1);
158 AsmWriteGdtr (&Gdtr);
159
160 //
161 // Update selector (segment) registers base on new GDT
162 //
163 SetCodeSelector ((UINT16)CPU_CODE_SEL);
164 SetDataSelectors ((UINT16)CPU_DATA_SEL);
165 }