x86defs.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*++
  2. Copyright (c) 2017 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. x86defs.h
  9. Abstract:
  10. This header contains architecture preprocessor definitions that are common
  11. to x86 and x64 (AMD64). This file is included by assembly.
  12. Author:
  13. Evan Green 2-Jun-2017
  14. --*/
  15. //
  16. // ---------------------------------------------------------------- Definitions
  17. //
  18. #define SEGMENT_PRIVILEGE_MASK 0x0003
  19. #define SEGMENT_PRIVILEGE_KERNEL 0x0000
  20. #define SEGMENT_PRIVILEGE_USER 0x0003
  21. //
  22. // Define the GDT slots. This is a little confusing because it defines both
  23. // x86, x64, and some temporary slots used in special cases. On x64,
  24. // much of the layout and definition of these entries is defined by the
  25. // syscall/sysret instructions, so please be aware of those constraints when
  26. // moving these entries around.
  27. // For x64: KERNEL64_TRANSITION_CS is used by the boot environment and during
  28. // AP startup. It's not needed at regular kernel runtime, so USER32_CS aliases
  29. // on it. Also, the KERNEL_TSS segment takes up two slots since it's a 64-bit
  30. // entry. The alternate TSS slots needed by x86 are not used, the IST mechanism
  31. // replaces task switches.
  32. //
  33. // For x86: KERNEL64_TRANSITION_CS obviously is never used. USER64_CS isn't a
  34. // thing either, so that slot is taken by GDT_PROCESSOR.
  35. //
  36. #define KERNEL_CS 0x08
  37. #define KERNEL_DS 0x10
  38. #define KERNEL64_TRANSITION_CS 0x18
  39. #define USER32_CS (0x18 | SEGMENT_PRIVILEGE_USER)
  40. #define USER_DS (0x20 | SEGMENT_PRIVILEGE_USER)
  41. #define USER64_CS (0x28 | SEGMENT_PRIVILEGE_USER)
  42. #define KERNEL_TSS 0x30
  43. #define X64_GDT_ENTRIES 8
  44. #define GDT_PROCESSOR 0x28
  45. #define GDT_THREAD (0x38 | SEGMENT_PRIVILEGE_USER)
  46. #define DOUBLE_FAULT_TSS 0x40
  47. #define NMI_TSS 0x48
  48. #define X86_GDT_ENTRIES 10
  49. //
  50. // Define the IST indices.
  51. //
  52. #define X64_IST_NMI 1
  53. #define X64_IST_DOUBLE_FAULT 2
  54. #define GATE_ACCESS_PRESENT 0x80
  55. #define GATE_ACCESS_USER (SEGMENT_PRIVILEGE_USER << 5)
  56. #define MAX_GDT_LIMIT 0xFFFFF
  57. #define GDT_SYSTEM_SEGMENT 0x00
  58. #define GDT_CODE_DATA_SEGMENT 0x10
  59. #define GDT_TSS_BUSY 0x02
  60. #define GDT_TYPE_DATA_READ 0x10
  61. #define GDT_TYPE_DATA_WRITE 0x12
  62. #define GDT_TYPE_SYSTEM_LDT 0x02
  63. #define GDT_TYPE_CODE 0x18
  64. #define GATE_TYPE_TASK 0x05
  65. #define GDT_TYPE_TSS 0x09
  66. #define GATE_TYPE_CALL 0x0C
  67. #define GATE_TYPE_INTERRUPT 0x0E
  68. #define GATE_TYPE_TRAP 0x0F
  69. #define GDT_GRANULARITY_KILOBYTE 0x80
  70. #define GDT_GRANULARITY_64BIT 0x20
  71. #define GDT_GRANULARITY_32BIT 0x40
  72. #define IDT_SIZE 0x100
  73. #define VECTOR_DIVIDE_ERROR 0x00
  74. #define VECTOR_DEBUG 0x01
  75. #define VECTOR_NMI 0x02
  76. #define VECTOR_BREAKPOINT 0x03
  77. #define VECTOR_OVERFLOW 0x04
  78. #define VECTOR_BOUND 0x05
  79. #define VECTOR_INVALID_OPCODE 0x06
  80. #define VECTOR_DEVICE_NOT_AVAILABLE 0x07
  81. #define VECTOR_DOUBLE_FAULT 0x08
  82. #define VECTOR_SEGMENT_OVERRUN 0x09
  83. #define VECTOR_INVALID_TSS 0x0A
  84. #define VECTOR_INVALID_SEGMENT 0x0B
  85. #define VECTOR_STACK_EXCEPTION 0x0C
  86. #define VECTOR_PROTECTION_FAULT 0x0D
  87. #define VECTOR_PAGE_FAULT 0x0E
  88. #define VECTOR_MATH_FAULT 0x10
  89. #define VECTOR_ALIGNMENT_CHECK 0x11
  90. #define VECTOR_MACHINE_CHECK 0x12
  91. #define VECTOR_SIMD_EXCEPTION 0x13
  92. #define VECTOR_DEBUG_SERVICE 0x21
  93. #define VECTOR_SYSTEM_CALL 0x2F
  94. #define VECTOR_CLOCK_INTERRUPT 0xD0
  95. #define VECTOR_CLOCK_IPI 0xD1
  96. #define VECTOR_IPI_INTERRUPT 0xE0
  97. #define VECTOR_TLB_IPI 0xE1
  98. #define VECTOR_PROFILER_INTERRUPT 0xF0
  99. #define PROCESSOR_VECTOR_COUNT 0x20
  100. #define MINIMUM_VECTOR 0x30
  101. #define MAXIMUM_VECTOR 0xFF
  102. #define MAXIMUM_DEVICE_VECTOR 0xBF
  103. #define INTERRUPT_VECTOR_COUNT IDT_SIZE
  104. #define IO_PORT_COUNT 0x10000
  105. #define IA32_EFLAG_CF 0x00000001
  106. #define IA32_EFLAG_PF 0x00000004
  107. #define IA32_EFLAG_AF 0x00000010
  108. #define IA32_EFLAG_ZF 0x00000040
  109. #define IA32_EFLAG_SF 0x00000080
  110. #define IA32_EFLAG_TF 0x00000100
  111. #define IA32_EFLAG_IF 0x00000200
  112. #define IA32_EFLAG_DF 0x00000400
  113. #define IA32_EFLAG_OF 0x00000800
  114. #define IA32_EFLAG_IOPL_MASK 0x00003000
  115. #define IA32_EFLAG_IOPL_USER 0x00003000
  116. #define IA32_EFLAG_IOPL_SHIFT 12
  117. #define IA32_EFLAG_NT 0x00004000
  118. #define IA32_EFLAG_RF 0x00010000
  119. #define IA32_EFLAG_VM 0x00020000
  120. #define IA32_EFLAG_AC 0x00040000
  121. #define IA32_EFLAG_VIF 0x00080000
  122. #define IA32_EFLAG_VIP 0x00100000
  123. #define IA32_EFLAG_ID 0x00200000
  124. #define IA32_EFLAG_ALWAYS_0 0xFFC08028
  125. #define IA32_EFLAG_ALWAYS_1 0x00000002
  126. #define IA32_EFLAG_STATUS \
  127. (IA32_EFLAG_CF | IA32_EFLAG_PF | IA32_EFLAG_AF | IA32_EFLAG_ZF | \
  128. IA32_EFLAG_SF | IA32_EFLAG_OF)
  129. #define IA32_EFLAG_USER \
  130. (IA32_EFLAG_STATUS | IA32_EFLAG_DF | IA32_EFLAG_TF | IA32_EFLAG_RF)
  131. #define CR0_PAGING_ENABLE 0x80000000
  132. #define CR0_CACHE_DISABLE 0x40000000
  133. #define CR0_NOT_WRITE_THROUGH 0x20000000
  134. #define CR0_ALIGNMENT_MASK 0x00040000
  135. #define CR0_WRITE_PROTECT_ENABLE 0x00010000
  136. #define CR0_NUMERIC_ERROR 0x00000020
  137. #define CR0_EXTENSION_TYPE 0x00000010
  138. #define CR0_TASK_SWITCHED 0x00000008
  139. #define CR0_X87_EMULATION 0x00000004
  140. #define CR0_MONITOR_COPROCESSOR 0x00000002
  141. #define CR0_PROTECTED_MODE 0x00000001
  142. //
  143. // Default masks.
  144. //
  145. #define CR0_OR_MASK \
  146. (CR0_PROTECTED_MODE | CR0_MONITOR_COPROCESSOR | CR0_TASK_SWITCHED | \
  147. CR0_NUMERIC_ERROR | CR0_WRITE_PROTECT_ENABLE | CR0_PAGING_ENABLE)
  148. #define CR0_AND_MASK \
  149. ~(CR0_CACHE_DISABLE | CR0_NOT_WRITE_THROUGH | CR0_X87_EMULATION)
  150. #define CR4_PKE_ENABLE 0x00400000
  151. #define CR4_SMAP_ENABLE 0x00200000
  152. #define CR4_SMEP_ENABLE 0x00100000
  153. #define CR4_OS_XSAVE 0x00040000
  154. #define CR4_PCID_ENABLE 0x00020000
  155. #define CR4_FSGS_BASE 0x00010000
  156. #define CR4_TXT_EXTENSIONS 0x00004000
  157. #define CR4_VT_X_EXTENSIONS 0x00002000
  158. #define CR4_OS_XMM_EXCEPTIONS 0x00000400
  159. #define CR4_OS_FX_SAVE_RESTORE 0x00000200
  160. #define CR4_PERF_COUNTER_ENABLE 0x00000100
  161. #define CR4_PAGE_GLOBAL_ENABLE 0x00000080
  162. #define CR4_MACHINE_CHECK_EXTENSION 0x00000040
  163. #define CR4_PHYSICAL_ADDRESS_EXTENSION 0x00000020
  164. #define CR4_PAGE_SIZE_EXTENSION 0x00000010
  165. #define CR4_DEBUGGING_EXTENSIONS 0x00000008
  166. #define CR4_TIMESTAMP_DISABLE 0x00000004
  167. #define CR4_PROTECTED_MODE_VIRTUAL_INTERRUPTS 0x00000002
  168. #define CR4_V8086_EXTENSIONS 0x00000001
  169. #define CR4_OR_MASK \
  170. (CR4_OS_FX_SAVE_RESTORE | CR4_PAGE_GLOBAL_ENABLE | \
  171. CR4_PHYSICAL_ADDRESS_EXTENSION)
  172. #define EFER_TRANSLATION_CACHE_EXTENSION 0x00008000
  173. #define EFER_FAST_FXSAVE 0x00004000
  174. #define EFER_LONG_MODE_SEGMENT_LIMIT 0x00002000
  175. #define EFER_SECURE_VIRTUAL_MACHINE 0x00001000
  176. #define EFER_NO_EXECUTE_ENABLE 0x00000800
  177. #define EFER_LONG_MODE_ACTIVE 0x00000400
  178. #define EFER_LONG_MODE_ENABLE 0x00000100
  179. #define EFER_SYSTEM_CALL_EXTENSIONS 0x00000001
  180. #define PAGE_SIZE 4096
  181. #define PAGE_MASK 0x00000FFF
  182. #define PAGE_SHIFT 12
  183. #define PAGE_DIRECTORY_SHIFT 22
  184. #define PDE_INDEX_MASK 0xFFC00000
  185. #define PTE_INDEX_MASK 0x003FF000
  186. #define X86_FAULT_ERROR_CODE_PRESENT 0x00000001
  187. #define X86_FAULT_ERROR_CODE_WRITE 0x00000002
  188. #define X86_FAULT_ERROR_CODE_USER_MODE 0x00000004
  189. #define X86_FAULT_ERROR_CODE_RESERVED 0x00000008
  190. #define X86_FAULT_ERROR_CODE_EXECUTE 0x00000010
  191. //
  192. // Define the location of the legacy keyboard controller. While not strictly
  193. // architectural, it's pretty close.
  194. //
  195. #define PC_8042_CONTROL_PORT 0x64
  196. #define PC_8042_RESET_VALUE 0xFE
  197. #define PC_8042_INPUT_BUFFER_FULL 0x02
  198. //
  199. // Define CPUID EAX values.
  200. //
  201. #define X86_CPUID_IDENTIFICATION 0x00000000
  202. #define X86_CPUID_BASIC_INFORMATION 0x00000001
  203. #define X86_CPUID_MWAIT 0x00000005
  204. #define X86_CPUID_EXTENDED_IDENTIFICATION 0x80000000
  205. #define X86_CPUID_EXTENDED_INFORMATION 0x80000001
  206. #define X86_CPUID_ADVANCED_POWER_MANAGEMENT 0x80000007
  207. //
  208. // Define basic information CPUID bits (eax is 1).
  209. //
  210. #define X86_CPUID_BASIC_EAX_STEPPING_MASK 0x00000003
  211. #define X86_CPUID_BASIC_EAX_BASE_MODEL_MASK (0xF << 4)
  212. #define X86_CPUID_BASIC_EAX_BASE_MODEL_SHIFT 4
  213. #define X86_CPUID_BASIC_EAX_BASE_FAMILY_MASK (0xF << 8)
  214. #define X86_CPUID_BASIC_EAX_BASE_FAMILY_SHIFT 8
  215. #define X86_CPUID_BASIC_EAX_EXTENDED_MODEL_MASK (0xF << 16)
  216. #define X86_CPUID_BASIC_EAX_EXTENDED_MODEL_SHIFT 16
  217. #define X86_CPUID_BASIC_EAX_EXTENDED_FAMILY_MASK (0xFF << 20)
  218. #define X86_CPUID_BASIC_EAX_EXTENDED_FAMILY_SHIFT 20
  219. #define X86_CPUID_BASIC_ECX_MONITOR (1 << 3)
  220. #define X86_CPUID_BASIC_EDX_SYSENTER (1 << 11)
  221. #define X86_CPUID_BASIC_EDX_CMOV (1 << 15)
  222. #define X86_CPUID_BASIC_EDX_FX_SAVE_RESTORE (1 << 24)
  223. //
  224. // Define known CPU vendors.
  225. //
  226. #define X86_VENDOR_INTEL 0x756E6547
  227. #define X86_VENDOR_AMD 0x68747541
  228. //
  229. // Define monitor/mwait leaf bits.
  230. //
  231. #define X86_CPUID_MWAIT_ECX_EXTENSIONS_SUPPORTED 0x00000001
  232. #define X86_CPUID_MWAIT_ECX_INTERRUPT_BREAK 0x00000002
  233. //
  234. // Define extended information CPUID bits (eax is 0x80000001).
  235. //
  236. #define X86_CPUID_EXTENDED_INFORMATION_EDX_SYSCALL (1 << 11)
  237. #define X86_CPUID_EXTENDED_INFORMATION_EDX_1GB_PAGES (1 << 26)
  238. #define X86_CPUID_EXTENDED_INFORMATION_EDX_LONG_MODE (1 << 29)
  239. //
  240. // Define advanced power management CPUID bits (eax 0x80000007).
  241. //
  242. //
  243. // This bit is set to indicate that the TSC is invariant across all P-states
  244. // and C-states
  245. //
  246. #define X86_CPUID_ADVANCED_POWER_EDX_TSC_INVARIANT (1 << 8)
  247. //
  248. // Define the required alignment for FPU context.
  249. //
  250. #define FPU_CONTEXT_ALIGNMENT 64
  251. //
  252. // Define MSR values.
  253. //
  254. #define X86_MSR_POWER_CONTROL_C1E_PROMOTION 0x00000002
  255. #define X86_MSR_SYSENTER_CS 0x00000174
  256. #define X86_MSR_SYSENTER_ESP 0x00000175
  257. #define X86_MSR_SYSENTER_EIP 0x00000176
  258. #define X86_MSR_POWER_CONTROL 0x000001FC
  259. #define X86_MSR_EFER 0xC0000080
  260. #define X86_MSR_STAR 0xC0000081
  261. #define X86_MSR_LSTAR 0xC0000082
  262. #define X86_MSR_FMASK 0xC0000084
  263. #define X86_MSR_FSBASE 0xC0000100
  264. #define X86_MSR_GSBASE 0xC0000101
  265. #define X86_MSR_KERNEL_GSBASE 0xC0000102
  266. //
  267. // Define the PTE bits.
  268. //
  269. #define X86_PTE_PRESENT 0x00000001
  270. #define X86_PTE_WRITABLE 0x00000002
  271. #define X86_PTE_USER_MODE 0x00000004
  272. #define X86_PTE_WRITE_THROUGH 0x00000008
  273. #define X86_PTE_CACHE_DISABLED 0x00000010
  274. #define X86_PTE_ACCESSED 0x00000020
  275. #define X86_PTE_DIRTY 0x00000040
  276. #define X86_PTE_LARGE 0x00000080
  277. #define X86_PTE_GLOBAL 0x00000100
  278. #define X86_PTE_NX 0x8000000000000000
  279. #define X86_PTE_ENTRY_SHIFT 12
  280. //
  281. // Define the canonical regions. Addresses between the low and high values are
  282. // "non-canonical" and generate a general protection fault if used.
  283. //
  284. #define X64_CANONICAL_HIGH 0xFFFF800000000000
  285. #define X64_CANONICAL_LOW 0x00007FFFFFFFFFFF
  286. //
  287. // Define the size of the x64 red zone. This is not used in the kernel, since
  288. // the exception handlers in the hardware don't honor it. But it is used by
  289. // user mode, so signal dispatching has to be careful.
  290. //
  291. #define X64_RED_ZONE 128
  292. //
  293. // Define the location of the identity mapped stub. Since x86 doesn't have
  294. // relative addressing the AP code really is hardwired for this address. This
  295. // needs to be in the first megabyte since it starts running in real mode, and
  296. // needs to avoid known BIOS regions.
  297. //
  298. #define IDENTITY_STUB_ADDRESS 0x00001000
  299. //
  300. // --------------------------------------------------------------------- Macros
  301. //
  302. //
  303. // This macro gets a value at the given offset from the current processor block.
  304. // _Result should be the appropriate size.
  305. //
  306. #define FS_READ32(_Result, _Offset) \
  307. asm volatile ("movl %%fs:(%1), %k0" : "=r" (_Result) : "r" (_Offset))
  308. #define FS_READ64(_Result, _Offset) \
  309. asm volatile ("movq %%fs:(%1), %q0" : "=r" (_Result) : "r" (_Offset))
  310. #define GS_READ32(_Result, _Offset) \
  311. asm volatile ("movl %%gs:(%1), %k0" : "=r" (_Result) : "r" (_Offset))
  312. #define GS_READ64(_Result, _Offset) \
  313. asm volatile ("movq %%gs:(%1), %q0" : "=r" (_Result) : "r" (_Offset))
  314. #if __SIZEOF_LONG__ == 8
  315. #define FS_READN(_Result, _Offset) FS_READ64(_Result, _Offset)
  316. #define GS_READN(_Result, _Offset) GS_READ64(_Result, _Offset)
  317. #else
  318. #define FS_READN(_Result, _Offset) FS_READ32(_Result, _Offset)
  319. #define GS_READN(_Result, _Offset) GS_READ32(_Result, _Offset)
  320. #endif
  321. //
  322. // This macro determines whether or not the given trap frame is from privileged
  323. // mode.
  324. //
  325. #define IS_TRAP_FRAME_FROM_PRIVILEGED_MODE(_TrapFrame) \
  326. (((_TrapFrame)->Cs & SEGMENT_PRIVILEGE_MASK) == 0)
  327. //
  328. // This macro determines whether or not the given trap frame is complete or
  329. // left mostly uninitialized by the system call handler. The system call
  330. // handler sets CS to user DS as a hint that the trap frame is incomplete.
  331. //
  332. #define IS_TRAP_FRAME_COMPLETE(_TrapFrame) ((_TrapFrame)->Cs != USER_DS)
  333. //
  334. // This macro extracts the address ut of a PTE (or PDE, etc).
  335. //
  336. #define X86_PTE_ENTRY(_Pte) ((_Pte) & ~(PAGE_MASK | X86_PTE_NX))