Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "cpu_detect_test.h"
12 : #include <stdbool.h>
13 : #include "cpu_detect_print.h"
14 :
15 : #define GROUP_GAP_TIME 1000 // 1000us
16 :
17 : typedef CpudStatus (*GroupDetectFunc)(uint32_t* regValues, uint32_t* loadStoreBuf, int32_t cpu);
18 : typedef void (*TestcaseDetectFuncA)(uint32_t* regValues);
19 : typedef void (*TestcaseDetectFuncB)(uint32_t* regValues, uint32_t* loadStoreBuf);
20 :
21 : typedef struct {
22 : const char* name;
23 : GroupDetectFunc func;
24 : } CpuGroupDetectSets;
25 :
26 : typedef struct {
27 : const char* name;
28 : TestcaseDetectFuncA funcA;
29 : TestcaseDetectFuncB funcB;
30 : } CpuTestcaseDetectSets;
31 :
32 : STATIC CpuGroupDetectSets g_cpuDetectSets[] = {
33 : {"GroupTaiShan", CpuDetectGroupTaiShan},
34 : {"GroupA", CpuDetectGroupA},
35 : {"GroupB", CpuDetectGroupB},
36 : {"GroupC", CpuDetectGroupC},
37 : {"GroupD", CpuDetectGroupD},
38 : {"GroupE", CpuDetectGroupE},
39 : {"GroupF", CpuDetectGroupF},
40 : {"GroupG", CpuDetectGroupG},
41 : {"GroupH", CpuDetectGroupH},
42 : };
43 :
44 : #ifdef CPU_DETECT_LINX_CORE
45 : // Taishan
46 : STATIC CpuTestcaseDetectSets g_cpuGroupTaiShanDetectSets[] = {};
47 :
48 : // GroupA
49 : STATIC CpuTestcaseDetectSets g_cpuGroupADetectSets[] = {
50 : {"TSRTIntAlu", TSRTIntAlu, NULL},
51 : {"TSRTIntCompare", TSRTIntCompare, NULL},
52 : {"TSRTIntCRCAndShiftAndMov", TSRTIntCRCAndShiftAndMov, NULL},
53 : };
54 :
55 : // GroupB
56 : STATIC CpuTestcaseDetectSets g_cpuGroupBDetectSets[] = {};
57 :
58 : // GroupC
59 : STATIC CpuTestcaseDetectSets g_cpuGroupCDetectSets[] = {};
60 :
61 : // GroupD
62 : STATIC CpuTestcaseDetectSets g_cpuGroupDDetectSets[] = {};
63 :
64 : // GroupE
65 : STATIC CpuTestcaseDetectSets g_cpuGroupEDetectSets[] = {
66 : {"GeneralLoadStoreP01", NULL, GeneralLoadStoreP01},
67 : {"GeneralLoadStoreP02", NULL, GeneralLoadStoreP02},
68 : {"LCRTGeneralLoadStoreP02", NULL, LCRTGeneralLoadStoreP02},
69 : {"LCRTGeneralLoadStoreP03", NULL, LCRTGeneralLoadStoreP03},
70 : {"LCRTGeneralLoadStoreP04", NULL, LCRTGeneralLoadStoreP04},
71 : {"GeneralPrefetchP01", NULL, GeneralPrefetchP01},
72 : {"LCRTGeneralLoadStoreP05", NULL, LCRTGeneralLoadStoreP05},
73 : };
74 :
75 : // GroupF
76 : STATIC CpuTestcaseDetectSets g_cpuGroupFDetectSets[] = {
77 : {"BranchInGeneralP01", BranchInGeneralP01, NULL},
78 : {"BranchInGeneralP02", BranchInGeneralP02, NULL},
79 : };
80 :
81 : // GroupG
82 : STATIC CpuTestcaseDetectSets g_cpuGroupGDetectSets[] = {
83 : {"EnhanceBranchP01", EnhanceBranchP01, NULL},
84 : {"EnhanceLoadStoreP02", NULL, EnhanceLoadStoreP02},
85 : {"BrAdrLiteral", BrAdrLiteral, NULL},
86 : {"DataCacheInvalidP01", NULL, DataCacheInvalidP01},
87 : {"EnhanceLoadStoreP01", NULL, EnhanceLoadStoreP01},
88 : {"InstrCacheInvalid", InstrCacheInvalid, NULL},
89 : {"LoadALUDependencyP01", NULL, LoadALUDependencyP01},
90 : };
91 :
92 : // GroupH
93 : STATIC CpuTestcaseDetectSets g_cpuGroupHDetectSets[] = {};
94 :
95 : #else
96 : // Taishan
97 : STATIC CpuTestcaseDetectSets g_cpuGroupTaiShanDetectSets[] = {
98 : {"TaishanFpComparisonP01", TaishanFpComparisonP01, NULL},
99 : {"TaishanFpMiniMaxiP01", TaishanFpMiniMaxiP01, NULL},
100 : {"TaishanFpMovMaddP01", TaishanFpMovMaddP01, NULL},
101 : {"TaishanSimdAddP01", TaishanSimdAddP01, NULL},
102 : {"TaishanSimdAritheticP01", TaishanSimdAritheticP01, NULL},
103 : {"TaishanSimdCompareP01", TaishanSimdCompareP01, NULL},
104 : {"TaishanSimdComplexP01", TaishanSimdComplexP01, NULL},
105 : {"TaishanSimdCryptoP01", TaishanSimdCryptoP01, NULL},
106 : {"TaishanSimdElementArithemticP01", TaishanSimdElementArithemticP01, NULL},
107 : {"TaishanSimdFpIntConversionP01", TaishanSimdFpIntConversionP01, NULL},
108 : {"TaishanSimdImmP01", TaishanSimdImmP01, NULL},
109 : {"TaishanSimdMovP01", TaishanSimdMovP01, NULL},
110 : {"TaishanSimdPairArithmeticP01", TaishanSimdPairArithmeticP01, NULL},
111 : {"TaishanSimdPermuteP01", TaishanSimdPermuteP01, NULL},
112 : {"TaishanSimdReduceP01", TaishanSimdReduceP01, NULL},
113 : {"TaishanSimdUnaryArithmeticP01", TaishanSimdUnaryArithmeticP01, NULL},
114 : {"TaishanSimdWideNarryArthemticP01", TaishanSimdWideNarryArthemticP01, NULL},
115 : {"TaishanIntAluP01", TaishanIntAluP01, NULL},
116 : {"TaishanIntCcP01", TaishanIntCcP01, NULL},
117 : {"TaishanIntMduP01", TaishanIntMduP01, NULL},
118 : {"TaishanIntAluP02", TaishanIntAluP02, NULL},
119 : {"TaishanIntMduP02", TaishanIntMduP02, NULL},
120 : {"TaishanIntCacheWriteReadP01", NULL, TaishanIntCacheWriteReadP01},
121 : {"TaishanIntCacheWriteReadP02", NULL, TaishanIntCacheWriteReadP02},
122 : {"TaishanIntCacheWriteReadP03", NULL, TaishanIntCacheWriteReadP03},
123 : {"TaishanIntCacheWriteReadP04", NULL, TaishanIntCacheWriteReadP04},
124 : {"TaishanIntCacheWriteReadP05", NULL, TaishanIntCacheWriteReadP05},
125 : {"TaishanIntCacheWriteReadP06", NULL, TaishanIntCacheWriteReadP06},
126 : };
127 :
128 : // GroupA
129 : STATIC CpuTestcaseDetectSets g_cpuGroupADetectSets[] = {
130 : {"SinglePressAdvsimdScalar01", SinglePressAdvsimdScalar01, NULL},
131 : {"SinglePressAdvsimdScalar02", SinglePressAdvsimdScalar02, NULL},
132 : {"SinglePressAdvsimdScalar03", SinglePressAdvsimdScalar03, NULL},
133 : {"SinglePressAdvsimdVector01", SinglePressAdvsimdVector01, NULL},
134 : {"SinglePressAdvsimdVector02", SinglePressAdvsimdVector02, NULL},
135 : {"SinglePressAdvsimdVector03", SinglePressAdvsimdVector03, NULL},
136 : {"SinglePressAdvsimdVector04", SinglePressAdvsimdVector04, NULL},
137 : {"SinglePressAdvsimdVector05", SinglePressAdvsimdVector05, NULL},
138 : {"SinglePressAdvsimdVector06", SinglePressAdvsimdVector06, NULL},
139 : {"SinglePressAdvsimdVector07", SinglePressAdvsimdVector07, NULL},
140 : {"SinglePressAdvsimdVector08", SinglePressAdvsimdVector08, NULL},
141 : {"SinglePressFloat01", SinglePressFloat01, NULL},
142 : {"SinglePressFloat02", SinglePressFloat02, NULL},
143 : {"SinglePressFloat03", SinglePressFloat03, NULL},
144 : {"SinglePressInt01", SinglePressInt01, NULL},
145 : {"SinglePressInt02", SinglePressInt02, NULL},
146 : {"SinglePressInt03", SinglePressInt03, NULL},
147 : };
148 :
149 : // GroupB
150 : STATIC CpuTestcaseDetectSets g_cpuGroupBDetectSets[] = {
151 : {"TSRTIntAllOperation", TSRTIntAllOperation, NULL},
152 : {"TSRTIntCompare", TSRTIntCompare, NULL},
153 : {"TSRTIntAlu", TSRTIntAlu, NULL},
154 : {"TSRTIntCRCAndShiftAndMov", TSRTIntCRCAndShiftAndMov, NULL},
155 : };
156 :
157 : // GroupC
158 : STATIC CpuTestcaseDetectSets g_cpuGroupCDetectSets[] = {
159 : {"TSRTFloatAllOperation", TSRTFloatAllOperation, NULL},
160 : {"TSRTFloatCompare", TSRTFloatCompare, NULL},
161 : {"TSRTFloatFixedPointConvertToFloatPoint", TSRTFloatFixedPointConvertToFloatPoint, NULL},
162 : {"TSRTFloatFloatPointConvertPrecision", TSRTFloatFloatPointConvertPrecision, NULL},
163 : {"TSRTFloatFloatPointRoundToInteger", TSRTFloatFloatPointRoundToInteger, NULL},
164 : {"TSRTFloatMinMax", TSRTFloatMinMax, NULL},
165 : {"TSRTFloatMovMadd", TSRTFloatMovMadd, NULL},
166 : };
167 :
168 : // GroupD
169 : STATIC CpuTestcaseDetectSets g_cpuGroupDDetectSets[] = {
170 : {"TSRTAdvsimdScalarAllOperation", TSRTAdvsimdScalarAllOperation, NULL},
171 : {"TSRTAdvsimdScalarCompare", TSRTAdvsimdScalarCompare, NULL},
172 : {"TSRTAdvsimdScalarFixedPointConvertToFloatPoint", TSRTAdvsimdScalarFixedPointConvertToFloatPoint, NULL},
173 : {"TSRTAdvsimdScalarFloatPointConvertToInteger", TSRTAdvsimdScalarFloatPointConvertToInteger, NULL},
174 : {"TSRTAdvsimdScalarGeneralOperation", TSRTAdvsimdScalarGeneralOperation, NULL},
175 : };
176 :
177 : // GroupE
178 : STATIC CpuTestcaseDetectSets g_cpuGroupEDetectSets[] = {
179 : {"TSRTAdvsimdVectorAllOperation", TSRTAdvsimdVectorAllOperation, NULL},
180 : {"TSRTAdvsimdVectorCompare", TSRTAdvsimdVectorCompare, NULL},
181 : {"TSRTAdvsimdVectorFixedPointConvertToFloatingPoint", TSRTAdvsimdVectorFixedPointConvertToFloatingPoint, NULL},
182 : {"TSRTAdvsimdVectorFloatingPointConvertToInteger", TSRTAdvsimdVectorFloatingPointConvertToInteger, NULL},
183 : {"TSRTAdvsimdVectorFloatingPointOperation", TSRTAdvsimdVectorFloatingPointOperation, NULL},
184 : {"TSRTAdvsimdVectorGeneralOperation", TSRTAdvsimdVectorGeneralOperation, NULL},
185 : {"TSRTAdvsimdVectorMaxMin", TSRTAdvsimdVectorMaxMin, NULL},
186 : {"TSRTAdvsimdVectorSecureHashStandard", TSRTAdvsimdVectorSecureHashStandard, NULL},
187 : {"TSRTAdvsimdVectorSignedOperation", TSRTAdvsimdVectorSignedOperation, NULL},
188 : {"TSRTAdvsimdVectorUnsignedOperation", TSRTAdvsimdVectorUnsignedOperation, NULL},
189 : };
190 :
191 : // GroupF
192 : STATIC CpuTestcaseDetectSets g_cpuGroupFDetectSets[] = {
193 : {"AdvsimdLoadDeprecatedP01", NULL, AdvsimdLoadDeprecatedP01},
194 : {"AdvsimdLoadDeprecatedP02", NULL, AdvsimdLoadDeprecatedP02},
195 : {"AdvsimdLoadDeprecatedP03", NULL, AdvsimdLoadDeprecatedP03},
196 : {"AdvsimdLoadDeprecatedP04", NULL, AdvsimdLoadDeprecatedP04},
197 : {"AdvsimdLoadStoreP01", NULL, AdvsimdLoadStoreP01},
198 : {"AdvsimdLoadStoreP02", NULL, AdvsimdLoadStoreP02},
199 : {"AdvsimdLoadStoreP03", NULL, AdvsimdLoadStoreP03},
200 : {"AdvsimdLoadStoreP04", NULL, AdvsimdLoadStoreP04},
201 : {"AdvsimdLoadStoreP05", NULL, AdvsimdLoadStoreP05},
202 : {"AdvsimdLoadStoreP06", NULL, AdvsimdLoadStoreP06},
203 : {"AdvsimdLoadStoreP07", NULL, AdvsimdLoadStoreP07},
204 : {"FpsimdLoadStoreP01", NULL, FpsimdLoadStoreP01},
205 : {"FpsimdLoadStoreP02", NULL, FpsimdLoadStoreP02},
206 : {"GeneralLoadStoreP01", NULL, GeneralLoadStoreP01},
207 : {"GeneralLoadStoreP02", NULL, GeneralLoadStoreP02},
208 : {"GeneralLoadStoreP03", NULL, GeneralLoadStoreP03},
209 : {"GeneralLoadStoreP04", NULL, GeneralLoadStoreP04},
210 : };
211 :
212 : // GroupG
213 : STATIC CpuTestcaseDetectSets g_cpuGroupGDetectSets[] = {
214 : {"BranchInGeneralP01", BranchInGeneralP01, NULL},
215 : {"BranchInGeneralP02", BranchInGeneralP02, NULL},
216 :
217 : };
218 :
219 : // GroupH
220 : STATIC CpuTestcaseDetectSets g_cpuGroupHDetectSets[] = {
221 : {"DataReverseAdvsimdScalarP01", DataReverseAdvsimdScalarP01, NULL},
222 : {"DataReverseAdvsimdVectorP01", DataReverseAdvsimdVectorP01, NULL},
223 : {"DataReverseAdvsimdVectorP02", DataReverseAdvsimdVectorP02, NULL},
224 : {"DataReverseAdvsimdVectorP03", DataReverseAdvsimdVectorP03, NULL},
225 : {"DataReverseAdvsimdVectorP04", DataReverseAdvsimdVectorP04, NULL},
226 : {"DataReverseFloatP01", DataReverseFloatP01, NULL},
227 : {"DataReverseIntP01", DataReverseIntP01, NULL},
228 : {"EnhanceBranchP01", EnhanceBranchP01, NULL},
229 : {"EnhanceDependencyP01", EnhanceDependencyP01, NULL},
230 : {"EnhanceLoadStoreP01", NULL, EnhanceLoadStoreP01},
231 : {"EnhanceLoadStoreP02", NULL, EnhanceLoadStoreP02},
232 : };
233 :
234 : #endif
235 :
236 : // print the debug info of CPU
237 1 : STATIC void CpuDetectDumpBuf(uint32_t* regValues, int32_t len, int32_t cpu)
238 : {
239 1 : const int32_t regSize = 4;
240 1 : const int32_t regNum = len / regSize;
241 1 : uint32_t* p = regValues;
242 17 : for (int32_t idx = 0; idx < regNum; idx++) {
243 16 : int32_t v = idx * regSize;
244 16 : ADETECT_ERR(
245 : "cpu(%d) detect failed, X%02d:0x%08x_%08x X%02d:0x%08x_%08x", cpu, (v / 2 + 1), p[v + 1], p[v], (v / 2 + 2),
246 : p[v + 3], p[v + 2]); // 一个寄存器有4个字节,分别打印0\1\2\3字节
247 : }
248 1 : }
249 :
250 1007 : STATIC bool CpuDetectCheckBuf(uint32_t* regValues, int32_t len)
251 : {
252 : // if test fail, buf[1][0] will not be zero
253 1007 : const int32_t retReg = 2;
254 1007 : if ((len < retReg) || (regValues[0] != 0) || (regValues[1] != 0)) {
255 1 : return false;
256 : }
257 1006 : return true;
258 : }
259 :
260 90 : STATIC CpudStatus CpuDetectGroupComm(
261 : const CpuTestcaseDetectSets* detectSet, uint32_t num, uint32_t* regValues, uint32_t* loadStoreBuf, int cpu)
262 : {
263 1092 : for (uint32_t i = 0; i < num; i++) {
264 1002 : if ((detectSet[i].funcA == NULL) && (detectSet[i].funcB == NULL)) {
265 0 : continue;
266 : }
267 : // run testcase
268 1002 : if (detectSet[i].funcA != NULL) {
269 755 : (void)memset_s(regValues, TEMP_BUF_SIZE, 0, TEMP_BUF_SIZE);
270 760 : detectSet[i].funcA(regValues);
271 247 : } else if (detectSet[i].funcB != NULL) {
272 247 : (void)memset_s(regValues, TEMP_BUF_SIZE, 0, TEMP_BUF_SIZE);
273 250 : (void)memset_s(loadStoreBuf, TEMP_BUF_SIZE, 0, TEMP_BUF_SIZE);
274 250 : detectSet[i].funcB(regValues, loadStoreBuf);
275 : }
276 :
277 : // check
278 1008 : bool result = CpuDetectCheckBuf(regValues, TEMP_BUF_SIZE);
279 1006 : if (!result) {
280 4 : ADETECT_ERR(
281 : "cpu(%d) detection run testcase(%s) failed, reg[0] = %d, reg[1] = %d.", cpu, detectSet[i].name,
282 : regValues[0], regValues[1]);
283 1 : CpuDetectDumpBuf(regValues, PRINT_TEMP_BUF_LEN, cpu);
284 1 : return CPUD_ERROR_TESTCASE;
285 : }
286 : }
287 90 : usleep(GROUP_GAP_TIME);
288 89 : return CPUD_SUCCESS;
289 : }
290 :
291 10 : CpudStatus CpuDetectGroupTaiShan(uint32_t* regValues, uint32_t* loadStoreBuf, int32_t cpu)
292 : {
293 10 : const uint32_t num = sizeof(g_cpuGroupTaiShanDetectSets) / sizeof(CpuTestcaseDetectSets);
294 10 : return CpuDetectGroupComm(g_cpuGroupTaiShanDetectSets, num, regValues, loadStoreBuf, cpu);
295 : }
296 :
297 10 : CpudStatus CpuDetectGroupA(uint32_t* regValues, uint32_t* loadStoreBuf, int32_t cpu)
298 : {
299 10 : const uint32_t num = sizeof(g_cpuGroupADetectSets) / sizeof(CpuTestcaseDetectSets);
300 10 : return CpuDetectGroupComm(g_cpuGroupADetectSets, num, regValues, loadStoreBuf, cpu);
301 : }
302 :
303 10 : CpudStatus CpuDetectGroupB(uint32_t* regValues, uint32_t* loadStoreBuf, int32_t cpu)
304 : {
305 10 : const uint32_t num = sizeof(g_cpuGroupBDetectSets) / sizeof(CpuTestcaseDetectSets);
306 10 : return CpuDetectGroupComm(g_cpuGroupBDetectSets, num, regValues, loadStoreBuf, cpu);
307 : }
308 :
309 10 : CpudStatus CpuDetectGroupC(uint32_t* regValues, uint32_t* loadStoreBuf, int32_t cpu)
310 : {
311 10 : const uint32_t num = sizeof(g_cpuGroupCDetectSets) / sizeof(CpuTestcaseDetectSets);
312 10 : return CpuDetectGroupComm(g_cpuGroupCDetectSets, num, regValues, loadStoreBuf, cpu);
313 : }
314 :
315 10 : CpudStatus CpuDetectGroupD(uint32_t* regValues, uint32_t* loadStoreBuf, int32_t cpu)
316 : {
317 10 : const uint32_t num = sizeof(g_cpuGroupDDetectSets) / sizeof(CpuTestcaseDetectSets);
318 10 : return CpuDetectGroupComm(g_cpuGroupDDetectSets, num, regValues, loadStoreBuf, cpu);
319 : }
320 :
321 10 : CpudStatus CpuDetectGroupE(uint32_t* regValues, uint32_t* loadStoreBuf, int32_t cpu)
322 : {
323 10 : const uint32_t num = sizeof(g_cpuGroupEDetectSets) / sizeof(CpuTestcaseDetectSets);
324 10 : return CpuDetectGroupComm(g_cpuGroupEDetectSets, num, regValues, loadStoreBuf, cpu);
325 : }
326 :
327 10 : CpudStatus CpuDetectGroupF(uint32_t* regValues, uint32_t* loadStoreBuf, int32_t cpu)
328 : {
329 10 : const uint32_t num = sizeof(g_cpuGroupFDetectSets) / sizeof(CpuTestcaseDetectSets);
330 10 : return CpuDetectGroupComm(g_cpuGroupFDetectSets, num, regValues, loadStoreBuf, cpu);
331 : }
332 :
333 10 : CpudStatus CpuDetectGroupG(uint32_t* regValues, uint32_t* loadStoreBuf, int32_t cpu)
334 : {
335 10 : const uint32_t num = sizeof(g_cpuGroupGDetectSets) / sizeof(CpuTestcaseDetectSets);
336 10 : return CpuDetectGroupComm(g_cpuGroupGDetectSets, num, regValues, loadStoreBuf, cpu);
337 : }
338 :
339 10 : CpudStatus CpuDetectGroupH(uint32_t* regValues, uint32_t* loadStoreBuf, int32_t cpu)
340 : {
341 10 : const uint32_t num = sizeof(g_cpuGroupHDetectSets) / sizeof(CpuTestcaseDetectSets);
342 10 : return CpuDetectGroupComm(g_cpuGroupHDetectSets, num, regValues, loadStoreBuf, cpu);
343 : }
344 :
345 10 : CpudStatus CpuDetectGroup(uint32_t* regValues, uint32_t* loadStoreBuf, int32_t cpu)
346 : {
347 10 : ADETECT_CHK_EXPR_ACTION(
348 : (regValues == NULL) || (loadStoreBuf == NULL), return CPUD_ERROR_PARAM, "invalid input param.");
349 10 : int32_t num = sizeof(g_cpuDetectSets) / sizeof(CpuGroupDetectSets);
350 99 : for (int32_t i = 0; i < num; i++) {
351 90 : if (g_cpuDetectSets[i].func == NULL) {
352 0 : continue;
353 : }
354 90 : CpudStatus ret = g_cpuDetectSets[i].func(regValues, loadStoreBuf, cpu);
355 90 : if (ret != CPUD_SUCCESS) {
356 1 : ADETECT_ERR("cpu(%d) run testcase group(%s) failed.", cpu, g_cpuDetectSets[i].name);
357 1 : return ret;
358 : }
359 : }
360 9 : return CPUD_SUCCESS;
361 : }
|