CpuGdt.c 3.9 KB

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