aboutsummaryrefslogtreecommitdiff
path: root/src/x86/mockcpuid.c
blob: 2631f09ba83e2ca5b292685b0a22c5d44bb74af8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <stdint.h>
#include <stddef.h>

#if !CPUINFO_MOCK
	#error This file should be built only in mock mode
#endif

#include <cpuinfo-mock.h>


static struct cpuinfo_mock_cpuid* cpuinfo_mock_cpuid_data = NULL;
static uint32_t cpuinfo_mock_cpuid_entries = 0;
static uint32_t cpuinfo_mock_cpuid_leaf4_iteration = 0;

void CPUINFO_ABI cpuinfo_mock_set_cpuid(struct cpuinfo_mock_cpuid* dump, size_t entries) {
	cpuinfo_mock_cpuid_data = dump;
	cpuinfo_mock_cpuid_entries = entries;
};

void CPUINFO_ABI cpuinfo_mock_get_cpuid(uint32_t eax, uint32_t regs[4]) {
	if (eax != 4) {
		cpuinfo_mock_cpuid_leaf4_iteration = 0;
	}
	if (cpuinfo_mock_cpuid_data != NULL && cpuinfo_mock_cpuid_entries != 0) {
		if (eax == 4) {
			uint32_t skip_entries = cpuinfo_mock_cpuid_leaf4_iteration;
			for (uint32_t i = 0; i < cpuinfo_mock_cpuid_entries; i++) {
				if (eax == cpuinfo_mock_cpuid_data[i].input_eax) {
					if (skip_entries-- == 0) {
						regs[0] = cpuinfo_mock_cpuid_data[i].eax;
						regs[1] = cpuinfo_mock_cpuid_data[i].ebx;
						regs[2] = cpuinfo_mock_cpuid_data[i].ecx;
						regs[3] = cpuinfo_mock_cpuid_data[i].edx;
						cpuinfo_mock_cpuid_leaf4_iteration++;
						return;
					}
				}
			}
		} else {
			for (uint32_t i = 0; i < cpuinfo_mock_cpuid_entries; i++) {
				if (eax == cpuinfo_mock_cpuid_data[i].input_eax) {
					regs[0] = cpuinfo_mock_cpuid_data[i].eax;
					regs[1] = cpuinfo_mock_cpuid_data[i].ebx;
					regs[2] = cpuinfo_mock_cpuid_data[i].ecx;
					regs[3] = cpuinfo_mock_cpuid_data[i].edx;
					return;
				}
			}
		}
	}
	regs[0] = regs[1] = regs[2] = regs[3] = 0;
}

void CPUINFO_ABI cpuinfo_mock_get_cpuidex(uint32_t eax, uint32_t ecx, uint32_t regs[4]) {
	cpuinfo_mock_cpuid_leaf4_iteration = 0;
	if (cpuinfo_mock_cpuid_data != NULL && cpuinfo_mock_cpuid_entries != 0) {
		for (uint32_t i = 0; i < cpuinfo_mock_cpuid_entries; i++) {
			if (eax == cpuinfo_mock_cpuid_data[i].input_eax &&
				ecx == cpuinfo_mock_cpuid_data[i].input_ecx)
			{
				regs[0] = cpuinfo_mock_cpuid_data[i].eax;
				regs[1] = cpuinfo_mock_cpuid_data[i].ebx;
				regs[2] = cpuinfo_mock_cpuid_data[i].ecx;
				regs[3] = cpuinfo_mock_cpuid_data[i].edx;
				return;
			}
		}
	}
	regs[0] = regs[1] = regs[2] = regs[3] = 0;
}