1 #pragma once 2 3 #include <DragonOS/stdint.h> 4 5 #define sti() __asm__ __volatile__("sti\n\t" :: \ 6 : "memory") //开启外部中断 7 #define cli() __asm__ __volatile__("cli\n\t" :: \ 8 : "memory") //关闭外部中断 9 #define nop() __asm__ __volatile__("nop\n\t") 10 #define hlt() __asm__ __volatile__("hlt\n\t") 11 #define pause() asm volatile("pause\n\t"); // 处理器等待一段时间 12 13 //内存屏障 14 #define io_mfence() __asm__ __volatile__("mfence\n\t" :: \ 15 : "memory") // 在mfence指令前的读写操作必须在mfence指令后的读写操作前完成。 16 #define io_sfence() __asm__ __volatile__("sfence\n\t" :: \ 17 : "memory") // 在sfence指令前的写操作必须在sfence指令后的写操作前完成 18 #define io_lfence() __asm__ __volatile__("lfence\n\t" :: \ 19 : "memory") // 在lfence指令前的读操作必须在lfence指令后的读操作前完成。 20 21 /* 22 * Macros to generate condition code outputs from inline assembly, 23 * The output operand must be type "bool". 24 */ 25 // 如果编译器支持输出标志寄存器值到变量的话,则会定义__GCC_ASM_FLAG_OUTPUTS__ 26 #ifdef __GCC_ASM_FLAG_OUTPUTS__ 27 // CC_SET(c)则是用于设置标志寄存器中的某一位 28 #define CC_SET(c) "\n\t/* output condition code " #c "*/\n" 29 // "=@cccond"的用法是,将标志寄存器中的cond(也就是指令集定义的标准条件)的值输出到变量中 30 #define CC_OUT(c) "=@cc" #c 31 #else 32 #define CC_SET(c) "\n\tset" #c " %[_cc_" #c "]\n" 33 #define CC_OUT(c) [_cc_##c] "=qm" 34 #endif 35 36 #define rdtsc() ({ \ 37 uint64_t tmp1 = 0, tmp2 = 0; \ 38 asm volatile("rdtsc" \ 39 : "=d"(tmp1), "=a"(tmp2)::"memory"); \ 40 (tmp1 << 32 | tmp2); \ 41 }) 42 43 /** 44 * @brief 读取rsp寄存器的值(存储了页目录的基地址) 45 * 46 * @return unsigned* rsp的值的指针 47 */ 48 unsigned long *get_rsp() 49 { 50 uint64_t *tmp; 51 __asm__ __volatile__( 52 "movq %%rsp, %0\n\t" 53 : "=r"(tmp)::"memory"); 54 return tmp; 55 } 56 57 /** 58 * @brief 读取rbp寄存器的值(存储了页目录的基地址) 59 * 60 * @return unsigned* rbp的值的指针 61 */ 62 unsigned long *get_rbp() 63 { 64 uint64_t *tmp; 65 __asm__ __volatile__( 66 "movq %%rbp, %0\n\t" 67 : "=r"(tmp)::"memory"); 68 return tmp; 69 } 70 71 /** 72 * @brief 读取ds寄存器的值(存储了页目录的基地址) 73 * 74 * @return unsigned* ds的值的指针 75 */ 76 unsigned long *get_ds() 77 { 78 uint64_t *tmp; 79 __asm__ __volatile__( 80 "movq %%ds, %0\n\t" 81 : "=r"(tmp)::"memory"); 82 return tmp; 83 } 84 85 /** 86 * @brief 读取rax寄存器的值(存储了页目录的基地址) 87 * 88 * @return unsigned* rax的值的指针 89 */ 90 unsigned long *get_rax() 91 { 92 uint64_t *tmp; 93 __asm__ __volatile__( 94 "movq %%rax, %0\n\t" 95 : "=r"(tmp)::"memory"); 96 return tmp; 97 } 98 /** 99 * @brief 读取rbx寄存器的值(存储了页目录的基地址) 100 * 101 * @return unsigned* rbx的值的指针 102 */ 103 unsigned long *get_rbx() 104 { 105 uint64_t *tmp; 106 __asm__ __volatile__( 107 "movq %%rbx, %0\n\t" 108 : "=r"(tmp)::"memory"); 109 return tmp; 110 } 111 112 // ========= MSR寄存器组操作 ============= 113 /** 114 * @brief 向msr寄存器组的address处的寄存器写入值value 115 * 116 * @param address 地址 117 * @param value 要写入的值 118 */ 119 void wrmsr(uint64_t address, uint64_t value) 120 { 121 __asm__ __volatile__("wrmsr \n\t" ::"d"(value >> 32), "a"(value & 0xffffffff), "c"(address) 122 : "memory"); 123 } 124 125 /** 126 * @brief 从msr寄存器组的address地址处读取值 127 * rdmsr返回高32bits在edx,低32bits在eax 128 * @param address 地址 129 * @return uint64_t address处的寄存器的值 130 */ 131 uint64_t rdmsr(uint64_t address) 132 { 133 unsigned int tmp0, tmp1; 134 __asm__ __volatile__("rdmsr \n\t" 135 : "=d"(tmp0), "=a"(tmp1) 136 : "c"(address) 137 : "memory"); 138 return ((uint64_t)tmp0 << 32) | tmp1; 139 } 140 141 uint64_t get_rflags() 142 { 143 unsigned long tmp = 0; 144 __asm__ __volatile__("pushfq \n\t" 145 "movq (%%rsp), %0 \n\t" 146 "popfq \n\t" 147 : "=r"(tmp)::"memory"); 148 return tmp; 149 }