Merge branch 'master' into prog-loader
[lunaix-os.git] / lunaix-os / hal / cpu.c
1 #include <cpuid.h>
2 #include <hal/cpu.h>
3 #include <hal/rnd.h>
4 #include <stdint.h>
5
6 void
7 cpu_get_model(char* model_out)
8 {
9     u32_t* out = (u32_t*)model_out;
10     reg32 eax = 0, ebx = 0, edx = 0, ecx = 0;
11
12     __get_cpuid(0, &eax, &ebx, &ecx, &edx);
13
14     out[0] = ebx;
15     out[1] = edx;
16     out[2] = ecx;
17     model_out[12] = '\0';
18 }
19
20 #define BRAND_LEAF 0x80000000UL
21
22 int
23 cpu_brand_string_supported()
24 {
25     reg32 supported = __get_cpuid_max(BRAND_LEAF, 0);
26     return (supported >= 0x80000004UL);
27 }
28
29 void
30 cpu_get_brand(char* brand_out)
31 {
32     if (!cpu_brand_string_supported()) {
33         brand_out[0] = '?';
34         brand_out[1] = '\0';
35     }
36     u32_t* out = (u32_t*)brand_out;
37     reg32 eax = 0, ebx = 0, edx = 0, ecx = 0;
38     for (u32_t i = 2, j = 0; i < 5; i++) {
39         __get_cpuid(BRAND_LEAF + i, &eax, &ebx, &ecx, &edx);
40         out[j] = eax;
41         out[j + 1] = ebx;
42         out[j + 2] = ecx;
43         out[j + 3] = edx;
44         j += 4;
45     }
46     brand_out[48] = '\0';
47 }
48
49 int
50 cpu_has_apic()
51 {
52     // reference: Intel manual, section 10.4.2
53     reg32 eax = 0, ebx = 0, edx = 0, ecx = 0;
54     __get_cpuid(1, &eax, &ebx, &ecx, &edx);
55
56     return (edx & 0x100);
57 }
58
59 void
60 cpu_rdmsr(u32_t msr_idx, u32_t* reg_high, u32_t* reg_low)
61 {
62     u32_t h = 0, l = 0;
63     asm volatile("rdmsr" : "=d"(h), "=a"(l) : "c"(msr_idx));
64
65     *reg_high = h;
66     *reg_low = l;
67 }
68
69 void
70 cpu_wrmsr(u32_t msr_idx, u32_t reg_high, u32_t reg_low)
71 {
72     asm volatile("wrmsr" : : "d"(reg_high), "a"(reg_low), "c"(msr_idx));
73 }
74
75 int
76 rnd_is_supported()
77 {
78     reg32 eax, ebx, ecx, edx;
79     __get_cpuid(0x01, &eax, &ebx, &ecx, &edx);
80     return (ecx & (1 << 30));
81 }