Reviewed the code comments in the Include/Protocol directory for typos, grammar issue...
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / CpuGdt.c
1 /** @file
2 C based implemention of IA32 interrupt handling only
3 requiring a minimal assembly interrupt entry point.
4
5 Copyright (c) 2006 - 2009, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "CpuDxe.h"
17
18
19 //
20 // Local structure definitions
21 //
22
23 #pragma pack (1)
24
25 //
26 // Global Descriptor Entry structures
27 //
28
29 typedef
30 struct _GDT_ENTRY {
31 UINT16 limit15_0;
32 UINT16 base15_0;
33 UINT8 base23_16;
34 UINT8 type;
35 UINT8 limit19_16_and_flags;
36 UINT8 base31_24;
37 } GDT_ENTRY;
38
39 typedef
40 struct _GDT_ENTRIES {
41 GDT_ENTRY Null;
42 GDT_ENTRY Linear;
43 GDT_ENTRY LinearCode;
44 GDT_ENTRY SysData;
45 GDT_ENTRY SysCode;
46 GDT_ENTRY LinearCode64;
47 GDT_ENTRY Spare4;
48 GDT_ENTRY Spare5;
49 } GDT_ENTRIES;
50
51 #define NULL_SEL OFFSET_OF (GDT_ENTRIES, Null)
52 #define LINEAR_SEL OFFSET_OF (GDT_ENTRIES, Linear)
53 #define LINEAR_CODE_SEL OFFSET_OF (GDT_ENTRIES, LinearCode)
54 #define SYS_DATA_SEL OFFSET_OF (GDT_ENTRIES, SysData)
55 #define SYS_CODE_SEL OFFSET_OF (GDT_ENTRIES, SysCode)
56 #define LINEAR_CODE64_SEL OFFSET_OF (GDT_ENTRIES, LinearCode64)
57 #define SPARE4_SEL OFFSET_OF (GDT_ENTRIES, Spare4)
58 #define SPARE5_SEL OFFSET_OF (GDT_ENTRIES, Spare5)
59
60 #if defined (MDE_CPU_IA32)
61 #define CPU_CODE_SEL LINEAR_CODE_SEL
62 #define CPU_DATA_SEL LINEAR_SEL
63 #elif defined (MDE_CPU_X64)
64 #define CPU_CODE_SEL LINEAR_CODE64_SEL
65 #define CPU_DATA_SEL LINEAR_SEL
66 #else
67 #error CPU type not supported for CPU GDT initialization!
68 #endif
69
70 //
71 // Global descriptor table (GDT) Template
72 //
73 STATIC GDT_ENTRIES GdtTemplate = {
74 //
75 // NULL_SEL
76 //
77 {
78 0x0, // limit 15:0
79 0x0, // base 15:0
80 0x0, // base 23:16
81 0x0, // type
82 0x0, // limit 19:16, flags
83 0x0, // base 31:24
84 },
85 //
86 // LINEAR_SEL
87 //
88 {
89 0x0FFFF, // limit 0xFFFFF
90 0x0, // base 0
91 0x0,
92 0x092, // present, ring 0, data, expand-up, writable
93 0x0CF, // page-granular, 32-bit
94 0x0,
95 },
96 //
97 // LINEAR_CODE_SEL
98 //
99 {
100 0x0FFFF, // limit 0xFFFFF
101 0x0, // base 0
102 0x0,
103 0x09A, // present, ring 0, data, expand-up, writable
104 0x0CF, // page-granular, 32-bit
105 0x0,
106 },
107 //
108 // SYS_DATA_SEL
109 //
110 {
111 0x0FFFF, // limit 0xFFFFF
112 0x0, // base 0
113 0x0,
114 0x092, // present, ring 0, data, expand-up, writable
115 0x0CF, // page-granular, 32-bit
116 0x0,
117 },
118 //
119 // SYS_CODE_SEL
120 //
121 {
122 0x0FFFF, // limit 0xFFFFF
123 0x0, // base 0
124 0x0,
125 0x09A, // present, ring 0, data, expand-up, writable
126 0x0CF, // page-granular, 32-bit
127 0x0,
128 },
129 //
130 // LINEAR_CODE64_SEL
131 //
132 {
133 0x0FFFF, // limit 0xFFFFF
134 0x0, // base 0
135 0x0,
136 0x09B, // present, ring 0, code, expand-up, writable
137 0x0AF, // LimitHigh (CS.L=1, CS.D=0)
138 0x0, // base (high)
139 },
140 //
141 // SPARE4_SEL
142 //
143 {
144 0x0, // limit 0
145 0x0, // base 0
146 0x0,
147 0x0, // present, ring 0, data, expand-up, writable
148 0x0, // page-granular, 32-bit
149 0x0,
150 },
151 //
152 // SPARE5_SEL
153 //
154 {
155 0x0, // limit 0
156 0x0, // base 0
157 0x0,
158 0x0, // present, ring 0, data, expand-up, writable
159 0x0, // page-granular, 32-bit
160 0x0,
161 },
162 };
163
164 /**
165 Initialize Global Descriptor Table
166
167 **/
168 VOID
169 InitGlobalDescriptorTable (
170 )
171 {
172 GDT_ENTRIES *gdt;
173 IA32_DESCRIPTOR gdtPtr;
174
175 //
176 // Allocate Runtime Data for the GDT
177 //
178 gdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8);
179 ASSERT (gdt != NULL);
180 gdt = ALIGN_POINTER (gdt, 8);
181
182 //
183 // Initialize all GDT entries
184 //
185 CopyMem (gdt, &GdtTemplate, sizeof (GdtTemplate));
186
187 //
188 // Write GDT register
189 //
190 gdtPtr.Base = (UINT32)(UINTN)(VOID*) gdt;
191 gdtPtr.Limit = sizeof (GdtTemplate) - 1;
192 AsmWriteGdtr (&gdtPtr);
193
194 //
195 // Update selector (segment) registers base on new GDT
196 //
197 SetCodeSelector ((UINT16)CPU_CODE_SEL);
198 SetDataSelectors ((UINT16)CPU_DATA_SEL);
199 }
200