DRNG::DRNG(void)
{
	int info[4];

	if (_drng_support != DRNG_SUPPORT_UNKNOWN) return;
	
	_drng_support= DRNG_SUPPORT_NONE;

	// Check our feature support

	__cpuid(info, 0);

	if ( memcmp(&(info[1]), "Genu", 4) ||
		memcmp(&(info[3]), "ineI", 4) ||
		memcmp(&(info[2]), "ntel", 4) ) return;

	__cpuidex(info, 1, 0);

	if ( ((UINT) info[2]) & (1<<30) ) _drng_support|= DRNG_SUPPORT_RDRAND;

#ifdef COMPILER_HAS_RDSEED_SUPPORT
	__cpuidex(info, 7, 0);

	if ( ((UINT) info[1]) & (1<<18) ) _drng_support|= DRNG_SUPPORT_RDSEED;
#endif
}
Пример #2
0
/// @todo docs
void init_cpuinfo(cpuinfo::impl& info)
{
    int registers[4];

    /// According to the msvc docs eax, ebx, ecx and edx are
    /// stored (in that order) in the array passed to the __cpuid
    /// function.

    // The register information per input can be extracted from here:
    // http://en.wikipedia.org/wiki/CPUID

    // CPUID should be called with EAX=0 first, as this will return the
    // maximum supported EAX input value for future calls
    __cpuid(registers, 0);
    uint32_t maximum_eax = registers[0];

    // Set registers for basic flag extraction, eax=1
    // All CPUs should support index=1
    if (maximum_eax >= 1U)
    {
        __cpuid(registers, 1);
        extract_x86_flags(info, registers[2], registers[3]);
    }

    // Set registers for extended flags extraction, eax=7 and ecx=0
    // This operation is not supported on older CPUs, so it should be skipped
    // to avoid incorrect results
    if (maximum_eax >= 7U)
    {
        __cpuidex(registers, 7, 0);
        extract_x86_extended_flags(info, registers[1]);
    }
}
Пример #3
0
static unsigned init_caps(void) {
  unsigned int caps = 0;

  union {
    struct {
      unsigned int eax, ebx, ecx, edx;
    };
    int data[4];
  } regs = {0};

  __cpuid(regs.data, 0);
  unsigned int max = regs.eax;

  if (max >= 1) {
    __cpuid(regs.data, 0);
    if (regs.edx & (1 << 26)) {
      caps |= CPU_CAP_SSE2;
    }
    if (regs.ecx & (1 << 19)) {
      caps |= CPU_CAP_SSE4_1;
    }
  }

  if (max >= 7) {
    __cpuidex(regs.data, 7, 0);
    if (regs.ebx & (1 << 5)) {
      caps |= CPU_CAP_AVX2;
    }
  }

  return caps;
}
Пример #4
0
_Use_decl_annotations_ bool EptIsEptAvailable() {
  PAGED_CODE();

  int regs[4] = {};
  __cpuidex(regs, 0x80000008, 0);
  Cpuid80000008Eax cpuidEax = {static_cast<ULONG32>(regs[0])};
  HYPERPLATFORM_LOG_DEBUG("Physical Address Range = %d bits",
                          cpuidEax.fields.physical_address_bits);

  // No processors supporting the Intel 64 architecture support more than 48
  // physical-address bits
  if (cpuidEax.fields.physical_address_bits > 48) {
    return false;
  }

  // page walk length is 4 steps
  // extended page tables can be laid out in write-back memory
  // INVEPT instruction with all possible types is supported
  Ia32VmxEptVpidCapMsr vpid = {UtilReadMsr64(Msr::kIa32VmxEptVpidCap)};
  if (!vpid.fields.support_page_walk_length4 ||
      !vpid.fields.support_write_back_memory_type ||
      !vpid.fields.support_invept ||
      !vpid.fields.support_single_context_invept ||
      !vpid.fields.support_all_context_invept) {
    return false;
  }
  return true;
}
Пример #5
0
VOID
ShvVpUninitialize (
    _In_ PSHV_VP_DATA VpData
    )
{
    INT dummy[4];
    UNREFERENCED_PARAMETER(VpData);

    //
    // Send the magic shutdown instruction sequence
    //
    __cpuidex(dummy, 0x41414141, 0x42424242);

    //
    // The processor will return here after the hypervisor issues a VMXOFF
    // instruction and restores the CPU context to this location. Unfortunately
    // because this is done with RtlRestoreContext which returns using "iretq",
    // this causes the processor to remove the RPL bits off the segments. As
    // the x64 kernel does not expect kernel-mode code to chang ethe value of
    // any segments, this results in the DS and ES segments being stuck 0x20,
    // and the FS segment being stuck at 0x50, until the next context switch.
    //
    // If the DPC happened to have interrupted either the idle thread or system
    // thread, that's perfectly fine (albeit unusual). If the DPC interrupted a
    // 64-bit long-mode thread, that's also fine. However if the DPC interrupts
    // a thread in compatibility-mode, running as part of WoW64, it will hit a
    // GPF instantenously and crash.
    //
    // Thus, set the segments to their correct value, one more time, as a fix.
    //
    ShvVmxCleanup(KGDT64_R3_DATA | RPL_MASK, KGDT64_R3_CMTEB | RPL_MASK);
}
Пример #6
0
// __asm__ blocks are only checked for inline functions that end up being
// emitted, so call functions with __asm__ blocks to make sure their inline
// assembly parses.
void f() {
  __movsb(0, 0, 0);
  __movsd(0, 0, 0);
  __movsw(0, 0, 0);

  __stosd(0, 0, 0);
  __stosw(0, 0, 0);

#ifdef _M_X64
  __movsq(0, 0, 0);
  __stosq(0, 0, 0);
#endif

  int info[4];
  __cpuid(info, 0);
  __cpuidex(info, 0, 0);
  _xgetbv(0);
  __halt();
  __nop();
  __readmsr(0);

  // FIXME: Call these in 64-bit too once the intrinsics have been fixed to
  // work there, PR19301
#ifndef _M_X64
  __readcr3();
  __writecr3(0);
#endif

#ifdef _M_ARM
  __dmb(_ARM_BARRIER_ISHST);
#endif
}
Пример #7
0
static inline void get_cpuid2(int *array, int info_type, int ecx)
{
#if defined(_MSC_VER)
    __cpuidex(array, info_type, ecx);
#else
    __cpuid_count(info_type, ecx, array[0], array[1], array[2], array[3]);
#endif
}
Пример #8
0
  inline void cpuidex(register_type pRegisters[4], int function, int subfunction) {
#if defined(BOOST_SIMD_CPUID_HEADER)
    __cpuid_count ( function, subfunction
                  , pRegisters[eax], pRegisters[ebx], pRegisters[ecx], pRegisters[edx]
                  );
#else
  __cpuidex(pRegisters, function, subfunction);
#endif
  }
Пример #9
0
/* I hate this. */
BOOL cpuid(uint32_t *_eax, uint32_t *_ebx, uint32_t *_ecx, uint32_t *_edx)
{
	uint32_t regs[4];
	__cpuidex(regs, *_eax, *_ecx);
	*_eax = regs[0];
	*_ebx = regs[1];
	*_ecx = regs[2];
	*_edx = regs[3];
	return TRUE;
}
Пример #10
0
String GetProcessorInfo()
{
    char brand[0x40] = {};
    int cpui[4] = { -1 };

    __cpuidex(cpui, 0x80000002, 0);

    //unsigned int blocks = cpui[0];
    for (int i = 0; i <= 2; ++i)
    {
        __cpuidex(cpui, 0x80000002 + i, 0);
        *reinterpret_cast<int*>(brand + i * 16) = cpui[0];
        *reinterpret_cast<int*>(brand + 4 + i * 16) = cpui[1];
        *reinterpret_cast<int*>(brand + 8 + i * 16) = cpui[2];
        *reinterpret_cast<int*>(brand + 12 + i * 16) = cpui[3];

    }
    return String(brand, 0x40);
}
Пример #11
0
 static bool internal_cpuid(int32_t out[4], int32_t x)
 {
   #if defined __GNUC__
   __cpuid_count(x, 0, out[0], out[1], out[2], out[3]);
   return true;
   #endif
   #if defined _MSC_VER
   __cpuidex(out, x, 0);
   return true;
   #endif
   return false;
 }
Пример #12
0
void init_functions ()
{
    int out [4];

    __cpuid (out, 1);

    BOOL sse42 = (out [2] & (1 << 20)) != 0;
    BOOL sse41 = (out [2] & (1 << 19)) != 0;
    BOOL fma = (out [2] & (1 << 12)) != 0;
    BOOL avx = (out [2] & (1 << 28)) != 0;
    BOOL osxsave = (out [2] & (1 << 29)) != 0;

    __cpuidex (out, 7, 0);
    BOOL avx2 = (out [1] & 0x20) != 0;

    int i = 0;
    funcs [i] = calculate_float; method_names [i] = "float"; if (full_mode) i++;

    if (sse42) {
        funcs [i] = calculate_sse_float; method_names [i] = "float SSE"; if (full_mode) i++;
    }
    if (osxsave && avx) {
        funcs [i] = calculate_avx_float; method_names [i] = "float AVX"; if (full_mode) i++;
    }
    if (osxsave && avx && avx2) {
        funcs [i] = calculate_avx2_float; method_names [i] = "float AVX2"; if (full_mode) i++;
    }
    if (osxsave && avx && avx2 && fma) {
        funcs [i] = calculate_fma_float; method_names [i] = "float FMA"; if (full_mode) i++;
    }
    if (!full_mode) i++;

    funcs [i] = calculate_double; method_names [i] = "double"; if (full_mode) i++;

    if (sse42) {
        funcs [i] = calculate_sse_double; method_names [i] = "double SSE"; if (full_mode) i++;
    }
    if (osxsave && avx) {
        funcs [i] = calculate_avx_double; method_names [i] = "double AVX"; if (full_mode) i++;
    }
    if (osxsave && avx && avx2) {
        funcs [i] = calculate_avx2_double; method_names [i] = "double AVX2"; if (full_mode) i++;
    }
    if (osxsave && avx && avx2 && fma) {
        funcs [i] = calculate_fma_double; method_names [i] = "double FMA"; if (full_mode) i++;
    }
    if (!full_mode) i++;

    func_count = i;
    func_index = 0;
    calculate_func = funcs [func_index];
}
Пример #13
0
CPUInfo __stdcall cpuidex(int InfoType, int ECXValue)
{
	int results[4];
	__cpuidex(results, InfoType, ECXValue);

	CPUInfo i;
	i.Part1 = results[0];
	i.Part2 = results[1];
	i.Part3 = results[2];
	i.Part4 = results[3];

	return i;
}
Пример #14
0
Файл: hw.c Проект: yoanlcq/FATE
 void fe_hw_x86_cpuidex(uint32_t leaf, uint32_t subleaf, 
                        uint32_t *eax, uint32_t *ebx, 
                        uint32_t *ecx, uint32_t *edx) {
 #if (defined(__GNUC__) || defined(__clang__))
     __cpuid_count(leaf, subleaf, eax, ebx, ecx, edx);
 #elif defined(_MSC_VER)
     int regs[4];
     __cpuidex(regs, leaf, subleaf);
     *eax = regs[0];
     *ebx = regs[1];
     *ecx = regs[2];
     *edx = regs[3];
 #else
 #error "No cpuid intrinsic for this target !"
 #endif
 }
Пример #15
0
VOID
ShvVmxHandleCpuid (
    _In_ PSHV_VP_STATE VpState
    )
{
    INT cpu_info[4];

    //
    // Check for the magic CPUID sequence, and check that it is is coming from
    // Ring 0. Technically we could also check the RIP and see if this falls
    // in the expected function, but we may want to allow a sepaarate "unload"
    // driver or code at some point.
    //
    if ((VpState->VpRegs->Rax == 0x41414141) &&
        (VpState->VpRegs->Rcx == 0x42424242) &&
        ((ShvVmxRead(GUEST_CS_SELECTOR) & RPL_MASK) == DPL_SYSTEM))
    {
        VpState->ExitVm = TRUE;
        return;
    }

    //
    // Otherwise, issue the CPUID to the logical processor based on the indexes
    // on the VP's GPRs.
    //
    __cpuidex(cpu_info, (INT)VpState->VpRegs->Rax, (INT)VpState->VpRegs->Rcx);

    //
    // Check if this was CPUID 1h, which is the features request.
    //
    if (VpState->VpRegs->Rax == 1)
    {
        //
        // Set the Hypervisor Present-bit in RCX, which Intel and AMD have both
        // reserved for this indication.
        //
        cpu_info[2] |= 0x80000000;
    }

    //
    // Copy the values from the logical processor registers into the VP GPRs.
    //
    VpState->VpRegs->Rax = cpu_info[0];
    VpState->VpRegs->Rbx = cpu_info[1];
    VpState->VpRegs->Rcx = cpu_info[2];
    VpState->VpRegs->Rdx = cpu_info[3];
}
Пример #16
0
	CCpuAccel()
	{
		int info[4];

		__cpuid(info, 0x00000000);
		int Basic = info[0];
		__cpuid(info, 0x00000001);
		if (info[3] & 0x00800000)
			m_Supported |= ACCEL_MMX;
		if (info[3] & 0x02000000)
			m_Supported |= ACCEL_SSE;
		if (info[3] & 0x04000000)
			m_Supported |= ACCEL_SSE2;
		if (info[2] & 0x00000001)
			m_Supported |= ACCEL_SSE3;
		if (info[2] & 0x00000200)
			m_Supported |= ACCEL_SSSE3;
		if (info[2] & 0x00080000)
			m_Supported |= ACCEL_SSE4_1;
		if (info[2] & 0x00100000)
			m_Supported |= ACCEL_SSE4_2;
		if (info[2] & 0x10000000)
			m_Supported |= ACCEL_AVX;
		if (Basic >= 7) {
			__cpuidex(info, 7, 0);
			if (info[1] & 0x00000020)
				m_Supported |= ACCEL_AVX2;
		}

		bool fAVX = false;
		if (::IsProcessorFeaturePresent(PF_XSAVE_ENABLED)) {
			GetEnabledXStateFeatures_Ptr pGetEnabledXStateFeatures =
				(GetEnabledXStateFeatures_Ptr)
					::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),
									 "GetEnabledXStateFeatures");
			if (pGetEnabledXStateFeatures
					&& (pGetEnabledXStateFeatures() & XSTATE_MASK_AVX)) {
				fAVX = true;
			}
		}
		if (!fAVX)
			m_Supported &= ~(ACCEL_AVX | ACCEL_AVX2);

		m_Enabled = m_Supported;
	}
Пример #17
0
void X86CpuUtil::callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* outResult) {

#ifdef _MSC_VER
// 2009-02-05: Thanks to Mike Tajmajer for supporting VC7.1 compiler.
// ASMJIT_HOST_X64 is here only for readibility, only VS2005 can compile 64-bit code.
# if _MSC_VER >= 1400 || defined(ASMJIT_HOST_X64)
  // Done by intrinsics.
  __cpuidex(reinterpret_cast<int*>(outResult->i), inEax, inEcx);
# else // _MSC_VER < 1400
  uint32_t cpuid_eax = inEax;
  uint32_t cpuid_ecx = inCax;
  uint32_t* cpuid_out = outResult->i;

  __asm {
    mov     eax, cpuid_eax
    mov     ecx, cpuid_ecx
    mov     edi, cpuid_out
    cpuid
    mov     dword ptr[edi +  0], eax
    mov     dword ptr[edi +  4], ebx
    mov     dword ptr[edi +  8], ecx
    mov     dword ptr[edi + 12], edx
  }
# endif // _MSC_VER < 1400

#elif defined(__GNUC__)
// Note, patched to preserve ebx/rbx register which is used by GCC.
# if defined(ASMJIT_HOST_X86)
#  define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \
  asm ("mov %%ebx, %%edi\n"  \
       "cpuid\n"             \
       "xchg %%edi, %%ebx\n" \
       : "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) : "a" (inEax), "c" (inEcx))
# else
#  define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \
  asm ("mov %%rbx, %%rdi\n"  \
       "cpuid\n"             \
       "xchg %%rdi, %%rbx\n" \
       : "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) : "a" (inEax), "c" (inEcx))
# endif
  __myCpuId(inEax, inEcx, outResult->eax, outResult->ebx, outResult->ecx, outResult->edx);
#endif // COMPILER
}
Пример #18
0
// CPUID
_Use_decl_annotations_ static void VmmpHandleCpuid(
    GuestContext *guest_context) {
  HYPERPLATFORM_PERFORMANCE_MEASURE_THIS_SCOPE();
  unsigned int cpu_info[4] = {};
  const auto function_id = static_cast<int>(guest_context->gp_regs->ax);
  const auto sub_function_id = static_cast<int>(guest_context->gp_regs->cx);

  if (function_id == 0 && sub_function_id == kHyperPlatformVmmBackdoorCode) {
    // Say "Pong by VMM!" when the back-door code was given
    guest_context->gp_regs->bx = 'gnoP';
    guest_context->gp_regs->dx = ' yb ';
    guest_context->gp_regs->cx = '!MMV';
  } else {
    __cpuidex(reinterpret_cast<int *>(cpu_info), function_id, sub_function_id);
    guest_context->gp_regs->ax = cpu_info[0];
    guest_context->gp_regs->bx = cpu_info[1];
    guest_context->gp_regs->cx = cpu_info[2];
    guest_context->gp_regs->dx = cpu_info[3];
  }

  VmmpAdjustGuestInstructionPointer(guest_context->ip);
}
Пример #19
0
		InstructionSet_Internal()
			: nIds_{ 0 },
			nExIds_{ 0 },
			isIntel_{ false },
			isAMD_{ false },
			f_1_ECX_{ 0 },
			f_1_EDX_{ 0 },
			f_7_EBX_{ 0 },
			f_7_ECX_{ 0 },
			f_81_ECX_{ 0 },
			f_81_EDX_{ 0 },
			data_{},
			extdata_{}
		{
			//int cpuInfo[4] = {-1};
			std::array<int, 4> cpui;

			// Calling __cpuid with 0x0 as the function_id argument
			// gets the number of the highest valid function ID.
			__cpuid(cpui.data(), 0);
			nIds_ = cpui[0];

			for (int i = 0; i <= nIds_; ++i)
			{
				__cpuidex(cpui.data(), i, 0);
				data_.push_back(cpui);
			}

			// Capture vendor string
			char vendor[0x20];
			memset(vendor, 0, sizeof(vendor));
			*reinterpret_cast<int*>(vendor) = data_[0][1];
			*reinterpret_cast<int*>(vendor + 4) = data_[0][3];
			*reinterpret_cast<int*>(vendor + 8) = data_[0][2];
			vendor_ = vendor;
			if (vendor_ == "GenuineIntel")
			{
				isIntel_ = true;
			}
			else if (vendor_ == "AuthenticAMD")
			{
				isAMD_ = true;
			}

			// load bitset with flags for function 0x00000001
			if (nIds_ >= 1)
			{
				f_1_ECX_ = data_[1][2];
				f_1_EDX_ = data_[1][3];
			}

			// load bitset with flags for function 0x00000007
			if (nIds_ >= 7)
			{
				f_7_EBX_ = data_[7][1];
				f_7_ECX_ = data_[7][2];
			}

			// Calling __cpuid with 0x80000000 as the function_id argument
			// gets the number of the highest valid extended ID.
			__cpuid(cpui.data(), 0x80000000);
			nExIds_ = cpui[0];

			char brand[0x40];
			memset(brand, 0, sizeof(brand));

			for (int i = 0x80000000; i <= nExIds_; ++i)
			{
				__cpuidex(cpui.data(), i, 0);
				extdata_.push_back(cpui);
			}

			// load bitset with flags for function 0x80000001
			if (nExIds_ >= 0x80000001)
			{
				f_81_ECX_ = extdata_[1][2];
				f_81_EDX_ = extdata_[1][3];
			}

			// Interpret CPU brand string if reported
			if (nExIds_ >= 0x80000004)
			{
				memcpy(brand, extdata_[2].data(), sizeof(cpui));
				memcpy(brand + 16, extdata_[3].data(), sizeof(cpui));
				memcpy(brand + 32, extdata_[4].data(), sizeof(cpui));
				brand_ = brand;
			}
		};
Пример #20
0
int CALLBACK WinMain(
    HINSTANCE   hInstance,
    HINSTANCE   hPrevInstance,
    LPSTR       lpCmdLine,
    int         nCmdShow)
{
    s_gameFuncs = LoadGameFuncs();
    assert(s_gameFuncs.valid);

    ImGuiIO& io = ImGui::GetIO();
    //io.MemAllocFn = memory::malloc;
    //io.MemFreeFn = memory::free;

    //_crtBreakAlloc = 4015;
    s_queue = new util::ThreadSafeQueue<WindowEvent>();

    g_LogInfo(SL_BUILD_DATE);

    // Log CPU features
    {
#if 0
        struct CPUInfo {
            union {
                int i[4];
            };
        } info = { 0 };

        // Get number of functions
        __cpuid(info.i, 0);
        int nIds_ = info.i[0];

        // Dump info
        std::vector<CPUInfo> data;
        for (int i = 0; i <= nIds_; ++i)
        {
            __cpuidex(info.i, i, 0);
            data.push_back(info);
        }

        // Vendor
        if(data.size() >= 0) {
            char vendor[13] = {0};
            memcpy(vendor + 0, data[0].i + 1, 4);
            memcpy(vendor + 4, data[0].i + 3, 4);
            memcpy(vendor + 8, data[0].i + 2, 4);
            g_LogInfo("CPU Vendor: " + std::string(vendor));
        }
#endif
        // http://stackoverflow.com/questions/850774/how-to-determine-the-hardware-cpu-and-ram-on-a-machine
        int CPUInfo[4] = { 0 };
        char CPUBrandString[0x40];
        // Get the information associated with each extended ID.
        __cpuid(CPUInfo, 0x80000000);
        int nExIds = CPUInfo[0];
        for (int i = 0x80000000; i <= nExIds; i++)
        {
            __cpuid(CPUInfo, i);
            // Interpret CPU brand string
            if  (i == 0x80000002)
                memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
            else if  (i == 0x80000003)
                memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
            else if  (i == 0x80000004)
                memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
        }
        //string includes manufacturer, model and clockspeed
        std::string brand(CPUBrandString);
        g_LogInfo(brand.substr(brand.find_first_not_of(" ")));

        SYSTEM_INFO sysInfo;
        GetSystemInfo(&sysInfo);
        g_LogInfo("Logical processors: " + std::to_string(sysInfo.dwNumberOfProcessors));

        MEMORYSTATUSEX statex;
        statex.dwLength = sizeof (statex);
        GlobalMemoryStatusEx(&statex);
        g_LogInfo("Total System Memory: " + std::to_string(statex.ullTotalPhys/1024/1024) + " MB");
    }

    auto className = L"StarlightClassName";

    WNDCLASSEXW wndClass = { 0 };
    wndClass.cbSize = sizeof(WNDCLASSEXW);
    wndClass.style = CS_CLASSDC;
    wndClass.lpfnWndProc = WndProc;
    wndClass.hInstance = GetModuleHandleW(nullptr);
    wndClass.hCursor = LoadCursorW(nullptr, IDC_ARROW);
    wndClass.lpszClassName = className;

    RegisterClassExW(&wndClass);

    // Get desktop rectangle
    RECT desktopRect;
    GetClientRect(GetDesktopWindow(), &desktopRect);

    // Get window rectangle
    RECT windowRect = { 0, 0, 800, 600 }; // TODO: Config file?
    AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE);

    // Calculate window dimensions
    LONG windowWidth = windowRect.right - windowRect.left;
    LONG windowHeight = windowRect.bottom - windowRect.top;
    LONG x = desktopRect.right / 2 - windowWidth / 2;
    LONG y = desktopRect.bottom / 2 - windowHeight / 2;

#ifdef _DEBUG
    // Move the screen to the right monitor on JOTARO
    wchar_t computerName[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD dwSize = sizeof(computerName);
    GetComputerNameW(computerName, &dwSize);
    if (wcscmp(computerName, L"JOTARO") == 0) {
        x += 1920;
    }
#endif

    s_config.Load();

    s_hwnd = CreateWindowExW(
        0L,
        className,
        L"Starlight",
        WS_OVERLAPPEDWINDOW,
        x,
        y,
        windowWidth,
        windowHeight,
        nullptr,
        nullptr,
        GetModuleHandleW(nullptr),
        nullptr
        );

    // Show the window
    ShowWindow(s_hwnd, SW_MAXIMIZE);
    UpdateWindow(s_hwnd);

    // Create thread
    s_running.store(true);
    unsigned int threadID;
    HANDLE thread = (HANDLE) _beginthreadex(nullptr, 0, MyThreadFunction, nullptr, 0, &threadID);
    if (!thread) {
        // Error creating thread
        return 1;
    }

    // Watch Lua directory
    hDirectoryChange = FindFirstChangeNotification(L"../starlight/", TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE);
    if (!hDirectoryChange) {
        g_LogInfo("Error creating directory change notification handle: Lua reload on save will not work.");
    }

    // Message loop
    MSG msg;
    while (s_running.load() && GetMessageW(&msg, nullptr, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }

    WaitForSingleObject(thread, INFINITE);
    CloseHandle(thread);

    if (hDirectoryChange) {
        if (!FindCloseChangeNotification(hDirectoryChange)) {
            g_LogInfo("Failed to close directory change notification handle.");
        }
    }

    s_gameFuncs.DestroyLogger();

    io.Fonts->Clear();

    s_config.Save();

    delete s_queue;

    UnregisterClassW(className, GetModuleHandleW(nullptr));

    _CrtDumpMemoryLeaks();

    return 0;
}
Пример #21
0
void dbt_cpuid(int eax, int ecx, struct cpuid_t *cpuid)
{
	int cpuinfo[4];
	__cpuidex(cpuinfo, eax, ecx);
	cpuid->eax = cpuinfo[0];
	cpuid->ebx = cpuinfo[1];
	cpuid->ecx = cpuinfo[2];
	cpuid->edx = cpuinfo[3];
	/* Mangle cpu feature bits, omit unsupported features  */
	if (eax == 0x01)
	{
		/* Feature information */
		cpuid->edx &= (0
			| FEATURE_FPU
			| FEATURE_VME
			| FEATURE_DE
			| FEATURE_PSE
			| FEATURE_TSC
			| FEATURE_MSR
			| FEATURE_PAE
			| FEATURE_MCE
			| FEATURE_CX8
			| FEATURE_APIC
			//| FEATURE_SEP
			| FEATURE_MTRR
			| FEATURE_PGE
			| FEATURE_MCA
			| FEATURE_CMOV
			| FEATURE_PAT
			| FEATURE_PSE_36
			| FEATURE_PSN
			| FEATURE_CLFSH
			| FEATURE_DS
			| FEATURE_ACPI
			| FEATURE_MMX
			| FEATURE_FXSR
			| FEATURE_SSE
			| FEATURE_SSE2
			| FEATURE_SS
			| FEATURE_HTT
			| FEATURE_TM
			| FEATURE_IA64
			| FEATURE_PBE
			);
		cpuid->ecx &= (0
			| FEATURE_SSE3
			//| FEATURE_PCLMULQDQ
			| FEATURE_DTES64
			| FEATURE_MONITOR
			| FEATURE_DS_CPL
			| FEATURE_VMX
			| FEATURE_SMX
			| FEATURE_EST
			| FEATURE_TM2
			| FEATURE_SSSE3
			| FEATURE_CNXT_ID
			//| FEATURE_FMA
			//| FEATURE_CMPXCHG16B
			| FEATURE_XTPR
			| FEATURE_PDCM
			| FEATURE_PCID
			| FEATURE_DCA
			| FEATURE_SSE41
			| FEATURE_SSE42
			| FEATURE_X2APIC
			| FEATURE_MOVBE
			| FEATURE_POPCNT
			| FEATURE_TSC_DEADLINE
			//| FEATURE_AES
			//| FEATURE_XSAVE
			//| FEATURE_OSXSAVE
			//| FEATURE_AVX
			//| FEATURE_F16C
			//| FEATURE_RDRAND
			| FEATURE_HYPERVISOR
			);
	}
	else if (eax == 0x80000001)
	{
		/* Extended function */
		cpuid->edx &= (0
			| FEATURE_SYSCALL
			| FEATURE_NX
			//| FEATURE_MMXEXT
			//| FEATURE_FXSR_OPT
			| FEATURE_GPAGE
			//| FEATURE_RDTSCP
			| FEATURE_64
			//| FEATURE_3DNOWEXT
			//| FEATURE_3DNOW
			);
		/* AMD extensions */
		cpuid->ecx &= (0
			| FEATURE_LAHF
			//| FEATURE_CMP_LEGACY
			//| FEATURE_SVM
			//| FEATURE_EXTAPIC
			//| FEATURE_CR8_LEGACY
			//| FEATURE_ABM
			//| FEATURE_SSE4A
			//| FEATURE_MISALIGNSSE
			//| FEATURE_3DNOWPREFETCH
			//| FEATURE_OSVW
			//| FEATURE_IBS
			//| FEATURE_XOP
			//| FEATURE_SKINIT
			//| FEATURE_WDT
			//| FEATURE_LWP
			//| FEATURE_FMA4
			//| FEATURE_TCE
			//| FEATURE_NODEID_MSR
			//| FEATURE_TBM
			//| FEATURE_TOPOEXT
			//| FEATURE_PERFCTR_CORE
			//| FEATURE_PERFCTR_NB
			//| FEATURE_BPEXT
			//| FEATURE_PERFCTR_L2
			);
	}
	else if (eax == 0x07)
	{
		/* Structured extended feature flags */
		if (ecx == 0x00)
		{
			cpuid->eax = 0;
			cpuid->ebx &= (0
				//| FEATURE_FSGSBASE
				| FEATURE_TSC_ADJUST
				//| FEATURE_BMI1
				//| FEATURE_HLE
				//| FEATURE_AVX2
				| FEATURE_SMEP
				//| FEATURE_BMI2
				| FEATURE_ERMS
				//| FEATURE_INVPCID
				//| FEATURE_RTM
				//| FEATURE_MPX
				//| FEATURE_AVX512F
				//| FEATURE_RDSEED
				//| FEATURE_ADX
				//| FEATURE_SMAP
				//| FEATURE_CLFLUSHOPT
				//| FEATURE_AVX512PF
				//| FEATURE_AVX512ER
				//| FEATURE_AVX512CD
				);
			cpuid->ecx = 0;
			cpuid->edx = 0;
		}
		else
			cpuid->eax = cpuid->ebx = cpuid->ecx = cpuid->edx = 0;
	}
}
Пример #22
0
static void cpuid(int32_t out[4], int32_t x) {
    __cpuidex(out,x,0);
}
Пример #23
0
NTSTATUS
DriverDeviceControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{

    NTSTATUS           Status = STATUS_UNSUCCESSFUL;
    PIO_STACK_LOCATION IrpSp;
    ULONG              IOControlCode = 0;
    ULONG              dwBytesWritten = 0;
    PCHAR              pInBuf = NULL, pOutBuf = NULL;
    unsigned int       _cpu_thread_id = 0;
    unsigned int       new_cpu_thread_id = 0;
    ULONG              _num_active_cpus = 0;
    KAFFINITY          _kaffinity = 0;
    UINT32             core_id = 0;

    //
    // Get the current IRP stack location of this request
    //
    IrpSp = IoGetCurrentIrpStackLocation (Irp);
    IOControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;

    DbgPrint( "[chipsec] >>>>>>>>>> IOCTL >>>>>>>>>>\n" );
    DbgPrint( "[chipsec] DeviceObject = 0x%x IOCTL = 0x%x\n", DeviceObject, IOControlCode );
    DbgPrint( "[chipsec] InputBufferLength = 0x%x, OutputBufferLength = 0x%x\n", IrpSp->Parameters.DeviceIoControl.InputBufferLength, IrpSp->Parameters.DeviceIoControl.OutputBufferLength );

    //
    // CPU thread ID
    // 
    _num_active_cpus = KeQueryActiveProcessorCount( NULL );
    _kaffinity       = KeQueryActiveProcessors();
    _cpu_thread_id   = KeGetCurrentProcessorNumber();
    DbgPrint( "[chipsec] Active CPU threads         : %d (KeNumberProcessors = %d)\n", _num_active_cpus, KeNumberProcessors );
    DbgPrint( "[chipsec] Active CPU mask (KAFFINITY): 0x%08X\n", _kaffinity );
    DbgPrint( "[chipsec] Current CPU thread         : %d\n", _cpu_thread_id );

    //
    // Switch on the IOCTL code that is being requested by the user.  If the
    // operation is a valid one for this device do the needful.
    //
    Irp -> IoStatus.Information = 0;
    switch( IOControlCode )
      {
        case READ_PCI_CFG_REGISTER:
          {
            DWORD val;
            BYTE size = 0;
            WORD bdf[4];
            BYTE bus = 0, dev = 0, fun = 0, off = 0;
            DbgPrint( "[chipsec] > READ_PCI_CFG_REGISTER\n" );

            RtlCopyBytes( bdf,Irp->AssociatedIrp.SystemBuffer, 4*sizeof(WORD) );
            RtlCopyBytes( &size, (BYTE*)Irp->AssociatedIrp.SystemBuffer + 4*sizeof(WORD), sizeof(BYTE) );
            bus = (UINT8)bdf[0];
            dev = (UINT8)bdf[1];
            fun = (UINT8)bdf[2];
            off = (UINT8)bdf[3];

            if( 1 != size && 2 != size && 4 != size)
              {
              DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER\n" );
              Status = STATUS_INVALID_PARAMETER;
              break;
              }
            val = ReadPCICfg( bus, dev, fun, off, size );             

            IrpSp->Parameters.Read.Length = size;
            RtlCopyBytes( Irp->AssociatedIrp.SystemBuffer, (VOID*)&val, size );
            DbgPrint( "[chipsec][READ_PCI_CFG_REGISTER] B/D/F: %#04x/%#04x/%#04x, OFFSET: %#04x, value = %#010x (size = 0x%x)\n", bus, dev, fun, off, val, size );

            dwBytesWritten = IrpSp->Parameters.Read.Length;
            Status = STATUS_SUCCESS;
            break;
          }
        case WRITE_PCI_CFG_REGISTER:
          {
            DWORD val = 0;
            WORD bdf[6];
            BYTE bus = 0, dev = 0, fun = 0, off = 0;
            BYTE size = 0;
            DbgPrint( "[chipsec] > WRITE_PCI_CFG_REGISTER\n" );

            RtlCopyBytes( bdf, Irp->AssociatedIrp.SystemBuffer, 6 * sizeof(WORD) );
            bus = (UINT8)bdf[0];
            dev = (UINT8)bdf[1];
            fun = (UINT8)bdf[2];
            off = (UINT8)bdf[3];
            RtlCopyBytes( &size, (BYTE*)Irp->AssociatedIrp.SystemBuffer + 6*sizeof(WORD), sizeof(BYTE) );

            val = ((DWORD)bdf[5] << 16) | bdf[4];
            DbgPrint( "[chipsec][WRITE_PCI_CFG_REGISTER] B/D/F: %#02x/%#02x/%#02x, OFFSET: %#02x, value = %#010x (size = %#02x)\n", bus, dev, fun, off, val, size );
            WritePCICfg( bus, dev, fun, off, size, val );

            Status = STATUS_SUCCESS;
            break;
          }
        case IOCTL_READ_PHYSMEM:
          {
            UINT32 len = 0;
            PVOID virt_addr;
            PHYSICAL_ADDRESS phys_addr = { 0x0, 0x0 };

            DbgPrint( "[chipsec] > IOCTL_READ_PHYSMEM\n" );
            if( !Irp->AssociatedIrp.SystemBuffer ||
                IrpSp->Parameters.DeviceIoControl.InputBufferLength < 3*sizeof(UINT32))
              {
                DbgPrint( "[chipsec][IOCTL_READ_PHYSMEM] ERROR: STATUS_INVALID_PARAMETER\n" );
                Status = STATUS_INVALID_PARAMETER;
                break;
              }

            pInBuf = Irp->AssociatedIrp.SystemBuffer;
            pOutBuf = Irp->AssociatedIrp.SystemBuffer;

            phys_addr.HighPart = ((UINT32*)pInBuf)[0];
            phys_addr.LowPart  = ((UINT32*)pInBuf)[1];
            len                = ((UINT32*)pInBuf)[2];
            if( !len ) len = 4;

            if( IrpSp->Parameters.DeviceIoControl.OutputBufferLength < len )
              {
                DbgPrint( "[chipsec][IOCTL_READ_PHYSMEM] ERROR: STATUS_BUFFER_TOO_SMALL\n" );
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
              }

            __try
              {
                Status = _read_phys_mem( phys_addr, len, pOutBuf );
              }
            __except (EXCEPTION_EXECUTE_HANDLER)
              {
                Status = GetExceptionCode();
                DbgPrint( "[chipsec][IOCTL_READ_PHYSMEM] ERROR: exception code 0x%X\n", Status );
                break;
              }

            if( NT_SUCCESS(Status) )
              {
                DbgPrint( "[chipsec][IOCTL_READ_PHYSMEM] Contents:\n" );
                _dump_buffer( (unsigned char *)pOutBuf, min(len,0x100) );
                dwBytesWritten = len;
              }
            break;
          }
        case IOCTL_WRITE_PHYSMEM:
          {
            UINT32 len = 0;
            PVOID virt_addr = 0;
            PHYSICAL_ADDRESS phys_addr = { 0x0, 0x0 };

            DbgPrint( "[chipsec] > IOCTL_WRITE_PHYSMEM\n" );
            if( Irp->AssociatedIrp.SystemBuffer )
              {
                pInBuf = Irp->AssociatedIrp.SystemBuffer;
                pOutBuf = Irp->AssociatedIrp.SystemBuffer;

                if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < 3*sizeof(UINT32) )
                  {
                    DbgPrint( "[chipsec][IOCTL_WRITE_PHYSMEM] ERROR: STATUS_INVALID_PARAMETER\n" );
                    Status = STATUS_INVALID_PARAMETER;
                    break;
                  }

                phys_addr.HighPart = ((UINT32*)pInBuf)[0];
                phys_addr.LowPart  = ((UINT32*)pInBuf)[1];
                len                = ((UINT32*)pInBuf)[2];
                ((UINT32*)pInBuf) += 3;

                if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < len + 3*sizeof(UINT32) )
                  {
                    DbgPrint( "[chipsec][IOCTL_WRITE_PHYSMEM] ERROR: STATUS_INVALID_PARAMETER\n" );
                    Status = STATUS_INVALID_PARAMETER;
                    break;
                  }

                DbgPrint( "[chipsec][IOCTL_WRITE_PHYSMEM] Writing contents:\n" );
                _dump_buffer( (unsigned char *)pInBuf, min(len,0x100) );

                __try
                  {
                    Status = _write_phys_mem( phys_addr, len, pInBuf );
                  }
                __except (EXCEPTION_EXECUTE_HANDLER)
                  {
                    Status = GetExceptionCode();
                    DbgPrint( "[chipsec][IOCTL_WRITE_PHYSMEM] ERROR: exception code 0x%X\n", Status );
                    break;
                  }

                break;
              }
          }
        case IOCTL_ALLOC_PHYSMEM:
          {
            SIZE_T NumberOfBytes = 0;
            PVOID va = 0;
            PHYSICAL_ADDRESS HighestAcceptableAddress = { 0xFFFFFFFF, 0xFFFFFFFF };

            DbgPrint( "[chipsec] > IOCTL_ALLOC_PHYSMEM\n" );
            pInBuf  = Irp->AssociatedIrp.SystemBuffer;
            pOutBuf = Irp->AssociatedIrp.SystemBuffer;
            if( !pInBuf || IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(UINT64) + sizeof(UINT32))
              {
                DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER\n" );
                Status = STATUS_INVALID_PARAMETER;
                break;
              }
            RtlCopyBytes( &HighestAcceptableAddress.QuadPart, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(UINT64) );
            RtlCopyBytes( &NumberOfBytes, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(UINT64), sizeof(UINT32) );
            DbgPrint( "[chipsec] Allocating: NumberOfBytes = 0x%X, PhysAddr = 0x%I64x", NumberOfBytes, HighestAcceptableAddress.QuadPart );
            va = MmAllocateContiguousMemory( NumberOfBytes, HighestAcceptableAddress );
            if( !va )
              {
                DbgPrint( "[chipsec] ERROR: STATUS_UNSUCCESSFUL - could not allocate memory\n" );
                Status = STATUS_UNSUCCESSFUL;
              }
            else if( IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 2*sizeof(UINT64) )
              {
                DbgPrint( "[chipsec] ERROR: STATUS_BUFFER_TOO_SMALL - should be at least 2*UINT64\n" );
                Status = STATUS_BUFFER_TOO_SMALL;
              }
            else
              {
                PHYSICAL_ADDRESS pa   = MmGetPhysicalAddress( va );
                DbgPrint( "[chipsec] Allocated Buffer: VirtAddr = 0x%I64x, PhysAddr = 0x%I64x\n", (UINT64)va, pa.QuadPart );
                ((UINT64*)pOutBuf)[0] = (UINT64)va;
                ((UINT64*)pOutBuf)[1] = pa.QuadPart;

                IrpSp->Parameters.Read.Length = 2*sizeof(UINT64);
                dwBytesWritten = IrpSp->Parameters.Read.Length;
                Status = STATUS_SUCCESS;
              }

            break;
          }

        case IOCTL_FREE_PHYSMEM:
          {
            UINT64 va = 0x0;
            pInBuf  = Irp->AssociatedIrp.SystemBuffer;
            pOutBuf = Irp->AssociatedIrp.SystemBuffer;

            DbgPrint( "[chipsec] > IOCTL_FREE_PHYSMEM\n" );
            if( !Irp->AssociatedIrp.SystemBuffer ||
                IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(UINT64))
            {
               DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER\n" );
               Status = STATUS_INVALID_PARAMETER;
               break;
            }

            RtlCopyBytes( &va, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(UINT64) );
            DbgPrint( "[chipsec][IOCTL_FREE_PHYSMEM] Virtual address of the memory being freed: 0x%I64X\n", va );
            MmFreeContiguousMemory( (PVOID)va );

            IrpSp->Parameters.Read.Length = 0;
            dwBytesWritten = IrpSp->Parameters.Read.Length;
            Status = STATUS_SUCCESS;
            break;
          }

        case IOCTL_GET_PHYSADDR:
          {
            UINT64 va = 0x0;
            PHYSICAL_ADDRESS pa = { 0x0, 0x0 };

            pInBuf  = Irp->AssociatedIrp.SystemBuffer;
            pOutBuf = Irp->AssociatedIrp.SystemBuffer;

            DbgPrint( "[chipsec] > IOCTL_GET_PHYSADDR\n" );
            if( !Irp->AssociatedIrp.SystemBuffer ||
                IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(UINT64))
            {
               DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER\n" );
               Status = STATUS_INVALID_PARAMETER;
               break;
            }

            if( IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(UINT64))
            {
               DbgPrint( "[chipsec] ERROR: STATUS_BUFFER_TOO_SMALL\n" );
               Status = STATUS_BUFFER_TOO_SMALL;
               break;
            }

            RtlCopyBytes( &va, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(UINT64) );
            pa = MmGetPhysicalAddress( (PVOID)va );

            DbgPrint( "[chipsec][IOCTL_GET_PHYSADDR] Traslated virtual address 0x%I64X to physical: 0x%I64X\n", va, pa.QuadPart, pa.LowPart);
            RtlCopyBytes( Irp->AssociatedIrp.SystemBuffer, (void*)&pa, sizeof(UINT64) );
            IrpSp->Parameters.Read.Length = sizeof(UINT64);
            dwBytesWritten = IrpSp->Parameters.Read.Length;
            Status = STATUS_SUCCESS;
            break;
          }

        case IOCTL_MAP_IO_SPACE:
          {
            PVOID va  = 0x0;
            PHYSICAL_ADDRESS pa = { 0x0, 0x0 };
            unsigned int len = 0;
            unsigned int cache_type = 0;

            pInBuf  = Irp->AssociatedIrp.SystemBuffer;
            pOutBuf = Irp->AssociatedIrp.SystemBuffer;

            DbgPrint( "[chipsec] > IOCTL_MAP_IO_SPACE\n" );
            if( !Irp->AssociatedIrp.SystemBuffer ||
                IrpSp->Parameters.DeviceIoControl.InputBufferLength != 3*8)
            {
               DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER\n" );
               Status = STATUS_INVALID_PARAMETER;
               break;
            }

            if( IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(UINT64))
            {
               DbgPrint( "[chipsec] ERROR: STATUS_BUFFER_TOO_SMALL\n" );
               Status = STATUS_BUFFER_TOO_SMALL;
               break;
            }

            RtlCopyBytes( &pa,         (BYTE*)Irp->AssociatedIrp.SystemBuffer + 0x00, 0x8 );
            RtlCopyBytes( &len,        (BYTE*)Irp->AssociatedIrp.SystemBuffer + 0x08, 0x4 );
            RtlCopyBytes( &cache_type, (BYTE*)Irp->AssociatedIrp.SystemBuffer + 0x10, 0x4 );

            va = MmMapIoSpace(pa, len, cache_type);

            DbgPrint( "[chipsec][IOCTL_MAP_IO_SPACE] Mapping physical address 0x%016llX to virtual 0x%016llX\n", pa, va);
            RtlCopyBytes( Irp->AssociatedIrp.SystemBuffer, (void*)&va, sizeof(va) );
            IrpSp->Parameters.Read.Length = sizeof(va);
            dwBytesWritten = sizeof(va);
            Status = STATUS_SUCCESS;
            break;
          }

        case IOCTL_LOAD_UCODE_PATCH:
          {
            PVOID ucode_buf = NULL;
            UINT64 ucode_start = 0;
            UINT16 ucode_size = 0;
            UINT32 _eax = 0, _edx = 0;
            int CPUInfo[4] = {-1};

            DbgPrint("[chipsec] > IOCTL_LOAD_UCODE_UPDATE\n" );

            if( !Irp->AssociatedIrp.SystemBuffer ||
                IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(BYTE) + sizeof(UINT16) )
            {
               DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER (input buffer size < 3)\n" );
               Status = STATUS_INVALID_PARAMETER;
               break;
            }

            RtlCopyBytes( &new_cpu_thread_id, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(BYTE) );
            if( new_cpu_thread_id >= _num_active_cpus ) new_cpu_thread_id = 0;
            KeSetSystemAffinityThread( (KAFFINITY)(1 << new_cpu_thread_id) );
            DbgPrint( "[chipsec][IOCTL_LOAD_UCODE_UPDATE] Changed CPU thread to %d\n", KeGetCurrentProcessorNumber() );

            RtlCopyBytes( &ucode_size, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(BYTE), sizeof(UINT16) );
            DbgPrint( "[chipsec][IOCTL_LOAD_UCODE_UPDATE] Ucode update size = 0x%X\n", ucode_size );

            if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < ucode_size + sizeof(BYTE) + sizeof(UINT16) )
              {
                DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER (input buffer size < ucode_size + 3)\n" );
                Status = STATUS_INVALID_PARAMETER;
                break;
              }

            ucode_buf = ExAllocatePoolWithTag( NonPagedPool, ucode_size, 0x3184 );
            if( !ucode_buf )
              {
                DbgPrint( "[chipsec] ERROR: couldn't allocate pool for ucode binary\n" );
                break;
              }           
            RtlCopyBytes( ucode_buf, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(BYTE) + sizeof(UINT16), ucode_size );
            ucode_start = (UINT64)ucode_buf;
            DbgPrint( "[chipsec][IOCTL_LOAD_UCODE_UPDATE] ucode update address = 0x%p (eax = 0x%08X, edx = 0x%08X)\n", ucode_start, (UINT32)(ucode_start & 0xFFFFFFFF), (UINT32)((ucode_start >> 32) & 0xFFFFFFFF) );
            DbgPrint( "[chipsec][IOCTL_LOAD_UCODE_UPDATE] ucode update contents:\n" );
            _dump_buffer( (unsigned char *)ucode_buf, min(ucode_size,0x100) );

            // --
            // -- trigger CPU ucode patch update
            // -- pInBuf points to the beginning of ucode update binary
            // --
            _wrmsr( MSR_IA32_BIOS_UPDT_TRIG, (UINT32)((ucode_start >> 32) & 0xFFFFFFFF), (UINT32)(ucode_start & 0xFFFFFFFF) );

            ExFreePoolWithTag( ucode_buf, 0x3184 );

            // --
            // -- check if patch was loaded
            // --
            // -- need to clear IA32_BIOS_SIGN_ID MSR first
            // -- CPUID will deposit an update ID value in 64-bit MSR at address MSR_IA32_BIOS_SIGN_ID
            // -- read IA32_BIOS_SIGN_ID MSR to check patch ID != 0
            // --
            DbgPrint( "[chipsec][IOCTL_LOAD_UCODE_UPDATE] checking ucode update was loaded..\n" );
            DbgPrint( "[chipsec][IOCTL_LOAD_UCODE_UPDATE] clear IA32_BIOS_SIGN_ID, CPUID EAX=1, read back IA32_BIOS_SIGN_ID\n" );
            _wrmsr( MSR_IA32_BIOS_SIGN_ID, 0, 0 );
            __cpuid(CPUInfo, 1);
            _rdmsr( MSR_IA32_BIOS_SIGN_ID, &_eax, &_edx );
            DbgPrint( "[chipsec][IOCTL_LOAD_UCODE_UPDATE] RDMSR( IA32_BIOS_SIGN_ID=0x8b ) = 0x%08x%08x\n", _edx, _eax );
            if( 0 != _edx ) DbgPrint( "[chipsec][IOCTL_LOAD_UCODE_UPDATE] Microcode update loaded (ID != 0)\n" );
            else            DbgPrint( "[chipsec] ERROR: Microcode update failed\n" );

            Status = STATUS_SUCCESS;
            break;
          }
        case IOCTL_WRMSR:
          {

            UINT32 msrData[3];
            UINT32 _eax = 0, _edx = 0;
            unsigned int _msr_addr;

            DbgPrint("[chipsec] > IOCTL_WRMSR\n");

            pInBuf = Irp->AssociatedIrp.SystemBuffer;
            if( !pInBuf )
              {
	        DbgPrint( "[chipsec][IOCTL_WRMSR] ERROR: NO data provided\n" );
                Status = STATUS_INVALID_PARAMETER;
                break;
              }
            if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(BYTE) + 3*sizeof(UINT32) )
              {
                DbgPrint( "[chipsec][IOCTL_WRMSR] ERROR: STATUS_INVALID_PARAMETER (input buffer size < sizeof(BYTE) + 3*sizeof(UINT32))\n" );
                Status = STATUS_INVALID_PARAMETER;
                break;
              }

            RtlCopyBytes( &new_cpu_thread_id, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(BYTE) );
            if( new_cpu_thread_id >= _num_active_cpus ) new_cpu_thread_id = 0;
            KeSetSystemAffinityThread( (KAFFINITY)(1 << new_cpu_thread_id) );
            DbgPrint( "[chipsec][IOCTL_WRMSR] Changed CPU thread to %d\n", KeGetCurrentProcessorNumber() );

            RtlCopyBytes( msrData, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(BYTE), 3 * sizeof(UINT32) );
            _msr_addr = msrData[0];
            _eax      = msrData[1];
            _edx      = msrData[2];
            DbgPrint( "[chipsec][IOCTL_WRMSR] WRMSR( 0x%x ) <-- 0x%08x%08x\n", _msr_addr, _edx, _eax );

            // --
            // -- write MSR
            // --
            __try
              {
                _wrmsr( _msr_addr, _edx, _eax );
              }
            __except (EXCEPTION_EXECUTE_HANDLER)
              {
                Status = GetExceptionCode();
                DbgPrint( "[chipsec][IOCTL_WRMSR] ERROR: exception code 0x%X\n", Status );
                break;
              }

            // --
            // -- read MSR to check if it was written
            // --
//            _rdmsr( _msr_addr, &_eax, &_edx );
//            DbgPrint( "[chipsec][IOCTL_WRMSR] RDMSR( 0x%x ) --> 0x%08x%08x\n", _msr_addr, _edx, _eax );

            Status = STATUS_SUCCESS;
            break;
          }
        case IOCTL_RDMSR:
          {
            UINT32 msrData[1];
            UINT32 _eax = 0;
            UINT32 _edx = 0;
            UINT32 _msr_addr = 0;

            DbgPrint("[chipsec] > IOCTL_RDMSR\n");

            pInBuf  = Irp->AssociatedIrp.SystemBuffer;
            pOutBuf = Irp->AssociatedIrp.SystemBuffer;
            if( !pInBuf )
              {
                DbgPrint( "[chipsec] ERROR: No input provided\n" );
                Status = STATUS_INVALID_PARAMETER;
                break;
              }
            if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(BYTE) + sizeof(UINT32) )
              {
                DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER - input buffer size < sizeof(BYTE) + sizeof(UINT32)\n" );
                Status = STATUS_INVALID_PARAMETER;
                break;
              }

            RtlCopyBytes( &new_cpu_thread_id, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(BYTE) );
            if( new_cpu_thread_id >= _num_active_cpus ) new_cpu_thread_id = 0;
            KeSetSystemAffinityThread( (KAFFINITY)(1 << new_cpu_thread_id) );
            DbgPrint( "[chipsec][IOCTL_RDMSR] Changed CPU thread to %d\n", KeGetCurrentProcessorNumber() );

            RtlCopyBytes( msrData, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(BYTE), sizeof(UINT32) );
            _msr_addr = msrData[0];

            __try
              {
                _rdmsr( _msr_addr, &_eax, &_edx );
              }
            __except( EXCEPTION_EXECUTE_HANDLER )
              {
                Status = GetExceptionCode();
                DbgPrint( "[chipsec][IOCTL_RDMSR] ERROR: exception code 0x%X\n", Status );
                break;
              }
            DbgPrint( "[chipsec][IOCTL_RDMSR] RDMSR( 0x%x ) --> 0x%08x%08x\n", _msr_addr, _edx, _eax );

            if( IrpSp->Parameters.DeviceIoControl.OutputBufferLength >= 2*sizeof(UINT32) )
              {
                IrpSp->Parameters.Read.Length = 2*sizeof(UINT32);
                RtlCopyBytes( Irp->AssociatedIrp.SystemBuffer, (VOID*)&_eax, sizeof(UINT32) );
                RtlCopyBytes( ((UINT8*)Irp->AssociatedIrp.SystemBuffer) + sizeof(UINT32), (VOID*)&_edx, sizeof(UINT32) );

                dwBytesWritten = 2*sizeof(UINT32);
                Status = STATUS_SUCCESS;
              }
            else
              {
                DbgPrint( "[chipsec] ERROR: STATUS_BUFFER_TOO_SMALL - should be at least 2 UINT32\n" );
                Status = STATUS_BUFFER_TOO_SMALL;
              }

            break;
          }
        case READ_IO_PORT:
          {
            DWORD value;
            BYTE size = 0;
            WORD io_port;
            DbgPrint( "[chipsec] > READ_IO_PORT\n" );

            RtlCopyBytes( &io_port, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(WORD) );
            RtlCopyBytes( &size, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(WORD), sizeof(BYTE) );
            if( 1 != size && 2 != size && 4 != size)
              {
              DbgPrint( "[chipsec][READ_IO_PORT] ERROR: STATUS_INVALID_PARAMETER\n" );
              Status = STATUS_INVALID_PARAMETER;
              break;
              }

            __try
              {
                value = ReadIOPort( io_port, size );             
              }
            __except( EXCEPTION_EXECUTE_HANDLER )
              {
                Status = GetExceptionCode();
                DbgPrint( "[chipsec][READ_IO_PORT] ERROR: exception code 0x%X\n", Status );
                break;
              }

            IrpSp->Parameters.Read.Length = size;
            RtlCopyBytes( Irp->AssociatedIrp.SystemBuffer, (VOID*)&value, size );
            DbgPrint( "[chipsec][READ_IO_PORT] I/O Port %#04x, value = %#010x (size = %#02x)\n", io_port, value, size );

            dwBytesWritten = IrpSp->Parameters.Read.Length;
            Status = STATUS_SUCCESS;
            break;
          }
        case WRITE_IO_PORT:
          {
            DWORD value = 0;
            WORD io_port = 0;
            BYTE size = 0;
            DbgPrint( "[chipsec] > WRITE_IO_PORT\n" );

            RtlCopyBytes( &io_port, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(WORD) );
            RtlCopyBytes( &value, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(WORD), sizeof(DWORD) );
            RtlCopyBytes( &size, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(WORD) + sizeof(DWORD), sizeof(BYTE) );
            DbgPrint( "[chipsec][WRITE_IO_PORT] I/O Port %#04x, value = %#010x (size = %#02x)\n", io_port, value, size );

            __try
              {
                WriteIOPort( value, io_port, size );
              }
            __except( EXCEPTION_EXECUTE_HANDLER )
              {
                Status = GetExceptionCode();
                DbgPrint( "[chipsec][WRITE_IO_PORT] ERROR: exception code 0x%X\n", Status );
                break;
              }

            Status = STATUS_SUCCESS;
            break;
          }
        case GET_CPU_DESCRIPTOR_TABLE:
          {
            BYTE dt_code = 0;
            DESCRIPTOR_TABLE_RECORD dtr;
            PDESCRIPTOR_TABLE_RECORD pdtr = &dtr;
            PHYSICAL_ADDRESS dt_pa;

            DbgPrint( "[chipsec] > GET_CPU_DESCRIPTOR_TABLE\n" );

            RtlCopyBytes( &new_cpu_thread_id, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(BYTE) );
            if( new_cpu_thread_id >= _num_active_cpus ) new_cpu_thread_id = 0;
            KeSetSystemAffinityThread( (KAFFINITY)(1 << new_cpu_thread_id) );
            DbgPrint( "[chipsec][GET_CPU_DESCRIPTOR_TABLE] Changed CPU thread to %d\n", KeGetCurrentProcessorNumber() );
            RtlCopyBytes( &dt_code, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(BYTE), sizeof(BYTE) );
            DbgPrint( "[chipsec][GET_CPU_DESCRIPTOR_TABLE] Descriptor table: %x\n", dt_code );

            switch( dt_code )
              {
                case CPU_DT_CODE_GDTR:  { _store_gdtr( (void*)pdtr ); break; }
                case CPU_DT_CODE_LDTR:  { _store_ldtr( (void*)pdtr ); break; }
                case CPU_DT_CODE_IDTR:
                default:                { _store_idtr( (void*)pdtr ); break; }
              }

            DbgPrint( "[chipsec][GET_CPU_DESCRIPTOR_TABLE] Descriptor table register contents:\n" );
            _dump_buffer( (unsigned char *)pdtr, sizeof(DESCRIPTOR_TABLE_RECORD) );
            DbgPrint( "[chipsec][GET_CPU_DESCRIPTOR_TABLE] IDTR: Limit = 0x%04x, Base = 0x%I64x\n", dtr.limit, dtr.base );

            dt_pa = MmGetPhysicalAddress( (PVOID)dtr.base );
            DbgPrint( "[chipsec][GET_CPU_DESCRIPTOR_TABLE] Descriptor table PA: 0x%I64X (0x%08X_%08X)\n", dt_pa.QuadPart, dt_pa.HighPart, dt_pa.LowPart );

            IrpSp->Parameters.Read.Length = sizeof(DESCRIPTOR_TABLE_RECORD) + sizeof(dt_pa.QuadPart);
            RtlCopyBytes( Irp->AssociatedIrp.SystemBuffer, (void*)pdtr, sizeof(DESCRIPTOR_TABLE_RECORD) );    
            RtlCopyBytes( (UINT8*)Irp->AssociatedIrp.SystemBuffer + sizeof(DESCRIPTOR_TABLE_RECORD), (VOID*)&dt_pa.QuadPart, sizeof(dt_pa.QuadPart) );    

            dwBytesWritten = IrpSp->Parameters.Read.Length;
            Status = STATUS_SUCCESS;
            break;
          }
        case IOCTL_SWSMI:
          {
            CPU_REG_TYPE gprs[6] = {0};
            CPU_REG_TYPE _rax = 0, _rbx = 0, _rcx = 0, _rdx = 0, _rsi = 0, _rdi = 0;
            unsigned int _smi_code_data = 0;

            DbgPrint("[chipsec] > IOCTL_SWSMI\n");
            pInBuf = Irp->AssociatedIrp.SystemBuffer;
            if( !pInBuf )
              {
	        DbgPrint( "[chipsec] ERROR: NO data provided\n" );
                Status = STATUS_INVALID_PARAMETER;
                break;
              }
            if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(UINT16) + sizeof(gprs) )
              {
                DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER (input buffer size < sizeof(UINT16) + sizeof(gprs))\n" );
                Status = STATUS_INVALID_PARAMETER;
                break;
              }
            RtlCopyBytes( &_smi_code_data, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(UINT16) );
            RtlCopyBytes( gprs, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(UINT16), sizeof(gprs) );
            _rax = gprs[ 0 ];
            _rbx = gprs[ 1 ];
            _rcx = gprs[ 2 ];
            _rdx = gprs[ 3 ];
            _rsi = gprs[ 4 ];
            _rdi = gprs[ 5 ];
            DbgPrint( "[chipsec][IOCTL_SWSMI] SW SMI to ports 0x%X-0x%X <- 0x%04X\n", 0xB2, 0xB3, _smi_code_data );
            DbgPrint( "                       RAX = 0x%I64x\n", _rax );
            DbgPrint( "                       RBX = 0x%I64x\n", _rbx );
            DbgPrint( "                       RCX = 0x%I64x\n", _rcx );
            DbgPrint( "                       RDX = 0x%I64x\n", _rdx );
            DbgPrint( "                       RSI = 0x%I64x\n", _rsi );
            DbgPrint( "                       RDI = 0x%I64x\n", _rdi );
            // --
            // -- send SMI using port 0xB2
            // --
            __try
              {
                _swsmi( _smi_code_data, _rax, _rbx, _rcx, _rdx, _rsi, _rdi );
              }
            __except( EXCEPTION_EXECUTE_HANDLER )
              {
                Status = GetExceptionCode();
                break;
              }
            Status = STATUS_SUCCESS;
            break;
          }
        case IOCTL_CPUID:
          {
            DWORD CPUInfo[4] = {-1};
            DWORD gprs[2] = {0};
            DWORD _rax = 0, _rcx = 0;
            //CPU_REG_TYPE gprs[6];
            //CPU_REG_TYPE _rax = 0, _rbx = 0, _rcx = 0, _rdx = 0, _rsi = 0, _rdi = 0;

            DbgPrint("[chipsec] > IOCTL_CPUID\n");
            pInBuf = Irp->AssociatedIrp.SystemBuffer;
            if( !pInBuf )
              {
	        DbgPrint( "[chipsec] ERROR: NO data provided\n" );
                Status = STATUS_INVALID_PARAMETER;
                break;
              }
            if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(gprs) )
              {
                DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER (input buffer size < %d)\n", sizeof(gprs) );
                Status = STATUS_INVALID_PARAMETER;
                break;
              }
            RtlCopyBytes( gprs, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(gprs) );
            _rax = gprs[ 0 ];
            _rcx = gprs[ 1 ];
            DbgPrint( "[chipsec][IOCTL_CPUID] CPUID:\n" );
            DbgPrint( "                       EAX = 0x%08X\n", _rax );
            DbgPrint( "                       ECX = 0x%08X\n", _rcx );

            __cpuidex( CPUInfo, _rax, _rcx );

            DbgPrint( "[chipsec][IOCTL_CPUID] CPUID returned:\n" );
            DbgPrint( "                       EAX = 0x%08X\n", CPUInfo[0] );
            DbgPrint( "                       EBX = 0x%08X\n", CPUInfo[1] );
            DbgPrint( "                       ECX = 0x%08X\n", CPUInfo[2] );
            DbgPrint( "                       EDX = 0x%08X\n", CPUInfo[3] );

            IrpSp->Parameters.Read.Length = sizeof(CPUInfo);
            RtlCopyBytes( Irp->AssociatedIrp.SystemBuffer, (void*)CPUInfo, sizeof(CPUInfo) );    

            dwBytesWritten = IrpSp->Parameters.Read.Length;
            Status = STATUS_SUCCESS;
            break;
          }

        case IOCTL_WRCR:
          {
            UINT64 val64 = 0;
            CPU_REG_TYPE value = 0;
            WORD cr_reg = 0;
            DbgPrint( "[chipsec] > WRITE_CR\n" );

            if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < (sizeof(cr_reg) + sizeof(val64) + sizeof(BYTE)))
            {
                 Status = STATUS_INVALID_PARAMETER;
                 break;
            }

            RtlCopyBytes( &cr_reg, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(cr_reg) );
            RtlCopyBytes( &val64, (BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(cr_reg), sizeof(val64) );
            new_cpu_thread_id = *((BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(cr_reg) + sizeof(val64));
            if( new_cpu_thread_id >= _num_active_cpus )
            {
            //    new_cpu_thread_id = 0;
                 Status = STATUS_INVALID_PARAMETER;
                 break;
            }

            KeSetSystemAffinityThread( (KAFFINITY)(1 << new_cpu_thread_id) );
            value = (CPU_REG_TYPE)val64;
            DbgPrint( "[chipsec][WRITE_CR] CR Reg %#04x, value = %#010x \n", cr_reg, value );

            switch (cr_reg) {
            case 0: WriteCR0(value);
                Status = STATUS_SUCCESS;
                break;
            case 2: WriteCR2(value);
                Status = STATUS_SUCCESS;
                break;
            case 3: WriteCR3(value);
                Status = STATUS_SUCCESS;
                break;
            case 4: WriteCR4(value);
                Status = STATUS_SUCCESS;
                break;
            case 8:
#if defined(_M_AMD64)
                WriteCR8(value);
                Status = STATUS_SUCCESS;
                break;
#endif
            default:
                Status = STATUS_INVALID_PARAMETER;
                break;
            }

            if( !NT_SUCCESS(Status) ) {
                break;
            }

            dwBytesWritten = 0;
            Status = STATUS_SUCCESS;
            break;
          }
        case IOCTL_RDCR:
          {
            UINT64 val64 = 0;
            CPU_REG_TYPE value = 0;
            WORD cr_reg = 0;
            DbgPrint( "[chipsec] > READ_CR\n" );

            if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < (sizeof(cr_reg)+sizeof(BYTE))
             || IrpSp->Parameters.DeviceIoControl.OutputBufferLength < (sizeof(val64))
              )
            {
                 Status = STATUS_INVALID_PARAMETER;
                 break;
            }

            RtlCopyBytes( &cr_reg, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(cr_reg) );
            new_cpu_thread_id = *((BYTE*)Irp->AssociatedIrp.SystemBuffer + sizeof(cr_reg));
            if( new_cpu_thread_id >= _num_active_cpus )
            {
            //    new_cpu_thread_id = 0;
                 Status = STATUS_INVALID_PARAMETER;
                 break;
            }

            KeSetSystemAffinityThread( (KAFFINITY)(1 << new_cpu_thread_id) );

            switch (cr_reg) {
            case 0: value = ReadCR0();
                Status = STATUS_SUCCESS;
                break;
            case 2: value = ReadCR2();
                Status = STATUS_SUCCESS;
                break;
            case 3: value = ReadCR3();
                Status = STATUS_SUCCESS;
                break;
            case 4: value = ReadCR4();
                Status = STATUS_SUCCESS;
                break;
            case 8:
#if defined(_M_AMD64)
                value = ReadCR8();
                Status = STATUS_SUCCESS;
                break;
#endif
            default:
                Status = STATUS_INVALID_PARAMETER;
                break;
            }
            
            if( !NT_SUCCESS(Status) ) {
                break;
            }

            val64 = value;
            RtlCopyBytes( (BYTE*)Irp->AssociatedIrp.SystemBuffer, &val64, sizeof(val64) );
            dwBytesWritten = sizeof(val64);

            DbgPrint( "[chipsec][READ_CR] CR Reg %#04x, value = %#010x \n", cr_reg, value );

            Status = STATUS_SUCCESS;
            break;

          }
        case IOCTL_HYPERCALL:
          {
            CPU_REG_TYPE regs[11] = {0};
            CPU_REG_TYPE result = 0;

            DbgPrint("[chipsec] > IOCTL_HYPERCALL\n");
            pInBuf = Irp->AssociatedIrp.SystemBuffer;

            if( !Irp->AssociatedIrp.SystemBuffer ||
                IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(regs))
            {
                DbgPrint( "[chipsec] ERROR: STATUS_INVALID_PARAMETER\n" );
                Status = STATUS_INVALID_PARAMETER;
                break;
            }

            if( IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(result))
            {
               DbgPrint( "[chipsec] ERROR: STATUS_BUFFER_TOO_SMALL\n" );
               Status = STATUS_BUFFER_TOO_SMALL;
               break;
            }

            RtlCopyBytes( regs, (BYTE*)Irp->AssociatedIrp.SystemBuffer, sizeof(regs) );
            DbgPrint( "[chipsec][IOCTL_HYPERCALL] HYPERCALL:\n" );
            #if defined(_M_AMD64)
            DbgPrint( "    RCX = 0x%016llX  RDX = 0x%016llX\n", regs[0], regs[1] );
            DbgPrint( "    R8  = 0x%016llX  R9  = 0x%016llX\n", regs[2], regs[3] );
            DbgPrint( "    R10 = 0x%016llX  R11 = 0x%016llX\n", regs[4], regs[5] );
            DbgPrint( "    RAX = 0x%016llX  RBX = 0x%016llX\n", regs[6], regs[7] );
            DbgPrint( "    RDI = 0x%016llX  RSI = 0x%016llX\n", regs[8], regs[9] );
            #endif
            #if defined(_M_IX86)
            DbgPrint( "    EAX = 0x%08X  EBX = 0x%08X  ECX = 0x%08X\n", regs[6], regs[7], regs[0] );
            DbgPrint( "    EDX = 0x%08X  ESI = 0x%08X  EDI = 0x%08X\n", regs[1], regs[8], regs[9] );
            #endif
            DbgPrint( "    XMM0-XMM5 buffer VA = 0x%016llX\n", regs[9] );

            __try
              {
                result = hypercall(regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7], regs[8], regs[9], regs[10], &hypercall_page);
              }
            __except( EXCEPTION_EXECUTE_HANDLER )
              {
                Status = GetExceptionCode();
                DbgPrint( "[chipsec][IOCTL_HYPERCALL] ERROR: exception code 0x%X\n", Status );
                break;
              }

            DbgPrint( "[chipsec][IOCTL_HYPERCALL] returned: 0x%016llX\n", result);

            IrpSp->Parameters.Read.Length = sizeof(result);
            RtlCopyBytes( Irp->AssociatedIrp.SystemBuffer, (void*)&result, sizeof(result) );

            dwBytesWritten = IrpSp->Parameters.Read.Length;
            Status = STATUS_SUCCESS;
            break;
          }

        default:
            DbgPrint( "[chipsec] ERROR: invalid IOCTL\n");
            Status = STATUS_NOT_IMPLEMENTED;
            break;

      } // -- switch
Пример #24
0
inline CPUIDInfo cpuid(std::uint32_t eax)
{
    CPUIDInfo info;
    __cpuidex((int*)&info.data[0], eax, 0);
    return info;
}
	void VCIntrinsicCPUIDPolicy::CPUIDExtended( CPUIDSubleafResult & Registers, uint32_t Leaf, uint32_t Subleaf ) noexcept
	{
		static_assert( sizeof( uint32_t ) == sizeof( int ), "VC's intrinsic requires an int for the registers" );
		__cpuidex( reinterpret_cast< int * >( & Registers ), Leaf, Subleaf );
	}
Пример #26
0
// Allocates structures for virtualization, initializes VMCS and virtualizes
// the current processor
_Use_decl_annotations_ static void VmpInitializeVm(
    ULONG_PTR guest_stack_pointer, ULONG_PTR guest_instruction_pointer,
    void *context) {
  PAGED_CODE();

  const auto shared_data = reinterpret_cast<SharedProcessorData *>(context);
  if (!shared_data) {
    return;
  }

  // Allocate related structures
  const auto processor_data =
      reinterpret_cast<ProcessorData *>(ExAllocatePoolWithTag(
          NonPagedPool, sizeof(ProcessorData), kHyperPlatformCommonPoolTag));
  if (!processor_data) {
    return;
  }
  RtlZeroMemory(processor_data, sizeof(ProcessorData));
  processor_data->shared_data = shared_data;
  InterlockedIncrement(&processor_data->shared_data->reference_count);

  // Set up EPT
  processor_data->ept_data = EptInitialization();
  if (!processor_data->ept_data) {
    goto ReturnFalse;
  }

  // Check if XSAVE/XRSTOR are available and save an instruction mask for all
  // supported user state components
  processor_data->xsave_inst_mask =
      RtlGetEnabledExtendedFeatures(static_cast<ULONG64>(-1));
  HYPERPLATFORM_LOG_DEBUG("xsave_inst_mask       = %p",
                          processor_data->xsave_inst_mask);
  if (processor_data->xsave_inst_mask) {
    // Allocate a large enough XSAVE area to store all supported user state
    // components. A size is round-up to multiple of the page size so that the
    // address fulfills a requirement of 64K alignment.
    //
    // See: ENUMERATION OF CPU SUPPORT FOR XSAVE INSTRUCTIONS AND XSAVESUPPORTED
    // FEATURES
    int cpu_info[4] = {};
    __cpuidex(cpu_info, 0xd, 0);
    const auto xsave_area_size = ROUND_TO_PAGES(cpu_info[2]);  // ecx
    processor_data->xsave_area = ExAllocatePoolWithTag(
        NonPagedPool, xsave_area_size, kHyperPlatformCommonPoolTag);
    if (!processor_data->xsave_area) {
      goto ReturnFalse;
    }
    RtlZeroMemory(processor_data->xsave_area, xsave_area_size);
  } else {
    // Use FXSAVE/FXRSTOR instead.
    int cpu_info[4] = {};
    __cpuid(cpu_info, 1);
    const CpuFeaturesEcx cpu_features_ecx = {static_cast<ULONG32>(cpu_info[2])};
    const CpuFeaturesEdx cpu_features_edx = {static_cast<ULONG32>(cpu_info[3])};
    if (cpu_features_ecx.fields.avx) {
      HYPERPLATFORM_LOG_ERROR("A processor supports AVX but not XSAVE/XRSTOR.");
      goto ReturnFalse;
    }
    if (!cpu_features_edx.fields.fxsr) {
      HYPERPLATFORM_LOG_ERROR("A processor does not support FXSAVE/FXRSTOR.");
      goto ReturnFalse;
    }
  }

  // Allocate other processor data fields
  processor_data->vmm_stack_limit =
      UtilAllocateContiguousMemory(KERNEL_STACK_SIZE);
  if (!processor_data->vmm_stack_limit) {
    goto ReturnFalse;
  }
  RtlZeroMemory(processor_data->vmm_stack_limit, KERNEL_STACK_SIZE);

  processor_data->vmcs_region =
      reinterpret_cast<VmControlStructure *>(ExAllocatePoolWithTag(
          NonPagedPool, kVmxMaxVmcsSize, kHyperPlatformCommonPoolTag));
  if (!processor_data->vmcs_region) {
    goto ReturnFalse;
  }
  RtlZeroMemory(processor_data->vmcs_region, kVmxMaxVmcsSize);

  processor_data->vmxon_region =
      reinterpret_cast<VmControlStructure *>(ExAllocatePoolWithTag(
          NonPagedPool, kVmxMaxVmcsSize, kHyperPlatformCommonPoolTag));
  if (!processor_data->vmxon_region) {
    goto ReturnFalse;
  }
  RtlZeroMemory(processor_data->vmxon_region, kVmxMaxVmcsSize);

  // Initialize stack memory for VMM like this:
  //
  // (High)
  // +------------------+  <- vmm_stack_region_base      (eg, AED37000)
  // | processor_data   |
  // +------------------+  <- vmm_stack_data             (eg, AED36FFC)
  // | MAXULONG_PTR     |
  // +------------------+  <- vmm_stack_base (initial SP)(eg, AED36FF8)
  // |                  |    v
  // | (VMM Stack)      |    v (grow)
  // |                  |    v
  // +------------------+  <- vmm_stack_limit            (eg, AED34000)
  // (Low)
  const auto vmm_stack_region_base =
      reinterpret_cast<ULONG_PTR>(processor_data->vmm_stack_limit) +
      KERNEL_STACK_SIZE;
  const auto vmm_stack_data = vmm_stack_region_base - sizeof(void *);
  const auto vmm_stack_base = vmm_stack_data - sizeof(void *);
  HYPERPLATFORM_LOG_DEBUG("vmm_stack_limit       = %p",
                          processor_data->vmm_stack_limit);
  HYPERPLATFORM_LOG_DEBUG("vmm_stack_region_base = %p", vmm_stack_region_base);
  HYPERPLATFORM_LOG_DEBUG("vmm_stack_data        = %p", vmm_stack_data);
  HYPERPLATFORM_LOG_DEBUG("vmm_stack_base        = %p", vmm_stack_base);
  HYPERPLATFORM_LOG_DEBUG("processor_data        = %p stored at %p",
                          processor_data, vmm_stack_data);
  HYPERPLATFORM_LOG_DEBUG("guest_stack_pointer   = %p", guest_stack_pointer);
  HYPERPLATFORM_LOG_DEBUG("guest_inst_pointer    = %p",
                          guest_instruction_pointer);
  *reinterpret_cast<ULONG_PTR *>(vmm_stack_base) = MAXULONG_PTR;
  *reinterpret_cast<ProcessorData **>(vmm_stack_data) = processor_data;

  // Set up VMCS
  if (!VmpEnterVmxMode(processor_data)) {
    goto ReturnFalse;
  }
  if (!VmpInitializeVmcs(processor_data)) {
    goto ReturnFalseWithVmxOff;
  }
  if (!VmpSetupVmcs(processor_data, guest_stack_pointer,
                    guest_instruction_pointer, vmm_stack_base)) {
    goto ReturnFalseWithVmxOff;
  }

  // Do virtualize the processor
  VmpLaunchVm();

// Here is not be executed with successful vmlaunch. Instead, the context
// jumps to an address specified by guest_instruction_pointer.

ReturnFalseWithVmxOff:;
  __vmx_off();

ReturnFalse:;
  VmpFreeProcessorData(processor_data);
}
Пример #27
0
Файл: cpu.c Проект: ChandKV/nvml
static inline void
cpuid(unsigned func, unsigned subfunc, unsigned cpuinfo[4])
{
	__cpuidex(cpuinfo, func, subfunc);
}
Пример #28
0
inline static void cpuid (int output[4], int aa, int cc = 0) {	
    __cpuidex(output, aa, cc);
}
Пример #29
0
extern "C" __declspec(dllexport) BOOLEAN hasSSE2()
{
    //  Misc.
    bool HW_MMX;
    bool HW_x64;
    bool HW_ABM;      // Advanced Bit Manipulation
    bool HW_RDRAND;
    bool HW_BMI1;
    bool HW_BMI2;
    bool HW_ADX;
    bool HW_PREFETCHWT1;

    //  SIMD: 128-bit
    bool HW_SSE;
    bool HW_SSE2;
    bool HW_SSE3;
    bool HW_SSSE3;
    bool HW_SSE41;
    bool HW_SSE42;
    bool HW_SSE4a;
    bool HW_AES;
    bool HW_SHA;

    //  SIMD: 256-bit
    bool HW_AVX;
    bool HW_XOP;
    bool HW_FMA3;
    bool HW_FMA4;
    bool HW_AVX2;

    //  SIMD: 512-bit
    bool HW_AVX512F;    //  AVX512 Foundation
    bool HW_AVX512CD;   //  AVX512 Conflict Detection
    bool HW_AVX512PF;   //  AVX512 Prefetch
    bool HW_AVX512ER;   //  AVX512 Exponential + Reciprocal
    bool HW_AVX512VL;   //  AVX512 Vector Length Extensions
    bool HW_AVX512BW;   //  AVX512 Byte + Word
    bool HW_AVX512DQ;   //  AVX512 Doubleword + Quadword
    bool HW_AVX512IFMA; //  AVX512 Integer 52-bit Fused Multiply-Add
    bool HW_AVX512VBMI; //  AVX512 Vector Byte Manipulation Instructions

    int info[4];
    __cpuidex(info, 0, 0);
    int nIds = info[0];

    __cpuidex(info, 0x80000000, 0);
    unsigned nExIds = info[0];

    //  Detect Features
    if (nIds >= 0x00000001) {
        __cpuidex(info, 0x00000001, 0);
        HW_MMX = (info[3] & ((int)1 << 23)) != 0;
        HW_SSE = (info[3] & ((int)1 << 25)) != 0;
        HW_SSE2 = (info[3] & ((int)1 << 26)) != 0;
        HW_SSE3 = (info[2] & ((int)1 << 0)) != 0;

        HW_SSSE3 = (info[2] & ((int)1 << 9)) != 0;
        HW_SSE41 = (info[2] & ((int)1 << 19)) != 0;
        HW_SSE42 = (info[2] & ((int)1 << 20)) != 0;
        HW_AES = (info[2] & ((int)1 << 25)) != 0;

        HW_AVX = (info[2] & ((int)1 << 28)) != 0;
        HW_FMA3 = (info[2] & ((int)1 << 12)) != 0;

        HW_RDRAND = (info[2] & ((int)1 << 30)) != 0;
    }
    if (nIds >= 0x00000007) {
        __cpuidex(info, 0x00000007,0);
        HW_AVX2 = (info[1] & ((int)1 << 5)) != 0;

        HW_BMI1 = (info[1] & ((int)1 << 3)) != 0;
        HW_BMI2 = (info[1] & ((int)1 << 8)) != 0;
        HW_ADX = (info[1] & ((int)1 << 19)) != 0;
        HW_SHA = (info[1] & ((int)1 << 29)) != 0;
        HW_PREFETCHWT1 = (info[2] & ((int)1 << 0)) != 0;

        HW_AVX512F = (info[1] & ((int)1 << 16)) != 0;
        HW_AVX512CD = (info[1] & ((int)1 << 28)) != 0;
        HW_AVX512PF = (info[1] & ((int)1 << 26)) != 0;
        HW_AVX512ER = (info[1] & ((int)1 << 27)) != 0;
        HW_AVX512VL = (info[1] & ((int)1 << 31)) != 0;
        HW_AVX512BW = (info[1] & ((int)1 << 30)) != 0;
        HW_AVX512DQ = (info[1] & ((int)1 << 17)) != 0;
        HW_AVX512IFMA = (info[1] & ((int)1 << 21)) != 0;
        HW_AVX512VBMI = (info[2] & ((int)1 << 1)) != 0;
    }
    if (nExIds >= 0x80000001) {
        __cpuidex(info, 0x80000001,0);
        HW_x64 = (info[3] & ((int)1 << 29)) != 0;
        HW_ABM = (info[2] & ((int)1 << 5)) != 0;
        HW_SSE4a = (info[2] & ((int)1 << 6)) != 0;
        HW_FMA4 = (info[2] & ((int)1 << 16)) != 0;
        HW_XOP = (info[2] & ((int)1 << 11)) != 0;
    }

    return (BOOLEAN)HW_SSE2;
}
Пример #30
0
CpuDetect::CpuDetect()
  : m_mmx(false),
  m_sse(false),
  m_sse2(false),
  m_sse3(false),
  m_ssse3(false),
  m_sse41(false),
  m_sse42(false),
  m_aes(false),
  m_avx(false),
  m_fma3(false),
  m_rdrand(false),
  m_avx2(false),
  m_bmi1(false),
  m_bmi2(false),
  m_adx(false),
  m_sha(false),
  m_prefetchwt1(false),
  m_avx512f(false),
  m_avx512cd(false),
  m_avx512pf(false),
  m_avx512er(false),
  m_avx512vl(false),
  m_avx512bw(false),
  m_avx512dq(false),
  m_avx512ifma(false),
  m_avx512vbmi(false),
  m_x64(false),
  m_abm(false),
  m_sse4a(false),
  m_fma4(false),
  m_hop(false)

{
  int cpuInfo[4];
  __cpuidex(cpuInfo, 0, 0);
  int nIds = cpuInfo[0];

  __cpuidex(cpuInfo, 0x80000000, 0);
  unsigned nExIds = cpuInfo[0];
  if (nIds >= 0x00000001)
  {
    __cpuidex(cpuInfo, 1, 0);

    m_mmx = (cpuInfo[3] & ((int)1 << 23)) != 0;
    m_sse = (cpuInfo[3] & ((int)1 << 25)) != 0;
    m_sse2 = (cpuInfo[3] & ((int)1 << 26)) != 0;
    m_sse3 = (cpuInfo[2] & ((int)1 << 0)) != 0;

    m_ssse3 = (cpuInfo[2] & ((int)1 << 9)) != 0;
    m_sse41 = (cpuInfo[2] & ((int)1 << 19)) != 0;
    m_sse42 = (cpuInfo[2] & ((int)1 << 20)) != 0;
    m_aes = (cpuInfo[2] & ((int)1 << 25)) != 0;

    m_avx = (cpuInfo[2] & ((int)1 << 28)) != 0;
    m_fma3 = (cpuInfo[2] & ((int)1 << 12)) != 0;
    m_rdrand = (cpuInfo[2] & ((int)1 << 30)) != 0;
  }
  if (nIds >= 0x00000007)
  {
    __cpuidex(cpuInfo, 0x00000007, 0);
    m_avx2 = (cpuInfo[1] & ((int)1 << 5)) != 0;

    m_bmi1 = (cpuInfo[1] & ((int)1 << 3)) != 0;
    m_bmi2 = (cpuInfo[1] & ((int)1 << 8)) != 0;
    m_adx = (cpuInfo[1] & ((int)1 << 19)) != 0;
    m_sha = (cpuInfo[1] & ((int)1 << 29)) != 0;
    m_prefetchwt1 = (cpuInfo[2] & ((int)1 << 0)) != 0;

    m_avx512f = (cpuInfo[1] & ((int)1 << 16)) != 0;
    m_avx512cd = (cpuInfo[1] & ((int)1 << 28)) != 0;
    m_avx512pf = (cpuInfo[1] & ((int)1 << 26)) != 0;
    m_avx512er = (cpuInfo[1] & ((int)1 << 27)) != 0;
    m_avx512vl = (cpuInfo[1] & ((int)1 << 31)) != 0;
    m_avx512bw = (cpuInfo[1] & ((int)1 << 30)) != 0;
    m_avx512dq = (cpuInfo[1] & ((int)1 << 17)) != 0;
    m_avx512ifma = (cpuInfo[1] & ((int)1 << 21)) != 0;
    m_avx512vbmi = (cpuInfo[2] & ((int)1 << 1)) != 0;
  }
  if (nExIds >= 0x80000001)
  {
    __cpuidex(cpuInfo, 0x80000001, 0);
    m_x64 = (cpuInfo[3] & ((int)1 << 29)) != 0;
    m_abm = (cpuInfo[2] & ((int)1 << 5)) != 0;
    m_sse4a = (cpuInfo[2] & ((int)1 << 6)) != 0;
    m_fma4 = (cpuInfo[2] & ((int)1 << 16)) != 0;
    m_hop = (cpuInfo[2] & ((int)1 << 11)) != 0;
  }


}