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