1 | /*␊ |
2 | * platform.c␊ |
3 | *␊ |
4 | */␊ |
5 | ␊ |
6 | #include "libsaio.h"␊ |
7 | #include "bootstruct.h"␊ |
8 | #include "pci.h"␊ |
9 | #include "freq_detect.h"␊ |
10 | #include "nvidia.h"␊ |
11 | #include "spd.h"␊ |
12 | #include "platform.h"␊ |
13 | ␊ |
14 | #ifndef DEBUG_PLATFORM␊ |
15 | #define DEBUG_PLATFORM 0␊ |
16 | #endif␊ |
17 | ␊ |
18 | #if DEBUG_PLATFORM␊ |
19 | #define DBG(x...)␉printf(x)␊ |
20 | #else␊ |
21 | #define DBG(x...)␊ |
22 | #endif␊ |
23 | ␊ |
24 | PlatformInfo_t Platform;␊ |
25 | ␊ |
26 | void scan_cpu_amd()␊ |
27 | {␊ |
28 | ␉// AMD␊ |
29 | ␉␊ |
30 | ␉// TODO: Retrieve cpu brand string␊ |
31 | ␉// TODO: Retrieve cpu core count␊ |
32 | ␉// TODO: Retrieve cpu mobile info␊ |
33 | ␉␊ |
34 | }␊ |
35 | ␊ |
36 | void scan_cpu_intel()␊ |
37 | {␊ |
38 | ␉uint32_t␉cpuid_reg[4];␊ |
39 | ␊ |
40 | ␉// Get Number of cores per package␊ |
41 | ␉/*␊ |
42 | ␉ Initially set the EAX register to 4 and the ECX register to 0 prior to executing the CPUID instruction.␊ |
43 | ␉ After executing the CPUID instruction, (EAX[31:26] + 1) contains the number of cores.␊ |
44 | ␉ */␊ |
45 | ␉cpuid_reg[2]=1;␊ |
46 | ␉do_cpuid(4, cpuid_reg);␊ |
47 | ␉do_cpuid(4, cpuid_reg); // FIXME: why does this only work the 2nd time ?␊ |
48 | ␉Platform.CPU.NoCores = bitfield(cpuid_reg[0], 31, 26) + 1;␊ |
49 | ␉␊ |
50 | ␉// Find Number of Concurrent Threads Processed (HyperThreading) ␊ |
51 | ␉do_cpuid(1,cpuid_reg);␊ |
52 | ␉if(bitfield(cpuid_reg[1], 23, 16) > 1)␊ |
53 | ␉␉Platform.CPU.NoThreads=Platform.CPU.NoCores;␊ |
54 | ␉else␊ |
55 | ␉␉Platform.CPU.NoThreads=Platform.CPU.NoCores * 2;␊ |
56 | ␉␊ |
57 | ␉// Mobile CPU ?␊ |
58 | ␉if (rdmsr64(0x17) & (1<<28))␊ |
59 | ␉␉Platform.CPU.Mobile = 1;␊ |
60 | ␉else␊ |
61 | ␉␉Platform.CPU.Mobile = 0;␊ |
62 | }␊ |
63 | ␊ |
64 | void scan_platform()␊ |
65 | {␊ |
66 | ␉uint32_t␉cpuid_reg[4];␊ |
67 | ␊ |
68 | ␉build_pci_dt();␊ |
69 | ␊ |
70 | ␉calculate_freq();␊ |
71 | ␉␊ |
72 | ␉// Copy the values from calculate_freq()␊ |
73 | ␉Platform.CPU.TSCFrequency = tscFrequency;␊ |
74 | ␉Platform.CPU.FSBFrequency = fsbFrequency;␊ |
75 | ␉Platform.CPU.CPUFrequency = cpuFrequency;␊ |
76 | ␉␊ |
77 | ␉do_cpuid(0, cpuid_reg);␊ |
78 | ␉Platform.CPU.Vendor = cpuid_reg[1];␊ |
79 | ␉␊ |
80 | ␉do_cpuid(1, cpuid_reg);␊ |
81 | ␉Platform.CPU.Model = bitfield(cpuid_reg[0], 7, 4);␊ |
82 | ␉Platform.CPU.Family = bitfield(cpuid_reg[0], 11, 8);␊ |
83 | ␉Platform.CPU.ExtModel = bitfield(cpuid_reg[0], 19, 16);␊ |
84 | ␉Platform.CPU.ExtFamily = bitfield(cpuid_reg[0], 27, 20);␊ |
85 | ␊ |
86 | ␉// Get vendor specific cpu data ␊ |
87 | ␉if((Platform.CPU.Vendor == 0x756E6547 /* Intel */) && ((Platform.CPU.Family == 0x06) || (Platform.CPU.Family == 0x0f)))␊ |
88 | ␉␉scan_cpu_intel();␊ |
89 | ␉else if((Platform.CPU.Vendor == 0x68747541 /* AMD */) && (Platform.CPU.Family == 0x0f))␊ |
90 | ␉␉scan_cpu_amd();␊ |
91 | }␊ |
92 | ␊ |
93 | ␊ |
94 | |