xref: /rk3399_rockchip-uboot/cmd/ddr_tool/stressapptest/stressapptest.c (revision aa9eaea12b9e05b8bb350786ff42ca72290d52fa)
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