166f67c6aSlogin #pragma once 266f67c6aSlogin 3*0e0c1874Slogin #include <DragonOS/stdint.h> 466f67c6aSlogin 566f67c6aSlogin #define sti() __asm__ __volatile__("sti\n\t" :: \ 666f67c6aSlogin : "memory") //开启外部中断 766f67c6aSlogin #define cli() __asm__ __volatile__("cli\n\t" :: \ 866f67c6aSlogin : "memory") //关闭外部中断 966f67c6aSlogin #define nop() __asm__ __volatile__("nop\n\t") 1066f67c6aSlogin #define hlt() __asm__ __volatile__("hlt\n\t") 1166f67c6aSlogin #define pause() asm volatile("pause\n\t"); // 处理器等待一段时间 1266f67c6aSlogin 1366f67c6aSlogin //内存屏障 1466f67c6aSlogin #define io_mfence() __asm__ __volatile__("mfence\n\t" :: \ 1566f67c6aSlogin : "memory") // 在mfence指令前的读写操作必须在mfence指令后的读写操作前完成。 1666f67c6aSlogin #define io_sfence() __asm__ __volatile__("sfence\n\t" :: \ 1766f67c6aSlogin : "memory") // 在sfence指令前的写操作必须在sfence指令后的写操作前完成 1866f67c6aSlogin #define io_lfence() __asm__ __volatile__("lfence\n\t" :: \ 1966f67c6aSlogin : "memory") // 在lfence指令前的读操作必须在lfence指令后的读操作前完成。 2066f67c6aSlogin 2166f67c6aSlogin /* 2266f67c6aSlogin * Macros to generate condition code outputs from inline assembly, 2366f67c6aSlogin * The output operand must be type "bool". 2466f67c6aSlogin */ 2566f67c6aSlogin // 如果编译器支持输出标志寄存器值到变量的话,则会定义__GCC_ASM_FLAG_OUTPUTS__ 2666f67c6aSlogin #ifdef __GCC_ASM_FLAG_OUTPUTS__ 2766f67c6aSlogin // CC_SET(c)则是用于设置标志寄存器中的某一位 2866f67c6aSlogin #define CC_SET(c) "\n\t/* output condition code " #c "*/\n" 2966f67c6aSlogin // "=@cccond"的用法是,将标志寄存器中的cond(也就是指令集定义的标准条件)的值输出到变量中 3066f67c6aSlogin #define CC_OUT(c) "=@cc" #c 3166f67c6aSlogin #else 3266f67c6aSlogin #define CC_SET(c) "\n\tset" #c " %[_cc_" #c "]\n" 3366f67c6aSlogin #define CC_OUT(c) [_cc_##c] "=qm" 3466f67c6aSlogin #endif 3566f67c6aSlogin 3666f67c6aSlogin #define rdtsc() ({ \ 3766f67c6aSlogin uint64_t tmp1 = 0, tmp2 = 0; \ 3866f67c6aSlogin asm volatile("rdtsc" \ 3966f67c6aSlogin : "=d"(tmp1), "=a"(tmp2)::"memory"); \ 4066f67c6aSlogin (tmp1 << 32 | tmp2); \ 4166f67c6aSlogin }) 4266f67c6aSlogin 4366f67c6aSlogin /** 4466f67c6aSlogin * @brief 读取rsp寄存器的值(存储了页目录的基地址) 4566f67c6aSlogin * 4666f67c6aSlogin * @return unsigned* rsp的值的指针 4766f67c6aSlogin */ 4866f67c6aSlogin unsigned long *get_rsp() 4966f67c6aSlogin { 5066f67c6aSlogin uint64_t *tmp; 5166f67c6aSlogin __asm__ __volatile__( 5266f67c6aSlogin "movq %%rsp, %0\n\t" 5366f67c6aSlogin : "=r"(tmp)::"memory"); 5466f67c6aSlogin return tmp; 5566f67c6aSlogin } 5666f67c6aSlogin 5766f67c6aSlogin /** 5866f67c6aSlogin * @brief 读取rbp寄存器的值(存储了页目录的基地址) 5966f67c6aSlogin * 6066f67c6aSlogin * @return unsigned* rbp的值的指针 6166f67c6aSlogin */ 6266f67c6aSlogin unsigned long *get_rbp() 6366f67c6aSlogin { 6466f67c6aSlogin uint64_t *tmp; 6566f67c6aSlogin __asm__ __volatile__( 6666f67c6aSlogin "movq %%rbp, %0\n\t" 6766f67c6aSlogin : "=r"(tmp)::"memory"); 6866f67c6aSlogin return tmp; 6966f67c6aSlogin } 7066f67c6aSlogin 7166f67c6aSlogin /** 7266f67c6aSlogin * @brief 读取ds寄存器的值(存储了页目录的基地址) 7366f67c6aSlogin * 7466f67c6aSlogin * @return unsigned* ds的值的指针 7566f67c6aSlogin */ 7666f67c6aSlogin unsigned long *get_ds() 7766f67c6aSlogin { 7866f67c6aSlogin uint64_t *tmp; 7966f67c6aSlogin __asm__ __volatile__( 8066f67c6aSlogin "movq %%ds, %0\n\t" 8166f67c6aSlogin : "=r"(tmp)::"memory"); 8266f67c6aSlogin return tmp; 8366f67c6aSlogin } 8466f67c6aSlogin 8566f67c6aSlogin /** 8666f67c6aSlogin * @brief 读取rax寄存器的值(存储了页目录的基地址) 8766f67c6aSlogin * 8866f67c6aSlogin * @return unsigned* rax的值的指针 8966f67c6aSlogin */ 9066f67c6aSlogin unsigned long *get_rax() 9166f67c6aSlogin { 9266f67c6aSlogin uint64_t *tmp; 9366f67c6aSlogin __asm__ __volatile__( 9466f67c6aSlogin "movq %%rax, %0\n\t" 9566f67c6aSlogin : "=r"(tmp)::"memory"); 9666f67c6aSlogin return tmp; 9766f67c6aSlogin } 9866f67c6aSlogin /** 9966f67c6aSlogin * @brief 读取rbx寄存器的值(存储了页目录的基地址) 10066f67c6aSlogin * 10166f67c6aSlogin * @return unsigned* rbx的值的指针 10266f67c6aSlogin */ 10366f67c6aSlogin unsigned long *get_rbx() 10466f67c6aSlogin { 10566f67c6aSlogin uint64_t *tmp; 10666f67c6aSlogin __asm__ __volatile__( 10766f67c6aSlogin "movq %%rbx, %0\n\t" 10866f67c6aSlogin : "=r"(tmp)::"memory"); 10966f67c6aSlogin return tmp; 11066f67c6aSlogin } 11166f67c6aSlogin 11266f67c6aSlogin // ========= MSR寄存器组操作 ============= 11366f67c6aSlogin /** 11466f67c6aSlogin * @brief 向msr寄存器组的address处的寄存器写入值value 11566f67c6aSlogin * 11666f67c6aSlogin * @param address 地址 11766f67c6aSlogin * @param value 要写入的值 11866f67c6aSlogin */ 11966f67c6aSlogin void wrmsr(uint64_t address, uint64_t value) 12066f67c6aSlogin { 12166f67c6aSlogin __asm__ __volatile__("wrmsr \n\t" ::"d"(value >> 32), "a"(value & 0xffffffff), "c"(address) 12266f67c6aSlogin : "memory"); 12366f67c6aSlogin } 12466f67c6aSlogin 12566f67c6aSlogin /** 12666f67c6aSlogin * @brief 从msr寄存器组的address地址处读取值 12766f67c6aSlogin * rdmsr返回高32bits在edx,低32bits在eax 12866f67c6aSlogin * @param address 地址 12966f67c6aSlogin * @return uint64_t address处的寄存器的值 13066f67c6aSlogin */ 13166f67c6aSlogin uint64_t rdmsr(uint64_t address) 13266f67c6aSlogin { 13366f67c6aSlogin unsigned int tmp0, tmp1; 13466f67c6aSlogin __asm__ __volatile__("rdmsr \n\t" 13566f67c6aSlogin : "=d"(tmp0), "=a"(tmp1) 13666f67c6aSlogin : "c"(address) 13766f67c6aSlogin : "memory"); 13866f67c6aSlogin return ((uint64_t)tmp0 << 32) | tmp1; 13966f67c6aSlogin } 14066f67c6aSlogin 14166f67c6aSlogin uint64_t get_rflags() 14266f67c6aSlogin { 14366f67c6aSlogin unsigned long tmp = 0; 14466f67c6aSlogin __asm__ __volatile__("pushfq \n\t" 14566f67c6aSlogin "movq (%%rsp), %0 \n\t" 14666f67c6aSlogin "popfq \n\t" 14766f67c6aSlogin : "=r"(tmp)::"memory"); 14866f67c6aSlogin return tmp; 14966f67c6aSlogin }