adae763feed1424f600559254a49c10bf4ed6c88
[AROS.git] / arch / x86-all / processor / getcpuinfo.c
blobadae763feed1424f600559254a49c10bf4ed6c88
1 /*
2 Copyright © 2010-2011, 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 <proto/utility.h>
16 #include "processor_intern.h"
17 #include "processor_arch_intern.h"
19 static void ProcessFeaturesTag(struct X86ProcessorInformation * info, struct TagItem * tag);
21 /*****************************************************************************
23 NAME */
24 #include <proto/processor.h>
26 AROS_LH1(void, GetCPUInfo,
28 /* SYNOPSIS */
29 AROS_LHA(struct TagItem *, tagList, A0),
31 /* LOCATION */
32 struct ProcessorBase *, ProcessorBase, 1, Processor)
34 /* FUNCTION
36 INPUTS
38 TAGS
40 RESULT
42 NOTES
44 EXAMPLE
46 BUGS
48 SEE ALSO
50 INTERNALS
52 ******************************************************************************/
54 AROS_LIBFUNC_INIT
56 struct TagItem * passedTag = NULL;
57 struct X86ProcessorInformation * processor = NULL;
58 struct X86ProcessorInformation **sysprocs = ProcessorBase->Private1;
59 ULONG selectedprocessor = 0;
61 D(bug("[processor.x86] :%s()\n", __PRETTY_FUNCTION__));
63 /* If processor was not selected, fall back to legacy mode and report on
64 first available processor */
65 selectedprocessor = (ULONG)GetTagData(GCIT_SelectedProcessor, 0, tagList);
67 /* If selectedprocessor not in line with number of processors, report on
68 first available processor */
69 if (selectedprocessor >= ProcessorBase->cpucount)
70 selectedprocessor = 0;
72 processor = sysprocs[selectedprocessor];
74 /* Go over each passed tag and fill apprioprate data */
75 while ((passedTag = NextTagItem(&tagList)) != NULL)
77 if ((passedTag->ti_Tag > GCIT_FeaturesBase) &&
78 (passedTag->ti_Tag <= GCIT_FeaturesLast))
80 ProcessFeaturesTag(processor, passedTag);
82 else
84 switch(passedTag->ti_Tag)
86 case(GCIT_NumberOfProcessors):
87 *((ULONG *)passedTag->ti_Data) = ProcessorBase->cpucount;
88 break;
89 case(GCIT_ModelString):
90 *((CONST_STRPTR *)passedTag->ti_Data) = processor->BrandString;
91 break;
92 case(GCIT_Family):
93 *((ULONG *)passedTag->ti_Data) = processor->Family;
94 break;
95 case(GCIT_VectorUnit):
96 *((ULONG *)passedTag->ti_Data) = processor->VectorUnit;
97 break;
98 case(GCIT_L1CacheSize):
99 *((ULONG *)passedTag->ti_Data) =
100 (processor->L1DataCacheSize + processor->L1InstructionCacheSize);
101 break;
102 case(GCIT_L1DataCacheSize):
103 *((ULONG *)passedTag->ti_Data) = processor->L1DataCacheSize;
104 break;
105 case(GCIT_L1InstructionCacheSize):
106 *((ULONG *)passedTag->ti_Data) = processor->L1InstructionCacheSize;
107 break;
108 case(GCIT_L2CacheSize):
109 *((ULONG *)passedTag->ti_Data) = processor->L2CacheSize;
110 break;
111 case(GCIT_L3CacheSize):
112 *((ULONG *)passedTag->ti_Data) = processor->L3CacheSize;
113 break;
114 case(GCIT_CacheLineSize):
115 *((ULONG *)passedTag->ti_Data) = processor->CacheLineSize;
116 break;
117 case(GCIT_Architecture):
118 *((ULONG *)passedTag->ti_Data) = PROCESSORARCH_X86;
119 break;
120 case(GCIT_Endianness):
121 *((ULONG *)passedTag->ti_Data) = ENDIANNESS_LE;
122 break;
123 case(GCIT_ProcessorSpeed):
124 *((UQUAD *)passedTag->ti_Data) = GetCurrentProcessorFrequency(processor);
125 break;
126 case(GCIT_ProcessorLoad):
127 *((UBYTE *)passedTag->ti_Data) = 0; /* TODO: IMPLEMENT */
128 break;
129 case(GCIT_FrontsideSpeed):
130 *((UQUAD *)passedTag->ti_Data) = processor->MaxFSBFrequency;
131 break;
133 case GCIT_Vendor:
134 *((ULONG *)passedTag->ti_Data) = processor->Vendor;
135 break;
140 AROS_LIBFUNC_EXIT
141 } /* GetCPUInfo() */
143 static void ProcessFeaturesTag(struct X86ProcessorInformation * info, struct TagItem * tag)
145 D(bug("[processor.x86] :%s()\n", __PRETTY_FUNCTION__));
147 switch(tag->ti_Tag)
149 case(GCIT_SupportsFPU):
150 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_FPU) >> FEATB_FPU); break;
151 case(GCIT_SupportsMMX):
152 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_MMX) >> FEATB_MMX); break;
153 case(GCIT_SupportsSSE):
154 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_SSE) >> FEATB_SSE); break;
155 case(GCIT_SupportsSSE2):
156 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_SSE2) >> FEATB_SSE2); break;
157 case(GCIT_SupportsSSE3):
158 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_SSE3) >> FEATB_SSE3); break;
159 case(GCIT_SupportsSSSE3):
160 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_SSSE3) >> FEATB_SSSE3); break;
161 case(GCIT_SupportsSSE41):
162 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_SSE41) >> FEATB_SSE41); break;
163 case(GCIT_SupportsSSE42):
164 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_SSE42) >> FEATB_SSE42); break;
165 case(GCIT_SupportsMMXEXT):
166 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features3 & FEATF_MMXEXT) >> FEATB_MMXEXT); break;
167 case(GCIT_Supports3DNOW):
168 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features3 & FEATF_3DNOW) >> FEATB_3DNOW); break;
169 case(GCIT_Supports3DNOWEXT):
170 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features3 & FEATF_3DNOWEXT) >> FEATB_3DNOWEXT); break;
171 case(GCIT_SupportsSSE4A):
172 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features4 & FEATF_SSE4A) >> FEATB_SSE4A); break;
173 case(GCIT_SupportsVME):
174 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_VME) >> FEATB_VME); break;
175 case(GCIT_SupportsPSE):
176 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_PSE) >> FEATB_PSE); break;
177 case(GCIT_SupportsPAE):
178 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_PAE) >> FEATB_PAE); break;
179 case(GCIT_SupportsCX8):
180 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_CX8) >> FEATB_CX8); break;
181 case(GCIT_SupportsAPIC):
182 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_APIC) >> FEATB_APIC); break;
183 case(GCIT_SupportsCMOV):
184 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_CMOV) >> FEATB_CMOV); break;
185 case(GCIT_SupportsPSE36):
186 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_PSE36) >> FEATB_PSE36); break;
187 case(GCIT_SupportsCLFSH):
188 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_CLFSH) >> FEATB_CLFSH); break;
189 case(GCIT_SupportsACPI):
190 if (info->Vendor == VENDOR_INTEL)
191 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_ACPI) >> FEATB_ACPI);
192 else
193 *((BOOL *)tag->ti_Data) = FALSE; /* TODO: IMPLEMENT FOR AMD */
194 break;
195 case(GCIT_SupportsFXSR):
196 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_FXSR) >> FEATB_FXSR); break;
197 case(GCIT_SupportsHTT):
198 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_HTT) >> FEATB_HTT); break;
199 case(GCIT_SupportsCX16):
200 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_CX16) >> FEATB_CX16); break;
201 case(GCIT_SupportsVirtualization):
202 switch(info->Vendor)
204 case(VENDOR_INTEL):
205 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features2 & FEATF_VMX) >> FEATB_VMX); break;
206 case(VENDOR_AMD):
207 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features4 & FEATF_SVM) >> FEATB_SVM); break;
208 default:
209 *((BOOL *)tag->ti_Data) = FALSE; break;
211 break;
212 case(GCIT_SupportsNoExecutionBit):
213 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features3 & FEATF_XDNX) >> FEATB_XDNX); break;
214 case(GCIT_Supports64BitMode):
215 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features3 & FEATF_AMD64) >> FEATB_AMD64); break;
216 case(GCIT_SupportsMSR):
217 *((BOOL *)tag->ti_Data) = (BOOL)((info->Features1 & FEATF_MSR) >> FEATB_MSR); break;
218 default:
219 *((BOOL *)tag->ti_Data) = FALSE; break;