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