ASM_wrapper.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Types.h>
  8. namespace Kernel {
  9. ALWAYS_INLINE void cli()
  10. {
  11. asm volatile("cli" ::
  12. : "memory");
  13. }
  14. ALWAYS_INLINE void sti()
  15. {
  16. asm volatile("sti" ::
  17. : "memory");
  18. }
  19. ALWAYS_INLINE FlatPtr cpu_flags()
  20. {
  21. FlatPtr flags;
  22. asm volatile(
  23. "pushf\n"
  24. "pop %0\n"
  25. : "=rm"(flags)::"memory");
  26. return flags;
  27. }
  28. #if ARCH(I386)
  29. ALWAYS_INLINE void set_fs(u16 segment)
  30. {
  31. asm volatile(
  32. "mov %%ax, %%fs" ::"a"(segment)
  33. : "memory");
  34. }
  35. ALWAYS_INLINE void set_gs(u16 segment)
  36. {
  37. asm volatile(
  38. "mov %%ax, %%gs" ::"a"(segment)
  39. : "memory");
  40. }
  41. ALWAYS_INLINE u16 get_fs()
  42. {
  43. u16 fs;
  44. asm("mov %%fs, %%eax"
  45. : "=a"(fs));
  46. return fs;
  47. }
  48. ALWAYS_INLINE u16 get_gs()
  49. {
  50. u16 gs;
  51. asm("mov %%gs, %%eax"
  52. : "=a"(gs));
  53. return gs;
  54. }
  55. #endif
  56. template<typename T>
  57. ALWAYS_INLINE T read_gs_value(FlatPtr offset)
  58. {
  59. T val;
  60. asm volatile(
  61. "mov %%gs:%a[off], %[val]"
  62. : [val] "=r"(val)
  63. : [off] "ir"(offset));
  64. return val;
  65. }
  66. template<typename T>
  67. ALWAYS_INLINE void write_gs_value(FlatPtr offset, T val)
  68. {
  69. asm volatile(
  70. "mov %[val], %%gs:%a[off]" ::[off] "ir"(offset), [val] "r"(val)
  71. : "memory");
  72. }
  73. ALWAYS_INLINE FlatPtr read_gs_ptr(FlatPtr offset)
  74. {
  75. FlatPtr val;
  76. asm volatile(
  77. "mov %%gs:%a[off], %[val]"
  78. : [val] "=r"(val)
  79. : [off] "ir"(offset));
  80. return val;
  81. }
  82. ALWAYS_INLINE void write_gs_ptr(u32 offset, FlatPtr val)
  83. {
  84. asm volatile(
  85. "mov %[val], %%gs:%a[off]" ::[off] "ir"(offset), [val] "r"(val)
  86. : "memory");
  87. }
  88. ALWAYS_INLINE bool are_interrupts_enabled()
  89. {
  90. return cpu_flags() & 0x200;
  91. }
  92. FlatPtr read_cr0();
  93. FlatPtr read_cr2();
  94. FlatPtr read_cr3();
  95. FlatPtr read_cr4();
  96. u64 read_xcr0();
  97. void write_cr0(FlatPtr);
  98. void write_cr3(FlatPtr);
  99. void write_cr4(FlatPtr);
  100. void write_xcr0(u64);
  101. void flush_idt();
  102. ALWAYS_INLINE void load_task_register(u16 selector)
  103. {
  104. asm("ltr %0" ::"r"(selector));
  105. }
  106. FlatPtr read_dr0();
  107. void write_dr0(FlatPtr);
  108. FlatPtr read_dr1();
  109. void write_dr1(FlatPtr);
  110. FlatPtr read_dr2();
  111. void write_dr2(FlatPtr);
  112. FlatPtr read_dr3();
  113. void write_dr3(FlatPtr);
  114. FlatPtr read_dr6();
  115. void write_dr6(FlatPtr);
  116. FlatPtr read_dr7();
  117. void write_dr7(FlatPtr);
  118. ALWAYS_INLINE static bool is_kernel_mode()
  119. {
  120. u16 cs;
  121. asm volatile(
  122. "mov %%cs, %[cs] \n"
  123. : [cs] "=g"(cs));
  124. return (cs & 3) == 0;
  125. }
  126. ALWAYS_INLINE void read_tsc(u32& lsw, u32& msw)
  127. {
  128. asm volatile("rdtsc"
  129. : "=d"(msw), "=a"(lsw));
  130. }
  131. ALWAYS_INLINE u64 read_tsc()
  132. {
  133. u32 lsw;
  134. u32 msw;
  135. read_tsc(lsw, msw);
  136. return ((u64)msw << 32) | lsw;
  137. }
  138. void stac();
  139. void clac();
  140. [[noreturn]] ALWAYS_INLINE void halt_this()
  141. {
  142. for (;;) {
  143. asm volatile("cli; hlt");
  144. }
  145. }
  146. }