19bf9a700SWesley Yao // Copyright 2006 Google Inc. All Rights Reserved. 29bf9a700SWesley Yao /* Licensed under the Apache License, Version 2.0 (the "License"); 39bf9a700SWesley Yao * you may not use this file except in compliance with the License. 49bf9a700SWesley Yao * You may obtain a copy of the License at 59bf9a700SWesley Yao * 69bf9a700SWesley Yao * http://www.apache.org/licenses/LICENSE-2.0 79bf9a700SWesley Yao * 89bf9a700SWesley Yao * Unless required by applicable law or agreed to in writing, software 99bf9a700SWesley Yao * distributed under the License is distributed on an "AS IS" BASIS, 109bf9a700SWesley Yao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 119bf9a700SWesley Yao * See the License for the specific language governing permissions and 129bf9a700SWesley Yao * limitations under the License. 139bf9a700SWesley Yao */ 149bf9a700SWesley Yao 159bf9a700SWesley Yao /* This is stressapptest for Rockchip platform in U-Boot, the design idea and 169bf9a700SWesley Yao * the patterns are from code.google.com/p/stressapptest. 179bf9a700SWesley Yao */ 189bf9a700SWesley Yao 199bf9a700SWesley Yao #include <common.h> 209bf9a700SWesley Yao #include <amp.h> 219bf9a700SWesley Yao #include <div64.h> 229bf9a700SWesley Yao #include <malloc.h> 239bf9a700SWesley Yao #include <asm/arch/rockchip_smccc.h> 249bf9a700SWesley Yao #include "stressapptest.h" 259bf9a700SWesley Yao #include "../ddr_tool_common.h" 269bf9a700SWesley Yao 27*aa9eaea1SWesley Yao #define __version__ "v1.1.0 20230523" 289bf9a700SWesley Yao 299bf9a700SWesley Yao #if defined(CONFIG_ARM64) 309bf9a700SWesley Yao /* Float operation in TOOLCHAIN_ARM32 will cause the compile error */ 319bf9a700SWesley Yao #define WARM_CPU 329bf9a700SWesley Yao #endif 339bf9a700SWesley Yao 349bf9a700SWesley Yao #define PAT_NUM 26 359bf9a700SWesley Yao #define PATTERN_LIST_SIZE (PAT_NUM * 2 * 4) 369bf9a700SWesley Yao 379bf9a700SWesley Yao #define CPU_NUM_MAX 16 389bf9a700SWesley Yao 399bf9a700SWesley Yao static u32 walking_1_data[] = { 409bf9a700SWesley Yao 0x00000001, 0x00000002, 0x00000004, 0x00000008, 419bf9a700SWesley Yao 0x00000010, 0x00000020, 0x00000040, 0x00000080, 429bf9a700SWesley Yao 0x00000100, 0x00000200, 0x00000400, 0x00000800, 439bf9a700SWesley Yao 0x00001000, 0x00002000, 0x00004000, 0x00008000, 449bf9a700SWesley Yao 0x00010000, 0x00020000, 0x00040000, 0x00080000, 459bf9a700SWesley Yao 0x00100000, 0x00200000, 0x00400000, 0x00800000, 469bf9a700SWesley Yao 0x01000000, 0x02000000, 0x04000000, 0x08000000, 479bf9a700SWesley Yao 0x10000000, 0x20000000, 0x40000000, 0x80000000, 489bf9a700SWesley Yao 0x40000000, 0x20000000, 0x10000000, 0x08000000, 499bf9a700SWesley Yao 0x04000000, 0x02000000, 0x01000000, 0x00800000, 509bf9a700SWesley Yao 0x00400000, 0x00200000, 0x00100000, 0x00080000, 519bf9a700SWesley Yao 0x00040000, 0x00020000, 0x00010000, 0x00008000, 529bf9a700SWesley Yao 0x00004000, 0x00002000, 0x00001000, 0x00000800, 539bf9a700SWesley Yao 0x00000400, 0x00000200, 0x00000100, 0x00000080, 549bf9a700SWesley Yao 0x00000040, 0x00000020, 0x00000010, 0x00000008, 559bf9a700SWesley Yao 0x00000004, 0x00000002, 0x00000001, 0x00000000 569bf9a700SWesley Yao }; 579bf9a700SWesley Yao 589bf9a700SWesley Yao static struct pat walking_1 = { 599bf9a700SWesley Yao "walking_1", 609bf9a700SWesley Yao walking_1_data, 619bf9a700SWesley Yao ARRAY_SIZE(walking_1_data) - 1, /* mask */ 629bf9a700SWesley Yao {1, 1, 2, 1} /* weight */ 639bf9a700SWesley Yao }; 649bf9a700SWesley Yao 659bf9a700SWesley Yao static u32 walking_1_x16_data[] = { 669bf9a700SWesley Yao 0x00020001, 0x00080004, 0x00200010, 0x00800040, 679bf9a700SWesley Yao 0x02000100, 0x08000400, 0x20001000, 0x80004000, 689bf9a700SWesley Yao 0x20004000, 0x08001000, 0x02000400, 0x00800100, 699bf9a700SWesley Yao 0x00200040, 0x00080010, 0x00020004, 0x00000001 709bf9a700SWesley Yao }; 719bf9a700SWesley Yao 729bf9a700SWesley Yao static struct pat walking_1_x16 = { 739bf9a700SWesley Yao "walking_1_x16", 749bf9a700SWesley Yao walking_1_x16_data, 759bf9a700SWesley Yao ARRAY_SIZE(walking_1_x16_data) - 1, /* mask */ 769bf9a700SWesley Yao {2, 0, 0, 0} /* Weight for choosing 32/64/128/256 bit wide of this pattern */ 779bf9a700SWesley Yao /* Reuse for walking_0_x16, because of invert */ 789bf9a700SWesley Yao }; 799bf9a700SWesley Yao 809bf9a700SWesley Yao static u32 walking_1_x16_repeat_data[] = { 819bf9a700SWesley Yao 0x00010001, 0x00020002, 0x00040004, 0x00080008, 829bf9a700SWesley Yao 0x00100010, 0x00200020, 0x00400040, 0x00800080, 839bf9a700SWesley Yao 0x01000100, 0x02000200, 0x04000400, 0x08000800, 849bf9a700SWesley Yao 0x10001000, 0x20002000, 0x40004000, 0x80008000, 859bf9a700SWesley Yao 0x40004000, 0x20002000, 0x10001000, 0x08000800, 869bf9a700SWesley Yao 0x04000400, 0x02000200, 0x01000100, 0x00800080, 879bf9a700SWesley Yao 0x00400040, 0x00200020, 0x00100010, 0x00080008, 889bf9a700SWesley Yao 0x00040004, 0x00020002, 0x00010001, 0x00000000 899bf9a700SWesley Yao }; 909bf9a700SWesley Yao 919bf9a700SWesley Yao static struct pat walking_1_x16_repeat = { 929bf9a700SWesley Yao "walking_1_x16_repeat", 939bf9a700SWesley Yao walking_1_x16_repeat_data, 949bf9a700SWesley Yao ARRAY_SIZE(walking_1_x16_repeat_data) - 1, /* mask */ 959bf9a700SWesley Yao {2, 4, 2, 0} /* Weight for choosing 32/64/128/256 bit wide of this pattern */ 969bf9a700SWesley Yao /* Reuse for walking_0_x16_repeat, because of invert */ 979bf9a700SWesley Yao }; 989bf9a700SWesley Yao 999bf9a700SWesley Yao static u32 walking_inv_1_data[] = { 1009bf9a700SWesley Yao 0x00000001, 0xfffffffe, 0x00000002, 0xfffffffd, 1019bf9a700SWesley Yao 0x00000004, 0xfffffffb, 0x00000008, 0xfffffff7, 1029bf9a700SWesley Yao 0x00000010, 0xffffffef, 0x00000020, 0xffffffdf, 1039bf9a700SWesley Yao 0x00000040, 0xffffffbf, 0x00000080, 0xffffff7f, 1049bf9a700SWesley Yao 0x00000100, 0xfffffeff, 0x00000200, 0xfffffdff, 1059bf9a700SWesley Yao 0x00000400, 0xfffffbff, 0x00000800, 0xfffff7ff, 1069bf9a700SWesley Yao 0x00001000, 0xffffefff, 0x00002000, 0xffffdfff, 1079bf9a700SWesley Yao 0x00004000, 0xffffbfff, 0x00008000, 0xffff7fff, 1089bf9a700SWesley Yao 0x00010000, 0xfffeffff, 0x00020000, 0xfffdffff, 1099bf9a700SWesley Yao 0x00040000, 0xfffbffff, 0x00080000, 0xfff7ffff, 1109bf9a700SWesley Yao 0x00100000, 0xffefffff, 0x00200000, 0xffdfffff, 1119bf9a700SWesley Yao 0x00400000, 0xffbfffff, 0x00800000, 0xff7fffff, 1129bf9a700SWesley Yao 0x01000000, 0xfeffffff, 0x02000000, 0xfdffffff, 1139bf9a700SWesley Yao 0x04000000, 0xfbffffff, 0x08000000, 0xf7ffffff, 1149bf9a700SWesley Yao 0x10000000, 0xefffffff, 0x20000000, 0xdfffffff, 1159bf9a700SWesley Yao 0x40000000, 0xbfffffff, 0x80000000, 0x7fffffff, 1169bf9a700SWesley Yao 0x40000000, 0xbfffffff, 0x20000000, 0xdfffffff, 1179bf9a700SWesley Yao 0x10000000, 0xefffffff, 0x08000000, 0xf7ffffff, 1189bf9a700SWesley Yao 0x04000000, 0xfbffffff, 0x02000000, 0xfdffffff, 1199bf9a700SWesley Yao 0x01000000, 0xfeffffff, 0x00800000, 0xff7fffff, 1209bf9a700SWesley Yao 0x00400000, 0xffbfffff, 0x00200000, 0xffdfffff, 1219bf9a700SWesley Yao 0x00100000, 0xffefffff, 0x00080000, 0xfff7ffff, 1229bf9a700SWesley Yao 0x00040000, 0xfffbffff, 0x00020000, 0xfffdffff, 1239bf9a700SWesley Yao 0x00010000, 0xfffeffff, 0x00008000, 0xffff7fff, 1249bf9a700SWesley Yao 0x00004000, 0xffffbfff, 0x00002000, 0xffffdfff, 1259bf9a700SWesley Yao 0x00001000, 0xffffefff, 0x00000800, 0xfffff7ff, 1269bf9a700SWesley Yao 0x00000400, 0xfffffbff, 0x00000200, 0xfffffdff, 1279bf9a700SWesley Yao 0x00000100, 0xfffffeff, 0x00000080, 0xffffff7f, 1289bf9a700SWesley Yao 0x00000040, 0xffffffbf, 0x00000020, 0xffffffdf, 1299bf9a700SWesley Yao 0x00000010, 0xffffffef, 0x00000008, 0xfffffff7, 1309bf9a700SWesley Yao 0x00000004, 0xfffffffb, 0x00000002, 0xfffffffd, 1319bf9a700SWesley Yao 0x00000001, 0xfffffffe, 0x00000000, 0xffffffff 1329bf9a700SWesley Yao }; 1339bf9a700SWesley Yao 1349bf9a700SWesley Yao static struct pat walking_inv_1 = { 1359bf9a700SWesley Yao "walking_inv_1", 1369bf9a700SWesley Yao walking_inv_1_data, 1379bf9a700SWesley Yao ARRAY_SIZE(walking_inv_1_data) - 1, /* mask */ 1389bf9a700SWesley Yao {2, 2, 5, 5} /* weight */ 1399bf9a700SWesley Yao }; 1409bf9a700SWesley Yao 1419bf9a700SWesley Yao static u32 walking_inv_1_x16_data[] = { 1429bf9a700SWesley Yao 0xfffe0001, 0xfffd0002, 0xfffb0004, 0xfff70008, 1439bf9a700SWesley Yao 0xffef0010, 0xffdf0020, 0xffbf0040, 0xff7f0080, 1449bf9a700SWesley Yao 0xfeff0100, 0xfdff0200, 0xfbff0400, 0xf7ff0800, 1459bf9a700SWesley Yao 0xefff1000, 0xdfff2000, 0xbfff4000, 0x7fff8000, 1469bf9a700SWesley Yao 0xbfff4000, 0xdfff2000, 0xefff1000, 0xf7ff0800, 1479bf9a700SWesley Yao 0xfbff0400, 0xfdff0200, 0xfeff0100, 0xff7f0080, 1489bf9a700SWesley Yao 0xffbf0040, 0xffdf0020, 0xffef0010, 0xfff70008, 1499bf9a700SWesley Yao 0xfffb0004, 0xfffd0002, 0xfffe0001, 0xffff0000 1509bf9a700SWesley Yao }; 1519bf9a700SWesley Yao 1529bf9a700SWesley Yao static struct pat walking_inv_1_x16 = { 1539bf9a700SWesley Yao "walking_inv_1_x16", 1549bf9a700SWesley Yao walking_inv_1_x16_data, 1559bf9a700SWesley Yao ARRAY_SIZE(walking_inv_1_x16_data) - 1, /* mask */ 1569bf9a700SWesley Yao {2, 0, 0, 0} /* weight */ 1579bf9a700SWesley Yao }; 1589bf9a700SWesley Yao 1599bf9a700SWesley Yao static u32 walking_inv_1_x16_repeat_data[] = { 1609bf9a700SWesley Yao 0x00010001, 0xfffefffe, 0x00020002, 0xfffdfffd, 1619bf9a700SWesley Yao 0x00040004, 0xfffbfffb, 0x00080008, 0xfff7fff7, 1629bf9a700SWesley Yao 0x00100010, 0xffefffef, 0x00200020, 0xffdfffdf, 1639bf9a700SWesley Yao 0x00400040, 0xffbfffbf, 0x00800080, 0xff7fff7f, 1649bf9a700SWesley Yao 0x01000100, 0xfefffeff, 0x02000200, 0xfdfffdff, 1659bf9a700SWesley Yao 0x04000400, 0xfbfffbff, 0x08000800, 0xf7fff7ff, 1669bf9a700SWesley Yao 0x10001000, 0xefffefff, 0x20002000, 0xdfffdfff, 1679bf9a700SWesley Yao 0x40004000, 0xbfffbfff, 0x80008000, 0x7fff7fff, 1689bf9a700SWesley Yao 0x40004000, 0xbfffbfff, 0x20002000, 0xdfffdfff, 1699bf9a700SWesley Yao 0x10001000, 0xefffefff, 0x08000800, 0xf7fff7ff, 1709bf9a700SWesley Yao 0x04000400, 0xfbfffbff, 0x02000200, 0xfdfffdff, 1719bf9a700SWesley Yao 0x01000100, 0xfefffeff, 0x00800080, 0xff7fff7f, 1729bf9a700SWesley Yao 0x00400040, 0xffbfffbf, 0x00200020, 0xffdfffdf, 1739bf9a700SWesley Yao 0x00100010, 0xffefffef, 0x00080008, 0xfff7fff7, 1749bf9a700SWesley Yao 0x00040004, 0xfffbfffb, 0x00020002, 0xfffdfffd, 1759bf9a700SWesley Yao 0x00010001, 0xfffefffe, 0x00000000, 0xffffffff 1769bf9a700SWesley Yao }; 1779bf9a700SWesley Yao 1789bf9a700SWesley Yao static struct pat walking_inv_1_x16_repeat = { 1799bf9a700SWesley Yao "walking_inv_1_x16_repeat", 1809bf9a700SWesley Yao walking_inv_1_x16_repeat_data, 1819bf9a700SWesley Yao ARRAY_SIZE(walking_inv_1_x16_repeat_data) - 1, /* mask */ 1829bf9a700SWesley Yao {2, 5, 5, 0} /* weight */ 1839bf9a700SWesley Yao }; 1849bf9a700SWesley Yao 1859bf9a700SWesley Yao static u32 walking_0_data[] = { 1869bf9a700SWesley Yao 0xfffffffe, 0xfffffffd, 0xfffffffb, 0xfffffff7, 1879bf9a700SWesley Yao 0xffffffef, 0xffffffdf, 0xffffffbf, 0xffffff7f, 1889bf9a700SWesley Yao 0xfffffeff, 0xfffffdff, 0xfffffbff, 0xfffff7ff, 1899bf9a700SWesley Yao 0xffffefff, 0xffffdfff, 0xffffbfff, 0xffff7fff, 1909bf9a700SWesley Yao 0xfffeffff, 0xfffdffff, 0xfffbffff, 0xfff7ffff, 1919bf9a700SWesley Yao 0xffefffff, 0xffdfffff, 0xffbfffff, 0xff7fffff, 1929bf9a700SWesley Yao 0xfeffffff, 0xfdffffff, 0xfbffffff, 0xf7ffffff, 1939bf9a700SWesley Yao 0xefffffff, 0xdfffffff, 0xbfffffff, 0x7fffffff, 1949bf9a700SWesley Yao 0xbfffffff, 0xdfffffff, 0xefffffff, 0xf7ffffff, 1959bf9a700SWesley Yao 0xfbffffff, 0xfdffffff, 0xfeffffff, 0xff7fffff, 1969bf9a700SWesley Yao 0xffbfffff, 0xffdfffff, 0xffefffff, 0xfff7ffff, 1979bf9a700SWesley Yao 0xfffbffff, 0xfffdffff, 0xfffeffff, 0xffff7fff, 1989bf9a700SWesley Yao 0xffffbfff, 0xffffdfff, 0xffffefff, 0xfffff7ff, 1999bf9a700SWesley Yao 0xfffffbff, 0xfffffdff, 0xfffffeff, 0xffffff7f, 2009bf9a700SWesley Yao 0xffffffbf, 0xffffffdf, 0xffffffef, 0xfffffff7, 2019bf9a700SWesley Yao 0xfffffffb, 0xfffffffd, 0xfffffffe, 0xffffffff 2029bf9a700SWesley Yao }; 2039bf9a700SWesley Yao 2049bf9a700SWesley Yao static struct pat walking_0 = { 2059bf9a700SWesley Yao "walking_0", 2069bf9a700SWesley Yao walking_0_data, 2079bf9a700SWesley Yao ARRAY_SIZE(walking_0_data) - 1, /* mask */ 2089bf9a700SWesley Yao {1, 1, 2, 1} /* weight */ 2099bf9a700SWesley Yao }; 2109bf9a700SWesley Yao 2119bf9a700SWesley Yao static u32 one_zero_data[] = {0x00000000, 0xffffffff}; 2129bf9a700SWesley Yao 2139bf9a700SWesley Yao static struct pat one_zero = { 2149bf9a700SWesley Yao "one_zero", 2159bf9a700SWesley Yao one_zero_data, 2169bf9a700SWesley Yao ARRAY_SIZE(one_zero_data) - 1, /* mask */ 2179bf9a700SWesley Yao {5, 5, 15, 5} /* weight */ 2189bf9a700SWesley Yao }; 2199bf9a700SWesley Yao 2209bf9a700SWesley Yao static unsigned int one_zero_x16_data[] = {0x0000ffff, 0x0000ffff}; 2219bf9a700SWesley Yao 2229bf9a700SWesley Yao static struct pat one_zero_x16 = { 2239bf9a700SWesley Yao "one_zero_x16", 2249bf9a700SWesley Yao one_zero_x16_data, 2259bf9a700SWesley Yao ARRAY_SIZE(one_zero_x16_data) - 1, /* mask */ 2269bf9a700SWesley Yao {5, 0, 0, 0} /* weight */ 2279bf9a700SWesley Yao }; 2289bf9a700SWesley Yao 2299bf9a700SWesley Yao static u32 just_0_data[] = {0x00000000, 0x00000000}; 2309bf9a700SWesley Yao 2319bf9a700SWesley Yao static struct pat just_0 = { 2329bf9a700SWesley Yao "just_0", 2339bf9a700SWesley Yao just_0_data, 2349bf9a700SWesley Yao ARRAY_SIZE(just_0_data) - 1, /* mask */ 2359bf9a700SWesley Yao {2, 0, 0, 0} /* weight */ 2369bf9a700SWesley Yao }; 2379bf9a700SWesley Yao 2389bf9a700SWesley Yao static u32 just_1_data[] = {0xffffffff, 0xffffffff}; 2399bf9a700SWesley Yao 2409bf9a700SWesley Yao static struct pat just_1 = { 2419bf9a700SWesley Yao "just_1", 2429bf9a700SWesley Yao just_1_data, 2439bf9a700SWesley Yao ARRAY_SIZE(just_1_data) - 1, /* mask */ 2449bf9a700SWesley Yao {2, 0, 0, 0} /* weight */ 2459bf9a700SWesley Yao }; 2469bf9a700SWesley Yao 2479bf9a700SWesley Yao static u32 just_5_data[] = {0x55555555, 0x55555555}; 2489bf9a700SWesley Yao 2499bf9a700SWesley Yao static struct pat just_5 = { 2509bf9a700SWesley Yao "just_5", 2519bf9a700SWesley Yao just_5_data, 2529bf9a700SWesley Yao ARRAY_SIZE(just_5_data) - 1, /* mask */ 2539bf9a700SWesley Yao {2, 0, 0, 0} /* weight */ 2549bf9a700SWesley Yao }; 2559bf9a700SWesley Yao 2569bf9a700SWesley Yao static u32 just_a_data[] = {0xaaaaaaaa, 0xaaaaaaaa}; 2579bf9a700SWesley Yao 2589bf9a700SWesley Yao static struct pat just_a = { 2599bf9a700SWesley Yao "just_a", 2609bf9a700SWesley Yao just_a_data, 2619bf9a700SWesley Yao ARRAY_SIZE(just_a_data) - 1, /* mask */ 2629bf9a700SWesley Yao {2, 0, 0, 0} /* weight */ 2639bf9a700SWesley Yao }; 2649bf9a700SWesley Yao 2659bf9a700SWesley Yao static u32 five_a_data[] = {0x55555555, 0xaaaaaaaa}; 2669bf9a700SWesley Yao 2679bf9a700SWesley Yao static struct pat five_a = { 2689bf9a700SWesley Yao "five_a", 2699bf9a700SWesley Yao five_a_data, 2709bf9a700SWesley Yao ARRAY_SIZE(five_a_data) - 1, /* mask */ 2719bf9a700SWesley Yao {1, 1, 1, 1} /* weight */ 2729bf9a700SWesley Yao }; 2739bf9a700SWesley Yao 2749bf9a700SWesley Yao static unsigned int five_a_x16_data[] = {0x5555aaaa, 0x5555aaaa}; 2759bf9a700SWesley Yao 2769bf9a700SWesley Yao static struct pat five_a_x16 = { 2779bf9a700SWesley Yao "five_a_x16", 2789bf9a700SWesley Yao five_a_x16_data, 2799bf9a700SWesley Yao ARRAY_SIZE(five_a_x16_data) - 1, /* mask */ 2809bf9a700SWesley Yao {1, 0, 0, 0} /* weight */ 2819bf9a700SWesley Yao }; 2829bf9a700SWesley Yao 2839bf9a700SWesley Yao static u32 five_a8_data[] = { 2849bf9a700SWesley Yao 0x5aa5a55a, 0xa55a5aa5, 0xa55a5aa5, 0x5aa5a55a 2859bf9a700SWesley Yao }; 2869bf9a700SWesley Yao 2879bf9a700SWesley Yao static struct pat five_a8 = { 2889bf9a700SWesley Yao "five_a8", 2899bf9a700SWesley Yao five_a8_data, 2909bf9a700SWesley Yao ARRAY_SIZE(five_a8_data) - 1, /* mask */ 2919bf9a700SWesley Yao {1, 1, 1, 1} /* weight */ 2929bf9a700SWesley Yao }; 2939bf9a700SWesley Yao 2949bf9a700SWesley Yao static u32 five_a8_x16_data[] = {0x5aa5a55a, 0xa55a5aa5}; 2959bf9a700SWesley Yao 2969bf9a700SWesley Yao static struct pat five_a8_x16 = { 2979bf9a700SWesley Yao "five_a8_x16", 2989bf9a700SWesley Yao five_a8_x16_data, 2999bf9a700SWesley Yao ARRAY_SIZE(five_a8_x16_data) - 1, /* mask */ 3009bf9a700SWesley Yao {1, 0, 0, 0} /* weight */ 3019bf9a700SWesley Yao }; 3029bf9a700SWesley Yao 3039bf9a700SWesley Yao static unsigned int five_a8_x16_repeat_data[] = { 3049bf9a700SWesley Yao 0x5aa55aa5, 0xa55aa55a, 0xa55aa55a, 0x5aa55aa5 3059bf9a700SWesley Yao }; 3069bf9a700SWesley Yao 3079bf9a700SWesley Yao static struct pat five_a8_x16_repeat = { 3089bf9a700SWesley Yao "five_a8_x16_repeat", 3099bf9a700SWesley Yao five_a8_x16_repeat_data, 3109bf9a700SWesley Yao ARRAY_SIZE(five_a8_x16_repeat_data) - 1, /* mask */ 3119bf9a700SWesley Yao {1, 1, 1, 0} /* weight */ 3129bf9a700SWesley Yao }; 3139bf9a700SWesley Yao 3149bf9a700SWesley Yao static u32 long_8b10b_data[] = {0x16161616, 0x16161616}; 3159bf9a700SWesley Yao 3169bf9a700SWesley Yao static struct pat long_8b10b = { 3179bf9a700SWesley Yao "long_8b10b", 3189bf9a700SWesley Yao long_8b10b_data, 3199bf9a700SWesley Yao ARRAY_SIZE(long_8b10b_data) - 1, /* mask */ 3209bf9a700SWesley Yao {2, 0, 0, 0} /* weight */ 3219bf9a700SWesley Yao }; 3229bf9a700SWesley Yao 3239bf9a700SWesley Yao static u32 short_8b10b_data[] = {0xb5b5b5b5, 0xb5b5b5b5}; 3249bf9a700SWesley Yao 3259bf9a700SWesley Yao static struct pat short_8b10b = { 3269bf9a700SWesley Yao "short_8b10b", 3279bf9a700SWesley Yao short_8b10b_data, 3289bf9a700SWesley Yao ARRAY_SIZE(short_8b10b_data) - 1, /* mask */ 3299bf9a700SWesley Yao {2, 0, 0, 0} /* weight */ 3309bf9a700SWesley Yao }; 3319bf9a700SWesley Yao 3329bf9a700SWesley Yao static u32 checker_8b10b_data[] = {0xb5b5b5b5, 0x4a4a4a4a}; 3339bf9a700SWesley Yao 3349bf9a700SWesley Yao static struct pat checker_8b10b = { 3359bf9a700SWesley Yao "checker_8b10b", 3369bf9a700SWesley Yao checker_8b10b_data, 3379bf9a700SWesley Yao ARRAY_SIZE(checker_8b10b_data) - 1, /* mask */ 3389bf9a700SWesley Yao {1, 0, 1, 1} /* weight */ 3399bf9a700SWesley Yao }; 3409bf9a700SWesley Yao 3419bf9a700SWesley Yao static u32 checker_8b10b_x16_data[] = {0xb5b54a4a, 0xb5b54a4a}; 3429bf9a700SWesley Yao 3439bf9a700SWesley Yao static struct pat checker_8b10b_x16 = { 3449bf9a700SWesley Yao "checker_8b10b_x16", 3459bf9a700SWesley Yao checker_8b10b_x16_data, 3469bf9a700SWesley Yao ARRAY_SIZE(checker_8b10b_x16_data) - 1, /* mask */ 3479bf9a700SWesley Yao {1, 0, 0, 0} /* weight */ 3489bf9a700SWesley Yao }; 3499bf9a700SWesley Yao 3509bf9a700SWesley Yao static u32 five_7_data[] = {0x55555557, 0x55575555}; 3519bf9a700SWesley Yao 3529bf9a700SWesley Yao static struct pat five_7 = { 3539bf9a700SWesley Yao "five_7", 3549bf9a700SWesley Yao five_7_data, 3559bf9a700SWesley Yao ARRAY_SIZE(five_7_data) - 1, /* mask */ 3569bf9a700SWesley Yao {0, 2, 0, 0} /* weight */ 3579bf9a700SWesley Yao }; 3589bf9a700SWesley Yao 3599bf9a700SWesley Yao static u32 five_7_x16_data[] = {0x55575557, 0x57555755}; 3609bf9a700SWesley Yao 3619bf9a700SWesley Yao static struct pat five_7_x16 = { 3629bf9a700SWesley Yao "five_7_x16", 3639bf9a700SWesley Yao five_7_x16_data, 3649bf9a700SWesley Yao ARRAY_SIZE(five_7_x16_data) - 1, /* mask */ 3659bf9a700SWesley Yao {2, 0, 0, 0} /* weight */ 3669bf9a700SWesley Yao }; 3679bf9a700SWesley Yao 3689bf9a700SWesley Yao static u32 zero2_fd_data[] = {0x00020002, 0xfffdfffd}; 3699bf9a700SWesley Yao 3709bf9a700SWesley Yao static struct pat zero2_fd = { 3719bf9a700SWesley Yao "zero2_fd", 3729bf9a700SWesley Yao zero2_fd_data, 3739bf9a700SWesley Yao ARRAY_SIZE(zero2_fd_data) - 1, /* mask */ 3749bf9a700SWesley Yao {0, 2, 0, 0} /* weight */ 3759bf9a700SWesley Yao }; 3769bf9a700SWesley Yao 3779bf9a700SWesley Yao static u32 zero2_fd_x16_data[] = {0x02020202, 0xfdfdfdfd}; 3789bf9a700SWesley Yao 3799bf9a700SWesley Yao static struct pat zero2_fd_x16 = { 3809bf9a700SWesley Yao "zero2_fd_x16", 3819bf9a700SWesley Yao zero2_fd_x16_data, 3829bf9a700SWesley Yao ARRAY_SIZE(zero2_fd_x16_data) - 1, /* mask */ 3839bf9a700SWesley Yao {2, 0, 0, 0} /* weight */ 3849bf9a700SWesley Yao }; 3859bf9a700SWesley Yao 3869bf9a700SWesley Yao static struct pat *pat_array[] = { 3879bf9a700SWesley Yao &walking_1, 3889bf9a700SWesley Yao &walking_1_x16, 3899bf9a700SWesley Yao &walking_1_x16_repeat, 3909bf9a700SWesley Yao &walking_inv_1, 3919bf9a700SWesley Yao &walking_inv_1_x16, 3929bf9a700SWesley Yao &walking_inv_1_x16_repeat, 3939bf9a700SWesley Yao &walking_0, 3949bf9a700SWesley Yao &one_zero, 3959bf9a700SWesley Yao &one_zero_x16, 3969bf9a700SWesley Yao &just_0, 3979bf9a700SWesley Yao &just_1, 3989bf9a700SWesley Yao &just_5, 3999bf9a700SWesley Yao &just_a, 4009bf9a700SWesley Yao &five_a, 4019bf9a700SWesley Yao &five_a_x16, 4029bf9a700SWesley Yao &five_a8, 4039bf9a700SWesley Yao &five_a8_x16, 4049bf9a700SWesley Yao &five_a8_x16_repeat, 4059bf9a700SWesley Yao &long_8b10b, 4069bf9a700SWesley Yao &short_8b10b, 4079bf9a700SWesley Yao &checker_8b10b, 4089bf9a700SWesley Yao &checker_8b10b_x16, 4099bf9a700SWesley Yao &five_7, 4109bf9a700SWesley Yao &five_7_x16, 4119bf9a700SWesley Yao &zero2_fd, 4129bf9a700SWesley Yao &zero2_fd_x16 4139bf9a700SWesley Yao }; 4149bf9a700SWesley Yao 4159bf9a700SWesley Yao static u32 cpu_copy_err[CPU_NUM_MAX]; 4169bf9a700SWesley Yao static u32 cpu_inv_err[CPU_NUM_MAX]; 4179bf9a700SWesley Yao 4189bf9a700SWesley Yao static u64 start_time_us; 4199bf9a700SWesley Yao static u64 test_time_us; 4209bf9a700SWesley Yao 4219bf9a700SWesley Yao static bool cpu_init_finish[CPU_NUM_MAX]; 4229bf9a700SWesley Yao static bool cpu_test_finish[CPU_NUM_MAX]; 4239bf9a700SWesley Yao static bool pattern_page_init_finish; 4249bf9a700SWesley Yao 4259bf9a700SWesley Yao #if (CPU_NUM_MAX > 1) 4269bf9a700SWesley Yao static ulong test_count = 0; 4279bf9a700SWesley Yao static ulong __gd; /* set r9/x18 of secondary cpu to gd addr */ 4289bf9a700SWesley Yao #endif 4299bf9a700SWesley Yao ulong __sp; /* set sp of secondary cpu */ 4309bf9a700SWesley Yao 4319bf9a700SWesley Yao u32 print_mutex; /* 0: unlock, 1: lock */ 4329bf9a700SWesley Yao 4339bf9a700SWesley Yao static u64 get_time_us(void) 4349bf9a700SWesley Yao { 4359bf9a700SWesley Yao return lldiv(get_ticks(), CONFIG_SYS_HZ_CLOCK / (CONFIG_SYS_HZ * 1000)); 4369bf9a700SWesley Yao } 4379bf9a700SWesley Yao 4389bf9a700SWesley Yao static u64 run_time_us(void) 4399bf9a700SWesley Yao { 4409bf9a700SWesley Yao return get_time_us() - start_time_us; 4419bf9a700SWesley Yao } 4429bf9a700SWesley Yao 4439bf9a700SWesley Yao static void print_time_stamp(void) 4449bf9a700SWesley Yao { 4459bf9a700SWesley Yao u64 time_us; 4469bf9a700SWesley Yao 4479bf9a700SWesley Yao time_us = run_time_us(); 4489bf9a700SWesley Yao 4499bf9a700SWesley Yao printf("[%5d.%06d] ", (u32)(time_us / 1000000), (u32)(time_us % 1000000)); 4509bf9a700SWesley Yao } 4519bf9a700SWesley Yao 4529bf9a700SWesley Yao static u32 pattern_get(struct pattern *pattern, u32 offset) 4539bf9a700SWesley Yao { 4549bf9a700SWesley Yao u32 ret; 4559bf9a700SWesley Yao 4569bf9a700SWesley Yao ret = pattern->pat->data_array[(offset >> pattern->repeat) & 4579bf9a700SWesley Yao pattern->pat->mask]; 4589bf9a700SWesley Yao 4599bf9a700SWesley Yao return pattern->inv ? ~ret : ret; 4609bf9a700SWesley Yao } 4619bf9a700SWesley Yao 4629bf9a700SWesley Yao static void pattern_adler_sum_calc(struct pattern *pattern, 4639bf9a700SWesley Yao struct stressapptest_params *sat) 4649bf9a700SWesley Yao { 4659bf9a700SWesley Yao int i = 0; 4669bf9a700SWesley Yao u64 a1 = 1; 4679bf9a700SWesley Yao u64 b1 = 0; 4689bf9a700SWesley Yao u64 a2 = 1; 4699bf9a700SWesley Yao u64 b2 = 0; 4709bf9a700SWesley Yao 4719bf9a700SWesley Yao while (i < sat->block_size_byte / sizeof(u32)) { 4729bf9a700SWesley Yao a1 += (u64)pattern_get(pattern, i++); 4739bf9a700SWesley Yao b1 += a1; 4749bf9a700SWesley Yao a1 += pattern_get(pattern, i++); 4759bf9a700SWesley Yao b1 += a1; 4769bf9a700SWesley Yao 4779bf9a700SWesley Yao a2 += (u64)pattern_get(pattern, i++); 4789bf9a700SWesley Yao b2 += a2; 4799bf9a700SWesley Yao a2 += pattern_get(pattern, i++); 4809bf9a700SWesley Yao b2 += a2; 4819bf9a700SWesley Yao } 4829bf9a700SWesley Yao 4839bf9a700SWesley Yao pattern->adler_sum.a1 = a1; 4849bf9a700SWesley Yao pattern->adler_sum.b1 = b1; 4859bf9a700SWesley Yao pattern->adler_sum.a2 = a2; 4869bf9a700SWesley Yao pattern->adler_sum.b2 = b2; 4879bf9a700SWesley Yao } 4889bf9a700SWesley Yao 4899bf9a700SWesley Yao static void pattern_list_init(struct pattern *pattern_list, 4909bf9a700SWesley Yao struct stressapptest_params *sat) 4919bf9a700SWesley Yao { 4929bf9a700SWesley Yao u32 weight_count = 0; 4939bf9a700SWesley Yao int k = 0; 4949bf9a700SWesley Yao 4959bf9a700SWesley Yao for (int i = 0; i < PAT_NUM; i++) { 4969bf9a700SWesley Yao for (int j = 0; j < 8; j++) { 4979bf9a700SWesley Yao pattern_list[k].pat = pat_array[i]; 4989bf9a700SWesley Yao pattern_list[k].inv = j % 2; 4999bf9a700SWesley Yao pattern_list[k].repeat = j / 2; 5009bf9a700SWesley Yao pattern_list[k].weight = pattern_list[k].pat->weight[j / 2]; 5019bf9a700SWesley Yao pattern_adler_sum_calc(&pattern_list[k], sat); 5029bf9a700SWesley Yao weight_count += pattern_list[k].weight; 5039bf9a700SWesley Yao k++; 5049bf9a700SWesley Yao } 5059bf9a700SWesley Yao } 5069bf9a700SWesley Yao 5079bf9a700SWesley Yao sat->weight_count = weight_count; 5089bf9a700SWesley Yao } 5099bf9a700SWesley Yao 5109c15e090SWesley Yao static u32 get_max_page_num(ulong page_size_byte) 5119c15e090SWesley Yao { 5129c15e090SWesley Yao ulong start_adr[CONFIG_NR_DRAM_BANKS], length[CONFIG_NR_DRAM_BANKS]; 5139c15e090SWesley Yao u32 page_num = 0; 5149c15e090SWesley Yao 5159c15e090SWesley Yao get_print_available_addr(start_adr, length, 0); 5169c15e090SWesley Yao 5179c15e090SWesley Yao page_num = 0; 5189c15e090SWesley Yao for (int i = 0; i < ARRAY_SIZE(start_adr) || i < ARRAY_SIZE(length); i++) { 5199c15e090SWesley Yao if ((start_adr[i] == 0 && length[i] == 0)) 5209c15e090SWesley Yao break; 5219c15e090SWesley Yao page_num += (u32)(length[i] / page_size_byte); 5229c15e090SWesley Yao } 5239c15e090SWesley Yao 5249c15e090SWesley Yao return page_num; 5259c15e090SWesley Yao } 5269c15e090SWesley Yao 5279bf9a700SWesley Yao static int get_page_addr(struct page *page_list, 5289bf9a700SWesley Yao struct stressapptest_params *sat) 5299bf9a700SWesley Yao { 5309bf9a700SWesley Yao ulong start_adr[CONFIG_NR_DRAM_BANKS], length[CONFIG_NR_DRAM_BANKS]; 5319bf9a700SWesley Yao ulong used_length; 5329bf9a700SWesley Yao u32 page = 0; 5339bf9a700SWesley Yao 534*aa9eaea1SWesley Yao get_print_available_addr(start_adr, length, 0); 5359bf9a700SWesley Yao 536*aa9eaea1SWesley Yao printf("Address for test:\n Start End Length\n"); 5379bf9a700SWesley Yao for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 5389bf9a700SWesley Yao if ((start_adr[i] == 0 && length[i] == 0) || page >= sat->page_num) 5399bf9a700SWesley Yao break; 5402ac0a64aSWesley Yao if (start_adr[i] + length[i] < sat->total_start_addr) 5412ac0a64aSWesley Yao continue; 5422ac0a64aSWesley Yao if (start_adr[i] < sat->total_start_addr) { 5432ac0a64aSWesley Yao length[i] -= sat->total_start_addr - start_adr[i]; 5442ac0a64aSWesley Yao start_adr[i] = sat->total_start_addr; 5452ac0a64aSWesley Yao } 5469bf9a700SWesley Yao 5479bf9a700SWesley Yao used_length = 0; 5489bf9a700SWesley Yao while (page < sat->page_num && 5499bf9a700SWesley Yao length[i] >= used_length + sat->page_size_byte) { 5509bf9a700SWesley Yao page_list[page].base_addr = (void *)(start_adr[i] + used_length); 5519bf9a700SWesley Yao used_length += sat->page_size_byte; 5529bf9a700SWesley Yao page++; 5539bf9a700SWesley Yao } 554*aa9eaea1SWesley Yao printf(" 0x%09lx - 0x%09lx 0x%09lx\n", 555*aa9eaea1SWesley Yao start_adr[i], start_adr[i] + used_length, used_length); 5569bf9a700SWesley Yao } 5579bf9a700SWesley Yao 558*aa9eaea1SWesley Yao printf("page_num = %d, page_size = 0x%lx, total_test_size = 0x%lx\n", 559*aa9eaea1SWesley Yao page, sat->page_size_byte, sat->page_size_byte * page); 560*aa9eaea1SWesley Yao 5619c15e090SWesley Yao if (sat->total_test_size_mb == 0) { 5629c15e090SWesley Yao /* No arg for total_test_size_mb, test all available space by default. */ 5639c15e090SWesley Yao sat->page_num = page; 5649c15e090SWesley Yao } else if (page < sat->page_num || page < sat->cpu_num * 4) { 5659bf9a700SWesley Yao printf("ERROR: Cannot get enough pages to test.\n"); 5669bf9a700SWesley Yao printf("Please decrease page_size or test_size\n"); 5679bf9a700SWesley Yao 5689bf9a700SWesley Yao return -1; 5699bf9a700SWesley Yao } 5709bf9a700SWesley Yao 5719bf9a700SWesley Yao return 0; 5729bf9a700SWesley Yao } 5739bf9a700SWesley Yao 5749bf9a700SWesley Yao static void page_init_valid(struct page *page, struct pattern *pattern_list, 5759bf9a700SWesley Yao struct stressapptest_params *sat) 5769bf9a700SWesley Yao { 5779bf9a700SWesley Yao int target; 5789bf9a700SWesley Yao int i = 0; 5799bf9a700SWesley Yao u64 *mem; 5809bf9a700SWesley Yao 5819bf9a700SWesley Yao target = (rand() % sat->weight_count) + 1; 5829bf9a700SWesley Yao do { 5839bf9a700SWesley Yao target -= pattern_list[i++].weight; 5849bf9a700SWesley Yao if (target <= 0) 5859bf9a700SWesley Yao break; 5869bf9a700SWesley Yao } while (i < PATTERN_LIST_SIZE); 5879bf9a700SWesley Yao page->pattern = &pattern_list[--i]; 5889bf9a700SWesley Yao page->valid = 1; 5899bf9a700SWesley Yao 5909bf9a700SWesley Yao mem = (u64 *)page->base_addr; 5919bf9a700SWesley Yao for (i = 0; i < sat->page_size_byte / sizeof(u64); i++) 5929bf9a700SWesley Yao mem[i] = (u64)pattern_get(page->pattern, i * 2) | 5939bf9a700SWesley Yao (u64)pattern_get(page->pattern, i * 2 + 1) << 32; 5949bf9a700SWesley Yao } 5959bf9a700SWesley Yao 5969bf9a700SWesley Yao static void page_init_empty(struct page *page) 5979bf9a700SWesley Yao { 5989bf9a700SWesley Yao page->valid = 0; 5999bf9a700SWesley Yao } 6009bf9a700SWesley Yao 6019bf9a700SWesley Yao static void page_init(struct pattern *pattern_list, 6029bf9a700SWesley Yao struct stressapptest_params *sat) 6039bf9a700SWesley Yao { 6049bf9a700SWesley Yao int i, cpu; 6059bf9a700SWesley Yao u32 empty_page_num; 6069bf9a700SWesley Yao 6079bf9a700SWesley Yao for (cpu = 0; cpu < sat->cpu_num; cpu++) { 6089bf9a700SWesley Yao empty_page_num = 0; 6099bf9a700SWesley Yao for (i = cpu; i < sat->page_num; i += sat->cpu_num) { 6109bf9a700SWesley Yao if (rand() % 5 < 3) { 6119bf9a700SWesley Yao page_list[i].valid = 1; 6129bf9a700SWesley Yao } else { 6139bf9a700SWesley Yao page_list[i].valid = 0; 6149bf9a700SWesley Yao empty_page_num++; 6159bf9a700SWesley Yao } 6169bf9a700SWesley Yao } 6179bf9a700SWesley Yao while (empty_page_num >= sat->page_num / sat->cpu_num / 2 && i > 0) { 6189bf9a700SWesley Yao i -= sat->cpu_num; 6199bf9a700SWesley Yao if (page_list[i].valid == 0) { 6209bf9a700SWesley Yao page_list[i].valid = 1; 6219bf9a700SWesley Yao empty_page_num--; 6229bf9a700SWesley Yao } 6239bf9a700SWesley Yao } 6249bf9a700SWesley Yao i = cpu; 6259bf9a700SWesley Yao while (empty_page_num < 2 && i < sat->page_num) { 6269bf9a700SWesley Yao if (page_list[i].valid == 1) { 6279bf9a700SWesley Yao page_list[i].valid = 0; 6289bf9a700SWesley Yao empty_page_num++; 6299bf9a700SWesley Yao } 6309bf9a700SWesley Yao i += sat->cpu_num; 6319bf9a700SWesley Yao } 6329bf9a700SWesley Yao } 6339bf9a700SWesley Yao 6349bf9a700SWesley Yao for (i = 0; i < sat->page_num; i++) { 6359bf9a700SWesley Yao if (page_list[i].valid == 1) 6369bf9a700SWesley Yao page_init_valid(&page_list[i], pattern_list, sat); 6379bf9a700SWesley Yao else 6389bf9a700SWesley Yao page_init_empty(&page_list[i]); 6399bf9a700SWesley Yao } 6409bf9a700SWesley Yao flush_dcache_all(); 6419bf9a700SWesley Yao } 6429bf9a700SWesley Yao 6439bf9a700SWesley Yao static u32 page_rand_pick(struct page *page_list, bool valid, 6442d08ea87SWesley Yao struct stressapptest_params *sat, u8 cpu_id) 6459bf9a700SWesley Yao { 6469bf9a700SWesley Yao u32 pick; 6479bf9a700SWesley Yao 64850e09059SWesley Yao pick = rand() % sat->page_num; 64950e09059SWesley Yao pick = pick / sat->cpu_num * sat->cpu_num + cpu_id; 65050e09059SWesley Yao if (pick >= sat->page_num) 65150e09059SWesley Yao pick = cpu_id; 65250e09059SWesley Yao 6539bf9a700SWesley Yao while (page_list[pick].valid != valid) { 6549bf9a700SWesley Yao pick += sat->cpu_num; 6559bf9a700SWesley Yao if (pick >= sat->page_num) 6569bf9a700SWesley Yao pick = cpu_id; 6579bf9a700SWesley Yao } 6589bf9a700SWesley Yao 6599bf9a700SWesley Yao return pick; 6609bf9a700SWesley Yao } 6619bf9a700SWesley Yao 6629bf9a700SWesley Yao static u32 block_inv_mis_search(void *dst_addr, struct pattern *src_pattern, 6639bf9a700SWesley Yao struct stressapptest_params *sat) 6649bf9a700SWesley Yao { 6659bf9a700SWesley Yao u32 *dst_mem; 6669bf9a700SWesley Yao u32 dst_data; 6679bf9a700SWesley Yao u32 expc_data; 6689bf9a700SWesley Yao u32 mis_bit; 6699bf9a700SWesley Yao u32 err = 0; 6709bf9a700SWesley Yao 6719bf9a700SWesley Yao dst_mem = (u32 *)dst_addr; 6729bf9a700SWesley Yao 6739bf9a700SWesley Yao for (int i = 0; i < sat->block_size_byte / sizeof(u32); i++) { 6749bf9a700SWesley Yao dst_data = dst_mem[i]; 6759bf9a700SWesley Yao expc_data = pattern_get(src_pattern, i); 6769bf9a700SWesley Yao 6779bf9a700SWesley Yao if (dst_data != expc_data) { 6789bf9a700SWesley Yao lock_byte_mutex(&print_mutex); 6799bf9a700SWesley Yao 6809bf9a700SWesley Yao print_time_stamp(); 6819bf9a700SWesley Yao printf("INV ERROR at 0x%010lx:\n", (ulong)&dst_mem[i]); 6829bf9a700SWesley Yao printf(" data = 0x%08x\n", dst_data); 6839bf9a700SWesley Yao printf(" expc = 0x%08x\n", expc_data); 6849bf9a700SWesley Yao 6859bf9a700SWesley Yao mis_bit = dst_data ^ expc_data; 6869bf9a700SWesley Yao printf(" mismatch at bit"); 6879bf9a700SWesley Yao for (int j = 31; j >= 0; j--) { 6889bf9a700SWesley Yao if (((mis_bit >> j) & 1) == 1) 6899bf9a700SWesley Yao printf(" %d", j); 6909bf9a700SWesley Yao } 6919bf9a700SWesley Yao printf("\n"); 6929bf9a700SWesley Yao 6939bf9a700SWesley Yao unlock_byte_mutex(&print_mutex); 6949bf9a700SWesley Yao dst_mem[i] = expc_data; 6959bf9a700SWesley Yao err++; 6969bf9a700SWesley Yao } 6979bf9a700SWesley Yao } 6989bf9a700SWesley Yao flush_dcache_all(); 6999bf9a700SWesley Yao 7009bf9a700SWesley Yao if (err == 0) { 7019bf9a700SWesley Yao lock_byte_mutex(&print_mutex); 7029bf9a700SWesley Yao printf("INV ERROR detected but cannot find mismatch data (maybe read error).\n"); 7039bf9a700SWesley Yao unlock_byte_mutex(&print_mutex); 7049bf9a700SWesley Yao } 7059bf9a700SWesley Yao 7069bf9a700SWesley Yao return err; 7079bf9a700SWesley Yao } 7089bf9a700SWesley Yao 7099bf9a700SWesley Yao static u32 block_inv_check(void *dst_addr, struct pattern *src_pattern, 7102d08ea87SWesley Yao struct stressapptest_params *sat, u8 cpu_id) 7119bf9a700SWesley Yao { 7129bf9a700SWesley Yao u32 *dst_mem; 7139bf9a700SWesley Yao u32 err = 0; 7149bf9a700SWesley Yao int i = 0; 7159bf9a700SWesley Yao #if defined(WARM_CPU) 7169bf9a700SWesley Yao double a, b, c, d; 7179bf9a700SWesley Yao #endif 7189bf9a700SWesley Yao 7199bf9a700SWesley Yao struct adler_sum adler_sum = { 7209bf9a700SWesley Yao 1, 0, 1, 0 7219bf9a700SWesley Yao }; 7229bf9a700SWesley Yao 7239bf9a700SWesley Yao dst_mem = (u32 *)dst_addr; 7249bf9a700SWesley Yao 7259bf9a700SWesley Yao #if defined(WARM_CPU) 7269bf9a700SWesley Yao a = 2.0 * dst_mem[0]; 7279bf9a700SWesley Yao b = 5.0 * dst_mem[0]; 7289bf9a700SWesley Yao c = 7.0 * dst_mem[0]; 7299bf9a700SWesley Yao d = 9.0 * dst_mem[0]; 7309bf9a700SWesley Yao #endif 7319bf9a700SWesley Yao 7329bf9a700SWesley Yao while (i < sat->block_size_byte / sizeof(u32)) { 7339bf9a700SWesley Yao adler_sum.a1 += dst_mem[i++]; 7349bf9a700SWesley Yao adler_sum.b1 += adler_sum.a1; 7359bf9a700SWesley Yao adler_sum.a1 += dst_mem[i++]; 7369bf9a700SWesley Yao adler_sum.b1 += adler_sum.a1; 7379bf9a700SWesley Yao 7389bf9a700SWesley Yao #if defined(WARM_CPU) 7399bf9a700SWesley Yao a = a * b; 7409bf9a700SWesley Yao b = b + c; 7419bf9a700SWesley Yao #endif 7429bf9a700SWesley Yao 7439bf9a700SWesley Yao adler_sum.a2 += dst_mem[i++]; 7449bf9a700SWesley Yao adler_sum.b2 += adler_sum.a2; 7459bf9a700SWesley Yao adler_sum.a2 += dst_mem[i++]; 7469bf9a700SWesley Yao adler_sum.b2 += adler_sum.a2; 7479bf9a700SWesley Yao #if defined(WARM_CPU) 7489bf9a700SWesley Yao c = c * d; 7499bf9a700SWesley Yao d = d + d; 7509bf9a700SWesley Yao #endif 7519bf9a700SWesley Yao } 7529bf9a700SWesley Yao 7539bf9a700SWesley Yao #if defined(WARM_CPU) 7549bf9a700SWesley Yao d = a + b + c + d; 7559bf9a700SWesley Yao if (d == 1.0) 7569bf9a700SWesley Yao /* Reference the result so that it can't be discarded by the compiler. */ 7579bf9a700SWesley Yao printf("This will probably never happen.\n"); 7589bf9a700SWesley Yao #endif 7599bf9a700SWesley Yao 7609bf9a700SWesley Yao if (adler_sum.a1 != src_pattern->adler_sum.a1 || 7619bf9a700SWesley Yao adler_sum.b1 != src_pattern->adler_sum.b1 || 7629bf9a700SWesley Yao adler_sum.a2 != src_pattern->adler_sum.a2 || 7639bf9a700SWesley Yao adler_sum.b2 != src_pattern->adler_sum.b2) { 7649bf9a700SWesley Yao err = block_inv_mis_search(dst_addr, src_pattern, sat); 7659bf9a700SWesley Yao 7669bf9a700SWesley Yao lock_byte_mutex(&print_mutex); 7679bf9a700SWesley Yao printf("(CPU%d, Pattern: %s, inv: %d, repeat: %d)\n\n", 7682d08ea87SWesley Yao cpu_id, src_pattern->pat->name, src_pattern->inv, 7699bf9a700SWesley Yao src_pattern->repeat); 7709bf9a700SWesley Yao unlock_byte_mutex(&print_mutex); 7719bf9a700SWesley Yao } 7729bf9a700SWesley Yao 7739bf9a700SWesley Yao return err; 7749bf9a700SWesley Yao } 7759bf9a700SWesley Yao 7769bf9a700SWesley Yao static void page_inv_up(void *src_addr, struct stressapptest_params *sat) 7779bf9a700SWesley Yao { 7789bf9a700SWesley Yao void *dst_addr = src_addr; 7799bf9a700SWesley Yao uint data; 7809bf9a700SWesley Yao uint *dst_mem; 7819bf9a700SWesley Yao 7829bf9a700SWesley Yao for (int i = 0; i < sat->block_num; i++) { 7839bf9a700SWesley Yao dst_mem = (uint *)dst_addr; 7849bf9a700SWesley Yao for (int j = 0; j < sat->block_size_byte / sizeof(uint); j++) { 7859bf9a700SWesley Yao data = dst_mem[j]; 7869bf9a700SWesley Yao dst_mem[j] = ~data; 7879bf9a700SWesley Yao } 7889bf9a700SWesley Yao dst_addr += sat->block_size_byte; 7899bf9a700SWesley Yao flush_dcache_all(); 7909bf9a700SWesley Yao } 7919bf9a700SWesley Yao } 7929bf9a700SWesley Yao 7939bf9a700SWesley Yao static void page_inv_down(void *src_addr, struct stressapptest_params *sat) 7949bf9a700SWesley Yao { 7959bf9a700SWesley Yao void *dst_addr = src_addr; 7969bf9a700SWesley Yao uint data; 7979bf9a700SWesley Yao uint *dst_mem; 7989bf9a700SWesley Yao 7999bf9a700SWesley Yao dst_addr += sat->block_size_byte * (sat->block_num - 1); 8009bf9a700SWesley Yao 8019bf9a700SWesley Yao for (int i = sat->block_num - 1; i >= 0; i--) { 8029bf9a700SWesley Yao dst_mem = (uint *)dst_addr; 8039bf9a700SWesley Yao for (int j = sat->block_size_byte / sizeof(uint) - 1; j >= 0; j--) { 8049bf9a700SWesley Yao data = dst_mem[j]; 8059bf9a700SWesley Yao dst_mem[j] = ~data; 8069bf9a700SWesley Yao } 8079bf9a700SWesley Yao dst_addr -= sat->block_size_byte; 8089bf9a700SWesley Yao flush_dcache_all(); 8099bf9a700SWesley Yao } 8109bf9a700SWesley Yao } 8119bf9a700SWesley Yao 8122d08ea87SWesley Yao static u32 page_inv(struct stressapptest_params *sat, u8 cpu_id) 8139bf9a700SWesley Yao { 8149bf9a700SWesley Yao u32 src; 8159bf9a700SWesley Yao void *dst_block_addr; 8169bf9a700SWesley Yao u32 err = 0; 8179bf9a700SWesley Yao 8182d08ea87SWesley Yao src = page_rand_pick(page_list, 1, sat, cpu_id); /* pick a valid page */ 8199bf9a700SWesley Yao dst_block_addr = page_list[src].base_addr; 8209bf9a700SWesley Yao 8219bf9a700SWesley Yao for (int i = 0; i < 4; i++) { 8229bf9a700SWesley Yao if (rand() % 2 == 0) 8239bf9a700SWesley Yao page_inv_up(page_list[src].base_addr, sat); 8249bf9a700SWesley Yao else 8259bf9a700SWesley Yao page_inv_down(page_list[src].base_addr, sat); 8269bf9a700SWesley Yao } 8279bf9a700SWesley Yao 8289bf9a700SWesley Yao for (int i = 0; i < sat->block_num; i++) { 8292d08ea87SWesley Yao err += block_inv_check(dst_block_addr, page_list[src].pattern, sat, cpu_id); 8309bf9a700SWesley Yao dst_block_addr += sat->block_size_byte; 8319bf9a700SWesley Yao } 8329bf9a700SWesley Yao 8339bf9a700SWesley Yao flush_dcache_all(); 8349bf9a700SWesley Yao 8359bf9a700SWesley Yao return err; 8369bf9a700SWesley Yao } 8379bf9a700SWesley Yao 8389bf9a700SWesley Yao static u32 block_copy_mis_search(void *dst_addr, void *src_addr, 8399bf9a700SWesley Yao struct pattern *src_pattern, 8409bf9a700SWesley Yao struct stressapptest_params *sat) 8419bf9a700SWesley Yao { 8429bf9a700SWesley Yao u32 *dst_mem; 8439bf9a700SWesley Yao u32 *src_mem; 8449bf9a700SWesley Yao u32 dst_data; 8459bf9a700SWesley Yao u32 src_data; 8469bf9a700SWesley Yao u32 expc_data; 8479bf9a700SWesley Yao u32 mis_bit; 8489bf9a700SWesley Yao u32 err = 0; 8499bf9a700SWesley Yao 8509bf9a700SWesley Yao dst_mem = (u32 *)dst_addr; 8519bf9a700SWesley Yao src_mem = (u32 *)src_addr; 8529bf9a700SWesley Yao 8539bf9a700SWesley Yao for (int i = 0; i < sat->block_size_byte / sizeof(u32); i++) { 8549bf9a700SWesley Yao dst_data = dst_mem[i]; 8559bf9a700SWesley Yao src_data = src_mem[i]; 8569bf9a700SWesley Yao expc_data = pattern_get(src_pattern, i); 8579bf9a700SWesley Yao 8589bf9a700SWesley Yao if (dst_data != expc_data) { 8599bf9a700SWesley Yao lock_byte_mutex(&print_mutex); 8609bf9a700SWesley Yao 8619bf9a700SWesley Yao print_time_stamp(); 8629bf9a700SWesley Yao printf("COPY ERROR ("); 8639bf9a700SWesley Yao if (src_data == expc_data) 8649bf9a700SWesley Yao printf("read"); 8659bf9a700SWesley Yao else if (src_data != expc_data) 8669bf9a700SWesley Yao printf("write"); 8679bf9a700SWesley Yao printf(" error) at 0x%010lx:\n", (ulong)&src_mem[i]); 8689bf9a700SWesley Yao printf(" data = 0x%08x\n", dst_data); 8699bf9a700SWesley Yao printf(" expc = 0x%08x\n", expc_data); 8709bf9a700SWesley Yao 8719bf9a700SWesley Yao mis_bit = dst_data ^ expc_data; 8729bf9a700SWesley Yao printf(" mismatch at bit"); 8739bf9a700SWesley Yao for (int j = 31; j >= 0; j--) { 8749bf9a700SWesley Yao if (((mis_bit >> j) & 1) == 1) 8759bf9a700SWesley Yao printf(" %d", j); 8769bf9a700SWesley Yao } 8779bf9a700SWesley Yao printf("\n"); 8789bf9a700SWesley Yao 8799bf9a700SWesley Yao unlock_byte_mutex(&print_mutex); 8809bf9a700SWesley Yao err++; 8819bf9a700SWesley Yao dst_mem[i] = expc_data; 8829bf9a700SWesley Yao } 8839bf9a700SWesley Yao } 8849bf9a700SWesley Yao flush_dcache_all(); 8859bf9a700SWesley Yao 8869bf9a700SWesley Yao if (err == 0) { 8879bf9a700SWesley Yao lock_byte_mutex(&print_mutex); 8889bf9a700SWesley Yao printf("COPY ERROR detected but cannot find mismatch data (maybe read error).\n"); 8899bf9a700SWesley Yao unlock_byte_mutex(&print_mutex); 8909bf9a700SWesley Yao } 8919bf9a700SWesley Yao 8929bf9a700SWesley Yao return err; 8939bf9a700SWesley Yao } 8949bf9a700SWesley Yao 8959bf9a700SWesley Yao static u32 block_copy_check(void *dst_addr, void *src_addr, 8969bf9a700SWesley Yao struct adler_sum *adler_sum, 8979bf9a700SWesley Yao struct pattern *src_pattern, 8982d08ea87SWesley Yao struct stressapptest_params *sat, u8 cpu_id) 8999bf9a700SWesley Yao { 9009bf9a700SWesley Yao u32 err = 0; 9019bf9a700SWesley Yao 9029bf9a700SWesley Yao if (adler_sum->a1 != src_pattern->adler_sum.a1 || 9039bf9a700SWesley Yao adler_sum->b1 != src_pattern->adler_sum.b1 || 9049bf9a700SWesley Yao adler_sum->a2 != src_pattern->adler_sum.a2 || 9059bf9a700SWesley Yao adler_sum->b2 != src_pattern->adler_sum.b2) { 9069bf9a700SWesley Yao err += block_copy_mis_search(dst_addr, src_addr, src_pattern, sat); 9079bf9a700SWesley Yao 9089bf9a700SWesley Yao lock_byte_mutex(&print_mutex); 9099bf9a700SWesley Yao printf("(CPU%d, Pattern: %s, inv: %d, repeat: %d)\n\n", 9102d08ea87SWesley Yao cpu_id, src_pattern->pat->name, src_pattern->inv, 9119bf9a700SWesley Yao src_pattern->repeat); 9129bf9a700SWesley Yao unlock_byte_mutex(&print_mutex); 9139bf9a700SWesley Yao } 9149bf9a700SWesley Yao 9159bf9a700SWesley Yao return err; 9169bf9a700SWesley Yao } 9179bf9a700SWesley Yao 9189bf9a700SWesley Yao static u32 block_copy(void *dst_addr, void *src_addr, 9199bf9a700SWesley Yao struct pattern *src_pattern, 9202d08ea87SWesley Yao struct stressapptest_params *sat, u8 cpu_id) 9219bf9a700SWesley Yao { 9229bf9a700SWesley Yao u64 *dst_mem; 9239bf9a700SWesley Yao u64 *src_mem; 9249bf9a700SWesley Yao u64 data; 9259bf9a700SWesley Yao int i = 0; 9269bf9a700SWesley Yao #if defined(WARM_CPU) 9279bf9a700SWesley Yao double a, b, c, d; 9289bf9a700SWesley Yao #endif 9299bf9a700SWesley Yao 9309bf9a700SWesley Yao struct adler_sum adler_sum = { 9319bf9a700SWesley Yao 1, 0, 1, 0 9329bf9a700SWesley Yao }; 9339bf9a700SWesley Yao 9349bf9a700SWesley Yao dst_mem = (u64 *)dst_addr; 9359bf9a700SWesley Yao src_mem = (u64 *)src_addr; 9369bf9a700SWesley Yao 9379bf9a700SWesley Yao #if defined(WARM_CPU) 9389bf9a700SWesley Yao a = 2.0 * src_mem[0]; 9399bf9a700SWesley Yao b = 5.0 * src_mem[0]; 9409bf9a700SWesley Yao c = 7.0 * src_mem[0]; 9419bf9a700SWesley Yao d = 9.0 * src_mem[0]; 9429bf9a700SWesley Yao #endif 9439bf9a700SWesley Yao 9449bf9a700SWesley Yao while (i < sat->block_size_byte / sizeof(u64)) { 9459bf9a700SWesley Yao data = src_mem[i]; 9469bf9a700SWesley Yao adler_sum.a1 += data & 0xffffffff; 9479bf9a700SWesley Yao adler_sum.b1 += adler_sum.a1; 9489bf9a700SWesley Yao adler_sum.a1 += data >> 32; 9499bf9a700SWesley Yao adler_sum.b1 += adler_sum.a1; 9509bf9a700SWesley Yao dst_mem[i] = data; 9519bf9a700SWesley Yao i++; 9529bf9a700SWesley Yao 9539bf9a700SWesley Yao #if defined(WARM_CPU) 9549bf9a700SWesley Yao a = a * b; 9559bf9a700SWesley Yao b = b + c; 9569bf9a700SWesley Yao #endif 9579bf9a700SWesley Yao 9589bf9a700SWesley Yao data = src_mem[i]; 9599bf9a700SWesley Yao adler_sum.a2 += data & 0xffffffff; 9609bf9a700SWesley Yao adler_sum.b2 += adler_sum.a2; 9619bf9a700SWesley Yao adler_sum.a2 += data >> 32; 9629bf9a700SWesley Yao adler_sum.b2 += adler_sum.a2; 9639bf9a700SWesley Yao dst_mem[i] = data; 9649bf9a700SWesley Yao i++; 9659bf9a700SWesley Yao 9669bf9a700SWesley Yao #if defined(WARM_CPU) 9679bf9a700SWesley Yao c = c * d; 9689bf9a700SWesley Yao d = d + d; 9699bf9a700SWesley Yao #endif 9709bf9a700SWesley Yao } 9719bf9a700SWesley Yao 9729bf9a700SWesley Yao flush_dcache_all(); 9739bf9a700SWesley Yao 9749bf9a700SWesley Yao #if defined(WARM_CPU) 9759bf9a700SWesley Yao d = a + b + c + d; 9769bf9a700SWesley Yao if (d == 1.0) 9779bf9a700SWesley Yao /* Reference the result so that it can't be discarded by the compiler. */ 9789bf9a700SWesley Yao printf("This will probably never happen.\n"); 9799bf9a700SWesley Yao #endif 9809bf9a700SWesley Yao 9812d08ea87SWesley Yao return block_copy_check(dst_addr, src_addr, &adler_sum, src_pattern, sat, cpu_id); 9829bf9a700SWesley Yao } 9839bf9a700SWesley Yao 9842d08ea87SWesley Yao static u32 page_copy(struct stressapptest_params *sat, u8 cpu_id) 9859bf9a700SWesley Yao { 9869bf9a700SWesley Yao u32 dst; 9879bf9a700SWesley Yao u32 src; 9889bf9a700SWesley Yao void *dst_block_addr; 9899bf9a700SWesley Yao void *src_block_addr; 9909bf9a700SWesley Yao u32 err = 0; 9919bf9a700SWesley Yao 9922d08ea87SWesley Yao dst = page_rand_pick(page_list, 0, sat, cpu_id); /* pick a empty page */ 9939bf9a700SWesley Yao dst_block_addr = page_list[dst].base_addr; 9942d08ea87SWesley Yao src = page_rand_pick(page_list, 1, sat, cpu_id); /* pick a valid page */ 9959bf9a700SWesley Yao src_block_addr = page_list[src].base_addr; 9969bf9a700SWesley Yao flush_dcache_all(); 9979bf9a700SWesley Yao 9989bf9a700SWesley Yao for (int i = 0; i < sat->block_num; i++) { 9999bf9a700SWesley Yao err += block_copy(dst_block_addr, src_block_addr, 10002d08ea87SWesley Yao page_list[src].pattern, sat, cpu_id); 10019bf9a700SWesley Yao dst_block_addr += sat->block_size_byte; 10029bf9a700SWesley Yao src_block_addr += sat->block_size_byte; 10039bf9a700SWesley Yao } 10049bf9a700SWesley Yao 10059bf9a700SWesley Yao page_list[dst].pattern = page_list[src].pattern; 10069bf9a700SWesley Yao page_list[dst].valid = 1; 10079bf9a700SWesley Yao page_list[src].valid = 0; 10089bf9a700SWesley Yao flush_dcache_all(); 10099bf9a700SWesley Yao 10109bf9a700SWesley Yao return err; 10119bf9a700SWesley Yao } 10129bf9a700SWesley Yao 10139bf9a700SWesley Yao void secondary_main(void) 10149bf9a700SWesley Yao { 10159bf9a700SWesley Yao #if (CPU_NUM_MAX > 1) 10169bf9a700SWesley Yao u8 cpu_id; 10179bf9a700SWesley Yao ulong test = 0; 10189bf9a700SWesley Yao 10199bf9a700SWesley Yao #ifndef CONFIG_ARM64 10209bf9a700SWesley Yao asm volatile("mov r9, %0" : : "r" (__gd)); /* set r9 to gd addr */ 10219bf9a700SWesley Yao #else 10229bf9a700SWesley Yao asm volatile("mov x18, %0" : : "r" (__gd)); /* set x18 to gd addr */ 10239bf9a700SWesley Yao #endif 10249bf9a700SWesley Yao dcache_enable(); 10259bf9a700SWesley Yao icache_enable(); 10269bf9a700SWesley Yao 10279bf9a700SWesley Yao udelay(100); 10289bf9a700SWesley Yao 10299bf9a700SWesley Yao flush_dcache_all(); 10302d08ea87SWesley Yao 10319bf9a700SWesley Yao cpu_id = sat.cpu_num; 10329bf9a700SWesley Yao cpu_init_finish[cpu_id] = 1; 10339bf9a700SWesley Yao printf("CPU%d start OK.\n", cpu_id); 10349bf9a700SWesley Yao 10359bf9a700SWesley Yao while (pattern_page_init_finish == 0) { 10369bf9a700SWesley Yao udelay(100); 10379bf9a700SWesley Yao flush_dcache_all(); 10389bf9a700SWesley Yao } 10399bf9a700SWesley Yao 10409bf9a700SWesley Yao while (1) { 10419bf9a700SWesley Yao udelay(100); 10429bf9a700SWesley Yao flush_dcache_all(); 10439bf9a700SWesley Yao while (test < test_count) { 10449bf9a700SWesley Yao cpu_test_finish[cpu_id] = 0; 10459bf9a700SWesley Yao flush_dcache_all(); 10469bf9a700SWesley Yao while (run_time_us() < test_time_us) { 10479bf9a700SWesley Yao if (rand() % 2 == 0) 10482d08ea87SWesley Yao cpu_copy_err[cpu_id] += page_copy(&sat, cpu_id); 10499bf9a700SWesley Yao else 10502d08ea87SWesley Yao cpu_inv_err[cpu_id] += page_inv(&sat, cpu_id); 10519bf9a700SWesley Yao } 10529bf9a700SWesley Yao test++; 10539bf9a700SWesley Yao cpu_test_finish[cpu_id] = 1; 10549bf9a700SWesley Yao flush_dcache_all(); 10559bf9a700SWesley Yao } 10569bf9a700SWesley Yao } 10579bf9a700SWesley Yao #else 10589bf9a700SWesley Yao return; 10599bf9a700SWesley Yao #endif 10609bf9a700SWesley Yao } 10619bf9a700SWesley Yao 10629bf9a700SWesley Yao static int doing_stressapptest(void) 10639bf9a700SWesley Yao { 10649bf9a700SWesley Yao int i; 10659bf9a700SWesley Yao u32 pre_10s; 10669bf9a700SWesley Yao u32 now_10s; 10679bf9a700SWesley Yao 10689bf9a700SWesley Yao struct pattern pattern_list[PATTERN_LIST_SIZE]; 10699bf9a700SWesley Yao void *page_info; 10709bf9a700SWesley Yao 10719bf9a700SWesley Yao u32 all_copy_err = 0; 10729bf9a700SWesley Yao u32 all_inv_err = 0; 10739bf9a700SWesley Yao u32 cpu_no_response_err = 0; 10749bf9a700SWesley Yao 10759bf9a700SWesley Yao int ret = CMD_RET_SUCCESS; 10769bf9a700SWesley Yao 10779bf9a700SWesley Yao for (i = 0; i < CPU_NUM_MAX; i++) { 10789bf9a700SWesley Yao cpu_copy_err[i] = 0; 10799bf9a700SWesley Yao cpu_inv_err[i] = 0; 10809bf9a700SWesley Yao cpu_init_finish[i] = 0; 10819bf9a700SWesley Yao cpu_test_finish[i] = 0; 10829bf9a700SWesley Yao } 10839bf9a700SWesley Yao pattern_page_init_finish = 0; 10849bf9a700SWesley Yao print_mutex = 0; 10859bf9a700SWesley Yao asm volatile("clrex"); 10869bf9a700SWesley Yao 10879bf9a700SWesley Yao #if (CPU_NUM_MAX > 1) 10889bf9a700SWesley Yao if (test_count == 0) { 10899bf9a700SWesley Yao __gd = (ulong)gd; 10909bf9a700SWesley Yao asm volatile("mov %0, sp" : "=r" (__sp)); 10919bf9a700SWesley Yao printf("CPU0 sp is at 0x%lx now.\n", __sp); 10929bf9a700SWesley Yao __sp &= ~(ulong)0xffff; 10939bf9a700SWesley Yao for (sat.cpu_num = 1; sat.cpu_num < CPU_NUM_MAX; sat.cpu_num++) { 10949bf9a700SWesley Yao __sp -= 0x10000; 10959bf9a700SWesley Yao flush_dcache_all(); 10969bf9a700SWesley Yao if (psci_cpu_on(sat.cpu_num, (ulong)secondary_init) == 0) { 10979bf9a700SWesley Yao mdelay(10); 10989bf9a700SWesley Yao printf("Calling CPU%d, sp = 0x%lx\n", sat.cpu_num, __sp); 10999bf9a700SWesley Yao } else { 11009bf9a700SWesley Yao break; 11019bf9a700SWesley Yao } 11029bf9a700SWesley Yao while (cpu_init_finish[sat.cpu_num] == 0) { 11039bf9a700SWesley Yao udelay(1000); 11049bf9a700SWesley Yao flush_dcache_all(); 11059bf9a700SWesley Yao } 11069bf9a700SWesley Yao } 11079bf9a700SWesley Yao } 11089bf9a700SWesley Yao #else 11099bf9a700SWesley Yao sat.cpu_num = 1; 11109bf9a700SWesley Yao #endif 11119bf9a700SWesley Yao 11129c15e090SWesley Yao if (sat.total_test_size_mb == 0) 11139c15e090SWesley Yao sat.page_num = get_max_page_num(sat.page_size_byte); 11149c15e090SWesley Yao else 11159bf9a700SWesley Yao sat.page_num = (sat.total_test_size_mb << 20) / sat.page_size_byte; 11169bf9a700SWesley Yao sat.block_num = sat.page_size_byte / sat.block_size_byte; 11179bf9a700SWesley Yao 11189bf9a700SWesley Yao udelay(100); 11199bf9a700SWesley Yao 11209bf9a700SWesley Yao page_info = malloc(sizeof(struct page) * sat.page_num); 11219bf9a700SWesley Yao if (page_info == 0) { 11229bf9a700SWesley Yao printf("ERROR: StressAppTest fail to malloc.\n"); 11239bf9a700SWesley Yao printf("Please try increasing CONFIG_SYS_MALLOC_LEN in include/configs/rxxxxx_common.h.\n"); 11249bf9a700SWesley Yao ret = CMD_RET_FAILURE; 11259bf9a700SWesley Yao goto out; 11269bf9a700SWesley Yao } 11279bf9a700SWesley Yao page_list = (struct page *)page_info; 11289bf9a700SWesley Yao 11299bf9a700SWesley Yao if (get_page_addr(page_list, &sat) < 0) { 11309bf9a700SWesley Yao ret = CMD_RET_FAILURE; 11319bf9a700SWesley Yao goto out; 11329bf9a700SWesley Yao } 11339bf9a700SWesley Yao 11349bf9a700SWesley Yao pattern_list_init(pattern_list, &sat); 11359bf9a700SWesley Yao page_init(pattern_list, &sat); 11369bf9a700SWesley Yao 11379bf9a700SWesley Yao #if (CPU_NUM_MAX > 1) 11389bf9a700SWesley Yao if (sat.cpu_num > 1) { 11399bf9a700SWesley Yao pattern_page_init_finish = 1; 11409bf9a700SWesley Yao test_count++; 11419bf9a700SWesley Yao flush_dcache_all(); 11429bf9a700SWesley Yao } 11439bf9a700SWesley Yao #endif 11449bf9a700SWesley Yao 11459bf9a700SWesley Yao pre_10s = (u32)(run_time_us() / 1000000 / 10); 11469bf9a700SWesley Yao lock_byte_mutex(&print_mutex); 11479bf9a700SWesley Yao print_time_stamp(); 11489bf9a700SWesley Yao printf("Start StressAppTest in U-Boot:\n"); 11499bf9a700SWesley Yao unlock_byte_mutex(&print_mutex); 11509bf9a700SWesley Yao 11519bf9a700SWesley Yao while (run_time_us() < test_time_us) { 11529bf9a700SWesley Yao if (rand() % 2 == 0) 11532d08ea87SWesley Yao cpu_copy_err[0] += page_copy(&sat, 0); 11549bf9a700SWesley Yao else 11552d08ea87SWesley Yao cpu_inv_err[0] += page_inv(&sat, 0); 11569bf9a700SWesley Yao 11579bf9a700SWesley Yao /* Print every 10 seconds */ 11589bf9a700SWesley Yao now_10s = (u32)(run_time_us() / 1000000 / 10); 11599bf9a700SWesley Yao if (now_10s > pre_10s) { 11609bf9a700SWesley Yao pre_10s = now_10s; 11619bf9a700SWesley Yao lock_byte_mutex(&print_mutex); 11629bf9a700SWesley Yao print_time_stamp(); 11639bf9a700SWesley Yao printf("Seconds remaining: %d\n", (u32)(test_time_us / 1000000 - now_10s * 10)); 11649bf9a700SWesley Yao unlock_byte_mutex(&print_mutex); 11659bf9a700SWesley Yao } 11669bf9a700SWesley Yao } 11679bf9a700SWesley Yao 11689bf9a700SWesley Yao #if (CPU_NUM_MAX > 1) 11699bf9a700SWesley Yao for (i = 1; i < sat.cpu_num; i++) { 11709bf9a700SWesley Yao while (cpu_test_finish[i] == 0) { 11719bf9a700SWesley Yao if ((u32)(run_time_us() / 1000000 / 10) > pre_10s + 6) { 11729bf9a700SWesley Yao /* wait for secondary CPU in 60s */ 11739bf9a700SWesley Yao lock_byte_mutex(&print_mutex); 11749bf9a700SWesley Yao print_time_stamp(); 11759bf9a700SWesley Yao printf("ERROR: Cannot wait for CPU%d to finish!\n", i); 11769bf9a700SWesley Yao unlock_byte_mutex(&print_mutex); 11779bf9a700SWesley Yao cpu_no_response_err++; 11789bf9a700SWesley Yao break; 11799bf9a700SWesley Yao } 11809bf9a700SWesley Yao mdelay(1); 11819bf9a700SWesley Yao flush_dcache_all(); 11829bf9a700SWesley Yao } 11839bf9a700SWesley Yao } 11849bf9a700SWesley Yao #endif 11859bf9a700SWesley Yao 11869bf9a700SWesley Yao for (i = 0; i < sat.cpu_num; i++) { 11879bf9a700SWesley Yao all_copy_err += cpu_copy_err[i]; 11889bf9a700SWesley Yao all_inv_err += cpu_inv_err[i]; 11899bf9a700SWesley Yao } 11909bf9a700SWesley Yao print_time_stamp(); 11919bf9a700SWesley Yao printf("StressAppTest Result: "); 11929bf9a700SWesley Yao if (all_copy_err == 0 && all_inv_err == 0 && cpu_no_response_err == 0) 11939bf9a700SWesley Yao printf("Pass.\n"); 11949bf9a700SWesley Yao else 11959bf9a700SWesley Yao printf("FAIL!\nStressAppTest detects %d copy errors, %d inv errors.\n", 11969bf9a700SWesley Yao all_copy_err, all_inv_err); 11979bf9a700SWesley Yao 11989bf9a700SWesley Yao out: 11999bf9a700SWesley Yao free(page_info); 12009bf9a700SWesley Yao 12019bf9a700SWesley Yao return ret; 12029bf9a700SWesley Yao } 12039bf9a700SWesley Yao 12049bf9a700SWesley Yao static int do_stressapptest(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 12059bf9a700SWesley Yao { 12069bf9a700SWesley Yao ulong test_time_sec = 20; 12079bf9a700SWesley Yao ulong page_size_kb = 1024; 12089bf9a700SWesley Yao 12099c15e090SWesley Yao sat.total_test_size_mb = 0; 12109bf9a700SWesley Yao sat.block_size_byte = 4096; 12112ac0a64aSWesley Yao sat.total_start_addr = 0x0; 12129bf9a700SWesley Yao 12139bf9a700SWesley Yao printf("StressAppTest in U-Boot, " __version__ "\n"); 12149bf9a700SWesley Yao 12159bf9a700SWesley Yao if (argc > 1) { 12169bf9a700SWesley Yao if (strict_strtoul(argv[1], 0, &test_time_sec) < 0) 12179bf9a700SWesley Yao return CMD_RET_USAGE; 12189bf9a700SWesley Yao if (test_time_sec < 1) 12199bf9a700SWesley Yao test_time_sec = 20; 12209bf9a700SWesley Yao } 12219bf9a700SWesley Yao if (argc > 2) { 12229bf9a700SWesley Yao if (strict_strtoul(argv[2], 0, &sat.total_test_size_mb) < 0) 12239bf9a700SWesley Yao return CMD_RET_USAGE; 12249bf9a700SWesley Yao if (sat.total_test_size_mb < 1) 12259c15e090SWesley Yao sat.total_test_size_mb = 0; 12269bf9a700SWesley Yao } 12279bf9a700SWesley Yao if (argc > 3) { 12282ac0a64aSWesley Yao if (strict_strtoul(argv[3], 0, &sat.total_start_addr) < 0) 12292ac0a64aSWesley Yao return CMD_RET_USAGE; 12302ac0a64aSWesley Yao if (sat.total_start_addr < 0x1) 12312ac0a64aSWesley Yao sat.total_start_addr = 0x0; 12322ac0a64aSWesley Yao } 12332ac0a64aSWesley Yao if (argc > 4) { 12342ac0a64aSWesley Yao if (strict_strtoul(argv[4], 0, &page_size_kb) < 0) 12359bf9a700SWesley Yao return CMD_RET_USAGE; 12369bf9a700SWesley Yao if (page_size_kb < 1) 12379bf9a700SWesley Yao page_size_kb = 1024; 12389bf9a700SWesley Yao } 12399bf9a700SWesley Yao 12409bf9a700SWesley Yao sat.page_size_byte = page_size_kb << 10; 12419bf9a700SWesley Yao 12429bf9a700SWesley Yao start_time_us = get_time_us(); 12439bf9a700SWesley Yao test_time_us = (u64)test_time_sec * 1000000; 12449bf9a700SWesley Yao 12459bf9a700SWesley Yao /* Change rand seed. If not do this, rand() would be same after boot.*/ 12469bf9a700SWesley Yao srand((unsigned int)(start_time_us & 0xffffffff)); 12479bf9a700SWesley Yao 12489bf9a700SWesley Yao return doing_stressapptest(); 12499bf9a700SWesley Yao } 12509bf9a700SWesley Yao 12512ac0a64aSWesley Yao U_BOOT_CMD(stressapptest, 5, 1, do_stressapptest, 12522ac0a64aSWesley Yao "StressAppTest for Rockchip\n", 12532ac0a64aSWesley Yao "\narg1: test time in second, default value is 20s.\n" 12549c15e090SWesley Yao "arg2: test size in MB, default value is all available space.\n" 12552ac0a64aSWesley Yao "arg3: start addr for test.\n" 12562ac0a64aSWesley Yao "arg4: test page size in kB, default value is 1024kB(1MB).\n" 12579bf9a700SWesley Yao "example:\n" 12589c15e090SWesley Yao " stressapptest: test for 20s, test size is all available space, each page size is 1MB.\n" 12599bf9a700SWesley Yao " stressapptest 43200 64: test for 12h, test size is 64MB, each page size is 1MB (64 pages).\n" 12602ac0a64aSWesley Yao " stressapptest 86400 1024 0x80000000: test for 24h, test size is 1024MB, start addr for test is 0x80000000, each page size is 1MB (1024 pages).\n" 12612ac0a64aSWesley Yao " stressapptest 43200 16 0x40000000 512: test for 12h, test size is 16MB, start addr for test is 0x40000000, each page size is 512kB (32 pages).\n" 12629bf9a700SWesley Yao ); 1263