blob: 0f977fe2450f912f5a2dddd8e531e8d712c97052 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
wdenka042ac82002-09-12 22:36:57 +00002/*
3 * (C) Copyright 2002
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
wdenka042ac82002-09-12 22:36:57 +00005 */
6
7#include <common.h>
Simon Glass52f24232020-05-10 11:40:00 -06008#include <bootstage.h>
Simon Glass3a7d5572019-08-01 09:46:42 -06009#include <env.h>
Simon Glass336d4612020-02-03 07:36:16 -070010#include <malloc.h>
Jean-Christophe PLAGNIOL-VILLARD52cb4d42009-05-16 12:14:54 +020011#include <stdio_dev.h>
Simon Glass10453152019-11-14 12:57:30 -070012#include <time.h>
wdenka042ac82002-09-12 22:36:57 +000013#include <watchdog.h>
Christian Rieschc90a4dd2011-12-09 16:54:02 +010014#include <div64.h>
wdenka042ac82002-09-12 22:36:57 +000015#include <post.h>
16
Mike Frysinger9146d132011-05-10 07:01:21 +000017#ifdef CONFIG_SYS_POST_HOTKEYS_GPIO
18#include <asm/gpio.h>
19#endif
20
Wolfgang Denkd87080b2006-03-31 18:32:53 +020021DECLARE_GLOBAL_DATA_PTR;
22
wdenka042ac82002-09-12 22:36:57 +000023#define POST_MAX_NUMBER 32
24
25#define BOOTMODE_MAGIC 0xDEAD0000
26
Heiko Schochere92372c2011-10-12 01:18:05 +000027int post_init_f(void)
wdenk4532cb62003-04-27 22:52:51 +000028{
wdenk4532cb62003-04-27 22:52:51 +000029 int res = 0;
30 unsigned int i;
31
32 for (i = 0; i < post_list_size; i++) {
33 struct post_test *test = post_list + i;
34
Wolfgang Denk50da8372011-10-29 09:42:22 +000035 if (test->init_f && test->init_f())
wdenk4532cb62003-04-27 22:52:51 +000036 res = -1;
wdenk4532cb62003-04-27 22:52:51 +000037 }
wdenk8bde7f72003-06-27 21:31:46 +000038
wdenk4532cb62003-04-27 22:52:51 +000039 gd->post_init_f_time = post_time_ms(0);
40 if (!gd->post_init_f_time)
Heiko Schochere92372c2011-10-12 01:18:05 +000041 printf("%s: post_time_ms not implemented\n", __FILE__);
wdenk4532cb62003-04-27 22:52:51 +000042
43 return res;
44}
45
Stefan Roese39ff7d52009-12-03 06:24:30 +010046/*
47 * Supply a default implementation for post_hotkeys_pressed() for boards
48 * without hotkey support. We always return 0 here, so that the
49 * long-running tests won't be started.
50 *
51 * Boards with hotkey support can override this weak default function
52 * by defining one in their board specific code.
53 */
Jeroen Hofstee002ad7b2014-10-08 22:57:25 +020054__weak int post_hotkeys_pressed(void)
Stefan Roese39ff7d52009-12-03 06:24:30 +010055{
Mike Frysinger9146d132011-05-10 07:01:21 +000056#ifdef CONFIG_SYS_POST_HOTKEYS_GPIO
57 int ret;
58 unsigned gpio = CONFIG_SYS_POST_HOTKEYS_GPIO;
59
60 ret = gpio_request(gpio, "hotkeys");
61 if (ret) {
62 printf("POST: gpio hotkey request failed\n");
63 return 0;
64 }
65
66 gpio_direction_input(gpio);
67 ret = gpio_get_value(gpio);
68 gpio_free(gpio);
69
70 return ret;
71#endif
72
Stefan Roese39ff7d52009-12-03 06:24:30 +010073 return 0; /* No hotkeys supported */
74}
Stefan Roese39ff7d52009-12-03 06:24:30 +010075
Heiko Schochere92372c2011-10-12 01:18:05 +000076void post_bootmode_init(void)
wdenka042ac82002-09-12 22:36:57 +000077{
Heiko Schochere92372c2011-10-12 01:18:05 +000078 int bootmode = post_bootmode_get(0);
wdenk27b207f2003-07-24 23:38:38 +000079 int newword;
wdenk42d1f032003-10-15 23:53:47 +000080
Heiko Schochere92372c2011-10-12 01:18:05 +000081 if (post_hotkeys_pressed() && !(bootmode & POST_POWERTEST))
wdenk27b207f2003-07-24 23:38:38 +000082 newword = BOOTMODE_MAGIC | POST_SLOWTEST;
Heiko Schochere92372c2011-10-12 01:18:05 +000083 else if (bootmode == 0)
wdenk27b207f2003-07-24 23:38:38 +000084 newword = BOOTMODE_MAGIC | POST_POWERON;
Heiko Schochere92372c2011-10-12 01:18:05 +000085 else if (bootmode == POST_POWERON || bootmode == POST_SLOWTEST)
wdenk27b207f2003-07-24 23:38:38 +000086 newword = BOOTMODE_MAGIC | POST_NORMAL;
Heiko Schochere92372c2011-10-12 01:18:05 +000087 else
wdenk27b207f2003-07-24 23:38:38 +000088 /* Use old value */
Wolfgang Denk50da8372011-10-29 09:42:22 +000089 newword = post_word_load() & ~POST_COLDBOOT;
wdenka042ac82002-09-12 22:36:57 +000090
wdenk27b207f2003-07-24 23:38:38 +000091 if (bootmode == 0)
wdenk27b207f2003-07-24 23:38:38 +000092 /* We are booting after power-on */
93 newword |= POST_COLDBOOT;
wdenk27b207f2003-07-24 23:38:38 +000094
Heiko Schochere92372c2011-10-12 01:18:05 +000095 post_word_store(newword);
wdenk27b207f2003-07-24 23:38:38 +000096
wdenk228f29a2002-12-08 09:53:23 +000097 /* Reset activity record */
98 gd->post_log_word = 0;
Valentin Longchamp79843952011-08-03 02:37:01 +000099 gd->post_log_res = 0;
wdenka042ac82002-09-12 22:36:57 +0000100}
101
Heiko Schochere92372c2011-10-12 01:18:05 +0000102int post_bootmode_get(unsigned int *last_test)
wdenka042ac82002-09-12 22:36:57 +0000103{
Heiko Schochere92372c2011-10-12 01:18:05 +0000104 unsigned long word = post_word_load();
wdenka042ac82002-09-12 22:36:57 +0000105 int bootmode;
106
Heiko Schochere92372c2011-10-12 01:18:05 +0000107 if ((word & 0xFFFF0000) != BOOTMODE_MAGIC)
wdenka042ac82002-09-12 22:36:57 +0000108 return 0;
wdenka042ac82002-09-12 22:36:57 +0000109
wdenk27b207f2003-07-24 23:38:38 +0000110 bootmode = word & 0x7F;
wdenka042ac82002-09-12 22:36:57 +0000111
Heiko Schochere92372c2011-10-12 01:18:05 +0000112 if (last_test && (bootmode & POST_POWERTEST))
wdenka042ac82002-09-12 22:36:57 +0000113 *last_test = (word >> 8) & 0xFF;
wdenka042ac82002-09-12 22:36:57 +0000114
115 return bootmode;
116}
117
wdenk228f29a2002-12-08 09:53:23 +0000118/* POST tests run before relocation only mark status bits .... */
Heiko Schochere92372c2011-10-12 01:18:05 +0000119static void post_log_mark_start(unsigned long testid)
wdenk228f29a2002-12-08 09:53:23 +0000120{
Valentin Longchamp79843952011-08-03 02:37:01 +0000121 gd->post_log_word |= testid;
wdenk228f29a2002-12-08 09:53:23 +0000122}
123
Heiko Schochere92372c2011-10-12 01:18:05 +0000124static void post_log_mark_succ(unsigned long testid)
wdenk228f29a2002-12-08 09:53:23 +0000125{
Valentin Longchamp79843952011-08-03 02:37:01 +0000126 gd->post_log_res |= testid;
wdenk228f29a2002-12-08 09:53:23 +0000127}
128
129/* ... and the messages are output once we are relocated */
Heiko Schochere92372c2011-10-12 01:18:05 +0000130void post_output_backlog(void)
wdenk228f29a2002-12-08 09:53:23 +0000131{
wdenk228f29a2002-12-08 09:53:23 +0000132 int j;
133
134 for (j = 0; j < post_list_size; j++) {
Valentin Longchamp79843952011-08-03 02:37:01 +0000135 if (gd->post_log_word & (post_list[j].testid)) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000136 post_log("POST %s ", post_list[j].cmd);
Valentin Longchamp79843952011-08-03 02:37:01 +0000137 if (gd->post_log_res & post_list[j].testid)
Wolfgang Denk50da8372011-10-29 09:42:22 +0000138 post_log("PASSED\n");
wdenk63e73c92004-02-23 22:22:28 +0000139 else {
Heiko Schochere92372c2011-10-12 01:18:05 +0000140 post_log("FAILED\n");
Simon Glass770605e2012-02-13 13:51:18 +0000141 bootstage_error(BOOTSTAGE_ID_POST_FAIL_R);
wdenk63e73c92004-02-23 22:22:28 +0000142 }
wdenk228f29a2002-12-08 09:53:23 +0000143 }
144 }
145}
146
Heiko Schochere92372c2011-10-12 01:18:05 +0000147static void post_bootmode_test_on(unsigned int last_test)
wdenka042ac82002-09-12 22:36:57 +0000148{
Heiko Schochere92372c2011-10-12 01:18:05 +0000149 unsigned long word = post_word_load();
wdenka042ac82002-09-12 22:36:57 +0000150
151 word |= POST_POWERTEST;
152
153 word |= (last_test & 0xFF) << 8;
154
Heiko Schochere92372c2011-10-12 01:18:05 +0000155 post_word_store(word);
wdenka042ac82002-09-12 22:36:57 +0000156}
157
Heiko Schochere92372c2011-10-12 01:18:05 +0000158static void post_bootmode_test_off(void)
wdenka042ac82002-09-12 22:36:57 +0000159{
Heiko Schochere92372c2011-10-12 01:18:05 +0000160 unsigned long word = post_word_load();
wdenka042ac82002-09-12 22:36:57 +0000161
162 word &= ~POST_POWERTEST;
163
Heiko Schochere92372c2011-10-12 01:18:05 +0000164 post_word_store(word);
wdenka042ac82002-09-12 22:36:57 +0000165}
166
Valentin Longchamp212a0ca2011-08-03 02:37:02 +0000167#ifndef CONFIG_POST_SKIP_ENV_FLAGS
168static void post_get_env_flags(int *test_flags)
wdenka042ac82002-09-12 22:36:57 +0000169{
Yuri Tikhonove262efe2008-02-04 14:11:03 +0100170 int flag[] = { POST_POWERON, POST_NORMAL, POST_SLOWTEST,
171 POST_CRITICAL };
172 char *var[] = { "post_poweron", "post_normal", "post_slowtest",
173 "post_critical" };
Mike Frysingerd2397812011-05-10 07:28:35 +0000174 int varnum = ARRAY_SIZE(var);
wdenka042ac82002-09-12 22:36:57 +0000175 char list[128]; /* long enough for POST list */
176 char *name;
177 char *s;
178 int last;
179 int i, j;
180
wdenka042ac82002-09-12 22:36:57 +0000181 for (i = 0; i < varnum; i++) {
Simon Glass00caae62017-08-03 12:22:12 -0600182 if (env_get_f(var[i], list, sizeof(list)) <= 0)
wdenka042ac82002-09-12 22:36:57 +0000183 continue;
184
Wolfgang Denk50da8372011-10-29 09:42:22 +0000185 for (j = 0; j < post_list_size; j++)
wdenka042ac82002-09-12 22:36:57 +0000186 test_flags[j] &= ~flag[i];
wdenka042ac82002-09-12 22:36:57 +0000187
188 last = 0;
189 name = list;
190 while (!last) {
191 while (*name && *name == ' ')
192 name++;
193 if (*name == 0)
194 break;
195 s = name + 1;
196 while (*s && *s != ' ')
197 s++;
198 if (*s == 0)
199 last = 1;
200 else
201 *s = 0;
202
203 for (j = 0; j < post_list_size; j++) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000204 if (strcmp(post_list[j].cmd, name) == 0) {
wdenka042ac82002-09-12 22:36:57 +0000205 test_flags[j] |= flag[i];
206 break;
207 }
208 }
209
Heiko Schochere92372c2011-10-12 01:18:05 +0000210 if (j == post_list_size)
Wolfgang Denk50da8372011-10-29 09:42:22 +0000211 printf("No such test: %s\n", name);
wdenka042ac82002-09-12 22:36:57 +0000212
213 name = s + 1;
214 }
215 }
Valentin Longchamp212a0ca2011-08-03 02:37:02 +0000216}
217#endif
218
219static void post_get_flags(int *test_flags)
220{
221 int j;
222
223 for (j = 0; j < post_list_size; j++)
224 test_flags[j] = post_list[j].flags;
225
226#ifndef CONFIG_POST_SKIP_ENV_FLAGS
227 post_get_env_flags(test_flags);
228#endif
wdenk6dff5522003-07-15 07:45:49 +0000229
Heiko Schochere92372c2011-10-12 01:18:05 +0000230 for (j = 0; j < post_list_size; j++)
231 if (test_flags[j] & POST_POWERON)
wdenk6dff5522003-07-15 07:45:49 +0000232 test_flags[j] |= POST_SLOWTEST;
wdenka042ac82002-09-12 22:36:57 +0000233}
234
Jeroen Hofstee002ad7b2014-10-08 22:57:25 +0200235__weak void show_post_progress(unsigned int test_num, int before, int result)
Michael Zaidmane070a562010-03-01 11:47:36 +0200236{
237}
Michael Zaidmane070a562010-03-01 11:47:36 +0200238
Heiko Schochere92372c2011-10-12 01:18:05 +0000239static int post_run_single(struct post_test *test,
wdenka042ac82002-09-12 22:36:57 +0000240 int test_flags, int flags, unsigned int i)
241{
242 if ((flags & test_flags & POST_ALWAYS) &&
243 (flags & test_flags & POST_MEM)) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000244 WATCHDOG_RESET();
wdenka042ac82002-09-12 22:36:57 +0000245
246 if (!(flags & POST_REBOOT)) {
Heiko Schochere92372c2011-10-12 01:18:05 +0000247 if ((test_flags & POST_REBOOT) &&
248 !(flags & POST_MANUAL)) {
249 post_bootmode_test_on(
Yuri Tikhonove262efe2008-02-04 14:11:03 +0100250 (gd->flags & GD_FLG_POSTFAIL) ?
251 POST_FAIL_SAVE | i : i);
wdenka042ac82002-09-12 22:36:57 +0000252 }
253
wdenk228f29a2002-12-08 09:53:23 +0000254 if (test_flags & POST_PREREL)
Heiko Schochere92372c2011-10-12 01:18:05 +0000255 post_log_mark_start(test->testid);
wdenk228f29a2002-12-08 09:53:23 +0000256 else
Heiko Schochere92372c2011-10-12 01:18:05 +0000257 post_log("POST %s ", test->cmd);
wdenka042ac82002-09-12 22:36:57 +0000258 }
259
Michael Zaidmane070a562010-03-01 11:47:36 +0200260 show_post_progress(i, POST_BEFORE, POST_FAILED);
261
wdenk228f29a2002-12-08 09:53:23 +0000262 if (test_flags & POST_PREREL) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000263 if ((*test->test)(flags) == 0) {
Heiko Schochere92372c2011-10-12 01:18:05 +0000264 post_log_mark_succ(test->testid);
Michael Zaidmane070a562010-03-01 11:47:36 +0200265 show_post_progress(i, POST_AFTER, POST_PASSED);
Wolfgang Denk50da8372011-10-29 09:42:22 +0000266 } else {
Michael Zaidmane070a562010-03-01 11:47:36 +0200267 show_post_progress(i, POST_AFTER, POST_FAILED);
Yuri Tikhonov28a38502008-05-08 15:45:26 +0200268 if (test_flags & POST_CRITICAL)
269 gd->flags |= GD_FLG_POSTFAIL;
270 if (test_flags & POST_STOP)
271 gd->flags |= GD_FLG_POSTSTOP;
272 }
wdenk228f29a2002-12-08 09:53:23 +0000273 } else {
James Kosin975afc32011-07-14 08:15:06 +0000274 if ((*test->test)(flags) != 0) {
275 post_log("FAILED\n");
Simon Glass770605e2012-02-13 13:51:18 +0000276 bootstage_error(BOOTSTAGE_ID_POST_FAIL_R);
James Kosin975afc32011-07-14 08:15:06 +0000277 show_post_progress(i, POST_AFTER, POST_FAILED);
278 if (test_flags & POST_CRITICAL)
279 gd->flags |= GD_FLG_POSTFAIL;
280 if (test_flags & POST_STOP)
281 gd->flags |= GD_FLG_POSTSTOP;
282 } else {
283 post_log("PASSED\n");
284 show_post_progress(i, POST_AFTER, POST_PASSED);
285 }
wdenk228f29a2002-12-08 09:53:23 +0000286 }
wdenka042ac82002-09-12 22:36:57 +0000287
Wolfgang Denk50da8372011-10-29 09:42:22 +0000288 if ((test_flags & POST_REBOOT) && !(flags & POST_MANUAL))
Heiko Schochere92372c2011-10-12 01:18:05 +0000289 post_bootmode_test_off();
wdenka042ac82002-09-12 22:36:57 +0000290
291 return 0;
292 } else {
293 return -1;
294 }
295}
296
Wolfgang Denk50da8372011-10-29 09:42:22 +0000297int post_run(char *name, int flags)
wdenka042ac82002-09-12 22:36:57 +0000298{
299 unsigned int i;
300 int test_flags[POST_MAX_NUMBER];
301
Heiko Schochere92372c2011-10-12 01:18:05 +0000302 post_get_flags(test_flags);
wdenka042ac82002-09-12 22:36:57 +0000303
304 if (name == NULL) {
305 unsigned int last;
306
Yuri Tikhonov28a38502008-05-08 15:45:26 +0200307 if (gd->flags & GD_FLG_POSTSTOP)
308 return 0;
309
Heiko Schochere92372c2011-10-12 01:18:05 +0000310 if (post_bootmode_get(&last) & POST_POWERTEST) {
Yuri Tikhonove262efe2008-02-04 14:11:03 +0100311 if (last & POST_FAIL_SAVE) {
312 last &= ~POST_FAIL_SAVE;
313 gd->flags |= GD_FLG_POSTFAIL;
314 }
wdenka042ac82002-09-12 22:36:57 +0000315 if (last < post_list_size &&
316 (flags & test_flags[last] & POST_ALWAYS) &&
317 (flags & test_flags[last] & POST_MEM)) {
318
Heiko Schochere92372c2011-10-12 01:18:05 +0000319 post_run_single(post_list + last,
wdenkea909b72002-11-21 23:11:29 +0000320 test_flags[last],
321 flags | POST_REBOOT, last);
wdenka042ac82002-09-12 22:36:57 +0000322
323 for (i = last + 1; i < post_list_size; i++) {
Yuri Tikhonov28a38502008-05-08 15:45:26 +0200324 if (gd->flags & GD_FLG_POSTSTOP)
325 break;
Heiko Schochere92372c2011-10-12 01:18:05 +0000326 post_run_single(post_list + i,
wdenkea909b72002-11-21 23:11:29 +0000327 test_flags[i],
328 flags, i);
wdenka042ac82002-09-12 22:36:57 +0000329 }
330 }
331 } else {
332 for (i = 0; i < post_list_size; i++) {
Yuri Tikhonov28a38502008-05-08 15:45:26 +0200333 if (gd->flags & GD_FLG_POSTSTOP)
334 break;
Heiko Schochere92372c2011-10-12 01:18:05 +0000335 post_run_single(post_list + i,
wdenkea909b72002-11-21 23:11:29 +0000336 test_flags[i],
337 flags, i);
wdenka042ac82002-09-12 22:36:57 +0000338 }
339 }
340
341 return 0;
342 } else {
343 for (i = 0; i < post_list_size; i++) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000344 if (strcmp(post_list[i].cmd, name) == 0)
wdenka042ac82002-09-12 22:36:57 +0000345 break;
346 }
347
348 if (i < post_list_size) {
Sascha Laue5744ddc2008-05-30 09:48:14 +0200349 WATCHDOG_RESET();
Heiko Schochere92372c2011-10-12 01:18:05 +0000350 return post_run_single(post_list + i,
wdenka042ac82002-09-12 22:36:57 +0000351 test_flags[i],
352 flags, i);
353 } else {
354 return -1;
355 }
356 }
357}
358
Heiko Schochere92372c2011-10-12 01:18:05 +0000359static int post_info_single(struct post_test *test, int full)
wdenka042ac82002-09-12 22:36:57 +0000360{
361 if (test->flags & POST_MANUAL) {
362 if (full)
Heiko Schochere92372c2011-10-12 01:18:05 +0000363 printf("%s - %s\n"
wdenka042ac82002-09-12 22:36:57 +0000364 " %s\n", test->cmd, test->name, test->desc);
365 else
Heiko Schochere92372c2011-10-12 01:18:05 +0000366 printf(" %-15s - %s\n", test->cmd, test->name);
wdenka042ac82002-09-12 22:36:57 +0000367
368 return 0;
369 } else {
370 return -1;
371 }
372}
373
Wolfgang Denk50da8372011-10-29 09:42:22 +0000374int post_info(char *name)
wdenka042ac82002-09-12 22:36:57 +0000375{
376 unsigned int i;
377
378 if (name == NULL) {
Heiko Schochere92372c2011-10-12 01:18:05 +0000379 for (i = 0; i < post_list_size; i++)
380 post_info_single(post_list + i, 0);
wdenka042ac82002-09-12 22:36:57 +0000381
382 return 0;
383 } else {
384 for (i = 0; i < post_list_size; i++) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000385 if (strcmp(post_list[i].cmd, name) == 0)
wdenka042ac82002-09-12 22:36:57 +0000386 break;
387 }
388
Wolfgang Denk50da8372011-10-29 09:42:22 +0000389 if (i < post_list_size)
Heiko Schochere92372c2011-10-12 01:18:05 +0000390 return post_info_single(post_list + i, 1);
Wolfgang Denk50da8372011-10-29 09:42:22 +0000391 else
wdenka042ac82002-09-12 22:36:57 +0000392 return -1;
wdenka042ac82002-09-12 22:36:57 +0000393 }
394}
395
Heiko Schochere92372c2011-10-12 01:18:05 +0000396int post_log(char *format, ...)
wdenka042ac82002-09-12 22:36:57 +0000397{
398 va_list args;
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200399 char printbuffer[CONFIG_SYS_PBSIZE];
wdenka042ac82002-09-12 22:36:57 +0000400
Wolfgang Denk50da8372011-10-29 09:42:22 +0000401 va_start(args, format);
wdenka042ac82002-09-12 22:36:57 +0000402
403 /* For this to work, printbuffer must be larger than
404 * anything we ever want to print.
405 */
Wolfgang Denk4d6402b2011-10-29 09:42:23 +0000406 vsprintf(printbuffer, format, args);
Wolfgang Denk50da8372011-10-29 09:42:22 +0000407 va_end(args);
wdenka042ac82002-09-12 22:36:57 +0000408
409 /* Send to the stdout file */
Heiko Schochere92372c2011-10-12 01:18:05 +0000410 puts(printbuffer);
wdenka042ac82002-09-12 22:36:57 +0000411
412 return 0;
413}
414
Wolfgang Denk2e5167c2010-10-28 20:00:11 +0200415#ifdef CONFIG_NEEDS_MANUAL_RELOC
Heiko Schochere92372c2011-10-12 01:18:05 +0000416void post_reloc(void)
wdenka042ac82002-09-12 22:36:57 +0000417{
wdenka042ac82002-09-12 22:36:57 +0000418 unsigned int i;
419
420 /*
421 * We have to relocate the test table manually
422 */
423 for (i = 0; i < post_list_size; i++) {
424 ulong addr;
425 struct post_test *test = post_list + i;
426
427 if (test->name) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000428 addr = (ulong)(test->name) + gd->reloc_off;
Heiko Schochere92372c2011-10-12 01:18:05 +0000429 test->name = (char *)addr;
wdenka042ac82002-09-12 22:36:57 +0000430 }
431
432 if (test->cmd) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000433 addr = (ulong)(test->cmd) + gd->reloc_off;
Heiko Schochere92372c2011-10-12 01:18:05 +0000434 test->cmd = (char *)addr;
wdenka042ac82002-09-12 22:36:57 +0000435 }
436
437 if (test->desc) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000438 addr = (ulong)(test->desc) + gd->reloc_off;
Heiko Schochere92372c2011-10-12 01:18:05 +0000439 test->desc = (char *)addr;
wdenka042ac82002-09-12 22:36:57 +0000440 }
441
442 if (test->test) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000443 addr = (ulong)(test->test) + gd->reloc_off;
wdenka042ac82002-09-12 22:36:57 +0000444 test->test = (int (*)(int flags)) addr;
445 }
wdenk4532cb62003-04-27 22:52:51 +0000446
447 if (test->init_f) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000448 addr = (ulong)(test->init_f) + gd->reloc_off;
wdenk4532cb62003-04-27 22:52:51 +0000449 test->init_f = (int (*)(void)) addr;
450 }
451
452 if (test->reloc) {
Wolfgang Denk50da8372011-10-29 09:42:22 +0000453 addr = (ulong)(test->reloc) + gd->reloc_off;
wdenk4532cb62003-04-27 22:52:51 +0000454 test->reloc = (void (*)(void)) addr;
wdenk8bde7f72003-06-27 21:31:46 +0000455
wdenk4532cb62003-04-27 22:52:51 +0000456 test->reloc();
457 }
wdenka042ac82002-09-12 22:36:57 +0000458 }
459}
Peter Tyser521af042009-09-21 11:20:36 -0500460#endif
wdenka042ac82002-09-12 22:36:57 +0000461
wdenk4532cb62003-04-27 22:52:51 +0000462
463/*
464 * Some tests (e.g. SYSMON) need the time when post_init_f started,
465 * but we cannot use get_timer() at this point.
466 *
467 * On PowerPC we implement it using the timebase register.
468 */
Heiko Schochere92372c2011-10-12 01:18:05 +0000469unsigned long post_time_ms(unsigned long base)
wdenk4532cb62003-04-27 22:52:51 +0000470{
Tom Riniea3310e2017-03-14 11:08:10 -0400471#if defined(CONFIG_PPC) || defined(CONFIG_ARM)
Christian Rieschc90a4dd2011-12-09 16:54:02 +0100472 return (unsigned long)lldiv(get_ticks(), get_tbclk() / CONFIG_SYS_HZ)
Heiko Schochere92372c2011-10-12 01:18:05 +0000473 - base;
wdenk4532cb62003-04-27 22:52:51 +0000474#else
Wolfgang Denkad5bb452007-03-06 18:08:43 +0100475#warning "Not implemented yet"
wdenk4532cb62003-04-27 22:52:51 +0000476 return 0; /* Not implemented yet */
477#endif
478}