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