#pragma once #include #include namespace assembly { inline static std::uint64_t rdmsr(std::uint32_t msr) { std::uint32_t lo, hi; __asm__ volatile ("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr)); return ((std::uint64_t)hi << 32) | lo; } inline static void wrmsr(std::uint32_t msr, std::uint64_t value) { std::uint32_t lo = (uint32_t)(value & 0xFFFFFFFF); std::uint32_t hi = (uint32_t)(value >> 32); __asm__ volatile ("wrmsr" : : "c"(msr), "a"(lo), "d"(hi)); } inline static void cpuid(int code, int code2, std::uint32_t *a, std::uint32_t *b, std::uint32_t *c , std::uint32_t *d) { __asm__ volatile("cpuid":"=a"(*a),"=b"(*b),"=c"(*c),"=d"(*d):"a"(code),"c"(code2)); } inline static int cpuid_string(int code, std::uint32_t where[4]) { __asm__ volatile("cpuid":"=a"(*where),"=b"(*(where+1)),"=c"(*(where+2)),"=d"(*(where+3)):"a"(code)); return (int)where[0]; } inline static std::uint64_t rdtsc() { unsigned int hi, lo; __asm__ volatile ("rdtsc" : "=a"(lo), "=d"(hi)); return ((uint64_t)hi << 32) | lo; } inline static bool is_qemu() { uint32_t a,b,c,d; cpuid(0x40000000, 0, &a, &b, &c, &d); char hypervisorSignature[13]; ((uint32_t *)hypervisorSignature)[0] = b; ((uint32_t *)hypervisorSignature)[1] = c; ((uint32_t *)hypervisorSignature)[2] = d; hypervisorSignature[12] = '\0'; if (klibc::memcmp(hypervisorSignature, (void*)"TCGTCGTCGTCG", 12) == 0 || klibc::memcmp(hypervisorSignature, (void*)"KVMKVMKVM\0\0\0", 12) == 0) { return true; } return false; } };