use WFI instruction when waiting for interrupts
[AROS.git] / arch / all-pc / processor / getcpuinfo.c
blob2d6163db0055d125e95834bee87bedcbc7281b19
1 /*
2 Copyright © 2010-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: GetCPUInfo() - Provides information about installed CPUs
6 Lang: english
7 */
9 #define DEBUG 0
10 #include <aros/debug.h>
12 #include <aros/libcall.h>
13 #include <resources/processor.h>
14 #include <aros/kernel.h>
15 #include <proto/kernel.h>
16 #include <proto/utility.h>
18 #include "processor_intern.h"
19 #include "processor_arch_intern.h"
21 static void ProcessFeaturesTag(struct X86ProcessorInformation * info, struct TagItem * tag);
23 #include <proto/processor.h>
25 /* See rom/processor/getcpuinfo.c for documentation */
27 AROS_LH1(void, GetCPUInfo,
28 AROS_LHA(struct TagItem *, tagList, A0),
29 struct ProcessorBase *, ProcessorBase, 1, Processor)
31 AROS_LIBFUNC_INIT
33 struct TagItem * passedTag = NULL;
34 struct X86ProcessorInformation * processor = NULL;
35 struct X86ProcessorInformation **sysprocs = ProcessorBase->Private1;
36 ULONG selectedprocessor = 0;
38 D(bug("[processor.x86] :%s()\n", __func__));
40 /* If processor was not selected, fall back to legacy mode and report on
41 first available processor */
42 selectedprocessor = (ULONG)GetTagData(GCIT_SelectedProcessor, 0, tagList);
44 /* If selectedprocessor not in line with number of processors, report on
45 first available processor */
46 if (selectedprocessor >= ProcessorBase->cpucount)
47 selectedprocessor = 0;
49 processor = sysprocs[selectedprocessor];
51 /* Go over each passed tag and fill apprioprate data */
52 while ((passedTag = NextTagItem(&tagList)) != NULL)
54 if ((passedTag->ti_Tag > GCIT_FeaturesBase) &&
55 (passedTag->ti_Tag <= GCIT_FeaturesLast))
57 ProcessFeaturesTag(processor, passedTag);
59 else
61 switch(passedTag->ti_Tag)
63 case(GCIT_NumberOfProcessors):
64 *((ULONG *)passedTag->ti_Data) = ProcessorBase->cpucount;
65 break;
66 case(GCIT_ModelString):
67 *((CONST_STRPTR *)passedTag->ti_Data) = processor->BrandString;
68 break;
69 case(GCIT_Family):
70 *((ULONG *)passedTag->ti_Data) = processor->Family;
71 break;
72 case(GCIT_VectorUnit):
73 *((ULONG *)passedTag->ti_Data) = processor->VectorUnit;
74 break;
75 case(GCIT_L1CacheSize):
76 *((ULONG *)passedTag->ti_Data) =
77 (processor->L1DataCacheSize + processor->L1InstructionCacheSize);
78 break;
79 case(GCIT_L1DataCacheSize):
80 *((ULONG *)passedTag->ti_Data) = processor->L1DataCacheSize;
81 break;
82 case(GCIT_L1InstructionCacheSize):
83 *((ULONG *)passedTag->ti_Data) = processor->L1InstructionCacheSize;
84 break;
85 case(GCIT_L2CacheSize):
86 *((ULONG *)passedTag->ti_Data) = processor->L2CacheSize;
87 break;
88 case(GCIT_L3CacheSize):
89 *((ULONG *)passedTag->ti_Data) = processor->L3CacheSize;
90 break;
91 case(GCIT_CacheLineSize):
92 *((ULONG *)passedTag->ti_Data) = processor->CacheLineSize;
93 break;
94 case(GCIT_Architecture):
95 *((ULONG *)passedTag->ti_Data) = PROCESSORARCH_X86;
96 break;
97 case(GCIT_Endianness):
98 *((ULONG *)passedTag->ti_Data) = ENDIANNESS_LE;
99 break;
100 case(GCIT_ProcessorSpeed):
101 *((UQUAD *)passedTag->ti_Data) = GetCurrentProcessorFrequency(processor);
102 break;
103 case(GCIT_ProcessorLoad):
104 #if defined(__AROSEXEC_SMP__)
105 *((ULONG *)passedTag->ti_Data) = KrnGetSystemAttr(KATTR_CPULoad + selectedprocessor);
106 #else
107 *((ULONG *)passedTag->ti_Data) = 0; /* TODO: IMPLEMENT */
108 #endif
109 break;
110 case(GCIT_FrontsideSpeed):
111 *((UQUAD *)passedTag->ti_Data) = processor->MaxFSBFrequency;
112 break;
114 case GCIT_Vendor:
115 *((ULONG *)passedTag->ti_Data) = processor->Vendor;
116 break;
121 AROS_LIBFUNC_EXIT
122 } /* GetCPUInfo() */
124 static void ProcessFeaturesTag(struct X86ProcessorInformation * info, struct TagItem * tag)
126 D(bug("[processor.x86] :%s()\n", __func__));
128 switch(tag->ti_Tag)
130 case(GCIT_SupportsFPU):
131 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_FPU) >> FEATB_FPU); break;
132 case(GCIT_SupportsMMX):
133 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_MMX) >> FEATB_MMX); break;
134 case(GCIT_SupportsSSE):
135 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_SSE) >> FEATB_SSE); break;
136 case(GCIT_SupportsSSE2):
137 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_SSE2) >> FEATB_SSE2); break;
138 case(GCIT_SupportsSSE3):
139 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_SSE3) >> FEATB_SSE3); break;
140 case(GCIT_SupportsSSSE3):
141 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_SSSE3) >> FEATB_SSSE3); break;
142 case(GCIT_SupportsSSE41):
143 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_SSE41) >> FEATB_SSE41); break;
144 case(GCIT_SupportsSSE42):
145 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_SSE42) >> FEATB_SSE42); break;
146 case(GCIT_SupportsMMXEXT):
147 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features3 & FEATF_MMXEXT) >> FEATB_MMXEXT); break;
148 case(GCIT_Supports3DNOW):
149 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features3 & FEATF_3DNOW) >> FEATB_3DNOW); break;
150 case(GCIT_Supports3DNOWEXT):
151 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features3 & FEATF_3DNOWEXT) >> FEATB_3DNOWEXT); break;
152 case(GCIT_SupportsSSE4A):
153 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features4 & FEATF_SSE4A) >> FEATB_SSE4A); break;
154 case(GCIT_SupportsVME):
155 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_VME) >> FEATB_VME); break;
156 case(GCIT_SupportsPSE):
157 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_PSE) >> FEATB_PSE); break;
158 case(GCIT_SupportsPAE):
159 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_PAE) >> FEATB_PAE); break;
160 case(GCIT_SupportsCX8):
161 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_CX8) >> FEATB_CX8); break;
162 case(GCIT_SupportsAPIC):
163 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_APIC) >> FEATB_APIC); break;
164 case(GCIT_SupportsCMOV):
165 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_CMOV) >> FEATB_CMOV); break;
166 case(GCIT_SupportsPSE36):
167 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_PSE36) >> FEATB_PSE36); break;
168 case(GCIT_SupportsCLFSH):
169 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_CLFSH) >> FEATB_CLFSH); break;
170 case(GCIT_SupportsACPI):
171 if (info->Vendor == VENDOR_INTEL)
172 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_ACPI) >> FEATB_ACPI);
173 else
174 *((BOOL *)tag->ti_Data) = FALSE; /* TODO: IMPLEMENT FOR AMD */
175 break;
176 case(GCIT_SupportsFXSR):
177 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_FXSR) >> FEATB_FXSR); break;
178 case(GCIT_SupportsHTT):
179 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_HTT) >> FEATB_HTT); break;
180 case(GCIT_SupportsCX16):
181 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_CX16) >> FEATB_CX16); break;
182 case(GCIT_SupportsVirtualization):
183 switch(info->Vendor)
185 case(VENDOR_INTEL):
186 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_VMX) >> FEATB_VMX); break;
187 case(VENDOR_AMD):
188 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features4 & FEATF_SVM) >> FEATB_SVM); break;
189 default:
190 *((BOOL *)tag->ti_Data) = FALSE; break;
192 break;
193 case(GCIT_SupportsNoExecutionBit):
194 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features3 & FEATF_XDNX) >> FEATB_XDNX); break;
195 case(GCIT_Supports64BitMode):
196 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features3 & FEATF_AMD64) >> FEATB_AMD64); break;
197 case(GCIT_SupportsMSR):
198 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_MSR) >> FEATB_MSR); break;
199 default:
200 *((BOOL *)tag->ti_Data) = FALSE; break;