xref: /rk3399_rockchip-uboot/cmd/ddr_tool/stressapptest/stressapptest.c (revision 9bf9a700c88f8fafafed7d71fef827e52c5548e8)
1*9bf9a700SWesley Yao // Copyright 2006 Google Inc. All Rights Reserved.
2*9bf9a700SWesley Yao /* Licensed under the Apache License, Version 2.0 (the "License");
3*9bf9a700SWesley Yao  * you may not use this file except in compliance with the License.
4*9bf9a700SWesley Yao  * You may obtain a copy of the License at
5*9bf9a700SWesley Yao  *
6*9bf9a700SWesley Yao  *	http://www.apache.org/licenses/LICENSE-2.0
7*9bf9a700SWesley Yao  *
8*9bf9a700SWesley Yao  * Unless required by applicable law or agreed to in writing, software
9*9bf9a700SWesley Yao  * distributed under the License is distributed on an "AS IS" BASIS,
10*9bf9a700SWesley Yao  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11*9bf9a700SWesley Yao  * See the License for the specific language governing permissions and
12*9bf9a700SWesley Yao  * limitations under the License.
13*9bf9a700SWesley Yao  */
14*9bf9a700SWesley Yao 
15*9bf9a700SWesley Yao /* This is stressapptest for Rockchip platform in U-Boot, the design idea and
16*9bf9a700SWesley Yao  * the patterns are from code.google.com/p/stressapptest.
17*9bf9a700SWesley Yao  */
18*9bf9a700SWesley Yao 
19*9bf9a700SWesley Yao #include <common.h>
20*9bf9a700SWesley Yao #include <amp.h>
21*9bf9a700SWesley Yao #include <div64.h>
22*9bf9a700SWesley Yao #include <malloc.h>
23*9bf9a700SWesley Yao #include <asm/arch/rockchip_smccc.h>
24*9bf9a700SWesley Yao #include "stressapptest.h"
25*9bf9a700SWesley Yao #include "../ddr_tool_common.h"
26*9bf9a700SWesley Yao 
27*9bf9a700SWesley Yao #define __version__ "v1.0.0 20230214"
28*9bf9a700SWesley Yao 
29*9bf9a700SWesley Yao #if defined(CONFIG_ARM64)
30*9bf9a700SWesley Yao /* Float operation in TOOLCHAIN_ARM32 will cause the compile error */
31*9bf9a700SWesley Yao #define WARM_CPU
32*9bf9a700SWesley Yao #endif
33*9bf9a700SWesley Yao 
34*9bf9a700SWesley Yao #define PAT_NUM			26
35*9bf9a700SWesley Yao #define PATTERN_LIST_SIZE	(PAT_NUM * 2 * 4)
36*9bf9a700SWesley Yao 
37*9bf9a700SWesley Yao #define CPU_NUM_MAX		16
38*9bf9a700SWesley Yao 
39*9bf9a700SWesley Yao static u32 walking_1_data[] = {
40*9bf9a700SWesley Yao 	0x00000001, 0x00000002, 0x00000004, 0x00000008,
41*9bf9a700SWesley Yao 	0x00000010, 0x00000020, 0x00000040, 0x00000080,
42*9bf9a700SWesley Yao 	0x00000100, 0x00000200, 0x00000400, 0x00000800,
43*9bf9a700SWesley Yao 	0x00001000, 0x00002000, 0x00004000, 0x00008000,
44*9bf9a700SWesley Yao 	0x00010000, 0x00020000, 0x00040000, 0x00080000,
45*9bf9a700SWesley Yao 	0x00100000, 0x00200000, 0x00400000, 0x00800000,
46*9bf9a700SWesley Yao 	0x01000000, 0x02000000, 0x04000000, 0x08000000,
47*9bf9a700SWesley Yao 	0x10000000, 0x20000000, 0x40000000, 0x80000000,
48*9bf9a700SWesley Yao 	0x40000000, 0x20000000, 0x10000000, 0x08000000,
49*9bf9a700SWesley Yao 	0x04000000, 0x02000000, 0x01000000, 0x00800000,
50*9bf9a700SWesley Yao 	0x00400000, 0x00200000, 0x00100000, 0x00080000,
51*9bf9a700SWesley Yao 	0x00040000, 0x00020000, 0x00010000, 0x00008000,
52*9bf9a700SWesley Yao 	0x00004000, 0x00002000, 0x00001000, 0x00000800,
53*9bf9a700SWesley Yao 	0x00000400, 0x00000200, 0x00000100, 0x00000080,
54*9bf9a700SWesley Yao 	0x00000040, 0x00000020, 0x00000010, 0x00000008,
55*9bf9a700SWesley Yao 	0x00000004, 0x00000002, 0x00000001, 0x00000000
56*9bf9a700SWesley Yao };
57*9bf9a700SWesley Yao 
58*9bf9a700SWesley Yao static struct pat walking_1 = {
59*9bf9a700SWesley Yao 	"walking_1",
60*9bf9a700SWesley Yao 	walking_1_data,
61*9bf9a700SWesley Yao 	ARRAY_SIZE(walking_1_data) - 1,	/* mask */
62*9bf9a700SWesley Yao 	{1, 1, 2, 1}	/* weight */
63*9bf9a700SWesley Yao };
64*9bf9a700SWesley Yao 
65*9bf9a700SWesley Yao static u32 walking_1_x16_data[] =   {
66*9bf9a700SWesley Yao 	0x00020001, 0x00080004, 0x00200010, 0x00800040,
67*9bf9a700SWesley Yao 	0x02000100, 0x08000400, 0x20001000, 0x80004000,
68*9bf9a700SWesley Yao 	0x20004000, 0x08001000, 0x02000400, 0x00800100,
69*9bf9a700SWesley Yao 	0x00200040, 0x00080010, 0x00020004, 0x00000001
70*9bf9a700SWesley Yao };
71*9bf9a700SWesley Yao 
72*9bf9a700SWesley Yao static struct pat walking_1_x16 = {
73*9bf9a700SWesley Yao 	"walking_1_x16",
74*9bf9a700SWesley Yao 	walking_1_x16_data,
75*9bf9a700SWesley Yao 	ARRAY_SIZE(walking_1_x16_data) - 1,	/* mask */
76*9bf9a700SWesley Yao 	{2, 0, 0, 0}	/* Weight for choosing 32/64/128/256 bit wide of this pattern */
77*9bf9a700SWesley Yao 	/* Reuse for walking_0_x16, because of invert */
78*9bf9a700SWesley Yao };
79*9bf9a700SWesley Yao 
80*9bf9a700SWesley Yao static u32 walking_1_x16_repeat_data[] =   {
81*9bf9a700SWesley Yao 	0x00010001, 0x00020002, 0x00040004, 0x00080008,
82*9bf9a700SWesley Yao 	0x00100010, 0x00200020, 0x00400040, 0x00800080,
83*9bf9a700SWesley Yao 	0x01000100, 0x02000200, 0x04000400, 0x08000800,
84*9bf9a700SWesley Yao 	0x10001000, 0x20002000, 0x40004000, 0x80008000,
85*9bf9a700SWesley Yao 	0x40004000, 0x20002000, 0x10001000, 0x08000800,
86*9bf9a700SWesley Yao 	0x04000400, 0x02000200, 0x01000100, 0x00800080,
87*9bf9a700SWesley Yao 	0x00400040, 0x00200020, 0x00100010, 0x00080008,
88*9bf9a700SWesley Yao 	0x00040004, 0x00020002, 0x00010001, 0x00000000
89*9bf9a700SWesley Yao };
90*9bf9a700SWesley Yao 
91*9bf9a700SWesley Yao static struct pat walking_1_x16_repeat = {
92*9bf9a700SWesley Yao 	"walking_1_x16_repeat",
93*9bf9a700SWesley Yao 	walking_1_x16_repeat_data,
94*9bf9a700SWesley Yao 	ARRAY_SIZE(walking_1_x16_repeat_data) - 1,	/* mask */
95*9bf9a700SWesley Yao 	{2, 4, 2, 0}	/* Weight for choosing 32/64/128/256 bit wide of this pattern */
96*9bf9a700SWesley Yao 	/* Reuse for walking_0_x16_repeat, because of invert */
97*9bf9a700SWesley Yao };
98*9bf9a700SWesley Yao 
99*9bf9a700SWesley Yao static u32 walking_inv_1_data[] = {
100*9bf9a700SWesley Yao 	0x00000001, 0xfffffffe, 0x00000002, 0xfffffffd,
101*9bf9a700SWesley Yao 	0x00000004, 0xfffffffb, 0x00000008, 0xfffffff7,
102*9bf9a700SWesley Yao 	0x00000010, 0xffffffef, 0x00000020, 0xffffffdf,
103*9bf9a700SWesley Yao 	0x00000040, 0xffffffbf, 0x00000080, 0xffffff7f,
104*9bf9a700SWesley Yao 	0x00000100, 0xfffffeff, 0x00000200, 0xfffffdff,
105*9bf9a700SWesley Yao 	0x00000400, 0xfffffbff, 0x00000800, 0xfffff7ff,
106*9bf9a700SWesley Yao 	0x00001000, 0xffffefff, 0x00002000, 0xffffdfff,
107*9bf9a700SWesley Yao 	0x00004000, 0xffffbfff, 0x00008000, 0xffff7fff,
108*9bf9a700SWesley Yao 	0x00010000, 0xfffeffff, 0x00020000, 0xfffdffff,
109*9bf9a700SWesley Yao 	0x00040000, 0xfffbffff, 0x00080000, 0xfff7ffff,
110*9bf9a700SWesley Yao 	0x00100000, 0xffefffff, 0x00200000, 0xffdfffff,
111*9bf9a700SWesley Yao 	0x00400000, 0xffbfffff, 0x00800000, 0xff7fffff,
112*9bf9a700SWesley Yao 	0x01000000, 0xfeffffff, 0x02000000, 0xfdffffff,
113*9bf9a700SWesley Yao 	0x04000000, 0xfbffffff, 0x08000000, 0xf7ffffff,
114*9bf9a700SWesley Yao 	0x10000000, 0xefffffff, 0x20000000, 0xdfffffff,
115*9bf9a700SWesley Yao 	0x40000000, 0xbfffffff, 0x80000000, 0x7fffffff,
116*9bf9a700SWesley Yao 	0x40000000, 0xbfffffff, 0x20000000, 0xdfffffff,
117*9bf9a700SWesley Yao 	0x10000000, 0xefffffff, 0x08000000, 0xf7ffffff,
118*9bf9a700SWesley Yao 	0x04000000, 0xfbffffff, 0x02000000, 0xfdffffff,
119*9bf9a700SWesley Yao 	0x01000000, 0xfeffffff, 0x00800000, 0xff7fffff,
120*9bf9a700SWesley Yao 	0x00400000, 0xffbfffff, 0x00200000, 0xffdfffff,
121*9bf9a700SWesley Yao 	0x00100000, 0xffefffff, 0x00080000, 0xfff7ffff,
122*9bf9a700SWesley Yao 	0x00040000, 0xfffbffff, 0x00020000, 0xfffdffff,
123*9bf9a700SWesley Yao 	0x00010000, 0xfffeffff, 0x00008000, 0xffff7fff,
124*9bf9a700SWesley Yao 	0x00004000, 0xffffbfff, 0x00002000, 0xffffdfff,
125*9bf9a700SWesley Yao 	0x00001000, 0xffffefff, 0x00000800, 0xfffff7ff,
126*9bf9a700SWesley Yao 	0x00000400, 0xfffffbff, 0x00000200, 0xfffffdff,
127*9bf9a700SWesley Yao 	0x00000100, 0xfffffeff, 0x00000080, 0xffffff7f,
128*9bf9a700SWesley Yao 	0x00000040, 0xffffffbf, 0x00000020, 0xffffffdf,
129*9bf9a700SWesley Yao 	0x00000010, 0xffffffef, 0x00000008, 0xfffffff7,
130*9bf9a700SWesley Yao 	0x00000004, 0xfffffffb, 0x00000002, 0xfffffffd,
131*9bf9a700SWesley Yao 	0x00000001, 0xfffffffe, 0x00000000, 0xffffffff
132*9bf9a700SWesley Yao };
133*9bf9a700SWesley Yao 
134*9bf9a700SWesley Yao static struct pat walking_inv_1 = {
135*9bf9a700SWesley Yao 	"walking_inv_1",
136*9bf9a700SWesley Yao 	walking_inv_1_data,
137*9bf9a700SWesley Yao 	ARRAY_SIZE(walking_inv_1_data) - 1,	/* mask */
138*9bf9a700SWesley Yao 	{2, 2, 5, 5}	/* weight */
139*9bf9a700SWesley Yao };
140*9bf9a700SWesley Yao 
141*9bf9a700SWesley Yao static u32 walking_inv_1_x16_data[] = {
142*9bf9a700SWesley Yao 	0xfffe0001, 0xfffd0002, 0xfffb0004, 0xfff70008,
143*9bf9a700SWesley Yao 	0xffef0010, 0xffdf0020, 0xffbf0040, 0xff7f0080,
144*9bf9a700SWesley Yao 	0xfeff0100, 0xfdff0200, 0xfbff0400, 0xf7ff0800,
145*9bf9a700SWesley Yao 	0xefff1000, 0xdfff2000, 0xbfff4000, 0x7fff8000,
146*9bf9a700SWesley Yao 	0xbfff4000, 0xdfff2000, 0xefff1000, 0xf7ff0800,
147*9bf9a700SWesley Yao 	0xfbff0400, 0xfdff0200, 0xfeff0100, 0xff7f0080,
148*9bf9a700SWesley Yao 	0xffbf0040, 0xffdf0020, 0xffef0010, 0xfff70008,
149*9bf9a700SWesley Yao 	0xfffb0004, 0xfffd0002, 0xfffe0001, 0xffff0000
150*9bf9a700SWesley Yao };
151*9bf9a700SWesley Yao 
152*9bf9a700SWesley Yao static struct pat walking_inv_1_x16 = {
153*9bf9a700SWesley Yao 	"walking_inv_1_x16",
154*9bf9a700SWesley Yao 	walking_inv_1_x16_data,
155*9bf9a700SWesley Yao 	ARRAY_SIZE(walking_inv_1_x16_data) - 1,	/* mask */
156*9bf9a700SWesley Yao 	{2, 0, 0, 0}	/* weight */
157*9bf9a700SWesley Yao };
158*9bf9a700SWesley Yao 
159*9bf9a700SWesley Yao static u32 walking_inv_1_x16_repeat_data[] = {
160*9bf9a700SWesley Yao 	0x00010001, 0xfffefffe, 0x00020002, 0xfffdfffd,
161*9bf9a700SWesley Yao 	0x00040004, 0xfffbfffb, 0x00080008, 0xfff7fff7,
162*9bf9a700SWesley Yao 	0x00100010, 0xffefffef, 0x00200020, 0xffdfffdf,
163*9bf9a700SWesley Yao 	0x00400040, 0xffbfffbf, 0x00800080, 0xff7fff7f,
164*9bf9a700SWesley Yao 	0x01000100, 0xfefffeff, 0x02000200, 0xfdfffdff,
165*9bf9a700SWesley Yao 	0x04000400, 0xfbfffbff, 0x08000800, 0xf7fff7ff,
166*9bf9a700SWesley Yao 	0x10001000, 0xefffefff, 0x20002000, 0xdfffdfff,
167*9bf9a700SWesley Yao 	0x40004000, 0xbfffbfff, 0x80008000, 0x7fff7fff,
168*9bf9a700SWesley Yao 	0x40004000, 0xbfffbfff, 0x20002000, 0xdfffdfff,
169*9bf9a700SWesley Yao 	0x10001000, 0xefffefff, 0x08000800, 0xf7fff7ff,
170*9bf9a700SWesley Yao 	0x04000400, 0xfbfffbff, 0x02000200, 0xfdfffdff,
171*9bf9a700SWesley Yao 	0x01000100, 0xfefffeff, 0x00800080, 0xff7fff7f,
172*9bf9a700SWesley Yao 	0x00400040, 0xffbfffbf, 0x00200020, 0xffdfffdf,
173*9bf9a700SWesley Yao 	0x00100010, 0xffefffef, 0x00080008, 0xfff7fff7,
174*9bf9a700SWesley Yao 	0x00040004, 0xfffbfffb, 0x00020002, 0xfffdfffd,
175*9bf9a700SWesley Yao 	0x00010001, 0xfffefffe, 0x00000000, 0xffffffff
176*9bf9a700SWesley Yao };
177*9bf9a700SWesley Yao 
178*9bf9a700SWesley Yao static struct pat walking_inv_1_x16_repeat = {
179*9bf9a700SWesley Yao 	"walking_inv_1_x16_repeat",
180*9bf9a700SWesley Yao 	walking_inv_1_x16_repeat_data,
181*9bf9a700SWesley Yao 	ARRAY_SIZE(walking_inv_1_x16_repeat_data) - 1,	/* mask */
182*9bf9a700SWesley Yao 	{2, 5, 5, 0}	/* weight */
183*9bf9a700SWesley Yao };
184*9bf9a700SWesley Yao 
185*9bf9a700SWesley Yao static u32 walking_0_data[] = {
186*9bf9a700SWesley Yao 	0xfffffffe, 0xfffffffd, 0xfffffffb, 0xfffffff7,
187*9bf9a700SWesley Yao 	0xffffffef, 0xffffffdf, 0xffffffbf, 0xffffff7f,
188*9bf9a700SWesley Yao 	0xfffffeff, 0xfffffdff, 0xfffffbff, 0xfffff7ff,
189*9bf9a700SWesley Yao 	0xffffefff, 0xffffdfff, 0xffffbfff, 0xffff7fff,
190*9bf9a700SWesley Yao 	0xfffeffff, 0xfffdffff, 0xfffbffff, 0xfff7ffff,
191*9bf9a700SWesley Yao 	0xffefffff, 0xffdfffff, 0xffbfffff, 0xff7fffff,
192*9bf9a700SWesley Yao 	0xfeffffff, 0xfdffffff, 0xfbffffff, 0xf7ffffff,
193*9bf9a700SWesley Yao 	0xefffffff, 0xdfffffff, 0xbfffffff, 0x7fffffff,
194*9bf9a700SWesley Yao 	0xbfffffff, 0xdfffffff, 0xefffffff, 0xf7ffffff,
195*9bf9a700SWesley Yao 	0xfbffffff, 0xfdffffff, 0xfeffffff, 0xff7fffff,
196*9bf9a700SWesley Yao 	0xffbfffff, 0xffdfffff, 0xffefffff, 0xfff7ffff,
197*9bf9a700SWesley Yao 	0xfffbffff, 0xfffdffff, 0xfffeffff, 0xffff7fff,
198*9bf9a700SWesley Yao 	0xffffbfff, 0xffffdfff, 0xffffefff, 0xfffff7ff,
199*9bf9a700SWesley Yao 	0xfffffbff, 0xfffffdff, 0xfffffeff, 0xffffff7f,
200*9bf9a700SWesley Yao 	0xffffffbf, 0xffffffdf, 0xffffffef, 0xfffffff7,
201*9bf9a700SWesley Yao 	0xfffffffb, 0xfffffffd, 0xfffffffe, 0xffffffff
202*9bf9a700SWesley Yao };
203*9bf9a700SWesley Yao 
204*9bf9a700SWesley Yao static struct pat walking_0 = {
205*9bf9a700SWesley Yao 	"walking_0",
206*9bf9a700SWesley Yao 	walking_0_data,
207*9bf9a700SWesley Yao 	ARRAY_SIZE(walking_0_data) - 1,	/* mask */
208*9bf9a700SWesley Yao 	{1, 1, 2, 1}	/* weight */
209*9bf9a700SWesley Yao };
210*9bf9a700SWesley Yao 
211*9bf9a700SWesley Yao static u32 one_zero_data[] = {0x00000000, 0xffffffff};
212*9bf9a700SWesley Yao 
213*9bf9a700SWesley Yao static struct pat one_zero = {
214*9bf9a700SWesley Yao 	"one_zero",
215*9bf9a700SWesley Yao 	one_zero_data,
216*9bf9a700SWesley Yao 	ARRAY_SIZE(one_zero_data) - 1,	/* mask */
217*9bf9a700SWesley Yao 	{5, 5, 15, 5}	/* weight */
218*9bf9a700SWesley Yao };
219*9bf9a700SWesley Yao 
220*9bf9a700SWesley Yao static unsigned int one_zero_x16_data[] = {0x0000ffff, 0x0000ffff};
221*9bf9a700SWesley Yao 
222*9bf9a700SWesley Yao static struct pat one_zero_x16 = {
223*9bf9a700SWesley Yao 	"one_zero_x16",
224*9bf9a700SWesley Yao 	one_zero_x16_data,
225*9bf9a700SWesley Yao 	ARRAY_SIZE(one_zero_x16_data) - 1,	/* mask */
226*9bf9a700SWesley Yao 	{5, 0, 0, 0}	/* weight */
227*9bf9a700SWesley Yao };
228*9bf9a700SWesley Yao 
229*9bf9a700SWesley Yao static u32 just_0_data[] = {0x00000000, 0x00000000};
230*9bf9a700SWesley Yao 
231*9bf9a700SWesley Yao static struct pat just_0 = {
232*9bf9a700SWesley Yao 	"just_0",
233*9bf9a700SWesley Yao 	just_0_data,
234*9bf9a700SWesley Yao 	ARRAY_SIZE(just_0_data) - 1,	/* mask */
235*9bf9a700SWesley Yao 	{2, 0, 0, 0}	/* weight */
236*9bf9a700SWesley Yao };
237*9bf9a700SWesley Yao 
238*9bf9a700SWesley Yao static u32 just_1_data[] = {0xffffffff, 0xffffffff};
239*9bf9a700SWesley Yao 
240*9bf9a700SWesley Yao static struct pat just_1 = {
241*9bf9a700SWesley Yao 	"just_1",
242*9bf9a700SWesley Yao 	just_1_data,
243*9bf9a700SWesley Yao 	ARRAY_SIZE(just_1_data) - 1,	/* mask */
244*9bf9a700SWesley Yao 	{2, 0, 0, 0}	/* weight */
245*9bf9a700SWesley Yao };
246*9bf9a700SWesley Yao 
247*9bf9a700SWesley Yao static u32 just_5_data[] = {0x55555555, 0x55555555};
248*9bf9a700SWesley Yao 
249*9bf9a700SWesley Yao static struct pat just_5 = {
250*9bf9a700SWesley Yao 	"just_5",
251*9bf9a700SWesley Yao 	just_5_data,
252*9bf9a700SWesley Yao 	ARRAY_SIZE(just_5_data) - 1,	/* mask */
253*9bf9a700SWesley Yao 	{2, 0, 0, 0}	/* weight */
254*9bf9a700SWesley Yao };
255*9bf9a700SWesley Yao 
256*9bf9a700SWesley Yao static u32 just_a_data[] = {0xaaaaaaaa, 0xaaaaaaaa};
257*9bf9a700SWesley Yao 
258*9bf9a700SWesley Yao static struct pat just_a = {
259*9bf9a700SWesley Yao 	"just_a",
260*9bf9a700SWesley Yao 	just_a_data,
261*9bf9a700SWesley Yao 	ARRAY_SIZE(just_a_data) - 1,	/* mask */
262*9bf9a700SWesley Yao 	{2, 0, 0, 0}	/* weight */
263*9bf9a700SWesley Yao };
264*9bf9a700SWesley Yao 
265*9bf9a700SWesley Yao static u32 five_a_data[] = {0x55555555, 0xaaaaaaaa};
266*9bf9a700SWesley Yao 
267*9bf9a700SWesley Yao static struct pat five_a = {
268*9bf9a700SWesley Yao 	"five_a",
269*9bf9a700SWesley Yao 	five_a_data,
270*9bf9a700SWesley Yao 	ARRAY_SIZE(five_a_data) - 1,	/* mask */
271*9bf9a700SWesley Yao 	{1, 1, 1, 1}	/* weight */
272*9bf9a700SWesley Yao };
273*9bf9a700SWesley Yao 
274*9bf9a700SWesley Yao static unsigned int five_a_x16_data[] = {0x5555aaaa, 0x5555aaaa};
275*9bf9a700SWesley Yao 
276*9bf9a700SWesley Yao static struct pat five_a_x16 = {
277*9bf9a700SWesley Yao 	"five_a_x16",
278*9bf9a700SWesley Yao 	five_a_x16_data,
279*9bf9a700SWesley Yao 	ARRAY_SIZE(five_a_x16_data) - 1,	/* mask */
280*9bf9a700SWesley Yao 	{1, 0, 0, 0}	/* weight */
281*9bf9a700SWesley Yao };
282*9bf9a700SWesley Yao 
283*9bf9a700SWesley Yao static u32 five_a8_data[] = {
284*9bf9a700SWesley Yao 	0x5aa5a55a, 0xa55a5aa5, 0xa55a5aa5, 0x5aa5a55a
285*9bf9a700SWesley Yao };
286*9bf9a700SWesley Yao 
287*9bf9a700SWesley Yao static struct pat five_a8 = {
288*9bf9a700SWesley Yao 	"five_a8",
289*9bf9a700SWesley Yao 	five_a8_data,
290*9bf9a700SWesley Yao 	ARRAY_SIZE(five_a8_data) - 1,	/* mask */
291*9bf9a700SWesley Yao 	{1, 1, 1, 1}	/* weight */
292*9bf9a700SWesley Yao };
293*9bf9a700SWesley Yao 
294*9bf9a700SWesley Yao static u32 five_a8_x16_data[] = {0x5aa5a55a, 0xa55a5aa5};
295*9bf9a700SWesley Yao 
296*9bf9a700SWesley Yao static struct pat five_a8_x16 = {
297*9bf9a700SWesley Yao 	"five_a8_x16",
298*9bf9a700SWesley Yao 	five_a8_x16_data,
299*9bf9a700SWesley Yao 	ARRAY_SIZE(five_a8_x16_data) - 1,	/* mask */
300*9bf9a700SWesley Yao 	{1, 0, 0, 0}	/* weight */
301*9bf9a700SWesley Yao };
302*9bf9a700SWesley Yao 
303*9bf9a700SWesley Yao static unsigned int five_a8_x16_repeat_data[] = {
304*9bf9a700SWesley Yao 	0x5aa55aa5, 0xa55aa55a, 0xa55aa55a, 0x5aa55aa5
305*9bf9a700SWesley Yao };
306*9bf9a700SWesley Yao 
307*9bf9a700SWesley Yao static struct pat five_a8_x16_repeat = {
308*9bf9a700SWesley Yao 	"five_a8_x16_repeat",
309*9bf9a700SWesley Yao 	five_a8_x16_repeat_data,
310*9bf9a700SWesley Yao 	ARRAY_SIZE(five_a8_x16_repeat_data) - 1,	/* mask */
311*9bf9a700SWesley Yao 	{1, 1, 1, 0}	/* weight */
312*9bf9a700SWesley Yao };
313*9bf9a700SWesley Yao 
314*9bf9a700SWesley Yao static u32 long_8b10b_data[] = {0x16161616, 0x16161616};
315*9bf9a700SWesley Yao 
316*9bf9a700SWesley Yao static struct pat long_8b10b = {
317*9bf9a700SWesley Yao 	"long_8b10b",
318*9bf9a700SWesley Yao 	long_8b10b_data,
319*9bf9a700SWesley Yao 	ARRAY_SIZE(long_8b10b_data) - 1,	/* mask */
320*9bf9a700SWesley Yao 	{2, 0, 0, 0}	/* weight */
321*9bf9a700SWesley Yao };
322*9bf9a700SWesley Yao 
323*9bf9a700SWesley Yao static u32 short_8b10b_data[] = {0xb5b5b5b5, 0xb5b5b5b5};
324*9bf9a700SWesley Yao 
325*9bf9a700SWesley Yao static struct pat short_8b10b = {
326*9bf9a700SWesley Yao 	"short_8b10b",
327*9bf9a700SWesley Yao 	short_8b10b_data,
328*9bf9a700SWesley Yao 	ARRAY_SIZE(short_8b10b_data) - 1,	/* mask */
329*9bf9a700SWesley Yao 	{2, 0, 0, 0}	/* weight */
330*9bf9a700SWesley Yao };
331*9bf9a700SWesley Yao 
332*9bf9a700SWesley Yao static u32 checker_8b10b_data[] = {0xb5b5b5b5, 0x4a4a4a4a};
333*9bf9a700SWesley Yao 
334*9bf9a700SWesley Yao static struct pat checker_8b10b = {
335*9bf9a700SWesley Yao 	"checker_8b10b",
336*9bf9a700SWesley Yao 	checker_8b10b_data,
337*9bf9a700SWesley Yao 	ARRAY_SIZE(checker_8b10b_data) - 1,	/* mask */
338*9bf9a700SWesley Yao 	{1, 0, 1, 1}	/* weight */
339*9bf9a700SWesley Yao };
340*9bf9a700SWesley Yao 
341*9bf9a700SWesley Yao static u32 checker_8b10b_x16_data[] = {0xb5b54a4a, 0xb5b54a4a};
342*9bf9a700SWesley Yao 
343*9bf9a700SWesley Yao static struct pat checker_8b10b_x16 = {
344*9bf9a700SWesley Yao 	"checker_8b10b_x16",
345*9bf9a700SWesley Yao 	checker_8b10b_x16_data,
346*9bf9a700SWesley Yao 	ARRAY_SIZE(checker_8b10b_x16_data) - 1,	/* mask */
347*9bf9a700SWesley Yao 	{1, 0, 0, 0}	/* weight */
348*9bf9a700SWesley Yao };
349*9bf9a700SWesley Yao 
350*9bf9a700SWesley Yao static u32 five_7_data[] = {0x55555557, 0x55575555};
351*9bf9a700SWesley Yao 
352*9bf9a700SWesley Yao static struct pat five_7 = {
353*9bf9a700SWesley Yao 	"five_7",
354*9bf9a700SWesley Yao 	five_7_data,
355*9bf9a700SWesley Yao 	ARRAY_SIZE(five_7_data) - 1,	/* mask */
356*9bf9a700SWesley Yao 	{0, 2, 0, 0}	/* weight */
357*9bf9a700SWesley Yao };
358*9bf9a700SWesley Yao 
359*9bf9a700SWesley Yao static u32 five_7_x16_data[] = {0x55575557, 0x57555755};
360*9bf9a700SWesley Yao 
361*9bf9a700SWesley Yao static struct pat five_7_x16 = {
362*9bf9a700SWesley Yao 	"five_7_x16",
363*9bf9a700SWesley Yao 	five_7_x16_data,
364*9bf9a700SWesley Yao 	ARRAY_SIZE(five_7_x16_data) - 1,	/* mask */
365*9bf9a700SWesley Yao 	{2, 0, 0, 0}	/* weight */
366*9bf9a700SWesley Yao };
367*9bf9a700SWesley Yao 
368*9bf9a700SWesley Yao static u32 zero2_fd_data[] = {0x00020002, 0xfffdfffd};
369*9bf9a700SWesley Yao 
370*9bf9a700SWesley Yao static struct pat zero2_fd = {
371*9bf9a700SWesley Yao 	"zero2_fd",
372*9bf9a700SWesley Yao 	zero2_fd_data,
373*9bf9a700SWesley Yao 	ARRAY_SIZE(zero2_fd_data) - 1,	/* mask */
374*9bf9a700SWesley Yao 	{0, 2, 0, 0}	/* weight */
375*9bf9a700SWesley Yao };
376*9bf9a700SWesley Yao 
377*9bf9a700SWesley Yao static u32 zero2_fd_x16_data[] = {0x02020202, 0xfdfdfdfd};
378*9bf9a700SWesley Yao 
379*9bf9a700SWesley Yao static struct pat zero2_fd_x16 = {
380*9bf9a700SWesley Yao 	"zero2_fd_x16",
381*9bf9a700SWesley Yao 	zero2_fd_x16_data,
382*9bf9a700SWesley Yao 	ARRAY_SIZE(zero2_fd_x16_data) - 1,	/* mask */
383*9bf9a700SWesley Yao 	{2, 0, 0, 0}	/* weight */
384*9bf9a700SWesley Yao };
385*9bf9a700SWesley Yao 
386*9bf9a700SWesley Yao static struct pat *pat_array[] = {
387*9bf9a700SWesley Yao 	&walking_1,
388*9bf9a700SWesley Yao 	&walking_1_x16,
389*9bf9a700SWesley Yao 	&walking_1_x16_repeat,
390*9bf9a700SWesley Yao 	&walking_inv_1,
391*9bf9a700SWesley Yao 	&walking_inv_1_x16,
392*9bf9a700SWesley Yao 	&walking_inv_1_x16_repeat,
393*9bf9a700SWesley Yao 	&walking_0,
394*9bf9a700SWesley Yao 	&one_zero,
395*9bf9a700SWesley Yao 	&one_zero_x16,
396*9bf9a700SWesley Yao 	&just_0,
397*9bf9a700SWesley Yao 	&just_1,
398*9bf9a700SWesley Yao 	&just_5,
399*9bf9a700SWesley Yao 	&just_a,
400*9bf9a700SWesley Yao 	&five_a,
401*9bf9a700SWesley Yao 	&five_a_x16,
402*9bf9a700SWesley Yao 	&five_a8,
403*9bf9a700SWesley Yao 	&five_a8_x16,
404*9bf9a700SWesley Yao 	&five_a8_x16_repeat,
405*9bf9a700SWesley Yao 	&long_8b10b,
406*9bf9a700SWesley Yao 	&short_8b10b,
407*9bf9a700SWesley Yao 	&checker_8b10b,
408*9bf9a700SWesley Yao 	&checker_8b10b_x16,
409*9bf9a700SWesley Yao 	&five_7,
410*9bf9a700SWesley Yao 	&five_7_x16,
411*9bf9a700SWesley Yao 	&zero2_fd,
412*9bf9a700SWesley Yao 	&zero2_fd_x16
413*9bf9a700SWesley Yao };
414*9bf9a700SWesley Yao 
415*9bf9a700SWesley Yao static u32 cpu_copy_err[CPU_NUM_MAX];
416*9bf9a700SWesley Yao static u32 cpu_inv_err[CPU_NUM_MAX];
417*9bf9a700SWesley Yao 
418*9bf9a700SWesley Yao static u64 start_time_us;
419*9bf9a700SWesley Yao static u64 test_time_us;
420*9bf9a700SWesley Yao 
421*9bf9a700SWesley Yao static bool cpu_init_finish[CPU_NUM_MAX];
422*9bf9a700SWesley Yao static bool cpu_test_finish[CPU_NUM_MAX];
423*9bf9a700SWesley Yao static bool pattern_page_init_finish;
424*9bf9a700SWesley Yao 
425*9bf9a700SWesley Yao #if (CPU_NUM_MAX > 1)
426*9bf9a700SWesley Yao static ulong test_count = 0;
427*9bf9a700SWesley Yao static ulong __gd;	/* set r9/x18 of secondary cpu to gd addr */
428*9bf9a700SWesley Yao #endif
429*9bf9a700SWesley Yao ulong __sp;		/* set sp of secondary cpu */
430*9bf9a700SWesley Yao 
431*9bf9a700SWesley Yao u32 print_mutex;	/* 0: unlock, 1: lock */
432*9bf9a700SWesley Yao 
433*9bf9a700SWesley Yao static u64 get_time_us(void)
434*9bf9a700SWesley Yao {
435*9bf9a700SWesley Yao 	return lldiv(get_ticks(), CONFIG_SYS_HZ_CLOCK / (CONFIG_SYS_HZ * 1000));
436*9bf9a700SWesley Yao }
437*9bf9a700SWesley Yao 
438*9bf9a700SWesley Yao static u64 run_time_us(void)
439*9bf9a700SWesley Yao {
440*9bf9a700SWesley Yao 	return get_time_us() - start_time_us;
441*9bf9a700SWesley Yao }
442*9bf9a700SWesley Yao 
443*9bf9a700SWesley Yao static void print_time_stamp(void)
444*9bf9a700SWesley Yao {
445*9bf9a700SWesley Yao 	u64 time_us;
446*9bf9a700SWesley Yao 
447*9bf9a700SWesley Yao 	time_us = run_time_us();
448*9bf9a700SWesley Yao 
449*9bf9a700SWesley Yao 	printf("[%5d.%06d] ", (u32)(time_us / 1000000), (u32)(time_us % 1000000));
450*9bf9a700SWesley Yao }
451*9bf9a700SWesley Yao 
452*9bf9a700SWesley Yao static u32 pattern_get(struct pattern *pattern, u32 offset)
453*9bf9a700SWesley Yao {
454*9bf9a700SWesley Yao 	u32 ret;
455*9bf9a700SWesley Yao 
456*9bf9a700SWesley Yao 	ret = pattern->pat->data_array[(offset >> pattern->repeat) &
457*9bf9a700SWesley Yao 				       pattern->pat->mask];
458*9bf9a700SWesley Yao 
459*9bf9a700SWesley Yao 	return pattern->inv ? ~ret : ret;
460*9bf9a700SWesley Yao }
461*9bf9a700SWesley Yao 
462*9bf9a700SWesley Yao static void pattern_adler_sum_calc(struct pattern *pattern,
463*9bf9a700SWesley Yao 				   struct stressapptest_params *sat)
464*9bf9a700SWesley Yao {
465*9bf9a700SWesley Yao 	int i = 0;
466*9bf9a700SWesley Yao 	u64 a1 = 1;
467*9bf9a700SWesley Yao 	u64 b1 = 0;
468*9bf9a700SWesley Yao 	u64 a2 = 1;
469*9bf9a700SWesley Yao 	u64 b2 = 0;
470*9bf9a700SWesley Yao 
471*9bf9a700SWesley Yao 	while (i < sat->block_size_byte / sizeof(u32)) {
472*9bf9a700SWesley Yao 		a1 += (u64)pattern_get(pattern, i++);
473*9bf9a700SWesley Yao 		b1 += a1;
474*9bf9a700SWesley Yao 		a1 += pattern_get(pattern, i++);
475*9bf9a700SWesley Yao 		b1 += a1;
476*9bf9a700SWesley Yao 
477*9bf9a700SWesley Yao 		a2 += (u64)pattern_get(pattern, i++);
478*9bf9a700SWesley Yao 		b2 += a2;
479*9bf9a700SWesley Yao 		a2 += pattern_get(pattern, i++);
480*9bf9a700SWesley Yao 		b2 += a2;
481*9bf9a700SWesley Yao 	}
482*9bf9a700SWesley Yao 
483*9bf9a700SWesley Yao 	pattern->adler_sum.a1 = a1;
484*9bf9a700SWesley Yao 	pattern->adler_sum.b1 = b1;
485*9bf9a700SWesley Yao 	pattern->adler_sum.a2 = a2;
486*9bf9a700SWesley Yao 	pattern->adler_sum.b2 = b2;
487*9bf9a700SWesley Yao }
488*9bf9a700SWesley Yao 
489*9bf9a700SWesley Yao static void pattern_list_init(struct pattern *pattern_list,
490*9bf9a700SWesley Yao 			      struct stressapptest_params *sat)
491*9bf9a700SWesley Yao {
492*9bf9a700SWesley Yao 	u32 weight_count = 0;
493*9bf9a700SWesley Yao 	int k = 0;
494*9bf9a700SWesley Yao 
495*9bf9a700SWesley Yao 	for (int i = 0; i < PAT_NUM; i++) {
496*9bf9a700SWesley Yao 		for (int j = 0; j < 8; j++) {
497*9bf9a700SWesley Yao 			pattern_list[k].pat = pat_array[i];
498*9bf9a700SWesley Yao 			pattern_list[k].inv = j % 2;
499*9bf9a700SWesley Yao 			pattern_list[k].repeat = j / 2;
500*9bf9a700SWesley Yao 			pattern_list[k].weight = pattern_list[k].pat->weight[j / 2];
501*9bf9a700SWesley Yao 			pattern_adler_sum_calc(&pattern_list[k], sat);
502*9bf9a700SWesley Yao 			weight_count += pattern_list[k].weight;
503*9bf9a700SWesley Yao 			k++;
504*9bf9a700SWesley Yao 		}
505*9bf9a700SWesley Yao 	}
506*9bf9a700SWesley Yao 
507*9bf9a700SWesley Yao 	sat->weight_count = weight_count;
508*9bf9a700SWesley Yao }
509*9bf9a700SWesley Yao 
510*9bf9a700SWesley Yao static int get_page_addr(struct page *page_list,
511*9bf9a700SWesley Yao 			 struct stressapptest_params *sat)
512*9bf9a700SWesley Yao {
513*9bf9a700SWesley Yao 	ulong start_adr[CONFIG_NR_DRAM_BANKS], length[CONFIG_NR_DRAM_BANKS];
514*9bf9a700SWesley Yao 	ulong used_length;
515*9bf9a700SWesley Yao 	u32 page = 0;
516*9bf9a700SWesley Yao 
517*9bf9a700SWesley Yao 	get_print_available_addr(start_adr, length, 1);
518*9bf9a700SWesley Yao 
519*9bf9a700SWesley Yao 	printf("Pages for test:\n	Page	Start        End        Length\n");
520*9bf9a700SWesley Yao 
521*9bf9a700SWesley Yao 	for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
522*9bf9a700SWesley Yao 		if ((start_adr[i] == 0 && length[i] == 0) || page >= sat->page_num)
523*9bf9a700SWesley Yao 			break;
524*9bf9a700SWesley Yao 
525*9bf9a700SWesley Yao 		used_length = 0;
526*9bf9a700SWesley Yao 		while (page < sat->page_num &&
527*9bf9a700SWesley Yao 		       length[i] >= used_length + sat->page_size_byte) {
528*9bf9a700SWesley Yao 			page_list[page].base_addr = (void *)(start_adr[i] + used_length);
529*9bf9a700SWesley Yao 			used_length += sat->page_size_byte;
530*9bf9a700SWesley Yao 			printf("	%d	0x%08lx - 0x%08lx 0x%08lx\n",
531*9bf9a700SWesley Yao 			       page, (ulong)page_list[page].base_addr,
532*9bf9a700SWesley Yao 			       (ulong)page_list[page].base_addr + sat->page_size_byte,
533*9bf9a700SWesley Yao 			       (ulong)sat->page_size_byte);
534*9bf9a700SWesley Yao 			page++;
535*9bf9a700SWesley Yao 		}
536*9bf9a700SWesley Yao 	}
537*9bf9a700SWesley Yao 
538*9bf9a700SWesley Yao 	if (page < sat->page_num) {
539*9bf9a700SWesley Yao 		printf("ERROR: Cannot get enough pages to test.\n");
540*9bf9a700SWesley Yao 		printf("Please decrease page_size or test_size\n");
541*9bf9a700SWesley Yao 
542*9bf9a700SWesley Yao 		return -1;
543*9bf9a700SWesley Yao 	}
544*9bf9a700SWesley Yao 
545*9bf9a700SWesley Yao 	return 0;
546*9bf9a700SWesley Yao }
547*9bf9a700SWesley Yao 
548*9bf9a700SWesley Yao static void page_init_valid(struct page *page, struct pattern *pattern_list,
549*9bf9a700SWesley Yao 			    struct stressapptest_params *sat)
550*9bf9a700SWesley Yao {
551*9bf9a700SWesley Yao 	int target;
552*9bf9a700SWesley Yao 	int i = 0;
553*9bf9a700SWesley Yao 	u64 *mem;
554*9bf9a700SWesley Yao 
555*9bf9a700SWesley Yao 	target = (rand() % sat->weight_count) + 1;
556*9bf9a700SWesley Yao 	do {
557*9bf9a700SWesley Yao 		target -= pattern_list[i++].weight;
558*9bf9a700SWesley Yao 		if (target <= 0)
559*9bf9a700SWesley Yao 			break;
560*9bf9a700SWesley Yao 	} while (i < PATTERN_LIST_SIZE);
561*9bf9a700SWesley Yao 	page->pattern = &pattern_list[--i];
562*9bf9a700SWesley Yao 	page->valid = 1;
563*9bf9a700SWesley Yao 
564*9bf9a700SWesley Yao 	mem = (u64 *)page->base_addr;
565*9bf9a700SWesley Yao 	for (i = 0; i < sat->page_size_byte / sizeof(u64); i++)
566*9bf9a700SWesley Yao 		mem[i] = (u64)pattern_get(page->pattern, i * 2) |
567*9bf9a700SWesley Yao 			 (u64)pattern_get(page->pattern, i * 2 + 1) << 32;
568*9bf9a700SWesley Yao }
569*9bf9a700SWesley Yao 
570*9bf9a700SWesley Yao static void page_init_empty(struct page *page)
571*9bf9a700SWesley Yao {
572*9bf9a700SWesley Yao 	page->valid = 0;
573*9bf9a700SWesley Yao }
574*9bf9a700SWesley Yao 
575*9bf9a700SWesley Yao static void page_init(struct pattern *pattern_list,
576*9bf9a700SWesley Yao 		      struct stressapptest_params *sat)
577*9bf9a700SWesley Yao {
578*9bf9a700SWesley Yao 	int i, cpu;
579*9bf9a700SWesley Yao 	u32 empty_page_num;
580*9bf9a700SWesley Yao 
581*9bf9a700SWesley Yao 	for (cpu = 0; cpu < sat->cpu_num; cpu++) {
582*9bf9a700SWesley Yao 		empty_page_num = 0;
583*9bf9a700SWesley Yao 		for (i = cpu; i < sat->page_num; i += sat->cpu_num) {
584*9bf9a700SWesley Yao 			if (rand() % 5 < 3) {
585*9bf9a700SWesley Yao 				page_list[i].valid = 1;
586*9bf9a700SWesley Yao 			} else {
587*9bf9a700SWesley Yao 				page_list[i].valid = 0;
588*9bf9a700SWesley Yao 				empty_page_num++;
589*9bf9a700SWesley Yao 			}
590*9bf9a700SWesley Yao 		}
591*9bf9a700SWesley Yao 		while (empty_page_num >= sat->page_num / sat->cpu_num / 2 && i > 0) {
592*9bf9a700SWesley Yao 			i -= sat->cpu_num;
593*9bf9a700SWesley Yao 			if (page_list[i].valid == 0) {
594*9bf9a700SWesley Yao 				page_list[i].valid = 1;
595*9bf9a700SWesley Yao 				empty_page_num--;
596*9bf9a700SWesley Yao 			}
597*9bf9a700SWesley Yao 		}
598*9bf9a700SWesley Yao 		i = cpu;
599*9bf9a700SWesley Yao 		while (empty_page_num < 2 && i < sat->page_num) {
600*9bf9a700SWesley Yao 			if (page_list[i].valid == 1) {
601*9bf9a700SWesley Yao 				page_list[i].valid = 0;
602*9bf9a700SWesley Yao 				empty_page_num++;
603*9bf9a700SWesley Yao 			}
604*9bf9a700SWesley Yao 			i += sat->cpu_num;
605*9bf9a700SWesley Yao 		}
606*9bf9a700SWesley Yao 	}
607*9bf9a700SWesley Yao 
608*9bf9a700SWesley Yao 	for (i = 0; i < sat->page_num; i++) {
609*9bf9a700SWesley Yao 		if (page_list[i].valid == 1)
610*9bf9a700SWesley Yao 			page_init_valid(&page_list[i], pattern_list, sat);
611*9bf9a700SWesley Yao 		else
612*9bf9a700SWesley Yao 			page_init_empty(&page_list[i]);
613*9bf9a700SWesley Yao 	}
614*9bf9a700SWesley Yao 	flush_dcache_all();
615*9bf9a700SWesley Yao }
616*9bf9a700SWesley Yao 
617*9bf9a700SWesley Yao static u32 page_rand_pick(struct page *page_list, bool valid,
618*9bf9a700SWesley Yao 			  struct stressapptest_params *sat)
619*9bf9a700SWesley Yao {
620*9bf9a700SWesley Yao 	u32 pick;
621*9bf9a700SWesley Yao 	u32 cpu_id;
622*9bf9a700SWesley Yao 
623*9bf9a700SWesley Yao 	cpu_id = get_cpu_id();
624*9bf9a700SWesley Yao 	pick = rand() % (sat->page_num / sat->cpu_num) * sat->cpu_num + cpu_id;
625*9bf9a700SWesley Yao 	while (page_list[pick].valid != valid) {
626*9bf9a700SWesley Yao 		pick += sat->cpu_num;
627*9bf9a700SWesley Yao 		if (pick >= sat->page_num)
628*9bf9a700SWesley Yao 			pick = cpu_id;
629*9bf9a700SWesley Yao 	}
630*9bf9a700SWesley Yao 
631*9bf9a700SWesley Yao 	return pick;
632*9bf9a700SWesley Yao }
633*9bf9a700SWesley Yao 
634*9bf9a700SWesley Yao static u32 block_inv_mis_search(void *dst_addr, struct pattern *src_pattern,
635*9bf9a700SWesley Yao 				struct stressapptest_params *sat)
636*9bf9a700SWesley Yao {
637*9bf9a700SWesley Yao 	u32 *dst_mem;
638*9bf9a700SWesley Yao 	u32 dst_data;
639*9bf9a700SWesley Yao 	u32 expc_data;
640*9bf9a700SWesley Yao 	u32 mis_bit;
641*9bf9a700SWesley Yao 	u32 err = 0;
642*9bf9a700SWesley Yao 
643*9bf9a700SWesley Yao 	dst_mem = (u32 *)dst_addr;
644*9bf9a700SWesley Yao 
645*9bf9a700SWesley Yao 	for (int i = 0; i < sat->block_size_byte / sizeof(u32); i++) {
646*9bf9a700SWesley Yao 		dst_data = dst_mem[i];
647*9bf9a700SWesley Yao 		expc_data = pattern_get(src_pattern, i);
648*9bf9a700SWesley Yao 
649*9bf9a700SWesley Yao 		if (dst_data != expc_data) {
650*9bf9a700SWesley Yao 			lock_byte_mutex(&print_mutex);
651*9bf9a700SWesley Yao 
652*9bf9a700SWesley Yao 			print_time_stamp();
653*9bf9a700SWesley Yao 			printf("INV ERROR at 0x%010lx:\n", (ulong)&dst_mem[i]);
654*9bf9a700SWesley Yao 			printf("	data = 0x%08x\n", dst_data);
655*9bf9a700SWesley Yao 			printf("	expc = 0x%08x\n", expc_data);
656*9bf9a700SWesley Yao 
657*9bf9a700SWesley Yao 			mis_bit = dst_data ^ expc_data;
658*9bf9a700SWesley Yao 			printf("	mismatch at bit");
659*9bf9a700SWesley Yao 			for (int j = 31; j >= 0; j--) {
660*9bf9a700SWesley Yao 				if (((mis_bit >> j) & 1) == 1)
661*9bf9a700SWesley Yao 					printf(" %d", j);
662*9bf9a700SWesley Yao 			}
663*9bf9a700SWesley Yao 			printf("\n");
664*9bf9a700SWesley Yao 
665*9bf9a700SWesley Yao 			unlock_byte_mutex(&print_mutex);
666*9bf9a700SWesley Yao 			dst_mem[i] = expc_data;
667*9bf9a700SWesley Yao 			err++;
668*9bf9a700SWesley Yao 		}
669*9bf9a700SWesley Yao 	}
670*9bf9a700SWesley Yao 	flush_dcache_all();
671*9bf9a700SWesley Yao 
672*9bf9a700SWesley Yao 	if (err == 0) {
673*9bf9a700SWesley Yao 		lock_byte_mutex(&print_mutex);
674*9bf9a700SWesley Yao 		printf("INV ERROR detected but cannot find mismatch data (maybe read error).\n");
675*9bf9a700SWesley Yao 		unlock_byte_mutex(&print_mutex);
676*9bf9a700SWesley Yao 	}
677*9bf9a700SWesley Yao 
678*9bf9a700SWesley Yao 	return err;
679*9bf9a700SWesley Yao }
680*9bf9a700SWesley Yao 
681*9bf9a700SWesley Yao static u32 block_inv_check(void *dst_addr, struct pattern *src_pattern,
682*9bf9a700SWesley Yao 			   struct stressapptest_params *sat)
683*9bf9a700SWesley Yao {
684*9bf9a700SWesley Yao 	u32 *dst_mem;
685*9bf9a700SWesley Yao 	u32 err = 0;
686*9bf9a700SWesley Yao 	int i = 0;
687*9bf9a700SWesley Yao #if defined(WARM_CPU)
688*9bf9a700SWesley Yao 	double a, b, c, d;
689*9bf9a700SWesley Yao #endif
690*9bf9a700SWesley Yao 
691*9bf9a700SWesley Yao 	struct adler_sum adler_sum = {
692*9bf9a700SWesley Yao 		1, 0, 1, 0
693*9bf9a700SWesley Yao 	};
694*9bf9a700SWesley Yao 
695*9bf9a700SWesley Yao 	dst_mem = (u32 *)dst_addr;
696*9bf9a700SWesley Yao 
697*9bf9a700SWesley Yao #if defined(WARM_CPU)
698*9bf9a700SWesley Yao 	a = 2.0 * dst_mem[0];
699*9bf9a700SWesley Yao 	b = 5.0 * dst_mem[0];
700*9bf9a700SWesley Yao 	c = 7.0 * dst_mem[0];
701*9bf9a700SWesley Yao 	d = 9.0 * dst_mem[0];
702*9bf9a700SWesley Yao #endif
703*9bf9a700SWesley Yao 
704*9bf9a700SWesley Yao 	while (i < sat->block_size_byte / sizeof(u32)) {
705*9bf9a700SWesley Yao 		adler_sum.a1 += dst_mem[i++];
706*9bf9a700SWesley Yao 		adler_sum.b1 += adler_sum.a1;
707*9bf9a700SWesley Yao 		adler_sum.a1 += dst_mem[i++];
708*9bf9a700SWesley Yao 		adler_sum.b1 += adler_sum.a1;
709*9bf9a700SWesley Yao 
710*9bf9a700SWesley Yao #if defined(WARM_CPU)
711*9bf9a700SWesley Yao 		a = a * b;
712*9bf9a700SWesley Yao 		b = b + c;
713*9bf9a700SWesley Yao #endif
714*9bf9a700SWesley Yao 
715*9bf9a700SWesley Yao 		adler_sum.a2 += dst_mem[i++];
716*9bf9a700SWesley Yao 		adler_sum.b2 += adler_sum.a2;
717*9bf9a700SWesley Yao 		adler_sum.a2 += dst_mem[i++];
718*9bf9a700SWesley Yao 		adler_sum.b2 += adler_sum.a2;
719*9bf9a700SWesley Yao #if defined(WARM_CPU)
720*9bf9a700SWesley Yao 		c = c * d;
721*9bf9a700SWesley Yao 		d = d + d;
722*9bf9a700SWesley Yao #endif
723*9bf9a700SWesley Yao 	}
724*9bf9a700SWesley Yao 
725*9bf9a700SWesley Yao #if defined(WARM_CPU)
726*9bf9a700SWesley Yao 	d = a + b + c + d;
727*9bf9a700SWesley Yao 	if (d == 1.0)
728*9bf9a700SWesley Yao 		/* Reference the result so that it can't be discarded by the compiler. */
729*9bf9a700SWesley Yao 		printf("This will probably never happen.\n");
730*9bf9a700SWesley Yao #endif
731*9bf9a700SWesley Yao 
732*9bf9a700SWesley Yao 	if (adler_sum.a1 != src_pattern->adler_sum.a1 ||
733*9bf9a700SWesley Yao 	    adler_sum.b1 != src_pattern->adler_sum.b1 ||
734*9bf9a700SWesley Yao 	    adler_sum.a2 != src_pattern->adler_sum.a2 ||
735*9bf9a700SWesley Yao 	    adler_sum.b2 != src_pattern->adler_sum.b2) {
736*9bf9a700SWesley Yao 		err = block_inv_mis_search(dst_addr, src_pattern, sat);
737*9bf9a700SWesley Yao 
738*9bf9a700SWesley Yao 		lock_byte_mutex(&print_mutex);
739*9bf9a700SWesley Yao 		printf("(CPU%d, Pattern: %s, inv: %d, repeat: %d)\n\n",
740*9bf9a700SWesley Yao 		       get_cpu_id(), src_pattern->pat->name, src_pattern->inv,
741*9bf9a700SWesley Yao 		       src_pattern->repeat);
742*9bf9a700SWesley Yao 		unlock_byte_mutex(&print_mutex);
743*9bf9a700SWesley Yao 	}
744*9bf9a700SWesley Yao 
745*9bf9a700SWesley Yao 	return err;
746*9bf9a700SWesley Yao }
747*9bf9a700SWesley Yao 
748*9bf9a700SWesley Yao static void page_inv_up(void *src_addr, struct stressapptest_params *sat)
749*9bf9a700SWesley Yao {
750*9bf9a700SWesley Yao 	void *dst_addr = src_addr;
751*9bf9a700SWesley Yao 	uint data;
752*9bf9a700SWesley Yao 	uint *dst_mem;
753*9bf9a700SWesley Yao 
754*9bf9a700SWesley Yao 	for (int i = 0; i < sat->block_num; i++) {
755*9bf9a700SWesley Yao 		dst_mem = (uint *)dst_addr;
756*9bf9a700SWesley Yao 		for (int j = 0; j < sat->block_size_byte / sizeof(uint); j++) {
757*9bf9a700SWesley Yao 			data = dst_mem[j];
758*9bf9a700SWesley Yao 			dst_mem[j] = ~data;
759*9bf9a700SWesley Yao 		}
760*9bf9a700SWesley Yao 		dst_addr += sat->block_size_byte;
761*9bf9a700SWesley Yao 		flush_dcache_all();
762*9bf9a700SWesley Yao 	}
763*9bf9a700SWesley Yao }
764*9bf9a700SWesley Yao 
765*9bf9a700SWesley Yao static void page_inv_down(void *src_addr, struct stressapptest_params *sat)
766*9bf9a700SWesley Yao {
767*9bf9a700SWesley Yao 	void *dst_addr = src_addr;
768*9bf9a700SWesley Yao 	uint data;
769*9bf9a700SWesley Yao 	uint *dst_mem;
770*9bf9a700SWesley Yao 
771*9bf9a700SWesley Yao 	dst_addr += sat->block_size_byte * (sat->block_num - 1);
772*9bf9a700SWesley Yao 
773*9bf9a700SWesley Yao 	for (int i = sat->block_num - 1; i >= 0; i--) {
774*9bf9a700SWesley Yao 		dst_mem = (uint *)dst_addr;
775*9bf9a700SWesley Yao 		for (int j = sat->block_size_byte / sizeof(uint) - 1; j >= 0; j--) {
776*9bf9a700SWesley Yao 			data = dst_mem[j];
777*9bf9a700SWesley Yao 			dst_mem[j] = ~data;
778*9bf9a700SWesley Yao 		}
779*9bf9a700SWesley Yao 		dst_addr -= sat->block_size_byte;
780*9bf9a700SWesley Yao 		flush_dcache_all();
781*9bf9a700SWesley Yao 	}
782*9bf9a700SWesley Yao }
783*9bf9a700SWesley Yao 
784*9bf9a700SWesley Yao static u32 page_inv(struct stressapptest_params *sat)
785*9bf9a700SWesley Yao {
786*9bf9a700SWesley Yao 	u32 src;
787*9bf9a700SWesley Yao 	void *dst_block_addr;
788*9bf9a700SWesley Yao 	u32 err = 0;
789*9bf9a700SWesley Yao 
790*9bf9a700SWesley Yao 	src = page_rand_pick(page_list, 1, sat);	/* pick a valid page */
791*9bf9a700SWesley Yao 	dst_block_addr = page_list[src].base_addr;
792*9bf9a700SWesley Yao 
793*9bf9a700SWesley Yao 	for (int i = 0; i < 4; i++) {
794*9bf9a700SWesley Yao 		if (rand() % 2 == 0)
795*9bf9a700SWesley Yao 			page_inv_up(page_list[src].base_addr, sat);
796*9bf9a700SWesley Yao 		else
797*9bf9a700SWesley Yao 			page_inv_down(page_list[src].base_addr, sat);
798*9bf9a700SWesley Yao 	}
799*9bf9a700SWesley Yao 
800*9bf9a700SWesley Yao 	for (int i = 0; i < sat->block_num; i++) {
801*9bf9a700SWesley Yao 		err += block_inv_check(dst_block_addr, page_list[src].pattern, sat);
802*9bf9a700SWesley Yao 		dst_block_addr += sat->block_size_byte;
803*9bf9a700SWesley Yao 	}
804*9bf9a700SWesley Yao 
805*9bf9a700SWesley Yao 	flush_dcache_all();
806*9bf9a700SWesley Yao 
807*9bf9a700SWesley Yao 	return err;
808*9bf9a700SWesley Yao }
809*9bf9a700SWesley Yao 
810*9bf9a700SWesley Yao static u32 block_copy_mis_search(void *dst_addr, void *src_addr,
811*9bf9a700SWesley Yao 				 struct pattern *src_pattern,
812*9bf9a700SWesley Yao 				 struct stressapptest_params *sat)
813*9bf9a700SWesley Yao {
814*9bf9a700SWesley Yao 	u32 *dst_mem;
815*9bf9a700SWesley Yao 	u32 *src_mem;
816*9bf9a700SWesley Yao 	u32 dst_data;
817*9bf9a700SWesley Yao 	u32 src_data;
818*9bf9a700SWesley Yao 	u32 expc_data;
819*9bf9a700SWesley Yao 	u32 mis_bit;
820*9bf9a700SWesley Yao 	u32 err = 0;
821*9bf9a700SWesley Yao 
822*9bf9a700SWesley Yao 	dst_mem = (u32 *)dst_addr;
823*9bf9a700SWesley Yao 	src_mem = (u32 *)src_addr;
824*9bf9a700SWesley Yao 
825*9bf9a700SWesley Yao 	for (int i = 0; i < sat->block_size_byte / sizeof(u32); i++) {
826*9bf9a700SWesley Yao 		dst_data = dst_mem[i];
827*9bf9a700SWesley Yao 		src_data = src_mem[i];
828*9bf9a700SWesley Yao 		expc_data = pattern_get(src_pattern, i);
829*9bf9a700SWesley Yao 
830*9bf9a700SWesley Yao 		if (dst_data != expc_data) {
831*9bf9a700SWesley Yao 			lock_byte_mutex(&print_mutex);
832*9bf9a700SWesley Yao 
833*9bf9a700SWesley Yao 			print_time_stamp();
834*9bf9a700SWesley Yao 			printf("COPY ERROR (");
835*9bf9a700SWesley Yao 			if (src_data == expc_data)
836*9bf9a700SWesley Yao 				printf("read");
837*9bf9a700SWesley Yao 			else if (src_data != expc_data)
838*9bf9a700SWesley Yao 				printf("write");
839*9bf9a700SWesley Yao 			printf(" error) at 0x%010lx:\n", (ulong)&src_mem[i]);
840*9bf9a700SWesley Yao 			printf("	data = 0x%08x\n", dst_data);
841*9bf9a700SWesley Yao 			printf("	expc = 0x%08x\n", expc_data);
842*9bf9a700SWesley Yao 
843*9bf9a700SWesley Yao 			mis_bit = dst_data ^ expc_data;
844*9bf9a700SWesley Yao 			printf("	mismatch at bit");
845*9bf9a700SWesley Yao 			for (int j = 31; j >= 0; j--) {
846*9bf9a700SWesley Yao 				if (((mis_bit >> j) & 1) == 1)
847*9bf9a700SWesley Yao 					printf(" %d", j);
848*9bf9a700SWesley Yao 			}
849*9bf9a700SWesley Yao 			printf("\n");
850*9bf9a700SWesley Yao 
851*9bf9a700SWesley Yao 			unlock_byte_mutex(&print_mutex);
852*9bf9a700SWesley Yao 			err++;
853*9bf9a700SWesley Yao 			dst_mem[i] = expc_data;
854*9bf9a700SWesley Yao 		}
855*9bf9a700SWesley Yao 	}
856*9bf9a700SWesley Yao 	flush_dcache_all();
857*9bf9a700SWesley Yao 
858*9bf9a700SWesley Yao 	if (err == 0) {
859*9bf9a700SWesley Yao 		lock_byte_mutex(&print_mutex);
860*9bf9a700SWesley Yao 		printf("COPY ERROR detected but cannot find mismatch data (maybe read error).\n");
861*9bf9a700SWesley Yao 		unlock_byte_mutex(&print_mutex);
862*9bf9a700SWesley Yao 	}
863*9bf9a700SWesley Yao 
864*9bf9a700SWesley Yao 	return err;
865*9bf9a700SWesley Yao }
866*9bf9a700SWesley Yao 
867*9bf9a700SWesley Yao static u32 block_copy_check(void *dst_addr, void *src_addr,
868*9bf9a700SWesley Yao 			    struct adler_sum *adler_sum,
869*9bf9a700SWesley Yao 			    struct pattern *src_pattern,
870*9bf9a700SWesley Yao 			    struct stressapptest_params *sat)
871*9bf9a700SWesley Yao {
872*9bf9a700SWesley Yao 	u32 err = 0;
873*9bf9a700SWesley Yao 
874*9bf9a700SWesley Yao 	if (adler_sum->a1 != src_pattern->adler_sum.a1 ||
875*9bf9a700SWesley Yao 	    adler_sum->b1 != src_pattern->adler_sum.b1 ||
876*9bf9a700SWesley Yao 	    adler_sum->a2 != src_pattern->adler_sum.a2 ||
877*9bf9a700SWesley Yao 	    adler_sum->b2 != src_pattern->adler_sum.b2) {
878*9bf9a700SWesley Yao 		err += block_copy_mis_search(dst_addr, src_addr, src_pattern, sat);
879*9bf9a700SWesley Yao 
880*9bf9a700SWesley Yao 		lock_byte_mutex(&print_mutex);
881*9bf9a700SWesley Yao 		printf("(CPU%d, Pattern: %s, inv: %d, repeat: %d)\n\n",
882*9bf9a700SWesley Yao 		       get_cpu_id(), src_pattern->pat->name, src_pattern->inv,
883*9bf9a700SWesley Yao 		       src_pattern->repeat);
884*9bf9a700SWesley Yao 		unlock_byte_mutex(&print_mutex);
885*9bf9a700SWesley Yao 	}
886*9bf9a700SWesley Yao 
887*9bf9a700SWesley Yao 	return err;
888*9bf9a700SWesley Yao }
889*9bf9a700SWesley Yao 
890*9bf9a700SWesley Yao static u32 block_copy(void *dst_addr, void *src_addr,
891*9bf9a700SWesley Yao 		      struct pattern *src_pattern,
892*9bf9a700SWesley Yao 		      struct stressapptest_params *sat)
893*9bf9a700SWesley Yao {
894*9bf9a700SWesley Yao 	u64 *dst_mem;
895*9bf9a700SWesley Yao 	u64 *src_mem;
896*9bf9a700SWesley Yao 	u64 data;
897*9bf9a700SWesley Yao 	int i = 0;
898*9bf9a700SWesley Yao #if defined(WARM_CPU)
899*9bf9a700SWesley Yao 	double a, b, c, d;
900*9bf9a700SWesley Yao #endif
901*9bf9a700SWesley Yao 
902*9bf9a700SWesley Yao 	struct adler_sum adler_sum = {
903*9bf9a700SWesley Yao 		1, 0, 1, 0
904*9bf9a700SWesley Yao 	};
905*9bf9a700SWesley Yao 
906*9bf9a700SWesley Yao 	dst_mem = (u64 *)dst_addr;
907*9bf9a700SWesley Yao 	src_mem = (u64 *)src_addr;
908*9bf9a700SWesley Yao 
909*9bf9a700SWesley Yao #if defined(WARM_CPU)
910*9bf9a700SWesley Yao 	a = 2.0 * src_mem[0];
911*9bf9a700SWesley Yao 	b = 5.0 * src_mem[0];
912*9bf9a700SWesley Yao 	c = 7.0 * src_mem[0];
913*9bf9a700SWesley Yao 	d = 9.0 * src_mem[0];
914*9bf9a700SWesley Yao #endif
915*9bf9a700SWesley Yao 
916*9bf9a700SWesley Yao 	while (i < sat->block_size_byte / sizeof(u64)) {
917*9bf9a700SWesley Yao 		data = src_mem[i];
918*9bf9a700SWesley Yao 		adler_sum.a1 += data & 0xffffffff;
919*9bf9a700SWesley Yao 		adler_sum.b1 += adler_sum.a1;
920*9bf9a700SWesley Yao 		adler_sum.a1 += data >> 32;
921*9bf9a700SWesley Yao 		adler_sum.b1 += adler_sum.a1;
922*9bf9a700SWesley Yao 		dst_mem[i] = data;
923*9bf9a700SWesley Yao 		i++;
924*9bf9a700SWesley Yao 
925*9bf9a700SWesley Yao #if defined(WARM_CPU)
926*9bf9a700SWesley Yao 		a = a * b;
927*9bf9a700SWesley Yao 		b = b + c;
928*9bf9a700SWesley Yao #endif
929*9bf9a700SWesley Yao 
930*9bf9a700SWesley Yao 		data = src_mem[i];
931*9bf9a700SWesley Yao 		adler_sum.a2 += data & 0xffffffff;
932*9bf9a700SWesley Yao 		adler_sum.b2 += adler_sum.a2;
933*9bf9a700SWesley Yao 		adler_sum.a2 += data >> 32;
934*9bf9a700SWesley Yao 		adler_sum.b2 += adler_sum.a2;
935*9bf9a700SWesley Yao 		dst_mem[i] = data;
936*9bf9a700SWesley Yao 		i++;
937*9bf9a700SWesley Yao 
938*9bf9a700SWesley Yao #if defined(WARM_CPU)
939*9bf9a700SWesley Yao 		c = c * d;
940*9bf9a700SWesley Yao 		d = d + d;
941*9bf9a700SWesley Yao #endif
942*9bf9a700SWesley Yao 	}
943*9bf9a700SWesley Yao 
944*9bf9a700SWesley Yao 	flush_dcache_all();
945*9bf9a700SWesley Yao 
946*9bf9a700SWesley Yao #if defined(WARM_CPU)
947*9bf9a700SWesley Yao 	d = a + b + c + d;
948*9bf9a700SWesley Yao 	if (d == 1.0)
949*9bf9a700SWesley Yao 		/* Reference the result so that it can't be discarded by the compiler. */
950*9bf9a700SWesley Yao 		printf("This will probably never happen.\n");
951*9bf9a700SWesley Yao #endif
952*9bf9a700SWesley Yao 
953*9bf9a700SWesley Yao 	return block_copy_check(dst_addr, src_addr, &adler_sum, src_pattern, sat);
954*9bf9a700SWesley Yao }
955*9bf9a700SWesley Yao 
956*9bf9a700SWesley Yao static u32 page_copy(struct stressapptest_params *sat)
957*9bf9a700SWesley Yao {
958*9bf9a700SWesley Yao 	u32 dst;
959*9bf9a700SWesley Yao 	u32 src;
960*9bf9a700SWesley Yao 	void *dst_block_addr;
961*9bf9a700SWesley Yao 	void *src_block_addr;
962*9bf9a700SWesley Yao 	u32 err = 0;
963*9bf9a700SWesley Yao 
964*9bf9a700SWesley Yao 	dst = page_rand_pick(page_list, 0, sat);	/* pick a empty page */
965*9bf9a700SWesley Yao 	dst_block_addr = page_list[dst].base_addr;
966*9bf9a700SWesley Yao 	src = page_rand_pick(page_list, 1, sat);	/* pick a valid page */
967*9bf9a700SWesley Yao 	src_block_addr = page_list[src].base_addr;
968*9bf9a700SWesley Yao 	flush_dcache_all();
969*9bf9a700SWesley Yao 
970*9bf9a700SWesley Yao 	for (int i = 0; i < sat->block_num; i++) {
971*9bf9a700SWesley Yao 		err += block_copy(dst_block_addr, src_block_addr,
972*9bf9a700SWesley Yao 				  page_list[src].pattern, sat);
973*9bf9a700SWesley Yao 		dst_block_addr += sat->block_size_byte;
974*9bf9a700SWesley Yao 		src_block_addr += sat->block_size_byte;
975*9bf9a700SWesley Yao 	}
976*9bf9a700SWesley Yao 
977*9bf9a700SWesley Yao 	page_list[dst].pattern = page_list[src].pattern;
978*9bf9a700SWesley Yao 	page_list[dst].valid = 1;
979*9bf9a700SWesley Yao 	page_list[src].valid = 0;
980*9bf9a700SWesley Yao 	flush_dcache_all();
981*9bf9a700SWesley Yao 
982*9bf9a700SWesley Yao 	return err;
983*9bf9a700SWesley Yao }
984*9bf9a700SWesley Yao 
985*9bf9a700SWesley Yao void secondary_main(void)
986*9bf9a700SWesley Yao {
987*9bf9a700SWesley Yao #if (CPU_NUM_MAX > 1)
988*9bf9a700SWesley Yao 	u8 cpu_id;
989*9bf9a700SWesley Yao 	ulong test = 0;
990*9bf9a700SWesley Yao 
991*9bf9a700SWesley Yao #ifndef CONFIG_ARM64
992*9bf9a700SWesley Yao 	asm volatile("mov r9, %0" : : "r" (__gd));	/* set r9 to gd addr */
993*9bf9a700SWesley Yao #else
994*9bf9a700SWesley Yao 	asm volatile("mov x18, %0" : : "r" (__gd));	/* set x18 to gd addr */
995*9bf9a700SWesley Yao #endif
996*9bf9a700SWesley Yao 	dcache_enable();
997*9bf9a700SWesley Yao 	icache_enable();
998*9bf9a700SWesley Yao 
999*9bf9a700SWesley Yao 	udelay(100);
1000*9bf9a700SWesley Yao 
1001*9bf9a700SWesley Yao 	flush_dcache_all();
1002*9bf9a700SWesley Yao 	cpu_id = get_cpu_id();
1003*9bf9a700SWesley Yao 	if (cpu_id != sat.cpu_num) {
1004*9bf9a700SWesley Yao 		printf("Note: Cannot get correct CPU ID, CPU%d is identified as CPU%d.\n",
1005*9bf9a700SWesley Yao 		       sat.cpu_num, cpu_id);
1006*9bf9a700SWesley Yao 		cpu_id = sat.cpu_num;
1007*9bf9a700SWesley Yao 	}
1008*9bf9a700SWesley Yao 	cpu_init_finish[cpu_id] = 1;
1009*9bf9a700SWesley Yao 	printf("CPU%d start OK.\n", cpu_id);
1010*9bf9a700SWesley Yao 
1011*9bf9a700SWesley Yao 	while (pattern_page_init_finish == 0) {
1012*9bf9a700SWesley Yao 		udelay(100);
1013*9bf9a700SWesley Yao 		flush_dcache_all();
1014*9bf9a700SWesley Yao 	}
1015*9bf9a700SWesley Yao 
1016*9bf9a700SWesley Yao 	while (1) {
1017*9bf9a700SWesley Yao 		udelay(100);
1018*9bf9a700SWesley Yao 		flush_dcache_all();
1019*9bf9a700SWesley Yao 		while (test < test_count) {
1020*9bf9a700SWesley Yao 			cpu_test_finish[cpu_id] = 0;
1021*9bf9a700SWesley Yao 			flush_dcache_all();
1022*9bf9a700SWesley Yao 			while (run_time_us() < test_time_us) {
1023*9bf9a700SWesley Yao 				if (rand() % 2 == 0)
1024*9bf9a700SWesley Yao 					cpu_copy_err[cpu_id] += page_copy(&sat);
1025*9bf9a700SWesley Yao 				else
1026*9bf9a700SWesley Yao 					cpu_inv_err[cpu_id] += page_inv(&sat);
1027*9bf9a700SWesley Yao 			}
1028*9bf9a700SWesley Yao 			test++;
1029*9bf9a700SWesley Yao 			cpu_test_finish[cpu_id] = 1;
1030*9bf9a700SWesley Yao 			flush_dcache_all();
1031*9bf9a700SWesley Yao 		}
1032*9bf9a700SWesley Yao 	}
1033*9bf9a700SWesley Yao #else
1034*9bf9a700SWesley Yao 	return;
1035*9bf9a700SWesley Yao #endif
1036*9bf9a700SWesley Yao }
1037*9bf9a700SWesley Yao 
1038*9bf9a700SWesley Yao static int doing_stressapptest(void)
1039*9bf9a700SWesley Yao {
1040*9bf9a700SWesley Yao 	int i;
1041*9bf9a700SWesley Yao 	u32 pre_10s;
1042*9bf9a700SWesley Yao 	u32 now_10s;
1043*9bf9a700SWesley Yao 
1044*9bf9a700SWesley Yao 	struct pattern pattern_list[PATTERN_LIST_SIZE];
1045*9bf9a700SWesley Yao 	void *page_info;
1046*9bf9a700SWesley Yao 
1047*9bf9a700SWesley Yao 	u32 all_copy_err = 0;
1048*9bf9a700SWesley Yao 	u32 all_inv_err = 0;
1049*9bf9a700SWesley Yao 	u32 cpu_no_response_err = 0;
1050*9bf9a700SWesley Yao 
1051*9bf9a700SWesley Yao 	int ret = CMD_RET_SUCCESS;
1052*9bf9a700SWesley Yao 
1053*9bf9a700SWesley Yao 	for (i = 0; i < CPU_NUM_MAX; i++) {
1054*9bf9a700SWesley Yao 		cpu_copy_err[i] = 0;
1055*9bf9a700SWesley Yao 		cpu_inv_err[i] = 0;
1056*9bf9a700SWesley Yao 		cpu_init_finish[i] = 0;
1057*9bf9a700SWesley Yao 		cpu_test_finish[i] = 0;
1058*9bf9a700SWesley Yao 	}
1059*9bf9a700SWesley Yao 	pattern_page_init_finish = 0;
1060*9bf9a700SWesley Yao 	print_mutex = 0;
1061*9bf9a700SWesley Yao 	asm volatile("clrex");
1062*9bf9a700SWesley Yao 
1063*9bf9a700SWesley Yao #if (CPU_NUM_MAX > 1)
1064*9bf9a700SWesley Yao 	if (test_count == 0) {
1065*9bf9a700SWesley Yao 		__gd = (ulong)gd;
1066*9bf9a700SWesley Yao 		asm volatile("mov %0, sp" : "=r" (__sp));
1067*9bf9a700SWesley Yao 		printf("CPU0 sp is at 0x%lx now.\n", __sp);
1068*9bf9a700SWesley Yao 		__sp &= ~(ulong)0xffff;
1069*9bf9a700SWesley Yao 		for (sat.cpu_num = 1; sat.cpu_num < CPU_NUM_MAX; sat.cpu_num++) {
1070*9bf9a700SWesley Yao 			__sp -= 0x10000;
1071*9bf9a700SWesley Yao 			flush_dcache_all();
1072*9bf9a700SWesley Yao 			if (psci_cpu_on(sat.cpu_num, (ulong)secondary_init) == 0) {
1073*9bf9a700SWesley Yao 				mdelay(10);
1074*9bf9a700SWesley Yao 				printf("Calling CPU%d, sp = 0x%lx\n", sat.cpu_num, __sp);
1075*9bf9a700SWesley Yao 			} else {
1076*9bf9a700SWesley Yao 				break;
1077*9bf9a700SWesley Yao 			}
1078*9bf9a700SWesley Yao 			while (cpu_init_finish[sat.cpu_num] == 0) {
1079*9bf9a700SWesley Yao 				udelay(1000);
1080*9bf9a700SWesley Yao 				flush_dcache_all();
1081*9bf9a700SWesley Yao 			}
1082*9bf9a700SWesley Yao 		}
1083*9bf9a700SWesley Yao 	}
1084*9bf9a700SWesley Yao #else
1085*9bf9a700SWesley Yao 	sat.cpu_num = 1;
1086*9bf9a700SWesley Yao #endif
1087*9bf9a700SWesley Yao 
1088*9bf9a700SWesley Yao 	sat.page_num = (sat.total_test_size_mb << 20) / sat.page_size_byte;
1089*9bf9a700SWesley Yao 	sat.block_num = sat.page_size_byte / sat.block_size_byte;
1090*9bf9a700SWesley Yao 
1091*9bf9a700SWesley Yao 	udelay(100);
1092*9bf9a700SWesley Yao 
1093*9bf9a700SWesley Yao 	page_info = malloc(sizeof(struct page) * sat.page_num);
1094*9bf9a700SWesley Yao 	if (page_info == 0) {
1095*9bf9a700SWesley Yao 		printf("ERROR: StressAppTest fail to malloc.\n");
1096*9bf9a700SWesley Yao 		printf("Please try increasing CONFIG_SYS_MALLOC_LEN in include/configs/rxxxxx_common.h.\n");
1097*9bf9a700SWesley Yao 		ret = CMD_RET_FAILURE;
1098*9bf9a700SWesley Yao 		goto out;
1099*9bf9a700SWesley Yao 	}
1100*9bf9a700SWesley Yao 	page_list = (struct page *)page_info;
1101*9bf9a700SWesley Yao 
1102*9bf9a700SWesley Yao 	if (get_page_addr(page_list, &sat) < 0) {
1103*9bf9a700SWesley Yao 		ret = CMD_RET_FAILURE;
1104*9bf9a700SWesley Yao 		goto out;
1105*9bf9a700SWesley Yao 	}
1106*9bf9a700SWesley Yao 
1107*9bf9a700SWesley Yao 	pattern_list_init(pattern_list, &sat);
1108*9bf9a700SWesley Yao 	page_init(pattern_list, &sat);
1109*9bf9a700SWesley Yao 
1110*9bf9a700SWesley Yao #if (CPU_NUM_MAX > 1)
1111*9bf9a700SWesley Yao 	if (sat.cpu_num > 1) {
1112*9bf9a700SWesley Yao 		pattern_page_init_finish = 1;
1113*9bf9a700SWesley Yao 		test_count++;
1114*9bf9a700SWesley Yao 		flush_dcache_all();
1115*9bf9a700SWesley Yao 	}
1116*9bf9a700SWesley Yao #endif
1117*9bf9a700SWesley Yao 
1118*9bf9a700SWesley Yao 	pre_10s = (u32)(run_time_us() / 1000000 / 10);
1119*9bf9a700SWesley Yao 	lock_byte_mutex(&print_mutex);
1120*9bf9a700SWesley Yao 	print_time_stamp();
1121*9bf9a700SWesley Yao 	printf("Start StressAppTest in U-Boot:\n");
1122*9bf9a700SWesley Yao 	unlock_byte_mutex(&print_mutex);
1123*9bf9a700SWesley Yao 
1124*9bf9a700SWesley Yao 	while (run_time_us() < test_time_us) {
1125*9bf9a700SWesley Yao 		if (rand() % 2 == 0)
1126*9bf9a700SWesley Yao 			cpu_copy_err[0] += page_copy(&sat);
1127*9bf9a700SWesley Yao 		else
1128*9bf9a700SWesley Yao 			cpu_inv_err[0] += page_inv(&sat);
1129*9bf9a700SWesley Yao 
1130*9bf9a700SWesley Yao 		/* Print every 10 seconds */
1131*9bf9a700SWesley Yao 		now_10s = (u32)(run_time_us() / 1000000 / 10);
1132*9bf9a700SWesley Yao 		if (now_10s > pre_10s) {
1133*9bf9a700SWesley Yao 			pre_10s = now_10s;
1134*9bf9a700SWesley Yao 			lock_byte_mutex(&print_mutex);
1135*9bf9a700SWesley Yao 			print_time_stamp();
1136*9bf9a700SWesley Yao 			printf("Seconds remaining: %d\n", (u32)(test_time_us / 1000000 - now_10s * 10));
1137*9bf9a700SWesley Yao 			unlock_byte_mutex(&print_mutex);
1138*9bf9a700SWesley Yao 		}
1139*9bf9a700SWesley Yao 	}
1140*9bf9a700SWesley Yao 
1141*9bf9a700SWesley Yao #if (CPU_NUM_MAX > 1)
1142*9bf9a700SWesley Yao 	for (i = 1; i < sat.cpu_num; i++) {
1143*9bf9a700SWesley Yao 		while (cpu_test_finish[i] == 0) {
1144*9bf9a700SWesley Yao 			if ((u32)(run_time_us() / 1000000 / 10) > pre_10s + 6) {
1145*9bf9a700SWesley Yao 				/* wait for secondary CPU in 60s */
1146*9bf9a700SWesley Yao 				lock_byte_mutex(&print_mutex);
1147*9bf9a700SWesley Yao 				print_time_stamp();
1148*9bf9a700SWesley Yao 				printf("ERROR: Cannot wait for CPU%d to finish!\n", i);
1149*9bf9a700SWesley Yao 				unlock_byte_mutex(&print_mutex);
1150*9bf9a700SWesley Yao 				cpu_no_response_err++;
1151*9bf9a700SWesley Yao 				break;
1152*9bf9a700SWesley Yao 			}
1153*9bf9a700SWesley Yao 			mdelay(1);
1154*9bf9a700SWesley Yao 			flush_dcache_all();
1155*9bf9a700SWesley Yao 		}
1156*9bf9a700SWesley Yao 	}
1157*9bf9a700SWesley Yao #endif
1158*9bf9a700SWesley Yao 
1159*9bf9a700SWesley Yao 	for (i = 0; i < sat.cpu_num; i++) {
1160*9bf9a700SWesley Yao 		all_copy_err += cpu_copy_err[i];
1161*9bf9a700SWesley Yao 		all_inv_err += cpu_inv_err[i];
1162*9bf9a700SWesley Yao 	}
1163*9bf9a700SWesley Yao 	print_time_stamp();
1164*9bf9a700SWesley Yao 	printf("StressAppTest Result: ");
1165*9bf9a700SWesley Yao 	if (all_copy_err == 0 && all_inv_err == 0 && cpu_no_response_err == 0)
1166*9bf9a700SWesley Yao 		printf("Pass.\n");
1167*9bf9a700SWesley Yao 	else
1168*9bf9a700SWesley Yao 		printf("FAIL!\nStressAppTest detects %d copy errors, %d inv errors.\n",
1169*9bf9a700SWesley Yao 		       all_copy_err, all_inv_err);
1170*9bf9a700SWesley Yao 
1171*9bf9a700SWesley Yao out:
1172*9bf9a700SWesley Yao 	free(page_info);
1173*9bf9a700SWesley Yao 
1174*9bf9a700SWesley Yao 	return ret;
1175*9bf9a700SWesley Yao }
1176*9bf9a700SWesley Yao 
1177*9bf9a700SWesley Yao static int do_stressapptest(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
1178*9bf9a700SWesley Yao {
1179*9bf9a700SWesley Yao 	ulong test_time_sec = 20;
1180*9bf9a700SWesley Yao 	ulong page_size_kb = 1024;
1181*9bf9a700SWesley Yao 
1182*9bf9a700SWesley Yao 	sat.total_test_size_mb = 32;
1183*9bf9a700SWesley Yao 	sat.block_size_byte = 4096;
1184*9bf9a700SWesley Yao 
1185*9bf9a700SWesley Yao 	printf("StressAppTest in U-Boot, " __version__ "\n");
1186*9bf9a700SWesley Yao 
1187*9bf9a700SWesley Yao 	if (argc > 1) {
1188*9bf9a700SWesley Yao 		if (strict_strtoul(argv[1], 0, &test_time_sec) < 0)
1189*9bf9a700SWesley Yao 			return CMD_RET_USAGE;
1190*9bf9a700SWesley Yao 		if (test_time_sec < 1)
1191*9bf9a700SWesley Yao 			test_time_sec = 20;
1192*9bf9a700SWesley Yao 	}
1193*9bf9a700SWesley Yao 	if (argc > 2) {
1194*9bf9a700SWesley Yao 		if (strict_strtoul(argv[2], 0, &sat.total_test_size_mb) < 0)
1195*9bf9a700SWesley Yao 			return CMD_RET_USAGE;
1196*9bf9a700SWesley Yao 		if (sat.total_test_size_mb < 1)
1197*9bf9a700SWesley Yao 			sat.total_test_size_mb = 32;
1198*9bf9a700SWesley Yao 	}
1199*9bf9a700SWesley Yao 	if (argc > 3) {
1200*9bf9a700SWesley Yao 		if (strict_strtoul(argv[3], 0, &page_size_kb) < 0)
1201*9bf9a700SWesley Yao 			return CMD_RET_USAGE;
1202*9bf9a700SWesley Yao 		if (page_size_kb < 1)
1203*9bf9a700SWesley Yao 			page_size_kb = 1024;
1204*9bf9a700SWesley Yao 	}
1205*9bf9a700SWesley Yao 
1206*9bf9a700SWesley Yao 	sat.page_size_byte = page_size_kb << 10;
1207*9bf9a700SWesley Yao 
1208*9bf9a700SWesley Yao 	start_time_us = get_time_us();
1209*9bf9a700SWesley Yao 	test_time_us = (u64)test_time_sec * 1000000;
1210*9bf9a700SWesley Yao 
1211*9bf9a700SWesley Yao 	/* Change rand seed. If not do this, rand() would be same after boot.*/
1212*9bf9a700SWesley Yao 	srand((unsigned int)(start_time_us & 0xffffffff));
1213*9bf9a700SWesley Yao 
1214*9bf9a700SWesley Yao 	return doing_stressapptest();
1215*9bf9a700SWesley Yao }
1216*9bf9a700SWesley Yao 
1217*9bf9a700SWesley Yao U_BOOT_CMD(stressapptest,	4,	1,	do_stressapptest,
1218*9bf9a700SWesley Yao 	   "StressAppTest for Rockship\n",
1219*9bf9a700SWesley Yao 	   "\narg1: test time in second, null or 0 for 20s.\n"
1220*9bf9a700SWesley Yao 	   "arg2: test size in MB, null or 0 for 32MB.\n"
1221*9bf9a700SWesley Yao 	   "arg3: test page size in Byte, null or 0 for 1024kB(1MB).\n"
1222*9bf9a700SWesley Yao 	   "example:\n"
1223*9bf9a700SWesley Yao 	   "	stressapptest: test for 20s, test size is 32MB, each page size is 1MB (32 pages).\n"
1224*9bf9a700SWesley Yao 	   "	stressapptest 43200 64: test for 12h, test size is 64MB, each page size is 1MB (64 pages).\n"
1225*9bf9a700SWesley Yao 	   "	stressapptest 43200 16 512: test for 12h, test size is 16MB, each page size is 512kB (32 pages).\n"
1226*9bf9a700SWesley Yao );
1227