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