1 /** @file
2 C based implemention of IA32 interrupt handling only
3 requiring a minimal assembly interrupt entry point.
4
5 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
6 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 #include "CpuGdt.h"
18
19 //
20 // Global descriptor table (GDT) Template
21 //
22 STATIC GDT_ENTRIES GdtTemplate = {
23 //
24 // NULL_SEL
25 //
26 {
27 0x0, // limit 15:0
28 0x0, // base 15:0
29 0x0, // base 23:16
30 0x0, // type
31 0x0, // limit 19:16, flags
32 0x0, // base 31:24
33 },
34 //
35 // LINEAR_SEL
36 //
37 {
38 0x0FFFF, // limit 15:0
39 0x0, // base 15:0
40 0x0, // base 23:16
41 0x092, // present, ring 0, data, read/write
42 0x0CF, // page-granular, 32-bit
43 0x0,
44 },
45 //
46 // LINEAR_CODE_SEL
47 //
48 {
49 0x0FFFF, // limit 15:0
50 0x0, // base 15:0
51 0x0, // base 23:16
52 0x09F, // present, ring 0, code, execute/read, conforming, accessed
53 0x0CF, // page-granular, 32-bit
54 0x0,
55 },
56 //
57 // SYS_DATA_SEL
58 //
59 {
60 0x0FFFF, // limit 15:0
61 0x0, // base 15:0
62 0x0, // base 23:16
63 0x093, // present, ring 0, data, read/write, accessed
64 0x0CF, // page-granular, 32-bit
65 0x0,
66 },
67 //
68 // SYS_CODE_SEL
69 //
70 {
71 0x0FFFF, // limit 15:0
72 0x0, // base 15:0
73 0x0, // base 23:16
74 0x09A, // present, ring 0, code, execute/read
75 0x0CF, // page-granular, 32-bit
76 0x0,
77 },
78 //
79 // SPARE4_SEL
80 //
81 {
82 0x0, // limit 15:0
83 0x0, // base 15:0
84 0x0, // base 23:16
85 0x0, // type
86 0x0, // limit 19:16, flags
87 0x0, // base 31:24
88 },
89 //
90 // LINEAR_DATA64_SEL
91 //
92 {
93 0x0FFFF, // limit 15:0
94 0x0, // base 15:0
95 0x0, // base 23:16
96 0x092, // present, ring 0, data, read/write
97 0x0CF, // page-granular, 32-bit
98 0x0,
99 },
100 //
101 // LINEAR_CODE64_SEL
102 //
103 {
104 0x0FFFF, // limit 15:0
105 0x0, // base 15:0
106 0x0, // base 23:16
107 0x09A, // present, ring 0, code, execute/read
108 0x0AF, // page-granular, 64-bit code
109 0x0, // base (high)
110 },
111 //
112 // SPARE5_SEL
113 //
114 {
115 0x0, // limit 15:0
116 0x0, // base 15:0
117 0x0, // base 23:16
118 0x0, // type
119 0x0, // limit 19:16, flags
120 0x0, // base 31:24
121 },
122 };
123
124 /**
125 Initialize Global Descriptor Table.
126
127 **/
128 VOID
InitGlobalDescriptorTable(VOID)129 InitGlobalDescriptorTable (
130 VOID
131 )
132 {
133 GDT_ENTRIES *gdt;
134 IA32_DESCRIPTOR gdtPtr;
135
136 //
137 // Allocate Runtime Data for the GDT
138 //
139 gdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8);
140 ASSERT (gdt != NULL);
141 gdt = ALIGN_POINTER (gdt, 8);
142
143 //
144 // Initialize all GDT entries
145 //
146 CopyMem (gdt, &GdtTemplate, sizeof (GdtTemplate));
147
148 //
149 // Write GDT register
150 //
151 gdtPtr.Base = (UINT32)(UINTN)(VOID*) gdt;
152 gdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1);
153 AsmWriteGdtr (&gdtPtr);
154
155 //
156 // Update selector (segment) registers base on new GDT
157 //
158 SetCodeSelector ((UINT16)CPU_CODE_SEL);
159 SetDataSelectors ((UINT16)CPU_DATA_SEL);
160 }
161
162